All of lore.kernel.org
 help / color / mirror / Atom feed
From: Benny Halevy <bhalevy@panasas.com>
To: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: Fred Isaman <iisaman@netapp.com>, linux-nfs@vger.kernel.org
Subject: Re: [PATCH 09/13] RFC: nfs: create and destroy inode's layout cache
Date: Mon, 13 Sep 2010 13:32:10 +0200	[thread overview]
Message-ID: <4C8E0BBA.9070109@panasas.com> (raw)
In-Reply-To: <1284147785.10062.80.camel@heimdal.trondhjem.org>

On 2010-09-10 22:43, Trond Myklebust wrote:
> On Thu, 2010-09-02 at 14:00 -0400, Fred Isaman wrote:
>> From: The pNFS Team <linux-nfs@vger.kernel.org>
>>
>> At the start of the io paths, try to grab the relevant layout
>> information.  This will initiate the inode's layout cache, but
>> stubs ensure the cache stays empty.
>>
>> Signed-off-by: TBD - melding/reorganization of several patches
>> ---
>>  fs/nfs/file.c          |    5 ++
>>  fs/nfs/inode.c         |    3 +
>>  fs/nfs/pnfs.c          |  140 ++++++++++++++++++++++++++++++++++++++++++++++++
>>  fs/nfs/pnfs.h          |   39 +++++++++++++
>>  fs/nfs/read.c          |    3 +
>>  include/linux/nfs_fs.h |    3 +
>>  6 files changed, 193 insertions(+), 0 deletions(-)
>>
>> diff --git a/fs/nfs/file.c b/fs/nfs/file.c
>> index eb51bd6..10ebdfb 100644
>> --- a/fs/nfs/file.c
>> +++ b/fs/nfs/file.c
>> @@ -36,6 +36,7 @@
>>  #include "internal.h"
>>  #include "iostat.h"
>>  #include "fscache.h"
>> +#include "pnfs.h"
>>  
>>  #define NFSDBG_FACILITY		NFSDBG_FILE
>>  
>> @@ -386,6 +387,10 @@ static int nfs_write_begin(struct file *file, struct address_space *mapping,
>>  		file->f_path.dentry->d_name.name,
>>  		mapping->host->i_ino, len, (long long) pos);
>>  
>> +	pnfs_update_layout(mapping->host,
>> +			   nfs_file_open_context(file),
>> +			   IOMODE_RW);
>> +
>>  start:
>>  	/*
>>  	 * Prevent starvation issues if someone is doing a consistency
>> diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
>> index 7d2d6c7..0dc6dad 100644
>> --- a/fs/nfs/inode.c
>> +++ b/fs/nfs/inode.c
>> @@ -48,6 +48,7 @@
>>  #include "internal.h"
>>  #include "fscache.h"
>>  #include "dns_resolve.h"
>> +#include "pnfs.h"
>>  
>>  #define NFSDBG_FACILITY		NFSDBG_VFS
>>  
>> @@ -1409,6 +1410,7 @@ void nfs4_evict_inode(struct inode *inode)
>>  {
>>  	truncate_inode_pages(&inode->i_data, 0);
>>  	end_writeback(inode);
>> +	pnfs_destroy_layout(NFS_I(inode));
>>  	/* If we are holding a delegation, return it! */
>>  	nfs_inode_return_delegation_noreclaim(inode);
>>  	/* First call standard NFS clear_inode() code */
>> @@ -1446,6 +1448,7 @@ static inline void nfs4_init_once(struct nfs_inode *nfsi)
>>  	nfsi->delegation = NULL;
>>  	nfsi->delegation_state = 0;
>>  	init_rwsem(&nfsi->rwsem);
>> +	nfsi->layout = NULL;
>>  #endif
>>  }
>>  
>> diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
>> index 8d503fc..65f923b 100644
>> --- a/fs/nfs/pnfs.c
>> +++ b/fs/nfs/pnfs.c
>> @@ -151,3 +151,143 @@ pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *ld_type)
>>  	spin_unlock(&pnfs_spinlock);
>>  }
>>  EXPORT_SYMBOL(pnfs_unregister_layoutdriver);
>> +
>> +static void
>> +get_layout_hdr_locked(struct pnfs_layout_hdr *lo)
>> +{
>> +	assert_spin_locked(&lo->inode->i_lock);
>> +	lo->refcount++;
>> +}
>> +
>> +static void
>> +put_layout_hdr_locked(struct pnfs_layout_hdr *lo)
>> +{
>> +	assert_spin_locked(&lo->inode->i_lock);
>> +	BUG_ON(lo->refcount <= 0);
>> +
>> +	lo->refcount--;
>> +	if (!lo->refcount) {
>> +		dprintk("%s: freeing layout cache %p\n", __func__, lo);
>> +		NFS_I(lo->inode)->layout = NULL;
>> +		kfree(lo);
>> +	}
>> +}
>> +
>> +void
>> +pnfs_destroy_layout(struct nfs_inode *nfsi)
>> +{
>> +	struct pnfs_layout_hdr *lo;
>> +
>> +	spin_lock(&nfsi->vfs_inode.i_lock);
>> +	lo = nfsi->layout;
>> +	if (lo) {
>> +		/* Matched by refcount set to 1 in alloc_init_layout_hdr */
>> +		put_layout_hdr_locked(lo);
>> +	}
>> +	spin_unlock(&nfsi->vfs_inode.i_lock);
>> +}
>> +
>> +/* STUB - pretend LAYOUTGET to server failed */
>> +static struct pnfs_layout_segment *
>> +send_layoutget(struct pnfs_layout_hdr *lo,
>> +	   struct nfs_open_context *ctx,
>> +	   u32 iomode)
>> +{
>> +	struct inode *ino = lo->inode;
>> +
>> +	set_bit(lo_fail_bit(iomode), &lo->state);
>> +	spin_lock(&ino->i_lock);
>> +	put_layout_hdr_locked(lo);
>> +	spin_unlock(&ino->i_lock);
>> +	return NULL;
>> +}
>> +
>> +static struct pnfs_layout_hdr *
>> +alloc_init_layout_hdr(struct inode *ino)
>> +{
>> +	struct pnfs_layout_hdr *lo;
>> +
>> +	lo = kzalloc(sizeof(struct pnfs_layout_hdr), GFP_KERNEL);
>> +	if (!lo)
>> +		return NULL;
>> +	lo->refcount = 1;
>> +	lo->inode = ino;
>> +	return lo;
>> +}
>> +
>> +static struct pnfs_layout_hdr *
>> +pnfs_find_alloc_layout(struct inode *ino)
>> +{
>> +	struct nfs_inode *nfsi = NFS_I(ino);
>> +	struct pnfs_layout_hdr *new = NULL;
>> +
>> +	dprintk("%s Begin ino=%p layout=%p\n", __func__, ino, nfsi->layout);
>> +
>> +	assert_spin_locked(&ino->i_lock);
>> +	if (nfsi->layout)
>> +		return nfsi->layout;
>> +
>> +	spin_unlock(&ino->i_lock);
>> +	new = alloc_init_layout_hdr(ino);
>> +	spin_lock(&ino->i_lock);
>> +
>> +	if (likely(nfsi->layout == NULL))	/* Won the race? */
>> +		nfsi->layout = new;
>> +	else
>> +		kfree(new);
>> +	return nfsi->layout;
>> +}
>> +
>> +/* STUB - LAYOUTGET never succeeds, so cache is empty */
>> +static struct pnfs_layout_segment *
>> +pnfs_has_layout(struct pnfs_layout_hdr *lo, u32 iomode)
>> +{
>> +	return NULL;
>> +}
>> +
>> +/*
>> + * Layout segment is retreived from the server if not cached.
>> + * The appropriate layout segment is referenced and returned to the caller.
>> + */
>> +struct pnfs_layout_segment *
>> +pnfs_update_layout(struct inode *ino,
>> +		   struct nfs_open_context *ctx,
>> +		   enum pnfs_iomode iomode)
>> +{
>> +	struct nfs_inode *nfsi = NFS_I(ino);
>> +	struct pnfs_layout_hdr *lo;
>> +	struct pnfs_layout_segment *lseg = NULL;
>> +
>> +	if (!pnfs_enabled_sb(NFS_SERVER(ino)))
>> +		return NULL;
>> +	spin_lock(&ino->i_lock);
>> +	lo = pnfs_find_alloc_layout(ino);
>> +	if (lo == NULL) {
>> +		dprintk("%s ERROR: can't get pnfs_layout_hdr\n", __func__);
>> +		goto out_unlock;
>> +	}
>> +
>> +	/* Check to see if the layout for the given range already exists */
>> +	lseg = pnfs_has_layout(lo, iomode);
>> +	if (lseg) {
>> +		dprintk("%s: Using cached lseg %p for iomode %d)\n",
>> +			__func__, lseg, iomode);
>> +		goto out_unlock;
>> +	}
>> +
>> +	/* if LAYOUTGET already failed once we don't try again */
>> +	if (test_bit(lo_fail_bit(iomode), &nfsi->layout->state))
>> +		goto out_unlock;
>> +
>> +	get_layout_hdr_locked(lo);
>> +	spin_unlock(&ino->i_lock);
>> +
>> +	lseg = send_layoutget(lo, ctx, iomode);
>> +out:
>> +	dprintk("%s end, state 0x%lx lseg %p\n", __func__,
>> +		nfsi->layout->state, lseg);
>> +	return lseg;
>> +out_unlock:
>> +	spin_unlock(&ino->i_lock);
>> +	goto out;
>> +}
>> diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
>> index 9049b9a..b63b445 100644
>> --- a/fs/nfs/pnfs.h
>> +++ b/fs/nfs/pnfs.h
>> @@ -14,6 +14,11 @@
>>  
>>  #define LAYOUT_NFSV4_1_MODULE_PREFIX "nfs-layouttype4"
>>  
>> +enum {
>> +	NFS_LAYOUT_RO_FAILED = 0,	/* get ro layout failed stop trying */
>> +	NFS_LAYOUT_RW_FAILED,		/* get rw layout failed stop trying */
>> +};
>> +
>>  /* Per-layout driver specific registration structure */
>>  struct pnfs_layoutdriver_type {
>>  	struct list_head pnfs_tblid;
>> @@ -22,6 +27,12 @@ struct pnfs_layoutdriver_type {
>>  	struct layoutdriver_io_operations *ld_io_ops;
>>  };
>>  
>> +struct pnfs_layout_hdr {
>> +	int			refcount;
>         ^^^^^ Why not make this 'unsigned int', and/or 'unsigned long'?

Should be fine, we just need to be careful about underflow/overflow
before changing its value.

Benny

  parent reply	other threads:[~2010-09-13 11:32 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-02 18:00 [PATCH 00/13] RFC: pnfs: LAYOUTGET/DEVINFO submission Fred Isaman
2010-09-02 18:00 ` [PATCH 01/13] NFSD: remove duplicate NFS4_STATEID_SIZE Fred Isaman
2010-09-02 18:00 ` [PATCH 02/13] SUNRPC: define xdr_decode_opaque_fixed Fred Isaman
2010-09-02 18:00 ` [PATCH 03/13] RFC: pnfsd, pnfs: protocol level pnfs constants Fred Isaman
2010-09-02 18:00 ` [PATCH 04/13] RFC: nfs: change stateid to be a union Fred Isaman
2010-09-02 18:00 ` [PATCH 05/13] RFC: nfs: ask for layouttypes during fsinfo call Fred Isaman
2010-09-02 18:00 ` [PATCH 06/13] RFC: nfs: set layout driver Fred Isaman
2010-09-02 18:00 ` [PATCH 07/13] RFC: pnfs: full mount/umount infrastructure Fred Isaman
2010-09-10 19:23   ` Trond Myklebust
     [not found]     ` <1284146604.10062.68.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2010-09-10 20:53       ` Fred Isaman
2010-09-13 11:06     ` Boaz Harrosh
2010-09-13 14:44       ` Christoph Hellwig
2010-09-13 15:14         ` Boaz Harrosh
2010-09-13 11:20     ` Benny Halevy
2010-09-10 23:58   ` Christoph Hellwig
2010-09-11  0:07     ` Trond Myklebust
2010-09-13 11:24       ` Benny Halevy
2010-09-13 12:29         ` Trond Myklebust
2010-09-13 14:37           ` Benny Halevy
2010-09-13 16:55             ` Trond Myklebust
2010-09-13 14:28         ` Christoph Hellwig
2010-09-13 14:39           ` Benny Halevy
2010-09-13 15:07   ` Christoph Hellwig
2010-09-13 15:27     ` Fred Isaman
2010-09-02 18:00 ` [PATCH 08/13] RFC: pnfs: filelayout: introduce minimal file layout driver Fred Isaman
2010-09-10 19:31   ` Trond Myklebust
2010-09-10 21:11     ` Fred Isaman
2010-09-10 22:37       ` Trond Myklebust
2010-09-13 10:32         ` Benny Halevy
2010-09-13 13:01           ` Fred Isaman
     [not found]             ` <AANLkTimONZfA6ZX4xtzbmy0NdfEtbwMAi+__PhFYznTn-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-09-13 14:23               ` Benny Halevy
2010-09-13 14:48         ` Christoph Hellwig
2010-09-13 10:16       ` Benny Halevy
2010-09-10 23:56     ` Christoph Hellwig
2010-09-11  0:03       ` Trond Myklebust
2010-09-11  0:07         ` Christoph Hellwig
2010-09-11  0:13           ` Trond Myklebust
2010-09-13 11:28             ` Benny Halevy
2010-09-13 15:08   ` Christoph Hellwig
2010-09-13 15:16     ` Fred Isaman
2010-09-02 18:00 ` [PATCH 09/13] RFC: nfs: create and destroy inode's layout cache Fred Isaman
2010-09-10 19:43   ` Trond Myklebust
     [not found]     ` <1284147785.10062.80.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2010-09-10 21:13       ` Fred Isaman
2010-09-13 11:32     ` Benny Halevy [this message]
2010-09-02 18:00 ` [PATCH 10/13] RFC: nfs: client needs to maintain list of inodes with active layouts Fred Isaman
2010-09-10 19:59   ` Trond Myklebust
     [not found]     ` <1284148768.10062.94.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
2010-09-10 21:18       ` Fred Isaman
2010-09-02 18:00 ` [PATCH 11/13] RFC: nfs: retry on certain pnfs errors Fred Isaman
2010-09-02 18:00 ` [PATCH 12/13] RFC: pnfs: add LAYOUTGET and GETDEVICEINFO infrastructure Fred Isaman
2010-09-10 20:11   ` Trond Myklebust
2010-09-10 21:47     ` Fred Isaman
2010-09-10 22:43       ` Trond Myklebust
2010-09-13 14:16       ` Benny Halevy
2010-09-02 18:00 ` [PATCH 13/13] RFC: pnfs: filelayout: add driver's " Fred Isaman
2010-09-10 20:33   ` Trond Myklebust

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4C8E0BBA.9070109@panasas.com \
    --to=bhalevy@panasas.com \
    --cc=Trond.Myklebust@netapp.com \
    --cc=iisaman@netapp.com \
    --cc=linux-nfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.