add OCFS2_LOCK_IGNORE_BLOCKED arg_flags to ocfs2_cluster_lock() to prevent hang
PATCH 1/1 add OCFS2_LOCK_IGNORE_BLOCKED arg_flags to ocfs2_cluster_lock() to prevent hang
From: Linus Torvalds <[email protected]>
Orabug: 21793017
commit 743b5f1434f5 ("ocfs2: take inode lock in ocfs2_iop_set/get_acl()") introduced this issue. ocfs2_setattr called by chmod command holds cluster wide inode lock (Orabug 21685187) when calling posix_acl_chmod. This latter function in turn calls ocfs2_iop_get_acl and ocfs2_iop_set_acl. These two are also called directly from vfs layer for getfacl/setfacl commands and therefore acquire the cluster wide inode lock. If a remote conversion request comes after the first inode lock in ocfs2_setattr, OCFS2_LOCK_BLOCKED will be set in l_flags. This will cause the second call to inode lock from the ocfs2_iop_get|set_acl() to block indefinetly. The new flag OCFS2_LOCK_IGNORE_BLOCKED will be used to prevent this blocking.
Junxiao Bi <[email protected]>
--- Makefile | 2 +- fs/ocfs2/acl.c | 7 +++++-- fs/ocfs2/dlmglue.c | 3 ++- fs/ocfs2/dlmglue.h | 2 ++ 4 files changed, 10 insertions(+), 4 deletions(-)
Makefile +1 -1
@@ -1,7 +1,7 @@ VERSION = 4 PATCHLEVEL = 3 SUBLEVEL = 0 -EXTRAVERSION = -rc7 +EXTRAVERSION = NAME = Blurry Fish Butt # *DOCUMENTATION*
fs/ocfs2/acl.c +5 -2
@@ -37,6 +37,7 @@#include "xattr.h" #include "acl.h" +/* * Convert from xattr value to acl struct. */
@@ -287,7 +288,8 @@ int ocfs2_iop_set_acl(struct inode *inode, struct posix_acl *acl, int type)struct buffer_head *bh =NULL ;int status =0 ; - status =ocfs2_inode_lock (inode, &bh,1 ); + status =ocfs2_inode_lock_full (inode, &bh,1 , +OCFS2_LOCK_IGNORE_BLOCKED );if (status <0 ) {if (status != -ENOENT )mlog_errno (status);
@@ -309,7 +311,8 @@ struct posix_acl *ocfs2_iop_get_acl(struct inode *inode, int type) osb =OCFS2_SB (inode->i_sb);if (!(osb->s_mount_opt &OCFS2_MOUNT_POSIX_ACL ))return NULL ; - ret =ocfs2_inode_lock (inode, &di_bh,0 ); + ret =ocfs2_inode_lock_full (inode, &di_bh,0 , +OCFS2_LOCK_IGNORE_BLOCKED );if (ret <0 ) {if (ret != -ENOENT )mlog_errno (ret);
fs/ocfs2/dlmglue.c +2 -1
@@ -1447,7 +1447,8 @@ again: }if (lockres->l_flags &OCFS2_LOCK_BLOCKED && - !ocfs2_may_continue_on_blocked_lock (lockres, level)) { + !ocfs2_may_continue_on_blocked_lock (lockres, level) && + !(arg_flags &OCFS2_LOCK_IGNORE_BLOCKED )) {/* is the lock is currently blocked on behalf of * another node */ lockres_add_mask_waiter (lockres, &mw,OCFS2_LOCK_BLOCKED ,0 );
fs/ocfs2/dlmglue.h +2 -0
@@ -78,6 +78,8 @@ struct ocfs2_orphan_scan_lvb {/* don't block waiting for the downconvert thread, instead return -EAGAIN */ #define OCFS2_LOCK_NONBLOCK (0x04) +/* if requested level is <= l_level, ignore BLOCKED flag. */ +#define OCFS2_LOCK_IGNORE_BLOCKED (0x08)/* Locking subclasses of inode cluster lock */ enum {OI_LS_NORMAL =0 ,
Signature · 1 line
1.7.1
Mark Fasheh
NAKPATCH 1/1 add OCFS2_LOCK_IGNORE_BLOCKED arg_flags to ocfs2_cluster_lock() to prevent hang
Quoted 4 lines · Tariq Saeed
From: Linus Torvalds <[email protected]>
Orabug: 21793017
Quoted 11 lines
commit
743b5f1434f5("ocfs2: take inode lock in ocfs2_iop_set/get_acl()") introduced this issue.ocfs2_setattrcalled by chmod command holds cluster wide inode lock (Orabug 21685187) when callingposix_acl_chmod. This latter function in turn callsocfs2_iop_get_aclandocfs2_iop_set_acl. These two are also called directly from vfs layer for getfacl/setfacl commands and therefore acquire the cluster wide inode lock. If a remote conversion request comes after the first inode lock inocfs2_setattr,OCFS2_LOCK_BLOCKEDwill be set inl_flags. This will cause the second call to inode lock from the ocfs2_iop_get|set_acl() to block indefinetly. The new flagOCFS2_LOCK_IGNORE_BLOCKEDwill be used to prevent this blocking.
NACK - as I explained earlier on this list we need to refactor the code to avoid double locking the same resource. It is not acceptable to introduce recursive locks into the code.
--Mark
--
Mark Fasheh
PATCH 1/1 add OCFS2_LOCK_IGNORE_BLOCKED arg_flags to ocfs2_cluster_lock() to prevent hang
Quoted 1 line · Mark Fasheh
NACK - as I explained earlier on this list we need to refactor the code to
Not sure how things work in the open source world. Is refactoring to be picked by
somebody soon?
Thanks
-Tariq
PATCH 1/1 add OCFS2_LOCK_IGNORE_BLOCKED arg_flags to ocfs2_cluster_lock() to prevent hang
Quoted 6 lines · Tariq Saeed
Quoted 1 line · Mark Fasheh
NACK - as I explained earlier on this list we need to refactor the code to
Not sure how things work in the open source world. Is refactoring to be picked by
somebody soon?
No problem, A couple explanations / notes:
1) CC me with your patches (someone had to point the last one out to me).
I'll get to reviewing most things but if you CC me then it can happen sooner.
2) You are fixing the bug and sending the patches. We usually expect the sender to incorporate feedback into their patch so the answer would be that you get to to the refactoring :)
If you need to make small changes to the VFS to let this happen (sometimes we might want 'nolock' variants of funtions, etc), do them in seperate patches and send them along with your changes.
Hope this helps,
--Mark
--
Mark Fasheh
PATCH 1/1 add OCFS2_LOCK_IGNORE_BLOCKED arg_flags to ocfs2_cluster_lock() to prevent hang
Hi Mark,
We may fix this issue in another way, without recursive locking and without refactoring. We can check before asking for the second locking, if lock is already hold, then skip the second locking, do you agree fixing like this?
Thanks,
Junxiao.
Quoted 35 lines · Mark Fasheh
Quoted 6 lines · Tariq Saeed
Quoted 1 line · Mark Fasheh
NACK - as I explained earlier on this list we need to refactor the code to
Not sure how things work in the open source world. Is refactoring to be picked by
somebody soon?No problem, A couple explanations / notes:
1) CC me with your patches (someone had to point the last one out to me).
I'll get to reviewing most things but if you CC me then it can happen sooner.
2) You are fixing the bug and sending the patches. We usually expect the sender to incorporate feedback into their patch so the answer would be that you get to to the refactoring :)
If you need to make small changes to the VFS to let this happen (sometimes we might want 'nolock' variants of funtions, etc), do them in seperate patches and send them along with your changes.
Hope this helps,
--Mark--
Mark Fasheh_______________________________________________
Ocfs2-devel mailing list
Ocfs2-devel at oss.oracle.com
https://oss.oracle.com/mailman/listinfo/ocfs2-devel
Joel Becker
maintainerPATCH 1/1 add OCFS2_LOCK_IGNORE_BLOCKED arg_flags to ocfs2_cluster_lock() to prevent hang
Quoted 6 lines · Junxiao Bi
Hi Mark,
We may fix this issue in another way, without recursive locking and without refactoring. We can check before asking for the second locking, if lock is already hold, then skip the second locking, do you agree fixing like this?
Hey Junxiao,
What is to prevent the second lock from being dropped while in the middle of the operation?
Joel
PATCH 1/1 add OCFS2_LOCK_IGNORE_BLOCKED arg_flags to ocfs2_cluster_lock() to prevent hang
Hi Joel,
Quoted 8 lines · Joel Becker
Quoted 6 lines · Junxiao Bi
Hi Mark,
We may fix this issue in another way, without recursive locking and without refactoring. We can check before asking for the second locking, if lock is already hold, then skip the second locking, do you agree fixing like this?
Quoted 4 lines
Hey Junxiao,
What is to prevent the second lock from being dropped while in the middle of the operation?
Log processes id into lockres when lock is got. When do second locking, if this lock is already got by this process, then skip it.
Thanks,
Junxiao.
Quoted 3 lines
Joel