From 49a85061b0bc9cb26361096482c81172c666c937 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 18 Sep 2012 20:43:31 -0400 Subject: NFSv4.1: Cleanup add a "pnfs_" prefix to mark_matching_lsegs_invalid Signed-off-by: Trond Myklebust --- fs/nfs/callback_proc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'fs/nfs/callback_proc.c') diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 1b5d809a105..57b8bda0f4e 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -158,7 +158,7 @@ static u32 initiate_file_draining(struct nfs_client *clp, ino = lo->plh_inode; spin_lock(&ino->i_lock); if (test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags) || - mark_matching_lsegs_invalid(lo, &free_me_list, + pnfs_mark_matching_lsegs_invalid(lo, &free_me_list, &args->cbl_range)) rv = NFS4ERR_DELAY; else @@ -211,7 +211,7 @@ static u32 initiate_bulk_draining(struct nfs_client *clp, ino = lo->plh_inode; spin_lock(&ino->i_lock); set_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags); - if (mark_matching_lsegs_invalid(lo, &free_me_list, &range)) + if (pnfs_mark_matching_lsegs_invalid(lo, &free_me_list, &range)) rv = NFS4ERR_DELAY; list_del_init(&lo->plh_bulk_recall); spin_unlock(&ino->i_lock); -- cgit v1.2.3-70-g09d2 From 70c3bd2bdf9a3c7c9282c362a4ec9ec88c713e13 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 18 Sep 2012 20:51:13 -0400 Subject: NFSv4.1: Cleanup; add "pnfs_" prefix to get_layout_hdr() and put_layout_hdr() Signed-off-by: Trond Myklebust --- fs/nfs/callback_proc.c | 8 ++++---- fs/nfs/nfs4proc.c | 2 +- fs/nfs/pnfs.c | 30 +++++++++++++++--------------- fs/nfs/pnfs.h | 4 ++-- 4 files changed, 22 insertions(+), 22 deletions(-) (limited to 'fs/nfs/callback_proc.c') diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 57b8bda0f4e..24252fea2c9 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -122,7 +122,7 @@ static struct pnfs_layout_hdr * get_layout_by_fh_locked(struct nfs_client *clp, ino = igrab(lo->plh_inode); if (!ino) continue; - get_layout_hdr(lo); + pnfs_get_layout_hdr(lo); return lo; } } @@ -166,7 +166,7 @@ static u32 initiate_file_draining(struct nfs_client *clp, pnfs_set_layout_stateid(lo, &args->cbl_stateid, true); spin_unlock(&ino->i_lock); pnfs_free_lseg_list(&free_me_list); - put_layout_hdr(lo); + pnfs_put_layout_hdr(lo); iput(ino); return rv; } @@ -198,7 +198,7 @@ static u32 initiate_bulk_draining(struct nfs_client *clp, list_for_each_entry(lo, &server->layouts, plh_layouts) { if (!igrab(lo->plh_inode)) continue; - get_layout_hdr(lo); + pnfs_get_layout_hdr(lo); BUG_ON(!list_empty(&lo->plh_bulk_recall)); list_add(&lo->plh_bulk_recall, &recall_list); } @@ -216,7 +216,7 @@ static u32 initiate_bulk_draining(struct nfs_client *clp, list_del_init(&lo->plh_bulk_recall); spin_unlock(&ino->i_lock); pnfs_free_lseg_list(&free_me_list); - put_layout_hdr(lo); + pnfs_put_layout_hdr(lo); iput(ino); } return rv; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 1c8656f8745..bdacb8c21a3 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -6375,7 +6375,7 @@ static void nfs4_layoutreturn_release(void *calldata) struct nfs4_layoutreturn *lrp = calldata; dprintk("--> %s\n", __func__); - put_layout_hdr(lrp->args.layout); + pnfs_put_layout_hdr(lrp->args.layout); kfree(calldata); dprintk("<-- %s\n", __func__); } diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index aea2e5256fe..512c8632bf3 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -190,7 +190,7 @@ EXPORT_SYMBOL_GPL(pnfs_unregister_layoutdriver); /* Need to hold i_lock if caller does not already hold reference */ void -get_layout_hdr(struct pnfs_layout_hdr *lo) +pnfs_get_layout_hdr(struct pnfs_layout_hdr *lo) { atomic_inc(&lo->plh_refcount); } @@ -221,14 +221,14 @@ destroy_layout_hdr(struct pnfs_layout_hdr *lo) } static void -put_layout_hdr_locked(struct pnfs_layout_hdr *lo) +pnfs_put_layout_hdr_locked(struct pnfs_layout_hdr *lo) { if (atomic_dec_and_test(&lo->plh_refcount)) destroy_layout_hdr(lo); } void -put_layout_hdr(struct pnfs_layout_hdr *lo) +pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo) { struct inode *inode = lo->plh_inode; @@ -254,8 +254,8 @@ static void free_lseg(struct pnfs_layout_segment *lseg) struct inode *ino = lseg->pls_layout->plh_inode; NFS_SERVER(ino)->pnfs_curr_ld->free_lseg(lseg); - /* Matched by get_layout_hdr in pnfs_insert_layout */ - put_layout_hdr(NFS_I(ino)->layout); + /* Matched by pnfs_get_layout_hdr in pnfs_insert_layout */ + pnfs_put_layout_hdr(NFS_I(ino)->layout); } static void @@ -268,7 +268,7 @@ put_lseg_common(struct pnfs_layout_segment *lseg) if (list_empty(&lseg->pls_layout->plh_segs)) { set_bit(NFS_LAYOUT_DESTROYED, &lseg->pls_layout->plh_flags); /* Matched by initial refcount set in alloc_init_layout_hdr */ - put_layout_hdr_locked(lseg->pls_layout); + pnfs_put_layout_hdr_locked(lseg->pls_layout); } rpc_wake_up(&NFS_SERVER(inode)->roc_rpcwaitq); } @@ -404,7 +404,7 @@ pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, NFS_I(lo->plh_inode)->write_io = 0; NFS_I(lo->plh_inode)->read_io = 0; if (!test_and_set_bit(NFS_LAYOUT_DESTROYED, &lo->plh_flags)) - put_layout_hdr_locked(lo); + pnfs_put_layout_hdr_locked(lo); return 0; } list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list) @@ -649,13 +649,13 @@ _pnfs_return_layout(struct inode *ino) } stateid = nfsi->layout->plh_stateid; /* Reference matched in nfs4_layoutreturn_release */ - get_layout_hdr(lo); + pnfs_get_layout_hdr(lo); empty = list_empty(&lo->plh_segs); pnfs_mark_matching_lsegs_invalid(lo, &tmp_list, NULL); /* Don't send a LAYOUTRETURN if list was initially empty */ if (empty) { spin_unlock(&ino->i_lock); - put_layout_hdr(lo); + pnfs_put_layout_hdr(lo); dprintk("NFS: %s no layout segments to return\n", __func__); goto out; } @@ -672,7 +672,7 @@ _pnfs_return_layout(struct inode *ino) set_bit(NFS_LAYOUT_RW_FAILED, &lo->plh_flags); set_bit(NFS_LAYOUT_RO_FAILED, &lo->plh_flags); pnfs_clear_layout_returned(lo); - put_layout_hdr(lo); + pnfs_put_layout_hdr(lo); goto out; } @@ -709,7 +709,7 @@ bool pnfs_roc(struct inode *ino) if (!found) goto out_nolayout; lo->plh_block_lgets++; - get_layout_hdr(lo); /* matched in pnfs_roc_release */ + pnfs_get_layout_hdr(lo); /* matched in pnfs_roc_release */ spin_unlock(&ino->i_lock); pnfs_free_lseg_list(&tmp_list); return true; @@ -726,7 +726,7 @@ void pnfs_roc_release(struct inode *ino) spin_lock(&ino->i_lock); lo = NFS_I(ino)->layout; lo->plh_block_lgets--; - put_layout_hdr_locked(lo); + pnfs_put_layout_hdr_locked(lo); spin_unlock(&ino->i_lock); } @@ -819,7 +819,7 @@ pnfs_insert_layout(struct pnfs_layout_hdr *lo, __func__, lseg, lseg->pls_range.iomode, lseg->pls_range.offset, lseg->pls_range.length); out: - get_layout_hdr(lo); + pnfs_get_layout_hdr(lo); dprintk("%s:Return\n", __func__); } @@ -1058,7 +1058,7 @@ pnfs_update_layout(struct inode *ino, goto out_unlock; atomic_inc(&lo->plh_outstanding); - get_layout_hdr(lo); + pnfs_get_layout_hdr(lo); if (list_empty(&lo->plh_segs)) first = true; @@ -1091,7 +1091,7 @@ pnfs_update_layout(struct inode *ino, spin_unlock(&clp->cl_lock); } atomic_dec(&lo->plh_outstanding); - put_layout_hdr(lo); + pnfs_put_layout_hdr(lo); out: dprintk("%s end, state 0x%lx lseg %p\n", __func__, nfsi->layout ? nfsi->layout->plh_flags : -1, lseg); diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index 6af518934e4..2af681f0a49 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -176,7 +176,7 @@ extern struct pnfs_layout_segment* nfs4_proc_layoutget(struct nfs4_layoutget *lg extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp); /* pnfs.c */ -void get_layout_hdr(struct pnfs_layout_hdr *lo); +void pnfs_get_layout_hdr(struct pnfs_layout_hdr *lo); void put_lseg(struct pnfs_layout_segment *lseg); void pnfs_pageio_init_read(struct nfs_pageio_descriptor *, struct inode *, @@ -196,7 +196,7 @@ struct pnfs_layout_segment *pnfs_layout_process(struct nfs4_layoutget *lgp); void pnfs_free_lseg_list(struct list_head *tmp_list); void pnfs_destroy_layout(struct nfs_inode *); void pnfs_destroy_all_layouts(struct nfs_client *); -void put_layout_hdr(struct pnfs_layout_hdr *lo); +void pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo); void pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new, bool update_barrier); -- cgit v1.2.3-70-g09d2 From 9c6263819f25254f2ed48f076b50096dd5893dfb Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 20 Sep 2012 17:31:43 -0400 Subject: NFSv4.1: Clean up the removal of pnfs_layout_hdr from the server list Move the code into pnfs_free_layout_hdr(), and add checks to get_layout_by_fh_locked to ensure that they don't reference a layout that is being freed. Signed-off-by: Trond Myklebust --- fs/nfs/callback_proc.c | 19 ++++++++++++++++++- fs/nfs/pnfs.c | 29 ++++++++++------------------- 2 files changed, 28 insertions(+), 20 deletions(-) (limited to 'fs/nfs/callback_proc.c') diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 24252fea2c9..76b4a7a3e55 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -122,7 +122,15 @@ static struct pnfs_layout_hdr * get_layout_by_fh_locked(struct nfs_client *clp, ino = igrab(lo->plh_inode); if (!ino) continue; + spin_lock(&ino->i_lock); + /* Is this layout in the process of being freed? */ + if (NFS_I(ino)->layout != lo) { + spin_unlock(&ino->i_lock); + iput(ino); + continue; + } pnfs_get_layout_hdr(lo); + spin_unlock(&ino->i_lock); return lo; } } @@ -196,9 +204,18 @@ static u32 initiate_bulk_draining(struct nfs_client *clp, continue; list_for_each_entry(lo, &server->layouts, plh_layouts) { - if (!igrab(lo->plh_inode)) + ino = igrab(lo->plh_inode); + if (ino) + continue; + spin_lock(&ino->i_lock); + /* Is this layout in the process of being freed? */ + if (NFS_I(ino)->layout != lo) { + spin_unlock(&ino->i_lock); + iput(ino); continue; + } pnfs_get_layout_hdr(lo); + spin_unlock(&ino->i_lock); BUG_ON(!list_empty(&lo->plh_bulk_recall)); list_add(&lo->plh_bulk_recall, &recall_list); } diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 08663146f5f..11cc0ad6b40 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -207,7 +207,16 @@ pnfs_alloc_layout_hdr(struct inode *ino, gfp_t gfp_flags) static void pnfs_free_layout_hdr(struct pnfs_layout_hdr *lo) { - struct pnfs_layoutdriver_type *ld = NFS_SERVER(lo->plh_inode)->pnfs_curr_ld; + struct nfs_server *server = NFS_SERVER(lo->plh_inode); + struct pnfs_layoutdriver_type *ld = server->pnfs_curr_ld; + + if (!list_empty(&lo->plh_layouts)) { + struct nfs_client *clp = server->nfs_client; + + spin_lock(&clp->cl_lock); + list_del_init(&lo->plh_layouts); + spin_unlock(&clp->cl_lock); + } put_rpccred(lo->plh_lc_cred); return ld->alloc_layout_hdr ? ld->free_layout_hdr(lo) : kfree(lo); } @@ -217,7 +226,6 @@ pnfs_detach_layout_hdr(struct pnfs_layout_hdr *lo) { struct nfs_inode *nfsi = NFS_I(lo->plh_inode); dprintk("%s: freeing layout cache %p\n", __func__, lo); - BUG_ON(!list_empty(&lo->plh_layouts)); nfsi->layout = NULL; /* Reset MDS Threshold I/O counters */ nfsi->write_io = 0; @@ -480,22 +488,10 @@ void pnfs_free_lseg_list(struct list_head *free_me) { struct pnfs_layout_segment *lseg, *tmp; - struct pnfs_layout_hdr *lo; if (list_empty(free_me)) return; - lo = list_first_entry(free_me, struct pnfs_layout_segment, - pls_list)->pls_layout; - - if (test_bit(NFS_LAYOUT_DESTROYED, &lo->plh_flags)) { - struct nfs_client *clp; - - clp = NFS_SERVER(lo->plh_inode)->nfs_client; - spin_lock(&clp->cl_lock); - list_del_init(&lo->plh_layouts); - spin_unlock(&clp->cl_lock); - } list_for_each_entry_safe(lseg, tmp, free_me, pls_list) { list_del(&lseg->pls_list); free_lseg(lseg); @@ -1148,11 +1144,6 @@ pnfs_update_layout(struct inode *ino, arg.length = PAGE_CACHE_ALIGN(arg.length); lseg = send_layoutget(lo, ctx, &arg, gfp_flags); - if (!lseg && first) { - spin_lock(&clp->cl_lock); - list_del_init(&lo->plh_layouts); - spin_unlock(&clp->cl_lock); - } atomic_dec(&lo->plh_outstanding); out_put_layout_hdr: pnfs_put_layout_hdr(lo); -- cgit v1.2.3-70-g09d2