]> git.hungrycats.org Git - linux/commitdiff
[PATCH] further rpc_pipefs cleanups...
authorTrond Myklebust <trond.myklebust@fys.uio.no>
Thu, 13 Feb 2003 10:26:15 +0000 (02:26 -0800)
committerTrond Myklebust <trond.myklebust@fys.uio.no>
Thu, 13 Feb 2003 10:26:15 +0000 (02:26 -0800)
 - Only set up pipefs entries for those RPC services that actually
   need them (for the moment NFS only). Portmap, lockd,... shouldn't
   need to make upcalls.

 - Add in missing semaphore in rpc_populate().

 - Make inode/dentry variable names in rpc_depopulate/rpc_populate
   more consistent w.r.t other functions in rpc_pipe.c

 - Call shrink_dcache_parent() in order to clean up child entries
   before we rmdir().

fs/nfs/inode.c
include/linux/sunrpc/clnt.h
net/sunrpc/clnt.c
net/sunrpc/rpc_pipe.c

index 78d1f895740fcb9c82740cabd47b85fea24ab59c..ea39aa340908e451ad0d07c3a9b7d17b6eb9b75f 100644 (file)
@@ -93,6 +93,7 @@ struct rpc_program            nfs_program = {
        .nrvers                 = sizeof(nfs_version) / sizeof(nfs_version[0]),
        .version                = nfs_version,
        .stats                  = &nfs_rpcstat,
+       .pipe_dir_name          = "/nfs",
 };
 
 static inline unsigned long
index 26a73231ad16a78b24c79dd81dceb3a050489513..99d57fec03a9535b8742310633ff101ff33a15e9 100644 (file)
@@ -79,6 +79,7 @@ struct rpc_program {
        unsigned int            nrvers;         /* number of versions */
        struct rpc_version **   version;        /* version array */
        struct rpc_stat *       stats;          /* statistics */
+       char *                  pipe_dir_name;  /* path to rpc_pipefs dir */
 };
 
 struct rpc_version {
index f0da5234b1099a592e831041b1babce0eec6bdc1..d57c24e010a68008b641d4f7746f8a954e092726 100644 (file)
@@ -63,6 +63,32 @@ static u32 * call_header(struct rpc_task *task);
 static u32 *   call_verify(struct rpc_task *task);
 
 
+static int
+rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name)
+{
+       static uint32_t clntid;
+       int maxlen = sizeof(clnt->cl_pathname);
+       int error;
+
+       if (dir_name == NULL)
+               return 0;
+       for (;;) {
+               snprintf(clnt->cl_pathname, sizeof(clnt->cl_pathname),
+                               "%s/clnt%x", dir_name,
+                               (unsigned int)clntid++);
+               clnt->cl_pathname[sizeof(clnt->cl_pathname) - 1] = '\0';
+               clnt->cl_dentry = rpc_mkdir(clnt->cl_pathname, clnt);
+               if (!IS_ERR(clnt->cl_dentry))
+                       return 0;
+               error = PTR_ERR(clnt->cl_dentry);
+               if (error != -EEXIST) {
+                       printk(KERN_INFO "RPC: Couldn't create pipefs entry %s, error %d\n",
+                                       clnt->cl_pathname, error);
+                       return error;
+               }
+       }
+}
+
 /*
  * Create an RPC client
  * FIXME: This should also take a flags argument (as in task->tk_flags).
@@ -109,14 +135,9 @@ rpc_create_client(struct rpc_xprt *xprt, char *servname,
 
        rpc_init_rtt(&clnt->cl_rtt, xprt->timeout.to_initval);
 
-       snprintf(clnt->cl_pathname, sizeof(clnt->cl_pathname),
-                       "/%s/clnt%p", clnt->cl_protname, clnt);
-       clnt->cl_dentry = rpc_mkdir(clnt->cl_pathname, clnt);
-       if (IS_ERR(clnt->cl_dentry)) {
-               printk(KERN_INFO "RPC: Couldn't create pipefs entry %s\n",
-                               clnt->cl_pathname);
+       if (rpc_setup_pipedir(clnt, program->pipe_dir_name) < 0)
                goto out_no_path;
-       }
+
        if (!rpcauth_create(flavor, clnt)) {
                printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n",
                                flavor);
index f46ddb41c49f9cbeaf522a3dd1fe5d1714af2363..b014047650a9c4fd2195794ae9752bae30d60a31 100644 (file)
@@ -476,15 +476,16 @@ rpc_get_inode(struct super_block *sb, int mode)
  * FIXME: This probably has races.
  */
 static void
-rpc_depopulate(struct dentry *dir)
+rpc_depopulate(struct dentry *parent)
 {
+       struct inode *dir = parent->d_inode;
        LIST_HEAD(head);
        struct list_head *pos, *next;
        struct dentry *dentry;
 
-       down(&dir->d_inode->i_sem);
+       down(&dir->i_sem);
        spin_lock(&dcache_lock);
-       list_for_each_safe(pos, next, &dir->d_subdirs) {
+       list_for_each_safe(pos, next, &parent->d_subdirs) {
                dentry = list_entry(pos, struct dentry, d_child);
                if (!d_unhashed(dentry)) {
                        dget_locked(dentry);
@@ -499,32 +500,34 @@ rpc_depopulate(struct dentry *dir)
                __d_drop(dentry);
                if (dentry->d_inode) {
                        rpc_inode_setowner(dentry->d_inode, NULL);
-                       simple_unlink(dir->d_inode, dentry);
+                       simple_unlink(dir, dentry);
                }
                dput(dentry);
        }
-       up(&dir->d_inode->i_sem);
+       up(&dir->i_sem);
 }
 
 static int
-rpc_populate(struct dentry *dir,
+rpc_populate(struct dentry *parent,
                struct rpc_filelist *files,
                int start, int eof)
 {
-       void *private = RPC_I(dir->d_inode)->private;
+       struct inode *inode, *dir = parent->d_inode;
+       void *private = RPC_I(dir)->private;
        struct qstr name;
        struct dentry *dentry;
-       struct inode *inode;
        int mode, i;
+
+       down(&dir->i_sem);
        for (i = start; i < eof; i++) {
                name.name = files[i].name;
                name.len = strlen(name.name);
                name.hash = full_name_hash(name.name, name.len);
-               dentry = d_alloc(dir, &name);
+               dentry = d_alloc(parent, &name);
                if (!dentry)
                        goto out_bad;
                mode = files[i].mode;
-               inode = rpc_get_inode(dir->d_inode->i_sb, mode);
+               inode = rpc_get_inode(dir->i_sb, mode);
                if (!inode) {
                        dput(dentry);
                        goto out_bad;
@@ -535,13 +538,15 @@ rpc_populate(struct dentry *dir,
                if (private)
                        rpc_inode_setowner(inode, private);
                if (S_ISDIR(mode))
-                       dir->d_inode->i_nlink++;
+                       dir->i_nlink++;
                d_add(dentry, inode);
        }
+       up(&dir->i_sem);
        return 0;
 out_bad:
+       up(&dir->i_sem);
        printk(KERN_WARNING "%s: %s failed to populate directory %s\n",
-                       __FILE__, __FUNCTION__, dir->d_name.name);
+                       __FILE__, __FUNCTION__, parent->d_name.name);
        return -ENOMEM;
 }
 
@@ -570,6 +575,7 @@ __rpc_rmdir(struct inode *dir, struct dentry *dentry)
 {
        int error;
 
+       shrink_dcache_parent(dentry);
        rpc_inode_setowner(dentry->d_inode, NULL);
        if ((error = simple_rmdir(dir, dentry)) != 0)
                return error;