send.c (ef8c029fa793423439e67ef0416b220d3fa3321a) send.c (96b5bd777118bb673b458b41bbefc7f0f31d65c9)
1/*
2 * Copyright (C) 2012 Alexander Block. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License v2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,

--- 731 unchanged lines hidden (view full) ---

740 return ret;
741}
742
743typedef int (*iterate_inode_ref_t)(int num, u64 dir, int index,
744 struct fs_path *p,
745 void *ctx);
746
747/*
1/*
2 * Copyright (C) 2012 Alexander Block. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License v2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,

--- 731 unchanged lines hidden (view full) ---

740 return ret;
741}
742
743typedef int (*iterate_inode_ref_t)(int num, u64 dir, int index,
744 struct fs_path *p,
745 void *ctx);
746
747/*
748 * Helper function to iterate the entries in ONE btrfs_inode_ref.
748 * Helper function to iterate the entries in ONE btrfs_inode_ref or
749 * btrfs_inode_extref.
749 * The iterate callback may return a non zero value to stop iteration. This can
750 * be a negative value for error codes or 1 to simply stop it.
751 *
750 * The iterate callback may return a non zero value to stop iteration. This can
751 * be a negative value for error codes or 1 to simply stop it.
752 *
752 * path must point to the INODE_REF when called.
753 * path must point to the INODE_REF or INODE_EXTREF when called.
753 */
754static int iterate_inode_ref(struct send_ctx *sctx,
755 struct btrfs_root *root, struct btrfs_path *path,
756 struct btrfs_key *found_key, int resolve,
757 iterate_inode_ref_t iterate, void *ctx)
758{
754 */
755static int iterate_inode_ref(struct send_ctx *sctx,
756 struct btrfs_root *root, struct btrfs_path *path,
757 struct btrfs_key *found_key, int resolve,
758 iterate_inode_ref_t iterate, void *ctx)
759{
759 struct extent_buffer *eb;
760 struct extent_buffer *eb = path->nodes[0];
760 struct btrfs_item *item;
761 struct btrfs_inode_ref *iref;
761 struct btrfs_item *item;
762 struct btrfs_inode_ref *iref;
763 struct btrfs_inode_extref *extref;
762 struct btrfs_path *tmp_path;
763 struct fs_path *p;
764 struct btrfs_path *tmp_path;
765 struct fs_path *p;
764 u32 cur;
765 u32 len;
766 u32 cur = 0;
766 u32 total;
767 u32 total;
767 int slot;
768 int slot = path->slots[0];
768 u32 name_len;
769 char *start;
770 int ret = 0;
769 u32 name_len;
770 char *start;
771 int ret = 0;
771 int num;
772 int num = 0;
772 int index;
773 int index;
774 u64 dir;
775 unsigned long name_off;
776 unsigned long elem_size;
777 unsigned long ptr;
773
774 p = fs_path_alloc_reversed(sctx);
775 if (!p)
776 return -ENOMEM;
777
778 tmp_path = alloc_path_for_send();
779 if (!tmp_path) {
780 fs_path_free(sctx, p);
781 return -ENOMEM;
782 }
783
778
779 p = fs_path_alloc_reversed(sctx);
780 if (!p)
781 return -ENOMEM;
782
783 tmp_path = alloc_path_for_send();
784 if (!tmp_path) {
785 fs_path_free(sctx, p);
786 return -ENOMEM;
787 }
788
784 eb = path->nodes[0];
785 slot = path->slots[0];
786 item = btrfs_item_nr(eb, slot);
787 iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref);
788 cur = 0;
789 len = 0;
790 total = btrfs_item_size(eb, item);
791
789
792 num = 0;
790 if (found_key->type == BTRFS_INODE_REF_KEY) {
791 ptr = (unsigned long)btrfs_item_ptr(eb, slot,
792 struct btrfs_inode_ref);
793 item = btrfs_item_nr(eb, slot);
794 total = btrfs_item_size(eb, item);
795 elem_size = sizeof(*iref);
796 } else {
797 ptr = btrfs_item_ptr_offset(eb, slot);
798 total = btrfs_item_size_nr(eb, slot);
799 elem_size = sizeof(*extref);
800 }
801
793 while (cur < total) {
794 fs_path_reset(p);
795
802 while (cur < total) {
803 fs_path_reset(p);
804
796 name_len = btrfs_inode_ref_name_len(eb, iref);
797 index = btrfs_inode_ref_index(eb, iref);
805 if (found_key->type == BTRFS_INODE_REF_KEY) {
806 iref = (struct btrfs_inode_ref *)(ptr + cur);
807 name_len = btrfs_inode_ref_name_len(eb, iref);
808 name_off = (unsigned long)(iref + 1);
809 index = btrfs_inode_ref_index(eb, iref);
810 dir = found_key->offset;
811 } else {
812 extref = (struct btrfs_inode_extref *)(ptr + cur);
813 name_len = btrfs_inode_extref_name_len(eb, extref);
814 name_off = (unsigned long)&extref->name;
815 index = btrfs_inode_extref_index(eb, extref);
816 dir = btrfs_inode_extref_parent(eb, extref);
817 }
818
798 if (resolve) {
819 if (resolve) {
799 start = btrfs_iref_to_path(root, tmp_path, iref, eb,
800 found_key->offset, p->buf,
801 p->buf_len);
820 start = btrfs_ref_to_path(root, tmp_path, name_len,
821 name_off, eb, dir,
822 p->buf, p->buf_len);
802 if (IS_ERR(start)) {
803 ret = PTR_ERR(start);
804 goto out;
805 }
806 if (start < p->buf) {
807 /* overflow , try again with larger buffer */
808 ret = fs_path_ensure_buf(p,
809 p->buf_len + p->buf - start);
810 if (ret < 0)
811 goto out;
823 if (IS_ERR(start)) {
824 ret = PTR_ERR(start);
825 goto out;
826 }
827 if (start < p->buf) {
828 /* overflow , try again with larger buffer */
829 ret = fs_path_ensure_buf(p,
830 p->buf_len + p->buf - start);
831 if (ret < 0)
832 goto out;
812 start = btrfs_iref_to_path(root, tmp_path, iref,
813 eb, found_key->offset, p->buf,
814 p->buf_len);
833 start = btrfs_ref_to_path(root, tmp_path,
834 name_len, name_off,
835 eb, dir,
836 p->buf, p->buf_len);
815 if (IS_ERR(start)) {
816 ret = PTR_ERR(start);
817 goto out;
818 }
819 BUG_ON(start < p->buf);
820 }
821 p->start = start;
822 } else {
837 if (IS_ERR(start)) {
838 ret = PTR_ERR(start);
839 goto out;
840 }
841 BUG_ON(start < p->buf);
842 }
843 p->start = start;
844 } else {
823 ret = fs_path_add_from_extent_buffer(p, eb,
824 (unsigned long)(iref + 1), name_len);
845 ret = fs_path_add_from_extent_buffer(p, eb, name_off,
846 name_len);
825 if (ret < 0)
826 goto out;
827 }
828
847 if (ret < 0)
848 goto out;
849 }
850
829
830 len = sizeof(*iref) + name_len;
831 iref = (struct btrfs_inode_ref *)((char *)iref + len);
832 cur += len;
833
834 ret = iterate(num, found_key->offset, index, p, ctx);
851 cur += elem_size + name_len;
852 ret = iterate(num, dir, index, p, ctx);
835 if (ret)
836 goto out;
853 if (ret)
854 goto out;
837
838 num++;
839 }
840
841out:
842 btrfs_free_path(tmp_path);
843 fs_path_free(sctx, p);
844 return ret;
845}

--- 147 unchanged lines hidden (view full) ---

993 if (ret < 0)
994 goto out;
995 if (ret) {
996 ret = 1;
997 goto out;
998 }
999 btrfs_item_key_to_cpu(p->nodes[0], &found_key, p->slots[0]);
1000 if (found_key.objectid != ino ||
855 num++;
856 }
857
858out:
859 btrfs_free_path(tmp_path);
860 fs_path_free(sctx, p);
861 return ret;
862}

--- 147 unchanged lines hidden (view full) ---

1010 if (ret < 0)
1011 goto out;
1012 if (ret) {
1013 ret = 1;
1014 goto out;
1015 }
1016 btrfs_item_key_to_cpu(p->nodes[0], &found_key, p->slots[0]);
1017 if (found_key.objectid != ino ||
1001 found_key.type != BTRFS_INODE_REF_KEY) {
1018 (found_key.type != BTRFS_INODE_REF_KEY &&
1019 found_key.type != BTRFS_INODE_EXTREF_KEY)) {
1002 ret = -ENOENT;
1003 goto out;
1004 }
1005
1006 ret = iterate_inode_ref(sctx, root, p, &found_key, 1,
1007 __copy_first_ref, path);
1008 if (ret < 0)
1009 goto out;

--- 536 unchanged lines hidden (view full) ---

1546static int get_first_ref(struct send_ctx *sctx,
1547 struct btrfs_root *root, u64 ino,
1548 u64 *dir, u64 *dir_gen, struct fs_path *name)
1549{
1550 int ret;
1551 struct btrfs_key key;
1552 struct btrfs_key found_key;
1553 struct btrfs_path *path;
1020 ret = -ENOENT;
1021 goto out;
1022 }
1023
1024 ret = iterate_inode_ref(sctx, root, p, &found_key, 1,
1025 __copy_first_ref, path);
1026 if (ret < 0)
1027 goto out;

--- 536 unchanged lines hidden (view full) ---

1564static int get_first_ref(struct send_ctx *sctx,
1565 struct btrfs_root *root, u64 ino,
1566 u64 *dir, u64 *dir_gen, struct fs_path *name)
1567{
1568 int ret;
1569 struct btrfs_key key;
1570 struct btrfs_key found_key;
1571 struct btrfs_path *path;
1554 struct btrfs_inode_ref *iref;
1555 int len;
1572 int len;
1573 u64 parent_dir;
1556
1557 path = alloc_path_for_send();
1558 if (!path)
1559 return -ENOMEM;
1560
1561 key.objectid = ino;
1562 key.type = BTRFS_INODE_REF_KEY;
1563 key.offset = 0;
1564
1565 ret = btrfs_search_slot_for_read(root, &key, path, 1, 0);
1566 if (ret < 0)
1567 goto out;
1568 if (!ret)
1569 btrfs_item_key_to_cpu(path->nodes[0], &found_key,
1570 path->slots[0]);
1574
1575 path = alloc_path_for_send();
1576 if (!path)
1577 return -ENOMEM;
1578
1579 key.objectid = ino;
1580 key.type = BTRFS_INODE_REF_KEY;
1581 key.offset = 0;
1582
1583 ret = btrfs_search_slot_for_read(root, &key, path, 1, 0);
1584 if (ret < 0)
1585 goto out;
1586 if (!ret)
1587 btrfs_item_key_to_cpu(path->nodes[0], &found_key,
1588 path->slots[0]);
1571 if (ret || found_key.objectid != key.objectid ||
1572 found_key.type != key.type) {
1589 if (ret || found_key.objectid != ino ||
1590 (found_key.type != BTRFS_INODE_REF_KEY &&
1591 found_key.type != BTRFS_INODE_EXTREF_KEY)) {
1573 ret = -ENOENT;
1574 goto out;
1575 }
1576
1592 ret = -ENOENT;
1593 goto out;
1594 }
1595
1577 iref = btrfs_item_ptr(path->nodes[0], path->slots[0],
1578 struct btrfs_inode_ref);
1579 len = btrfs_inode_ref_name_len(path->nodes[0], iref);
1580 ret = fs_path_add_from_extent_buffer(name, path->nodes[0],
1581 (unsigned long)(iref + 1), len);
1596 if (key.type == BTRFS_INODE_REF_KEY) {
1597 struct btrfs_inode_ref *iref;
1598 iref = btrfs_item_ptr(path->nodes[0], path->slots[0],
1599 struct btrfs_inode_ref);
1600 len = btrfs_inode_ref_name_len(path->nodes[0], iref);
1601 ret = fs_path_add_from_extent_buffer(name, path->nodes[0],
1602 (unsigned long)(iref + 1),
1603 len);
1604 parent_dir = found_key.offset;
1605 } else {
1606 struct btrfs_inode_extref *extref;
1607 extref = btrfs_item_ptr(path->nodes[0], path->slots[0],
1608 struct btrfs_inode_extref);
1609 len = btrfs_inode_extref_name_len(path->nodes[0], extref);
1610 ret = fs_path_add_from_extent_buffer(name, path->nodes[0],
1611 (unsigned long)&extref->name, len);
1612 parent_dir = btrfs_inode_extref_parent(path->nodes[0], extref);
1613 }
1582 if (ret < 0)
1583 goto out;
1584 btrfs_release_path(path);
1585
1614 if (ret < 0)
1615 goto out;
1616 btrfs_release_path(path);
1617
1586 ret = get_inode_info(root, found_key.offset, NULL, dir_gen, NULL, NULL,
1618 ret = get_inode_info(root, parent_dir, NULL, dir_gen, NULL, NULL,
1587 NULL, NULL);
1588 if (ret < 0)
1589 goto out;
1590
1619 NULL, NULL);
1620 if (ret < 0)
1621 goto out;
1622
1591 *dir = found_key.offset;
1623 *dir = parent_dir;
1592
1593out:
1594 btrfs_free_path(path);
1595 return ret;
1596}
1597
1598static int is_first_ref(struct send_ctx *sctx,
1599 struct btrfs_root *root,

--- 1621 unchanged lines hidden (view full) ---

3221 if (ret)
3222 break;
3223
3224 eb = path->nodes[0];
3225 slot = path->slots[0];
3226 btrfs_item_key_to_cpu(eb, &found_key, slot);
3227
3228 if (found_key.objectid != key.objectid ||
1624
1625out:
1626 btrfs_free_path(path);
1627 return ret;
1628}
1629
1630static int is_first_ref(struct send_ctx *sctx,
1631 struct btrfs_root *root,

--- 1621 unchanged lines hidden (view full) ---

3253 if (ret)
3254 break;
3255
3256 eb = path->nodes[0];
3257 slot = path->slots[0];
3258 btrfs_item_key_to_cpu(eb, &found_key, slot);
3259
3260 if (found_key.objectid != key.objectid ||
3229 found_key.type != key.type)
3261 (found_key.type != BTRFS_INODE_REF_KEY &&
3262 found_key.type != BTRFS_INODE_EXTREF_KEY))
3230 break;
3231
3232 ret = iterate_inode_ref(sctx, root, path, &found_key, 0, cb,
3233 sctx);
3234 btrfs_release_path(path);
3235 if (ret < 0)
3236 goto out;
3237

--- 744 unchanged lines hidden (view full) ---

3982
3983static int process_recorded_refs_if_needed(struct send_ctx *sctx, int at_end)
3984{
3985 int ret = 0;
3986
3987 if (sctx->cur_ino == 0)
3988 goto out;
3989 if (!at_end && sctx->cur_ino == sctx->cmp_key->objectid &&
3263 break;
3264
3265 ret = iterate_inode_ref(sctx, root, path, &found_key, 0, cb,
3266 sctx);
3267 btrfs_release_path(path);
3268 if (ret < 0)
3269 goto out;
3270

--- 744 unchanged lines hidden (view full) ---

4015
4016static int process_recorded_refs_if_needed(struct send_ctx *sctx, int at_end)
4017{
4018 int ret = 0;
4019
4020 if (sctx->cur_ino == 0)
4021 goto out;
4022 if (!at_end && sctx->cur_ino == sctx->cmp_key->objectid &&
3990 sctx->cmp_key->type <= BTRFS_INODE_REF_KEY)
4023 sctx->cmp_key->type <= BTRFS_INODE_EXTREF_KEY)
3991 goto out;
3992 if (list_empty(&sctx->new_refs) && list_empty(&sctx->deleted_refs))
3993 goto out;
3994
3995 ret = process_recorded_refs(sctx);
3996 if (ret < 0)
3997 goto out;
3998

--- 331 unchanged lines hidden (view full) ---

4330
4331 /* Ignore non-FS objects */
4332 if (key->objectid == BTRFS_FREE_INO_OBJECTID ||
4333 key->objectid == BTRFS_FREE_SPACE_OBJECTID)
4334 goto out;
4335
4336 if (key->type == BTRFS_INODE_ITEM_KEY)
4337 ret = changed_inode(sctx, result);
4024 goto out;
4025 if (list_empty(&sctx->new_refs) && list_empty(&sctx->deleted_refs))
4026 goto out;
4027
4028 ret = process_recorded_refs(sctx);
4029 if (ret < 0)
4030 goto out;
4031

--- 331 unchanged lines hidden (view full) ---

4363
4364 /* Ignore non-FS objects */
4365 if (key->objectid == BTRFS_FREE_INO_OBJECTID ||
4366 key->objectid == BTRFS_FREE_SPACE_OBJECTID)
4367 goto out;
4368
4369 if (key->type == BTRFS_INODE_ITEM_KEY)
4370 ret = changed_inode(sctx, result);
4338 else if (key->type == BTRFS_INODE_REF_KEY)
4371 else if (key->type == BTRFS_INODE_REF_KEY ||
4372 key->type == BTRFS_INODE_EXTREF_KEY)
4339 ret = changed_ref(sctx, result);
4340 else if (key->type == BTRFS_XATTR_ITEM_KEY)
4341 ret = changed_xattr(sctx, result);
4342 else if (key->type == BTRFS_EXTENT_DATA_KEY)
4343 ret = changed_extent(sctx, result);
4344
4345out:
4346 return ret;

--- 313 unchanged lines hidden ---
4373 ret = changed_ref(sctx, result);
4374 else if (key->type == BTRFS_XATTR_ITEM_KEY)
4375 ret = changed_xattr(sctx, result);
4376 else if (key->type == BTRFS_EXTENT_DATA_KEY)
4377 ret = changed_extent(sctx, result);
4378
4379out:
4380 return ret;

--- 313 unchanged lines hidden ---