summaryrefslogtreecommitdiffstats
path: root/sys/fs/ext2fs/ext2_vfsops.c
diff options
context:
space:
mode:
authorpfg <pfg@FreeBSD.org>2011-12-15 20:31:18 +0000
committerpfg <pfg@FreeBSD.org>2011-12-15 20:31:18 +0000
commit37ef732e3706f181d980062a33f308832cd40d73 (patch)
treed9583affe60423447807fff7c05f2b9f2a1c852b /sys/fs/ext2fs/ext2_vfsops.c
parent1551a9d47765ddb3229399b4bb3fbacf4faaf66b (diff)
downloadFreeBSD-src-37ef732e3706f181d980062a33f308832cd40d73.zip
FreeBSD-src-37ef732e3706f181d980062a33f308832cd40d73.tar.gz
Bring in reallocblk to ext2fs.
The feature has been standard for a while in UFS as a means to reduce fragmentation, therefore maintaining consistent performance with filesystem aging. This is also very similar to what ext4 calls "delayed allocation". In his 2010 GSoC, Zheng Liu ported and benchmarked the missing FANCY_REALLOC code to find more consistent performance improvements than with the preallocation approach. PR: 159233 Author: Zheng Liu <gnehzuil AT SPAMFREE gmail DOT com> Sponsored by: Google Inc. Approved by: jhb (mentor) MFC after: 2 weeks
Diffstat (limited to 'sys/fs/ext2fs/ext2_vfsops.c')
-rw-r--r--sys/fs/ext2fs/ext2_vfsops.c57
1 files changed, 54 insertions, 3 deletions
diff --git a/sys/fs/ext2fs/ext2_vfsops.c b/sys/fs/ext2fs/ext2_vfsops.c
index 1b47e91..9395f98 100644
--- a/sys/fs/ext2fs/ext2_vfsops.c
+++ b/sys/fs/ext2fs/ext2_vfsops.c
@@ -405,7 +405,7 @@ compute_sb_data(struct vnode *devvp, struct ext2fs *es,
* Things to do to update the mount:
* 1) invalidate all cached meta-data.
* 2) re-read superblock from disk.
- * 3) re-read summary information from disk.
+ * 3) invalidate all cluster summary information.
* 4) invalidate all inactive vnodes.
* 5) invalidate all cached file data.
* 6) re-read inode data for all active vnodes.
@@ -419,7 +419,9 @@ ext2_reload(struct mount *mp, struct thread *td)
struct buf *bp;
struct ext2fs *es;
struct m_ext2fs *fs;
- int error;
+ struct csum *sump;
+ int error, i;
+ int32_t *lp;
if ((mp->mnt_flag & MNT_RDONLY) == 0)
return (EINVAL);
@@ -456,6 +458,19 @@ ext2_reload(struct mount *mp, struct thread *td)
#endif
brelse(bp);
+ /*
+ * Step 3: invalidate all cluster summary information.
+ */
+ if (fs->e2fs_contigsumsize > 0) {
+ lp = fs->e2fs_maxcluster;
+ sump = fs->e2fs_clustersum;
+ for (i = 0; i < fs->e2fs_gcount; i++, sump++) {
+ *lp++ = fs->e2fs_contigsumsize;
+ sump->cs_init = 0;
+ bzero(sump->cs_sum, fs->e2fs_contigsumsize + 1);
+ }
+ }
+
loop:
MNT_ILOCK(mp);
MNT_VNODE_FOREACH(vp, mp, mvp) {
@@ -511,8 +526,11 @@ ext2_mountfs(struct vnode *devvp, struct mount *mp)
struct cdev *dev = devvp->v_rdev;
struct g_consumer *cp;
struct bufobj *bo;
+ struct csum *sump;
int error;
int ronly;
+ int i, size;
+ int32_t *lp;
ronly = vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0);
/* XXX: use VOP_ACESS to check FS perms */
@@ -582,6 +600,33 @@ ext2_mountfs(struct vnode *devvp, struct mount *mp)
if ((error = compute_sb_data(devvp, ump->um_e2fs->e2fs, ump->um_e2fs)))
goto out;
+ /*
+ * Calculate the maximum contiguous blocks and size of cluster summary
+ * array. In FFS this is done by newfs; however the superblock in
+ * ext2fs doesn't have these variables so we just can calculate
+ * them here.
+ */
+ ump->um_e2fs->e2fs_maxcontig = MAX(1, MAXPHYS / ump->um_e2fs->e2fs_bsize);
+ if (ump->um_e2fs->e2fs_maxcontig > 0)
+ ump->um_e2fs->e2fs_contigsumsize =
+ MIN(ump->um_e2fs->e2fs_maxcontig, EXT2_MAXCONTIG);
+ else
+ ump->um_e2fs->e2fs_contigsumsize = 0;
+ if (ump->um_e2fs->e2fs_contigsumsize > 0) {
+ size = ump->um_e2fs->e2fs_gcount * sizeof(int32_t);
+ ump->um_e2fs->e2fs_maxcluster = malloc(size, M_EXT2MNT, M_WAITOK);
+ size = ump->um_e2fs->e2fs_gcount * sizeof(struct csum);
+ ump->um_e2fs->e2fs_clustersum = malloc(size, M_EXT2MNT, M_WAITOK);
+ lp = ump->um_e2fs->e2fs_maxcluster;
+ sump = ump->um_e2fs->e2fs_clustersum;
+ for (i = 0; i < ump->um_e2fs->e2fs_gcount; i++, sump++) {
+ *lp++ = ump->um_e2fs->e2fs_contigsumsize;
+ sump->cs_init = 0;
+ sump->cs_sum = malloc((ump->um_e2fs->e2fs_contigsumsize + 1) *
+ sizeof(int32_t), M_EXT2MNT, M_WAITOK | M_ZERO);
+ }
+ }
+
brelse(bp);
bp = NULL;
fs = ump->um_e2fs;
@@ -656,7 +701,8 @@ ext2_unmount(struct mount *mp, int mntflags)
{
struct ext2mount *ump;
struct m_ext2fs *fs;
- int error, flags, ronly;
+ struct csum *sump;
+ int error, flags, i, ronly;
flags = 0;
if (mntflags & MNT_FORCE) {
@@ -681,6 +727,11 @@ ext2_unmount(struct mount *mp, int mntflags)
g_topology_unlock();
PICKUP_GIANT();
vrele(ump->um_devvp);
+ sump = fs->e2fs_clustersum;
+ for (i = 0; i < fs->e2fs_gcount; i++, sump++)
+ free(sump->cs_sum, M_EXT2MNT);
+ free(fs->e2fs_clustersum, M_EXT2MNT);
+ free(fs->e2fs_maxcluster, M_EXT2MNT);
free(fs->e2fs_gd, M_EXT2MNT);
free(fs->e2fs_contigdirs, M_EXT2MNT);
free(fs->e2fs, M_EXT2MNT);
OpenPOWER on IntegriCloud