mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-04-18 11:07:38 +07:00
xfs: simplify the fallocate path
Call xfs_alloc_file_space or xfs_free_file_space directly from xfs_file_fallocate instead of going through xfs_change_file_space. This simplified the code by removing the unessecary marshalling of the arguments into an xfs_flock64_t structure and allows removing checks that are already done in the VFS code. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Ben Myers <bpm@sgi.com>
This commit is contained in:
parent
5f8aca8b43
commit
83aee9e4c2
@ -965,28 +965,9 @@ xfs_free_eofblocks(
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
int
|
||||||
* xfs_alloc_file_space()
|
|
||||||
* This routine allocates disk space for the given file.
|
|
||||||
*
|
|
||||||
* If alloc_type == 0, this request is for an ALLOCSP type
|
|
||||||
* request which will change the file size. In this case, no
|
|
||||||
* DMAPI event will be generated by the call. A TRUNCATE event
|
|
||||||
* will be generated later by xfs_setattr.
|
|
||||||
*
|
|
||||||
* If alloc_type != 0, this request is for a RESVSP type
|
|
||||||
* request, and a DMAPI DM_EVENT_WRITE will be generated if the
|
|
||||||
* lower block boundary byte address is less than the file's
|
|
||||||
* length.
|
|
||||||
*
|
|
||||||
* RETURNS:
|
|
||||||
* 0 on success
|
|
||||||
* errno on error
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
STATIC int
|
|
||||||
xfs_alloc_file_space(
|
xfs_alloc_file_space(
|
||||||
xfs_inode_t *ip,
|
struct xfs_inode *ip,
|
||||||
xfs_off_t offset,
|
xfs_off_t offset,
|
||||||
xfs_off_t len,
|
xfs_off_t len,
|
||||||
int alloc_type)
|
int alloc_type)
|
||||||
@ -1231,21 +1212,9 @@ xfs_zero_remaining_bytes(
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
int
|
||||||
* xfs_free_file_space()
|
|
||||||
* This routine frees disk space for the given file.
|
|
||||||
*
|
|
||||||
* This routine is only called by xfs_change_file_space
|
|
||||||
* for an UNRESVSP type call.
|
|
||||||
*
|
|
||||||
* RETURNS:
|
|
||||||
* 0 on success
|
|
||||||
* errno on error
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
STATIC int
|
|
||||||
xfs_free_file_space(
|
xfs_free_file_space(
|
||||||
xfs_inode_t *ip,
|
struct xfs_inode *ip,
|
||||||
xfs_off_t offset,
|
xfs_off_t offset,
|
||||||
xfs_off_t len)
|
xfs_off_t len)
|
||||||
{
|
{
|
||||||
|
@ -96,6 +96,10 @@ int xfs_bmap_last_extent(struct xfs_trans *tp, struct xfs_inode *ip,
|
|||||||
int xfs_change_file_space(struct xfs_inode *ip, int cmd,
|
int xfs_change_file_space(struct xfs_inode *ip, int cmd,
|
||||||
xfs_flock64_t *bf, xfs_off_t offset,
|
xfs_flock64_t *bf, xfs_off_t offset,
|
||||||
int attr_flags);
|
int attr_flags);
|
||||||
|
int xfs_alloc_file_space(struct xfs_inode *ip, xfs_off_t offset,
|
||||||
|
xfs_off_t len, int alloc_type);
|
||||||
|
int xfs_free_file_space(struct xfs_inode *ip, xfs_off_t offset,
|
||||||
|
xfs_off_t len);
|
||||||
|
|
||||||
/* EOF block manipulation functions */
|
/* EOF block manipulation functions */
|
||||||
bool xfs_can_free_eofblocks(struct xfs_inode *ip, bool force);
|
bool xfs_can_free_eofblocks(struct xfs_inode *ip, bool force);
|
||||||
|
@ -805,44 +805,64 @@ xfs_file_aio_write(
|
|||||||
|
|
||||||
STATIC long
|
STATIC long
|
||||||
xfs_file_fallocate(
|
xfs_file_fallocate(
|
||||||
struct file *file,
|
struct file *file,
|
||||||
int mode,
|
int mode,
|
||||||
loff_t offset,
|
loff_t offset,
|
||||||
loff_t len)
|
loff_t len)
|
||||||
{
|
{
|
||||||
struct inode *inode = file_inode(file);
|
struct inode *inode = file_inode(file);
|
||||||
long error;
|
struct xfs_inode *ip = XFS_I(inode);
|
||||||
loff_t new_size = 0;
|
struct xfs_trans *tp;
|
||||||
xfs_flock64_t bf;
|
long error;
|
||||||
xfs_inode_t *ip = XFS_I(inode);
|
loff_t new_size = 0;
|
||||||
int cmd = XFS_IOC_RESVSP;
|
|
||||||
int attr_flags = 0;
|
|
||||||
|
|
||||||
|
if (!S_ISREG(inode->i_mode))
|
||||||
|
return -EINVAL;
|
||||||
if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
|
if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
bf.l_whence = 0;
|
|
||||||
bf.l_start = offset;
|
|
||||||
bf.l_len = len;
|
|
||||||
|
|
||||||
xfs_ilock(ip, XFS_IOLOCK_EXCL);
|
xfs_ilock(ip, XFS_IOLOCK_EXCL);
|
||||||
|
if (mode & FALLOC_FL_PUNCH_HOLE) {
|
||||||
|
error = xfs_free_file_space(ip, offset, len);
|
||||||
|
if (error)
|
||||||
|
goto out_unlock;
|
||||||
|
} else {
|
||||||
|
if (!(mode & FALLOC_FL_KEEP_SIZE) &&
|
||||||
|
offset + len > i_size_read(inode)) {
|
||||||
|
new_size = offset + len;
|
||||||
|
error = -inode_newsize_ok(inode, new_size);
|
||||||
|
if (error)
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
if (mode & FALLOC_FL_PUNCH_HOLE)
|
error = xfs_alloc_file_space(ip, offset, len,
|
||||||
cmd = XFS_IOC_UNRESVSP;
|
XFS_BMAPI_PREALLOC);
|
||||||
|
|
||||||
/* check the new inode size is valid before allocating */
|
|
||||||
if (!(mode & FALLOC_FL_KEEP_SIZE) &&
|
|
||||||
offset + len > i_size_read(inode)) {
|
|
||||||
new_size = offset + len;
|
|
||||||
error = inode_newsize_ok(inode, new_size);
|
|
||||||
if (error)
|
if (error)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file->f_flags & O_DSYNC)
|
tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_WRITEID);
|
||||||
attr_flags |= XFS_ATTR_SYNC;
|
error = xfs_trans_reserve(tp, &M_RES(ip->i_mount)->tr_writeid, 0, 0);
|
||||||
|
if (error) {
|
||||||
|
xfs_trans_cancel(tp, 0);
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
error = -xfs_change_file_space(ip, cmd, &bf, 0, attr_flags);
|
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))
|
||||||
|
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);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
@ -852,12 +872,12 @@ xfs_file_fallocate(
|
|||||||
|
|
||||||
iattr.ia_valid = ATTR_SIZE;
|
iattr.ia_valid = ATTR_SIZE;
|
||||||
iattr.ia_size = new_size;
|
iattr.ia_size = new_size;
|
||||||
error = -xfs_setattr_size(ip, &iattr);
|
error = xfs_setattr_size(ip, &iattr);
|
||||||
}
|
}
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
|
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
|
||||||
return error;
|
return -error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user