mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
opendb: add write time handling
metze
This commit is contained in:
parent
fde9880f99
commit
3868d8ce63
@ -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
|
||||
|
@ -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];
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user