linux/fs/xfs/xfs_bmap_item.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2016 Oracle.  All Rights Reserved.
   3 *
   4 * Author: Darrick J. Wong <darrick.wong@oracle.com>
   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
   8 * as published by the Free Software Foundation; either version 2
   9 * of the License, or (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it would be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write the Free Software Foundation,
  18 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
  19 */
  20#include "xfs.h"
  21#include "xfs_fs.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_defer.h"
  28#include "xfs_inode.h"
  29#include "xfs_trans.h"
  30#include "xfs_trans_priv.h"
  31#include "xfs_buf_item.h"
  32#include "xfs_bmap_item.h"
  33#include "xfs_log.h"
  34#include "xfs_bmap.h"
  35#include "xfs_icache.h"
  36#include "xfs_trace.h"
  37#include "xfs_bmap_btree.h"
  38#include "xfs_trans_space.h"
  39
  40
  41kmem_zone_t     *xfs_bui_zone;
  42kmem_zone_t     *xfs_bud_zone;
  43
  44static inline struct xfs_bui_log_item *BUI_ITEM(struct xfs_log_item *lip)
  45{
  46        return container_of(lip, struct xfs_bui_log_item, bui_item);
  47}
  48
  49void
  50xfs_bui_item_free(
  51        struct xfs_bui_log_item *buip)
  52{
  53        kmem_zone_free(xfs_bui_zone, buip);
  54}
  55
  56STATIC void
  57xfs_bui_item_size(
  58        struct xfs_log_item     *lip,
  59        int                     *nvecs,
  60        int                     *nbytes)
  61{
  62        struct xfs_bui_log_item *buip = BUI_ITEM(lip);
  63
  64        *nvecs += 1;
  65        *nbytes += xfs_bui_log_format_sizeof(buip->bui_format.bui_nextents);
  66}
  67
  68/*
  69 * This is called to fill in the vector of log iovecs for the
  70 * given bui log item. We use only 1 iovec, and we point that
  71 * at the bui_log_format structure embedded in the bui item.
  72 * It is at this point that we assert that all of the extent
  73 * slots in the bui item have been filled.
  74 */
  75STATIC void
  76xfs_bui_item_format(
  77        struct xfs_log_item     *lip,
  78        struct xfs_log_vec      *lv)
  79{
  80        struct xfs_bui_log_item *buip = BUI_ITEM(lip);
  81        struct xfs_log_iovec    *vecp = NULL;
  82
  83        ASSERT(atomic_read(&buip->bui_next_extent) ==
  84                        buip->bui_format.bui_nextents);
  85
  86        buip->bui_format.bui_type = XFS_LI_BUI;
  87        buip->bui_format.bui_size = 1;
  88
  89        xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_BUI_FORMAT, &buip->bui_format,
  90                        xfs_bui_log_format_sizeof(buip->bui_format.bui_nextents));
  91}
  92
  93/*
  94 * Pinning has no meaning for an bui item, so just return.
  95 */
  96STATIC void
  97xfs_bui_item_pin(
  98        struct xfs_log_item     *lip)
  99{
 100}
 101
 102/*
 103 * The unpin operation is the last place an BUI is manipulated in the log. It is
 104 * either inserted in the AIL or aborted in the event of a log I/O error. In
 105 * either case, the BUI transaction has been successfully committed to make it
 106 * this far. Therefore, we expect whoever committed the BUI to either construct
 107 * and commit the BUD or drop the BUD's reference in the event of error. Simply
 108 * drop the log's BUI reference now that the log is done with it.
 109 */
 110STATIC void
 111xfs_bui_item_unpin(
 112        struct xfs_log_item     *lip,
 113        int                     remove)
 114{
 115        struct xfs_bui_log_item *buip = BUI_ITEM(lip);
 116
 117        xfs_bui_release(buip);
 118}
 119
 120/*
 121 * BUI items have no locking or pushing.  However, since BUIs are pulled from
 122 * the AIL when their corresponding BUDs are committed to disk, their situation
 123 * is very similar to being pinned.  Return XFS_ITEM_PINNED so that the caller
 124 * will eventually flush the log.  This should help in getting the BUI out of
 125 * the AIL.
 126 */
 127STATIC uint
 128xfs_bui_item_push(
 129        struct xfs_log_item     *lip,
 130        struct list_head        *buffer_list)
 131{
 132        return XFS_ITEM_PINNED;
 133}
 134
 135/*
 136 * The BUI has been either committed or aborted if the transaction has been
 137 * cancelled. If the transaction was cancelled, an BUD isn't going to be
 138 * constructed and thus we free the BUI here directly.
 139 */
 140STATIC void
 141xfs_bui_item_unlock(
 142        struct xfs_log_item     *lip)
 143{
 144        if (lip->li_flags & XFS_LI_ABORTED)
 145                xfs_bui_item_free(BUI_ITEM(lip));
 146}
 147
 148/*
 149 * The BUI is logged only once and cannot be moved in the log, so simply return
 150 * the lsn at which it's been logged.
 151 */
 152STATIC xfs_lsn_t
 153xfs_bui_item_committed(
 154        struct xfs_log_item     *lip,
 155        xfs_lsn_t               lsn)
 156{
 157        return lsn;
 158}
 159
 160/*
 161 * The BUI dependency tracking op doesn't do squat.  It can't because
 162 * it doesn't know where the free extent is coming from.  The dependency
 163 * tracking has to be handled by the "enclosing" metadata object.  For
 164 * example, for inodes, the inode is locked throughout the extent freeing
 165 * so the dependency should be recorded there.
 166 */
 167STATIC void
 168xfs_bui_item_committing(
 169        struct xfs_log_item     *lip,
 170        xfs_lsn_t               lsn)
 171{
 172}
 173
 174/*
 175 * This is the ops vector shared by all bui log items.
 176 */
 177static const struct xfs_item_ops xfs_bui_item_ops = {
 178        .iop_size       = xfs_bui_item_size,
 179        .iop_format     = xfs_bui_item_format,
 180        .iop_pin        = xfs_bui_item_pin,
 181        .iop_unpin      = xfs_bui_item_unpin,
 182        .iop_unlock     = xfs_bui_item_unlock,
 183        .iop_committed  = xfs_bui_item_committed,
 184        .iop_push       = xfs_bui_item_push,
 185        .iop_committing = xfs_bui_item_committing,
 186};
 187
 188/*
 189 * Allocate and initialize an bui item with the given number of extents.
 190 */
 191struct xfs_bui_log_item *
 192xfs_bui_init(
 193        struct xfs_mount                *mp)
 194
 195{
 196        struct xfs_bui_log_item         *buip;
 197
 198        buip = kmem_zone_zalloc(xfs_bui_zone, KM_SLEEP);
 199
 200        xfs_log_item_init(mp, &buip->bui_item, XFS_LI_BUI, &xfs_bui_item_ops);
 201        buip->bui_format.bui_nextents = XFS_BUI_MAX_FAST_EXTENTS;
 202        buip->bui_format.bui_id = (uintptr_t)(void *)buip;
 203        atomic_set(&buip->bui_next_extent, 0);
 204        atomic_set(&buip->bui_refcount, 2);
 205
 206        return buip;
 207}
 208
 209/*
 210 * Freeing the BUI requires that we remove it from the AIL if it has already
 211 * been placed there. However, the BUI may not yet have been placed in the AIL
 212 * when called by xfs_bui_release() from BUD processing due to the ordering of
 213 * committed vs unpin operations in bulk insert operations. Hence the reference
 214 * count to ensure only the last caller frees the BUI.
 215 */
 216void
 217xfs_bui_release(
 218        struct xfs_bui_log_item *buip)
 219{
 220        ASSERT(atomic_read(&buip->bui_refcount) > 0);
 221        if (atomic_dec_and_test(&buip->bui_refcount)) {
 222                xfs_trans_ail_remove(&buip->bui_item, SHUTDOWN_LOG_IO_ERROR);
 223                xfs_bui_item_free(buip);
 224        }
 225}
 226
 227static inline struct xfs_bud_log_item *BUD_ITEM(struct xfs_log_item *lip)
 228{
 229        return container_of(lip, struct xfs_bud_log_item, bud_item);
 230}
 231
 232STATIC void
 233xfs_bud_item_size(
 234        struct xfs_log_item     *lip,
 235        int                     *nvecs,
 236        int                     *nbytes)
 237{
 238        *nvecs += 1;
 239        *nbytes += sizeof(struct xfs_bud_log_format);
 240}
 241
 242/*
 243 * This is called to fill in the vector of log iovecs for the
 244 * given bud log item. We use only 1 iovec, and we point that
 245 * at the bud_log_format structure embedded in the bud item.
 246 * It is at this point that we assert that all of the extent
 247 * slots in the bud item have been filled.
 248 */
 249STATIC void
 250xfs_bud_item_format(
 251        struct xfs_log_item     *lip,
 252        struct xfs_log_vec      *lv)
 253{
 254        struct xfs_bud_log_item *budp = BUD_ITEM(lip);
 255        struct xfs_log_iovec    *vecp = NULL;
 256
 257        budp->bud_format.bud_type = XFS_LI_BUD;
 258        budp->bud_format.bud_size = 1;
 259
 260        xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_BUD_FORMAT, &budp->bud_format,
 261                        sizeof(struct xfs_bud_log_format));
 262}
 263
 264/*
 265 * Pinning has no meaning for an bud item, so just return.
 266 */
 267STATIC void
 268xfs_bud_item_pin(
 269        struct xfs_log_item     *lip)
 270{
 271}
 272
 273/*
 274 * Since pinning has no meaning for an bud item, unpinning does
 275 * not either.
 276 */
 277STATIC void
 278xfs_bud_item_unpin(
 279        struct xfs_log_item     *lip,
 280        int                     remove)
 281{
 282}
 283
 284/*
 285 * There isn't much you can do to push on an bud item.  It is simply stuck
 286 * waiting for the log to be flushed to disk.
 287 */
 288STATIC uint
 289xfs_bud_item_push(
 290        struct xfs_log_item     *lip,
 291        struct list_head        *buffer_list)
 292{
 293        return XFS_ITEM_PINNED;
 294}
 295
 296/*
 297 * The BUD is either committed or aborted if the transaction is cancelled. If
 298 * the transaction is cancelled, drop our reference to the BUI and free the
 299 * BUD.
 300 */
 301STATIC void
 302xfs_bud_item_unlock(
 303        struct xfs_log_item     *lip)
 304{
 305        struct xfs_bud_log_item *budp = BUD_ITEM(lip);
 306
 307        if (lip->li_flags & XFS_LI_ABORTED) {
 308                xfs_bui_release(budp->bud_buip);
 309                kmem_zone_free(xfs_bud_zone, budp);
 310        }
 311}
 312
 313/*
 314 * When the bud item is committed to disk, all we need to do is delete our
 315 * reference to our partner bui item and then free ourselves. Since we're
 316 * freeing ourselves we must return -1 to keep the transaction code from
 317 * further referencing this item.
 318 */
 319STATIC xfs_lsn_t
 320xfs_bud_item_committed(
 321        struct xfs_log_item     *lip,
 322        xfs_lsn_t               lsn)
 323{
 324        struct xfs_bud_log_item *budp = BUD_ITEM(lip);
 325
 326        /*
 327         * Drop the BUI reference regardless of whether the BUD has been
 328         * aborted. Once the BUD transaction is constructed, it is the sole
 329         * responsibility of the BUD to release the BUI (even if the BUI is
 330         * aborted due to log I/O error).
 331         */
 332        xfs_bui_release(budp->bud_buip);
 333        kmem_zone_free(xfs_bud_zone, budp);
 334
 335        return (xfs_lsn_t)-1;
 336}
 337
 338/*
 339 * The BUD dependency tracking op doesn't do squat.  It can't because
 340 * it doesn't know where the free extent is coming from.  The dependency
 341 * tracking has to be handled by the "enclosing" metadata object.  For
 342 * example, for inodes, the inode is locked throughout the extent freeing
 343 * so the dependency should be recorded there.
 344 */
 345STATIC void
 346xfs_bud_item_committing(
 347        struct xfs_log_item     *lip,
 348        xfs_lsn_t               lsn)
 349{
 350}
 351
 352/*
 353 * This is the ops vector shared by all bud log items.
 354 */
 355static const struct xfs_item_ops xfs_bud_item_ops = {
 356        .iop_size       = xfs_bud_item_size,
 357        .iop_format     = xfs_bud_item_format,
 358        .iop_pin        = xfs_bud_item_pin,
 359        .iop_unpin      = xfs_bud_item_unpin,
 360        .iop_unlock     = xfs_bud_item_unlock,
 361        .iop_committed  = xfs_bud_item_committed,
 362        .iop_push       = xfs_bud_item_push,
 363        .iop_committing = xfs_bud_item_committing,
 364};
 365
 366/*
 367 * Allocate and initialize an bud item with the given number of extents.
 368 */
 369struct xfs_bud_log_item *
 370xfs_bud_init(
 371        struct xfs_mount                *mp,
 372        struct xfs_bui_log_item         *buip)
 373
 374{
 375        struct xfs_bud_log_item *budp;
 376
 377        budp = kmem_zone_zalloc(xfs_bud_zone, KM_SLEEP);
 378        xfs_log_item_init(mp, &budp->bud_item, XFS_LI_BUD, &xfs_bud_item_ops);
 379        budp->bud_buip = buip;
 380        budp->bud_format.bud_bui_id = buip->bui_format.bui_id;
 381
 382        return budp;
 383}
 384
 385/*
 386 * Process a bmap update intent item that was recovered from the log.
 387 * We need to update some inode's bmbt.
 388 */
 389int
 390xfs_bui_recover(
 391        struct xfs_mount                *mp,
 392        struct xfs_bui_log_item         *buip)
 393{
 394        int                             error = 0;
 395        unsigned int                    bui_type;
 396        struct xfs_map_extent           *bmap;
 397        xfs_fsblock_t                   startblock_fsb;
 398        xfs_fsblock_t                   inode_fsb;
 399        xfs_filblks_t                   count;
 400        bool                            op_ok;
 401        struct xfs_bud_log_item         *budp;
 402        enum xfs_bmap_intent_type       type;
 403        int                             whichfork;
 404        xfs_exntst_t                    state;
 405        struct xfs_trans                *tp;
 406        struct xfs_inode                *ip = NULL;
 407        struct xfs_defer_ops            dfops;
 408        struct xfs_bmbt_irec            irec;
 409        xfs_fsblock_t                   firstfsb;
 410
 411        ASSERT(!test_bit(XFS_BUI_RECOVERED, &buip->bui_flags));
 412
 413        /* Only one mapping operation per BUI... */
 414        if (buip->bui_format.bui_nextents != XFS_BUI_MAX_FAST_EXTENTS) {
 415                set_bit(XFS_BUI_RECOVERED, &buip->bui_flags);
 416                xfs_bui_release(buip);
 417                return -EIO;
 418        }
 419
 420        /*
 421         * First check the validity of the extent described by the
 422         * BUI.  If anything is bad, then toss the BUI.
 423         */
 424        bmap = &buip->bui_format.bui_extents[0];
 425        startblock_fsb = XFS_BB_TO_FSB(mp,
 426                           XFS_FSB_TO_DADDR(mp, bmap->me_startblock));
 427        inode_fsb = XFS_BB_TO_FSB(mp, XFS_FSB_TO_DADDR(mp,
 428                        XFS_INO_TO_FSB(mp, bmap->me_owner)));
 429        switch (bmap->me_flags & XFS_BMAP_EXTENT_TYPE_MASK) {
 430        case XFS_BMAP_MAP:
 431        case XFS_BMAP_UNMAP:
 432                op_ok = true;
 433                break;
 434        default:
 435                op_ok = false;
 436                break;
 437        }
 438        if (!op_ok || startblock_fsb == 0 ||
 439            bmap->me_len == 0 ||
 440            inode_fsb == 0 ||
 441            startblock_fsb >= mp->m_sb.sb_dblocks ||
 442            bmap->me_len >= mp->m_sb.sb_agblocks ||
 443            inode_fsb >= mp->m_sb.sb_dblocks ||
 444            (bmap->me_flags & ~XFS_BMAP_EXTENT_FLAGS)) {
 445                /*
 446                 * This will pull the BUI from the AIL and
 447                 * free the memory associated with it.
 448                 */
 449                set_bit(XFS_BUI_RECOVERED, &buip->bui_flags);
 450                xfs_bui_release(buip);
 451                return -EIO;
 452        }
 453
 454        error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate,
 455                        XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK), 0, 0, &tp);
 456        if (error)
 457                return error;
 458        budp = xfs_trans_get_bud(tp, buip);
 459
 460        /* Grab the inode. */
 461        error = xfs_iget(mp, tp, bmap->me_owner, 0, XFS_ILOCK_EXCL, &ip);
 462        if (error)
 463                goto err_inode;
 464
 465        if (VFS_I(ip)->i_nlink == 0)
 466                xfs_iflags_set(ip, XFS_IRECOVERY);
 467        xfs_defer_init(&dfops, &firstfsb);
 468
 469        /* Process deferred bmap item. */
 470        state = (bmap->me_flags & XFS_BMAP_EXTENT_UNWRITTEN) ?
 471                        XFS_EXT_UNWRITTEN : XFS_EXT_NORM;
 472        whichfork = (bmap->me_flags & XFS_BMAP_EXTENT_ATTR_FORK) ?
 473                        XFS_ATTR_FORK : XFS_DATA_FORK;
 474        bui_type = bmap->me_flags & XFS_BMAP_EXTENT_TYPE_MASK;
 475        switch (bui_type) {
 476        case XFS_BMAP_MAP:
 477        case XFS_BMAP_UNMAP:
 478                type = bui_type;
 479                break;
 480        default:
 481                error = -EFSCORRUPTED;
 482                goto err_dfops;
 483        }
 484        xfs_trans_ijoin(tp, ip, 0);
 485
 486        count = bmap->me_len;
 487        error = xfs_trans_log_finish_bmap_update(tp, budp, &dfops, type,
 488                        ip, whichfork, bmap->me_startoff,
 489                        bmap->me_startblock, &count, state);
 490        if (error)
 491                goto err_dfops;
 492
 493        if (count > 0) {
 494                ASSERT(type == XFS_BMAP_UNMAP);
 495                irec.br_startblock = bmap->me_startblock;
 496                irec.br_blockcount = count;
 497                irec.br_startoff = bmap->me_startoff;
 498                irec.br_state = state;
 499                error = xfs_bmap_unmap_extent(tp->t_mountp, &dfops, ip, &irec);
 500                if (error)
 501                        goto err_dfops;
 502        }
 503
 504        /* Finish transaction, free inodes. */
 505        error = xfs_defer_finish(&tp, &dfops);
 506        if (error)
 507                goto err_dfops;
 508
 509        set_bit(XFS_BUI_RECOVERED, &buip->bui_flags);
 510        error = xfs_trans_commit(tp);
 511        xfs_iunlock(ip, XFS_ILOCK_EXCL);
 512        IRELE(ip);
 513
 514        return error;
 515
 516err_dfops:
 517        xfs_defer_cancel(&dfops);
 518err_inode:
 519        xfs_trans_cancel(tp);
 520        if (ip) {
 521                xfs_iunlock(ip, XFS_ILOCK_EXCL);
 522                IRELE(ip);
 523        }
 524        return error;
 525}
 526