All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] ksmbd: avoid reclaiming expired durable opens by the client
@ 2024-06-10 14:14 Namjae Jeon
  2024-06-10 14:14 ` [PATCH 2/3] ksmbd: add durable scavenger timer Namjae Jeon
  2024-06-10 14:14 ` [PATCH 3/3] ksmbd: move leading slash check to smb2_get_name() Namjae Jeon
  0 siblings, 2 replies; 6+ messages in thread
From: Namjae Jeon @ 2024-06-10 14:14 UTC (permalink / raw)
  To: linux-cifs; +Cc: smfrench, senozhatsky, tom, atteh.mailbox, Namjae Jeon

The expired durable opens should not be reclaimed by client.
This patch add ->durable_scavenger_timeout to fp and check it in
ksmbd_lookup_durable_fd().

Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
---
 fs/smb/server/vfs_cache.c | 9 ++++++++-
 fs/smb/server/vfs_cache.h | 1 +
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c
index 6cb599cd287e..a6804545db28 100644
--- a/fs/smb/server/vfs_cache.c
+++ b/fs/smb/server/vfs_cache.c
@@ -476,7 +476,10 @@ struct ksmbd_file *ksmbd_lookup_durable_fd(unsigned long long id)
 	struct ksmbd_file *fp;
 
 	fp = __ksmbd_lookup_fd(&global_ft, id);
-	if (fp && fp->conn) {
+	if (fp && (fp->conn ||
+		   (fp->durable_scavenger_timeout &&
+		    (fp->durable_scavenger_timeout <
+		     jiffies_to_msecs(jiffies))))) {
 		ksmbd_put_durable_fd(fp);
 		fp = NULL;
 	}
@@ -717,6 +720,10 @@ static bool session_fd_check(struct ksmbd_tree_connect *tcon,
 	fp->tcon = NULL;
 	fp->volatile_id = KSMBD_NO_FID;
 
+	if (fp->durable_timeout)
+		fp->durable_scavenger_timeout =
+			jiffies_to_msecs(jiffies) + fp->durable_timeout;
+
 	return true;
 }
 
diff --git a/fs/smb/server/vfs_cache.h b/fs/smb/server/vfs_cache.h
index 5a225e7055f1..f2ab1514e81a 100644
--- a/fs/smb/server/vfs_cache.h
+++ b/fs/smb/server/vfs_cache.h
@@ -101,6 +101,7 @@ struct ksmbd_file {
 	struct list_head		lock_list;
 
 	int				durable_timeout;
+	int				durable_scavenger_timeout;
 
 	/* if ls is happening on directory, below is valid*/
 	struct ksmbd_readdir_data	readdir_data;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/3] ksmbd: add durable scavenger timer
  2024-06-10 14:14 [PATCH 1/3] ksmbd: avoid reclaiming expired durable opens by the client Namjae Jeon
@ 2024-06-10 14:14 ` Namjae Jeon
  2024-06-10 15:30   ` Steve French
  2024-06-13 10:01   ` kernel test robot
  2024-06-10 14:14 ` [PATCH 3/3] ksmbd: move leading slash check to smb2_get_name() Namjae Jeon
  1 sibling, 2 replies; 6+ messages in thread
From: Namjae Jeon @ 2024-06-10 14:14 UTC (permalink / raw)
  To: linux-cifs; +Cc: smfrench, senozhatsky, tom, atteh.mailbox, Namjae Jeon

Launch ksmbd-durable-scavenger kernel thread to scan durable fps that
have not been reclaimed by a client within the configured time.

Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
---
 fs/smb/server/mgmt/user_session.c |   2 +
 fs/smb/server/server.c            |   1 +
 fs/smb/server/server.h            |   1 +
 fs/smb/server/smb2pdu.c           |   2 +-
 fs/smb/server/smb2pdu.h           |   2 +
 fs/smb/server/vfs_cache.c         | 165 +++++++++++++++++++++++++++++-
 fs/smb/server/vfs_cache.h         |   2 +
 7 files changed, 169 insertions(+), 6 deletions(-)

diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c
index aec0a7a12405..162a12685d2c 100644
--- a/fs/smb/server/mgmt/user_session.c
+++ b/fs/smb/server/mgmt/user_session.c
@@ -149,6 +149,7 @@ void ksmbd_session_destroy(struct ksmbd_session *sess)
 
 	ksmbd_tree_conn_session_logoff(sess);
 	ksmbd_destroy_file_table(&sess->file_table);
+	ksmbd_launch_ksmbd_durable_scavenger();
 	ksmbd_session_rpc_clear_list(sess);
 	free_channel_list(sess);
 	kfree(sess->Preauth_HashValue);
@@ -326,6 +327,7 @@ void destroy_previous_session(struct ksmbd_conn *conn,
 
 	ksmbd_destroy_file_table(&prev_sess->file_table);
 	prev_sess->state = SMB2_SESSION_EXPIRED;
+	ksmbd_launch_ksmbd_durable_scavenger();
 out:
 	up_write(&conn->session_lock);
 	up_write(&sessions_table_lock);
diff --git a/fs/smb/server/server.c b/fs/smb/server/server.c
index c67fbc8d6683..4d24cc105ef6 100644
--- a/fs/smb/server/server.c
+++ b/fs/smb/server/server.c
@@ -377,6 +377,7 @@ static void server_ctrl_handle_reset(struct server_ctrl_struct *ctrl)
 {
 	ksmbd_ipc_soft_reset();
 	ksmbd_conn_transport_destroy();
+	ksmbd_stop_durable_scavenger();
 	server_conf_free();
 	server_conf_init();
 	WRITE_ONCE(server_conf.state, SERVER_STATE_STARTING_UP);
diff --git a/fs/smb/server/server.h b/fs/smb/server/server.h
index db7278181760..4fc529335271 100644
--- a/fs/smb/server/server.h
+++ b/fs/smb/server/server.h
@@ -44,6 +44,7 @@ struct ksmbd_server_config {
 	unsigned int		max_connections;
 
 	char			*conf[SERVER_CONF_WORK_GROUP + 1];
+	struct task_struct	*dh_task;
 };
 
 extern struct ksmbd_server_config server_conf;
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index b6c5a8ea3887..4fb5070d3dc5 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -3519,7 +3519,7 @@ int smb2_open(struct ksmbd_work *work)
 					SMB2_CREATE_GUID_SIZE);
 			if (dh_info.timeout)
 				fp->durable_timeout = min(dh_info.timeout,
-						300000);
+						DURABLE_HANDLE_MAX_TIMEOUT);
 			else
 				fp->durable_timeout = 60;
 		}
diff --git a/fs/smb/server/smb2pdu.h b/fs/smb/server/smb2pdu.h
index 643f5e1cfe35..3be7d5ae65a8 100644
--- a/fs/smb/server/smb2pdu.h
+++ b/fs/smb/server/smb2pdu.h
@@ -72,6 +72,8 @@ struct create_durable_req_v2 {
 	__u8 CreateGuid[16];
 } __packed;
 
+#define DURABLE_HANDLE_MAX_TIMEOUT	300000
+
 struct create_durable_reconn_req {
 	struct create_context_hdr ccontext;
 	__u8   Name[8];
diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c
index a6804545db28..882a87f9e3ab 100644
--- a/fs/smb/server/vfs_cache.c
+++ b/fs/smb/server/vfs_cache.c
@@ -8,6 +8,8 @@
 #include <linux/filelock.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
 
 #include "glob.h"
 #include "vfs_cache.h"
@@ -17,6 +19,7 @@
 #include "mgmt/tree_connect.h"
 #include "mgmt/user_session.h"
 #include "smb_common.h"
+#include "server.h"
 
 #define S_DEL_PENDING			1
 #define S_DEL_ON_CLS			2
@@ -31,6 +34,11 @@ static struct ksmbd_file_table global_ft;
 static atomic_long_t fd_limit;
 static struct kmem_cache *filp_cache;
 
+static bool durable_scavenger_running;
+static DEFINE_MUTEX(durable_scavenger_lock);
+struct task_struc *dh_task;
+wait_queue_head_t dh_wq;
+
 void ksmbd_set_fd_limit(unsigned long limit)
 {
 	limit = min(limit, get_max_files());
@@ -279,9 +287,16 @@ static void __ksmbd_remove_durable_fd(struct ksmbd_file *fp)
 	if (!has_file_id(fp->persistent_id))
 		return;
 
-	write_lock(&global_ft.lock);
 	idr_remove(global_ft.idr, fp->persistent_id);
+}
+
+static void ksmbd_remove_durable_fd(struct ksmbd_file *fp)
+{
+	write_lock(&global_ft.lock);
+	__ksmbd_remove_durable_fd(fp);
 	write_unlock(&global_ft.lock);
+	if (waitqueue_active(&dh_wq))
+		wake_up(&dh_wq);
 }
 
 static void __ksmbd_remove_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp)
@@ -304,7 +319,7 @@ static void __ksmbd_close_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp)
 	struct ksmbd_lock *smb_lock, *tmp_lock;
 
 	fd_limit_close();
-	__ksmbd_remove_durable_fd(fp);
+	ksmbd_remove_durable_fd(fp);
 	if (ft)
 		__ksmbd_remove_fd(ft, fp);
 
@@ -696,6 +711,142 @@ static bool tree_conn_fd_check(struct ksmbd_tree_connect *tcon,
 	return fp->tcon != tcon;
 }
 
+static bool ksmbd_durable_scavenger_alive(void)
+{
+	mutex_lock(&durable_scavenger_lock);
+	if (!durable_scavenger_running) {
+		mutex_unlock(&durable_scavenger_lock);
+		return false;
+	}
+	mutex_unlock(&durable_scavenger_lock);
+
+	if (kthread_should_stop())
+		return false;
+
+	if (idr_is_empty(global_ft.idr))
+		return false;
+
+	return true;
+}
+
+static void ksmbd_scavenger_dispose_dh(struct list_head *head)
+{
+	while (!list_empty(head)) {
+		struct ksmbd_file *fp;
+
+		fp = list_first_entry(head, struct ksmbd_file, node);
+		list_del_init(&fp->node);
+		__ksmbd_close_fd(NULL, fp);
+	}
+}
+
+static int ksmbd_durable_scavenger(void *dummy)
+{
+	struct ksmbd_file *fp = NULL;
+	unsigned int id;
+	unsigned int min_timeout = 1;
+	bool found_fp_timeout;
+	LIST_HEAD(scavenger_list);
+	unsigned long remaining_jiffies;
+
+	__module_get(THIS_MODULE);
+
+	set_freezable();
+	while (ksmbd_durable_scavenger_alive()) {
+		if (try_to_freeze())
+			continue;
+
+		found_fp_timeout = false;
+
+		remaining_jiffies = wait_event_timeout(dh_wq,
+				   ksmbd_durable_scavenger_alive() == false,
+				   __msecs_to_jiffies(min_timeout));
+		if (remaining_jiffies)
+			min_timeout = jiffies_to_msecs(remaining_jiffies);
+		else
+			min_timeout = DURABLE_HANDLE_MAX_TIMEOUT;
+
+		write_lock(&global_ft.lock);
+		idr_for_each_entry(global_ft.idr, fp, id) {
+			if (!fp->durable_timeout)
+				continue;
+
+			if (atomic_read(&fp->refcount) > 1 ||
+			    fp->conn)
+				continue;
+
+			found_fp_timeout = true;
+			if (fp->durable_scavenger_timeout <=
+			    jiffies_to_msecs(jiffies)) {
+				__ksmbd_remove_durable_fd(fp);
+				list_add(&fp->node, &scavenger_list);
+			} else {
+				unsigned long durable_timeout;
+
+				durable_timeout =
+					fp->durable_scavenger_timeout -
+						jiffies_to_msecs(jiffies);
+
+				if (min_timeout > durable_timeout)
+					min_timeout = durable_timeout;
+			}
+		}
+		write_unlock(&global_ft.lock);
+
+		ksmbd_scavenger_dispose_dh(&scavenger_list);
+
+		if (found_fp_timeout == false)
+			break;
+	}
+
+	mutex_lock(&durable_scavenger_lock);
+	durable_scavenger_running = false;
+	mutex_unlock(&durable_scavenger_lock);
+
+	module_put(THIS_MODULE);
+
+	return 0;
+}
+
+void ksmbd_launch_ksmbd_durable_scavenger(void)
+{
+	if (!(server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE))
+		return;
+
+	mutex_lock(&durable_scavenger_lock);
+	if (durable_scavenger_running == true) {
+		mutex_unlock(&durable_scavenger_lock);
+		return;
+	}
+
+	durable_scavenger_running = true;
+
+	server_conf.dh_task = kthread_run(ksmbd_durable_scavenger,
+				     (void *)NULL, "ksmbd-durable-scavenger");
+	if (IS_ERR(server_conf.dh_task))
+		pr_err("cannot start conn thread, err : %ld\n",
+		       PTR_ERR(server_conf.dh_task));
+	mutex_unlock(&durable_scavenger_lock);
+}
+
+void ksmbd_stop_durable_scavenger(void)
+{
+	if (!(server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE))
+		return;
+
+	mutex_lock(&durable_scavenger_lock);
+	if (!durable_scavenger_running) {
+		mutex_unlock(&durable_scavenger_lock);
+		return;
+	}
+
+	durable_scavenger_running = false;
+	if (waitqueue_active(&dh_wq))
+		wake_up(&dh_wq);
+	mutex_unlock(&durable_scavenger_lock);
+	kthread_stop(server_conf.dh_task);
+}
+
 static bool session_fd_check(struct ksmbd_tree_connect *tcon,
 			     struct ksmbd_file *fp)
 {
@@ -756,11 +907,12 @@ void ksmbd_free_global_file_table(void)
 	unsigned int		id;
 
 	idr_for_each_entry(global_ft.idr, fp, id) {
-		__ksmbd_remove_durable_fd(fp);
-		kmem_cache_free(filp_cache, fp);
+		ksmbd_remove_durable_fd(fp);
+		__ksmbd_close_fd(NULL, fp);
 	}
 
-	ksmbd_destroy_file_table(&global_ft);
+	idr_destroy(global_ft.idr);
+	kfree(global_ft.idr);
 }
 
 int ksmbd_validate_name_reconnect(struct ksmbd_share_config *share,
@@ -816,6 +968,7 @@ int ksmbd_reopen_durable_fd(struct ksmbd_work *work, struct ksmbd_file *fp)
 	}
 	up_write(&ci->m_lock);
 
+	fp->f_state = FP_NEW;
 	__open_id(&work->sess->file_table, fp, OPEN_ID_TYPE_VOLATILE_ID);
 	if (!has_file_id(fp->volatile_id)) {
 		fp->conn = NULL;
@@ -855,6 +1008,8 @@ int ksmbd_init_file_cache(void)
 	if (!filp_cache)
 		goto out;
 
+	init_waitqueue_head(&dh_wq);
+
 	return 0;
 
 out:
diff --git a/fs/smb/server/vfs_cache.h b/fs/smb/server/vfs_cache.h
index f2ab1514e81a..b0f6d0f94cb8 100644
--- a/fs/smb/server/vfs_cache.h
+++ b/fs/smb/server/vfs_cache.h
@@ -153,6 +153,8 @@ struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid);
 struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry);
 unsigned int ksmbd_open_durable_fd(struct ksmbd_file *fp);
 struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp);
+void ksmbd_launch_ksmbd_durable_scavenger(void);
+void ksmbd_stop_durable_scavenger(void);
 void ksmbd_close_tree_conn_fds(struct ksmbd_work *work);
 void ksmbd_close_session_fds(struct ksmbd_work *work);
 int ksmbd_close_inode_fds(struct ksmbd_work *work, struct inode *inode);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/3] ksmbd: move leading slash check to smb2_get_name()
  2024-06-10 14:14 [PATCH 1/3] ksmbd: avoid reclaiming expired durable opens by the client Namjae Jeon
  2024-06-10 14:14 ` [PATCH 2/3] ksmbd: add durable scavenger timer Namjae Jeon
@ 2024-06-10 14:14 ` Namjae Jeon
  1 sibling, 0 replies; 6+ messages in thread
From: Namjae Jeon @ 2024-06-10 14:14 UTC (permalink / raw)
  To: linux-cifs; +Cc: smfrench, senozhatsky, tom, atteh.mailbox, Namjae Jeon

If the directory name in the root of the share starts with
character like 镜(0x955c) or Ṝ(0x1e5c), it (and anything inside)
cannot be accessed. The leading slash check must be checked after
converting unicode to nls string.

Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
---
 fs/smb/server/smb2pdu.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 4fb5070d3dc5..8bcede718c21 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -630,6 +630,12 @@ smb2_get_name(const char *src, const int maxlen, struct nls_table *local_nls)
 		return name;
 	}
 
+	if (*name == '\\') {
+		pr_err("not allow directory name included leading slash\n");
+		kfree(name);
+		return ERR_PTR(-EINVAL);
+	}
+
 	ksmbd_conv_path_to_unix(name);
 	ksmbd_strip_last_slash(name);
 	return name;
@@ -2842,20 +2848,11 @@ int smb2_open(struct ksmbd_work *work)
 	}
 
 	if (req->NameLength) {
-		if ((req->CreateOptions & FILE_DIRECTORY_FILE_LE) &&
-		    *(char *)req->Buffer == '\\') {
-			pr_err("not allow directory name included leading slash\n");
-			rc = -EINVAL;
-			goto err_out2;
-		}
-
 		name = smb2_get_name((char *)req + le16_to_cpu(req->NameOffset),
 				     le16_to_cpu(req->NameLength),
 				     work->conn->local_nls);
 		if (IS_ERR(name)) {
 			rc = PTR_ERR(name);
-			if (rc != -ENOMEM)
-				rc = -ENOENT;
 			name = NULL;
 			goto err_out2;
 		}
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/3] ksmbd: add durable scavenger timer
  2024-06-10 14:14 ` [PATCH 2/3] ksmbd: add durable scavenger timer Namjae Jeon
@ 2024-06-10 15:30   ` Steve French
  2024-06-11 13:05     ` Namjae Jeon
  2024-06-13 10:01   ` kernel test robot
  1 sibling, 1 reply; 6+ messages in thread
From: Steve French @ 2024-06-10 15:30 UTC (permalink / raw)
  To: Namjae Jeon; +Cc: linux-cifs, senozhatsky, tom, atteh.mailbox

Minor compile warning was generated by this:

/home/smfrench/smb3-kernel/fs/smb/server/vfs_cache.c:39:19: warning:
symbol 'dh_task' was not declared. Should it be static?
/home/smfrench/smb3-kernel/fs/smb/server/vfs_cache.c:40:19: warning:
symbol 'dh_wq' was not declared. Should it be static?

On Mon, Jun 10, 2024 at 9:14 AM Namjae Jeon <linkinjeon@kernel.org> wrote:
>
> Launch ksmbd-durable-scavenger kernel thread to scan durable fps that
> have not been reclaimed by a client within the configured time.
>
> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
> ---
>  fs/smb/server/mgmt/user_session.c |   2 +
>  fs/smb/server/server.c            |   1 +
>  fs/smb/server/server.h            |   1 +
>  fs/smb/server/smb2pdu.c           |   2 +-
>  fs/smb/server/smb2pdu.h           |   2 +
>  fs/smb/server/vfs_cache.c         | 165 +++++++++++++++++++++++++++++-
>  fs/smb/server/vfs_cache.h         |   2 +
>  7 files changed, 169 insertions(+), 6 deletions(-)
>
> diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c
> index aec0a7a12405..162a12685d2c 100644
> --- a/fs/smb/server/mgmt/user_session.c
> +++ b/fs/smb/server/mgmt/user_session.c
> @@ -149,6 +149,7 @@ void ksmbd_session_destroy(struct ksmbd_session *sess)
>
>         ksmbd_tree_conn_session_logoff(sess);
>         ksmbd_destroy_file_table(&sess->file_table);
> +       ksmbd_launch_ksmbd_durable_scavenger();
>         ksmbd_session_rpc_clear_list(sess);
>         free_channel_list(sess);
>         kfree(sess->Preauth_HashValue);
> @@ -326,6 +327,7 @@ void destroy_previous_session(struct ksmbd_conn *conn,
>
>         ksmbd_destroy_file_table(&prev_sess->file_table);
>         prev_sess->state = SMB2_SESSION_EXPIRED;
> +       ksmbd_launch_ksmbd_durable_scavenger();
>  out:
>         up_write(&conn->session_lock);
>         up_write(&sessions_table_lock);
> diff --git a/fs/smb/server/server.c b/fs/smb/server/server.c
> index c67fbc8d6683..4d24cc105ef6 100644
> --- a/fs/smb/server/server.c
> +++ b/fs/smb/server/server.c
> @@ -377,6 +377,7 @@ static void server_ctrl_handle_reset(struct server_ctrl_struct *ctrl)
>  {
>         ksmbd_ipc_soft_reset();
>         ksmbd_conn_transport_destroy();
> +       ksmbd_stop_durable_scavenger();
>         server_conf_free();
>         server_conf_init();
>         WRITE_ONCE(server_conf.state, SERVER_STATE_STARTING_UP);
> diff --git a/fs/smb/server/server.h b/fs/smb/server/server.h
> index db7278181760..4fc529335271 100644
> --- a/fs/smb/server/server.h
> +++ b/fs/smb/server/server.h
> @@ -44,6 +44,7 @@ struct ksmbd_server_config {
>         unsigned int            max_connections;
>
>         char                    *conf[SERVER_CONF_WORK_GROUP + 1];
> +       struct task_struct      *dh_task;
>  };
>
>  extern struct ksmbd_server_config server_conf;
> diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
> index b6c5a8ea3887..4fb5070d3dc5 100644
> --- a/fs/smb/server/smb2pdu.c
> +++ b/fs/smb/server/smb2pdu.c
> @@ -3519,7 +3519,7 @@ int smb2_open(struct ksmbd_work *work)
>                                         SMB2_CREATE_GUID_SIZE);
>                         if (dh_info.timeout)
>                                 fp->durable_timeout = min(dh_info.timeout,
> -                                               300000);
> +                                               DURABLE_HANDLE_MAX_TIMEOUT);
>                         else
>                                 fp->durable_timeout = 60;
>                 }
> diff --git a/fs/smb/server/smb2pdu.h b/fs/smb/server/smb2pdu.h
> index 643f5e1cfe35..3be7d5ae65a8 100644
> --- a/fs/smb/server/smb2pdu.h
> +++ b/fs/smb/server/smb2pdu.h
> @@ -72,6 +72,8 @@ struct create_durable_req_v2 {
>         __u8 CreateGuid[16];
>  } __packed;
>
> +#define DURABLE_HANDLE_MAX_TIMEOUT     300000
> +
>  struct create_durable_reconn_req {
>         struct create_context_hdr ccontext;
>         __u8   Name[8];
> diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c
> index a6804545db28..882a87f9e3ab 100644
> --- a/fs/smb/server/vfs_cache.c
> +++ b/fs/smb/server/vfs_cache.c
> @@ -8,6 +8,8 @@
>  #include <linux/filelock.h>
>  #include <linux/slab.h>
>  #include <linux/vmalloc.h>
> +#include <linux/kthread.h>
> +#include <linux/freezer.h>
>
>  #include "glob.h"
>  #include "vfs_cache.h"
> @@ -17,6 +19,7 @@
>  #include "mgmt/tree_connect.h"
>  #include "mgmt/user_session.h"
>  #include "smb_common.h"
> +#include "server.h"
>
>  #define S_DEL_PENDING                  1
>  #define S_DEL_ON_CLS                   2
> @@ -31,6 +34,11 @@ static struct ksmbd_file_table global_ft;
>  static atomic_long_t fd_limit;
>  static struct kmem_cache *filp_cache;
>
> +static bool durable_scavenger_running;
> +static DEFINE_MUTEX(durable_scavenger_lock);
> +struct task_struc *dh_task;
> +wait_queue_head_t dh_wq;
> +
>  void ksmbd_set_fd_limit(unsigned long limit)
>  {
>         limit = min(limit, get_max_files());
> @@ -279,9 +287,16 @@ static void __ksmbd_remove_durable_fd(struct ksmbd_file *fp)
>         if (!has_file_id(fp->persistent_id))
>                 return;
>
> -       write_lock(&global_ft.lock);
>         idr_remove(global_ft.idr, fp->persistent_id);
> +}
> +
> +static void ksmbd_remove_durable_fd(struct ksmbd_file *fp)
> +{
> +       write_lock(&global_ft.lock);
> +       __ksmbd_remove_durable_fd(fp);
>         write_unlock(&global_ft.lock);
> +       if (waitqueue_active(&dh_wq))
> +               wake_up(&dh_wq);
>  }
>
>  static void __ksmbd_remove_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp)
> @@ -304,7 +319,7 @@ static void __ksmbd_close_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp)
>         struct ksmbd_lock *smb_lock, *tmp_lock;
>
>         fd_limit_close();
> -       __ksmbd_remove_durable_fd(fp);
> +       ksmbd_remove_durable_fd(fp);
>         if (ft)
>                 __ksmbd_remove_fd(ft, fp);
>
> @@ -696,6 +711,142 @@ static bool tree_conn_fd_check(struct ksmbd_tree_connect *tcon,
>         return fp->tcon != tcon;
>  }
>
> +static bool ksmbd_durable_scavenger_alive(void)
> +{
> +       mutex_lock(&durable_scavenger_lock);
> +       if (!durable_scavenger_running) {
> +               mutex_unlock(&durable_scavenger_lock);
> +               return false;
> +       }
> +       mutex_unlock(&durable_scavenger_lock);
> +
> +       if (kthread_should_stop())
> +               return false;
> +
> +       if (idr_is_empty(global_ft.idr))
> +               return false;
> +
> +       return true;
> +}
> +
> +static void ksmbd_scavenger_dispose_dh(struct list_head *head)
> +{
> +       while (!list_empty(head)) {
> +               struct ksmbd_file *fp;
> +
> +               fp = list_first_entry(head, struct ksmbd_file, node);
> +               list_del_init(&fp->node);
> +               __ksmbd_close_fd(NULL, fp);
> +       }
> +}
> +
> +static int ksmbd_durable_scavenger(void *dummy)
> +{
> +       struct ksmbd_file *fp = NULL;
> +       unsigned int id;
> +       unsigned int min_timeout = 1;
> +       bool found_fp_timeout;
> +       LIST_HEAD(scavenger_list);
> +       unsigned long remaining_jiffies;
> +
> +       __module_get(THIS_MODULE);
> +
> +       set_freezable();
> +       while (ksmbd_durable_scavenger_alive()) {
> +               if (try_to_freeze())
> +                       continue;
> +
> +               found_fp_timeout = false;
> +
> +               remaining_jiffies = wait_event_timeout(dh_wq,
> +                                  ksmbd_durable_scavenger_alive() == false,
> +                                  __msecs_to_jiffies(min_timeout));
> +               if (remaining_jiffies)
> +                       min_timeout = jiffies_to_msecs(remaining_jiffies);
> +               else
> +                       min_timeout = DURABLE_HANDLE_MAX_TIMEOUT;
> +
> +               write_lock(&global_ft.lock);
> +               idr_for_each_entry(global_ft.idr, fp, id) {
> +                       if (!fp->durable_timeout)
> +                               continue;
> +
> +                       if (atomic_read(&fp->refcount) > 1 ||
> +                           fp->conn)
> +                               continue;
> +
> +                       found_fp_timeout = true;
> +                       if (fp->durable_scavenger_timeout <=
> +                           jiffies_to_msecs(jiffies)) {
> +                               __ksmbd_remove_durable_fd(fp);
> +                               list_add(&fp->node, &scavenger_list);
> +                       } else {
> +                               unsigned long durable_timeout;
> +
> +                               durable_timeout =
> +                                       fp->durable_scavenger_timeout -
> +                                               jiffies_to_msecs(jiffies);
> +
> +                               if (min_timeout > durable_timeout)
> +                                       min_timeout = durable_timeout;
> +                       }
> +               }
> +               write_unlock(&global_ft.lock);
> +
> +               ksmbd_scavenger_dispose_dh(&scavenger_list);
> +
> +               if (found_fp_timeout == false)
> +                       break;
> +       }
> +
> +       mutex_lock(&durable_scavenger_lock);
> +       durable_scavenger_running = false;
> +       mutex_unlock(&durable_scavenger_lock);
> +
> +       module_put(THIS_MODULE);
> +
> +       return 0;
> +}
> +
> +void ksmbd_launch_ksmbd_durable_scavenger(void)
> +{
> +       if (!(server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE))
> +               return;
> +
> +       mutex_lock(&durable_scavenger_lock);
> +       if (durable_scavenger_running == true) {
> +               mutex_unlock(&durable_scavenger_lock);
> +               return;
> +       }
> +
> +       durable_scavenger_running = true;
> +
> +       server_conf.dh_task = kthread_run(ksmbd_durable_scavenger,
> +                                    (void *)NULL, "ksmbd-durable-scavenger");
> +       if (IS_ERR(server_conf.dh_task))
> +               pr_err("cannot start conn thread, err : %ld\n",
> +                      PTR_ERR(server_conf.dh_task));
> +       mutex_unlock(&durable_scavenger_lock);
> +}
> +
> +void ksmbd_stop_durable_scavenger(void)
> +{
> +       if (!(server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE))
> +               return;
> +
> +       mutex_lock(&durable_scavenger_lock);
> +       if (!durable_scavenger_running) {
> +               mutex_unlock(&durable_scavenger_lock);
> +               return;
> +       }
> +
> +       durable_scavenger_running = false;
> +       if (waitqueue_active(&dh_wq))
> +               wake_up(&dh_wq);
> +       mutex_unlock(&durable_scavenger_lock);
> +       kthread_stop(server_conf.dh_task);
> +}
> +
>  static bool session_fd_check(struct ksmbd_tree_connect *tcon,
>                              struct ksmbd_file *fp)
>  {
> @@ -756,11 +907,12 @@ void ksmbd_free_global_file_table(void)
>         unsigned int            id;
>
>         idr_for_each_entry(global_ft.idr, fp, id) {
> -               __ksmbd_remove_durable_fd(fp);
> -               kmem_cache_free(filp_cache, fp);
> +               ksmbd_remove_durable_fd(fp);
> +               __ksmbd_close_fd(NULL, fp);
>         }
>
> -       ksmbd_destroy_file_table(&global_ft);
> +       idr_destroy(global_ft.idr);
> +       kfree(global_ft.idr);
>  }
>
>  int ksmbd_validate_name_reconnect(struct ksmbd_share_config *share,
> @@ -816,6 +968,7 @@ int ksmbd_reopen_durable_fd(struct ksmbd_work *work, struct ksmbd_file *fp)
>         }
>         up_write(&ci->m_lock);
>
> +       fp->f_state = FP_NEW;
>         __open_id(&work->sess->file_table, fp, OPEN_ID_TYPE_VOLATILE_ID);
>         if (!has_file_id(fp->volatile_id)) {
>                 fp->conn = NULL;
> @@ -855,6 +1008,8 @@ int ksmbd_init_file_cache(void)
>         if (!filp_cache)
>                 goto out;
>
> +       init_waitqueue_head(&dh_wq);
> +
>         return 0;
>
>  out:
> diff --git a/fs/smb/server/vfs_cache.h b/fs/smb/server/vfs_cache.h
> index f2ab1514e81a..b0f6d0f94cb8 100644
> --- a/fs/smb/server/vfs_cache.h
> +++ b/fs/smb/server/vfs_cache.h
> @@ -153,6 +153,8 @@ struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid);
>  struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry);
>  unsigned int ksmbd_open_durable_fd(struct ksmbd_file *fp);
>  struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp);
> +void ksmbd_launch_ksmbd_durable_scavenger(void);
> +void ksmbd_stop_durable_scavenger(void);
>  void ksmbd_close_tree_conn_fds(struct ksmbd_work *work);
>  void ksmbd_close_session_fds(struct ksmbd_work *work);
>  int ksmbd_close_inode_fds(struct ksmbd_work *work, struct inode *inode);
> --
> 2.25.1
>


-- 
Thanks,

Steve

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/3] ksmbd: add durable scavenger timer
  2024-06-10 15:30   ` Steve French
@ 2024-06-11 13:05     ` Namjae Jeon
  0 siblings, 0 replies; 6+ messages in thread
From: Namjae Jeon @ 2024-06-11 13:05 UTC (permalink / raw)
  To: Steve French; +Cc: linux-cifs, senozhatsky, tom, atteh.mailbox

2024년 6월 11일 (화) 오전 12:31, Steve French <smfrench@gmail.com>님이 작성:
>
> Minor compile warning was generated by this:
Okay, I will fix it.
Thanks for your review:)
>
> /home/smfrench/smb3-kernel/fs/smb/server/vfs_cache.c:39:19: warning:
> symbol 'dh_task' was not declared. Should it be static?
> /home/smfrench/smb3-kernel/fs/smb/server/vfs_cache.c:40:19: warning:
> symbol 'dh_wq' was not declared. Should it be static?
>
> On Mon, Jun 10, 2024 at 9:14 AM Namjae Jeon <linkinjeon@kernel.org> wrote:
> >
> > Launch ksmbd-durable-scavenger kernel thread to scan durable fps that
> > have not been reclaimed by a client within the configured time.
> >
> > Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
> > ---
> >  fs/smb/server/mgmt/user_session.c |   2 +
> >  fs/smb/server/server.c            |   1 +
> >  fs/smb/server/server.h            |   1 +
> >  fs/smb/server/smb2pdu.c           |   2 +-
> >  fs/smb/server/smb2pdu.h           |   2 +
> >  fs/smb/server/vfs_cache.c         | 165 +++++++++++++++++++++++++++++-
> >  fs/smb/server/vfs_cache.h         |   2 +
> >  7 files changed, 169 insertions(+), 6 deletions(-)
> >
> > diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c
> > index aec0a7a12405..162a12685d2c 100644
> > --- a/fs/smb/server/mgmt/user_session.c
> > +++ b/fs/smb/server/mgmt/user_session.c
> > @@ -149,6 +149,7 @@ void ksmbd_session_destroy(struct ksmbd_session *sess)
> >
> >         ksmbd_tree_conn_session_logoff(sess);
> >         ksmbd_destroy_file_table(&sess->file_table);
> > +       ksmbd_launch_ksmbd_durable_scavenger();
> >         ksmbd_session_rpc_clear_list(sess);
> >         free_channel_list(sess);
> >         kfree(sess->Preauth_HashValue);
> > @@ -326,6 +327,7 @@ void destroy_previous_session(struct ksmbd_conn *conn,
> >
> >         ksmbd_destroy_file_table(&prev_sess->file_table);
> >         prev_sess->state = SMB2_SESSION_EXPIRED;
> > +       ksmbd_launch_ksmbd_durable_scavenger();
> >  out:
> >         up_write(&conn->session_lock);
> >         up_write(&sessions_table_lock);
> > diff --git a/fs/smb/server/server.c b/fs/smb/server/server.c
> > index c67fbc8d6683..4d24cc105ef6 100644
> > --- a/fs/smb/server/server.c
> > +++ b/fs/smb/server/server.c
> > @@ -377,6 +377,7 @@ static void server_ctrl_handle_reset(struct server_ctrl_struct *ctrl)
> >  {
> >         ksmbd_ipc_soft_reset();
> >         ksmbd_conn_transport_destroy();
> > +       ksmbd_stop_durable_scavenger();
> >         server_conf_free();
> >         server_conf_init();
> >         WRITE_ONCE(server_conf.state, SERVER_STATE_STARTING_UP);
> > diff --git a/fs/smb/server/server.h b/fs/smb/server/server.h
> > index db7278181760..4fc529335271 100644
> > --- a/fs/smb/server/server.h
> > +++ b/fs/smb/server/server.h
> > @@ -44,6 +44,7 @@ struct ksmbd_server_config {
> >         unsigned int            max_connections;
> >
> >         char                    *conf[SERVER_CONF_WORK_GROUP + 1];
> > +       struct task_struct      *dh_task;
> >  };
> >
> >  extern struct ksmbd_server_config server_conf;
> > diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
> > index b6c5a8ea3887..4fb5070d3dc5 100644
> > --- a/fs/smb/server/smb2pdu.c
> > +++ b/fs/smb/server/smb2pdu.c
> > @@ -3519,7 +3519,7 @@ int smb2_open(struct ksmbd_work *work)
> >                                         SMB2_CREATE_GUID_SIZE);
> >                         if (dh_info.timeout)
> >                                 fp->durable_timeout = min(dh_info.timeout,
> > -                                               300000);
> > +                                               DURABLE_HANDLE_MAX_TIMEOUT);
> >                         else
> >                                 fp->durable_timeout = 60;
> >                 }
> > diff --git a/fs/smb/server/smb2pdu.h b/fs/smb/server/smb2pdu.h
> > index 643f5e1cfe35..3be7d5ae65a8 100644
> > --- a/fs/smb/server/smb2pdu.h
> > +++ b/fs/smb/server/smb2pdu.h
> > @@ -72,6 +72,8 @@ struct create_durable_req_v2 {
> >         __u8 CreateGuid[16];
> >  } __packed;
> >
> > +#define DURABLE_HANDLE_MAX_TIMEOUT     300000
> > +
> >  struct create_durable_reconn_req {
> >         struct create_context_hdr ccontext;
> >         __u8   Name[8];
> > diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c
> > index a6804545db28..882a87f9e3ab 100644
> > --- a/fs/smb/server/vfs_cache.c
> > +++ b/fs/smb/server/vfs_cache.c
> > @@ -8,6 +8,8 @@
> >  #include <linux/filelock.h>
> >  #include <linux/slab.h>
> >  #include <linux/vmalloc.h>
> > +#include <linux/kthread.h>
> > +#include <linux/freezer.h>
> >
> >  #include "glob.h"
> >  #include "vfs_cache.h"
> > @@ -17,6 +19,7 @@
> >  #include "mgmt/tree_connect.h"
> >  #include "mgmt/user_session.h"
> >  #include "smb_common.h"
> > +#include "server.h"
> >
> >  #define S_DEL_PENDING                  1
> >  #define S_DEL_ON_CLS                   2
> > @@ -31,6 +34,11 @@ static struct ksmbd_file_table global_ft;
> >  static atomic_long_t fd_limit;
> >  static struct kmem_cache *filp_cache;
> >
> > +static bool durable_scavenger_running;
> > +static DEFINE_MUTEX(durable_scavenger_lock);
> > +struct task_struc *dh_task;
> > +wait_queue_head_t dh_wq;
> > +
> >  void ksmbd_set_fd_limit(unsigned long limit)
> >  {
> >         limit = min(limit, get_max_files());
> > @@ -279,9 +287,16 @@ static void __ksmbd_remove_durable_fd(struct ksmbd_file *fp)
> >         if (!has_file_id(fp->persistent_id))
> >                 return;
> >
> > -       write_lock(&global_ft.lock);
> >         idr_remove(global_ft.idr, fp->persistent_id);
> > +}
> > +
> > +static void ksmbd_remove_durable_fd(struct ksmbd_file *fp)
> > +{
> > +       write_lock(&global_ft.lock);
> > +       __ksmbd_remove_durable_fd(fp);
> >         write_unlock(&global_ft.lock);
> > +       if (waitqueue_active(&dh_wq))
> > +               wake_up(&dh_wq);
> >  }
> >
> >  static void __ksmbd_remove_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp)
> > @@ -304,7 +319,7 @@ static void __ksmbd_close_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp)
> >         struct ksmbd_lock *smb_lock, *tmp_lock;
> >
> >         fd_limit_close();
> > -       __ksmbd_remove_durable_fd(fp);
> > +       ksmbd_remove_durable_fd(fp);
> >         if (ft)
> >                 __ksmbd_remove_fd(ft, fp);
> >
> > @@ -696,6 +711,142 @@ static bool tree_conn_fd_check(struct ksmbd_tree_connect *tcon,
> >         return fp->tcon != tcon;
> >  }
> >
> > +static bool ksmbd_durable_scavenger_alive(void)
> > +{
> > +       mutex_lock(&durable_scavenger_lock);
> > +       if (!durable_scavenger_running) {
> > +               mutex_unlock(&durable_scavenger_lock);
> > +               return false;
> > +       }
> > +       mutex_unlock(&durable_scavenger_lock);
> > +
> > +       if (kthread_should_stop())
> > +               return false;
> > +
> > +       if (idr_is_empty(global_ft.idr))
> > +               return false;
> > +
> > +       return true;
> > +}
> > +
> > +static void ksmbd_scavenger_dispose_dh(struct list_head *head)
> > +{
> > +       while (!list_empty(head)) {
> > +               struct ksmbd_file *fp;
> > +
> > +               fp = list_first_entry(head, struct ksmbd_file, node);
> > +               list_del_init(&fp->node);
> > +               __ksmbd_close_fd(NULL, fp);
> > +       }
> > +}
> > +
> > +static int ksmbd_durable_scavenger(void *dummy)
> > +{
> > +       struct ksmbd_file *fp = NULL;
> > +       unsigned int id;
> > +       unsigned int min_timeout = 1;
> > +       bool found_fp_timeout;
> > +       LIST_HEAD(scavenger_list);
> > +       unsigned long remaining_jiffies;
> > +
> > +       __module_get(THIS_MODULE);
> > +
> > +       set_freezable();
> > +       while (ksmbd_durable_scavenger_alive()) {
> > +               if (try_to_freeze())
> > +                       continue;
> > +
> > +               found_fp_timeout = false;
> > +
> > +               remaining_jiffies = wait_event_timeout(dh_wq,
> > +                                  ksmbd_durable_scavenger_alive() == false,
> > +                                  __msecs_to_jiffies(min_timeout));
> > +               if (remaining_jiffies)
> > +                       min_timeout = jiffies_to_msecs(remaining_jiffies);
> > +               else
> > +                       min_timeout = DURABLE_HANDLE_MAX_TIMEOUT;
> > +
> > +               write_lock(&global_ft.lock);
> > +               idr_for_each_entry(global_ft.idr, fp, id) {
> > +                       if (!fp->durable_timeout)
> > +                               continue;
> > +
> > +                       if (atomic_read(&fp->refcount) > 1 ||
> > +                           fp->conn)
> > +                               continue;
> > +
> > +                       found_fp_timeout = true;
> > +                       if (fp->durable_scavenger_timeout <=
> > +                           jiffies_to_msecs(jiffies)) {
> > +                               __ksmbd_remove_durable_fd(fp);
> > +                               list_add(&fp->node, &scavenger_list);
> > +                       } else {
> > +                               unsigned long durable_timeout;
> > +
> > +                               durable_timeout =
> > +                                       fp->durable_scavenger_timeout -
> > +                                               jiffies_to_msecs(jiffies);
> > +
> > +                               if (min_timeout > durable_timeout)
> > +                                       min_timeout = durable_timeout;
> > +                       }
> > +               }
> > +               write_unlock(&global_ft.lock);
> > +
> > +               ksmbd_scavenger_dispose_dh(&scavenger_list);
> > +
> > +               if (found_fp_timeout == false)
> > +                       break;
> > +       }
> > +
> > +       mutex_lock(&durable_scavenger_lock);
> > +       durable_scavenger_running = false;
> > +       mutex_unlock(&durable_scavenger_lock);
> > +
> > +       module_put(THIS_MODULE);
> > +
> > +       return 0;
> > +}
> > +
> > +void ksmbd_launch_ksmbd_durable_scavenger(void)
> > +{
> > +       if (!(server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE))
> > +               return;
> > +
> > +       mutex_lock(&durable_scavenger_lock);
> > +       if (durable_scavenger_running == true) {
> > +               mutex_unlock(&durable_scavenger_lock);
> > +               return;
> > +       }
> > +
> > +       durable_scavenger_running = true;
> > +
> > +       server_conf.dh_task = kthread_run(ksmbd_durable_scavenger,
> > +                                    (void *)NULL, "ksmbd-durable-scavenger");
> > +       if (IS_ERR(server_conf.dh_task))
> > +               pr_err("cannot start conn thread, err : %ld\n",
> > +                      PTR_ERR(server_conf.dh_task));
> > +       mutex_unlock(&durable_scavenger_lock);
> > +}
> > +
> > +void ksmbd_stop_durable_scavenger(void)
> > +{
> > +       if (!(server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE))
> > +               return;
> > +
> > +       mutex_lock(&durable_scavenger_lock);
> > +       if (!durable_scavenger_running) {
> > +               mutex_unlock(&durable_scavenger_lock);
> > +               return;
> > +       }
> > +
> > +       durable_scavenger_running = false;
> > +       if (waitqueue_active(&dh_wq))
> > +               wake_up(&dh_wq);
> > +       mutex_unlock(&durable_scavenger_lock);
> > +       kthread_stop(server_conf.dh_task);
> > +}
> > +
> >  static bool session_fd_check(struct ksmbd_tree_connect *tcon,
> >                              struct ksmbd_file *fp)
> >  {
> > @@ -756,11 +907,12 @@ void ksmbd_free_global_file_table(void)
> >         unsigned int            id;
> >
> >         idr_for_each_entry(global_ft.idr, fp, id) {
> > -               __ksmbd_remove_durable_fd(fp);
> > -               kmem_cache_free(filp_cache, fp);
> > +               ksmbd_remove_durable_fd(fp);
> > +               __ksmbd_close_fd(NULL, fp);
> >         }
> >
> > -       ksmbd_destroy_file_table(&global_ft);
> > +       idr_destroy(global_ft.idr);
> > +       kfree(global_ft.idr);
> >  }
> >
> >  int ksmbd_validate_name_reconnect(struct ksmbd_share_config *share,
> > @@ -816,6 +968,7 @@ int ksmbd_reopen_durable_fd(struct ksmbd_work *work, struct ksmbd_file *fp)
> >         }
> >         up_write(&ci->m_lock);
> >
> > +       fp->f_state = FP_NEW;
> >         __open_id(&work->sess->file_table, fp, OPEN_ID_TYPE_VOLATILE_ID);
> >         if (!has_file_id(fp->volatile_id)) {
> >                 fp->conn = NULL;
> > @@ -855,6 +1008,8 @@ int ksmbd_init_file_cache(void)
> >         if (!filp_cache)
> >                 goto out;
> >
> > +       init_waitqueue_head(&dh_wq);
> > +
> >         return 0;
> >
> >  out:
> > diff --git a/fs/smb/server/vfs_cache.h b/fs/smb/server/vfs_cache.h
> > index f2ab1514e81a..b0f6d0f94cb8 100644
> > --- a/fs/smb/server/vfs_cache.h
> > +++ b/fs/smb/server/vfs_cache.h
> > @@ -153,6 +153,8 @@ struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid);
> >  struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry);
> >  unsigned int ksmbd_open_durable_fd(struct ksmbd_file *fp);
> >  struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp);
> > +void ksmbd_launch_ksmbd_durable_scavenger(void);
> > +void ksmbd_stop_durable_scavenger(void);
> >  void ksmbd_close_tree_conn_fds(struct ksmbd_work *work);
> >  void ksmbd_close_session_fds(struct ksmbd_work *work);
> >  int ksmbd_close_inode_fds(struct ksmbd_work *work, struct inode *inode);
> > --
> > 2.25.1
> >
>
>
> --
> Thanks,
>
> Steve

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/3] ksmbd: add durable scavenger timer
  2024-06-10 14:14 ` [PATCH 2/3] ksmbd: add durable scavenger timer Namjae Jeon
  2024-06-10 15:30   ` Steve French
@ 2024-06-13 10:01   ` kernel test robot
  1 sibling, 0 replies; 6+ messages in thread
From: kernel test robot @ 2024-06-13 10:01 UTC (permalink / raw)
  To: Namjae Jeon; +Cc: oe-kbuild-all

Hi Namjae,

kernel test robot noticed the following build warnings:

[auto build test WARNING on linus/master]
[also build test WARNING on v6.10-rc3 next-20240613]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Namjae-Jeon/ksmbd-add-durable-scavenger-timer/20240610-221647
base:   linus/master
patch link:    https://lore.kernel.org/r/20240610141416.8039-2-linkinjeon%40kernel.org
patch subject: [PATCH 2/3] ksmbd: add durable scavenger timer
config: s390-randconfig-r112-20240613 (https://download.01.org/0day-ci/archive/20240613/202406131718.ee85fdua-lkp@intel.com/config)
compiler: clang version 15.0.7 (https://github.com/llvm/llvm-project 8dfdcc7b7bf66834a761bd8de445840ef68e4d1a)
reproduce: (https://download.01.org/0day-ci/archive/20240613/202406131718.ee85fdua-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202406131718.ee85fdua-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> fs/smb/server/vfs_cache.c:40:19: sparse: sparse: symbol 'dh_wq' was not declared. Should it be static?
   fs/smb/server/vfs_cache.c: note: in included file (through include/linux/wait.h, include/linux/wait_bit.h, include/linux/fs.h):
   include/linux/list.h:83:21: sparse: sparse: self-comparison always evaluates to true

vim +/dh_wq +40 fs/smb/server/vfs_cache.c

    36	
    37	static bool durable_scavenger_running;
    38	static DEFINE_MUTEX(durable_scavenger_lock);
    39	struct task_struc *dh_task;
  > 40	wait_queue_head_t dh_wq;
    41	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2024-06-13 10:02 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-10 14:14 [PATCH 1/3] ksmbd: avoid reclaiming expired durable opens by the client Namjae Jeon
2024-06-10 14:14 ` [PATCH 2/3] ksmbd: add durable scavenger timer Namjae Jeon
2024-06-10 15:30   ` Steve French
2024-06-11 13:05     ` Namjae Jeon
2024-06-13 10:01   ` kernel test robot
2024-06-10 14:14 ` [PATCH 3/3] ksmbd: move leading slash check to smb2_get_name() Namjae Jeon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.