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_log_format.h"
  22#include "xfs_trans_resv.h"
  23#include "xfs_sb.h"
  24#include "xfs_ag.h"
  25#include "xfs_mount.h"
  26#include "xfs_trans.h"
  27#include "xfs_trans_priv.h"
  28#include "xfs_extfree_item.h"
  29
  30/*
  31 * This routine is called to allocate an "extent free intention"
  32 * log item that will hold nextents worth of extents.  The
  33 * caller must use all nextents extents, because we are not
  34 * flexible about this at all.
  35 */
  36xfs_efi_log_item_t *
  37xfs_trans_get_efi(xfs_trans_t   *tp,
  38                  uint          nextents)
  39{
  40        xfs_efi_log_item_t      *efip;
  41
  42        ASSERT(tp != NULL);
  43        ASSERT(nextents > 0);
  44
  45        efip = xfs_efi_init(tp->t_mountp, nextents);
  46        ASSERT(efip != NULL);
  47
  48        /*
  49         * Get a log_item_desc to point at the new item.
  50         */
  51        xfs_trans_add_item(tp, &efip->efi_item);
  52        return efip;
  53}
  54
  55/*
  56 * This routine is called to indicate that the described
  57 * extent is to be logged as needing to be freed.  It should
  58 * be called once for each extent to be freed.
  59 */
  60void
  61xfs_trans_log_efi_extent(xfs_trans_t            *tp,
  62                         xfs_efi_log_item_t     *efip,
  63                         xfs_fsblock_t          start_block,
  64                         xfs_extlen_t           ext_len)
  65{
  66        uint                    next_extent;
  67        xfs_extent_t            *extp;
  68
  69        tp->t_flags |= XFS_TRANS_DIRTY;
  70        efip->efi_item.li_desc->lid_flags |= XFS_LID_DIRTY;
  71
  72        /*
  73         * atomic_inc_return gives us the value after the increment;
  74         * we want to use it as an array index so we need to subtract 1 from
  75         * it.
  76         */
  77        next_extent = atomic_inc_return(&efip->efi_next_extent) - 1;
  78        ASSERT(next_extent < efip->efi_format.efi_nextents);
  79        extp = &(efip->efi_format.efi_extents[next_extent]);
  80        extp->ext_start = start_block;
  81        extp->ext_len = ext_len;
  82}
  83
  84
  85/*
  86 * This routine is called to allocate an "extent free done"
  87 * log item that will hold nextents worth of extents.  The
  88 * caller must use all nextents extents, because we are not
  89 * flexible about this at all.
  90 */
  91xfs_efd_log_item_t *
  92xfs_trans_get_efd(xfs_trans_t           *tp,
  93                  xfs_efi_log_item_t    *efip,
  94                  uint                  nextents)
  95{
  96        xfs_efd_log_item_t      *efdp;
  97
  98        ASSERT(tp != NULL);
  99        ASSERT(nextents > 0);
 100
 101        efdp = xfs_efd_init(tp->t_mountp, efip, nextents);
 102        ASSERT(efdp != NULL);
 103
 104        /*
 105         * Get a log_item_desc to point at the new item.
 106         */
 107        xfs_trans_add_item(tp, &efdp->efd_item);
 108        return efdp;
 109}
 110
 111/*
 112 * This routine is called to indicate that the described
 113 * extent is to be logged as having been freed.  It should
 114 * be called once for each extent freed.
 115 */
 116void
 117xfs_trans_log_efd_extent(xfs_trans_t            *tp,
 118                         xfs_efd_log_item_t     *efdp,
 119                         xfs_fsblock_t          start_block,
 120                         xfs_extlen_t           ext_len)
 121{
 122        uint                    next_extent;
 123        xfs_extent_t            *extp;
 124
 125        tp->t_flags |= XFS_TRANS_DIRTY;
 126        efdp->efd_item.li_desc->lid_flags |= XFS_LID_DIRTY;
 127
 128        next_extent = efdp->efd_next_extent;
 129        ASSERT(next_extent < efdp->efd_format.efd_nextents);
 130        extp = &(efdp->efd_format.efd_extents[next_extent]);
 131        extp->ext_start = start_block;
 132        extp->ext_len = ext_len;
 133        efdp->efd_next_extent++;
 134}
 135