1/* 2 * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc. 3 * Copyright (c) 2013 Red Hat, Inc. 4 * All Rights Reserved. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it would be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19#include "xfs.h" 20#include "xfs_fs.h" 21#include "xfs_shared.h" 22#include "xfs_format.h" 23#include "xfs_log_format.h" 24#include "xfs_trans_resv.h" 25#include "xfs_mount.h" 26#include "xfs_da_format.h" 27#include "xfs_da_btree.h" 28#include "xfs_inode.h" 29#include "xfs_dir2.h" 30#include "xfs_dir2_priv.h" 31 32/* 33 * Shortform directory ops 34 */ 35static int 36xfs_dir2_sf_entsize( 37 struct xfs_dir2_sf_hdr *hdr, 38 int len) 39{ 40 int count = sizeof(struct xfs_dir2_sf_entry); /* namelen + offset */ 41 42 count += len; /* name */ 43 count += hdr->i8count ? sizeof(xfs_dir2_ino8_t) : 44 sizeof(xfs_dir2_ino4_t); /* ino # */ 45 return count; 46} 47 48static int 49xfs_dir3_sf_entsize( 50 struct xfs_dir2_sf_hdr *hdr, 51 int len) 52{ 53 return xfs_dir2_sf_entsize(hdr, len) + sizeof(__uint8_t); 54} 55 56static struct xfs_dir2_sf_entry * 57xfs_dir2_sf_nextentry( 58 struct xfs_dir2_sf_hdr *hdr, 59 struct xfs_dir2_sf_entry *sfep) 60{ 61 return (struct xfs_dir2_sf_entry *) 62 ((char *)sfep + xfs_dir2_sf_entsize(hdr, sfep->namelen)); 63} 64 65static struct xfs_dir2_sf_entry * 66xfs_dir3_sf_nextentry( 67 struct xfs_dir2_sf_hdr *hdr, 68 struct xfs_dir2_sf_entry *sfep) 69{ 70 return (struct xfs_dir2_sf_entry *) 71 ((char *)sfep + xfs_dir3_sf_entsize(hdr, sfep->namelen)); 72} 73 74 75/* 76 * For filetype enabled shortform directories, the file type field is stored at 77 * the end of the name. Because it's only a single byte, endian conversion is 78 * not necessary. For non-filetype enable directories, the type is always 79 * unknown and we never store the value. 80 */ 81static __uint8_t 82xfs_dir2_sfe_get_ftype( 83 struct xfs_dir2_sf_entry *sfep) 84{ 85 return XFS_DIR3_FT_UNKNOWN; 86} 87 88static void 89xfs_dir2_sfe_put_ftype( 90 struct xfs_dir2_sf_entry *sfep, 91 __uint8_t ftype) 92{ 93 ASSERT(ftype < XFS_DIR3_FT_MAX); 94} 95 96static __uint8_t 97xfs_dir3_sfe_get_ftype( 98 struct xfs_dir2_sf_entry *sfep) 99{ 100 __uint8_t ftype; 101 102 ftype = sfep->name[sfep->namelen]; 103 if (ftype >= XFS_DIR3_FT_MAX) 104 return XFS_DIR3_FT_UNKNOWN; 105 return ftype; 106} 107 108static void 109xfs_dir3_sfe_put_ftype( 110 struct xfs_dir2_sf_entry *sfep, 111 __uint8_t ftype) 112{ 113 ASSERT(ftype < XFS_DIR3_FT_MAX); 114 115 sfep->name[sfep->namelen] = ftype; 116} 117 118/* 119 * Inode numbers in short-form directories can come in two versions, 120 * either 4 bytes or 8 bytes wide. These helpers deal with the 121 * two forms transparently by looking at the headers i8count field. 122 * 123 * For 64-bit inode number the most significant byte must be zero. 124 */ 125static xfs_ino_t 126xfs_dir2_sf_get_ino( 127 struct xfs_dir2_sf_hdr *hdr, 128 xfs_dir2_inou_t *from) 129{ 130 if (hdr->i8count) 131 return get_unaligned_be64(&from->i8.i) & 0x00ffffffffffffffULL; 132 else 133 return get_unaligned_be32(&from->i4.i); 134} 135 136static void 137xfs_dir2_sf_put_ino( 138 struct xfs_dir2_sf_hdr *hdr, 139 xfs_dir2_inou_t *to, 140 xfs_ino_t ino) 141{ 142 ASSERT((ino & 0xff00000000000000ULL) == 0); 143 144 if (hdr->i8count) 145 put_unaligned_be64(ino, &to->i8.i); 146 else 147 put_unaligned_be32(ino, &to->i4.i); 148} 149 150static xfs_ino_t 151xfs_dir2_sf_get_parent_ino( 152 struct xfs_dir2_sf_hdr *hdr) 153{ 154 return xfs_dir2_sf_get_ino(hdr, &hdr->parent); 155} 156 157static void 158xfs_dir2_sf_put_parent_ino( 159 struct xfs_dir2_sf_hdr *hdr, 160 xfs_ino_t ino) 161{ 162 xfs_dir2_sf_put_ino(hdr, &hdr->parent, ino); 163} 164 165/* 166 * In short-form directory entries the inode numbers are stored at variable 167 * offset behind the entry name. If the entry stores a filetype value, then it 168 * sits between the name and the inode number. Hence the inode numbers may only 169 * be accessed through the helpers below. 170 */ 171static xfs_ino_t 172xfs_dir2_sfe_get_ino( 173 struct xfs_dir2_sf_hdr *hdr, 174 struct xfs_dir2_sf_entry *sfep) 175{ 176 return xfs_dir2_sf_get_ino(hdr, 177 (xfs_dir2_inou_t *)&sfep->name[sfep->namelen]); 178} 179 180static void 181xfs_dir2_sfe_put_ino( 182 struct xfs_dir2_sf_hdr *hdr, 183 struct xfs_dir2_sf_entry *sfep, 184 xfs_ino_t ino) 185{ 186 xfs_dir2_sf_put_ino(hdr, 187 (xfs_dir2_inou_t *)&sfep->name[sfep->namelen], ino); 188} 189 190static xfs_ino_t 191xfs_dir3_sfe_get_ino( 192 struct xfs_dir2_sf_hdr *hdr, 193 struct xfs_dir2_sf_entry *sfep) 194{ 195 return xfs_dir2_sf_get_ino(hdr, 196 (xfs_dir2_inou_t *)&sfep->name[sfep->namelen + 1]); 197} 198 199static void 200xfs_dir3_sfe_put_ino( 201 struct xfs_dir2_sf_hdr *hdr, 202 struct xfs_dir2_sf_entry *sfep, 203 xfs_ino_t ino) 204{ 205 xfs_dir2_sf_put_ino(hdr, 206 (xfs_dir2_inou_t *)&sfep->name[sfep->namelen + 1], ino); 207} 208 209 210/* 211 * Directory data block operations 212 */ 213 214/* 215 * For special situations, the dirent size ends up fixed because we always know 216 * what the size of the entry is. That's true for the "." and "..", and 217 * therefore we know that they are a fixed size and hence their offsets are 218 * constant, as is the first entry. 219 * 220 * Hence, this calculation is written as a macro to be able to be calculated at 221 * compile time and so certain offsets can be calculated directly in the 222 * structure initaliser via the macro. There are two macros - one for dirents 223 * with ftype and without so there are no unresolvable conditionals in the 224 * calculations. We also use round_up() as XFS_DIR2_DATA_ALIGN is always a power 225 * of 2 and the compiler doesn't reject it (unlike roundup()). 226 */ 227#define XFS_DIR2_DATA_ENTSIZE(n) \ 228 round_up((offsetof(struct xfs_dir2_data_entry, name[0]) + (n) + \ 229 sizeof(xfs_dir2_data_off_t)), XFS_DIR2_DATA_ALIGN) 230 231#define XFS_DIR3_DATA_ENTSIZE(n) \ 232 round_up((offsetof(struct xfs_dir2_data_entry, name[0]) + (n) + \ 233 sizeof(xfs_dir2_data_off_t) + sizeof(__uint8_t)), \ 234 XFS_DIR2_DATA_ALIGN) 235 236static int 237xfs_dir2_data_entsize( 238 int n) 239{ 240 return XFS_DIR2_DATA_ENTSIZE(n); 241} 242 243static int 244xfs_dir3_data_entsize( 245 int n) 246{ 247 return XFS_DIR3_DATA_ENTSIZE(n); 248} 249 250static __uint8_t 251xfs_dir2_data_get_ftype( 252 struct xfs_dir2_data_entry *dep) 253{ 254 return XFS_DIR3_FT_UNKNOWN; 255} 256 257static void 258xfs_dir2_data_put_ftype( 259 struct xfs_dir2_data_entry *dep, 260 __uint8_t ftype) 261{ 262 ASSERT(ftype < XFS_DIR3_FT_MAX); 263} 264 265static __uint8_t 266xfs_dir3_data_get_ftype( 267 struct xfs_dir2_data_entry *dep) 268{ 269 __uint8_t ftype = dep->name[dep->namelen]; 270 271 if (ftype >= XFS_DIR3_FT_MAX) 272 return XFS_DIR3_FT_UNKNOWN; 273 return ftype; 274} 275 276static void 277xfs_dir3_data_put_ftype( 278 struct xfs_dir2_data_entry *dep, 279 __uint8_t type) 280{ 281 ASSERT(type < XFS_DIR3_FT_MAX); 282 ASSERT(dep->namelen != 0); 283 284 dep->name[dep->namelen] = type; 285} 286 287/* 288 * Pointer to an entry's tag word. 289 */ 290static __be16 * 291xfs_dir2_data_entry_tag_p( 292 struct xfs_dir2_data_entry *dep) 293{ 294 return (__be16 *)((char *)dep + 295 xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16)); 296} 297 298static __be16 * 299xfs_dir3_data_entry_tag_p( 300 struct xfs_dir2_data_entry *dep) 301{ 302 return (__be16 *)((char *)dep + 303 xfs_dir3_data_entsize(dep->namelen) - sizeof(__be16)); 304} 305 306/* 307 * location of . and .. in data space (always block 0) 308 */ 309static struct xfs_dir2_data_entry * 310xfs_dir2_data_dot_entry_p( 311 struct xfs_dir2_data_hdr *hdr) 312{ 313 return (struct xfs_dir2_data_entry *) 314 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr)); 315} 316 317static struct xfs_dir2_data_entry * 318xfs_dir2_data_dotdot_entry_p( 319 struct xfs_dir2_data_hdr *hdr) 320{ 321 return (struct xfs_dir2_data_entry *) 322 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) + 323 XFS_DIR2_DATA_ENTSIZE(1)); 324} 325 326static struct xfs_dir2_data_entry * 327xfs_dir2_data_first_entry_p( 328 struct xfs_dir2_data_hdr *hdr) 329{ 330 return (struct xfs_dir2_data_entry *) 331 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) + 332 XFS_DIR2_DATA_ENTSIZE(1) + 333 XFS_DIR2_DATA_ENTSIZE(2)); 334} 335 336static struct xfs_dir2_data_entry * 337xfs_dir2_ftype_data_dotdot_entry_p( 338 struct xfs_dir2_data_hdr *hdr) 339{ 340 return (struct xfs_dir2_data_entry *) 341 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) + 342 XFS_DIR3_DATA_ENTSIZE(1)); 343} 344 345static struct xfs_dir2_data_entry * 346xfs_dir2_ftype_data_first_entry_p( 347 struct xfs_dir2_data_hdr *hdr) 348{ 349 return (struct xfs_dir2_data_entry *) 350 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) + 351 XFS_DIR3_DATA_ENTSIZE(1) + 352 XFS_DIR3_DATA_ENTSIZE(2)); 353} 354 355static struct xfs_dir2_data_entry * 356xfs_dir3_data_dot_entry_p( 357 struct xfs_dir2_data_hdr *hdr) 358{ 359 return (struct xfs_dir2_data_entry *) 360 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr)); 361} 362 363static struct xfs_dir2_data_entry * 364xfs_dir3_data_dotdot_entry_p( 365 struct xfs_dir2_data_hdr *hdr) 366{ 367 return (struct xfs_dir2_data_entry *) 368 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr) + 369 XFS_DIR3_DATA_ENTSIZE(1)); 370} 371 372static struct xfs_dir2_data_entry * 373xfs_dir3_data_first_entry_p( 374 struct xfs_dir2_data_hdr *hdr) 375{ 376 return (struct xfs_dir2_data_entry *) 377 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr) + 378 XFS_DIR3_DATA_ENTSIZE(1) + 379 XFS_DIR3_DATA_ENTSIZE(2)); 380} 381 382static struct xfs_dir2_data_free * 383xfs_dir2_data_bestfree_p(struct xfs_dir2_data_hdr *hdr) 384{ 385 return hdr->bestfree; 386} 387 388static struct xfs_dir2_data_free * 389xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr) 390{ 391 return ((struct xfs_dir3_data_hdr *)hdr)->best_free; 392} 393 394static struct xfs_dir2_data_entry * 395xfs_dir2_data_entry_p(struct xfs_dir2_data_hdr *hdr) 396{ 397 return (struct xfs_dir2_data_entry *) 398 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr)); 399} 400 401static struct xfs_dir2_data_unused * 402xfs_dir2_data_unused_p(struct xfs_dir2_data_hdr *hdr) 403{ 404 return (struct xfs_dir2_data_unused *) 405 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr)); 406} 407 408static struct xfs_dir2_data_entry * 409xfs_dir3_data_entry_p(struct xfs_dir2_data_hdr *hdr) 410{ 411 return (struct xfs_dir2_data_entry *) 412 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr)); 413} 414 415static struct xfs_dir2_data_unused * 416xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr) 417{ 418 return (struct xfs_dir2_data_unused *) 419 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr)); 420} 421 422 423/* 424 * Directory Leaf block operations 425 */ 426static int 427xfs_dir2_max_leaf_ents(struct xfs_da_geometry *geo) 428{ 429 return (geo->blksize - sizeof(struct xfs_dir2_leaf_hdr)) / 430 (uint)sizeof(struct xfs_dir2_leaf_entry); 431} 432 433static struct xfs_dir2_leaf_entry * 434xfs_dir2_leaf_ents_p(struct xfs_dir2_leaf *lp) 435{ 436 return lp->__ents; 437} 438 439static int 440xfs_dir3_max_leaf_ents(struct xfs_da_geometry *geo) 441{ 442 return (geo->blksize - sizeof(struct xfs_dir3_leaf_hdr)) / 443 (uint)sizeof(struct xfs_dir2_leaf_entry); 444} 445 446static struct xfs_dir2_leaf_entry * 447xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp) 448{ 449 return ((struct xfs_dir3_leaf *)lp)->__ents; 450} 451 452static void 453xfs_dir2_leaf_hdr_from_disk( 454 struct xfs_dir3_icleaf_hdr *to, 455 struct xfs_dir2_leaf *from) 456{ 457 to->forw = be32_to_cpu(from->hdr.info.forw); 458 to->back = be32_to_cpu(from->hdr.info.back); 459 to->magic = be16_to_cpu(from->hdr.info.magic); 460 to->count = be16_to_cpu(from->hdr.count); 461 to->stale = be16_to_cpu(from->hdr.stale); 462 463 ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC || 464 to->magic == XFS_DIR2_LEAFN_MAGIC); 465} 466 467static void 468xfs_dir2_leaf_hdr_to_disk( 469 struct xfs_dir2_leaf *to, 470 struct xfs_dir3_icleaf_hdr *from) 471{ 472 ASSERT(from->magic == XFS_DIR2_LEAF1_MAGIC || 473 from->magic == XFS_DIR2_LEAFN_MAGIC); 474 475 to->hdr.info.forw = cpu_to_be32(from->forw); 476 to->hdr.info.back = cpu_to_be32(from->back); 477 to->hdr.info.magic = cpu_to_be16(from->magic); 478 to->hdr.count = cpu_to_be16(from->count); 479 to->hdr.stale = cpu_to_be16(from->stale); 480} 481 482static void 483xfs_dir3_leaf_hdr_from_disk( 484 struct xfs_dir3_icleaf_hdr *to, 485 struct xfs_dir2_leaf *from) 486{ 487 struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)from; 488 489 to->forw = be32_to_cpu(hdr3->info.hdr.forw); 490 to->back = be32_to_cpu(hdr3->info.hdr.back); 491 to->magic = be16_to_cpu(hdr3->info.hdr.magic); 492 to->count = be16_to_cpu(hdr3->count); 493 to->stale = be16_to_cpu(hdr3->stale); 494 495 ASSERT(to->magic == XFS_DIR3_LEAF1_MAGIC || 496 to->magic == XFS_DIR3_LEAFN_MAGIC); 497} 498 499static void 500xfs_dir3_leaf_hdr_to_disk( 501 struct xfs_dir2_leaf *to, 502 struct xfs_dir3_icleaf_hdr *from) 503{ 504 struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)to; 505 506 ASSERT(from->magic == XFS_DIR3_LEAF1_MAGIC || 507 from->magic == XFS_DIR3_LEAFN_MAGIC); 508 509 hdr3->info.hdr.forw = cpu_to_be32(from->forw); 510 hdr3->info.hdr.back = cpu_to_be32(from->back); 511 hdr3->info.hdr.magic = cpu_to_be16(from->magic); 512 hdr3->count = cpu_to_be16(from->count); 513 hdr3->stale = cpu_to_be16(from->stale); 514} 515 516 517/* 518 * Directory/Attribute Node block operations 519 */ 520static struct xfs_da_node_entry * 521xfs_da2_node_tree_p(struct xfs_da_intnode *dap) 522{ 523 return dap->__btree; 524} 525 526static struct xfs_da_node_entry * 527xfs_da3_node_tree_p(struct xfs_da_intnode *dap) 528{ 529 return ((struct xfs_da3_intnode *)dap)->__btree; 530} 531 532static void 533xfs_da2_node_hdr_from_disk( 534 struct xfs_da3_icnode_hdr *to, 535 struct xfs_da_intnode *from) 536{ 537 ASSERT(from->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); 538 to->forw = be32_to_cpu(from->hdr.info.forw); 539 to->back = be32_to_cpu(from->hdr.info.back); 540 to->magic = be16_to_cpu(from->hdr.info.magic); 541 to->count = be16_to_cpu(from->hdr.__count); 542 to->level = be16_to_cpu(from->hdr.__level); 543} 544 545static void 546xfs_da2_node_hdr_to_disk( 547 struct xfs_da_intnode *to, 548 struct xfs_da3_icnode_hdr *from) 549{ 550 ASSERT(from->magic == XFS_DA_NODE_MAGIC); 551 to->hdr.info.forw = cpu_to_be32(from->forw); 552 to->hdr.info.back = cpu_to_be32(from->back); 553 to->hdr.info.magic = cpu_to_be16(from->magic); 554 to->hdr.__count = cpu_to_be16(from->count); 555 to->hdr.__level = cpu_to_be16(from->level); 556} 557 558static void 559xfs_da3_node_hdr_from_disk( 560 struct xfs_da3_icnode_hdr *to, 561 struct xfs_da_intnode *from) 562{ 563 struct xfs_da3_node_hdr *hdr3 = (struct xfs_da3_node_hdr *)from; 564 565 ASSERT(from->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC)); 566 to->forw = be32_to_cpu(hdr3->info.hdr.forw); 567 to->back = be32_to_cpu(hdr3->info.hdr.back); 568 to->magic = be16_to_cpu(hdr3->info.hdr.magic); 569 to->count = be16_to_cpu(hdr3->__count); 570 to->level = be16_to_cpu(hdr3->__level); 571} 572 573static void 574xfs_da3_node_hdr_to_disk( 575 struct xfs_da_intnode *to, 576 struct xfs_da3_icnode_hdr *from) 577{ 578 struct xfs_da3_node_hdr *hdr3 = (struct xfs_da3_node_hdr *)to; 579 580 ASSERT(from->magic == XFS_DA3_NODE_MAGIC); 581 hdr3->info.hdr.forw = cpu_to_be32(from->forw); 582 hdr3->info.hdr.back = cpu_to_be32(from->back); 583 hdr3->info.hdr.magic = cpu_to_be16(from->magic); 584 hdr3->__count = cpu_to_be16(from->count); 585 hdr3->__level = cpu_to_be16(from->level); 586} 587 588 589/* 590 * Directory free space block operations 591 */ 592static int 593xfs_dir2_free_max_bests(struct xfs_da_geometry *geo) 594{ 595 return (geo->blksize - sizeof(struct xfs_dir2_free_hdr)) / 596 sizeof(xfs_dir2_data_off_t); 597} 598 599static __be16 * 600xfs_dir2_free_bests_p(struct xfs_dir2_free *free) 601{ 602 return (__be16 *)((char *)free + sizeof(struct xfs_dir2_free_hdr)); 603} 604 605/* 606 * Convert data space db to the corresponding free db. 607 */ 608static xfs_dir2_db_t 609xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db) 610{ 611 return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) + 612 (db / xfs_dir2_free_max_bests(geo)); 613} 614 615/* 616 * Convert data space db to the corresponding index in a free db. 617 */ 618static int 619xfs_dir2_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db) 620{ 621 return db % xfs_dir2_free_max_bests(geo); 622} 623 624static int 625xfs_dir3_free_max_bests(struct xfs_da_geometry *geo) 626{ 627 return (geo->blksize - sizeof(struct xfs_dir3_free_hdr)) / 628 sizeof(xfs_dir2_data_off_t); 629} 630 631static __be16 * 632xfs_dir3_free_bests_p(struct xfs_dir2_free *free) 633{ 634 return (__be16 *)((char *)free + sizeof(struct xfs_dir3_free_hdr)); 635} 636 637/* 638 * Convert data space db to the corresponding free db. 639 */ 640static xfs_dir2_db_t 641xfs_dir3_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db) 642{ 643 return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) + 644 (db / xfs_dir3_free_max_bests(geo)); 645} 646 647/* 648 * Convert data space db to the corresponding index in a free db. 649 */ 650static int 651xfs_dir3_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db) 652{ 653 return db % xfs_dir3_free_max_bests(geo); 654} 655 656static void 657xfs_dir2_free_hdr_from_disk( 658 struct xfs_dir3_icfree_hdr *to, 659 struct xfs_dir2_free *from) 660{ 661 to->magic = be32_to_cpu(from->hdr.magic); 662 to->firstdb = be32_to_cpu(from->hdr.firstdb); 663 to->nvalid = be32_to_cpu(from->hdr.nvalid); 664 to->nused = be32_to_cpu(from->hdr.nused); 665 ASSERT(to->magic == XFS_DIR2_FREE_MAGIC); 666} 667 668static void 669xfs_dir2_free_hdr_to_disk( 670 struct xfs_dir2_free *to, 671 struct xfs_dir3_icfree_hdr *from) 672{ 673 ASSERT(from->magic == XFS_DIR2_FREE_MAGIC); 674 675 to->hdr.magic = cpu_to_be32(from->magic); 676 to->hdr.firstdb = cpu_to_be32(from->firstdb); 677 to->hdr.nvalid = cpu_to_be32(from->nvalid); 678 to->hdr.nused = cpu_to_be32(from->nused); 679} 680 681static void 682xfs_dir3_free_hdr_from_disk( 683 struct xfs_dir3_icfree_hdr *to, 684 struct xfs_dir2_free *from) 685{ 686 struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)from; 687 688 to->magic = be32_to_cpu(hdr3->hdr.magic); 689 to->firstdb = be32_to_cpu(hdr3->firstdb); 690 to->nvalid = be32_to_cpu(hdr3->nvalid); 691 to->nused = be32_to_cpu(hdr3->nused); 692 693 ASSERT(to->magic == XFS_DIR3_FREE_MAGIC); 694} 695 696static void 697xfs_dir3_free_hdr_to_disk( 698 struct xfs_dir2_free *to, 699 struct xfs_dir3_icfree_hdr *from) 700{ 701 struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)to; 702 703 ASSERT(from->magic == XFS_DIR3_FREE_MAGIC); 704 705 hdr3->hdr.magic = cpu_to_be32(from->magic); 706 hdr3->firstdb = cpu_to_be32(from->firstdb); 707 hdr3->nvalid = cpu_to_be32(from->nvalid); 708 hdr3->nused = cpu_to_be32(from->nused); 709} 710 711static const struct xfs_dir_ops xfs_dir2_ops = { 712 .sf_entsize = xfs_dir2_sf_entsize, 713 .sf_nextentry = xfs_dir2_sf_nextentry, 714 .sf_get_ftype = xfs_dir2_sfe_get_ftype, 715 .sf_put_ftype = xfs_dir2_sfe_put_ftype, 716 .sf_get_ino = xfs_dir2_sfe_get_ino, 717 .sf_put_ino = xfs_dir2_sfe_put_ino, 718 .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino, 719 .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino, 720 721 .data_entsize = xfs_dir2_data_entsize, 722 .data_get_ftype = xfs_dir2_data_get_ftype, 723 .data_put_ftype = xfs_dir2_data_put_ftype, 724 .data_entry_tag_p = xfs_dir2_data_entry_tag_p, 725 .data_bestfree_p = xfs_dir2_data_bestfree_p, 726 727 .data_dot_offset = sizeof(struct xfs_dir2_data_hdr), 728 .data_dotdot_offset = sizeof(struct xfs_dir2_data_hdr) + 729 XFS_DIR2_DATA_ENTSIZE(1), 730 .data_first_offset = sizeof(struct xfs_dir2_data_hdr) + 731 XFS_DIR2_DATA_ENTSIZE(1) + 732 XFS_DIR2_DATA_ENTSIZE(2), 733 .data_entry_offset = sizeof(struct xfs_dir2_data_hdr), 734 735 .data_dot_entry_p = xfs_dir2_data_dot_entry_p, 736 .data_dotdot_entry_p = xfs_dir2_data_dotdot_entry_p, 737 .data_first_entry_p = xfs_dir2_data_first_entry_p, 738 .data_entry_p = xfs_dir2_data_entry_p, 739 .data_unused_p = xfs_dir2_data_unused_p, 740 741 .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr), 742 .leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk, 743 .leaf_hdr_from_disk = xfs_dir2_leaf_hdr_from_disk, 744 .leaf_max_ents = xfs_dir2_max_leaf_ents, 745 .leaf_ents_p = xfs_dir2_leaf_ents_p, 746 747 .node_hdr_size = sizeof(struct xfs_da_node_hdr), 748 .node_hdr_to_disk = xfs_da2_node_hdr_to_disk, 749 .node_hdr_from_disk = xfs_da2_node_hdr_from_disk, 750 .node_tree_p = xfs_da2_node_tree_p, 751 752 .free_hdr_size = sizeof(struct xfs_dir2_free_hdr), 753 .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk, 754 .free_hdr_from_disk = xfs_dir2_free_hdr_from_disk, 755 .free_max_bests = xfs_dir2_free_max_bests, 756 .free_bests_p = xfs_dir2_free_bests_p, 757 .db_to_fdb = xfs_dir2_db_to_fdb, 758 .db_to_fdindex = xfs_dir2_db_to_fdindex, 759}; 760 761static const struct xfs_dir_ops xfs_dir2_ftype_ops = { 762 .sf_entsize = xfs_dir3_sf_entsize, 763 .sf_nextentry = xfs_dir3_sf_nextentry, 764 .sf_get_ftype = xfs_dir3_sfe_get_ftype, 765 .sf_put_ftype = xfs_dir3_sfe_put_ftype, 766 .sf_get_ino = xfs_dir3_sfe_get_ino, 767 .sf_put_ino = xfs_dir3_sfe_put_ino, 768 .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino, 769 .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino, 770 771 .data_entsize = xfs_dir3_data_entsize, 772 .data_get_ftype = xfs_dir3_data_get_ftype, 773 .data_put_ftype = xfs_dir3_data_put_ftype, 774 .data_entry_tag_p = xfs_dir3_data_entry_tag_p, 775 .data_bestfree_p = xfs_dir2_data_bestfree_p, 776 777 .data_dot_offset = sizeof(struct xfs_dir2_data_hdr), 778 .data_dotdot_offset = sizeof(struct xfs_dir2_data_hdr) + 779 XFS_DIR3_DATA_ENTSIZE(1), 780 .data_first_offset = sizeof(struct xfs_dir2_data_hdr) + 781 XFS_DIR3_DATA_ENTSIZE(1) + 782 XFS_DIR3_DATA_ENTSIZE(2), 783 .data_entry_offset = sizeof(struct xfs_dir2_data_hdr), 784 785 .data_dot_entry_p = xfs_dir2_data_dot_entry_p, 786 .data_dotdot_entry_p = xfs_dir2_ftype_data_dotdot_entry_p, 787 .data_first_entry_p = xfs_dir2_ftype_data_first_entry_p, 788 .data_entry_p = xfs_dir2_data_entry_p, 789 .data_unused_p = xfs_dir2_data_unused_p, 790 791 .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr), 792 .leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk, 793 .leaf_hdr_from_disk = xfs_dir2_leaf_hdr_from_disk, 794 .leaf_max_ents = xfs_dir2_max_leaf_ents, 795 .leaf_ents_p = xfs_dir2_leaf_ents_p, 796 797 .node_hdr_size = sizeof(struct xfs_da_node_hdr), 798 .node_hdr_to_disk = xfs_da2_node_hdr_to_disk, 799 .node_hdr_from_disk = xfs_da2_node_hdr_from_disk, 800 .node_tree_p = xfs_da2_node_tree_p, 801 802 .free_hdr_size = sizeof(struct xfs_dir2_free_hdr), 803 .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk, 804 .free_hdr_from_disk = xfs_dir2_free_hdr_from_disk, 805 .free_max_bests = xfs_dir2_free_max_bests, 806 .free_bests_p = xfs_dir2_free_bests_p, 807 .db_to_fdb = xfs_dir2_db_to_fdb, 808 .db_to_fdindex = xfs_dir2_db_to_fdindex, 809}; 810 811static const struct xfs_dir_ops xfs_dir3_ops = { 812 .sf_entsize = xfs_dir3_sf_entsize, 813 .sf_nextentry = xfs_dir3_sf_nextentry, 814 .sf_get_ftype = xfs_dir3_sfe_get_ftype, 815 .sf_put_ftype = xfs_dir3_sfe_put_ftype, 816 .sf_get_ino = xfs_dir3_sfe_get_ino, 817 .sf_put_ino = xfs_dir3_sfe_put_ino, 818 .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino, 819 .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino, 820 821 .data_entsize = xfs_dir3_data_entsize, 822 .data_get_ftype = xfs_dir3_data_get_ftype, 823 .data_put_ftype = xfs_dir3_data_put_ftype, 824 .data_entry_tag_p = xfs_dir3_data_entry_tag_p, 825 .data_bestfree_p = xfs_dir3_data_bestfree_p, 826 827 .data_dot_offset = sizeof(struct xfs_dir3_data_hdr), 828 .data_dotdot_offset = sizeof(struct xfs_dir3_data_hdr) + 829 XFS_DIR3_DATA_ENTSIZE(1), 830 .data_first_offset = sizeof(struct xfs_dir3_data_hdr) + 831 XFS_DIR3_DATA_ENTSIZE(1) + 832 XFS_DIR3_DATA_ENTSIZE(2), 833 .data_entry_offset = sizeof(struct xfs_dir3_data_hdr), 834 835 .data_dot_entry_p = xfs_dir3_data_dot_entry_p, 836 .data_dotdot_entry_p = xfs_dir3_data_dotdot_entry_p, 837 .data_first_entry_p = xfs_dir3_data_first_entry_p, 838 .data_entry_p = xfs_dir3_data_entry_p, 839 .data_unused_p = xfs_dir3_data_unused_p, 840 841 .leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr), 842 .leaf_hdr_to_disk = xfs_dir3_leaf_hdr_to_disk, 843 .leaf_hdr_from_disk = xfs_dir3_leaf_hdr_from_disk, 844 .leaf_max_ents = xfs_dir3_max_leaf_ents, 845 .leaf_ents_p = xfs_dir3_leaf_ents_p, 846 847 .node_hdr_size = sizeof(struct xfs_da3_node_hdr), 848 .node_hdr_to_disk = xfs_da3_node_hdr_to_disk, 849 .node_hdr_from_disk = xfs_da3_node_hdr_from_disk, 850 .node_tree_p = xfs_da3_node_tree_p, 851 852 .free_hdr_size = sizeof(struct xfs_dir3_free_hdr), 853 .free_hdr_to_disk = xfs_dir3_free_hdr_to_disk, 854 .free_hdr_from_disk = xfs_dir3_free_hdr_from_disk, 855 .free_max_bests = xfs_dir3_free_max_bests, 856 .free_bests_p = xfs_dir3_free_bests_p, 857 .db_to_fdb = xfs_dir3_db_to_fdb, 858 .db_to_fdindex = xfs_dir3_db_to_fdindex, 859}; 860 861static const struct xfs_dir_ops xfs_dir2_nondir_ops = { 862 .node_hdr_size = sizeof(struct xfs_da_node_hdr), 863 .node_hdr_to_disk = xfs_da2_node_hdr_to_disk, 864 .node_hdr_from_disk = xfs_da2_node_hdr_from_disk, 865 .node_tree_p = xfs_da2_node_tree_p, 866}; 867 868static const struct xfs_dir_ops xfs_dir3_nondir_ops = { 869 .node_hdr_size = sizeof(struct xfs_da3_node_hdr), 870 .node_hdr_to_disk = xfs_da3_node_hdr_to_disk, 871 .node_hdr_from_disk = xfs_da3_node_hdr_from_disk, 872 .node_tree_p = xfs_da3_node_tree_p, 873}; 874 875/* 876 * Return the ops structure according to the current config. If we are passed 877 * an inode, then that overrides the default config we use which is based on 878 * feature bits. 879 */ 880const struct xfs_dir_ops * 881xfs_dir_get_ops( 882 struct xfs_mount *mp, 883 struct xfs_inode *dp) 884{ 885 if (dp) 886 return dp->d_ops; 887 if (mp->m_dir_inode_ops) 888 return mp->m_dir_inode_ops; 889 if (xfs_sb_version_hascrc(&mp->m_sb)) 890 return &xfs_dir3_ops; 891 if (xfs_sb_version_hasftype(&mp->m_sb)) 892 return &xfs_dir2_ftype_ops; 893 return &xfs_dir2_ops; 894} 895 896const struct xfs_dir_ops * 897xfs_nondir_get_ops( 898 struct xfs_mount *mp, 899 struct xfs_inode *dp) 900{ 901 if (dp) 902 return dp->d_ops; 903 if (mp->m_nondir_inode_ops) 904 return mp->m_nondir_inode_ops; 905 if (xfs_sb_version_hascrc(&mp->m_sb)) 906 return &xfs_dir3_nondir_ops; 907 return &xfs_dir2_nondir_ops; 908} 909