Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
0004  * Copyright (c) 2013 Red Hat, Inc.
0005  * All Rights Reserved.
0006  */
0007 #include "xfs.h"
0008 #include "xfs_fs.h"
0009 #include "xfs_shared.h"
0010 #include "xfs_format.h"
0011 #include "xfs_log_format.h"
0012 #include "xfs_trans_resv.h"
0013 #include "xfs_bit.h"
0014 #include "xfs_mount.h"
0015 #include "xfs_da_format.h"
0016 #include "xfs_da_btree.h"
0017 #include "xfs_inode.h"
0018 #include "xfs_attr.h"
0019 #include "xfs_attr_remote.h"
0020 #include "xfs_trans.h"
0021 #include "xfs_bmap.h"
0022 #include "xfs_attr_leaf.h"
0023 #include "xfs_quota.h"
0024 #include "xfs_dir2.h"
0025 #include "xfs_error.h"
0026 
0027 /*
0028  * Invalidate any incore buffers associated with this remote attribute value
0029  * extent.   We never log remote attribute value buffers, which means that they
0030  * won't be attached to a transaction and are therefore safe to mark stale.
0031  * The actual bunmapi will be taken care of later.
0032  */
0033 STATIC int
0034 xfs_attr3_rmt_stale(
0035     struct xfs_inode    *dp,
0036     xfs_dablk_t     blkno,
0037     int         blkcnt)
0038 {
0039     struct xfs_bmbt_irec    map;
0040     int         nmap;
0041     int         error;
0042 
0043     /*
0044      * Roll through the "value", invalidating the attribute value's
0045      * blocks.
0046      */
0047     while (blkcnt > 0) {
0048         /*
0049          * Try to remember where we decided to put the value.
0050          */
0051         nmap = 1;
0052         error = xfs_bmapi_read(dp, (xfs_fileoff_t)blkno, blkcnt,
0053                        &map, &nmap, XFS_BMAPI_ATTRFORK);
0054         if (error)
0055             return error;
0056         if (XFS_IS_CORRUPT(dp->i_mount, nmap != 1))
0057             return -EFSCORRUPTED;
0058 
0059         /*
0060          * Mark any incore buffers for the remote value as stale.  We
0061          * never log remote attr value buffers, so the buffer should be
0062          * easy to kill.
0063          */
0064         error = xfs_attr_rmtval_stale(dp, &map, 0);
0065         if (error)
0066             return error;
0067 
0068         blkno += map.br_blockcount;
0069         blkcnt -= map.br_blockcount;
0070     }
0071 
0072     return 0;
0073 }
0074 
0075 /*
0076  * Invalidate all of the "remote" value regions pointed to by a particular
0077  * leaf block.
0078  * Note that we must release the lock on the buffer so that we are not
0079  * caught holding something that the logging code wants to flush to disk.
0080  */
0081 STATIC int
0082 xfs_attr3_leaf_inactive(
0083     struct xfs_trans        **trans,
0084     struct xfs_inode        *dp,
0085     struct xfs_buf          *bp)
0086 {
0087     struct xfs_attr3_icleaf_hdr ichdr;
0088     struct xfs_mount        *mp = bp->b_mount;
0089     struct xfs_attr_leafblock   *leaf = bp->b_addr;
0090     struct xfs_attr_leaf_entry  *entry;
0091     struct xfs_attr_leaf_name_remote *name_rmt;
0092     int             error = 0;
0093     int             i;
0094 
0095     xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf);
0096 
0097     /*
0098      * Find the remote value extents for this leaf and invalidate their
0099      * incore buffers.
0100      */
0101     entry = xfs_attr3_leaf_entryp(leaf);
0102     for (i = 0; i < ichdr.count; entry++, i++) {
0103         int     blkcnt;
0104 
0105         if (!entry->nameidx || (entry->flags & XFS_ATTR_LOCAL))
0106             continue;
0107 
0108         name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
0109         if (!name_rmt->valueblk)
0110             continue;
0111 
0112         blkcnt = xfs_attr3_rmt_blocks(dp->i_mount,
0113                 be32_to_cpu(name_rmt->valuelen));
0114         error = xfs_attr3_rmt_stale(dp,
0115                 be32_to_cpu(name_rmt->valueblk), blkcnt);
0116         if (error)
0117             goto err;
0118     }
0119 
0120     xfs_trans_brelse(*trans, bp);
0121 err:
0122     return error;
0123 }
0124 
0125 /*
0126  * Recurse (gasp!) through the attribute nodes until we find leaves.
0127  * We're doing a depth-first traversal in order to invalidate everything.
0128  */
0129 STATIC int
0130 xfs_attr3_node_inactive(
0131     struct xfs_trans    **trans,
0132     struct xfs_inode    *dp,
0133     struct xfs_buf      *bp,
0134     int         level)
0135 {
0136     struct xfs_mount    *mp = dp->i_mount;
0137     struct xfs_da_blkinfo   *info;
0138     xfs_dablk_t     child_fsb;
0139     xfs_daddr_t     parent_blkno, child_blkno;
0140     struct xfs_buf      *child_bp;
0141     struct xfs_da3_icnode_hdr ichdr;
0142     int         error, i;
0143 
0144     /*
0145      * Since this code is recursive (gasp!) we must protect ourselves.
0146      */
0147     if (level > XFS_DA_NODE_MAXDEPTH) {
0148         xfs_buf_mark_corrupt(bp);
0149         xfs_trans_brelse(*trans, bp);   /* no locks for later trans */
0150         return -EFSCORRUPTED;
0151     }
0152 
0153     xfs_da3_node_hdr_from_disk(dp->i_mount, &ichdr, bp->b_addr);
0154     parent_blkno = xfs_buf_daddr(bp);
0155     if (!ichdr.count) {
0156         xfs_trans_brelse(*trans, bp);
0157         return 0;
0158     }
0159     child_fsb = be32_to_cpu(ichdr.btree[0].before);
0160     xfs_trans_brelse(*trans, bp);   /* no locks for later trans */
0161     bp = NULL;
0162 
0163     /*
0164      * If this is the node level just above the leaves, simply loop
0165      * over the leaves removing all of them.  If this is higher up
0166      * in the tree, recurse downward.
0167      */
0168     for (i = 0; i < ichdr.count; i++) {
0169         /*
0170          * Read the subsidiary block to see what we have to work with.
0171          * Don't do this in a transaction.  This is a depth-first
0172          * traversal of the tree so we may deal with many blocks
0173          * before we come back to this one.
0174          */
0175         error = xfs_da3_node_read(*trans, dp, child_fsb, &child_bp,
0176                       XFS_ATTR_FORK);
0177         if (error)
0178             return error;
0179 
0180         /* save for re-read later */
0181         child_blkno = xfs_buf_daddr(child_bp);
0182 
0183         /*
0184          * Invalidate the subtree, however we have to.
0185          */
0186         info = child_bp->b_addr;
0187         switch (info->magic) {
0188         case cpu_to_be16(XFS_DA_NODE_MAGIC):
0189         case cpu_to_be16(XFS_DA3_NODE_MAGIC):
0190             error = xfs_attr3_node_inactive(trans, dp, child_bp,
0191                             level + 1);
0192             break;
0193         case cpu_to_be16(XFS_ATTR_LEAF_MAGIC):
0194         case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC):
0195             error = xfs_attr3_leaf_inactive(trans, dp, child_bp);
0196             break;
0197         default:
0198             xfs_buf_mark_corrupt(child_bp);
0199             xfs_trans_brelse(*trans, child_bp);
0200             error = -EFSCORRUPTED;
0201             break;
0202         }
0203         if (error)
0204             return error;
0205 
0206         /*
0207          * Remove the subsidiary block from the cache and from the log.
0208          */
0209         error = xfs_trans_get_buf(*trans, mp->m_ddev_targp,
0210                 child_blkno,
0211                 XFS_FSB_TO_BB(mp, mp->m_attr_geo->fsbcount), 0,
0212                 &child_bp);
0213         if (error)
0214             return error;
0215         xfs_trans_binval(*trans, child_bp);
0216         child_bp = NULL;
0217 
0218         /*
0219          * If we're not done, re-read the parent to get the next
0220          * child block number.
0221          */
0222         if (i + 1 < ichdr.count) {
0223             struct xfs_da3_icnode_hdr phdr;
0224 
0225             error = xfs_da3_node_read_mapped(*trans, dp,
0226                     parent_blkno, &bp, XFS_ATTR_FORK);
0227             if (error)
0228                 return error;
0229             xfs_da3_node_hdr_from_disk(dp->i_mount, &phdr,
0230                           bp->b_addr);
0231             child_fsb = be32_to_cpu(phdr.btree[i + 1].before);
0232             xfs_trans_brelse(*trans, bp);
0233             bp = NULL;
0234         }
0235         /*
0236          * Atomically commit the whole invalidate stuff.
0237          */
0238         error = xfs_trans_roll_inode(trans, dp);
0239         if (error)
0240             return  error;
0241     }
0242 
0243     return 0;
0244 }
0245 
0246 /*
0247  * Indiscriminately delete the entire attribute fork
0248  *
0249  * Recurse (gasp!) through the attribute nodes until we find leaves.
0250  * We're doing a depth-first traversal in order to invalidate everything.
0251  */
0252 static int
0253 xfs_attr3_root_inactive(
0254     struct xfs_trans    **trans,
0255     struct xfs_inode    *dp)
0256 {
0257     struct xfs_mount    *mp = dp->i_mount;
0258     struct xfs_da_blkinfo   *info;
0259     struct xfs_buf      *bp;
0260     xfs_daddr_t     blkno;
0261     int         error;
0262 
0263     /*
0264      * Read block 0 to see what we have to work with.
0265      * We only get here if we have extents, since we remove
0266      * the extents in reverse order the extent containing
0267      * block 0 must still be there.
0268      */
0269     error = xfs_da3_node_read(*trans, dp, 0, &bp, XFS_ATTR_FORK);
0270     if (error)
0271         return error;
0272     blkno = xfs_buf_daddr(bp);
0273 
0274     /*
0275      * Invalidate the tree, even if the "tree" is only a single leaf block.
0276      * This is a depth-first traversal!
0277      */
0278     info = bp->b_addr;
0279     switch (info->magic) {
0280     case cpu_to_be16(XFS_DA_NODE_MAGIC):
0281     case cpu_to_be16(XFS_DA3_NODE_MAGIC):
0282         error = xfs_attr3_node_inactive(trans, dp, bp, 1);
0283         break;
0284     case cpu_to_be16(XFS_ATTR_LEAF_MAGIC):
0285     case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC):
0286         error = xfs_attr3_leaf_inactive(trans, dp, bp);
0287         break;
0288     default:
0289         error = -EFSCORRUPTED;
0290         xfs_buf_mark_corrupt(bp);
0291         xfs_trans_brelse(*trans, bp);
0292         break;
0293     }
0294     if (error)
0295         return error;
0296 
0297     /*
0298      * Invalidate the incore copy of the root block.
0299      */
0300     error = xfs_trans_get_buf(*trans, mp->m_ddev_targp, blkno,
0301             XFS_FSB_TO_BB(mp, mp->m_attr_geo->fsbcount), 0, &bp);
0302     if (error)
0303         return error;
0304     error = bp->b_error;
0305     if (error) {
0306         xfs_trans_brelse(*trans, bp);
0307         return error;
0308     }
0309     xfs_trans_binval(*trans, bp);   /* remove from cache */
0310     /*
0311      * Commit the invalidate and start the next transaction.
0312      */
0313     error = xfs_trans_roll_inode(trans, dp);
0314 
0315     return error;
0316 }
0317 
0318 /*
0319  * xfs_attr_inactive kills all traces of an attribute fork on an inode. It
0320  * removes both the on-disk and in-memory inode fork. Note that this also has to
0321  * handle the condition of inodes without attributes but with an attribute fork
0322  * configured, so we can't use xfs_inode_hasattr() here.
0323  *
0324  * The in-memory attribute fork is removed even on error.
0325  */
0326 int
0327 xfs_attr_inactive(
0328     struct xfs_inode    *dp)
0329 {
0330     struct xfs_trans    *trans;
0331     struct xfs_mount    *mp;
0332     int         lock_mode = XFS_ILOCK_SHARED;
0333     int         error = 0;
0334 
0335     mp = dp->i_mount;
0336     ASSERT(! XFS_NOT_DQATTACHED(mp, dp));
0337 
0338     xfs_ilock(dp, lock_mode);
0339     if (!xfs_inode_has_attr_fork(dp))
0340         goto out_destroy_fork;
0341     xfs_iunlock(dp, lock_mode);
0342 
0343     lock_mode = 0;
0344 
0345     error = xfs_trans_alloc(mp, &M_RES(mp)->tr_attrinval, 0, 0, 0, &trans);
0346     if (error)
0347         goto out_destroy_fork;
0348 
0349     lock_mode = XFS_ILOCK_EXCL;
0350     xfs_ilock(dp, lock_mode);
0351 
0352     if (!xfs_inode_has_attr_fork(dp))
0353         goto out_cancel;
0354 
0355     /*
0356      * No need to make quota reservations here. We expect to release some
0357      * blocks, not allocate, in the common case.
0358      */
0359     xfs_trans_ijoin(trans, dp, 0);
0360 
0361     /*
0362      * Invalidate and truncate the attribute fork extents. Make sure the
0363      * fork actually has xattr blocks as otherwise the invalidation has no
0364      * blocks to read and returns an error. In this case, just do the fork
0365      * removal below.
0366      */
0367     if (dp->i_af.if_nextents > 0) {
0368         error = xfs_attr3_root_inactive(&trans, dp);
0369         if (error)
0370             goto out_cancel;
0371 
0372         error = xfs_itruncate_extents(&trans, dp, XFS_ATTR_FORK, 0);
0373         if (error)
0374             goto out_cancel;
0375     }
0376 
0377     /* Reset the attribute fork - this also destroys the in-core fork */
0378     xfs_attr_fork_remove(dp, trans);
0379 
0380     error = xfs_trans_commit(trans);
0381     xfs_iunlock(dp, lock_mode);
0382     return error;
0383 
0384 out_cancel:
0385     xfs_trans_cancel(trans);
0386 out_destroy_fork:
0387     /* kill the in-core attr fork before we drop the inode lock */
0388     xfs_ifork_zap_attr(dp);
0389     if (lock_mode)
0390         xfs_iunlock(dp, lock_mode);
0391     return error;
0392 }