aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJan Schmidt <list.btrfs@jan-o-sch.net>2012-08-17 17:04:41 -0400
committerChris Mason <chris.mason@fusionio.com>2012-10-08 20:09:02 -0400
commit5a1d7843ca4b3a9009bea87f85ad33854b910aea (patch)
tree37622948b54f5123c8b816a21f7f76a202f74710 /fs
parent0aa4a17d8232e7d8a42763b53bb9943bc0484b18 (diff)
btrfs: improved readablity for add_inode_ref
Moved part of the code into a sub function and replaced most of the gotos by ifs, hoping that it will be easier to read now. Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net> Signed-off-by: Mark Fasheh <mfasheh@suse.de>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/tree-log.c178
1 files changed, 97 insertions, 81 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index e0ef92f91d66..15dae589e59f 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -785,76 +785,18 @@ out:
785 return match; 785 return match;
786} 786}
787 787
788 788static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
789/*
790 * replay one inode back reference item found in the log tree.
791 * eb, slot and key refer to the buffer and key found in the log tree.
792 * root is the destination we are replaying into, and path is for temp
793 * use by this function. (it should be released on return).
794 */
795static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
796 struct btrfs_root *root, 789 struct btrfs_root *root,
797 struct btrfs_root *log,
798 struct btrfs_path *path, 790 struct btrfs_path *path,
799 struct extent_buffer *eb, int slot, 791 struct btrfs_root *log_root,
800 struct btrfs_key *key) 792 struct inode *dir, struct inode *inode,
793 struct btrfs_key *key,
794 struct extent_buffer *eb,
795 struct btrfs_inode_ref *ref,
796 char *name, int namelen, int *search_done)
801{ 797{
802 struct btrfs_inode_ref *ref;
803 struct btrfs_dir_item *di;
804 struct inode *dir;
805 struct inode *inode;
806 unsigned long ref_ptr;
807 unsigned long ref_end;
808 char *name;
809 int namelen;
810 int ret; 798 int ret;
811 int search_done = 0; 799 struct btrfs_dir_item *di;
812
813 /*
814 * it is possible that we didn't log all the parent directories
815 * for a given inode. If we don't find the dir, just don't
816 * copy the back ref in. The link count fixup code will take
817 * care of the rest
818 */
819 dir = read_one_inode(root, key->offset);
820 if (!dir)
821 return -ENOENT;
822
823 inode = read_one_inode(root, key->objectid);
824 if (!inode) {
825 iput(dir);
826 return -EIO;
827 }
828
829 ref_ptr = btrfs_item_ptr_offset(eb, slot);
830 ref_end = ref_ptr + btrfs_item_size_nr(eb, slot);
831
832again:
833 ref = (struct btrfs_inode_ref *)ref_ptr;
834
835 namelen = btrfs_inode_ref_name_len(eb, ref);
836 name = kmalloc(namelen, GFP_NOFS);
837 BUG_ON(!name);
838
839 read_extent_buffer(eb, name, (unsigned long)(ref + 1), namelen);
840
841 /* if we already have a perfect match, we're done */
842 if (inode_in_dir(root, path, btrfs_ino(dir), btrfs_ino(inode),
843 btrfs_inode_ref_index(eb, ref),
844 name, namelen)) {
845 goto out;
846 }
847
848 /*
849 * look for a conflicting back reference in the metadata.
850 * if we find one we have to unlink that name of the file
851 * before we add our new link. Later on, we overwrite any
852 * existing back reference, and we don't want to create
853 * dangling pointers in the directory.
854 */
855
856 if (search_done)
857 goto insert;
858 800
859 ret = btrfs_search_slot(NULL, root, key, path, 0, 0); 801 ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
860 if (ret == 0) { 802 if (ret == 0) {
@@ -869,7 +811,7 @@ again:
869 * if so, just jump out, we're done 811 * if so, just jump out, we're done
870 */ 812 */
871 if (key->objectid == key->offset) 813 if (key->objectid == key->offset)
872 goto out_nowrite; 814 return 1;
873 815
874 /* check all the names in this back reference to see 816 /* check all the names in this back reference to see
875 * if they are in the log. if so, we allow them to stay 817 * if they are in the log. if so, we allow them to stay
@@ -888,7 +830,7 @@ again:
888 (unsigned long)(victim_ref + 1), 830 (unsigned long)(victim_ref + 1),
889 victim_name_len); 831 victim_name_len);
890 832
891 if (!backref_in_log(log, key, victim_name, 833 if (!backref_in_log(log_root, key, victim_name,
892 victim_name_len)) { 834 victim_name_len)) {
893 btrfs_inc_nlink(inode); 835 btrfs_inc_nlink(inode);
894 btrfs_release_path(path); 836 btrfs_release_path(path);
@@ -907,7 +849,7 @@ again:
907 * NOTE: we have searched root tree and checked the 849 * NOTE: we have searched root tree and checked the
908 * coresponding ref, it does not need to check again. 850 * coresponding ref, it does not need to check again.
909 */ 851 */
910 search_done = 1; 852 *search_done = 1;
911 } 853 }
912 btrfs_release_path(path); 854 btrfs_release_path(path);
913 855
@@ -930,25 +872,99 @@ again:
930 } 872 }
931 btrfs_release_path(path); 873 btrfs_release_path(path);
932 874
933insert: 875 return 0;
934 /* insert our name */ 876}
935 ret = btrfs_add_link(trans, dir, inode, name, namelen, 0, 877
936 btrfs_inode_ref_index(eb, ref)); 878/*
937 BUG_ON(ret); 879 * replay one inode back reference item found in the log tree.
880 * eb, slot and key refer to the buffer and key found in the log tree.
881 * root is the destination we are replaying into, and path is for temp
882 * use by this function. (it should be released on return).
883 */
884static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
885 struct btrfs_root *root,
886 struct btrfs_root *log,
887 struct btrfs_path *path,
888 struct extent_buffer *eb, int slot,
889 struct btrfs_key *key)
890{
891 struct btrfs_inode_ref *ref;
892 struct inode *dir;
893 struct inode *inode;
894 unsigned long ref_ptr;
895 unsigned long ref_end;
896 char *name;
897 int namelen;
898 int ret;
899 int search_done = 0;
900
901 /*
902 * it is possible that we didn't log all the parent directories
903 * for a given inode. If we don't find the dir, just don't
904 * copy the back ref in. The link count fixup code will take
905 * care of the rest
906 */
907 dir = read_one_inode(root, key->offset);
908 if (!dir)
909 return -ENOENT;
938 910
939 btrfs_update_inode(trans, root, inode); 911 inode = read_one_inode(root, key->objectid);
912 if (!inode) {
913 iput(dir);
914 return -EIO;
915 }
940 916
941out: 917 ref_ptr = btrfs_item_ptr_offset(eb, slot);
942 ref_ptr = (unsigned long)(ref + 1) + namelen; 918 ref_end = ref_ptr + btrfs_item_size_nr(eb, slot);
943 kfree(name); 919
944 if (ref_ptr < ref_end) 920 while (ref_ptr < ref_end) {
945 goto again; 921 ref = (struct btrfs_inode_ref *)ref_ptr;
922
923 namelen = btrfs_inode_ref_name_len(eb, ref);
924 name = kmalloc(namelen, GFP_NOFS);
925 BUG_ON(!name);
926
927 read_extent_buffer(eb, name, (unsigned long)(ref + 1), namelen);
928
929 /* if we already have a perfect match, we're done */
930 if (!inode_in_dir(root, path, btrfs_ino(dir), btrfs_ino(inode),
931 btrfs_inode_ref_index(eb, ref),
932 name, namelen)) {
933 /*
934 * look for a conflicting back reference in the
935 * metadata. if we find one we have to unlink that name
936 * of the file before we add our new link. Later on, we
937 * overwrite any existing back reference, and we don't
938 * want to create dangling pointers in the directory.
939 */
940
941 if (!search_done) {
942 ret = __add_inode_ref(trans, root, path, log,
943 dir, inode, key, eb, ref,
944 name, namelen,
945 &search_done);
946 if (ret == 1)
947 goto out;
948 BUG_ON(ret);
949 }
950
951 /* insert our name */
952 ret = btrfs_add_link(trans, dir, inode, name, namelen,
953 0, btrfs_inode_ref_index(eb, ref));
954 BUG_ON(ret);
955
956 btrfs_update_inode(trans, root, inode);
957 }
958
959 ref_ptr = (unsigned long)(ref + 1) + namelen;
960 kfree(name);
961 }
946 962
947 /* finally write the back reference in the inode */ 963 /* finally write the back reference in the inode */
948 ret = overwrite_item(trans, root, path, eb, slot, key); 964 ret = overwrite_item(trans, root, path, eb, slot, key);
949 BUG_ON(ret); 965 BUG_ON(ret);
950 966
951out_nowrite: 967out:
952 btrfs_release_path(path); 968 btrfs_release_path(path);
953 iput(dir); 969 iput(dir);
954 iput(inode); 970 iput(inode);