]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - libxfs/xfs_trans_inode.c
xfsprogs: Release v6.7.0
[thirdparty/xfsprogs-dev.git] / libxfs / xfs_trans_inode.c
CommitLineData
5539639c
ES
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2000,2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
5 */
6#include "libxfs_priv.h"
7#include "xfs_fs.h"
8#include "xfs_shared.h"
9#include "xfs_format.h"
10#include "xfs_log_format.h"
2b8ea826
DC
11#include "xfs_trans_resv.h"
12#include "xfs_mount.h"
5539639c
ES
13#include "xfs_inode.h"
14#include "xfs_trans.h"
5539639c 15
998aed52 16
5539639c
ES
17/*
18 * Add a locked inode to the transaction.
19 *
20 * The inode must be locked, and it cannot be associated with any transaction.
21 * If lock_flags is non-zero the inode will be unlocked on transaction commit.
22 */
23void
24xfs_trans_ijoin(
25 struct xfs_trans *tp,
26 struct xfs_inode *ip,
27 uint lock_flags)
28{
ed8d09e1 29 struct xfs_inode_log_item *iip;
5539639c
ES
30
31 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
32 if (ip->i_itemp == NULL)
33 xfs_inode_item_init(ip, ip->i_mount);
34 iip = ip->i_itemp;
35
36 ASSERT(iip->ili_lock_flags == 0);
37 iip->ili_lock_flags = lock_flags;
d5c6e6a1 38 ASSERT(!xfs_iflags_test(ip, XFS_ISTALE));
5539639c 39
a565e345
DC
40 /* Reset the per-tx dirty context and add the item to the tx. */
41 iip->ili_dirty_flags = 0;
5539639c
ES
42 xfs_trans_add_item(tp, &iip->ili_item);
43}
44
45/*
46 * Transactional inode timestamp update. Requires the inode to be locked and
47 * joined to the transaction supplied. Relies on the transaction subsystem to
48 * track dirty state and update/writeback the inode accordingly.
49 */
50void
51xfs_trans_ichgtime(
52 struct xfs_trans *tp,
53 struct xfs_inode *ip,
54 int flags)
55{
56 struct inode *inode = VFS_I(ip);
cb49e9a4 57 struct timespec64 tv;
5539639c
ES
58
59 ASSERT(tp);
60 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
61
faea09b8 62 tv = current_time(inode);
5539639c
ES
63
64 if (flags & XFS_ICHGTIME_MOD)
bb16db6a 65 inode_set_mtime_to_ts(inode, tv);
faea09b8
CB
66 if (flags & XFS_ICHGTIME_CHG)
67 inode_set_ctime_to_ts(inode, tv);
cb49e9a4 68 if (flags & XFS_ICHGTIME_CREATE)
a1f6b388 69 ip->i_crtime = tv;
5539639c
ES
70}
71
72/*
2b8ea826
DC
73 * This is called to mark the fields indicated in fieldmask as needing to be
74 * logged when the transaction is committed. The inode must already be
a565e345
DC
75 * associated with the given transaction. All we do here is record where the
76 * inode was dirtied and mark the transaction and inode log item dirty;
77 * everything else is done in the ->precommit log item operation after the
78 * changes in the transaction have been completed.
5539639c
ES
79 */
80void
81xfs_trans_log_inode(
847ab4e0
DC
82 struct xfs_trans *tp,
83 struct xfs_inode *ip,
84 uint flags)
5539639c 85{
847ab4e0
DC
86 struct xfs_inode_log_item *iip = ip->i_itemp;
87 struct inode *inode = VFS_I(ip);
5539639c 88
847ab4e0 89 ASSERT(iip);
5539639c 90 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
d5c6e6a1 91 ASSERT(!xfs_iflags_test(ip, XFS_ISTALE));
5539639c 92
847ab4e0
DC
93 tp->t_flags |= XFS_TRANS_DIRTY;
94
5539639c
ES
95 /*
96 * First time we log the inode in a transaction, bump the inode change
97 * counter if it is configured for this to occur. While we have the
98 * inode locked exclusively for metadata modification, we can usually
99 * avoid setting XFS_ILOG_CORE if no one has queried the value since
100 * the last time it was incremented. If we have XFS_ILOG_CORE already
101 * set however, then go ahead and bump the i_version counter
102 * unconditionally.
103 */
847ab4e0
DC
104 if (!test_and_set_bit(XFS_LI_DIRTY, &iip->ili_item.li_flags)) {
105 if (IS_I_VERSION(inode) &&
106 inode_maybe_inc_iversion(inode, flags & XFS_ILOG_CORE))
a565e345 107 flags |= XFS_ILOG_IVERSION;
c16edcd7
DW
108 }
109
a565e345 110 iip->ili_dirty_flags |= flags;
5539639c
ES
111}
112
113int
114xfs_trans_roll_inode(
115 struct xfs_trans **tpp,
116 struct xfs_inode *ip)
117{
118 int error;
119
120 xfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE);
121 error = xfs_trans_roll(tpp);
122 if (!error)
123 xfs_trans_ijoin(*tpp, ip, 0);
124 return error;
125}