diff options
-rw-r--r-- | source4/cluster/ctdb/opendb_ctdb.c | 51 | ||||
-rw-r--r-- | source4/librpc/idl/opendb.idl | 2 | ||||
-rw-r--r-- | source4/ntvfs/common/opendb.c | 24 | ||||
-rw-r--r-- | source4/ntvfs/common/opendb.h | 9 | ||||
-rw-r--r-- | source4/ntvfs/common/opendb_tdb.c | 51 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_open.c | 23 | ||||
-rw-r--r-- | source4/ntvfs/posix/vfs_posix.h | 8 |
7 files changed, 116 insertions, 52 deletions
diff --git a/source4/cluster/ctdb/opendb_ctdb.c b/source4/cluster/ctdb/opendb_ctdb.c index ed09cf0bbc..b1faf9e0e6 100644 --- a/source4/cluster/ctdb/opendb_ctdb.c +++ b/source4/cluster/ctdb/opendb_ctdb.c @@ -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 diff --git a/source4/librpc/idl/opendb.idl b/source4/librpc/idl/opendb.idl index 72bf23a9b4..cdbaa6cb1b 100644 --- a/source4/librpc/idl/opendb.idl +++ b/source4/librpc/idl/opendb.idl @@ -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]; diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 2913ea8431..6917bad52a 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -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, diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h index 045476337a..179db111ca 100644 --- a/source4/ntvfs/common/opendb.h +++ b/source4/ntvfs/common/opendb.h @@ -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, diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 99c0a95c20..d7531297ed 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -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 */ @@ -785,20 +790,53 @@ static NTSTATUS odb_tdb_set_delete_on_close(struct odb_lock *lck, bool del_on_cl } /* + 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 diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index dada9f503f..bdb6c9bad0 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -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; diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index c194698b64..875deb4015 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -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; }; |