diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2013-07-12 06:34:42 -0400 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2013-07-12 06:34:42 -0400 |
| commit | f2006e27396f55276f24434f56e208d86e7f9908 (patch) | |
| tree | 71896db916d33888b4286f80117d3cac0da40e6d /fs/btrfs/send.c | |
| parent | e399eb56a6110e13f97e644658648602e2b08de7 (diff) | |
| parent | 9903883f1dd6e86f286b7bfa6e4b423f98c1cd9e (diff) | |
Merge branch 'linus' into timers/urgent
Get upstream changes so we can apply fixes against them
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'fs/btrfs/send.c')
| -rw-r--r-- | fs/btrfs/send.c | 235 |
1 files changed, 128 insertions, 107 deletions
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index ff40f1c00ce3..d3f3b43cae0b 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c | |||
| @@ -158,7 +158,7 @@ static void fs_path_reset(struct fs_path *p) | |||
| 158 | } | 158 | } |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | static struct fs_path *fs_path_alloc(struct send_ctx *sctx) | 161 | static struct fs_path *fs_path_alloc(void) |
| 162 | { | 162 | { |
| 163 | struct fs_path *p; | 163 | struct fs_path *p; |
| 164 | 164 | ||
| @@ -173,11 +173,11 @@ static struct fs_path *fs_path_alloc(struct send_ctx *sctx) | |||
| 173 | return p; | 173 | return p; |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | static struct fs_path *fs_path_alloc_reversed(struct send_ctx *sctx) | 176 | static struct fs_path *fs_path_alloc_reversed(void) |
| 177 | { | 177 | { |
| 178 | struct fs_path *p; | 178 | struct fs_path *p; |
| 179 | 179 | ||
| 180 | p = fs_path_alloc(sctx); | 180 | p = fs_path_alloc(); |
| 181 | if (!p) | 181 | if (!p) |
| 182 | return NULL; | 182 | return NULL; |
| 183 | p->reversed = 1; | 183 | p->reversed = 1; |
| @@ -185,7 +185,7 @@ static struct fs_path *fs_path_alloc_reversed(struct send_ctx *sctx) | |||
| 185 | return p; | 185 | return p; |
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | static void fs_path_free(struct send_ctx *sctx, struct fs_path *p) | 188 | static void fs_path_free(struct fs_path *p) |
| 189 | { | 189 | { |
| 190 | if (!p) | 190 | if (!p) |
| 191 | return; | 191 | return; |
| @@ -753,8 +753,7 @@ typedef int (*iterate_inode_ref_t)(int num, u64 dir, int index, | |||
| 753 | * | 753 | * |
| 754 | * path must point to the INODE_REF or INODE_EXTREF when called. | 754 | * path must point to the INODE_REF or INODE_EXTREF when called. |
| 755 | */ | 755 | */ |
| 756 | static int iterate_inode_ref(struct send_ctx *sctx, | 756 | static int iterate_inode_ref(struct btrfs_root *root, struct btrfs_path *path, |
| 757 | struct btrfs_root *root, struct btrfs_path *path, | ||
| 758 | struct btrfs_key *found_key, int resolve, | 757 | struct btrfs_key *found_key, int resolve, |
| 759 | iterate_inode_ref_t iterate, void *ctx) | 758 | iterate_inode_ref_t iterate, void *ctx) |
| 760 | { | 759 | { |
| @@ -777,13 +776,13 @@ static int iterate_inode_ref(struct send_ctx *sctx, | |||
| 777 | unsigned long elem_size; | 776 | unsigned long elem_size; |
| 778 | unsigned long ptr; | 777 | unsigned long ptr; |
| 779 | 778 | ||
| 780 | p = fs_path_alloc_reversed(sctx); | 779 | p = fs_path_alloc_reversed(); |
| 781 | if (!p) | 780 | if (!p) |
| 782 | return -ENOMEM; | 781 | return -ENOMEM; |
| 783 | 782 | ||
| 784 | tmp_path = alloc_path_for_send(); | 783 | tmp_path = alloc_path_for_send(); |
| 785 | if (!tmp_path) { | 784 | if (!tmp_path) { |
| 786 | fs_path_free(sctx, p); | 785 | fs_path_free(p); |
| 787 | return -ENOMEM; | 786 | return -ENOMEM; |
| 788 | } | 787 | } |
| 789 | 788 | ||
| @@ -858,7 +857,7 @@ static int iterate_inode_ref(struct send_ctx *sctx, | |||
| 858 | 857 | ||
| 859 | out: | 858 | out: |
| 860 | btrfs_free_path(tmp_path); | 859 | btrfs_free_path(tmp_path); |
| 861 | fs_path_free(sctx, p); | 860 | fs_path_free(p); |
| 862 | return ret; | 861 | return ret; |
| 863 | } | 862 | } |
| 864 | 863 | ||
| @@ -874,8 +873,7 @@ typedef int (*iterate_dir_item_t)(int num, struct btrfs_key *di_key, | |||
| 874 | * | 873 | * |
| 875 | * path must point to the dir item when called. | 874 | * path must point to the dir item when called. |
| 876 | */ | 875 | */ |
| 877 | static int iterate_dir_item(struct send_ctx *sctx, | 876 | static int iterate_dir_item(struct btrfs_root *root, struct btrfs_path *path, |
| 878 | struct btrfs_root *root, struct btrfs_path *path, | ||
| 879 | struct btrfs_key *found_key, | 877 | struct btrfs_key *found_key, |
| 880 | iterate_dir_item_t iterate, void *ctx) | 878 | iterate_dir_item_t iterate, void *ctx) |
| 881 | { | 879 | { |
| @@ -990,7 +988,7 @@ static int __copy_first_ref(int num, u64 dir, int index, | |||
| 990 | * Retrieve the first path of an inode. If an inode has more then one | 988 | * Retrieve the first path of an inode. If an inode has more then one |
| 991 | * ref/hardlink, this is ignored. | 989 | * ref/hardlink, this is ignored. |
| 992 | */ | 990 | */ |
| 993 | static int get_inode_path(struct send_ctx *sctx, struct btrfs_root *root, | 991 | static int get_inode_path(struct btrfs_root *root, |
| 994 | u64 ino, struct fs_path *path) | 992 | u64 ino, struct fs_path *path) |
| 995 | { | 993 | { |
| 996 | int ret; | 994 | int ret; |
| @@ -1022,8 +1020,8 @@ static int get_inode_path(struct send_ctx *sctx, struct btrfs_root *root, | |||
| 1022 | goto out; | 1020 | goto out; |
| 1023 | } | 1021 | } |
| 1024 | 1022 | ||
| 1025 | ret = iterate_inode_ref(sctx, root, p, &found_key, 1, | 1023 | ret = iterate_inode_ref(root, p, &found_key, 1, |
| 1026 | __copy_first_ref, path); | 1024 | __copy_first_ref, path); |
| 1027 | if (ret < 0) | 1025 | if (ret < 0) |
| 1028 | goto out; | 1026 | goto out; |
| 1029 | ret = 0; | 1027 | ret = 0; |
| @@ -1314,8 +1312,7 @@ out: | |||
| 1314 | return ret; | 1312 | return ret; |
| 1315 | } | 1313 | } |
| 1316 | 1314 | ||
| 1317 | static int read_symlink(struct send_ctx *sctx, | 1315 | static int read_symlink(struct btrfs_root *root, |
| 1318 | struct btrfs_root *root, | ||
| 1319 | u64 ino, | 1316 | u64 ino, |
| 1320 | struct fs_path *dest) | 1317 | struct fs_path *dest) |
| 1321 | { | 1318 | { |
| @@ -1562,8 +1559,7 @@ out: | |||
| 1562 | * Looks up the first btrfs_inode_ref of a given ino. It returns the parent dir, | 1559 | * Looks up the first btrfs_inode_ref of a given ino. It returns the parent dir, |
| 1563 | * generation of the parent dir and the name of the dir entry. | 1560 | * generation of the parent dir and the name of the dir entry. |
| 1564 | */ | 1561 | */ |
| 1565 | static int get_first_ref(struct send_ctx *sctx, | 1562 | static int get_first_ref(struct btrfs_root *root, u64 ino, |
| 1566 | struct btrfs_root *root, u64 ino, | ||
| 1567 | u64 *dir, u64 *dir_gen, struct fs_path *name) | 1563 | u64 *dir, u64 *dir_gen, struct fs_path *name) |
| 1568 | { | 1564 | { |
| 1569 | int ret; | 1565 | int ret; |
| @@ -1628,8 +1624,7 @@ out: | |||
| 1628 | return ret; | 1624 | return ret; |
| 1629 | } | 1625 | } |
| 1630 | 1626 | ||
| 1631 | static int is_first_ref(struct send_ctx *sctx, | 1627 | static int is_first_ref(struct btrfs_root *root, |
| 1632 | struct btrfs_root *root, | ||
| 1633 | u64 ino, u64 dir, | 1628 | u64 ino, u64 dir, |
| 1634 | const char *name, int name_len) | 1629 | const char *name, int name_len) |
| 1635 | { | 1630 | { |
| @@ -1638,11 +1633,11 @@ static int is_first_ref(struct send_ctx *sctx, | |||
| 1638 | u64 tmp_dir; | 1633 | u64 tmp_dir; |
| 1639 | u64 tmp_dir_gen; | 1634 | u64 tmp_dir_gen; |
| 1640 | 1635 | ||
| 1641 | tmp_name = fs_path_alloc(sctx); | 1636 | tmp_name = fs_path_alloc(); |
| 1642 | if (!tmp_name) | 1637 | if (!tmp_name) |
| 1643 | return -ENOMEM; | 1638 | return -ENOMEM; |
| 1644 | 1639 | ||
| 1645 | ret = get_first_ref(sctx, root, ino, &tmp_dir, &tmp_dir_gen, tmp_name); | 1640 | ret = get_first_ref(root, ino, &tmp_dir, &tmp_dir_gen, tmp_name); |
| 1646 | if (ret < 0) | 1641 | if (ret < 0) |
| 1647 | goto out; | 1642 | goto out; |
| 1648 | 1643 | ||
| @@ -1654,7 +1649,7 @@ static int is_first_ref(struct send_ctx *sctx, | |||
| 1654 | ret = !memcmp(tmp_name->start, name, name_len); | 1649 | ret = !memcmp(tmp_name->start, name, name_len); |
| 1655 | 1650 | ||
| 1656 | out: | 1651 | out: |
| 1657 | fs_path_free(sctx, tmp_name); | 1652 | fs_path_free(tmp_name); |
| 1658 | return ret; | 1653 | return ret; |
| 1659 | } | 1654 | } |
| 1660 | 1655 | ||
| @@ -1783,11 +1778,11 @@ static int did_overwrite_first_ref(struct send_ctx *sctx, u64 ino, u64 gen) | |||
| 1783 | if (!sctx->parent_root) | 1778 | if (!sctx->parent_root) |
| 1784 | goto out; | 1779 | goto out; |
| 1785 | 1780 | ||
| 1786 | name = fs_path_alloc(sctx); | 1781 | name = fs_path_alloc(); |
| 1787 | if (!name) | 1782 | if (!name) |
| 1788 | return -ENOMEM; | 1783 | return -ENOMEM; |
| 1789 | 1784 | ||
| 1790 | ret = get_first_ref(sctx, sctx->parent_root, ino, &dir, &dir_gen, name); | 1785 | ret = get_first_ref(sctx->parent_root, ino, &dir, &dir_gen, name); |
| 1791 | if (ret < 0) | 1786 | if (ret < 0) |
| 1792 | goto out; | 1787 | goto out; |
| 1793 | 1788 | ||
| @@ -1795,7 +1790,7 @@ static int did_overwrite_first_ref(struct send_ctx *sctx, u64 ino, u64 gen) | |||
| 1795 | name->start, fs_path_len(name)); | 1790 | name->start, fs_path_len(name)); |
| 1796 | 1791 | ||
| 1797 | out: | 1792 | out: |
| 1798 | fs_path_free(sctx, name); | 1793 | fs_path_free(name); |
| 1799 | return ret; | 1794 | return ret; |
| 1800 | } | 1795 | } |
| 1801 | 1796 | ||
| @@ -1979,11 +1974,11 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx, | |||
| 1979 | * send_root or parent_root for ref lookup. | 1974 | * send_root or parent_root for ref lookup. |
| 1980 | */ | 1975 | */ |
| 1981 | if (ino < sctx->send_progress) | 1976 | if (ino < sctx->send_progress) |
| 1982 | ret = get_first_ref(sctx, sctx->send_root, ino, | 1977 | ret = get_first_ref(sctx->send_root, ino, |
| 1983 | parent_ino, parent_gen, dest); | 1978 | parent_ino, parent_gen, dest); |
| 1984 | else | 1979 | else |
| 1985 | ret = get_first_ref(sctx, sctx->parent_root, ino, | 1980 | ret = get_first_ref(sctx->parent_root, ino, |
| 1986 | parent_ino, parent_gen, dest); | 1981 | parent_ino, parent_gen, dest); |
| 1987 | if (ret < 0) | 1982 | if (ret < 0) |
| 1988 | goto out; | 1983 | goto out; |
| 1989 | 1984 | ||
| @@ -2070,7 +2065,7 @@ static int get_cur_path(struct send_ctx *sctx, u64 ino, u64 gen, | |||
| 2070 | u64 parent_gen = 0; | 2065 | u64 parent_gen = 0; |
| 2071 | int stop = 0; | 2066 | int stop = 0; |
| 2072 | 2067 | ||
| 2073 | name = fs_path_alloc(sctx); | 2068 | name = fs_path_alloc(); |
| 2074 | if (!name) { | 2069 | if (!name) { |
| 2075 | ret = -ENOMEM; | 2070 | ret = -ENOMEM; |
| 2076 | goto out; | 2071 | goto out; |
| @@ -2098,7 +2093,7 @@ static int get_cur_path(struct send_ctx *sctx, u64 ino, u64 gen, | |||
| 2098 | } | 2093 | } |
| 2099 | 2094 | ||
| 2100 | out: | 2095 | out: |
| 2101 | fs_path_free(sctx, name); | 2096 | fs_path_free(name); |
| 2102 | if (!ret) | 2097 | if (!ret) |
| 2103 | fs_path_unreverse(dest); | 2098 | fs_path_unreverse(dest); |
| 2104 | return ret; | 2099 | return ret; |
| @@ -2263,7 +2258,7 @@ static int send_truncate(struct send_ctx *sctx, u64 ino, u64 gen, u64 size) | |||
| 2263 | 2258 | ||
| 2264 | verbose_printk("btrfs: send_truncate %llu size=%llu\n", ino, size); | 2259 | verbose_printk("btrfs: send_truncate %llu size=%llu\n", ino, size); |
| 2265 | 2260 | ||
| 2266 | p = fs_path_alloc(sctx); | 2261 | p = fs_path_alloc(); |
| 2267 | if (!p) | 2262 | if (!p) |
| 2268 | return -ENOMEM; | 2263 | return -ENOMEM; |
| 2269 | 2264 | ||
| @@ -2281,7 +2276,7 @@ verbose_printk("btrfs: send_truncate %llu size=%llu\n", ino, size); | |||
| 2281 | 2276 | ||
| 2282 | tlv_put_failure: | 2277 | tlv_put_failure: |
| 2283 | out: | 2278 | out: |
| 2284 | fs_path_free(sctx, p); | 2279 | fs_path_free(p); |
| 2285 | return ret; | 2280 | return ret; |
| 2286 | } | 2281 | } |
| 2287 | 2282 | ||
| @@ -2292,7 +2287,7 @@ static int send_chmod(struct send_ctx *sctx, u64 ino, u64 gen, u64 mode) | |||
| 2292 | 2287 | ||
| 2293 | verbose_printk("btrfs: send_chmod %llu mode=%llu\n", ino, mode); | 2288 | verbose_printk("btrfs: send_chmod %llu mode=%llu\n", ino, mode); |
| 2294 | 2289 | ||
| 2295 | p = fs_path_alloc(sctx); | 2290 | p = fs_path_alloc(); |
| 2296 | if (!p) | 2291 | if (!p) |
| 2297 | return -ENOMEM; | 2292 | return -ENOMEM; |
| 2298 | 2293 | ||
| @@ -2310,7 +2305,7 @@ verbose_printk("btrfs: send_chmod %llu mode=%llu\n", ino, mode); | |||
| 2310 | 2305 | ||
| 2311 | tlv_put_failure: | 2306 | tlv_put_failure: |
| 2312 | out: | 2307 | out: |
| 2313 | fs_path_free(sctx, p); | 2308 | fs_path_free(p); |
| 2314 | return ret; | 2309 | return ret; |
| 2315 | } | 2310 | } |
| 2316 | 2311 | ||
| @@ -2321,7 +2316,7 @@ static int send_chown(struct send_ctx *sctx, u64 ino, u64 gen, u64 uid, u64 gid) | |||
| 2321 | 2316 | ||
| 2322 | verbose_printk("btrfs: send_chown %llu uid=%llu, gid=%llu\n", ino, uid, gid); | 2317 | verbose_printk("btrfs: send_chown %llu uid=%llu, gid=%llu\n", ino, uid, gid); |
| 2323 | 2318 | ||
| 2324 | p = fs_path_alloc(sctx); | 2319 | p = fs_path_alloc(); |
| 2325 | if (!p) | 2320 | if (!p) |
| 2326 | return -ENOMEM; | 2321 | return -ENOMEM; |
| 2327 | 2322 | ||
| @@ -2340,7 +2335,7 @@ verbose_printk("btrfs: send_chown %llu uid=%llu, gid=%llu\n", ino, uid, gid); | |||
| 2340 | 2335 | ||
| 2341 | tlv_put_failure: | 2336 | tlv_put_failure: |
| 2342 | out: | 2337 | out: |
| 2343 | fs_path_free(sctx, p); | 2338 | fs_path_free(p); |
| 2344 | return ret; | 2339 | return ret; |
| 2345 | } | 2340 | } |
| 2346 | 2341 | ||
| @@ -2356,7 +2351,7 @@ static int send_utimes(struct send_ctx *sctx, u64 ino, u64 gen) | |||
| 2356 | 2351 | ||
| 2357 | verbose_printk("btrfs: send_utimes %llu\n", ino); | 2352 | verbose_printk("btrfs: send_utimes %llu\n", ino); |
| 2358 | 2353 | ||
| 2359 | p = fs_path_alloc(sctx); | 2354 | p = fs_path_alloc(); |
| 2360 | if (!p) | 2355 | if (!p) |
| 2361 | return -ENOMEM; | 2356 | return -ENOMEM; |
| 2362 | 2357 | ||
| @@ -2397,7 +2392,7 @@ verbose_printk("btrfs: send_utimes %llu\n", ino); | |||
| 2397 | 2392 | ||
| 2398 | tlv_put_failure: | 2393 | tlv_put_failure: |
| 2399 | out: | 2394 | out: |
| 2400 | fs_path_free(sctx, p); | 2395 | fs_path_free(p); |
| 2401 | btrfs_free_path(path); | 2396 | btrfs_free_path(path); |
| 2402 | return ret; | 2397 | return ret; |
| 2403 | } | 2398 | } |
| @@ -2418,7 +2413,7 @@ static int send_create_inode(struct send_ctx *sctx, u64 ino) | |||
| 2418 | 2413 | ||
| 2419 | verbose_printk("btrfs: send_create_inode %llu\n", ino); | 2414 | verbose_printk("btrfs: send_create_inode %llu\n", ino); |
| 2420 | 2415 | ||
| 2421 | p = fs_path_alloc(sctx); | 2416 | p = fs_path_alloc(); |
| 2422 | if (!p) | 2417 | if (!p) |
| 2423 | return -ENOMEM; | 2418 | return -ENOMEM; |
| 2424 | 2419 | ||
| @@ -2459,7 +2454,7 @@ verbose_printk("btrfs: send_create_inode %llu\n", ino); | |||
| 2459 | 2454 | ||
| 2460 | if (S_ISLNK(mode)) { | 2455 | if (S_ISLNK(mode)) { |
| 2461 | fs_path_reset(p); | 2456 | fs_path_reset(p); |
| 2462 | ret = read_symlink(sctx, sctx->send_root, ino, p); | 2457 | ret = read_symlink(sctx->send_root, ino, p); |
| 2463 | if (ret < 0) | 2458 | if (ret < 0) |
| 2464 | goto out; | 2459 | goto out; |
| 2465 | TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_LINK, p); | 2460 | TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_LINK, p); |
| @@ -2476,7 +2471,7 @@ verbose_printk("btrfs: send_create_inode %llu\n", ino); | |||
| 2476 | 2471 | ||
| 2477 | tlv_put_failure: | 2472 | tlv_put_failure: |
| 2478 | out: | 2473 | out: |
| 2479 | fs_path_free(sctx, p); | 2474 | fs_path_free(p); |
| 2480 | return ret; | 2475 | return ret; |
| 2481 | } | 2476 | } |
| 2482 | 2477 | ||
| @@ -2615,13 +2610,13 @@ static int record_ref(struct list_head *head, u64 dir, | |||
| 2615 | return 0; | 2610 | return 0; |
| 2616 | } | 2611 | } |
| 2617 | 2612 | ||
| 2618 | static void __free_recorded_refs(struct send_ctx *sctx, struct list_head *head) | 2613 | static void __free_recorded_refs(struct list_head *head) |
| 2619 | { | 2614 | { |
| 2620 | struct recorded_ref *cur; | 2615 | struct recorded_ref *cur; |
| 2621 | 2616 | ||
| 2622 | while (!list_empty(head)) { | 2617 | while (!list_empty(head)) { |
| 2623 | cur = list_entry(head->next, struct recorded_ref, list); | 2618 | cur = list_entry(head->next, struct recorded_ref, list); |
| 2624 | fs_path_free(sctx, cur->full_path); | 2619 | fs_path_free(cur->full_path); |
| 2625 | list_del(&cur->list); | 2620 | list_del(&cur->list); |
| 2626 | kfree(cur); | 2621 | kfree(cur); |
| 2627 | } | 2622 | } |
| @@ -2629,8 +2624,8 @@ static void __free_recorded_refs(struct send_ctx *sctx, struct list_head *head) | |||
| 2629 | 2624 | ||
| 2630 | static void free_recorded_refs(struct send_ctx *sctx) | 2625 | static void free_recorded_refs(struct send_ctx *sctx) |
| 2631 | { | 2626 | { |
| 2632 | __free_recorded_refs(sctx, &sctx->new_refs); | 2627 | __free_recorded_refs(&sctx->new_refs); |
| 2633 | __free_recorded_refs(sctx, &sctx->deleted_refs); | 2628 | __free_recorded_refs(&sctx->deleted_refs); |
| 2634 | } | 2629 | } |
| 2635 | 2630 | ||
| 2636 | /* | 2631 | /* |
| @@ -2644,7 +2639,7 @@ static int orphanize_inode(struct send_ctx *sctx, u64 ino, u64 gen, | |||
| 2644 | int ret; | 2639 | int ret; |
| 2645 | struct fs_path *orphan; | 2640 | struct fs_path *orphan; |
| 2646 | 2641 | ||
| 2647 | orphan = fs_path_alloc(sctx); | 2642 | orphan = fs_path_alloc(); |
| 2648 | if (!orphan) | 2643 | if (!orphan) |
| 2649 | return -ENOMEM; | 2644 | return -ENOMEM; |
| 2650 | 2645 | ||
| @@ -2655,7 +2650,7 @@ static int orphanize_inode(struct send_ctx *sctx, u64 ino, u64 gen, | |||
| 2655 | ret = send_rename(sctx, path, orphan); | 2650 | ret = send_rename(sctx, path, orphan); |
| 2656 | 2651 | ||
| 2657 | out: | 2652 | out: |
| 2658 | fs_path_free(sctx, orphan); | 2653 | fs_path_free(orphan); |
| 2659 | return ret; | 2654 | return ret; |
| 2660 | } | 2655 | } |
| 2661 | 2656 | ||
| @@ -2746,7 +2741,7 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); | |||
| 2746 | */ | 2741 | */ |
| 2747 | BUG_ON(sctx->cur_ino <= BTRFS_FIRST_FREE_OBJECTID); | 2742 | BUG_ON(sctx->cur_ino <= BTRFS_FIRST_FREE_OBJECTID); |
| 2748 | 2743 | ||
| 2749 | valid_path = fs_path_alloc(sctx); | 2744 | valid_path = fs_path_alloc(); |
| 2750 | if (!valid_path) { | 2745 | if (!valid_path) { |
| 2751 | ret = -ENOMEM; | 2746 | ret = -ENOMEM; |
| 2752 | goto out; | 2747 | goto out; |
| @@ -2843,9 +2838,9 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); | |||
| 2843 | if (ret < 0) | 2838 | if (ret < 0) |
| 2844 | goto out; | 2839 | goto out; |
| 2845 | if (ret) { | 2840 | if (ret) { |
| 2846 | ret = is_first_ref(sctx, sctx->parent_root, | 2841 | ret = is_first_ref(sctx->parent_root, |
| 2847 | ow_inode, cur->dir, cur->name, | 2842 | ow_inode, cur->dir, cur->name, |
| 2848 | cur->name_len); | 2843 | cur->name_len); |
| 2849 | if (ret < 0) | 2844 | if (ret < 0) |
| 2850 | goto out; | 2845 | goto out; |
| 2851 | if (ret) { | 2846 | if (ret) { |
| @@ -3024,7 +3019,7 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); | |||
| 3024 | out: | 3019 | out: |
| 3025 | free_recorded_refs(sctx); | 3020 | free_recorded_refs(sctx); |
| 3026 | ulist_free(check_dirs); | 3021 | ulist_free(check_dirs); |
| 3027 | fs_path_free(sctx, valid_path); | 3022 | fs_path_free(valid_path); |
| 3028 | return ret; | 3023 | return ret; |
| 3029 | } | 3024 | } |
| 3030 | 3025 | ||
| @@ -3037,7 +3032,7 @@ static int __record_new_ref(int num, u64 dir, int index, | |||
| 3037 | struct fs_path *p; | 3032 | struct fs_path *p; |
| 3038 | u64 gen; | 3033 | u64 gen; |
| 3039 | 3034 | ||
| 3040 | p = fs_path_alloc(sctx); | 3035 | p = fs_path_alloc(); |
| 3041 | if (!p) | 3036 | if (!p) |
| 3042 | return -ENOMEM; | 3037 | return -ENOMEM; |
| 3043 | 3038 | ||
| @@ -3057,7 +3052,7 @@ static int __record_new_ref(int num, u64 dir, int index, | |||
| 3057 | 3052 | ||
| 3058 | out: | 3053 | out: |
| 3059 | if (ret) | 3054 | if (ret) |
| 3060 | fs_path_free(sctx, p); | 3055 | fs_path_free(p); |
| 3061 | return ret; | 3056 | return ret; |
| 3062 | } | 3057 | } |
| 3063 | 3058 | ||
| @@ -3070,7 +3065,7 @@ static int __record_deleted_ref(int num, u64 dir, int index, | |||
| 3070 | struct fs_path *p; | 3065 | struct fs_path *p; |
| 3071 | u64 gen; | 3066 | u64 gen; |
| 3072 | 3067 | ||
| 3073 | p = fs_path_alloc(sctx); | 3068 | p = fs_path_alloc(); |
| 3074 | if (!p) | 3069 | if (!p) |
| 3075 | return -ENOMEM; | 3070 | return -ENOMEM; |
| 3076 | 3071 | ||
| @@ -3090,7 +3085,7 @@ static int __record_deleted_ref(int num, u64 dir, int index, | |||
| 3090 | 3085 | ||
| 3091 | out: | 3086 | out: |
| 3092 | if (ret) | 3087 | if (ret) |
| 3093 | fs_path_free(sctx, p); | 3088 | fs_path_free(p); |
| 3094 | return ret; | 3089 | return ret; |
| 3095 | } | 3090 | } |
| 3096 | 3091 | ||
| @@ -3098,8 +3093,8 @@ static int record_new_ref(struct send_ctx *sctx) | |||
| 3098 | { | 3093 | { |
| 3099 | int ret; | 3094 | int ret; |
| 3100 | 3095 | ||
| 3101 | ret = iterate_inode_ref(sctx, sctx->send_root, sctx->left_path, | 3096 | ret = iterate_inode_ref(sctx->send_root, sctx->left_path, |
| 3102 | sctx->cmp_key, 0, __record_new_ref, sctx); | 3097 | sctx->cmp_key, 0, __record_new_ref, sctx); |
| 3103 | if (ret < 0) | 3098 | if (ret < 0) |
| 3104 | goto out; | 3099 | goto out; |
| 3105 | ret = 0; | 3100 | ret = 0; |
| @@ -3112,8 +3107,8 @@ static int record_deleted_ref(struct send_ctx *sctx) | |||
| 3112 | { | 3107 | { |
| 3113 | int ret; | 3108 | int ret; |
| 3114 | 3109 | ||
| 3115 | ret = iterate_inode_ref(sctx, sctx->parent_root, sctx->right_path, | 3110 | ret = iterate_inode_ref(sctx->parent_root, sctx->right_path, |
| 3116 | sctx->cmp_key, 0, __record_deleted_ref, sctx); | 3111 | sctx->cmp_key, 0, __record_deleted_ref, sctx); |
| 3117 | if (ret < 0) | 3112 | if (ret < 0) |
| 3118 | goto out; | 3113 | goto out; |
| 3119 | ret = 0; | 3114 | ret = 0; |
| @@ -3142,8 +3137,7 @@ static int __find_iref(int num, u64 dir, int index, | |||
| 3142 | return 0; | 3137 | return 0; |
| 3143 | } | 3138 | } |
| 3144 | 3139 | ||
| 3145 | static int find_iref(struct send_ctx *sctx, | 3140 | static int find_iref(struct btrfs_root *root, |
| 3146 | struct btrfs_root *root, | ||
| 3147 | struct btrfs_path *path, | 3141 | struct btrfs_path *path, |
| 3148 | struct btrfs_key *key, | 3142 | struct btrfs_key *key, |
| 3149 | u64 dir, struct fs_path *name) | 3143 | u64 dir, struct fs_path *name) |
| @@ -3155,7 +3149,7 @@ static int find_iref(struct send_ctx *sctx, | |||
| 3155 | ctx.name = name; | 3149 | ctx.name = name; |
| 3156 | ctx.found_idx = -1; | 3150 | ctx.found_idx = -1; |
| 3157 | 3151 | ||
| 3158 | ret = iterate_inode_ref(sctx, root, path, key, 0, __find_iref, &ctx); | 3152 | ret = iterate_inode_ref(root, path, key, 0, __find_iref, &ctx); |
| 3159 | if (ret < 0) | 3153 | if (ret < 0) |
| 3160 | return ret; | 3154 | return ret; |
| 3161 | 3155 | ||
| @@ -3172,7 +3166,7 @@ static int __record_changed_new_ref(int num, u64 dir, int index, | |||
| 3172 | int ret; | 3166 | int ret; |
| 3173 | struct send_ctx *sctx = ctx; | 3167 | struct send_ctx *sctx = ctx; |
| 3174 | 3168 | ||
| 3175 | ret = find_iref(sctx, sctx->parent_root, sctx->right_path, | 3169 | ret = find_iref(sctx->parent_root, sctx->right_path, |
| 3176 | sctx->cmp_key, dir, name); | 3170 | sctx->cmp_key, dir, name); |
| 3177 | if (ret == -ENOENT) | 3171 | if (ret == -ENOENT) |
| 3178 | ret = __record_new_ref(num, dir, index, name, sctx); | 3172 | ret = __record_new_ref(num, dir, index, name, sctx); |
| @@ -3189,7 +3183,7 @@ static int __record_changed_deleted_ref(int num, u64 dir, int index, | |||
| 3189 | int ret; | 3183 | int ret; |
| 3190 | struct send_ctx *sctx = ctx; | 3184 | struct send_ctx *sctx = ctx; |
| 3191 | 3185 | ||
| 3192 | ret = find_iref(sctx, sctx->send_root, sctx->left_path, sctx->cmp_key, | 3186 | ret = find_iref(sctx->send_root, sctx->left_path, sctx->cmp_key, |
| 3193 | dir, name); | 3187 | dir, name); |
| 3194 | if (ret == -ENOENT) | 3188 | if (ret == -ENOENT) |
| 3195 | ret = __record_deleted_ref(num, dir, index, name, sctx); | 3189 | ret = __record_deleted_ref(num, dir, index, name, sctx); |
| @@ -3203,11 +3197,11 @@ static int record_changed_ref(struct send_ctx *sctx) | |||
| 3203 | { | 3197 | { |
| 3204 | int ret = 0; | 3198 | int ret = 0; |
| 3205 | 3199 | ||
| 3206 | ret = iterate_inode_ref(sctx, sctx->send_root, sctx->left_path, | 3200 | ret = iterate_inode_ref(sctx->send_root, sctx->left_path, |
| 3207 | sctx->cmp_key, 0, __record_changed_new_ref, sctx); | 3201 | sctx->cmp_key, 0, __record_changed_new_ref, sctx); |
| 3208 | if (ret < 0) | 3202 | if (ret < 0) |
| 3209 | goto out; | 3203 | goto out; |
| 3210 | ret = iterate_inode_ref(sctx, sctx->parent_root, sctx->right_path, | 3204 | ret = iterate_inode_ref(sctx->parent_root, sctx->right_path, |
| 3211 | sctx->cmp_key, 0, __record_changed_deleted_ref, sctx); | 3205 | sctx->cmp_key, 0, __record_changed_deleted_ref, sctx); |
| 3212 | if (ret < 0) | 3206 | if (ret < 0) |
| 3213 | goto out; | 3207 | goto out; |
| @@ -3266,8 +3260,7 @@ static int process_all_refs(struct send_ctx *sctx, | |||
| 3266 | found_key.type != BTRFS_INODE_EXTREF_KEY)) | 3260 | found_key.type != BTRFS_INODE_EXTREF_KEY)) |
| 3267 | break; | 3261 | break; |
| 3268 | 3262 | ||
| 3269 | ret = iterate_inode_ref(sctx, root, path, &found_key, 0, cb, | 3263 | ret = iterate_inode_ref(root, path, &found_key, 0, cb, sctx); |
| 3270 | sctx); | ||
| 3271 | btrfs_release_path(path); | 3264 | btrfs_release_path(path); |
| 3272 | if (ret < 0) | 3265 | if (ret < 0) |
| 3273 | goto out; | 3266 | goto out; |
| @@ -3335,7 +3328,7 @@ static int __process_new_xattr(int num, struct btrfs_key *di_key, | |||
| 3335 | struct fs_path *p; | 3328 | struct fs_path *p; |
| 3336 | posix_acl_xattr_header dummy_acl; | 3329 | posix_acl_xattr_header dummy_acl; |
| 3337 | 3330 | ||
| 3338 | p = fs_path_alloc(sctx); | 3331 | p = fs_path_alloc(); |
| 3339 | if (!p) | 3332 | if (!p) |
| 3340 | return -ENOMEM; | 3333 | return -ENOMEM; |
| 3341 | 3334 | ||
| @@ -3362,7 +3355,7 @@ static int __process_new_xattr(int num, struct btrfs_key *di_key, | |||
| 3362 | ret = send_set_xattr(sctx, p, name, name_len, data, data_len); | 3355 | ret = send_set_xattr(sctx, p, name, name_len, data, data_len); |
| 3363 | 3356 | ||
| 3364 | out: | 3357 | out: |
| 3365 | fs_path_free(sctx, p); | 3358 | fs_path_free(p); |
| 3366 | return ret; | 3359 | return ret; |
| 3367 | } | 3360 | } |
| 3368 | 3361 | ||
| @@ -3375,7 +3368,7 @@ static int __process_deleted_xattr(int num, struct btrfs_key *di_key, | |||
| 3375 | struct send_ctx *sctx = ctx; | 3368 | struct send_ctx *sctx = ctx; |
| 3376 | struct fs_path *p; | 3369 | struct fs_path *p; |
| 3377 | 3370 | ||
| 3378 | p = fs_path_alloc(sctx); | 3371 | p = fs_path_alloc(); |
| 3379 | if (!p) | 3372 | if (!p) |
| 3380 | return -ENOMEM; | 3373 | return -ENOMEM; |
| 3381 | 3374 | ||
| @@ -3386,7 +3379,7 @@ static int __process_deleted_xattr(int num, struct btrfs_key *di_key, | |||
| 3386 | ret = send_remove_xattr(sctx, p, name, name_len); | 3379 | ret = send_remove_xattr(sctx, p, name, name_len); |
| 3387 | 3380 | ||
| 3388 | out: | 3381 | out: |
| 3389 | fs_path_free(sctx, p); | 3382 | fs_path_free(p); |
| 3390 | return ret; | 3383 | return ret; |
| 3391 | } | 3384 | } |
| 3392 | 3385 | ||
| @@ -3394,8 +3387,8 @@ static int process_new_xattr(struct send_ctx *sctx) | |||
| 3394 | { | 3387 | { |
| 3395 | int ret = 0; | 3388 | int ret = 0; |
| 3396 | 3389 | ||
| 3397 | ret = iterate_dir_item(sctx, sctx->send_root, sctx->left_path, | 3390 | ret = iterate_dir_item(sctx->send_root, sctx->left_path, |
| 3398 | sctx->cmp_key, __process_new_xattr, sctx); | 3391 | sctx->cmp_key, __process_new_xattr, sctx); |
| 3399 | 3392 | ||
| 3400 | return ret; | 3393 | return ret; |
| 3401 | } | 3394 | } |
| @@ -3404,8 +3397,8 @@ static int process_deleted_xattr(struct send_ctx *sctx) | |||
| 3404 | { | 3397 | { |
| 3405 | int ret; | 3398 | int ret; |
| 3406 | 3399 | ||
| 3407 | ret = iterate_dir_item(sctx, sctx->parent_root, sctx->right_path, | 3400 | ret = iterate_dir_item(sctx->parent_root, sctx->right_path, |
| 3408 | sctx->cmp_key, __process_deleted_xattr, sctx); | 3401 | sctx->cmp_key, __process_deleted_xattr, sctx); |
| 3409 | 3402 | ||
| 3410 | return ret; | 3403 | return ret; |
| 3411 | } | 3404 | } |
| @@ -3429,17 +3422,15 @@ static int __find_xattr(int num, struct btrfs_key *di_key, | |||
| 3429 | strncmp(name, ctx->name, name_len) == 0) { | 3422 | strncmp(name, ctx->name, name_len) == 0) { |
| 3430 | ctx->found_idx = num; | 3423 | ctx->found_idx = num; |
| 3431 | ctx->found_data_len = data_len; | 3424 | ctx->found_data_len = data_len; |
| 3432 | ctx->found_data = kmalloc(data_len, GFP_NOFS); | 3425 | ctx->found_data = kmemdup(data, data_len, GFP_NOFS); |
| 3433 | if (!ctx->found_data) | 3426 | if (!ctx->found_data) |
| 3434 | return -ENOMEM; | 3427 | return -ENOMEM; |
| 3435 | memcpy(ctx->found_data, data, data_len); | ||
| 3436 | return 1; | 3428 | return 1; |
| 3437 | } | 3429 | } |
| 3438 | return 0; | 3430 | return 0; |
| 3439 | } | 3431 | } |
| 3440 | 3432 | ||
| 3441 | static int find_xattr(struct send_ctx *sctx, | 3433 | static int find_xattr(struct btrfs_root *root, |
| 3442 | struct btrfs_root *root, | ||
| 3443 | struct btrfs_path *path, | 3434 | struct btrfs_path *path, |
| 3444 | struct btrfs_key *key, | 3435 | struct btrfs_key *key, |
| 3445 | const char *name, int name_len, | 3436 | const char *name, int name_len, |
| @@ -3454,7 +3445,7 @@ static int find_xattr(struct send_ctx *sctx, | |||
| 3454 | ctx.found_data = NULL; | 3445 | ctx.found_data = NULL; |
| 3455 | ctx.found_data_len = 0; | 3446 | ctx.found_data_len = 0; |
| 3456 | 3447 | ||
| 3457 | ret = iterate_dir_item(sctx, root, path, key, __find_xattr, &ctx); | 3448 | ret = iterate_dir_item(root, path, key, __find_xattr, &ctx); |
| 3458 | if (ret < 0) | 3449 | if (ret < 0) |
| 3459 | return ret; | 3450 | return ret; |
| 3460 | 3451 | ||
| @@ -3480,9 +3471,9 @@ static int __process_changed_new_xattr(int num, struct btrfs_key *di_key, | |||
| 3480 | char *found_data = NULL; | 3471 | char *found_data = NULL; |
| 3481 | int found_data_len = 0; | 3472 | int found_data_len = 0; |
| 3482 | 3473 | ||
| 3483 | ret = find_xattr(sctx, sctx->parent_root, sctx->right_path, | 3474 | ret = find_xattr(sctx->parent_root, sctx->right_path, |
| 3484 | sctx->cmp_key, name, name_len, &found_data, | 3475 | sctx->cmp_key, name, name_len, &found_data, |
| 3485 | &found_data_len); | 3476 | &found_data_len); |
| 3486 | if (ret == -ENOENT) { | 3477 | if (ret == -ENOENT) { |
| 3487 | ret = __process_new_xattr(num, di_key, name, name_len, data, | 3478 | ret = __process_new_xattr(num, di_key, name, name_len, data, |
| 3488 | data_len, type, ctx); | 3479 | data_len, type, ctx); |
| @@ -3508,8 +3499,8 @@ static int __process_changed_deleted_xattr(int num, struct btrfs_key *di_key, | |||
| 3508 | int ret; | 3499 | int ret; |
| 3509 | struct send_ctx *sctx = ctx; | 3500 | struct send_ctx *sctx = ctx; |
| 3510 | 3501 | ||
| 3511 | ret = find_xattr(sctx, sctx->send_root, sctx->left_path, sctx->cmp_key, | 3502 | ret = find_xattr(sctx->send_root, sctx->left_path, sctx->cmp_key, |
| 3512 | name, name_len, NULL, NULL); | 3503 | name, name_len, NULL, NULL); |
| 3513 | if (ret == -ENOENT) | 3504 | if (ret == -ENOENT) |
| 3514 | ret = __process_deleted_xattr(num, di_key, name, name_len, data, | 3505 | ret = __process_deleted_xattr(num, di_key, name, name_len, data, |
| 3515 | data_len, type, ctx); | 3506 | data_len, type, ctx); |
| @@ -3523,11 +3514,11 @@ static int process_changed_xattr(struct send_ctx *sctx) | |||
| 3523 | { | 3514 | { |
| 3524 | int ret = 0; | 3515 | int ret = 0; |
| 3525 | 3516 | ||
| 3526 | ret = iterate_dir_item(sctx, sctx->send_root, sctx->left_path, | 3517 | ret = iterate_dir_item(sctx->send_root, sctx->left_path, |
| 3527 | sctx->cmp_key, __process_changed_new_xattr, sctx); | 3518 | sctx->cmp_key, __process_changed_new_xattr, sctx); |
| 3528 | if (ret < 0) | 3519 | if (ret < 0) |
| 3529 | goto out; | 3520 | goto out; |
| 3530 | ret = iterate_dir_item(sctx, sctx->parent_root, sctx->right_path, | 3521 | ret = iterate_dir_item(sctx->parent_root, sctx->right_path, |
| 3531 | sctx->cmp_key, __process_changed_deleted_xattr, sctx); | 3522 | sctx->cmp_key, __process_changed_deleted_xattr, sctx); |
| 3532 | 3523 | ||
| 3533 | out: | 3524 | out: |
| @@ -3572,8 +3563,8 @@ static int process_all_new_xattrs(struct send_ctx *sctx) | |||
| 3572 | goto out; | 3563 | goto out; |
| 3573 | } | 3564 | } |
| 3574 | 3565 | ||
| 3575 | ret = iterate_dir_item(sctx, root, path, &found_key, | 3566 | ret = iterate_dir_item(root, path, &found_key, |
| 3576 | __process_new_xattr, sctx); | 3567 | __process_new_xattr, sctx); |
| 3577 | if (ret < 0) | 3568 | if (ret < 0) |
| 3578 | goto out; | 3569 | goto out; |
| 3579 | 3570 | ||
| @@ -3598,7 +3589,7 @@ static int send_write(struct send_ctx *sctx, u64 offset, u32 len) | |||
| 3598 | int num_read = 0; | 3589 | int num_read = 0; |
| 3599 | mm_segment_t old_fs; | 3590 | mm_segment_t old_fs; |
| 3600 | 3591 | ||
| 3601 | p = fs_path_alloc(sctx); | 3592 | p = fs_path_alloc(); |
| 3602 | if (!p) | 3593 | if (!p) |
| 3603 | return -ENOMEM; | 3594 | return -ENOMEM; |
| 3604 | 3595 | ||
| @@ -3640,7 +3631,7 @@ verbose_printk("btrfs: send_write offset=%llu, len=%d\n", offset, len); | |||
| 3640 | 3631 | ||
| 3641 | tlv_put_failure: | 3632 | tlv_put_failure: |
| 3642 | out: | 3633 | out: |
| 3643 | fs_path_free(sctx, p); | 3634 | fs_path_free(p); |
| 3644 | set_fs(old_fs); | 3635 | set_fs(old_fs); |
| 3645 | if (ret < 0) | 3636 | if (ret < 0) |
| 3646 | return ret; | 3637 | return ret; |
| @@ -3663,7 +3654,7 @@ verbose_printk("btrfs: send_clone offset=%llu, len=%d, clone_root=%llu, " | |||
| 3663 | clone_root->root->objectid, clone_root->ino, | 3654 | clone_root->root->objectid, clone_root->ino, |
| 3664 | clone_root->offset); | 3655 | clone_root->offset); |
| 3665 | 3656 | ||
| 3666 | p = fs_path_alloc(sctx); | 3657 | p = fs_path_alloc(); |
| 3667 | if (!p) | 3658 | if (!p) |
| 3668 | return -ENOMEM; | 3659 | return -ENOMEM; |
| 3669 | 3660 | ||
| @@ -3686,8 +3677,7 @@ verbose_printk("btrfs: send_clone offset=%llu, len=%d, clone_root=%llu, " | |||
| 3686 | goto out; | 3677 | goto out; |
| 3687 | ret = get_cur_path(sctx, clone_root->ino, gen, p); | 3678 | ret = get_cur_path(sctx, clone_root->ino, gen, p); |
| 3688 | } else { | 3679 | } else { |
| 3689 | ret = get_inode_path(sctx, clone_root->root, | 3680 | ret = get_inode_path(clone_root->root, clone_root->ino, p); |
| 3690 | clone_root->ino, p); | ||
| 3691 | } | 3681 | } |
| 3692 | if (ret < 0) | 3682 | if (ret < 0) |
| 3693 | goto out; | 3683 | goto out; |
| @@ -3704,7 +3694,7 @@ verbose_printk("btrfs: send_clone offset=%llu, len=%d, clone_root=%llu, " | |||
| 3704 | 3694 | ||
| 3705 | tlv_put_failure: | 3695 | tlv_put_failure: |
| 3706 | out: | 3696 | out: |
| 3707 | fs_path_free(sctx, p); | 3697 | fs_path_free(p); |
| 3708 | return ret; | 3698 | return ret; |
| 3709 | } | 3699 | } |
| 3710 | 3700 | ||
| @@ -3717,7 +3707,7 @@ static int send_update_extent(struct send_ctx *sctx, | |||
| 3717 | int ret = 0; | 3707 | int ret = 0; |
| 3718 | struct fs_path *p; | 3708 | struct fs_path *p; |
| 3719 | 3709 | ||
| 3720 | p = fs_path_alloc(sctx); | 3710 | p = fs_path_alloc(); |
| 3721 | if (!p) | 3711 | if (!p) |
| 3722 | return -ENOMEM; | 3712 | return -ENOMEM; |
| 3723 | 3713 | ||
| @@ -3737,7 +3727,7 @@ static int send_update_extent(struct send_ctx *sctx, | |||
| 3737 | 3727 | ||
| 3738 | tlv_put_failure: | 3728 | tlv_put_failure: |
| 3739 | out: | 3729 | out: |
| 3740 | fs_path_free(sctx, p); | 3730 | fs_path_free(p); |
| 3741 | return ret; | 3731 | return ret; |
| 3742 | } | 3732 | } |
| 3743 | 3733 | ||
| @@ -4579,6 +4569,41 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) | |||
| 4579 | send_root = BTRFS_I(file_inode(mnt_file))->root; | 4569 | send_root = BTRFS_I(file_inode(mnt_file))->root; |
| 4580 | fs_info = send_root->fs_info; | 4570 | fs_info = send_root->fs_info; |
| 4581 | 4571 | ||
| 4572 | /* | ||
| 4573 | * This is done when we lookup the root, it should already be complete | ||
| 4574 | * by the time we get here. | ||
| 4575 | */ | ||
| 4576 | WARN_ON(send_root->orphan_cleanup_state != ORPHAN_CLEANUP_DONE); | ||
| 4577 | |||
| 4578 | /* | ||
| 4579 | * If we just created this root we need to make sure that the orphan | ||
| 4580 | * cleanup has been done and committed since we search the commit root, | ||
| 4581 | * so check its commit root transid with our otransid and if they match | ||
| 4582 | * commit the transaction to make sure everything is updated. | ||
| 4583 | */ | ||
| 4584 | down_read(&send_root->fs_info->extent_commit_sem); | ||
| 4585 | if (btrfs_header_generation(send_root->commit_root) == | ||
| 4586 | btrfs_root_otransid(&send_root->root_item)) { | ||
| 4587 | struct btrfs_trans_handle *trans; | ||
| 4588 | |||
| 4589 | up_read(&send_root->fs_info->extent_commit_sem); | ||
| 4590 | |||
| 4591 | trans = btrfs_attach_transaction_barrier(send_root); | ||
| 4592 | if (IS_ERR(trans)) { | ||
| 4593 | if (PTR_ERR(trans) != -ENOENT) { | ||
| 4594 | ret = PTR_ERR(trans); | ||
| 4595 | goto out; | ||
| 4596 | } | ||
| 4597 | /* ENOENT means theres no transaction */ | ||
| 4598 | } else { | ||
| 4599 | ret = btrfs_commit_transaction(trans, send_root); | ||
| 4600 | if (ret) | ||
| 4601 | goto out; | ||
| 4602 | } | ||
| 4603 | } else { | ||
| 4604 | up_read(&send_root->fs_info->extent_commit_sem); | ||
| 4605 | } | ||
| 4606 | |||
| 4582 | arg = memdup_user(arg_, sizeof(*arg)); | 4607 | arg = memdup_user(arg_, sizeof(*arg)); |
| 4583 | if (IS_ERR(arg)) { | 4608 | if (IS_ERR(arg)) { |
| 4584 | ret = PTR_ERR(arg); | 4609 | ret = PTR_ERR(arg); |
| @@ -4663,10 +4688,6 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) | |||
| 4663 | key.type = BTRFS_ROOT_ITEM_KEY; | 4688 | key.type = BTRFS_ROOT_ITEM_KEY; |
| 4664 | key.offset = (u64)-1; | 4689 | key.offset = (u64)-1; |
| 4665 | clone_root = btrfs_read_fs_root_no_name(fs_info, &key); | 4690 | clone_root = btrfs_read_fs_root_no_name(fs_info, &key); |
| 4666 | if (!clone_root) { | ||
| 4667 | ret = -EINVAL; | ||
| 4668 | goto out; | ||
| 4669 | } | ||
| 4670 | if (IS_ERR(clone_root)) { | 4691 | if (IS_ERR(clone_root)) { |
| 4671 | ret = PTR_ERR(clone_root); | 4692 | ret = PTR_ERR(clone_root); |
| 4672 | goto out; | 4693 | goto out; |
| @@ -4682,8 +4703,8 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) | |||
| 4682 | key.type = BTRFS_ROOT_ITEM_KEY; | 4703 | key.type = BTRFS_ROOT_ITEM_KEY; |
| 4683 | key.offset = (u64)-1; | 4704 | key.offset = (u64)-1; |
| 4684 | sctx->parent_root = btrfs_read_fs_root_no_name(fs_info, &key); | 4705 | sctx->parent_root = btrfs_read_fs_root_no_name(fs_info, &key); |
| 4685 | if (!sctx->parent_root) { | 4706 | if (IS_ERR(sctx->parent_root)) { |
| 4686 | ret = -EINVAL; | 4707 | ret = PTR_ERR(sctx->parent_root); |
| 4687 | goto out; | 4708 | goto out; |
| 4688 | } | 4709 | } |
| 4689 | } | 4710 | } |
