0001
0002
0003
0004
0005
0006 #include "xfs.h"
0007 #include "xfs_fs.h"
0008 #include "xfs_shared.h"
0009 #include "xfs_format.h"
0010 #include "xfs_log_format.h"
0011 #include "xfs_trans_resv.h"
0012 #include "xfs_mount.h"
0013 #include "xfs_inode.h"
0014 #include "xfs_trans.h"
0015 #include "xfs_trans_priv.h"
0016 #include "xfs_inode_item.h"
0017
0018 #include <linux/iversion.h>
0019
0020
0021
0022
0023
0024
0025
0026 void
0027 xfs_trans_ijoin(
0028 struct xfs_trans *tp,
0029 struct xfs_inode *ip,
0030 uint lock_flags)
0031 {
0032 struct xfs_inode_log_item *iip;
0033
0034 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
0035 if (ip->i_itemp == NULL)
0036 xfs_inode_item_init(ip, ip->i_mount);
0037 iip = ip->i_itemp;
0038
0039 ASSERT(iip->ili_lock_flags == 0);
0040 iip->ili_lock_flags = lock_flags;
0041 ASSERT(!xfs_iflags_test(ip, XFS_ISTALE));
0042
0043
0044
0045
0046 xfs_trans_add_item(tp, &iip->ili_item);
0047 }
0048
0049
0050
0051
0052
0053
0054 void
0055 xfs_trans_ichgtime(
0056 struct xfs_trans *tp,
0057 struct xfs_inode *ip,
0058 int flags)
0059 {
0060 struct inode *inode = VFS_I(ip);
0061 struct timespec64 tv;
0062
0063 ASSERT(tp);
0064 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
0065
0066 tv = current_time(inode);
0067
0068 if (flags & XFS_ICHGTIME_MOD)
0069 inode->i_mtime = tv;
0070 if (flags & XFS_ICHGTIME_CHG)
0071 inode->i_ctime = tv;
0072 if (flags & XFS_ICHGTIME_CREATE)
0073 ip->i_crtime = tv;
0074 }
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091 void
0092 xfs_trans_log_inode(
0093 struct xfs_trans *tp,
0094 struct xfs_inode *ip,
0095 uint flags)
0096 {
0097 struct xfs_inode_log_item *iip = ip->i_itemp;
0098 struct inode *inode = VFS_I(ip);
0099 uint iversion_flags = 0;
0100
0101 ASSERT(iip);
0102 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
0103 ASSERT(!xfs_iflags_test(ip, XFS_ISTALE));
0104
0105 tp->t_flags |= XFS_TRANS_DIRTY;
0106
0107
0108
0109
0110
0111
0112
0113 if (inode->i_state & I_DIRTY_TIME) {
0114 spin_lock(&inode->i_lock);
0115 inode->i_state &= ~I_DIRTY_TIME;
0116 spin_unlock(&inode->i_lock);
0117 }
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128 if (!test_and_set_bit(XFS_LI_DIRTY, &iip->ili_item.li_flags)) {
0129 if (IS_I_VERSION(inode) &&
0130 inode_maybe_inc_iversion(inode, flags & XFS_ILOG_CORE))
0131 iversion_flags = XFS_ILOG_CORE;
0132 }
0133
0134
0135
0136
0137
0138 if ((flags & (XFS_ILOG_CORE | XFS_ILOG_TIMESTAMP)) &&
0139 xfs_has_bigtime(ip->i_mount) &&
0140 !xfs_inode_has_bigtime(ip)) {
0141 ip->i_diflags2 |= XFS_DIFLAG2_BIGTIME;
0142 flags |= XFS_ILOG_CORE;
0143 }
0144
0145
0146
0147
0148
0149
0150
0151 if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) &&
0152 (ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) &&
0153 (ip->i_extsize % ip->i_mount->m_sb.sb_rextsize) > 0) {
0154 ip->i_diflags &= ~(XFS_DIFLAG_EXTSIZE |
0155 XFS_DIFLAG_EXTSZINHERIT);
0156 ip->i_extsize = 0;
0157 flags |= XFS_ILOG_CORE;
0158 }
0159
0160
0161
0162
0163
0164
0165 spin_lock(&iip->ili_lock);
0166 iip->ili_fsync_fields |= flags;
0167
0168 if (!iip->ili_item.li_buf) {
0169 struct xfs_buf *bp;
0170 int error;
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 spin_unlock(&iip->ili_lock);
0182 error = xfs_imap_to_bp(ip->i_mount, tp, &ip->i_imap, &bp);
0183 if (error) {
0184 xfs_force_shutdown(ip->i_mount, SHUTDOWN_META_IO_ERROR);
0185 return;
0186 }
0187
0188
0189
0190
0191
0192
0193
0194
0195 xfs_buf_hold(bp);
0196 spin_lock(&iip->ili_lock);
0197 iip->ili_item.li_buf = bp;
0198 bp->b_flags |= _XBF_INODES;
0199 list_add_tail(&iip->ili_item.li_bio_list, &bp->b_li_list);
0200 xfs_trans_brelse(tp, bp);
0201 }
0202
0203
0204
0205
0206
0207
0208
0209 iip->ili_fields |= (flags | iip->ili_last_fields | iversion_flags);
0210 spin_unlock(&iip->ili_lock);
0211 }
0212
0213 int
0214 xfs_trans_roll_inode(
0215 struct xfs_trans **tpp,
0216 struct xfs_inode *ip)
0217 {
0218 int error;
0219
0220 xfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE);
0221 error = xfs_trans_roll(tpp);
0222 if (!error)
0223 xfs_trans_ijoin(*tpp, ip, 0);
0224 return error;
0225 }