This is a note to let you know that I've just added the patch titled NFSv4.1/pnfs: replace broken pnfs_put_lseg_async to the 3.17-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: nfsv4.1-pnfs-replace-broken-pnfs_put_lseg_async.patch and it can be found in the queue-3.17 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 6543f803670530f6aa93790d9fa116d8395a537d Mon Sep 17 00:00:00 2001 From: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> Date: Wed, 8 Oct 2014 16:39:12 -0400 Subject: NFSv4.1/pnfs: replace broken pnfs_put_lseg_async From: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> commit 6543f803670530f6aa93790d9fa116d8395a537d upstream. You cannot call pnfs_put_lseg_async() more than once per lseg, so it is really an inappropriate way to deal with a refcount issue. Instead, replace it with a function that decrements the refcount, and puts the final 'free' operation (which is incompatible with locks) on the workqueue. Cc: Weston Andros Adamson <dros@xxxxxxxxxxxxxxx> Fixes: e6cf82d1830f: pnfs: add pnfs_put_lseg_async Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- fs/nfs/filelayout/filelayout.c | 2 +- fs/nfs/pnfs.c | 33 +++++++++++++++++++++++++++------ fs/nfs/pnfs.h | 6 +----- 3 files changed, 29 insertions(+), 12 deletions(-) --- a/fs/nfs/filelayout/filelayout.c +++ b/fs/nfs/filelayout/filelayout.c @@ -1031,7 +1031,7 @@ filelayout_clear_request_commit(struct n } out: nfs_request_remove_commit_list(req, cinfo); - pnfs_put_lseg_async(freeme); + pnfs_put_lseg_locked(freeme); } static void --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -361,22 +361,43 @@ pnfs_put_lseg(struct pnfs_layout_segment } EXPORT_SYMBOL_GPL(pnfs_put_lseg); -static void pnfs_put_lseg_async_work(struct work_struct *work) +static void pnfs_free_lseg_async_work(struct work_struct *work) { struct pnfs_layout_segment *lseg; + struct pnfs_layout_hdr *lo; lseg = container_of(work, struct pnfs_layout_segment, pls_work); + lo = lseg->pls_layout; - pnfs_put_lseg(lseg); + pnfs_free_lseg(lseg); + pnfs_put_layout_hdr(lo); } -void -pnfs_put_lseg_async(struct pnfs_layout_segment *lseg) +static void pnfs_free_lseg_async(struct pnfs_layout_segment *lseg) { - INIT_WORK(&lseg->pls_work, pnfs_put_lseg_async_work); + INIT_WORK(&lseg->pls_work, pnfs_free_lseg_async_work); schedule_work(&lseg->pls_work); } -EXPORT_SYMBOL_GPL(pnfs_put_lseg_async); + +void +pnfs_put_lseg_locked(struct pnfs_layout_segment *lseg) +{ + if (!lseg) + return; + + assert_spin_locked(&lseg->pls_layout->plh_inode->i_lock); + + dprintk("%s: lseg %p ref %d valid %d\n", __func__, lseg, + atomic_read(&lseg->pls_refcount), + test_bit(NFS_LSEG_VALID, &lseg->pls_flags)); + if (atomic_dec_and_test(&lseg->pls_refcount)) { + struct pnfs_layout_hdr *lo = lseg->pls_layout; + pnfs_get_layout_hdr(lo); + pnfs_layout_remove_lseg(lo, lseg); + pnfs_free_lseg_async(lseg); + } +} +EXPORT_SYMBOL_GPL(pnfs_put_lseg_locked); static u64 end_offset(u64 start, u64 len) --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -183,7 +183,7 @@ extern int nfs4_proc_layoutreturn(struct /* pnfs.c */ void pnfs_get_layout_hdr(struct pnfs_layout_hdr *lo); void pnfs_put_lseg(struct pnfs_layout_segment *lseg); -void pnfs_put_lseg_async(struct pnfs_layout_segment *lseg); +void pnfs_put_lseg_locked(struct pnfs_layout_segment *lseg); void set_pnfs_layoutdriver(struct nfs_server *, const struct nfs_fh *, u32); void unset_pnfs_layoutdriver(struct nfs_server *); @@ -422,10 +422,6 @@ static inline void pnfs_put_lseg(struct { } -static inline void pnfs_put_lseg_async(struct pnfs_layout_segment *lseg) -{ -} - static inline int pnfs_return_layout(struct inode *ino) { return 0; Patches currently in stable-queue which might be from trond.myklebust@xxxxxxxxxxxxxxx are queue-3.17/nfsv4.1-pnfs-replace-broken-pnfs_put_lseg_async.patch queue-3.17/nfs-fix-an-uninitialised-pointer-oops-in-the-writeback-error-path.patch queue-3.17/nfs-fix-duplicate-proc-entries.patch queue-3.17/fixing-lease-renewal.patch queue-3.17/nfsv4-fix-lock-recovery-when-create_session-setclientid_confirm-fails.patch queue-3.17/nfsv4.1-fix-an-nfsv4.1-state-renewal-regression.patch queue-3.17/nfs-fix-a-bogus-warning-in-nfs_generic_pgio.patch queue-3.17/nfsv4-fix-open-lock-state-recovery-error-handling.patch -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html