[SCM] Samba Shared Repository - branch master updated

Michael Adam obnox at samba.org
Thu Apr 18 07:11:03 MDT 2013


The branch, master has been updated
       via  87685b3 s4:torture:smb2 delete temp memory context in test_durable_open_oplock_disconnect
       via  2ef02e4 s4:torture:smb2:durable_v2: remove an unused variable
       via  c2ef518 s3:smbd: call scavenger_schedule_disconnected() from close normal file for durable handles
       via  1ed22ba s3:smbd: add a scavenger process for disconnected durable handles
       via  f608bed s3:locking: add function share_mode_cleanup_disconnected()
       via  0ac0b35 s3:locking: improve debug output of parse_share_modes()
       via  3d3e7e8 s3:locking: no need to make a file_id passed by value a constant
       via  ee81a6e s3:locking:brlock: add function brl_cleanup_disconnected()
       via  6ee1555 s3:locking:brlock: explain the lockdb_clean semantic better in brl_reconnect_disconnected()
       via  f08bda2 s3:locking:brlock: let validate_lock_entries keep entries for disconnected servers in traverses
       via  fe0bf0b s3:locking:brlock: improve the comment for the brl self cleaning code
       via  02cc5a5 s3:locking:brlock: use serverids_exist to validate_lock_entries
       via  941e84d s3:smbXsrv_open: add function smbXsrv_open_cleanup()
       via  9d47dc8 s3:smbXsrv_open: factor out smbXsrv_open_global_parse_record
       via  49cd31e s3:net registry check: use tdb_data_string()
       via  037f57e util_tdb: add function tdb_data_string()
       via  450ebe9 s3:winbindd: avoid usage of procid_self()
       via  beb9a27 s3:smbd:smb2: fix setting of scavenge timeout when reconnecting durable handles
      from  bb7c6a0 netcmd/dns: fix typo

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


- Log -----------------------------------------------------------------
commit 87685b30d7ab52193c54abacdab0b442bcc51a47
Author: Gregor Beck <gbeck at sernet.de>
Date:   Wed Apr 3 09:27:26 2013 +0200

    s4:torture:smb2 delete temp memory context in test_durable_open_oplock_disconnect
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    
    Autobuild-User(master): Michael Adam <obnox at samba.org>
    Autobuild-Date(master): Thu Apr 18 15:10:31 CEST 2013 on sn-devel-104

commit 2ef02e4f5a5772c1b598fa0df6e5cf0a10d2e060
Author: Michael Adam <obnox at samba.org>
Date:   Thu Jan 17 22:17:42 2013 +0100

    s4:torture:smb2:durable_v2: remove an unused variable
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit c2ef5182e32fafeb3e279d9fc3a2a409e4aa0543
Author: Gregor Beck <gbeck at sernet.de>
Date:   Wed Mar 20 10:01:43 2013 +0100

    s3:smbd: call scavenger_schedule_disconnected() from close normal file for durable handles
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 1ed22ba4b7998c1fc29476e931bd463f2bc1ba7e
Author: Gregor Beck <gbeck at sernet.de>
Date:   Thu Feb 7 15:26:37 2013 +0100

    s3:smbd: add a scavenger process for disconnected durable handles
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit f608bedfca4118b7e3606802df40e266bcc099d8
Author: Gregor Beck <gbeck at sernet.de>
Date:   Wed Mar 13 11:35:37 2013 +0100

    s3:locking: add function share_mode_cleanup_disconnected()
    
    For a given file, clean share mode entries for a given persistent file id.
    
    Pair-Programmed-With: Michael Adam <obnox at samba.org>
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Signed-off-by: Michael Adam <obnox at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 0ac0b35dad796d10cf04ab77a53a926420cc0589
Author: Gregor Beck <gbeck at sernet.de>
Date:   Wed Mar 20 10:22:06 2013 +0100

    s3:locking: improve debug output of parse_share_modes()
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 3d3e7e837a339dfc1aaf4d7fc52f95f3f6a80173
Author: Gregor Beck <gbeck at sernet.de>
Date:   Tue Mar 12 15:10:51 2013 +0100

    s3:locking: no need to make a file_id passed by value a constant
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit ee81a6e7d0263d263f7d4e7bd5bd9c4156cae8cf
Author: Gregor Beck <gbeck at sernet.de>
Date:   Wed Mar 13 14:47:18 2013 +0100

    s3:locking:brlock: add function brl_cleanup_disconnected()
    
    For a given file, clean up brl entries belonging to a given persistent file id.
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 6ee1555df2e69aead00ee231c990020cc4bf04bc
Author: Michael Adam <obnox at samba.org>
Date:   Fri Apr 12 11:13:57 2013 +0200

    s3:locking:brlock: explain the lockdb_clean semantic better in brl_reconnect_disconnected()
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit f08bda22dc7a5038fab77ad7dd090a6f72d94c7f
Author: Gregor Beck <gbeck at sernet.de>
Date:   Tue Mar 5 14:49:28 2013 +0100

    s3:locking:brlock: let validate_lock_entries keep entries for disconnected servers in traverses
    
    We should not remove locks of disconnected opens just like that.
    When getting the byte range lock record for a newly connected file
    handle, we still do the clean up, because in that situation,
    disconnected entries are not valid any more.
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit fe0bf0b6d67a49a30969f922ee65f0af88a952a1
Author: Michael Adam <obnox at samba.org>
Date:   Fri Apr 12 11:05:29 2013 +0200

    s3:locking:brlock: improve the comment for the brl self cleaning code
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 02cc5a5c6a6b6b2b796abe573a671853d945b22f
Author: Gregor Beck <gbeck at sernet.de>
Date:   Tue Mar 5 14:02:10 2013 +0100

    s3:locking:brlock: use serverids_exist to validate_lock_entries
    
    ...instead of checking each server-id separately which can
    be expensive in a cluster.
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 941e84dcfe985559e5e75318e7b5dd9d50fcc47b
Author: Gregor Beck <gbeck at sernet.de>
Date:   Tue Mar 12 14:36:32 2013 +0100

    s3:smbXsrv_open: add function smbXsrv_open_cleanup()
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 9d47dc8958f7fcab77460495bd1ae940122dddd8
Author: Gregor Beck <gbeck at sernet.de>
Date:   Tue Mar 12 13:43:30 2013 +0100

    s3:smbXsrv_open: factor out smbXsrv_open_global_parse_record
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 49cd31e39d70c090c448df5a9b6c50ca83e06f9b
Author: Gregor Beck <gbeck at sernet.de>
Date:   Thu Mar 28 10:28:21 2013 +0100

    s3:net registry check: use tdb_data_string()
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 037f57e12fb7b87e0c5c035ae85cb698bca64f4d
Author: Gregor Beck <gbeck at sernet.de>
Date:   Wed Mar 20 09:56:54 2013 +0100

    util_tdb: add function tdb_data_string()
    
    Signed-off-by: Gregor Beck <gbeck at sernet.de>
    Reviewed-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 450ebe97d1c36a8041e3567c0b1fe94822909ea2
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Apr 15 11:28:47 2013 +0200

    s3:winbindd: avoid usage of procid_self()
    
    metze
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit beb9a27180e5570337381d03fac55bbe6d1637e0
Author: Michael Adam <obnox at samba.org>
Date:   Thu Apr 18 13:11:03 2013 +0200

    s3:smbd:smb2: fix setting of scavenge timeout when reconnecting durable handles
    
    The bug fixed with this commit led to reconnected durable handles
    having a disconnect timeout of 0 msec. This fix re-establishes the
    original timeout for the reconnected handle.
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Signed-off-by: Michael Adam <obnox at samba.org>

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

Summary of changes:
 lib/util/debug.c                                   |    1 +
 lib/util/debug.h                                   |    3 +-
 source3/Makefile.in                                |    1 +
 source3/include/util_tdb.h                         |    2 +
 source3/lib/util_tdb.c                             |   33 ++
 source3/librpc/idl/messaging.idl                   |    1 +
 source3/locking/brlock.c                           |  152 +++++-
 source3/locking/proto.h                            |   10 +-
 source3/locking/share_mode_lock.c                  |  119 ++++-
 source3/smbd/close.c                               |    2 +
 source3/smbd/globals.h                             |    3 +
 source3/smbd/scavenger.c                           |  531 ++++++++++++++++++++
 .../echo_server.h => source3/smbd/scavenger.h      |   20 +-
 source3/smbd/server.c                              |    5 +
 source3/smbd/smb2_create.c                         |    9 +-
 source3/smbd/smbXsrv_open.c                        |  127 +++++-
 source3/utils/net_registry_check.c                 |   23 +-
 source3/winbindd/winbindd.c                        |    4 +-
 source3/wscript_build                              |    1 +
 source4/torture/smb2/durable_open.c                |    4 +-
 source4/torture/smb2/durable_v2_open.c             |    1 -
 21 files changed, 970 insertions(+), 82 deletions(-)
 create mode 100644 source3/smbd/scavenger.c
 copy source4/echo_server/echo_server.h => source3/smbd/scavenger.h (69%)


Changeset truncated at 500 lines:

diff --git a/lib/util/debug.c b/lib/util/debug.c
index 7509f90..6207b61 100644
--- a/lib/util/debug.c
+++ b/lib/util/debug.c
@@ -176,6 +176,7 @@ static const char *default_classname_table[] = {
 	"msdfs",	     /* DBGC_MSDFS	  */
 	"dmapi",	     /* DBGC_DMAPI	  */
 	"registry",          /* DBGC_REGISTRY     */
+	"scavenger",         /* DBGC_SCAVENGER    */
 	NULL
 };
 
diff --git a/lib/util/debug.h b/lib/util/debug.h
index 2566418..c61fd13 100644
--- a/lib/util/debug.h
+++ b/lib/util/debug.h
@@ -79,9 +79,10 @@ bool dbghdr( int level, const char *location, const char *func);
 #define DBGC_MSDFS		17
 #define DBGC_DMAPI		18
 #define DBGC_REGISTRY		19
+#define DBGC_SCAVENGER		20
 
 /* Always ensure this is updated when new fixed classes area added, to ensure the array in debug.c is the right size */
-#define DBGC_MAX_FIXED		19
+#define DBGC_MAX_FIXED		20
 
 /* So you can define DBGC_CLASS before including debug.h */
 #ifndef DBGC_CLASS
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 42332c6..a868685 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -999,6 +999,7 @@ SMBD_OBJ_SRV = smbd/server_reload.o \
 	       smbd/smbXsrv_tcon.o \
 	       smbd/smbXsrv_open.o \
 	       smbd/durable.o \
+	       smbd/scavenger.o \
 	       autoconf/librpc/gen_ndr/ndr_ioctl.o \
 	       $(MANGLE_OBJ) @VFS_STATIC@
 
diff --git a/source3/include/util_tdb.h b/source3/include/util_tdb.h
index e350413..c9e9e40 100644
--- a/source3/include/util_tdb.h
+++ b/source3/include/util_tdb.h
@@ -44,4 +44,6 @@ NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err);
 
 int tdb_data_cmp(TDB_DATA t1, TDB_DATA t2);
 
+char *tdb_data_string(TALLOC_CTX *mem_ctx, TDB_DATA d);
+
 #endif /* __TDBUTIL_H__ */
diff --git a/source3/lib/util_tdb.c b/source3/lib/util_tdb.c
index 8bfc75f..440c28b 100644
--- a/source3/lib/util_tdb.c
+++ b/source3/lib/util_tdb.c
@@ -22,6 +22,7 @@
 #include "includes.h"
 #include "system/filesys.h"
 #include "util_tdb.h"
+#include "cbuf.h"
 
 #undef malloc
 #undef realloc
@@ -418,3 +419,35 @@ int tdb_data_cmp(TDB_DATA t1, TDB_DATA t2)
 	}
 	return ret;
 }
+
+char *tdb_data_string(TALLOC_CTX *mem_ctx, TDB_DATA d)
+{
+	int len;
+	char *ret = NULL;
+	cbuf *ost = cbuf_new(mem_ctx);
+
+	if (ost == NULL) {
+		return NULL;
+	}
+
+	len = cbuf_printf(ost, "%d:");
+	if (len == -1) {
+		goto done;
+	}
+
+	if (d.dptr == NULL) {
+		len = cbuf_puts(ost, "<NULL>", -1);
+	} else {
+		len = cbuf_print_quoted(ost, (const char*)d.dptr, d.dsize);
+	}
+	if (len == -1) {
+		goto done;
+	}
+
+	cbuf_swapptr(ost, &ret, 0);
+	talloc_steal(mem_ctx, ret);
+
+done:
+	talloc_free(ost);
+	return ret;
+}
diff --git a/source3/librpc/idl/messaging.idl b/source3/librpc/idl/messaging.idl
index df1f321..c262889 100644
--- a/source3/librpc/idl/messaging.idl
+++ b/source3/librpc/idl/messaging.idl
@@ -87,6 +87,7 @@ interface messaging
 
 		/* Trigger a notify cleanup run */
 		MSG_SMB_NOTIFY_CLEANUP		= 0x0314,
+		MSG_SMB_SCAVENGER		= 0x0315,
 
 		/* winbind messages */
 		MSG_WINBIND_FINISHED		= 0x0401,
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c
index c5bbcd1..865aaca 100644
--- a/source3/locking/brlock.c
+++ b/source3/locking/brlock.c
@@ -32,6 +32,7 @@
 #include "dbwrap/dbwrap_open.h"
 #include "serverid.h"
 #include "messages.h"
+#include "util_tdb.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_LOCKING
@@ -1595,7 +1596,11 @@ bool brl_reconnect_disconnected(struct files_struct *fsp)
 		return false;
 	}
 
-	/* we want to validate ourself */
+	/*
+	 * When reconnecting, we do not want to validate the brlock entries
+	 * and thereby remove our own (disconnected) entries but reactivate
+	 * them instead.
+	 */
 	fsp->lockdb_clean = true;
 
 	br_lck = brl_get_locks(talloc_tos(), fsp);
@@ -1650,22 +1655,62 @@ bool brl_reconnect_disconnected(struct files_struct *fsp)
 /****************************************************************************
  Ensure this set of lock entries is valid.
 ****************************************************************************/
-static bool validate_lock_entries(unsigned int *pnum_entries, struct lock_struct **pplocks)
+static bool validate_lock_entries(unsigned int *pnum_entries, struct lock_struct **pplocks,
+				  bool keep_disconnected)
 {
 	unsigned int i;
 	unsigned int num_valid_entries = 0;
 	struct lock_struct *locks = *pplocks;
+	TALLOC_CTX *frame = talloc_stackframe();
+	struct server_id *ids;
+	bool *exists;
+
+	ids = talloc_array(frame, struct server_id, *pnum_entries);
+	if (ids == NULL) {
+		DEBUG(0, ("validate_lock_entries: "
+			  "talloc_array(struct server_id, %u) failed\n",
+			  *pnum_entries));
+		talloc_free(frame);
+		return false;
+	}
+
+	exists = talloc_array(frame, bool, *pnum_entries);
+	if (exists == NULL) {
+		DEBUG(0, ("validate_lock_entries: "
+			  "talloc_array(bool, %u) failed\n",
+			  *pnum_entries));
+		talloc_free(frame);
+		return false;
+	}
 
 	for (i = 0; i < *pnum_entries; i++) {
-		struct lock_struct *lock_data = &locks[i];
-		if (!serverid_exists(&lock_data->context.pid)) {
-			/* This process no longer exists - mark this
-			   entry as invalid by zeroing it. */
-			ZERO_STRUCTP(lock_data);
-		} else {
+		ids[i] = locks[i].context.pid;
+	}
+
+	if (!serverids_exist(ids, *pnum_entries, exists)) {
+		DEBUG(3, ("validate_lock_entries: serverids_exists failed\n"));
+		talloc_free(frame);
+		return false;
+	}
+
+	for (i = 0; i < *pnum_entries; i++) {
+		if (exists[i]) {
 			num_valid_entries++;
+			continue;
 		}
+
+		if (keep_disconnected &&
+		    server_id_is_disconnected(&ids[i]))
+		{
+			num_valid_entries++;
+			continue;
+		}
+
+		/* This process no longer exists - mark this
+		   entry as invalid by zeroing it. */
+		ZERO_STRUCTP(&locks[i]);
 	}
+	TALLOC_FREE(frame);
 
 	if (num_valid_entries != *pnum_entries) {
 		struct lock_struct *new_lock_data = NULL;
@@ -1739,7 +1784,7 @@ static int brl_traverse_fn(struct db_record *rec, void *state)
 
 	/* Ensure the lock db is clean of entries from invalid processes. */
 
-	if (!validate_lock_entries(&num_locks, &locks)) {
+	if (!validate_lock_entries(&num_locks, &locks, true)) {
 		SAFE_FREE(locks);
 		return -1; /* Terminate traversal */
 	}
@@ -1927,12 +1972,21 @@ static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx,
 	if (!fsp->lockdb_clean) {
 		int orig_num_locks = br_lck->num_locks;
 
-		/* This is the first time we've accessed this. */
-		/* Go through and ensure all entries exist - remove any that don't. */
-		/* Makes the lockdb self cleaning at low cost. */
+		/*
+		 * This is the first time we access the byte range lock
+		 * record with this fsp. Go through and ensure all entries
+		 * are valid - remove any that don't.
+		 * This makes the lockdb self cleaning at low cost.
+		 *
+		 * Note: Disconnected entries belong to disconnected
+		 * durable handles. So at this point, we have a new
+		 * handle on the file and the disconnected durable has
+		 * already been closed (we are not a durable reconnect).
+		 * So we need to clean the disconnected brl entry.
+		 */
 
 		if (!validate_lock_entries(&br_lck->num_locks,
-					   &br_lck->lock_data)) {
+					   &br_lck->lock_data, false)) {
 			SAFE_FREE(br_lck->lock_data);
 			TALLOC_FREE(br_lck);
 			return NULL;
@@ -2099,3 +2153,75 @@ void brl_revalidate(struct messaging_context *msg_ctx,
 	TALLOC_FREE(state);
 	return;
 }
+
+bool brl_cleanup_disconnected(struct file_id fid, uint64_t open_persistent_id)
+{
+	bool ret = false;
+	TALLOC_CTX *frame = talloc_stackframe();
+	TDB_DATA key, val;
+	struct db_record *rec;
+	struct lock_struct *lock;
+	unsigned n, num;
+	NTSTATUS status;
+
+	key = make_tdb_data((void*)&fid, sizeof(fid));
+
+	rec = dbwrap_fetch_locked(brlock_db, frame, key);
+	if (rec == NULL) {
+		DEBUG(5, ("brl_cleanup_disconnected: failed to fetch record "
+			  "for file %s\n", file_id_string(frame, &fid)));
+		goto done;
+	}
+
+	val = dbwrap_record_get_value(rec);
+	lock = (struct lock_struct*)val.dptr;
+	num = val.dsize / sizeof(struct lock_struct);
+	if (lock == NULL) {
+		DEBUG(10, ("brl_cleanup_disconnected: no byte range locks for "
+			   "file %s\n", file_id_string(frame, &fid)));
+		ret = true;
+		goto done;
+	}
+
+	for (n=0; n<num; n++) {
+		struct lock_context *ctx = &lock[n].context;
+
+		if (!server_id_is_disconnected(&ctx->pid)) {
+			DEBUG(5, ("brl_cleanup_disconnected: byte range lock "
+				  "%s used by server %s, do not cleanup\n",
+				  file_id_string(frame, &fid),
+				  server_id_str(frame, &ctx->pid)));
+			goto done;
+		}
+
+		if (ctx->smblctx != open_persistent_id)	{
+			DEBUG(5, ("brl_cleanup_disconnected: byte range lock "
+				  "%s expected smblctx %llu but found %llu"
+				  ", do not cleanup\n",
+				  file_id_string(frame, &fid),
+				  (unsigned long long)open_persistent_id,
+				  (unsigned long long)ctx->smblctx));
+			goto done;
+		}
+	}
+
+	status = dbwrap_record_delete(rec);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(5, ("brl_cleanup_disconnected: failed to delete record "
+			  "for file %s from %s, open %llu: %s\n",
+			  file_id_string(frame, &fid), dbwrap_name(brlock_db),
+			  (unsigned long long)open_persistent_id,
+			  nt_errstr(status)));
+		goto done;
+	}
+
+	DEBUG(10, ("brl_cleanup_disconnected: "
+		   "file %s cleaned up %u entries from open %llu\n",
+		   file_id_string(frame, &fid), num,
+		   (unsigned long long)open_persistent_id));
+
+	ret = true;
+done:
+	talloc_free(frame);
+	return ret;
+}
diff --git a/source3/locking/proto.h b/source3/locking/proto.h
index c170c73..bb7255d 100644
--- a/source3/locking/proto.h
+++ b/source3/locking/proto.h
@@ -97,6 +97,7 @@ void brl_revalidate(struct messaging_context *msg_ctx,
 		    uint32_t msg_type,
 		    struct server_id server_id,
 		    DATA_BLOB *data);
+bool brl_cleanup_disconnected(struct file_id fid, uint64_t open_persistent_id);
 
 /* The following definitions come from locking/locking.c  */
 
@@ -149,15 +150,15 @@ bool locking_init_readonly(void);
 bool locking_end(void);
 char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e);
 struct share_mode_lock *get_existing_share_mode_lock(TALLOC_CTX *mem_ctx,
-						     const struct file_id id);
+						     struct file_id id);
 struct share_mode_lock *get_share_mode_lock(
 	TALLOC_CTX *mem_ctx,
-	const struct file_id id,
+	struct file_id id,
 	const char *servicepath,
 	const struct smb_filename *smb_fname,
 	const struct timespec *old_write_time);
 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
-						  const struct file_id id);
+						  struct file_id id);
 bool rename_share_filename(struct messaging_context *msg_ctx,
 			struct share_mode_lock *lck,
 			const char *servicepath,
@@ -201,6 +202,9 @@ bool set_write_time(struct file_id fileid, struct timespec write_time);
 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
 				 const char *, void *),
 		      void *private_data);
+bool share_mode_cleanup_disconnected(struct file_id id,
+				     uint64_t open_persistent_id);
+
 
 /* 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 4f26099..04ff247 100644
--- a/source3/locking/share_mode_lock.c
+++ b/source3/locking/share_mode_lock.c
@@ -104,10 +104,9 @@ bool locking_end(void)
  Form a static locking key for a dev/inode pair.
 ******************************************************************/
 
-static TDB_DATA locking_key(const struct file_id *id, struct file_id *tmp)
+static TDB_DATA locking_key(const struct file_id *id)
 {
-	*tmp = *id;
-	return make_tdb_data((const uint8_t *)tmp, sizeof(*tmp));
+	return make_tdb_data((const uint8_t *)id, sizeof(*id));
 }
 
 /*******************************************************************
@@ -133,7 +132,8 @@ static struct share_mode_data *parse_share_modes(TALLOC_CTX *mem_ctx,
 	ndr_err = ndr_pull_struct_blob(
 		&blob, d, d, (ndr_pull_flags_fn_t)ndr_pull_share_mode_data);
 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-		DEBUG(1, ("ndr_pull_share_mode_lock failed\n"));
+		DEBUG(1, ("ndr_pull_share_mode_lock failed: %s\n",
+			  ndr_errstr(ndr_err)));
 		goto fail;
 	}
 
@@ -286,15 +286,14 @@ fail:
 ********************************************************************/
 
 static struct share_mode_lock *get_share_mode_lock_internal(
-	TALLOC_CTX *mem_ctx, const struct file_id id,
+	TALLOC_CTX *mem_ctx, struct file_id id,
 	const char *servicepath, const struct smb_filename *smb_fname,
 	const struct timespec *old_write_time)
 {
 	struct share_mode_lock *lck;
 	struct share_mode_data *d;
-	struct file_id tmp;
 	struct db_record *rec;
-	TDB_DATA key = locking_key(&id, &tmp);
+	TDB_DATA key = locking_key(&id);
 	TDB_DATA value;
 
 	rec = dbwrap_fetch_locked(lock_db, mem_ctx, key);
@@ -351,7 +350,7 @@ static int the_lock_destructor(struct share_mode_lock *l)
 
 struct share_mode_lock *get_share_mode_lock(
 	TALLOC_CTX *mem_ctx,
-	const struct file_id id,
+	struct file_id id,
 	const char *servicepath,
 	const struct smb_filename *smb_fname,
 	const struct timespec *old_write_time)
@@ -404,11 +403,10 @@ static void fetch_share_mode_unlocked_parser(
 ********************************************************************/
 
 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
-						  const struct file_id id)
+						  struct file_id id)
 {
 	struct share_mode_lock *lck;
-	struct file_id tmp;
-	TDB_DATA key = locking_key(&id, &tmp);
+	TDB_DATA key = locking_key(&id);
 	NTSTATUS status;
 
 	lck = talloc(mem_ctx, struct share_mode_lock);
@@ -503,3 +501,102 @@ int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
 		return count;
 	}
 }
+
+bool share_mode_cleanup_disconnected(struct file_id fid,
+				     uint64_t open_persistent_id)
+{
+	bool ret = false;
+	TALLOC_CTX *frame = talloc_stackframe();
+	unsigned n;
+	struct share_mode_data *data;
+	struct share_mode_lock *lck;
+	bool ok;
+
+	lck = get_existing_share_mode_lock(frame, fid);
+	if (lck == NULL) {
+		DEBUG(5, ("share_mode_cleanup_disconnected: "
+			  "Could not fetch share mode entry for %s\n",
+			  file_id_string(frame, &fid)));
+		goto done;
+	}
+	data = lck->data;
+
+	for (n=0; n < data->num_share_modes; n++) {
+		struct share_mode_entry *entry = &data->share_modes[n];
+
+		if (!server_id_is_disconnected(&entry->pid)) {
+			DEBUG(5, ("share_mode_cleanup_disconnected: "
+				  "file (file-id='%s', servicepath='%s', "
+				  "base_name='%s%s%s') "
+				  "is used by server %s ==> do not cleanup\n",
+				  file_id_string(frame, &fid),
+				  data->servicepath,
+				  data->base_name,
+				  (data->stream_name == NULL)
+				  ? "" : "', stream_name='",
+				  (data->stream_name == NULL)
+				  ? "" : data->stream_name,
+				  server_id_str(frame, &entry->pid)));
+			goto done;
+		}
+		if (open_persistent_id != entry->share_file_id) {
+			DEBUG(5, ("share_mode_cleanup_disconnected: "
+				  "entry for file "
+				  "(file-id='%s', servicepath='%s', "
+				  "base_name='%s%s%s') "
+				  "has share_file_id %llu but expected %llu"
+				  "==> do not cleanup\n",
+				  file_id_string(frame, &fid),
+				  data->servicepath,
+				  data->base_name,
+				  (data->stream_name == NULL)
+				  ? "" : "', stream_name='",
+				  (data->stream_name == NULL)
+				  ? "" : data->stream_name,
+				  (unsigned long long)entry->share_file_id,
+				  (unsigned long long)open_persistent_id));
+			goto done;
+		}
+	}
+
+	ok = brl_cleanup_disconnected(fid, open_persistent_id);
+	if (!ok) {
+		DEBUG(10, ("share_mode_cleanup_disconnected: "
+			   "failed to clean up byte range locks associated "
+			   "with file (file-id='%s', servicepath='%s', "
+			   "base_name='%s%s%s') and open_persistent_id %llu "
+			   "==> do not cleanup\n",
+			   file_id_string(frame, &fid),
+			   data->servicepath,
+			   data->base_name,
+			   (data->stream_name == NULL)
+			   ? "" : "', stream_name='",


-- 
Samba Shared Repository


More information about the samba-cvs mailing list