summaryrefslogtreecommitdiffstats
path: root/sys/gnu
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1997-08-04 05:10:31 +0000
committerdyson <dyson@FreeBSD.org>1997-08-04 05:10:31 +0000
commitec0474c458fa4162bdea016821c68694840ce909 (patch)
tree460f71c900f27e7ad0d39327671ffc14c15b95cf /sys/gnu
parent17f776e5506226b7d23df2e9e363af9203813a2c (diff)
downloadFreeBSD-src-ec0474c458fa4162bdea016821c68694840ce909.zip
FreeBSD-src-ec0474c458fa4162bdea016821c68694840ce909.tar.gz
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>
Diffstat (limited to 'sys/gnu')
-rw-r--r--sys/gnu/ext2fs/ext2_linux_balloc.c4
-rw-r--r--sys/gnu/ext2fs/ext2_linux_ialloc.c3
-rw-r--r--sys/gnu/ext2fs/ext2_vfsops.c30
-rw-r--r--sys/gnu/ext2fs/fs.h20
-rw-r--r--sys/gnu/fs/ext2fs/ext2_linux_balloc.c4
-rw-r--r--sys/gnu/fs/ext2fs/ext2_linux_ialloc.c3
-rw-r--r--sys/gnu/fs/ext2fs/ext2_vfsops.c30
-rw-r--r--sys/gnu/fs/ext2fs/fs.h20
8 files changed, 76 insertions, 38 deletions
diff --git a/sys/gnu/ext2fs/ext2_linux_balloc.c b/sys/gnu/ext2fs/ext2_linux_balloc.c
index e0c955a..aa17650 100644
--- a/sys/gnu/ext2fs/ext2_linux_balloc.c
+++ b/sys/gnu/ext2fs/ext2_linux_balloc.c
@@ -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];
diff --git a/sys/gnu/ext2fs/ext2_linux_ialloc.c b/sys/gnu/ext2fs/ext2_linux_ialloc.c
index c93c20e..9f2a967 100644
--- a/sys/gnu/ext2fs/ext2_linux_ialloc.c
+++ b/sys/gnu/ext2fs/ext2_linux_ialloc.c
@@ -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];
diff --git a/sys/gnu/ext2fs/ext2_vfsops.c b/sys/gnu/ext2fs/ext2_vfsops.c
index b56ed97..253d0e5 100644
--- a/sys/gnu/ext2fs/ext2_vfsops.c
+++ b/sys/gnu/ext2fs/ext2_vfsops.c
@@ -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);
}
diff --git a/sys/gnu/ext2fs/fs.h b/sys/gnu/ext2fs/fs.h
index 03f137c..3cb4fc0 100644
--- a/sys/gnu/ext2fs/fs.h
+++ b/sys/gnu/ext2fs/fs.h
@@ -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); \
+}
diff --git a/sys/gnu/fs/ext2fs/ext2_linux_balloc.c b/sys/gnu/fs/ext2fs/ext2_linux_balloc.c
index e0c955a..aa17650 100644
--- a/sys/gnu/fs/ext2fs/ext2_linux_balloc.c
+++ b/sys/gnu/fs/ext2fs/ext2_linux_balloc.c
@@ -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];
diff --git a/sys/gnu/fs/ext2fs/ext2_linux_ialloc.c b/sys/gnu/fs/ext2fs/ext2_linux_ialloc.c
index c93c20e..9f2a967 100644
--- a/sys/gnu/fs/ext2fs/ext2_linux_ialloc.c
+++ b/sys/gnu/fs/ext2fs/ext2_linux_ialloc.c
@@ -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];
diff --git a/sys/gnu/fs/ext2fs/ext2_vfsops.c b/sys/gnu/fs/ext2fs/ext2_vfsops.c
index b56ed97..253d0e5 100644
--- a/sys/gnu/fs/ext2fs/ext2_vfsops.c
+++ b/sys/gnu/fs/ext2fs/ext2_vfsops.c
@@ -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);
}
diff --git a/sys/gnu/fs/ext2fs/fs.h b/sys/gnu/fs/ext2fs/fs.h
index 03f137c..3cb4fc0 100644
--- a/sys/gnu/fs/ext2fs/fs.h
+++ b/sys/gnu/fs/ext2fs/fs.h
@@ -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); \
+}
OpenPOWER on IntegriCloud