aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
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.