TRIM patch v2
Link to this paste: http://bugs.dragonflybsd.org/pastes/422
Added by bissont 7 months ago.
Syntax: Diff
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
* Removed DRAT conditional to enable TRIM * 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 softdep. 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 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 */ |