ksmbd: lazy v2 lease break on smb2_write()
Don't immediately send directory lease break notification on smb2_write(). Instead, It postpones it until smb2_close(). Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
d47d9886ae
commit
c2a721eead
@ -396,8 +396,8 @@ void close_id_del_oplock(struct ksmbd_file *fp)
|
||||
{
|
||||
struct oplock_info *opinfo;
|
||||
|
||||
if (S_ISDIR(file_inode(fp->filp)->i_mode))
|
||||
return;
|
||||
if (fp->reserve_lease_break)
|
||||
smb_lazy_parent_lease_break_close(fp);
|
||||
|
||||
opinfo = opinfo_get(fp);
|
||||
if (!opinfo)
|
||||
@ -1127,6 +1127,47 @@ void smb_send_parent_lease_break_noti(struct ksmbd_file *fp,
|
||||
ksmbd_inode_put(p_ci);
|
||||
}
|
||||
|
||||
void smb_lazy_parent_lease_break_close(struct ksmbd_file *fp)
|
||||
{
|
||||
struct oplock_info *opinfo;
|
||||
struct ksmbd_inode *p_ci = NULL;
|
||||
|
||||
rcu_read_lock();
|
||||
opinfo = rcu_dereference(fp->f_opinfo);
|
||||
rcu_read_unlock();
|
||||
|
||||
if (!opinfo->is_lease || opinfo->o_lease->version != 2)
|
||||
return;
|
||||
|
||||
p_ci = ksmbd_inode_lookup_lock(fp->filp->f_path.dentry->d_parent);
|
||||
if (!p_ci)
|
||||
return;
|
||||
|
||||
read_lock(&p_ci->m_lock);
|
||||
list_for_each_entry(opinfo, &p_ci->m_op_list, op_entry) {
|
||||
if (!opinfo->is_lease)
|
||||
continue;
|
||||
|
||||
if (opinfo->o_lease->state != SMB2_OPLOCK_LEVEL_NONE) {
|
||||
if (!atomic_inc_not_zero(&opinfo->refcount))
|
||||
continue;
|
||||
|
||||
atomic_inc(&opinfo->conn->r_count);
|
||||
if (ksmbd_conn_releasing(opinfo->conn)) {
|
||||
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);
|
||||
|
||||
ksmbd_inode_put(p_ci);
|
||||
}
|
||||
|
||||
/**
|
||||
* smb_grant_oplock() - handle oplock/lease request on file open
|
||||
* @work: smb work
|
||||
|
@ -129,4 +129,5 @@ int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci,
|
||||
void destroy_lease_table(struct ksmbd_conn *conn);
|
||||
void smb_send_parent_lease_break_noti(struct ksmbd_file *fp,
|
||||
struct lease_ctx_info *lctx);
|
||||
void smb_lazy_parent_lease_break_close(struct ksmbd_file *fp);
|
||||
#endif /* __KSMBD_OPLOCK_H */
|
||||
|
@ -517,6 +517,9 @@ int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp,
|
||||
}
|
||||
}
|
||||
|
||||
/* Reserve lease break for parent dir at closing time */
|
||||
fp->reserve_lease_break = true;
|
||||
|
||||
/* Do we need to break any of a levelII oplock? */
|
||||
smb_break_all_levII_oplock(work, fp, 1);
|
||||
|
||||
|
@ -105,6 +105,7 @@ struct ksmbd_file {
|
||||
struct ksmbd_readdir_data readdir_data;
|
||||
int dot_dotdot[2];
|
||||
unsigned int f_state;
|
||||
bool reserve_lease_break;
|
||||
};
|
||||
|
||||
static inline void set_ctx_actor(struct dir_context *ctx,
|
||||
|
Loading…
x
Reference in New Issue
Block a user