1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2022-2024 Oracle.
4 * All Rights Reserved.
5 */
6 #ifndef __XFS_PARENT_H__
7 #define __XFS_PARENT_H__
8
9 /* Metadata validators */
10 bool xfs_parent_namecheck(unsigned int attr_flags, const void *name,
11 size_t length);
12 bool xfs_parent_valuecheck(struct xfs_mount *mp, const void *value,
13 size_t valuelen);
14
15 xfs_dahash_t xfs_parent_hashval(struct xfs_mount *mp, const uint8_t *name,
16 int namelen, xfs_ino_t parent_ino);
17 xfs_dahash_t xfs_parent_hashattr(struct xfs_mount *mp, const uint8_t *name,
18 int namelen, const void *value, int valuelen);
19
20 /* Initializes a xfs_parent_rec to be stored as an attribute name. */
21 static inline void
xfs_parent_rec_init(struct xfs_parent_rec * rec,xfs_ino_t ino,uint32_t gen)22 xfs_parent_rec_init(
23 struct xfs_parent_rec *rec,
24 xfs_ino_t ino,
25 uint32_t gen)
26 {
27 rec->p_ino = cpu_to_be64(ino);
28 rec->p_gen = cpu_to_be32(gen);
29 }
30
31 /* Initializes a xfs_parent_rec to be stored as an attribute name. */
32 static inline void
xfs_inode_to_parent_rec(struct xfs_parent_rec * rec,const struct xfs_inode * dp)33 xfs_inode_to_parent_rec(
34 struct xfs_parent_rec *rec,
35 const struct xfs_inode *dp)
36 {
37 xfs_parent_rec_init(rec, dp->i_ino, VFS_IC(dp)->i_generation);
38 }
39
40 extern struct kmem_cache *xfs_parent_args_cache;
41
42 /*
43 * Parent pointer information needed to pass around the deferred xattr update
44 * machinery.
45 */
46 struct xfs_parent_args {
47 struct xfs_parent_rec rec;
48 struct xfs_parent_rec new_rec;
49 struct xfs_da_args args;
50 };
51
52 /*
53 * Start a parent pointer update by allocating the context object we need to
54 * perform a parent pointer update.
55 */
56 static inline int
xfs_parent_start(struct xfs_mount * mp,struct xfs_parent_args ** ppargsp)57 xfs_parent_start(
58 struct xfs_mount *mp,
59 struct xfs_parent_args **ppargsp)
60 {
61 if (!xfs_has_parent(mp)) {
62 *ppargsp = NULL;
63 return 0;
64 }
65
66 *ppargsp = kmem_cache_zalloc(xfs_parent_args_cache, GFP_KERNEL);
67 if (!*ppargsp)
68 return -ENOMEM;
69 return 0;
70 }
71
72 /* Finish a parent pointer update by freeing the context object. */
73 static inline void
xfs_parent_finish(struct xfs_mount * mp,struct xfs_parent_args * ppargs)74 xfs_parent_finish(
75 struct xfs_mount *mp,
76 struct xfs_parent_args *ppargs)
77 {
78 if (ppargs)
79 kmem_cache_free(xfs_parent_args_cache, ppargs);
80 }
81
82 int xfs_parent_addname(struct xfs_trans *tp, struct xfs_parent_args *ppargs,
83 struct xfs_inode *dp, const struct xfs_name *parent_name,
84 struct xfs_inode *child);
85 int xfs_parent_removename(struct xfs_trans *tp, struct xfs_parent_args *ppargs,
86 struct xfs_inode *dp, const struct xfs_name *parent_name,
87 struct xfs_inode *child);
88 int xfs_parent_replacename(struct xfs_trans *tp,
89 struct xfs_parent_args *ppargs,
90 struct xfs_inode *old_dp, const struct xfs_name *old_name,
91 struct xfs_inode *new_dp, const struct xfs_name *new_name,
92 struct xfs_inode *child);
93
94 int xfs_parent_from_attr(struct xfs_mount *mp, unsigned int attr_flags,
95 const unsigned char *name, unsigned int namelen,
96 const void *value, unsigned int valuelen,
97 xfs_ino_t *parent_ino, uint32_t *parent_gen);
98
99 /* Repair functions */
100 int xfs_parent_lookup(struct xfs_trans *tp, struct xfs_inode *ip,
101 const struct xfs_name *name, struct xfs_parent_rec *pptr,
102 struct xfs_da_args *scratch);
103 int xfs_parent_set(struct xfs_inode *ip, xfs_ino_t owner,
104 const struct xfs_name *name, struct xfs_parent_rec *pptr,
105 struct xfs_da_args *scratch);
106 int xfs_parent_unset(struct xfs_inode *ip, xfs_ino_t owner,
107 const struct xfs_name *name, struct xfs_parent_rec *pptr,
108 struct xfs_da_args *scratch);
109
110 #endif /* __XFS_PARENT_H__ */
111