aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_iops.c')
-rw-r--r--fs/xfs/xfs_iops.c94
1 files changed, 63 insertions, 31 deletions
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index f4cd7204e236..4e4d6511185b 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -537,6 +537,30 @@ xfs_setattr_time(
537 } 537 }
538} 538}
539 539
540static int
541xfs_vn_change_ok(
542 struct dentry *dentry,
543 struct iattr *iattr)
544{
545 struct inode *inode = d_inode(dentry);
546 struct xfs_inode *ip = XFS_I(inode);
547 struct xfs_mount *mp = ip->i_mount;
548
549 if (mp->m_flags & XFS_MOUNT_RDONLY)
550 return -EROFS;
551
552 if (XFS_FORCED_SHUTDOWN(mp))
553 return -EIO;
554
555 return setattr_prepare(dentry, iattr);
556}
557
558/*
559 * Set non-size attributes of an inode.
560 *
561 * Caution: The caller of this function is responsible for calling
562 * setattr_prepare() or otherwise verifying the change is fine.
563 */
540int 564int
541xfs_setattr_nonsize( 565xfs_setattr_nonsize(
542 struct xfs_inode *ip, 566 struct xfs_inode *ip,
@@ -553,21 +577,6 @@ xfs_setattr_nonsize(
553 struct xfs_dquot *udqp = NULL, *gdqp = NULL; 577 struct xfs_dquot *udqp = NULL, *gdqp = NULL;
554 struct xfs_dquot *olddquot1 = NULL, *olddquot2 = NULL; 578 struct xfs_dquot *olddquot1 = NULL, *olddquot2 = NULL;
555 579
556 trace_xfs_setattr(ip);
557
558 /* If acls are being inherited, we already have this checked */
559 if (!(flags & XFS_ATTR_NOACL)) {
560 if (mp->m_flags & XFS_MOUNT_RDONLY)
561 return -EROFS;
562
563 if (XFS_FORCED_SHUTDOWN(mp))
564 return -EIO;
565
566 error = inode_change_ok(inode, iattr);
567 if (error)
568 return error;
569 }
570
571 ASSERT((mask & ATTR_SIZE) == 0); 580 ASSERT((mask & ATTR_SIZE) == 0);
572 581
573 /* 582 /*
@@ -741,8 +750,27 @@ out_dqrele:
741 return error; 750 return error;
742} 751}
743 752
753int
754xfs_vn_setattr_nonsize(
755 struct dentry *dentry,
756 struct iattr *iattr)
757{
758 struct xfs_inode *ip = XFS_I(d_inode(dentry));
759 int error;
760
761 trace_xfs_setattr(ip);
762
763 error = xfs_vn_change_ok(dentry, iattr);
764 if (error)
765 return error;
766 return xfs_setattr_nonsize(ip, iattr, 0);
767}
768
744/* 769/*
745 * Truncate file. Must have write permission and not be a directory. 770 * Truncate file. Must have write permission and not be a directory.
771 *
772 * Caution: The caller of this function is responsible for calling
773 * setattr_prepare() or otherwise verifying the change is fine.
746 */ 774 */
747int 775int
748xfs_setattr_size( 776xfs_setattr_size(
@@ -758,18 +786,6 @@ xfs_setattr_size(
758 uint commit_flags = 0; 786 uint commit_flags = 0;
759 bool did_zeroing = false; 787 bool did_zeroing = false;
760 788
761 trace_xfs_setattr(ip);
762
763 if (mp->m_flags & XFS_MOUNT_RDONLY)
764 return -EROFS;
765
766 if (XFS_FORCED_SHUTDOWN(mp))
767 return -EIO;
768
769 error = inode_change_ok(inode, iattr);
770 if (error)
771 return error;
772
773 ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); 789 ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
774 ASSERT(xfs_isilocked(ip, XFS_MMAPLOCK_EXCL)); 790 ASSERT(xfs_isilocked(ip, XFS_MMAPLOCK_EXCL));
775 ASSERT(S_ISREG(ip->i_d.di_mode)); 791 ASSERT(S_ISREG(ip->i_d.di_mode));
@@ -941,16 +957,32 @@ out_trans_cancel:
941 goto out_unlock; 957 goto out_unlock;
942} 958}
943 959
960int
961xfs_vn_setattr_size(
962 struct dentry *dentry,
963 struct iattr *iattr)
964{
965 struct xfs_inode *ip = XFS_I(d_inode(dentry));
966 int error;
967
968 trace_xfs_setattr(ip);
969
970 error = xfs_vn_change_ok(dentry, iattr);
971 if (error)
972 return error;
973 return xfs_setattr_size(ip, iattr);
974}
975
944STATIC int 976STATIC int
945xfs_vn_setattr( 977xfs_vn_setattr(
946 struct dentry *dentry, 978 struct dentry *dentry,
947 struct iattr *iattr) 979 struct iattr *iattr)
948{ 980{
949 struct xfs_inode *ip = XFS_I(d_inode(dentry));
950 int error; 981 int error;
951 982
952 if (iattr->ia_valid & ATTR_SIZE) { 983 if (iattr->ia_valid & ATTR_SIZE) {
953 uint iolock = XFS_IOLOCK_EXCL; 984 struct xfs_inode *ip = XFS_I(d_inode(dentry));
985 uint iolock = XFS_IOLOCK_EXCL;
954 986
955 xfs_ilock(ip, iolock); 987 xfs_ilock(ip, iolock);
956 error = xfs_break_layouts(d_inode(dentry), &iolock, true); 988 error = xfs_break_layouts(d_inode(dentry), &iolock, true);
@@ -958,11 +990,11 @@ xfs_vn_setattr(
958 xfs_ilock(ip, XFS_MMAPLOCK_EXCL); 990 xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
959 iolock |= XFS_MMAPLOCK_EXCL; 991 iolock |= XFS_MMAPLOCK_EXCL;
960 992
961 error = xfs_setattr_size(ip, iattr); 993 error = xfs_vn_setattr_size(dentry, iattr);
962 } 994 }
963 xfs_iunlock(ip, iolock); 995 xfs_iunlock(ip, iolock);
964 } else { 996 } else {
965 error = xfs_setattr_nonsize(ip, iattr, 0); 997 error = xfs_vn_setattr_nonsize(dentry, iattr);
966 } 998 }
967 999
968 return error; 1000 return error;