Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * Copyright (c) 2022-2023 Oracle, Inc.
4 : * All rights reserved.
5 : */
6 : #include "xfs.h"
7 : #include "xfs_fs.h"
8 : #include "xfs_format.h"
9 : #include "xfs_da_format.h"
10 : #include "xfs_log_format.h"
11 : #include "xfs_shared.h"
12 : #include "xfs_trans_resv.h"
13 : #include "xfs_mount.h"
14 : #include "xfs_bmap_btree.h"
15 : #include "xfs_inode.h"
16 : #include "xfs_error.h"
17 : #include "xfs_trace.h"
18 : #include "xfs_trans.h"
19 : #include "xfs_da_btree.h"
20 : #include "xfs_attr.h"
21 : #include "xfs_dir2.h"
22 : #include "xfs_dir2_priv.h"
23 : #include "xfs_attr_sf.h"
24 : #include "xfs_bmap.h"
25 : #include "xfs_defer.h"
26 : #include "xfs_log.h"
27 : #include "xfs_xattr.h"
28 : #include "xfs_parent.h"
29 : #include "xfs_trans_space.h"
30 : #include "xfs_health.h"
31 :
32 : struct kmem_cache *xfs_parent_intent_cache;
33 :
34 : /*
35 : * Parent pointer attribute handling.
36 : *
37 : * Because the attribute value is a filename component, it will never be longer
38 : * than 255 bytes. This means the attribute will always be a local format
39 : * attribute as it is xfs_attr_leaf_entsize_local_max() for v5 filesystems will
40 : * always be larger than this (max is 75% of block size).
41 : *
42 : * Creating a new parent attribute will always create a new attribute - there
43 : * should never, ever be an existing attribute in the tree for a new inode.
44 : * ENOSPC behavior is problematic - creating the inode without the parent
45 : * pointer is effectively a corruption, so we allow parent attribute creation
46 : * to dip into the reserve block pool to avoid unexpected ENOSPC errors from
47 : * occurring.
48 : */
49 :
50 : /* Return true if parent pointer EA name is valid. */
51 : bool
52 2755476707 : xfs_parent_namecheck(
53 : struct xfs_mount *mp,
54 : const struct xfs_parent_name_rec *rec,
55 : size_t reclen,
56 : unsigned int attr_flags)
57 : {
58 2755476707 : xfs_ino_t p_ino;
59 :
60 2755476707 : if (!(attr_flags & XFS_ATTR_PARENT))
61 : return false;
62 :
63 : /* pptr updates use logged xattrs, so we should never see this flag */
64 2755476707 : if (attr_flags & XFS_ATTR_INCOMPLETE)
65 : return false;
66 :
67 2755476707 : if (reclen != sizeof(struct xfs_parent_name_rec))
68 : return false;
69 :
70 : /* Only one namespace bit allowed. */
71 5511622518 : if (hweight32(attr_flags & XFS_ATTR_NSP_ONDISK_MASK) > 1)
72 : return false;
73 :
74 2755674251 : p_ino = be64_to_cpu(rec->p_ino);
75 2755674251 : if (!xfs_verify_ino(mp, p_ino))
76 0 : return false;
77 :
78 : return true;
79 : }
80 :
81 : /* Return true if parent pointer EA value is valid. */
82 : bool
83 2178586143 : xfs_parent_valuecheck(
84 : struct xfs_mount *mp,
85 : const void *value,
86 : size_t valuelen)
87 : {
88 2178586143 : if (valuelen == 0 || valuelen > XFS_PARENT_DIRENT_NAME_MAX_SIZE)
89 : return false;
90 :
91 2178586143 : if (value == NULL)
92 : return false;
93 :
94 : /* Valid dirent name? */
95 2178586143 : if (!xfs_dir2_namecheck(value, valuelen))
96 0 : return false;
97 :
98 : return true;
99 : }
100 :
101 : /* Initializes a xfs_parent_name_rec to be stored as an attribute name. */
102 : static inline void
103 181947847 : xfs_init_parent_name_rec(
104 : struct xfs_parent_name_rec *rec,
105 : const struct xfs_inode *dp,
106 : const struct xfs_name *name,
107 : struct xfs_inode *ip)
108 : {
109 181947847 : rec->p_ino = cpu_to_be64(dp->i_ino);
110 181947847 : rec->p_gen = cpu_to_be32(VFS_IC(dp)->i_generation);
111 181947847 : rec->p_namehash = cpu_to_be32(xfs_dir2_hashname(dp->i_mount, name));
112 181949194 : }
113 :
114 : /* Point the da args value fields at the non-key parts of a parent pointer. */
115 : static inline void
116 : xfs_init_parent_davalue(
117 : struct xfs_da_args *args,
118 : const struct xfs_name *name)
119 : {
120 144541109 : args->valuelen = name->len;
121 144541109 : args->value = (void *)name->name;
122 : }
123 :
124 : /*
125 : * Point the da args new value fields at the non-key parts of a replacement
126 : * parent pointer.
127 : */
128 : static inline void
129 : xfs_init_parent_danewvalue(
130 : struct xfs_da_args *args,
131 : const struct xfs_name *name)
132 : {
133 37416931 : args->new_valuelen = name->len;
134 37416931 : args->new_value = (void *)name->name;
135 : }
136 :
137 : /*
138 : * Allocate memory to control a logged parent pointer update as part of a
139 : * dirent operation.
140 : */
141 : int
142 238280061 : __xfs_parent_init(
143 : struct xfs_mount *mp,
144 : bool grab_log,
145 : struct xfs_parent_defer **parentp)
146 : {
147 238280061 : struct xfs_parent_defer *parent;
148 238280061 : int error;
149 :
150 238280061 : if (grab_log) {
151 136724789 : error = xfs_attr_grab_log_assist(mp);
152 136726761 : if (error)
153 : return error;
154 : }
155 :
156 238281822 : parent = kmem_cache_zalloc(xfs_parent_intent_cache, GFP_KERNEL);
157 238291333 : if (!parent) {
158 0 : if (grab_log)
159 0 : xfs_attr_rele_log_assist(mp);
160 0 : return -ENOMEM;
161 : }
162 :
163 : /* init parent da_args */
164 238291333 : parent->have_log = grab_log;
165 238291333 : parent->args.geo = mp->m_attr_geo;
166 238291333 : parent->args.whichfork = XFS_ATTR_FORK;
167 238291333 : parent->args.attr_filter = XFS_ATTR_PARENT;
168 238291333 : parent->args.op_flags = XFS_DA_OP_OKNOENT | XFS_DA_OP_LOGGED |
169 : XFS_DA_OP_NVLOOKUP;
170 238291333 : parent->args.name = (const uint8_t *)&parent->rec;
171 238291333 : parent->args.namelen = sizeof(struct xfs_parent_name_rec);
172 :
173 238291333 : *parentp = parent;
174 238291333 : return 0;
175 : }
176 :
177 : static inline xfs_dahash_t
178 : xfs_parent_hashname(
179 : struct xfs_inode *ip,
180 : const struct xfs_parent_defer *parent)
181 : {
182 144541350 : return xfs_da_hashname((const void *)&parent->rec,
183 : sizeof(struct xfs_parent_name_rec));
184 : }
185 :
186 : /* Add a parent pointer to reflect a dirent addition. */
187 : int
188 66040269 : xfs_parent_add(
189 : struct xfs_trans *tp,
190 : struct xfs_parent_defer *parent,
191 : struct xfs_inode *dp,
192 : const struct xfs_name *parent_name,
193 : struct xfs_inode *child)
194 : {
195 66040269 : struct xfs_da_args *args = &parent->args;
196 :
197 66040269 : xfs_init_parent_name_rec(&parent->rec, dp, parent_name, child);
198 66041041 : args->hashval = xfs_parent_hashname(dp, parent);
199 :
200 66040756 : args->trans = tp;
201 66040756 : args->dp = child;
202 66040756 : args->owner = child->i_ino;
203 :
204 66040756 : xfs_init_parent_davalue(&parent->args, parent_name);
205 :
206 66040756 : return xfs_attr_defer_add(args);
207 : }
208 :
209 : /* Remove a parent pointer to reflect a dirent removal. */
210 : int
211 41083468 : xfs_parent_remove(
212 : struct xfs_trans *tp,
213 : struct xfs_parent_defer *parent,
214 : struct xfs_inode *dp,
215 : const struct xfs_name *parent_name,
216 : struct xfs_inode *child)
217 : {
218 41083468 : struct xfs_da_args *args = &parent->args;
219 :
220 : /*
221 : * For regular attrs, removing an attr from a !hasattr inode is a nop.
222 : * For parent pointers, we require that the pointer must exist if the
223 : * caller wants us to remove the pointer.
224 : */
225 41083468 : if (XFS_IS_CORRUPT(child->i_mount, !xfs_inode_hasattr(child))) {
226 0 : xfs_inode_mark_sick(child, XFS_SICK_INO_PARENT);
227 0 : return -EFSCORRUPTED;
228 : }
229 :
230 41083606 : xfs_init_parent_name_rec(&parent->rec, dp, parent_name, child);
231 41083388 : args->hashval = xfs_parent_hashname(dp, parent);
232 :
233 41083422 : args->trans = tp;
234 41083422 : args->dp = child;
235 41083422 : args->owner = child->i_ino;
236 :
237 41083422 : xfs_init_parent_davalue(&parent->args, parent_name);
238 :
239 41083422 : return xfs_attr_defer_remove(args);
240 : }
241 :
242 : /* Replace one parent pointer with another to reflect a rename. */
243 : int
244 37416925 : xfs_parent_replace(
245 : struct xfs_trans *tp,
246 : struct xfs_parent_defer *parent,
247 : struct xfs_inode *old_dp,
248 : const struct xfs_name *old_name,
249 : struct xfs_inode *new_dp,
250 : const struct xfs_name *new_name,
251 : struct xfs_inode *child)
252 : {
253 37416925 : struct xfs_da_args *args = &parent->args;
254 :
255 : /*
256 : * For regular attrs, replacing an attr from a !hasattr inode becomes
257 : * an attr-set operation. For replacing a parent pointer, however, we
258 : * require that the old pointer must exist.
259 : */
260 37416925 : if (XFS_IS_CORRUPT(child->i_mount, !xfs_inode_hasattr(child))) {
261 0 : xfs_inode_mark_sick(child, XFS_SICK_INO_PARENT);
262 0 : return -EFSCORRUPTED;
263 : }
264 :
265 37416922 : xfs_init_parent_name_rec(&parent->rec, old_dp, old_name, child);
266 37416921 : args->hashval = xfs_parent_hashname(old_dp, parent);
267 :
268 37416933 : xfs_init_parent_name_rec(&parent->new_rec, new_dp, new_name, child);
269 37416931 : args->new_name = (const uint8_t *)&parent->new_rec;
270 37416931 : args->new_namelen = sizeof(struct xfs_parent_name_rec);
271 :
272 37416931 : args->trans = tp;
273 37416931 : args->dp = child;
274 37416931 : args->owner = child->i_ino;
275 :
276 37416931 : xfs_init_parent_davalue(&parent->args, old_name);
277 37416931 : xfs_init_parent_danewvalue(&parent->args, new_name);
278 :
279 37416931 : return xfs_attr_defer_replace(args);
280 : }
281 :
282 : /* Cancel a parent pointer operation. */
283 : void
284 238179286 : __xfs_parent_cancel(
285 : struct xfs_mount *mp,
286 : struct xfs_parent_defer *parent)
287 : {
288 238179286 : if (parent->have_log)
289 136618534 : xlog_drop_incompat_feat(mp->m_log, XLOG_INCOMPAT_FEAT_XATTRS);
290 238216244 : kmem_cache_free(xfs_parent_intent_cache, parent);
291 238249929 : }
292 :
293 : /* Convert an ondisk parent pointer to the incore format. */
294 : void
295 2178232452 : xfs_parent_irec_from_disk(
296 : struct xfs_parent_name_irec *irec,
297 : const struct xfs_parent_name_rec *rec,
298 : const void *value,
299 : unsigned int valuelen)
300 : {
301 2178232452 : irec->p_ino = be64_to_cpu(rec->p_ino);
302 2178232452 : irec->p_gen = be32_to_cpu(rec->p_gen);
303 2178232452 : irec->p_namehash = be32_to_cpu(rec->p_namehash);
304 2178232452 : irec->p_namelen = valuelen;
305 4356464904 : memcpy(irec->p_name, value, valuelen);
306 2178232452 : }
307 :
308 : /* Convert an incore parent pointer to the ondisk attr name format. */
309 : void
310 122813918 : xfs_parent_irec_to_disk(
311 : struct xfs_parent_name_rec *rec,
312 : const struct xfs_parent_name_irec *irec)
313 : {
314 122813918 : rec->p_ino = cpu_to_be64(irec->p_ino);
315 122813918 : rec->p_gen = cpu_to_be32(irec->p_gen);
316 122813918 : rec->p_namehash = cpu_to_be32(irec->p_namehash);
317 122813918 : }
318 :
319 : /* Compute p_namehash for the this parent pointer. */
320 : void
321 122827924 : xfs_parent_irec_hashname(
322 : struct xfs_mount *mp,
323 : struct xfs_parent_name_irec *irec)
324 : {
325 122827924 : struct xfs_name dname = {
326 122827924 : .name = irec->p_name,
327 122827924 : .len = irec->p_namelen,
328 : };
329 :
330 122827924 : irec->p_namehash = xfs_dir2_hashname(mp, &dname);
331 122818790 : }
332 :
333 : static inline void
334 122816408 : xfs_parent_scratch_init(
335 : struct xfs_trans *tp,
336 : struct xfs_inode *ip,
337 : xfs_ino_t owner,
338 : const struct xfs_parent_name_irec *pptr,
339 : struct xfs_parent_scratch *scr)
340 : {
341 122816408 : memset(&scr->args, 0, sizeof(struct xfs_da_args));
342 122816408 : scr->args.attr_filter = XFS_ATTR_PARENT;
343 122816408 : scr->args.dp = ip;
344 122816408 : scr->args.geo = ip->i_mount->m_attr_geo;
345 122816408 : scr->args.name = (const unsigned char *)&scr->rec;
346 122816408 : scr->args.namelen = sizeof(struct xfs_parent_name_rec);
347 122816408 : scr->args.op_flags = XFS_DA_OP_NVLOOKUP;
348 122816408 : scr->args.trans = tp;
349 122816408 : scr->args.value = (void *)pptr->p_name;
350 122816408 : scr->args.valuelen = pptr->p_namelen;
351 122816408 : scr->args.whichfork = XFS_ATTR_FORK;
352 122816408 : scr->args.hashval = xfs_da_hashname((const void *)&scr->rec,
353 : sizeof(struct xfs_parent_name_rec));
354 122805929 : scr->args.owner = owner;
355 122805929 : }
356 :
357 : /*
358 : * Look up the @name associated with the parent pointer (@pptr) of @ip.
359 : * Caller must hold at least ILOCK_SHARED. Returns 0 if the pointer is found,
360 : * -ENOATTR if there is no match, or a negative errno. The scratchpad need not
361 : * be initialized.
362 : */
363 : int
364 122727051 : xfs_parent_lookup(
365 : struct xfs_trans *tp,
366 : struct xfs_inode *ip,
367 : const struct xfs_parent_name_irec *pptr,
368 : struct xfs_parent_scratch *scr)
369 : {
370 122727051 : xfs_parent_irec_to_disk(&scr->rec, pptr);
371 122716471 : xfs_parent_scratch_init(tp, ip, ip->i_ino, pptr, scr);
372 122720791 : scr->args.op_flags |= XFS_DA_OP_OKNOENT;
373 :
374 122720791 : return xfs_attr_get_ilocked(&scr->args);
375 : }
376 :
377 : /*
378 : * Attach the parent pointer (@pptr -> @name) to @ip immediately. Caller must
379 : * not have a transaction or hold the ILOCK. The update will not use logged
380 : * xattrs. This is for specialized repair functions only. The scratchpad need
381 : * not be initialized.
382 : */
383 : int
384 89323 : xfs_parent_set(
385 : struct xfs_inode *ip,
386 : xfs_ino_t owner,
387 : const struct xfs_parent_name_irec *pptr,
388 : struct xfs_parent_scratch *scr)
389 : {
390 89323 : xfs_parent_irec_to_disk(&scr->rec, pptr);
391 89321 : xfs_parent_scratch_init(NULL, ip, owner, pptr, scr);
392 :
393 89322 : return xfs_attr_set(&scr->args);
394 : }
395 :
396 : /*
397 : * Remove the parent pointer (@rec -> @name) from @ip immediately. Caller must
398 : * not have a transaction or hold the ILOCK. The update will not use logged
399 : * xattrs. This is for specialized repair functions only. The scratchpad need
400 : * not be initialized.
401 : */
402 : int
403 0 : xfs_parent_unset(
404 : struct xfs_inode *ip,
405 : xfs_ino_t owner,
406 : const struct xfs_parent_name_irec *pptr,
407 : struct xfs_parent_scratch *scr)
408 : {
409 0 : xfs_parent_irec_to_disk(&scr->rec, pptr);
410 0 : xfs_parent_scratch_init(NULL, ip, owner, pptr, scr);
411 0 : scr->args.op_flags |= XFS_DA_OP_REMOVE;
412 :
413 0 : return xfs_attr_set(&scr->args);
414 : }
|