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