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