]>
Commit | Line | Data |
---|---|---|
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 | */ | |
23 | void | |
24 | xfs_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 | */ | |
50 | void | |
51 | xfs_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 | */ |
80 | void | |
81 | xfs_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 | ||
113 | int | |
114 | xfs_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 | } |