aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/the_nilfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nilfs2/the_nilfs.c')
-rw-r--r--fs/nilfs2/the_nilfs.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
index 6a012b9e1b31..f1d599273d9e 100644
--- a/fs/nilfs2/the_nilfs.c
+++ b/fs/nilfs2/the_nilfs.c
@@ -89,6 +89,8 @@ static struct the_nilfs *alloc_nilfs(struct block_device *bdev)
89 INIT_LIST_HEAD(&nilfs->ns_supers); 89 INIT_LIST_HEAD(&nilfs->ns_supers);
90 INIT_LIST_HEAD(&nilfs->ns_gc_inodes); 90 INIT_LIST_HEAD(&nilfs->ns_gc_inodes);
91 spin_lock_init(&nilfs->ns_last_segment_lock); 91 spin_lock_init(&nilfs->ns_last_segment_lock);
92 nilfs->ns_cptree = RB_ROOT;
93 spin_lock_init(&nilfs->ns_cptree_lock);
92 init_rwsem(&nilfs->ns_segctor_sem); 94 init_rwsem(&nilfs->ns_segctor_sem);
93 95
94 return nilfs; 96 return nilfs;
@@ -809,6 +811,96 @@ int nilfs_near_disk_full(struct the_nilfs *nilfs)
809 return ncleansegs <= nilfs->ns_nrsvsegs + nincsegs; 811 return ncleansegs <= nilfs->ns_nrsvsegs + nincsegs;
810} 812}
811 813
814struct nilfs_root *nilfs_lookup_root(struct the_nilfs *nilfs, __u64 cno)
815{
816 struct rb_node *n;
817 struct nilfs_root *root;
818
819 spin_lock(&nilfs->ns_cptree_lock);
820 n = nilfs->ns_cptree.rb_node;
821 while (n) {
822 root = rb_entry(n, struct nilfs_root, rb_node);
823
824 if (cno < root->cno) {
825 n = n->rb_left;
826 } else if (cno > root->cno) {
827 n = n->rb_right;
828 } else {
829 atomic_inc(&root->count);
830 spin_unlock(&nilfs->ns_cptree_lock);
831 return root;
832 }
833 }
834 spin_unlock(&nilfs->ns_cptree_lock);
835
836 return NULL;
837}
838
839struct nilfs_root *
840nilfs_find_or_create_root(struct the_nilfs *nilfs, __u64 cno)
841{
842 struct rb_node **p, *parent;
843 struct nilfs_root *root, *new;
844
845 root = nilfs_lookup_root(nilfs, cno);
846 if (root)
847 return root;
848
849 new = kmalloc(sizeof(*root), GFP_KERNEL);
850 if (!new)
851 return NULL;
852
853 spin_lock(&nilfs->ns_cptree_lock);
854
855 p = &nilfs->ns_cptree.rb_node;
856 parent = NULL;
857
858 while (*p) {
859 parent = *p;
860 root = rb_entry(parent, struct nilfs_root, rb_node);
861
862 if (cno < root->cno) {
863 p = &(*p)->rb_left;
864 } else if (cno > root->cno) {
865 p = &(*p)->rb_right;
866 } else {
867 atomic_inc(&root->count);
868 spin_unlock(&nilfs->ns_cptree_lock);
869 kfree(new);
870 return root;
871 }
872 }
873
874 new->cno = cno;
875 new->ifile = NULL;
876 new->nilfs = nilfs;
877 atomic_set(&new->count, 1);
878 atomic_set(&new->inodes_count, 0);
879 atomic_set(&new->blocks_count, 0);
880
881 rb_link_node(&new->rb_node, parent, p);
882 rb_insert_color(&new->rb_node, &nilfs->ns_cptree);
883
884 spin_unlock(&nilfs->ns_cptree_lock);
885
886 return new;
887}
888
889void nilfs_put_root(struct nilfs_root *root)
890{
891 if (atomic_dec_and_test(&root->count)) {
892 struct the_nilfs *nilfs = root->nilfs;
893
894 spin_lock(&nilfs->ns_cptree_lock);
895 rb_erase(&root->rb_node, &nilfs->ns_cptree);
896 spin_unlock(&nilfs->ns_cptree_lock);
897 if (root->ifile)
898 nilfs_mdt_destroy(root->ifile);
899
900 kfree(root);
901 }
902}
903
812/** 904/**
813 * nilfs_find_sbinfo - find existing nilfs_sb_info structure 905 * nilfs_find_sbinfo - find existing nilfs_sb_info structure
814 * @nilfs: nilfs object 906 * @nilfs: nilfs object