summaryrefslogtreecommitdiff
path: root/source4/ntvfs/common/opendb_tdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/ntvfs/common/opendb_tdb.c')
-rw-r--r--source4/ntvfs/common/opendb_tdb.c75
1 files changed, 57 insertions, 18 deletions
diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c
index fe5a0a8864..47b35f594c 100644
--- a/source4/ntvfs/common/opendb_tdb.c
+++ b/source4/ntvfs/common/opendb_tdb.c
@@ -376,8 +376,26 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb,
exclusive oplocks afterwards. */
for (i=0;i<file->num_entries;i++) {
if (file->entries[i].oplock_level == OPLOCK_EXCLUSIVE) {
+ bool oplock_return = OPLOCK_BREAK_TO_LEVEL_II;
+ /* if this is an attribute only access
+ * it doesn't conflict with an EXCLUSIVE oplock
+ * but we'll not grant the oplock below
+ */
+ attrs_only = access_attributes_only(access_mask,
+ open_disposition,
+ break_to_none);
+ if (attrs_only) {
+ break;
+ }
+ /*
+ * send an oplock break to the holder of the
+ * oplock and tell caller to retry later
+ */
+ if (break_to_none) {
+ oplock_return = OPLOCK_BREAK_TO_NONE;
+ }
odb_oplock_break_send(odb, &file->entries[i],
- OPLOCK_BREAK_TO_NONE);
+ oplock_return);
return NT_STATUS_OPLOCK_NOT_GRANTED;
}
}
@@ -449,8 +467,8 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck,
e.oplock_level = OPLOCK_EXCLUSIVE;
*oplock_granted = EXCLUSIVE_OPLOCK_RETURN;
} else {
- e.oplock_level = OPLOCK_NONE;
- *oplock_granted = NO_OPLOCK_RETURN;
+ e.oplock_level = OPLOCK_LEVEL_II;
+ *oplock_granted = LEVEL_II_OPLOCK_RETURN;
}
} else if (oplock_level == OPLOCK_BATCH) {
if (file.num_entries == 0) {
@@ -509,10 +527,12 @@ static NTSTATUS odb_tdb_open_file_pending(struct odb_lock *lck, void *private)
/*
remove a opendb entry
*/
-static NTSTATUS odb_tdb_close_file(struct odb_lock *lck, void *file_handle)
+static NTSTATUS odb_tdb_close_file(struct odb_lock *lck, void *file_handle,
+ const char **_delete_path)
{
struct odb_context *odb = lck->odb;
struct opendb_file file;
+ const char *delete_path = NULL;
int i;
NTSTATUS status;
@@ -548,7 +568,16 @@ static NTSTATUS odb_tdb_close_file(struct odb_lock *lck, void *file_handle)
file.num_pending = 0;
file.num_entries--;
-
+
+ if (file.num_entries == 0 && file.delete_on_close) {
+ delete_path = talloc_strdup(lck, file.path);
+ NT_STATUS_HAVE_NO_MEMORY(delete_path);
+ }
+
+ if (_delete_path) {
+ *_delete_path = delete_path;
+ }
+
return odb_push_record(lck, &file);
}
@@ -685,6 +714,25 @@ static NTSTATUS odb_tdb_rename(struct odb_lock *lck, const char *path)
}
/*
+ get the path of an open file
+*/
+static NTSTATUS odb_tdb_get_path(struct odb_lock *lck, const char **path)
+{
+ struct opendb_file file;
+ NTSTATUS status;
+
+ *path = NULL;
+
+ status = odb_pull_record(lck, &file);
+ /* we don't ignore NT_STATUS_OBJECT_NAME_NOT_FOUND here */
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ *path = file.path;
+
+ return NT_STATUS_OK;
+}
+
+/*
update delete on close flag on an open file
*/
static NTSTATUS odb_tdb_set_delete_on_close(struct odb_lock *lck, bool del_on_close)
@@ -705,20 +753,20 @@ static NTSTATUS odb_tdb_set_delete_on_close(struct odb_lock *lck, bool del_on_cl
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,
- int *open_count, char **path)
+ DATA_BLOB *key, bool *del_on_close)
{
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);
- (*del_on_close) = false;
return NT_STATUS_OK;
}
if (!NT_STATUS_IS_OK(status)) {
@@ -727,16 +775,6 @@ static NTSTATUS odb_tdb_get_delete_on_close(struct odb_context *odb,
}
(*del_on_close) = file.delete_on_close;
- if (open_count != NULL) {
- (*open_count) = file.num_entries;
- }
- if (path != NULL) {
- *path = talloc_strdup(odb, file.path);
- NT_STATUS_HAVE_NO_MEMORY(*path);
- if (file.num_entries == 1 && file.entries[0].delete_on_close) {
- (*del_on_close) = true;
- }
- }
talloc_free(lck);
@@ -783,6 +821,7 @@ static const struct opendb_ops opendb_tdb_ops = {
.odb_close_file = odb_tdb_close_file,
.odb_remove_pending = odb_tdb_remove_pending,
.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_can_open = odb_tdb_can_open,