ext4: elevate write count for migrate ioctl
The migrate ioctl writes to the filsystem, so we need to elevate the write count. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
This commit is contained in:
committed by
Theodore Ts'o
parent
7ee1ec4ca3
commit
2a43a87800
@@ -1084,8 +1084,7 @@ extern long ext4_ioctl(struct file *, unsigned int, unsigned long);
|
|||||||
extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long);
|
extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long);
|
||||||
|
|
||||||
/* migrate.c */
|
/* migrate.c */
|
||||||
extern int ext4_ext_migrate(struct inode *, struct file *, unsigned int,
|
extern int ext4_ext_migrate(struct inode *);
|
||||||
unsigned long);
|
|
||||||
/* namei.c */
|
/* namei.c */
|
||||||
extern int ext4_orphan_add(handle_t *, struct inode *);
|
extern int ext4_orphan_add(handle_t *, struct inode *);
|
||||||
extern int ext4_orphan_del(handle_t *, struct inode *);
|
extern int ext4_orphan_del(handle_t *, struct inode *);
|
||||||
|
@@ -267,7 +267,26 @@ setversion_out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
case EXT4_IOC_MIGRATE:
|
case EXT4_IOC_MIGRATE:
|
||||||
return ext4_ext_migrate(inode, filp, cmd, arg);
|
{
|
||||||
|
int err;
|
||||||
|
if (!is_owner_or_cap(inode))
|
||||||
|
return -EACCES;
|
||||||
|
|
||||||
|
err = mnt_want_write(filp->f_path.mnt);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
/*
|
||||||
|
* inode_mutex prevent write and truncate on the file.
|
||||||
|
* Read still goes through. We take i_data_sem in
|
||||||
|
* ext4_ext_swap_inode_data before we switch the
|
||||||
|
* inode format to prevent read.
|
||||||
|
*/
|
||||||
|
mutex_lock(&(inode->i_mutex));
|
||||||
|
err = ext4_ext_migrate(inode);
|
||||||
|
mutex_unlock(&(inode->i_mutex));
|
||||||
|
mnt_drop_write(filp->f_path.mnt);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
|
@@ -447,8 +447,7 @@ static int free_ext_block(handle_t *handle, struct inode *inode)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ext4_ext_migrate(struct inode *inode, struct file *filp,
|
int ext4_ext_migrate(struct inode *inode)
|
||||||
unsigned int cmd, unsigned long arg)
|
|
||||||
{
|
{
|
||||||
handle_t *handle;
|
handle_t *handle;
|
||||||
int retval = 0, i;
|
int retval = 0, i;
|
||||||
@@ -515,12 +514,6 @@ int ext4_ext_migrate(struct inode *inode, struct file *filp,
|
|||||||
* trascation that created the inode. Later as and
|
* trascation that created the inode. Later as and
|
||||||
* when we add extents we extent the journal
|
* when we add extents we extent the journal
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
* inode_mutex prevent write and truncate on the file. Read still goes
|
|
||||||
* through. We take i_data_sem in ext4_ext_swap_inode_data before we
|
|
||||||
* switch the inode format to prevent read.
|
|
||||||
*/
|
|
||||||
mutex_lock(&(inode->i_mutex));
|
|
||||||
/*
|
/*
|
||||||
* Even though we take i_mutex we can still cause block allocation
|
* Even though we take i_mutex we can still cause block allocation
|
||||||
* via mmap write to holes. If we have allocated new blocks we fail
|
* via mmap write to holes. If we have allocated new blocks we fail
|
||||||
@@ -623,7 +616,6 @@ err_out:
|
|||||||
tmp_inode->i_nlink = 0;
|
tmp_inode->i_nlink = 0;
|
||||||
|
|
||||||
ext4_journal_stop(handle);
|
ext4_journal_stop(handle);
|
||||||
mutex_unlock(&(inode->i_mutex));
|
|
||||||
|
|
||||||
if (tmp_inode)
|
if (tmp_inode)
|
||||||
iput(tmp_inode);
|
iput(tmp_inode);
|
||||||
|
Reference in New Issue
Block a user