1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 4 * Copyright (c) 2013 Red Hat, Inc. 5 * All Rights Reserved. 6 */ 7 #include "xfs.h" 8 #include "xfs_fs.h" 9 #include "xfs_shared.h" 10 #include "xfs_format.h" 11 #include "xfs_log_format.h" 12 #include "xfs_trans_resv.h" 13 #include "xfs_mount.h" 14 #include "xfs_da_format.h" 15 #include "xfs_inode.h" 16 #include "xfs_trans.h" 17 #include "xfs_bmap.h" 18 #include "xfs_da_btree.h" 19 #include "xfs_attr.h" 20 #include "xfs_attr_sf.h" 21 #include "xfs_attr_leaf.h" 22 #include "xfs_error.h" 23 #include "xfs_trace.h" 24 #include "xfs_dir2.h" 25 26 STATIC int 27 xfs_attr_shortform_compare(const void *a, const void *b) 28 { 29 xfs_attr_sf_sort_t *sa, *sb; 30 31 sa = (xfs_attr_sf_sort_t *)a; 32 sb = (xfs_attr_sf_sort_t *)b; 33 if (sa->hash < sb->hash) { 34 return -1; 35 } else if (sa->hash > sb->hash) { 36 return 1; 37 } else { 38 return sa->entno - sb->entno; 39 } 40 } 41 42 #define XFS_ISRESET_CURSOR(cursor) \ 43 (!((cursor)->initted) && !((cursor)->hashval) && \ 44 !((cursor)->blkno) && !((cursor)->offset)) 45 /* 46 * Copy out entries of shortform attribute lists for attr_list(). 47 * Shortform attribute lists are not stored in hashval sorted order. 48 * If the output buffer is not large enough to hold them all, then 49 * we have to calculate each entries' hashvalue and sort them before 50 * we can begin returning them to the user. 51 */ 52 static int 53 xfs_attr_shortform_list( 54 struct xfs_attr_list_context *context) 55 { 56 struct xfs_attrlist_cursor_kern *cursor = &context->cursor; 57 struct xfs_inode *dp = context->dp; 58 struct xfs_attr_sf_sort *sbuf, *sbp; 59 struct xfs_attr_shortform *sf; 60 struct xfs_attr_sf_entry *sfe; 61 int sbsize, nsbuf, count, i; 62 int error = 0; 63 64 sf = (struct xfs_attr_shortform *)dp->i_af.if_u1.if_data; 65 ASSERT(sf != NULL); 66 if (!sf->hdr.count) 67 return 0; 68 69 trace_xfs_attr_list_sf(context); 70 71 /* 72 * If the buffer is large enough and the cursor is at the start, 73 * do not bother with sorting since we will return everything in 74 * one buffer and another call using the cursor won't need to be 75 * made. 76 * Note the generous fudge factor of 16 overhead bytes per entry. 77 * If bufsize is zero then put_listent must be a search function 78 * and can just scan through what we have. 79 */ 80 if (context->bufsize == 0 || 81 (XFS_ISRESET_CURSOR(cursor) && 82 (dp->i_af.if_bytes + sf->hdr.count * 16) < context->bufsize)) { 83 for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { 84 if (XFS_IS_CORRUPT(context->dp->i_mount, 85 !xfs_attr_namecheck(sfe->flags, 86 sfe->nameval, 87 sfe->namelen))) 88 return -EFSCORRUPTED; 89 context->put_listent(context, 90 sfe->flags, 91 sfe->nameval, 92 (int)sfe->namelen, 93 (int)sfe->valuelen); 94 /* 95 * Either search callback finished early or 96 * didn't fit it all in the buffer after all. 97 */ 98 if (context->seen_enough) 99 break; 100 sfe = xfs_attr_sf_nextentry(sfe); 101 } 102 trace_xfs_attr_list_sf_all(context); 103 return 0; 104 } 105 106 /* do no more for a search callback */ 107 if (context->bufsize == 0) 108 return 0; 109 110 /* 111 * It didn't all fit, so we have to sort everything on hashval. 112 */ 113 sbsize = sf->hdr.count * sizeof(*sbuf); 114 sbp = sbuf = kmem_alloc(sbsize, KM_NOFS); 115 116 /* 117 * Scan the attribute list for the rest of the entries, storing 118 * the relevant info from only those that match into a buffer. 119 */ 120 nsbuf = 0; 121 for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { 122 if (unlikely( 123 ((char *)sfe < (char *)sf) || 124 ((char *)sfe >= ((char *)sf + dp->i_af.if_bytes)) || 125 !xfs_attr_check_namespace(sfe->flags))) { 126 XFS_CORRUPTION_ERROR("xfs_attr_shortform_list", 127 XFS_ERRLEVEL_LOW, 128 context->dp->i_mount, sfe, 129 sizeof(*sfe)); 130 kmem_free(sbuf); 131 return -EFSCORRUPTED; 132 } 133 134 sbp->entno = i; 135 sbp->hash = xfs_da_hashname(sfe->nameval, sfe->namelen); 136 sbp->name = sfe->nameval; 137 sbp->namelen = sfe->namelen; 138 /* These are bytes, and both on-disk, don't endian-flip */ 139 sbp->valuelen = sfe->valuelen; 140 sbp->flags = sfe->flags; 141 sfe = xfs_attr_sf_nextentry(sfe); 142 sbp++; 143 nsbuf++; 144 } 145 146 /* 147 * Sort the entries on hash then entno. 148 */ 149 xfs_sort(sbuf, nsbuf, sizeof(*sbuf), xfs_attr_shortform_compare); 150 151 /* 152 * Re-find our place IN THE SORTED LIST. 153 */ 154 count = 0; 155 cursor->initted = 1; 156 cursor->blkno = 0; 157 for (sbp = sbuf, i = 0; i < nsbuf; i++, sbp++) { 158 if (sbp->hash == cursor->hashval) { 159 if (cursor->offset == count) { 160 break; 161 } 162 count++; 163 } else if (sbp->hash > cursor->hashval) { 164 break; 165 } 166 } 167 if (i == nsbuf) 168 goto out; 169 170 /* 171 * Loop putting entries into the user buffer. 172 */ 173 for ( ; i < nsbuf; i++, sbp++) { 174 if (cursor->hashval != sbp->hash) { 175 cursor->hashval = sbp->hash; 176 cursor->offset = 0; 177 } 178 if (XFS_IS_CORRUPT(context->dp->i_mount, 179 !xfs_attr_namecheck(sbp->flags, sbp->name, 180 sbp->namelen))) { 181 error = -EFSCORRUPTED; 182 goto out; 183 } 184 context->put_listent(context, 185 sbp->flags, 186 sbp->name, 187 sbp->namelen, 188 sbp->valuelen); 189 if (context->seen_enough) 190 break; 191 cursor->offset++; 192 } 193 out: 194 kmem_free(sbuf); 195 return error; 196 } 197 198 /* 199 * We didn't find the block & hash mentioned in the cursor state, so 200 * walk down the attr btree looking for the hash. 201 */ 202 STATIC int 203 xfs_attr_node_list_lookup( 204 struct xfs_attr_list_context *context, 205 struct xfs_attrlist_cursor_kern *cursor, 206 struct xfs_buf **pbp) 207 { 208 struct xfs_da3_icnode_hdr nodehdr; 209 struct xfs_da_intnode *node; 210 struct xfs_da_node_entry *btree; 211 struct xfs_inode *dp = context->dp; 212 struct xfs_mount *mp = dp->i_mount; 213 struct xfs_trans *tp = context->tp; 214 struct xfs_buf *bp; 215 int i; 216 int error = 0; 217 unsigned int expected_level = 0; 218 uint16_t magic; 219 220 ASSERT(*pbp == NULL); 221 cursor->blkno = 0; 222 for (;;) { 223 error = xfs_da3_node_read(tp, dp, cursor->blkno, &bp, 224 XFS_ATTR_FORK); 225 if (error) 226 return error; 227 node = bp->b_addr; 228 magic = be16_to_cpu(node->hdr.info.magic); 229 if (magic == XFS_ATTR_LEAF_MAGIC || 230 magic == XFS_ATTR3_LEAF_MAGIC) 231 break; 232 if (magic != XFS_DA_NODE_MAGIC && 233 magic != XFS_DA3_NODE_MAGIC) { 234 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, 235 node, sizeof(*node)); 236 goto out_corruptbuf; 237 } 238 239 xfs_da3_node_hdr_from_disk(mp, &nodehdr, node); 240 241 /* Tree taller than we can handle; bail out! */ 242 if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH) 243 goto out_corruptbuf; 244 245 /* Check the level from the root node. */ 246 if (cursor->blkno == 0) 247 expected_level = nodehdr.level - 1; 248 else if (expected_level != nodehdr.level) 249 goto out_corruptbuf; 250 else 251 expected_level--; 252 253 btree = nodehdr.btree; 254 for (i = 0; i < nodehdr.count; btree++, i++) { 255 if (cursor->hashval <= be32_to_cpu(btree->hashval)) { 256 cursor->blkno = be32_to_cpu(btree->before); 257 trace_xfs_attr_list_node_descend(context, 258 btree); 259 break; 260 } 261 } 262 xfs_trans_brelse(tp, bp); 263 264 if (i == nodehdr.count) 265 return 0; 266 267 /* We can't point back to the root. */ 268 if (XFS_IS_CORRUPT(mp, cursor->blkno == 0)) 269 return -EFSCORRUPTED; 270 } 271 272 if (expected_level != 0) 273 goto out_corruptbuf; 274 275 *pbp = bp; 276 return 0; 277 278 out_corruptbuf: 279 xfs_buf_mark_corrupt(bp); 280 xfs_trans_brelse(tp, bp); 281 return -EFSCORRUPTED; 282 } 283 284 STATIC int 285 xfs_attr_node_list( 286 struct xfs_attr_list_context *context) 287 { 288 struct xfs_attrlist_cursor_kern *cursor = &context->cursor; 289 struct xfs_attr3_icleaf_hdr leafhdr; 290 struct xfs_attr_leafblock *leaf; 291 struct xfs_da_intnode *node; 292 struct xfs_buf *bp; 293 struct xfs_inode *dp = context->dp; 294 struct xfs_mount *mp = dp->i_mount; 295 int error = 0; 296 297 trace_xfs_attr_node_list(context); 298 299 cursor->initted = 1; 300 301 /* 302 * Do all sorts of validation on the passed-in cursor structure. 303 * If anything is amiss, ignore the cursor and look up the hashval 304 * starting from the btree root. 305 */ 306 bp = NULL; 307 if (cursor->blkno > 0) { 308 error = xfs_da3_node_read(context->tp, dp, cursor->blkno, &bp, 309 XFS_ATTR_FORK); 310 if ((error != 0) && (error != -EFSCORRUPTED)) 311 return error; 312 if (bp) { 313 struct xfs_attr_leaf_entry *entries; 314 315 node = bp->b_addr; 316 switch (be16_to_cpu(node->hdr.info.magic)) { 317 case XFS_DA_NODE_MAGIC: 318 case XFS_DA3_NODE_MAGIC: 319 trace_xfs_attr_list_wrong_blk(context); 320 xfs_trans_brelse(context->tp, bp); 321 bp = NULL; 322 break; 323 case XFS_ATTR_LEAF_MAGIC: 324 case XFS_ATTR3_LEAF_MAGIC: 325 leaf = bp->b_addr; 326 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, 327 &leafhdr, leaf); 328 entries = xfs_attr3_leaf_entryp(leaf); 329 if (cursor->hashval > be32_to_cpu( 330 entries[leafhdr.count - 1].hashval)) { 331 trace_xfs_attr_list_wrong_blk(context); 332 xfs_trans_brelse(context->tp, bp); 333 bp = NULL; 334 } else if (cursor->hashval <= be32_to_cpu( 335 entries[0].hashval)) { 336 trace_xfs_attr_list_wrong_blk(context); 337 xfs_trans_brelse(context->tp, bp); 338 bp = NULL; 339 } 340 break; 341 default: 342 trace_xfs_attr_list_wrong_blk(context); 343 xfs_trans_brelse(context->tp, bp); 344 bp = NULL; 345 } 346 } 347 } 348 349 /* 350 * We did not find what we expected given the cursor's contents, 351 * so we start from the top and work down based on the hash value. 352 * Note that start of node block is same as start of leaf block. 353 */ 354 if (bp == NULL) { 355 error = xfs_attr_node_list_lookup(context, cursor, &bp); 356 if (error || !bp) 357 return error; 358 } 359 ASSERT(bp != NULL); 360 361 /* 362 * Roll upward through the blocks, processing each leaf block in 363 * order. As long as there is space in the result buffer, keep 364 * adding the information. 365 */ 366 for (;;) { 367 leaf = bp->b_addr; 368 error = xfs_attr3_leaf_list_int(bp, context); 369 if (error) 370 break; 371 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf); 372 if (context->seen_enough || leafhdr.forw == 0) 373 break; 374 cursor->blkno = leafhdr.forw; 375 xfs_trans_brelse(context->tp, bp); 376 error = xfs_attr3_leaf_read(context->tp, dp, cursor->blkno, 377 &bp); 378 if (error) 379 return error; 380 } 381 xfs_trans_brelse(context->tp, bp); 382 return error; 383 } 384 385 /* 386 * Copy out attribute list entries for attr_list(), for leaf attribute lists. 387 */ 388 int 389 xfs_attr3_leaf_list_int( 390 struct xfs_buf *bp, 391 struct xfs_attr_list_context *context) 392 { 393 struct xfs_attrlist_cursor_kern *cursor = &context->cursor; 394 struct xfs_attr_leafblock *leaf; 395 struct xfs_attr3_icleaf_hdr ichdr; 396 struct xfs_attr_leaf_entry *entries; 397 struct xfs_attr_leaf_entry *entry; 398 int i; 399 struct xfs_mount *mp = context->dp->i_mount; 400 401 trace_xfs_attr_list_leaf(context); 402 403 leaf = bp->b_addr; 404 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf); 405 entries = xfs_attr3_leaf_entryp(leaf); 406 407 cursor->initted = 1; 408 409 /* 410 * Re-find our place in the leaf block if this is a new syscall. 411 */ 412 if (context->resynch) { 413 entry = &entries[0]; 414 for (i = 0; i < ichdr.count; entry++, i++) { 415 if (be32_to_cpu(entry->hashval) == cursor->hashval) { 416 if (cursor->offset == context->dupcnt) { 417 context->dupcnt = 0; 418 break; 419 } 420 context->dupcnt++; 421 } else if (be32_to_cpu(entry->hashval) > 422 cursor->hashval) { 423 context->dupcnt = 0; 424 break; 425 } 426 } 427 if (i == ichdr.count) { 428 trace_xfs_attr_list_notfound(context); 429 return 0; 430 } 431 } else { 432 entry = &entries[0]; 433 i = 0; 434 } 435 context->resynch = 0; 436 437 /* 438 * We have found our place, start copying out the new attributes. 439 */ 440 for (; i < ichdr.count; entry++, i++) { 441 char *name; 442 int namelen, valuelen; 443 444 if (be32_to_cpu(entry->hashval) != cursor->hashval) { 445 cursor->hashval = be32_to_cpu(entry->hashval); 446 cursor->offset = 0; 447 } 448 449 if ((entry->flags & XFS_ATTR_INCOMPLETE) && 450 !context->allow_incomplete) 451 continue; 452 453 if (entry->flags & XFS_ATTR_LOCAL) { 454 xfs_attr_leaf_name_local_t *name_loc; 455 456 name_loc = xfs_attr3_leaf_name_local(leaf, i); 457 name = name_loc->nameval; 458 namelen = name_loc->namelen; 459 valuelen = be16_to_cpu(name_loc->valuelen); 460 } else { 461 xfs_attr_leaf_name_remote_t *name_rmt; 462 463 name_rmt = xfs_attr3_leaf_name_remote(leaf, i); 464 name = name_rmt->name; 465 namelen = name_rmt->namelen; 466 valuelen = be32_to_cpu(name_rmt->valuelen); 467 } 468 469 if (XFS_IS_CORRUPT(context->dp->i_mount, 470 !xfs_attr_namecheck(entry->flags, name, 471 namelen))) 472 return -EFSCORRUPTED; 473 context->put_listent(context, entry->flags, 474 name, namelen, valuelen); 475 if (context->seen_enough) 476 break; 477 cursor->offset++; 478 } 479 trace_xfs_attr_list_leaf_end(context); 480 return 0; 481 } 482 483 /* 484 * Copy out attribute entries for attr_list(), for leaf attribute lists. 485 */ 486 STATIC int 487 xfs_attr_leaf_list( 488 struct xfs_attr_list_context *context) 489 { 490 struct xfs_buf *bp; 491 int error; 492 493 trace_xfs_attr_leaf_list(context); 494 495 context->cursor.blkno = 0; 496 error = xfs_attr3_leaf_read(context->tp, context->dp, 0, &bp); 497 if (error) 498 return error; 499 500 error = xfs_attr3_leaf_list_int(bp, context); 501 xfs_trans_brelse(context->tp, bp); 502 return error; 503 } 504 505 int 506 xfs_attr_list_ilocked( 507 struct xfs_attr_list_context *context) 508 { 509 struct xfs_inode *dp = context->dp; 510 511 ASSERT(xfs_isilocked(dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)); 512 513 /* 514 * Decide on what work routines to call based on the inode size. 515 */ 516 if (!xfs_inode_hasattr(dp)) 517 return 0; 518 if (dp->i_af.if_format == XFS_DINODE_FMT_LOCAL) 519 return xfs_attr_shortform_list(context); 520 if (xfs_attr_is_leaf(dp)) 521 return xfs_attr_leaf_list(context); 522 return xfs_attr_node_list(context); 523 } 524 525 int 526 xfs_attr_list( 527 struct xfs_attr_list_context *context) 528 { 529 struct xfs_inode *dp = context->dp; 530 uint lock_mode; 531 int error; 532 533 XFS_STATS_INC(dp->i_mount, xs_attr_list); 534 535 if (xfs_is_shutdown(dp->i_mount)) 536 return -EIO; 537 538 lock_mode = xfs_ilock_attr_map_shared(dp); 539 error = xfs_attr_list_ilocked(context); 540 xfs_iunlock(dp, lock_mode); 541 return error; 542 } 543