Commit caeeeecfdaeada2998eb3c29c3ebd59afb79ef06
Committed by
Linus Torvalds
1 parent
c51b1a160b
Exists in
master
and in
7 other branches
eCryptfs: fix dentry handling on create error, unlink, and inode destroy
This patch corrects some erroneous dentry handling in eCryptfs. If there is a problem creating the lower file, then there is nothing that the persistent lower file can do to really help us. This patch makes a vfs_create() failure in the lower filesystem always lead to an unconditional do_create failure in eCryptfs. Under certain sequences of operations, the eCryptfs dentry can remain in the dcache after an unlink. This patch calls d_drop() on the eCryptfs dentry to correct this. eCryptfs has no business calling d_delete() directly on a lower filesystem's dentry. This patch removes the call to d_delete() on the lower persistent file's dentry in ecryptfs_destroy_inode(). (Thanks to David Kleikamp, Eric Sandeen, and Jeff Moyer for helping identify and resolve this issue) Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com> Cc: Dave Kleikamp <shaggy@austin.ibm.com> Cc: Eric Sandeen <sandeen@redhat.com> Cc: Jeff Moyer <jmoyer@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 2 changed files with 4 additions and 17 deletions Side-by-side Diff
fs/ecryptfs/inode.c
... | ... | @@ -120,22 +120,9 @@ |
120 | 120 | rc = ecryptfs_create_underlying_file(lower_dir_dentry->d_inode, |
121 | 121 | ecryptfs_dentry, mode, nd); |
122 | 122 | if (rc) { |
123 | - struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode; | |
124 | - struct ecryptfs_inode_info *inode_info = | |
125 | - ecryptfs_inode_to_private(ecryptfs_inode); | |
126 | - | |
127 | - printk(KERN_WARNING "%s: Error creating underlying file; " | |
128 | - "rc = [%d]; checking for existing\n", __FUNCTION__, rc); | |
129 | - if (inode_info) { | |
130 | - mutex_lock(&inode_info->lower_file_mutex); | |
131 | - if (!inode_info->lower_file) { | |
132 | - mutex_unlock(&inode_info->lower_file_mutex); | |
133 | - printk(KERN_ERR "%s: Failure to set underlying " | |
134 | - "file; rc = [%d]\n", __FUNCTION__, rc); | |
135 | - goto out_lock; | |
136 | - } | |
137 | - mutex_unlock(&inode_info->lower_file_mutex); | |
138 | - } | |
123 | + printk(KERN_ERR "%s: Failure to create dentry in lower fs; " | |
124 | + "rc = [%d]\n", __FUNCTION__, rc); | |
125 | + goto out_lock; | |
139 | 126 | } |
140 | 127 | rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry, |
141 | 128 | directory_inode->i_sb, 0); |
... | ... | @@ -451,6 +438,7 @@ |
451 | 438 | dentry->d_inode->i_nlink = |
452 | 439 | ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink; |
453 | 440 | dentry->d_inode->i_ctime = dir->i_ctime; |
441 | + d_drop(dentry); | |
454 | 442 | out_unlock: |
455 | 443 | unlock_parent(lower_dentry); |
456 | 444 | return rc; |