| .. | .. |
|---|
| 6 | 6 | */ |
|---|
| 7 | 7 | #include "xfs.h" |
|---|
| 8 | 8 | #include "xfs_fs.h" |
|---|
| 9 | +#include "xfs_shared.h" |
|---|
| 9 | 10 | #include "xfs_format.h" |
|---|
| 10 | 11 | #include "xfs_log_format.h" |
|---|
| 11 | 12 | #include "xfs_trans_resv.h" |
|---|
| 12 | 13 | #include "xfs_mount.h" |
|---|
| 13 | | -#include "xfs_da_format.h" |
|---|
| 14 | | -#include "xfs_da_btree.h" |
|---|
| 15 | 14 | #include "xfs_inode.h" |
|---|
| 16 | 15 | #include "xfs_trans.h" |
|---|
| 17 | | -#include "xfs_inode_item.h" |
|---|
| 18 | 16 | #include "xfs_bmap.h" |
|---|
| 19 | 17 | #include "xfs_buf_item.h" |
|---|
| 20 | 18 | #include "xfs_dir2.h" |
|---|
| 21 | 19 | #include "xfs_dir2_priv.h" |
|---|
| 22 | 20 | #include "xfs_error.h" |
|---|
| 23 | 21 | #include "xfs_trace.h" |
|---|
| 24 | | -#include "xfs_cksum.h" |
|---|
| 25 | 22 | #include "xfs_log.h" |
|---|
| 26 | 23 | |
|---|
| 27 | 24 | /* |
|---|
| .. | .. |
|---|
| 50 | 47 | xfs_dir3_block_verify( |
|---|
| 51 | 48 | struct xfs_buf *bp) |
|---|
| 52 | 49 | { |
|---|
| 53 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
|---|
| 50 | + struct xfs_mount *mp = bp->b_mount; |
|---|
| 54 | 51 | struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; |
|---|
| 55 | 52 | |
|---|
| 53 | + if (!xfs_verify_magic(bp, hdr3->magic)) |
|---|
| 54 | + return __this_address; |
|---|
| 55 | + |
|---|
| 56 | 56 | if (xfs_sb_version_hascrc(&mp->m_sb)) { |
|---|
| 57 | | - if (hdr3->magic != cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) |
|---|
| 58 | | - return __this_address; |
|---|
| 59 | 57 | if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_meta_uuid)) |
|---|
| 60 | 58 | return __this_address; |
|---|
| 61 | 59 | if (be64_to_cpu(hdr3->blkno) != bp->b_bn) |
|---|
| 62 | 60 | return __this_address; |
|---|
| 63 | 61 | if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->lsn))) |
|---|
| 64 | | - return __this_address; |
|---|
| 65 | | - } else { |
|---|
| 66 | | - if (hdr3->magic != cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)) |
|---|
| 67 | 62 | return __this_address; |
|---|
| 68 | 63 | } |
|---|
| 69 | 64 | return __xfs_dir3_data_check(NULL, bp); |
|---|
| .. | .. |
|---|
| 73 | 68 | xfs_dir3_block_read_verify( |
|---|
| 74 | 69 | struct xfs_buf *bp) |
|---|
| 75 | 70 | { |
|---|
| 76 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
|---|
| 71 | + struct xfs_mount *mp = bp->b_mount; |
|---|
| 77 | 72 | xfs_failaddr_t fa; |
|---|
| 78 | 73 | |
|---|
| 79 | 74 | if (xfs_sb_version_hascrc(&mp->m_sb) && |
|---|
| .. | .. |
|---|
| 90 | 85 | xfs_dir3_block_write_verify( |
|---|
| 91 | 86 | struct xfs_buf *bp) |
|---|
| 92 | 87 | { |
|---|
| 93 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
|---|
| 88 | + struct xfs_mount *mp = bp->b_mount; |
|---|
| 94 | 89 | struct xfs_buf_log_item *bip = bp->b_log_item; |
|---|
| 95 | 90 | struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; |
|---|
| 96 | 91 | xfs_failaddr_t fa; |
|---|
| .. | .. |
|---|
| 112 | 107 | |
|---|
| 113 | 108 | const struct xfs_buf_ops xfs_dir3_block_buf_ops = { |
|---|
| 114 | 109 | .name = "xfs_dir3_block", |
|---|
| 110 | + .magic = { cpu_to_be32(XFS_DIR2_BLOCK_MAGIC), |
|---|
| 111 | + cpu_to_be32(XFS_DIR3_BLOCK_MAGIC) }, |
|---|
| 115 | 112 | .verify_read = xfs_dir3_block_read_verify, |
|---|
| 116 | 113 | .verify_write = xfs_dir3_block_write_verify, |
|---|
| 117 | 114 | .verify_struct = xfs_dir3_block_verify, |
|---|
| 118 | 115 | }; |
|---|
| 116 | + |
|---|
| 117 | +static xfs_failaddr_t |
|---|
| 118 | +xfs_dir3_block_header_check( |
|---|
| 119 | + struct xfs_inode *dp, |
|---|
| 120 | + struct xfs_buf *bp) |
|---|
| 121 | +{ |
|---|
| 122 | + struct xfs_mount *mp = dp->i_mount; |
|---|
| 123 | + |
|---|
| 124 | + if (xfs_sb_version_hascrc(&mp->m_sb)) { |
|---|
| 125 | + struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; |
|---|
| 126 | + |
|---|
| 127 | + if (be64_to_cpu(hdr3->owner) != dp->i_ino) |
|---|
| 128 | + return __this_address; |
|---|
| 129 | + } |
|---|
| 130 | + |
|---|
| 131 | + return NULL; |
|---|
| 132 | +} |
|---|
| 119 | 133 | |
|---|
| 120 | 134 | int |
|---|
| 121 | 135 | xfs_dir3_block_read( |
|---|
| .. | .. |
|---|
| 124 | 138 | struct xfs_buf **bpp) |
|---|
| 125 | 139 | { |
|---|
| 126 | 140 | struct xfs_mount *mp = dp->i_mount; |
|---|
| 141 | + xfs_failaddr_t fa; |
|---|
| 127 | 142 | int err; |
|---|
| 128 | 143 | |
|---|
| 129 | | - err = xfs_da_read_buf(tp, dp, mp->m_dir_geo->datablk, -1, bpp, |
|---|
| 144 | + err = xfs_da_read_buf(tp, dp, mp->m_dir_geo->datablk, 0, bpp, |
|---|
| 130 | 145 | XFS_DATA_FORK, &xfs_dir3_block_buf_ops); |
|---|
| 131 | | - if (!err && tp && *bpp) |
|---|
| 132 | | - xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_BLOCK_BUF); |
|---|
| 146 | + if (err || !*bpp) |
|---|
| 147 | + return err; |
|---|
| 148 | + |
|---|
| 149 | + /* Check things that we can't do in the verifier. */ |
|---|
| 150 | + fa = xfs_dir3_block_header_check(dp, *bpp); |
|---|
| 151 | + if (fa) { |
|---|
| 152 | + __xfs_buf_mark_corrupt(*bpp, fa); |
|---|
| 153 | + xfs_trans_brelse(tp, *bpp); |
|---|
| 154 | + *bpp = NULL; |
|---|
| 155 | + return -EFSCORRUPTED; |
|---|
| 156 | + } |
|---|
| 157 | + |
|---|
| 158 | + xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_BLOCK_BUF); |
|---|
| 133 | 159 | return err; |
|---|
| 134 | 160 | } |
|---|
| 135 | 161 | |
|---|
| .. | .. |
|---|
| 175 | 201 | struct xfs_dir2_data_unused *enddup = NULL; |
|---|
| 176 | 202 | |
|---|
| 177 | 203 | *compact = 0; |
|---|
| 178 | | - bf = dp->d_ops->data_bestfree_p(hdr); |
|---|
| 204 | + bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); |
|---|
| 179 | 205 | |
|---|
| 180 | 206 | /* |
|---|
| 181 | 207 | * If there are stale entries we'll use one for the leaf. |
|---|
| .. | .. |
|---|
| 314 | 340 | * This needs to happen before the next call to use_free. |
|---|
| 315 | 341 | */ |
|---|
| 316 | 342 | if (needscan) |
|---|
| 317 | | - xfs_dir2_data_freescan(args->dp, hdr, needlog); |
|---|
| 343 | + xfs_dir2_data_freescan(args->dp->i_mount, hdr, needlog); |
|---|
| 318 | 344 | } |
|---|
| 319 | 345 | |
|---|
| 320 | 346 | /* |
|---|
| .. | .. |
|---|
| 358 | 384 | if (error) |
|---|
| 359 | 385 | return error; |
|---|
| 360 | 386 | |
|---|
| 361 | | - len = dp->d_ops->data_entsize(args->namelen); |
|---|
| 387 | + len = xfs_dir2_data_entsize(dp->i_mount, args->namelen); |
|---|
| 362 | 388 | |
|---|
| 363 | 389 | /* |
|---|
| 364 | 390 | * Set up pointers to parts of the block. |
|---|
| .. | .. |
|---|
| 461 | 487 | * This needs to happen before the next call to use_free. |
|---|
| 462 | 488 | */ |
|---|
| 463 | 489 | if (needscan) { |
|---|
| 464 | | - xfs_dir2_data_freescan(dp, hdr, &needlog); |
|---|
| 490 | + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); |
|---|
| 465 | 491 | needscan = 0; |
|---|
| 466 | 492 | } |
|---|
| 467 | 493 | /* |
|---|
| .. | .. |
|---|
| 544 | 570 | dep->inumber = cpu_to_be64(args->inumber); |
|---|
| 545 | 571 | dep->namelen = args->namelen; |
|---|
| 546 | 572 | memcpy(dep->name, args->name, args->namelen); |
|---|
| 547 | | - dp->d_ops->data_put_ftype(dep, args->filetype); |
|---|
| 548 | | - tagp = dp->d_ops->data_entry_tag_p(dep); |
|---|
| 573 | + xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype); |
|---|
| 574 | + tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep); |
|---|
| 549 | 575 | *tagp = cpu_to_be16((char *)dep - (char *)hdr); |
|---|
| 550 | 576 | /* |
|---|
| 551 | 577 | * Clean up the bestfree array and log the header, tail, and entry. |
|---|
| 552 | 578 | */ |
|---|
| 553 | 579 | if (needscan) |
|---|
| 554 | | - xfs_dir2_data_freescan(dp, hdr, &needlog); |
|---|
| 580 | + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); |
|---|
| 555 | 581 | if (needlog) |
|---|
| 556 | 582 | xfs_dir2_data_log_header(args, bp); |
|---|
| 557 | 583 | xfs_dir2_block_log_tail(tp, bp); |
|---|
| .. | .. |
|---|
| 636 | 662 | * Fill in inode number, CI name if appropriate, release the block. |
|---|
| 637 | 663 | */ |
|---|
| 638 | 664 | args->inumber = be64_to_cpu(dep->inumber); |
|---|
| 639 | | - args->filetype = dp->d_ops->data_get_ftype(dep); |
|---|
| 665 | + args->filetype = xfs_dir2_data_get_ftype(dp->i_mount, dep); |
|---|
| 640 | 666 | error = xfs_dir_cilookup_result(args, dep->name, dep->namelen); |
|---|
| 641 | 667 | xfs_trans_brelse(args->trans, bp); |
|---|
| 642 | 668 | return error; |
|---|
| .. | .. |
|---|
| 663 | 689 | int high; /* binary search high index */ |
|---|
| 664 | 690 | int low; /* binary search low index */ |
|---|
| 665 | 691 | int mid; /* binary search current idx */ |
|---|
| 666 | | - xfs_mount_t *mp; /* filesystem mount point */ |
|---|
| 667 | 692 | xfs_trans_t *tp; /* transaction pointer */ |
|---|
| 668 | 693 | enum xfs_dacmp cmp; /* comparison result */ |
|---|
| 669 | 694 | |
|---|
| 670 | 695 | dp = args->dp; |
|---|
| 671 | 696 | tp = args->trans; |
|---|
| 672 | | - mp = dp->i_mount; |
|---|
| 673 | 697 | |
|---|
| 674 | 698 | error = xfs_dir3_block_read(tp, dp, &bp); |
|---|
| 675 | 699 | if (error) |
|---|
| .. | .. |
|---|
| 721 | 745 | * and buffer. If it's the first case-insensitive match, store |
|---|
| 722 | 746 | * the index and buffer and continue looking for an exact match. |
|---|
| 723 | 747 | */ |
|---|
| 724 | | - cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); |
|---|
| 748 | + cmp = xfs_dir2_compname(args, dep->name, dep->namelen); |
|---|
| 725 | 749 | if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { |
|---|
| 726 | 750 | args->cmpresult = cmp; |
|---|
| 727 | 751 | *bpp = bp; |
|---|
| .. | .. |
|---|
| 794 | 818 | needlog = needscan = 0; |
|---|
| 795 | 819 | xfs_dir2_data_make_free(args, bp, |
|---|
| 796 | 820 | (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr), |
|---|
| 797 | | - dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan); |
|---|
| 821 | + xfs_dir2_data_entsize(dp->i_mount, dep->namelen), &needlog, |
|---|
| 822 | + &needscan); |
|---|
| 798 | 823 | /* |
|---|
| 799 | 824 | * Fix up the block tail. |
|---|
| 800 | 825 | */ |
|---|
| .. | .. |
|---|
| 809 | 834 | * Fix up bestfree, log the header if necessary. |
|---|
| 810 | 835 | */ |
|---|
| 811 | 836 | if (needscan) |
|---|
| 812 | | - xfs_dir2_data_freescan(dp, hdr, &needlog); |
|---|
| 837 | + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); |
|---|
| 813 | 838 | if (needlog) |
|---|
| 814 | 839 | xfs_dir2_data_log_header(args, bp); |
|---|
| 815 | 840 | xfs_dir3_data_check(dp, bp); |
|---|
| .. | .. |
|---|
| 867 | 892 | * Change the inode number to the new value. |
|---|
| 868 | 893 | */ |
|---|
| 869 | 894 | dep->inumber = cpu_to_be64(args->inumber); |
|---|
| 870 | | - dp->d_ops->data_put_ftype(dep, args->filetype); |
|---|
| 895 | + xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype); |
|---|
| 871 | 896 | xfs_dir2_data_log_entry(args, bp, dep); |
|---|
| 872 | 897 | xfs_dir3_data_check(dp, bp); |
|---|
| 873 | 898 | return 0; |
|---|
| .. | .. |
|---|
| 917 | 942 | __be16 *tagp; /* end of entry (tag) */ |
|---|
| 918 | 943 | int to; /* block/leaf to index */ |
|---|
| 919 | 944 | xfs_trans_t *tp; /* transaction pointer */ |
|---|
| 920 | | - struct xfs_dir2_leaf_entry *ents; |
|---|
| 921 | 945 | struct xfs_dir3_icleaf_hdr leafhdr; |
|---|
| 922 | 946 | |
|---|
| 923 | 947 | trace_xfs_dir2_leaf_to_block(args); |
|---|
| .. | .. |
|---|
| 926 | 950 | tp = args->trans; |
|---|
| 927 | 951 | mp = dp->i_mount; |
|---|
| 928 | 952 | leaf = lbp->b_addr; |
|---|
| 929 | | - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); |
|---|
| 930 | | - ents = dp->d_ops->leaf_ents_p(leaf); |
|---|
| 953 | + xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); |
|---|
| 931 | 954 | ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); |
|---|
| 932 | 955 | |
|---|
| 933 | 956 | ASSERT(leafhdr.magic == XFS_DIR2_LEAF1_MAGIC || |
|---|
| .. | .. |
|---|
| 941 | 964 | while (dp->i_d.di_size > args->geo->blksize) { |
|---|
| 942 | 965 | int hdrsz; |
|---|
| 943 | 966 | |
|---|
| 944 | | - hdrsz = dp->d_ops->data_entry_offset; |
|---|
| 967 | + hdrsz = args->geo->data_entry_offset; |
|---|
| 945 | 968 | bestsp = xfs_dir2_leaf_bests_p(ltp); |
|---|
| 946 | 969 | if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) == |
|---|
| 947 | 970 | args->geo->blksize - hdrsz) { |
|---|
| .. | .. |
|---|
| 956 | 979 | * Read the data block if we don't already have it, give up if it fails. |
|---|
| 957 | 980 | */ |
|---|
| 958 | 981 | if (!dbp) { |
|---|
| 959 | | - error = xfs_dir3_data_read(tp, dp, args->geo->datablk, -1, &dbp); |
|---|
| 982 | + error = xfs_dir3_data_read(tp, dp, args->geo->datablk, 0, &dbp); |
|---|
| 960 | 983 | if (error) |
|---|
| 961 | 984 | return error; |
|---|
| 962 | 985 | } |
|---|
| .. | .. |
|---|
| 1007 | 1030 | */ |
|---|
| 1008 | 1031 | lep = xfs_dir2_block_leaf_p(btp); |
|---|
| 1009 | 1032 | for (from = to = 0; from < leafhdr.count; from++) { |
|---|
| 1010 | | - if (ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) |
|---|
| 1033 | + if (leafhdr.ents[from].address == |
|---|
| 1034 | + cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) |
|---|
| 1011 | 1035 | continue; |
|---|
| 1012 | | - lep[to++] = ents[from]; |
|---|
| 1036 | + lep[to++] = leafhdr.ents[from]; |
|---|
| 1013 | 1037 | } |
|---|
| 1014 | 1038 | ASSERT(to == be32_to_cpu(btp->count)); |
|---|
| 1015 | 1039 | xfs_dir2_block_log_leaf(tp, dbp, 0, be32_to_cpu(btp->count) - 1); |
|---|
| .. | .. |
|---|
| 1017 | 1041 | * Scan the bestfree if we need it and log the data block header. |
|---|
| 1018 | 1042 | */ |
|---|
| 1019 | 1043 | if (needscan) |
|---|
| 1020 | | - xfs_dir2_data_freescan(dp, hdr, &needlog); |
|---|
| 1044 | + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); |
|---|
| 1021 | 1045 | if (needlog) |
|---|
| 1022 | 1046 | xfs_dir2_data_log_header(args, dbp); |
|---|
| 1023 | 1047 | /* |
|---|
| .. | .. |
|---|
| 1042 | 1066 | */ |
|---|
| 1043 | 1067 | int /* error */ |
|---|
| 1044 | 1068 | xfs_dir2_sf_to_block( |
|---|
| 1045 | | - xfs_da_args_t *args) /* operation arguments */ |
|---|
| 1069 | + struct xfs_da_args *args) |
|---|
| 1046 | 1070 | { |
|---|
| 1071 | + struct xfs_trans *tp = args->trans; |
|---|
| 1072 | + struct xfs_inode *dp = args->dp; |
|---|
| 1073 | + struct xfs_mount *mp = dp->i_mount; |
|---|
| 1074 | + struct xfs_ifork *ifp = XFS_IFORK_PTR(dp, XFS_DATA_FORK); |
|---|
| 1075 | + struct xfs_da_geometry *geo = args->geo; |
|---|
| 1047 | 1076 | xfs_dir2_db_t blkno; /* dir-relative block # (0) */ |
|---|
| 1048 | 1077 | xfs_dir2_data_hdr_t *hdr; /* block header */ |
|---|
| 1049 | 1078 | xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ |
|---|
| 1050 | 1079 | struct xfs_buf *bp; /* block buffer */ |
|---|
| 1051 | 1080 | xfs_dir2_block_tail_t *btp; /* block tail pointer */ |
|---|
| 1052 | 1081 | xfs_dir2_data_entry_t *dep; /* data entry pointer */ |
|---|
| 1053 | | - xfs_inode_t *dp; /* incore directory inode */ |
|---|
| 1054 | 1082 | int dummy; /* trash */ |
|---|
| 1055 | 1083 | xfs_dir2_data_unused_t *dup; /* unused entry pointer */ |
|---|
| 1056 | 1084 | int endoffset; /* end of data objects */ |
|---|
| 1057 | 1085 | int error; /* error return value */ |
|---|
| 1058 | 1086 | int i; /* index */ |
|---|
| 1059 | | - xfs_mount_t *mp; /* filesystem mount point */ |
|---|
| 1060 | 1087 | int needlog; /* need to log block header */ |
|---|
| 1061 | 1088 | int needscan; /* need to scan block freespc */ |
|---|
| 1062 | 1089 | int newoffset; /* offset from current entry */ |
|---|
| 1063 | | - int offset; /* target block offset */ |
|---|
| 1090 | + unsigned int offset = geo->data_entry_offset; |
|---|
| 1064 | 1091 | xfs_dir2_sf_entry_t *sfep; /* sf entry pointer */ |
|---|
| 1065 | 1092 | xfs_dir2_sf_hdr_t *oldsfp; /* old shortform header */ |
|---|
| 1066 | 1093 | xfs_dir2_sf_hdr_t *sfp; /* shortform header */ |
|---|
| 1067 | 1094 | __be16 *tagp; /* end of data entry */ |
|---|
| 1068 | | - xfs_trans_t *tp; /* transaction pointer */ |
|---|
| 1069 | 1095 | struct xfs_name name; |
|---|
| 1070 | | - struct xfs_ifork *ifp; |
|---|
| 1071 | 1096 | |
|---|
| 1072 | 1097 | trace_xfs_dir2_sf_to_block(args); |
|---|
| 1073 | 1098 | |
|---|
| 1074 | | - dp = args->dp; |
|---|
| 1075 | | - tp = args->trans; |
|---|
| 1076 | | - mp = dp->i_mount; |
|---|
| 1077 | | - ifp = XFS_IFORK_PTR(dp, XFS_DATA_FORK); |
|---|
| 1078 | 1099 | ASSERT(ifp->if_flags & XFS_IFINLINE); |
|---|
| 1079 | | - /* |
|---|
| 1080 | | - * Bomb out if the shortform directory is way too short. |
|---|
| 1081 | | - */ |
|---|
| 1082 | | - if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) { |
|---|
| 1083 | | - ASSERT(XFS_FORCED_SHUTDOWN(mp)); |
|---|
| 1084 | | - return -EIO; |
|---|
| 1085 | | - } |
|---|
| 1100 | + ASSERT(dp->i_d.di_size >= offsetof(struct xfs_dir2_sf_hdr, parent)); |
|---|
| 1086 | 1101 | |
|---|
| 1087 | 1102 | oldsfp = (xfs_dir2_sf_hdr_t *)ifp->if_u1.if_data; |
|---|
| 1088 | 1103 | |
|---|
| 1089 | 1104 | ASSERT(ifp->if_bytes == dp->i_d.di_size); |
|---|
| 1090 | 1105 | ASSERT(ifp->if_u1.if_data != NULL); |
|---|
| 1091 | 1106 | ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(oldsfp->i8count)); |
|---|
| 1092 | | - ASSERT(dp->i_d.di_nextents == 0); |
|---|
| 1107 | + ASSERT(dp->i_df.if_nextents == 0); |
|---|
| 1093 | 1108 | |
|---|
| 1094 | 1109 | /* |
|---|
| 1095 | 1110 | * Copy the directory into a temporary buffer. |
|---|
| 1096 | 1111 | * Then pitch the incore inode data so we can make extents. |
|---|
| 1097 | 1112 | */ |
|---|
| 1098 | | - sfp = kmem_alloc(ifp->if_bytes, KM_SLEEP); |
|---|
| 1113 | + sfp = kmem_alloc(ifp->if_bytes, 0); |
|---|
| 1099 | 1114 | memcpy(sfp, oldsfp, ifp->if_bytes); |
|---|
| 1100 | 1115 | |
|---|
| 1101 | 1116 | xfs_idata_realloc(dp, -ifp->if_bytes, XFS_DATA_FORK); |
|---|
| 1102 | | - xfs_bmap_local_to_extents_empty(dp, XFS_DATA_FORK); |
|---|
| 1117 | + xfs_bmap_local_to_extents_empty(tp, dp, XFS_DATA_FORK); |
|---|
| 1103 | 1118 | dp->i_d.di_size = 0; |
|---|
| 1104 | 1119 | |
|---|
| 1105 | 1120 | /* |
|---|
| .. | .. |
|---|
| 1126 | 1141 | * The whole thing is initialized to free by the init routine. |
|---|
| 1127 | 1142 | * Say we're using the leaf and tail area. |
|---|
| 1128 | 1143 | */ |
|---|
| 1129 | | - dup = dp->d_ops->data_unused_p(hdr); |
|---|
| 1144 | + dup = bp->b_addr + offset; |
|---|
| 1130 | 1145 | needlog = needscan = 0; |
|---|
| 1131 | 1146 | error = xfs_dir2_data_use_free(args, bp, dup, args->geo->blksize - i, |
|---|
| 1132 | 1147 | i, &needlog, &needscan); |
|---|
| .. | .. |
|---|
| 1149 | 1164 | be16_to_cpu(dup->length), &needlog, &needscan); |
|---|
| 1150 | 1165 | if (error) |
|---|
| 1151 | 1166 | goto out_free; |
|---|
| 1167 | + |
|---|
| 1152 | 1168 | /* |
|---|
| 1153 | 1169 | * Create entry for . |
|---|
| 1154 | 1170 | */ |
|---|
| 1155 | | - dep = dp->d_ops->data_dot_entry_p(hdr); |
|---|
| 1171 | + dep = bp->b_addr + offset; |
|---|
| 1156 | 1172 | dep->inumber = cpu_to_be64(dp->i_ino); |
|---|
| 1157 | 1173 | dep->namelen = 1; |
|---|
| 1158 | 1174 | dep->name[0] = '.'; |
|---|
| 1159 | | - dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR); |
|---|
| 1160 | | - tagp = dp->d_ops->data_entry_tag_p(dep); |
|---|
| 1161 | | - *tagp = cpu_to_be16((char *)dep - (char *)hdr); |
|---|
| 1175 | + xfs_dir2_data_put_ftype(mp, dep, XFS_DIR3_FT_DIR); |
|---|
| 1176 | + tagp = xfs_dir2_data_entry_tag_p(mp, dep); |
|---|
| 1177 | + *tagp = cpu_to_be16(offset); |
|---|
| 1162 | 1178 | xfs_dir2_data_log_entry(args, bp, dep); |
|---|
| 1163 | 1179 | blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot); |
|---|
| 1164 | | - blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr( |
|---|
| 1165 | | - (char *)dep - (char *)hdr)); |
|---|
| 1180 | + blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(offset)); |
|---|
| 1181 | + offset += xfs_dir2_data_entsize(mp, dep->namelen); |
|---|
| 1182 | + |
|---|
| 1166 | 1183 | /* |
|---|
| 1167 | 1184 | * Create entry for .. |
|---|
| 1168 | 1185 | */ |
|---|
| 1169 | | - dep = dp->d_ops->data_dotdot_entry_p(hdr); |
|---|
| 1170 | | - dep->inumber = cpu_to_be64(dp->d_ops->sf_get_parent_ino(sfp)); |
|---|
| 1186 | + dep = bp->b_addr + offset; |
|---|
| 1187 | + dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp)); |
|---|
| 1171 | 1188 | dep->namelen = 2; |
|---|
| 1172 | 1189 | dep->name[0] = dep->name[1] = '.'; |
|---|
| 1173 | | - dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR); |
|---|
| 1174 | | - tagp = dp->d_ops->data_entry_tag_p(dep); |
|---|
| 1175 | | - *tagp = cpu_to_be16((char *)dep - (char *)hdr); |
|---|
| 1190 | + xfs_dir2_data_put_ftype(mp, dep, XFS_DIR3_FT_DIR); |
|---|
| 1191 | + tagp = xfs_dir2_data_entry_tag_p(mp, dep); |
|---|
| 1192 | + *tagp = cpu_to_be16(offset); |
|---|
| 1176 | 1193 | xfs_dir2_data_log_entry(args, bp, dep); |
|---|
| 1177 | 1194 | blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot); |
|---|
| 1178 | | - blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr( |
|---|
| 1179 | | - (char *)dep - (char *)hdr)); |
|---|
| 1180 | | - offset = dp->d_ops->data_first_offset; |
|---|
| 1195 | + blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(offset)); |
|---|
| 1196 | + offset += xfs_dir2_data_entsize(mp, dep->namelen); |
|---|
| 1197 | + |
|---|
| 1181 | 1198 | /* |
|---|
| 1182 | 1199 | * Loop over existing entries, stuff them in. |
|---|
| 1183 | 1200 | */ |
|---|
| .. | .. |
|---|
| 1186 | 1203 | sfep = NULL; |
|---|
| 1187 | 1204 | else |
|---|
| 1188 | 1205 | sfep = xfs_dir2_sf_firstentry(sfp); |
|---|
| 1206 | + |
|---|
| 1189 | 1207 | /* |
|---|
| 1190 | 1208 | * Need to preserve the existing offset values in the sf directory. |
|---|
| 1191 | 1209 | * Insert holes (unused entries) where necessary. |
|---|
| .. | .. |
|---|
| 1202 | 1220 | * There should be a hole here, make one. |
|---|
| 1203 | 1221 | */ |
|---|
| 1204 | 1222 | if (offset < newoffset) { |
|---|
| 1205 | | - dup = (xfs_dir2_data_unused_t *)((char *)hdr + offset); |
|---|
| 1223 | + dup = bp->b_addr + offset; |
|---|
| 1206 | 1224 | dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); |
|---|
| 1207 | 1225 | dup->length = cpu_to_be16(newoffset - offset); |
|---|
| 1208 | | - *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16( |
|---|
| 1209 | | - ((char *)dup - (char *)hdr)); |
|---|
| 1226 | + *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16(offset); |
|---|
| 1210 | 1227 | xfs_dir2_data_log_unused(args, bp, dup); |
|---|
| 1211 | 1228 | xfs_dir2_data_freeinsert(hdr, |
|---|
| 1212 | | - dp->d_ops->data_bestfree_p(hdr), |
|---|
| 1213 | | - dup, &dummy); |
|---|
| 1229 | + xfs_dir2_data_bestfree_p(mp, hdr), |
|---|
| 1230 | + dup, &dummy); |
|---|
| 1214 | 1231 | offset += be16_to_cpu(dup->length); |
|---|
| 1215 | 1232 | continue; |
|---|
| 1216 | 1233 | } |
|---|
| 1217 | 1234 | /* |
|---|
| 1218 | 1235 | * Copy a real entry. |
|---|
| 1219 | 1236 | */ |
|---|
| 1220 | | - dep = (xfs_dir2_data_entry_t *)((char *)hdr + newoffset); |
|---|
| 1221 | | - dep->inumber = cpu_to_be64(dp->d_ops->sf_get_ino(sfp, sfep)); |
|---|
| 1237 | + dep = bp->b_addr + newoffset; |
|---|
| 1238 | + dep->inumber = cpu_to_be64(xfs_dir2_sf_get_ino(mp, sfp, sfep)); |
|---|
| 1222 | 1239 | dep->namelen = sfep->namelen; |
|---|
| 1223 | | - dp->d_ops->data_put_ftype(dep, dp->d_ops->sf_get_ftype(sfep)); |
|---|
| 1240 | + xfs_dir2_data_put_ftype(mp, dep, |
|---|
| 1241 | + xfs_dir2_sf_get_ftype(mp, sfep)); |
|---|
| 1224 | 1242 | memcpy(dep->name, sfep->name, dep->namelen); |
|---|
| 1225 | | - tagp = dp->d_ops->data_entry_tag_p(dep); |
|---|
| 1226 | | - *tagp = cpu_to_be16((char *)dep - (char *)hdr); |
|---|
| 1243 | + tagp = xfs_dir2_data_entry_tag_p(mp, dep); |
|---|
| 1244 | + *tagp = cpu_to_be16(newoffset); |
|---|
| 1227 | 1245 | xfs_dir2_data_log_entry(args, bp, dep); |
|---|
| 1228 | 1246 | name.name = sfep->name; |
|---|
| 1229 | 1247 | name.len = sfep->namelen; |
|---|
| 1230 | | - blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops-> |
|---|
| 1231 | | - hashname(&name)); |
|---|
| 1232 | | - blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr( |
|---|
| 1233 | | - (char *)dep - (char *)hdr)); |
|---|
| 1248 | + blp[2 + i].hashval = cpu_to_be32(xfs_dir2_hashname(mp, &name)); |
|---|
| 1249 | + blp[2 + i].address = |
|---|
| 1250 | + cpu_to_be32(xfs_dir2_byte_to_dataptr(newoffset)); |
|---|
| 1234 | 1251 | offset = (int)((char *)(tagp + 1) - (char *)hdr); |
|---|
| 1235 | 1252 | if (++i == sfp->count) |
|---|
| 1236 | 1253 | sfep = NULL; |
|---|
| 1237 | 1254 | else |
|---|
| 1238 | | - sfep = dp->d_ops->sf_nextentry(sfp, sfep); |
|---|
| 1255 | + sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); |
|---|
| 1239 | 1256 | } |
|---|
| 1240 | 1257 | /* Done with the temporary buffer */ |
|---|
| 1241 | 1258 | kmem_free(sfp); |
|---|