On Wed, May 5, 2010 at 1:00 PM, Alexandros Batsakis <batsakis@xxxxxxxxxx> wrote: > (also minor cleanup of pnfs_free_layout()) > > Signed-off-by: Alexandros Batsakis <batsakis@xxxxxxxxxx> > --- > fs/nfs/pnfs.c | 73 ++++++++++++++++++++++++++++++++++++-------------------- > 1 files changed, 47 insertions(+), 26 deletions(-) > > diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c > index f32dbbb..a4031b4 100644 > --- a/fs/nfs/pnfs.c > +++ b/fs/nfs/pnfs.c > @@ -60,6 +60,8 @@ static int pnfs_initialized; > static void pnfs_free_layout(struct pnfs_layout_type *lo, > struct nfs4_pnfs_layout_segment *range); > static enum pnfs_try_status pnfs_commit(struct nfs_write_data *data, int sync); > +static inline void lock_current_layout(struct nfs_inode *nfsi); > +static inline void unlock_current_layout(struct nfs_inode *nfsi); > > /* Locking: > * > @@ -152,15 +154,15 @@ void > pnfs_need_layoutcommit(struct nfs_inode *nfsi, struct nfs_open_context *ctx) > { > dprintk("%s: has_layout=%d ctx=%p\n", __func__, has_layout(nfsi), ctx); > - spin_lock(&nfsi->lo_lock); > + lock_current_layout(nfsi); > if (has_layout(nfsi) && !layoutcommit_needed(nfsi)) { > nfsi->layout.lo_cred = get_rpccred(ctx->state->owner->so_cred); > nfsi->change_attr++; > - spin_unlock(&nfsi->lo_lock); > + unlock_current_layout(nfsi); > dprintk("%s: Set layoutcommit\n", __func__); > return; > } > - spin_unlock(&nfsi->lo_lock); > + unlock_current_layout(nfsi); > } > > /* Update last_write_offset for layoutcommit. > @@ -173,7 +175,7 @@ pnfs_update_last_write(struct nfs_inode *nfsi, loff_t offset, size_t extent) > { > loff_t end_pos; > > - spin_lock(&nfsi->lo_lock); > + lock_current_layout(nfsi); > if (offset < nfsi->layout.pnfs_write_begin_pos) > nfsi->layout.pnfs_write_begin_pos = offset; > end_pos = offset + extent - 1; /* I'm being inclusive */ > @@ -185,7 +187,7 @@ pnfs_update_last_write(struct nfs_inode *nfsi, loff_t offset, size_t extent) > (unsigned long) offset , > (unsigned long) nfsi->layout.pnfs_write_begin_pos, > (unsigned long) nfsi->layout.pnfs_write_end_pos); > - spin_unlock(&nfsi->lo_lock); > + unlock_current_layout(nfsi); > } > > /* Unitialize a mountpoint in a layout driver */ > @@ -313,6 +315,17 @@ pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *ld_type) > #define BUG_ON_UNLOCKED_LO(lo) do {} while (0) > #endif /* CONFIG_SMP */ > > +static inline void lock_current_layout(struct nfs_inode *nfsi) > +{ > + spin_lock(&nfsi->lo_lock); > +} > + > +static inline void unlock_current_layout(struct nfs_inode *nfsi) > +{ > + BUG_ON_UNLOCKED_LO((&nfsi->layout)); > + spin_unlock(&nfsi->lo_lock); > +} > + > /* > * get and lock nfsi->layout > */ > @@ -321,10 +334,10 @@ get_lock_current_layout(struct nfs_inode *nfsi) > { > struct pnfs_layout_type *lo; > > + lock_current_layout(nfsi); > lo = &nfsi->layout; > - spin_lock(&nfsi->lo_lock); > if (!lo->ld_data) { > - spin_unlock(&nfsi->lo_lock); > + unlock_current_layout(nfsi); > return NULL; > } > > @@ -344,7 +357,12 @@ put_unlock_current_layout(struct pnfs_layout_type *lo) > BUG_ON_UNLOCKED_LO(lo); > BUG_ON(lo->refcount <= 0); > > - if (--lo->refcount == 0 && list_empty(&lo->segs)) { > + lo->refcount--; > + > + if (lo->refcount > 0) > + goto out; > + > + if (list_empty(&lo->segs)) { > struct layoutdriver_io_operations *io_ops = > PNFS_LD_IO_OPS(lo); > > @@ -358,7 +376,8 @@ put_unlock_current_layout(struct pnfs_layout_type *lo) > list_del_init(&nfsi->lo_inodes); > spin_unlock(&clp->cl_lock); > } > - spin_unlock(&nfsi->lo_lock); > +out: > + unlock_current_layout(nfsi); > } > > void > @@ -367,7 +386,7 @@ pnfs_layout_release(struct pnfs_layout_type *lo, atomic_t *count, > { > struct nfs_inode *nfsi = PNFS_NFS_INODE(lo); > > - spin_lock(&nfsi->lo_lock); > + lock_current_layout(nfsi); > if (range) > pnfs_free_layout(lo, range); > atomic_dec(count); > @@ -386,6 +405,8 @@ pnfs_destroy_layout(struct nfs_inode *nfsi) > }; > > lo = get_lock_current_layout(nfsi); > + if (!lo) > + return; > pnfs_free_layout(lo, &range); > put_unlock_current_layout(lo); > } > @@ -663,7 +684,7 @@ pnfs_return_layout_barrier(struct nfs_inode *nfsi, > struct pnfs_layout_segment *lseg; > bool ret = false; > > - spin_lock(&nfsi->lo_lock); > + lock_current_layout(nfsi); > list_for_each_entry (lseg, &nfsi->layout.segs, fi_list) { > if (!should_free_lseg(lseg, range)) > continue; > @@ -677,7 +698,7 @@ pnfs_return_layout_barrier(struct nfs_inode *nfsi, > } > if (atomic_read(&nfsi->layout.lgetcount)) > ret = true; > - spin_unlock(&nfsi->lo_lock); > + unlock_current_layout(nfsi); > > dprintk("%s:Return %d\n", __func__, ret); > return ret; > @@ -759,7 +780,7 @@ _pnfs_return_layout(struct inode *ino, struct nfs4_pnfs_layout_segment *range, > /* unlock w/o put rebalanced by eventual call to > * pnfs_layout_release > */ > - spin_unlock(&nfsi->lo_lock); > + unlock_current_layout(nfsi); > > if (pnfs_return_layout_barrier(nfsi, &arg)) { > dprintk("%s: waiting\n", __func__); > @@ -900,7 +921,7 @@ static int pnfs_wait_schedule(void *word) > * > * Note: If successful, nfsi->lo_lock is taken and the caller > * must put and unlock current_layout by using put_unlock_current_layout() > - * when the returned layout is released. > + * directly or pnfs_layout_release() when the returned layout is released. > */ > static struct pnfs_layout_type * > get_lock_alloc_layout(struct inode *ino) > @@ -935,7 +956,7 @@ get_lock_alloc_layout(struct inode *ino) > struct nfs_client *clp = NFS_SERVER(ino)->nfs_client; > > /* must grab the layout lock before the client lock */ > - spin_lock(&nfsi->lo_lock); > + lock_current_layout(nfsi); > > spin_lock(&clp->cl_lock); > if (list_empty(&nfsi->lo_inodes)) > @@ -1051,10 +1072,10 @@ void drain_layoutreturns(struct pnfs_layout_type *lo) > while (atomic_read(&lo->lretcount)) { > struct nfs_inode *nfsi = PNFS_NFS_INODE(lo); > > - spin_unlock(&nfsi->lo_lock); > + unlock_current_layout(nfsi); > dprintk("%s: waiting\n", __func__); > wait_event(nfsi->lo_waitq, (atomic_read(&lo->lretcount) == 0)); > - spin_lock(&nfsi->lo_lock); > + lock_current_layout(nfsi); > } > } > > @@ -1093,13 +1114,13 @@ pnfs_update_layout(struct inode *ino, > /* Check to see if the layout for the given range already exists */ > lseg = pnfs_has_layout(lo, &arg, take_ref, !take_ref); > if (lseg && !lseg->valid) { > - spin_unlock(&nfsi->lo_lock); > + unlock_current_layout(nfsi); > if (take_ref) > put_lseg(lseg); > for (;;) { > prepare_to_wait(&nfsi->lo_waitq, &__wait, > TASK_KILLABLE); > - spin_lock(&nfsi->lo_lock); > + lock_current_layout(nfsi); > lseg = pnfs_has_layout(lo, &arg, take_ref, !take_ref); > if (!lseg || lseg->valid) > break; > @@ -1112,7 +1133,7 @@ pnfs_update_layout(struct inode *ino, > result = -ERESTARTSYS; > break; > } > - spin_unlock(&nfsi->lo_lock); > + unlock_current_layout(nfsi); > schedule(); > } > finish_wait(&nfsi->lo_waitq, &__wait); > @@ -1149,7 +1170,7 @@ pnfs_update_layout(struct inode *ino, > /* 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 */ > - spin_unlock(&nfsi->lo_lock); > + unlock_current_layout(nfsi); > > result = get_layout(ino, ctx, &arg, lsegpp, lo); > out: > @@ -1299,7 +1320,7 @@ pnfs_layout_process(struct nfs4_pnfs_layoutget *lgp) > *lgp->lsegpp = lseg; > } > > - spin_lock(&nfsi->lo_lock); > + lock_current_layout(nfsi); > pnfs_insert_layout(lo, lseg); > > if (res->return_on_close) { > @@ -1310,7 +1331,7 @@ pnfs_layout_process(struct nfs4_pnfs_layoutget *lgp) > > /* Done processing layoutget. Set the layout stateid */ > pnfs_set_layout_stateid(lo, &res->stateid); > - spin_unlock(&nfsi->lo_lock); > + unlock_current_layout(nfsi); > out: > return status; > } > @@ -2140,9 +2161,9 @@ pnfs_layoutcommit_inode(struct inode *inode, int sync) > if (!data) > return -ENOMEM; > > - spin_lock(&nfsi->lo_lock); > + lock_current_layout(nfsi); > if (!layoutcommit_needed(nfsi)) { > - spin_unlock(&nfsi->lo_lock); > + lock_current_layout(nfsi); This should be unlock_current_layout Fred > goto out_free; > } > > @@ -2157,7 +2178,7 @@ pnfs_layoutcommit_inode(struct inode *inode, int sync) > nfsi->layout.lo_cred = NULL; > pnfs_get_layout_stateid(&data->args.stateid, &nfsi->layout); > > - spin_unlock(&nfsi->lo_lock); > + unlock_current_layout(nfsi); > > /* Set up layout commit args */ > status = pnfs_layoutcommit_setup(inode, data, write_begin_pos, > -- > 1.6.2.5 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-nfs" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html