diff options
author | Christoph Hellwig <hch@lst.de> | 2011-01-14 07:07:43 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-01-17 02:25:31 -0500 |
commit | 2fe17c1075836b66678ed2a305fd09b6773883aa (patch) | |
tree | eb5287be8138686682eef9622872cfc7657e0664 /fs/ocfs2/file.c | |
parent | 64c23e86873ee410554d6d1c76b60da47025e96f (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/ocfs2/file.c')
-rw-r--r-- | fs/ocfs2/file.c | 8 |
1 files changed, 3 insertions, 5 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index cf254ce8c941..a6651956482e 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -1989,9 +1989,10 @@ int ocfs2_change_file_space(struct file *file, unsigned int cmd, | |||
1989 | return __ocfs2_change_file_space(file, inode, file->f_pos, cmd, sr, 0); | 1989 | return __ocfs2_change_file_space(file, inode, file->f_pos, cmd, sr, 0); |
1990 | } | 1990 | } |
1991 | 1991 | ||
1992 | static long ocfs2_fallocate(struct inode *inode, int mode, loff_t offset, | 1992 | static long ocfs2_fallocate(struct file *file, int mode, loff_t offset, |
1993 | loff_t len) | 1993 | loff_t len) |
1994 | { | 1994 | { |
1995 | struct inode *inode = file->f_path.dentry->d_inode; | ||
1995 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 1996 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
1996 | struct ocfs2_space_resv sr; | 1997 | struct ocfs2_space_resv sr; |
1997 | int change_size = 1; | 1998 | int change_size = 1; |
@@ -2002,9 +2003,6 @@ static long ocfs2_fallocate(struct inode *inode, int mode, loff_t offset, | |||
2002 | if (!ocfs2_writes_unwritten_extents(osb)) | 2003 | if (!ocfs2_writes_unwritten_extents(osb)) |
2003 | return -EOPNOTSUPP; | 2004 | return -EOPNOTSUPP; |
2004 | 2005 | ||
2005 | if (S_ISDIR(inode->i_mode)) | ||
2006 | return -ENODEV; | ||
2007 | |||
2008 | if (mode & FALLOC_FL_KEEP_SIZE) | 2006 | if (mode & FALLOC_FL_KEEP_SIZE) |
2009 | change_size = 0; | 2007 | change_size = 0; |
2010 | 2008 | ||
@@ -2612,7 +2610,6 @@ const struct inode_operations ocfs2_file_iops = { | |||
2612 | .getxattr = generic_getxattr, | 2610 | .getxattr = generic_getxattr, |
2613 | .listxattr = ocfs2_listxattr, | 2611 | .listxattr = ocfs2_listxattr, |
2614 | .removexattr = generic_removexattr, | 2612 | .removexattr = generic_removexattr, |
2615 | .fallocate = ocfs2_fallocate, | ||
2616 | .fiemap = ocfs2_fiemap, | 2613 | .fiemap = ocfs2_fiemap, |
2617 | }; | 2614 | }; |
2618 | 2615 | ||
@@ -2644,6 +2641,7 @@ const struct file_operations ocfs2_fops = { | |||
2644 | .flock = ocfs2_flock, | 2641 | .flock = ocfs2_flock, |
2645 | .splice_read = ocfs2_file_splice_read, | 2642 | .splice_read = ocfs2_file_splice_read, |
2646 | .splice_write = ocfs2_file_splice_write, | 2643 | .splice_write = ocfs2_file_splice_write, |
2644 | .fallocate = ocfs2_fallocate, | ||
2647 | }; | 2645 | }; |
2648 | 2646 | ||
2649 | const struct file_operations ocfs2_dops = { | 2647 | const struct file_operations ocfs2_dops = { |