summaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_file.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-10 16:15:17 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-10 16:15:17 -0800
commitae90fb14206efda2c2ea6d61e14f14bf0132f676 (patch)
treef8ec87d501ec4d091177b8916d0e0c81e570454c /fs/xfs/xfs_file.c
parentc5452a58db9bbcb331ee92afa99a6f42e39085c7 (diff)
parentbad962662dbc60e76ec1baae34af56b1ba2dfa5f (diff)
downloadop-kernel-dev-ae90fb14206efda2c2ea6d61e14f14bf0132f676.zip
op-kernel-dev-ae90fb14206efda2c2ea6d61e14f14bf0132f676.tar.gz
Merge tag 'xfs-for-linus-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs
Pull xfs update from Dave Chinner: "This update contains: - RENAME_EXCHANGE support - Rework of the superblock logging infrastructure - Rework of the XFS_IOCTL_SETXATTR implementation * enables use inside user namespaces * fixes inconsistencies setting extent size hints - fixes for missing buffer type annotations used in log recovery - more consolidation of libxfs headers - preparation patches for block based PNFS support - miscellaneous bug fixes and cleanups" * tag 'xfs-for-linus-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs: (37 commits) xfs: only trace buffer items if they exist xfs: report proper f_files in statfs if we overshoot imaxpct xfs: fix panic_mask documentation xfs: xfs_ioctl_setattr_check_projid can be static xfs: growfs should use synchronous transactions xfs: fix behaviour of XFS_IOC_FSSETXATTR on directories xfs: factor projid hint checking out of xfs_ioctl_setattr xfs: factor extsize hint checking out of xfs_ioctl_setattr xfs: XFS_IOCTL_SETXATTR can run in user namespaces xfs: kill xfs_ioctl_setattr behaviour mask xfs: disaggregate xfs_ioctl_setattr xfs: factor out xfs_ioctl_setattr transaciton preamble xfs: separate xflags from xfs_ioctl_setattr xfs: FSX_NONBLOCK is not used xfs: don't allocate an ioend for direct I/O completions xfs: change kmem_free to use generic kvfree() xfs: factor out a xfs_update_prealloc_flags() helper xfs: remove incorrect error negation in attr_multi ioctl xfs: set superblock buffer type correctly xfs: set buf types when converting extent formats ...
Diffstat (limited to 'fs/xfs/xfs_file.c')
-rw-r--r--fs/xfs/xfs_file.c64
1 files changed, 42 insertions, 22 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 13e974e..712d312 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -127,6 +127,42 @@ xfs_iozero(
return (-status);
}
+int
+xfs_update_prealloc_flags(
+ struct xfs_inode *ip,
+ enum xfs_prealloc_flags flags)
+{
+ struct xfs_trans *tp;
+ int error;
+
+ tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_WRITEID);
+ error = xfs_trans_reserve(tp, &M_RES(ip->i_mount)->tr_writeid, 0, 0);
+ if (error) {
+ xfs_trans_cancel(tp, 0);
+ return error;
+ }
+
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+ xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
+
+ if (!(flags & XFS_PREALLOC_INVISIBLE)) {
+ ip->i_d.di_mode &= ~S_ISUID;
+ if (ip->i_d.di_mode & S_IXGRP)
+ ip->i_d.di_mode &= ~S_ISGID;
+ xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
+ }
+
+ if (flags & XFS_PREALLOC_SET)
+ ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC;
+ if (flags & XFS_PREALLOC_CLEAR)
+ ip->i_d.di_flags &= ~XFS_DIFLAG_PREALLOC;
+
+ xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+ if (flags & XFS_PREALLOC_SYNC)
+ xfs_trans_set_sync(tp);
+ return xfs_trans_commit(tp, 0);
+}
+
/*
* Fsync operations on directories are much simpler than on regular files,
* as there is no file data to flush, and thus also no need for explicit
@@ -784,8 +820,8 @@ xfs_file_fallocate(
{
struct inode *inode = file_inode(file);
struct xfs_inode *ip = XFS_I(inode);
- struct xfs_trans *tp;
long error;
+ enum xfs_prealloc_flags flags = 0;
loff_t new_size = 0;
if (!S_ISREG(inode->i_mode))
@@ -822,6 +858,8 @@ xfs_file_fallocate(
if (error)
goto out_unlock;
} else {
+ flags |= XFS_PREALLOC_SET;
+
if (!(mode & FALLOC_FL_KEEP_SIZE) &&
offset + len > i_size_read(inode)) {
new_size = offset + len;
@@ -839,28 +877,10 @@ xfs_file_fallocate(
goto out_unlock;
}
- tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_WRITEID);
- error = xfs_trans_reserve(tp, &M_RES(ip->i_mount)->tr_writeid, 0, 0);
- if (error) {
- xfs_trans_cancel(tp, 0);
- goto out_unlock;
- }
-
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- ip->i_d.di_mode &= ~S_ISUID;
- if (ip->i_d.di_mode & S_IXGRP)
- ip->i_d.di_mode &= ~S_ISGID;
-
- if (!(mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE)))
- ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC;
-
- xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
- xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-
if (file->f_flags & O_DSYNC)
- xfs_trans_set_sync(tp);
- error = xfs_trans_commit(tp, 0);
+ flags |= XFS_PREALLOC_SYNC;
+
+ error = xfs_update_prealloc_flags(ip, flags);
if (error)
goto out_unlock;
OpenPOWER on IntegriCloud