opendb: add odb_break_oplocks() function
authorStefan Metzmacher <metze@samba.org>
Fri, 22 Feb 2008 15:30:13 +0000 (16:30 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 26 Feb 2008 08:29:40 +0000 (09:29 +0100)
This send breaks to none to all level2 holders

metze

source/cluster/ctdb/opendb_ctdb.c
source/ntvfs/common/opendb.c
source/ntvfs/common/opendb.h
source/ntvfs/common/opendb_tdb.c

index 86dc1f50f11c6fd18d8aef6fd247c00a931adafd..915b76042451f28406bc57492e76808bc00871c5 100644 (file)
@@ -464,6 +464,16 @@ static NTSTATUS odb_ctdb_update_oplock(struct odb_lock *lck, void *file_handle,
        return NT_STATUS_FOOBAR;
 }
 
+static NTSTATUS odb_ctdb_break_oplocks(struct odb_lock *lck)
+{
+       /*
+        * as this file will went away and isn't used yet,
+        * copy the implementation from the tdb backend
+        * --metze
+        */
+       return NT_STATUS_FOOBAR;
+}
+
 /*
   remove a pending opendb entry
 */
@@ -642,7 +652,8 @@ static const struct opendb_ops opendb_ctdb_ops = {
        .odb_set_delete_on_close = odb_ctdb_set_delete_on_close,
        .odb_get_delete_on_close = odb_ctdb_get_delete_on_close,
        .odb_can_open            = odb_ctdb_can_open,
-       .odb_update_oplock       = odb_ctdb_update_oplock
+       .odb_update_oplock       = odb_ctdb_update_oplock,
+       .odb_break_oplocks       = odb_ctdb_break_oplocks
 };
 
 
index 4ac10806e13255cf0d45fe1985f8c8fd6155d6d7..3f5d7210bec91ca0b0cd02bf71d16dfe33ea7c0e 100644 (file)
@@ -176,3 +176,8 @@ _PUBLIC_ NTSTATUS odb_update_oplock(struct odb_lock *lck, void *file_handle,
 {
        return ops->odb_update_oplock(lck, file_handle, oplock_level);
 }
+
+_PUBLIC_ NTSTATUS odb_break_oplocks(struct odb_lock *lck)
+{
+       return ops->odb_break_oplocks(lck);
+}
index c34a07d6facf31d1e40114bf59af86ec967aa65d..c46390446cd3e6e0181b5a8de78bc2e6b2c2c1ed 100644 (file)
@@ -43,6 +43,7 @@ struct opendb_ops {
                                 uint32_t access_mask);
        NTSTATUS (*odb_update_oplock)(struct odb_lock *lck, void *file_handle,
                                      uint32_t oplock_level);
+       NTSTATUS (*odb_break_oplocks)(struct odb_lock *lck);
 };
 
 struct opendb_oplock_break {
index 3d4a760e2e4adcb8d8e9aaa35e52d3571f586f07..dd2fb138d65c74940efd125c89ec2484cde2a19b 100644 (file)
@@ -503,6 +503,43 @@ static NTSTATUS odb_tdb_update_oplock(struct odb_lock *lck, void *file_handle,
        return odb_push_record(lck, &file);
 }
 
+/*
+  send oplocks breaks to none to all level2 holders
+*/
+static NTSTATUS odb_tdb_break_oplocks(struct odb_lock *lck)
+{
+       struct odb_context *odb = lck->odb;
+       NTSTATUS status;
+       struct opendb_file file;
+       int i;
+       bool modified = true;
+
+       status = odb_pull_record(lck, &file);
+       if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+               return NT_STATUS_OK;
+       }
+       NT_STATUS_NOT_OK_RETURN(status);
+
+       /* see if anyone has an oplock, which we need to break */
+       for (i=0;i<file.num_entries;i++) {
+               if (file.entries[i].oplock_level == OPLOCK_LEVEL_II) {
+                       /*
+                        * there could be multiple level2 oplocks
+                        * and we just send a break to none to all of them
+                        * without waiting for a release
+                        */
+                       odb_oplock_break_send(odb, &file.entries[i],
+                                             OPLOCK_BREAK_TO_NONE);
+                       file.entries[i].oplock_level = OPLOCK_NONE;
+                       modified = true;
+               }
+       }
+
+       if (modified) {
+               return odb_push_record(lck, &file);
+       }
+       return NT_STATUS_OK;
+}
 
 /*
   remove a pending opendb entry
@@ -682,7 +719,8 @@ static const struct opendb_ops opendb_tdb_ops = {
        .odb_set_delete_on_close = odb_tdb_set_delete_on_close,
        .odb_get_delete_on_close = odb_tdb_get_delete_on_close,
        .odb_can_open            = odb_tdb_can_open,
-       .odb_update_oplock       = odb_tdb_update_oplock
+       .odb_update_oplock       = odb_tdb_update_oplock,
+       .odb_break_oplocks       = odb_tdb_break_oplocks
 };