aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_attr_leaf.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_attr_leaf.c')
-rw-r--r--fs/xfs/xfs_attr_leaf.c352
1 files changed, 0 insertions, 352 deletions
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 90c033e41eb9..fe0ade9a74ba 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -79,16 +79,6 @@ STATIC int xfs_attr3_leaf_figure_balance(xfs_da_state_t *state,
79 int *number_usedbytes_in_blk1); 79 int *number_usedbytes_in_blk1);
80 80
81/* 81/*
82 * Routines used for shrinking the Btree.
83 */
84STATIC int xfs_attr3_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp,
85 struct xfs_buf *bp, int level);
86STATIC int xfs_attr3_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp,
87 struct xfs_buf *bp);
88STATIC int xfs_attr3_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
89 xfs_dablk_t blkno, int blkcnt);
90
91/*
92 * Utility routines. 82 * Utility routines.
93 */ 83 */
94STATIC void xfs_attr3_leaf_moveents(struct xfs_attr_leafblock *src_leaf, 84STATIC void xfs_attr3_leaf_moveents(struct xfs_attr_leafblock *src_leaf,
@@ -2712,345 +2702,3 @@ xfs_attr3_leaf_flipflags(
2712 2702
2713 return error; 2703 return error;
2714} 2704}
2715
2716/*========================================================================
2717 * Indiscriminately delete the entire attribute fork
2718 *========================================================================*/
2719
2720/*
2721 * Recurse (gasp!) through the attribute nodes until we find leaves.
2722 * We're doing a depth-first traversal in order to invalidate everything.
2723 */
2724int
2725xfs_attr3_root_inactive(
2726 struct xfs_trans **trans,
2727 struct xfs_inode *dp)
2728{
2729 struct xfs_da_blkinfo *info;
2730 struct xfs_buf *bp;
2731 xfs_daddr_t blkno;
2732 int error;
2733
2734 /*
2735 * Read block 0 to see what we have to work with.
2736 * We only get here if we have extents, since we remove
2737 * the extents in reverse order the extent containing
2738 * block 0 must still be there.
2739 */
2740 error = xfs_da3_node_read(*trans, dp, 0, -1, &bp, XFS_ATTR_FORK);
2741 if (error)
2742 return error;
2743 blkno = bp->b_bn;
2744
2745 /*
2746 * Invalidate the tree, even if the "tree" is only a single leaf block.
2747 * This is a depth-first traversal!
2748 */
2749 info = bp->b_addr;
2750 switch (info->magic) {
2751 case cpu_to_be16(XFS_DA_NODE_MAGIC):
2752 case cpu_to_be16(XFS_DA3_NODE_MAGIC):
2753 error = xfs_attr3_node_inactive(trans, dp, bp, 1);
2754 break;
2755 case cpu_to_be16(XFS_ATTR_LEAF_MAGIC):
2756 case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC):
2757 error = xfs_attr3_leaf_inactive(trans, dp, bp);
2758 break;
2759 default:
2760 error = XFS_ERROR(EIO);
2761 xfs_trans_brelse(*trans, bp);
2762 break;
2763 }
2764 if (error)
2765 return error;
2766
2767 /*
2768 * Invalidate the incore copy of the root block.
2769 */
2770 error = xfs_da_get_buf(*trans, dp, 0, blkno, &bp, XFS_ATTR_FORK);
2771 if (error)
2772 return error;
2773 xfs_trans_binval(*trans, bp); /* remove from cache */
2774 /*
2775 * Commit the invalidate and start the next transaction.
2776 */
2777 error = xfs_trans_roll(trans, dp);
2778
2779 return error;
2780}
2781
2782/*
2783 * Recurse (gasp!) through the attribute nodes until we find leaves.
2784 * We're doing a depth-first traversal in order to invalidate everything.
2785 */
2786STATIC int
2787xfs_attr3_node_inactive(
2788 struct xfs_trans **trans,
2789 struct xfs_inode *dp,
2790 struct xfs_buf *bp,
2791 int level)
2792{
2793 xfs_da_blkinfo_t *info;
2794 xfs_da_intnode_t *node;
2795 xfs_dablk_t child_fsb;
2796 xfs_daddr_t parent_blkno, child_blkno;
2797 int error, i;
2798 struct xfs_buf *child_bp;
2799 struct xfs_da_node_entry *btree;
2800 struct xfs_da3_icnode_hdr ichdr;
2801
2802 /*
2803 * Since this code is recursive (gasp!) we must protect ourselves.
2804 */
2805 if (level > XFS_DA_NODE_MAXDEPTH) {
2806 xfs_trans_brelse(*trans, bp); /* no locks for later trans */
2807 return XFS_ERROR(EIO);
2808 }
2809
2810 node = bp->b_addr;
2811 xfs_da3_node_hdr_from_disk(&ichdr, node);
2812 parent_blkno = bp->b_bn;
2813 if (!ichdr.count) {
2814 xfs_trans_brelse(*trans, bp);
2815 return 0;
2816 }
2817 btree = xfs_da3_node_tree_p(node);
2818 child_fsb = be32_to_cpu(btree[0].before);
2819 xfs_trans_brelse(*trans, bp); /* no locks for later trans */
2820
2821 /*
2822 * If this is the node level just above the leaves, simply loop
2823 * over the leaves removing all of them. If this is higher up
2824 * in the tree, recurse downward.
2825 */
2826 for (i = 0; i < ichdr.count; i++) {
2827 /*
2828 * Read the subsidiary block to see what we have to work with.
2829 * Don't do this in a transaction. This is a depth-first
2830 * traversal of the tree so we may deal with many blocks
2831 * before we come back to this one.
2832 */
2833 error = xfs_da3_node_read(*trans, dp, child_fsb, -2, &child_bp,
2834 XFS_ATTR_FORK);
2835 if (error)
2836 return(error);
2837 if (child_bp) {
2838 /* save for re-read later */
2839 child_blkno = XFS_BUF_ADDR(child_bp);
2840
2841 /*
2842 * Invalidate the subtree, however we have to.
2843 */
2844 info = child_bp->b_addr;
2845 switch (info->magic) {
2846 case cpu_to_be16(XFS_DA_NODE_MAGIC):
2847 case cpu_to_be16(XFS_DA3_NODE_MAGIC):
2848 error = xfs_attr3_node_inactive(trans, dp,
2849 child_bp, level + 1);
2850 break;
2851 case cpu_to_be16(XFS_ATTR_LEAF_MAGIC):
2852 case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC):
2853 error = xfs_attr3_leaf_inactive(trans, dp,
2854 child_bp);
2855 break;
2856 default:
2857 error = XFS_ERROR(EIO);
2858 xfs_trans_brelse(*trans, child_bp);
2859 break;
2860 }
2861 if (error)
2862 return error;
2863
2864 /*
2865 * Remove the subsidiary block from the cache
2866 * and from the log.
2867 */
2868 error = xfs_da_get_buf(*trans, dp, 0, child_blkno,
2869 &child_bp, XFS_ATTR_FORK);
2870 if (error)
2871 return error;
2872 xfs_trans_binval(*trans, child_bp);
2873 }
2874
2875 /*
2876 * If we're not done, re-read the parent to get the next
2877 * child block number.
2878 */
2879 if (i + 1 < ichdr.count) {
2880 error = xfs_da3_node_read(*trans, dp, 0, parent_blkno,
2881 &bp, XFS_ATTR_FORK);
2882 if (error)
2883 return error;
2884 child_fsb = be32_to_cpu(btree[i + 1].before);
2885 xfs_trans_brelse(*trans, bp);
2886 }
2887 /*
2888 * Atomically commit the whole invalidate stuff.
2889 */
2890 error = xfs_trans_roll(trans, dp);
2891 if (error)
2892 return error;
2893 }
2894
2895 return 0;
2896}
2897
2898/*
2899 * Invalidate all of the "remote" value regions pointed to by a particular
2900 * leaf block.
2901 * Note that we must release the lock on the buffer so that we are not
2902 * caught holding something that the logging code wants to flush to disk.
2903 */
2904STATIC int
2905xfs_attr3_leaf_inactive(
2906 struct xfs_trans **trans,
2907 struct xfs_inode *dp,
2908 struct xfs_buf *bp)
2909{
2910 struct xfs_attr_leafblock *leaf;
2911 struct xfs_attr3_icleaf_hdr ichdr;
2912 struct xfs_attr_leaf_entry *entry;
2913 struct xfs_attr_leaf_name_remote *name_rmt;
2914 struct xfs_attr_inactive_list *list;
2915 struct xfs_attr_inactive_list *lp;
2916 int error;
2917 int count;
2918 int size;
2919 int tmp;
2920 int i;
2921
2922 leaf = bp->b_addr;
2923 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
2924
2925 /*
2926 * Count the number of "remote" value extents.
2927 */
2928 count = 0;
2929 entry = xfs_attr3_leaf_entryp(leaf);
2930 for (i = 0; i < ichdr.count; entry++, i++) {
2931 if (be16_to_cpu(entry->nameidx) &&
2932 ((entry->flags & XFS_ATTR_LOCAL) == 0)) {
2933 name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
2934 if (name_rmt->valueblk)
2935 count++;
2936 }
2937 }
2938
2939 /*
2940 * If there are no "remote" values, we're done.
2941 */
2942 if (count == 0) {
2943 xfs_trans_brelse(*trans, bp);
2944 return 0;
2945 }
2946
2947 /*
2948 * Allocate storage for a list of all the "remote" value extents.
2949 */
2950 size = count * sizeof(xfs_attr_inactive_list_t);
2951 list = kmem_alloc(size, KM_SLEEP);
2952
2953 /*
2954 * Identify each of the "remote" value extents.
2955 */
2956 lp = list;
2957 entry = xfs_attr3_leaf_entryp(leaf);
2958 for (i = 0; i < ichdr.count; entry++, i++) {
2959 if (be16_to_cpu(entry->nameidx) &&
2960 ((entry->flags & XFS_ATTR_LOCAL) == 0)) {
2961 name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
2962 if (name_rmt->valueblk) {
2963 lp->valueblk = be32_to_cpu(name_rmt->valueblk);
2964 lp->valuelen = xfs_attr3_rmt_blocks(dp->i_mount,
2965 be32_to_cpu(name_rmt->valuelen));
2966 lp++;
2967 }
2968 }
2969 }
2970 xfs_trans_brelse(*trans, bp); /* unlock for trans. in freextent() */
2971
2972 /*
2973 * Invalidate each of the "remote" value extents.
2974 */
2975 error = 0;
2976 for (lp = list, i = 0; i < count; i++, lp++) {
2977 tmp = xfs_attr3_leaf_freextent(trans, dp,
2978 lp->valueblk, lp->valuelen);
2979
2980 if (error == 0)
2981 error = tmp; /* save only the 1st errno */
2982 }
2983
2984 kmem_free(list);
2985 return error;
2986}
2987
2988/*
2989 * Look at all the extents for this logical region,
2990 * invalidate any buffers that are incore/in transactions.
2991 */
2992STATIC int
2993xfs_attr3_leaf_freextent(
2994 struct xfs_trans **trans,
2995 struct xfs_inode *dp,
2996 xfs_dablk_t blkno,
2997 int blkcnt)
2998{
2999 struct xfs_bmbt_irec map;
3000 struct xfs_buf *bp;
3001 xfs_dablk_t tblkno;
3002 xfs_daddr_t dblkno;
3003 int tblkcnt;
3004 int dblkcnt;
3005 int nmap;
3006 int error;
3007
3008 /*
3009 * Roll through the "value", invalidating the attribute value's
3010 * blocks.
3011 */
3012 tblkno = blkno;
3013 tblkcnt = blkcnt;
3014 while (tblkcnt > 0) {
3015 /*
3016 * Try to remember where we decided to put the value.
3017 */
3018 nmap = 1;
3019 error = xfs_bmapi_read(dp, (xfs_fileoff_t)tblkno, tblkcnt,
3020 &map, &nmap, XFS_BMAPI_ATTRFORK);
3021 if (error) {
3022 return(error);
3023 }
3024 ASSERT(nmap == 1);
3025 ASSERT(map.br_startblock != DELAYSTARTBLOCK);
3026
3027 /*
3028 * If it's a hole, these are already unmapped
3029 * so there's nothing to invalidate.
3030 */
3031 if (map.br_startblock != HOLESTARTBLOCK) {
3032
3033 dblkno = XFS_FSB_TO_DADDR(dp->i_mount,
3034 map.br_startblock);
3035 dblkcnt = XFS_FSB_TO_BB(dp->i_mount,
3036 map.br_blockcount);
3037 bp = xfs_trans_get_buf(*trans,
3038 dp->i_mount->m_ddev_targp,
3039 dblkno, dblkcnt, 0);
3040 if (!bp)
3041 return ENOMEM;
3042 xfs_trans_binval(*trans, bp);
3043 /*
3044 * Roll to next transaction.
3045 */
3046 error = xfs_trans_roll(trans, dp);
3047 if (error)
3048 return (error);
3049 }
3050
3051 tblkno += map.br_blockcount;
3052 tblkcnt -= map.br_blockcount;
3053 }
3054
3055 return(0);
3056}