Skip to content

Commit

Permalink
Merge branch 'nfs-for-2.6.37' of git://git.linux-nfs.org/projects/tro…
Browse files Browse the repository at this point in the history
…ndmy/nfs-2.6

* 'nfs-for-2.6.37' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6:
  net/sunrpc: Use static const char arrays
  nfs4: fix channel attribute sanity-checks
  NFSv4.1: Use more sensible names for 'initialize_mountpoint'
  NFSv4.1: pnfs: filelayout: add driver's LAYOUTGET and GETDEVICEINFO infrastructure
  NFSv4.1: pnfs: add LAYOUTGET and GETDEVICEINFO infrastructure
  NFS: client needs to maintain list of inodes with active layouts
  NFS: create and destroy inode's layout cache
  NFSv4.1: pnfs: filelayout: introduce minimal file layout driver
  NFSv4.1: pnfs: full mount/umount infrastructure
  NFS: set layout driver
  NFS: ask for layouttypes during v4 fsinfo call
  NFS: change stateid to be a union
  NFSv4.1: pnfsd, pnfs: protocol level pnfs constants
  SUNRPC: define xdr_decode_opaque_fixed
  NFSD: remove duplicate NFS4_STATEID_SIZE
  • Loading branch information
torvalds committed Oct 26, 2010
2 parents b18cae4 + 411b5e0 commit a4dd8dc
Show file tree
Hide file tree
Showing 24 changed files with 2,550 additions and 45 deletions.
2 changes: 2 additions & 0 deletions Documentation/filesystems/nfs/00-INDEX
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ nfs-rdma.txt
- how to install and setup the Linux NFS/RDMA client and server software
nfsroot.txt
- short guide on setting up a diskless box with NFS root filesystem.
pnfs.txt
- short explanation of some of the internals of the pnfs client code
rpc-cache.txt
- introduction to the caching mechanisms in the sunrpc layer.
idmapper.txt
Expand Down
48 changes: 48 additions & 0 deletions Documentation/filesystems/nfs/pnfs.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
Reference counting in pnfs:
==========================

The are several inter-related caches. We have layouts which can
reference multiple devices, each of which can reference multiple data servers.
Each data server can be referenced by multiple devices. Each device
can be referenced by multiple layouts. To keep all of this straight,
we need to reference count.


struct pnfs_layout_hdr
----------------------
The on-the-wire command LAYOUTGET corresponds to struct
pnfs_layout_segment, usually referred to by the variable name lseg.
Each nfs_inode may hold a pointer to a cache of of these layout
segments in nfsi->layout, of type struct pnfs_layout_hdr.

We reference the header for the inode pointing to it, across each
outstanding RPC call that references it (LAYOUTGET, LAYOUTRETURN,
LAYOUTCOMMIT), and for each lseg held within.

Each header is also (when non-empty) put on a list associated with
struct nfs_client (cl_layouts). Being put on this list does not bump
the reference count, as the layout is kept around by the lseg that
keeps it in the list.

deviceid_cache
--------------
lsegs reference device ids, which are resolved per nfs_client and
layout driver type. The device ids are held in a RCU cache (struct
nfs4_deviceid_cache). The cache itself is referenced across each
mount. The entries (struct nfs4_deviceid) themselves are held across
the lifetime of each lseg referencing them.

RCU is used because the deviceid is basically a write once, read many
data structure. The hlist size of 32 buckets needs better
justification, but seems reasonable given that we can have multiple
deviceid's per filesystem, and multiple filesystems per nfs_client.

The hash code is copied from the nfsd code base. A discussion of
hashing and variations of this algorithm can be found at:
http://groups.google.com/group/comp.lang.c/browse_thread/thread/9522965e2b8d3809

data server cache
-----------------
file driver devices refer to data servers, which are kept in a module
level cache. Its reference is held over the lifetime of the deviceid
pointing to it.
8 changes: 6 additions & 2 deletions fs/nfs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,17 @@ config NFS_V4

config NFS_V4_1
bool "NFS client support for NFSv4.1 (EXPERIMENTAL)"
depends on NFS_V4 && EXPERIMENTAL
depends on NFS_FS && NFS_V4 && EXPERIMENTAL
select PNFS_FILE_LAYOUT
help
This option enables support for minor version 1 of the NFSv4 protocol
(draft-ietf-nfsv4-minorversion1) in the kernel's NFS client.
(RFC 5661) in the kernel's NFS client.

If unsure, say N.

config PNFS_FILE_LAYOUT
tristate

config ROOT_NFS
bool "Root file system on NFS"
depends on NFS_FS=y && IP_PNP
Expand Down
4 changes: 4 additions & 0 deletions fs/nfs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,9 @@ nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
delegation.o idmap.o \
callback.o callback_xdr.o callback_proc.o \
nfs4namespace.o
nfs-$(CONFIG_NFS_V4_1) += pnfs.o
nfs-$(CONFIG_SYSCTL) += sysctl.o
nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o

obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o
nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o
8 changes: 4 additions & 4 deletions fs/nfs/callback_proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,11 @@ int nfs41_validate_delegation_stateid(struct nfs_delegation *delegation, const n
if (delegation == NULL)
return 0;

/* seqid is 4-bytes long */
if (((u32 *) &stateid->data)[0] != 0)
if (stateid->stateid.seqid != 0)
return 0;
if (memcmp(&delegation->stateid.data[4], &stateid->data[4],
sizeof(stateid->data)-4))
if (memcmp(&delegation->stateid.stateid.other,
&stateid->stateid.other,
NFS4_STATEID_OTHER_SIZE))
return 0;

return 1;
Expand Down
10 changes: 9 additions & 1 deletion fs/nfs/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include "iostat.h"
#include "internal.h"
#include "fscache.h"
#include "pnfs.h"

#define NFSDBG_FACILITY NFSDBG_CLIENT

Expand Down Expand Up @@ -155,7 +156,9 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
cred = rpc_lookup_machine_cred();
if (!IS_ERR(cred))
clp->cl_machine_cred = cred;

#if defined(CONFIG_NFS_V4_1)
INIT_LIST_HEAD(&clp->cl_layouts);
#endif
nfs_fscache_get_client_cookie(clp);

return clp;
Expand Down Expand Up @@ -252,6 +255,7 @@ void nfs_put_client(struct nfs_client *clp)
nfs_free_client(clp);
}
}
EXPORT_SYMBOL_GPL(nfs_put_client);

#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
/*
Expand Down Expand Up @@ -900,6 +904,8 @@ static void nfs_server_set_fsinfo(struct nfs_server *server, struct nfs_fsinfo *
if (server->wsize > NFS_MAX_FILE_IO_SIZE)
server->wsize = NFS_MAX_FILE_IO_SIZE;
server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
set_pnfs_layoutdriver(server, fsinfo->layouttype);

server->wtmult = nfs_block_bits(fsinfo->wtmult, NULL);

server->dtsize = nfs_block_size(fsinfo->dtpref, NULL);
Expand Down Expand Up @@ -939,6 +945,7 @@ static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, str
}

fsinfo.fattr = fattr;
fsinfo.layouttype = 0;
error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo);
if (error < 0)
goto out_error;
Expand Down Expand Up @@ -1021,6 +1028,7 @@ void nfs_free_server(struct nfs_server *server)
{
dprintk("--> nfs_free_server()\n");

unset_pnfs_layoutdriver(server);
spin_lock(&nfs_client_lock);
list_del(&server->client_link);
list_del(&server->master_link);
Expand Down
5 changes: 5 additions & 0 deletions fs/nfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "internal.h"
#include "iostat.h"
#include "fscache.h"
#include "pnfs.h"

#define NFSDBG_FACILITY NFSDBG_FILE

Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions fs/nfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include "internal.h"
#include "fscache.h"
#include "dns_resolve.h"
#include "pnfs.h"

#define NFSDBG_FACILITY NFSDBG_VFS

Expand Down Expand Up @@ -1410,6 +1411,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 */
Expand Down Expand Up @@ -1447,6 +1449,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
}

Expand Down
Loading

0 comments on commit a4dd8dc

Please sign in to comment.