提交 b797cac7 编写于 作者: D David Howells

NFS: Add mount options to enable local caching on NFS

Add NFS mount options to allow the local caching support to be enabled.

The attached patch makes it possible for the NFS filesystem to be told to make
use of the network filesystem local caching service (FS-Cache).

To be able to use this, a recent nfsutils package is required.

There are three variant NFS mount options that can be added to a mount command
to control caching for a mount.  Only the last one specified takes effect:

 (*) Adding "fsc" will request caching.

 (*) Adding "fsc=<string>" will request caching and also specify a uniquifier.

 (*) Adding "nofsc" will disable caching.

For example:

	mount warthog:/ /a -o fsc

The cache of a particular superblock (NFS FSID) will be shared between all
mounts of that volume, provided they have the same connection parameters and
are not marked 'nosharecache'.

Where it is otherwise impossible to distinguish superblocks because all the
parameters are identical, but the 'nosharecache' option is supplied, a
uniquifying string must be supplied, else only the first mount will be
permitted to use the cache.

If there's a key collision, then the second mount will disable caching and give
a warning into the kernel log.
Signed-off-by: NDavid Howells <dhowells@redhat.com>
Acked-by: NSteve Dickson <steved@redhat.com>
Acked-by: NTrond Myklebust <Trond.Myklebust@netapp.com>
Acked-by: NAl Viro <viro@zeniv.linux.org.uk>
Tested-by: NDaire Byrne <Daire.Byrne@framestore.com>
上级 5d1acff1
...@@ -765,6 +765,7 @@ static int nfs_init_server(struct nfs_server *server, ...@@ -765,6 +765,7 @@ static int nfs_init_server(struct nfs_server *server,
/* Initialise the client representation from the mount data */ /* Initialise the client representation from the mount data */
server->flags = data->flags; server->flags = data->flags;
server->options = data->options;
if (data->rsize) if (data->rsize)
server->rsize = nfs_block_size(data->rsize, NULL); server->rsize = nfs_block_size(data->rsize, NULL);
...@@ -1153,6 +1154,7 @@ static int nfs4_init_server(struct nfs_server *server, ...@@ -1153,6 +1154,7 @@ static int nfs4_init_server(struct nfs_server *server,
/* Initialise the client representation from the mount data */ /* Initialise the client representation from the mount data */
server->flags = data->flags; server->flags = data->flags;
server->caps |= NFS_CAP_ATOMIC_OPEN; server->caps |= NFS_CAP_ATOMIC_OPEN;
server->options = data->options;
/* Get a client record */ /* Get a client record */
error = nfs4_set_client(server, error = nfs4_set_client(server,
......
...@@ -39,6 +39,7 @@ struct nfs_parsed_mount_data { ...@@ -39,6 +39,7 @@ struct nfs_parsed_mount_data {
int acregmin, acregmax, int acregmin, acregmax,
acdirmin, acdirmax; acdirmin, acdirmax;
int namlen; int namlen;
unsigned int options;
unsigned int bsize; unsigned int bsize;
unsigned int auth_flavor_len; unsigned int auth_flavor_len;
rpc_authflavor_t auth_flavors[1]; rpc_authflavor_t auth_flavors[1];
......
...@@ -77,6 +77,7 @@ enum { ...@@ -77,6 +77,7 @@ enum {
Opt_rdirplus, Opt_nordirplus, Opt_rdirplus, Opt_nordirplus,
Opt_sharecache, Opt_nosharecache, Opt_sharecache, Opt_nosharecache,
Opt_resvport, Opt_noresvport, Opt_resvport, Opt_noresvport,
Opt_fscache, Opt_nofscache,
/* Mount options that take integer arguments */ /* Mount options that take integer arguments */
Opt_port, Opt_port,
...@@ -94,6 +95,7 @@ enum { ...@@ -94,6 +95,7 @@ enum {
Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost, Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost,
Opt_addr, Opt_mountaddr, Opt_clientaddr, Opt_addr, Opt_mountaddr, Opt_clientaddr,
Opt_lookupcache, Opt_lookupcache,
Opt_fscache_uniq,
/* Special mount options */ /* Special mount options */
Opt_userspace, Opt_deprecated, Opt_sloppy, Opt_userspace, Opt_deprecated, Opt_sloppy,
...@@ -133,6 +135,9 @@ static const match_table_t nfs_mount_option_tokens = { ...@@ -133,6 +135,9 @@ static const match_table_t nfs_mount_option_tokens = {
{ Opt_nosharecache, "nosharecache" }, { Opt_nosharecache, "nosharecache" },
{ Opt_resvport, "resvport" }, { Opt_resvport, "resvport" },
{ Opt_noresvport, "noresvport" }, { Opt_noresvport, "noresvport" },
{ Opt_fscache, "fsc" },
{ Opt_fscache_uniq, "fsc=%s" },
{ Opt_nofscache, "nofsc" },
{ Opt_port, "port=%u" }, { Opt_port, "port=%u" },
{ Opt_rsize, "rsize=%u" }, { Opt_rsize, "rsize=%u" },
...@@ -564,6 +569,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, ...@@ -564,6 +569,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
if (clp->rpc_ops->version == 4) if (clp->rpc_ops->version == 4)
seq_printf(m, ",clientaddr=%s", clp->cl_ipaddr); seq_printf(m, ",clientaddr=%s", clp->cl_ipaddr);
#endif #endif
if (nfss->options & NFS_OPTION_FSCACHE)
seq_printf(m, ",fsc");
} }
/* /*
...@@ -1056,6 +1063,24 @@ static int nfs_parse_mount_options(char *raw, ...@@ -1056,6 +1063,24 @@ static int nfs_parse_mount_options(char *raw,
case Opt_noresvport: case Opt_noresvport:
mnt->flags |= NFS_MOUNT_NORESVPORT; mnt->flags |= NFS_MOUNT_NORESVPORT;
break; break;
case Opt_fscache:
mnt->options |= NFS_OPTION_FSCACHE;
kfree(mnt->fscache_uniq);
mnt->fscache_uniq = NULL;
break;
case Opt_nofscache:
mnt->options &= ~NFS_OPTION_FSCACHE;
kfree(mnt->fscache_uniq);
mnt->fscache_uniq = NULL;
break;
case Opt_fscache_uniq:
string = match_strdup(args);
if (!string)
goto out_nomem;
kfree(mnt->fscache_uniq);
mnt->fscache_uniq = string;
mnt->options |= NFS_OPTION_FSCACHE;
break;
/* /*
* options that take numeric values * options that take numeric values
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册