^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2000-2005 Silicon Graphics, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2013 Red Hat, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "xfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "xfs_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "xfs_shared.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "xfs_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "xfs_log_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "xfs_trans_resv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "xfs_bit.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "xfs_mount.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "xfs_da_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "xfs_da_btree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "xfs_inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "xfs_attr_remote.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "xfs_trans.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "xfs_bmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "xfs_attr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "xfs_attr_leaf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "xfs_quota.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "xfs_dir2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "xfs_error.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * Invalidate any incore buffers associated with this remote attribute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * extent. We never log remote attribute value buffers, which means that they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * won't be attached to a transaction and are therefore safe to mark stale.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * The actual bunmapi will be taken care of later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) xfs_attr3_rmt_stale(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct xfs_inode *dp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) xfs_dablk_t blkno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) int blkcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct xfs_bmbt_irec map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int nmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * Roll through the "value", invalidating the attribute value's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) while (blkcnt > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Try to remember where we decided to put the value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) nmap = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) error = xfs_bmapi_read(dp, (xfs_fileoff_t)blkno, blkcnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) &map, &nmap, XFS_BMAPI_ATTRFORK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (XFS_IS_CORRUPT(dp->i_mount, nmap != 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * Mark any incore buffers for the remote value as stale. We
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * never log remote attr value buffers, so the buffer should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * easy to kill.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) error = xfs_attr_rmtval_stale(dp, &map, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) blkno += map.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) blkcnt -= map.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * Invalidate all of the "remote" value regions pointed to by a particular
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * leaf block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * Note that we must release the lock on the buffer so that we are not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * caught holding something that the logging code wants to flush to disk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) xfs_attr3_leaf_inactive(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct xfs_trans **trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct xfs_inode *dp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct xfs_buf *bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct xfs_attr3_icleaf_hdr ichdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct xfs_mount *mp = bp->b_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct xfs_attr_leafblock *leaf = bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct xfs_attr_leaf_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct xfs_attr_leaf_name_remote *name_rmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * Find the remote value extents for this leaf and invalidate their
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * incore buffers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) entry = xfs_attr3_leaf_entryp(leaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) for (i = 0; i < ichdr.count; entry++, i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int blkcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (!entry->nameidx || (entry->flags & XFS_ATTR_LOCAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (!name_rmt->valueblk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) blkcnt = xfs_attr3_rmt_blocks(dp->i_mount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) be32_to_cpu(name_rmt->valuelen));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) error = xfs_attr3_rmt_stale(dp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) be32_to_cpu(name_rmt->valueblk), blkcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) xfs_trans_brelse(*trans, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * Recurse (gasp!) through the attribute nodes until we find leaves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * We're doing a depth-first traversal in order to invalidate everything.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) xfs_attr3_node_inactive(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct xfs_trans **trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct xfs_inode *dp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct xfs_buf *bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) int level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct xfs_mount *mp = dp->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct xfs_da_blkinfo *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) xfs_dablk_t child_fsb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) xfs_daddr_t parent_blkno, child_blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct xfs_buf *child_bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct xfs_da3_icnode_hdr ichdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int error, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * Since this code is recursive (gasp!) we must protect ourselves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (level > XFS_DA_NODE_MAXDEPTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) xfs_buf_mark_corrupt(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) xfs_trans_brelse(*trans, bp); /* no locks for later trans */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) xfs_da3_node_hdr_from_disk(dp->i_mount, &ichdr, bp->b_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) parent_blkno = bp->b_bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (!ichdr.count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) xfs_trans_brelse(*trans, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) child_fsb = be32_to_cpu(ichdr.btree[0].before);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) xfs_trans_brelse(*trans, bp); /* no locks for later trans */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * If this is the node level just above the leaves, simply loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * over the leaves removing all of them. If this is higher up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * in the tree, recurse downward.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) for (i = 0; i < ichdr.count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * Read the subsidiary block to see what we have to work with.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * Don't do this in a transaction. This is a depth-first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * traversal of the tree so we may deal with many blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * before we come back to this one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) error = xfs_da3_node_read(*trans, dp, child_fsb, &child_bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) XFS_ATTR_FORK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /* save for re-read later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) child_blkno = XFS_BUF_ADDR(child_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * Invalidate the subtree, however we have to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) info = child_bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) switch (info->magic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) case cpu_to_be16(XFS_DA_NODE_MAGIC):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) case cpu_to_be16(XFS_DA3_NODE_MAGIC):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) error = xfs_attr3_node_inactive(trans, dp, child_bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) level + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) case cpu_to_be16(XFS_ATTR_LEAF_MAGIC):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) error = xfs_attr3_leaf_inactive(trans, dp, child_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) xfs_buf_mark_corrupt(child_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) xfs_trans_brelse(*trans, child_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * Remove the subsidiary block from the cache and from the log.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) error = xfs_trans_get_buf(*trans, mp->m_ddev_targp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) child_blkno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) XFS_FSB_TO_BB(mp, mp->m_attr_geo->fsbcount), 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) &child_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) error = bp->b_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) xfs_trans_brelse(*trans, child_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) xfs_trans_binval(*trans, child_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * If we're not done, re-read the parent to get the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * child block number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (i + 1 < ichdr.count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct xfs_da3_icnode_hdr phdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) error = xfs_da3_node_read_mapped(*trans, dp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) parent_blkno, &bp, XFS_ATTR_FORK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) xfs_da3_node_hdr_from_disk(dp->i_mount, &phdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) bp->b_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) child_fsb = be32_to_cpu(phdr.btree[i + 1].before);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) xfs_trans_brelse(*trans, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * Atomically commit the whole invalidate stuff.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) error = xfs_trans_roll_inode(trans, dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * Indiscriminately delete the entire attribute fork
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * Recurse (gasp!) through the attribute nodes until we find leaves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * We're doing a depth-first traversal in order to invalidate everything.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) xfs_attr3_root_inactive(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) struct xfs_trans **trans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct xfs_inode *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct xfs_mount *mp = dp->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) struct xfs_da_blkinfo *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct xfs_buf *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) xfs_daddr_t blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * Read block 0 to see what we have to work with.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * We only get here if we have extents, since we remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * the extents in reverse order the extent containing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * block 0 must still be there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) error = xfs_da3_node_read(*trans, dp, 0, &bp, XFS_ATTR_FORK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) blkno = bp->b_bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * Invalidate the tree, even if the "tree" is only a single leaf block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * This is a depth-first traversal!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) info = bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) switch (info->magic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) case cpu_to_be16(XFS_DA_NODE_MAGIC):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) case cpu_to_be16(XFS_DA3_NODE_MAGIC):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) error = xfs_attr3_node_inactive(trans, dp, bp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) case cpu_to_be16(XFS_ATTR_LEAF_MAGIC):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) error = xfs_attr3_leaf_inactive(trans, dp, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) xfs_buf_mark_corrupt(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) xfs_trans_brelse(*trans, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * Invalidate the incore copy of the root block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) error = xfs_trans_get_buf(*trans, mp->m_ddev_targp, blkno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) XFS_FSB_TO_BB(mp, mp->m_attr_geo->fsbcount), 0, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) error = bp->b_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) xfs_trans_brelse(*trans, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) xfs_trans_binval(*trans, bp); /* remove from cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * Commit the invalidate and start the next transaction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) error = xfs_trans_roll_inode(trans, dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * xfs_attr_inactive kills all traces of an attribute fork on an inode. It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * removes both the on-disk and in-memory inode fork. Note that this also has to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * handle the condition of inodes without attributes but with an attribute fork
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * configured, so we can't use xfs_inode_hasattr() here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * The in-memory attribute fork is removed even on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) xfs_attr_inactive(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct xfs_inode *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct xfs_trans *trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct xfs_mount *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) int lock_mode = XFS_ILOCK_SHARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) mp = dp->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) ASSERT(! XFS_NOT_DQATTACHED(mp, dp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) xfs_ilock(dp, lock_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (!XFS_IFORK_Q(dp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) goto out_destroy_fork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) xfs_iunlock(dp, lock_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) lock_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) error = xfs_trans_alloc(mp, &M_RES(mp)->tr_attrinval, 0, 0, 0, &trans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) goto out_destroy_fork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) lock_mode = XFS_ILOCK_EXCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) xfs_ilock(dp, lock_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (!XFS_IFORK_Q(dp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) goto out_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * No need to make quota reservations here. We expect to release some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * blocks, not allocate, in the common case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) xfs_trans_ijoin(trans, dp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * Invalidate and truncate the attribute fork extents. Make sure the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * fork actually has attributes as otherwise the invalidation has no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * blocks to read and returns an error. In this case, just do the fork
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * removal below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (xfs_inode_hasattr(dp) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) dp->i_afp->if_format != XFS_DINODE_FMT_LOCAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) error = xfs_attr3_root_inactive(&trans, dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) goto out_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) error = xfs_itruncate_extents(&trans, dp, XFS_ATTR_FORK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) goto out_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /* Reset the attribute fork - this also destroys the in-core fork */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) xfs_attr_fork_remove(dp, trans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) error = xfs_trans_commit(trans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) xfs_iunlock(dp, lock_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) out_cancel:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) xfs_trans_cancel(trans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) out_destroy_fork:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) /* kill the in-core attr fork before we drop the inode lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (dp->i_afp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) xfs_idestroy_fork(dp->i_afp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) kmem_cache_free(xfs_ifork_zone, dp->i_afp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) dp->i_afp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (lock_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) xfs_iunlock(dp, lock_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }