Fix a problem with ext2fs so that filesystems mounted at reboot don't
keep ahold of buffers, and therefore leave filesystems dirty. I haven't been able to test, but the code compiles. Those who run -current, please test and report back!!! (Sorry :-)). PR: kern/3571 Submitted by: Dirk Keunecke <dk@panda.rhein-main.de>
This commit is contained in:
parent
a6eecebbe5
commit
5fd549b62e
@ -69,6 +69,7 @@ static void read_block_bitmap (struct mount * mp,
|
||||
block_group, (unsigned long) gdp->bg_block_bitmap);
|
||||
sb->s_block_bitmap_number[bitmap_nr] = block_group;
|
||||
sb->s_block_bitmap[bitmap_nr] = bh;
|
||||
LCK_BUF(bh)
|
||||
}
|
||||
|
||||
/*
|
||||
@ -129,7 +130,8 @@ static int load__block_bitmap (struct mount * mp,
|
||||
if (sb->s_loaded_block_bitmaps < EXT2_MAX_GROUP_LOADED)
|
||||
sb->s_loaded_block_bitmaps++;
|
||||
else
|
||||
brelse (sb->s_block_bitmap[EXT2_MAX_GROUP_LOADED - 1]);
|
||||
ULCK_BUF(sb->s_block_bitmap[EXT2_MAX_GROUP_LOADED - 1])
|
||||
|
||||
for (j = sb->s_loaded_block_bitmaps - 1; j > 0; j--) {
|
||||
sb->s_block_bitmap_number[j] =
|
||||
sb->s_block_bitmap_number[j - 1];
|
||||
|
@ -127,6 +127,7 @@ static void read_inode_bitmap (struct mount * mp,
|
||||
block_group, (unsigned long) gdp->bg_inode_bitmap);
|
||||
sb->s_inode_bitmap_number[bitmap_nr] = block_group;
|
||||
sb->s_inode_bitmap[bitmap_nr] = bh;
|
||||
LCK_BUF(bh)
|
||||
}
|
||||
|
||||
/*
|
||||
@ -190,7 +191,7 @@ static int load_inode_bitmap (struct mount * mp,
|
||||
if (sb->s_loaded_inode_bitmaps < EXT2_MAX_GROUP_LOADED)
|
||||
sb->s_loaded_inode_bitmaps++;
|
||||
else
|
||||
brelse (sb->s_inode_bitmap[EXT2_MAX_GROUP_LOADED - 1]);
|
||||
ULCK_BUF(sb->s_inode_bitmap[EXT2_MAX_GROUP_LOADED - 1])
|
||||
for (j = sb->s_loaded_inode_bitmaps - 1; j > 0; j--) {
|
||||
sb->s_inode_bitmap_number[j] =
|
||||
sb->s_inode_bitmap_number[j - 1];
|
||||
|
@ -412,10 +412,12 @@ static int compute_sb_data(devvp, es, fs)
|
||||
printf("EXT2-fs: unable to read group descriptors (%d)\n", error);
|
||||
return EIO;
|
||||
}
|
||||
/* Set the B_LOCKED flag on the buffer, then brelse() it */
|
||||
LCK_BUF(fs->s_group_desc[i])
|
||||
}
|
||||
if(!ext2_check_descriptors(fs)) {
|
||||
for (j = 0; j < db_count; j++)
|
||||
brelse(fs->s_group_desc[j]);
|
||||
ULCK_BUF(fs->s_group_desc[j])
|
||||
bsd_free(fs->s_group_desc, M_UFSMNT);
|
||||
printf("EXT2-fs: (ext2_check_descriptors failure) "
|
||||
"unable to read group descriptors\n");
|
||||
@ -691,16 +693,19 @@ ext2_unmount(mp, mntflags, p)
|
||||
fs->s_es->s_state |= EXT2_VALID_FS; /* was fs_clean = 1 */
|
||||
ext2_sbupdate(ump, MNT_WAIT);
|
||||
}
|
||||
|
||||
/* release buffers containing group descriptors */
|
||||
for(i = 0; i < fs->s_db_per_group; i++)
|
||||
brelse(fs->s_group_desc[i]);
|
||||
ULCK_BUF(fs->s_group_desc[i])
|
||||
|
||||
/* release cached inode/block bitmaps */
|
||||
for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
|
||||
if (fs->s_inode_bitmap[i])
|
||||
brelse (fs->s_inode_bitmap[i]);
|
||||
ULCK_BUF(fs->s_inode_bitmap[i])
|
||||
|
||||
for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
|
||||
if (fs->s_block_bitmap[i])
|
||||
brelse (fs->s_block_bitmap[i]);
|
||||
ULCK_BUF(fs->s_block_bitmap[i])
|
||||
|
||||
ump->um_devvp->v_specflags &= ~SI_MOUNTEDON;
|
||||
error = VOP_CLOSE(ump->um_devvp, ronly ? FREAD : FREAD|FWRITE,
|
||||
@ -1106,20 +1111,11 @@ printf("\nupdating superblock, waitfor=%s\n", waitfor == MNT_WAIT ? "yes":"no");
|
||||
else
|
||||
bawrite(bp);
|
||||
|
||||
/* write group descriptors back on disk */
|
||||
for(i = 0; i < fs->s_db_per_group; i++)
|
||||
/* Godmar thinks: we must avoid using any of the b*write
|
||||
* functions here: we want to keep the buffer locked
|
||||
* so we use my 'housemade' write routine:
|
||||
/*
|
||||
* The buffers for group descriptors, inode bitmaps and block bitmaps
|
||||
* are not busy at this point and are (hopefully) written by the
|
||||
* usual sync mechanism. No need to write them here
|
||||
*/
|
||||
error |= ll_w_block(fs->s_group_desc[i], waitfor == MNT_WAIT);
|
||||
|
||||
for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
|
||||
if (fs->s_inode_bitmap[i])
|
||||
ll_w_block (fs->s_inode_bitmap[i], 1);
|
||||
for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
|
||||
if (fs->s_block_bitmap[i])
|
||||
ll_w_block (fs->s_block_bitmap[i], 1);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
@ -155,3 +155,23 @@ extern u_char *fragtbl[];
|
||||
#define lock_super(devvp) vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, curproc)
|
||||
#define unlock_super(devvp) VOP_UNLOCK(devvp, 0, curproc)
|
||||
|
||||
/*
|
||||
* To lock a buffer, set the B_LOCKED flag and then brelse() it. To unlock,
|
||||
* reset the B_LOCKED flag and brelse() the buffer back on the LRU list
|
||||
*/
|
||||
#define LCK_BUF(bp) { \
|
||||
int s; \
|
||||
s = splbio(); \
|
||||
(bp)->b_flags |= B_LOCKED; \
|
||||
splx(s); \
|
||||
brelse(bp); \
|
||||
}
|
||||
|
||||
#define ULCK_BUF(bp) { \
|
||||
int s; \
|
||||
s = splbio(); \
|
||||
(bp)->b_flags &= ~B_LOCKED; \
|
||||
splx(s); \
|
||||
bremfree(bp); \
|
||||
brelse(bp); \
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ static void read_block_bitmap (struct mount * mp,
|
||||
block_group, (unsigned long) gdp->bg_block_bitmap);
|
||||
sb->s_block_bitmap_number[bitmap_nr] = block_group;
|
||||
sb->s_block_bitmap[bitmap_nr] = bh;
|
||||
LCK_BUF(bh)
|
||||
}
|
||||
|
||||
/*
|
||||
@ -129,7 +130,8 @@ static int load__block_bitmap (struct mount * mp,
|
||||
if (sb->s_loaded_block_bitmaps < EXT2_MAX_GROUP_LOADED)
|
||||
sb->s_loaded_block_bitmaps++;
|
||||
else
|
||||
brelse (sb->s_block_bitmap[EXT2_MAX_GROUP_LOADED - 1]);
|
||||
ULCK_BUF(sb->s_block_bitmap[EXT2_MAX_GROUP_LOADED - 1])
|
||||
|
||||
for (j = sb->s_loaded_block_bitmaps - 1; j > 0; j--) {
|
||||
sb->s_block_bitmap_number[j] =
|
||||
sb->s_block_bitmap_number[j - 1];
|
||||
|
@ -127,6 +127,7 @@ static void read_inode_bitmap (struct mount * mp,
|
||||
block_group, (unsigned long) gdp->bg_inode_bitmap);
|
||||
sb->s_inode_bitmap_number[bitmap_nr] = block_group;
|
||||
sb->s_inode_bitmap[bitmap_nr] = bh;
|
||||
LCK_BUF(bh)
|
||||
}
|
||||
|
||||
/*
|
||||
@ -190,7 +191,7 @@ static int load_inode_bitmap (struct mount * mp,
|
||||
if (sb->s_loaded_inode_bitmaps < EXT2_MAX_GROUP_LOADED)
|
||||
sb->s_loaded_inode_bitmaps++;
|
||||
else
|
||||
brelse (sb->s_inode_bitmap[EXT2_MAX_GROUP_LOADED - 1]);
|
||||
ULCK_BUF(sb->s_inode_bitmap[EXT2_MAX_GROUP_LOADED - 1])
|
||||
for (j = sb->s_loaded_inode_bitmaps - 1; j > 0; j--) {
|
||||
sb->s_inode_bitmap_number[j] =
|
||||
sb->s_inode_bitmap_number[j - 1];
|
||||
|
@ -412,10 +412,12 @@ static int compute_sb_data(devvp, es, fs)
|
||||
printf("EXT2-fs: unable to read group descriptors (%d)\n", error);
|
||||
return EIO;
|
||||
}
|
||||
/* Set the B_LOCKED flag on the buffer, then brelse() it */
|
||||
LCK_BUF(fs->s_group_desc[i])
|
||||
}
|
||||
if(!ext2_check_descriptors(fs)) {
|
||||
for (j = 0; j < db_count; j++)
|
||||
brelse(fs->s_group_desc[j]);
|
||||
ULCK_BUF(fs->s_group_desc[j])
|
||||
bsd_free(fs->s_group_desc, M_UFSMNT);
|
||||
printf("EXT2-fs: (ext2_check_descriptors failure) "
|
||||
"unable to read group descriptors\n");
|
||||
@ -691,16 +693,19 @@ ext2_unmount(mp, mntflags, p)
|
||||
fs->s_es->s_state |= EXT2_VALID_FS; /* was fs_clean = 1 */
|
||||
ext2_sbupdate(ump, MNT_WAIT);
|
||||
}
|
||||
|
||||
/* release buffers containing group descriptors */
|
||||
for(i = 0; i < fs->s_db_per_group; i++)
|
||||
brelse(fs->s_group_desc[i]);
|
||||
ULCK_BUF(fs->s_group_desc[i])
|
||||
|
||||
/* release cached inode/block bitmaps */
|
||||
for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
|
||||
if (fs->s_inode_bitmap[i])
|
||||
brelse (fs->s_inode_bitmap[i]);
|
||||
ULCK_BUF(fs->s_inode_bitmap[i])
|
||||
|
||||
for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
|
||||
if (fs->s_block_bitmap[i])
|
||||
brelse (fs->s_block_bitmap[i]);
|
||||
ULCK_BUF(fs->s_block_bitmap[i])
|
||||
|
||||
ump->um_devvp->v_specflags &= ~SI_MOUNTEDON;
|
||||
error = VOP_CLOSE(ump->um_devvp, ronly ? FREAD : FREAD|FWRITE,
|
||||
@ -1106,20 +1111,11 @@ printf("\nupdating superblock, waitfor=%s\n", waitfor == MNT_WAIT ? "yes":"no");
|
||||
else
|
||||
bawrite(bp);
|
||||
|
||||
/* write group descriptors back on disk */
|
||||
for(i = 0; i < fs->s_db_per_group; i++)
|
||||
/* Godmar thinks: we must avoid using any of the b*write
|
||||
* functions here: we want to keep the buffer locked
|
||||
* so we use my 'housemade' write routine:
|
||||
/*
|
||||
* The buffers for group descriptors, inode bitmaps and block bitmaps
|
||||
* are not busy at this point and are (hopefully) written by the
|
||||
* usual sync mechanism. No need to write them here
|
||||
*/
|
||||
error |= ll_w_block(fs->s_group_desc[i], waitfor == MNT_WAIT);
|
||||
|
||||
for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
|
||||
if (fs->s_inode_bitmap[i])
|
||||
ll_w_block (fs->s_inode_bitmap[i], 1);
|
||||
for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
|
||||
if (fs->s_block_bitmap[i])
|
||||
ll_w_block (fs->s_block_bitmap[i], 1);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
@ -155,3 +155,23 @@ extern u_char *fragtbl[];
|
||||
#define lock_super(devvp) vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, curproc)
|
||||
#define unlock_super(devvp) VOP_UNLOCK(devvp, 0, curproc)
|
||||
|
||||
/*
|
||||
* To lock a buffer, set the B_LOCKED flag and then brelse() it. To unlock,
|
||||
* reset the B_LOCKED flag and brelse() the buffer back on the LRU list
|
||||
*/
|
||||
#define LCK_BUF(bp) { \
|
||||
int s; \
|
||||
s = splbio(); \
|
||||
(bp)->b_flags |= B_LOCKED; \
|
||||
splx(s); \
|
||||
brelse(bp); \
|
||||
}
|
||||
|
||||
#define ULCK_BUF(bp) { \
|
||||
int s; \
|
||||
s = splbio(); \
|
||||
(bp)->b_flags &= ~B_LOCKED; \
|
||||
splx(s); \
|
||||
bremfree(bp); \
|
||||
brelse(bp); \
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user