1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

opendb: add write time handling

metze
This commit is contained in:
Stefan Metzmacher 2008-04-15 16:00:42 +02:00
parent fde9880f99
commit 3868d8ce63
7 changed files with 116 additions and 52 deletions

View 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, static NTSTATUS odb_ctdb_open_file(struct odb_lock *lck,
void *file_handle, const char *path, 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) 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); 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 return the current value of the delete_on_close bit, and how many
people still have the file open people still have the file open
*/ */
static NTSTATUS odb_ctdb_get_delete_on_close(struct odb_context *odb, static NTSTATUS odb_ctdb_get_file_infos(struct odb_context *odb, DATA_BLOB *key,
DATA_BLOB *key, bool *del_on_close) bool *del_on_close, NTTIME *write_time)
{ {
NTSTATUS status; /*
struct opendb_file file; * as this file will went away and isn't used yet,
struct odb_lock *lck; * copy the implementation from the tdb backend
* --metze
(*del_on_close) = false; */
return NT_STATUS_FOOBAR;
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;
} }
@ -589,7 +583,8 @@ static const struct opendb_ops opendb_ctdb_ops = {
.odb_rename = odb_ctdb_rename, .odb_rename = odb_ctdb_rename,
.odb_get_path = odb_ctdb_get_path, .odb_get_path = odb_ctdb_get_path,
.odb_set_delete_on_close = odb_ctdb_set_delete_on_close, .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_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 .odb_break_oplocks = odb_ctdb_break_oplocks

View File

@ -35,6 +35,8 @@ interface opendb
typedef [public] struct { typedef [public] struct {
boolean8 delete_on_close; boolean8 delete_on_close;
NTTIME open_write_time;
NTTIME changed_write_time;
utf8string path; utf8string path;
uint32 num_entries; uint32 num_entries;
opendb_entry entries[num_entries]; opendb_entry entries[num_entries];

View 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, NTSTATUS odb_open_file(struct odb_lock *lck,
void *file_handle, const char *path, 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) uint32_t oplock_level, uint32_t *oplock_granted)
{ {
return ops->odb_open_file(lck, file_handle, path, 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); 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 update the write time on an open file
people still have the file open
*/ */
NTSTATUS odb_get_delete_on_close(struct odb_context *odb, NTSTATUS odb_set_write_time(struct odb_lock *lck,
DATA_BLOB *key, bool *del_on_close) 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, determine if a file can be opened with the given share_access,

View File

@ -27,7 +27,8 @@ struct opendb_ops {
DATA_BLOB (*odb_get_key)(TALLOC_CTX *mem_ctx, struct odb_lock *lck); DATA_BLOB (*odb_get_key)(TALLOC_CTX *mem_ctx, struct odb_lock *lck);
NTSTATUS (*odb_open_file)(struct odb_lock *lck, NTSTATUS (*odb_open_file)(struct odb_lock *lck,
void *file_handle, const char *path, 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); uint32_t oplock_level, uint32_t *oplock_granted);
NTSTATUS (*odb_open_file_pending)(struct odb_lock *lck, void *private); NTSTATUS (*odb_open_file_pending)(struct odb_lock *lck, void *private);
NTSTATUS (*odb_close_file)(struct odb_lock *lck, void *file_handle, 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_rename)(struct odb_lock *lck, const char *path);
NTSTATUS (*odb_get_path)(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_set_delete_on_close)(struct odb_lock *lck, bool del_on_close);
NTSTATUS (*odb_get_delete_on_close)(struct odb_context *odb, NTSTATUS (*odb_set_write_time)(struct odb_lock *lck,
DATA_BLOB *key, bool *del_on_close); 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, NTSTATUS (*odb_can_open)(struct odb_lock *lck,
uint32_t stream_id, uint32_t share_access, uint32_t stream_id, uint32_t share_access,
uint32_t access_mask, bool delete_on_close, uint32_t access_mask, bool delete_on_close,

View 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, static NTSTATUS odb_tdb_open_file(struct odb_lock *lck,
void *file_handle, const char *path, 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) uint32_t oplock_level, uint32_t *oplock_granted)
{ {
struct odb_context *odb = lck->odb; 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); 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 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); 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 return the current value of the delete_on_close bit, and how many
people still have the file open people still have the file open
*/ */
static NTSTATUS odb_tdb_get_delete_on_close(struct odb_context *odb, static NTSTATUS odb_tdb_get_file_infos(struct odb_context *odb, DATA_BLOB *key,
DATA_BLOB *key, bool *del_on_close) bool *del_on_close, NTTIME *write_time)
{ {
struct odb_lock *lck; 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); lck = odb_lock(odb, odb, key);
NT_STATUS_HAVE_NO_MEMORY(lck); 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); talloc_free(lck);
@ -852,7 +890,8 @@ static const struct opendb_ops opendb_tdb_ops = {
.odb_rename = odb_tdb_rename, .odb_rename = odb_tdb_rename,
.odb_get_path = odb_tdb_get_path, .odb_get_path = odb_tdb_get_path,
.odb_set_delete_on_close = odb_tdb_set_delete_on_close, .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_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 .odb_break_oplocks = odb_tdb_break_oplocks

View File

@ -280,6 +280,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
f->handle->position = 0; f->handle->position = 0;
f->handle->mode = 0; f->handle->mode = 0;
f->handle->oplock = NULL; f->handle->oplock = NULL;
ZERO_STRUCT(f->handle->write_time);
f->handle->open_completed = false; f->handle->open_completed = false;
if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && 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 */ /* now really mark the file as open */
status = odb_open_file(lck, f->handle, name->full_name, 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)) { if (!NT_STATUS_IS_OK(status)) {
talloc_free(lck); 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, 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)) { if (!NT_STATUS_IS_OK(status)) {
goto cleanup_delete; goto cleanup_delete;
@ -594,8 +597,8 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
DATA_BLOB locking_key; DATA_BLOB locking_key;
status = pvfs_locking_key(parent, req, &locking_key); status = pvfs_locking_key(parent, req, &locking_key);
NT_STATUS_NOT_OK_RETURN(status); NT_STATUS_NOT_OK_RETURN(status);
status = odb_get_delete_on_close(pvfs->odb_context, &locking_key, status = odb_get_file_infos(pvfs->odb_context, &locking_key,
&del_on_close); &del_on_close, NULL);
NT_STATUS_NOT_OK_RETURN(status); NT_STATUS_NOT_OK_RETURN(status);
if (del_on_close) { if (del_on_close) {
return NT_STATUS_DELETE_PENDING; return NT_STATUS_DELETE_PENDING;
@ -730,10 +733,12 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
f->handle->mode = 0; f->handle->mode = 0;
f->handle->oplock = NULL; f->handle->oplock = NULL;
f->handle->have_opendb_entry = true; f->handle->have_opendb_entry = true;
ZERO_STRUCT(f->handle->write_time);
f->handle->open_completed = false; f->handle->open_completed = false;
status = odb_open_file(lck, f->handle, name->full_name, 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); oplock_level, &oplock_granted);
talloc_free(lck); talloc_free(lck);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
@ -1334,6 +1339,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
f->handle->mode = 0; f->handle->mode = 0;
f->handle->oplock = NULL; f->handle->oplock = NULL;
f->handle->have_opendb_entry = false; f->handle->have_opendb_entry = false;
ZERO_STRUCT(f->handle->write_time);
f->handle->open_completed = false; f->handle->open_completed = false;
/* form the lock context used for byte range locking and /* 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 */ /* now really mark the file as open */
status = odb_open_file(lck, f->handle, name->full_name, 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); oplock_level, &oplock_granted);
if (!NT_STATUS_IS_OK(status)) { 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; NTSTATUS status;
bool del_on_close; bool del_on_close;
status = odb_get_delete_on_close(pvfs->odb_context, &h->odb_locking_key, status = odb_get_file_infos(pvfs->odb_context, &h->odb_locking_key,
&del_on_close); &del_on_close, NULL);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
DEBUG(1,("WARNING: unable to determine delete on close status for open file\n")); DEBUG(1,("WARNING: unable to determine delete on close status for open file\n"));
return false; return false;

View File

@ -169,6 +169,14 @@ struct pvfs_file_handle {
/* we need this hook back to our parent for lock destruction */ /* we need this hook back to our parent for lock destruction */
struct pvfs_state *pvfs; 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 */ /* the open went through to completion */
bool open_completed; bool open_completed;
}; };