aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p
diff options
context:
space:
mode:
authorM. Mohan Kumar <mohan@in.ibm.com>2010-09-27 02:52:13 -0400
committerEric Van Hensbergen <ericvh@gmail.com>2010-10-28 10:08:47 -0400
commit1d769cd192fc8c4097b1e2cd41fdee6ba3d1b2af (patch)
tree16fd71ff9178bbfe144a28a2e168c85fb541a11b /fs/9p
parenta099027c779068b834f335cfdc3f2bf10f531dd9 (diff)
9p: Implement TGETLOCK
Synopsis size[4] TGetlock tag[2] fid[4] getlock[n] size[4] RGetlock tag[2] getlock[n] Description TGetlock is used to test for the existence of byte range posix locks on a file identified by given fid. The reply contains getlock structure. If the lock could be placed it returns F_UNLCK in type field of getlock structure. Otherwise it returns the details of the conflicting locks in the getlock structure getlock structure: type[1] - Type of lock: F_RDLCK, F_WRLCK start[8] - Starting offset for lock length[8] - Number of bytes to check for the lock If length is 0, check for lock in all bytes starting at the location 'start' through to the end of file pid[4] - PID of the process that wants to take lock/owns the task in case of reply client[4] - Client id of the system that owns the process which has the conflicting lock Signed-off-by: M. Mohan Kumar <mohan@in.ibm.com> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com> Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
Diffstat (limited to 'fs/9p')
-rw-r--r--fs/9p/vfs_file.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 6f77abd23184..3a4352f23a98 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -211,6 +211,51 @@ out:
211 return res; 211 return res;
212} 212}
213 213
214static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
215{
216 struct p9_getlock glock;
217 struct p9_fid *fid;
218 int res = 0;
219
220 fid = filp->private_data;
221 BUG_ON(fid == NULL);
222
223 posix_test_lock(filp, fl);
224 /*
225 * if we have a conflicting lock locally, no need to validate
226 * with server
227 */
228 if (fl->fl_type != F_UNLCK)
229 return res;
230
231 /* convert posix lock to p9 tgetlock args */
232 memset(&glock, 0, sizeof(glock));
233 glock.type = fl->fl_type;
234 glock.start = fl->fl_start;
235 if (fl->fl_end == OFFSET_MAX)
236 glock.length = 0;
237 else
238 glock.length = fl->fl_end - fl->fl_start + 1;
239 glock.proc_id = fl->fl_pid;
240 glock.client_id = utsname()->nodename;
241
242 res = p9_client_getlock_dotl(fid, &glock);
243 if (res < 0)
244 return res;
245 if (glock.type != F_UNLCK) {
246 fl->fl_type = glock.type;
247 fl->fl_start = glock.start;
248 if (glock.length == 0)
249 fl->fl_end = OFFSET_MAX;
250 else
251 fl->fl_end = glock.start + glock.length - 1;
252 fl->fl_pid = glock.proc_id;
253 } else
254 fl->fl_type = F_UNLCK;
255
256 return res;
257}
258
214/** 259/**
215 * v9fs_file_lock_dotl - lock a file (or directory) 260 * v9fs_file_lock_dotl - lock a file (or directory)
216 * @filp: file to be locked 261 * @filp: file to be locked
@@ -238,6 +283,8 @@ static int v9fs_file_lock_dotl(struct file *filp, int cmd, struct file_lock *fl)
238 283
239 if (IS_SETLK(cmd) || IS_SETLKW(cmd)) 284 if (IS_SETLK(cmd) || IS_SETLKW(cmd))
240 ret = v9fs_file_do_lock(filp, cmd, fl); 285 ret = v9fs_file_do_lock(filp, cmd, fl);
286 else if (IS_GETLK(cmd))
287 ret = v9fs_file_getlock(filp, fl);
241 else 288 else
242 ret = -EINVAL; 289 ret = -EINVAL;
243out_err: 290out_err: