mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-10 23:29:46 +00:00
xfs: factor out xfs_ioctl_setattr transaciton preamble
The setup of the transaction is done after a random smattering of checks and before another bunch of ioperations specific validity checks. Pull all the preamble out into a helper function that returns a transaction or error. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:
parent
29a17c00d4
commit
8f3d17ab06
@ -1042,7 +1042,6 @@ xfs_ioctl_setattr_xflags(
|
|||||||
!capable(CAP_LINUX_IMMUTABLE))
|
!capable(CAP_LINUX_IMMUTABLE))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
xfs_trans_ijoin(tp, ip, 0);
|
|
||||||
xfs_set_diflags(ip, fa->fsx_xflags);
|
xfs_set_diflags(ip, fa->fsx_xflags);
|
||||||
xfs_diflags_to_linux(ip);
|
xfs_diflags_to_linux(ip);
|
||||||
xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
|
xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
|
||||||
@ -1051,6 +1050,54 @@ xfs_ioctl_setattr_xflags(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up the transaction structure for the setattr operation, checking that we
|
||||||
|
* have permission to do so. On success, return a clean transaction and the
|
||||||
|
* inode locked exclusively ready for further operation specific checks. On
|
||||||
|
* failure, return an error without modifying or locking the inode.
|
||||||
|
*/
|
||||||
|
static struct xfs_trans *
|
||||||
|
xfs_ioctl_setattr_get_trans(
|
||||||
|
struct xfs_inode *ip)
|
||||||
|
{
|
||||||
|
struct xfs_mount *mp = ip->i_mount;
|
||||||
|
struct xfs_trans *tp;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if (mp->m_flags & XFS_MOUNT_RDONLY)
|
||||||
|
return ERR_PTR(-EROFS);
|
||||||
|
if (XFS_FORCED_SHUTDOWN(mp))
|
||||||
|
return ERR_PTR(-EIO);
|
||||||
|
|
||||||
|
tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE);
|
||||||
|
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0);
|
||||||
|
if (error)
|
||||||
|
goto out_cancel;
|
||||||
|
|
||||||
|
xfs_ilock(ip, XFS_ILOCK_EXCL);
|
||||||
|
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CAP_FOWNER overrides the following restrictions:
|
||||||
|
*
|
||||||
|
* The user ID of the calling process must be equal to the file owner
|
||||||
|
* ID, except in cases where the CAP_FSETID capability is applicable.
|
||||||
|
*/
|
||||||
|
if (!inode_owner_or_capable(VFS_I(ip))) {
|
||||||
|
error = -EPERM;
|
||||||
|
goto out_cancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mp->m_flags & XFS_MOUNT_WSYNC)
|
||||||
|
xfs_trans_set_sync(tp);
|
||||||
|
|
||||||
|
return tp;
|
||||||
|
|
||||||
|
out_cancel:
|
||||||
|
xfs_trans_cancel(tp, 0);
|
||||||
|
return ERR_PTR(error);
|
||||||
|
}
|
||||||
|
|
||||||
#define FSX_PROJID 1
|
#define FSX_PROJID 1
|
||||||
#define FSX_EXTSIZE 2
|
#define FSX_EXTSIZE 2
|
||||||
#define FSX_XFLAGS 4
|
#define FSX_XFLAGS 4
|
||||||
@ -1063,7 +1110,6 @@ xfs_ioctl_setattr(
|
|||||||
{
|
{
|
||||||
struct xfs_mount *mp = ip->i_mount;
|
struct xfs_mount *mp = ip->i_mount;
|
||||||
struct xfs_trans *tp;
|
struct xfs_trans *tp;
|
||||||
unsigned int lock_flags = 0;
|
|
||||||
struct xfs_dquot *udqp = NULL;
|
struct xfs_dquot *udqp = NULL;
|
||||||
struct xfs_dquot *pdqp = NULL;
|
struct xfs_dquot *pdqp = NULL;
|
||||||
struct xfs_dquot *olddquot = NULL;
|
struct xfs_dquot *olddquot = NULL;
|
||||||
@ -1071,11 +1117,6 @@ xfs_ioctl_setattr(
|
|||||||
|
|
||||||
trace_xfs_ioctl_setattr(ip);
|
trace_xfs_ioctl_setattr(ip);
|
||||||
|
|
||||||
if (mp->m_flags & XFS_MOUNT_RDONLY)
|
|
||||||
return -EROFS;
|
|
||||||
if (XFS_FORCED_SHUTDOWN(mp))
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Disallow 32bit project ids when projid32bit feature is not enabled.
|
* Disallow 32bit project ids when projid32bit feature is not enabled.
|
||||||
*/
|
*/
|
||||||
@ -1099,28 +1140,10 @@ xfs_ioctl_setattr(
|
|||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
tp = xfs_ioctl_setattr_get_trans(ip);
|
||||||
* For the other attributes, we acquire the inode lock and
|
if (IS_ERR(tp)) {
|
||||||
* first do an error checking pass.
|
code = PTR_ERR(tp);
|
||||||
*/
|
goto error_free_dquots;
|
||||||
tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE);
|
|
||||||
code = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0);
|
|
||||||
if (code)
|
|
||||||
goto error_return;
|
|
||||||
|
|
||||||
lock_flags = XFS_ILOCK_EXCL;
|
|
||||||
xfs_ilock(ip, lock_flags);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* CAP_FOWNER overrides the following restrictions:
|
|
||||||
*
|
|
||||||
* The user ID of the calling process must be equal
|
|
||||||
* to the file owner ID, except in cases where the
|
|
||||||
* CAP_FSETID capability is applicable.
|
|
||||||
*/
|
|
||||||
if (!inode_owner_or_capable(VFS_I(ip))) {
|
|
||||||
code = -EPERM;
|
|
||||||
goto error_return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1244,20 +1267,7 @@ xfs_ioctl_setattr(
|
|||||||
ip->i_d.di_extsize = extsize;
|
ip->i_d.di_extsize = extsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* If this is a synchronous mount, make sure that the
|
|
||||||
* transaction goes to disk before returning to the user.
|
|
||||||
* This is slightly sub-optimal in that truncates require
|
|
||||||
* two sync transactions instead of one for wsync filesystems.
|
|
||||||
* One for the truncate and one for the timestamps since we
|
|
||||||
* don't want to change the timestamps unless we're sure the
|
|
||||||
* truncate worked. Truncates are less than 1% of the laddis
|
|
||||||
* mix so this probably isn't worth the trouble to optimize.
|
|
||||||
*/
|
|
||||||
if (mp->m_flags & XFS_MOUNT_WSYNC)
|
|
||||||
xfs_trans_set_sync(tp);
|
|
||||||
code = xfs_trans_commit(tp, 0);
|
code = xfs_trans_commit(tp, 0);
|
||||||
xfs_iunlock(ip, lock_flags);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Release any dquot(s) the inode had kept before chown.
|
* Release any dquot(s) the inode had kept before chown.
|
||||||
@ -1268,12 +1278,11 @@ xfs_ioctl_setattr(
|
|||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
|
||||||
error_return:
|
error_return:
|
||||||
|
xfs_trans_cancel(tp, 0);
|
||||||
|
error_free_dquots:
|
||||||
xfs_qm_dqrele(udqp);
|
xfs_qm_dqrele(udqp);
|
||||||
xfs_qm_dqrele(pdqp);
|
xfs_qm_dqrele(pdqp);
|
||||||
xfs_trans_cancel(tp, 0);
|
|
||||||
if (lock_flags)
|
|
||||||
xfs_iunlock(ip, lock_flags);
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user