Thread (58 messages) flat view 58 messages, 5 authors, 2012-11-16

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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help