diff options
author | M. Mohan Kumar <mohan@in.ibm.com> | 2010-09-27 02:52:13 -0400 |
---|---|---|
committer | Eric Van Hensbergen <ericvh@gmail.com> | 2010-10-28 10:08:47 -0400 |
commit | 1d769cd192fc8c4097b1e2cd41fdee6ba3d1b2af (patch) | |
tree | 16fd71ff9178bbfe144a28a2e168c85fb541a11b /fs/9p/vfs_file.c | |
parent | a099027c779068b834f335cfdc3f2bf10f531dd9 (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/vfs_file.c')
-rw-r--r-- | fs/9p/vfs_file.c | 47 |
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 | ||
214 | static 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; |
243 | out_err: | 290 | out_err: |