Skip to content

Commit b1b07ba

Browse files
committed
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
2 parents f0614ee + 01728b4 commit b1b07ba

27 files changed

Lines changed: 344 additions & 211 deletions

fs/xfs/libxfs/xfs_dir2.c

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@
1919
#include "xfs_error.h"
2020
#include "xfs_trace.h"
2121

22-
struct xfs_name xfs_name_dotdot = { (unsigned char *)"..", 2, XFS_DIR3_FT_DIR };
22+
const struct xfs_name xfs_name_dotdot = {
23+
.name = (const unsigned char *)"..",
24+
.len = 2,
25+
.type = XFS_DIR3_FT_DIR,
26+
};
2327

2428
/*
2529
* Convert inode mode to directory entry filetype
@@ -54,10 +58,10 @@ xfs_mode_to_ftype(
5458
*/
5559
xfs_dahash_t
5660
xfs_ascii_ci_hashname(
57-
struct xfs_name *name)
61+
const struct xfs_name *name)
5862
{
59-
xfs_dahash_t hash;
60-
int i;
63+
xfs_dahash_t hash;
64+
int i;
6165

6266
for (i = 0, hash = 0; i < name->len; i++)
6367
hash = tolower(name->name[i]) ^ rol32(hash, 7);
@@ -243,7 +247,7 @@ int
243247
xfs_dir_createname(
244248
struct xfs_trans *tp,
245249
struct xfs_inode *dp,
246-
struct xfs_name *name,
250+
const struct xfs_name *name,
247251
xfs_ino_t inum, /* new entry inode number */
248252
xfs_extlen_t total) /* bmap's total block count */
249253
{
@@ -337,16 +341,16 @@ xfs_dir_cilookup_result(
337341

338342
int
339343
xfs_dir_lookup(
340-
xfs_trans_t *tp,
341-
xfs_inode_t *dp,
342-
struct xfs_name *name,
343-
xfs_ino_t *inum, /* out: inode number */
344-
struct xfs_name *ci_name) /* out: actual name if CI match */
344+
struct xfs_trans *tp,
345+
struct xfs_inode *dp,
346+
const struct xfs_name *name,
347+
xfs_ino_t *inum, /* out: inode number */
348+
struct xfs_name *ci_name) /* out: actual name if CI match */
345349
{
346-
struct xfs_da_args *args;
347-
int rval;
348-
int v; /* type-checking value */
349-
int lock_mode;
350+
struct xfs_da_args *args;
351+
int rval;
352+
int v; /* type-checking value */
353+
int lock_mode;
350354

351355
ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
352356
XFS_STATS_INC(dp->i_mount, xs_dir_lookup);
@@ -475,7 +479,7 @@ int
475479
xfs_dir_replace(
476480
struct xfs_trans *tp,
477481
struct xfs_inode *dp,
478-
struct xfs_name *name, /* name of entry to replace */
482+
const struct xfs_name *name, /* name of entry to replace */
479483
xfs_ino_t inum, /* new inode number */
480484
xfs_extlen_t total) /* bmap's total block count */
481485
{
@@ -728,7 +732,7 @@ xfs_dir2_namecheck(
728732
xfs_dahash_t
729733
xfs_dir2_hashname(
730734
struct xfs_mount *mp,
731-
struct xfs_name *name)
735+
const struct xfs_name *name)
732736
{
733737
if (unlikely(xfs_has_asciici(mp)))
734738
return xfs_ascii_ci_hashname(name);

fs/xfs/libxfs/xfs_dir2.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct xfs_dir2_data_unused;
2121
struct xfs_dir3_icfree_hdr;
2222
struct xfs_dir3_icleaf_hdr;
2323

24-
extern struct xfs_name xfs_name_dotdot;
24+
extern const struct xfs_name xfs_name_dotdot;
2525

2626
/*
2727
* Convert inode mode to directory entry filetype
@@ -39,16 +39,16 @@ extern int xfs_dir_isempty(struct xfs_inode *dp);
3939
extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp,
4040
struct xfs_inode *pdp);
4141
extern int xfs_dir_createname(struct xfs_trans *tp, struct xfs_inode *dp,
42-
struct xfs_name *name, xfs_ino_t inum,
42+
const struct xfs_name *name, xfs_ino_t inum,
4343
xfs_extlen_t tot);
4444
extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp,
45-
struct xfs_name *name, xfs_ino_t *inum,
45+
const struct xfs_name *name, xfs_ino_t *inum,
4646
struct xfs_name *ci_name);
4747
extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp,
4848
struct xfs_name *name, xfs_ino_t ino,
4949
xfs_extlen_t tot);
5050
extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp,
51-
struct xfs_name *name, xfs_ino_t inum,
51+
const struct xfs_name *name, xfs_ino_t inum,
5252
xfs_extlen_t tot);
5353
extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp,
5454
struct xfs_name *name);

fs/xfs/libxfs/xfs_dir2_priv.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ struct xfs_dir3_icfree_hdr {
4040
};
4141

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

204-
xfs_dahash_t xfs_dir2_hashname(struct xfs_mount *mp, struct xfs_name *name);
204+
xfs_dahash_t xfs_dir2_hashname(struct xfs_mount *mp,
205+
const struct xfs_name *name);
205206
enum xfs_dacmp xfs_dir2_compname(struct xfs_da_args *args,
206207
const unsigned char *name, int len);
207208

fs/xfs/xfs_bmap_item.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ xfs_bui_item_recover(
463463
struct xfs_bui_log_item *buip = BUI_ITEM(lip);
464464
struct xfs_trans *tp;
465465
struct xfs_inode *ip = NULL;
466-
struct xfs_mount *mp = lip->li_mountp;
466+
struct xfs_mount *mp = lip->li_log->l_mp;
467467
struct xfs_map_extent *bmap;
468468
struct xfs_bud_log_item *budp;
469469
xfs_filblks_t count;

fs/xfs/xfs_buf.c

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "xfs_trace.h"
1515
#include "xfs_log.h"
1616
#include "xfs_log_recover.h"
17+
#include "xfs_log_priv.h"
1718
#include "xfs_trans.h"
1819
#include "xfs_buf_item.h"
1920
#include "xfs_errortag.h"
@@ -813,7 +814,15 @@ xfs_buf_read_map(
813814
* buffer.
814815
*/
815816
if (error) {
816-
if (!xfs_is_shutdown(target->bt_mount))
817+
/*
818+
* Check against log shutdown for error reporting because
819+
* metadata writeback may require a read first and we need to
820+
* report errors in metadata writeback until the log is shut
821+
* down. High level transaction read functions already check
822+
* against mount shutdown, anyway, so we only need to be
823+
* concerned about low level IO interactions here.
824+
*/
825+
if (!xlog_is_shutdown(target->bt_mount->m_log))
817826
xfs_buf_ioerror_alert(bp, fa);
818827

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

11761185
/*
1177-
* If we've already decided to shutdown the filesystem because of I/O
1178-
* errors, there's no point in giving this a retry.
1186+
* If we've already shutdown the journal because of I/O errors, there's
1187+
* no point in giving this a retry.
11791188
*/
1180-
if (xfs_is_shutdown(mp))
1189+
if (xlog_is_shutdown(mp->m_log))
11811190
goto out_stale;
11821191

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

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

1591-
/* on shutdown we stale and complete the buffer immediately */
1592-
if (xfs_is_shutdown(bp->b_mount)) {
1600+
/*
1601+
* On log shutdown we stale and complete the buffer immediately. We can
1602+
* be called to read the superblock before the log has been set up, so
1603+
* be careful checking the log state.
1604+
*
1605+
* Checking the mount shutdown state here can result in the log tail
1606+
* moving inappropriately on disk as the log may not yet be shut down.
1607+
* i.e. failing this buffer on mount shutdown can remove it from the AIL
1608+
* and move the tail of the log forwards without having written this
1609+
* buffer to disk. This corrupts the log tail state in memory, and
1610+
* because the log may not be shut down yet, it can then be propagated
1611+
* to disk before the log is shutdown. Hence we check log shutdown
1612+
* state here rather than mount state to avoid corrupting the log tail
1613+
* on shutdown.
1614+
*/
1615+
if (bp->b_mount->m_log &&
1616+
xlog_is_shutdown(bp->b_mount->m_log)) {
15931617
xfs_buf_ioend_fail(bp);
15941618
return -EIO;
15951619
}
@@ -1803,10 +1827,10 @@ xfs_buftarg_drain(
18031827
* If one or more failed buffers were freed, that means dirty metadata
18041828
* was thrown away. This should only ever happen after I/O completion
18051829
* handling has elevated I/O error(s) to permanent failures and shuts
1806-
* down the fs.
1830+
* down the journal.
18071831
*/
18081832
if (write_fail) {
1809-
ASSERT(xfs_is_shutdown(btp->bt_mount));
1833+
ASSERT(xlog_is_shutdown(btp->bt_mount->m_log));
18101834
xfs_alert(btp->bt_mount,
18111835
"Please run xfs_repair to determine the extent of the problem.");
18121836
}
@@ -2089,12 +2113,13 @@ xfs_buf_delwri_submit_buffers(
20892113
blk_start_plug(&plug);
20902114
list_for_each_entry_safe(bp, n, buffer_list, b_list) {
20912115
if (!wait_list) {
2116+
if (!xfs_buf_trylock(bp))
2117+
continue;
20922118
if (xfs_buf_ispinned(bp)) {
2119+
xfs_buf_unlock(bp);
20932120
pinned++;
20942121
continue;
20952122
}
2096-
if (!xfs_buf_trylock(bp))
2097-
continue;
20982123
} else {
20992124
xfs_buf_lock(bp);
21002125
}

fs/xfs/xfs_buf_item.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "xfs_dquot.h"
2222
#include "xfs_trace.h"
2323
#include "xfs_log.h"
24+
#include "xfs_log_priv.h"
2425

2526

2627
struct kmem_cache *xfs_buf_item_cache;
@@ -428,7 +429,7 @@ xfs_buf_item_format(
428429
* occurs during recovery.
429430
*/
430431
if (bip->bli_flags & XFS_BLI_INODE_BUF) {
431-
if (xfs_has_v3inodes(lip->li_mountp) ||
432+
if (xfs_has_v3inodes(lip->li_log->l_mp) ||
432433
!((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) &&
433434
xfs_log_item_in_current_chkpt(lip)))
434435
bip->__bli_format.blf_flags |= XFS_BLF_INODE_BUF;
@@ -616,7 +617,7 @@ xfs_buf_item_put(
616617
* that case, the bli is freed on buffer writeback completion.
617618
*/
618619
aborted = test_bit(XFS_LI_ABORTED, &lip->li_flags) ||
619-
xfs_is_shutdown(lip->li_mountp);
620+
xlog_is_shutdown(lip->li_log);
620621
dirty = bip->bli_flags & XFS_BLI_DIRTY;
621622
if (dirty && !aborted)
622623
return false;

fs/xfs/xfs_extfree_item.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ xfs_efi_item_recover(
604604
struct list_head *capture_list)
605605
{
606606
struct xfs_efi_log_item *efip = EFI_ITEM(lip);
607-
struct xfs_mount *mp = lip->li_mountp;
607+
struct xfs_mount *mp = lip->li_log->l_mp;
608608
struct xfs_efd_log_item *efdp;
609609
struct xfs_trans *tp;
610610
struct xfs_extent *extp;

fs/xfs/xfs_fsmap.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -864,8 +864,8 @@ xfs_getfsmap(
864864
!xfs_getfsmap_is_valid_device(mp, &head->fmh_keys[1]))
865865
return -EINVAL;
866866

867-
use_rmap = capable(CAP_SYS_ADMIN) &&
868-
xfs_has_rmapbt(mp);
867+
use_rmap = xfs_has_rmapbt(mp) &&
868+
has_capability_noaudit(current, CAP_SYS_ADMIN);
869869
head->fmh_entries = 0;
870870

871871
/* Set up our device handlers. */

fs/xfs/xfs_icache.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "xfs_reflink.h"
2424
#include "xfs_ialloc.h"
2525
#include "xfs_ag.h"
26+
#include "xfs_log_priv.h"
2627

2728
#include <linux/iversion.h>
2829

@@ -873,7 +874,14 @@ xfs_reclaim_inode(
873874
if (xfs_iflags_test_and_set(ip, XFS_IFLUSHING))
874875
goto out_iunlock;
875876

876-
if (xfs_is_shutdown(ip->i_mount)) {
877+
/*
878+
* Check for log shutdown because aborting the inode can move the log
879+
* tail and corrupt in memory state. This is fine if the log is shut
880+
* down, but if the log is still active and only the mount is shut down
881+
* then the in-memory log tail movement caused by the abort can be
882+
* incorrectly propagated to disk.
883+
*/
884+
if (xlog_is_shutdown(ip->i_mount->m_log)) {
877885
xfs_iunpin_wait(ip);
878886
xfs_iflush_abort(ip);
879887
goto reclaim;

0 commit comments

Comments
 (0)