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/xfs/linux-2.6/xfs_iops.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/xfs/linux-2.6/xfs_iops.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_iops.c | 60 |
1 files changed, 0 insertions, 60 deletions
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index a4ecc2188a09..bd5727852fd6 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include <linux/namei.h> | 46 | #include <linux/namei.h> |
47 | #include <linux/posix_acl.h> | 47 | #include <linux/posix_acl.h> |
48 | #include <linux/security.h> | 48 | #include <linux/security.h> |
49 | #include <linux/falloc.h> | ||
50 | #include <linux/fiemap.h> | 49 | #include <linux/fiemap.h> |
51 | #include <linux/slab.h> | 50 | #include <linux/slab.h> |
52 | 51 | ||
@@ -505,64 +504,6 @@ xfs_vn_setattr( | |||
505 | return -xfs_setattr(XFS_I(dentry->d_inode), iattr, 0); | 504 | return -xfs_setattr(XFS_I(dentry->d_inode), iattr, 0); |
506 | } | 505 | } |
507 | 506 | ||
508 | STATIC long | ||
509 | xfs_vn_fallocate( | ||
510 | struct inode *inode, | ||
511 | int mode, | ||
512 | loff_t offset, | ||
513 | loff_t len) | ||
514 | { | ||
515 | long error; | ||
516 | loff_t new_size = 0; | ||
517 | xfs_flock64_t bf; | ||
518 | xfs_inode_t *ip = XFS_I(inode); | ||
519 | int cmd = XFS_IOC_RESVSP; | ||
520 | |||
521 | if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) | ||
522 | return -EOPNOTSUPP; | ||
523 | |||
524 | /* preallocation on directories not yet supported */ | ||
525 | error = -ENODEV; | ||
526 | if (S_ISDIR(inode->i_mode)) | ||
527 | goto out_error; | ||
528 | |||
529 | bf.l_whence = 0; | ||
530 | bf.l_start = offset; | ||
531 | bf.l_len = len; | ||
532 | |||
533 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | ||
534 | |||
535 | if (mode & FALLOC_FL_PUNCH_HOLE) | ||
536 | cmd = XFS_IOC_UNRESVSP; | ||
537 | |||
538 | /* check the new inode size is valid before allocating */ | ||
539 | if (!(mode & FALLOC_FL_KEEP_SIZE) && | ||
540 | offset + len > i_size_read(inode)) { | ||
541 | new_size = offset + len; | ||
542 | error = inode_newsize_ok(inode, new_size); | ||
543 | if (error) | ||
544 | goto out_unlock; | ||
545 | } | ||
546 | |||
547 | error = -xfs_change_file_space(ip, cmd, &bf, 0, XFS_ATTR_NOLOCK); | ||
548 | if (error) | ||
549 | goto out_unlock; | ||
550 | |||
551 | /* Change file size if needed */ | ||
552 | if (new_size) { | ||
553 | struct iattr iattr; | ||
554 | |||
555 | iattr.ia_valid = ATTR_SIZE; | ||
556 | iattr.ia_size = new_size; | ||
557 | error = -xfs_setattr(ip, &iattr, XFS_ATTR_NOLOCK); | ||
558 | } | ||
559 | |||
560 | out_unlock: | ||
561 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
562 | out_error: | ||
563 | return error; | ||
564 | } | ||
565 | |||
566 | #define XFS_FIEMAP_FLAGS (FIEMAP_FLAG_SYNC|FIEMAP_FLAG_XATTR) | 507 | #define XFS_FIEMAP_FLAGS (FIEMAP_FLAG_SYNC|FIEMAP_FLAG_XATTR) |
567 | 508 | ||
568 | /* | 509 | /* |
@@ -656,7 +597,6 @@ static const struct inode_operations xfs_inode_operations = { | |||
656 | .getxattr = generic_getxattr, | 597 | .getxattr = generic_getxattr, |
657 | .removexattr = generic_removexattr, | 598 | .removexattr = generic_removexattr, |
658 | .listxattr = xfs_vn_listxattr, | 599 | .listxattr = xfs_vn_listxattr, |
659 | .fallocate = xfs_vn_fallocate, | ||
660 | .fiemap = xfs_vn_fiemap, | 600 | .fiemap = xfs_vn_fiemap, |
661 | }; | 601 | }; |
662 | 602 | ||