Commit 9e12a7e7 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6

* 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6:
  NFS: Propagate 'fsc' mount option through automounts
  sunrpc/rpc_pipe: fix kernel-doc notation
  sunrpc: xdr_xcode_hyper helpers cannot presume 64-bit alignment
  NFS: Add nfs_alloc_parsed_mount_data
  NFS/RPC: fix problems with reestablish_timeout and related code.
  NFS: Get rid of the NFS_MOUNT_VER3 and NFS_MOUNT_TCP flags
parents a7ddbf89 2df54806
...@@ -648,8 +648,6 @@ static int nfs_start_lockd(struct nfs_server *server) ...@@ -648,8 +648,6 @@ static int nfs_start_lockd(struct nfs_server *server)
.hostname = clp->cl_hostname, .hostname = clp->cl_hostname,
.address = (struct sockaddr *)&clp->cl_addr, .address = (struct sockaddr *)&clp->cl_addr,
.addrlen = clp->cl_addrlen, .addrlen = clp->cl_addrlen,
.protocol = server->flags & NFS_MOUNT_TCP ?
IPPROTO_TCP : IPPROTO_UDP,
.nfs_version = clp->rpc_ops->version, .nfs_version = clp->rpc_ops->version,
.noresvport = server->flags & NFS_MOUNT_NORESVPORT ? .noresvport = server->flags & NFS_MOUNT_NORESVPORT ?
1 : 0, 1 : 0,
...@@ -660,6 +658,14 @@ static int nfs_start_lockd(struct nfs_server *server) ...@@ -660,6 +658,14 @@ static int nfs_start_lockd(struct nfs_server *server)
if (server->flags & NFS_MOUNT_NONLM) if (server->flags & NFS_MOUNT_NONLM)
return 0; return 0;
switch (clp->cl_proto) {
default:
nlm_init.protocol = IPPROTO_TCP;
break;
case XPRT_TRANSPORT_UDP:
nlm_init.protocol = IPPROTO_UDP;
}
host = nlmclnt_init(&nlm_init); host = nlmclnt_init(&nlm_init);
if (IS_ERR(host)) if (IS_ERR(host))
return PTR_ERR(host); return PTR_ERR(host);
...@@ -787,7 +793,7 @@ static int nfs_init_server(struct nfs_server *server, ...@@ -787,7 +793,7 @@ static int nfs_init_server(struct nfs_server *server,
dprintk("--> nfs_init_server()\n"); dprintk("--> nfs_init_server()\n");
#ifdef CONFIG_NFS_V3 #ifdef CONFIG_NFS_V3
if (data->flags & NFS_MOUNT_VER3) if (data->version == 3)
cl_init.rpc_ops = &nfs_v3_clientops; cl_init.rpc_ops = &nfs_v3_clientops;
#endif #endif
...@@ -964,6 +970,7 @@ static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_serve ...@@ -964,6 +970,7 @@ static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_serve
target->acdirmin = source->acdirmin; target->acdirmin = source->acdirmin;
target->acdirmax = source->acdirmax; target->acdirmax = source->acdirmax;
target->caps = source->caps; target->caps = source->caps;
target->options = source->options;
} }
/* /*
......
...@@ -58,17 +58,34 @@ void nfs_fscache_release_client_cookie(struct nfs_client *clp) ...@@ -58,17 +58,34 @@ void nfs_fscache_release_client_cookie(struct nfs_client *clp)
/* /*
* Get the cache cookie for an NFS superblock. We have to handle * Get the cache cookie for an NFS superblock. We have to handle
* uniquification here because the cache doesn't do it for us. * uniquification here because the cache doesn't do it for us.
*
* The default uniquifier is just an empty string, but it may be overridden
* either by the 'fsc=xxx' option to mount, or by inheriting it from the parent
* superblock across an automount point of some nature.
*/ */
void nfs_fscache_get_super_cookie(struct super_block *sb, void nfs_fscache_get_super_cookie(struct super_block *sb, const char *uniq,
struct nfs_parsed_mount_data *data) struct nfs_clone_mount *mntdata)
{ {
struct nfs_fscache_key *key, *xkey; struct nfs_fscache_key *key, *xkey;
struct nfs_server *nfss = NFS_SB(sb); struct nfs_server *nfss = NFS_SB(sb);
struct rb_node **p, *parent; struct rb_node **p, *parent;
const char *uniq = data->fscache_uniq ?: "";
int diff, ulen; int diff, ulen;
ulen = strlen(uniq); if (uniq) {
ulen = strlen(uniq);
} else if (mntdata) {
struct nfs_server *mnt_s = NFS_SB(mntdata->sb);
if (mnt_s->fscache_key) {
uniq = mnt_s->fscache_key->key.uniquifier;
ulen = mnt_s->fscache_key->key.uniq_len;
}
}
if (!uniq) {
uniq = "";
ulen = 1;
}
key = kzalloc(sizeof(*key) + ulen, GFP_KERNEL); key = kzalloc(sizeof(*key) + ulen, GFP_KERNEL);
if (!key) if (!key)
return; return;
......
...@@ -74,7 +74,8 @@ extern void nfs_fscache_get_client_cookie(struct nfs_client *); ...@@ -74,7 +74,8 @@ extern void nfs_fscache_get_client_cookie(struct nfs_client *);
extern void nfs_fscache_release_client_cookie(struct nfs_client *); extern void nfs_fscache_release_client_cookie(struct nfs_client *);
extern void nfs_fscache_get_super_cookie(struct super_block *, extern void nfs_fscache_get_super_cookie(struct super_block *,
struct nfs_parsed_mount_data *); const char *,
struct nfs_clone_mount *);
extern void nfs_fscache_release_super_cookie(struct super_block *); extern void nfs_fscache_release_super_cookie(struct super_block *);
extern void nfs_fscache_init_inode_cookie(struct inode *); extern void nfs_fscache_init_inode_cookie(struct inode *);
...@@ -173,7 +174,8 @@ static inline void nfs_fscache_release_client_cookie(struct nfs_client *clp) {} ...@@ -173,7 +174,8 @@ static inline void nfs_fscache_release_client_cookie(struct nfs_client *clp) {}
static inline void nfs_fscache_get_super_cookie( static inline void nfs_fscache_get_super_cookie(
struct super_block *sb, struct super_block *sb,
struct nfs_parsed_mount_data *data) const char *uniq,
struct nfs_clone_mount *mntdata)
{ {
} }
static inline void nfs_fscache_release_super_cookie(struct super_block *sb) {} static inline void nfs_fscache_release_super_cookie(struct super_block *sb) {}
......
...@@ -728,6 +728,27 @@ static void nfs_umount_begin(struct super_block *sb) ...@@ -728,6 +728,27 @@ static void nfs_umount_begin(struct super_block *sb)
unlock_kernel(); unlock_kernel();
} }
static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(int flags)
{
struct nfs_parsed_mount_data *data;
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (data) {
data->flags = flags;
data->rsize = NFS_MAX_FILE_IO_SIZE;
data->wsize = NFS_MAX_FILE_IO_SIZE;
data->acregmin = NFS_DEF_ACREGMIN;
data->acregmax = NFS_DEF_ACREGMAX;
data->acdirmin = NFS_DEF_ACDIRMIN;
data->acdirmax = NFS_DEF_ACDIRMAX;
data->nfs_server.port = NFS_UNSPEC_PORT;
data->auth_flavors[0] = RPC_AUTH_UNIX;
data->auth_flavor_len = 1;
data->minorversion = 0;
}
return data;
}
/* /*
* Sanity-check a server address provided by the mount command. * Sanity-check a server address provided by the mount command.
* *
...@@ -1430,10 +1451,13 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args, ...@@ -1430,10 +1451,13 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
int status; int status;
if (args->mount_server.version == 0) { if (args->mount_server.version == 0) {
if (args->flags & NFS_MOUNT_VER3) switch (args->version) {
args->mount_server.version = NFS_MNT3_VERSION; default:
else args->mount_server.version = NFS_MNT3_VERSION;
args->mount_server.version = NFS_MNT_VERSION; break;
case 2:
args->mount_server.version = NFS_MNT_VERSION;
}
} }
request.version = args->mount_server.version; request.version = args->mount_server.version;
...@@ -1634,20 +1658,6 @@ static int nfs_validate_mount_data(void *options, ...@@ -1634,20 +1658,6 @@ static int nfs_validate_mount_data(void *options,
if (data == NULL) if (data == NULL)
goto out_no_data; goto out_no_data;
args->flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP);
args->rsize = NFS_MAX_FILE_IO_SIZE;
args->wsize = NFS_MAX_FILE_IO_SIZE;
args->acregmin = NFS_DEF_ACREGMIN;
args->acregmax = NFS_DEF_ACREGMAX;
args->acdirmin = NFS_DEF_ACDIRMIN;
args->acdirmax = NFS_DEF_ACDIRMAX;
args->mount_server.port = NFS_UNSPEC_PORT;
args->nfs_server.port = NFS_UNSPEC_PORT;
args->nfs_server.protocol = XPRT_TRANSPORT_TCP;
args->auth_flavors[0] = RPC_AUTH_UNIX;
args->auth_flavor_len = 1;
args->minorversion = 0;
switch (data->version) { switch (data->version) {
case 1: case 1:
data->namlen = 0; data->namlen = 0;
...@@ -1778,7 +1788,7 @@ static int nfs_validate_mount_data(void *options, ...@@ -1778,7 +1788,7 @@ static int nfs_validate_mount_data(void *options,
} }
#ifndef CONFIG_NFS_V3 #ifndef CONFIG_NFS_V3
if (args->flags & NFS_MOUNT_VER3) if (args->version == 3)
goto out_v3_not_compiled; goto out_v3_not_compiled;
#endif /* !CONFIG_NFS_V3 */ #endif /* !CONFIG_NFS_V3 */
...@@ -1936,7 +1946,7 @@ static void nfs_fill_super(struct super_block *sb, ...@@ -1936,7 +1946,7 @@ static void nfs_fill_super(struct super_block *sb,
if (data->bsize) if (data->bsize)
sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits); sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits);
if (server->flags & NFS_MOUNT_VER3) { if (server->nfs_client->rpc_ops->version == 3) {
/* The VFS shouldn't apply the umask to mode bits. We will do /* The VFS shouldn't apply the umask to mode bits. We will do
* so ourselves when necessary. * so ourselves when necessary.
*/ */
...@@ -1960,7 +1970,7 @@ static void nfs_clone_super(struct super_block *sb, ...@@ -1960,7 +1970,7 @@ static void nfs_clone_super(struct super_block *sb,
sb->s_blocksize = old_sb->s_blocksize; sb->s_blocksize = old_sb->s_blocksize;
sb->s_maxbytes = old_sb->s_maxbytes; sb->s_maxbytes = old_sb->s_maxbytes;
if (server->flags & NFS_MOUNT_VER3) { if (server->nfs_client->rpc_ops->version == 3) {
/* The VFS shouldn't apply the umask to mode bits. We will do /* The VFS shouldn't apply the umask to mode bits. We will do
* so ourselves when necessary. * so ourselves when necessary.
*/ */
...@@ -2094,7 +2104,7 @@ static int nfs_get_sb(struct file_system_type *fs_type, ...@@ -2094,7 +2104,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
}; };
int error = -ENOMEM; int error = -ENOMEM;
data = kzalloc(sizeof(*data), GFP_KERNEL); data = nfs_alloc_parsed_mount_data(NFS_MOUNT_VER3 | NFS_MOUNT_TCP);
mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL); mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL);
if (data == NULL || mntfh == NULL) if (data == NULL || mntfh == NULL)
goto out_free_fh; goto out_free_fh;
...@@ -2144,7 +2154,8 @@ static int nfs_get_sb(struct file_system_type *fs_type, ...@@ -2144,7 +2154,8 @@ static int nfs_get_sb(struct file_system_type *fs_type,
if (!s->s_root) { if (!s->s_root) {
/* initial superblock/root creation */ /* initial superblock/root creation */
nfs_fill_super(s, data); nfs_fill_super(s, data);
nfs_fscache_get_super_cookie(s, data); nfs_fscache_get_super_cookie(
s, data ? data->fscache_uniq : NULL, NULL);
} }
mntroot = nfs_get_root(s, mntfh); mntroot = nfs_get_root(s, mntfh);
...@@ -2245,6 +2256,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags, ...@@ -2245,6 +2256,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
if (!s->s_root) { if (!s->s_root) {
/* initial superblock/root creation */ /* initial superblock/root creation */
nfs_clone_super(s, data->sb); nfs_clone_super(s, data->sb);
nfs_fscache_get_super_cookie(s, NULL, data);
} }
mntroot = nfs_get_root(s, data->fh); mntroot = nfs_get_root(s, data->fh);
...@@ -2362,18 +2374,7 @@ static int nfs4_validate_mount_data(void *options, ...@@ -2362,18 +2374,7 @@ static int nfs4_validate_mount_data(void *options,
if (data == NULL) if (data == NULL)
goto out_no_data; goto out_no_data;
args->rsize = NFS_MAX_FILE_IO_SIZE;
args->wsize = NFS_MAX_FILE_IO_SIZE;
args->acregmin = NFS_DEF_ACREGMIN;
args->acregmax = NFS_DEF_ACREGMAX;
args->acdirmin = NFS_DEF_ACDIRMIN;
args->acdirmax = NFS_DEF_ACDIRMAX;
args->nfs_server.port = NFS_UNSPEC_PORT;
args->auth_flavors[0] = RPC_AUTH_UNIX;
args->auth_flavor_len = 1;
args->version = 4; args->version = 4;
args->minorversion = 0;
switch (data->version) { switch (data->version) {
case 1: case 1:
if (data->host_addrlen > sizeof(args->nfs_server.address)) if (data->host_addrlen > sizeof(args->nfs_server.address))
...@@ -2508,7 +2509,8 @@ static int nfs4_remote_get_sb(struct file_system_type *fs_type, ...@@ -2508,7 +2509,8 @@ static int nfs4_remote_get_sb(struct file_system_type *fs_type,
if (!s->s_root) { if (!s->s_root) {
/* initial superblock/root creation */ /* initial superblock/root creation */
nfs4_fill_super(s); nfs4_fill_super(s);
nfs_fscache_get_super_cookie(s, data); nfs_fscache_get_super_cookie(
s, data ? data->fscache_uniq : NULL, NULL);
} }
mntroot = nfs4_get_root(s, mntfh); mntroot = nfs4_get_root(s, mntfh);
...@@ -2656,7 +2658,7 @@ static int nfs4_get_sb(struct file_system_type *fs_type, ...@@ -2656,7 +2658,7 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
struct nfs_parsed_mount_data *data; struct nfs_parsed_mount_data *data;
int error = -ENOMEM; int error = -ENOMEM;
data = kzalloc(sizeof(*data), GFP_KERNEL); data = nfs_alloc_parsed_mount_data(0);
if (data == NULL) if (data == NULL)
goto out_free_data; goto out_free_data;
...@@ -2741,6 +2743,7 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags, ...@@ -2741,6 +2743,7 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
if (!s->s_root) { if (!s->s_root) {
/* initial superblock/root creation */ /* initial superblock/root creation */
nfs4_clone_super(s, data->sb); nfs4_clone_super(s, data->sb);
nfs_fscache_get_super_cookie(s, NULL, data);
} }
mntroot = nfs4_get_root(s, data->fh); mntroot = nfs4_get_root(s, data->fh);
...@@ -2822,6 +2825,7 @@ static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type, ...@@ -2822,6 +2825,7 @@ static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type,
if (!s->s_root) { if (!s->s_root) {
/* initial superblock/root creation */ /* initial superblock/root creation */
nfs4_fill_super(s); nfs4_fill_super(s);
nfs_fscache_get_super_cookie(s, NULL, data);
} }
mntroot = nfs4_get_root(s, &mntfh); mntroot = nfs4_get_root(s, &mntfh);
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/uio.h> #include <linux/uio.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/unaligned.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
/* /*
...@@ -117,14 +118,14 @@ static inline __be32 *xdr_encode_array(__be32 *p, const void *s, unsigned int le ...@@ -117,14 +118,14 @@ static inline __be32 *xdr_encode_array(__be32 *p, const void *s, unsigned int le
static inline __be32 * static inline __be32 *
xdr_encode_hyper(__be32 *p, __u64 val) xdr_encode_hyper(__be32 *p, __u64 val)
{ {
*(__be64 *)p = cpu_to_be64(val); put_unaligned_be64(val, p);
return p + 2; return p + 2;
} }
static inline __be32 * static inline __be32 *
xdr_decode_hyper(__be32 *p, __u64 *valp) xdr_decode_hyper(__be32 *p, __u64 *valp)
{ {
*valp = be64_to_cpup((__be64 *)p); *valp = get_unaligned_be64(p);
return p + 2; return p + 2;
} }
......
...@@ -860,7 +860,8 @@ static void rpc_clntdir_depopulate(struct dentry *dentry) ...@@ -860,7 +860,8 @@ static void rpc_clntdir_depopulate(struct dentry *dentry)
/** /**
* rpc_create_client_dir - Create a new rpc_client directory in rpc_pipefs * rpc_create_client_dir - Create a new rpc_client directory in rpc_pipefs
* @path: path from the rpc_pipefs root to the new directory * @dentry: dentry from the rpc_pipefs root to the new directory
* @name: &struct qstr for the name
* @rpc_client: rpc client to associate with this directory * @rpc_client: rpc client to associate with this directory
* *
* This creates a directory at the given @path associated with * This creates a directory at the given @path associated with
......
...@@ -773,6 +773,7 @@ static void xs_close(struct rpc_xprt *xprt) ...@@ -773,6 +773,7 @@ static void xs_close(struct rpc_xprt *xprt)
dprintk("RPC: xs_close xprt %p\n", xprt); dprintk("RPC: xs_close xprt %p\n", xprt);
xs_reset_transport(transport); xs_reset_transport(transport);
xprt->reestablish_timeout = 0;
smp_mb__before_clear_bit(); smp_mb__before_clear_bit();
clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); clear_bit(XPRT_CONNECTION_ABORT, &xprt->state);
...@@ -1264,6 +1265,12 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes) ...@@ -1264,6 +1265,12 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes)
if (xprt->shutdown) if (xprt->shutdown)
goto out; goto out;
/* Any data means we had a useful conversation, so
* the we don't need to delay the next reconnect
*/
if (xprt->reestablish_timeout)
xprt->reestablish_timeout = 0;
/* We use rd_desc to pass struct xprt to xs_tcp_data_recv */ /* We use rd_desc to pass struct xprt to xs_tcp_data_recv */
rd_desc.arg.data = xprt; rd_desc.arg.data = xprt;
do { do {
...@@ -2034,6 +2041,8 @@ static void xs_connect(struct rpc_task *task) ...@@ -2034,6 +2041,8 @@ static void xs_connect(struct rpc_task *task)
&transport->connect_worker, &transport->connect_worker,
xprt->reestablish_timeout); xprt->reestablish_timeout);
xprt->reestablish_timeout <<= 1; xprt->reestablish_timeout <<= 1;
if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO)
xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO) if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO)
xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO; xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO;
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment