Commit 9085bbcb authored by Trond Myklebust's avatar Trond Myklebust

[PATCH] NFS: Kill annoying mount version mismatch printks

 Ensure that we fix up the missing fields in the nfs_mount_data with
 sane defaults for older versions of mount, and return errors in the
 cases where we cannot.

 Convert a bunch of annoying warnings into dprintks()

 Return -EPROTONOSUPPORT rather than EIO if mount() tries to set NFSv3
 without it actually being compiled in.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 5ee0ed7d
...@@ -366,13 +366,15 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data) ...@@ -366,13 +366,15 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data)
xprt = xprt_create_proto(tcp ? IPPROTO_TCP : IPPROTO_UDP, xprt = xprt_create_proto(tcp ? IPPROTO_TCP : IPPROTO_UDP,
&server->addr, &timeparms); &server->addr, &timeparms);
if (IS_ERR(xprt)) { if (IS_ERR(xprt)) {
printk(KERN_WARNING "NFS: cannot create RPC transport.\n"); dprintk("%s: cannot create RPC transport. Error = %ld\n",
__FUNCTION__, PTR_ERR(xprt));
return (struct rpc_clnt *)xprt; return (struct rpc_clnt *)xprt;
} }
clnt = rpc_create_client(xprt, server->hostname, &nfs_program, clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
server->rpc_ops->version, data->pseudoflavor); server->rpc_ops->version, data->pseudoflavor);
if (IS_ERR(clnt)) { if (IS_ERR(clnt)) {
printk(KERN_WARNING "NFS: cannot create RPC client.\n"); dprintk("%s: cannot create RPC client. Error = %ld\n",
__FUNCTION__, PTR_ERR(xprt));
goto out_fail; goto out_fail;
} }
...@@ -426,21 +428,16 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent) ...@@ -426,21 +428,16 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent)
/* Check NFS protocol revision and initialize RPC op vector /* Check NFS protocol revision and initialize RPC op vector
* and file handle pool. */ * and file handle pool. */
if (server->flags & NFS_MOUNT_VER3) {
#ifdef CONFIG_NFS_V3 #ifdef CONFIG_NFS_V3
if (server->flags & NFS_MOUNT_VER3) {
server->rpc_ops = &nfs_v3_clientops; server->rpc_ops = &nfs_v3_clientops;
server->caps |= NFS_CAP_READDIRPLUS; server->caps |= NFS_CAP_READDIRPLUS;
if (data->version < 4) {
printk(KERN_NOTICE "NFS: NFSv3 not supported by mount program.\n");
return -EIO;
}
#else
printk(KERN_NOTICE "NFS: NFSv3 not supported.\n");
return -EIO;
#endif
} else { } else {
server->rpc_ops = &nfs_v2_clientops; server->rpc_ops = &nfs_v2_clientops;
} }
#else
server->rpc_ops = &nfs_v2_clientops;
#endif
/* Fill in pseudoflavor for mount version < 5 */ /* Fill in pseudoflavor for mount version < 5 */
if (!(data->flags & NFS_MOUNT_SECFLAVOUR)) if (!(data->flags & NFS_MOUNT_SECFLAVOUR))
...@@ -1384,74 +1381,94 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type, ...@@ -1384,74 +1381,94 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name, void *raw_data) int flags, const char *dev_name, void *raw_data)
{ {
int error; int error;
struct nfs_server *server; struct nfs_server *server = NULL;
struct super_block *s; struct super_block *s;
struct nfs_fh *root; struct nfs_fh *root;
struct nfs_mount_data *data = raw_data; struct nfs_mount_data *data = raw_data;
if (!data) { s = ERR_PTR(-EINVAL);
printk("nfs_read_super: missing data argument\n"); if (data == NULL) {
return ERR_PTR(-EINVAL); dprintk("%s: missing data argument\n", __FUNCTION__);
goto out_err;
} }
if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) {
server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL); dprintk("%s: bad mount version\n", __FUNCTION__);
if (!server) goto out_err;
return ERR_PTR(-ENOMEM); }
memset(server, 0, sizeof(struct nfs_server)); switch (data->version) {
/* Zero out the NFS state stuff */ case 1:
init_nfsv4_state(server);
if (data->version != NFS_MOUNT_VERSION) {
printk("nfs warning: mount version %s than kernel\n",
data->version < NFS_MOUNT_VERSION ? "older" : "newer");
if (data->version < 2)
data->namlen = 0; data->namlen = 0;
if (data->version < 3) case 2:
data->bsize = 0; data->bsize = 0;
if (data->version < 4) { case 3:
data->flags &= ~NFS_MOUNT_VER3; if (data->flags & NFS_MOUNT_VER3) {
dprintk("%s: mount structure version %d does not support NFSv3\n",
__FUNCTION__,
data->version);
goto out_err;
}
data->root.size = NFS2_FHSIZE; data->root.size = NFS2_FHSIZE;
memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE); memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
case 4:
if (data->flags & NFS_MOUNT_SECFLAVOUR) {
dprintk("%s: mount structure version %d does not support strong security\n",
__FUNCTION__,
data->version);
goto out_err;
} }
if (data->version < 5) case 5:
data->flags &= ~NFS_MOUNT_SECFLAVOUR; memset(data->context, 0, sizeof(data->context));
} }
#ifndef CONFIG_NFS_V3
/* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */
s = ERR_PTR(-EPROTONOSUPPORT);
if (data->flags & NFS_MOUNT_VER3) {
dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__);
goto out_err;
}
#endif /* CONFIG_NFS_V3 */
s = ERR_PTR(-ENOMEM);
server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL);
if (!server)
goto out_err;
memset(server, 0, sizeof(struct nfs_server));
/* Zero out the NFS state stuff */
init_nfsv4_state(server);
root = &server->fh; root = &server->fh;
if (data->flags & NFS_MOUNT_VER3) if (data->flags & NFS_MOUNT_VER3)
root->size = data->root.size; root->size = data->root.size;
else else
root->size = NFS2_FHSIZE; root->size = NFS2_FHSIZE;
s = ERR_PTR(-EINVAL);
if (root->size > sizeof(root->data)) { if (root->size > sizeof(root->data)) {
printk("nfs_get_sb: invalid root filehandle\n"); dprintk("%s: invalid root filehandle\n", __FUNCTION__);
kfree(server); goto out_err;
return ERR_PTR(-EINVAL);
} }
memcpy(root->data, data->root.data, root->size); memcpy(root->data, data->root.data, root->size);
/* We now require that the mount process passes the remote address */ /* We now require that the mount process passes the remote address */
memcpy(&server->addr, &data->addr, sizeof(server->addr)); memcpy(&server->addr, &data->addr, sizeof(server->addr));
if (server->addr.sin_addr.s_addr == INADDR_ANY) { if (server->addr.sin_addr.s_addr == INADDR_ANY) {
printk("NFS: mount program didn't pass remote address!\n"); dprintk("%s: mount program didn't pass remote address!\n",
kfree(server); __FUNCTION__);
return ERR_PTR(-EINVAL); goto out_err;
} }
s = sget(fs_type, nfs_compare_super, nfs_set_super, server); /* Fire up rpciod if not yet running */
s = ERR_PTR(rpciod_up());
if (IS_ERR(s) || s->s_root) { if (IS_ERR(s)) {
kfree(server); dprintk("%s: couldn't start rpciod! Error = %ld\n",
return s; __FUNCTION__, PTR_ERR(s));
goto out_err;
} }
s->s_flags = flags; s = sget(fs_type, nfs_compare_super, nfs_set_super, server);
if (IS_ERR(s) || s->s_root)
goto out_rpciod_down;
/* Fire up rpciod if not yet running */ s->s_flags = flags;
if (rpciod_up() != 0) {
printk(KERN_WARNING "NFS: couldn't start rpciod!\n");
kfree(server);
return ERR_PTR(-EIO);
}
error = nfs_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0); error = nfs_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
if (error) { if (error) {
...@@ -1461,6 +1478,11 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type, ...@@ -1461,6 +1478,11 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
} }
s->s_flags |= MS_ACTIVE; s->s_flags |= MS_ACTIVE;
return s; return s;
out_rpciod_down:
rpciod_down();
out_err:
kfree(server);
return s;
} }
static void nfs_kill_super(struct super_block *s) static void nfs_kill_super(struct super_block *s)
...@@ -1593,15 +1615,19 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, ...@@ -1593,15 +1615,19 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
clp = nfs4_get_client(&server->addr.sin_addr); clp = nfs4_get_client(&server->addr.sin_addr);
if (!clp) { if (!clp) {
printk(KERN_WARNING "NFS: failed to create NFS4 client.\n"); dprintk("%s: failed to create NFS4 client.\n", __FUNCTION__);
return -EIO; return -EIO;
} }
/* Now create transport and client */ /* Now create transport and client */
authflavour = RPC_AUTH_UNIX; authflavour = RPC_AUTH_UNIX;
if (data->auth_flavourlen != 0) { if (data->auth_flavourlen != 0) {
if (data->auth_flavourlen > 1) if (data->auth_flavourlen != 1) {
printk(KERN_INFO "NFS: cannot yet deal with multiple auth flavours.\n"); dprintk("%s: Invalid number of RPC auth flavours %d.\n",
__FUNCTION__, data->auth_flavourlen);
err = -EINVAL;
goto out_fail;
}
if (copy_from_user(&authflavour, data->auth_flavours, sizeof(authflavour))) { if (copy_from_user(&authflavour, data->auth_flavours, sizeof(authflavour))) {
err = -EFAULT; err = -EFAULT;
goto out_fail; goto out_fail;
...@@ -1613,16 +1639,18 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, ...@@ -1613,16 +1639,18 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
xprt = xprt_create_proto(proto, &server->addr, &timeparms); xprt = xprt_create_proto(proto, &server->addr, &timeparms);
if (IS_ERR(xprt)) { if (IS_ERR(xprt)) {
up_write(&clp->cl_sem); up_write(&clp->cl_sem);
printk(KERN_WARNING "NFS: cannot create RPC transport.\n");
err = PTR_ERR(xprt); err = PTR_ERR(xprt);
dprintk("%s: cannot create RPC transport. Error = %d\n",
__FUNCTION__, err);
goto out_fail; goto out_fail;
} }
clnt = rpc_create_client(xprt, server->hostname, &nfs_program, clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
server->rpc_ops->version, authflavour); server->rpc_ops->version, authflavour);
if (IS_ERR(clnt)) { if (IS_ERR(clnt)) {
up_write(&clp->cl_sem); up_write(&clp->cl_sem);
printk(KERN_WARNING "NFS: cannot create RPC client.\n");
err = PTR_ERR(clnt); err = PTR_ERR(clnt);
dprintk("%s: cannot create RPC client. Error = %d\n",
__FUNCTION__, err);
goto out_fail; goto out_fail;
} }
clnt->cl_intr = 1; clnt->cl_intr = 1;
...@@ -1654,20 +1682,22 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, ...@@ -1654,20 +1682,22 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
clp = NULL; clp = NULL;
if (IS_ERR(clnt)) { if (IS_ERR(clnt)) {
printk(KERN_WARNING "NFS: cannot create RPC client.\n"); err = PTR_ERR(clnt);
return PTR_ERR(clnt); dprintk("%s: cannot create RPC client. Error = %d\n",
__FUNCTION__, err);
return err;
} }
server->client = clnt; server->client = clnt;
if (server->nfs4_state->cl_idmap == NULL) { if (server->nfs4_state->cl_idmap == NULL) {
printk(KERN_WARNING "NFS: failed to create idmapper.\n"); dprintk("%s: failed to create idmapper.\n", __FUNCTION__);
return -ENOMEM; return -ENOMEM;
} }
if (clnt->cl_auth->au_flavor != authflavour) { if (clnt->cl_auth->au_flavor != authflavour) {
if (rpcauth_create(authflavour, clnt) == NULL) { if (rpcauth_create(authflavour, clnt) == NULL) {
printk(KERN_WARNING "NFS: couldn't create credcache!\n"); dprintk("%s: couldn't create credcache!\n", __FUNCTION__);
return -ENOMEM; return -ENOMEM;
} }
} }
...@@ -1728,8 +1758,12 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type, ...@@ -1728,8 +1758,12 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
struct nfs4_mount_data *data = raw_data; struct nfs4_mount_data *data = raw_data;
void *p; void *p;
if (!data) { if (data == NULL) {
printk("nfs_read_super: missing data argument\n"); dprintk("%s: missing data argument\n", __FUNCTION__);
return ERR_PTR(-EINVAL);
}
if (data->version <= 0 || data->version > NFS4_MOUNT_VERSION) {
dprintk("%s: bad mount version\n", __FUNCTION__);
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
...@@ -1740,11 +1774,6 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type, ...@@ -1740,11 +1774,6 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
/* Zero out the NFS state stuff */ /* Zero out the NFS state stuff */
init_nfsv4_state(server); init_nfsv4_state(server);
if (data->version != NFS4_MOUNT_VERSION) {
printk("nfs warning: mount version %s than kernel\n",
data->version < NFS4_MOUNT_VERSION ? "older" : "newer");
}
p = nfs_copy_user_string(NULL, &data->hostname, 256); p = nfs_copy_user_string(NULL, &data->hostname, 256);
if (IS_ERR(p)) if (IS_ERR(p))
goto out_err; goto out_err;
...@@ -1771,11 +1800,20 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type, ...@@ -1771,11 +1800,20 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
} }
if (server->addr.sin_family != AF_INET || if (server->addr.sin_family != AF_INET ||
server->addr.sin_addr.s_addr == INADDR_ANY) { server->addr.sin_addr.s_addr == INADDR_ANY) {
printk("NFS: mount program didn't pass remote IP address!\n"); dprintk("%s: mount program didn't pass remote IP address!\n",
__FUNCTION__);
s = ERR_PTR(-EINVAL); s = ERR_PTR(-EINVAL);
goto out_free; goto out_free;
} }
/* Fire up rpciod if not yet running */
s = ERR_PTR(rpciod_up());
if (IS_ERR(s)) {
dprintk("%s: couldn't start rpciod! Error = %ld\n",
__FUNCTION__, PTR_ERR(s));
goto out_free;
}
s = sget(fs_type, nfs4_compare_super, nfs_set_super, server); s = sget(fs_type, nfs4_compare_super, nfs_set_super, server);
if (IS_ERR(s) || s->s_root) if (IS_ERR(s) || s->s_root)
...@@ -1783,13 +1821,6 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type, ...@@ -1783,13 +1821,6 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
s->s_flags = flags; s->s_flags = flags;
/* Fire up rpciod if not yet running */
if (rpciod_up() != 0) {
printk(KERN_WARNING "NFS: couldn't start rpciod!\n");
s = ERR_PTR(-EIO);
goto out_free;
}
error = nfs4_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0); error = nfs4_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
if (error) { if (error) {
up_write(&s->s_umount); up_write(&s->s_umount);
......
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