linux/fs/xfs/xfs_icreate_item.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2008-2010, 2013 Dave Chinner
   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_bit.h"
  25#include "xfs_mount.h"
  26#include "xfs_trans.h"
  27#include "xfs_trans_priv.h"
  28#include "xfs_error.h"
  29#include "xfs_icreate_item.h"
  30#include "xfs_log.h"
  31
  32kmem_zone_t     *xfs_icreate_zone;              /* inode create item zone */
  33
  34static inline struct xfs_icreate_item *ICR_ITEM(struct xfs_log_item *lip)
  35{
  36        return container_of(lip, struct xfs_icreate_item, ic_item);
  37}
  38
  39/*
  40 * This returns the number of iovecs needed to log the given inode item.
  41 *
  42 * We only need one iovec for the icreate log structure.
  43 */
  44STATIC void
  45xfs_icreate_item_size(
  46        struct xfs_log_item     *lip,
  47        int                     *nvecs,
  48        int                     *nbytes)
  49{
  50        *nvecs += 1;
  51        *nbytes += sizeof(struct xfs_icreate_log);
  52}
  53
  54/*
  55 * This is called to fill in the vector of log iovecs for the
  56 * given inode create log item.
  57 */
  58STATIC void
  59xfs_icreate_item_format(
  60        struct xfs_log_item     *lip,
  61        struct xfs_log_vec      *lv)
  62{
  63        struct xfs_icreate_item *icp = ICR_ITEM(lip);
  64        struct xfs_log_iovec    *vecp = NULL;
  65
  66        xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ICREATE,
  67                        &icp->ic_format,
  68                        sizeof(struct xfs_icreate_log));
  69}
  70
  71
  72/* Pinning has no meaning for the create item, so just return. */
  73STATIC void
  74xfs_icreate_item_pin(
  75        struct xfs_log_item     *lip)
  76{
  77}
  78
  79
  80/* pinning has no meaning for the create item, so just return. */
  81STATIC void
  82xfs_icreate_item_unpin(
  83        struct xfs_log_item     *lip,
  84        int                     remove)
  85{
  86}
  87
  88STATIC void
  89xfs_icreate_item_unlock(
  90        struct xfs_log_item     *lip)
  91{
  92        struct xfs_icreate_item *icp = ICR_ITEM(lip);
  93
  94        if (icp->ic_item.li_flags & XFS_LI_ABORTED)
  95                kmem_zone_free(xfs_icreate_zone, icp);
  96        return;
  97}
  98
  99/*
 100 * Because we have ordered buffers being tracked in the AIL for the inode
 101 * creation, we don't need the create item after this. Hence we can free
 102 * the log item and return -1 to tell the caller we're done with the item.
 103 */
 104STATIC xfs_lsn_t
 105xfs_icreate_item_committed(
 106        struct xfs_log_item     *lip,
 107        xfs_lsn_t               lsn)
 108{
 109        struct xfs_icreate_item *icp = ICR_ITEM(lip);
 110
 111        kmem_zone_free(xfs_icreate_zone, icp);
 112        return (xfs_lsn_t)-1;
 113}
 114
 115/* item can never get into the AIL */
 116STATIC uint
 117xfs_icreate_item_push(
 118        struct xfs_log_item     *lip,
 119        struct list_head        *buffer_list)
 120{
 121        ASSERT(0);
 122        return XFS_ITEM_SUCCESS;
 123}
 124
 125/* Ordered buffers do the dependency tracking here, so this does nothing. */
 126STATIC void
 127xfs_icreate_item_committing(
 128        struct xfs_log_item     *lip,
 129        xfs_lsn_t               lsn)
 130{
 131}
 132
 133/*
 134 * This is the ops vector shared by all buf log items.
 135 */
 136static const struct xfs_item_ops xfs_icreate_item_ops = {
 137        .iop_size       = xfs_icreate_item_size,
 138        .iop_format     = xfs_icreate_item_format,
 139        .iop_pin        = xfs_icreate_item_pin,
 140        .iop_unpin      = xfs_icreate_item_unpin,
 141        .iop_push       = xfs_icreate_item_push,
 142        .iop_unlock     = xfs_icreate_item_unlock,
 143        .iop_committed  = xfs_icreate_item_committed,
 144        .iop_committing = xfs_icreate_item_committing,
 145};
 146
 147
 148/*
 149 * Initialize the inode log item for a newly allocated (in-core) inode.
 150 *
 151 * Inode extents can only reside within an AG. Hence specify the starting
 152 * block for the inode chunk by offset within an AG as well as the
 153 * length of the allocated extent.
 154 *
 155 * This joins the item to the transaction and marks it dirty so
 156 * that we don't need a separate call to do this, nor does the
 157 * caller need to know anything about the icreate item.
 158 */
 159void
 160xfs_icreate_log(
 161        struct xfs_trans        *tp,
 162        xfs_agnumber_t          agno,
 163        xfs_agblock_t           agbno,
 164        unsigned int            count,
 165        unsigned int            inode_size,
 166        xfs_agblock_t           length,
 167        unsigned int            generation)
 168{
 169        struct xfs_icreate_item *icp;
 170
 171        icp = kmem_zone_zalloc(xfs_icreate_zone, KM_SLEEP);
 172
 173        xfs_log_item_init(tp->t_mountp, &icp->ic_item, XFS_LI_ICREATE,
 174                          &xfs_icreate_item_ops);
 175
 176        icp->ic_format.icl_type = XFS_LI_ICREATE;
 177        icp->ic_format.icl_size = 1;    /* single vector */
 178        icp->ic_format.icl_ag = cpu_to_be32(agno);
 179        icp->ic_format.icl_agbno = cpu_to_be32(agbno);
 180        icp->ic_format.icl_count = cpu_to_be32(count);
 181        icp->ic_format.icl_isize = cpu_to_be32(inode_size);
 182        icp->ic_format.icl_length = cpu_to_be32(length);
 183        icp->ic_format.icl_gen = cpu_to_be32(generation);
 184
 185        xfs_trans_add_item(tp, &icp->ic_item);
 186        tp->t_flags |= XFS_TRANS_DIRTY;
 187        icp->ic_item.li_desc->lid_flags |= XFS_LID_DIRTY;
 188}
 189