| // SPDX-License-Identifier: GPL-2.0 | 
 | /* | 
 |  * Copyright (c) 2022-2024 Oracle. | 
 |  * All Rights Reserved. | 
 |  */ | 
 | #ifndef	__XFS_PARENT_H__ | 
 | #define	__XFS_PARENT_H__ | 
 |  | 
 | /* Metadata validators */ | 
 | bool xfs_parent_namecheck(unsigned int attr_flags, const void *name, | 
 | 		size_t length); | 
 | bool xfs_parent_valuecheck(struct xfs_mount *mp, const void *value, | 
 | 		size_t valuelen); | 
 |  | 
 | xfs_dahash_t xfs_parent_hashval(struct xfs_mount *mp, const uint8_t *name, | 
 | 		int namelen, xfs_ino_t parent_ino); | 
 | xfs_dahash_t xfs_parent_hashattr(struct xfs_mount *mp, const uint8_t *name, | 
 | 		int namelen, const void *value, int valuelen); | 
 |  | 
 | /* Initializes a xfs_parent_rec to be stored as an attribute name. */ | 
 | static inline void | 
 | xfs_parent_rec_init( | 
 | 	struct xfs_parent_rec	*rec, | 
 | 	xfs_ino_t		ino, | 
 | 	uint32_t		gen) | 
 | { | 
 | 	rec->p_ino = cpu_to_be64(ino); | 
 | 	rec->p_gen = cpu_to_be32(gen); | 
 | } | 
 |  | 
 | /* Initializes a xfs_parent_rec to be stored as an attribute name. */ | 
 | static inline void | 
 | xfs_inode_to_parent_rec( | 
 | 	struct xfs_parent_rec	*rec, | 
 | 	const struct xfs_inode	*dp) | 
 | { | 
 | 	xfs_parent_rec_init(rec, dp->i_ino, VFS_IC(dp)->i_generation); | 
 | } | 
 |  | 
 | extern struct kmem_cache	*xfs_parent_args_cache; | 
 |  | 
 | /* | 
 |  * Parent pointer information needed to pass around the deferred xattr update | 
 |  * machinery. | 
 |  */ | 
 | struct xfs_parent_args { | 
 | 	struct xfs_parent_rec	rec; | 
 | 	struct xfs_parent_rec	new_rec; | 
 | 	struct xfs_da_args	args; | 
 | }; | 
 |  | 
 | /* | 
 |  * Start a parent pointer update by allocating the context object we need to | 
 |  * perform a parent pointer update. | 
 |  */ | 
 | static inline int | 
 | xfs_parent_start( | 
 | 	struct xfs_mount	*mp, | 
 | 	struct xfs_parent_args	**ppargsp) | 
 | { | 
 | 	if (!xfs_has_parent(mp)) { | 
 | 		*ppargsp = NULL; | 
 | 		return 0; | 
 | 	} | 
 |  | 
 | 	*ppargsp = kmem_cache_zalloc(xfs_parent_args_cache, GFP_KERNEL); | 
 | 	if (!*ppargsp) | 
 | 		return -ENOMEM; | 
 | 	return 0; | 
 | } | 
 |  | 
 | /* Finish a parent pointer update by freeing the context object. */ | 
 | static inline void | 
 | xfs_parent_finish( | 
 | 	struct xfs_mount	*mp, | 
 | 	struct xfs_parent_args	*ppargs) | 
 | { | 
 | 	if (ppargs) | 
 | 		kmem_cache_free(xfs_parent_args_cache, ppargs); | 
 | } | 
 |  | 
 | 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); | 
 | 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); | 
 | 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); | 
 |  | 
 | 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); | 
 |  | 
 | /* Repair functions */ | 
 | int xfs_parent_lookup(struct xfs_trans *tp, struct xfs_inode *ip, | 
 | 		const struct xfs_name *name, struct xfs_parent_rec *pptr, | 
 | 		struct xfs_da_args *scratch); | 
 | int xfs_parent_set(struct xfs_inode *ip, xfs_ino_t owner, | 
 | 		const struct xfs_name *name, struct xfs_parent_rec *pptr, | 
 | 		struct xfs_da_args *scratch); | 
 | int xfs_parent_unset(struct xfs_inode *ip, xfs_ino_t owner, | 
 | 		const struct xfs_name *name, struct xfs_parent_rec *pptr, | 
 | 		struct xfs_da_args *scratch); | 
 |  | 
 | #endif /* __XFS_PARENT_H__ */ |