[pnfs] [PATCH 19/37] pnfs: client layout cache: allow waiting for alloc_layout
Dean Hildebrand
seattleplus at gmail.com
Wed Jan 2 18:54:34 EST 2008
> /*
> * get, possibly allocate current_layout
> */
> @@ -442,14 +450,32 @@ get_alloc_layout(struct inode *ino,
> {
> struct nfs_inode *nfsi = NFS_I(ino);
> struct pnfs_layout_type *lo;
> + int res;
>
> dprintk("%s Begin\n", __FUNCTION__);
>
> +retry:
> lo = nfsi->current_layout;
> if (lo)
> goto out;
>
> + res = wait_on_bit_lock(&nfsi->pnfs_layout_state, NFS_INO_LAYOUT_ALLOC,
> + pnfs_wait_schedule, TASK_INTERRUPTIBLE);
> + if (res) {
> + lo = ERR_PTR(res);
> + goto err;
> + }
> +
> + if (nfsi->current_layout) {
> + clear_bit_unlock(NFS_INO_LAYOUT_ALLOC,
> + &nfsi->pnfs_layout_state);
> + goto retry;
> + }
> +
> lo = nfsi->current_layout = alloc_init_layout(ino, io_ops);
> + clear_bit_unlock(NFS_INO_LAYOUT_ALLOC, &nfsi->pnfs_layout_state);
> + wake_up_bit(&nfsi->pnfs_layout_state, NFS_INO_LAYOUT_ALLOC);
> +
>
This function seems a little muddled (or maybe some comments would
help). I've never been a fan of backward gotos. Would something like
the following be any less correct or inefficient? Actually, if the
following code works, could we just use a spinlock instead? Are we just
protecting nfsi->current_layout?
res = wait_on_bit_lock(&nfsi->pnfs_layout_state, NFS_INO_LAYOUT_ALLOC,
pnfs_wait_schedule, TASK_INTERRUPTIBLE);
if (res) {
lo = ERR_PTR(res);
goto err;
}
if (nfsi->current_layout) {
clear_bit_unlock(NFS_INO_LAYOUT_ALLOC,
&nfsi->pnfs_layout_state);
wake_up_bit(&nfsi->pnfs_layout_state, NFS_INO_LAYOUT_ALLOC);
goto out;
}
lo = nfsi->current_layout = alloc_init_layout(ino, io_ops);
clear_bit_unlock(NFS_INO_LAYOUT_ALLOC, &nfsi->pnfs_layout_state);
wake_up_bit(&nfsi->pnfs_layout_state, NFS_INO_LAYOUT_ALLOC);
Dean
> if (!lo) {
> lo = ERR_PTR(-ENOMEM);
> goto err;
> diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
> index 3d6bfbf..1a093b1 100644
> --- a/include/linux/nfs_fs.h
> +++ b/include/linux/nfs_fs.h
> @@ -178,7 +178,9 @@ struct nfs_inode {
> #if defined(CONFIG_PNFS)
> unsigned long pnfs_layout_state;
> #define NFS_INO_LAYOUT_FAILED 0x0001 /* get layout failed, stop trying */
> +#define NFS_INO_LAYOUT_ALLOC 0x0002 /* get layout failed, stop trying */
> time_t pnfs_layout_suspend;
> + wait_queue_head_t lo_waitq;
> struct pnfs_layout_type *current_layout;
> /* use rpc_creds in this open_context to send LAYOUTCOMMIT to MDS */
> struct nfs_open_context *layoutcommit_ctx;
>
More information about the pNFS
mailing list