aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/rpc_pipe.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/rpc_pipe.c')
-rw-r--r--net/sunrpc/rpc_pipe.c42
1 files changed, 29 insertions, 13 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 23a2b8f6dc49..192453248870 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -113,7 +113,7 @@ out:
113 wake_up(&rpci->waitq); 113 wake_up(&rpci->waitq);
114 return res; 114 return res;
115} 115}
116EXPORT_SYMBOL(rpc_queue_upcall); 116EXPORT_SYMBOL_GPL(rpc_queue_upcall);
117 117
118static inline void 118static inline void
119rpc_inode_setowner(struct inode *inode, void *private) 119rpc_inode_setowner(struct inode *inode, void *private)
@@ -126,13 +126,14 @@ rpc_close_pipes(struct inode *inode)
126{ 126{
127 struct rpc_inode *rpci = RPC_I(inode); 127 struct rpc_inode *rpci = RPC_I(inode);
128 struct rpc_pipe_ops *ops; 128 struct rpc_pipe_ops *ops;
129 int need_release;
129 130
130 mutex_lock(&inode->i_mutex); 131 mutex_lock(&inode->i_mutex);
131 ops = rpci->ops; 132 ops = rpci->ops;
132 if (ops != NULL) { 133 if (ops != NULL) {
133 LIST_HEAD(free_list); 134 LIST_HEAD(free_list);
134
135 spin_lock(&inode->i_lock); 135 spin_lock(&inode->i_lock);
136 need_release = rpci->nreaders != 0 || rpci->nwriters != 0;
136 rpci->nreaders = 0; 137 rpci->nreaders = 0;
137 list_splice_init(&rpci->in_upcall, &free_list); 138 list_splice_init(&rpci->in_upcall, &free_list);
138 list_splice_init(&rpci->pipe, &free_list); 139 list_splice_init(&rpci->pipe, &free_list);
@@ -141,7 +142,7 @@ rpc_close_pipes(struct inode *inode)
141 spin_unlock(&inode->i_lock); 142 spin_unlock(&inode->i_lock);
142 rpc_purge_list(rpci, &free_list, ops->destroy_msg, -EPIPE); 143 rpc_purge_list(rpci, &free_list, ops->destroy_msg, -EPIPE);
143 rpci->nwriters = 0; 144 rpci->nwriters = 0;
144 if (ops->release_pipe) 145 if (need_release && ops->release_pipe)
145 ops->release_pipe(inode); 146 ops->release_pipe(inode);
146 cancel_delayed_work_sync(&rpci->queue_timeout); 147 cancel_delayed_work_sync(&rpci->queue_timeout);
147 } 148 }
@@ -169,16 +170,24 @@ static int
169rpc_pipe_open(struct inode *inode, struct file *filp) 170rpc_pipe_open(struct inode *inode, struct file *filp)
170{ 171{
171 struct rpc_inode *rpci = RPC_I(inode); 172 struct rpc_inode *rpci = RPC_I(inode);
173 int first_open;
172 int res = -ENXIO; 174 int res = -ENXIO;
173 175
174 mutex_lock(&inode->i_mutex); 176 mutex_lock(&inode->i_mutex);
175 if (rpci->ops != NULL) { 177 if (rpci->ops == NULL)
176 if (filp->f_mode & FMODE_READ) 178 goto out;
177 rpci->nreaders ++; 179 first_open = rpci->nreaders == 0 && rpci->nwriters == 0;
178 if (filp->f_mode & FMODE_WRITE) 180 if (first_open && rpci->ops->open_pipe) {
179 rpci->nwriters ++; 181 res = rpci->ops->open_pipe(inode);
180 res = 0; 182 if (res)
183 goto out;
181 } 184 }
185 if (filp->f_mode & FMODE_READ)
186 rpci->nreaders++;
187 if (filp->f_mode & FMODE_WRITE)
188 rpci->nwriters++;
189 res = 0;
190out:
182 mutex_unlock(&inode->i_mutex); 191 mutex_unlock(&inode->i_mutex);
183 return res; 192 return res;
184} 193}
@@ -188,6 +197,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp)
188{ 197{
189 struct rpc_inode *rpci = RPC_I(inode); 198 struct rpc_inode *rpci = RPC_I(inode);
190 struct rpc_pipe_msg *msg; 199 struct rpc_pipe_msg *msg;
200 int last_close;
191 201
192 mutex_lock(&inode->i_mutex); 202 mutex_lock(&inode->i_mutex);
193 if (rpci->ops == NULL) 203 if (rpci->ops == NULL)
@@ -214,7 +224,8 @@ rpc_pipe_release(struct inode *inode, struct file *filp)
214 rpci->ops->destroy_msg, -EAGAIN); 224 rpci->ops->destroy_msg, -EAGAIN);
215 } 225 }
216 } 226 }
217 if (rpci->ops->release_pipe) 227 last_close = rpci->nwriters == 0 && rpci->nreaders == 0;
228 if (last_close && rpci->ops->release_pipe)
218 rpci->ops->release_pipe(inode); 229 rpci->ops->release_pipe(inode);
219out: 230out:
220 mutex_unlock(&inode->i_mutex); 231 mutex_unlock(&inode->i_mutex);
@@ -396,6 +407,7 @@ enum {
396 RPCAUTH_nfs, 407 RPCAUTH_nfs,
397 RPCAUTH_portmap, 408 RPCAUTH_portmap,
398 RPCAUTH_statd, 409 RPCAUTH_statd,
410 RPCAUTH_nfsd4_cb,
399 RPCAUTH_RootEOF 411 RPCAUTH_RootEOF
400}; 412};
401 413
@@ -429,6 +441,10 @@ static struct rpc_filelist files[] = {
429 .name = "statd", 441 .name = "statd",
430 .mode = S_IFDIR | S_IRUGO | S_IXUGO, 442 .mode = S_IFDIR | S_IRUGO | S_IXUGO,
431 }, 443 },
444 [RPCAUTH_nfsd4_cb] = {
445 .name = "nfsd4_cb",
446 .mode = S_IFDIR | S_IRUGO | S_IXUGO,
447 },
432}; 448};
433 449
434enum { 450enum {
@@ -748,7 +764,7 @@ rpc_rmdir(struct dentry *dentry)
748 * @name: name of pipe 764 * @name: name of pipe
749 * @private: private data to associate with the pipe, for the caller's use 765 * @private: private data to associate with the pipe, for the caller's use
750 * @ops: operations defining the behavior of the pipe: upcall, downcall, 766 * @ops: operations defining the behavior of the pipe: upcall, downcall,
751 * release_pipe, and destroy_msg. 767 * release_pipe, open_pipe, and destroy_msg.
752 * @flags: rpc_inode flags 768 * @flags: rpc_inode flags
753 * 769 *
754 * Data is made available for userspace to read by calls to 770 * Data is made available for userspace to read by calls to
@@ -808,7 +824,7 @@ err_dput:
808 -ENOMEM); 824 -ENOMEM);
809 goto out; 825 goto out;
810} 826}
811EXPORT_SYMBOL(rpc_mkpipe); 827EXPORT_SYMBOL_GPL(rpc_mkpipe);
812 828
813/** 829/**
814 * rpc_unlink - remove a pipe 830 * rpc_unlink - remove a pipe
@@ -839,7 +855,7 @@ rpc_unlink(struct dentry *dentry)
839 dput(parent); 855 dput(parent);
840 return error; 856 return error;
841} 857}
842EXPORT_SYMBOL(rpc_unlink); 858EXPORT_SYMBOL_GPL(rpc_unlink);
843 859
844/* 860/*
845 * populate the filesystem 861 * populate the filesystem