From: Chris Mason Date: Sun, 22 May 2011 11:07:01 +0000 (-0400) Subject: Merge branch 'delayed_inode' into inode_numbers X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=dcc6d073225b6b732a52477c91bd4edc9b4d5502;p=openwrt%2Fstaging%2Fblogic.git Merge branch 'delayed_inode' into inode_numbers Conflicts: fs/btrfs/inode.c fs/btrfs/ioctl.c fs/btrfs/transaction.c Signed-off-by: Chris Mason --- dcc6d073225b6b732a52477c91bd4edc9b4d5502 diff --cc fs/btrfs/inode.c index 01438e9ba2e2,3470f67c6258..6cef48572e9e --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@@ -2659,11 -2647,26 +2659,26 @@@ noinline int btrfs_update_inode(struct struct extent_buffer *leaf; int ret; + /* + * If root is tree root, it means this inode is used to + * store free space information. And these inodes are updated + * when committing the transaction, so they needn't delaye to + * be updated, or deadlock will occured. + */ - if (likely(root != root->fs_info->tree_root)) { ++ if (!is_free_space_inode(root, inode)) { + ret = btrfs_delayed_update_inode(trans, root, inode); + if (!ret) + btrfs_set_inode_last_trans(trans, inode); + return ret; + } + path = btrfs_alloc_path(); - BUG_ON(!path); + if (!path) + return -ENOMEM; + path->leave_spinning = 1; - ret = btrfs_lookup_inode(trans, root, path, - &BTRFS_I(inode)->location, 1); + ret = btrfs_lookup_inode(trans, root, path, &BTRFS_I(inode)->location, + 1); if (ret) { if (ret > 0) ret = -ENOENT; @@@ -2737,21 -2738,12 +2751,12 @@@ static int __btrfs_unlink_inode(struct goto err; } - di = btrfs_lookup_dir_index_item(trans, root, path, dir_ino, - index, name, name_len, -1); - if (IS_ERR(di)) { - ret = PTR_ERR(di); - goto err; - } - if (!di) { - ret = -ENOENT; + ret = btrfs_delete_delayed_dir_index(trans, root, dir, index); + if (ret) goto err; - } - ret = btrfs_delete_one_dir_name(trans, root, path, di); - btrfs_release_path(root, path); ret = btrfs_del_inode_ref_in_log(trans, root, name, name_len, - inode, dir->i_ino); + inode, dir_ino); BUG_ON(ret != 0 && ret != -ENOENT); ret = btrfs_del_dir_entries_in_log(trans, root, name, name_len, @@@ -2939,7 -2929,15 +2944,15 @@@ static struct btrfs_trans_handle *__unl index = btrfs_inode_ref_index(path->nodes[0], ref); btrfs_release_path(root, path); + /* + * This is a commit root search, if we can lookup inode item and other + * relative items in the commit root, it means the transaction of + * dir/file creation has been committed, and the dir index item that we + * delay to insert has also been inserted into the commit root. So + * we needn't worry about the delayed insertion of the dir index item + * here. + */ - di = btrfs_lookup_dir_index_item(trans, root, path, dir->i_ino, index, + di = btrfs_lookup_dir_index_item(trans, root, path, dir_ino, index, dentry->d_name.name, dentry->d_name.len, 0); if (IS_ERR(di)) { err = PTR_ERR(di); @@@ -4280,11 -4275,19 +4297,19 @@@ static int btrfs_real_readdir(struct fi filp->f_pos = 2; } path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; path->reada = 2; + if (key_type == BTRFS_DIR_INDEX_KEY) { + INIT_LIST_HEAD(&ins_list); + INIT_LIST_HEAD(&del_list); + btrfs_get_delayed_items(inode, &ins_list, &del_list); + } + btrfs_set_key_type(&key, key_type); key.offset = filp->f_pos; - key.objectid = inode->i_ino; + key.objectid = btrfs_ino(inode); ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); if (ret < 0)