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:
John Dyson 1997-08-04 05:10:31 +00:00
parent a6eecebbe5
commit 5fd549b62e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=27881
8 changed files with 76 additions and 38 deletions

View File

@ -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];

View File

@ -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];

View File

@ -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);
}

View File

@ -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); \
}

View File

@ -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];

View File

@ -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];

View File

@ -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);
}

View File

@ -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); \
}