[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Wed Dec 18 00:06:02 UTC 2019


The branch, master has been updated
       via  1141fbe9842 smbd: Convert share_mode_data->num_share_modes into a boolean8
       via  4a60e577db5 smbd: Don't store "num_share_modes" in locking.tdb
       via  9734bad37b8 smbd: Use share_mode_data->num_share_modes as a boolean
       via  42ce74994e9 smbd: Avoid a direct access to share_mode_data->num_share_modes
       via  15977f5df85 smbd: Introduce share_mode_have_entries()
       via  0df06f51ffb smbd: Avoid a reference to share_mode_data->num_share_modes
       via  5a2fa45741d smbd: Avoid a reference to share_mode_data->num_share_modes
       via  21eff9d18d2 smbd: Pass num_share_modes to share_mode_entry_do() callback
       via  3e5f1be8eac net: Use share_mode_count_entries()
       via  28d9c418605 smbd: Add share_mode_count_entries()
       via  54293f92cd8 vfs_ceph_snapshots: fix root relative path handling
      from  fca2d3e0d1f s3: VFS: glusterfs: Reset nlinks for symlink entries during readdir

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 1141fbe9842c57fca7ee1175665638a0c1f5a181
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Dec 11 16:19:59 2019 +0100

    smbd: Convert share_mode_data->num_share_modes into a boolean8
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Wed Dec 18 00:05:13 UTC 2019 on sn-devel-184

commit 4a60e577db51b0ee5b450d643872463d6939ccee
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Dec 11 10:02:54 2019 +0100

    smbd: Don't store "num_share_modes" in locking.tdb
    
    With the last commit we don't store the share mode entry count
    anymore. With this commit we go one step further and avoid storing
    it. If there's valid record in locking.tdb, there is a corresponding
    record in share_entries.tdb, so there's no point storing that once
    more explicitly.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 9734bad37b8bc4b2815f2bff4c0f48d33fb76c4d
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Dec 10 18:15:40 2019 +0100

    smbd: Use share_mode_data->num_share_modes as a boolean
    
    This is a micro-commit showing that we don't actually need
    share_mode_data->num_share_modes as a number *counting* the share mode
    entries in share_entries.tdb anymore. Instead, we are only using it as
    an indication for share_mode_lock_destructor() to see whether share
    entries are around or not, i.e. whether it's worth keeping or deleting
    the record in locking.tdb.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 42ce74994e98dda95c32d3fcbd66d825f6d84519
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Dec 17 14:23:16 2019 +0100

    smbd: Avoid a direct access to share_mode_data->num_share_modes
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 15977f5df85980ff0adbb372e4a4f0d51dde39dc
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Dec 17 14:20:48 2019 +0100

    smbd: Introduce share_mode_have_entries()
    
    This hides a use of share_mode_data->num_share_modes in
    share_mode_lock.c
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 0df06f51ffbc200b0525e175e7ac58795fd93bab
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Dec 10 14:41:57 2019 +0100

    smbd: Avoid a reference to share_mode_data->num_share_modes
    
    share_mode_data->num_share_modes will go away soon, count the values
    directly while walking the array.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 5a2fa45741db6d157705f81a8830907e34f07120
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Dec 3 10:39:12 2019 +0100

    smbd: Avoid a reference to share_mode_data->num_share_modes
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 21eff9d18d23ddc232a566eca51a6f32e30f0c11
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Dec 3 10:36:21 2019 +0100

    smbd: Pass num_share_modes to share_mode_entry_do() callback
    
    mark_share_mode_disconnected_fn() will need this, the information is
    easily available and should not hurt the other callers.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 3e5f1be8eace95cffa9d7e4cfd55eedca9ce2ceb
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Nov 29 15:46:20 2019 +0100

    net: Use share_mode_count_entries()
    
    Avoid a reference to share_mode_data->num_share_modes
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 28d9c418605356db65e90b1386d890308f3ab41f
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Nov 29 15:45:22 2019 +0100

    smbd: Add share_mode_count_entries()
    
    In order to not write the share mode on every open/close, we need to get rid of
    share_mode_data->num_share_modes. "net tdb" needs this information precisely
    though, and it's pretty cheap to calculate.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 54293f92cd83efc3a5a78fc29a85643921da9d32
Author: David Disseldorp <ddiss at samba.org>
Date:   Thu Dec 12 22:14:50 2019 +0100

    vfs_ceph_snapshots: fix root relative path handling
    
    For file paths relative to root, ceph_snap_get_parent_path() may return
    an empty parent dir string, in which case the CephFS snashot path should
    be ".snap".
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=14216
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source3/librpc/idl/open_files.idl    |   2 +-
 source3/locking/proto.h              |   2 +
 source3/locking/share_mode_lock.c    | 121 +++++++++++++++++++++++++++--------
 source3/modules/vfs_ceph_snapshots.c |  14 +++-
 source3/smbd/open.c                  |   9 ++-
 source3/utils/net_tdb.c              |  14 +++-
 6 files changed, 129 insertions(+), 33 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/librpc/idl/open_files.idl b/source3/librpc/idl/open_files.idl
index 4bfadb5656a..432c1e71bc0 100644
--- a/source3/librpc/idl/open_files.idl
+++ b/source3/librpc/idl/open_files.idl
@@ -58,13 +58,13 @@ interface open_files
 		[string,charset(UTF8)] char *servicepath;
 		[string,charset(UTF8)] char *base_name;
 		[string,charset(UTF8)] char *stream_name;
-		uint32 num_share_modes;
 		uint32 num_delete_tokens;
 		[size_is(num_delete_tokens)] delete_token delete_tokens[];
 		NTTIME old_write_time;
 		NTTIME changed_write_time;
 		[skip] boolean8 fresh;
 		[skip] boolean8 modified;
+		[skip] boolean8 have_share_modes;
 		[ignore] file_id id; /* In memory key used to lookup cache. */
 	} share_mode_data;
 
diff --git a/source3/locking/proto.h b/source3/locking/proto.h
index 432278e3c30..b7098c1e788 100644
--- a/source3/locking/proto.h
+++ b/source3/locking/proto.h
@@ -149,6 +149,7 @@ NTSTATUS share_mode_do_locked(
 		   void *private_data),
 	void *private_data);
 NTSTATUS share_mode_wakeup_waiters(struct file_id id);
+bool share_mode_have_entries(struct share_mode_lock *lck);
 
 struct tevent_req *share_mode_watch_send(
 	TALLOC_CTX *mem_ctx,
@@ -244,6 +245,7 @@ bool share_mode_forall_entries(
 		   void *private_data),
 	void *private_data);
 
+NTSTATUS share_mode_count_entries(struct file_id fid, size_t *num_share_modes);
 
 /* The following definitions come from locking/posix.c  */
 
diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c
index 6704f34523a..ce22ce540cf 100644
--- a/source3/locking/share_mode_lock.c
+++ b/source3/locking/share_mode_lock.c
@@ -404,6 +404,14 @@ static struct share_mode_data *parse_share_modes(TALLOC_CTX *mem_ctx,
 		NDR_PRINT_DEBUG(share_mode_data, d);
 	}
 
+	/*
+	 * We have a non-zero locking.tdb record that was correctly
+	 * parsed. This means a share_entries.tdb entry exists,
+	 * otherwise we'd have paniced before in
+	 * share_mode_data_store()
+	 */
+	d->have_share_modes = true;
+
 	return d;
 fail:
 	TALLOC_FREE(d);
@@ -433,7 +441,7 @@ static NTSTATUS share_mode_data_store(
 
 	d->sequence_number += 1;
 
-	if (d->num_share_modes == 0) {
+	if (!d->have_share_modes) {
 		TDB_DATA key = dbwrap_record_get_key(rec);
 		bool share_entries_exist;
 		share_entries_exist = dbwrap_exists(share_entries_db, key);
@@ -684,7 +692,7 @@ static int share_mode_lock_destructor(struct share_mode_lock *lck)
 		TALLOC_FREE(static_share_mode_record);
 	}
 
-	if (static_share_mode_data->num_share_modes != 0) {
+	if (static_share_mode_data->have_share_modes) {
 		/*
 		 * This is worth keeping. Without share modes,
 		 * share_mode_data_store above has left nothing in the
@@ -805,6 +813,11 @@ NTSTATUS share_mode_wakeup_waiters(struct file_id id)
 	return share_mode_do_locked(id, share_mode_wakeup_waiters_fn, NULL);
 }
 
+bool share_mode_have_entries(struct share_mode_lock *lck)
+{
+	return lck->data->have_share_modes;
+}
+
 struct share_mode_watch_state {
 	struct tevent_context *ev;
 	bool blockerdead;
@@ -1197,6 +1210,7 @@ int share_entry_forall(int (*fn)(struct file_id fid,
 struct cleanup_disconnected_state {
 	struct share_mode_lock *lck;
 	uint64_t open_persistent_id;
+	size_t num_disconnected;
 	bool found_connected;
 };
 
@@ -1265,6 +1279,8 @@ static bool share_mode_find_connected_fn(
 		return true;
 	}
 
+	state->num_disconnected += 1;
+
 	return false;
 }
 
@@ -1334,11 +1350,11 @@ bool share_mode_cleanup_disconnected(struct file_id fid,
 		goto done;
 	}
 
-	DBG_DEBUG("cleaning up %u entries for file "
+	DBG_DEBUG("cleaning up %zu entries for file "
 		  "(file-id='%s', servicepath='%s', "
 		  "base_name='%s%s%s') "
 		  "from open_persistent_id %"PRIu64"\n",
-		  data->num_share_modes,
+		  state.num_disconnected,
 		  file_id_str_buf(fid, &idbuf),
 		  data->servicepath,
 		  data->base_name,
@@ -1358,7 +1374,7 @@ bool share_mode_cleanup_disconnected(struct file_id fid,
 		goto done;
 	}
 
-	data->num_share_modes = 0;
+	data->have_share_modes = false;
 	data->modified = true;
 
 	ret = true;
@@ -1500,7 +1516,7 @@ static size_t share_mode_entry_find(
 
 struct set_share_mode_state {
 	struct share_mode_entry e;
-	uint32_t num_share_modes;
+	bool created_share_mode_record;
 	NTSTATUS status;
 };
 
@@ -1580,7 +1596,7 @@ static void set_share_mode_fn(
 		}
 	}
 
-	state->num_share_modes = num_share_modes+1;
+	state->created_share_mode_record = (num_share_modes == 0);
 	state->status = dbwrap_record_storev(rec, dbufs, num_dbufs, 0);
 }
 
@@ -1633,8 +1649,10 @@ bool set_share_mode(struct share_mode_lock *lck,
 		return false;
 	}
 
-	d->num_share_modes = state.num_share_modes;
-	d->modified = true;
+	if (state.created_share_mode_record) {
+		d->have_share_modes = true;
+		d->modified = true;
+	}
 
 	return true;
 }
@@ -1645,7 +1663,6 @@ struct share_mode_forall_entries_state {
 		   bool *modified,
 		   void *private_data);
 	void *private_data;
-	size_t num_share_modes;
 	bool ok;
 };
 
@@ -1780,12 +1797,11 @@ static void share_mode_forall_entries_fn(
 		return;
 	}
 
-	if (num_share_modes != d->num_share_modes) {
-		d->num_share_modes = num_share_modes;
-		d->modified = true;
-	}
-
 	if (num_share_modes == 0) {
+		if (data.dsize != 0) {
+			d->have_share_modes = false;
+			d->modified = true;
+		}
 		status = dbwrap_record_delete(rec);
 	} else {
 		TDB_DATA value = {
@@ -1838,10 +1854,57 @@ bool share_mode_forall_entries(
 	return state.ok;
 }
 
+struct share_mode_count_entries_state {
+	size_t num_share_modes;
+	NTSTATUS status;
+};
+
+static void share_mode_count_entries_fn(
+	TDB_DATA key, TDB_DATA data, void *private_data)
+{
+	struct share_mode_count_entries_state *state = private_data;
+
+	if ((data.dsize % SHARE_MODE_ENTRY_SIZE) != 0) {
+		DBG_WARNING("Invalid data size %zu\n", data.dsize);
+		state->status = NT_STATUS_INTERNAL_DB_CORRUPTION;
+		return;
+	}
+	state->num_share_modes = data.dsize / SHARE_MODE_ENTRY_SIZE;
+	state->status = NT_STATUS_OK;
+}
+
+NTSTATUS share_mode_count_entries(struct file_id fid, size_t *num_share_modes)
+{
+	struct share_mode_count_entries_state state = {
+		.status = NT_STATUS_NOT_FOUND,
+	};
+	NTSTATUS status;
+
+	status = dbwrap_parse_record(
+		share_entries_db,
+		locking_key(&fid),
+		share_mode_count_entries_fn,
+		&state);
+	if (!NT_STATUS_IS_OK(status)) {
+		DBG_DEBUG("dbwrap_parse_record failed: %s\n",
+			  nt_errstr(status));
+		return status;
+	}
+	if (!NT_STATUS_IS_OK(state.status)) {
+		DBG_DEBUG("share_mode_forall_entries_fn failed: %s\n",
+			  nt_errstr(state.status));
+		return state.status;
+	}
+
+	*num_share_modes = state.num_share_modes;
+	return NT_STATUS_OK;
+}
+
 struct share_mode_entry_do_state {
 	struct server_id pid;
 	uint64_t share_file_id;
 	void (*fn)(struct share_mode_entry *e,
+		   size_t num_share_modes,
 		   bool *modified,
 		   void *private_data);
 	void *private_data;
@@ -1886,7 +1949,7 @@ static void share_mode_entry_do_fn(
 		return;
 	}
 
-	state->fn(&e, &modified, state->private_data);
+	state->fn(&e, state->num_share_modes, &modified, state->private_data);
 
 	if (!e.stale && !modified) {
 		state->status = NT_STATUS_OK;
@@ -1952,6 +2015,7 @@ static bool share_mode_entry_do(
 	struct server_id pid,
 	uint64_t share_file_id,
 	void (*fn)(struct share_mode_entry *e,
+		   size_t num_share_modes,
 		   bool *modified,
 		   void *private_data),
 	void *private_data)
@@ -1964,6 +2028,7 @@ static bool share_mode_entry_do(
 		.private_data = private_data,
 	};
 	NTSTATUS status;
+	bool have_share_modes;
 
 	status = dbwrap_do_locked(
 		share_entries_db,
@@ -1981,8 +2046,9 @@ static bool share_mode_entry_do(
 		return false;
 	}
 
-	if (d->num_share_modes != state.num_share_modes) {
-		d->num_share_modes = state.num_share_modes;
+	have_share_modes = (state.num_share_modes != 0);
+	if (d->have_share_modes != have_share_modes) {
+		d->have_share_modes = have_share_modes;
 		d->modified = true;
 	}
 
@@ -1995,6 +2061,7 @@ struct del_share_mode_state {
 
 static void del_share_mode_fn(
 	struct share_mode_entry *e,
+	size_t num_share_modes,
 	bool *modified,
 	void *private_data)
 {
@@ -2031,6 +2098,7 @@ struct remove_share_oplock_state {
 
 static void remove_share_oplock_fn(
 	struct share_mode_entry *e,
+	size_t num_share_modes,
 	bool *modified,
 	void *private_data)
 {
@@ -2079,6 +2147,7 @@ struct downgrade_share_oplock_state {
 
 static void downgrade_share_oplock_fn(
 	struct share_mode_entry *e,
+	size_t num_share_modes,
 	bool *modified,
 	void *private_data)
 {
@@ -2122,10 +2191,17 @@ struct mark_share_mode_disconnected_state {
 
 static void mark_share_mode_disconnected_fn(
 	struct share_mode_entry *e,
+	size_t num_share_modes,
 	bool *modified,
 	void *private_data)
 {
 	struct mark_share_mode_disconnected_state *state = private_data;
+
+	if (num_share_modes != 1) {
+		state->ok = false;
+		return;
+	}
+
 	server_id_set_disconnected(&e->pid);
 	e->share_file_id = state->open_persistent_id;
 	*modified = true;
@@ -2138,10 +2214,6 @@ bool mark_share_mode_disconnected(struct share_mode_lock *lck,
 	struct mark_share_mode_disconnected_state state;
 	bool ok;
 
-	if (lck->data->num_share_modes != 1) {
-		return false;
-	}
-
 	if (fsp->op == NULL) {
 		return false;
 	}
@@ -2174,6 +2246,7 @@ bool mark_share_mode_disconnected(struct share_mode_lock *lck,
 
 static void reset_share_mode_entry_del_fn(
 	struct share_mode_entry *e,
+	size_t num_share_modes,
 	bool *modified,
 	void *private_data)
 {
@@ -2235,9 +2308,7 @@ bool reset_share_mode_entry(
 			    nt_errstr(state.status));
 		return false;
 	}
-
-	d->num_share_modes = state.num_share_modes;
-	d->modified = true;
+	d->have_share_modes = true;
 
 	return true;
 }
diff --git a/source3/modules/vfs_ceph_snapshots.c b/source3/modules/vfs_ceph_snapshots.c
index ce364ae83dc..64f195f4add 100644
--- a/source3/modules/vfs_ceph_snapshots.c
+++ b/source3/modules/vfs_ceph_snapshots.c
@@ -390,8 +390,12 @@ static int ceph_snap_get_shadow_copy_data(struct vfs_handle_struct *handle,
 		parent_dir = tmp;
 	}
 
-	ret = snprintf(snaps_path, sizeof(snaps_path), "%s/%s",
-		       parent_dir, snapdir);
+	if (strlen(parent_dir) == 0) {
+		ret = strlcpy(snaps_path, snapdir, sizeof(snaps_path));
+	} else {
+		ret = snprintf(snaps_path, sizeof(snaps_path), "%s/%s",
+			       parent_dir, snapdir);
+	}
 	if (ret >= sizeof(snaps_path)) {
 		ret = -EINVAL;
 		goto err_out;
@@ -534,7 +538,11 @@ static int ceph_snap_gmt_convert_dir(struct vfs_handle_struct *handle,
 	/*
 	 * Temporally use the caller's return buffer for this.
 	 */
-	ret = snprintf(_converted_buf, buflen, "%s/%s", name, snapdir);
+	if (strlen(name) == 0) {
+		ret = strlcpy(_converted_buf, snapdir, buflen);
+	} else {
+		ret = snprintf(_converted_buf, buflen, "%s/%s", name, snapdir);
+	}
 	if (ret >= buflen) {
 		ret = -EINVAL;
 		goto err_out;
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index d1c3f6badc8..a999f86dd44 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -1811,7 +1811,7 @@ static NTSTATUS open_mode_check(connection_struct *conn,
 	struct share_mode_data *d = lck->data;
 	struct open_mode_check_state state;
 	uint16_t new_flags;
-	bool ok, conflict;
+	bool ok, conflict, have_share_entries;
 
 	if (is_stat_open(access_mask)) {
 		/* Stat open that doesn't trigger oplock breaks or share mode
@@ -1836,7 +1836,12 @@ static NTSTATUS open_mode_check(connection_struct *conn,
 	}
 #endif
 
-	if (d->num_share_modes == 0) {
+	have_share_entries = share_mode_have_entries(lck);
+	if (!have_share_entries) {
+		/*
+		 * This is a fresh share mode lock where no conflicts
+		 * can happen.
+		 */
 		return NT_STATUS_OK;
 	}
 
diff --git a/source3/utils/net_tdb.c b/source3/utils/net_tdb.c
index 49dbd04664a..0b81acf18e5 100644
--- a/source3/utils/net_tdb.c
+++ b/source3/utils/net_tdb.c
@@ -95,10 +95,20 @@ static int net_tdb_locking(struct net_context *c, int argc, const char **argv)
 	if (argc == 2 && strequal(argv[1], "dump")) {
 		ret = net_tdb_locking_dump(mem_ctx, lock->data);
 	} else {
+		NTSTATUS status;
+		size_t num_share_modes = 0;
+
+		status = share_mode_count_entries(
+			lock->data->id, &num_share_modes);
+		if (!NT_STATUS_IS_OK(status)) {
+			d_fprintf(stderr,
+				  "Could not count share entries: %s\n",
+				  nt_errstr(status));
+		}
+
 		d_printf("Share path:            %s\n", lock->data->servicepath);
 		d_printf("Name:                  %s\n", lock->data->base_name);
-		d_printf("Number of share modes: %" PRIu32 "\n",
-			 lock->data->num_share_modes);
+		d_printf("Number of share modes: %zu\n", num_share_modes);
 	}
 
 out:


-- 
Samba Shared Repository



More information about the samba-cvs mailing list