Skip to content

Commit

Permalink
eCryptfs: fix dentry handling on create error, unlink, and inode destroy
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Michael Halcrow authored and Linus Torvalds committed Jan 9, 2008
1 parent c51b1a1 commit caeeeec
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 17 deletions.
20 changes: 4 additions & 16 deletions fs/ecryptfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,22 +120,9 @@ ecryptfs_do_create(struct inode *directory_inode,
rc = ecryptfs_create_underlying_file(lower_dir_dentry->d_inode,
ecryptfs_dentry, mode, nd);
if (rc) {
struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode;
struct ecryptfs_inode_info *inode_info =
ecryptfs_inode_to_private(ecryptfs_inode);

printk(KERN_WARNING "%s: Error creating underlying file; "
"rc = [%d]; checking for existing\n", __FUNCTION__, rc);
if (inode_info) {
mutex_lock(&inode_info->lower_file_mutex);
if (!inode_info->lower_file) {
mutex_unlock(&inode_info->lower_file_mutex);
printk(KERN_ERR "%s: Failure to set underlying "
"file; rc = [%d]\n", __FUNCTION__, rc);
goto out_lock;
}
mutex_unlock(&inode_info->lower_file_mutex);
}
printk(KERN_ERR "%s: Failure to create dentry in lower fs; "
"rc = [%d]\n", __FUNCTION__, rc);
goto out_lock;
}
rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry,
directory_inode->i_sb, 0);
Expand Down Expand Up @@ -451,6 +438,7 @@ static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry)
dentry->d_inode->i_nlink =
ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink;
dentry->d_inode->i_ctime = dir->i_ctime;
d_drop(dentry);
out_unlock:
unlock_parent(lower_dentry);
return rc;
Expand Down
1 change: 0 additions & 1 deletion fs/ecryptfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ static void ecryptfs_destroy_inode(struct inode *inode)
fput(inode_info->lower_file);
inode_info->lower_file = NULL;
d_drop(lower_dentry);
d_delete(lower_dentry);
}
}
mutex_unlock(&inode_info->lower_file_mutex);
Expand Down

0 comments on commit caeeeec

Please sign in to comment.