Re: [RFC v4+ hot_track 03/19] vfs: add I/O frequency update function
From: Zhi Yong Wu <hidden>
Date: 2012-11-07 07:03:54
Also in:
linux-btrfs, linux-fsdevel, lkml
On Wed, Nov 7, 2012 at 6:37 AM, David Sterba [off-list ref] wrote:
On Mon, Oct 29, 2012 at 12:30:45PM +0800, zwu.kernel@gmail.com wrote:quoted
--- a/fs/hot_tracking.c +++ b/fs/hot_tracking.c +struct hot_inode_item +*hot_inode_item_find(struct hot_info *root, u64 ino) +{ + struct hot_inode_item *he; + int ret; + +again: + spin_lock(&root->lock); + he = radix_tree_lookup(&root->hot_inode_tree, ino); + if (he) { + kref_get(&he->hot_inode.refs); + spin_unlock(&root->lock); + return he; + } + spin_unlock(&root->lock); + + he = kmem_cache_zalloc(hot_inode_item_cachep, + GFP_KERNEL | GFP_NOFS); + if (!he) + return ERR_PTR(-ENOMEM); + + hot_inode_item_init(he, ino, &root->hot_inode_tree); + + ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM); + if (ret) { + kmem_cache_free(hot_inode_item_cachep, he);radix_tree_preload_end()quoted
+ return ERR_PTR(ret); + } + + spin_lock(&root->lock); + ret = radix_tree_insert(&root->hot_inode_tree, ino, he); + if (ret == -EEXIST) { + kmem_cache_free(hot_inode_item_cachep, he); + spin_unlock(&root->lock); + radix_tree_preload_end(); + goto again; + } + spin_unlock(&root->lock); + radix_tree_preload_end(); + + kref_get(&he->hot_inode.refs); + return he; +} +EXPORT_SYMBOL_GPL(hot_inode_item_find); + +static struct hot_range_item +*hot_range_item_find(struct hot_inode_item *he, + u32 start) +{ + struct hot_range_item *hr; + int ret; + +again: + spin_lock(&he->lock); + hr = radix_tree_lookup(&he->hot_range_tree, start); + if (hr) { + kref_get(&hr->hot_range.refs); + spin_unlock(&he->lock); + return hr; + } + spin_unlock(&he->lock); + + hr = kmem_cache_zalloc(hot_range_item_cachep, + GFP_KERNEL | GFP_NOFS); + if (!hr) + return ERR_PTR(-ENOMEM); + + hot_range_item_init(hr, start, he); + + ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM); + if (ret) { + kmem_cache_free(hot_range_item_cachep, hr);radix_tree_preload_end()
I checked some kernel existing cases about the usage of radix_tree_preload(), it seems that when radix_tree_preload() fail, its error handling doesn't need call radix_tree_preload_end() any more.
quoted
+ return ERR_PTR(ret); + } + + spin_lock(&he->lock); + ret = radix_tree_insert(&he->hot_range_tree, start, hr); + if (ret == -EEXIST) { + kmem_cache_free(hot_range_item_cachep, hr); + spin_unlock(&he->lock); + radix_tree_preload_end();
ditto.
quoted
+ goto again; + } + spin_unlock(&he->lock); + radix_tree_preload_end(); + + kref_get(&hr->hot_range.refs); + return hr; +}david
-- Regards, Zhi Yong Wu