From 4c50d6f2a3f84cddd465d2ba70420d01b7fc6110 Mon Sep 17 00:00:00 2001 From: Tim Bisson Date: Sun, 21 Oct 2012 19:50:39 -0700 Subject: [PATCH] TRIM fixes: * if trim is on as a option, display that when typing "mount" * change post trim ffs_blkfree_cg() to use taskqueue_swi_mp and get mp token when modifying freemap * Make TRIM work with softdep. origional ptr to vnode will go away with oftdep. Stash a copy of that vnode's mount point in the ufs inode so that if we are using softdep, we can get access to the mount point through the faked up inode (created in freeblocks). ** ip->i_devvp->v_mount->mnt_flag doesn't have mount options --- sys/kern/vfs_subr.c | 1 + sys/vfs/ufs/ffs_alloc.c | 15 +++++++++++++-- sys/vfs/ufs/ffs_softdep.c | 3 +++ sys/vfs/ufs/inode.h | 1 + sys/vfs/ufs/softdep.h | 1 + 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index e6a0024..a3b2035 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1835,6 +1835,7 @@ vfs_flagstostr(int flags, const struct mountctl_opt *optp, { MNT_SUIDDIR, "suiddir" }, { MNT_SOFTDEP, "soft-updates" }, { MNT_IGNORE, "ignore" }, + { MNT_TRIM, "trim" }, { 0, NULL} }; int bwritten; diff --git a/sys/vfs/ufs/ffs_alloc.c b/sys/vfs/ufs/ffs_alloc.c index afcde72..65d18c1 100644 --- a/sys/vfs/ufs/ffs_alloc.c +++ b/sys/vfs/ufs/ffs_alloc.c @@ -1627,8 +1627,10 @@ ffs_blkfree_trim_task(void *ctx, int pending) struct ffs_blkfree_trim_params *tp; tp = ctx; + lwkt_gettoken(&tp->i_devvp->v_mount->mnt_token); ffs_blkfree_cg(tp->i_fs, tp->i_devvp, tp->i_dev, tp->i_number, tp->i_din_uid, tp->bno, tp->size); + lwkt_reltoken(&tp->i_devvp->v_mount->mnt_token); kfree(tp, M_TEMP); } @@ -1643,7 +1645,7 @@ ffs_blkfree_trim_completed(struct bio *biop) tp = bp->b_bio1.bio_caller_info1.ptr; TASK_INIT(&tp->task, 0, ffs_blkfree_trim_task, tp); tp = biop->bio_caller_info1.ptr; - taskqueue_enqueue(taskqueue_swi, &tp->task); + taskqueue_enqueue(taskqueue_swi_mp, &tp->task); biodone(biop); } @@ -1658,8 +1660,17 @@ ffs_blkfree_trim_completed(struct bio *biop) void ffs_blkfree(struct inode *ip, ufs_daddr_t bno, long size) { - struct mount *mp = ip->i_devvp->v_mount; + struct vnode *vn = ip->i_vnode; struct ffs_blkfree_trim_params *tp; + struct mount *mp; + + if (vn == NULL) { + /* coming here through softdep w/ stored vnode's mp */ + mp = ip->i_vmnt; + } + else { /* The vnode is still around */ + mp = vn->v_mount; + } if (!(mp->mnt_flag & MNT_TRIM)) { ffs_blkfree_cg(ip->i_fs, ip->i_devvp,ip->i_dev,ip->i_number, diff --git a/sys/vfs/ufs/ffs_softdep.c b/sys/vfs/ufs/ffs_softdep.c index b6a8cbf..2559aa5 100644 --- a/sys/vfs/ufs/ffs_softdep.c +++ b/sys/vfs/ufs/ffs_softdep.c @@ -1740,6 +1740,7 @@ softdep_setup_freeblocks(struct inode *ip, off_t length) freeblks->fb_uid = ip->i_uid; freeblks->fb_previousinum = ip->i_number; freeblks->fb_devvp = ip->i_devvp; + freeblks->fb_vmount = ITOV(ip)->v_mount; freeblks->fb_fs = fs; freeblks->fb_oldsize = ip->i_size; freeblks->fb_newsize = length; @@ -2130,6 +2131,8 @@ handle_workitem_freeblocks(struct freeblks *freeblks) ufs_lbn_t baselbns[NIADDR], tmpval; tip.i_number = freeblks->fb_previousinum; + tip.i_vnode = NULL; + tip.i_vmnt = freeblks->fb_vmount; tip.i_devvp = freeblks->fb_devvp; tip.i_dev = freeblks->fb_devvp->v_rdev; tip.i_fs = freeblks->fb_fs; diff --git a/sys/vfs/ufs/inode.h b/sys/vfs/ufs/inode.h index f85ccfa..b700984 100644 --- a/sys/vfs/ufs/inode.h +++ b/sys/vfs/ufs/inode.h @@ -92,6 +92,7 @@ struct inode { struct ufs_dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */ u_quad_t i_modrev; /* Revision level for NFS lease. */ struct lockf i_lockf;/* Head of byte-level lock list. */ + struct mount *i_vmnt;/* Vnode's mp: for (soft-dep) blk-free */ /* * Side effects; used during directory lookup. */ diff --git a/sys/vfs/ufs/softdep.h b/sys/vfs/ufs/softdep.h index c99396a..d65e48a 100644 --- a/sys/vfs/ufs/softdep.h +++ b/sys/vfs/ufs/softdep.h @@ -401,6 +401,7 @@ struct freeblks { ino_t fb_previousinum; /* inode of previous owner of blocks */ struct vnode *fb_devvp; /* filesystem device vnode */ struct fs *fb_fs; /* addr of superblock */ + struct mount *fb_vmount; /* vnode mp */ off_t fb_oldsize; /* previous file size */ off_t fb_newsize; /* new file size */ int fb_chkcnt; /* used to check cnt of blks released */ -- 1.7.9.6 (Apple Git-31.1)