aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2012-11-12 06:54:16 -0500
committerBen Myers <bpm@sgi.com>2012-11-15 22:34:52 -0500
commitad14c33ac862601c4c22755ed3b59f1906b134e5 (patch)
tree80d2fe31b0db8c0f763080ca69902cf903764da9 /fs/xfs
parente6f7667c4eef42b6f5bc6cdeb31d0bab62fe5f79 (diff)
xfs: factor and verify attr leaf reads
Some reads are not converted yet because it isn't obvious ahead of time what the format of the block is going to be. Need to determine how to tell if the first block in the tree is a node or leaf format block. That will be done in later patches. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Phil White <pwhite@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_attr.c70
-rw-r--r--fs/xfs/xfs_attr_leaf.c78
-rw-r--r--fs/xfs/xfs_attr_leaf.h3
3 files changed, 66 insertions, 85 deletions
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index cd5a9cd0ded0..d644915367e3 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -903,11 +903,9 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
903 */ 903 */
904 dp = args->dp; 904 dp = args->dp;
905 args->blkno = 0; 905 args->blkno = 0;
906 error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, 906 error = xfs_attr_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
907 XFS_ATTR_FORK, NULL);
908 if (error) 907 if (error)
909 return(error); 908 return error;
910 ASSERT(bp != NULL);
911 909
912 /* 910 /*
913 * Look up the given attribute in the leaf block. Figure out if 911 * Look up the given attribute in the leaf block. Figure out if
@@ -1031,12 +1029,12 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
1031 * Read in the block containing the "old" attr, then 1029 * Read in the block containing the "old" attr, then
1032 * remove the "old" attr from that block (neat, huh!) 1030 * remove the "old" attr from that block (neat, huh!)
1033 */ 1031 */
1034 error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, 1032 error = xfs_attr_leaf_read(args->trans, args->dp, args->blkno,
1035 &bp, XFS_ATTR_FORK, NULL); 1033 -1, &bp);
1036 if (error) 1034 if (error)
1037 return(error); 1035 return error;
1038 ASSERT(bp != NULL); 1036
1039 (void)xfs_attr_leaf_remove(bp, args); 1037 xfs_attr_leaf_remove(bp, args);
1040 1038
1041 /* 1039 /*
1042 * If the result is small enough, shrink it all into the inode. 1040 * If the result is small enough, shrink it all into the inode.
@@ -1100,20 +1098,17 @@ xfs_attr_leaf_removename(xfs_da_args_t *args)
1100 */ 1098 */
1101 dp = args->dp; 1099 dp = args->dp;
1102 args->blkno = 0; 1100 args->blkno = 0;
1103 error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, 1101 error = xfs_attr_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
1104 XFS_ATTR_FORK, NULL); 1102 if (error)
1105 if (error) { 1103 return error;
1106 return(error);
1107 }
1108 1104
1109 ASSERT(bp != NULL);
1110 error = xfs_attr_leaf_lookup_int(bp, args); 1105 error = xfs_attr_leaf_lookup_int(bp, args);
1111 if (error == ENOATTR) { 1106 if (error == ENOATTR) {
1112 xfs_trans_brelse(args->trans, bp); 1107 xfs_trans_brelse(args->trans, bp);
1113 return(error); 1108 return(error);
1114 } 1109 }
1115 1110
1116 (void)xfs_attr_leaf_remove(bp, args); 1111 xfs_attr_leaf_remove(bp, args);
1117 1112
1118 /* 1113 /*
1119 * If the result is small enough, shrink it all into the inode. 1114 * If the result is small enough, shrink it all into the inode.
@@ -1158,11 +1153,9 @@ xfs_attr_leaf_get(xfs_da_args_t *args)
1158 trace_xfs_attr_leaf_get(args); 1153 trace_xfs_attr_leaf_get(args);
1159 1154
1160 args->blkno = 0; 1155 args->blkno = 0;
1161 error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, 1156 error = xfs_attr_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
1162 XFS_ATTR_FORK, NULL);
1163 if (error) 1157 if (error)
1164 return(error); 1158 return error;
1165 ASSERT(bp != NULL);
1166 1159
1167 error = xfs_attr_leaf_lookup_int(bp, args); 1160 error = xfs_attr_leaf_lookup_int(bp, args);
1168 if (error != EEXIST) { 1161 if (error != EEXIST) {
@@ -1183,25 +1176,15 @@ xfs_attr_leaf_get(xfs_da_args_t *args)
1183STATIC int 1176STATIC int
1184xfs_attr_leaf_list(xfs_attr_list_context_t *context) 1177xfs_attr_leaf_list(xfs_attr_list_context_t *context)
1185{ 1178{
1186 xfs_attr_leafblock_t *leaf;
1187 int error; 1179 int error;
1188 struct xfs_buf *bp; 1180 struct xfs_buf *bp;
1189 1181
1190 trace_xfs_attr_leaf_list(context); 1182 trace_xfs_attr_leaf_list(context);
1191 1183
1192 context->cursor->blkno = 0; 1184 context->cursor->blkno = 0;
1193 error = xfs_da_read_buf(NULL, context->dp, 0, -1, &bp, XFS_ATTR_FORK, 1185 error = xfs_attr_leaf_read(NULL, context->dp, 0, -1, &bp);
1194 NULL);
1195 if (error) 1186 if (error)
1196 return XFS_ERROR(error); 1187 return XFS_ERROR(error);
1197 ASSERT(bp != NULL);
1198 leaf = bp->b_addr;
1199 if (unlikely(leaf->hdr.info.magic != cpu_to_be16(XFS_ATTR_LEAF_MAGIC))) {
1200 XFS_CORRUPTION_ERROR("xfs_attr_leaf_list", XFS_ERRLEVEL_LOW,
1201 context->dp->i_mount, leaf);
1202 xfs_trans_brelse(NULL, bp);
1203 return XFS_ERROR(EFSCORRUPTED);
1204 }
1205 1188
1206 error = xfs_attr_leaf_list_int(bp, context); 1189 error = xfs_attr_leaf_list_int(bp, context);
1207 xfs_trans_brelse(NULL, bp); 1190 xfs_trans_brelse(NULL, bp);
@@ -1605,12 +1588,9 @@ xfs_attr_node_removename(xfs_da_args_t *args)
1605 ASSERT(state->path.blk[0].bp); 1588 ASSERT(state->path.blk[0].bp);
1606 state->path.blk[0].bp = NULL; 1589 state->path.blk[0].bp = NULL;
1607 1590
1608 error = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, 1591 error = xfs_attr_leaf_read(args->trans, args->dp, 0, -1, &bp);
1609 XFS_ATTR_FORK, NULL);
1610 if (error) 1592 if (error)
1611 goto out; 1593 goto out;
1612 ASSERT((((xfs_attr_leafblock_t *)bp->b_addr)->hdr.info.magic) ==
1613 cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
1614 1594
1615 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { 1595 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
1616 xfs_bmap_init(args->flist, args->firstblock); 1596 xfs_bmap_init(args->flist, args->firstblock);
@@ -1920,14 +1900,6 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
1920 */ 1900 */
1921 for (;;) { 1901 for (;;) {
1922 leaf = bp->b_addr; 1902 leaf = bp->b_addr;
1923 if (unlikely(leaf->hdr.info.magic !=
1924 cpu_to_be16(XFS_ATTR_LEAF_MAGIC))) {
1925 XFS_CORRUPTION_ERROR("xfs_attr_node_list(4)",
1926 XFS_ERRLEVEL_LOW,
1927 context->dp->i_mount, leaf);
1928 xfs_trans_brelse(NULL, bp);
1929 return(XFS_ERROR(EFSCORRUPTED));
1930 }
1931 error = xfs_attr_leaf_list_int(bp, context); 1903 error = xfs_attr_leaf_list_int(bp, context);
1932 if (error) { 1904 if (error) {
1933 xfs_trans_brelse(NULL, bp); 1905 xfs_trans_brelse(NULL, bp);
@@ -1937,16 +1909,10 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
1937 break; 1909 break;
1938 cursor->blkno = be32_to_cpu(leaf->hdr.info.forw); 1910 cursor->blkno = be32_to_cpu(leaf->hdr.info.forw);
1939 xfs_trans_brelse(NULL, bp); 1911 xfs_trans_brelse(NULL, bp);
1940 error = xfs_da_read_buf(NULL, context->dp, cursor->blkno, -1, 1912 error = xfs_attr_leaf_read(NULL, context->dp, cursor->blkno, -1,
1941 &bp, XFS_ATTR_FORK, NULL); 1913 &bp);
1942 if (error) 1914 if (error)
1943 return(error); 1915 return error;
1944 if (unlikely((bp == NULL))) {
1945 XFS_ERROR_REPORT("xfs_attr_node_list(5)",
1946 XFS_ERRLEVEL_LOW,
1947 context->dp->i_mount);
1948 return(XFS_ERROR(EFSCORRUPTED));
1949 }
1950 } 1916 }
1951 xfs_trans_brelse(NULL, bp); 1917 xfs_trans_brelse(NULL, bp);
1952 return(0); 1918 return(0);
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index ba2b9a2cd236..357971536d50 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -88,6 +88,36 @@ STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf,
88 xfs_mount_t *mp); 88 xfs_mount_t *mp);
89STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); 89STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
90 90
91static void
92xfs_attr_leaf_verify(
93 struct xfs_buf *bp)
94{
95 struct xfs_mount *mp = bp->b_target->bt_mount;
96 struct xfs_attr_leaf_hdr *hdr = bp->b_addr;
97 int block_ok = 0;
98
99 block_ok = hdr->info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC);
100 if (!block_ok) {
101 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, hdr);
102 xfs_buf_ioerror(bp, EFSCORRUPTED);
103 }
104
105 bp->b_iodone = NULL;
106 xfs_buf_ioend(bp, 0);
107}
108
109int
110xfs_attr_leaf_read(
111 struct xfs_trans *tp,
112 struct xfs_inode *dp,
113 xfs_dablk_t bno,
114 xfs_daddr_t mappedbno,
115 struct xfs_buf **bpp)
116{
117 return xfs_da_read_buf(tp, dp, bno, mappedbno, bpp,
118 XFS_ATTR_FORK, xfs_attr_leaf_verify);
119}
120
91/*======================================================================== 121/*========================================================================
92 * Namespace helper routines 122 * Namespace helper routines
93 *========================================================================*/ 123 *========================================================================*/
@@ -870,11 +900,10 @@ xfs_attr_leaf_to_node(xfs_da_args_t *args)
870 error = xfs_da_grow_inode(args, &blkno); 900 error = xfs_da_grow_inode(args, &blkno);
871 if (error) 901 if (error)
872 goto out; 902 goto out;
873 error = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp1, 903 error = xfs_attr_leaf_read(args->trans, args->dp, 0, -1, &bp1);
874 XFS_ATTR_FORK, NULL);
875 if (error) 904 if (error)
876 goto out; 905 goto out;
877 ASSERT(bp1 != NULL); 906
878 bp2 = NULL; 907 bp2 = NULL;
879 error = xfs_da_get_buf(args->trans, args->dp, blkno, -1, &bp2, 908 error = xfs_da_get_buf(args->trans, args->dp, blkno, -1, &bp2,
880 XFS_ATTR_FORK); 909 XFS_ATTR_FORK);
@@ -1641,18 +1670,16 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action)
1641 blkno = be32_to_cpu(info->back); 1670 blkno = be32_to_cpu(info->back);
1642 if (blkno == 0) 1671 if (blkno == 0)
1643 continue; 1672 continue;
1644 error = xfs_da_read_buf(state->args->trans, state->args->dp, 1673 error = xfs_attr_leaf_read(state->args->trans, state->args->dp,
1645 blkno, -1, &bp, XFS_ATTR_FORK, NULL); 1674 blkno, -1, &bp);
1646 if (error) 1675 if (error)
1647 return(error); 1676 return(error);
1648 ASSERT(bp != NULL);
1649 1677
1650 leaf = (xfs_attr_leafblock_t *)info; 1678 leaf = (xfs_attr_leafblock_t *)info;
1651 count = be16_to_cpu(leaf->hdr.count); 1679 count = be16_to_cpu(leaf->hdr.count);
1652 bytes = state->blocksize - (state->blocksize>>2); 1680 bytes = state->blocksize - (state->blocksize>>2);
1653 bytes -= be16_to_cpu(leaf->hdr.usedbytes); 1681 bytes -= be16_to_cpu(leaf->hdr.usedbytes);
1654 leaf = bp->b_addr; 1682 leaf = bp->b_addr;
1655 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
1656 count += be16_to_cpu(leaf->hdr.count); 1683 count += be16_to_cpu(leaf->hdr.count);
1657 bytes -= be16_to_cpu(leaf->hdr.usedbytes); 1684 bytes -= be16_to_cpu(leaf->hdr.usedbytes);
1658 bytes -= count * sizeof(xfs_attr_leaf_entry_t); 1685 bytes -= count * sizeof(xfs_attr_leaf_entry_t);
@@ -2518,15 +2545,11 @@ xfs_attr_leaf_clearflag(xfs_da_args_t *args)
2518 /* 2545 /*
2519 * Set up the operation. 2546 * Set up the operation.
2520 */ 2547 */
2521 error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, 2548 error = xfs_attr_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
2522 XFS_ATTR_FORK, NULL); 2549 if (error)
2523 if (error) {
2524 return(error); 2550 return(error);
2525 }
2526 ASSERT(bp != NULL);
2527 2551
2528 leaf = bp->b_addr; 2552 leaf = bp->b_addr;
2529 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
2530 ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); 2553 ASSERT(args->index < be16_to_cpu(leaf->hdr.count));
2531 ASSERT(args->index >= 0); 2554 ASSERT(args->index >= 0);
2532 entry = &leaf->entries[ args->index ]; 2555 entry = &leaf->entries[ args->index ];
@@ -2583,15 +2606,11 @@ xfs_attr_leaf_setflag(xfs_da_args_t *args)
2583 /* 2606 /*
2584 * Set up the operation. 2607 * Set up the operation.
2585 */ 2608 */
2586 error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp, 2609 error = xfs_attr_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
2587 XFS_ATTR_FORK, NULL); 2610 if (error)
2588 if (error) {
2589 return(error); 2611 return(error);
2590 }
2591 ASSERT(bp != NULL);
2592 2612
2593 leaf = bp->b_addr; 2613 leaf = bp->b_addr;
2594 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
2595 ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); 2614 ASSERT(args->index < be16_to_cpu(leaf->hdr.count));
2596 ASSERT(args->index >= 0); 2615 ASSERT(args->index >= 0);
2597 entry = &leaf->entries[ args->index ]; 2616 entry = &leaf->entries[ args->index ];
@@ -2640,35 +2659,28 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args)
2640 /* 2659 /*
2641 * Read the block containing the "old" attr 2660 * Read the block containing the "old" attr
2642 */ 2661 */
2643 error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp1, 2662 error = xfs_attr_leaf_read(args->trans, args->dp, args->blkno, -1, &bp1);
2644 XFS_ATTR_FORK, NULL); 2663 if (error)
2645 if (error) { 2664 return error;
2646 return(error);
2647 }
2648 ASSERT(bp1 != NULL);
2649 2665
2650 /* 2666 /*
2651 * Read the block containing the "new" attr, if it is different 2667 * Read the block containing the "new" attr, if it is different
2652 */ 2668 */
2653 if (args->blkno2 != args->blkno) { 2669 if (args->blkno2 != args->blkno) {
2654 error = xfs_da_read_buf(args->trans, args->dp, args->blkno2, 2670 error = xfs_attr_leaf_read(args->trans, args->dp, args->blkno2,
2655 -1, &bp2, XFS_ATTR_FORK, NULL); 2671 -1, &bp2);
2656 if (error) { 2672 if (error)
2657 return(error); 2673 return error;
2658 }
2659 ASSERT(bp2 != NULL);
2660 } else { 2674 } else {
2661 bp2 = bp1; 2675 bp2 = bp1;
2662 } 2676 }
2663 2677
2664 leaf1 = bp1->b_addr; 2678 leaf1 = bp1->b_addr;
2665 ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
2666 ASSERT(args->index < be16_to_cpu(leaf1->hdr.count)); 2679 ASSERT(args->index < be16_to_cpu(leaf1->hdr.count));
2667 ASSERT(args->index >= 0); 2680 ASSERT(args->index >= 0);
2668 entry1 = &leaf1->entries[ args->index ]; 2681 entry1 = &leaf1->entries[ args->index ];
2669 2682
2670 leaf2 = bp2->b_addr; 2683 leaf2 = bp2->b_addr;
2671 ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
2672 ASSERT(args->index2 < be16_to_cpu(leaf2->hdr.count)); 2684 ASSERT(args->index2 < be16_to_cpu(leaf2->hdr.count));
2673 ASSERT(args->index2 >= 0); 2685 ASSERT(args->index2 >= 0);
2674 entry2 = &leaf2->entries[ args->index2 ]; 2686 entry2 = &leaf2->entries[ args->index2 ];
diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h
index dea17722945e..8f7ab986f45d 100644
--- a/fs/xfs/xfs_attr_leaf.h
+++ b/fs/xfs/xfs_attr_leaf.h
@@ -227,6 +227,9 @@ int xfs_attr_leaf_to_shortform(struct xfs_buf *bp,
227int xfs_attr_leaf_clearflag(struct xfs_da_args *args); 227int xfs_attr_leaf_clearflag(struct xfs_da_args *args);
228int xfs_attr_leaf_setflag(struct xfs_da_args *args); 228int xfs_attr_leaf_setflag(struct xfs_da_args *args);
229int xfs_attr_leaf_flipflags(xfs_da_args_t *args); 229int xfs_attr_leaf_flipflags(xfs_da_args_t *args);
230int xfs_attr_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp,
231 xfs_dablk_t bno, xfs_daddr_t mappedbno,
232 struct xfs_buf **bpp);
230 233
231/* 234/*
232 * Routines used for growing the Btree. 235 * Routines used for growing the Btree.