Status of btrfs-unstable-standalone?
I've noticed that the btrfs-unstable-standalone repository hasn't been updated in over three weeks. It seems all active development is taking place on btrfs-unstable. What is happening to the btfs-unstable-standalone repository? Will all future development only be on btrfs-unstable or is there some other reason btrfs-unstable-standalone hasn't been updated? Thanks, Lee -- To unsubscribe from this list: send the line unsubscribe linux-btrfs in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] btrfs: make sure all pending extent operations are complete
Hello, Theres a slight problem with finish_current_insert, if we set all to 1 and then go through and don't actually skip any of the extents on the pending list, we could exit right after we've added new extents. This is a problem because by inserting the new extents we could have gotten new COW's to happen and such, so we may have some pending updates to do or even more inserts to do after that. So this patch will only exit if we have never skipped any of the extents in the pending list, and we have no extents to insert, this will make sure that all of the pending work is truly done before we return. I've been running with this patch for a few days with all of my other testing and have not seen issues. Thanks, Signed-off-by: Josef Bacik jba...@redhat.com --- fs/btrfs/extent-tree.c | 50 ++- 1 files changed, 23 insertions(+), 27 deletions(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 8121f00..d2bc0fc 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -2379,13 +2379,12 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, u64 end; u64 priv; u64 search = 0; - u64 skipped = 0; struct btrfs_fs_info *info = extent_root-fs_info; struct btrfs_path *path; struct pending_extent_op *extent_op, *tmp; struct list_head insert_list, update_list; int ret; - int num_inserts = 0, max_inserts; + int num_inserts = 0, max_inserts, restart = 0; path = btrfs_alloc_path(); INIT_LIST_HEAD(insert_list); @@ -2401,19 +2400,19 @@ again: ret = find_first_extent_bit(info-extent_ins, search, start, end, EXTENT_WRITEBACK); if (ret) { - if (skipped all !num_inserts + if (restart !num_inserts list_empty(update_list)) { - skipped = 0; + restart = 0; search = 0; continue; } - mutex_unlock(info-extent_ins_mutex); break; } ret = try_lock_extent(info-extent_ins, start, end, GFP_NOFS); if (!ret) { - skipped = 1; + if (all) + restart = 1; search = end + 1; if (need_resched()) { mutex_unlock(info-extent_ins_mutex); @@ -2432,7 +2431,7 @@ again: list_add_tail(extent_op-list, insert_list); search = end + 1; if (num_inserts == max_inserts) { - mutex_unlock(info-extent_ins_mutex); + restart = 1; break; } } else if (extent_op-type == PENDING_BACKREF_UPDATE) { @@ -2448,7 +2447,6 @@ again: * somebody marked this thing for deletion then just unlock it and be * done, the free_extents will handle it */ - mutex_lock(info-extent_ins_mutex); list_for_each_entry_safe(extent_op, tmp, update_list, list) { clear_extent_bits(info-extent_ins, extent_op-bytenr, extent_op-bytenr + extent_op-num_bytes - 1, @@ -2470,6 +2468,10 @@ again: if (!list_empty(update_list)) { ret = update_backrefs(trans, extent_root, path, update_list); BUG_ON(ret); + + /* we may have COW'ed new blocks, so lets start over */ + if (all) + restart = 1; } /* @@ -2477,9 +2479,9 @@ again: * need to make sure everything is cleaned then reset everything and * go back to the beginning */ - if (!num_inserts all skipped) { + if (!num_inserts restart) { search = 0; - skipped = 0; + restart = 0; INIT_LIST_HEAD(update_list); INIT_LIST_HEAD(insert_list); goto again; @@ -2536,27 +2538,19 @@ again: BUG_ON(ret); /* -* if we broke out of the loop in order to insert stuff because we hit -* the maximum number of inserts at a time we can handle, then loop -* back and pick up where we left off +* if restart is set for whatever reason we need to go back and start +* searching through the pending list again. +* +* We just inserted some extents, which could have resulted in new +* blocks being allocated, which would result in new blocks needing +* updates, so if all is set we _must_ restart to get the updated +* blocks. */ - if
[PATCH] Updated Backport to 2.6.27 and 2.6.26
Since for the past three weeks all new patches have been submitted only to btrfs-unstable I have updated my backport patch for btrfs-unstable. This patch only works with 2.6.27 and 2.6.26(thanks Michele for testing it for me) Lee diff -Naur btrfs-old/async-thread.c btrfs/async-thread.c --- btrfs-old/async-thread.c2009-02-11 16:24:09.0 -0500 +++ btrfs/async-thread.c2009-02-11 15:47:44.0 -0500 @@ -20,7 +20,10 @@ #include linux/list.h #include linux/spinlock.h #include linux/freezer.h +#include linux/version.h +#if LINUX_VERSION_CODE = KERNEL_VERSION(2, 6, 29) #include linux/ftrace.h +#endif #include async-thread.h #define WORK_QUEUED_BIT 0 diff -Naur btrfs-old/compat.h btrfs/compat.h --- btrfs-old/compat.h 2009-02-11 16:24:09.0 -0500 +++ btrfs/compat.h 2009-02-11 15:24:52.0 -0500 @@ -1,7 +1,33 @@ #ifndef _COMPAT_H_ #define _COMPAT_H_ +#include linux/version.h + #define btrfs_drop_nlink(inode) drop_nlink(inode) #define btrfs_inc_nlink(inode) inc_nlink(inode) +#if LINUX_VERSION_CODE = KERNEL_VERSION(2, 6, 27) +static inline struct dentry *d_obtain_alias(struct inode *inode) +{ + struct dentry *d; + + if (!inode) + return NULL; + if (IS_ERR(inode)) + return ERR_CAST(inode); + + d = d_alloc_anon(inode); + if (!d) + iput(inode); + return d; +} +#endif + +#if LINUX_VERSION_CODE KERNEL_VERSION(2, 6, 28) +#define __pagevec_lru_add_file __pagevec_lru_add +#define open_bdev_exclusive open_bdev_excl +#define close_bdev_exclusive(bdev, mode) close_bdev_excl(bdev) +typedef unsigned __bitwise__ fmode_t; +#endif + #endif /* _COMPAT_H_ */ diff -Naur btrfs-old/export.h btrfs/export.h --- btrfs-old/export.h 2009-02-11 16:24:11.0 -0500 +++ btrfs/export.h 2009-02-11 15:18:16.0 -0500 @@ -16,4 +16,32 @@ u64 parent_root_objectid; } __attribute__ ((packed)); +// BTRFS needs the btrfs from fid_type which was added in 2.6.27 +// All I did was copy the btrfs defse which was found in +// linux-2.6.27/include/linux/exportfs.h +#if LINUX_VERSION_CODE KERNEL_VERSION(2, 6, 27) +enum btrfs_fid_type { + /* +* 64 bit object ID, 64 bit root object ID, +* 32 bit generation number. +*/ + FILEID_BTRFS_WITHOUT_PARENT = 0x4d, + + /* +* 64 bit object ID, 64 bit root object ID, +* 32 bit generation number, +* 64 bit parent object ID, 32 bit parent generation. +*/ + FILEID_BTRFS_WITH_PARENT = 0x4e, + + /* +* 64 bit object ID, 64 bit root object ID, +* 32 bit generation number, +* 64 bit parent object ID, 32 bit parent generation, +* 64 bit parent root object ID. +*/ + FILEID_BTRFS_WITH_PARENT_ROOT = 0x4f, +}; +#endif + #endif diff -Naur btrfs-old/extent_io.c btrfs/extent_io.c --- btrfs-old/extent_io.c 2009-02-11 16:24:11.0 -0500 +++ btrfs/extent_io.c 2009-02-11 15:44:02.0 -0500 @@ -2849,6 +2849,7 @@ return sector; } +#if LINUX_VERSION_CODE = KERNEL_VERSION(2, 6, 29) int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, __u64 start, __u64 len, get_extent_t *get_extent) { @@ -2940,6 +2941,7 @@ GFP_NOFS); return ret; } +#endif static inline struct page *extent_buffer_page(struct extent_buffer *eb, unsigned long i) @@ -3165,13 +3167,21 @@ } } clear_page_dirty_for_io(page); +#if LINUX_VERSION_CODE = KERNEL_VERSION(2, 6, 27) spin_lock_irq(page-mapping-tree_lock); +#else + read_lock_irq(page-mapping-tree_lock); +#endif if (!PageDirty(page)) { radix_tree_tag_clear(page-mapping-page_tree, page_index(page), PAGECACHE_TAG_DIRTY); } +#if LINUX_VERSION_CODE = KERNEL_VERSION(2, 6, 27) spin_unlock_irq(page-mapping-tree_lock); +#else + read_unlock_irq(page-mapping-tree_lock); +#endif unlock_page(page); } return 0; @@ -3349,7 +3359,11 @@ for (i = start_i; i num_pages; i++) { page = extent_buffer_page(eb, i); if (!wait) { +#if LINUX_VERSION_CODE = KERNEL_VERSION(2, 6, 27) if (!trylock_page(page)) +#else + if(!TestSetPageLocked(page)) +#endif goto unlock_exit; } else { lock_page(page); diff -Naur btrfs-old/extent_io.h btrfs/extent_io.h --- btrfs-old/extent_io.h 2009-02-11 16:24:11.0 -0500 +++ btrfs/extent_io.h 2009-02-11 15:44:41.0 -0500 @@ -2,6 +2,7 @@ #define __EXTENTIO__ #include linux/rbtree.h +#include linux/version.h /*
[PATCH] btrfs: fix btrfs_read_block_groups return value
btrfs_read_block_groups returns an ambiguous value. Whether it finds a block group or not, it will return -ENOENT. find_first_block_group will eventually return -ENOENT when it reaches past the last block group, and that is what is returned to the caller. Also, if the kzalloc fails, it will return 0. None of this matters right now because open_ctree isn't checking the return value, but I have a patch to handle that as well. This patch returns 0 if find_first_block_group after it has already found at least one block group, and -ENOENT if it has found none. It also returns -ENOMEM if the kzalloc fails. Signed-off-by: Jeff Mahoney je...@suse.com --- fs/btrfs/extent-tree.c |8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -6106,7 +6106,7 @@ int btrfs_free_block_groups(struct btrfs int btrfs_read_block_groups(struct btrfs_root *root) { struct btrfs_path *path; - int ret; + int ret, found = 0; struct btrfs_block_group_cache *cache; struct btrfs_fs_info *info = root-fs_info; struct btrfs_space_info *space_info; @@ -6124,10 +6124,11 @@ int btrfs_read_block_groups(struct btrfs while (1) { ret = find_first_block_group(root, path, key); - if (ret 0) { + if (ret 0 || (found ret == -ENOENT)) { ret = 0; goto error; } + if (ret != 0) goto error; @@ -6136,7 +6137,7 @@ int btrfs_read_block_groups(struct btrfs cache = kzalloc(sizeof(*cache), GFP_NOFS); if (!cache) { ret = -ENOMEM; - break; + goto error; } atomic_set(cache-count, 1); @@ -6168,6 +6169,7 @@ int btrfs_read_block_groups(struct btrfs set_avail_alloc_bits(root-fs_info, cache-flags); if (btrfs_chunk_readonly(root, cache-key.objectid)) set_block_group_readonly(cache); + found = 1; } ret = 0; error: -- Jeff Mahoney SUSE Labs -- To unsubscribe from this list: send the line unsubscribe linux-btrfs in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH] btrfs: Check transaction start
This patch changes start_transaction() to return an ERR_PTR instead of NULL. Things like I/O errors and allocation failures can be handled differently. It also checks every start_transaction call. Where the error can be handled simply, we clean up state and return an error. If the recovery is more involved, we BUG. This isn't a change in functionality since we'd Oops anyway. The more complex recovery should be done in separate patches, so this is really just to annotate where that needs to happen. Signed-off-by: Jeff Mahoney je...@suse.com --- fs/btrfs/disk-io.c |4 +++ fs/btrfs/extent-tree.c | 24 ++ fs/btrfs/extent_io.c | 18 -- fs/btrfs/file.c|9 +++ fs/btrfs/inode.c | 62 +++-- fs/btrfs/ioctl.c | 34 ++ fs/btrfs/super.c | 13 +++--- fs/btrfs/transaction.c | 25 ++- fs/btrfs/tree-log.c|4 +++ fs/btrfs/volumes.c | 17 ++--- 10 files changed, 166 insertions(+), 44 deletions(-) --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1447,6 +1447,8 @@ static int transaction_kthread(void *arg } mutex_unlock(root-fs_info-trans_mutex); trans = btrfs_start_transaction(root, 1); + if (IS_ERR(trans)) + goto sleep; ret = btrfs_commit_transaction(trans, root); sleep: wake_up_process(root-fs_info-cleaner_kthread); @@ -2197,10 +2199,12 @@ int btrfs_commit_super(struct btrfs_root btrfs_clean_old_snapshots(root); mutex_unlock(root-fs_info-cleaner_mutex); trans = btrfs_start_transaction(root, 1); + BUG_ON(IS_ERR(trans)); ret = btrfs_commit_transaction(trans, root); BUG_ON(ret); /* run commit again to drop the original snapshot */ trans = btrfs_start_transaction(root, 1); + BUG_ON(IS_ERR(trans)); btrfs_commit_transaction(trans, root); ret = btrfs_write_and_wait_transaction(NULL, root); BUG_ON(ret); --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -5259,7 +5259,7 @@ int btrfs_drop_dead_reloc_roots(struct b BUG_ON(reloc_root-commit_root != NULL); while (1) { trans = btrfs_join_transaction(root, 1); - BUG_ON(!trans); + BUG_ON(IS_ERR(trans)); mutex_lock(root-fs_info-drop_mutex); ret = btrfs_drop_snapshot(trans, reloc_root); @@ -5317,7 +5317,7 @@ int btrfs_cleanup_reloc_trees(struct btr if (found) { trans = btrfs_start_transaction(root, 1); - BUG_ON(!trans); + BUG_ON(IS_ERR(trans)); ret = btrfs_commit_transaction(trans, root); BUG_ON(ret); } @@ -5564,7 +5564,8 @@ static noinline int relocate_one_extent( trans = btrfs_start_transaction(extent_root, 1); - BUG_ON(!trans); + if (IS_ERR(trans)) + return PTR_ERR(trans); if (extent_key-objectid == 0) { ret = del_extent_zero(trans, extent_root, path, extent_key); @@ -5742,6 +5743,8 @@ static int __alloc_chunk_for_shrink(stru spin_unlock(shrink_block_group-lock); trans = btrfs_start_transaction(root, 1); + if (IS_ERR(trans)) + return PTR_ERR(trans); spin_lock(shrink_block_group-lock); new_alloc_flags = update_block_group_flags(root, @@ -5812,7 +5815,8 @@ static noinline struct inode *create_rel return ERR_CAST(root); trans = btrfs_start_transaction(root, 1); - BUG_ON(!trans); + if (IS_ERR(trans)) + return ERR_CAST(trans); err = btrfs_find_free_objectid(trans, root, objectid, objectid); if (err) @@ -5924,7 +5928,8 @@ int btrfs_relocate_block_group(struct bt reloc_inode = create_reloc_inode(info, block_group); BUG_ON(IS_ERR(reloc_inode)); - __alloc_chunk_for_shrink(root, block_group, 1); + ret = __alloc_chunk_for_shrink(root, block_group, 1); + BUG_ON(ret); set_block_group_readonly(block_group); btrfs_start_delalloc_inodes(info-tree_root); @@ -5939,6 +5944,10 @@ again: cur_byte = key.objectid; trans = btrfs_start_transaction(info-tree_root, 1); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + goto out; + } btrfs_commit_transaction(trans, info-tree_root); mutex_lock(root-fs_info-cleaner_mutex); @@ -5989,7 +5998,8 @@ next: cur_byte = key.objectid + key.offset; btrfs_release_path(root, path); - __alloc_chunk_for_shrink(root, block_group, 0); + ret = __alloc_chunk_for_shrink(root, block_group, 0); +
[PATCH] btrfs: remove btrfs_init_path
Since btrfs_alloc_path is universally used, there's no point in keeping btrfs_init_path around. This patch removes it, and just uses the __GFP_ZERO flag for kmem_cache_alloc to zero out the object. Signed-off-by: Jeff Mahoney je...@suse.com --- fs/btrfs/ctree.c | 12 ++-- fs/btrfs/ctree.h |1 - fs/btrfs/inode-map.c |1 - fs/btrfs/inode.c |2 -- 4 files changed, 2 insertions(+), 14 deletions(-) --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -38,20 +38,12 @@ static int balance_node_right(struct btr static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, int level, int slot); -inline void btrfs_init_path(struct btrfs_path *p) -{ - memset(p, 0, sizeof(*p)); -} - struct btrfs_path *btrfs_alloc_path(void) { struct btrfs_path *path; - path = kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS); - if (path) { - btrfs_init_path(path); + path = kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS | __GFP_ZERO); + if (path) path-reada = 1; - } - WARN_ON_ONCE(!path); return path; } --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -1834,7 +1834,6 @@ int btrfs_realloc_node(struct btrfs_tran void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p); struct btrfs_path *btrfs_alloc_path(void); void btrfs_free_path(struct btrfs_path *p); -void btrfs_init_path(struct btrfs_path *p); void btrfs_set_path_blocking(struct btrfs_path *p); void btrfs_clear_path_blocking(struct btrfs_path *p); void btrfs_unlock_up_safe(struct btrfs_path *p, int level); --- a/fs/btrfs/inode-map.c +++ b/fs/btrfs/inode-map.c @@ -84,7 +84,6 @@ int btrfs_find_free_objectid(struct btrf search_key.type = 0; search_key.offset = 0; - btrfs_init_path(path); start_found = 0; ret = btrfs_search_slot(trans, root, search_key, path, 0, 0); if (ret 0) --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2543,8 +2543,6 @@ noinline int btrfs_truncate_inode_items( key.offset = (u64)-1; key.type = (u8)-1; - btrfs_init_path(path); - search_again: ret = btrfs_search_slot(trans, root, key, path, -1, 1); if (ret 0) -- Jeff Mahoney SUSE Labs -- To unsubscribe from this list: send the line unsubscribe linux-btrfs in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
btrfs lockup after mounting for a second time on 2.6.26
While running a few tests with the btrfs sources pulled from btrfs-unstable patched with my patch to compile under 2.6.26 I encountered a very weird problem. Everything works fine the first time I mount the file system (either actual disk or loop back). When I unmounted the file system and mounted it again(I'm not doing mount -o remount ...) btrfs is completely unusable. When I tried to view some of the data which I previously put on the btrfs partition by doing a simple ls /mnt/btrfs in bash nothing happens. ls shows nothing, just hangs, and I am unable to kill ls. The same thing happens when I try to copy a file from my ext3 partition onto the btrfs partition after mounting it for a second time. The rest of the system is completely usable and the only things that are effects are applications which are trying to read/write from the btrfs file system. There are no kernel opps or any other errors messages in any of my logs. This happens if I have compression on or not. I'd be happy to fix this issue but I don't have a clue about where to start looking for what is wrong. Could someone please help me? Thanks, Lee -- To unsubscribe from this list: send the line unsubscribe linux-btrfs in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html