mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 20:48:49 +08:00
ksmbd: use rwsem instead of rwlock for lease break
lease break wait for lease break acknowledgment. rwsem is more suitable than unlock while traversing the list for parent lease break in ->m_op_list. Cc: stable@vger.kernel.org Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
97c2ec6466
commit
d1c189c6cb
@ -207,9 +207,9 @@ static void opinfo_add(struct oplock_info *opinfo)
|
||||
{
|
||||
struct ksmbd_inode *ci = opinfo->o_fp->f_ci;
|
||||
|
||||
write_lock(&ci->m_lock);
|
||||
down_write(&ci->m_lock);
|
||||
list_add_rcu(&opinfo->op_entry, &ci->m_op_list);
|
||||
write_unlock(&ci->m_lock);
|
||||
up_write(&ci->m_lock);
|
||||
}
|
||||
|
||||
static void opinfo_del(struct oplock_info *opinfo)
|
||||
@ -221,9 +221,9 @@ static void opinfo_del(struct oplock_info *opinfo)
|
||||
lease_del_list(opinfo);
|
||||
write_unlock(&lease_list_lock);
|
||||
}
|
||||
write_lock(&ci->m_lock);
|
||||
down_write(&ci->m_lock);
|
||||
list_del_rcu(&opinfo->op_entry);
|
||||
write_unlock(&ci->m_lock);
|
||||
up_write(&ci->m_lock);
|
||||
}
|
||||
|
||||
static unsigned long opinfo_count(struct ksmbd_file *fp)
|
||||
@ -526,21 +526,18 @@ static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci,
|
||||
* Compare lease key and client_guid to know request from same owner
|
||||
* of same client
|
||||
*/
|
||||
read_lock(&ci->m_lock);
|
||||
down_read(&ci->m_lock);
|
||||
list_for_each_entry(opinfo, &ci->m_op_list, op_entry) {
|
||||
if (!opinfo->is_lease || !opinfo->conn)
|
||||
continue;
|
||||
read_unlock(&ci->m_lock);
|
||||
lease = opinfo->o_lease;
|
||||
|
||||
ret = compare_guid_key(opinfo, client_guid, lctx->lease_key);
|
||||
if (ret) {
|
||||
m_opinfo = opinfo;
|
||||
/* skip upgrading lease about breaking lease */
|
||||
if (atomic_read(&opinfo->breaking_cnt)) {
|
||||
read_lock(&ci->m_lock);
|
||||
if (atomic_read(&opinfo->breaking_cnt))
|
||||
continue;
|
||||
}
|
||||
|
||||
/* upgrading lease */
|
||||
if ((atomic_read(&ci->op_count) +
|
||||
@ -570,9 +567,8 @@ static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci,
|
||||
lease_none_upgrade(opinfo, lctx->req_state);
|
||||
}
|
||||
}
|
||||
read_lock(&ci->m_lock);
|
||||
}
|
||||
read_unlock(&ci->m_lock);
|
||||
up_read(&ci->m_lock);
|
||||
|
||||
return m_opinfo;
|
||||
}
|
||||
@ -1114,7 +1110,7 @@ void smb_send_parent_lease_break_noti(struct ksmbd_file *fp,
|
||||
if (!p_ci)
|
||||
return;
|
||||
|
||||
read_lock(&p_ci->m_lock);
|
||||
down_read(&p_ci->m_lock);
|
||||
list_for_each_entry(opinfo, &p_ci->m_op_list, op_entry) {
|
||||
if (opinfo->conn == NULL || !opinfo->is_lease)
|
||||
continue;
|
||||
@ -1132,13 +1128,11 @@ void smb_send_parent_lease_break_noti(struct ksmbd_file *fp,
|
||||
continue;
|
||||
}
|
||||
|
||||
read_unlock(&p_ci->m_lock);
|
||||
oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE);
|
||||
opinfo_conn_put(opinfo);
|
||||
read_lock(&p_ci->m_lock);
|
||||
}
|
||||
}
|
||||
read_unlock(&p_ci->m_lock);
|
||||
up_read(&p_ci->m_lock);
|
||||
|
||||
ksmbd_inode_put(p_ci);
|
||||
}
|
||||
@ -1159,7 +1153,7 @@ void smb_lazy_parent_lease_break_close(struct ksmbd_file *fp)
|
||||
if (!p_ci)
|
||||
return;
|
||||
|
||||
read_lock(&p_ci->m_lock);
|
||||
down_read(&p_ci->m_lock);
|
||||
list_for_each_entry(opinfo, &p_ci->m_op_list, op_entry) {
|
||||
if (opinfo->conn == NULL || !opinfo->is_lease)
|
||||
continue;
|
||||
@ -1173,13 +1167,11 @@ void smb_lazy_parent_lease_break_close(struct ksmbd_file *fp)
|
||||
atomic_dec(&opinfo->conn->r_count);
|
||||
continue;
|
||||
}
|
||||
read_unlock(&p_ci->m_lock);
|
||||
oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE);
|
||||
opinfo_conn_put(opinfo);
|
||||
read_lock(&p_ci->m_lock);
|
||||
}
|
||||
}
|
||||
read_unlock(&p_ci->m_lock);
|
||||
up_read(&p_ci->m_lock);
|
||||
|
||||
ksmbd_inode_put(p_ci);
|
||||
}
|
||||
|
@ -3376,9 +3376,9 @@ int smb2_open(struct ksmbd_work *work)
|
||||
* after daccess, saccess, attrib_only, and stream are
|
||||
* initialized.
|
||||
*/
|
||||
write_lock(&fp->f_ci->m_lock);
|
||||
down_write(&fp->f_ci->m_lock);
|
||||
list_add(&fp->node, &fp->f_ci->m_fp_list);
|
||||
write_unlock(&fp->f_ci->m_lock);
|
||||
up_write(&fp->f_ci->m_lock);
|
||||
|
||||
/* Check delete pending among previous fp before oplock break */
|
||||
if (ksmbd_inode_pending_delete(fp)) {
|
||||
|
@ -646,7 +646,7 @@ int ksmbd_smb_check_shared_mode(struct file *filp, struct ksmbd_file *curr_fp)
|
||||
* Lookup fp in master fp list, and check desired access and
|
||||
* shared mode between previous open and current open.
|
||||
*/
|
||||
read_lock(&curr_fp->f_ci->m_lock);
|
||||
down_read(&curr_fp->f_ci->m_lock);
|
||||
list_for_each_entry(prev_fp, &curr_fp->f_ci->m_fp_list, node) {
|
||||
if (file_inode(filp) != file_inode(prev_fp->filp))
|
||||
continue;
|
||||
@ -722,7 +722,7 @@ int ksmbd_smb_check_shared_mode(struct file *filp, struct ksmbd_file *curr_fp)
|
||||
break;
|
||||
}
|
||||
}
|
||||
read_unlock(&curr_fp->f_ci->m_lock);
|
||||
up_read(&curr_fp->f_ci->m_lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ static int ksmbd_inode_init(struct ksmbd_inode *ci, struct ksmbd_file *fp)
|
||||
ci->m_fattr = 0;
|
||||
INIT_LIST_HEAD(&ci->m_fp_list);
|
||||
INIT_LIST_HEAD(&ci->m_op_list);
|
||||
rwlock_init(&ci->m_lock);
|
||||
init_rwsem(&ci->m_lock);
|
||||
ci->m_de = fp->filp->f_path.dentry;
|
||||
return 0;
|
||||
}
|
||||
@ -261,14 +261,14 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp)
|
||||
}
|
||||
|
||||
if (atomic_dec_and_test(&ci->m_count)) {
|
||||
write_lock(&ci->m_lock);
|
||||
down_write(&ci->m_lock);
|
||||
if (ci->m_flags & (S_DEL_ON_CLS | S_DEL_PENDING)) {
|
||||
ci->m_flags &= ~(S_DEL_ON_CLS | S_DEL_PENDING);
|
||||
write_unlock(&ci->m_lock);
|
||||
up_write(&ci->m_lock);
|
||||
ksmbd_vfs_unlink(filp);
|
||||
write_lock(&ci->m_lock);
|
||||
down_write(&ci->m_lock);
|
||||
}
|
||||
write_unlock(&ci->m_lock);
|
||||
up_write(&ci->m_lock);
|
||||
|
||||
ksmbd_inode_free(ci);
|
||||
}
|
||||
@ -289,9 +289,9 @@ static void __ksmbd_remove_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp
|
||||
if (!has_file_id(fp->volatile_id))
|
||||
return;
|
||||
|
||||
write_lock(&fp->f_ci->m_lock);
|
||||
down_write(&fp->f_ci->m_lock);
|
||||
list_del_init(&fp->node);
|
||||
write_unlock(&fp->f_ci->m_lock);
|
||||
up_write(&fp->f_ci->m_lock);
|
||||
|
||||
write_lock(&ft->lock);
|
||||
idr_remove(ft->idr, fp->volatile_id);
|
||||
@ -523,17 +523,17 @@ struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry)
|
||||
if (!ci)
|
||||
return NULL;
|
||||
|
||||
read_lock(&ci->m_lock);
|
||||
down_read(&ci->m_lock);
|
||||
list_for_each_entry(lfp, &ci->m_fp_list, node) {
|
||||
if (inode == file_inode(lfp->filp)) {
|
||||
atomic_dec(&ci->m_count);
|
||||
lfp = ksmbd_fp_get(lfp);
|
||||
read_unlock(&ci->m_lock);
|
||||
up_read(&ci->m_lock);
|
||||
return lfp;
|
||||
}
|
||||
}
|
||||
atomic_dec(&ci->m_count);
|
||||
read_unlock(&ci->m_lock);
|
||||
up_read(&ci->m_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -705,13 +705,13 @@ static bool session_fd_check(struct ksmbd_tree_connect *tcon,
|
||||
|
||||
conn = fp->conn;
|
||||
ci = fp->f_ci;
|
||||
write_lock(&ci->m_lock);
|
||||
down_write(&ci->m_lock);
|
||||
list_for_each_entry_rcu(op, &ci->m_op_list, op_entry) {
|
||||
if (op->conn != conn)
|
||||
continue;
|
||||
op->conn = NULL;
|
||||
}
|
||||
write_unlock(&ci->m_lock);
|
||||
up_write(&ci->m_lock);
|
||||
|
||||
fp->conn = NULL;
|
||||
fp->tcon = NULL;
|
||||
@ -801,13 +801,13 @@ int ksmbd_reopen_durable_fd(struct ksmbd_work *work, struct ksmbd_file *fp)
|
||||
fp->tcon = work->tcon;
|
||||
|
||||
ci = fp->f_ci;
|
||||
write_lock(&ci->m_lock);
|
||||
down_write(&ci->m_lock);
|
||||
list_for_each_entry_rcu(op, &ci->m_op_list, op_entry) {
|
||||
if (op->conn)
|
||||
continue;
|
||||
op->conn = fp->conn;
|
||||
}
|
||||
write_unlock(&ci->m_lock);
|
||||
up_write(&ci->m_lock);
|
||||
|
||||
__open_id(&work->sess->file_table, fp, OPEN_ID_TYPE_VOLATILE_ID);
|
||||
if (!has_file_id(fp->volatile_id)) {
|
||||
|
@ -47,7 +47,7 @@ struct stream {
|
||||
};
|
||||
|
||||
struct ksmbd_inode {
|
||||
rwlock_t m_lock;
|
||||
struct rw_semaphore m_lock;
|
||||
atomic_t m_count;
|
||||
atomic_t op_count;
|
||||
/* opinfo count for streams */
|
||||
|
Loading…
Reference in New Issue
Block a user