提交 1547cb80 编写于 作者: L Linus Torvalds

Merge tag 'ecryptfs-3.6-rc6-fixes' of...

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
...@@ -275,8 +275,14 @@ static int ecryptfs_open(struct inode *inode, struct file *file) ...@@ -275,8 +275,14 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
static int ecryptfs_flush(struct file *file, fl_owner_t td) static int ecryptfs_flush(struct file *file, fl_owner_t td)
{ {
return file->f_mode & FMODE_WRITE struct file *lower_file = ecryptfs_file_to_lower(file);
? filemap_write_and_wait(file->f_mapping) : 0;
if (lower_file->f_op && lower_file->f_op->flush) {
filemap_write_and_wait(file->f_mapping);
return lower_file->f_op->flush(lower_file, td);
}
return 0;
} }
static int ecryptfs_release(struct inode *inode, struct file *file) static int ecryptfs_release(struct inode *inode, struct file *file)
......
...@@ -619,6 +619,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -619,6 +619,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct dentry *lower_old_dir_dentry; struct dentry *lower_old_dir_dentry;
struct dentry *lower_new_dir_dentry; struct dentry *lower_new_dir_dentry;
struct dentry *trap = NULL; struct dentry *trap = NULL;
struct inode *target_inode;
lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
...@@ -626,6 +627,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -626,6 +627,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
dget(lower_new_dentry); dget(lower_new_dentry);
lower_old_dir_dentry = dget_parent(lower_old_dentry); lower_old_dir_dentry = dget_parent(lower_old_dentry);
lower_new_dir_dentry = dget_parent(lower_new_dentry); lower_new_dir_dentry = dget_parent(lower_new_dentry);
target_inode = new_dentry->d_inode;
trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
/* source should not be ancestor of target */ /* source should not be ancestor of target */
if (trap == lower_old_dentry) { if (trap == lower_old_dentry) {
...@@ -641,6 +643,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -641,6 +643,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
lower_new_dir_dentry->d_inode, lower_new_dentry); lower_new_dir_dentry->d_inode, lower_new_dentry);
if (rc) if (rc)
goto out_lock; goto out_lock;
if (target_inode)
fsstack_copy_attr_all(target_inode,
ecryptfs_inode_to_lower(target_inode));
fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode); fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode);
if (new_dir != old_dir) if (new_dir != old_dir)
fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode);
......
...@@ -162,6 +162,7 @@ void ecryptfs_put_lower_file(struct inode *inode) ...@@ -162,6 +162,7 @@ void ecryptfs_put_lower_file(struct inode *inode)
inode_info = ecryptfs_inode_to_private(inode); inode_info = ecryptfs_inode_to_private(inode);
if (atomic_dec_and_mutex_lock(&inode_info->lower_file_count, if (atomic_dec_and_mutex_lock(&inode_info->lower_file_count,
&inode_info->lower_file_mutex)) { &inode_info->lower_file_mutex)) {
filemap_write_and_wait(inode->i_mapping);
fput(inode_info->lower_file); fput(inode_info->lower_file);
inode_info->lower_file = NULL; inode_info->lower_file = NULL;
mutex_unlock(&inode_info->lower_file_mutex); mutex_unlock(&inode_info->lower_file_mutex);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册