linux/fs/xfs/xfs_attr_inactive.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
   3 * Copyright (c) 2013 Red Hat, Inc.
   4 * All Rights Reserved.
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License as
   8 * published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it would be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write the Free Software Foundation,
  17 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  18 */
  19#include "xfs.h"
  20#include "xfs_fs.h"
  21#include "xfs_shared.h"
  22#include "xfs_format.h"
  23#include "xfs_log_format.h"
  24#include "xfs_trans_resv.h"
  25#include "xfs_bit.h"
  26#include "xfs_mount.h"
  27#include "xfs_da_format.h"
  28#include "xfs_da_btree.h"
  29#include "xfs_inode.h"
  30#include "xfs_alloc.h"
  31#include "xfs_attr_remote.h"
  32#include "xfs_trans.h"
  33#include "xfs_inode_item.h"
  34#include "xfs_bmap.h"
  35#include "xfs_attr.h"
  36#include "xfs_attr_leaf.h"
  37#include "xfs_error.h"
  38#include "xfs_quota.h"
  39#include "xfs_trace.h"
  40#include "xfs_dir2.h"
  41
  42/*
  43 * Look at all the extents for this logical region,
  44 * invalidate any buffers that are incore/in transactions.
  45 */
  46STATIC int
  47xfs_attr3_leaf_freextent(
  48        struct xfs_trans        **trans,
  49        struct xfs_inode        *dp,
  50        xfs_dablk_t             blkno,
  51        int                     blkcnt)
  52{
  53        struct xfs_bmbt_irec    map;
  54        struct xfs_buf          *bp;
  55        xfs_dablk_t             tblkno;
  56        xfs_daddr_t             dblkno;
  57        int                     tblkcnt;
  58        int                     dblkcnt;
  59        int                     nmap;
  60        int                     error;
  61
  62        /*
  63         * Roll through the "value", invalidating the attribute value's
  64         * blocks.
  65         */
  66        tblkno = blkno;
  67        tblkcnt = blkcnt;
  68        while (tblkcnt > 0) {
  69                /*
  70                 * Try to remember where we decided to put the value.
  71                 */
  72                nmap = 1;
  73                error = xfs_bmapi_read(dp, (xfs_fileoff_t)tblkno, tblkcnt,
  74                                       &map, &nmap, XFS_BMAPI_ATTRFORK);
  75                if (error) {
  76                        return error;
  77                }
  78                ASSERT(nmap == 1);
  79                ASSERT(map.br_startblock != DELAYSTARTBLOCK);
  80
  81                /*
  82                 * If it's a hole, these are already unmapped
  83                 * so there's nothing to invalidate.
  84                 */
  85                if (map.br_startblock != HOLESTARTBLOCK) {
  86
  87                        dblkno = XFS_FSB_TO_DADDR(dp->i_mount,
  88                                                  map.br_startblock);
  89                        dblkcnt = XFS_FSB_TO_BB(dp->i_mount,
  90                                                map.br_blockcount);
  91                        bp = xfs_trans_get_buf(*trans,
  92                                        dp->i_mount->m_ddev_targp,
  93                                        dblkno, dblkcnt, 0);
  94                        if (!bp)
  95                                return -ENOMEM;
  96                        xfs_trans_binval(*trans, bp);
  97                        /*
  98                         * Roll to next transaction.
  99                         */
 100                        error = xfs_trans_roll(trans, dp);
 101                        if (error)
 102                                return error;
 103                }
 104
 105                tblkno += map.br_blockcount;
 106                tblkcnt -= map.br_blockcount;
 107        }
 108
 109        return 0;
 110}
 111
 112/*
 113 * Invalidate all of the "remote" value regions pointed to by a particular
 114 * leaf block.
 115 * Note that we must release the lock on the buffer so that we are not
 116 * caught holding something that the logging code wants to flush to disk.
 117 */
 118STATIC int
 119xfs_attr3_leaf_inactive(
 120        struct xfs_trans        **trans,
 121        struct xfs_inode        *dp,
 122        struct xfs_buf          *bp)
 123{
 124        struct xfs_attr_leafblock *leaf;
 125        struct xfs_attr3_icleaf_hdr ichdr;
 126        struct xfs_attr_leaf_entry *entry;
 127        struct xfs_attr_leaf_name_remote *name_rmt;
 128        struct xfs_attr_inactive_list *list;
 129        struct xfs_attr_inactive_list *lp;
 130        int                     error;
 131        int                     count;
 132        int                     size;
 133        int                     tmp;
 134        int                     i;
 135        struct xfs_mount        *mp = bp->b_target->bt_mount;
 136
 137        leaf = bp->b_addr;
 138        xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf);
 139
 140        /*
 141         * Count the number of "remote" value extents.
 142         */
 143        count = 0;
 144        entry = xfs_attr3_leaf_entryp(leaf);
 145        for (i = 0; i < ichdr.count; entry++, i++) {
 146                if (be16_to_cpu(entry->nameidx) &&
 147                    ((entry->flags & XFS_ATTR_LOCAL) == 0)) {
 148                        name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
 149                        if (name_rmt->valueblk)
 150                                count++;
 151                }
 152        }
 153
 154        /*
 155         * If there are no "remote" values, we're done.
 156         */
 157        if (count == 0) {
 158                xfs_trans_brelse(*trans, bp);
 159                return 0;
 160        }
 161
 162        /*
 163         * Allocate storage for a list of all the "remote" value extents.
 164         */
 165        size = count * sizeof(xfs_attr_inactive_list_t);
 166        list = kmem_alloc(size, KM_SLEEP);
 167
 168        /*
 169         * Identify each of the "remote" value extents.
 170         */
 171        lp = list;
 172        entry = xfs_attr3_leaf_entryp(leaf);
 173        for (i = 0; i < ichdr.count; entry++, i++) {
 174                if (be16_to_cpu(entry->nameidx) &&
 175                    ((entry->flags & XFS_ATTR_LOCAL) == 0)) {
 176                        name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
 177                        if (name_rmt->valueblk) {
 178                                lp->valueblk = be32_to_cpu(name_rmt->valueblk);
 179                                lp->valuelen = xfs_attr3_rmt_blocks(dp->i_mount,
 180                                                    be32_to_cpu(name_rmt->valuelen));
 181                                lp++;
 182                        }
 183                }
 184        }
 185        xfs_trans_brelse(*trans, bp);   /* unlock for trans. in freextent() */
 186
 187        /*
 188         * Invalidate each of the "remote" value extents.
 189         */
 190        error = 0;
 191        for (lp = list, i = 0; i < count; i++, lp++) {
 192                tmp = xfs_attr3_leaf_freextent(trans, dp,
 193                                lp->valueblk, lp->valuelen);
 194
 195                if (error == 0)
 196                        error = tmp;    /* save only the 1st errno */
 197        }
 198
 199        kmem_free(list);
 200        return error;
 201}
 202
 203/*
 204 * Recurse (gasp!) through the attribute nodes until we find leaves.
 205 * We're doing a depth-first traversal in order to invalidate everything.
 206 */
 207STATIC int
 208xfs_attr3_node_inactive(
 209        struct xfs_trans **trans,
 210        struct xfs_inode *dp,
 211        struct xfs_buf  *bp,
 212        int             level)
 213{
 214        xfs_da_blkinfo_t *info;
 215        xfs_da_intnode_t *node;
 216        xfs_dablk_t child_fsb;
 217        xfs_daddr_t parent_blkno, child_blkno;
 218        int error, i;
 219        struct xfs_buf *child_bp;
 220        struct xfs_da_node_entry *btree;
 221        struct xfs_da3_icnode_hdr ichdr;
 222
 223        /*
 224         * Since this code is recursive (gasp!) we must protect ourselves.
 225         */
 226        if (level > XFS_DA_NODE_MAXDEPTH) {
 227                xfs_trans_brelse(*trans, bp);   /* no locks for later trans */
 228                return -EIO;
 229        }
 230
 231        node = bp->b_addr;
 232        dp->d_ops->node_hdr_from_disk(&ichdr, node);
 233        parent_blkno = bp->b_bn;
 234        if (!ichdr.count) {
 235                xfs_trans_brelse(*trans, bp);
 236                return 0;
 237        }
 238        btree = dp->d_ops->node_tree_p(node);
 239        child_fsb = be32_to_cpu(btree[0].before);
 240        xfs_trans_brelse(*trans, bp);   /* no locks for later trans */
 241
 242        /*
 243         * If this is the node level just above the leaves, simply loop
 244         * over the leaves removing all of them.  If this is higher up
 245         * in the tree, recurse downward.
 246         */
 247        for (i = 0; i < ichdr.count; i++) {
 248                /*
 249                 * Read the subsidiary block to see what we have to work with.
 250                 * Don't do this in a transaction.  This is a depth-first
 251                 * traversal of the tree so we may deal with many blocks
 252                 * before we come back to this one.
 253                 */
 254                error = xfs_da3_node_read(*trans, dp, child_fsb, -2, &child_bp,
 255                                                XFS_ATTR_FORK);
 256                if (error)
 257                        return error;
 258                if (child_bp) {
 259                                                /* save for re-read later */
 260                        child_blkno = XFS_BUF_ADDR(child_bp);
 261
 262                        /*
 263                         * Invalidate the subtree, however we have to.
 264                         */
 265                        info = child_bp->b_addr;
 266                        switch (info->magic) {
 267                        case cpu_to_be16(XFS_DA_NODE_MAGIC):
 268                        case cpu_to_be16(XFS_DA3_NODE_MAGIC):
 269                                error = xfs_attr3_node_inactive(trans, dp,
 270                                                        child_bp, level + 1);
 271                                break;
 272                        case cpu_to_be16(XFS_ATTR_LEAF_MAGIC):
 273                        case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC):
 274                                error = xfs_attr3_leaf_inactive(trans, dp,
 275                                                        child_bp);
 276                                break;
 277                        default:
 278                                error = -EIO;
 279                                xfs_trans_brelse(*trans, child_bp);
 280                                break;
 281                        }
 282                        if (error)
 283                                return error;
 284
 285                        /*
 286                         * Remove the subsidiary block from the cache
 287                         * and from the log.
 288                         */
 289                        error = xfs_da_get_buf(*trans, dp, 0, child_blkno,
 290                                &child_bp, XFS_ATTR_FORK);
 291                        if (error)
 292                                return error;
 293                        xfs_trans_binval(*trans, child_bp);
 294                }
 295
 296                /*
 297                 * If we're not done, re-read the parent to get the next
 298                 * child block number.
 299                 */
 300                if (i + 1 < ichdr.count) {
 301                        error = xfs_da3_node_read(*trans, dp, 0, parent_blkno,
 302                                                 &bp, XFS_ATTR_FORK);
 303                        if (error)
 304                                return error;
 305                        child_fsb = be32_to_cpu(btree[i + 1].before);
 306                        xfs_trans_brelse(*trans, bp);
 307                }
 308                /*
 309                 * Atomically commit the whole invalidate stuff.
 310                 */
 311                error = xfs_trans_roll(trans, dp);
 312                if (error)
 313                        return  error;
 314        }
 315
 316        return 0;
 317}
 318
 319/*
 320 * Indiscriminately delete the entire attribute fork
 321 *
 322 * Recurse (gasp!) through the attribute nodes until we find leaves.
 323 * We're doing a depth-first traversal in order to invalidate everything.
 324 */
 325int
 326xfs_attr3_root_inactive(
 327        struct xfs_trans        **trans,
 328        struct xfs_inode        *dp)
 329{
 330        struct xfs_da_blkinfo   *info;
 331        struct xfs_buf          *bp;
 332        xfs_daddr_t             blkno;
 333        int                     error;
 334
 335        /*
 336         * Read block 0 to see what we have to work with.
 337         * We only get here if we have extents, since we remove
 338         * the extents in reverse order the extent containing
 339         * block 0 must still be there.
 340         */
 341        error = xfs_da3_node_read(*trans, dp, 0, -1, &bp, XFS_ATTR_FORK);
 342        if (error)
 343                return error;
 344        blkno = bp->b_bn;
 345
 346        /*
 347         * Invalidate the tree, even if the "tree" is only a single leaf block.
 348         * This is a depth-first traversal!
 349         */
 350        info = bp->b_addr;
 351        switch (info->magic) {
 352        case cpu_to_be16(XFS_DA_NODE_MAGIC):
 353        case cpu_to_be16(XFS_DA3_NODE_MAGIC):
 354                error = xfs_attr3_node_inactive(trans, dp, bp, 1);
 355                break;
 356        case cpu_to_be16(XFS_ATTR_LEAF_MAGIC):
 357        case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC):
 358                error = xfs_attr3_leaf_inactive(trans, dp, bp);
 359                break;
 360        default:
 361                error = -EIO;
 362                xfs_trans_brelse(*trans, bp);
 363                break;
 364        }
 365        if (error)
 366                return error;
 367
 368        /*
 369         * Invalidate the incore copy of the root block.
 370         */
 371        error = xfs_da_get_buf(*trans, dp, 0, blkno, &bp, XFS_ATTR_FORK);
 372        if (error)
 373                return error;
 374        xfs_trans_binval(*trans, bp);   /* remove from cache */
 375        /*
 376         * Commit the invalidate and start the next transaction.
 377         */
 378        error = xfs_trans_roll(trans, dp);
 379
 380        return error;
 381}
 382
 383/*
 384 * xfs_attr_inactive kills all traces of an attribute fork on an inode. It
 385 * removes both the on-disk and in-memory inode fork. Note that this also has to
 386 * handle the condition of inodes without attributes but with an attribute fork
 387 * configured, so we can't use xfs_inode_hasattr() here.
 388 *
 389 * The in-memory attribute fork is removed even on error.
 390 */
 391int
 392xfs_attr_inactive(
 393        struct xfs_inode        *dp)
 394{
 395        struct xfs_trans        *trans;
 396        struct xfs_mount        *mp;
 397        int                     lock_mode = XFS_ILOCK_SHARED;
 398        int                     error = 0;
 399
 400        mp = dp->i_mount;
 401        ASSERT(! XFS_NOT_DQATTACHED(mp, dp));
 402
 403        xfs_ilock(dp, lock_mode);
 404        if (!XFS_IFORK_Q(dp))
 405                goto out_destroy_fork;
 406        xfs_iunlock(dp, lock_mode);
 407
 408        /*
 409         * Start our first transaction of the day.
 410         *
 411         * All future transactions during this code must be "chained" off
 412         * this one via the trans_dup() call.  All transactions will contain
 413         * the inode, and the inode will always be marked with trans_ihold().
 414         * Since the inode will be locked in all transactions, we must log
 415         * the inode in every transaction to let it float upward through
 416         * the log.
 417         */
 418        lock_mode = 0;
 419        trans = xfs_trans_alloc(mp, XFS_TRANS_ATTRINVAL);
 420        error = xfs_trans_reserve(trans, &M_RES(mp)->tr_attrinval, 0, 0);
 421        if (error)
 422                goto out_cancel;
 423
 424        lock_mode = XFS_ILOCK_EXCL;
 425        xfs_ilock(dp, lock_mode);
 426
 427        if (!XFS_IFORK_Q(dp))
 428                goto out_cancel;
 429
 430        /*
 431         * No need to make quota reservations here. We expect to release some
 432         * blocks, not allocate, in the common case.
 433         */
 434        xfs_trans_ijoin(trans, dp, 0);
 435
 436        /*
 437         * Invalidate and truncate the attribute fork extents. Make sure the
 438         * fork actually has attributes as otherwise the invalidation has no
 439         * blocks to read and returns an error. In this case, just do the fork
 440         * removal below.
 441         */
 442        if (xfs_inode_hasattr(dp) &&
 443            dp->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) {
 444                error = xfs_attr3_root_inactive(&trans, dp);
 445                if (error)
 446                        goto out_cancel;
 447
 448                error = xfs_itruncate_extents(&trans, dp, XFS_ATTR_FORK, 0);
 449                if (error)
 450                        goto out_cancel;
 451        }
 452
 453        /* Reset the attribute fork - this also destroys the in-core fork */
 454        xfs_attr_fork_remove(dp, trans);
 455
 456        error = xfs_trans_commit(trans);
 457        xfs_iunlock(dp, lock_mode);
 458        return error;
 459
 460out_cancel:
 461        xfs_trans_cancel(trans);
 462out_destroy_fork:
 463        /* kill the in-core attr fork before we drop the inode lock */
 464        if (dp->i_afp)
 465                xfs_idestroy_fork(dp, XFS_ATTR_FORK);
 466        if (lock_mode)
 467                xfs_iunlock(dp, lock_mode);
 468        return error;
 469}
 470