summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2008-02-26 16:19:57 +1100
committerAndrew Bartlett <abartlet@samba.org>2008-02-26 16:19:57 +1100
commit864328e6563621a0b4df2d49e04ff3b23b68e1ca (patch)
tree01b5af0b454d7235b5118ae53d078429dca26619
parent2c8415f767ca20fe90a97f8623d1617e015f183a (diff)
parent1e5ced379361fbdc0ccc48ad012f388f2e737ca7 (diff)
downloadsamba-864328e6563621a0b4df2d49e04ff3b23b68e1ca.tar.gz
samba-864328e6563621a0b4df2d49e04ff3b23b68e1ca.tar.bz2
samba-864328e6563621a0b4df2d49e04ff3b23b68e1ca.zip
Merge branch 'v4-0-test' of git://git.samba.org/samba into 4-0-local
(This used to be commit 35f7f488d84e3ec3224f3b40ff5881e91c11764d)
-rw-r--r--source4/cluster/ctdb/opendb_ctdb.c27
-rw-r--r--source4/lib/ldb/web/index.html24
-rw-r--r--source4/lib/talloc/web/index.html20
-rw-r--r--source4/lib/tdb/web/index.html14
-rw-r--r--source4/ntvfs/common/opendb.c10
-rw-r--r--source4/ntvfs/common/opendb.h7
-rw-r--r--source4/ntvfs/common/opendb_tdb.c80
-rw-r--r--source4/ntvfs/posix/pvfs_lock.c2
-rw-r--r--source4/ntvfs/posix/pvfs_notify.c8
-rw-r--r--source4/ntvfs/posix/pvfs_open.c46
-rw-r--r--source4/ntvfs/posix/pvfs_rename.c11
-rw-r--r--source4/ntvfs/posix/pvfs_setfileinfo.c4
-rw-r--r--source4/ntvfs/posix/pvfs_unlink.c107
-rw-r--r--source4/ntvfs/posix/pvfs_wait.c37
-rw-r--r--source4/ntvfs/posix/vfs_posix.h2
-rw-r--r--source4/samba4-skip2
-rwxr-xr-xsource4/selftest/samba4_tests.sh5
-rw-r--r--source4/torture/basic/base.c18
-rw-r--r--source4/torture/raw/oplock.c5
19 files changed, 280 insertions, 149 deletions
diff --git a/source4/cluster/ctdb/opendb_ctdb.c b/source4/cluster/ctdb/opendb_ctdb.c
index aaab3aa55d..86dc1f50f1 100644
--- a/source4/cluster/ctdb/opendb_ctdb.c
+++ b/source4/cluster/ctdb/opendb_ctdb.c
@@ -133,6 +133,16 @@ static struct odb_lock *odb_ctdb_lock(TALLOC_CTX *mem_ctx,
return lck;
}
+static DATA_BLOB odb_ctdb_get_key(TALLOC_CTX *mem_ctx, struct odb_lock *lck)
+{
+ /*
+ * as this file will went away and isn't used yet,
+ * copy the implementation from the tdb backend
+ * --metze
+ */
+ return data_blob_const(NULL, 0);
+}
+
/*
determine if two odb_entry structures conflict
@@ -440,6 +450,19 @@ static NTSTATUS odb_ctdb_close_file(struct odb_lock *lck, void *file_handle)
return odb_push_record(lck, &file);
}
+/*
+ update the oplock level of the client
+*/
+static NTSTATUS odb_ctdb_update_oplock(struct odb_lock *lck, void *file_handle,
+ uint32_t oplock_level)
+{
+ /*
+ * as this file will went away and isn't used yet,
+ * copy the implementation from the tdb backend
+ * --metze
+ */
+ return NT_STATUS_FOOBAR;
+}
/*
remove a pending opendb entry
@@ -610,6 +633,7 @@ static NTSTATUS odb_ctdb_can_open(struct odb_lock *lck,
static const struct opendb_ops opendb_ctdb_ops = {
.odb_init = odb_ctdb_init,
.odb_lock = odb_ctdb_lock,
+ .odb_get_key = odb_ctdb_get_key,
.odb_open_file = odb_ctdb_open_file,
.odb_open_file_pending = odb_ctdb_open_file_pending,
.odb_close_file = odb_ctdb_close_file,
@@ -617,7 +641,8 @@ static const struct opendb_ops opendb_ctdb_ops = {
.odb_rename = odb_ctdb_rename,
.odb_set_delete_on_close = odb_ctdb_set_delete_on_close,
.odb_get_delete_on_close = odb_ctdb_get_delete_on_close,
- .odb_can_open = odb_ctdb_can_open
+ .odb_can_open = odb_ctdb_can_open,
+ .odb_update_oplock = odb_ctdb_update_oplock
};
diff --git a/source4/lib/ldb/web/index.html b/source4/lib/ldb/web/index.html
index 76dbbdeafb..26dd344527 100644
--- a/source4/lib/ldb/web/index.html
+++ b/source4/lib/ldb/web/index.html
@@ -42,9 +42,9 @@ The main features that separate ldb from other solutions are:
Currently ldb is completely lacking in programmer or user
documentation. This is your opportunity to make a contribution! Start
with the public functions declared in <a
-href="http://samba.org/ftp/unpacked/samba4/source/lib/ldb/include/ldb.h">ldb.h</a>
+href="http://samba.org/ftp/unpacked/ldb/include/ldb.h">ldb.h</a>
and the example code in the <a
-href="http://samba.org/ftp/unpacked/samba4/source/lib/ldb/tools/">tools
+href="http://samba.org/ftp/unpacked/ldb/tools/">tools
directory</a>. Documentation in the same docbook format used by Samba
would be preferred.
@@ -53,21 +53,17 @@ would be preferred.
ldb does not currently have its own mailing list or bug tracking
system. For now, please use the <a
href="https://lists.samba.org/mailman/listinfo/samba-technical">samba-technical</a>
-mailing list, and the <a href="http://bugzilla.samba.org/">Samba
-bugzilla</a> bug tracking system.
+mailing list or the <a href="https://lists.samba.org/mailman/listinfo/ldb">ldb</a>
+mailing list, and the <a href="http://bugzilla.samba.org/">Samba bugzilla</a> bug tracking system.
<h2>Download</h2>
-You can download the latest release either via rsync or anonymous
-svn. To fetch via svn use the following commands:
-
-<pre>
- svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/ldb ldb
- svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/tdb tdb
- svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/talloc talloc
- svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/replace libreplace
-</pre>
-
+You can download the latest release either via rsync or thtough git.<br>
+<br>
+To fetch via git see the following guide:<br>
+<a href="http://wiki.samba.org/index.php/Using_Git_for_Samba_Development">Using Git for Samba Development</a><br>
+Once you have cloned the tree switch to the v4-0-test branch and cd into the source/lib/ldb directory.<br>
+<br>
To fetch via rsync use these commands:
<pre>
diff --git a/source4/lib/talloc/web/index.html b/source4/lib/talloc/web/index.html
index 628030ad4c..5deab93665 100644
--- a/source4/lib/talloc/web/index.html
+++ b/source4/lib/talloc/web/index.html
@@ -12,7 +12,7 @@ destructors. It is the core memory allocator used in Samba4, and has
made a huge difference in many aspects of Samba4 development.<p>
To get started with talloc, I would recommend you read the <a
-href="http://samba.org/ftp/unpacked/samba_4_0_test/source/lib/talloc/talloc_guide.txt">talloc guide</a>.
+href="http://samba.org/ftp/unpacked/talloc/talloc_guide.txt">talloc guide</a>.
<h2>Discussion and bug reports</h2>
@@ -24,20 +24,16 @@ bugzilla</a> bug tracking system.
<h2>Download</h2>
-You can download the latest release either via rsync or git.
-To fetch via git use the following command:
-
-<pre>
- git-clone git://git.samba.org/samba.git samba
- cd samba
- git checkout -b samba4 origin/v4-0-test
-</pre>
-
+You can download the latest release either via rsync or git.<br>
+<br>
+To fetch via git see the following guide:<br>
+<a href="http://wiki.samba.org/index.php/Using_Git_for_Samba_Development">Using Git for Samba Development</a><br>
+Once you have cloned the tree switch to the v4-0-test branch and cd into the source/lib/talloc directory.<br>
+<br>
To fetch via rsync use this command:
<pre>
- rsync -Pavz samba.org::ftp/unpacked/samba_4_0_test/source/lib/talloc .
- rsync -Pavz samba.org::ftp/unpacked/samba_4_0_test/source/lib/libreplace .
+ rsync -Pavz samba.org::ftp/unpacked/talloc .
</pre>
<hr>
diff --git a/source4/lib/tdb/web/index.html b/source4/lib/tdb/web/index.html
index 979665ae76..a53da6b8f7 100644
--- a/source4/lib/tdb/web/index.html
+++ b/source4/lib/tdb/web/index.html
@@ -22,14 +22,12 @@ bugzilla</a> bug tracking system.
<h2>Download</h2>
-You can download the latest release either via rsync or anonymous
-svn. To fetch via svn use the following commands:
-
-<pre>
- svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/tdb tdb
- svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/replace libreplace
-</pre>
-
+You can download the latest release either via rsync or git.<br>
+<br>
+To fetch via git see the following guide:<br>
+<a href="http://wiki.samba.org/index.php/Using_Git_for_Samba_Development">Using Git for Samba Development</a><br>
+Once you have cloned the tree switch to the v4-0-test branch and cd into the source/lib/tdb directory.<br>
+<br>
To fetch via rsync use these commands:
<pre>
diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c
index 4826ca5c26..4ac10806e1 100644
--- a/source4/ntvfs/common/opendb.c
+++ b/source4/ntvfs/common/opendb.c
@@ -81,6 +81,10 @@ _PUBLIC_ struct odb_lock *odb_lock(TALLOC_CTX *mem_ctx,
return ops->odb_lock(mem_ctx, odb, file_key);
}
+_PUBLIC_ DATA_BLOB odb_get_key(TALLOC_CTX *mem_ctx, struct odb_lock *lck)
+{
+ return ops->odb_get_key(mem_ctx, lck);
+}
/*
register an open file in the open files database. This implements the share_access
@@ -166,3 +170,9 @@ _PUBLIC_ NTSTATUS odb_can_open(struct odb_lock *lck,
{
return ops->odb_can_open(lck, share_access, create_options, access_mask);
}
+
+_PUBLIC_ NTSTATUS odb_update_oplock(struct odb_lock *lck, void *file_handle,
+ uint32_t oplock_level)
+{
+ return ops->odb_update_oplock(lck, file_handle, oplock_level);
+}
diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h
index 231ae3d7de..c34a07d6fa 100644
--- a/source4/ntvfs/common/opendb.h
+++ b/source4/ntvfs/common/opendb.h
@@ -24,6 +24,7 @@ struct opendb_ops {
struct ntvfs_context *ntvfs_ctx);
struct odb_lock *(*odb_lock)(TALLOC_CTX *mem_ctx,
struct odb_context *odb, DATA_BLOB *file_key);
+ DATA_BLOB (*odb_get_key)(TALLOC_CTX *mem_ctx, struct odb_lock *lck);
NTSTATUS (*odb_open_file)(struct odb_lock *lck, void *file_handle,
uint32_t stream_id, uint32_t share_access,
uint32_t access_mask, bool delete_on_close,
@@ -40,8 +41,14 @@ struct opendb_ops {
NTSTATUS (*odb_can_open)(struct odb_lock *lck,
uint32_t share_access, uint32_t create_options,
uint32_t access_mask);
+ NTSTATUS (*odb_update_oplock)(struct odb_lock *lck, void *file_handle,
+ uint32_t oplock_level);
};
+struct opendb_oplock_break {
+ void *file_handle;
+ uint8_t level;
+};
void odb_set_ops(const struct opendb_ops *new_ops);
void odb_tdb_init_ops(void);
diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c
index abd9ca708b..3d4a760e2e 100644
--- a/source4/ntvfs/common/opendb_tdb.c
+++ b/source4/ntvfs/common/opendb_tdb.c
@@ -2,7 +2,8 @@
Unix SMB/CIFS implementation.
Copyright (C) Andrew Tridgell 2004
-
+ Copyright (C) Stefan Metzmacher 2008
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
@@ -134,6 +135,12 @@ static struct odb_lock *odb_tdb_lock(TALLOC_CTX *mem_ctx,
return lck;
}
+static DATA_BLOB odb_tdb_get_key(TALLOC_CTX *mem_ctx, struct odb_lock *lck)
+{
+ return data_blob_talloc(mem_ctx, lck->key.dptr, lck->key.dsize);
+}
+
+
/*
determine if two odb_entry structures conflict
@@ -253,12 +260,28 @@ static NTSTATUS odb_push_record(struct odb_lock *lck, struct opendb_file *file)
/*
send an oplock break to a client
*/
-static NTSTATUS odb_oplock_break_send(struct odb_context *odb, struct opendb_entry *e)
+static NTSTATUS odb_oplock_break_send(struct odb_context *odb,
+ struct opendb_entry *e,
+ uint8_t level)
{
+ NTSTATUS status;
+ struct opendb_oplock_break op_break;
+ DATA_BLOB blob;
+
+ ZERO_STRUCT(op_break);
+
/* tell the server handling this open file about the need to send the client
a break */
- return messaging_send_ptr(odb->ntvfs_ctx->msg_ctx, e->server,
- MSG_NTVFS_OPLOCK_BREAK, e->file_handle);
+ op_break.file_handle = e->file_handle;
+ op_break.level = level;
+
+ blob = data_blob_const(&op_break, sizeof(op_break));
+
+ status = messaging_send(odb->ntvfs_ctx->msg_ctx, e->server,
+ MSG_NTVFS_OPLOCK_BREAK, &blob);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ return NT_STATUS_OK;
}
/*
@@ -312,7 +335,8 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle,
break request and suspending this call
until the break is acknowledged or the file
is closed */
- odb_oplock_break_send(odb, &file.entries[i]);
+ odb_oplock_break_send(odb, &file.entries[i],
+ OPLOCK_BREAK_TO_LEVEL_II/*TODO*/);
return NT_STATUS_OPLOCK_NOT_GRANTED;
}
}
@@ -336,7 +360,8 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle,
exclusive oplocks afterwards. */
for (i=0;i<file.num_entries;i++) {
if (file.entries[i].oplock_level == OPLOCK_EXCLUSIVE) {
- odb_oplock_break_send(odb, &file.entries[i]);
+ odb_oplock_break_send(odb, &file.entries[i],
+ OPLOCK_BREAK_TO_NONE/*TODO*/);
return NT_STATUS_OPLOCK_NOT_GRANTED;
}
}
@@ -439,6 +464,45 @@ static NTSTATUS odb_tdb_close_file(struct odb_lock *lck, void *file_handle)
return odb_push_record(lck, &file);
}
+/*
+ update the oplock level of the client
+*/
+static NTSTATUS odb_tdb_update_oplock(struct odb_lock *lck, void *file_handle,
+ uint32_t oplock_level)
+{
+ struct odb_context *odb = lck->odb;
+ struct opendb_file file;
+ int i;
+ NTSTATUS status;
+
+ status = odb_pull_record(lck, &file);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ /* find the entry, and update it */
+ for (i=0;i<file.num_entries;i++) {
+ if (file_handle == file.entries[i].file_handle &&
+ cluster_id_equal(&odb->ntvfs_ctx->server_id, &file.entries[i].server)) {
+ file.entries[i].oplock_level = oplock_level;
+ break;
+ }
+ }
+
+ if (i == file.num_entries) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* send any pending notifications, removing them once sent */
+ for (i=0;i<file.num_pending;i++) {
+ messaging_send_ptr(odb->ntvfs_ctx->msg_ctx,
+ file.pending[i].server,
+ MSG_PVFS_RETRY_OPEN,
+ file.pending[i].notify_ptr);
+ }
+ file.num_pending = 0;
+
+ return odb_push_record(lck, &file);
+}
+
/*
remove a pending opendb entry
@@ -609,6 +673,7 @@ static NTSTATUS odb_tdb_can_open(struct odb_lock *lck,
static const struct opendb_ops opendb_tdb_ops = {
.odb_init = odb_tdb_init,
.odb_lock = odb_tdb_lock,
+ .odb_get_key = odb_tdb_get_key,
.odb_open_file = odb_tdb_open_file,
.odb_open_file_pending = odb_tdb_open_file_pending,
.odb_close_file = odb_tdb_close_file,
@@ -616,7 +681,8 @@ static const struct opendb_ops opendb_tdb_ops = {
.odb_rename = odb_tdb_rename,
.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
+ .odb_can_open = odb_tdb_can_open,
+ .odb_update_oplock = odb_tdb_update_oplock
};
diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c
index b9bb58c71d..df85b2b775 100644
--- a/source4/ntvfs/posix/pvfs_lock.c
+++ b/source4/ntvfs/posix/pvfs_lock.c
@@ -53,7 +53,7 @@ struct pvfs_pending_lock {
struct pvfs_file *f;
struct ntvfs_request *req;
int pending_lock;
- void *wait_handle;
+ struct pvfs_wait *wait_handle;
struct timeval end_time;
};
diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c
index 210f949395..06d2bc8e0c 100644
--- a/source4/ntvfs/posix/pvfs_notify.c
+++ b/source4/ntvfs/posix/pvfs_notify.c
@@ -268,9 +268,11 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs,
/* if the buffer is empty then start waiting */
if (f->notify_buffer->num_changes == 0) {
- void *wait_handle =
- pvfs_wait_message(pvfs, req, -1, timeval_zero(),
- pvfs_notify_end, f->notify_buffer);
+ struct pvfs_wait *wait_handle;
+ wait_handle = pvfs_wait_message(pvfs, req, -1,
+ timeval_zero(),
+ pvfs_notify_end,
+ f->notify_buffer);
NT_STATUS_HAVE_NO_MEMORY(wait_handle);
talloc_steal(req, wait_handle);
return NT_STATUS_OK;
diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index 8558f0476a..3a8b17ab16 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -756,7 +756,7 @@ struct pvfs_open_retry {
struct ntvfs_module_context *ntvfs;
struct ntvfs_request *req;
union smb_open *io;
- void *wait_handle;
+ struct pvfs_wait *wait_handle;
DATA_BLOB odb_locking_key;
};
@@ -1447,10 +1447,24 @@ NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs,
status = pvfs_access_check_simple(pvfs, req, name, SEC_STD_DELETE);
}
- if (!NT_STATUS_IS_OK(status)) {
+ /*
+ * if it's a sharing violation or we got no oplock
+ * only keep the lock if the caller requested access
+ * to the lock
+ */
+ if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||
+ NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
+ if (lckp) {
+ *lckp = lck;
+ } else {
+ talloc_free(lck);
+ }
+ } else if (!NT_STATUS_IS_OK(status)) {
talloc_free(lck);
- *lckp = lck;
- } else if (lckp != NULL) {
+ if (lckp) {
+ *lckp = NULL;
+ }
+ } else if (lckp) {
*lckp = lck;
}
@@ -1487,10 +1501,24 @@ NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs,
0,
SEC_STD_DELETE);
- if (!NT_STATUS_IS_OK(status)) {
+ /*
+ * if it's a sharing violation or we got no oplock
+ * only keep the lock if the caller requested access
+ * to the lock
+ */
+ if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||
+ NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
+ if (lckp) {
+ *lckp = lck;
+ } else {
+ talloc_free(lck);
+ }
+ } else if (!NT_STATUS_IS_OK(status)) {
talloc_free(lck);
- *lckp = lck;
- } else if (lckp != NULL) {
+ if (lckp) {
+ *lckp = NULL;
+ }
+ } else if (lckp) {
*lckp = lck;
}
@@ -1525,6 +1553,10 @@ NTSTATUS pvfs_can_stat(struct pvfs_state *pvfs,
NTCREATEX_SHARE_ACCESS_WRITE,
0, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(lck);
+ }
+
return status;
}
diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c
index ea12f49333..5693e79314 100644
--- a/source4/ntvfs/posix/pvfs_rename.c
+++ b/source4/ntvfs/posix/pvfs_rename.c
@@ -192,8 +192,8 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs,
{
struct pvfs_filename *name1, *name2;
TALLOC_CTX *mem_ctx = talloc_new(req);
+ struct odb_lock *lck = NULL;
NTSTATUS status;
- struct odb_lock *lck, *lck2;
/* resolve the wildcard pattern for this name */
fname2 = pvfs_resolve_wildcard(mem_ctx, fname1, fname2);
@@ -216,6 +216,7 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs,
status = pvfs_can_rename(pvfs, req, name1, &lck);
if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(lck);
goto failed;
}
@@ -223,7 +224,7 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs,
status = pvfs_resolve_partial(pvfs, mem_ctx,
dir_path, fname2, &name2);
if (NT_STATUS_IS_OK(status)) {
- status = pvfs_can_delete(pvfs, req, name2, &lck2);
+ status = pvfs_can_delete(pvfs, req, name2, NULL);
if (!NT_STATUS_IS_OK(status)) {
goto failed;
}
@@ -311,7 +312,7 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs,
struct pvfs_state *pvfs = ntvfs->private_data;
NTSTATUS status;
struct pvfs_filename *name1, *name2;
- struct odb_lock *lck;
+ struct odb_lock *lck = NULL;
/* resolve the cifs name to a posix name */
status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern1,
@@ -354,6 +355,7 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs,
status = pvfs_can_rename(pvfs, req, name1, &lck);
if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(lck);
return status;
}
@@ -375,7 +377,6 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs,
struct pvfs_state *pvfs = ntvfs->private_data;
NTSTATUS status;
struct pvfs_filename *name1, *name2;
- struct odb_lock *lck;
switch (ren->ntrename.in.flags) {
case RENAME_FLAG_RENAME:
@@ -421,7 +422,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs,
return status;
}
- status = pvfs_can_rename(pvfs, req, name1, &lck);
+ status = pvfs_can_rename(pvfs, req, name1, NULL);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c
index 9c78699edb..fbbb8c2d4b 100644
--- a/source4/ntvfs/posix/pvfs_setfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_setfileinfo.c
@@ -142,8 +142,6 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs,
/* if the destination exists, then check the rename is allowed */
if (name2->exists) {
- struct odb_lock *lck;
-
if (strcmp(name2->full_name, name->full_name) == 0) {
/* rename to same name is null-op */
return NT_STATUS_OK;
@@ -153,7 +151,7 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs,
return NT_STATUS_OBJECT_NAME_COLLISION;
}
- status = pvfs_can_delete(pvfs, req, name2, &lck);
+ status = pvfs_can_delete(pvfs, req, name2, NULL);
if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
return NT_STATUS_ACCESS_DENIED;
}
diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c
index ef56d99fb5..bda4014bee 100644
--- a/source4/ntvfs/posix/pvfs_unlink.c
+++ b/source4/ntvfs/posix/pvfs_unlink.c
@@ -25,94 +25,70 @@
/*
- unlink a stream
- */
-static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs,
- struct ntvfs_request *req,
- struct pvfs_filename *name,
- uint16_t attrib)
+ unlink a file
+*/
+static NTSTATUS pvfs_unlink_file(struct pvfs_state *pvfs,
+ struct pvfs_filename *name)
{
NTSTATUS status;
- struct odb_lock *lck;
- if (!name->stream_exists) {
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) {
+ return NT_STATUS_FILE_IS_A_DIRECTORY;
}
- /* make sure its matches the given attributes */
- status = pvfs_match_attrib(pvfs, name, attrib, 0);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ if (name->st.st_nlink == 1) {
+ status = pvfs_xattr_unlink_hook(pvfs, name->full_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
}
- status = pvfs_can_delete(pvfs, req, name, &lck);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ /* finally try the actual unlink */
+ if (unlink(name->full_name) == -1) {
+ status = pvfs_map_errno(pvfs, errno);
}
- return pvfs_stream_delete(pvfs, name, -1);
-}
+ if (NT_STATUS_IS_OK(status)) {
+ notify_trigger(pvfs->notify_context,
+ NOTIFY_ACTION_REMOVED,
+ FILE_NOTIFY_CHANGE_FILE_NAME,
+ name->full_name);
+ }
+ return status;
+}
/*
unlink one file
*/
-static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs,
+static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs,
struct ntvfs_request *req,
- const char *unix_path,
- const char *fname, uint32_t attrib)
+ union smb_unlink *unl,
+ struct pvfs_filename *name)
{
- struct pvfs_filename *name;
NTSTATUS status;
- struct odb_lock *lck;
-
- /* get a pvfs_filename object */
- status = pvfs_resolve_partial(pvfs, req,
- unix_path, fname, &name);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
/* make sure its matches the given attributes */
- status = pvfs_match_attrib(pvfs, name, attrib, 0);
+ status = pvfs_match_attrib(pvfs, name,
+ unl->unlink.in.attrib, 0);
if (!NT_STATUS_IS_OK(status)) {
- talloc_free(name);
return status;
}
- status = pvfs_can_delete(pvfs, req, name, &lck);
+ status = pvfs_can_delete(pvfs, req, name, NULL);
if (!NT_STATUS_IS_OK(status)) {
- talloc_free(name);
return status;
}
- if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) {
- talloc_free(name);
- return NT_STATUS_FILE_IS_A_DIRECTORY;
- }
-
- if (name->st.st_nlink == 1) {
- status = pvfs_xattr_unlink_hook(pvfs, name->full_name);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ if (name->stream_name) {
+ if (!name->stream_exists) {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
- }
-
- /* finally try the actual unlink */
- if (unlink(name->full_name) == -1) {
- status = pvfs_map_errno(pvfs, errno);
- }
- if (NT_STATUS_IS_OK(status)) {
- notify_trigger(pvfs->notify_context,
- NOTIFY_ACTION_REMOVED,
- FILE_NOTIFY_CHANGE_FILE_NAME,
- name->full_name);
+ return pvfs_stream_delete(pvfs, name, -1);
}
- talloc_free(name);
-
- return status;
+ return pvfs_unlink_file(pvfs, name);
}
/*
@@ -147,8 +123,8 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs,
return NT_STATUS_FILE_IS_A_DIRECTORY;
}
- if (name->stream_name) {
- return pvfs_unlink_stream(pvfs, req, name, unl->unlink.in.attrib);
+ if (!name->has_wildcard) {
+ return pvfs_unlink_one(pvfs, req, unl, name);
}
/* get list of matching files */
@@ -158,6 +134,7 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs,
}
status = NT_STATUS_NO_SUCH_FILE;
+ talloc_free(name);
ofs = 0;
@@ -168,10 +145,20 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs,
return NT_STATUS_OBJECT_NAME_INVALID;
}
- status = pvfs_unlink_one(pvfs, req, pvfs_list_unix_path(dir), fname, unl->unlink.in.attrib);
+ /* get a pvfs_filename object */
+ status = pvfs_resolve_partial(pvfs, req,
+ pvfs_list_unix_path(dir),
+ fname, &name);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = pvfs_unlink_one(pvfs, req, unl, name);
if (NT_STATUS_IS_OK(status)) {
total_deleted++;
}
+
+ talloc_free(name);
}
if (total_deleted > 0) {
diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c
index 989985a033..291250befd 100644
--- a/source4/ntvfs/posix/pvfs_wait.c
+++ b/source4/ntvfs/posix/pvfs_wait.c
@@ -31,7 +31,7 @@ struct pvfs_wait {
struct pvfs_wait *next, *prev;
struct pvfs_state *pvfs;
void (*handler)(void *, enum pvfs_wait_notice);
- void *private;
+ void *private_data;
int msg_type;
struct messaging_context *msg_ctx;
struct event_context *ev;
@@ -45,20 +45,23 @@ struct pvfs_wait {
previous ntvfs handlers in the chain (such as security context)
*/
NTSTATUS pvfs_async_setup(struct ntvfs_module_context *ntvfs,
- struct ntvfs_request *req, void *private)
+ struct ntvfs_request *req, void *private_data)
{
- struct pvfs_wait *pwait = private;
- pwait->handler(pwait->private, pwait->reason);
+ struct pvfs_wait *pwait = talloc_get_type(private_data,
+ struct pvfs_wait);
+ pwait->handler(pwait->private_data, pwait->reason);
return NT_STATUS_OK;
}
/*
receive a completion message for a wait
*/
-static void pvfs_wait_dispatch(struct messaging_context *msg, void *private, uint32_t msg_type,
+static void pvfs_wait_dispatch(struct messaging_context *msg,
+ void *private_data, uint32_t msg_type,
struct server_id src, DATA_BLOB *data)
{
- struct pvfs_wait *pwait = private;
+ struct pvfs_wait *pwait = talloc_get_type(private_data,
+ struct pvfs_wait);
struct ntvfs_request *req;
void *p = NULL;
@@ -70,7 +73,7 @@ static void pvfs_wait_dispatch(struct messaging_context *msg, void *private, uin
pp = (void **)data->data;
p = *pp;
}
- if (p == NULL || p != pwait->private) {
+ if (p == NULL || p != pwait->private_data) {
return;
}
@@ -91,9 +94,11 @@ static void pvfs_wait_dispatch(struct messaging_context *msg, void *private, uin
receive a timeout on a message wait
*/
static void pvfs_wait_timeout(struct event_context *ev,
- struct timed_event *te, struct timeval t, void *private)
+ struct timed_event *te, struct timeval t,
+ void *private_data)
{
- struct pvfs_wait *pwait = talloc_get_type(private, struct pvfs_wait);
+ struct pvfs_wait *pwait = talloc_get_type(private_data,
+ struct pvfs_wait);
struct ntvfs_request *req = pwait->req;
pwait->reason = PVFS_WAIT_TIMEOUT;
@@ -126,12 +131,12 @@ static int pvfs_wait_destructor(struct pvfs_wait *pwait)
if msg_type == -1 then no message is registered, and it is assumed
that the caller handles any messaging setup needed
*/
-void *pvfs_wait_message(struct pvfs_state *pvfs,
- struct ntvfs_request *req,
- int msg_type,
- struct timeval end_time,
- void (*fn)(void *, enum pvfs_wait_notice),
- void *private)
+struct pvfs_wait *pvfs_wait_message(struct pvfs_state *pvfs,
+ struct ntvfs_request *req,
+ int msg_type,
+ struct timeval end_time,
+ void (*fn)(void *, enum pvfs_wait_notice),
+ void *private_data)
{
struct pvfs_wait *pwait;
@@ -140,7 +145,7 @@ void *pvfs_wait_message(struct pvfs_state *pvfs,
return NULL;
}
- pwait->private = private;
+ pwait->private_data = private_data;
pwait->handler = fn;
pwait->msg_ctx = pvfs->ntvfs->ctx->msg_ctx;
pwait->ev = pvfs->ntvfs->ctx->event_ctx;
diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h
index a660da329a..84c456dcfe 100644
--- a/source4/ntvfs/posix/vfs_posix.h
+++ b/source4/ntvfs/posix/vfs_posix.h
@@ -28,6 +28,8 @@
#include "ntvfs/common/ntvfs_common.h"
#include "dsdb/samdb/samdb.h"
+struct pvfs_wait;
+
/* this is the private structure for the posix vfs backend. It is used
to hold per-connection (per tree connect) state information */
struct pvfs_state {
diff --git a/source4/samba4-skip b/source4/samba4-skip
index e3d2b182d1..541738ecc4 100644
--- a/source4/samba4-skip
+++ b/source4/samba4-skip
@@ -1,4 +1,3 @@
-base.defer_open
base.delaywrite
raw.composite
raw.oplock
@@ -18,7 +17,6 @@ base.smb
smb2.notify
smb2.scan
ntvfs.cifs.base.charset
-ntvfs.cifs.base.defer_open
ntvfs.cifs.base.delaywrite
ntvfs.cifs.base.iometer
ntvfs.cifs.base.casetable
diff --git a/source4/selftest/samba4_tests.sh b/source4/selftest/samba4_tests.sh
index c57ec4d6bd..32386e5b9e 100755
--- a/source4/selftest/samba4_tests.sh
+++ b/source4/selftest/samba4_tests.sh
@@ -216,12 +216,13 @@ done
plantest "rpc.echo on ncacn_np over smb2" dc $smb4torture ncacn_np:"\$SERVER[smb2]" -U"\$USERNAME"%"\$PASSWORD" -W \$DOMAIN RPC-ECHO "$*"
# Tests against the NTVFS POSIX backend
+NTVFSARGS="--option=torture:sharedelay=100000"
smb2=`$smb4torture --list | grep "^SMB2-" | xargs`
raw=`$smb4torture --list | grep "^RAW-" | xargs`
base=`$smb4torture --list | grep "^BASE-" | xargs`
for t in $base $raw $smb2; do
- plansmbtorturetest "$t" dc $ADDARGS //\$SERVER/tmp -U"\$USERNAME"%"\$PASSWORD"
+ plansmbtorturetest "$t" dc $ADDARGS //\$SERVER/tmp -U"\$USERNAME"%"\$PASSWORD" $NTVFSARGS
done
rap=`$smb4torture --list | grep "^RAP-" | xargs`
@@ -231,7 +232,7 @@ done
# Tests against the NTVFS CIFS backend
for t in $base $raw; do
- plantest "ntvfs.cifs.`normalize_testname $t`" dc $VALGRIND $smb4torture //\$NETBIOSNAME/cifs -U"\$USERNAME"%"\$PASSWORD" $t
+ plantest "ntvfs.cifs.`normalize_testname $t`" dc $VALGRIND $smb4torture //\$NETBIOSNAME/cifs -U"\$USERNAME"%"\$PASSWORD" $NTVFSARGS $t
done
# Local tests
diff --git a/source4/torture/basic/base.c b/source4/torture/basic/base.c
index aa729ec0df..42d7ddaaa1 100644
--- a/source4/torture/basic/base.c
+++ b/source4/torture/basic/base.c
@@ -633,6 +633,13 @@ static bool run_deferopen(struct torture_context *tctx, struct smbcli_state *cli
int retries=4;
int i = 0;
bool correct = true;
+ int nsec;
+ int msec;
+ double sec;
+
+ nsec = torture_setting_int(tctx, "sharedelay", 1000000);
+ msec = nsec / 1000;
+ sec = ((double)nsec) / ((double) 1000000);
if (retries <= 0) {
torture_comment(tctx, "failed to connect\n");
@@ -657,9 +664,10 @@ static bool run_deferopen(struct torture_context *tctx, struct smbcli_state *cli
}
if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
double e = timeval_elapsed(&tv);
- if (e < 0.5 || e > 1.5) {
- torture_comment(tctx,"Timing incorrect %.2f violation\n",
- e);
+ if (e < (0.5 * sec) || e > (1.5 * sec)) {
+ torture_comment(tctx,"Timing incorrect %.2f violation 1 sec == %.2f\n",
+ e, sec);
+ return false;
}
}
} while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
@@ -671,13 +679,13 @@ static bool run_deferopen(struct torture_context *tctx, struct smbcli_state *cli
torture_comment(tctx, "pid %u open %d\n", (unsigned)getpid(), i);
- sleep(10);
+ msleep(10 * msec);
i++;
if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
torture_comment(tctx,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
return false;
}
- sleep(2);
+ msleep(2 * msec);
}
if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
diff --git a/source4/torture/raw/oplock.c b/source4/torture/raw/oplock.c
index 952088e46c..3edd0c6820 100644
--- a/source4/torture/raw/oplock.c
+++ b/source4/torture/raw/oplock.c
@@ -914,7 +914,7 @@ static bool test_raw_oplock_batch10(struct torture_context *tctx, struct smbcli_
CHECK_VAL(break_info.failures, 0);
CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
- smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli1->tree);
+ smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli2->tree);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
@@ -1058,7 +1058,7 @@ static bool test_raw_oplock_batch12(struct torture_context *tctx, struct smbcli_
bool ret = true;
union smb_open io;
union smb_setfileinfo sfi;
- uint16_t fnum=0, fnum2=0;
+ uint16_t fnum=0;
if (!torture_setup_dir(cli1, BASEDIR)) {
return false;
@@ -1118,7 +1118,6 @@ static bool test_raw_oplock_batch12(struct torture_context *tctx, struct smbcli_
CHECK_VAL(break_info.level, 0);
smbcli_close(cli1->tree, fnum);
- smbcli_close(cli2->tree, fnum2);
done:
smb_raw_exit(cli1->session);