TRIM patch v2

Link to this paste: http://bugs.dragonflybsd.org/pastes/422

Added by about 2 years 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 */

Download