aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2012-01-16 15:04:48 -0500
committerIlya Dryomov <idryomov@gmail.com>2012-01-16 15:04:48 -0500
commit94e60d5a5c4b98a32b1077dec88df09ada712376 (patch)
tree149b9c9f68b64c7aa6e4b07bf12940a6e27591ca /fs/btrfs/volumes.c
parent409d404b461afa9738619f249fd7f62a366b68c2 (diff)
Btrfs: devid subset filter
Select chunks which have at least one byte of at least one stripe located on a device with devid X in a given [pstart,pend) physical address range. This filter only works when devid filter is turned on. Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 9ff5cd09a256..c60071a448a5 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2167,6 +2167,46 @@ static int chunk_devid_filter(struct extent_buffer *leaf,
2167 return 1; 2167 return 1;
2168} 2168}
2169 2169
2170/* [pstart, pend) */
2171static int chunk_drange_filter(struct extent_buffer *leaf,
2172 struct btrfs_chunk *chunk,
2173 u64 chunk_offset,
2174 struct btrfs_balance_args *bargs)
2175{
2176 struct btrfs_stripe *stripe;
2177 int num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
2178 u64 stripe_offset;
2179 u64 stripe_length;
2180 int factor;
2181 int i;
2182
2183 if (!(bargs->flags & BTRFS_BALANCE_ARGS_DEVID))
2184 return 0;
2185
2186 if (btrfs_chunk_type(leaf, chunk) & (BTRFS_BLOCK_GROUP_DUP |
2187 BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10))
2188 factor = 2;
2189 else
2190 factor = 1;
2191 factor = num_stripes / factor;
2192
2193 for (i = 0; i < num_stripes; i++) {
2194 stripe = btrfs_stripe_nr(chunk, i);
2195 if (btrfs_stripe_devid(leaf, stripe) != bargs->devid)
2196 continue;
2197
2198 stripe_offset = btrfs_stripe_offset(leaf, stripe);
2199 stripe_length = btrfs_chunk_length(leaf, chunk);
2200 do_div(stripe_length, factor);
2201
2202 if (stripe_offset < bargs->pend &&
2203 stripe_offset + stripe_length > bargs->pstart)
2204 return 0;
2205 }
2206
2207 return 1;
2208}
2209
2170static int should_balance_chunk(struct btrfs_root *root, 2210static int should_balance_chunk(struct btrfs_root *root,
2171 struct extent_buffer *leaf, 2211 struct extent_buffer *leaf,
2172 struct btrfs_chunk *chunk, u64 chunk_offset) 2212 struct btrfs_chunk *chunk, u64 chunk_offset)
@@ -2206,6 +2246,12 @@ static int should_balance_chunk(struct btrfs_root *root,
2206 return 0; 2246 return 0;
2207 } 2247 }
2208 2248
2249 /* drange filter, makes sense only with devid filter */
2250 if ((bargs->flags & BTRFS_BALANCE_ARGS_DRANGE) &&
2251 chunk_drange_filter(leaf, chunk, chunk_offset, bargs)) {
2252 return 0;
2253 }
2254
2209 return 1; 2255 return 1;
2210} 2256}
2211 2257