summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/ufs/ffs/ffs_alloc.c6
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c13
-rw-r--r--sys/ufs/ufs/ufsmount.h3
3 files changed, 19 insertions, 3 deletions
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index 19c00de..799efe3 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -2270,8 +2270,6 @@ ffs_blkfree_cg(ump, fs, devvp, bno, size, inum, dephd)
bdwrite(bp);
}
-TASKQUEUE_DEFINE_THREAD(ffs_trim);
-
struct ffs_blkfree_trim_params {
struct task task;
struct ufsmount *ump;
@@ -2294,6 +2292,7 @@ ffs_blkfree_trim_task(ctx, pending)
ffs_blkfree_cg(tp->ump, tp->ump->um_fs, tp->devvp, tp->bno, tp->size,
tp->inum, tp->pdephd);
vn_finished_secondary_write(UFSTOVFS(tp->ump));
+ atomic_add_int(&tp->ump->um_trim_inflight, -1);
free(tp, M_TEMP);
}
@@ -2306,7 +2305,7 @@ ffs_blkfree_trim_completed(bip)
tp = bip->bio_caller2;
g_destroy_bio(bip);
TASK_INIT(&tp->task, 0, ffs_blkfree_trim_task, tp);
- taskqueue_enqueue(taskqueue_ffs_trim, &tp->task);
+ taskqueue_enqueue(tp->ump->um_trim_tq, &tp->task);
}
void
@@ -2350,6 +2349,7 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum, vtype, dephd)
* reordering, TRIM might be issued after we reuse the block
* and write some new data into it.
*/
+ atomic_add_int(&ump->um_trim_inflight, 1);
tp = malloc(sizeof(struct ffs_blkfree_trim_params), M_TEMP, M_WAITOK);
tp->ump = ump;
tp->devvp = devvp;
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index a82ef61..b89dc33 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <sys/namei.h>
#include <sys/priv.h>
#include <sys/proc.h>
+#include <sys/taskqueue.h>
#include <sys/kernel.h>
#include <sys/vnode.h>
#include <sys/mount.h>
@@ -1005,6 +1006,12 @@ ffs_mountfs(devvp, mp, td)
mp->mnt_stat.f_mntonname);
ump->um_candelete = 0;
}
+ if (ump->um_candelete) {
+ ump->um_trim_tq = taskqueue_create("trim", M_WAITOK,
+ taskqueue_thread_enqueue, &ump->um_trim_tq);
+ taskqueue_start_threads(&ump->um_trim_tq, 1, PVFS,
+ "%s trim", mp->mnt_stat.f_mntonname);
+ }
}
ump->um_mountp = mp;
@@ -1260,6 +1267,12 @@ ffs_unmount(mp, mntflags)
}
if (susp)
vfs_write_resume(mp, VR_START_WRITE);
+ if (ump->um_trim_tq != NULL) {
+ while (ump->um_trim_inflight != 0)
+ pause("ufsutr", hz);
+ taskqueue_drain_all(ump->um_trim_tq);
+ taskqueue_free(ump->um_trim_tq);
+ }
DROP_GIANT();
g_topology_lock();
if (ump->um_fsckpid > 0) {
diff --git a/sys/ufs/ufs/ufsmount.h b/sys/ufs/ufs/ufsmount.h
index 6b357c1..838c1e3 100644
--- a/sys/ufs/ufs/ufsmount.h
+++ b/sys/ufs/ufs/ufsmount.h
@@ -50,6 +50,7 @@ MALLOC_DECLARE(M_UFSMNT);
struct buf;
struct inode;
struct nameidata;
+struct taskqueue;
struct timeval;
struct ucred;
struct uio;
@@ -85,6 +86,8 @@ struct ufsmount {
int64_t um_savedmaxfilesize; /* XXX - limit maxfilesize */
int um_candelete; /* devvp supports TRIM */
int um_writesuspended; /* suspension in progress */
+ u_int um_trim_inflight;
+ struct taskqueue *um_trim_tq;
int (*um_balloc)(struct vnode *, off_t, int, struct ucred *,
int, struct buf **);
int (*um_blkatoff)(struct vnode *, off_t, char **, struct buf **);
OpenPOWER on IntegriCloud