Commit Graph

166 Commits

Author SHA1 Message Date
Bill O'Donnell 92b27a0cae xfs: reset XFS_ATTR_INCOMPLETE filter on node removal
JIRA: https://issues.redhat.com/browse/RHEL-65728

commit 82ef1a5356572219f41f9123ca047259a77bd67b
Author: Andrey Albershteyn <aalbersh@redhat.com>
Date:   Wed Jan 24 11:26:44 2024 +0100

    xfs: reset XFS_ATTR_INCOMPLETE filter on node removal

    In XFS_DAS_NODE_REMOVE_ATTR case, xfs_attr_mode_remove_attr() sets
    filter to XFS_ATTR_INCOMPLETE. The filter is then reset in
    xfs_attr_complete_op() if XFS_DA_OP_REPLACE operation is performed.

    The filter is not reset though if XFS just removes the attribute
    (args->value == NULL) with xfs_attr_defer_remove(). attr code goes
    to XFS_DAS_DONE state.

    Fix this by always resetting XFS_ATTR_INCOMPLETE filter. The replace
    operation already resets this filter in anyway and others are
    completed at this step hence don't need it.

    Fixes: fdaf1bb3cafc ("xfs: ATTR_REPLACE algorithm with LARP enabled needs rework")
    Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
    Reviewed-by: Christoph Hellwig <hch@lst.de>
    Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2024-11-20 11:26:21 -06:00
Bill O'Donnell b2b5014adf xfs: turn the XFS_DA_OP_REPLACE checks in xfs_attr_shortform_addname into asserts
JIRA: https://issues.redhat.com/browse/RHEL-65728

commit 378b6aef9de0f7c3d0de309ecc61c11eb29e57da
Author: Christoph Hellwig <hch@lst.de>
Date:   Wed Dec 20 07:35:03 2023 +0100

    xfs: turn the XFS_DA_OP_REPLACE checks in xfs_attr_shortform_addname into asserts

    Since commit deed951287 ("xfs: Check for -ENOATTR or -EEXIST"), the
    high-level attr code does a lookup for any attr we're trying to set,
    and does the checks to handle the create vs replace cases, which thus
    never hit the low-level attr code.

    Turn the checks in xfs_attr_shortform_addname as they must never trip.

    Signed-off-by: Christoph Hellwig <hch@lst.de>
    Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
    Reviewed-by: Dave Chinner <dchinner@redhat.com>
    Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2024-11-20 11:26:20 -06:00
Bill O'Donnell e21282d525 xfs: remove struct xfs_attr_shortform
JIRA: https://issues.redhat.com/browse/RHEL-65728

commit 414147225400a0c4562ebfb0fdd40f065099ede4
Author: Christoph Hellwig <hch@lst.de>
Date:   Wed Dec 20 07:35:01 2023 +0100

    xfs: remove struct xfs_attr_shortform

    sparse complains about struct xfs_attr_shortform because it embeds a
    structure with a variable sized array in a variable sized array.

    Given that xfs_attr_shortform is not a very useful structure, and the
    dir2 equivalent has been removed a long time ago, remove it as well.

    Provide a xfs_attr_sf_firstentry helper that returns the first
    xfs_attr_sf_entry behind a xfs_attr_sf_hdr to replace the structure
    dereference.

    Signed-off-by: Christoph Hellwig <hch@lst.de>
    Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
    Reviewed-by: Dave Chinner <dchinner@redhat.com>
    Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2024-11-20 11:26:19 -06:00
Bill O'Donnell 017b1c033f xfs: remove xfs_attr_shortform_lookup
JIRA: https://issues.redhat.com/browse/RHEL-65728

commit 22b7b1f597a6a21fb7b3791a55f3a7ae54d2dfe4
Author: Christoph Hellwig <hch@lst.de>
Date:   Wed Dec 20 07:34:59 2023 +0100

    xfs: remove xfs_attr_shortform_lookup

    xfs_attr_shortform_lookup is only used by xfs_attr_shortform_addname,
    which is much better served by calling xfs_attr_sf_findname.  Switch
    it over and remove xfs_attr_shortform_lookup.

    Signed-off-by: Christoph Hellwig <hch@lst.de>
    Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
    Reviewed-by: Dave Chinner <dchinner@redhat.com>
    Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2024-11-20 11:26:18 -06:00
Bill O'Donnell ac3b5d5adb xfs: simplify xfs_attr_sf_findname
JIRA: https://issues.redhat.com/browse/RHEL-65728

commit 6c8d169bbd51fc10d1d0029d495962881315b4c2
Author: Christoph Hellwig <hch@lst.de>
Date:   Wed Dec 20 07:34:58 2023 +0100

    xfs: simplify xfs_attr_sf_findname

    xfs_attr_sf_findname has the simple job of finding a xfs_attr_sf_entry in
    the attr fork, but the convoluted calling convention obfuscates that.

    Return the found entry as the return value instead of an pointer
    argument, as the -ENOATTR/-EEXIST can be trivally derived from that, and
    remove the basep argument, as it is equivalent of the offset of sfe in
    the data for if an sfe was found, or an offset of totsize if not was
    found.  To simplify the totsize computation add a xfs_attr_sf_endptr
    helper that returns the imaginative xfs_attr_sf_entry at the end of
    the current attrs.

    Signed-off-by: Christoph Hellwig <hch@lst.de>
    Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
    Reviewed-by: Dave Chinner <dchinner@redhat.com>
    Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2024-11-20 11:26:18 -06:00
Bill O'Donnell 86c0442471 xfs: make if_data a void pointer
JIRA: https://issues.redhat.com/browse/RHEL-65728

commit 6e145f943bd86be47e54101fa5939f9ed0cb73e5
Author: Christoph Hellwig <hch@lst.de>
Date:   Wed Dec 20 07:34:55 2023 +0100

    xfs: make if_data a void pointer

    The xfs_ifork structure currently has a union of the if_root void pointer
    and the if_data char pointer.  In either case it is an opaque pointer
    that depends on the fork format.  Replace the union with a single if_data
    void pointer as that is what almost all callers want.  Only the symlink
    NULL termination code in xfs_init_local_fork actually needs a new local
    variable now.

    Signed-off-by: Christoph Hellwig <hch@lst.de>
    Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
    Reviewed-by: Dave Chinner <dchinner@redhat.com>
    Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2024-11-20 11:26:17 -06:00
Bill O'Donnell 488519dd5a xfs: pass the defer ops directly to xfs_defer_add
JIRA: https://issues.redhat.com/browse/RHEL-65728

commit 603ce8ab12094a2d9483c79a7541335e258a5328
Author: Christoph Hellwig <hch@lst.de>
Date:   Wed Dec 13 10:06:33 2023 +0100

    xfs: pass the defer ops directly to xfs_defer_add

    Pass a pointer to the xfs_defer_op_type structure to xfs_defer_add and
    remove the indirection through the xfs_defer_ops_type enum and a global
    table of all possible operations.

    Signed-off-by: Christoph Hellwig <hch@lst.de>
    Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
    Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2024-11-20 11:26:00 -06:00
Bill O'Donnell 13ab201485 xfs: consolidate the xfs_attr_defer_* helpers
JIRA: https://issues.redhat.com/browse/RHEL-65728

commit c00eebd09e95757c9c1d08f0a6bbc32c543daf90
Author: Christoph Hellwig <hch@lst.de>
Date:   Wed Dec 13 10:06:29 2023 +0100

    xfs: consolidate the xfs_attr_defer_* helpers

    Consolidate the xfs_attr_defer_* helpers into a single xfs_attr_defer_add
    one that picks the right dela_state based on the passed in operation.
    Also move to a single trace point as the actual operation is visible
    through the flags in the delta_state passed to the trace point.

    Signed-off-by: Christoph Hellwig <hch@lst.de>
    Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
    Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2024-11-20 11:25:58 -06:00
Pavel Reichl 63883fef2b xfs: allow SECURE namespace xattrs to use reserved block pool
This is derived from upstream commit 39c1ddb064fd ("xfs: allow SECURE
	namespace xattrs to use reserved block pool").

JIRA: https://issues.redhat.com/browse/RHEL-49806
Upstream Status: RHEL-only

Signed-off-by: Pavel Reichl <preichl@redhat.com>
2024-08-14 17:13:25 +02:00
Bill O'Donnell f77675b5d0 xfs: replace XFS_IFORK_Q with a proper predicate function
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit 932b42c66cb5d0ca9800b128415b4ad6b1952b3e
Author: Darrick J. Wong <djwong@kernel.org>
Date:   Sat Jul 9 10:56:06 2022 -0700

    xfs: replace XFS_IFORK_Q with a proper predicate function

    Replace this shouty macro with a real C function that has a more
    descriptive name.

    Signed-off-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Dave Chinner <dchinner@redhat.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:43 -05:00
Bill O'Donnell 0036098801 xfs: use XFS_IFORK_Q to determine the presence of an xattr fork
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit e45d7cb2356e6b59fe64da28324025cc6fcd3fbd
Author: Darrick J. Wong <djwong@kernel.org>
Date:   Sat Jul 9 10:56:06 2022 -0700

    xfs: use XFS_IFORK_Q to determine the presence of an xattr fork

    Modify xfs_ifork_ptr to return a NULL pointer if the caller asks for the
    attribute fork but i_forkoff is zero.  This eliminates the ambiguity
    between i_forkoff and i_af.if_present, which should make it easier to
    understand the lifetime of attr forks.

    While we're at it, remove the if_present checks around calls to
    xfs_idestroy_fork and xfs_ifork_zap_attr since they can both handle attr
    forks that have already been torn down.

    Signed-off-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Dave Chinner <dchinner@redhat.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:43 -05:00
Bill O'Donnell a2d362f29a xfs: make inode attribute forks a permanent part of struct xfs_inode
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

Conflicts: previous out of order application of 5625ea0 requires minor adjust to xfs_iomap.c

commit 2ed5b09b3e8fc274ae8fecd6ab7c5106a364bed1
Author: Darrick J. Wong <djwong@kernel.org>
Date:   Sat Jul 9 10:56:06 2022 -0700

    xfs: make inode attribute forks a permanent part of struct xfs_inode

    Syzkaller reported a UAF bug a while back:

    ==================================================================
    BUG: KASAN: use-after-free in xfs_ilock_attr_map_shared+0xe3/0xf6 fs/xfs/xfs_inode.c:127
    Read of size 4 at addr ffff88802cec919c by task syz-executor262/2958

    CPU: 2 PID: 2958 Comm: syz-executor262 Not tainted
    5.15.0-0.30.3-20220406_1406 #3
    Hardware name: Red Hat KVM, BIOS 1.13.0-2.module+el8.3.0+7860+a7792d29
    04/01/2014
    Call Trace:
     <TASK>
     __dump_stack lib/dump_stack.c:88 [inline]
     dump_stack_lvl+0x82/0xa9 lib/dump_stack.c:106
     print_address_description.constprop.9+0x21/0x2d5 mm/kasan/report.c:256
     __kasan_report mm/kasan/report.c:442 [inline]
     kasan_report.cold.14+0x7f/0x11b mm/kasan/report.c:459
     xfs_ilock_attr_map_shared+0xe3/0xf6 fs/xfs/xfs_inode.c:127
     xfs_attr_get+0x378/0x4c2 fs/xfs/libxfs/xfs_attr.c:159
     xfs_xattr_get+0xe3/0x150 fs/xfs/xfs_xattr.c:36
     __vfs_getxattr+0xdf/0x13d fs/xattr.c:399
     cap_inode_need_killpriv+0x41/0x5d security/commoncap.c:300
     security_inode_need_killpriv+0x4c/0x97 security/security.c:1408
     dentry_needs_remove_privs.part.28+0x21/0x63 fs/inode.c:1912
     dentry_needs_remove_privs+0x80/0x9e fs/inode.c:1908
     do_truncate+0xc3/0x1e0 fs/open.c:56
     handle_truncate fs/namei.c:3084 [inline]
     do_open fs/namei.c:3432 [inline]
     path_openat+0x30ab/0x396d fs/namei.c:3561
     do_filp_open+0x1c4/0x290 fs/namei.c:3588
     do_sys_openat2+0x60d/0x98c fs/open.c:1212
     do_sys_open+0xcf/0x13c fs/open.c:1228
     do_syscall_x64 arch/x86/entry/common.c:50 [inline]
     do_syscall_64+0x3a/0x7e arch/x86/entry/common.c:80
     entry_SYSCALL_64_after_hwframe+0x44/0x0
    RIP: 0033:0x7f7ef4bb753d
    Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48
    89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73
    01 c3 48 8b 0d 1b 79 2c 00 f7 d8 64 89 01 48
    RSP: 002b:00007f7ef52c2ed8 EFLAGS: 00000246 ORIG_RAX: 0000000000000055
    RAX: ffffffffffffffda RBX: 0000000000404148 RCX: 00007f7ef4bb753d
    RDX: 00007f7ef4bb753d RSI: 0000000000000000 RDI: 0000000020004fc0
    RBP: 0000000000404140 R08: 0000000000000000 R09: 0000000000000000
    R10: 0000000000000000 R11: 0000000000000246 R12: 0030656c69662f2e
    R13: 00007ffd794db37f R14: 00007ffd794db470 R15: 00007f7ef52c2fc0
     </TASK>

    Allocated by task 2953:
     kasan_save_stack+0x19/0x38 mm/kasan/common.c:38
     kasan_set_track mm/kasan/common.c:46 [inline]
     set_alloc_info mm/kasan/common.c:434 [inline]
     __kasan_slab_alloc+0x68/0x7c mm/kasan/common.c:467
     kasan_slab_alloc include/linux/kasan.h:254 [inline]
     slab_post_alloc_hook mm/slab.h:519 [inline]
     slab_alloc_node mm/slub.c:3213 [inline]
     slab_alloc mm/slub.c:3221 [inline]
     kmem_cache_alloc+0x11b/0x3eb mm/slub.c:3226
     kmem_cache_zalloc include/linux/slab.h:711 [inline]
     xfs_ifork_alloc+0x25/0xa2 fs/xfs/libxfs/xfs_inode_fork.c:287
     xfs_bmap_add_attrfork+0x3f2/0x9b1 fs/xfs/libxfs/xfs_bmap.c:1098
     xfs_attr_set+0xe38/0x12a7 fs/xfs/libxfs/xfs_attr.c:746
     xfs_xattr_set+0xeb/0x1a9 fs/xfs/xfs_xattr.c:59
     __vfs_setxattr+0x11b/0x177 fs/xattr.c:180
     __vfs_setxattr_noperm+0x128/0x5e0 fs/xattr.c:214
     __vfs_setxattr_locked+0x1d4/0x258 fs/xattr.c:275
     vfs_setxattr+0x154/0x33d fs/xattr.c:301
     setxattr+0x216/0x29f fs/xattr.c:575
     __do_sys_fsetxattr fs/xattr.c:632 [inline]
     __se_sys_fsetxattr fs/xattr.c:621 [inline]
     __x64_sys_fsetxattr+0x243/0x2fe fs/xattr.c:621
     do_syscall_x64 arch/x86/entry/common.c:50 [inline]
     do_syscall_64+0x3a/0x7e arch/x86/entry/common.c:80
     entry_SYSCALL_64_after_hwframe+0x44/0x0

    Freed by task 2949:
     kasan_save_stack+0x19/0x38 mm/kasan/common.c:38
     kasan_set_track+0x1c/0x21 mm/kasan/common.c:46
     kasan_set_free_info+0x20/0x30 mm/kasan/generic.c:360
     ____kasan_slab_free mm/kasan/common.c:366 [inline]
     ____kasan_slab_free mm/kasan/common.c:328 [inline]
     __kasan_slab_free+0xe2/0x10e mm/kasan/common.c:374
     kasan_slab_free include/linux/kasan.h:230 [inline]
     slab_free_hook mm/slub.c:1700 [inline]
     slab_free_freelist_hook mm/slub.c:1726 [inline]
     slab_free mm/slub.c:3492 [inline]
     kmem_cache_free+0xdc/0x3ce mm/slub.c:3508
     xfs_attr_fork_remove+0x8d/0x132 fs/xfs/libxfs/xfs_attr_leaf.c:773
     xfs_attr_sf_removename+0x5dd/0x6cb fs/xfs/libxfs/xfs_attr_leaf.c:822
     xfs_attr_remove_iter+0x68c/0x805 fs/xfs/libxfs/xfs_attr.c:1413
     xfs_attr_remove_args+0xb1/0x10d fs/xfs/libxfs/xfs_attr.c:684
     xfs_attr_set+0xf1e/0x12a7 fs/xfs/libxfs/xfs_attr.c:802
     xfs_xattr_set+0xeb/0x1a9 fs/xfs/xfs_xattr.c:59
     __vfs_removexattr+0x106/0x16a fs/xattr.c:468
     cap_inode_killpriv+0x24/0x47 security/commoncap.c:324
     security_inode_killpriv+0x54/0xa1 security/security.c:1414
     setattr_prepare+0x1a6/0x897 fs/attr.c:146
     xfs_vn_change_ok+0x111/0x15e fs/xfs/xfs_iops.c:682
     xfs_vn_setattr_size+0x5f/0x15a fs/xfs/xfs_iops.c:1065
     xfs_vn_setattr+0x125/0x2ad fs/xfs/xfs_iops.c:1093
     notify_change+0xae5/0x10a1 fs/attr.c:410
     do_truncate+0x134/0x1e0 fs/open.c:64
     handle_truncate fs/namei.c:3084 [inline]
     do_open fs/namei.c:3432 [inline]
     path_openat+0x30ab/0x396d fs/namei.c:3561
     do_filp_open+0x1c4/0x290 fs/namei.c:3588
     do_sys_openat2+0x60d/0x98c fs/open.c:1212
     do_sys_open+0xcf/0x13c fs/open.c:1228
     do_syscall_x64 arch/x86/entry/common.c:50 [inline]
     do_syscall_64+0x3a/0x7e arch/x86/entry/common.c:80
     entry_SYSCALL_64_after_hwframe+0x44/0x0

    The buggy address belongs to the object at ffff88802cec9188
     which belongs to the cache xfs_ifork of size 40
    The buggy address is located 20 bytes inside of
     40-byte region [ffff88802cec9188, ffff88802cec91b0)
    The buggy address belongs to the page:
    page:00000000c3af36a1 refcount:1 mapcount:0 mapping:0000000000000000
    index:0x0 pfn:0x2cec9
    flags: 0xfffffc0000200(slab|node=0|zone=1|lastcpupid=0x1fffff)
    raw: 000fffffc0000200 ffffea00009d2580 0000000600000006 ffff88801a9ffc80
    raw: 0000000000000000 0000000080490049 00000001ffffffff 0000000000000000
    page dumped because: kasan: bad access detected

    Memory state around the buggy address:
     ffff88802cec9080: fb fb fb fc fc fa fb fb fb fb fc fc fb fb fb fb
     ffff88802cec9100: fb fc fc fb fb fb fb fb fc fc fb fb fb fb fb fc
    >ffff88802cec9180: fc fa fb fb fb fb fc fc fa fb fb fb fb fc fc fb
                                ^
     ffff88802cec9200: fb fb fb fb fc fc fb fb fb fb fb fc fc fb fb fb
     ffff88802cec9280: fb fb fc fc fa fb fb fb fb fc fc fa fb fb fb fb
    ==================================================================

    The root cause of this bug is the unlocked access to xfs_inode.i_afp
    from the getxattr code paths while trying to determine which ILOCK mode
    to use to stabilize the xattr data.  Unfortunately, the VFS does not
    acquire i_rwsem when vfs_getxattr (or listxattr) call into the
    filesystem, which means that getxattr can race with a removexattr that's
    tearing down the attr fork and crash:

    xfs_attr_set:                          xfs_attr_get:
    xfs_attr_fork_remove:                  xfs_ilock_attr_map_shared:

    xfs_idestroy_fork(ip->i_afp);
    kmem_cache_free(xfs_ifork_cache, ip->i_afp);

                                           if (ip->i_afp &&

    ip->i_afp = NULL;

                                               xfs_need_iread_extents(ip->i_afp))
                                           <KABOOM>

    ip->i_forkoff = 0;

    Regrettably, the VFS is much more lax about i_rwsem and getxattr than
    is immediately obvious -- not only does it not guarantee that we hold
    i_rwsem, it actually doesn't guarantee that we *don't* hold it either.
    The getxattr system call won't acquire the lock before calling XFS, but
    the file capabilities code calls getxattr with and without i_rwsem held
    to determine if the "security.capabilities" xattr is set on the file.

    Fixing the VFS locking requires a treewide investigation into every code
    path that could touch an xattr and what i_rwsem state it expects or sets
    up.  That could take years or even prove impossible; fortunately, we
    can fix this UAF problem inside XFS.

    An earlier version of this patch used smp_wmb in xfs_attr_fork_remove to
    ensure that i_forkoff is always zeroed before i_afp is set to null and
    changed the read paths to use smp_rmb before accessing i_forkoff and
    i_afp, which avoided these UAF problems.  However, the patch author was
    too busy dealing with other problems in the meantime, and by the time he
    came back to this issue, the situation had changed a bit.

    On a modern system with selinux, each inode will always have at least
    one xattr for the selinux label, so it doesn't make much sense to keep
    incurring the extra pointer dereference.  Furthermore, Allison's
    upcoming parent pointer patchset will also cause nearly every inode in
    the filesystem to have extended attributes.  Therefore, make the inode
    attribute fork structure part of struct xfs_inode, at a cost of 40 more
    bytes.

    This patch adds a clunky if_present field where necessary to maintain
    the existing logic of xattr fork null pointer testing in the existing
    codebase.  The next patch switches the logic over to XFS_IFORK_Q and it
    all goes away.

    Signed-off-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Dave Chinner <dchinner@redhat.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:42 -05:00
Bill O'Donnell 9ff1fe47d4 xfs: removed useless condition in function xfs_attr_node_get
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit 0f38063d7a38015a47ca1488406bf21e0effe80e
Author: Andrey Strachuk <strochuk@ispras.ru>
Date:   Sat Jul 9 10:56:02 2022 -0700

    xfs: removed useless condition in function xfs_attr_node_get

    At line 1561, variable "state" is being compared
    with NULL every loop iteration.

    -------------------------------------------------------------------
    1561    for (i = 0; state != NULL && i < state->path.active; i++) {
    1562            xfs_trans_brelse(args->trans, state->path.blk[i].bp);
    1563            state->path.blk[i].bp = NULL;
    1564    }
    -------------------------------------------------------------------

    However, it cannot be NULL.

    ----------------------------------------
    1546    state = xfs_da_state_alloc(args);
    ----------------------------------------

    xfs_da_state_alloc calls kmem_cache_zalloc. kmem_cache_zalloc is
    called with __GFP_NOFAIL flag and, therefore, it cannot return NULL.

    --------------------------------------------------------------------------
            struct xfs_da_state *
            xfs_da_state_alloc(
            struct xfs_da_args      *args)
            {
                    struct xfs_da_state     *state;

                    state = kmem_cache_zalloc(xfs_da_state_cache, GFP_NOFS | __GFP_NOFAIL);
                    state->args = args;
                    state->mp = args->dp->i_mount;
                    return state;
            }
    --------------------------------------------------------------------------

    Found by Linux Verification Center (linuxtesting.org) with SVACE.

    Signed-off-by: Andrey Strachuk <strochuk@ispras.ru>

    Fixes: 4d0cdd2bb8f0 ("xfs: clean up xfs_attr_node_hasname")
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Signed-off-by: Darrick J. Wong <djwong@kernel.org>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:42 -05:00
Bill O'Donnell 752ffec331 xfs: don't hold xattr leaf buffers across transaction rolls
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit e53bcffad0326c1ef4b4baec4262b5343e420c44
Author: Darrick J. Wong <djwong@kernel.org>
Date:   Sat Jun 25 10:01:20 2022 -0700

    xfs: don't hold xattr leaf buffers across transaction rolls

    Now that we've established (again!) that empty xattr leaf buffers are
    ok, we no longer need to bhold them to transactions when we're creating
    new leaf blocks.  Get rid of the entire mechanism, which should simplify
    the xattr code quite a bit.

    The original justification for using bhold here was to prevent the AIL
    from trying to write the empty leaf block into the fs during the brief
    time that we release the buffer lock.  The reason for /that/ was to
    prevent recovery from tripping over the empty ondisk block.

    Reviewed-by: Dave Chinner <dchinner@redhat.com>
    Signed-off-by: Darrick J. Wong <djwong@kernel.org>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:34 -05:00
Bill O'Donnell eaf46a7a2d xfs: fix variable state usage
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit 10930b254d5be1cb4350fb7a456ccd5ea7e3cbd9
Author: Darrick J. Wong <djwong@kernel.org>
Date:   Sun Jun 5 18:51:22 2022 -0700

    xfs: fix variable state usage

    The variable @args is fed to a tracepoint, and that's the only place
    it's used.  This is fine for the kernel, but for userspace, tracepoints
    are #define'd out of existence, which results in this warning on gcc
    11.2:

    xfs_attr.c: In function ‘xfs_attr_node_try_addname’:
    xfs_attr.c:1440:42: warning: unused variable ‘args’ [-Wunused-variable]
     1440 |         struct xfs_da_args              *args = attr->xattri_da_args;
          |                                          ^~~~

    Clean this up.

    Signed-off-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Dave Chinner <dchinner@redhat.com>
    Reviewed-by: Allison Henderson <allison.henderson@oracle.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:33 -05:00
Bill O'Donnell 510137b4dd xfs: fix TOCTOU race involving the new logged xattrs control knob
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit f4288f01820e2d57722d21874c1fda661003c9b9
Author: Darrick J. Wong <djwong@kernel.org>
Date:   Sun Jun 5 18:51:22 2022 -0700

    xfs: fix TOCTOU race involving the new logged xattrs control knob

    I found a race involving the larp control knob, aka the debugging knob
    that lets developers enable logging of extended attribute updates:

    Thread 1                        Thread 2

    echo 0 > /sys/fs/xfs/debug/larp
                                    setxattr(REPLACE)
                                    xfs_has_larp (returns false)
                                    xfs_attr_set

    echo 1 > /sys/fs/xfs/debug/larp

                                    xfs_attr_defer_replace
                                    xfs_attr_init_replace_state
                                    xfs_has_larp (returns true)
                                    xfs_attr_init_remove_state

                                    <oops, wrong DAS state!>

    This isn't a particularly severe problem right now because xattr logging
    is only enabled when CONFIG_XFS_DEBUG=y, and developers *should* know
    what they're doing.

    However, the eventual intent is that callers should be able to ask for
    the assistance of the log in persisting xattr updates.  This capability
    might not be required for /all/ callers, which means that dynamic
    control must work correctly.  Once an xattr update has decided whether
    or not to use logged xattrs, it needs to stay in that mode until the end
    of the operation regardless of what subsequent parallel operations might
    do.

    Therefore, it is an error to continue sampling xfs_globals.larp once
    xfs_attr_change has made a decision about larp, and it was not correct
    for me to have told Allison that ->create_intent functions can sample
    the global log incompat feature bitfield to decide to elide a log item.

    Instead, create a new op flag for the xfs_da_args structure, and convert
    all other callers of xfs_has_larp and xfs_sb_version_haslogxattrs within
    the attr update state machine to look for the operations flag.

    Signed-off-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Allison Henderson <allison.henderson@oracle.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:32 -05:00
Bill O'Donnell 7e02de7775 xfs: move xfs_attr_use_log_assist usage out of libxfs
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit efc2efeba169ff37bbd425631985064365c614e0
Author: Darrick J. Wong <djwong@kernel.org>
Date:   Fri May 27 10:34:04 2022 +1000

    xfs: move xfs_attr_use_log_assist usage out of libxfs

    The LARP patchset added an awkward coupling point between libxfs and
    what would be libxlog, if the XFS log were actually its own library.
    Move the code that sets up logged xattr updates out of libxfs and into
    xfs_xattr.c so that libxfs no longer has to know about xlog_* functions.

    Signed-off-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Dave Chinner <dchinner@redhat.com>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:32 -05:00
Bill O'Donnell 28daf69aec xfs: move xfs_attr_use_log_assist out of xfs_log.c
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit d9c61ccb3b09d8f892cccbf662ce0c870f8e4ade
Author: Darrick J. Wong <djwong@kernel.org>
Date:   Fri May 27 10:33:29 2022 +1000

    xfs: move xfs_attr_use_log_assist out of xfs_log.c

    The LARP patchset added an awkward coupling point between libxfs and
    what would be libxlog, if the XFS log were actually its own library.
    Move the code that enables logged xattr updates out of "lib"xlog and into
    xfs_xattr.c so that it no longer has to know about xlog_* functions.

    While we're at it, give xfs_xattr.c its own header file.

    Signed-off-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Dave Chinner <dchinner@redhat.com>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:32 -05:00
Bill O'Donnell 8869716414 xfs: do not use logged xattr updates on V4 filesystems
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit 22a68ba724232ba675166c307ddef3749ae4c37c
Author: Darrick J. Wong <djwong@kernel.org>
Date:   Mon May 23 08:41:03 2022 +1000

    xfs: do not use logged xattr updates on V4 filesystems

    V4 superblocks do not contain the log_incompat feature bit, which means
    that we cannot protect xattr log items against kernels that are too old
    to know how to recover them.  Turn off the log items for such
    filesystems and adjust the "delayed" name to reflect what it's really
    controlling.

    Signed-off-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Dave Chinner <dchinner@redhat.com>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:29 -05:00
Bill O'Donnell ac2b992ba2 xfs: rename struct xfs_attr_item to xfs_attr_intent
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit e3c5de22026fda01674c400b97f96857dfb58aab
Author: Darrick J. Wong <djwong@kernel.org>
Date:   Sun May 22 16:00:26 2022 +1000

    xfs: rename struct xfs_attr_item to xfs_attr_intent

    Everywhere else in XFS, structures that capture the state of an ongoing
    deferred work item all have names that end with "_intent".  The new
    extended attribute deferred work items are not named as such, so fix it
    to follow the naming convention used elsewhere.

    Signed-off-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Allison Henderson <allison.henderson@oracle.com>
    Reviewed-by: Dave Chinner <dchinner@redhat.com>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:27 -05:00
Bill O'Donnell 5a4626b9bc xfs: clean up state variable usage in xfs_attr_node_remove_attr
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit 3768f6985700106e90eca87d814dc08e609a9969
Author: Darrick J. Wong <djwong@kernel.org>
Date:   Sun May 22 15:59:48 2022 +1000

    xfs: clean up state variable usage in xfs_attr_node_remove_attr

    The state variable is now a local variable pointing to a heap
    allocation, so we don't need to zero-initialize it, nor do we need the
    conditional to decide if we should free it.

    Signed-off-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Dave Chinner <dchinner@redhat.com>
    Reviewed-by: Allison Henderson <allison.henderson@oracle.com>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:27 -05:00
Bill O'Donnell 1442807720 xfs: put attr[id] log item cache init with the others
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit 4136e38af728eddcab2e51aecde28e94d0782b9b
Author: Darrick J. Wong <djwong@kernel.org>
Date:   Sun May 22 15:59:48 2022 +1000

    xfs: put attr[id] log item cache init with the others

    Initialize and destroy the xattr log item caches in the same places that
    we do all the other log item caches.

    Signed-off-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Allison Henderson <allison.henderson@oracle.com>
    Reviewed-by: Dave Chinner <dchinner@redhat.com>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:27 -05:00
Bill O'Donnell 2ea31ec8ec xfs: use a separate slab cache for deferred xattr work state
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit e2c78949b641d34cb4051b32c2fa5e03a4bfef35
Author: Darrick J. Wong <djwong@kernel.org>
Date:   Sun May 22 15:59:48 2022 +1000

    xfs: use a separate slab cache for deferred xattr work state

    Create a separate slab cache for struct xfs_attr_item objects, since we
    can pack the (104-byte) intent items more tightly than we can with the
    general slab cache objects.  On x86, this means 39 intents per memory
    page instead of 32.

    Signed-off-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Allison Henderson <allison.henderson@oracle.com>
    Reviewed-by: Dave Chinner <dchinner@redhat.com>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:26 -05:00
Bill O'Donnell 4fe7300684 xfs: put the xattr intent item op flags in their own namespace
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit b53d212b4b5c29ab16edb7eca2b0e05927b7aa34
Author: Darrick J. Wong <djwong@kernel.org>
Date:   Sun May 22 15:59:48 2022 +1000

    xfs: put the xattr intent item op flags in their own namespace

    The flags that are stored in the extended attr intent log item really
    should have a separate namespace from the rest of the XFS_ATTR_* flags.
    Give them one to make it a little more obvious that they're intent item
    flags.

    Signed-off-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Dave Chinner <dchinner@redhat.com>
    Reviewed-by: Allison Henderson <allison.henderson@oracle.com>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:26 -05:00
Bill O'Donnell 01cdb845d3 xfs: clean up xfs_attr_node_hasname
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit 4d0cdd2bb8f0bf1a30d361f14bafc428794551e0
Author: Darrick J. Wong <djwong@kernel.org>
Date:   Sun May 22 15:59:34 2022 +1000

    xfs: clean up xfs_attr_node_hasname

    The calling conventions of this function are a mess -- callers /can/
    provide a pointer to a pointer to a state structure, but it's not
    required, and as evidenced by the last two patches, the callers that do
    weren't be careful enough about how to deal with an existing da state.

    Push the allocation and freeing responsibilty to the callers, which
    means that callers from the xattr node state machine steps now have the
    visibility to allocate or free the da state structure as they please.
    As a bonus, the node remove/add paths for larp-mode replaces can reset
    the da state structure instead of freeing and immediately reallocating
    it.

    Signed-off-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Allison Henderson <allison.henderson@oracle.com>
    Reviewed-by: Dave Chinner <dchinner@redhat.com>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:26 -05:00
Bill O'Donnell aa7449e18a xfs: don't leak the retained da state when doing a leaf to node conversion
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit a618acab136b1b01a4c10957ce8bae70cc9f7ca4
Author: Darrick J. Wong <djwong@kernel.org>
Date:   Fri May 20 14:41:42 2022 +1000

    xfs: don't leak the retained da state when doing a leaf to node conversion

    If a setxattr operation finds an xattr structure in leaf format, adding
    the attr can fail due to lack of space and hence requires an upgrade to
    node format.  After this happens, we'll roll the transaction and
    re-enter the state machine, at which time we need to perform a second
    lookup of the attribute name to find its new location.  This lookup
    attaches a new da state structure to the xfs_attr_item but doesn't free
    the old one (from the leaf lookup) and leaks it.  Fix that.

    Signed-off-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Allison Henderson <allison.henderson@oracle.com>
    Reviewed-by: Dave Chinner <dchinner@redhat.com>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:25 -05:00
Bill O'Donnell 2bbe240bc9 xfs: don't leak da state when freeing the attr intent item
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit 309001c22cdd75c62e6c3a217bf6967e178f929a
Author: Darrick J. Wong <djwong@kernel.org>
Date:   Fri May 20 14:41:34 2022 +1000

    xfs: don't leak da state when freeing the attr intent item

    kmemleak reported that we lost an xfs_da_state while removing xattrs in
    generic/020:

    unreferenced object 0xffff88801c0e4b40 (size 480):
      comm "attr", pid 30515, jiffies 4294931061 (age 5.960s)
      hex dump (first 32 bytes):
        78 bc 65 07 00 c9 ff ff 00 30 60 1c 80 88 ff ff  x.e......0`.....
        02 00 00 00 00 00 00 00 80 18 83 4e 80 88 ff ff  ...........N....
      backtrace:
        [<ffffffffa023ef4a>] xfs_da_state_alloc+0x1a/0x30 [xfs]
        [<ffffffffa021b6f3>] xfs_attr_node_hasname+0x23/0x90 [xfs]
        [<ffffffffa021c6f1>] xfs_attr_set_iter+0x441/0xa30 [xfs]
        [<ffffffffa02b5104>] xfs_xattri_finish_update+0x44/0x80 [xfs]
        [<ffffffffa02b515e>] xfs_attr_finish_item+0x1e/0x40 [xfs]
        [<ffffffffa0244744>] xfs_defer_finish_noroll+0x184/0x740 [xfs]
        [<ffffffffa02a6473>] __xfs_trans_commit+0x153/0x3e0 [xfs]
        [<ffffffffa021d149>] xfs_attr_set+0x469/0x7e0 [xfs]
        [<ffffffffa02a78d9>] xfs_xattr_set+0x89/0xd0 [xfs]
        [<ffffffff812e6512>] __vfs_removexattr+0x52/0x70
        [<ffffffff812e6a08>] __vfs_removexattr_locked+0xb8/0x150
        [<ffffffff812e6af6>] vfs_removexattr+0x56/0x100
        [<ffffffff812e6bf8>] removexattr+0x58/0x90
        [<ffffffff812e6cce>] path_removexattr+0x9e/0xc0
        [<ffffffff812e6d44>] __x64_sys_lremovexattr+0x14/0x20
        [<ffffffff81786b35>] do_syscall_64+0x35/0x80

    I think this is a consequence of xfs_attr_node_removename_setup
    attaching a new da(btree) state to xfs_attr_item and never freeing it.
    I /think/ it's the case that the remove paths could detach the da state
    earlier in the remove state machine since nothing else accesses the
    state.  However, let's future-proof the new xattr code by adding a
    catch-all when we free the xfs_attr_item to make sure we never leak the
    da state.

    Signed-off-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Allison Henderson <allison.henderson@oracle.com>
    Reviewed-by: Dave Chinner <dchinner@redhat.com>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:24 -05:00
Bill O'Donnell 38b5dff00d xfs: ATTR_REPLACE algorithm with LARP enabled needs rework
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit fdaf1bb3cafcfee9ef05c4eaf6ee1193fd90cbd2
Author: Dave Chinner <dchinner@redhat.com>
Date:   Thu May 12 15:12:56 2022 +1000

    xfs: ATTR_REPLACE algorithm with LARP enabled needs rework

    We can't use the same algorithm for replacing an existing attribute
    when logging attributes. The existing algorithm is essentially:

    1. create new attr w/ INCOMPLETE
    2. atomically flip INCOMPLETE flags between old + new attribute
    3. remove old attr which is marked w/ INCOMPLETE

    This algorithm guarantees that we see either the old or new
    attribute, and if we fail after the atomic flag flip, we don't have
    to recover the removal of the old attr because we never see
    INCOMPLETE attributes in lookups.

    For logged attributes, however, this does not work. The logged
    attribute intents do not track the work that has been done as the
    transaction rolls, and hence the only recovery mechanism we have is
    "run the replace operation from scratch".

    This is further exacerbated by the attempt to avoid needing the
    INCOMPLETE flag to create an atomic swap. This means we can create
    a second active attribute of the same name before we remove the
    original. If we fail at any point after the create but before the
    removal has completed, we end up with duplicate attributes in
    the attr btree and recovery only tries to replace one of them.

    There are several other failure modes where we can leave partially
    allocated remote attributes that expose stale data, partially free
    remote attributes that enable UAF based stale data exposure, etc.

    TO fix this, we need a different algorithm for replace operations
    when LARP is enabled. Luckily, it's not that complex if we take the
    right first step. That is, the first thing we log is the attri
    intent with the new name/value pair and mark the old attr as
    INCOMPLETE in the same transaction.

    From there, we then remove the old attr and keep relogging the
    new name/value in the intent, such that we always know that we have
    to create the new attr in recovery. Once the old attr is removed,
    we then run a normal ATTR_CREATE operation relogging the intent as
    we go. If the new attr is local, then it gets created in a single
    atomic transaction that also logs the final intent done. If the new
    attr is remote, the we set INCOMPLETE on the new attr while we
    allocate and set the remote value, and then we clear the INCOMPLETE
    flag at in the last transaction taht logs the final intent done.

    If we fail at any point in this algorithm, log recovery will always
    see the same state on disk: the new name/value in the intent, and
    either an INCOMPLETE attr or no attr in the attr btree. If we find
    an INCOMPLETE attr, we run the full replace starting with removing
    the INCOMPLETE attr. If we don't find it, then we simply create the
    new attr.

    Notably, recovery of a failed create that has an INCOMPLETE flag set
    is now the same - we start with the lookup of the INCOMPLETE attr,
    and if that exists then we do the full replace recovery process,
    otherwise we just create the new attr.

    Hence changing the way we do the replace operation when LARP is
    enabled allows us to use the same log recovery algorithm for both
    the ATTR_CREATE and ATTR_REPLACE operations. This is also the same
    algorithm we use for runtime ATTR_REPLACE operations (except for the
    step setting up the initial conditions).

    The result is that:

    - ATTR_CREATE uses the same algorithm regardless of whether LARP is
      enabled or not
    - ATTR_REPLACE with larp=0 is identical to the old algorithm
    - ATTR_REPLACE with larp=1 runs an unmodified attr removal algorithm
      from the larp=0 code and then runs the unmodified ATTR_CREATE
      code.
    - log recovery when larp=1 runs the same ATTR_REPLACE algorithm as
      it uses at runtime.

    Because the state machine is now quite clean, changing the algorithm
    is really just a case of changing the initial state and how the
    states link together for the ATTR_REPLACE case. Hence it's not a
    huge amount of code for what is a fairly substantial rework
    of the attr logging and recovery algorithm....

    Signed-off-by: Dave Chinner <dchinner@redhat.com>
    Reviewed-by: Allison Henderson <allison.henderson@oracle.com>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:23 -05:00
Bill O'Donnell 159a808d8f xfs: use XFS_DA_OP flags in deferred attr ops
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit e7f358dee4e5cf1ce8b11ff2e65d5ccb1ced24db
Author: Dave Chinner <dchinner@redhat.com>
Date:   Thu May 12 15:12:56 2022 +1000

    xfs: use XFS_DA_OP flags in deferred attr ops

    We currently store the high level attr operation in
    args->attr_flags. This field contains what the VFS is telling us to
    do, but don't necessarily match what we are doing in the low level
    modification state machine. e.g. XATTR_REPLACE implies both
    XFS_DA_OP_ADDNAME and XFS_DA_OP_RENAME because it is doing both a
    remove and adding a new attr.

    However, deep in the individual state machine operations, we check
    errors against this high level VFS op flags, not the low level
    XFS_DA_OP flags. Indeed, we don't even have a low level flag for
    a REMOVE operation, so the only way we know we are doing a remove
    is the complete absence of XATTR_REPLACE, XATTR_CREATE,
    XFS_DA_OP_ADDNAME and XFS_DA_OP_RENAME. And because there are other
    flags in these fields, this is a pain to check if we need to.

    As the XFS_DA_OP flags are only needed once the deferred operations
    are set up, set these flags appropriately when we set the initial
    operation state. We also introduce a XFS_DA_OP_REMOVE flag to make
    it easy to know that we are doing a remove operation.

    With these, we can remove the use of XATTR_REPLACE and XATTR_CREATE
    in low level lookup operations, and manipulate the low level flags
    according to the low level context that is operating. e.g. log
    recovery does not have a VFS xattr operation state to copy into
    args->attr_flags, and the low level state machine ops we do for
    recovery do not match the high level VFS operations that were in
    progress when the system failed...

    Signed-off-by: Dave Chinner <dchinner@redhat.com>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Allison Henderson <allison.henderson@oracle.com>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:23 -05:00
Bill O'Donnell 94432a9bfa xfs: remove xfs_attri_remove_iter
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit 59782a236b622a983ff101b2cb1333f714e4ed4e
Author: Dave Chinner <dchinner@redhat.com>
Date:   Thu May 12 15:12:56 2022 +1000

    xfs: remove xfs_attri_remove_iter

    xfs_attri_remove_iter is not used anymore, so remove it and all the
    infrastructure it uses and is needed to drive it. THe
    xfs_attr_refillstate() function now throws an unused warning, so
    isolate the xfs_attr_fillstate()/xfs_attr_refillstate() code pair
    with an #if 0 and a comment explaining why we want to keep this code
    and restore the optimisation it provides in the near future.

    Signed-off-by: Dave Chinner <dchinner@redhat.com>
    Reviewed-by: Allison Henderson<allison.henderson@oracle.com>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:23 -05:00
Bill O'Donnell a2331fc972 xfs: switch attr remove to xfs_attri_set_iter
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit 4b9879b19cafa63ae02fef30f678b2179a648d45
Author: Dave Chinner <dchinner@redhat.com>
Date:   Thu May 12 15:12:56 2022 +1000

    xfs: switch attr remove to xfs_attri_set_iter

    Now that xfs_attri_set_iter() has initial states for removing
    attributes, switch the pure attribute removal code over to using it.
    This requires attrs being removed to always be marked as INCOMPLETE
    before we start the removal due to the fact we look up the attr to
    remove again in xfs_attr_node_remove_attr().

    Note: this drops the fillstate/refillstate optimisations from
    the remove path that avoid having to look up the path again after
    setting the incomplete flag and removing remote attrs. Restoring
    that optimisation to this path is future Dave's problem.

    Signed-off-by: Dave Chinner <dchinner@redhat.com>
    Reviewed-by: Allison Henderson <allison.henderson@oracle.com>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:23 -05:00
Bill O'Donnell b643528b9a xfs: introduce attr remove initial states into xfs_attr_set_iter
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit e5d5596a2a1790d8c57938f820aa33e58f90ad0d
Author: Dave Chinner <dchinner@redhat.com>
Date:   Thu May 12 15:12:56 2022 +1000

    xfs: introduce attr remove initial states into xfs_attr_set_iter

    We need to merge the add and remove code paths to enable safe
    recovery of replace operations. Hoist the initial remove states from
    xfs_attr_remove_iter into xfs_attr_set_iter. We will make use of
    them in the next patches.

    Signed-off-by: Dave Chinner <dchinner@redhat.com>
    Reviewed-by: Allison Henderson<allison.henderson@oracle.com>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:22 -05:00
Bill O'Donnell 73aa3f6527 xfs: xfs_attr_set_iter() does not need to return EAGAIN
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit 4e3d96a57a06f20f4ce04a92422cc100251f346d
Author: Dave Chinner <dchinner@redhat.com>
Date:   Thu May 12 15:12:55 2022 +1000

    xfs: xfs_attr_set_iter() does not need to return EAGAIN

    Now that the full xfs_attr_set_iter() state machine always
    terminates with either the state being XFS_DAS_DONE on success or
    an error on failure, we can get rid of the need for it to return
    -EAGAIN whenever it needs to roll the transaction before running
    the next state.

    That is, we don't need to spray -EAGAIN return states everywhere,
    the caller just check the state machine state for completion to
    determine what action should be taken next. This greatly simplifies
    the code within the state machine implementation as it now only has
    to handle 0 for success or -errno for error and it doesn't need to
    tell the caller to retry.

    Signed-off-by: Dave Chinner <dchinner@redhat.com>
    Reviewed-by: Allison Henderson<allison.henderson@oracle.com>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:22 -05:00
Bill O'Donnell a3765ce89e xfs: clean up final attr removal in xfs_attr_set_iter
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit b11fa61bc4c679172a35e48d149f797ee37db3fc
Author: Dave Chinner <dchinner@redhat.com>
Date:   Thu May 12 15:12:55 2022 +1000

    xfs: clean up final attr removal in xfs_attr_set_iter

    Clean up the final leaf/node states in xfs_attr_set_iter() to
    further simplify the high level state machine and to set the
    completion state correctly. As we are adding a separate state
    for node format removal, we need to ensure that node formats
    are collapsed back to shortform or empty correctly.

    Signed-off-by: Dave Chinner <dchinner@redhat.com>
    Reviewed-by: Allison Henderson<allison.henderson@oracle.com>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:22 -05:00
Bill O'Donnell 0953949d50 xfs: remote xattr removal in xfs_attr_set_iter() is conditional
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit 2e7ef218e489f5b3f5156a305b55a08c41839c1b
Author: Dave Chinner <dchinner@redhat.com>
Date:   Thu May 12 15:12:55 2022 +1000

    xfs: remote xattr removal in xfs_attr_set_iter() is conditional

    We may not have a remote value for the old xattr we have to remove,
    so skip over the remote value removal states and go straight to
    the xattr name removal in the leaf/node block.

    Signed-off-by: Dave Chinner <dchinner@redhat.com>
    Reviewed-by: Allison Henderson<allison.henderson@oracle.com>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:22 -05:00
Bill O'Donnell 9cf180d6c1 xfs: XFS_DAS_LEAF_REPLACE state only needed if !LARP
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit 411b434a63248ecff58aaf498b09eaf3b3f52f90
Author: Dave Chinner <dchinner@redhat.com>
Date:   Thu May 12 15:12:55 2022 +1000

    xfs: XFS_DAS_LEAF_REPLACE state only needed if !LARP

    We can skip the REPLACE state when LARP is enabled, but that means
    the XFS_DAS_FLIP_LFLAG state is now poorly named - it indicates
    something that has been done rather than what the state is going to
    do. Rename it to "REMOVE_OLD" to indicate that we are now going to
    perform removal of the old attr.

    Signed-off-by: Dave Chinner <dchinner@redhat.com>
    Reviewed-by: Allison Henderson<allison.henderson@oracle.com>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:21 -05:00
Bill O'Donnell d00be923f2 xfs: split remote attr setting out from replace path
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit 7d03533629d1c3fca395e6fd0935ca1de676f2bc
Author: Dave Chinner <dchinner@redhat.com>
Date:   Thu May 12 15:12:55 2022 +1000

    xfs: split remote attr setting out from replace path

    When we set a new xattr, we have three exit paths:

            1. nothing else to do
            2. allocate and set the remote xattr value
            3. perform the rest of a replace operation

    Currently we push both 2 and 3 into the same state, regardless of
    whether we just set a remote attribute or not. Once we've set the
    remote xattr, we have two exit states:

            1. nothing else to do
            2. perform the rest of a replace operation

    Hence we can split the remote xattr allocation and setting into
    their own states and factor it out of xfs_attr_set_iter() to further
    clean up the state machine and the implementation of the state
    machine.

    Signed-off-by: Dave Chinner <dchinner@redhat.com>
    Reviewed-by: Allison Henderson<allison.henderson@oracle.com>
    Reviewed-by: Dave Chinner <david@fromorbit.com>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:21 -05:00
Bill O'Donnell 525e56c210 xfs: consolidate leaf/node states in xfs_attr_set_iter
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit 251b29c88eb84922e916ed4685f50db741aeb0af
Author: Dave Chinner <dchinner@redhat.com>
Date:   Thu May 12 15:12:54 2022 +1000

    xfs: consolidate leaf/node states in xfs_attr_set_iter

    The operations performed from XFS_DAS_FOUND_LBLK through to
    XFS_DAS_RM_LBLK are now identical to XFS_DAS_FOUND_NBLK through to
    XFS_DAS_RM_NBLK. We can collapse these down into a single set of
    code.

    To do this, define the states that leaf and node run through as
    separate sets of sequential states. Then as we move to the next
    state, we can use increments rather than specific state assignments
    to move through the states. This means the state progression is set
    by the initial state that enters the series and we don't need to
    duplicate the code anymore.

    At the exit point of the series we need to select the correct leaf
    or node state, but that can also be done by state increment rather
    than assignment.

    Signed-off-by: Dave Chinner <dchinner@redhat.com>
    Reviewed-by: Allison Henderson<allison.henderson@oracle.com>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:21 -05:00
Bill O'Donnell 925cfe938c xfs: kill XFS_DAC_LEAF_ADDNAME_INIT
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit 2157d1699e59819c8a31ba3e47008e4145d854a9
Author: Dave Chinner <dchinner@redhat.com>
Date:   Thu May 12 15:12:54 2022 +1000

    xfs: kill XFS_DAC_LEAF_ADDNAME_INIT

    We re-enter the XFS_DAS_FOUND_LBLK state when we have to allocate
    multiple extents for a remote xattr. We currently have a flag
    called XFS_DAC_LEAF_ADDNAME_INIT to avoid running the remote attr
    hole finding code more than once.

    However, for the node format tree, we have a separate state for this
    so we never reenter the state machine at XFS_DAS_FOUND_NBLK and so
    it does not need a special flag to skip over the remote attr hold
    finding code.

    Convert the leaf block code to use the same state machine as the
    node blocks and kill the  XFS_DAC_LEAF_ADDNAME_INIT flag.

    This further points out that this "ALLOC" state is only traversed
    if we have remote xattrs or we are doing a rename operation. Rename
    both the leaf and node alloc states to _ALLOC_RMT to indicate they
    are iterating to do allocation of remote xattr blocks.

    Signed-off-by: Dave Chinner <dchinner@redhat.com>
    Reviewed-by: Allison Henderson<allison.henderson@oracle.com>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:21 -05:00
Bill O'Donnell 7d916c32c4 xfs: separate out initial attr_set states
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit e0c41089b998f5a54dabd7a34ab24108e192d2ee
Author: Dave Chinner <dchinner@redhat.com>
Date:   Thu May 12 15:12:52 2022 +1000

    xfs: separate out initial attr_set states

    We current use XFS_DAS_UNINIT for several steps in the attr_set
    state machine. We use it for setting shortform xattrs, converting
    from shortform to leaf, leaf add, leaf-to-node and leaf add. All of
    these things are essentially known before we start the state machine
    iterating, so we really should separate them out:

    XFS_DAS_SF_ADD:
            - tries to do a shortform add
            - on success -> done
            - on ENOSPC converts to leaf, -> XFS_DAS_LEAF_ADD
            - on error, dies.

    XFS_DAS_LEAF_ADD:
            - tries to do leaf add
            - on success:
                    - inline attr -> done
                    - remote xattr || REPLACE -> XFS_DAS_FOUND_LBLK
            - on ENOSPC converts to node, -> XFS_DAS_NODE_ADD
            - on error, dies

    XFS_DAS_NODE_ADD:
            - tries to do node add
            - on success:
                    - inline attr -> done
                    - remote xattr || REPLACE -> XFS_DAS_FOUND_NBLK
            - on error, dies

    This makes it easier to understand how the state machine starts
    up and sets us up on the path to further state machine
    simplifications.

    This also converts the DAS state tracepoints to use strings rather
    than numbers, as converting between enums and numbers requires
    manual counting rather than just reading the name.

    This also introduces a XFS_DAS_DONE state so that we can trace
    successful operation completions easily.

    Signed-off-by: Dave Chinner <dchinner@redhat.com>
    Reviewed-by: Allison Henderson<allison.henderson@oracle.com>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:20 -05:00
Bill O'Donnell 245c3211b6 xfs: rework deferred attribute operation setup
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit 709c8632597c3276cd21324b0256628f1a7fd4df
Author: Dave Chinner <dchinner@redhat.com>
Date:   Wed May 11 17:05:23 2022 +1000

    xfs: rework deferred attribute operation setup

    Logged attribute intents only have set and remove types - there is
    no separate intent type for a replace operation. We should have a
    separate type for a replace operation, as it needs to perform
    operations that neither SET or REMOVE can perform.

    Add this type to the intent items and rearrange the deferred
    operation setup to reflect the different operations we are
    performing.

    Signed-off-by: Dave Chinner <dchinner@redhat.com>
    Reviewed-by: Allison Henderson<allison.henderson@oracle.com>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:19 -05:00
Bill O'Donnell d71fe03a09 xfs: make xattri_leaf_bp more useful
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit e22b88de5bacdd60ffa70e911e5fbae9ad36441a
Author: Dave Chinner <dchinner@redhat.com>
Date:   Wed May 11 17:04:23 2022 +1000

    xfs: make xattri_leaf_bp more useful

    We currently set it and hold it when converting from short to leaf
    form, then release it only to immediately look it back up again
    to do the leaf insert.

    Do a bit of refactoring to xfs_attr_leaf_try_add() to avoid this
    messy handling of the newly allocated leaf buffer.

    Signed-off-by: Dave Chinner <dchinner@redhat.com>
    Reviewed-by: Allison Henderson<allison.henderson@oracle.com>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:19 -05:00
Bill O'Donnell 5d523df3e5 xfs: avoid empty xattr transaction when attrs are inline
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit a4b8917b06c71a4ea61ac45b6e979eb7676417f8
Author: Dave Chinner <dchinner@redhat.com>
Date:   Wed May 11 17:02:23 2022 +1000

    xfs: avoid empty xattr transaction when attrs are inline

    generic/642 triggered a reproducable assert failure in
    xlog_cil_commit() that resulted from a xfs_attr_set() committing
    an empty but dirty transaction. When the CIL is empty and this
    occurs, xlog_cil_commit() tries a background push and this triggers
    a "pushing an empty CIL" assert.

    XFS: Assertion failed: !list_empty(&cil->xc_cil), file: fs/xfs/xfs_log_cil.c, line: 1274
    Call Trace:
     <TASK>
     xlog_cil_commit+0xa5a/0xad0
     __xfs_trans_commit+0xb8/0x330
     xfs_trans_commit+0x10/0x20
     xfs_attr_set+0x3e2/0x4c0
     xfs_xattr_set+0x8d/0xe0
     __vfs_setxattr+0x6b/0x90
     __vfs_setxattr_noperm+0x76/0x220
     __vfs_setxattr_locked+0xdf/0x100
     vfs_setxattr+0x94/0x170
     setxattr+0x110/0x200
     path_setxattr+0xbf/0xe0
     __x64_sys_setxattr+0x2b/0x30
     do_syscall_64+0x35/0x80

    The problem is related to the breakdown of attribute addition in
    xfs_attr_set_iter() and how it is called from deferred operations.
    When we have a pure leaf xattr insert, we add the xattr to the leaf
    and set the next state to XFS_DAS_FOUND_LBLK and return -EAGAIN.
    This requeues the xattr defered work, rolls the transaction and
    runs xfs_attr_set_iter() again. This then checks the xattr for
    being remote (it's not) and whether a replace op is being done (this
    is a create op) and if neither are true it returns without having
    done anything.

    xfs_xattri_finish_update() then unconditionally sets the transaction
    dirty, and the deferops finishes and returns to __xfs_trans_commit()
    which sees the transaction dirty and tries to commit it by calling
    xlog_cil_commit(). The transaction is empty, and then the assert
    fires if this happens when the CIL is empty.

    This patch addresses the structure of xfs_attr_set_iter() that
    requires re-entry on leaf add even when nothing will be done. This
    gets rid of the trailing empty transaction and so doesn't trigger
    the XFS_TRANS_DIRTY assignment in xfs_xattri_finish_update()
    incorrectly. Addressing that is for a different patch.

    Signed-off-by: Dave Chinner <dchinner@redhat.com>
    Reviewed-by: Allison Henderson<allison.henderson@oracle.com>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:19 -05:00
Bill O'Donnell 45f4aa4810 xfs: Add helper function xfs_init_attr_trans
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit c3546cf5d1e50389a789290f8c21a555e3408aa8
Author: Allison Henderson <allison.henderson@oracle.com>
Date:   Wed May 11 17:01:23 2022 +1000

    xfs: Add helper function xfs_init_attr_trans

    Quick helper function to collapse duplicate code to initialize
    transactions for attributes

    Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
    Suggested-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Chandan Babu R <chandan.babu@oracle.com>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:18 -05:00
Bill O'Donnell 1d80303f33 xfs: Add helper function xfs_attr_leaf_addname
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit cd1549d6df22e4f72903dbb169202203d429bcff
Author: Allison Henderson <allison.henderson@oracle.com>
Date:   Wed May 11 17:01:22 2022 +1000

    xfs: Add helper function xfs_attr_leaf_addname

    This patch adds a helper function xfs_attr_leaf_addname.  While this
    does help to break down xfs_attr_set_iter, it does also hoist out some
    of the state management.  This patch has been moved to the end of the
    clean up series for further discussion.

    Suggested-by: Darrick J. Wong <djwong@kernel.org>
    Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:18 -05:00
Bill O'Donnell bc92d8fa94 xfs: Merge xfs_delattr_context into xfs_attr_item
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit d68c51e9a4095b57f06bf5dd15ab8fae6dab5d8b
Author: Allison Henderson <allison.henderson@oracle.com>
Date:   Wed May 11 17:01:22 2022 +1000

    xfs: Merge xfs_delattr_context into xfs_attr_item

    This is a clean up patch that merges xfs_delattr_context into
    xfs_attr_item.  Now that the refactoring is complete and the delayed
    operation infrastructure is in place, we can combine these to eliminate
    the extra struct

    Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
    Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
    Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:17 -05:00
Bill O'Donnell c3a244a26d xfs: Remove unused xfs_attr_*_args
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit 73159fc27c6944ebe55e6652d6a1981d7cb3eb4a
Author: Allison Henderson <allison.henderson@oracle.com>
Date:   Wed May 11 17:01:22 2022 +1000

    xfs: Remove unused xfs_attr_*_args

    Remove xfs_attr_set_args, xfs_attr_remove_args, and xfs_attr_trans_roll.
    These high level loops are now driven by the delayed operations code,
    and can be removed.

    Additionally collapse in the leaf_bp parameter of xfs_attr_set_iter
    since we only have one caller that passes dac->leaf_bp

    Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:17 -05:00
Bill O'Donnell 1e8bb61942 xfs: Add xfs_attr_set_deferred and xfs_attr_remove_deferred
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit f3f36c893f260275eb9229cdc3dabb4c79650591
Author: Allison Henderson <allison.henderson@oracle.com>
Date:   Wed May 11 17:01:13 2022 +1000

    xfs: Add xfs_attr_set_deferred and xfs_attr_remove_deferred

    These routines set up and queue a new deferred attribute operations.
    These functions are meant to be called by any routine needing to
    initiate a deferred attribute operation as opposed to the existing
    inline operations. New helper function xfs_attr_item_init also added.

    Finally enable delayed attributes in xfs_attr_set and xfs_attr_remove.

    Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:16 -05:00
Bill O'Donnell 526f2aad48 xfs: Skip flip flags for delayed attrs
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit f38dc503d366b589d98d5676a5b279d10b47bcb9
Author: Allison Henderson <allison.henderson@oracle.com>
Date:   Mon May 9 19:09:10 2022 +1000

    xfs: Skip flip flags for delayed attrs

    This is a clean up patch that skips the flip flag logic for delayed attr
    renames.  Since the log replay keeps the inode locked, we do not need to
    worry about race windows with attr lookups.  So we can skip over
    flipping the flag and the extra transaction roll for it

    Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:16 -05:00
Bill O'Donnell db4b5bf1ae xfs: Set up infrastructure for log attribute replay
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2167832

commit fd920008784ead369e79c2be2f8d9cc736e306ca
Author: Allison Henderson <allison.henderson@oracle.com>
Date:   Wed May 4 12:41:02 2022 +1000

    xfs: Set up infrastructure for log attribute replay

    Currently attributes are modified directly across one or more
    transactions. But they are not logged or replayed in the event of an
    error. The goal of log attr replay is to enable logging and replaying
    of attribute operations using the existing delayed operations
    infrastructure.  This will later enable the attributes to become part of
    larger multi part operations that also must first be recorded to the
    log.  This is mostly of interest in the scheme of parent pointers which
    would need to maintain an attribute containing parent inode information
    any time an inode is moved, created, or removed.  Parent pointers would
    then be of interest to any feature that would need to quickly derive an
    inode path from the mount point. Online scrub, nfs lookups and fs grow
    or shrink operations are all features that could take advantage of this.

    This patch adds two new log item types for setting or removing
    attributes as deferred operations.  The xfs_attri_log_item will log an
    intent to set or remove an attribute.  The corresponding
    xfs_attrd_log_item holds a reference to the xfs_attri_log_item and is
    freed once the transaction is done.  Both log items use a generic
    xfs_attr_log_format structure that contains the attribute name, value,
    flags, inode, and an op_flag that indicates if the operations is a set
    or remove.

    [dchinner: added extra little bits needed for intent whiteouts]

    Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
    Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Signed-off-by: Dave Chinner <david@fromorbit.com>

Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
2023-05-18 11:11:16 -05:00