SUNRPC: Add a field to track the number of kernel users of an rpc_pipe
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Fri, 8 Jun 2007 18:14:53 +0000 (14:14 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Wed, 11 Jul 2007 03:40:33 +0000 (23:40 -0400)
This allows us to correctly deduce when we need to remove the pipe.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
include/linux/sunrpc/rpc_pipe_fs.h
net/sunrpc/rpc_pipe.c

index 430cea104817003fc0d3c445fd21f9723a92a816..51b977a4ca203eee00cb7b44f769a29c710064d5 100644 (file)
@@ -27,6 +27,7 @@ struct rpc_inode {
        int pipelen;
        int nreaders;
        int nwriters;
+       int nkern_readwriters;
        wait_queue_head_t waitq;
 #define RPC_PIPE_WAIT_FOR_OPEN 1
        int flags;
index e5fd796e897eb6e8c3a45e597b8b495bca7a7e79..e787b6a43eeeaccaeec0f9c73cb21c230b4d4826 100644 (file)
@@ -737,6 +737,7 @@ rpc_mkpipe(struct dentry *parent, const char *name, void *private, struct rpc_pi
                        dput (dentry);
                        dentry = ERR_PTR(-EBUSY);
                }
+               rpci->nkern_readwriters++;
                goto out;
        }
        inode = rpc_get_inode(dir->i_sb, S_IFIFO | S_IRUSR | S_IWUSR);
@@ -749,6 +750,7 @@ rpc_mkpipe(struct dentry *parent, const char *name, void *private, struct rpc_pi
        rpci->private = private;
        rpci->flags = flags;
        rpci->ops = ops;
+       rpci->nkern_readwriters = 1;
        inode_dir_notify(dir, DN_CREATE);
        dget(dentry);
 out:
@@ -773,10 +775,12 @@ rpc_unlink(struct dentry *dentry)
        parent = dget_parent(dentry);
        dir = parent->d_inode;
        mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
-       rpc_close_pipes(dentry->d_inode);
-       error = simple_unlink(dir, dentry);
-       if (!error)
-               d_delete(dentry);
+       if (--RPC_I(dentry->d_inode)->nkern_readwriters == 0) {
+               rpc_close_pipes(dentry->d_inode);
+               error = simple_unlink(dir, dentry);
+               if (!error)
+                       d_delete(dentry);
+       }
        dput(dentry);
        mutex_unlock(&dir->i_mutex);
        dput(parent);