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