aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_attr.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-04-03 01:11:27 -0400
committerBen Myers <bpm@sgi.com>2013-04-27 13:49:32 -0400
commit95920cd6ce1c9cd8d3a0f639a674aa26c974ed57 (patch)
tree9f35771c82bb79b469a0c64d8c9e0fe86c5ea0e3 /fs/xfs/xfs_attr.c
parent517c22207b045993a6529e1f8684095adaae9cf3 (diff)
xfs: split remote attribute code out
Adding CRC support to remote attributes adds a significant amount of remote attribute specific code. Split the existing remote attribute code out into it's own file so that all the relevant remote attribute code is in a single, easy to find place. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Ben Myers <bpm@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_attr.c')
-rw-r--r--fs/xfs/xfs_attr.c298
1 files changed, 1 insertions, 297 deletions
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index e70687541592..20fe3fe9d341 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -34,6 +34,7 @@
34#include "xfs_bmap.h" 34#include "xfs_bmap.h"
35#include "xfs_attr.h" 35#include "xfs_attr.h"
36#include "xfs_attr_leaf.h" 36#include "xfs_attr_leaf.h"
37#include "xfs_attr_remote.h"
37#include "xfs_error.h" 38#include "xfs_error.h"
38#include "xfs_quota.h" 39#include "xfs_quota.h"
39#include "xfs_trans_space.h" 40#include "xfs_trans_space.h"
@@ -73,13 +74,6 @@ STATIC int xfs_attr_node_list(xfs_attr_list_context_t *context);
73STATIC int xfs_attr_fillstate(xfs_da_state_t *state); 74STATIC int xfs_attr_fillstate(xfs_da_state_t *state);
74STATIC int xfs_attr_refillstate(xfs_da_state_t *state); 75STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
75 76
76/*
77 * Routines to manipulate out-of-line attribute values.
78 */
79STATIC int xfs_attr_rmtval_set(xfs_da_args_t *args);
80STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args);
81
82#define ATTR_RMTVALUE_MAPSIZE 1 /* # of map entries at once */
83 77
84STATIC int 78STATIC int
85xfs_attr_name_to_xname( 79xfs_attr_name_to_xname(
@@ -1926,293 +1920,3 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
1926 xfs_trans_brelse(NULL, bp); 1920 xfs_trans_brelse(NULL, bp);
1927 return 0; 1921 return 0;
1928} 1922}
1929
1930
1931/*========================================================================
1932 * External routines for manipulating out-of-line attribute values.
1933 *========================================================================*/
1934
1935/*
1936 * Read the value associated with an attribute from the out-of-line buffer
1937 * that we stored it in.
1938 */
1939int
1940xfs_attr_rmtval_get(xfs_da_args_t *args)
1941{
1942 xfs_bmbt_irec_t map[ATTR_RMTVALUE_MAPSIZE];
1943 xfs_mount_t *mp;
1944 xfs_daddr_t dblkno;
1945 void *dst;
1946 xfs_buf_t *bp;
1947 int nmap, error, tmp, valuelen, blkcnt, i;
1948 xfs_dablk_t lblkno;
1949
1950 trace_xfs_attr_rmtval_get(args);
1951
1952 ASSERT(!(args->flags & ATTR_KERNOVAL));
1953
1954 mp = args->dp->i_mount;
1955 dst = args->value;
1956 valuelen = args->valuelen;
1957 lblkno = args->rmtblkno;
1958 while (valuelen > 0) {
1959 nmap = ATTR_RMTVALUE_MAPSIZE;
1960 error = xfs_bmapi_read(args->dp, (xfs_fileoff_t)lblkno,
1961 args->rmtblkcnt, map, &nmap,
1962 XFS_BMAPI_ATTRFORK);
1963 if (error)
1964 return(error);
1965 ASSERT(nmap >= 1);
1966
1967 for (i = 0; (i < nmap) && (valuelen > 0); i++) {
1968 ASSERT((map[i].br_startblock != DELAYSTARTBLOCK) &&
1969 (map[i].br_startblock != HOLESTARTBLOCK));
1970 dblkno = XFS_FSB_TO_DADDR(mp, map[i].br_startblock);
1971 blkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
1972 error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp,
1973 dblkno, blkcnt, 0, &bp, NULL);
1974 if (error)
1975 return(error);
1976
1977 tmp = min_t(int, valuelen, BBTOB(bp->b_length));
1978 xfs_buf_iomove(bp, 0, tmp, dst, XBRW_READ);
1979 xfs_buf_relse(bp);
1980 dst += tmp;
1981 valuelen -= tmp;
1982
1983 lblkno += map[i].br_blockcount;
1984 }
1985 }
1986 ASSERT(valuelen == 0);
1987 return(0);
1988}
1989
1990/*
1991 * Write the value associated with an attribute into the out-of-line buffer
1992 * that we have defined for it.
1993 */
1994STATIC int
1995xfs_attr_rmtval_set(xfs_da_args_t *args)
1996{
1997 xfs_mount_t *mp;
1998 xfs_fileoff_t lfileoff;
1999 xfs_inode_t *dp;
2000 xfs_bmbt_irec_t map;
2001 xfs_daddr_t dblkno;
2002 void *src;
2003 xfs_buf_t *bp;
2004 xfs_dablk_t lblkno;
2005 int blkcnt, valuelen, nmap, error, tmp, committed;
2006
2007 trace_xfs_attr_rmtval_set(args);
2008
2009 dp = args->dp;
2010 mp = dp->i_mount;
2011 src = args->value;
2012
2013 /*
2014 * Find a "hole" in the attribute address space large enough for
2015 * us to drop the new attribute's value into.
2016 */
2017 blkcnt = XFS_B_TO_FSB(mp, args->valuelen);
2018 lfileoff = 0;
2019 error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff,
2020 XFS_ATTR_FORK);
2021 if (error) {
2022 return(error);
2023 }
2024 args->rmtblkno = lblkno = (xfs_dablk_t)lfileoff;
2025 args->rmtblkcnt = blkcnt;
2026
2027 /*
2028 * Roll through the "value", allocating blocks on disk as required.
2029 */
2030 while (blkcnt > 0) {
2031 /*
2032 * Allocate a single extent, up to the size of the value.
2033 */
2034 xfs_bmap_init(args->flist, args->firstblock);
2035 nmap = 1;
2036 error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno,
2037 blkcnt,
2038 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2039 args->firstblock, args->total, &map, &nmap,
2040 args->flist);
2041 if (!error) {
2042 error = xfs_bmap_finish(&args->trans, args->flist,
2043 &committed);
2044 }
2045 if (error) {
2046 ASSERT(committed);
2047 args->trans = NULL;
2048 xfs_bmap_cancel(args->flist);
2049 return(error);
2050 }
2051
2052 /*
2053 * bmap_finish() may have committed the last trans and started
2054 * a new one. We need the inode to be in all transactions.
2055 */
2056 if (committed)
2057 xfs_trans_ijoin(args->trans, dp, 0);
2058
2059 ASSERT(nmap == 1);
2060 ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
2061 (map.br_startblock != HOLESTARTBLOCK));
2062 lblkno += map.br_blockcount;
2063 blkcnt -= map.br_blockcount;
2064
2065 /*
2066 * Start the next trans in the chain.
2067 */
2068 error = xfs_trans_roll(&args->trans, dp);
2069 if (error)
2070 return (error);
2071 }
2072
2073 /*
2074 * Roll through the "value", copying the attribute value to the
2075 * already-allocated blocks. Blocks are written synchronously
2076 * so that we can know they are all on disk before we turn off
2077 * the INCOMPLETE flag.
2078 */
2079 lblkno = args->rmtblkno;
2080 valuelen = args->valuelen;
2081 while (valuelen > 0) {
2082 int buflen;
2083
2084 /*
2085 * Try to remember where we decided to put the value.
2086 */
2087 xfs_bmap_init(args->flist, args->firstblock);
2088 nmap = 1;
2089 error = xfs_bmapi_read(dp, (xfs_fileoff_t)lblkno,
2090 args->rmtblkcnt, &map, &nmap,
2091 XFS_BMAPI_ATTRFORK);
2092 if (error)
2093 return(error);
2094 ASSERT(nmap == 1);
2095 ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
2096 (map.br_startblock != HOLESTARTBLOCK));
2097
2098 dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock),
2099 blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount);
2100
2101 bp = xfs_buf_get(mp->m_ddev_targp, dblkno, blkcnt, 0);
2102 if (!bp)
2103 return ENOMEM;
2104
2105 buflen = BBTOB(bp->b_length);
2106 tmp = min_t(int, valuelen, buflen);
2107 xfs_buf_iomove(bp, 0, tmp, src, XBRW_WRITE);
2108 if (tmp < buflen)
2109 xfs_buf_zero(bp, tmp, buflen - tmp);
2110
2111 error = xfs_bwrite(bp); /* GROT: NOTE: synchronous write */
2112 xfs_buf_relse(bp);
2113 if (error)
2114 return error;
2115 src += tmp;
2116 valuelen -= tmp;
2117
2118 lblkno += map.br_blockcount;
2119 }
2120 ASSERT(valuelen == 0);
2121 return(0);
2122}
2123
2124/*
2125 * Remove the value associated with an attribute by deleting the
2126 * out-of-line buffer that it is stored on.
2127 */
2128STATIC int
2129xfs_attr_rmtval_remove(xfs_da_args_t *args)
2130{
2131 xfs_mount_t *mp;
2132 xfs_bmbt_irec_t map;
2133 xfs_buf_t *bp;
2134 xfs_daddr_t dblkno;
2135 xfs_dablk_t lblkno;
2136 int valuelen, blkcnt, nmap, error, done, committed;
2137
2138 trace_xfs_attr_rmtval_remove(args);
2139
2140 mp = args->dp->i_mount;
2141
2142 /*
2143 * Roll through the "value", invalidating the attribute value's
2144 * blocks.
2145 */
2146 lblkno = args->rmtblkno;
2147 valuelen = args->rmtblkcnt;
2148 while (valuelen > 0) {
2149 /*
2150 * Try to remember where we decided to put the value.
2151 */
2152 nmap = 1;
2153 error = xfs_bmapi_read(args->dp, (xfs_fileoff_t)lblkno,
2154 args->rmtblkcnt, &map, &nmap,
2155 XFS_BMAPI_ATTRFORK);
2156 if (error)
2157 return(error);
2158 ASSERT(nmap == 1);
2159 ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
2160 (map.br_startblock != HOLESTARTBLOCK));
2161
2162 dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock),
2163 blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount);
2164
2165 /*
2166 * If the "remote" value is in the cache, remove it.
2167 */
2168 bp = xfs_incore(mp->m_ddev_targp, dblkno, blkcnt, XBF_TRYLOCK);
2169 if (bp) {
2170 xfs_buf_stale(bp);
2171 xfs_buf_relse(bp);
2172 bp = NULL;
2173 }
2174
2175 valuelen -= map.br_blockcount;
2176
2177 lblkno += map.br_blockcount;
2178 }
2179
2180 /*
2181 * Keep de-allocating extents until the remote-value region is gone.
2182 */
2183 lblkno = args->rmtblkno;
2184 blkcnt = args->rmtblkcnt;
2185 done = 0;
2186 while (!done) {
2187 xfs_bmap_init(args->flist, args->firstblock);
2188 error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt,
2189 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2190 1, args->firstblock, args->flist,
2191 &done);
2192 if (!error) {
2193 error = xfs_bmap_finish(&args->trans, args->flist,
2194 &committed);
2195 }
2196 if (error) {
2197 ASSERT(committed);
2198 args->trans = NULL;
2199 xfs_bmap_cancel(args->flist);
2200 return(error);
2201 }
2202
2203 /*
2204 * bmap_finish() may have committed the last trans and started
2205 * a new one. We need the inode to be in all transactions.
2206 */
2207 if (committed)
2208 xfs_trans_ijoin(args->trans, args->dp, 0);
2209
2210 /*
2211 * Close out trans and start the next one in the chain.
2212 */
2213 error = xfs_trans_roll(&args->trans, args->dp);
2214 if (error)
2215 return (error);
2216 }
2217 return(0);
2218}