Commit 3605431fb9739a30ccd0c6380ae8e3c6f8e670a5

Authored by Dave Chinner
Committed by Ben Myers
1 parent 372cc85ec6

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 = &map;
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 = &map;
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 = &map;
  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 = &map;
  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 = &map;
  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.