diff options
-rw-r--r-- | fs/9p/vfs_file.c | 47 | ||||
-rw-r--r-- | include/net/9p/9p.h | 18 | ||||
-rw-r--r-- | include/net/9p/client.h | 1 | ||||
-rw-r--r-- | net/9p/client.c | 34 |
4 files changed, 100 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: |
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h index 1859a2560cc5..6367a71d84fc 100644 --- a/include/net/9p/9p.h +++ b/include/net/9p/9p.h | |||
@@ -167,6 +167,8 @@ enum p9_msg_t { | |||
167 | P9_RFSYNC, | 167 | P9_RFSYNC, |
168 | P9_TLOCK = 52, | 168 | P9_TLOCK = 52, |
169 | P9_RLOCK, | 169 | P9_RLOCK, |
170 | P9_TGETLOCK = 54, | ||
171 | P9_RGETLOCK, | ||
170 | P9_TLINK = 70, | 172 | P9_TLINK = 70, |
171 | P9_RLINK, | 173 | P9_RLINK, |
172 | P9_TMKDIR = 72, | 174 | P9_TMKDIR = 72, |
@@ -492,6 +494,22 @@ struct p9_flock { | |||
492 | char *client_id; | 494 | char *client_id; |
493 | }; | 495 | }; |
494 | 496 | ||
497 | /* struct p9_getlock: getlock structure | ||
498 | * @type - type of lock | ||
499 | * @start - starting offset of the lock | ||
500 | * @length - number of bytes | ||
501 | * @proc_id - process id which wants to take lock | ||
502 | * @client_id - client id | ||
503 | */ | ||
504 | |||
505 | struct p9_getlock { | ||
506 | u8 type; | ||
507 | u64 start; | ||
508 | u64 length; | ||
509 | u32 proc_id; | ||
510 | char *client_id; | ||
511 | }; | ||
512 | |||
495 | /* Structures for Protocol Operations */ | 513 | /* Structures for Protocol Operations */ |
496 | struct p9_tstatfs { | 514 | struct p9_tstatfs { |
497 | u32 fid; | 515 | u32 fid; |
diff --git a/include/net/9p/client.h b/include/net/9p/client.h index d7dcb142e3bb..127c9f2a9cb8 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h | |||
@@ -250,6 +250,7 @@ int p9_client_mknod_dotl(struct p9_fid *oldfid, char *name, int mode, | |||
250 | int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode, | 250 | int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode, |
251 | gid_t gid, struct p9_qid *); | 251 | gid_t gid, struct p9_qid *); |
252 | int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status); | 252 | int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status); |
253 | int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *fl); | ||
253 | struct p9_req_t *p9_tag_lookup(struct p9_client *, u16); | 254 | struct p9_req_t *p9_tag_lookup(struct p9_client *, u16); |
254 | void p9_client_cb(struct p9_client *c, struct p9_req_t *req); | 255 | void p9_client_cb(struct p9_client *c, struct p9_req_t *req); |
255 | 256 | ||
diff --git a/net/9p/client.c b/net/9p/client.c index fbd2b195801c..fc1b0579016a 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -1836,3 +1836,37 @@ error: | |||
1836 | 1836 | ||
1837 | } | 1837 | } |
1838 | EXPORT_SYMBOL(p9_client_lock_dotl); | 1838 | EXPORT_SYMBOL(p9_client_lock_dotl); |
1839 | |||
1840 | int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *glock) | ||
1841 | { | ||
1842 | int err; | ||
1843 | struct p9_client *clnt; | ||
1844 | struct p9_req_t *req; | ||
1845 | |||
1846 | err = 0; | ||
1847 | clnt = fid->clnt; | ||
1848 | P9_DPRINTK(P9_DEBUG_9P, ">>> TGETLOCK fid %d, type %i start %lld " | ||
1849 | "length %lld proc_id %d client_id %s\n", fid->fid, glock->type, | ||
1850 | glock->start, glock->length, glock->proc_id, glock->client_id); | ||
1851 | |||
1852 | req = p9_client_rpc(clnt, P9_TGETLOCK, "dbqqds", fid->fid, glock->type, | ||
1853 | glock->start, glock->length, glock->proc_id, glock->client_id); | ||
1854 | |||
1855 | if (IS_ERR(req)) | ||
1856 | return PTR_ERR(req); | ||
1857 | |||
1858 | err = p9pdu_readf(req->rc, clnt->proto_version, "bqqds", &glock->type, | ||
1859 | &glock->start, &glock->length, &glock->proc_id, | ||
1860 | &glock->client_id); | ||
1861 | if (err) { | ||
1862 | p9pdu_dump(1, req->rc); | ||
1863 | goto error; | ||
1864 | } | ||
1865 | P9_DPRINTK(P9_DEBUG_9P, "<<< RGETLOCK type %i start %lld length %lld " | ||
1866 | "proc_id %d client_id %s\n", glock->type, glock->start, | ||
1867 | glock->length, glock->proc_id, glock->client_id); | ||
1868 | error: | ||
1869 | p9_free_req(clnt, req); | ||
1870 | return err; | ||
1871 | } | ||
1872 | EXPORT_SYMBOL(p9_client_getlock_dotl); | ||