[PATCH] ksmbd: notify parent directory leases on child create
Namjae Jeon <[email protected]>
| Newsgroups | org.kernel.vger.linux-cifs |
|---|---|
| Message-ID | <[email protected]> |
BVT_DirectoryLeasing_ReadWriteHandleCaching requires a parent directory lease break notification when another client creates a child in the leased directory. A child CREATE without a lease context did not notify the parent lease holders because the notification path expected a non-NULL lease context. Allow the parent lease notification helper to handle a NULL child lease context and notify matching parent leases. Invoke it after a child is created without a lease context while preserving the existing lease-key filtering for requests that provide one. Signed-off-by: Namjae Jeon <[email protected]> --- fs/smb/server/oplock.c | 9 +++++---- fs/smb/server/smb2pdu.c | 3 +++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c index 5fc2c79881d1..58af0fddf39f 100644 --- a/fs/smb/server/oplock.c +++ b/fs/smb/server/oplock.c @@ -1450,7 +1450,7 @@ void smb_send_parent_lease_break_noti(struct ksmbd_file *fp, struct ksmbd_inode *p_ci = NULL; LIST_HEAD(brk_list); - if (lctx->version != 2) + if (lctx && lctx->version != 2) return; p_ci = ksmbd_inode_lookup_lock(fp->filp->f_path.dentry->d_parent); @@ -1463,9 +1463,10 @@ void smb_send_parent_lease_break_noti(struct ksmbd_file *fp, continue; if (opinfo->o_lease->state != SMB2_OPLOCK_LEVEL_NONE && - (!(lctx->flags & SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET_LE) || - !compare_guid_key(opinfo, fp->conn->ClientGUID, - lctx->parent_lease_key))) { + (!lctx || + (!(lctx->flags & SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET_LE) || + !compare_guid_key(opinfo, fp->conn->ClientGUID, + lctx->parent_lease_key)))) { if (!atomic_inc_not_zero(&opinfo->refcount)) continue; diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index da461535229a..bcf4e8e1ca22 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -4663,6 +4663,9 @@ int smb2_open(struct ksmbd_work *work) goto err_out1; } } else { + if (created && !lc) + smb_send_parent_lease_break_noti(fp, NULL); + if (req_op_level == SMB2_OPLOCK_LEVEL_LEASE && lc) { if (S_ISDIR(file_inode(filp)->i_mode)) { lc->req_state &= ~SMB2_LEASE_WRITE_CACHING_LE; -- 2.25.1