.. | .. |
---|
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); |
---|