s3:locking:brlock: add function brl_cleanup_disconnected()
authorGregor Beck <gbeck@sernet.de>
Wed, 13 Mar 2013 13:47:18 +0000 (14:47 +0100)
committerMichael Adam <obnox@samba.org>
Thu, 18 Apr 2013 11:15:12 +0000 (13:15 +0200)
For a given file, clean up brl entries belonging to a given persistent file id.

Signed-off-by: Gregor Beck <gbeck@sernet.de>
Reviewed-by: Michael Adam <obnox@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
source3/locking/brlock.c
source3/locking/proto.h

index 9680b8ff87805ad39823b86fcbb1c2458b172b03..865aaca1b4fa7ea0b2cfc9516d5eb06fbda73d6f 100644 (file)
@@ -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; 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;
+}
index c170c733010acad31f47b281aba4b1e511ed90c0..69c78e3233fb19c30a59729687fe7cef4fc90ac1 100644 (file)
@@ -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  */