Commit 8b943d21 authored by Darrick J. Wong's avatar Darrick J. Wong

Merge tag 'assorted-fixes-5.14-1_2021-06-03' of...

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
parents f52edf6c 977ec4dd
...@@ -1676,7 +1676,6 @@ xfs_alloc_ag_vextent_size( ...@@ -1676,7 +1676,6 @@ xfs_alloc_ag_vextent_size(
cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
args->pag, XFS_BTNUM_CNT); args->pag, XFS_BTNUM_CNT);
bno_cur = NULL; bno_cur = NULL;
busy = false;
/* /*
* Look for an entry >= maxlen+alignment-1 blocks. * Look for an entry >= maxlen+alignment-1 blocks.
......
...@@ -1029,7 +1029,7 @@ xfs_bmap_add_attrfork_local( ...@@ -1029,7 +1029,7 @@ xfs_bmap_add_attrfork_local(
/* /*
* Set an inode attr fork offset based on the format of the data fork. * Set an inode attr fork offset based on the format of the data fork.
*/ */
int static int
xfs_bmap_set_attrforkoff( xfs_bmap_set_attrforkoff(
struct xfs_inode *ip, struct xfs_inode *ip,
int size, int size,
......
...@@ -187,7 +187,6 @@ void xfs_trim_extent(struct xfs_bmbt_irec *irec, xfs_fileoff_t bno, ...@@ -187,7 +187,6 @@ void xfs_trim_extent(struct xfs_bmbt_irec *irec, xfs_fileoff_t bno,
xfs_filblks_t len); xfs_filblks_t len);
unsigned int xfs_bmap_compute_attr_offset(struct xfs_mount *mp); 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_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, void xfs_bmap_local_to_extents_empty(struct xfs_trans *tp,
struct xfs_inode *ip, int whichfork); struct xfs_inode *ip, int whichfork);
void __xfs_bmap_add_free(struct xfs_trans *tp, xfs_fsblock_t bno, void __xfs_bmap_add_free(struct xfs_trans *tp, xfs_fsblock_t bno,
......
...@@ -22,30 +22,26 @@ struct xfs_inode; ...@@ -22,30 +22,26 @@ struct xfs_inode;
* Buffer verifier operations are widely used, including userspace tools * 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_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_agfl_buf_ops;
extern const struct xfs_buf_ops xfs_bnobt_buf_ops; extern const struct xfs_buf_ops xfs_agi_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_attr3_leaf_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_attr3_rmt_buf_ops;
extern const struct xfs_buf_ops xfs_bmbt_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_da3_node_buf_ops;
extern const struct xfs_buf_ops xfs_dquot_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_dquot_buf_ra_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_finobt_buf_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_ops;
extern const struct xfs_buf_ops xfs_inode_buf_ra_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_refcountbt_buf_ops;
extern const struct xfs_buf_ops xfs_dquot_buf_ra_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_buf_ops;
extern const struct xfs_buf_ops xfs_sb_quiet_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_symlink_buf_ops;
extern const struct xfs_buf_ops xfs_rtbuf_ops;
/* log size calculation functions */ /* log size calculation functions */
int xfs_log_calc_unit_res(struct xfs_mount *mp, int unit_bytes); int xfs_log_calc_unit_res(struct xfs_mount *mp, int unit_bytes);
......
...@@ -384,21 +384,30 @@ xfs_file_write_checks( ...@@ -384,21 +384,30 @@ xfs_file_write_checks(
} }
goto restart; goto restart;
} }
/* /*
* If the offset is beyond the size of the file, we need to zero any * 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 * blocks that fall between the existing EOF and the start of this
* write. If zeroing is needed and we are currently holding the * write. If zeroing is needed and we are currently holding the iolock
* iolock shared, we need to update it to exclusive which implies * shared, we need to update it to exclusive which implies having to
* having to redo all checks before. * 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 * We can do an unlocked check here safely as IO completion can only
* completions here. We want to make sure that nobody is changing the * extend EOF. Truncate is locked out at this point, so the EOF can
* size while we do this check until we have placed an IO barrier (i.e. * not move backwards, only forwards. Hence we only need to take the
* hold the XFS_IOLOCK_EXCL) that prevents new IO from being dispatched. * slow path and spin locks when we are at or beyond the current EOF.
* 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.
*/ */
if (iocb->ki_pos <= i_size_read(inode))
goto out;
spin_lock(&ip->i_flags_lock); spin_lock(&ip->i_flags_lock);
isize = i_size_read(inode); isize = i_size_read(inode);
if (iocb->ki_pos > isize) { if (iocb->ki_pos > isize) {
...@@ -435,6 +444,7 @@ xfs_file_write_checks( ...@@ -435,6 +444,7 @@ xfs_file_write_checks(
} else } else
spin_unlock(&ip->i_flags_lock); spin_unlock(&ip->i_flags_lock);
out:
return file_modified(file); return file_modified(file);
} }
...@@ -500,7 +510,17 @@ xfs_dio_write_end_io( ...@@ -500,7 +510,17 @@ xfs_dio_write_end_io(
* other IO completions here to update the EOF. Failing to serialise * other IO completions here to update the EOF. Failing to serialise
* here can result in EOF moving backwards and Bad Things Happen when * here can result in EOF moving backwards and Bad Things Happen when
* that occurs. * 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); spin_lock(&ip->i_flags_lock);
if (offset + size > i_size_read(inode)) { if (offset + size > i_size_read(inode)) {
i_size_write(inode, offset + size); i_size_write(inode, offset + size);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment