fallocate should be a file operation
Currently all filesystems except XFS implement fallocate asynchronously, while XFS forced a commit. Both of these are suboptimal - in case of O_SYNC I/O we really want our allocation on disk, especially for the !KEEP_SIZE case where we actually grow the file with user-visible zeroes. On the other hand always commiting the transaction is a bad idea for fast-path uses of fallocate like for example in recent Samba versions. Given that block allocation is a data plane operation anyway change it from an inode operation to a file operation so that we have the file structure available that lets us check for O_SYNC. This also includes moving the code around for a few of the filesystems, and remove the already unnedded S_ISDIR checks given that we only wire up fallocate for regular files. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
committed by
Al Viro
parent
64c23e8687
commit
2fe17c1075
@@ -3627,14 +3627,15 @@ static void ext4_falloc_update_inode(struct inode *inode,
|
||||
}
|
||||
|
||||
/*
|
||||
* preallocate space for a file. This implements ext4's fallocate inode
|
||||
* preallocate space for a file. This implements ext4's fallocate file
|
||||
* operation, which gets called from sys_fallocate system call.
|
||||
* For block-mapped files, posix_fallocate should fall back to the method
|
||||
* of writing zeroes to the required new blocks (the same behavior which is
|
||||
* expected for file systems which do not support fallocate() system call).
|
||||
*/
|
||||
long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len)
|
||||
long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
|
||||
{
|
||||
struct inode *inode = file->f_path.dentry->d_inode;
|
||||
handle_t *handle;
|
||||
loff_t new_size;
|
||||
unsigned int max_blocks;
|
||||
@@ -3655,10 +3656,6 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len)
|
||||
if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* preallocation to directories is currently not supported */
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
return -ENODEV;
|
||||
|
||||
map.m_lblk = offset >> blkbits;
|
||||
/*
|
||||
* We can't just convert len to max_blocks because
|
||||
|
Reference in New Issue
Block a user