| // SPDX-License-Identifier: GPL-2.0 |
| /* |
| * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. |
| * All Rights Reserved. |
| */ |
| |
| #include "libxfs_priv.h" |
| #include "xfs_fs.h" |
| #include "xfs_shared.h" |
| #include "xfs_format.h" |
| #include "xfs_log_format.h" |
| #include "xfs_trans_resv.h" |
| #include "xfs_mount.h" |
| #include "xfs_inode_buf.h" |
| #include "xfs_inode_fork.h" |
| #include "xfs_inode.h" |
| #include "xfs_trans.h" |
| |
| kmem_zone_t *xfs_buf_item_zone; |
| kmem_zone_t *xfs_ili_zone; /* inode log item zone */ |
| |
| /* |
| * Following functions from fs/xfs/xfs_trans_buf.c |
| */ |
| |
| /* |
| * Check to see if a buffer matching the given parameters is already |
| * a part of the given transaction. |
| */ |
| xfs_buf_t * |
| xfs_trans_buf_item_match( |
| xfs_trans_t *tp, |
| struct xfs_buftarg *btp, |
| struct xfs_buf_map *map, |
| int nmaps) |
| { |
| struct xfs_log_item *lip; |
| struct xfs_buf_log_item *blip; |
| int len = 0; |
| int i; |
| |
| for (i = 0; i < nmaps; i++) |
| len += map[i].bm_len; |
| |
| list_for_each_entry(lip, &tp->t_items, li_trans) { |
| blip = (struct xfs_buf_log_item *)lip; |
| if (blip->bli_item.li_type == XFS_LI_BUF && |
| blip->bli_buf->b_target->dev == btp->dev && |
| XFS_BUF_ADDR(blip->bli_buf) == map[0].bm_bn && |
| blip->bli_buf->b_bcount == BBTOB(len)) { |
| ASSERT(blip->bli_buf->b_map_count == nmaps); |
| return blip->bli_buf; |
| } |
| } |
| |
| return NULL; |
| } |
| /* |
| * The following are from fs/xfs/xfs_buf_item.c |
| */ |
| |
| /* |
| * Allocate a new buf log item to go with the given buffer. |
| * Set the buffer's b_log_item field to point to the new |
| * buf log item. If there are other item's attached to the |
| * buffer (see xfs_buf_attach_iodone() below), then put the |
| * buf log item at the front. |
| */ |
| void |
| xfs_buf_item_init( |
| xfs_buf_t *bp, |
| xfs_mount_t *mp) |
| { |
| xfs_log_item_t *lip; |
| xfs_buf_log_item_t *bip; |
| |
| #ifdef LI_DEBUG |
| fprintf(stderr, "buf_item_init for buffer %p\n", bp); |
| #endif |
| |
| /* |
| * Check to see if there is already a buf log item for |
| * this buffer. If there is, it is guaranteed to be |
| * the first. If we do already have one, there is |
| * nothing to do here so return. |
| */ |
| XFS_BUF_SET_BDSTRAT_FUNC(bp, xfs_bdstrat_cb); |
| if (bp->b_log_item != NULL) { |
| lip = bp->b_log_item; |
| if (lip->li_type == XFS_LI_BUF) { |
| #ifdef LI_DEBUG |
| fprintf(stderr, |
| "reused buf item %p for pre-logged buffer %p\n", |
| lip, bp); |
| #endif |
| return; |
| } |
| } |
| |
| bip = (xfs_buf_log_item_t *)kmem_zone_zalloc(xfs_buf_item_zone, |
| KM_SLEEP); |
| #ifdef LI_DEBUG |
| fprintf(stderr, "adding buf item %p for not-logged buffer %p\n", |
| bip, bp); |
| #endif |
| bip->bli_item.li_type = XFS_LI_BUF; |
| bip->bli_item.li_mountp = mp; |
| INIT_LIST_HEAD(&bip->bli_item.li_trans); |
| bip->bli_buf = bp; |
| bip->bli_format.blf_type = XFS_LI_BUF; |
| bip->bli_format.blf_blkno = (int64_t)XFS_BUF_ADDR(bp); |
| bip->bli_format.blf_len = (unsigned short)BTOBB(bp->b_bcount); |
| bp->b_log_item = bip; |
| } |
| |
| |
| /* |
| * Mark bytes first through last inclusive as dirty in the buf |
| * item's bitmap. |
| */ |
| void |
| xfs_buf_item_log( |
| xfs_buf_log_item_t *bip, |
| uint first, |
| uint last) |
| { |
| /* |
| * Mark the item as having some dirty data for |
| * quick reference in xfs_buf_item_dirty. |
| */ |
| bip->bli_flags |= XFS_BLI_DIRTY; |
| } |
| |
| /* |
| * Initialize the inode log item for a newly allocated (in-core) inode. |
| */ |
| void |
| xfs_inode_item_init( |
| xfs_inode_t *ip, |
| xfs_mount_t *mp) |
| { |
| xfs_inode_log_item_t *iip; |
| |
| ASSERT(ip->i_itemp == NULL); |
| iip = ip->i_itemp = (xfs_inode_log_item_t *) |
| kmem_zone_zalloc(xfs_ili_zone, KM_SLEEP); |
| #ifdef LI_DEBUG |
| fprintf(stderr, "inode_item_init for inode %llu, iip=%p\n", |
| ip->i_ino, iip); |
| #endif |
| |
| iip->ili_item.li_type = XFS_LI_INODE; |
| iip->ili_item.li_mountp = mp; |
| INIT_LIST_HEAD(&iip->ili_item.li_trans); |
| iip->ili_inode = ip; |
| } |