[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