linux/fs/xfs/xfs_trans_extfree.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2000,2005 Silicon Graphics, Inc.
   3 * All Rights Reserved.
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License as
   7 * published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it would be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 *
  14 * You should have received a copy of the GNU General Public License
  15 * along with this program; if not, write the Free Software Foundation,
  16 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  17 */
  18#include "xfs.h"
  19#include "xfs_fs.h"
  20#include "xfs_shared.h"
  21#include "xfs_format.h"
  22#include "xfs_log_format.h"
  23#include "xfs_trans_resv.h"
  24#include "xfs_mount.h"
  25#include "xfs_trans.h"
  26#include "xfs_trans_priv.h"
  27#include "xfs_extfree_item.h"
  28
  29/*
  30 * This routine is called to allocate an "extent free intention"
  31 * log item that will hold nextents worth of extents.  The
  32 * caller must use all nextents extents, because we are not
  33 * flexible about this at all.
  34 */
  35xfs_efi_log_item_t *
  36xfs_trans_get_efi(xfs_trans_t   *tp,
  37                  uint          nextents)
  38{
  39        xfs_efi_log_item_t      *efip;
  40
  41        ASSERT(tp != NULL);
  42        ASSERT(nextents > 0);
  43
  44        efip = xfs_efi_init(tp->t_mountp, nextents);
  45        ASSERT(efip != NULL);
  46
  47        /*
  48         * Get a log_item_desc to point at the new item.
  49         */
  50        xfs_trans_add_item(tp, &efip->efi_item);
  51        return efip;
  52}
  53
  54/*
  55 * This routine is called to indicate that the described
  56 * extent is to be logged as needing to be freed.  It should
  57 * be called once for each extent to be freed.
  58 */
  59void
  60xfs_trans_log_efi_extent(xfs_trans_t            *tp,
  61                         xfs_efi_log_item_t     *efip,
  62                         xfs_fsblock_t          start_block,
  63                         xfs_extlen_t           ext_len)
  64{
  65        uint                    next_extent;
  66        xfs_extent_t            *extp;
  67
  68        tp->t_flags |= XFS_TRANS_DIRTY;
  69        efip->efi_item.li_desc->lid_flags |= XFS_LID_DIRTY;
  70
  71        /*
  72         * atomic_inc_return gives us the value after the increment;
  73         * we want to use it as an array index so we need to subtract 1 from
  74         * it.
  75         */
  76        next_extent = atomic_inc_return(&efip->efi_next_extent) - 1;
  77        ASSERT(next_extent < efip->efi_format.efi_nextents);
  78        extp = &(efip->efi_format.efi_extents[next_extent]);
  79        extp->ext_start = start_block;
  80        extp->ext_len = ext_len;
  81}
  82
  83
  84/*
  85 * This routine is called to allocate an "extent free done"
  86 * log item that will hold nextents worth of extents.  The
  87 * caller must use all nextents extents, because we are not
  88 * flexible about this at all.
  89 */
  90xfs_efd_log_item_t *
  91xfs_trans_get_efd(xfs_trans_t           *tp,
  92                  xfs_efi_log_item_t    *efip,
  93                  uint                  nextents)
  94{
  95        xfs_efd_log_item_t      *efdp;
  96
  97        ASSERT(tp != NULL);
  98        ASSERT(nextents > 0);
  99
 100        efdp = xfs_efd_init(tp->t_mountp, efip, nextents);
 101        ASSERT(efdp != NULL);
 102
 103        /*
 104         * Get a log_item_desc to point at the new item.
 105         */
 106        xfs_trans_add_item(tp, &efdp->efd_item);
 107        return efdp;
 108}
 109
 110/*
 111 * This routine is called to indicate that the described
 112 * extent is to be logged as having been freed.  It should
 113 * be called once for each extent freed.
 114 */
 115void
 116xfs_trans_log_efd_extent(xfs_trans_t            *tp,
 117                         xfs_efd_log_item_t     *efdp,
 118                         xfs_fsblock_t          start_block,
 119                         xfs_extlen_t           ext_len)
 120{
 121        uint                    next_extent;
 122        xfs_extent_t            *extp;
 123
 124        tp->t_flags |= XFS_TRANS_DIRTY;
 125        efdp->efd_item.li_desc->lid_flags |= XFS_LID_DIRTY;
 126
 127        next_extent = efdp->efd_next_extent;
 128        ASSERT(next_extent < efdp->efd_format.efd_nextents);
 129        extp = &(efdp->efd_format.efd_extents[next_extent]);
 130        extp->ext_start = start_block;
 131        extp->ext_len = ext_len;
 132        efdp->efd_next_extent++;
 133}
 134