Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 177836
b: refs/heads/master
c: c71bf09
h: refs/heads/master
v: v3
  • Loading branch information
Yan, Zheng authored and Chris Mason committed Dec 17, 2009
1 parent 97cfdc4 commit 6a4e9ae
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 37 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c216775458a2ee345d9412a2770c2916acfb5d30
refs/heads/master: c71bf099abddf3e0fdc27f251ba76fca1461d49a
5 changes: 3 additions & 2 deletions trunk/fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -859,8 +859,9 @@ struct btrfs_fs_info {
struct mutex ordered_operations_mutex;
struct rw_semaphore extent_commit_sem;

struct rw_semaphore subvol_sem;
struct rw_semaphore cleanup_work_sem;

struct rw_semaphore subvol_sem;
struct srcu_struct subvol_srcu;

struct list_head trans_list;
Expand Down Expand Up @@ -1034,12 +1035,12 @@ struct btrfs_root {
int ref_cows;
int track_dirty;
int in_radix;
int clean_orphans;

u64 defrag_trans_start;
struct btrfs_key defrag_progress;
struct btrfs_key defrag_max;
int defrag_running;
int defrag_level;
char *name;
int in_sysfs;

Expand Down
17 changes: 11 additions & 6 deletions trunk/fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,8 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
root->stripesize = stripesize;
root->ref_cows = 0;
root->track_dirty = 0;
root->in_radix = 0;
root->clean_orphans = 0;

root->fs_info = fs_info;
root->objectid = objectid;
Expand Down Expand Up @@ -928,7 +930,6 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
root->defrag_trans_start = fs_info->generation;
init_completion(&root->kobj_unregister);
root->defrag_running = 0;
root->defrag_level = 0;
root->root_key.objectid = objectid;
root->anon_super.s_root = NULL;
root->anon_super.s_dev = 0;
Expand Down Expand Up @@ -1210,8 +1211,10 @@ struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info,
ret = radix_tree_insert(&fs_info->fs_roots_radix,
(unsigned long)root->root_key.objectid,
root);
if (ret == 0)
if (ret == 0) {
root->in_radix = 1;
root->clean_orphans = 1;
}
spin_unlock(&fs_info->fs_roots_radix_lock);
radix_tree_preload_end();
if (ret) {
Expand All @@ -1225,10 +1228,6 @@ struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info,
ret = btrfs_find_dead_roots(fs_info->tree_root,
root->root_key.objectid);
WARN_ON(ret);

if (!(fs_info->sb->s_flags & MS_RDONLY))
btrfs_orphan_cleanup(root);

return root;
fail:
free_fs_root(root);
Expand Down Expand Up @@ -1689,6 +1688,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
mutex_init(&fs_info->cleaner_mutex);
mutex_init(&fs_info->volume_mutex);
init_rwsem(&fs_info->extent_commit_sem);
init_rwsem(&fs_info->cleanup_work_sem);
init_rwsem(&fs_info->subvol_sem);

btrfs_init_free_cluster(&fs_info->meta_alloc_cluster);
Expand Down Expand Up @@ -2388,6 +2388,11 @@ int btrfs_commit_super(struct btrfs_root *root)
mutex_lock(&root->fs_info->cleaner_mutex);
btrfs_clean_old_snapshots(root);
mutex_unlock(&root->fs_info->cleaner_mutex);

/* wait until ongoing cleanup work done */
down_write(&root->fs_info->cleanup_work_sem);
up_write(&root->fs_info->cleanup_work_sem);

trans = btrfs_start_transaction(root, 1);
ret = btrfs_commit_transaction(trans, root);
BUG_ON(ret);
Expand Down
19 changes: 16 additions & 3 deletions trunk/fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -2093,16 +2093,17 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
struct inode *inode;
int ret = 0, nr_unlink = 0, nr_truncate = 0;

path = btrfs_alloc_path();
if (!path)
if (!xchg(&root->clean_orphans, 0))
return;

path = btrfs_alloc_path();
BUG_ON(!path);
path->reada = -1;

key.objectid = BTRFS_ORPHAN_OBJECTID;
btrfs_set_key_type(&key, BTRFS_ORPHAN_ITEM_KEY);
key.offset = (u64)-1;


while (1) {
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
if (ret < 0) {
Expand Down Expand Up @@ -3298,6 +3299,11 @@ void btrfs_delete_inode(struct inode *inode)
}
btrfs_wait_ordered_range(inode, 0, (u64)-1);

if (root->fs_info->log_root_recovering) {
BUG_ON(!list_empty(&BTRFS_I(inode)->i_orphan));
goto no_delete;
}

if (inode->i_nlink > 0) {
BUG_ON(btrfs_root_refs(&root->root_item) != 0);
goto no_delete;
Expand Down Expand Up @@ -3705,6 +3711,13 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
}
srcu_read_unlock(&root->fs_info->subvol_srcu, index);

if (root != sub_root) {
down_read(&root->fs_info->cleanup_work_sem);
if (!(inode->i_sb->s_flags & MS_RDONLY))
btrfs_orphan_cleanup(sub_root);
up_read(&root->fs_info->cleanup_work_sem);
}

return inode;
}

Expand Down
1 change: 1 addition & 0 deletions trunk/fs/btrfs/relocation.c
Original file line number Diff line number Diff line change
Expand Up @@ -3755,6 +3755,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
BTRFS_DATA_RELOC_TREE_OBJECTID);
if (IS_ERR(fs_root))
err = PTR_ERR(fs_root);
btrfs_orphan_cleanup(fs_root);
}
return err;
}
Expand Down
49 changes: 24 additions & 25 deletions trunk/fs/btrfs/tree-log.c
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,17 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
return 0;
}

static int insert_orphan_item(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 offset)
{
int ret;
ret = btrfs_find_orphan_item(root, offset);
if (ret > 0)
ret = btrfs_insert_orphan_item(trans, root, offset);
return ret;
}


/*
* There are a few corners where the link count of the file can't
* be properly maintained during replay. So, instead of adding
Expand Down Expand Up @@ -997,9 +1008,13 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans,
}
BTRFS_I(inode)->index_cnt = (u64)-1;

if (inode->i_nlink == 0 && S_ISDIR(inode->i_mode)) {
ret = replay_dir_deletes(trans, root, NULL, path,
inode->i_ino, 1);
if (inode->i_nlink == 0) {
if (S_ISDIR(inode->i_mode)) {
ret = replay_dir_deletes(trans, root, NULL, path,
inode->i_ino, 1);
BUG_ON(ret);
}
ret = insert_orphan_item(trans, root, inode->i_ino);
BUG_ON(ret);
}
btrfs_free_path(path);
Expand Down Expand Up @@ -1587,7 +1602,6 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
/* inode keys are done during the first stage */
if (key.type == BTRFS_INODE_ITEM_KEY &&
wc->stage == LOG_WALK_REPLAY_INODES) {
struct inode *inode;
struct btrfs_inode_item *inode_item;
u32 mode;

Expand All @@ -1603,31 +1617,16 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
eb, i, &key);
BUG_ON(ret);

/* for regular files, truncate away
* extents past the new EOF
/* for regular files, make sure corresponding
* orhpan item exist. extents past the new EOF
* will be truncated later by orphan cleanup.
*/
if (S_ISREG(mode)) {
inode = read_one_inode(root,
key.objectid);
BUG_ON(!inode);

ret = btrfs_truncate_inode_items(wc->trans,
root, inode, inode->i_size,
BTRFS_EXTENT_DATA_KEY);
ret = insert_orphan_item(wc->trans, root,
key.objectid);
BUG_ON(ret);

/* if the nlink count is zero here, the iput
* will free the inode. We bump it to make
* sure it doesn't get freed until the link
* count fixup is done
*/
if (inode->i_nlink == 0) {
btrfs_inc_nlink(inode);
btrfs_update_inode(wc->trans,
root, inode);
}
iput(inode);
}

ret = link_to_fixup_dir(wc->trans, root,
path, key.objectid);
BUG_ON(ret);
Expand Down

0 comments on commit 6a4e9ae

Please sign in to comment.