mirror of https://gitee.com/openkylin/linux.git
xfs: assorted fixes for 5.14, part 1
This branch contains the first round of various small fixes for 5.14. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEUzaAxoMeQq6m2jMV+H93GTRKtOsFAmC5YvwACgkQ+H93GTRK tOuDTxAAmW+Mc4oPx/Fsa2xqvkDYCGaM1QtkIY9McrGsMdzF0JbB7bR5rrUET2+N /FsFTIQ31vZfMEJ69HM6NjQ4xXIKhdEj+PlGsjvg62BqhpPBRuFH7dLBWChiRcf2 M5SN1P9kcAjIoMR2tKzh8FMDmJTcJlJxxBi9kxb3YK1+UesUHsPS8/jSW3OuIov3 AJzAZ08SrA8ful5uCMy9Mf5uBgfRuAUjDzA5CM5kA1xqlHREQi+oHl62E81N33mu RR8tdHQzvPO5rHyX84GzV5cu2CsmDuOPF2nA5SUxRhIZFfMo5mEezA/nxqqACYti rnRGxZVwIG9YYBESVxXFQXIjn5lHoQ2jomk/CraszeVEJCteNRnpbVGzd1xczM3u 0iuDuHy+aVB/3QhfA6/0vjfttCzkMEld9U9c3WEjIaw5iUCxe531yfrvVEyF9blx NBjnQyHGbt+y26BzBjD33NJEdDoZqS3UIQ/rmb4f2mitGN5d9faAcJ754uRJt3o4 K9HXGjuR+iOH/tCZKDL1hBc4M/pFgNdeBWyFYdQhh8eSj9HSCTCG58zAyQ2WPOSr 6D/f4BMqivKzzz0HicZPJAoazrtcKGrWTHTxidHIkI4le367NOwv6YJquJ0pFMBs 8L7OdRqYT3yw6+qErCjEn03WkP9O7V8lHf8hFxt7+dNxDukIj40= =6eZB -----END PGP SIGNATURE----- Merge tag 'assorted-fixes-5.14-1_2021-06-03' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux into xfs-5.14-merge2 xfs: assorted fixes for 5.14, part 1 This branch contains the first round of various small fixes for 5.14. * tag 'assorted-fixes-5.14-1_2021-06-03' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux: xfs: don't take a spinlock unconditionally in the DIO fastpath xfs: mark xfs_bmap_set_attrforkoff static xfs: Remove redundant assignment to busy xfs: sort variable alphabetically to avoid repeated declaration
This commit is contained in:
commit
8b943d21d4
|
@ -1676,7 +1676,6 @@ xfs_alloc_ag_vextent_size(
|
|||
cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
|
||||
args->pag, XFS_BTNUM_CNT);
|
||||
bno_cur = NULL;
|
||||
busy = false;
|
||||
|
||||
/*
|
||||
* Look for an entry >= maxlen+alignment-1 blocks.
|
||||
|
|
|
@ -1029,7 +1029,7 @@ xfs_bmap_add_attrfork_local(
|
|||
/*
|
||||
* Set an inode attr fork offset based on the format of the data fork.
|
||||
*/
|
||||
int
|
||||
static int
|
||||
xfs_bmap_set_attrforkoff(
|
||||
struct xfs_inode *ip,
|
||||
int size,
|
||||
|
|
|
@ -187,7 +187,6 @@ void xfs_trim_extent(struct xfs_bmbt_irec *irec, xfs_fileoff_t bno,
|
|||
xfs_filblks_t len);
|
||||
unsigned int xfs_bmap_compute_attr_offset(struct xfs_mount *mp);
|
||||
int xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd);
|
||||
int xfs_bmap_set_attrforkoff(struct xfs_inode *ip, int size, int *version);
|
||||
void xfs_bmap_local_to_extents_empty(struct xfs_trans *tp,
|
||||
struct xfs_inode *ip, int whichfork);
|
||||
void __xfs_bmap_add_free(struct xfs_trans *tp, xfs_fsblock_t bno,
|
||||
|
|
|
@ -22,30 +22,26 @@ struct xfs_inode;
|
|||
* Buffer verifier operations are widely used, including userspace tools
|
||||
*/
|
||||
extern const struct xfs_buf_ops xfs_agf_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_agi_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_agf_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_agfl_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_bnobt_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_cntbt_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_rmapbt_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_refcountbt_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_agi_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_attr3_leaf_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_attr3_rmt_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_bmbt_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_bnobt_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_cntbt_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_da3_node_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_dquot_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_symlink_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_agi_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_inobt_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_dquot_buf_ra_ops;
|
||||
extern const struct xfs_buf_ops xfs_finobt_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_inobt_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_inode_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_inode_buf_ra_ops;
|
||||
extern const struct xfs_buf_ops xfs_dquot_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_dquot_buf_ra_ops;
|
||||
extern const struct xfs_buf_ops xfs_refcountbt_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_rmapbt_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_rtbuf_ops;
|
||||
extern const struct xfs_buf_ops xfs_sb_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_sb_quiet_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_symlink_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_rtbuf_ops;
|
||||
|
||||
/* log size calculation functions */
|
||||
int xfs_log_calc_unit_res(struct xfs_mount *mp, int unit_bytes);
|
||||
|
|
|
@ -384,21 +384,30 @@ xfs_file_write_checks(
|
|||
}
|
||||
goto restart;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the offset is beyond the size of the file, we need to zero any
|
||||
* blocks that fall between the existing EOF and the start of this
|
||||
* write. If zeroing is needed and we are currently holding the
|
||||
* iolock shared, we need to update it to exclusive which implies
|
||||
* having to redo all checks before.
|
||||
* write. If zeroing is needed and we are currently holding the iolock
|
||||
* shared, we need to update it to exclusive which implies having to
|
||||
* redo all checks before.
|
||||
*
|
||||
* We need to serialise against EOF updates that occur in IO
|
||||
* completions here. We want to make sure that nobody is changing the
|
||||
* size while we do this check until we have placed an IO barrier (i.e.
|
||||
* hold the XFS_IOLOCK_EXCL) that prevents new IO from being dispatched.
|
||||
* The spinlock effectively forms a memory barrier once we have the
|
||||
* XFS_IOLOCK_EXCL so we are guaranteed to see the latest EOF value
|
||||
* and hence be able to correctly determine if we need to run zeroing.
|
||||
* We need to serialise against EOF updates that occur in IO completions
|
||||
* here. We want to make sure that nobody is changing the size while we
|
||||
* do this check until we have placed an IO barrier (i.e. hold the
|
||||
* XFS_IOLOCK_EXCL) that prevents new IO from being dispatched. The
|
||||
* spinlock effectively forms a memory barrier once we have the
|
||||
* XFS_IOLOCK_EXCL so we are guaranteed to see the latest EOF value and
|
||||
* hence be able to correctly determine if we need to run zeroing.
|
||||
*
|
||||
* We can do an unlocked check here safely as IO completion can only
|
||||
* extend EOF. Truncate is locked out at this point, so the EOF can
|
||||
* not move backwards, only forwards. Hence we only need to take the
|
||||
* slow path and spin locks when we are at or beyond the current EOF.
|
||||
*/
|
||||
if (iocb->ki_pos <= i_size_read(inode))
|
||||
goto out;
|
||||
|
||||
spin_lock(&ip->i_flags_lock);
|
||||
isize = i_size_read(inode);
|
||||
if (iocb->ki_pos > isize) {
|
||||
|
@ -426,7 +435,7 @@ xfs_file_write_checks(
|
|||
drained_dio = true;
|
||||
goto restart;
|
||||
}
|
||||
|
||||
|
||||
trace_xfs_zero_eof(ip, isize, iocb->ki_pos - isize);
|
||||
error = iomap_zero_range(inode, isize, iocb->ki_pos - isize,
|
||||
NULL, &xfs_buffered_write_iomap_ops);
|
||||
|
@ -435,6 +444,7 @@ xfs_file_write_checks(
|
|||
} else
|
||||
spin_unlock(&ip->i_flags_lock);
|
||||
|
||||
out:
|
||||
return file_modified(file);
|
||||
}
|
||||
|
||||
|
@ -500,7 +510,17 @@ xfs_dio_write_end_io(
|
|||
* other IO completions here to update the EOF. Failing to serialise
|
||||
* here can result in EOF moving backwards and Bad Things Happen when
|
||||
* that occurs.
|
||||
*
|
||||
* As IO completion only ever extends EOF, we can do an unlocked check
|
||||
* here to avoid taking the spinlock. If we land within the current EOF,
|
||||
* then we do not need to do an extending update at all, and we don't
|
||||
* need to take the lock to check this. If we race with an update moving
|
||||
* EOF, then we'll either still be beyond EOF and need to take the lock,
|
||||
* or we'll be within EOF and we don't need to take it at all.
|
||||
*/
|
||||
if (offset + size <= i_size_read(inode))
|
||||
goto out;
|
||||
|
||||
spin_lock(&ip->i_flags_lock);
|
||||
if (offset + size > i_size_read(inode)) {
|
||||
i_size_write(inode, offset + size);
|
||||
|
|
Loading…
Reference in New Issue