1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2022-2024 Oracle.
4 * All rights reserved.
5 */
6 #include "xfs_platform.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_xattr.h"
27 #include "xfs_parent.h"
28 #include "xfs_trans_space.h"
29 #include "xfs_attr_item.h"
30 #include "xfs_health.h"
31 #include "xfs_attr_leaf.h"
32
33 struct kmem_cache *xfs_parent_args_cache;
34
35 /*
36 * Parent pointer attribute handling.
37 *
38 * Because the attribute name is a filename component, it will never be longer
39 * than 255 bytes and must not contain nulls or slashes. These are roughly the
40 * same constraints that apply to attribute names.
41 *
42 * The attribute value must always be a struct xfs_parent_rec. This means the
43 * attribute will never be in remote format because 12 bytes is nowhere near
44 * xfs_attr_leaf_entsize_local_max() (~75% of block size).
45 *
46 * Creating a new parent attribute will always create a new attribute - there
47 * should never, ever be an existing attribute in the tree for a new inode.
48 * ENOSPC behavior is problematic - creating the inode without the parent
49 * pointer is effectively a corruption, so we allow parent attribute creation
50 * to dip into the reserve block pool to avoid unexpected ENOSPC errors from
51 * occurring.
52 */
53
54 /* Return true if parent pointer attr name is valid. */
55 bool
xfs_parent_namecheck(unsigned int attr_flags,const void * name,size_t length)56 xfs_parent_namecheck(
57 unsigned int attr_flags,
58 const void *name,
59 size_t length)
60 {
61 /*
62 * Parent pointers always use logged operations, so there should never
63 * be incomplete xattrs.
64 */
65 if (attr_flags & XFS_ATTR_INCOMPLETE)
66 return false;
67
68 return xfs_dir2_namecheck(name, length);
69 }
70
71 /* Return true if parent pointer attr value is valid. */
72 bool
xfs_parent_valuecheck(struct xfs_mount * mp,const void * value,size_t valuelen)73 xfs_parent_valuecheck(
74 struct xfs_mount *mp,
75 const void *value,
76 size_t valuelen)
77 {
78 const struct xfs_parent_rec *rec = value;
79
80 if (!xfs_has_parent(mp))
81 return false;
82
83 /* The xattr value must be a parent record. */
84 if (valuelen != sizeof(struct xfs_parent_rec))
85 return false;
86
87 /* The parent record must be local. */
88 if (value == NULL)
89 return false;
90
91 /* The parent inumber must be valid. */
92 if (!xfs_verify_dir_ino(mp, be64_to_cpu(rec->p_ino)))
93 return false;
94
95 return true;
96 }
97
98 /* Compute the attribute name hash for a parent pointer. */
99 xfs_dahash_t
xfs_parent_hashval(struct xfs_mount * mp,const uint8_t * name,int namelen,xfs_ino_t parent_ino)100 xfs_parent_hashval(
101 struct xfs_mount *mp,
102 const uint8_t *name,
103 int namelen,
104 xfs_ino_t parent_ino)
105 {
106 struct xfs_name xname = {
107 .name = name,
108 .len = namelen,
109 };
110
111 /*
112 * Use the same dirent name hash as would be used on the directory, but
113 * mix in the parent inode number to avoid collisions on hardlinked
114 * files with identical names but different parents.
115 */
116 return xfs_dir2_hashname(mp, &xname) ^
117 upper_32_bits(parent_ino) ^ lower_32_bits(parent_ino);
118 }
119
120 /* Compute the attribute name hash from the xattr components. */
121 xfs_dahash_t
xfs_parent_hashattr(struct xfs_mount * mp,const uint8_t * name,int namelen,const void * value,int valuelen)122 xfs_parent_hashattr(
123 struct xfs_mount *mp,
124 const uint8_t *name,
125 int namelen,
126 const void *value,
127 int valuelen)
128 {
129 const struct xfs_parent_rec *rec = value;
130
131 /* Requires a local attr value in xfs_parent_rec format */
132 if (valuelen != sizeof(struct xfs_parent_rec)) {
133 ASSERT(valuelen == sizeof(struct xfs_parent_rec));
134 return 0;
135 }
136
137 if (!value) {
138 ASSERT(value != NULL);
139 return 0;
140 }
141
142 return xfs_parent_hashval(mp, name, namelen, be64_to_cpu(rec->p_ino));
143 }
144
145 /*
146 * Initialize the parent pointer arguments structure. Caller must have zeroed
147 * the contents of @args. @tp is only required for updates.
148 */
149 static void
xfs_parent_da_args_init(struct xfs_da_args * args,struct xfs_trans * tp,struct xfs_parent_rec * rec,struct xfs_inode * child,xfs_ino_t owner,const struct xfs_name * parent_name)150 xfs_parent_da_args_init(
151 struct xfs_da_args *args,
152 struct xfs_trans *tp,
153 struct xfs_parent_rec *rec,
154 struct xfs_inode *child,
155 xfs_ino_t owner,
156 const struct xfs_name *parent_name)
157 {
158 args->geo = child->i_mount->m_attr_geo;
159 args->whichfork = XFS_ATTR_FORK;
160 args->attr_filter = XFS_ATTR_PARENT;
161 args->op_flags = XFS_DA_OP_LOGGED | XFS_DA_OP_OKNOENT;
162 args->trans = tp;
163 args->dp = child;
164 args->owner = owner;
165 args->name = parent_name->name;
166 args->namelen = parent_name->len;
167 args->value = rec;
168 args->valuelen = sizeof(struct xfs_parent_rec);
169 xfs_attr_sethash(args);
170 }
171
172 /* Make sure the incore state is ready for a parent pointer query/update. */
173 static inline int
xfs_parent_iread_extents(struct xfs_trans * tp,struct xfs_inode * child)174 xfs_parent_iread_extents(
175 struct xfs_trans *tp,
176 struct xfs_inode *child)
177 {
178 /* Parent pointers require that the attr fork must exist. */
179 if (XFS_IS_CORRUPT(child->i_mount, !xfs_inode_has_attr_fork(child))) {
180 xfs_inode_mark_sick(child, XFS_SICK_INO_PARENT);
181 return -EFSCORRUPTED;
182 }
183
184 return xfs_iread_extents(tp, child, XFS_ATTR_FORK);
185 }
186
187 /* Add a parent pointer to reflect a dirent addition. */
188 int
xfs_parent_addname(struct xfs_trans * tp,struct xfs_parent_args * ppargs,struct xfs_inode * dp,const struct xfs_name * parent_name,struct xfs_inode * child)189 xfs_parent_addname(
190 struct xfs_trans *tp,
191 struct xfs_parent_args *ppargs,
192 struct xfs_inode *dp,
193 const struct xfs_name *parent_name,
194 struct xfs_inode *child)
195 {
196 int error, local;
197
198 error = xfs_parent_iread_extents(tp, child);
199 if (error)
200 return error;
201
202 xfs_inode_to_parent_rec(&ppargs->rec, dp);
203 xfs_parent_da_args_init(&ppargs->args, tp, &ppargs->rec, child,
204 I_INO(child), parent_name);
205
206 /* Growing the attr fork needs a real reservation in args->total. */
207 ppargs->args.total = xfs_attr_calc_size(&ppargs->args, &local);
208 ASSERT(local);
209
210 return xfs_attr_setname(&ppargs->args, 0);
211 }
212
213 /* Remove a parent pointer to reflect a dirent removal. */
214 int
xfs_parent_removename(struct xfs_trans * tp,struct xfs_parent_args * ppargs,struct xfs_inode * dp,const struct xfs_name * parent_name,struct xfs_inode * child)215 xfs_parent_removename(
216 struct xfs_trans *tp,
217 struct xfs_parent_args *ppargs,
218 struct xfs_inode *dp,
219 const struct xfs_name *parent_name,
220 struct xfs_inode *child)
221 {
222 int error;
223
224 error = xfs_parent_iread_extents(tp, child);
225 if (error)
226 return error;
227
228 xfs_inode_to_parent_rec(&ppargs->rec, dp);
229 xfs_parent_da_args_init(&ppargs->args, tp, &ppargs->rec, child,
230 I_INO(child), parent_name);
231
232 return xfs_attr_removename(&ppargs->args);
233 }
234
235 /* Replace one parent pointer with another to reflect a rename. */
236 int
xfs_parent_replacename(struct xfs_trans * tp,struct xfs_parent_args * ppargs,struct xfs_inode * old_dp,const struct xfs_name * old_name,struct xfs_inode * new_dp,const struct xfs_name * new_name,struct xfs_inode * child)237 xfs_parent_replacename(
238 struct xfs_trans *tp,
239 struct xfs_parent_args *ppargs,
240 struct xfs_inode *old_dp,
241 const struct xfs_name *old_name,
242 struct xfs_inode *new_dp,
243 const struct xfs_name *new_name,
244 struct xfs_inode *child)
245 {
246 int error, local;
247
248 error = xfs_parent_iread_extents(tp, child);
249 if (error)
250 return error;
251
252 xfs_inode_to_parent_rec(&ppargs->rec, old_dp);
253 xfs_parent_da_args_init(&ppargs->args, tp, &ppargs->rec, child,
254 I_INO(child), old_name);
255
256 /* Growing the attr fork needs a real reservation in args->total. */
257 ppargs->args.total = xfs_attr_calc_size(&ppargs->args, &local);
258 ASSERT(local);
259
260 xfs_inode_to_parent_rec(&ppargs->new_rec, new_dp);
261
262 ppargs->args.new_name = new_name->name;
263 ppargs->args.new_namelen = new_name->len;
264 ppargs->args.new_value = &ppargs->new_rec;
265 ppargs->args.new_valuelen = sizeof(struct xfs_parent_rec);
266
267 return xfs_attr_replacename(&ppargs->args, 0);
268 }
269
270 /*
271 * Extract parent pointer information from any parent pointer xattr into
272 * @parent_ino/gen. The last two parameters can be NULL pointers.
273 *
274 * Returns 0 if this is not a parent pointer xattr at all; or -EFSCORRUPTED for
275 * garbage.
276 */
277 int
xfs_parent_from_attr(struct xfs_mount * mp,unsigned int attr_flags,const unsigned char * name,unsigned int namelen,const void * value,unsigned int valuelen,xfs_ino_t * parent_ino,uint32_t * parent_gen)278 xfs_parent_from_attr(
279 struct xfs_mount *mp,
280 unsigned int attr_flags,
281 const unsigned char *name,
282 unsigned int namelen,
283 const void *value,
284 unsigned int valuelen,
285 xfs_ino_t *parent_ino,
286 uint32_t *parent_gen)
287 {
288 const struct xfs_parent_rec *rec = value;
289
290 ASSERT(attr_flags & XFS_ATTR_PARENT);
291
292 if (!xfs_parent_namecheck(attr_flags, name, namelen))
293 return -EFSCORRUPTED;
294 if (!xfs_parent_valuecheck(mp, value, valuelen))
295 return -EFSCORRUPTED;
296
297 if (parent_ino)
298 *parent_ino = be64_to_cpu(rec->p_ino);
299 if (parent_gen)
300 *parent_gen = be32_to_cpu(rec->p_gen);
301 return 0;
302 }
303
304 /*
305 * Look up a parent pointer record (@parent_name -> @pptr) of @ip.
306 *
307 * Caller must hold at least ILOCK_SHARED. The scratchpad need not be
308 * initialized.
309 *
310 * Returns 0 if the pointer is found, -ENOATTR if there is no match, or a
311 * negative errno.
312 */
313 int
xfs_parent_lookup(struct xfs_trans * tp,struct xfs_inode * ip,const struct xfs_name * parent_name,struct xfs_parent_rec * pptr,struct xfs_da_args * scratch)314 xfs_parent_lookup(
315 struct xfs_trans *tp,
316 struct xfs_inode *ip,
317 const struct xfs_name *parent_name,
318 struct xfs_parent_rec *pptr,
319 struct xfs_da_args *scratch)
320 {
321 memset(scratch, 0, sizeof(struct xfs_da_args));
322 xfs_parent_da_args_init(scratch, tp, pptr, ip, I_INO(ip), parent_name);
323 return xfs_attr_get_ilocked(scratch);
324 }
325
326 /* Sanity-check a parent pointer before we try to perform repairs. */
327 static inline bool
xfs_parent_sanity_check(struct xfs_mount * mp,const struct xfs_name * parent_name,const struct xfs_parent_rec * pptr)328 xfs_parent_sanity_check(
329 struct xfs_mount *mp,
330 const struct xfs_name *parent_name,
331 const struct xfs_parent_rec *pptr)
332 {
333 if (!xfs_parent_namecheck(XFS_ATTR_PARENT, parent_name->name,
334 parent_name->len))
335 return false;
336
337 if (!xfs_parent_valuecheck(mp, pptr, sizeof(*pptr)))
338 return false;
339
340 return true;
341 }
342
343
344 /*
345 * Attach the parent pointer (@parent_name -> @pptr) to @ip immediately.
346 * Caller must not have a transaction or hold the ILOCK. This is for
347 * specialized repair functions only. The scratchpad need not be initialized.
348 */
349 int
xfs_parent_set(struct xfs_inode * ip,xfs_ino_t owner,const struct xfs_name * parent_name,struct xfs_parent_rec * pptr,struct xfs_da_args * scratch)350 xfs_parent_set(
351 struct xfs_inode *ip,
352 xfs_ino_t owner,
353 const struct xfs_name *parent_name,
354 struct xfs_parent_rec *pptr,
355 struct xfs_da_args *scratch)
356 {
357 if (!xfs_parent_sanity_check(ip->i_mount, parent_name, pptr)) {
358 ASSERT(0);
359 return -EFSCORRUPTED;
360 }
361
362 memset(scratch, 0, sizeof(struct xfs_da_args));
363 xfs_parent_da_args_init(scratch, NULL, pptr, ip, owner, parent_name);
364 return xfs_attr_set(scratch, XFS_ATTRUPDATE_CREATE, false);
365 }
366
367 /*
368 * Remove the parent pointer (@parent_name -> @pptr) from @ip immediately.
369 * Caller must not have a transaction or hold the ILOCK. This is for
370 * specialized repair functions only. The scratchpad need not be initialized.
371 */
372 int
xfs_parent_unset(struct xfs_inode * ip,xfs_ino_t owner,const struct xfs_name * parent_name,struct xfs_parent_rec * pptr,struct xfs_da_args * scratch)373 xfs_parent_unset(
374 struct xfs_inode *ip,
375 xfs_ino_t owner,
376 const struct xfs_name *parent_name,
377 struct xfs_parent_rec *pptr,
378 struct xfs_da_args *scratch)
379 {
380 if (!xfs_parent_sanity_check(ip->i_mount, parent_name, pptr)) {
381 ASSERT(0);
382 return -EFSCORRUPTED;
383 }
384
385 memset(scratch, 0, sizeof(struct xfs_da_args));
386 xfs_parent_da_args_init(scratch, NULL, pptr, ip, owner, parent_name);
387 return xfs_attr_set(scratch, XFS_ATTRUPDATE_REMOVE, false);
388 }
389