Linux kernel -stable discussions
 help / color / mirror / Atom feed
From: Namjae Jeon <linkinjeon@kernel.org>
To: gregkh@linuxfoundation.org, stable@vger.kernel.org, sashal@kernel.org
Cc: smfrench@gmail.com, Namjae Jeon <linkinjeon@kernel.org>,
	Steve French <stfrench@microsoft.com>
Subject: [PATCH 6.6.y 18/19] ksmbd: lazy v2 lease break on smb2_write()
Date: Sun, 31 Dec 2023 16:19:18 +0900	[thread overview]
Message-ID: <20231231071919.32103-19-linkinjeon@kernel.org> (raw)
In-Reply-To: <20231231071919.32103-1-linkinjeon@kernel.org>

[ Upstream commit c2a721eead71202a0d8ddd9b56ec8dce652c71d1 ]

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>
---
 fs/smb/server/oplock.c    | 45 +++++++++++++++++++++++++++++++++++++--
 fs/smb/server/oplock.h    |  1 +
 fs/smb/server/vfs.c       |  3 +++
 fs/smb/server/vfs_cache.h |  1 +
 4 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c
index 147d98427ce8..562b180459a1 100644
--- a/fs/smb/server/oplock.c
+++ b/fs/smb/server/oplock.c
@@ -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
diff --git a/fs/smb/server/oplock.h b/fs/smb/server/oplock.h
index b64d1536882a..5b93ea9196c0 100644
--- a/fs/smb/server/oplock.h
+++ b/fs/smb/server/oplock.h
@@ -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 */
diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c
index 9091dcd7a310..4277750a6da1 100644
--- a/fs/smb/server/vfs.c
+++ b/fs/smb/server/vfs.c
@@ -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);
 
diff --git a/fs/smb/server/vfs_cache.h b/fs/smb/server/vfs_cache.h
index 4d4938d6029b..a528f0cc775a 100644
--- a/fs/smb/server/vfs_cache.h
+++ b/fs/smb/server/vfs_cache.h
@@ -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,
-- 
2.25.1


  parent reply	other threads:[~2023-12-31  7:20 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-31  7:19 [PATCH 6.6.y 00/19] ksmbd backport patches for linux-6.6.y Namjae Jeon
2023-12-31  7:19 ` [PATCH 6.6.y 01/19] ksmbd: Remove unused field in ksmbd_user struct Namjae Jeon
2023-12-31  7:19 ` [PATCH 6.6.y 02/19] ksmbd: reorganize ksmbd_iov_pin_rsp() Namjae Jeon
2023-12-31  7:19 ` [PATCH 6.6.y 03/19] ksmbd: fix kernel-doc comment of ksmbd_vfs_setxattr() Namjae Jeon
2023-12-31  7:19 ` [PATCH 6.6.y 04/19] ksmbd: fix missing RDMA-capable flag for IPoIB device in ksmbd_rdma_capable_netdev() Namjae Jeon
2023-12-31  7:19 ` [PATCH 6.6.y 05/19] ksmbd: add support for surrogate pair conversion Namjae Jeon
2023-12-31  7:19 ` [PATCH 6.6.y 06/19] ksmbd: no need to wait for binded connection termination at logoff Namjae Jeon
2023-12-31  7:19 ` [PATCH 6.6.y 07/19] ksmbd: fix kernel-doc comment of ksmbd_vfs_kern_path_locked() Namjae Jeon
2023-12-31  7:19 ` [PATCH 6.6.y 08/19] ksmbd: prevent memory leak on error return Namjae Jeon
2023-12-31  7:19 ` [PATCH 6.6.y 09/19] ksmbd: separately allocate ci per dentry Namjae Jeon
2023-12-31  7:19 ` [PATCH 6.6.y 10/19] ksmbd: move oplock handling after unlock parent dir Namjae Jeon
2023-12-31  7:19 ` [PATCH 6.6.y 11/19] ksmbd: release interim response after sending status pending response Namjae Jeon
2023-12-31  7:19 ` [PATCH 6.6.y 12/19] ksmbd: move setting SMB2_FLAGS_ASYNC_COMMAND and AsyncId Namjae Jeon
2023-12-31  7:19 ` [PATCH 6.6.y 13/19] ksmbd: don't update ->op_state as OPLOCK_STATE_NONE on error Namjae Jeon
2023-12-31  7:19 ` [PATCH 6.6.y 14/19] ksmbd: set epoch in create context v2 lease Namjae Jeon
2023-12-31  7:19 ` [PATCH 6.6.y 15/19] ksmbd: set v2 lease capability Namjae Jeon
2023-12-31  7:19 ` [PATCH 6.6.y 16/19] ksmbd: downgrade RWH lease caching state to RH for directory Namjae Jeon
2023-12-31  7:19 ` [PATCH 6.6.y 17/19] ksmbd: send v2 lease break notification " Namjae Jeon
2023-12-31  7:19 ` Namjae Jeon [this message]
2023-12-31  7:19 ` [PATCH 6.6.y 19/19] ksmbd: avoid duplicate opinfo_put() call on error of smb21_lease_break_ack() Namjae Jeon
2024-01-01 18:11 ` [PATCH 6.6.y 00/19] ksmbd backport patches for linux-6.6.y Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231231071919.32103-19-linkinjeon@kernel.org \
    --to=linkinjeon@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=sashal@kernel.org \
    --cc=smfrench@gmail.com \
    --cc=stable@vger.kernel.org \
    --cc=stfrench@microsoft.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox