|
@@ -534,38 +534,50 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
|
|
/**
|
|
/**
|
|
* v9fs_remove - helper function to remove files and directories
|
|
* v9fs_remove - helper function to remove files and directories
|
|
* @dir: directory inode that is being deleted
|
|
* @dir: directory inode that is being deleted
|
|
- * @file: dentry that is being deleted
|
|
|
|
|
|
+ * @dentry: dentry that is being deleted
|
|
* @rmdir: removing a directory
|
|
* @rmdir: removing a directory
|
|
*
|
|
*
|
|
*/
|
|
*/
|
|
|
|
|
|
-static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir)
|
|
|
|
|
|
+static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags)
|
|
{
|
|
{
|
|
- int retval;
|
|
|
|
- struct p9_fid *v9fid;
|
|
|
|
- struct inode *file_inode;
|
|
|
|
-
|
|
|
|
- P9_DPRINTK(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %d\n", dir, file,
|
|
|
|
- rmdir);
|
|
|
|
|
|
+ struct inode *inode;
|
|
|
|
+ int retval = -EOPNOTSUPP;
|
|
|
|
+ struct p9_fid *v9fid, *dfid;
|
|
|
|
+ struct v9fs_session_info *v9ses;
|
|
|
|
|
|
- file_inode = file->d_inode;
|
|
|
|
- v9fid = v9fs_fid_clone(file);
|
|
|
|
- if (IS_ERR(v9fid))
|
|
|
|
- return PTR_ERR(v9fid);
|
|
|
|
|
|
+ P9_DPRINTK(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %x\n",
|
|
|
|
+ dir, dentry, flags);
|
|
|
|
|
|
- retval = p9_client_remove(v9fid);
|
|
|
|
|
|
+ v9ses = v9fs_inode2v9ses(dir);
|
|
|
|
+ inode = dentry->d_inode;
|
|
|
|
+ dfid = v9fs_fid_lookup(dentry->d_parent);
|
|
|
|
+ if (IS_ERR(dfid)) {
|
|
|
|
+ retval = PTR_ERR(dfid);
|
|
|
|
+ P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", retval);
|
|
|
|
+ return retval;
|
|
|
|
+ }
|
|
|
|
+ if (v9fs_proto_dotl(v9ses))
|
|
|
|
+ retval = p9_client_unlinkat(dfid, dentry->d_name.name, flags);
|
|
|
|
+ if (retval == -EOPNOTSUPP) {
|
|
|
|
+ /* Try the one based on path */
|
|
|
|
+ v9fid = v9fs_fid_clone(dentry);
|
|
|
|
+ if (IS_ERR(v9fid))
|
|
|
|
+ return PTR_ERR(v9fid);
|
|
|
|
+ retval = p9_client_remove(v9fid);
|
|
|
|
+ }
|
|
if (!retval) {
|
|
if (!retval) {
|
|
/*
|
|
/*
|
|
* directories on unlink should have zero
|
|
* directories on unlink should have zero
|
|
* link count
|
|
* link count
|
|
*/
|
|
*/
|
|
- if (rmdir) {
|
|
|
|
- clear_nlink(file_inode);
|
|
|
|
|
|
+ if (flags & AT_REMOVEDIR) {
|
|
|
|
+ clear_nlink(inode);
|
|
drop_nlink(dir);
|
|
drop_nlink(dir);
|
|
} else
|
|
} else
|
|
- drop_nlink(file_inode);
|
|
|
|
|
|
+ drop_nlink(inode);
|
|
|
|
|
|
- v9fs_invalidate_inode_attr(file_inode);
|
|
|
|
|
|
+ v9fs_invalidate_inode_attr(inode);
|
|
v9fs_invalidate_inode_attr(dir);
|
|
v9fs_invalidate_inode_attr(dir);
|
|
}
|
|
}
|
|
return retval;
|
|
return retval;
|
|
@@ -856,7 +868,7 @@ int v9fs_vfs_unlink(struct inode *i, struct dentry *d)
|
|
|
|
|
|
int v9fs_vfs_rmdir(struct inode *i, struct dentry *d)
|
|
int v9fs_vfs_rmdir(struct inode *i, struct dentry *d)
|
|
{
|
|
{
|
|
- return v9fs_remove(i, d, 1);
|
|
|
|
|
|
+ return v9fs_remove(i, d, AT_REMOVEDIR);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|