aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2011-01-14 07:07:43 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2011-01-17 02:25:31 -0500
commit2fe17c1075836b66678ed2a305fd09b6773883aa (patch)
treeeb5287be8138686682eef9622872cfc7657e0664 /fs/ext4
parent64c23e86873ee410554d6d1c76b60da47025e96f (diff)
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>
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/ext4.h2
-rw-r--r--fs/ext4/extents.c9
-rw-r--r--fs/ext4/file.c2
3 files changed, 5 insertions, 8 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 1de65f572033..0c8d97b56f34 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2065,7 +2065,7 @@ extern int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
2065extern void ext4_ext_truncate(struct inode *); 2065extern void ext4_ext_truncate(struct inode *);
2066extern void ext4_ext_init(struct super_block *); 2066extern void ext4_ext_init(struct super_block *);
2067extern void ext4_ext_release(struct super_block *); 2067extern void ext4_ext_release(struct super_block *);
2068extern long ext4_fallocate(struct inode *inode, int mode, loff_t offset, 2068extern long ext4_fallocate(struct file *file, int mode, loff_t offset,
2069 loff_t len); 2069 loff_t len);
2070extern int ext4_convert_unwritten_extents(struct inode *inode, loff_t offset, 2070extern int ext4_convert_unwritten_extents(struct inode *inode, loff_t offset,
2071 ssize_t len); 2071 ssize_t len);
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 4bdd160854eb..63a75810b7c3 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -3627,14 +3627,15 @@ static void ext4_falloc_update_inode(struct inode *inode,
3627} 3627}
3628 3628
3629/* 3629/*
3630 * preallocate space for a file. This implements ext4's fallocate inode 3630 * preallocate space for a file. This implements ext4's fallocate file
3631 * operation, which gets called from sys_fallocate system call. 3631 * operation, which gets called from sys_fallocate system call.
3632 * For block-mapped files, posix_fallocate should fall back to the method 3632 * For block-mapped files, posix_fallocate should fall back to the method
3633 * of writing zeroes to the required new blocks (the same behavior which is 3633 * of writing zeroes to the required new blocks (the same behavior which is
3634 * expected for file systems which do not support fallocate() system call). 3634 * expected for file systems which do not support fallocate() system call).
3635 */ 3635 */
3636long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) 3636long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
3637{ 3637{
3638 struct inode *inode = file->f_path.dentry->d_inode;
3638 handle_t *handle; 3639 handle_t *handle;
3639 loff_t new_size; 3640 loff_t new_size;
3640 unsigned int max_blocks; 3641 unsigned int max_blocks;
@@ -3655,10 +3656,6 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len)
3655 if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) 3656 if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
3656 return -EOPNOTSUPP; 3657 return -EOPNOTSUPP;
3657 3658
3658 /* preallocation to directories is currently not supported */
3659 if (S_ISDIR(inode->i_mode))
3660 return -ENODEV;
3661
3662 map.m_lblk = offset >> blkbits; 3659 map.m_lblk = offset >> blkbits;
3663 /* 3660 /*
3664 * We can't just convert len to max_blocks because 3661 * We can't just convert len to max_blocks because
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index bb003dc9ffff..2e8322c8aa88 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -210,6 +210,7 @@ const struct file_operations ext4_file_operations = {
210 .fsync = ext4_sync_file, 210 .fsync = ext4_sync_file,
211 .splice_read = generic_file_splice_read, 211 .splice_read = generic_file_splice_read,
212 .splice_write = generic_file_splice_write, 212 .splice_write = generic_file_splice_write,
213 .fallocate = ext4_fallocate,
213}; 214};
214 215
215const struct inode_operations ext4_file_inode_operations = { 216const struct inode_operations ext4_file_inode_operations = {
@@ -223,7 +224,6 @@ const struct inode_operations ext4_file_inode_operations = {
223 .removexattr = generic_removexattr, 224 .removexattr = generic_removexattr,
224#endif 225#endif
225 .check_acl = ext4_check_acl, 226 .check_acl = ext4_check_acl,
226 .fallocate = ext4_fallocate,
227 .fiemap = ext4_fiemap, 227 .fiemap = ext4_fiemap,
228}; 228};
229 229