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