History

Merge tag 'ecryptfs-3.6-rc6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs

Pull ecryptfs fixes from Tyler Hicks: - Fixes a regression, introduced in 3.6-rc1, when a file is closed before its shared memory mapping is dirtied and unmapped. The lower file was being released when the eCryptfs file was closed and the dirtied pages could not be written out. - Adds a call to the lower filesystem's ->flush() from ecryptfs_flush(). - Fixes a regression, introduced in 2.6.39, when a file is renamed on top of another file. The target file's inode was not being evicted and the space taken by the file was not reclaimed until eCryptfs was unmounted. * tag 'ecryptfs-3.6-rc6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs: eCryptfs: Copy up attributes of the lower target inode after rename eCryptfs: Call lower ->flush() from ecryptfs_flush() eCryptfs: Write out all dirty pages just before releasing the lower file

Linus Torvalds committed 14 years ago

Commit 1547cb82 parents 1568d9f 8335eaf3 files · +14 −2Browse files

Unified · Split

3 files
  1. fs/ecryptfs/file.c +8 −2
  2. fs/ecryptfs/inode.c +5 −0
  3. fs/ecryptfs/main.c +1 −0
fs/ecryptfs/file.c+8−2
@@ -275,8 +275,14 @@ out: · 274 unmodified lines
275275
276276 static int ecryptfs_flush(struct file *file, fl_owner_t td)
277277 {
278− return file->f_mode & FMODE_WRITE
279− ? filemap_write_and_wait(file->f_mapping) : 0;
278+ struct file *lower_file = ecryptfs_file_to_lower(file);
279+
280+ if (lower_file->f_op && lower_file->f_op->flush) {
281+ filemap_write_and_wait(file->f_mapping);
282+ return lower_file->f_op->flush(lower_file, td);
283+ }
284+
285+ return 0;
280286 }
281287
282288 static int ecryptfs_release(struct inode *inode, struct file *file)
fs/ecryptfs/inode.c+5−0
@@ -619,6 +619,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, · 618 unmodified lines
619619 struct dentry *lower_old_dir_dentry;
620620 struct dentry *lower_new_dir_dentry;
621621 struct dentry *trap = NULL;
622+ struct inode *target_inode;
622623
623624 lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
624625 lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
@@ -626,6 +627,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, · 1 unmodified line
626627 dget(lower_new_dentry);
627628 lower_old_dir_dentry = dget_parent(lower_old_dentry);
628629 lower_new_dir_dentry = dget_parent(lower_new_dentry);
630+ target_inode = new_dentry->d_inode;
629631 trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
630632 /* source should not be ancestor of target */
631633 if (trap == lower_old_dentry) {
@@ -641,6 +643,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, · 9 unmodified lines
641643 lower_new_dir_dentry->d_inode, lower_new_dentry);
642644 if (rc)
643645 goto out_lock;
646+ if (target_inode)
647+ fsstack_copy_attr_all(target_inode,
648+ ecryptfs_inode_to_lower(target_inode));
644649 fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode);
645650 if (new_dir != old_dir)
646651 fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode);
fs/ecryptfs/main.c+1−0
@@ -162,6 +162,7 @@ void ecryptfs_put_lower_file(struct inode *inode) · 161 unmodified lines
162162 inode_info = ecryptfs_inode_to_private(inode);
163163 if (atomic_dec_and_mutex_lock(&inode_info->lower_file_count,
164164 &inode_info->lower_file_mutex)) {
165+ filemap_write_and_wait(inode->i_mapping);
165166 fput(inode_info->lower_file);
166167 inode_info->lower_file = NULL;
167168 mutex_unlock(&inode_info->lower_file_mutex);