Commit b1b07ba3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'xfs-5.18-merge-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull xfs updates from Darrick Wong:
 "The biggest change this cycle is bringing XFS' inode attribute setting
  code back towards alignment with what the VFS does. IOWs, setgid bit
  handling should be a closer match with ext4 and btrfs behavior.

  The rest of the branch is bug fixes around the filesystem -- patching
  gaps in quota enforcement, removing bogus selinux audit messages, and
  fixing log corruption and problems with log recovery. There will be a
  second pull request later on in the merge window with more bug fixes.

  Dave Chinner will be taking over as XFS maintainer for one release
  cycle, starting from the day 5.18-rc1 drops until 5.19-rc1 is tagged
  so that I can focus on starting a massive design review for the
  (feature complete after five years) online repair feature.

  Summary:

   - Fix some incorrect mapping state being passed to iomap during COW

   - Don't create bogus selinux audit messages when deciding to degrade
     gracefully due to lack of privilege

   - Fix setattr implementation to use VFS helpers so that we drop
     setgid consistently with the other filesystems

   - Fix link/unlink/rename to check quota limits

   - Constify xfs_name_dotdot to prevent abuse of in-kernel symbols

   - Fix log livelock between the AIL and inodegc threads during
     recovery

   - Fix a log stall when the AIL races with pushers

   - Fix stalls in CIL flushes due to pinned inode cluster buffers
     during recovery

   - Fix log corruption due to incorrect usage of xfs_is_shutdown vs
     xlog_is_shutdown because during an induced fs shutdown, AIL
     writeback must continue until the log is shut down, even if the
     filesystem has already shut down"

* tag 'xfs-5.18-merge-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
  xfs: xfs_is_shutdown vs xlog_is_shutdown cage fight
  xfs: AIL should be log centric
  xfs: log items should have a xlog pointer, not a mount
  xfs: async CIL flushes need pending pushes to be made stable
  xfs: xfs_ail_push_all_sync() stalls when racing with updates
  xfs: check buffer pin state after locking in delwri_submit
  xfs: log worker needs to start before intent/unlink recovery
  xfs: constify xfs_name_dotdot
  xfs: constify the name argument to various directory functions
  xfs: reserve quota for target dir expansion when renaming files
  xfs: reserve quota for dir expansion when linking/unlinking files
  xfs: refactor user/group quota chown in xfs_setattr_nonsize
  xfs: use setattr_copy to set vfs inode attributes
  xfs: don't generate selinux audit messages for capability testing
  xfs: add missing cmap->br_state = XFS_EXT_NORM update
parents f0614eef 01728b44
Loading
Loading
Loading
Loading
+20 −16
Original line number Diff line number Diff line
@@ -19,7 +19,11 @@
#include "xfs_error.h"
#include "xfs_trace.h"

struct xfs_name xfs_name_dotdot = { (unsigned char *)"..", 2, XFS_DIR3_FT_DIR };
const struct xfs_name xfs_name_dotdot = {
	.name	= (const unsigned char *)"..",
	.len	= 2,
	.type	= XFS_DIR3_FT_DIR,
};

/*
 * Convert inode mode to directory entry filetype
@@ -54,7 +58,7 @@ xfs_mode_to_ftype(
 */
xfs_dahash_t
xfs_ascii_ci_hashname(
	struct xfs_name	*name)
	const struct xfs_name	*name)
{
	xfs_dahash_t		hash;
	int			i;
@@ -243,7 +247,7 @@ int
xfs_dir_createname(
	struct xfs_trans	*tp,
	struct xfs_inode	*dp,
	struct xfs_name		*name,
	const struct xfs_name	*name,
	xfs_ino_t		inum,		/* new entry inode number */
	xfs_extlen_t		total)		/* bmap's total block count */
{
@@ -337,9 +341,9 @@ xfs_dir_cilookup_result(

int
xfs_dir_lookup(
	xfs_trans_t	*tp,
	xfs_inode_t	*dp,
	struct xfs_name	*name,
	struct xfs_trans	*tp,
	struct xfs_inode	*dp,
	const struct xfs_name	*name,
	xfs_ino_t		*inum,	  /* out: inode number */
	struct xfs_name		*ci_name) /* out: actual name if CI match */
{
@@ -475,7 +479,7 @@ int
xfs_dir_replace(
	struct xfs_trans	*tp,
	struct xfs_inode	*dp,
	struct xfs_name		*name,		/* name of entry to replace */
	const struct xfs_name	*name,		/* name of entry to replace */
	xfs_ino_t		inum,		/* new inode number */
	xfs_extlen_t		total)		/* bmap's total block count */
{
@@ -728,7 +732,7 @@ xfs_dir2_namecheck(
xfs_dahash_t
xfs_dir2_hashname(
	struct xfs_mount	*mp,
	struct xfs_name		*name)
	const struct xfs_name	*name)
{
	if (unlikely(xfs_has_asciici(mp)))
		return xfs_ascii_ci_hashname(name);
+4 −4
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ struct xfs_dir2_data_unused;
struct xfs_dir3_icfree_hdr;
struct xfs_dir3_icleaf_hdr;

extern struct xfs_name	xfs_name_dotdot;
extern const struct xfs_name	xfs_name_dotdot;

/*
 * Convert inode mode to directory entry filetype
@@ -39,16 +39,16 @@ extern int xfs_dir_isempty(struct xfs_inode *dp);
extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp,
				struct xfs_inode *pdp);
extern int xfs_dir_createname(struct xfs_trans *tp, struct xfs_inode *dp,
				struct xfs_name *name, xfs_ino_t inum,
				const struct xfs_name *name, xfs_ino_t inum,
				xfs_extlen_t tot);
extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp,
				struct xfs_name *name, xfs_ino_t *inum,
				const struct xfs_name *name, xfs_ino_t *inum,
				struct xfs_name *ci_name);
extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp,
				struct xfs_name *name, xfs_ino_t ino,
				xfs_extlen_t tot);
extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp,
				struct xfs_name *name, xfs_ino_t inum,
				const struct xfs_name *name, xfs_ino_t inum,
				xfs_extlen_t tot);
extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp,
				struct xfs_name *name);
+3 −2
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ struct xfs_dir3_icfree_hdr {
};

/* xfs_dir2.c */
xfs_dahash_t xfs_ascii_ci_hashname(struct xfs_name *name);
xfs_dahash_t xfs_ascii_ci_hashname(const struct xfs_name *name);
enum xfs_dacmp xfs_ascii_ci_compname(struct xfs_da_args *args,
		const unsigned char *name, int len);
extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
@@ -201,7 +201,8 @@ xfs_dir2_data_entsize(
	return round_up(len, XFS_DIR2_DATA_ALIGN);
}

xfs_dahash_t xfs_dir2_hashname(struct xfs_mount *mp, struct xfs_name *name);
xfs_dahash_t xfs_dir2_hashname(struct xfs_mount *mp,
		const struct xfs_name *name);
enum xfs_dacmp xfs_dir2_compname(struct xfs_da_args *args,
		const unsigned char *name, int len);

+1 −1
Original line number Diff line number Diff line
@@ -463,7 +463,7 @@ xfs_bui_item_recover(
	struct xfs_bui_log_item		*buip = BUI_ITEM(lip);
	struct xfs_trans		*tp;
	struct xfs_inode		*ip = NULL;
	struct xfs_mount		*mp = lip->li_mountp;
	struct xfs_mount		*mp = lip->li_log->l_mp;
	struct xfs_map_extent		*bmap;
	struct xfs_bud_log_item		*budp;
	xfs_filblks_t			count;
+35 −10
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include "xfs_trace.h"
#include "xfs_log.h"
#include "xfs_log_recover.h"
#include "xfs_log_priv.h"
#include "xfs_trans.h"
#include "xfs_buf_item.h"
#include "xfs_errortag.h"
@@ -813,7 +814,15 @@ xfs_buf_read_map(
	 * buffer.
	 */
	if (error) {
		if (!xfs_is_shutdown(target->bt_mount))
		/*
		 * Check against log shutdown for error reporting because
		 * metadata writeback may require a read first and we need to
		 * report errors in metadata writeback until the log is shut
		 * down. High level transaction read functions already check
		 * against mount shutdown, anyway, so we only need to be
		 * concerned about low level IO interactions here.
		 */
		if (!xlog_is_shutdown(target->bt_mount->m_log))
			xfs_buf_ioerror_alert(bp, fa);

		bp->b_flags &= ~XBF_DONE;
@@ -1174,10 +1183,10 @@ xfs_buf_ioend_handle_error(
	struct xfs_error_cfg	*cfg;

	/*
	 * If we've already decided to shutdown the filesystem because of I/O
	 * errors, there's no point in giving this a retry.
	 * If we've already shutdown the journal because of I/O errors, there's
	 * no point in giving this a retry.
	 */
	if (xfs_is_shutdown(mp))
	if (xlog_is_shutdown(mp->m_log))
		goto out_stale;

	xfs_buf_ioerror_alert_ratelimited(bp);
@@ -1588,8 +1597,23 @@ __xfs_buf_submit(

	ASSERT(!(bp->b_flags & _XBF_DELWRI_Q));

	/* on shutdown we stale and complete the buffer immediately */
	if (xfs_is_shutdown(bp->b_mount)) {
	/*
	 * On log shutdown we stale and complete the buffer immediately. We can
	 * be called to read the superblock before the log has been set up, so
	 * be careful checking the log state.
	 *
	 * Checking the mount shutdown state here can result in the log tail
	 * moving inappropriately on disk as the log may not yet be shut down.
	 * i.e. failing this buffer on mount shutdown can remove it from the AIL
	 * and move the tail of the log forwards without having written this
	 * buffer to disk. This corrupts the log tail state in memory, and
	 * because the log may not be shut down yet, it can then be propagated
	 * to disk before the log is shutdown. Hence we check log shutdown
	 * state here rather than mount state to avoid corrupting the log tail
	 * on shutdown.
	 */
	if (bp->b_mount->m_log &&
	    xlog_is_shutdown(bp->b_mount->m_log)) {
		xfs_buf_ioend_fail(bp);
		return -EIO;
	}
@@ -1803,10 +1827,10 @@ xfs_buftarg_drain(
	 * If one or more failed buffers were freed, that means dirty metadata
	 * was thrown away. This should only ever happen after I/O completion
	 * handling has elevated I/O error(s) to permanent failures and shuts
	 * down the fs.
	 * down the journal.
	 */
	if (write_fail) {
		ASSERT(xfs_is_shutdown(btp->bt_mount));
		ASSERT(xlog_is_shutdown(btp->bt_mount->m_log));
		xfs_alert(btp->bt_mount,
	      "Please run xfs_repair to determine the extent of the problem.");
	}
@@ -2089,12 +2113,13 @@ xfs_buf_delwri_submit_buffers(
	blk_start_plug(&plug);
	list_for_each_entry_safe(bp, n, buffer_list, b_list) {
		if (!wait_list) {
			if (!xfs_buf_trylock(bp))
				continue;
			if (xfs_buf_ispinned(bp)) {
				xfs_buf_unlock(bp);
				pinned++;
				continue;
			}
			if (!xfs_buf_trylock(bp))
				continue;
		} else {
			xfs_buf_lock(bp);
		}
Loading