From patchwork Fri Jan 14 13:49:14 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Kirill A. Shutemov" X-Patchwork-Id: 478431 X-Patchwork-Delegate: Trond.Myklebust@netapp.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p0EDoxGL018406 for ; Fri, 14 Jan 2011 13:51:06 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757638Ab1ANNuL (ORCPT ); Fri, 14 Jan 2011 08:50:11 -0500 Received: from shutemov.name ([188.40.19.243]:53374 "EHLO shutemov.name" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757571Ab1ANNtm (ORCPT ); Fri, 14 Jan 2011 08:49:42 -0500 Received: by shutemov.name (Postfix, from userid 500) id 0D1B9D4221; Fri, 14 Jan 2011 15:49:37 +0200 (EET) From: "Kirill A. Shutemov" To: Trond Myklebust , "J. Bruce Fields" , Neil Brown Cc: Pavel Emelyanov , linux-nfs@vger.kernel.org, "David S. Miller" , Rob Landley , Al Viro , containers@lists.linux-foundation.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, "Kirill A. Shutemov" Subject: [PATCH v3 16/16] Rework get_rpc_pipefs and introduce put_rpc_pipefs() Date: Fri, 14 Jan 2011 15:49:14 +0200 Message-Id: <1295012954-7769-17-git-send-email-kas@openvz.org> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <1295012954-7769-1-git-send-email-kas@openvz.org> References: <1295012954-7769-1-git-send-email-kas@openvz.org> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 14 Jan 2011 13:51:06 +0000 (UTC) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 8dd0e99..0b8ac12 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -838,7 +838,7 @@ static int nfs_init_server(struct nfs_server *server, /* Allocate or find a client reference we can use */ clp = nfs_get_client(&cl_init); - mntput(cl_init.rpcmount); + put_rpc_pipefs(cl_init.rpcmount); if (IS_ERR(clp)) { dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp)); return PTR_ERR(clp); @@ -1533,7 +1533,7 @@ static int nfs4_init_server(struct nfs_server *server, &timeparms, data->minorversion, rpcmount); - mntput(rpcmount); + put_rpc_pipefs(rpcmount); if (error < 0) goto error; diff --git a/fs/nfs/super.c b/fs/nfs/super.c index be4852b..148843e 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1668,7 +1668,7 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args, * to a file handle. */ status = nfs_mount(&request); - mntput(request.rpcmount); + put_rpc_pipefs(request.rpcmount); if (status != 0) { dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n", request.hostname, status); diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 61210b6..4d8383b 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -667,7 +667,7 @@ int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn) return PTR_ERR(args.rpcmount); /* Create RPC client */ client = rpc_create(&args); - mntput(args.rpcmount); + put_rpc_pipefs(args.rpcmount); if (IS_ERR(client)) { dprintk("NFSD: couldn't create callback client: %ld\n", PTR_ERR(client)); diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 7353420..cff49fc 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -227,7 +227,7 @@ static int nfsd_startup(unsigned short port, int nrservs) goto out_racache; } ret = lockd_up(rpcmount); - mntput(rpcmount); + put_rpc_pipefs(rpcmount); if (ret) goto out_racache; ret = nfs4_state_start(); @@ -346,7 +346,7 @@ int nfsd_create_serv(void) nfsd_serv = svc_create_pooled(&nfsd_program, rpcmount, nfsd_max_blksize, nfsd_last_thread, nfsd, THIS_MODULE); - mntput(rpcmount); + put_rpc_pipefs(rpcmount); if (nfsd_serv == NULL) return -ENOMEM; diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h index a0b9c46..328b3da 100644 --- a/include/linux/sunrpc/rpc_pipe_fs.h +++ b/include/linux/sunrpc/rpc_pipe_fs.h @@ -45,6 +45,7 @@ RPC_I(struct inode *inode) } extern struct vfsmount *get_rpc_pipefs(const char *path); +extern void put_rpc_pipefs(struct vfsmount *rpcmount); extern int rpc_pipefs_add_destroy_cb(struct super_block *sb, void (*destroy_cb)(void *data), void *data); diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 96973c0..82feacd 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -33,6 +33,7 @@ #include struct vfsmount *init_rpc_pipefs __read_mostly; +static int init_rpc_pipefs_count; static struct file_system_type rpc_pipe_fs_type; @@ -1005,22 +1006,35 @@ static int check_rpc_pipefs(struct vfsmount *mnt, void *arg) return 1; } -struct vfsmount *get_rpc_pipefs(const char *p) +static struct vfsmount *find_rpc_pipefs(void) { - int error; struct vfsmount *rpcmount = ERR_PTR(-EINVAL); - struct path path; + int err; - if (!p) { - iterate_mounts(check_rpc_pipefs, &rpcmount, - current->nsproxy->mnt_ns->root); + iterate_mounts(check_rpc_pipefs, &rpcmount, + current->nsproxy->mnt_ns->root); - if (IS_ERR(rpcmount) && (current->nsproxy->mnt_ns == - init_task.nsproxy->mnt_ns)) - return mntget(init_rpc_pipefs); + if (!IS_ERR(rpcmount)) + return rpcmount; + if (current->nsproxy->mnt_ns != init_task.nsproxy->mnt_ns) return rpcmount; - } + + err = simple_pin_fs(&rpc_pipe_fs_type, &init_rpc_pipefs, + &init_rpc_pipefs_count); + if (err) + return ERR_PTR(err); + return init_rpc_pipefs; +} + +struct vfsmount *get_rpc_pipefs(const char *p) +{ + int error; + struct vfsmount *rpcmount = ERR_PTR(-EINVAL); + struct path path; + + if (!p) + return find_rpc_pipefs(); error = kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path); if (error) @@ -1033,6 +1047,15 @@ struct vfsmount *get_rpc_pipefs(const char *p) } EXPORT_SYMBOL_GPL(get_rpc_pipefs); +void put_rpc_pipefs(struct vfsmount *rpcmount) +{ + if (rpcmount == init_rpc_pipefs) + simple_release_fs(&init_rpc_pipefs, &init_rpc_pipefs_count); + else + mntput(rpcmount); +} +EXPORT_SYMBOL_GPL(put_rpc_pipefs); + struct destroy_cb { struct list_head list; void (*callback)(void *data); @@ -1232,16 +1255,8 @@ int register_rpc_pipefs(void) if (err) goto destroy_cache; - init_rpc_pipefs = kern_mount(&rpc_pipe_fs_type); - if (IS_ERR(init_rpc_pipefs)) { - err = PTR_ERR(init_rpc_pipefs); - goto unregister_fs; - } - return 0; -unregister_fs: - unregister_filesystem(&rpc_pipe_fs_type); destroy_cache: kmem_cache_destroy(rpc_inode_cachep); return err;