xref: /linux/fs/xfs/libxfs/xfs_parent.c (revision a08d6729637428b6ef8c6a5a94d8c6db7b805a44)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2022-2024 Oracle.
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 
31 /*
32  * Parent pointer attribute handling.
33  *
34  * Because the attribute name is a filename component, it will never be longer
35  * than 255 bytes and must not contain nulls or slashes.  These are roughly the
36  * same constraints that apply to attribute names.
37  *
38  * The attribute value must always be a struct xfs_parent_rec.  This means the
39  * attribute will never be in remote format because 12 bytes is nowhere near
40  * xfs_attr_leaf_entsize_local_max() (~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 attr name is valid. */
51 bool
52 xfs_parent_namecheck(
53 	unsigned int			attr_flags,
54 	const void			*name,
55 	size_t				length)
56 {
57 	/*
58 	 * Parent pointers always use logged operations, so there should never
59 	 * be incomplete xattrs.
60 	 */
61 	if (attr_flags & XFS_ATTR_INCOMPLETE)
62 		return false;
63 
64 	return xfs_dir2_namecheck(name, length);
65 }
66 
67 /* Return true if parent pointer attr value is valid. */
68 bool
69 xfs_parent_valuecheck(
70 	struct xfs_mount		*mp,
71 	const void			*value,
72 	size_t				valuelen)
73 {
74 	const struct xfs_parent_rec	*rec = value;
75 
76 	if (!xfs_has_parent(mp))
77 		return false;
78 
79 	/* The xattr value must be a parent record. */
80 	if (valuelen != sizeof(struct xfs_parent_rec))
81 		return false;
82 
83 	/* The parent record must be local. */
84 	if (value == NULL)
85 		return false;
86 
87 	/* The parent inumber must be valid. */
88 	if (!xfs_verify_dir_ino(mp, be64_to_cpu(rec->p_ino)))
89 		return false;
90 
91 	return true;
92 }
93