diff options
author | David Howells <dhowells@redhat.com> | 2018-10-20 00:57:58 +0100 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2018-10-24 00:41:08 +0100 |
commit | f58db83fd3325a305cf615f4ffb0e6f60745ed8a (patch) | |
tree | c7e94eeb615d960433a3e27795463342e9f0e2d5 /fs/afs/dir.c | |
parent | 12d8e95a911eb3921a1fecf1e4d913654f6f4fb5 (diff) |
afs: Get the target vnode in afs_rmdir() and get a callback on it
Get the target vnode in afs_rmdir() and validate it before we attempt the
deletion, The vnode pointer will be passed through to the delivery function
in a later patch so that the delivery function can mark it deleted.
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs/dir.c')
-rw-r--r-- | fs/afs/dir.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 8936731c59ff..f2dd48d4363f 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c @@ -1174,7 +1174,7 @@ static void afs_dir_remove_subdir(struct dentry *dentry) static int afs_rmdir(struct inode *dir, struct dentry *dentry) { struct afs_fs_cursor fc; - struct afs_vnode *dvnode = AFS_FS_I(dir); + struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode = NULL; struct key *key; u64 data_version = dvnode->status.data_version; int ret; @@ -1188,6 +1188,14 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry) goto error; } + /* Try to make sure we have a callback promise on the victim. */ + if (d_really_is_positive(dentry)) { + vnode = AFS_FS_I(d_inode(dentry)); + ret = afs_validate(vnode, key); + if (ret < 0) + goto error_key; + } + ret = -ERESTARTSYS; if (afs_begin_vnode_operation(&fc, dvnode, key)) { while (afs_select_fileserver(&fc)) { @@ -1206,6 +1214,7 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry) } } +error_key: key_put(key); error: return ret; |