Date:2008-01-09 00:33:02 (14 years 8 months ago)
Author:Michael Halcrow
Commit:caeeeecfdaeada2998eb3c29c3ebd59afb79ef06
Message: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>
Files: fs/ecryptfs/inode.c (2 diffs)
fs/ecryptfs/super.c (1 diff)

Change Details

fs/ecryptfs/inode.c
120120    rc = ecryptfs_create_underlying_file(lower_dir_dentry->d_inode,
121121                         ecryptfs_dentry, mode, nd);
122122    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;
139126    }
140127    rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry,
141128                directory_inode->i_sb, 0);
...... 
451438    dentry->d_inode->i_nlink =
452439        ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink;
453440    dentry->d_inode->i_ctime = dir->i_ctime;
441    d_drop(dentry);
454442out_unlock:
455443    unlock_parent(lower_dentry);
456444    return rc;
fs/ecryptfs/super.c
8686            fput(inode_info->lower_file);
8787            inode_info->lower_file = NULL;
8888            d_drop(lower_dentry);
89            d_delete(lower_dentry);
9089        }
9190    }
9291    mutex_unlock(&inode_info->lower_file_mutex);

Archive Download the corresponding diff file



interactive