opendb: add write time handling
authorStefan Metzmacher <metze@samba.org>
Tue, 15 Apr 2008 14:00:42 +0000 (16:00 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 3 Jun 2008 12:03:49 +0000 (14:03 +0200)
metze
(This used to be commit 3868d8ce630c71e2c70aae442fcdbd68ba1eb708)

source4/cluster/ctdb/opendb_ctdb.c
source4/librpc/idl/opendb.idl
source4/ntvfs/common/opendb.c
source4/ntvfs/common/opendb.h
source4/ntvfs/common/opendb_tdb.c
source4/ntvfs/posix/pvfs_open.c
source4/ntvfs/posix/vfs_posix.h

index ed09cf0bbcc9efd0e1a00f58a5c12cc02ae8c126..b1faf9e0e645f5127e14f592a2e28f23d7a4fc73 100644 (file)
@@ -283,7 +283,8 @@ static NTSTATUS odb_oplock_break_send(struct odb_context *odb, struct opendb_ent
 */
 static NTSTATUS odb_ctdb_open_file(struct odb_lock *lck,
                                   void *file_handle, const char *path,
-                                  int *fd, bool allow_level_II_oplock,
+                                  int *fd, NTTIME open_write_time,
+                                  bool allow_level_II_oplock,
                                   uint32_t oplock_level, uint32_t *oplock_granted)
 
 {
@@ -492,37 +493,30 @@ static NTSTATUS odb_ctdb_set_delete_on_close(struct odb_lock *lck, bool del_on_c
        return odb_push_record(lck, &file);
 }
 
+static NTSTATUS odb_ctdb_set_write_time(struct odb_lock *lck,
+                                       NTTIME write_time, bool force)
+{
+       /*
+        * as this file will went away and isn't used yet,
+        * copy the implementation from the tdb backend
+        * --metze
+        */
+       return NT_STATUS_FOOBAR;
+}
+
 /*
   return the current value of the delete_on_close bit, and how many
   people still have the file open
 */
-static NTSTATUS odb_ctdb_get_delete_on_close(struct odb_context *odb, 
-                                           DATA_BLOB *key, bool *del_on_close)
+static NTSTATUS odb_ctdb_get_file_infos(struct odb_context *odb, DATA_BLOB *key,
+                                       bool *del_on_close, NTTIME *write_time)
 {
-       NTSTATUS status;
-       struct opendb_file file;
-       struct odb_lock *lck;
-
-       (*del_on_close) = false;
-
-       lck = odb_lock(odb, odb, key);
-       NT_STATUS_HAVE_NO_MEMORY(lck);
-
-       status = odb_pull_record(lck, &file);
-       if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
-               talloc_free(lck);
-               return NT_STATUS_OK;
-       }
-       if (!NT_STATUS_IS_OK(status)) {
-               talloc_free(lck);
-               return status;
-       }
-
-       (*del_on_close) = file.delete_on_close;
-
-       talloc_free(lck);
-
-       return NT_STATUS_OK;
+       /*
+        * as this file will went away and isn't used yet,
+        * copy the implementation from the tdb backend
+        * --metze
+        */
+       return NT_STATUS_FOOBAR;
 }
 
 
@@ -589,7 +583,8 @@ static const struct opendb_ops opendb_ctdb_ops = {
        .odb_rename              = odb_ctdb_rename,
        .odb_get_path            = odb_ctdb_get_path,
        .odb_set_delete_on_close = odb_ctdb_set_delete_on_close,
-       .odb_get_delete_on_close = odb_ctdb_get_delete_on_close,
+       .odb_set_write_time      = odb_ctdb_set_write_time,
+       .odb_get_file_infos      = odb_ctdb_get_file_infos,
        .odb_can_open            = odb_ctdb_can_open,
        .odb_update_oplock       = odb_ctdb_update_oplock,
        .odb_break_oplocks       = odb_ctdb_break_oplocks
index 72bf23a9b4b143d4a3d12049bc69c7782cf378d1..cdbaa6cb1b51e5d69d2c3525be8814bf7ccfb177 100644 (file)
@@ -35,6 +35,8 @@ interface opendb
 
        typedef [public] struct {
                boolean8 delete_on_close;
+               NTTIME open_write_time;
+               NTTIME changed_write_time;
                utf8string path;
                uint32 num_entries;
                opendb_entry entries[num_entries];
index 2913ea8431c0d9025bc486744d6d081379df3c25..6917bad52ab9bc7ca82f0a68499889445a63f7a8 100644 (file)
@@ -97,11 +97,13 @@ DATA_BLOB odb_get_key(TALLOC_CTX *mem_ctx, struct odb_lock *lck)
 */
 NTSTATUS odb_open_file(struct odb_lock *lck,
                                void *file_handle, const char *path,
-                               int *fd, bool allow_level_II_oplock,
+                               int *fd, NTTIME open_write_time,
+                               bool allow_level_II_oplock,
                                uint32_t oplock_level, uint32_t *oplock_granted)
 {
        return ops->odb_open_file(lck, file_handle, path,
-                                 fd, allow_level_II_oplock,
+                                 fd, open_write_time,
+                                 allow_level_II_oplock,
                                  oplock_level, oplock_granted);
 }
 
@@ -159,15 +161,23 @@ NTSTATUS odb_set_delete_on_close(struct odb_lock *lck, bool del_on_close)
 }
 
 /*
-  return the current value of the delete_on_close bit, and how many
-  people still have the file open
+  update the write time on an open file
 */
-NTSTATUS odb_get_delete_on_close(struct odb_context *odb, 
-                                         DATA_BLOB *key, bool *del_on_close)
+NTSTATUS odb_set_write_time(struct odb_lock *lck,
+                           NTTIME write_time, bool force)
 {
-       return ops->odb_get_delete_on_close(odb, key, del_on_close);
+       return ops->odb_set_write_time(lck, write_time, force);
 }
 
+/*
+  return the current value of the delete_on_close bit,
+  and the current write time.
+*/
+NTSTATUS odb_get_file_infos(struct odb_context *odb, DATA_BLOB *key,
+                           bool *del_on_close, NTTIME *write_time)
+{
+       return ops->odb_get_file_infos(odb, key, del_on_close, write_time);
+}
 
 /*
   determine if a file can be opened with the given share_access,
index 045476337abbb2bfd1acfbbd2825f3dbd6bc0a95..179db111ca06dd6e60190c996b2948a4348469e8 100644 (file)
@@ -27,7 +27,8 @@ struct opendb_ops {
        DATA_BLOB (*odb_get_key)(TALLOC_CTX *mem_ctx, struct odb_lock *lck);
        NTSTATUS (*odb_open_file)(struct odb_lock *lck,
                                  void *file_handle, const char *path,
-                                 int *fd, bool allow_level_II_oplock,
+                                 int *fd, NTTIME open_write_time,
+                                 bool allow_level_II_oplock,
                                  uint32_t oplock_level, uint32_t *oplock_granted);
        NTSTATUS (*odb_open_file_pending)(struct odb_lock *lck, void *private);
        NTSTATUS (*odb_close_file)(struct odb_lock *lck, void *file_handle,
@@ -36,8 +37,10 @@ struct opendb_ops {
        NTSTATUS (*odb_rename)(struct odb_lock *lck, const char *path);
        NTSTATUS (*odb_get_path)(struct odb_lock *lck, const char **path);
        NTSTATUS (*odb_set_delete_on_close)(struct odb_lock *lck, bool del_on_close);
-       NTSTATUS (*odb_get_delete_on_close)(struct odb_context *odb, 
-                                           DATA_BLOB *key, bool *del_on_close);
+       NTSTATUS (*odb_set_write_time)(struct odb_lock *lck,
+                                      NTTIME write_time, bool force);
+       NTSTATUS (*odb_get_file_infos)(struct odb_context *odb, DATA_BLOB *key,
+                                      bool *del_on_close, NTTIME *write_time);
        NTSTATUS (*odb_can_open)(struct odb_lock *lck,
                                 uint32_t stream_id, uint32_t share_access,
                                 uint32_t access_mask, bool delete_on_close,
index 99c0a95c20a4cac21853e6b50cd1a6f9b5e60af7..d7531297eda774e85f5bcda06f200461b2ad221f 100644 (file)
@@ -452,7 +452,8 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb,
 */
 static NTSTATUS odb_tdb_open_file(struct odb_lock *lck,
                                  void *file_handle, const char *path,
-                                 int *fd, bool allow_level_II_oplock,
+                                 int *fd, NTTIME open_write_time,
+                                 bool allow_level_II_oplock,
                                  uint32_t oplock_level, uint32_t *oplock_granted)
 {
        struct odb_context *odb = lck->odb;
@@ -474,6 +475,10 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck,
                NT_STATUS_HAVE_NO_MEMORY(lck->file.path);
        }
 
+       if (lck->file.open_write_time == 0) {
+               lck->file.open_write_time = open_write_time;
+       }
+
        /*
          possibly grant an exclusive, batch or level2 oplock
        */
@@ -784,21 +789,54 @@ static NTSTATUS odb_tdb_set_delete_on_close(struct odb_lock *lck, bool del_on_cl
        return odb_push_record(lck, &lck->file);
 }
 
+/*
+  update the write time on an open file
+*/
+static NTSTATUS odb_tdb_set_write_time(struct odb_lock *lck,
+                                      NTTIME write_time, bool force)
+{
+       if (lck->file.path == NULL) {
+               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       }
+
+       if (lck->file.changed_write_time != 0 && !force) {
+               return NT_STATUS_OK;
+       }
+
+       lck->file.changed_write_time = write_time;
+
+       return odb_push_record(lck, &lck->file);
+}
+
 /*
   return the current value of the delete_on_close bit, and how many
   people still have the file open
 */
-static NTSTATUS odb_tdb_get_delete_on_close(struct odb_context *odb, 
-                                           DATA_BLOB *key, bool *del_on_close)
+static NTSTATUS odb_tdb_get_file_infos(struct odb_context *odb, DATA_BLOB *key,
+                                      bool *del_on_close, NTTIME *write_time)
 {
        struct odb_lock *lck;
 
-       (*del_on_close) = false;
+       if (del_on_close) {
+               *del_on_close = false;
+       }
+       if (write_time) {
+               *write_time = 0;
+       }
 
        lck = odb_lock(odb, odb, key);
        NT_STATUS_HAVE_NO_MEMORY(lck);
 
-       (*del_on_close) = lck->file.delete_on_close;
+       if (del_on_close) {
+               *del_on_close = lck->file.delete_on_close;
+       }
+       if (write_time) {
+               if (lck->file.changed_write_time == 0) {
+                       *write_time = lck->file.open_write_time;
+               } else {
+                       *write_time = lck->file.changed_write_time;
+               }
+       }
 
        talloc_free(lck);
 
@@ -852,7 +890,8 @@ static const struct opendb_ops opendb_tdb_ops = {
        .odb_rename              = odb_tdb_rename,
        .odb_get_path            = odb_tdb_get_path,
        .odb_set_delete_on_close = odb_tdb_set_delete_on_close,
-       .odb_get_delete_on_close = odb_tdb_get_delete_on_close,
+       .odb_set_write_time      = odb_tdb_set_write_time,
+       .odb_get_file_infos      = odb_tdb_get_file_infos,
        .odb_can_open            = odb_tdb_can_open,
        .odb_update_oplock       = odb_tdb_update_oplock,
        .odb_break_oplocks       = odb_tdb_break_oplocks
index dada9f503f5334ce9b2b1e86b34cc2120cbdbd84..bdb6c9bad0b0ccd311ba3e33d40b252cd04de9ed 100644 (file)
@@ -280,6 +280,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
        f->handle->position          = 0;
        f->handle->mode              = 0;
        f->handle->oplock            = NULL;
+       ZERO_STRUCT(f->handle->write_time);
        f->handle->open_completed    = false;
 
        if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) &&
@@ -317,7 +318,8 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
 
                /* now really mark the file as open */
                status = odb_open_file(lck, f->handle, name->full_name,
-                                      NULL, false, OPLOCK_NONE, NULL);
+                                      NULL, name->dos.write_time,
+                                      false, OPLOCK_NONE, NULL);
 
                if (!NT_STATUS_IS_OK(status)) {
                        talloc_free(lck);
@@ -377,7 +379,8 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
                }
 
                status = odb_open_file(lck, f->handle, name->full_name,
-                                      NULL, false, OPLOCK_NONE, NULL);
+                                      NULL, name->dos.write_time,
+                                      false, OPLOCK_NONE, NULL);
 
                if (!NT_STATUS_IS_OK(status)) {
                        goto cleanup_delete;
@@ -594,8 +597,8 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
                DATA_BLOB locking_key;
                status = pvfs_locking_key(parent, req, &locking_key);
                NT_STATUS_NOT_OK_RETURN(status);
-               status = odb_get_delete_on_close(pvfs->odb_context, &locking_key, 
-                                                &del_on_close);
+               status = odb_get_file_infos(pvfs->odb_context, &locking_key,
+                                           &del_on_close, NULL);
                NT_STATUS_NOT_OK_RETURN(status);
                if (del_on_close) {
                        return NT_STATUS_DELETE_PENDING;
@@ -730,10 +733,12 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
        f->handle->mode              = 0;
        f->handle->oplock            = NULL;
        f->handle->have_opendb_entry = true;
+       ZERO_STRUCT(f->handle->write_time);
        f->handle->open_completed    = false;
 
        status = odb_open_file(lck, f->handle, name->full_name,
-                              &f->handle->fd, allow_level_II_oplock,
+                              &f->handle->fd, name->dos.write_time,
+                              allow_level_II_oplock,
                               oplock_level, &oplock_granted);
        talloc_free(lck);
        if (!NT_STATUS_IS_OK(status)) {
@@ -1334,6 +1339,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
        f->handle->mode              = 0;
        f->handle->oplock            = NULL;
        f->handle->have_opendb_entry = false;
+       ZERO_STRUCT(f->handle->write_time);
        f->handle->open_completed    = false;
 
        /* form the lock context used for byte range locking and
@@ -1437,7 +1443,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
 
        /* now really mark the file as open */
        status = odb_open_file(lck, f->handle, name->full_name,
-                              &f->handle->fd, allow_level_II_oplock,
+                              &f->handle->fd, name->dos.write_time,
+                              allow_level_II_oplock,
                               oplock_level, &oplock_granted);
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -1915,8 +1922,8 @@ bool pvfs_delete_on_close_set(struct pvfs_state *pvfs, struct pvfs_file_handle *
        NTSTATUS status;
        bool del_on_close;
 
-       status = odb_get_delete_on_close(pvfs->odb_context, &h->odb_locking_key, 
-                                        &del_on_close);
+       status = odb_get_file_infos(pvfs->odb_context, &h->odb_locking_key, 
+                                   &del_on_close, NULL);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1,("WARNING: unable to determine delete on close status for open file\n"));
                return false;
index c194698b64e23510ee486791702d284500b6520a..875deb40153db278abeff69b50bdfc6b7d8a11dc 100644 (file)
@@ -169,6 +169,14 @@ struct pvfs_file_handle {
        /* we need this hook back to our parent for lock destruction */
        struct pvfs_state *pvfs;
 
+       struct {
+               bool update_triggered;
+               struct timed_event *update_event;
+               bool update_on_close;
+               NTTIME close_time;
+               bool update_forced;
+       } write_time;
+
        /* the open went through to completion */
        bool open_completed;
 };