Commit 3605431fb9739a30ccd0c6380ae8e3c6f8e670a5
Committed by
Ben Myers
1 parent
372cc85ec6
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
xfs: use discontiguous xfs_buf support in dabuf wrappers
First step in converting the directory code to use native discontiguous buffers and replacing the dabuf construct. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ben Myers <bpm@sgi.com>
Showing 2 changed files with 239 additions and 305 deletions Side-by-side Diff
fs/xfs/xfs_da_btree.c
... | ... | @@ -85,7 +85,7 @@ |
85 | 85 | */ |
86 | 86 | STATIC uint xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count); |
87 | 87 | STATIC int xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp); |
88 | -STATIC xfs_dabuf_t *xfs_da_buf_make(int nbuf, xfs_buf_t **bps); | |
88 | +STATIC xfs_dabuf_t *xfs_da_buf_make(xfs_buf_t *bp); | |
89 | 89 | STATIC int xfs_da_blk_unlink(xfs_da_state_t *state, |
90 | 90 | xfs_da_state_blk_t *drop_blk, |
91 | 91 | xfs_da_state_blk_t *save_blk); |
92 | 92 | |
93 | 93 | |
94 | 94 | |
95 | 95 | |
... | ... | @@ -1967,35 +1967,75 @@ |
1967 | 1967 | } |
1968 | 1968 | |
1969 | 1969 | /* |
1970 | - * Make a dabuf. | |
1971 | - * Used for get_buf, read_buf, read_bufr, and reada_buf. | |
1970 | + * Convert a struct xfs_bmbt_irec to a struct xfs_buf_map. | |
1971 | + * | |
1972 | + * For the single map case, it is assumed that the caller has provided a pointer | |
1973 | + * to a valid xfs_buf_map. For the multiple map case, this function will | |
1974 | + * allocate the xfs_buf_map to hold all the maps and replace the caller's single | |
1975 | + * map pointer with the allocated map. | |
1972 | 1976 | */ |
1973 | -STATIC int | |
1974 | -xfs_da_do_buf( | |
1975 | - xfs_trans_t *trans, | |
1976 | - xfs_inode_t *dp, | |
1977 | - xfs_dablk_t bno, | |
1978 | - xfs_daddr_t *mappedbnop, | |
1979 | - xfs_dabuf_t **bpp, | |
1980 | - int whichfork, | |
1981 | - int caller) | |
1977 | +static int | |
1978 | +xfs_buf_map_from_irec( | |
1979 | + struct xfs_mount *mp, | |
1980 | + struct xfs_buf_map **mapp, | |
1981 | + unsigned int *nmaps, | |
1982 | + struct xfs_bmbt_irec *irecs, | |
1983 | + unsigned int nirecs) | |
1982 | 1984 | { |
1983 | - xfs_buf_t *bp = NULL; | |
1984 | - xfs_buf_t **bplist; | |
1985 | - int error=0; | |
1986 | - int i; | |
1987 | - xfs_bmbt_irec_t map; | |
1988 | - xfs_bmbt_irec_t *mapp; | |
1989 | - xfs_daddr_t mappedbno; | |
1990 | - xfs_mount_t *mp; | |
1991 | - int nbplist=0; | |
1992 | - int nfsb; | |
1993 | - int nmap; | |
1994 | - xfs_dabuf_t *rbp; | |
1985 | + struct xfs_buf_map *map; | |
1986 | + int i; | |
1995 | 1987 | |
1996 | - mp = dp->i_mount; | |
1988 | + ASSERT(*nmaps == 1); | |
1989 | + ASSERT(nirecs >= 1); | |
1990 | + | |
1991 | + if (nirecs > 1) { | |
1992 | + map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map), KM_SLEEP); | |
1993 | + if (!map) | |
1994 | + return ENOMEM; | |
1995 | + *mapp = map; | |
1996 | + } | |
1997 | + | |
1998 | + *nmaps = nirecs; | |
1999 | + map = *mapp; | |
2000 | + for (i = 0; i < *nmaps; i++) { | |
2001 | + ASSERT(irecs[i].br_startblock != DELAYSTARTBLOCK && | |
2002 | + irecs[i].br_startblock != HOLESTARTBLOCK); | |
2003 | + map[i].bm_bn = XFS_FSB_TO_DADDR(mp, irecs[i].br_startblock); | |
2004 | + map[i].bm_len = XFS_FSB_TO_BB(mp, irecs[i].br_blockcount); | |
2005 | + } | |
2006 | + return 0; | |
2007 | +} | |
2008 | + | |
2009 | +/* | |
2010 | + * Map the block we are given ready for reading. There are three possible return | |
2011 | + * values: | |
2012 | + * -1 - will be returned if we land in a hole and mappedbno == -2 so the | |
2013 | + * caller knows not to execute a subsequent read. | |
2014 | + * 0 - if we mapped the block successfully | |
2015 | + * >0 - positive error number if there was an error. | |
2016 | + */ | |
2017 | +static int | |
2018 | +xfs_dabuf_map( | |
2019 | + struct xfs_trans *trans, | |
2020 | + struct xfs_inode *dp, | |
2021 | + xfs_dablk_t bno, | |
2022 | + xfs_daddr_t mappedbno, | |
2023 | + int whichfork, | |
2024 | + struct xfs_buf_map **map, | |
2025 | + int *nmaps) | |
2026 | +{ | |
2027 | + struct xfs_mount *mp = dp->i_mount; | |
2028 | + int nfsb; | |
2029 | + int error = 0; | |
2030 | + struct xfs_bmbt_irec irec; | |
2031 | + struct xfs_bmbt_irec *irecs = &irec; | |
2032 | + int nirecs; | |
2033 | + | |
2034 | + ASSERT(map && *map); | |
2035 | + ASSERT(*nmaps == 1); | |
2036 | + | |
1997 | 2037 | nfsb = (whichfork == XFS_DATA_FORK) ? mp->m_dirblkfsbs : 1; |
1998 | - mappedbno = *mappedbnop; | |
2038 | + | |
1999 | 2039 | /* |
2000 | 2040 | * Caller doesn't have a mapping. -2 means don't complain |
2001 | 2041 | * if we land in a hole. |
2002 | 2042 | |
2003 | 2043 | |
2004 | 2044 | |
2005 | 2045 | |
2006 | 2046 | |
2007 | 2047 | |
2008 | 2048 | |
2009 | 2049 | |
2010 | 2050 | |
2011 | 2051 | |
2012 | 2052 | |
2013 | 2053 | |
2014 | 2054 | |
2015 | 2055 | |
2016 | 2056 | |
2017 | 2057 | |
... | ... | @@ -2004,112 +2044,152 @@ |
2004 | 2044 | /* |
2005 | 2045 | * Optimize the one-block case. |
2006 | 2046 | */ |
2007 | - if (nfsb == 1) | |
2008 | - mapp = ↦ | |
2009 | - else | |
2010 | - mapp = kmem_alloc(sizeof(*mapp) * nfsb, KM_SLEEP); | |
2047 | + if (nfsb != 1) | |
2048 | + irecs = kmem_zalloc(sizeof(irec) * nfsb, KM_SLEEP); | |
2011 | 2049 | |
2012 | - nmap = nfsb; | |
2013 | - error = xfs_bmapi_read(dp, (xfs_fileoff_t)bno, nfsb, mapp, | |
2014 | - &nmap, xfs_bmapi_aflag(whichfork)); | |
2050 | + nirecs = nfsb; | |
2051 | + error = xfs_bmapi_read(dp, (xfs_fileoff_t)bno, nfsb, irecs, | |
2052 | + &nirecs, xfs_bmapi_aflag(whichfork)); | |
2015 | 2053 | if (error) |
2016 | - goto exit0; | |
2054 | + goto out; | |
2017 | 2055 | } else { |
2018 | - map.br_startblock = XFS_DADDR_TO_FSB(mp, mappedbno); | |
2019 | - map.br_startoff = (xfs_fileoff_t)bno; | |
2020 | - map.br_blockcount = nfsb; | |
2021 | - mapp = ↦ | |
2022 | - nmap = 1; | |
2056 | + irecs->br_startblock = XFS_DADDR_TO_FSB(mp, mappedbno); | |
2057 | + irecs->br_startoff = (xfs_fileoff_t)bno; | |
2058 | + irecs->br_blockcount = nfsb; | |
2059 | + irecs->br_state = 0; | |
2060 | + nirecs = 1; | |
2023 | 2061 | } |
2024 | - if (!xfs_da_map_covers_blocks(nmap, mapp, bno, nfsb)) { | |
2025 | - error = mappedbno == -2 ? 0 : XFS_ERROR(EFSCORRUPTED); | |
2062 | + | |
2063 | + if (!xfs_da_map_covers_blocks(nirecs, irecs, bno, nfsb)) { | |
2064 | + error = mappedbno == -2 ? -1 : XFS_ERROR(EFSCORRUPTED); | |
2026 | 2065 | if (unlikely(error == EFSCORRUPTED)) { |
2027 | 2066 | if (xfs_error_level >= XFS_ERRLEVEL_LOW) { |
2067 | + int i; | |
2028 | 2068 | xfs_alert(mp, "%s: bno %lld dir: inode %lld", |
2029 | 2069 | __func__, (long long)bno, |
2030 | 2070 | (long long)dp->i_ino); |
2031 | - for (i = 0; i < nmap; i++) { | |
2071 | + for (i = 0; i < *nmaps; i++) { | |
2032 | 2072 | xfs_alert(mp, |
2033 | 2073 | "[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d", |
2034 | 2074 | i, |
2035 | - (long long)mapp[i].br_startoff, | |
2036 | - (long long)mapp[i].br_startblock, | |
2037 | - (long long)mapp[i].br_blockcount, | |
2038 | - mapp[i].br_state); | |
2075 | + (long long)irecs[i].br_startoff, | |
2076 | + (long long)irecs[i].br_startblock, | |
2077 | + (long long)irecs[i].br_blockcount, | |
2078 | + irecs[i].br_state); | |
2039 | 2079 | } |
2040 | 2080 | } |
2041 | 2081 | XFS_ERROR_REPORT("xfs_da_do_buf(1)", |
2042 | 2082 | XFS_ERRLEVEL_LOW, mp); |
2043 | 2083 | } |
2044 | - goto exit0; | |
2084 | + goto out; | |
2045 | 2085 | } |
2046 | - if (caller != 3 && nmap > 1) { | |
2047 | - bplist = kmem_alloc(sizeof(*bplist) * nmap, KM_SLEEP); | |
2048 | - nbplist = 0; | |
2049 | - } else | |
2050 | - bplist = NULL; | |
2051 | - /* | |
2052 | - * Turn the mapping(s) into buffer(s). | |
2053 | - */ | |
2054 | - for (i = 0; i < nmap; i++) { | |
2055 | - int nmapped; | |
2086 | + error = xfs_buf_map_from_irec(mp, map, nmaps, irecs, nirecs); | |
2087 | +out: | |
2088 | + if (irecs != &irec) | |
2089 | + kmem_free(irecs); | |
2090 | + return error; | |
2091 | +} | |
2056 | 2092 | |
2057 | - mappedbno = XFS_FSB_TO_DADDR(mp, mapp[i].br_startblock); | |
2058 | - if (i == 0) | |
2059 | - *mappedbnop = mappedbno; | |
2060 | - nmapped = (int)XFS_FSB_TO_BB(mp, mapp[i].br_blockcount); | |
2061 | - switch (caller) { | |
2062 | - case 0: | |
2063 | - bp = xfs_trans_get_buf(trans, mp->m_ddev_targp, | |
2064 | - mappedbno, nmapped, 0); | |
2065 | - error = bp ? bp->b_error : XFS_ERROR(EIO); | |
2066 | - break; | |
2067 | - case 1: | |
2068 | - case 2: | |
2069 | - bp = NULL; | |
2070 | - error = xfs_trans_read_buf(mp, trans, mp->m_ddev_targp, | |
2071 | - mappedbno, nmapped, 0, &bp); | |
2072 | - break; | |
2073 | - case 3: | |
2074 | - xfs_buf_readahead(mp->m_ddev_targp, mappedbno, nmapped); | |
2093 | +/* | |
2094 | + * Get a buffer for the dir/attr block. | |
2095 | + */ | |
2096 | +int | |
2097 | +xfs_da_get_buf( | |
2098 | + struct xfs_trans *trans, | |
2099 | + struct xfs_inode *dp, | |
2100 | + xfs_dablk_t bno, | |
2101 | + xfs_daddr_t mappedbno, | |
2102 | + xfs_dabuf_t **bpp, | |
2103 | + int whichfork) | |
2104 | +{ | |
2105 | + struct xfs_buf *bp; | |
2106 | + struct xfs_buf_map map; | |
2107 | + struct xfs_buf_map *mapp; | |
2108 | + int nmap; | |
2109 | + int error; | |
2110 | + | |
2111 | + *bpp = NULL; | |
2112 | + mapp = ↦ | |
2113 | + nmap = 1; | |
2114 | + error = xfs_dabuf_map(trans, dp, bno, mappedbno, whichfork, | |
2115 | + &mapp, &nmap); | |
2116 | + if (error) { | |
2117 | + /* mapping a hole is not an error, but we don't continue */ | |
2118 | + if (error == -1) | |
2075 | 2119 | error = 0; |
2076 | - bp = NULL; | |
2077 | - break; | |
2078 | - } | |
2079 | - if (error) { | |
2080 | - if (bp) | |
2081 | - xfs_trans_brelse(trans, bp); | |
2082 | - goto exit1; | |
2083 | - } | |
2084 | - if (!bp) | |
2085 | - continue; | |
2086 | - if (caller == 1) { | |
2087 | - if (whichfork == XFS_ATTR_FORK) | |
2088 | - xfs_buf_set_ref(bp, XFS_ATTR_BTREE_REF); | |
2089 | - else | |
2090 | - xfs_buf_set_ref(bp, XFS_DIR_BTREE_REF); | |
2091 | - } | |
2092 | - if (bplist) { | |
2093 | - bplist[nbplist++] = bp; | |
2094 | - } | |
2120 | + goto out_free; | |
2095 | 2121 | } |
2096 | - /* | |
2097 | - * Build a dabuf structure. | |
2098 | - */ | |
2099 | - if (bplist) { | |
2100 | - rbp = xfs_da_buf_make(nbplist, bplist); | |
2101 | - } else if (bp) | |
2102 | - rbp = xfs_da_buf_make(1, &bp); | |
2122 | + | |
2123 | + bp = xfs_trans_get_buf_map(trans, dp->i_mount->m_ddev_targp, | |
2124 | + mapp, nmap, 0); | |
2125 | + error = bp ? bp->b_error : XFS_ERROR(EIO); | |
2126 | + if (error) { | |
2127 | + xfs_trans_brelse(trans, bp); | |
2128 | + goto out_free; | |
2129 | + } | |
2130 | + | |
2131 | + *bpp = xfs_da_buf_make(bp); | |
2132 | + | |
2133 | +out_free: | |
2134 | + if (mapp != &map) | |
2135 | + kmem_free(mapp); | |
2136 | + | |
2137 | + return error; | |
2138 | +} | |
2139 | + | |
2140 | +/* | |
2141 | + * Get a buffer for the dir/attr block, fill in the contents. | |
2142 | + */ | |
2143 | +int | |
2144 | +xfs_da_read_buf( | |
2145 | + struct xfs_trans *trans, | |
2146 | + struct xfs_inode *dp, | |
2147 | + xfs_dablk_t bno, | |
2148 | + xfs_daddr_t mappedbno, | |
2149 | + xfs_dabuf_t **bpp, | |
2150 | + int whichfork) | |
2151 | +{ | |
2152 | + struct xfs_buf *bp; | |
2153 | + struct xfs_buf_map map; | |
2154 | + struct xfs_buf_map *mapp; | |
2155 | + int nmap; | |
2156 | + int error; | |
2157 | + | |
2158 | + *bpp = NULL; | |
2159 | + mapp = ↦ | |
2160 | + nmap = 1; | |
2161 | + error = xfs_dabuf_map(trans, dp, bno, mappedbno, whichfork, | |
2162 | + &mapp, &nmap); | |
2163 | + if (error) { | |
2164 | + /* mapping a hole is not an error, but we don't continue */ | |
2165 | + if (error == -1) | |
2166 | + error = 0; | |
2167 | + goto out_free; | |
2168 | + } | |
2169 | + | |
2170 | + error = xfs_trans_read_buf_map(dp->i_mount, trans, | |
2171 | + dp->i_mount->m_ddev_targp, | |
2172 | + mapp, nmap, 0, &bp); | |
2173 | + if (error) | |
2174 | + goto out_free; | |
2175 | + | |
2176 | + if (whichfork == XFS_ATTR_FORK) | |
2177 | + xfs_buf_set_ref(bp, XFS_ATTR_BTREE_REF); | |
2103 | 2178 | else |
2104 | - rbp = NULL; | |
2179 | + xfs_buf_set_ref(bp, XFS_DIR_BTREE_REF); | |
2180 | + | |
2181 | + *bpp = xfs_da_buf_make(bp); | |
2182 | + | |
2105 | 2183 | /* |
2106 | - * For read_buf, check the magic number. | |
2184 | + * This verification code will be moved to a CRC verification callback | |
2185 | + * function so just leave it here unchanged until then. | |
2107 | 2186 | */ |
2108 | - if (caller == 1) { | |
2109 | - xfs_dir2_data_hdr_t *hdr = rbp->data; | |
2110 | - xfs_dir2_free_t *free = rbp->data; | |
2111 | - xfs_da_blkinfo_t *info = rbp->data; | |
2187 | + { | |
2188 | + xfs_dir2_data_hdr_t *hdr = (*bpp)->data; | |
2189 | + xfs_dir2_free_t *free = (*bpp)->data; | |
2190 | + xfs_da_blkinfo_t *info = (*bpp)->data; | |
2112 | 2191 | uint magic, magic1; |
2192 | + struct xfs_mount *mp = dp->i_mount; | |
2113 | 2193 | |
2114 | 2194 | magic = be16_to_cpu(info->magic); |
2115 | 2195 | magic1 = be32_to_cpu(hdr->magic); |
2116 | 2196 | |
2117 | 2197 | |
2118 | 2198 | |
2119 | 2199 | |
2120 | 2200 | |
2121 | 2201 | |
2122 | 2202 | |
2123 | 2203 | |
... | ... | @@ -2123,85 +2203,59 @@ |
2123 | 2203 | (free->hdr.magic != cpu_to_be32(XFS_DIR2_FREE_MAGIC)), |
2124 | 2204 | mp, XFS_ERRTAG_DA_READ_BUF, |
2125 | 2205 | XFS_RANDOM_DA_READ_BUF))) { |
2126 | - trace_xfs_da_btree_corrupt(rbp->bps[0], _RET_IP_); | |
2206 | + trace_xfs_da_btree_corrupt(bp, _RET_IP_); | |
2127 | 2207 | XFS_CORRUPTION_ERROR("xfs_da_do_buf(2)", |
2128 | 2208 | XFS_ERRLEVEL_LOW, mp, info); |
2129 | 2209 | error = XFS_ERROR(EFSCORRUPTED); |
2130 | - xfs_da_brelse(trans, rbp); | |
2131 | - nbplist = 0; | |
2132 | - goto exit1; | |
2210 | + xfs_da_brelse(trans, *bpp); | |
2211 | + goto out_free; | |
2133 | 2212 | } |
2134 | 2213 | } |
2135 | - if (bplist) { | |
2136 | - kmem_free(bplist); | |
2137 | - } | |
2138 | - if (mapp != &map) { | |
2139 | - kmem_free(mapp); | |
2140 | - } | |
2141 | - if (bpp) | |
2142 | - *bpp = rbp; | |
2143 | - return 0; | |
2144 | -exit1: | |
2145 | - if (bplist) { | |
2146 | - for (i = 0; i < nbplist; i++) | |
2147 | - xfs_trans_brelse(trans, bplist[i]); | |
2148 | - kmem_free(bplist); | |
2149 | - } | |
2150 | -exit0: | |
2214 | + | |
2215 | +out_free: | |
2151 | 2216 | if (mapp != &map) |
2152 | 2217 | kmem_free(mapp); |
2153 | - if (bpp) | |
2154 | - *bpp = NULL; | |
2218 | + | |
2155 | 2219 | return error; |
2156 | 2220 | } |
2157 | 2221 | |
2158 | 2222 | /* |
2159 | - * Get a buffer for the dir/attr block. | |
2160 | - */ | |
2161 | -int | |
2162 | -xfs_da_get_buf( | |
2163 | - xfs_trans_t *trans, | |
2164 | - xfs_inode_t *dp, | |
2165 | - xfs_dablk_t bno, | |
2166 | - xfs_daddr_t mappedbno, | |
2167 | - xfs_dabuf_t **bpp, | |
2168 | - int whichfork) | |
2169 | -{ | |
2170 | - return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 0); | |
2171 | -} | |
2172 | - | |
2173 | -/* | |
2174 | - * Get a buffer for the dir/attr block, fill in the contents. | |
2175 | - */ | |
2176 | -int | |
2177 | -xfs_da_read_buf( | |
2178 | - xfs_trans_t *trans, | |
2179 | - xfs_inode_t *dp, | |
2180 | - xfs_dablk_t bno, | |
2181 | - xfs_daddr_t mappedbno, | |
2182 | - xfs_dabuf_t **bpp, | |
2183 | - int whichfork) | |
2184 | -{ | |
2185 | - return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 1); | |
2186 | -} | |
2187 | - | |
2188 | -/* | |
2189 | 2223 | * Readahead the dir/attr block. |
2190 | 2224 | */ |
2191 | 2225 | xfs_daddr_t |
2192 | 2226 | xfs_da_reada_buf( |
2193 | - xfs_trans_t *trans, | |
2194 | - xfs_inode_t *dp, | |
2195 | - xfs_dablk_t bno, | |
2196 | - int whichfork) | |
2227 | + struct xfs_trans *trans, | |
2228 | + struct xfs_inode *dp, | |
2229 | + xfs_dablk_t bno, | |
2230 | + int whichfork) | |
2197 | 2231 | { |
2198 | - xfs_daddr_t rval; | |
2232 | + xfs_daddr_t mappedbno = -1; | |
2233 | + struct xfs_buf_map map; | |
2234 | + struct xfs_buf_map *mapp; | |
2235 | + int nmap; | |
2236 | + int error; | |
2199 | 2237 | |
2200 | - rval = -1; | |
2201 | - if (xfs_da_do_buf(trans, dp, bno, &rval, NULL, whichfork, 3)) | |
2238 | + mapp = ↦ | |
2239 | + nmap = 1; | |
2240 | + error = xfs_dabuf_map(trans, dp, bno, -1, whichfork, | |
2241 | + &mapp, &nmap); | |
2242 | + if (error) { | |
2243 | + /* mapping a hole is not an error, but we don't continue */ | |
2244 | + if (error == -1) | |
2245 | + error = 0; | |
2246 | + goto out_free; | |
2247 | + } | |
2248 | + | |
2249 | + mappedbno = mapp[0].bm_bn; | |
2250 | + xfs_buf_readahead_map(dp->i_mount->m_ddev_targp, mapp, nmap); | |
2251 | + | |
2252 | +out_free: | |
2253 | + if (mapp != &map) | |
2254 | + kmem_free(mapp); | |
2255 | + | |
2256 | + if (error) | |
2202 | 2257 | return -1; |
2203 | - else | |
2204 | - return rval; | |
2258 | + return mappedbno; | |
2205 | 2259 | } |
2206 | 2260 | |
2207 | 2261 | kmem_zone_t *xfs_da_state_zone; /* anchor for state struct zone */ |
2208 | 2262 | |
2209 | 2263 | |
2210 | 2264 | |
2211 | 2265 | |
2212 | 2266 | |
... | ... | @@ -2261,78 +2315,25 @@ |
2261 | 2315 | */ |
2262 | 2316 | /* ARGSUSED */ |
2263 | 2317 | STATIC xfs_dabuf_t * |
2264 | -xfs_da_buf_make(int nbuf, xfs_buf_t **bps) | |
2318 | +xfs_da_buf_make(xfs_buf_t *bp) | |
2265 | 2319 | { |
2266 | - xfs_buf_t *bp; | |
2267 | 2320 | xfs_dabuf_t *dabuf; |
2268 | - int i; | |
2269 | - int off; | |
2270 | 2321 | |
2271 | - if (nbuf == 1) | |
2272 | - dabuf = kmem_zone_alloc(xfs_dabuf_zone, KM_NOFS); | |
2273 | - else | |
2274 | - dabuf = kmem_alloc(XFS_DA_BUF_SIZE(nbuf), KM_NOFS); | |
2275 | - dabuf->dirty = 0; | |
2276 | - if (nbuf == 1) { | |
2277 | - dabuf->nbuf = 1; | |
2278 | - bp = bps[0]; | |
2279 | - dabuf->bbcount = bp->b_length; | |
2280 | - dabuf->data = bp->b_addr; | |
2281 | - dabuf->bps[0] = bp; | |
2282 | - } else { | |
2283 | - dabuf->nbuf = nbuf; | |
2284 | - for (i = 0, dabuf->bbcount = 0; i < nbuf; i++) { | |
2285 | - dabuf->bps[i] = bp = bps[i]; | |
2286 | - dabuf->bbcount += bp->b_length; | |
2287 | - } | |
2288 | - dabuf->data = kmem_alloc(BBTOB(dabuf->bbcount), KM_SLEEP); | |
2289 | - for (i = off = 0; i < nbuf; i++, off += BBTOB(bp->b_length)) { | |
2290 | - bp = bps[i]; | |
2291 | - memcpy((char *)dabuf->data + off, bp->b_addr, | |
2292 | - BBTOB(bp->b_length)); | |
2293 | - } | |
2294 | - } | |
2322 | + dabuf = kmem_zone_alloc(xfs_dabuf_zone, KM_NOFS); | |
2323 | + dabuf->bbcount = bp->b_length; | |
2324 | + dabuf->data = bp->b_addr; | |
2325 | + dabuf->bp = bp; | |
2295 | 2326 | return dabuf; |
2296 | 2327 | } |
2297 | 2328 | |
2298 | 2329 | /* |
2299 | - * Un-dirty a dabuf. | |
2300 | - */ | |
2301 | -STATIC void | |
2302 | -xfs_da_buf_clean(xfs_dabuf_t *dabuf) | |
2303 | -{ | |
2304 | - xfs_buf_t *bp; | |
2305 | - int i; | |
2306 | - int off; | |
2307 | - | |
2308 | - if (dabuf->dirty) { | |
2309 | - ASSERT(dabuf->nbuf > 1); | |
2310 | - dabuf->dirty = 0; | |
2311 | - for (i = off = 0; i < dabuf->nbuf; | |
2312 | - i++, off += BBTOB(bp->b_length)) { | |
2313 | - bp = dabuf->bps[i]; | |
2314 | - memcpy(bp->b_addr, dabuf->data + off, | |
2315 | - BBTOB(bp->b_length)); | |
2316 | - } | |
2317 | - } | |
2318 | -} | |
2319 | - | |
2320 | -/* | |
2321 | 2330 | * Release a dabuf. |
2322 | 2331 | */ |
2323 | 2332 | void |
2324 | 2333 | xfs_da_buf_done(xfs_dabuf_t *dabuf) |
2325 | 2334 | { |
2326 | - ASSERT(dabuf); | |
2327 | - ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); | |
2328 | - if (dabuf->dirty) | |
2329 | - xfs_da_buf_clean(dabuf); | |
2330 | - if (dabuf->nbuf > 1) { | |
2331 | - kmem_free(dabuf->data); | |
2332 | - kmem_free(dabuf); | |
2333 | - } else { | |
2334 | - kmem_zone_free(xfs_dabuf_zone, dabuf); | |
2335 | - } | |
2335 | + ASSERT(dabuf->data && dabuf->bbcount && dabuf->bp); | |
2336 | + kmem_zone_free(xfs_dabuf_zone, dabuf); | |
2336 | 2337 | } |
2337 | 2338 | |
2338 | 2339 | /* |
... | ... | @@ -2341,41 +2342,9 @@ |
2341 | 2342 | void |
2342 | 2343 | xfs_da_log_buf(xfs_trans_t *tp, xfs_dabuf_t *dabuf, uint first, uint last) |
2343 | 2344 | { |
2344 | - xfs_buf_t *bp; | |
2345 | - uint f; | |
2346 | - int i; | |
2347 | - uint l; | |
2348 | - int off; | |
2349 | - | |
2350 | - ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); | |
2351 | - if (dabuf->nbuf == 1) { | |
2352 | - ASSERT(dabuf->data == dabuf->bps[0]->b_addr); | |
2353 | - xfs_trans_log_buf(tp, dabuf->bps[0], first, last); | |
2354 | - return; | |
2355 | - } | |
2356 | - dabuf->dirty = 1; | |
2357 | - ASSERT(first <= last); | |
2358 | - for (i = off = 0; i < dabuf->nbuf; i++, off += BBTOB(bp->b_length)) { | |
2359 | - bp = dabuf->bps[i]; | |
2360 | - f = off; | |
2361 | - l = f + BBTOB(bp->b_length) - 1; | |
2362 | - if (f < first) | |
2363 | - f = first; | |
2364 | - if (l > last) | |
2365 | - l = last; | |
2366 | - if (f <= l) | |
2367 | - xfs_trans_log_buf(tp, bp, f - off, l - off); | |
2368 | - /* | |
2369 | - * B_DONE is set by xfs_trans_log buf. | |
2370 | - * If we don't set it on a new buffer (get not read) | |
2371 | - * then if we don't put anything in the buffer it won't | |
2372 | - * be set, and at commit it it released into the cache, | |
2373 | - * and then a read will fail. | |
2374 | - */ | |
2375 | - else if (!(XFS_BUF_ISDONE(bp))) | |
2376 | - XFS_BUF_DONE(bp); | |
2377 | - } | |
2378 | - ASSERT(last < off); | |
2345 | + ASSERT(dabuf->data && dabuf->bbcount && dabuf->bp); | |
2346 | + ASSERT(dabuf->data == dabuf->bp->b_addr); | |
2347 | + xfs_trans_log_buf(tp, dabuf->bp, first, last); | |
2379 | 2348 | } |
2380 | 2349 | |
2381 | 2350 | /* |
2382 | 2351 | |
... | ... | @@ -2386,24 +2355,9 @@ |
2386 | 2355 | void |
2387 | 2356 | xfs_da_brelse(xfs_trans_t *tp, xfs_dabuf_t *dabuf) |
2388 | 2357 | { |
2389 | - xfs_buf_t *bp; | |
2390 | - xfs_buf_t **bplist; | |
2391 | - int i; | |
2392 | - int nbuf; | |
2393 | - | |
2394 | - ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); | |
2395 | - if ((nbuf = dabuf->nbuf) == 1) { | |
2396 | - bplist = &bp; | |
2397 | - bp = dabuf->bps[0]; | |
2398 | - } else { | |
2399 | - bplist = kmem_alloc(nbuf * sizeof(*bplist), KM_SLEEP); | |
2400 | - memcpy(bplist, dabuf->bps, nbuf * sizeof(*bplist)); | |
2401 | - } | |
2358 | + ASSERT(dabuf->data && dabuf->bbcount && dabuf->bp); | |
2359 | + xfs_trans_brelse(tp, dabuf->bp); | |
2402 | 2360 | xfs_da_buf_done(dabuf); |
2403 | - for (i = 0; i < nbuf; i++) | |
2404 | - xfs_trans_brelse(tp, bplist[i]); | |
2405 | - if (bplist != &bp) | |
2406 | - kmem_free(bplist); | |
2407 | 2361 | } |
2408 | 2362 | |
2409 | 2363 | /* |
2410 | 2364 | |
... | ... | @@ -2412,24 +2366,9 @@ |
2412 | 2366 | void |
2413 | 2367 | xfs_da_binval(xfs_trans_t *tp, xfs_dabuf_t *dabuf) |
2414 | 2368 | { |
2415 | - xfs_buf_t *bp; | |
2416 | - xfs_buf_t **bplist; | |
2417 | - int i; | |
2418 | - int nbuf; | |
2419 | - | |
2420 | - ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); | |
2421 | - if ((nbuf = dabuf->nbuf) == 1) { | |
2422 | - bplist = &bp; | |
2423 | - bp = dabuf->bps[0]; | |
2424 | - } else { | |
2425 | - bplist = kmem_alloc(nbuf * sizeof(*bplist), KM_SLEEP); | |
2426 | - memcpy(bplist, dabuf->bps, nbuf * sizeof(*bplist)); | |
2427 | - } | |
2369 | + ASSERT(dabuf->data && dabuf->bbcount && dabuf->bp); | |
2428 | 2370 | xfs_da_buf_done(dabuf); |
2429 | - for (i = 0; i < nbuf; i++) | |
2430 | - xfs_trans_binval(tp, bplist[i]); | |
2431 | - if (bplist != &bp) | |
2432 | - kmem_free(bplist); | |
2371 | + xfs_trans_binval(tp, dabuf->bp); | |
2433 | 2372 | } |
2434 | 2373 | |
2435 | 2374 | /* |
2436 | 2375 | |
... | ... | @@ -2438,8 +2377,7 @@ |
2438 | 2377 | xfs_daddr_t |
2439 | 2378 | xfs_da_blkno(xfs_dabuf_t *dabuf) |
2440 | 2379 | { |
2441 | - ASSERT(dabuf->nbuf); | |
2442 | 2380 | ASSERT(dabuf->data); |
2443 | - return XFS_BUF_ADDR(dabuf->bps[0]); | |
2381 | + return XFS_BUF_ADDR(dabuf->bp); | |
2444 | 2382 | } |
fs/xfs/xfs_da_btree.h
... | ... | @@ -141,14 +141,10 @@ |
141 | 141 | * same place as the b_addr field for the buffer, else to kmem_alloced memory. |
142 | 142 | */ |
143 | 143 | typedef struct xfs_dabuf { |
144 | - int nbuf; /* number of buffer pointers present */ | |
145 | - short dirty; /* data needs to be copied back */ | |
146 | 144 | short bbcount; /* how large is data in bbs */ |
147 | 145 | void *data; /* pointer for buffers' data */ |
148 | - struct xfs_buf *bps[1]; /* actually nbuf of these */ | |
146 | + struct xfs_buf *bp; /* actually nbuf of these */ | |
149 | 147 | } xfs_dabuf_t; |
150 | -#define XFS_DA_BUF_SIZE(n) \ | |
151 | - (sizeof(xfs_dabuf_t) + sizeof(struct xfs_buf *) * ((n) - 1)) | |
152 | 148 | |
153 | 149 | /* |
154 | 150 | * Storage for holding state during Btree searches and split/join ops. |