All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/3] ksmbd: request update to stale share config
@ 2022-08-08 22:02 atheik
  2022-08-08 22:02 ` [PATCH v2 2/3] ksmbd-tools: cleanup config group handling atheik
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: atheik @ 2022-08-08 22:02 UTC (permalink / raw)
  To: linux-cifs; +Cc: atheik

ksmbd_share_config_get() retrieves the cached share config as long
as there is at least one connection to the share. This is an issue when
the user space utilities are used to update share configs. In that case
there is a need to inform ksmbd that it should not use the cached share
config for a new connection to the share. With these changes the tree
connection flag KSMBD_TREE_CONN_FLAG_UPDATE indicates this. When this
flag is set, ksmbd removes the share config from the shares hash table
meaning that ksmbd_share_config_get() ends up requesting a share config
from user space.

Signed-off-by: Atte Heikkilä <atteh.mailbox@gmail.com>
---
 fs/ksmbd/ksmbd_netlink.h     |  2 ++
 fs/ksmbd/mgmt/share_config.c |  6 +++++-
 fs/ksmbd/mgmt/share_config.h |  1 +
 fs/ksmbd/mgmt/tree_connect.c | 14 ++++++++++++++
 fs/ksmbd/smb2pdu.c           |  1 +
 5 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/fs/ksmbd/ksmbd_netlink.h b/fs/ksmbd/ksmbd_netlink.h
index 52aa0adeb951..a3211c55b01f 100644
--- a/fs/ksmbd/ksmbd_netlink.h
+++ b/fs/ksmbd/ksmbd_netlink.h
@@ -349,6 +349,7 @@ enum KSMBD_TREE_CONN_STATUS {
 #define KSMBD_SHARE_FLAG_STREAMS		BIT(11)
 #define KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS	BIT(12)
 #define KSMBD_SHARE_FLAG_ACL_XATTR		BIT(13)
+#define KSMBD_SHARE_FLAG_UPDATE 		BIT(14)
 
 /*
  * Tree connect request flags.
@@ -364,6 +365,7 @@ enum KSMBD_TREE_CONN_STATUS {
 #define KSMBD_TREE_CONN_FLAG_READ_ONLY		BIT(1)
 #define KSMBD_TREE_CONN_FLAG_WRITABLE		BIT(2)
 #define KSMBD_TREE_CONN_FLAG_ADMIN_ACCOUNT	BIT(3)
+#define KSMBD_TREE_CONN_FLAG_UPDATE		BIT(4)
 
 /*
  * RPC over IPC.
diff --git a/fs/ksmbd/mgmt/share_config.c b/fs/ksmbd/mgmt/share_config.c
index 70655af93b44..c9bca1c2c834 100644
--- a/fs/ksmbd/mgmt/share_config.c
+++ b/fs/ksmbd/mgmt/share_config.c
@@ -51,12 +51,16 @@ static void kill_share(struct ksmbd_share_config *share)
 	kfree(share);
 }
 
-void __ksmbd_share_config_put(struct ksmbd_share_config *share)
+void ksmbd_share_config_del(struct ksmbd_share_config *share)
 {
 	down_write(&shares_table_lock);
 	hash_del(&share->hlist);
 	up_write(&shares_table_lock);
+}
 
+void __ksmbd_share_config_put(struct ksmbd_share_config *share)
+{
+	ksmbd_share_config_del(share);
 	kill_share(share);
 }
 
diff --git a/fs/ksmbd/mgmt/share_config.h b/fs/ksmbd/mgmt/share_config.h
index 28bf3511763f..902f2cb1963a 100644
--- a/fs/ksmbd/mgmt/share_config.h
+++ b/fs/ksmbd/mgmt/share_config.h
@@ -64,6 +64,7 @@ static inline int test_share_config_flag(struct ksmbd_share_config *share,
 	return share->flags & flag;
 }
 
+void ksmbd_share_config_del(struct ksmbd_share_config *share);
 void __ksmbd_share_config_put(struct ksmbd_share_config *share);
 
 static inline void ksmbd_share_config_put(struct ksmbd_share_config *share)
diff --git a/fs/ksmbd/mgmt/tree_connect.c b/fs/ksmbd/mgmt/tree_connect.c
index dd262daa2c4a..97ab7987df6e 100644
--- a/fs/ksmbd/mgmt/tree_connect.c
+++ b/fs/ksmbd/mgmt/tree_connect.c
@@ -57,6 +57,20 @@ ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess,
 		goto out_error;
 
 	tree_conn->flags = resp->connection_flags;
+	if (test_tree_conn_flag(tree_conn, KSMBD_TREE_CONN_FLAG_UPDATE)) {
+		struct ksmbd_share_config *new_sc;
+
+		ksmbd_share_config_del(sc);
+		new_sc = ksmbd_share_config_get(share_name);
+		if (!new_sc) {
+			pr_err("Failed to update stale share config\n");
+			status.ret = -ESTALE;
+			goto out_error;
+		}
+		ksmbd_share_config_put(sc);
+		sc = new_sc;
+	}
+
 	tree_conn->user = sess->user;
 	tree_conn->share_conf = sc;
 	status.tree_conn = tree_conn;
diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
index 1f9a2cda0c58..b5c36657ecfd 100644
--- a/fs/ksmbd/smb2pdu.c
+++ b/fs/ksmbd/smb2pdu.c
@@ -1944,6 +1944,7 @@ int smb2_tree_connect(struct ksmbd_work *work)
 		rsp->hdr.Status = STATUS_SUCCESS;
 		rc = 0;
 		break;
+	case -ESTALE:
 	case -ENOENT:
 	case KSMBD_TREE_CONN_STATUS_NO_SHARE:
 		rsp->hdr.Status = STATUS_BAD_NETWORK_NAME;
-- 
2.37.1


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

* [PATCH v2 2/3] ksmbd-tools: cleanup config group handling
  2022-08-08 22:02 [PATCH v2 1/3] ksmbd: request update to stale share config atheik
@ 2022-08-08 22:02 ` atheik
  2022-08-08 22:02 ` [PATCH v2 3/3] ksmbd-tools: inform ksmbd of stale share config atheik
  2022-08-09  0:38 ` [PATCH v2 1/3] ksmbd: request update to " Namjae Jeon
  2 siblings, 0 replies; 5+ messages in thread
From: atheik @ 2022-08-08 22:02 UTC (permalink / raw)
  To: linux-cifs; +Cc: atheik

Rename cp_add_ipc_share() to cp_add_ipc_group() in order to better
describe its purpose. Use the ipc_group global variable so as to get
rid of the group name comparison in groups_callback(). Keep track of
used groups callback mode by saving it per-group. Move global group
checks to global_conf_* functions.

Signed-off-by: Atte Heikkilä <atteh.mailbox@gmail.com>
---
 include/config_parser.h |  5 +++
 lib/config_parser.c     | 95 +++++++++++++++++++++++------------------
 2 files changed, 59 insertions(+), 41 deletions(-)

diff --git a/include/config_parser.h b/include/config_parser.h
index b6c49b9..43212c8 100644
--- a/include/config_parser.h
+++ b/include/config_parser.h
@@ -10,7 +10,12 @@
 
 #include <glib.h>
 
+#define GROUPS_CALLBACK_NONE	(0)
+#define GROUPS_CALLBACK_INIT	(1 << 0)
+#define GROUPS_CALLBACK_REINIT	(1 << 1)
+
 struct smbconf_group {
+	unsigned short		cb_mode;
 	char			*name;
 	GHashTable		*kv;
 };
diff --git a/lib/config_parser.c b/lib/config_parser.c
index 5e7a438..d311386 100644
--- a/lib/config_parser.c
+++ b/lib/config_parser.c
@@ -21,7 +21,7 @@
 
 struct smbconf_global global_conf;
 struct smbconf_parser parser;
-struct smbconf_group *global_group;
+struct smbconf_group *global_group, *ipc_group;
 
 unsigned long long memparse(const char *v)
 {
@@ -107,6 +107,7 @@ static int add_new_group(char *line)
 	}
 
 	group = g_malloc(sizeof(struct smbconf_group));
+	group->cb_mode = GROUPS_CALLBACK_NONE;
 	group->name = name;
 	group->kv = g_hash_table_new_full(g_str_hash,
 					  g_str_equal,
@@ -561,6 +562,9 @@ static void global_conf_default(void)
 
 static void global_conf_create(void)
 {
+	if (!global_group || global_group->cb_mode != GROUPS_CALLBACK_INIT)
+		return;
+
 	/*
 	 * This will transfer server options to global_conf, and leave behind
 	 * in the global parser group, the options that must be applied to every
@@ -569,6 +573,23 @@ static void global_conf_create(void)
 	g_hash_table_foreach_remove(global_group->kv, global_group_kv, NULL);
 }
 
+static void append_key_value(gpointer _k, gpointer _v, gpointer user_data)
+{
+	GHashTable *receiver = (GHashTable *) user_data;
+
+	/* Don't override local share options */
+	if (!g_hash_table_lookup(receiver, _k))
+		g_hash_table_insert(receiver, g_strdup(_k), g_strdup(_v));
+}
+
+static void global_conf_update(struct smbconf_group *group)
+{
+	if (!global_group)
+		return;
+
+	g_hash_table_foreach(global_group->kv, append_key_value, group->kv);
+}
+
 static void global_conf_fixup_missing(void)
 {
 	int ret;
@@ -607,39 +628,29 @@ static void global_conf_fixup_missing(void)
 			ret);
 }
 
-static void append_key_value(gpointer _k, gpointer _v, gpointer user_data)
-{
-	GHashTable *receiver = (GHashTable *) user_data;
-
-	/* Don't override local share options */
-	if (!g_hash_table_lookup(receiver, _k))
-		g_hash_table_insert(receiver, g_strdup(_k), g_strdup(_v));
-}
-
-#define GROUPS_CALLBACK_STARTUP_INIT	0x1
-#define GROUPS_CALLBACK_REINIT		0x2
-
 static void groups_callback(gpointer _k, gpointer _v, gpointer user_data)
 {
-	struct smbconf_group *group = (struct smbconf_group *)_v;
+	struct smbconf_group *group = (struct smbconf_group *) _v;
+	unsigned short cb_mode = *(unsigned short *) user_data;
 
-	if (group != global_group) {
-		if (global_group && g_ascii_strcasecmp(_k, "ipc$"))
-			g_hash_table_foreach(global_group->kv,
-					     append_key_value,
-					     group->kv);
+	if (group == global_group)
+		return;
 
-		shm_add_new_share(group);
-	}
+	group->cb_mode = cb_mode;
+
+	if (group != ipc_group)
+		global_conf_update(group);
+
+	shm_add_new_share(group);
 }
 
-static int cp_add_ipc_share(void)
+static int cp_add_ipc_group(void)
 {
 	char *comment = NULL, *guest = NULL;
 	int ret = 0;
 
-	if (g_hash_table_lookup(parser.groups, "ipc$"))
-		return 0;
+	if (ipc_group)
+		return ret;
 
 	comment = g_strdup("comment = IPC share");
 	guest = g_strdup("guest ok = yes");
@@ -649,13 +660,18 @@ static int cp_add_ipc_share(void)
 	if (ret) {
 		pr_err("Unable to add IPC$ share\n");
 		ret = -EINVAL;
+		goto out;
 	}
+
+	ipc_group = g_hash_table_lookup(parser.groups, "ipc$");
+out:
 	g_free(comment);
 	g_free(guest);
 	return ret;
 }
 
-static int __cp_parse_smbconfig(const char *smbconf, GHFunc cb, long flags)
+static int __cp_parse_smbconfig(const char *smbconf, GHFunc cb,
+				unsigned short cb_mode)
 {
 	int ret;
 
@@ -665,35 +681,32 @@ static int __cp_parse_smbconfig(const char *smbconf, GHFunc cb, long flags)
 	if (ret)
 		return ret;
 
-	ret = cp_add_ipc_share();
-	if (!ret) {
-		global_group = g_hash_table_lookup(parser.groups, "global");
+	ret = cp_add_ipc_group();
+	if (ret)
+		goto out;
 
-		if (global_group && (flags == GROUPS_CALLBACK_STARTUP_INIT))
-			global_conf_create();
+	global_group = g_hash_table_lookup(parser.groups, "global");
+	if (global_group)
+		global_group->cb_mode = cb_mode;
 
-		g_hash_table_foreach(parser.groups,
-				     groups_callback,
-				     NULL);
-
-		global_conf_fixup_missing();
-	}
+	global_conf_create();
+	g_hash_table_foreach(parser.groups, groups_callback, &cb_mode);
+	global_conf_fixup_missing();
+out:
 	cp_smbconfig_destroy();
 	return ret;
 }
 
 int cp_parse_reload_smbconf(const char *smbconf)
 {
-	return __cp_parse_smbconfig(smbconf,
-				    groups_callback,
+	return __cp_parse_smbconfig(smbconf, groups_callback,
 				    GROUPS_CALLBACK_REINIT);
 }
 
 int cp_parse_smbconf(const char *smbconf)
 {
-	return __cp_parse_smbconfig(smbconf,
-				    groups_callback,
-				    GROUPS_CALLBACK_STARTUP_INIT);
+	return __cp_parse_smbconfig(smbconf, groups_callback,
+				    GROUPS_CALLBACK_INIT);
 }
 
 int cp_parse_pwddb(const char *pwddb)
-- 
2.37.1


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

* [PATCH v2 3/3] ksmbd-tools: inform ksmbd of stale share config
  2022-08-08 22:02 [PATCH v2 1/3] ksmbd: request update to stale share config atheik
  2022-08-08 22:02 ` [PATCH v2 2/3] ksmbd-tools: cleanup config group handling atheik
@ 2022-08-08 22:02 ` atheik
  2022-08-10  8:06   ` Namjae Jeon
  2022-08-09  0:38 ` [PATCH v2 1/3] ksmbd: request update to " Namjae Jeon
  2 siblings, 1 reply; 5+ messages in thread
From: atheik @ 2022-08-08 22:02 UTC (permalink / raw)
  To: linux-cifs; +Cc: atheik

When initializing a share from a group, flag the share with
KSMBD_SHARE_FLAG_UPDATE if the group callback mode denotes that the
config file was reloaded. If the share was flagged, then later when
handling a tree connect request, flag the connection with
KSMBD_TREE_CONN_FLAG_UPDATE to inform ksmbd that its cached share
config is stale. If there are no failures when handling the request,
remove the share flag.

Signed-off-by: Atte Heikkilä <atteh.mailbox@gmail.com>
---
 include/linux/ksmbd_server.h | 2 ++
 lib/management/share.c       | 3 +++
 lib/management/tree_conn.c   | 8 +++++++-
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/include/linux/ksmbd_server.h b/include/linux/ksmbd_server.h
index 6705dac..7e86d5d 100644
--- a/include/linux/ksmbd_server.h
+++ b/include/linux/ksmbd_server.h
@@ -235,6 +235,7 @@ enum KSMBD_TREE_CONN_STATUS {
 #define KSMBD_SHARE_FLAG_STREAMS		(1 << 11)
 #define KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS	(1 << 12)
 #define KSMBD_SHARE_FLAG_ACL_XATTR		(1 << 13)
+#define KSMBD_SHARE_FLAG_UPDATE 		(1 << 14)
 
 /*
  * Tree connect request flags.
@@ -250,6 +251,7 @@ enum KSMBD_TREE_CONN_STATUS {
 #define KSMBD_TREE_CONN_FLAG_READ_ONLY		(1 << 1)
 #define KSMBD_TREE_CONN_FLAG_WRITABLE		(1 << 2)
 #define KSMBD_TREE_CONN_FLAG_ADMIN_ACCOUNT	(1 << 3)
+#define KSMBD_TREE_CONN_FLAG_UPDATE		(1 << 4)
 
 /*
  * RPC over IPC.
diff --git a/lib/management/share.c b/lib/management/share.c
index acd6d3f..e9492b5 100644
--- a/lib/management/share.c
+++ b/lib/management/share.c
@@ -605,6 +605,9 @@ static void init_share_from_group(struct ksmbd_share *share,
 	if (!g_ascii_strcasecmp(share->name, "ipc$"))
 		set_share_flag(share, KSMBD_SHARE_FLAG_PIPE);
 
+	if (group->cb_mode == GROUPS_CALLBACK_REINIT)
+		set_share_flag(share, KSMBD_SHARE_FLAG_UPDATE);
+
 	g_hash_table_foreach(group->kv, process_group_kv, share);
 
 	fixup_missing_fields(share);
diff --git a/lib/management/tree_conn.c b/lib/management/tree_conn.c
index 10304d1..f5c5749 100644
--- a/lib/management/tree_conn.c
+++ b/lib/management/tree_conn.c
@@ -73,6 +73,8 @@ int tcm_handle_tree_connect(struct ksmbd_tree_connect_request *req,
 		set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_WRITABLE);
 	if (test_share_flag(share, KSMBD_SHARE_FLAG_READONLY))
 		set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_READ_ONLY);
+	if (test_share_flag(share, KSMBD_SHARE_FLAG_UPDATE))
+		set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_UPDATE);
 
 	if (shm_open_connection(share)) {
 		resp->status = KSMBD_TREE_CONN_STATUS_TOO_MANY_CONNS;
@@ -207,8 +209,12 @@ bind:
 		tcm_tree_conn_free(conn);
 		put_ksmbd_user(user);
 	}
+
+	g_rw_lock_writer_lock(&share->update_lock);
+	clear_share_flag(share, KSMBD_SHARE_FLAG_UPDATE);
+	g_rw_lock_writer_unlock(&share->update_lock);
+
 	return 0;
-
 out_error:
 	tcm_tree_conn_free(conn);
 	shm_close_connection(share);
-- 
2.37.1


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

* Re: [PATCH v2 1/3] ksmbd: request update to stale share config
  2022-08-08 22:02 [PATCH v2 1/3] ksmbd: request update to stale share config atheik
  2022-08-08 22:02 ` [PATCH v2 2/3] ksmbd-tools: cleanup config group handling atheik
  2022-08-08 22:02 ` [PATCH v2 3/3] ksmbd-tools: inform ksmbd of stale share config atheik
@ 2022-08-09  0:38 ` Namjae Jeon
  2 siblings, 0 replies; 5+ messages in thread
From: Namjae Jeon @ 2022-08-09  0:38 UTC (permalink / raw)
  To: atheik; +Cc: linux-cifs, Steve French, Hyeoncheol Lee

2022-08-09 7:02 GMT+09:00, atheik <atteh.mailbox@gmail.com>:
> ksmbd_share_config_get() retrieves the cached share config as long
> as there is at least one connection to the share. This is an issue when
> the user space utilities are used to update share configs. In that case
> there is a need to inform ksmbd that it should not use the cached share
> config for a new connection to the share. With these changes the tree
> connection flag KSMBD_TREE_CONN_FLAG_UPDATE indicates this. When this
> flag is set, ksmbd removes the share config from the shares hash table
> meaning that ksmbd_share_config_get() ends up requesting a share config
> from user space.
>
> Signed-off-by: Atte Heikkilä <atteh.mailbox@gmail.com>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>

Thanks for your patch!

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

* Re: [PATCH v2 3/3] ksmbd-tools: inform ksmbd of stale share config
  2022-08-08 22:02 ` [PATCH v2 3/3] ksmbd-tools: inform ksmbd of stale share config atheik
@ 2022-08-10  8:06   ` Namjae Jeon
  0 siblings, 0 replies; 5+ messages in thread
From: Namjae Jeon @ 2022-08-10  8:06 UTC (permalink / raw)
  To: atheik; +Cc: linux-cifs

2022-08-09 7:02 GMT+09:00, atheik <atteh.mailbox@gmail.com>:
> When initializing a share from a group, flag the share with
> KSMBD_SHARE_FLAG_UPDATE if the group callback mode denotes that the
> config file was reloaded. If the share was flagged, then later when
> handling a tree connect request, flag the connection with
> KSMBD_TREE_CONN_FLAG_UPDATE to inform ksmbd that its cached share
> config is stale. If there are no failures when handling the request,
> remove the share flag.
>
> Signed-off-by: Atte Heikkilä <atteh.mailbox@gmail.com>
Applied 2/3, 3/3 patches.

Thanks!

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

end of thread, other threads:[~2022-08-10  8:06 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-08 22:02 [PATCH v2 1/3] ksmbd: request update to stale share config atheik
2022-08-08 22:02 ` [PATCH v2 2/3] ksmbd-tools: cleanup config group handling atheik
2022-08-08 22:02 ` [PATCH v2 3/3] ksmbd-tools: inform ksmbd of stale share config atheik
2022-08-10  8:06   ` Namjae Jeon
2022-08-09  0:38 ` [PATCH v2 1/3] ksmbd: request update to " 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.