aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorLiu Bo <bo.li.liu@oracle.com>2013-01-28 22:18:40 -0500
committerChris Mason <chris.mason@fusionio.com>2013-02-20 18:06:09 -0500
commit38c227d87c49ad5d173cb5d4374d49acec6a495d (patch)
treee68e689e44508cea68bf51928d864cd19f12e09d /fs/btrfs/inode.c
parent86db25785a6e7cacc1ee868fe437e8a2957eae94 (diff)
Btrfs: snapshot-aware defrag
This comes from one of btrfs's project ideas, As we defragment files, we break any sharing from other snapshots. The balancing code will preserve the sharing, and defrag needs to grow this as well. Now we're able to fill the blank with this patch, in which we make full use of backref walking stuff. Here is the basic idea, o set the writeback ranges started by defragment with flag EXTENT_DEFRAG o at endio, after we finish updating fs tree, we use backref walking to find all parents of the ranges and re-link them with the new COWed file layout by adding corresponding backrefs. Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> Signed-off-by: Liu Bo <bo.li.liu@oracle.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c654
1 files changed, 654 insertions, 0 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 3bc62b181ef8..4d0aec0cf5d8 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -55,6 +55,7 @@
55#include "locking.h" 55#include "locking.h"
56#include "free-space-cache.h" 56#include "free-space-cache.h"
57#include "inode-map.h" 57#include "inode-map.h"
58#include "backref.h"
58 59
59struct btrfs_iget_args { 60struct btrfs_iget_args {
60 u64 ino; 61 u64 ino;
@@ -1932,6 +1933,640 @@ out:
1932 return ret; 1933 return ret;
1933} 1934}
1934 1935
1936/* snapshot-aware defrag */
1937struct sa_defrag_extent_backref {
1938 struct rb_node node;
1939 struct old_sa_defrag_extent *old;
1940 u64 root_id;
1941 u64 inum;
1942 u64 file_pos;
1943 u64 extent_offset;
1944 u64 num_bytes;
1945 u64 generation;
1946};
1947
1948struct old_sa_defrag_extent {
1949 struct list_head list;
1950 struct new_sa_defrag_extent *new;
1951
1952 u64 extent_offset;
1953 u64 bytenr;
1954 u64 offset;
1955 u64 len;
1956 int count;
1957};
1958
1959struct new_sa_defrag_extent {
1960 struct rb_root root;
1961 struct list_head head;
1962 struct btrfs_path *path;
1963 struct inode *inode;
1964 u64 file_pos;
1965 u64 len;
1966 u64 bytenr;
1967 u64 disk_len;
1968 u8 compress_type;
1969};
1970
1971static int backref_comp(struct sa_defrag_extent_backref *b1,
1972 struct sa_defrag_extent_backref *b2)
1973{
1974 if (b1->root_id < b2->root_id)
1975 return -1;
1976 else if (b1->root_id > b2->root_id)
1977 return 1;
1978
1979 if (b1->inum < b2->inum)
1980 return -1;
1981 else if (b1->inum > b2->inum)
1982 return 1;
1983
1984 if (b1->file_pos < b2->file_pos)
1985 return -1;
1986 else if (b1->file_pos > b2->file_pos)
1987 return 1;
1988
1989 /*
1990 * [------------------------------] ===> (a range of space)
1991 * |<--->| |<---->| =============> (fs/file tree A)
1992 * |<---------------------------->| ===> (fs/file tree B)
1993 *
1994 * A range of space can refer to two file extents in one tree while
1995 * refer to only one file extent in another tree.
1996 *
1997 * So we may process a disk offset more than one time(two extents in A)
1998 * and locate at the same extent(one extent in B), then insert two same
1999 * backrefs(both refer to the extent in B).
2000 */
2001 return 0;
2002}
2003
2004static void backref_insert(struct rb_root *root,
2005 struct sa_defrag_extent_backref *backref)
2006{
2007 struct rb_node **p = &root->rb_node;
2008 struct rb_node *parent = NULL;
2009 struct sa_defrag_extent_backref *entry;
2010 int ret;
2011
2012 while (*p) {
2013 parent = *p;
2014 entry = rb_entry(parent, struct sa_defrag_extent_backref, node);
2015
2016 ret = backref_comp(backref, entry);
2017 if (ret < 0)
2018 p = &(*p)->rb_left;
2019 else
2020 p = &(*p)->rb_right;
2021 }
2022
2023 rb_link_node(&backref->node, parent, p);
2024 rb_insert_color(&backref->node, root);
2025}
2026
2027/*
2028 * Note the backref might has changed, and in this case we just return 0.
2029 */
2030static noinline int record_one_backref(u64 inum, u64 offset, u64 root_id,
2031 void *ctx)
2032{
2033 struct btrfs_file_extent_item *extent;
2034 struct btrfs_fs_info *fs_info;
2035 struct old_sa_defrag_extent *old = ctx;
2036 struct new_sa_defrag_extent *new = old->new;
2037 struct btrfs_path *path = new->path;
2038 struct btrfs_key key;
2039 struct btrfs_root *root;
2040 struct sa_defrag_extent_backref *backref;
2041 struct extent_buffer *leaf;
2042 struct inode *inode = new->inode;
2043 int slot;
2044 int ret;
2045 u64 extent_offset;
2046 u64 num_bytes;
2047
2048 if (BTRFS_I(inode)->root->root_key.objectid == root_id &&
2049 inum == btrfs_ino(inode))
2050 return 0;
2051
2052 key.objectid = root_id;
2053 key.type = BTRFS_ROOT_ITEM_KEY;
2054 key.offset = (u64)-1;
2055
2056 fs_info = BTRFS_I(inode)->root->fs_info;
2057 root = btrfs_read_fs_root_no_name(fs_info, &key);
2058 if (IS_ERR(root)) {
2059 if (PTR_ERR(root) == -ENOENT)
2060 return 0;
2061 WARN_ON(1);
2062 pr_debug("inum=%llu, offset=%llu, root_id=%llu\n",
2063 inum, offset, root_id);
2064 return PTR_ERR(root);
2065 }
2066
2067 key.objectid = inum;
2068 key.type = BTRFS_EXTENT_DATA_KEY;
2069 if (offset > (u64)-1 << 32)
2070 key.offset = 0;
2071 else
2072 key.offset = offset;
2073
2074 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
2075 if (ret < 0) {
2076 WARN_ON(1);
2077 return ret;
2078 }
2079
2080 while (1) {
2081 cond_resched();
2082
2083 leaf = path->nodes[0];
2084 slot = path->slots[0];
2085
2086 if (slot >= btrfs_header_nritems(leaf)) {
2087 ret = btrfs_next_leaf(root, path);
2088 if (ret < 0) {
2089 goto out;
2090 } else if (ret > 0) {
2091 ret = 0;
2092 goto out;
2093 }
2094 continue;
2095 }
2096
2097 path->slots[0]++;
2098
2099 btrfs_item_key_to_cpu(leaf, &key, slot);
2100
2101 if (key.objectid > inum)
2102 goto out;
2103
2104 if (key.objectid < inum || key.type != BTRFS_EXTENT_DATA_KEY)
2105 continue;
2106
2107 extent = btrfs_item_ptr(leaf, slot,
2108 struct btrfs_file_extent_item);
2109
2110 if (btrfs_file_extent_disk_bytenr(leaf, extent) != old->bytenr)
2111 continue;
2112
2113 extent_offset = btrfs_file_extent_offset(leaf, extent);
2114 if (key.offset - extent_offset != offset)
2115 continue;
2116
2117 num_bytes = btrfs_file_extent_num_bytes(leaf, extent);
2118 if (extent_offset >= old->extent_offset + old->offset +
2119 old->len || extent_offset + num_bytes <=
2120 old->extent_offset + old->offset)
2121 continue;
2122
2123 break;
2124 }
2125
2126 backref = kmalloc(sizeof(*backref), GFP_NOFS);
2127 if (!backref) {
2128 ret = -ENOENT;
2129 goto out;
2130 }
2131
2132 backref->root_id = root_id;
2133 backref->inum = inum;
2134 backref->file_pos = offset + extent_offset;
2135 backref->num_bytes = num_bytes;
2136 backref->extent_offset = extent_offset;
2137 backref->generation = btrfs_file_extent_generation(leaf, extent);
2138 backref->old = old;
2139 backref_insert(&new->root, backref);
2140 old->count++;
2141out:
2142 btrfs_release_path(path);
2143 WARN_ON(ret);
2144 return ret;
2145}
2146
2147static noinline bool record_extent_backrefs(struct btrfs_path *path,
2148 struct new_sa_defrag_extent *new)
2149{
2150 struct btrfs_fs_info *fs_info = BTRFS_I(new->inode)->root->fs_info;
2151 struct old_sa_defrag_extent *old, *tmp;
2152 int ret;
2153
2154 new->path = path;
2155
2156 list_for_each_entry_safe(old, tmp, &new->head, list) {
2157 ret = iterate_inodes_from_logical(old->bytenr, fs_info,
2158 path, record_one_backref,
2159 old);
2160 BUG_ON(ret < 0 && ret != -ENOENT);
2161
2162 /* no backref to be processed for this extent */
2163 if (!old->count) {
2164 list_del(&old->list);
2165 kfree(old);
2166 }
2167 }
2168
2169 if (list_empty(&new->head))
2170 return false;
2171
2172 return true;
2173}
2174
2175static int relink_is_mergable(struct extent_buffer *leaf,
2176 struct btrfs_file_extent_item *fi,
2177 u64 disk_bytenr)
2178{
2179 if (btrfs_file_extent_disk_bytenr(leaf, fi) != disk_bytenr)
2180 return 0;
2181
2182 if (btrfs_file_extent_type(leaf, fi) != BTRFS_FILE_EXTENT_REG)
2183 return 0;
2184
2185 if (btrfs_file_extent_compression(leaf, fi) ||
2186 btrfs_file_extent_encryption(leaf, fi) ||
2187 btrfs_file_extent_other_encoding(leaf, fi))
2188 return 0;
2189
2190 return 1;
2191}
2192
2193/*
2194 * Note the backref might has changed, and in this case we just return 0.
2195 */
2196static noinline int relink_extent_backref(struct btrfs_path *path,
2197 struct sa_defrag_extent_backref *prev,
2198 struct sa_defrag_extent_backref *backref)
2199{
2200 struct btrfs_file_extent_item *extent;
2201 struct btrfs_file_extent_item *item;
2202 struct btrfs_ordered_extent *ordered;
2203 struct btrfs_trans_handle *trans;
2204 struct btrfs_fs_info *fs_info;
2205 struct btrfs_root *root;
2206 struct btrfs_key key;
2207 struct extent_buffer *leaf;
2208 struct old_sa_defrag_extent *old = backref->old;
2209 struct new_sa_defrag_extent *new = old->new;
2210 struct inode *src_inode = new->inode;
2211 struct inode *inode;
2212 struct extent_state *cached = NULL;
2213 int ret = 0;
2214 u64 start;
2215 u64 len;
2216 u64 lock_start;
2217 u64 lock_end;
2218 bool merge = false;
2219 int index;
2220
2221 if (prev && prev->root_id == backref->root_id &&
2222 prev->inum == backref->inum &&
2223 prev->file_pos + prev->num_bytes == backref->file_pos)
2224 merge = true;
2225
2226 /* step 1: get root */
2227 key.objectid = backref->root_id;
2228 key.type = BTRFS_ROOT_ITEM_KEY;
2229 key.offset = (u64)-1;
2230
2231 fs_info = BTRFS_I(src_inode)->root->fs_info;
2232 index = srcu_read_lock(&fs_info->subvol_srcu);
2233
2234 root = btrfs_read_fs_root_no_name(fs_info, &key);
2235 if (IS_ERR(root)) {
2236 srcu_read_unlock(&fs_info->subvol_srcu, index);
2237 if (PTR_ERR(root) == -ENOENT)
2238 return 0;
2239 return PTR_ERR(root);
2240 }
2241 if (btrfs_root_refs(&root->root_item) == 0) {
2242 srcu_read_unlock(&fs_info->subvol_srcu, index);
2243 /* parse ENOENT to 0 */
2244 return 0;
2245 }
2246
2247 /* step 2: get inode */
2248 key.objectid = backref->inum;
2249 key.type = BTRFS_INODE_ITEM_KEY;
2250 key.offset = 0;
2251
2252 inode = btrfs_iget(fs_info->sb, &key, root, NULL);
2253 if (IS_ERR(inode)) {
2254 srcu_read_unlock(&fs_info->subvol_srcu, index);
2255 return 0;
2256 }
2257
2258 srcu_read_unlock(&fs_info->subvol_srcu, index);
2259
2260 /* step 3: relink backref */
2261 lock_start = backref->file_pos;
2262 lock_end = backref->file_pos + backref->num_bytes - 1;
2263 lock_extent_bits(&BTRFS_I(inode)->io_tree, lock_start, lock_end,
2264 0, &cached);
2265
2266 ordered = btrfs_lookup_first_ordered_extent(inode, lock_end);
2267 if (ordered) {
2268 btrfs_put_ordered_extent(ordered);
2269 goto out_unlock;
2270 }
2271
2272 trans = btrfs_join_transaction(root);
2273 if (IS_ERR(trans)) {
2274 ret = PTR_ERR(trans);
2275 goto out_unlock;
2276 }
2277
2278 key.objectid = backref->inum;
2279 key.type = BTRFS_EXTENT_DATA_KEY;
2280 key.offset = backref->file_pos;
2281
2282 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
2283 if (ret < 0) {
2284 goto out_free_path;
2285 } else if (ret > 0) {
2286 ret = 0;
2287 goto out_free_path;
2288 }
2289
2290 extent = btrfs_item_ptr(path->nodes[0], path->slots[0],
2291 struct btrfs_file_extent_item);
2292
2293 if (btrfs_file_extent_generation(path->nodes[0], extent) !=
2294 backref->generation)
2295 goto out_free_path;
2296
2297 btrfs_release_path(path);
2298
2299 start = backref->file_pos;
2300 if (backref->extent_offset < old->extent_offset + old->offset)
2301 start += old->extent_offset + old->offset -
2302 backref->extent_offset;
2303
2304 len = min(backref->extent_offset + backref->num_bytes,
2305 old->extent_offset + old->offset + old->len);
2306 len -= max(backref->extent_offset, old->extent_offset + old->offset);
2307
2308 ret = btrfs_drop_extents(trans, root, inode, start,
2309 start + len, 1);
2310 if (ret)
2311 goto out_free_path;
2312again:
2313 key.objectid = btrfs_ino(inode);
2314 key.type = BTRFS_EXTENT_DATA_KEY;
2315 key.offset = start;
2316
2317 if (merge) {
2318 struct btrfs_file_extent_item *fi;
2319 u64 extent_len;
2320 struct btrfs_key found_key;
2321
2322 ret = btrfs_search_slot(trans, root, &key, path, 1, 1);
2323 if (ret < 0)
2324 goto out_free_path;
2325
2326 path->slots[0]--;
2327 leaf = path->nodes[0];
2328 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
2329
2330 fi = btrfs_item_ptr(leaf, path->slots[0],
2331 struct btrfs_file_extent_item);
2332 extent_len = btrfs_file_extent_num_bytes(leaf, fi);
2333
2334 if (relink_is_mergable(leaf, fi, new->bytenr) &&
2335 extent_len + found_key.offset == start) {
2336 btrfs_set_file_extent_num_bytes(leaf, fi,
2337 extent_len + len);
2338 btrfs_mark_buffer_dirty(leaf);
2339 inode_add_bytes(inode, len);
2340
2341 ret = 1;
2342 goto out_free_path;
2343 } else {
2344 merge = false;
2345 btrfs_release_path(path);
2346 goto again;
2347 }
2348 }
2349
2350 ret = btrfs_insert_empty_item(trans, root, path, &key,
2351 sizeof(*extent));
2352 if (ret) {
2353 btrfs_abort_transaction(trans, root, ret);
2354 goto out_free_path;
2355 }
2356
2357 leaf = path->nodes[0];
2358 item = btrfs_item_ptr(leaf, path->slots[0],
2359 struct btrfs_file_extent_item);
2360 btrfs_set_file_extent_disk_bytenr(leaf, item, new->bytenr);
2361 btrfs_set_file_extent_disk_num_bytes(leaf, item, new->disk_len);
2362 btrfs_set_file_extent_offset(leaf, item, start - new->file_pos);
2363 btrfs_set_file_extent_num_bytes(leaf, item, len);
2364 btrfs_set_file_extent_ram_bytes(leaf, item, new->len);
2365 btrfs_set_file_extent_generation(leaf, item, trans->transid);
2366 btrfs_set_file_extent_type(leaf, item, BTRFS_FILE_EXTENT_REG);
2367 btrfs_set_file_extent_compression(leaf, item, new->compress_type);
2368 btrfs_set_file_extent_encryption(leaf, item, 0);
2369 btrfs_set_file_extent_other_encoding(leaf, item, 0);
2370
2371 btrfs_mark_buffer_dirty(leaf);
2372 inode_add_bytes(inode, len);
2373
2374 ret = btrfs_inc_extent_ref(trans, root, new->bytenr,
2375 new->disk_len, 0,
2376 backref->root_id, backref->inum,
2377 new->file_pos, 0); /* start - extent_offset */
2378 if (ret) {
2379 btrfs_abort_transaction(trans, root, ret);
2380 goto out_free_path;
2381 }
2382
2383 ret = 1;
2384out_free_path:
2385 btrfs_release_path(path);
2386 btrfs_end_transaction(trans, root);
2387out_unlock:
2388 unlock_extent_cached(&BTRFS_I(inode)->io_tree, lock_start, lock_end,
2389 &cached, GFP_NOFS);
2390 iput(inode);
2391 return ret;
2392}
2393
2394static void relink_file_extents(struct new_sa_defrag_extent *new)
2395{
2396 struct btrfs_path *path;
2397 struct old_sa_defrag_extent *old, *tmp;
2398 struct sa_defrag_extent_backref *backref;
2399 struct sa_defrag_extent_backref *prev = NULL;
2400 struct inode *inode;
2401 struct btrfs_root *root;
2402 struct rb_node *node;
2403 int ret;
2404
2405 inode = new->inode;
2406 root = BTRFS_I(inode)->root;
2407
2408 path = btrfs_alloc_path();
2409 if (!path)
2410 return;
2411
2412 if (!record_extent_backrefs(path, new)) {
2413 btrfs_free_path(path);
2414 goto out;
2415 }
2416 btrfs_release_path(path);
2417
2418 while (1) {
2419 node = rb_first(&new->root);
2420 if (!node)
2421 break;
2422 rb_erase(node, &new->root);
2423
2424 backref = rb_entry(node, struct sa_defrag_extent_backref, node);
2425
2426 ret = relink_extent_backref(path, prev, backref);
2427 WARN_ON(ret < 0);
2428
2429 kfree(prev);
2430
2431 if (ret == 1)
2432 prev = backref;
2433 else
2434 prev = NULL;
2435 cond_resched();
2436 }
2437 kfree(prev);
2438
2439 btrfs_free_path(path);
2440
2441 list_for_each_entry_safe(old, tmp, &new->head, list) {
2442 list_del(&old->list);
2443 kfree(old);
2444 }
2445out:
2446 atomic_dec(&root->fs_info->defrag_running);
2447 wake_up(&root->fs_info->transaction_wait);
2448
2449 kfree(new);
2450}
2451
2452static struct new_sa_defrag_extent *
2453record_old_file_extents(struct inode *inode,
2454 struct btrfs_ordered_extent *ordered)
2455{
2456 struct btrfs_root *root = BTRFS_I(inode)->root;
2457 struct btrfs_path *path;
2458 struct btrfs_key key;
2459 struct old_sa_defrag_extent *old, *tmp;
2460 struct new_sa_defrag_extent *new;
2461 int ret;
2462
2463 new = kmalloc(sizeof(*new), GFP_NOFS);
2464 if (!new)
2465 return NULL;
2466
2467 new->inode = inode;
2468 new->file_pos = ordered->file_offset;
2469 new->len = ordered->len;
2470 new->bytenr = ordered->start;
2471 new->disk_len = ordered->disk_len;
2472 new->compress_type = ordered->compress_type;
2473 new->root = RB_ROOT;
2474 INIT_LIST_HEAD(&new->head);
2475
2476 path = btrfs_alloc_path();
2477 if (!path)
2478 goto out_kfree;
2479
2480 key.objectid = btrfs_ino(inode);
2481 key.type = BTRFS_EXTENT_DATA_KEY;
2482 key.offset = new->file_pos;
2483
2484 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
2485 if (ret < 0)
2486 goto out_free_path;
2487 if (ret > 0 && path->slots[0] > 0)
2488 path->slots[0]--;
2489
2490 /* find out all the old extents for the file range */
2491 while (1) {
2492 struct btrfs_file_extent_item *extent;
2493 struct extent_buffer *l;
2494 int slot;
2495 u64 num_bytes;
2496 u64 offset;
2497 u64 end;
2498 u64 disk_bytenr;
2499 u64 extent_offset;
2500
2501 l = path->nodes[0];
2502 slot = path->slots[0];
2503
2504 if (slot >= btrfs_header_nritems(l)) {
2505 ret = btrfs_next_leaf(root, path);
2506 if (ret < 0)
2507 goto out_free_list;
2508 else if (ret > 0)
2509 break;
2510 continue;
2511 }
2512
2513 btrfs_item_key_to_cpu(l, &key, slot);
2514
2515 if (key.objectid != btrfs_ino(inode))
2516 break;
2517 if (key.type != BTRFS_EXTENT_DATA_KEY)
2518 break;
2519 if (key.offset >= new->file_pos + new->len)
2520 break;
2521
2522 extent = btrfs_item_ptr(l, slot, struct btrfs_file_extent_item);
2523
2524 num_bytes = btrfs_file_extent_num_bytes(l, extent);
2525 if (key.offset + num_bytes < new->file_pos)
2526 goto next;
2527
2528 disk_bytenr = btrfs_file_extent_disk_bytenr(l, extent);
2529 if (!disk_bytenr)
2530 goto next;
2531
2532 extent_offset = btrfs_file_extent_offset(l, extent);
2533
2534 old = kmalloc(sizeof(*old), GFP_NOFS);
2535 if (!old)
2536 goto out_free_list;
2537
2538 offset = max(new->file_pos, key.offset);
2539 end = min(new->file_pos + new->len, key.offset + num_bytes);
2540
2541 old->bytenr = disk_bytenr;
2542 old->extent_offset = extent_offset;
2543 old->offset = offset - key.offset;
2544 old->len = end - offset;
2545 old->new = new;
2546 old->count = 0;
2547 list_add_tail(&old->list, &new->head);
2548next:
2549 path->slots[0]++;
2550 cond_resched();
2551 }
2552
2553 btrfs_free_path(path);
2554 atomic_inc(&root->fs_info->defrag_running);
2555
2556 return new;
2557
2558out_free_list:
2559 list_for_each_entry_safe(old, tmp, &new->head, list) {
2560 list_del(&old->list);
2561 kfree(old);
2562 }
2563out_free_path:
2564 btrfs_free_path(path);
2565out_kfree:
2566 kfree(new);
2567 return NULL;
2568}
2569
1935/* 2570/*
1936 * helper function for btrfs_finish_ordered_io, this 2571 * helper function for btrfs_finish_ordered_io, this
1937 * just reads in some of the csum leaves to prime them into ram 2572 * just reads in some of the csum leaves to prime them into ram
@@ -1949,6 +2584,7 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
1949 struct btrfs_trans_handle *trans = NULL; 2584 struct btrfs_trans_handle *trans = NULL;
1950 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; 2585 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
1951 struct extent_state *cached_state = NULL; 2586 struct extent_state *cached_state = NULL;
2587 struct new_sa_defrag_extent *new = NULL;
1952 int compress_type = 0; 2588 int compress_type = 0;
1953 int ret; 2589 int ret;
1954 bool nolock; 2590 bool nolock;
@@ -1983,6 +2619,20 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
1983 ordered_extent->file_offset + ordered_extent->len - 1, 2619 ordered_extent->file_offset + ordered_extent->len - 1,
1984 0, &cached_state); 2620 0, &cached_state);
1985 2621
2622 ret = test_range_bit(io_tree, ordered_extent->file_offset,
2623 ordered_extent->file_offset + ordered_extent->len - 1,
2624 EXTENT_DEFRAG, 1, cached_state);
2625 if (ret) {
2626 u64 last_snapshot = btrfs_root_last_snapshot(&root->root_item);
2627 if (last_snapshot >= BTRFS_I(inode)->generation)
2628 /* the inode is shared */
2629 new = record_old_file_extents(inode, ordered_extent);
2630
2631 clear_extent_bit(io_tree, ordered_extent->file_offset,
2632 ordered_extent->file_offset + ordered_extent->len - 1,
2633 EXTENT_DEFRAG, 0, 0, &cached_state, GFP_NOFS);
2634 }
2635
1986 if (nolock) 2636 if (nolock)
1987 trans = btrfs_join_transaction_nolock(root); 2637 trans = btrfs_join_transaction_nolock(root);
1988 else 2638 else
@@ -2064,6 +2714,10 @@ out:
2064 */ 2714 */
2065 btrfs_remove_ordered_extent(inode, ordered_extent); 2715 btrfs_remove_ordered_extent(inode, ordered_extent);
2066 2716
2717 /* for snapshot-aware defrag */
2718 if (new)
2719 relink_file_extents(new);
2720
2067 /* once for us */ 2721 /* once for us */
2068 btrfs_put_ordered_extent(ordered_extent); 2722 btrfs_put_ordered_extent(ordered_extent);
2069 /* once for the tree */ 2723 /* once for the tree */