From: Alexandros Batsakis Subject: [PATCH 3/8] pnfs-submit: remove lgetcount, lretcount Date: Mon, 7 Jun 2010 14:11:48 -0700 Message-ID: <1275945113-3436-4-git-send-email-batsakis@netapp.com> References: <1275945113-3436-1-git-send-email-batsakis@netapp.com> <1275945113-3436-2-git-send-email-batsakis@netapp.com> <1275945113-3436-3-git-send-email-batsakis@netapp.com> Cc: bhalevy@panasas.com, Alexandros Batsakis To: linux-nfs@vger.kernel.org Return-path: Received: from mx2.netapp.com ([216.240.18.37]:54324 "EHLO mx2.netapp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753289Ab0FGVL0 (ORCPT ); Mon, 7 Jun 2010 17:11:26 -0400 In-Reply-To: <1275945113-3436-3-git-send-email-batsakis@netapp.com> Sender: linux-nfs-owner@vger.kernel.org List-ID: This is in order to prepare for the forgetful client. There is no need to explicitly count the number of outstanding layout operations, as the protocol has provision for it (seqid of stateid -- e.g. section 12.5.5.2.1.2). As long as no requests for intersecting layouts are issued LAYOUTGETs/LAYOUTRETURNs can be sent in parallel Signed-off-by: Alexandros Batsakis --- fs/nfs/nfs4proc.c | 5 ++--- fs/nfs/pnfs.c | 46 ++++++++++++---------------------------------- fs/nfs/pnfs.h | 3 +-- include/linux/nfs_fs.h | 2 -- 4 files changed, 15 insertions(+), 41 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index f962f92..bf854fe 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -5540,7 +5540,7 @@ static void nfs4_pnfs_layoutget_release(void *calldata) struct nfs4_pnfs_layoutget *lgp = calldata; dprintk("--> %s\n", __func__); - pnfs_layout_release(lgp->lo, &lgp->lo->lgetcount, NULL); + pnfs_layout_release(lgp->lo, NULL); if (lgp->res.layout.buf != NULL) free_page((unsigned long) lgp->res.layout.buf); kfree(calldata); @@ -5761,8 +5761,7 @@ static void nfs4_pnfs_layoutreturn_release(void *calldata) if (lrp->lo && (lrp->args.return_type == RETURN_FILE)) { if (!lrp->res.lrs_present) pnfs_set_layout_stateid(lrp->lo, &zero_stateid); - pnfs_layout_release(lrp->lo, &lrp->lo->lretcount, - &lrp->args.lseg); + pnfs_layout_release(lrp->lo, &lrp->args.lseg); } kfree(calldata); dprintk("<-- %s\n", __func__); diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index b0a4bca..8df4d75 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -380,7 +380,7 @@ out: } void -pnfs_layout_release(struct pnfs_layout_type *lo, atomic_t *count, +pnfs_layout_release(struct pnfs_layout_type *lo, struct nfs4_pnfs_layout_segment *range) { struct nfs_inode *nfsi = PNFS_NFS_INODE(lo); @@ -388,7 +388,6 @@ pnfs_layout_release(struct pnfs_layout_type *lo, atomic_t *count, lock_current_layout(nfsi); if (range) pnfs_free_layout(lo, range); - atomic_dec(count); put_unlock_current_layout(lo); wake_up_all(&nfsi->lo_waitq); } @@ -573,7 +572,7 @@ get_layout(struct inode *ino, lgp = kzalloc(sizeof(*lgp), GFP_KERNEL); if (lgp == NULL) { - pnfs_layout_release(lo, &lo->lgetcount, NULL); + pnfs_layout_release(lo, NULL); return -ENOMEM; } lgp->lo = lo; @@ -647,6 +646,13 @@ has_layout_to_return(struct pnfs_layout_type *lo, return out; } +static inline bool +_pnfs_can_return_lseg(struct pnfs_layout_segment *lseg) +{ + return atomic_read(&lseg->kref.refcount) == 1; +} + + static void pnfs_free_layout(struct pnfs_layout_type *lo, struct nfs4_pnfs_layout_segment *range) @@ -657,7 +663,8 @@ pnfs_free_layout(struct pnfs_layout_type *lo, BUG_ON_UNLOCKED_LO(lo); list_for_each_entry_safe (lseg, next, &lo->segs, fi_list) { - if (!should_free_lseg(lseg, range)) + if (!should_free_lseg(lseg, range) || + !_pnfs_can_return_lseg(lseg)) continue; dprintk("%s: freeing lseg %p iomode %d " "offset %llu length %llu\n", __func__, @@ -670,12 +677,6 @@ pnfs_free_layout(struct pnfs_layout_type *lo, dprintk("%s:Return\n", __func__); } -static inline bool -_pnfs_can_return_lseg(struct pnfs_layout_segment *lseg) -{ - return atomic_read(&lseg->kref.refcount) == 1; -} - static bool pnfs_return_layout_barrier(struct nfs_inode *nfsi, struct nfs4_pnfs_layout_segment *range) @@ -695,8 +696,6 @@ pnfs_return_layout_barrier(struct nfs_inode *nfsi, ret = true; } } - if (atomic_read(&nfsi->layout.lgetcount)) - ret = true; unlock_current_layout(nfsi); dprintk("%s:Return %d\n", __func__, ret); @@ -718,7 +717,7 @@ return_layout(struct inode *ino, struct nfs4_pnfs_layout_segment *range, lrp = kzalloc(sizeof(*lrp), GFP_KERNEL); if (lrp == NULL) { if (lo && (type == RETURN_FILE)) - pnfs_layout_release(lo, &lo->lretcount, NULL); + pnfs_layout_release(lo, NULL); goto out; } lrp->args.reclaim = 0; @@ -773,9 +772,6 @@ _pnfs_return_layout(struct inode *ino, struct nfs4_pnfs_layout_segment *range, goto out; } - /* Matching dec is done in .rpc_release (on non-error paths) */ - atomic_inc(&lo->lretcount); - /* unlock w/o put rebalanced by eventual call to * pnfs_layout_release */ @@ -900,8 +896,6 @@ alloc_init_layout(struct inode *ino) seqlock_init(&lo->seqlock); memset(&lo->stateid, 0, NFS4_STATEID_SIZE); lo->refcount = 1; - atomic_set(&lo->lgetcount, 0); - atomic_set(&lo->lretcount, 0); INIT_LIST_HEAD(&lo->segs); lo->roc_iomode = 0; return lo; @@ -1041,19 +1035,6 @@ pnfs_has_layout(struct pnfs_layout_type *lo, return ret; } -/* Called with spin lock held */ -void drain_layoutreturns(struct pnfs_layout_type *lo) -{ - while (atomic_read(&lo->lretcount)) { - struct nfs_inode *nfsi = PNFS_NFS_INODE(lo); - - unlock_current_layout(nfsi); - dprintk("%s: waiting\n", __func__); - wait_event(nfsi->lo_waitq, (atomic_read(&lo->lretcount) == 0)); - lock_current_layout(nfsi); - } -} - /* Update the file's layout for the given range and iomode. * Layout is retreived from the server if needed. * If lsegpp is given, the appropriate layout segment is referenced and @@ -1141,9 +1122,6 @@ pnfs_update_layout(struct inode *ino, } } - drain_layoutreturns(lo); - /* Matching dec is done in .rpc_release (on non-error paths) */ - atomic_inc(&lo->lgetcount); /* Lose lock, but not reference, match this with pnfs_layout_release */ unlock_current_layout(nfsi); diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index c89be78..a71145e 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -61,8 +61,7 @@ void pnfs_update_layout_commit(struct inode *, struct list_head *, pgoff_t, unsi ssize_t pnfs_file_write(struct file *, const char __user *, size_t, loff_t *); void pnfs_get_layout_done(struct nfs4_pnfs_layoutget *, int rpc_status); int pnfs_layout_process(struct nfs4_pnfs_layoutget *lgp); -void pnfs_layout_release(struct pnfs_layout_type *, atomic_t *, - struct nfs4_pnfs_layout_segment *range); +void pnfs_layout_release(struct pnfs_layout_type *, struct nfs4_pnfs_layout_segment *range); void pnfs_set_layout_stateid(struct pnfs_layout_type *lo, const nfs4_stateid *stateid); void pnfs_destroy_layout(struct nfs_inode *); diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 45846c5..f6e3e20 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -99,8 +99,6 @@ struct posix_acl; struct pnfs_layout_type { int refcount; - atomic_t lretcount; /* Layoutreturns outstanding */ - atomic_t lgetcount; /* Layoutgets outstanding */ struct list_head segs; /* layout segments list */ int roc_iomode; /* iomode to return on close, 0=none */ seqlock_t seqlock; /* Protects the stateid */ -- 1.6.2.5