diff options
author | Ingo Molnar <mingo@kernel.org> | 2015-03-04 00:35:43 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2015-03-04 00:35:43 -0500 |
commit | d2c032e3dc58137a7261a7824d3acce435db1d66 (patch) | |
tree | 7eea1c7c6103eefe879f07472eec99b3c41eb792 /fs/xfs/xfs_iops.c | |
parent | 7e8e385aaf6ed5b64b5d9108081cfcdcdd021b78 (diff) | |
parent | 13a7a6ac0a11197edcd0f756a035f472b42cdf8b (diff) |
Merge tag 'v4.0-rc2' into x86/asm, to refresh the tree
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'fs/xfs/xfs_iops.c')
-rw-r--r-- | fs/xfs/xfs_iops.c | 70 |
1 files changed, 38 insertions, 32 deletions
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index c50311cae1b1..e53a90331422 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include "xfs_da_btree.h" | 37 | #include "xfs_da_btree.h" |
38 | #include "xfs_dir2.h" | 38 | #include "xfs_dir2.h" |
39 | #include "xfs_trans_space.h" | 39 | #include "xfs_trans_space.h" |
40 | #include "xfs_pnfs.h" | ||
40 | 41 | ||
41 | #include <linux/capability.h> | 42 | #include <linux/capability.h> |
42 | #include <linux/xattr.h> | 43 | #include <linux/xattr.h> |
@@ -380,18 +381,27 @@ xfs_vn_rename( | |||
380 | struct inode *odir, | 381 | struct inode *odir, |
381 | struct dentry *odentry, | 382 | struct dentry *odentry, |
382 | struct inode *ndir, | 383 | struct inode *ndir, |
383 | struct dentry *ndentry) | 384 | struct dentry *ndentry, |
385 | unsigned int flags) | ||
384 | { | 386 | { |
385 | struct inode *new_inode = ndentry->d_inode; | 387 | struct inode *new_inode = ndentry->d_inode; |
388 | int omode = 0; | ||
386 | struct xfs_name oname; | 389 | struct xfs_name oname; |
387 | struct xfs_name nname; | 390 | struct xfs_name nname; |
388 | 391 | ||
389 | xfs_dentry_to_name(&oname, odentry, 0); | 392 | if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE)) |
393 | return -EINVAL; | ||
394 | |||
395 | /* if we are exchanging files, we need to set i_mode of both files */ | ||
396 | if (flags & RENAME_EXCHANGE) | ||
397 | omode = ndentry->d_inode->i_mode; | ||
398 | |||
399 | xfs_dentry_to_name(&oname, odentry, omode); | ||
390 | xfs_dentry_to_name(&nname, ndentry, odentry->d_inode->i_mode); | 400 | xfs_dentry_to_name(&nname, ndentry, odentry->d_inode->i_mode); |
391 | 401 | ||
392 | return xfs_rename(XFS_I(odir), &oname, XFS_I(odentry->d_inode), | 402 | return xfs_rename(XFS_I(odir), &oname, XFS_I(odentry->d_inode), |
393 | XFS_I(ndir), &nname, new_inode ? | 403 | XFS_I(ndir), &nname, |
394 | XFS_I(new_inode) : NULL); | 404 | new_inode ? XFS_I(new_inode) : NULL, flags); |
395 | } | 405 | } |
396 | 406 | ||
397 | /* | 407 | /* |
@@ -496,7 +506,7 @@ xfs_setattr_mode( | |||
496 | inode->i_mode |= mode & ~S_IFMT; | 506 | inode->i_mode |= mode & ~S_IFMT; |
497 | } | 507 | } |
498 | 508 | ||
499 | static void | 509 | void |
500 | xfs_setattr_time( | 510 | xfs_setattr_time( |
501 | struct xfs_inode *ip, | 511 | struct xfs_inode *ip, |
502 | struct iattr *iattr) | 512 | struct iattr *iattr) |
@@ -741,6 +751,7 @@ xfs_setattr_size( | |||
741 | int error; | 751 | int error; |
742 | uint lock_flags = 0; | 752 | uint lock_flags = 0; |
743 | uint commit_flags = 0; | 753 | uint commit_flags = 0; |
754 | bool did_zeroing = false; | ||
744 | 755 | ||
745 | trace_xfs_setattr(ip); | 756 | trace_xfs_setattr(ip); |
746 | 757 | ||
@@ -784,20 +795,16 @@ xfs_setattr_size( | |||
784 | return error; | 795 | return error; |
785 | 796 | ||
786 | /* | 797 | /* |
787 | * Now we can make the changes. Before we join the inode to the | 798 | * File data changes must be complete before we start the transaction to |
788 | * transaction, take care of the part of the truncation that must be | 799 | * modify the inode. This needs to be done before joining the inode to |
789 | * done without the inode lock. This needs to be done before joining | 800 | * the transaction because the inode cannot be unlocked once it is a |
790 | * the inode to the transaction, because the inode cannot be unlocked | 801 | * part of the transaction. |
791 | * once it is a part of the transaction. | 802 | * |
803 | * Start with zeroing any data block beyond EOF that we may expose on | ||
804 | * file extension. | ||
792 | */ | 805 | */ |
793 | if (newsize > oldsize) { | 806 | if (newsize > oldsize) { |
794 | /* | 807 | error = xfs_zero_eof(ip, newsize, oldsize, &did_zeroing); |
795 | * Do the first part of growing a file: zero any data in the | ||
796 | * last block that is beyond the old EOF. We need to do this | ||
797 | * before the inode is joined to the transaction to modify | ||
798 | * i_size. | ||
799 | */ | ||
800 | error = xfs_zero_eof(ip, newsize, oldsize); | ||
801 | if (error) | 808 | if (error) |
802 | return error; | 809 | return error; |
803 | } | 810 | } |
@@ -807,23 +814,18 @@ xfs_setattr_size( | |||
807 | * any previous writes that are beyond the on disk EOF and the new | 814 | * any previous writes that are beyond the on disk EOF and the new |
808 | * EOF that have not been written out need to be written here. If we | 815 | * EOF that have not been written out need to be written here. If we |
809 | * do not write the data out, we expose ourselves to the null files | 816 | * do not write the data out, we expose ourselves to the null files |
810 | * problem. | 817 | * problem. Note that this includes any block zeroing we did above; |
811 | * | 818 | * otherwise those blocks may not be zeroed after a crash. |
812 | * Only flush from the on disk size to the smaller of the in memory | ||
813 | * file size or the new size as that's the range we really care about | ||
814 | * here and prevents waiting for other data not within the range we | ||
815 | * care about here. | ||
816 | */ | 819 | */ |
817 | if (oldsize != ip->i_d.di_size && newsize > ip->i_d.di_size) { | 820 | if (newsize > ip->i_d.di_size && |
821 | (oldsize != ip->i_d.di_size || did_zeroing)) { | ||
818 | error = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, | 822 | error = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, |
819 | ip->i_d.di_size, newsize); | 823 | ip->i_d.di_size, newsize); |
820 | if (error) | 824 | if (error) |
821 | return error; | 825 | return error; |
822 | } | 826 | } |
823 | 827 | ||
824 | /* | 828 | /* Now wait for all direct I/O to complete. */ |
825 | * Wait for all direct I/O to complete. | ||
826 | */ | ||
827 | inode_dio_wait(inode); | 829 | inode_dio_wait(inode); |
828 | 830 | ||
829 | /* | 831 | /* |
@@ -970,9 +972,13 @@ xfs_vn_setattr( | |||
970 | int error; | 972 | int error; |
971 | 973 | ||
972 | if (iattr->ia_valid & ATTR_SIZE) { | 974 | if (iattr->ia_valid & ATTR_SIZE) { |
973 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | 975 | uint iolock = XFS_IOLOCK_EXCL; |
974 | error = xfs_setattr_size(ip, iattr); | 976 | |
975 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | 977 | xfs_ilock(ip, iolock); |
978 | error = xfs_break_layouts(dentry->d_inode, &iolock); | ||
979 | if (!error) | ||
980 | error = xfs_setattr_size(ip, iattr); | ||
981 | xfs_iunlock(ip, iolock); | ||
976 | } else { | 982 | } else { |
977 | error = xfs_setattr_nonsize(ip, iattr, 0); | 983 | error = xfs_setattr_nonsize(ip, iattr, 0); |
978 | } | 984 | } |
@@ -1144,7 +1150,7 @@ static const struct inode_operations xfs_dir_inode_operations = { | |||
1144 | */ | 1150 | */ |
1145 | .rmdir = xfs_vn_unlink, | 1151 | .rmdir = xfs_vn_unlink, |
1146 | .mknod = xfs_vn_mknod, | 1152 | .mknod = xfs_vn_mknod, |
1147 | .rename = xfs_vn_rename, | 1153 | .rename2 = xfs_vn_rename, |
1148 | .get_acl = xfs_get_acl, | 1154 | .get_acl = xfs_get_acl, |
1149 | .set_acl = xfs_set_acl, | 1155 | .set_acl = xfs_set_acl, |
1150 | .getattr = xfs_vn_getattr, | 1156 | .getattr = xfs_vn_getattr, |
@@ -1172,7 +1178,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = { | |||
1172 | */ | 1178 | */ |
1173 | .rmdir = xfs_vn_unlink, | 1179 | .rmdir = xfs_vn_unlink, |
1174 | .mknod = xfs_vn_mknod, | 1180 | .mknod = xfs_vn_mknod, |
1175 | .rename = xfs_vn_rename, | 1181 | .rename2 = xfs_vn_rename, |
1176 | .get_acl = xfs_get_acl, | 1182 | .get_acl = xfs_get_acl, |
1177 | .set_acl = xfs_set_acl, | 1183 | .set_acl = xfs_set_acl, |
1178 | .getattr = xfs_vn_getattr, | 1184 | .getattr = xfs_vn_getattr, |