With selinux enabled client has a dead lock which leads to
client eviction from MDS.
1 thread 2 thread
do file open do stat
inode_lock(parend dir)
got LDLM_PR(parent dir)
enqueue LDLM_CW(parent dir) waits on inode_lock to notify security
waits
timeout on enqueue
and client eviction because client didn't cancel a LDLM_PR lock
security_inode_notifysecctx()->selinux_inode_notifysecctx()->
selinux_inode_setsecurity()
The call of selinux_inode_setsecurity doesn't need to hold
inode_lock.
Fixes:
1d44980bcb ("LU-8956 llite: set sec ctx on client's inode at create time")
Signed-off-by: Alexander Boyko <alexander.boyko@hpe.com>
Cray-bug-id: LUS-8924
Change-Id: I4727da45590734bde57bee9d378b61c30b5d515a
Reviewed-on: https://review.whamcloud.com/38792
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: Sebastien Buisson <sbuisson@ddn.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andrew Perepechko <andrew.perepechko@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
dentry.d_inode = inode;
if (sbi->ll_flags & LL_SBI_FILE_SECCTX) {
dentry.d_inode = inode;
if (sbi->ll_flags & LL_SBI_FILE_SECCTX) {
+ /* no need to protect selinux_inode_setsecurity() by
+ * inode_lock. Taking it would lead to a client deadlock
+ * LU-13617
+ */
err = security_inode_notifysecctx(inode,
op_data->op_file_secctx,
op_data->op_file_secctx_size);
err = security_inode_notifysecctx(inode,
op_data->op_file_secctx,
op_data->op_file_secctx_size);
} else {
err = ll_inode_init_security(&dentry, inode, parent);
}
} else {
err = ll_inode_init_security(&dentry, inode, parent);
}
}
if (secctx != NULL && secctxlen != 0) {
}
if (secctx != NULL && secctxlen != 0) {
+ /* no need to protect selinux_inode_setsecurity() by
+ * inode_lock. Taking it would lead to a client deadlock
+ * LU-13617
+ */
rc = security_inode_notifysecctx(inode, secctx,
secctxlen);
rc = security_inode_notifysecctx(inode, secctx,
secctxlen);
if (rc)
CWARN("cannot set security context for "
DFID": rc = %d\n",
if (rc)
CWARN("cannot set security context for "
DFID": rc = %d\n",
if ((ll_i2sbi(inode)->ll_flags & LL_SBI_FILE_SECCTX) &&
secctx != NULL) {
if ((ll_i2sbi(inode)->ll_flags & LL_SBI_FILE_SECCTX) &&
secctx != NULL) {
/* must be done before d_instantiate, because it calls
* security_d_instantiate, which means a getxattr if security
* context is not set yet */
/* must be done before d_instantiate, because it calls
* security_d_instantiate, which means a getxattr if security
* context is not set yet */
+ /* no need to protect selinux_inode_setsecurity() by
+ * inode_lock. Taking it would lead to a client deadlock
+ * LU-13617
+ */
rc = security_inode_notifysecctx(inode, secctx, secctxlen);
rc = security_inode_notifysecctx(inode, secctx, secctxlen);
GOTO(err_exit, err);
if (sbi->ll_flags & LL_SBI_FILE_SECCTX) {
GOTO(err_exit, err);
if (sbi->ll_flags & LL_SBI_FILE_SECCTX) {
/* must be done before d_instantiate, because it calls
* security_d_instantiate, which means a getxattr if security
* context is not set yet */
/* must be done before d_instantiate, because it calls
* security_d_instantiate, which means a getxattr if security
* context is not set yet */
+ /* no need to protect selinux_inode_setsecurity() by
+ * inode_lock. Taking it would lead to a client deadlock
+ * LU-13617
+ */
err = security_inode_notifysecctx(inode,
op_data->op_file_secctx,
op_data->op_file_secctx_size);
err = security_inode_notifysecctx(inode,
op_data->op_file_secctx,
op_data->op_file_secctx_size);
if (err)
GOTO(err_exit, err);
}
if (err)
GOTO(err_exit, err);
}