@ -542,6 +542,30 @@ xfs_setattr_time(
inode - > i_mtime = iattr - > ia_mtime ;
}
static int
xfs_vn_change_ok (
struct dentry * dentry ,
struct iattr * iattr )
{
struct inode * inode = d_inode ( dentry ) ;
struct xfs_inode * ip = XFS_I ( inode ) ;
struct xfs_mount * mp = ip - > i_mount ;
if ( mp - > m_flags & XFS_MOUNT_RDONLY )
return - EROFS ;
if ( XFS_FORCED_SHUTDOWN ( mp ) )
return - EIO ;
return inode_change_ok ( inode , iattr ) ;
}
/*
* Set non - size attributes of an inode .
*
* Caution : The caller of this function is responsible for calling
* inode_change_ok ( ) or otherwise verifying the change is fine .
*/
int
xfs_setattr_nonsize (
struct xfs_inode * ip ,
@ -558,21 +582,6 @@ xfs_setattr_nonsize(
struct xfs_dquot * udqp = NULL , * gdqp = NULL ;
struct xfs_dquot * olddquot1 = NULL , * olddquot2 = NULL ;
trace_xfs_setattr ( ip ) ;
/* If acls are being inherited, we already have this checked */
if ( ! ( flags & XFS_ATTR_NOACL ) ) {
if ( mp - > m_flags & XFS_MOUNT_RDONLY )
return - EROFS ;
if ( XFS_FORCED_SHUTDOWN ( mp ) )
return - EIO ;
error = inode_change_ok ( inode , iattr ) ;
if ( error )
return error ;
}
ASSERT ( ( mask & ATTR_SIZE ) = = 0 ) ;
/*
@ -743,8 +752,27 @@ out_dqrele:
return error ;
}
int
xfs_vn_setattr_nonsize (
struct dentry * dentry ,
struct iattr * iattr )
{
struct xfs_inode * ip = XFS_I ( d_inode ( dentry ) ) ;
int error ;
trace_xfs_setattr ( ip ) ;
error = xfs_vn_change_ok ( dentry , iattr ) ;
if ( error )
return error ;
return xfs_setattr_nonsize ( ip , iattr , 0 ) ;
}
/*
* Truncate file . Must have write permission and not be a directory .
*
* Caution : The caller of this function is responsible for calling
* inode_change_ok ( ) or otherwise verifying the change is fine .
*/
int
xfs_setattr_size (
@ -759,18 +787,6 @@ xfs_setattr_size(
uint lock_flags = 0 ;
bool did_zeroing = false ;
trace_xfs_setattr ( ip ) ;
if ( mp - > m_flags & XFS_MOUNT_RDONLY )
return - EROFS ;
if ( XFS_FORCED_SHUTDOWN ( mp ) )
return - EIO ;
error = inode_change_ok ( inode , iattr ) ;
if ( error )
return error ;
ASSERT ( xfs_isilocked ( ip , XFS_IOLOCK_EXCL ) ) ;
ASSERT ( xfs_isilocked ( ip , XFS_MMAPLOCK_EXCL ) ) ;
ASSERT ( S_ISREG ( inode - > i_mode ) ) ;
@ -942,16 +958,32 @@ out_trans_cancel:
goto out_unlock ;
}
int
xfs_vn_setattr_size (
struct dentry * dentry ,
struct iattr * iattr )
{
struct xfs_inode * ip = XFS_I ( d_inode ( dentry ) ) ;
int error ;
trace_xfs_setattr ( ip ) ;
error = xfs_vn_change_ok ( dentry , iattr ) ;
if ( error )
return error ;
return xfs_setattr_size ( ip , iattr ) ;
}
STATIC int
xfs_vn_setattr (
struct dentry * dentry ,
struct iattr * iattr )
{
struct xfs_inode * ip = XFS_I ( d_inode ( dentry ) ) ;
int error ;
if ( iattr - > ia_valid & ATTR_SIZE ) {
uint iolock = XFS_IOLOCK_EXCL ;
struct xfs_inode * ip = XFS_I ( d_inode ( dentry ) ) ;
uint iolock = XFS_IOLOCK_EXCL ;
xfs_ilock ( ip , iolock ) ;
error = xfs_break_layouts ( d_inode ( dentry ) , & iolock , true ) ;
@ -959,11 +991,11 @@ xfs_vn_setattr(
xfs_ilock ( ip , XFS_MMAPLOCK_EXCL ) ;
iolock | = XFS_MMAPLOCK_EXCL ;
error = xfs_setattr_size ( ip , iattr ) ;
error = xfs_vn_ setattr_size ( dentry , iattr ) ;
}
xfs_iunlock ( ip , iolock ) ;
} else {
error = xfs_setattr_nonsize ( ip , iattr , 0 ) ;
error = xfs_vn_ setattr_nonsize ( dentry , iattr ) ;
}
return error ;