Hello, These changes are related to lock release when the error occurs. Regards YZ diff -r 24c661119092 inode.c --- a/inode.c Mon Sep 17 11:25:58 2007 -0400 +++ b/inode.c Thu Sep 20 22:06:04 2007 +0800 @@ -684,7 +684,7 @@ static int btrfs_truncate_page(struct ad u64 page_start; if ((offset & (blocksize - 1)) == 0) - goto out; + return 0; down_read(&BTRFS_I(inode)->root->snap_sem); ret = -ENOMEM; @@ -696,17 +696,17 @@ static int btrfs_truncate_page(struct ad lock_page(page); if (!PageUptodate(page)) { ret = -EIO; - goto out; + goto out_unlock; } } page_start = page->index << PAGE_CACHE_SHIFT; ret = btrfs_cow_one_page(inode, page, offset); - +out_unlock: unlock_page(page); page_cache_release(page); +out: up_read(&BTRFS_I(inode)->root->snap_sem); -out: return ret; } @@ -838,6 +838,7 @@ static int fixup_tree_root_location(stru { struct btrfs_path *path; struct btrfs_root_item *ri; + int ret = 0; if (btrfs_key_type(location) != BTRFS_ROOT_ITEM_KEY) return 0; @@ -851,18 +852,20 @@ static int fixup_tree_root_location(stru *sub_root = btrfs_read_fs_root(root->fs_info, location, dentry->d_name.name, dentry->d_name.len); - if (IS_ERR(*sub_root)) - return PTR_ERR(*sub_root); + if (IS_ERR(*sub_root)) { + ret = PTR_ERR(*sub_root); + goto out; + } ri = &(*sub_root)->root_item; location->objectid = btrfs_root_dirid(ri); location->flags = 0; btrfs_set_key_type(location, BTRFS_INODE_ITEM_KEY); location->offset = 0; - +out: btrfs_free_path(path); mutex_unlock(&root->fs_info->fs_mutex); - return 0; + return ret; } static int btrfs_init_locked_inode(struct inode *inode, void *p)