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:
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,
|
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
|
||||||
|
@ -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];
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user