summaryrefslogtreecommitdiffstats
path: root/fs/afs/dir.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2017-11-20 18:04:08 -0500
committerDavid Howells <dhowells@redhat.com>2017-11-24 05:56:51 -0500
commitbc1527dcb422ead9e1808def6824b4c0e469cc1c (patch)
tree75a8f9bfccc94685d6822235a9296bae3360c3a4 /fs/afs/dir.c
parent5a039c32271b9aaa1103e9b64412f520e72b67d3 (diff)
afs: Fix some dentry handling in dir ops and missing key_puts
Fix some of dentry handling in AFS directory ops: (1) Do d_drop() on the new_dentry before assigning a new inode to it in afs_vnode_new_inode(). It's fine to do this before calling afs_iget() because the operation has taken place on the server. (2) Replace d_instantiate()/d_rehash() with d_add(). (3) Don't d_drop() the new_dentry in afs_rename() on error. Also fix afs_link() and afs_rename() to call key_put() on all error paths where the key is taken. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs/dir.c')
-rw-r--r--fs/afs/dir.c15
1 files changed, 5 insertions, 10 deletions
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index ab618d32554c..bb89876fbb8e 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -765,6 +765,8 @@ static void afs_vnode_new_inode(struct afs_fs_cursor *fc,
765 if (fc->ac.error < 0) 765 if (fc->ac.error < 0)
766 return; 766 return;
767 767
768 d_drop(new_dentry);
769
768 inode = afs_iget(fc->vnode->vfs_inode.i_sb, fc->key, 770 inode = afs_iget(fc->vnode->vfs_inode.i_sb, fc->key,
769 newfid, newstatus, newcb, fc->cbi); 771 newfid, newstatus, newcb, fc->cbi);
770 if (IS_ERR(inode)) { 772 if (IS_ERR(inode)) {
@@ -775,9 +777,7 @@ static void afs_vnode_new_inode(struct afs_fs_cursor *fc,
775 return; 777 return;
776 } 778 }
777 779
778 d_instantiate(new_dentry, inode); 780 d_add(new_dentry, inode);
779 if (d_unhashed(new_dentry))
780 d_rehash(new_dentry);
781} 781}
782 782
783/* 783/*
@@ -1053,7 +1053,7 @@ static int afs_link(struct dentry *from, struct inode *dir,
1053 if (afs_begin_vnode_operation(&fc, dvnode, key)) { 1053 if (afs_begin_vnode_operation(&fc, dvnode, key)) {
1054 if (mutex_lock_interruptible_nested(&vnode->io_lock, 1) < 0) { 1054 if (mutex_lock_interruptible_nested(&vnode->io_lock, 1) < 0) {
1055 afs_end_vnode_operation(&fc); 1055 afs_end_vnode_operation(&fc);
1056 return -ERESTARTSYS; 1056 goto error_key;
1057 } 1057 }
1058 1058
1059 while (afs_select_fileserver(&fc)) { 1059 while (afs_select_fileserver(&fc)) {
@@ -1180,7 +1180,7 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
1180 if (orig_dvnode != new_dvnode) { 1180 if (orig_dvnode != new_dvnode) {
1181 if (mutex_lock_interruptible_nested(&new_dvnode->io_lock, 1) < 0) { 1181 if (mutex_lock_interruptible_nested(&new_dvnode->io_lock, 1) < 0) {
1182 afs_end_vnode_operation(&fc); 1182 afs_end_vnode_operation(&fc);
1183 return -ERESTARTSYS; 1183 goto error_key;
1184 } 1184 }
1185 } 1185 }
1186 while (afs_select_fileserver(&fc)) { 1186 while (afs_select_fileserver(&fc)) {
@@ -1199,14 +1199,9 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
1199 goto error_key; 1199 goto error_key;
1200 } 1200 }
1201 1201
1202 key_put(key);
1203 _leave(" = 0");
1204 return 0;
1205
1206error_key: 1202error_key:
1207 key_put(key); 1203 key_put(key);
1208error: 1204error:
1209 d_drop(new_dentry);
1210 _leave(" = %d", ret); 1205 _leave(" = %d", ret);
1211 return ret; 1206 return ret;
1212} 1207}