Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752746AbbHGKnA (ORCPT ); Fri, 7 Aug 2015 06:43:00 -0400 Received: from mailout2.samsung.com ([203.254.224.25]:58791 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751471AbbHGKm6 (ORCPT ); Fri, 7 Aug 2015 06:42:58 -0400 X-AuditID: cbfee61b-f79706d000001b96-0f-55c48bb0ac1d From: Chao Yu To: Jaegeuk Kim Cc: linux-f2fs-devel@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 4/4] f2fs: remove inmem radix tree Date: Fri, 07 Aug 2015 18:42:09 +0800 Message-id: <018101d0d0fd$d01959d0$704c0d70$@samsung.com> MIME-version: 1.0 Content-type: text/plain; charset=us-ascii Content-transfer-encoding: 7bit X-Mailer: Microsoft Outlook 14.0 Thread-index: AdDQ/ERUN3SdxdmkRCOAO2friaHhHw== Content-language: zh-cn X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrALMWRmVeSWpSXmKPExsVy+t9jQd0N3UdCDS7vEbN4sn4Ws8WlRe4W e/aeZLG4vGsOmwOLx6ZVnWweuxd8ZvL4vEkugDmKyyYlNSezLLVI3y6BK2P21IqCz1oV7+a1 sDUw/lbqYuTkkBAwkfj4dB0bhC0mceHeeiCbi0NIYBajxKdJl9ghnFeMEnP+NTODVLEJqEgs 7/jPBGKLANmHFl1mB7GZBTIl7jXNAKsRFjCSWH5iJ1gNi4CqxNpFf8A28ApYSlzd1MAOYQtK /Jh8jwWiV0ti/c7jTBC2vMTmNW+ZIS5SkNhx9jUjxC49ibVf90HtEpfYeOQWywRGoDMRRs1C MmoWklGzkLQsYGRZxSiRWpBcUJyUnmuUl1quV5yYW1yal66XnJ+7iREczs+kdzAe3uV+iFGA g1GJhzfh3+FQIdbEsuLK3EOMEhzMSiK8Z6uPhArxpiRWVqUW5ccXleakFh9ilOZgURLn1TfZ FCokkJ5YkpqdmlqQWgSTZeLglGpgbBG8Ft3ik7Ir7cG8mAerkuadvVt6J60pc1qt723z+yHq T+xXcO4yiJ67NL7g5KnM1DxzuctixtsC+l1ad5tJrsh4seVi04JteY4FhY8FFlnIFPctuZrs vyVhT4f/4Xuuda2COy8KGUyq8eHoTaysjXizyDEx8V7ruQkutsEnPy2v2PH02T0RJZbijERD Leai4kQAZgDrUmMCAAA= Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5560 Lines: 181 Previously, we use radix tree to index all registered page entries for atomic file, but now we only use radix tree to see whether current page is indexed or not, since the other user of radix tree is gone in commit 042b7816aaeb ("f2fs: remove unnecessary call to invalidate inmemory pages"). So in this patch, we try to use one more efficient way: Introducing a macro ATOMIC_WRITTEN_PAGE, and setting it as page private value to indicate page indexing status. By using this way, we can save memory and lookup time. Signed-off-by: Chao Yu --- fs/f2fs/data.c | 20 ++++++++++++++++++-- fs/f2fs/f2fs.h | 1 - fs/f2fs/segment.c | 25 +++++++++---------------- fs/f2fs/segment.h | 9 +++++++++ fs/f2fs/super.c | 1 - 5 files changed, 36 insertions(+), 20 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 7ea8eda..cad9ebe 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1558,6 +1558,11 @@ void f2fs_invalidate_page(struct page *page, unsigned int offset, else inode_dec_dirty_pages(inode); } + + /* This is atomic written page, keep Private */ + if (IS_ATOMIC_WRITTEN_PAGE(page)) + return; + ClearPagePrivate(page); } @@ -1567,6 +1572,10 @@ int f2fs_release_page(struct page *page, gfp_t wait) if (PageDirty(page)) return 0; + /* This is atomic written page, keep Private */ + if (IS_ATOMIC_WRITTEN_PAGE(page)) + return 0; + ClearPagePrivate(page); return 1; } @@ -1581,8 +1590,15 @@ static int f2fs_set_data_page_dirty(struct page *page) SetPageUptodate(page); if (f2fs_is_atomic_file(inode)) { - register_inmem_page(inode, page); - return 1; + if (!IS_ATOMIC_WRITTEN_PAGE(page)) { + register_inmem_page(inode, page); + return 1; + } + /* + * Previously, this page has been registered, we just + * return here. + */ + return 0; } if (!PageDirty(page)) { diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 4a6f69b..23bfc0c 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -424,7 +424,6 @@ struct f2fs_inode_info { unsigned long long xattr_ver; /* cp version of xattr modification */ struct inode_entry *dirty_dir; /* the pointer of dirty dir */ - struct radix_tree_root inmem_root; /* radix tree for inmem pages */ struct list_head inmem_pages; /* inmemory pages managed by f2fs */ struct mutex inmem_lock; /* lock for inmemory pages */ diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 1ad3cf3..cb6c61a 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -197,28 +197,20 @@ void register_inmem_page(struct inode *inode, struct page *page) { struct f2fs_inode_info *fi = F2FS_I(inode); struct inmem_pages *new; - int err; - SetPagePrivate(page); f2fs_trace_pid(page); + set_page_private(page, (unsigned long)ATOMIC_WRITTEN_PAGE); + SetPagePrivate(page); + new = f2fs_kmem_cache_alloc(inmem_entry_slab, GFP_NOFS); /* add atomic page indices to the list */ new->page = page; INIT_LIST_HEAD(&new->list); -retry: + /* increase reference count with clean state */ mutex_lock(&fi->inmem_lock); - err = radix_tree_insert(&fi->inmem_root, page->index, new); - if (err == -EEXIST) { - mutex_unlock(&fi->inmem_lock); - kmem_cache_free(inmem_entry_slab, new); - return; - } else if (err) { - mutex_unlock(&fi->inmem_lock); - goto retry; - } get_page(page); list_add_tail(&new->list, &fi->inmem_pages); inc_page_count(F2FS_I_SB(inode), F2FS_INMEM_PAGES); @@ -255,8 +247,8 @@ int commit_inmem_pages(struct inode *inode, bool abort) mutex_lock(&fi->inmem_lock); list_for_each_entry_safe(cur, tmp, &fi->inmem_pages, list) { + lock_page(cur->page); if (!abort) { - lock_page(cur->page); if (cur->page->mapping == inode->i_mapping) { set_page_dirty(cur->page); f2fs_wait_on_page_writeback(cur->page, DATA); @@ -271,12 +263,13 @@ int commit_inmem_pages(struct inode *inode, bool abort) break; } } - f2fs_put_page(cur->page, 1); } else { trace_f2fs_commit_inmem_page(cur->page, INMEM_DROP); - put_page(cur->page); } - radix_tree_delete(&fi->inmem_root, cur->page->index); + set_page_private(cur->page, 0); + ClearPagePrivate(cur->page); + f2fs_put_page(cur->page, 1); + list_del(&cur->list); kmem_cache_free(inmem_entry_slab, cur); dec_page_count(F2FS_I_SB(inode), F2FS_INMEM_PAGES); diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index 230f9cd..d0bd952 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h @@ -177,6 +177,15 @@ struct segment_allocation { void (*allocate_segment)(struct f2fs_sb_info *, int, bool); }; +/* + * this value is set in page as a private data which indicate that + * the page is atomically written, and it is in inmem_pages list. + */ +#define ATOMIC_WRITTEN_PAGE 0x0000ffff + +#define IS_ATOMIC_WRITTEN_PAGE(page) \ + (page_private(page) == (unsigned long)ATOMIC_WRITTEN_PAGE) + struct inmem_pages { struct list_head list; struct page *page; diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index e5efb53..4db5cd9 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -423,7 +423,6 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb) fi->i_current_depth = 1; fi->i_advise = 0; init_rwsem(&fi->i_sem); - INIT_RADIX_TREE(&fi->inmem_root, GFP_NOFS); INIT_LIST_HEAD(&fi->inmem_pages); mutex_init(&fi->inmem_lock); -- 2.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/