diff options
author | Dave Chinner <dchinner@redhat.com> | 2013-04-03 01:11:27 -0400 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2013-04-27 13:49:32 -0400 |
commit | 95920cd6ce1c9cd8d3a0f639a674aa26c974ed57 (patch) | |
tree | 9f35771c82bb79b469a0c64d8c9e0fe86c5ea0e3 /fs/xfs/xfs_attr.c | |
parent | 517c22207b045993a6529e1f8684095adaae9cf3 (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.c | 298 |
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); | |||
73 | STATIC int xfs_attr_fillstate(xfs_da_state_t *state); | 74 | STATIC int xfs_attr_fillstate(xfs_da_state_t *state); |
74 | STATIC int xfs_attr_refillstate(xfs_da_state_t *state); | 75 | STATIC int xfs_attr_refillstate(xfs_da_state_t *state); |
75 | 76 | ||
76 | /* | ||
77 | * Routines to manipulate out-of-line attribute values. | ||
78 | */ | ||
79 | STATIC int xfs_attr_rmtval_set(xfs_da_args_t *args); | ||
80 | STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args); | ||
81 | |||
82 | #define ATTR_RMTVALUE_MAPSIZE 1 /* # of map entries at once */ | ||
83 | 77 | ||
84 | STATIC int | 78 | STATIC int |
85 | xfs_attr_name_to_xname( | 79 | xfs_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 | */ | ||
1939 | int | ||
1940 | xfs_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 | */ | ||
1994 | STATIC int | ||
1995 | xfs_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 | */ | ||
2128 | STATIC int | ||
2129 | xfs_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 | } | ||