Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * Copyright (c) 2020-2022, Red Hat, Inc.
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_mount.h"
13 : #include "xfs_inode.h"
14 : #include "xfs_trans.h"
15 : #include "xfs_trans_priv.h"
16 : #include "xfs_ag.h"
17 : #include "xfs_iunlink_item.h"
18 : #include "xfs_trace.h"
19 : #include "xfs_error.h"
20 :
21 : struct kmem_cache *xfs_iunlink_cache;
22 :
23 : static inline struct xfs_iunlink_item *IUL_ITEM(struct xfs_log_item *lip)
24 : {
25 : return container_of(lip, struct xfs_iunlink_item, item);
26 : }
27 :
28 : static void
29 18157514 : xfs_iunlink_item_release(
30 : struct xfs_log_item *lip)
31 : {
32 18157514 : struct xfs_iunlink_item *iup = IUL_ITEM(lip);
33 :
34 18157514 : xfs_perag_put(iup->pag);
35 18157830 : kmem_cache_free(xfs_iunlink_cache, IUL_ITEM(lip));
36 18157351 : }
37 :
38 :
39 : static uint64_t
40 27510934 : xfs_iunlink_item_sort(
41 : struct xfs_log_item *lip)
42 : {
43 27510934 : return IUL_ITEM(lip)->ip->i_ino;
44 : }
45 :
46 : /*
47 : * Look up the inode cluster buffer and log the on-disk unlinked inode change
48 : * we need to make.
49 : */
50 : static int
51 18155700 : xfs_iunlink_log_dinode(
52 : struct xfs_trans *tp,
53 : struct xfs_iunlink_item *iup)
54 : {
55 18155700 : struct xfs_mount *mp = tp->t_mountp;
56 18155700 : struct xfs_inode *ip = iup->ip;
57 18155700 : struct xfs_dinode *dip;
58 18155700 : struct xfs_buf *ibp;
59 18155700 : int offset;
60 18155700 : int error;
61 :
62 18155700 : error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &ibp);
63 18158931 : if (error)
64 : return error;
65 : /*
66 : * Don't log the unlinked field on stale buffers as this may be the
67 : * transaction that frees the inode cluster and relogging the buffer
68 : * here will incorrectly remove the stale state.
69 : */
70 18158931 : if (ibp->b_flags & XBF_STALE)
71 21472 : goto out;
72 :
73 18137459 : dip = xfs_buf_offset(ibp, ip->i_imap.im_boffset);
74 :
75 : /* Make sure the old pointer isn't garbage. */
76 36270540 : if (be32_to_cpu(dip->di_next_unlinked) != iup->old_agino) {
77 0 : xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip,
78 0 : sizeof(*dip), __this_address);
79 0 : error = -EFSCORRUPTED;
80 0 : goto out;
81 : }
82 :
83 18135270 : trace_xfs_iunlink_update_dinode(mp, iup->pag->pag_agno,
84 18135270 : XFS_INO_TO_AGINO(mp, ip->i_ino),
85 : be32_to_cpu(dip->di_next_unlinked), iup->next_agino);
86 :
87 18135357 : dip->di_next_unlinked = cpu_to_be32(iup->next_agino);
88 18135357 : offset = ip->i_imap.im_boffset +
89 : offsetof(struct xfs_dinode, di_next_unlinked);
90 :
91 18135357 : xfs_dinode_calc_crc(mp, dip);
92 18133513 : xfs_trans_inode_buf(tp, ibp);
93 18133184 : xfs_trans_log_buf(tp, ibp, offset, offset + sizeof(xfs_agino_t) - 1);
94 18133184 : return 0;
95 21472 : out:
96 21472 : xfs_trans_brelse(tp, ibp);
97 21472 : return error;
98 : }
99 :
100 : /*
101 : * On precommit, we grab the inode cluster buffer for the inode number we were
102 : * passed, then update the next unlinked field for that inode in the buffer and
103 : * log the buffer. This ensures that the inode cluster buffer was logged in the
104 : * correct order w.r.t. other inode cluster buffers. We can then remove the
105 : * iunlink item from the transaction and release it as it is has now served it's
106 : * purpose.
107 : */
108 : static int
109 18154864 : xfs_iunlink_item_precommit(
110 : struct xfs_trans *tp,
111 : struct xfs_log_item *lip)
112 : {
113 18154864 : struct xfs_iunlink_item *iup = IUL_ITEM(lip);
114 18154864 : int error;
115 :
116 18154864 : error = xfs_iunlink_log_dinode(tp, iup);
117 18156493 : list_del(&lip->li_trans);
118 18157474 : xfs_iunlink_item_release(lip);
119 18157820 : return error;
120 : }
121 :
122 : static const struct xfs_item_ops xfs_iunlink_item_ops = {
123 : .iop_release = xfs_iunlink_item_release,
124 : .iop_sort = xfs_iunlink_item_sort,
125 : .iop_precommit = xfs_iunlink_item_precommit,
126 : };
127 :
128 :
129 : /*
130 : * Initialize the inode log item for a newly allocated (in-core) inode.
131 : *
132 : * Inode extents can only reside within an AG. Hence specify the starting
133 : * block for the inode chunk by offset within an AG as well as the
134 : * length of the allocated extent.
135 : *
136 : * This joins the item to the transaction and marks it dirty so
137 : * that we don't need a separate call to do this, nor does the
138 : * caller need to know anything about the iunlink item.
139 : */
140 : int
141 51445026 : xfs_iunlink_log_inode(
142 : struct xfs_trans *tp,
143 : struct xfs_inode *ip,
144 : struct xfs_perag *pag,
145 : xfs_agino_t next_agino)
146 : {
147 51445026 : struct xfs_mount *mp = tp->t_mountp;
148 51445026 : struct xfs_iunlink_item *iup;
149 :
150 61326780 : ASSERT(xfs_verify_agino_or_null(pag, next_agino));
151 61326371 : ASSERT(xfs_verify_agino_or_null(pag, ip->i_next_unlinked));
152 :
153 : /*
154 : * Since we're updating a linked list, we should never find that the
155 : * current pointer is the same as the new value, unless we're
156 : * terminating the list.
157 : */
158 51445026 : if (ip->i_next_unlinked == next_agino) {
159 33293948 : if (next_agino != NULLAGINO)
160 : return -EFSCORRUPTED;
161 33293948 : return 0;
162 : }
163 :
164 18151078 : iup = kmem_cache_zalloc(xfs_iunlink_cache, GFP_KERNEL | __GFP_NOFAIL);
165 18152809 : xfs_log_item_init(mp, &iup->item, XFS_LI_IUNLINK,
166 : &xfs_iunlink_item_ops);
167 :
168 18154994 : iup->ip = ip;
169 18154994 : iup->next_agino = next_agino;
170 18154994 : iup->old_agino = ip->i_next_unlinked;
171 18154994 : iup->pag = xfs_perag_hold(pag);
172 :
173 18154958 : xfs_trans_add_item(tp, &iup->item);
174 18154368 : tp->t_flags |= XFS_TRANS_DIRTY;
175 18154368 : set_bit(XFS_LI_DIRTY, &iup->item.li_flags);
176 : return 0;
177 : }
178 :
|