Commit 0c797892 authored by Davide Italiano's avatar Davide Italiano Committed by Zefan Li

ext4: move check under lock scope to close a race.

commit 280227a7 upstream.

fallocate() checks that the file is extent-based and returns
EOPNOTSUPP in case is not. Other tasks can convert from and to
indirect and extent so it's safe to check only after grabbing
the inode mutex.
Signed-off-by: default avatarDavide Italiano <dccitaliano@gmail.com>
Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
[lizf: Backported to 3.4:
 - adjust context
 - return -EOPNOTSUPP instead of jumping to the "out" label]
Signed-off-by: default avatarZefan Li <lizefan@huawei.com>
parent c79a5426
...@@ -4365,13 +4365,6 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len) ...@@ -4365,13 +4365,6 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
struct ext4_map_blocks map; struct ext4_map_blocks map;
unsigned int credits, blkbits = inode->i_blkbits; unsigned int credits, blkbits = inode->i_blkbits;
/*
* currently supporting (pre)allocate mode for extent-based
* files _only_
*/
if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
return -EOPNOTSUPP;
/* Return error if mode is not supported */ /* Return error if mode is not supported */
if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -4392,6 +4385,15 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len) ...@@ -4392,6 +4385,15 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
*/ */
credits = ext4_chunk_trans_blocks(inode, max_blocks); credits = ext4_chunk_trans_blocks(inode, max_blocks);
mutex_lock(&inode->i_mutex); mutex_lock(&inode->i_mutex);
/*
* We only support preallocation for extent-based files only
*/
if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
mutex_unlock(&inode->i_mutex);
return -EOPNOTSUPP;
}
ret = inode_newsize_ok(inode, (len + offset)); ret = inode_newsize_ok(inode, (len + offset));
if (ret) { if (ret) {
mutex_unlock(&inode->i_mutex); mutex_unlock(&inode->i_mutex);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment