From 4e7b66abe045d122a11f4d7f419ec6605b6c1fb6 Mon Sep 17 00:00:00 2001 From: kib Date: Sun, 10 Apr 2016 16:32:21 +0000 Subject: [PATCH] MFC r297311: Ensure that TRIMs are finished before unmount destroys ufsmount. git-svn-id: svn://svn.freebsd.org/base/stable/10@297787 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sys/ufs/ffs/ffs_alloc.c | 6 +++--- sys/ufs/ffs/ffs_vfsops.c | 13 +++++++++++++ sys/ufs/ufs/ufsmount.h | 3 +++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c index 9982139b9..958c37ec1 100644 --- a/sys/ufs/ffs/ffs_alloc.c +++ b/sys/ufs/ffs/ffs_alloc.c @@ -2259,8 +2259,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; @@ -2283,6 +2281,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); } @@ -2295,7 +2294,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 @@ -2339,6 +2338,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 1c7b9dbc3..a46ce4c90 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -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 8b7ad11a9..1d3de0bbe 100644 --- a/sys/ufs/ufs/ufsmount.h +++ b/sys/ufs/ufs/ufsmount.h @@ -52,6 +52,7 @@ MALLOC_DECLARE(M_UFSMNT); struct buf; struct inode; struct nameidata; +struct taskqueue; struct timeval; struct ucred; struct uio; @@ -87,6 +88,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 **); -- 2.45.0