linux/fs/xfs/libxfs/xfs_da_format.c
<<
>>
Prefs
   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