From ee81a6e7d0263d263f7d4e7bd5bd9c4156cae8cf Mon Sep 17 00:00:00 2001 From: Gregor Beck Date: Wed, 13 Mar 2013 14:47:18 +0100 Subject: [PATCH] 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 Reviewed-by: Michael Adam Reviewed-by: Stefan Metzmacher --- source3/locking/brlock.c | 73 ++++++++++++++++++++++++++++++++++++++++ source3/locking/proto.h | 1 + 2 files changed, 74 insertions(+) diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 9680b8ff8780..865aaca1b4fa 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 @@ -2152,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; npid)) { + 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 c170c733010a..69c78e3233fb 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 */ -- 2.34.1