Commit 7d4e31b1 authored by Trond Myklebust's avatar Trond Myklebust

NFS: Clean up the logic that handles recovery from a failed mount

   request. Get rid of nfs_put_super.
Signed-off-by: default avatarChuck Lever <cel@netapp.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@fys.uio.no>
parent 252470cd
...@@ -57,7 +57,6 @@ static struct inode *nfs_alloc_inode(struct super_block *sb); ...@@ -57,7 +57,6 @@ static struct inode *nfs_alloc_inode(struct super_block *sb);
static void nfs_destroy_inode(struct inode *); static void nfs_destroy_inode(struct inode *);
static void nfs_write_inode(struct inode *,int); static void nfs_write_inode(struct inode *,int);
static void nfs_delete_inode(struct inode *); static void nfs_delete_inode(struct inode *);
static void nfs_put_super(struct super_block *);
static void nfs_clear_inode(struct inode *); static void nfs_clear_inode(struct inode *);
static void nfs_umount_begin(struct super_block *); static void nfs_umount_begin(struct super_block *);
static int nfs_statfs(struct super_block *, struct kstatfs *); static int nfs_statfs(struct super_block *, struct kstatfs *);
...@@ -68,7 +67,6 @@ static struct super_operations nfs_sops = { ...@@ -68,7 +67,6 @@ static struct super_operations nfs_sops = {
.destroy_inode = nfs_destroy_inode, .destroy_inode = nfs_destroy_inode,
.write_inode = nfs_write_inode, .write_inode = nfs_write_inode,
.delete_inode = nfs_delete_inode, .delete_inode = nfs_delete_inode,
.put_super = nfs_put_super,
.statfs = nfs_statfs, .statfs = nfs_statfs,
.clear_inode = nfs_clear_inode, .clear_inode = nfs_clear_inode,
.umount_begin = nfs_umount_begin, .umount_begin = nfs_umount_begin,
...@@ -151,27 +149,6 @@ nfs_clear_inode(struct inode *inode) ...@@ -151,27 +149,6 @@ nfs_clear_inode(struct inode *inode)
BUG_ON(atomic_read(&nfsi->data_updates) != 0); BUG_ON(atomic_read(&nfsi->data_updates) != 0);
} }
void
nfs_put_super(struct super_block *sb)
{
struct nfs_server *server = NFS_SB(sb);
nfs4_renewd_prepare_shutdown(server);
if (server->client != NULL)
rpc_shutdown_client(server->client);
if (server->client_sys != NULL)
rpc_shutdown_client(server->client_sys);
if (!(server->flags & NFS_MOUNT_NONLM))
lockd_down(); /* release rpc.lockd */
rpciod_down(); /* release rpciod */
destroy_nfsv4_state(server);
kfree(server->hostname);
}
void void
nfs_umount_begin(struct super_block *sb) nfs_umount_begin(struct super_block *sb)
{ {
...@@ -405,7 +382,6 @@ static int ...@@ -405,7 +382,6 @@ static int
nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent) nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent)
{ {
struct nfs_server *server; struct nfs_server *server;
int err = -EIO;
rpc_authflavor_t authflavor; rpc_authflavor_t authflavor;
server = NFS_SB(sb); server = NFS_SB(sb);
...@@ -424,10 +400,14 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent) ...@@ -424,10 +400,14 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent)
server->acdirmin = data->acdirmin*HZ; server->acdirmin = data->acdirmin*HZ;
server->acdirmax = data->acdirmax*HZ; server->acdirmax = data->acdirmax*HZ;
/* Start lockd here, before we might error out */
if (!(server->flags & NFS_MOUNT_NONLM))
lockd_up();
server->namelen = data->namlen; server->namelen = data->namlen;
server->hostname = kmalloc(strlen(data->hostname) + 1, GFP_KERNEL); server->hostname = kmalloc(strlen(data->hostname) + 1, GFP_KERNEL);
if (!server->hostname) if (!server->hostname)
goto out_fail; return -ENOMEM;
strcpy(server->hostname, data->hostname); strcpy(server->hostname, data->hostname);
/* Check NFS protocol revision and initialize RPC op vector /* Check NFS protocol revision and initialize RPC op vector
...@@ -438,11 +418,11 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent) ...@@ -438,11 +418,11 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent)
server->caps |= NFS_CAP_READDIRPLUS; server->caps |= NFS_CAP_READDIRPLUS;
if (data->version < 4) { if (data->version < 4) {
printk(KERN_NOTICE "NFS: NFSv3 not supported by mount program.\n"); printk(KERN_NOTICE "NFS: NFSv3 not supported by mount program.\n");
goto out_fail; return -EIO;
} }
#else #else
printk(KERN_NOTICE "NFS: NFSv3 not supported.\n"); printk(KERN_NOTICE "NFS: NFSv3 not supported.\n");
goto out_fail; return -EIO;
#endif #endif
} else { } else {
server->rpc_ops = &nfs_v2_clientops; server->rpc_ops = &nfs_v2_clientops;
...@@ -457,30 +437,19 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent) ...@@ -457,30 +437,19 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent)
/* Create RPC client handles */ /* Create RPC client handles */
server->client = nfs_create_client(server, data); server->client = nfs_create_client(server, data);
if (IS_ERR(server->client)) if (IS_ERR(server->client))
goto out_fail; return PTR_ERR(server->client);
/* RFC 2623, sec 2.3.2 */ /* RFC 2623, sec 2.3.2 */
if (authflavor != RPC_AUTH_UNIX) { if (authflavor != RPC_AUTH_UNIX) {
server->client_sys = rpc_clone_client(server->client); server->client_sys = rpc_clone_client(server->client);
if (server->client_sys == NULL) if (IS_ERR(server->client_sys))
goto out_shutdown; return PTR_ERR(server->client_sys);
if (!rpcauth_create(RPC_AUTH_UNIX, server->client_sys)) if (!rpcauth_create(RPC_AUTH_UNIX, server->client_sys))
goto out_shutdown; return -ENOMEM;
} else { } else {
atomic_inc(&server->client->cl_count); atomic_inc(&server->client->cl_count);
server->client_sys = server->client; server->client_sys = server->client;
} }
/* Fire up rpciod if not yet running */
if (rpciod_up() != 0) {
printk(KERN_WARNING "NFS: couldn't start rpciod!\n");
goto out_shutdown;
}
sb->s_op = &nfs_sops;
err = nfs_sb_init(sb, authflavor);
if (err != 0)
goto out_noinit;
if (server->flags & NFS_MOUNT_VER3) { if (server->flags & NFS_MOUNT_VER3) {
if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN) if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
server->namelen = NFS3_MAXNAMLEN; server->namelen = NFS3_MAXNAMLEN;
...@@ -489,21 +458,8 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent) ...@@ -489,21 +458,8 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent)
server->namelen = NFS2_MAXNAMLEN; server->namelen = NFS2_MAXNAMLEN;
} }
/* Check whether to start the lockd process */ sb->s_op = &nfs_sops;
if (!(server->flags & NFS_MOUNT_NONLM)) return nfs_sb_init(sb, authflavor);
lockd_up();
return 0;
out_noinit:
rpciod_down();
out_shutdown:
if (server->client)
rpc_shutdown_client(server->client);
if (server->client_sys)
rpc_shutdown_client(server->client_sys);
out_fail:
if (server->hostname)
kfree(server->hostname);
return err;
} }
static int static int
...@@ -1373,6 +1329,13 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type, ...@@ -1373,6 +1329,13 @@ static struct super_block *nfs_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");
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) {
up_write(&s->s_umount); up_write(&s->s_umount);
...@@ -1386,7 +1349,25 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type, ...@@ -1386,7 +1349,25 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
static void nfs_kill_super(struct super_block *s) static void nfs_kill_super(struct super_block *s)
{ {
struct nfs_server *server = NFS_SB(s); struct nfs_server *server = NFS_SB(s);
kill_anon_super(s); kill_anon_super(s);
nfs4_renewd_prepare_shutdown(server);
if (server->client != NULL && !IS_ERR(server->client))
rpc_shutdown_client(server->client);
if (server->client_sys != NULL && !IS_ERR(server->client_sys))
rpc_shutdown_client(server->client_sys);
if (!(server->flags & NFS_MOUNT_NONLM))
lockd_down(); /* release rpc.lockd */
rpciod_down(); /* release rpciod */
destroy_nfsv4_state(server);
if (server->hostname != NULL)
kfree(server->hostname);
kfree(server); kfree(server);
} }
...@@ -1407,7 +1388,6 @@ static struct super_operations nfs4_sops = { ...@@ -1407,7 +1388,6 @@ static struct super_operations nfs4_sops = {
.destroy_inode = nfs_destroy_inode, .destroy_inode = nfs_destroy_inode,
.write_inode = nfs_write_inode, .write_inode = nfs_write_inode,
.delete_inode = nfs_delete_inode, .delete_inode = nfs_delete_inode,
.put_super = nfs_put_super,
.statfs = nfs_statfs, .statfs = nfs_statfs,
.clear_inode = nfs4_clear_inode, .clear_inode = nfs4_clear_inode,
.umount_begin = nfs_umount_begin, .umount_begin = nfs_umount_begin,
...@@ -1498,7 +1478,7 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, ...@@ -1498,7 +1478,7 @@ 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"); printk(KERN_WARNING "NFS: failed to create NFS4 client.\n");
goto out_fail; return -EIO;
} }
/* Now create transport and client */ /* Now create transport and client */
...@@ -1547,45 +1527,29 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, ...@@ -1547,45 +1527,29 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
if (IS_ERR(clnt)) { if (IS_ERR(clnt)) {
printk(KERN_WARNING "NFS: cannot create RPC client.\n"); printk(KERN_WARNING "NFS: cannot create RPC client.\n");
err = PTR_ERR(clnt); return PTR_ERR(clnt);
goto out_remove_list;
} }
clnt->cl_intr = (server->flags & NFS4_MOUNT_INTR) ? 1 : 0; clnt->cl_intr = (server->flags & NFS4_MOUNT_INTR) ? 1 : 0;
clnt->cl_softrtry = (server->flags & NFS4_MOUNT_SOFT) ? 1 : 0; clnt->cl_softrtry = (server->flags & NFS4_MOUNT_SOFT) ? 1 : 0;
server->client = clnt; server->client = clnt;
err = -ENOMEM;
if (server->nfs4_state->cl_idmap == NULL) { if (server->nfs4_state->cl_idmap == NULL) {
printk(KERN_WARNING "NFS: failed to create idmapper.\n"); printk(KERN_WARNING "NFS: failed to create idmapper.\n");
goto out_shutdown; 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"); printk(KERN_WARNING "NFS: couldn't create credcache!\n");
goto out_shutdown; return -ENOMEM;
} }
} }
/* Fire up rpciod if not yet running */
if (rpciod_up() != 0) {
printk(KERN_WARNING "NFS: couldn't start rpciod!\n");
goto out_shutdown;
}
sb->s_op = &nfs4_sops; sb->s_op = &nfs4_sops;
err = nfs_sb_init(sb, authflavour); err = nfs_sb_init(sb, authflavour);
if (err == 0) if (err == 0)
return 0; return 0;
rpciod_down();
out_shutdown:
rpc_shutdown_client(server->client);
out_remove_list:
down_write(&server->nfs4_state->cl_sem);
list_del_init(&server->nfs4_siblings);
up_write(&server->nfs4_state->cl_sem);
destroy_nfsv4_state(server);
out_fail: out_fail:
if (clp) if (clp)
nfs4_put_client(clp); nfs4_put_client(clp);
...@@ -1691,6 +1655,13 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type, ...@@ -1691,6 +1655,13 @@ 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