ocfs2: Avoid system inode ref in confusion by add mutex lock
PATCH 1/1 ocfs2: Avoid system inode ref in confusion by add mutex lock
The following case may lead to the same system inode ref in confusion.
A thread B threadocfs2_get_system_file_inode
->get_local_system_inode
->_ocfs2_get_system_file_inode
because of *arr == NULL,
ocfs2_get_system_file_inode
->get_local_system_inode
->_ocfs2_get_system_file_inodegets first ref thru_ocfs2_get_system_file_inode,
gets second ref thru igrab and
set *arr = inode
at the moment, B thread also gets two refs, so lead to one more inode ref.
So add mutex lock to avoid multi thread set two inode ref once at the same time.
--- fs/ocfs2/ocfs2.h | 2 ++ fs/ocfs2/super.c | 2 ++ fs/ocfs2/sysfile.c | 3 +++ 3 files changed, 7 insertions(+)
fs/ocfs2/ocfs2.h +2 -0
@@ -449,6 +449,8 @@ struct ocfs2_super/* rb tree root for refcount lock. */ struct rb_root osb_rf_lock_tree;struct ocfs2_refcount_tree *osb_ref_tree_lru; + +struct mutex system_file_mutex; };#define OCFS2_SB (sb) ((struct ocfs2_super *)(sb)->s_fs_info)
fs/ocfs2/super.c +2 -0
@@ -2123,6 +2123,8 @@ static int ocfs2_initialize_super(struct super_block *sb,spin_lock_init (&osb->osb_xattr_lock);ocfs2_init_steal_slots (osb); +mutex_init (&osb->system_file_mutex); +atomic_set (&osb->alloc_stats.moves,0 );atomic_set (&osb->alloc_stats.local_data,0 );atomic_set (&osb->alloc_stats.bitmap_data,0 );
fs/ocfs2/sysfile.c +3 -0
@@ -113,9 +113,11 @@ struct inode *ocfs2_get_system_file_inode(struct ocfs2_super *osb, }else arr =get_local_system_inode (osb, type, slot); +mutex_lock (&osb->system_file_mutex);if (arr && ((inode = *arr) !=NULL )) {/* get a ref in addition to the array ref */ inode =igrab (inode); +mutex_unlock (&osb->system_file_mutex);BUG_ON (!inode);return inode;
@@ -129,6 +131,7 @@ struct inode *ocfs2_get_system_file_inode(struct ocfs2_super *osb, *arr =igrab (inode);BUG_ON (!*arr); } +mutex_unlock (&osb->system_file_mutex);return inode; }
Signature · 1 line
1.8.4.3
PATCH 1/1 ocfs2: Avoid system inode ref in confusion by add mutex lock
Quoted 18 lines · On Fri, 14 Mar 2014 09:55:36 +0800 jiangyiwen <[email protected]> wrote:
The following case may lead to the same system inode ref in confusion.
A thread B thread
ocfs2_get_system_file_inode
->get_local_system_inode
->_ocfs2_get_system_file_inodebecause of *arr == NULL, ocfs2_get_system_file_inode ->get_local_system_inode ->_ocfs2_get_system_file_inodegets first ref thru
_ocfs2_get_system_file_inode,
gets second ref thru igrab and
set *arr = inode
at the moment, B thread also gets two refs, so lead to one more inode ref.
Quoted 2 lines
So add mutex lock to avoid multi thread set two inode ref once at the same time.
Looks good to me. I queued it for 3.15-rc1.
From: jiangyiwen <[email protected]>
Subject: ocfs2: avoid system inode ref confusion by adding mutex lock
The following case may lead to the same system inode ref in confusion.
A thread B threadocfs2_get_system_file_inode
->get_local_system_inode
->_ocfs2_get_system_file_inode
because of *arr == NULL,
ocfs2_get_system_file_inode
->get_local_system_inode
->_ocfs2_get_system_file_inodegets first ref thru_ocfs2_get_system_file_inode,
gets second ref thru igrab and
set *arr = inode
at the moment, B thread also gets two refs, so lead to one more inode ref.
So add mutex lock to avoid multi thread set two inode ref once at the same time.
---
fs/ocfs2/ocfs2.h | 2 ++ fs/ocfs2/super.c | 2 ++ fs/ocfs2/sysfile.c | 3 +++ 3 files changed, 7 insertions(+)
fs/ocfs2/ocfs2.h renamed from fs/ocfs2/ocfs2.h~ocfs2-avoid-system-inode-ref-confusion-by-adding-mutex-lock +2 -0
@@ -446,6 +446,8 @@ struct ocfs2_super/* rb tree root for refcount lock. */ struct rb_root osb_rf_lock_tree;struct ocfs2_refcount_tree *osb_ref_tree_lru; + +struct mutex system_file_mutex; };#define OCFS2_SB (sb) ((struct ocfs2_super *)(sb)->s_fs_info)
fs/ocfs2/super.c renamed from fs/ocfs2/super.c~ocfs2-avoid-system-inode-ref-confusion-by-adding-mutex-lock +2 -0
@@ -2100,6 +2100,8 @@ static int ocfs2_initialize_super(structspin_lock_init (&osb->osb_xattr_lock);ocfs2_init_steal_slots (osb); +mutex_init (&osb->system_file_mutex); +atomic_set (&osb->alloc_stats.moves,0 );atomic_set (&osb->alloc_stats.local_data,0 );atomic_set (&osb->alloc_stats.bitmap_data,0 );
fs/ocfs2/sysfile.c renamed from fs/ocfs2/sysfile.c~ocfs2-avoid-system-inode-ref-confusion-by-adding-mutex-lock +3 -0
@@ -113,9 +113,11 @@ struct inode *ocfs2_get_system_file_inod }else arr =get_local_system_inode (osb, type, slot); +mutex_lock (&osb->system_file_mutex);if (arr && ((inode = *arr) !=NULL )) {/* get a ref in addition to the array ref */ inode =igrab (inode); +mutex_unlock (&osb->system_file_mutex);BUG_ON (!inode);return inode;
@@ -129,6 +131,7 @@ struct inode *ocfs2_get_system_file_inod *arr =igrab (inode);BUG_ON (!*arr); } +mutex_unlock (&osb->system_file_mutex);return inode; }
_