Clean up the logic that handles recovery from a failed mount request. Get rid of nfs_put_super. Patch against 2.6.7-rc3. fs/nfs/inode.c | 126 +++++++++++++++++++------------------------------ 1 files changed, 50 insertions(+), 76 deletions(-) Signed-off-by: Chuck Lever Generated-at: Fri, 11 Jun 2004 17:15:30 -0400 diff -X /home/cel/src/linux/dont-diff -Naurp 01-blocksize/fs/nfs/inode.c 02-nfs_put_super/fs/nfs/inode.c --- 01-blocksize/fs/nfs/inode.c 2004-06-08 17:24:42.868800000 -0400 +++ 02-nfs_put_super/fs/nfs/inode.c 2004-06-08 17:26:09.151886000 -0400 @@ -57,7 +57,6 @@ static struct inode *nfs_alloc_inode(str static void nfs_destroy_inode(struct inode *); static void nfs_write_inode(struct inode *,int); 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_umount_begin(struct super_block *); static int nfs_statfs(struct super_block *, struct kstatfs *); @@ -68,7 +67,6 @@ static struct super_operations nfs_sops .destroy_inode = nfs_destroy_inode, .write_inode = nfs_write_inode, .delete_inode = nfs_delete_inode, - .put_super = nfs_put_super, .statfs = nfs_statfs, .clear_inode = nfs_clear_inode, .umount_begin = nfs_umount_begin, @@ -152,27 +150,6 @@ nfs_clear_inode(struct inode *inode) } 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 nfs_umount_begin(struct super_block *sb) { struct nfs_server *server = NFS_SB(sb); @@ -402,7 +379,7 @@ static int nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent) { struct nfs_server *server; - int err = -EIO; + int err = -ENOMEM; rpc_authflavor_t authflavor; server = NFS_SB(sb); @@ -421,25 +398,30 @@ nfs_fill_super(struct super_block *sb, s server->acdirmin = data->acdirmin*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->hostname = kmalloc(strlen(data->hostname) + 1, GFP_KERNEL); if (!server->hostname) - goto out_fail; + return err; strcpy(server->hostname, data->hostname); /* Check NFS protocol revision and initialize RPC op vector * and file handle pool. */ + err = -EIO; if (server->flags & NFS_MOUNT_VER3) { #ifdef CONFIG_NFS_V3 server->rpc_ops = &nfs_v3_clientops; server->caps |= NFS_CAP_READDIRPLUS; if (data->version < 4) { printk(KERN_NOTICE "NFS: NFSv3 not supported by mount program.\n"); - goto out_fail; + return err; } #else printk(KERN_NOTICE "NFS: NFSv3 not supported.\n"); - goto out_fail; + return err; #endif } else { server->rpc_ops = &nfs_v2_clientops; @@ -454,30 +436,19 @@ nfs_fill_super(struct super_block *sb, s /* Create RPC client handles */ server->client = nfs_create_client(server, data); if (server->client == NULL) - goto out_fail; + return err; /* RFC 2623, sec 2.3.2 */ if (authflavor != RPC_AUTH_UNIX) { server->client_sys = rpc_clone_client(server->client); if (server->client_sys == NULL) - goto out_shutdown; + return err; if (!rpcauth_create(RPC_AUTH_UNIX, server->client_sys)) - goto out_shutdown; + return err; } else { atomic_inc(&server->client->cl_count); 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->namelen == 0 || server->namelen > NFS3_MAXNAMLEN) server->namelen = NFS3_MAXNAMLEN; @@ -486,21 +457,8 @@ nfs_fill_super(struct super_block *sb, s server->namelen = NFS2_MAXNAMLEN; } - /* Check whether to start the lockd process */ - if (!(server->flags & NFS_MOUNT_NONLM)) - 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; + sb->s_op = &nfs_sops; + return nfs_sb_init(sb, authflavor); } static int @@ -1371,6 +1329,13 @@ static struct super_block *nfs_get_sb(st 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); if (error) { up_write(&s->s_umount); @@ -1384,7 +1349,25 @@ static struct super_block *nfs_get_sb(st static void nfs_kill_super(struct super_block *s) { struct nfs_server *server = NFS_SB(s); + kill_anon_super(s); + + nfs4_renewd_prepare_shutdown(server); + + if (server->client) + rpc_shutdown_client(server->client); + if (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) + kfree(server->hostname); kfree(server); } @@ -1405,7 +1388,6 @@ static struct super_operations nfs4_sops .destroy_inode = nfs_destroy_inode, .write_inode = nfs_write_inode, .delete_inode = nfs_delete_inode, - .put_super = nfs_put_super, .statfs = nfs_statfs, .clear_inode = nfs4_clear_inode, .umount_begin = nfs_umount_begin, @@ -1496,7 +1478,7 @@ static int nfs4_fill_super(struct super_ clp = nfs4_get_client(&server->addr.sin_addr); if (!clp) { printk(KERN_WARNING "NFS: failed to create NFS4 client.\n"); - goto out_fail; + return -EIO; } /* Now create transport and client */ @@ -1545,13 +1527,12 @@ static int nfs4_fill_super(struct super_ if (IS_ERR(clnt)) { printk(KERN_WARNING "NFS: cannot create RPC client.\n"); - err = PTR_ERR(clnt); - goto out_remove_list; + return PTR_ERR(clnt); } err = -ENOMEM; if (server->nfs4_state->cl_idmap == NULL) { printk(KERN_WARNING "NFS: failed to create idmapper.\n"); - goto out_shutdown; + return err; } clnt->cl_intr = (server->flags & NFS4_MOUNT_INTR) ? 1 : 0; @@ -1561,28 +1542,14 @@ static int nfs4_fill_super(struct super_ if (clnt->cl_auth->au_flavor != authflavour) { if (rpcauth_create(authflavour, clnt) == NULL) { printk(KERN_WARNING "NFS: couldn't create credcache!\n"); - goto out_shutdown; + return err; } } - /* 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; err = nfs_sb_init(sb, authflavour); if (err == 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: if (clp) nfs4_put_client(clp); @@ -1688,6 +1655,13 @@ static struct super_block *nfs4_get_sb(s 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); if (error) { up_write(&s->s_umount);