diff options
-rw-r--r-- | fs/9p/vfs_inode.c | 48 | ||||
-rw-r--r-- | include/net/9p/9p.h | 2 | ||||
-rw-r--r-- | include/net/9p/client.h | 1 | ||||
-rw-r--r-- | net/9p/client.c | 23 |
4 files changed, 56 insertions, 18 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index bce66f56c62c..8bb5507e822f 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -534,38 +534,50 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, | |||
534 | /** | 534 | /** |
535 | * v9fs_remove - helper function to remove files and directories | 535 | * v9fs_remove - helper function to remove files and directories |
536 | * @dir: directory inode that is being deleted | 536 | * @dir: directory inode that is being deleted |
537 | * @file: dentry that is being deleted | 537 | * @dentry: dentry that is being deleted |
538 | * @rmdir: removing a directory | 538 | * @rmdir: removing a directory |
539 | * | 539 | * |
540 | */ | 540 | */ |
541 | 541 | ||
542 | static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) | 542 | static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags) |
543 | { | 543 | { |
544 | int retval; | 544 | struct inode *inode; |
545 | struct p9_fid *v9fid; | 545 | int retval = -EOPNOTSUPP; |
546 | struct inode *file_inode; | 546 | struct p9_fid *v9fid, *dfid; |
547 | 547 | struct v9fs_session_info *v9ses; | |
548 | P9_DPRINTK(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %d\n", dir, file, | ||
549 | rmdir); | ||
550 | 548 | ||
551 | file_inode = file->d_inode; | 549 | P9_DPRINTK(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %x\n", |
552 | v9fid = v9fs_fid_clone(file); | 550 | dir, dentry, flags); |
553 | if (IS_ERR(v9fid)) | ||
554 | return PTR_ERR(v9fid); | ||
555 | 551 | ||
556 | retval = p9_client_remove(v9fid); | 552 | v9ses = v9fs_inode2v9ses(dir); |
553 | inode = dentry->d_inode; | ||
554 | dfid = v9fs_fid_lookup(dentry->d_parent); | ||
555 | if (IS_ERR(dfid)) { | ||
556 | retval = PTR_ERR(dfid); | ||
557 | P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", retval); | ||
558 | return retval; | ||
559 | } | ||
560 | if (v9fs_proto_dotl(v9ses)) | ||
561 | retval = p9_client_unlinkat(dfid, dentry->d_name.name, flags); | ||
562 | if (retval == -EOPNOTSUPP) { | ||
563 | /* Try the one based on path */ | ||
564 | v9fid = v9fs_fid_clone(dentry); | ||
565 | if (IS_ERR(v9fid)) | ||
566 | return PTR_ERR(v9fid); | ||
567 | retval = p9_client_remove(v9fid); | ||
568 | } | ||
557 | if (!retval) { | 569 | if (!retval) { |
558 | /* | 570 | /* |
559 | * directories on unlink should have zero | 571 | * directories on unlink should have zero |
560 | * link count | 572 | * link count |
561 | */ | 573 | */ |
562 | if (rmdir) { | 574 | if (flags & AT_REMOVEDIR) { |
563 | clear_nlink(file_inode); | 575 | clear_nlink(inode); |
564 | drop_nlink(dir); | 576 | drop_nlink(dir); |
565 | } else | 577 | } else |
566 | drop_nlink(file_inode); | 578 | drop_nlink(inode); |
567 | 579 | ||
568 | v9fs_invalidate_inode_attr(file_inode); | 580 | v9fs_invalidate_inode_attr(inode); |
569 | v9fs_invalidate_inode_attr(dir); | 581 | v9fs_invalidate_inode_attr(dir); |
570 | } | 582 | } |
571 | return retval; | 583 | return retval; |
@@ -856,7 +868,7 @@ int v9fs_vfs_unlink(struct inode *i, struct dentry *d) | |||
856 | 868 | ||
857 | int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) | 869 | int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) |
858 | { | 870 | { |
859 | return v9fs_remove(i, d, 1); | 871 | return v9fs_remove(i, d, AT_REMOVEDIR); |
860 | } | 872 | } |
861 | 873 | ||
862 | /** | 874 | /** |
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h index 61156207c98c..342dcf13d039 100644 --- a/include/net/9p/9p.h +++ b/include/net/9p/9p.h | |||
@@ -183,6 +183,8 @@ enum p9_msg_t { | |||
183 | P9_RMKDIR, | 183 | P9_RMKDIR, |
184 | P9_TRENAMEAT = 74, | 184 | P9_TRENAMEAT = 74, |
185 | P9_RRENAMEAT, | 185 | P9_RRENAMEAT, |
186 | P9_TUNLINKAT = 76, | ||
187 | P9_RUNLINKAT, | ||
186 | P9_TVERSION = 100, | 188 | P9_TVERSION = 100, |
187 | P9_RVERSION, | 189 | P9_RVERSION, |
188 | P9_TAUTH = 102, | 190 | P9_TAUTH = 102, |
diff --git a/include/net/9p/client.h b/include/net/9p/client.h index 62ceddf9994a..55ce72ce9861 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h | |||
@@ -234,6 +234,7 @@ int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode, | |||
234 | int p9_client_clunk(struct p9_fid *fid); | 234 | int p9_client_clunk(struct p9_fid *fid); |
235 | int p9_client_fsync(struct p9_fid *fid, int datasync); | 235 | int p9_client_fsync(struct p9_fid *fid, int datasync); |
236 | int p9_client_remove(struct p9_fid *fid); | 236 | int p9_client_remove(struct p9_fid *fid); |
237 | int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags); | ||
237 | int p9_client_read(struct p9_fid *fid, char *data, char __user *udata, | 238 | int p9_client_read(struct p9_fid *fid, char *data, char __user *udata, |
238 | u64 offset, u32 count); | 239 | u64 offset, u32 count); |
239 | int p9_client_write(struct p9_fid *fid, char *data, const char __user *udata, | 240 | int p9_client_write(struct p9_fid *fid, char *data, const char __user *udata, |
diff --git a/net/9p/client.c b/net/9p/client.c index c4b77f383582..a953baa3624e 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -1303,6 +1303,29 @@ error: | |||
1303 | } | 1303 | } |
1304 | EXPORT_SYMBOL(p9_client_remove); | 1304 | EXPORT_SYMBOL(p9_client_remove); |
1305 | 1305 | ||
1306 | int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags) | ||
1307 | { | ||
1308 | int err = 0; | ||
1309 | struct p9_req_t *req; | ||
1310 | struct p9_client *clnt; | ||
1311 | |||
1312 | P9_DPRINTK(P9_DEBUG_9P, ">>> TUNLINKAT fid %d %s %d\n", | ||
1313 | dfid->fid, name, flags); | ||
1314 | |||
1315 | clnt = dfid->clnt; | ||
1316 | req = p9_client_rpc(clnt, P9_TUNLINKAT, "dsd", dfid->fid, name, flags); | ||
1317 | if (IS_ERR(req)) { | ||
1318 | err = PTR_ERR(req); | ||
1319 | goto error; | ||
1320 | } | ||
1321 | P9_DPRINTK(P9_DEBUG_9P, "<<< RUNLINKAT fid %d %s\n", dfid->fid, name); | ||
1322 | |||
1323 | p9_free_req(clnt, req); | ||
1324 | error: | ||
1325 | return err; | ||
1326 | } | ||
1327 | EXPORT_SYMBOL(p9_client_unlinkat); | ||
1328 | |||
1306 | int | 1329 | int |
1307 | p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, | 1330 | p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, |
1308 | u32 count) | 1331 | u32 count) |