From 840933cd4eaca75ebb4d63928023e7d1d24f4a8c Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 21 Feb 2008 17:56:33 +0100 Subject: Try and fix getifaddrs check on irix: dont't try to include config.h The missing header file is judged "catastrophic" on irix. Michael (cherry picked from commit 5778c90819a5a5cee38be690f442c571f3a6a051) (This used to be commit 0d4522a06d4465f6eadbdf14381c9e08cf7e1dc9) --- source4/lib/replace/getifaddrs.m4 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source4/lib/replace/getifaddrs.m4 b/source4/lib/replace/getifaddrs.m4 index 4cf86d89cc..5d5edf1cbd 100644 --- a/source4/lib/replace/getifaddrs.m4 +++ b/source4/lib/replace/getifaddrs.m4 @@ -60,6 +60,7 @@ fi if test $iface = no; then AC_CACHE_CHECK([for iface AIX],libreplace_cv_HAVE_IFACE_AIX,[ AC_TRY_RUN([ +#define NO_CONFIG_H 1 #define HAVE_IFACE_AIX 1 #define AUTOCONF_TEST 1 #undef _XOPEN_SOURCE_EXTENDED @@ -74,6 +75,7 @@ fi if test $iface = no; then AC_CACHE_CHECK([for iface ifconf],libreplace_cv_HAVE_IFACE_IFCONF,[ AC_TRY_RUN([ +#define NO_CONFIG_H 1 #define HAVE_IFACE_IFCONF 1 #define AUTOCONF_TEST 1 #include "$libreplacedir/getifaddrs.c"], @@ -86,6 +88,7 @@ fi if test $iface = no; then AC_CACHE_CHECK([for iface ifreq],libreplace_cv_HAVE_IFACE_IFREQ,[ AC_TRY_RUN([ +#define NO_CONFIG_H 1 #define HAVE_IFACE_IFREQ 1 #define AUTOCONF_TEST 1 #include "$libreplacedir/getifaddrs.c"], -- cgit From c513546cda3d453748c88589b83015489fc6f14f Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 21 Feb 2008 18:16:10 +0100 Subject: libreplace: fix compile errors in getifaddrs.c Michael (cherry picked from commit 22cdd4cb507022d9c670b7d5cbc8d357b0b91637) (This used to be commit 4da2d999a28c8fd3e93480194a153cf6a10de986) --- source4/lib/replace/getifaddrs.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/source4/lib/replace/getifaddrs.c b/source4/lib/replace/getifaddrs.c index 4037d647d7..f12062bd8e 100644 --- a/source4/lib/replace/getifaddrs.c +++ b/source4/lib/replace/getifaddrs.c @@ -81,7 +81,6 @@ int rep_getifaddrs(struct ifaddrs **ifap) char buff[8192]; int fd, i, n; struct ifreq *ifr=NULL; - int total = 0; struct in_addr ipaddr; struct in_addr nmask; char *iname; @@ -106,7 +105,7 @@ int rep_getifaddrs(struct ifaddrs **ifap) n = ifc.ifc_len / sizeof(struct ifreq); /* Loop through interfaces, looking for given IP address */ - for (i=n-1;i>=0 && total < max_interfaces;i--) { + for (i=n-1; i>=0; i--) { if (ioctl(fd, SIOCGIFADDR, &ifr[i]) != 0) { freeifaddrs(*ifap); } @@ -166,11 +165,10 @@ int rep_getifaddrs(struct ifaddrs **ifap) char buff[8192]; int fd, i, n; struct ifreq *ifr=NULL; - int total = 0; struct in_addr ipaddr; struct in_addr nmask; char *iname; - struct ifaddrs *curif; + struct ifaddrs *curif, *lastif; *ifap = NULL; @@ -201,7 +199,7 @@ int rep_getifaddrs(struct ifaddrs **ifap) /* Loop through interfaces */ - for (i = 0; i Date: Fri, 22 Feb 2008 00:24:11 +0100 Subject: Add missing initalizations of lastif in rep_getifaddr implementations. Michael (cherry picked from commit 65710e752f72070cb911867ff9f31f91904ca5c0) (This used to be commit 5bd613a2cda5d287706f2ce72f4ee08a7fa45b72) --- source4/lib/replace/getifaddrs.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source4/lib/replace/getifaddrs.c b/source4/lib/replace/getifaddrs.c index f12062bd8e..60049caa99 100644 --- a/source4/lib/replace/getifaddrs.c +++ b/source4/lib/replace/getifaddrs.c @@ -84,7 +84,8 @@ int rep_getifaddrs(struct ifaddrs **ifap) struct in_addr ipaddr; struct in_addr nmask; char *iname; - struct ifaddrs *curif, *lastif; + struct ifaddrs *curif; + struct ifaddrs *lastif = NULL; *ifap = NULL; @@ -168,7 +169,8 @@ int rep_getifaddrs(struct ifaddrs **ifap) struct in_addr ipaddr; struct in_addr nmask; char *iname; - struct ifaddrs *curif, *lastif; + struct ifaddrs *curif; + struct ifaddrs *lastif = NULL; *ifap = NULL; @@ -268,7 +270,8 @@ int rep_getifaddrs(struct ifaddrs **ifap) struct in_addr ipaddr; struct in_addr nmask; char *iname; - struct ifaddrs *curif, *lastif; + struct ifaddrs *curif; + struct ifaddrs *lastif = NULL; *ifap = NULL; -- cgit From c2f92013c3304bf49622f7e0d5658f768898a4f1 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 22 Feb 2008 00:27:00 +0100 Subject: Fix linked list of ifaddrs in implementations of rep_getifaddrs. Produce proper list instead of one-node-loop. Michael (cherry picked from commit ec9f4f5066ba7a8bf3af931fd4969590140c0b2b) (This used to be commit 744d5ba7adab65a9774a18eb42b7090f49e423f2) --- source4/lib/replace/getifaddrs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source4/lib/replace/getifaddrs.c b/source4/lib/replace/getifaddrs.c index 60049caa99..37cd950e09 100644 --- a/source4/lib/replace/getifaddrs.c +++ b/source4/lib/replace/getifaddrs.c @@ -115,7 +115,7 @@ int rep_getifaddrs(struct ifaddrs **ifap) if (lastif == NULL) { *ifap = curif; } else { - lastif->ifa_next = (*ifap); + lastif->ifa_next = curif; } curif->ifa_name = strdup(ifr[i].ifr_name); @@ -208,7 +208,7 @@ int rep_getifaddrs(struct ifaddrs **ifap) if (lastif == NULL) { *ifap = curif; } else { - lastif->ifa_next = (*ifap); + lastif->ifa_next = curif; } strioctl.ic_cmd = SIOCGIFFLAGS; @@ -306,7 +306,7 @@ int rep_getifaddrs(struct ifaddrs **ifap) if (lastif == NULL) { *ifap = curif; } else { - lastif->ifa_next = (*ifap); + lastif->ifa_next = curif; } curif->ifa_name = strdup(ifr->ifr_name); -- cgit From 88c919c14af3b5e5cb9524ce3bb778b7c7bc6c72 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 22 Feb 2008 00:34:41 +0100 Subject: libreplace: fix creation of conftest files for getifaddrs tests. Add missing includes of replace.c and defines of SOCKET_WRAPPER_NOT_REPLACE. Michael (cherry picked from commit 26e6ebc7090b5742deb67805d85d809cafb4543d) (This used to be commit e00c6513e05afe91d4c419287283b34e931a161c) --- source4/lib/replace/getifaddrs.m4 | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/source4/lib/replace/getifaddrs.m4 b/source4/lib/replace/getifaddrs.m4 index 5d5edf1cbd..dd2a95cb81 100644 --- a/source4/lib/replace/getifaddrs.m4 +++ b/source4/lib/replace/getifaddrs.m4 @@ -44,9 +44,10 @@ iface=no; iface=no; AC_CACHE_CHECK([for iface getifaddrs],libreplace_cv_HAVE_IFACE_GETIFADDRS,[ AC_TRY_RUN([ -#define NO_CONFIG_H 1 #define HAVE_IFACE_GETIFADDRS 1 +#define NO_CONFIG_H 1 #define AUTOCONF_TEST 1 +#define SOCKET_WRAPPER_NOT_REPLACE #include "$libreplacedir/replace.c" #include "$libreplacedir/getifaddrs.c"], libreplace_cv_HAVE_IFACE_GETIFADDRS=yes,libreplace_cv_HAVE_IFACE_GETIFADDRS=no,libreplace_cv_HAVE_IFACE_GETIFADDRS=cross)]) @@ -60,10 +61,12 @@ fi if test $iface = no; then AC_CACHE_CHECK([for iface AIX],libreplace_cv_HAVE_IFACE_AIX,[ AC_TRY_RUN([ -#define NO_CONFIG_H 1 #define HAVE_IFACE_AIX 1 +#define NO_CONFIG_H 1 #define AUTOCONF_TEST 1 #undef _XOPEN_SOURCE_EXTENDED +#define SOCKET_WRAPPER_NOT_REPLACE +#include "$libreplacedir/replace.c" #include "$libreplacedir/getifaddrs.c"], libreplace_cv_HAVE_IFACE_AIX=yes,libreplace_cv_HAVE_IFACE_AIX=no,libreplace_cv_HAVE_IFACE_AIX=cross)]) if test x"$libreplace_cv_HAVE_IFACE_AIX" = x"yes"; then @@ -75,9 +78,11 @@ fi if test $iface = no; then AC_CACHE_CHECK([for iface ifconf],libreplace_cv_HAVE_IFACE_IFCONF,[ AC_TRY_RUN([ -#define NO_CONFIG_H 1 #define HAVE_IFACE_IFCONF 1 +#define NO_CONFIG_H 1 #define AUTOCONF_TEST 1 +#define SOCKET_WRAPPER_NOT_REPLACE +#include "$libreplacedir/replace.c" #include "$libreplacedir/getifaddrs.c"], libreplace_cv_HAVE_IFACE_IFCONF=yes,libreplace_cv_HAVE_IFACE_IFCONF=no,libreplace_cv_HAVE_IFACE_IFCONF=cross)]) if test x"$libreplace_cv_HAVE_IFACE_IFCONF" = x"yes"; then @@ -88,9 +93,11 @@ fi if test $iface = no; then AC_CACHE_CHECK([for iface ifreq],libreplace_cv_HAVE_IFACE_IFREQ,[ AC_TRY_RUN([ -#define NO_CONFIG_H 1 #define HAVE_IFACE_IFREQ 1 +#define NO_CONFIG_H 1 #define AUTOCONF_TEST 1 +#define SOCKET_WRAPPER_NOT_REPLACE +#include "$libreplacedir/replace.c" #include "$libreplacedir/getifaddrs.c"], libreplace_cv_HAVE_IFACE_IFREQ=yes,libreplace_cv_HAVE_IFACE_IFREQ=no,libreplace_cv_HAVE_IFACE_IFREQ=cross)]) if test x"$libreplace_cv_HAVE_IFACE_IFREQ" = x"yes"; then -- cgit From bf7d3b6ef440d61a8d65001f99c7526bb830f5d3 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 22 Feb 2008 10:42:22 +0100 Subject: libreplace: Fix comment originating from old samba source. Michael (This used to be commit 0440bcfe6359ca4842f473b1ca799cad9f1c6c96) --- source4/lib/replace/getifaddrs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/lib/replace/getifaddrs.c b/source4/lib/replace/getifaddrs.c index 37cd950e09..a6f06e545f 100644 --- a/source4/lib/replace/getifaddrs.c +++ b/source4/lib/replace/getifaddrs.c @@ -363,7 +363,7 @@ int rep_getifaddrs(struct ifaddrs **ifap) #endif #ifdef AUTOCONF_TEST -/* this is the autoconf driver to test get_interfaces() */ +/* this is the autoconf driver to test getifaddrs() */ int main() { -- cgit From 3fa76092e6cc48098f8da56452446791d09c76b5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Feb 2008 14:08:13 +0100 Subject: Happy New Year 2008! :-) metze (This used to be commit a601ecff4e8cbf71de9f140ee2faa0b75d695559) --- source4/smbd/server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/smbd/server.c b/source4/smbd/server.c index dd63ca1eca..fdeb541576 100644 --- a/source4/smbd/server.c +++ b/source4/smbd/server.c @@ -253,7 +253,7 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[ umask(0); DEBUG(0,("%s version %s started.\n", binary_name, SAMBA_VERSION_STRING)); - DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2007\n")); + DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2008\n")); if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) { DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n")); -- cgit From e9b0056586f6e57d4d1243c5622c568497e04d38 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 22 Feb 2008 13:53:05 +0100 Subject: libreplace: don't use socketwrapper for getifaddrs() implementations. Michael (cherry picked from commit 85eec1d1d6b674294c50eb912fbe7d5a1dd42909) (This used to be commit a83db886e50b6ceeb71d93bf86fb5e0964b8d45f) --- source4/lib/replace/getifaddrs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source4/lib/replace/getifaddrs.c b/source4/lib/replace/getifaddrs.c index a6f06e545f..053657475d 100644 --- a/source4/lib/replace/getifaddrs.c +++ b/source4/lib/replace/getifaddrs.c @@ -19,6 +19,8 @@ along with this program. If not, see . */ +#define SOCKET_WRAPPER_NOT_REPLACE + #include "replace.h" #include "system/network.h" -- cgit From bd95d6d5dbd27e2b904f7907ef39766159d0afcf Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 23 Feb 2008 10:26:52 +0100 Subject: Respect the return value of asprintf This removes tons of warnings warning: ignoring return value of 'fwrite', declared with attribute warn_unused_result for me. Lots of that kind left though :-) (This used to be commit ba29219ea243cc217ab3522b036a82ff8dfeedc8) --- source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm index ef3eb3dbcf..a959dc84f6 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm @@ -775,8 +775,7 @@ sub ParseElementPrint($$$$) $self->pidl("for ($counter=0;$counter<$length;$counter++) {"); $self->indent; $self->pidl("char *idx_$l->{LEVEL_INDEX}=NULL;"); - $self->pidl("asprintf(&idx_$l->{LEVEL_INDEX}, \"[\%d]\", $counter);"); - $self->pidl("if (idx_$l->{LEVEL_INDEX}) {"); + $self->pidl("if (asprintf(&idx_$l->{LEVEL_INDEX}, \"[\%d]\", $counter) != -1) {"); $self->indent; $var_name = get_array_element($var_name, $counter); -- cgit From a622f80c658bb1d0639e9ebe3a2be7093f15ffc6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 24 Feb 2008 00:13:36 +0100 Subject: BASE-DEFER_OPEN: add torture:sharedelays option to run this test faster metze (This used to be commit 877cc375d0523cb31324a5d611e73d666e7a9a78) --- source4/torture/basic/base.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) 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))) { -- cgit From 77054b42bdfcd077ede8a5c29aead2807f016ecc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 25 Feb 2008 07:42:38 +0100 Subject: selftest: we pass the BASE-DEFER_OPEN test We just need to pass the same sharedelay time to smbtorture as we use for smbd. metze (This used to be commit 3b78dc7ab2f8e3faffa2eb3ae2462c133e368be3) --- source4/samba4-skip | 2 -- source4/selftest/samba4_tests.sh | 5 +++-- 2 files changed, 3 insertions(+), 4 deletions(-) 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 -- cgit From a64bd41601b9b50075e95ca50510f04cd2bb8454 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 23 Feb 2008 11:51:23 +0100 Subject: RAW-OPLOCK: fix typo (send oplock releases on the correct connection) metze (This used to be commit f6ecf59c7555917374fc9e5430034815fd4cd245) --- source4/torture/raw/oplock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/torture/raw/oplock.c b/source4/torture/raw/oplock.c index 952088e46c..5ece01c505 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 | -- cgit From 5dc8d3ed8b5a5e263a74f880f6fb1d88d27bd5c6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 23 Feb 2008 11:51:43 +0100 Subject: RAW-OPLOCK: remove unused var (This used to be commit 6820da44828172769d9fdfa161acf762e3937a88) --- source4/torture/raw/oplock.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source4/torture/raw/oplock.c b/source4/torture/raw/oplock.c index 5ece01c505..3edd0c6820 100644 --- a/source4/torture/raw/oplock.c +++ b/source4/torture/raw/oplock.c @@ -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); -- cgit From fb6f52261a4cdbc529c04e28b29f82a8cbb9640f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 21 Feb 2008 08:59:21 +0100 Subject: pvfs_wait: 'private' -> 'private_data' and use talloc_get_type() metze (This used to be commit 16a7d0cc37614fc41245fdcdf3b5a4a4a421f31d) --- source4/ntvfs/posix/pvfs_wait.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 989985a033..838a801567 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; @@ -131,7 +136,7 @@ void *pvfs_wait_message(struct pvfs_state *pvfs, int msg_type, struct timeval end_time, void (*fn)(void *, enum pvfs_wait_notice), - void *private) + 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; -- cgit From a0a0d4a5d0c24729a26a37ff54caa665de9149a2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 21 Feb 2008 09:02:17 +0100 Subject: pvfs_wait: use struct pvfs_wait * instead of void * metze (This used to be commit 3b70331536d2402814db13a9f1f226a39373313a) --- source4/ntvfs/posix/pvfs_lock.c | 2 +- source4/ntvfs/posix/pvfs_notify.c | 8 +++++--- source4/ntvfs/posix/pvfs_open.c | 2 +- source4/ntvfs/posix/pvfs_wait.c | 12 ++++++------ source4/ntvfs/posix/vfs_posix.h | 2 ++ 5 files changed, 15 insertions(+), 11 deletions(-) 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..3ccd239523 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; }; diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 838a801567..291250befd 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -131,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_data) +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; 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 { -- cgit From 1cd2008aa49d38792f273bb28922d33b5b9b0066 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 21 Feb 2008 19:59:13 +0100 Subject: pvfs: pass NULL to pvfs_can_*() when no odb_lock is needed by the caller metze (This used to be commit e585e2306334bd919f567f53d8d08903dfdfb102) --- source4/ntvfs/posix/pvfs_rename.c | 11 ++++++----- source4/ntvfs/posix/pvfs_setfileinfo.c | 4 +--- source4/ntvfs/posix/pvfs_unlink.c | 6 ++---- 3 files changed, 9 insertions(+), 12 deletions(-) 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..d6e60b59d3 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -33,7 +33,6 @@ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, uint16_t attrib) { NTSTATUS status; - struct odb_lock *lck; if (!name->stream_exists) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; @@ -45,7 +44,7 @@ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, return status; } - status = pvfs_can_delete(pvfs, req, name, &lck); + status = pvfs_can_delete(pvfs, req, name, NULL); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -64,7 +63,6 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, { struct pvfs_filename *name; NTSTATUS status; - struct odb_lock *lck; /* get a pvfs_filename object */ status = pvfs_resolve_partial(pvfs, req, @@ -80,7 +78,7 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, 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; -- cgit From f56ff422a525fc6fdf04de8e2ce5c5fa4c097629 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 21 Feb 2008 20:01:25 +0100 Subject: pvfs: handle SHARING_VIOLATION and OPLOCK_NOT_GRANTED in pvfs_can_delete/rename() If the caller asks for the odb_lock return it also if we return NT_STATUS_SHARING_VIOLATION or NT_STATUS_OPLOCK_NOT_GRANTED so that the caller can add the pending notification. metze (This used to be commit daab9cb11eb540fae7ec3c024a586f5fd02cfc71) --- source4/ntvfs/posix/pvfs_open.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 3ccd239523..0d97b3d629 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1447,7 +1447,19 @@ 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) { @@ -1487,7 +1499,19 @@ 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) { -- cgit From 6f077d4017e6df9e070b1c3ea85b7afacf3437cd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 21 Feb 2008 19:56:36 +0100 Subject: pvfs_open: unify talloc behavior in pvfs_can_delete/rename/stat() And also handle NULL for lckp in the error path without crashing. metze (This used to be commit 04eb1be0c67317067ee0ca70c731fef958cd513c) --- source4/ntvfs/posix/pvfs_open.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 0d97b3d629..3a8b17ab16 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1461,8 +1461,10 @@ NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, } } 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; } @@ -1513,8 +1515,10 @@ NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs, } } 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; } @@ -1549,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; } -- cgit From 63b15441f4a5f636a079fa5407b2e97a8b99b6e2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 21 Feb 2008 20:12:46 +0100 Subject: pvfs_unlink: pass down a struct pvfs_filename to pvfs_unlink_one() metze (This used to be commit 43ec7fa2d898ce306557ea9092b6412bcc2f97ec) --- source4/ntvfs/posix/pvfs_unlink.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index d6e60b59d3..101dd75de6 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -58,34 +58,23 @@ static NTSTATUS pvfs_unlink_stream(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) + struct pvfs_filename *name, + uint32_t attrib) { - struct pvfs_filename *name; NTSTATUS status; - /* 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); if (!NT_STATUS_IS_OK(status)) { - talloc_free(name); return status; } 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; } @@ -108,8 +97,6 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, name->full_name); } - talloc_free(name); - return status; } @@ -156,6 +143,7 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, } status = NT_STATUS_NO_SUCH_FILE; + talloc_free(name); ofs = 0; @@ -166,10 +154,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, name, unl->unlink.in.attrib); if (NT_STATUS_IS_OK(status)) { total_deleted++; } + + talloc_free(name); } if (total_deleted > 0) { -- cgit From a56bd4fa82bcb5c586f182e8123f2fc41b12e41d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Feb 2008 09:23:53 +0100 Subject: pvfs_unlink: pass down union smb_unlink completely to sub functions metze (This used to be commit 8301189e94be850494482e8c064b2400a5d11157) --- source4/ntvfs/posix/pvfs_unlink.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 101dd75de6..8dbf9ee724 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -29,8 +29,8 @@ */ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, struct ntvfs_request *req, - struct pvfs_filename *name, - uint16_t attrib) + union smb_unlink *unl, + struct pvfs_filename *name) { NTSTATUS status; @@ -39,7 +39,8 @@ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, } /* 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)) { return status; } @@ -58,13 +59,14 @@ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, */ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, struct ntvfs_request *req, - struct pvfs_filename *name, - uint32_t attrib) + union smb_unlink *unl, + struct pvfs_filename *name) { NTSTATUS 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)) { return status; } @@ -133,7 +135,7 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, } if (name->stream_name) { - return pvfs_unlink_stream(pvfs, req, name, unl->unlink.in.attrib); + return pvfs_unlink_stream(pvfs, req, unl, name); } /* get list of matching files */ @@ -162,7 +164,7 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, return status; } - status = pvfs_unlink_one(pvfs, req, name, unl->unlink.in.attrib); + status = pvfs_unlink_one(pvfs, req, unl, name); if (NT_STATUS_IS_OK(status)) { total_deleted++; } -- cgit From d5414cdc63b797a47fcbd1f55df98c7dd850ffa6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Feb 2008 09:28:51 +0100 Subject: pvfs_unlink: move !name->stream_exists into the caller metze (This used to be commit e01554e1617dc3c08a4ed6b4e016fd627f529ef9) --- source4/ntvfs/posix/pvfs_unlink.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 8dbf9ee724..2b96a5032c 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -34,10 +34,6 @@ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, { NTSTATUS status; - if (!name->stream_exists) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - /* make sure its matches the given attributes */ status = pvfs_match_attrib(pvfs, name, unl->unlink.in.attrib, 0); @@ -135,6 +131,10 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, } if (name->stream_name) { + if (!name->stream_exists) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + return pvfs_unlink_stream(pvfs, req, unl, name); } -- cgit From 0634c12abb634034fcaf842647c2bc09a92bfd68 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Feb 2008 09:30:51 +0100 Subject: pvfs_unlink: add a fast path for the non wildcard case metze (This used to be commit 83e6c99f78990b6b1df520bdee14b9f931ad0420) --- source4/ntvfs/posix/pvfs_unlink.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 2b96a5032c..72649e646d 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -138,6 +138,10 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, return pvfs_unlink_stream(pvfs, req, unl, name); } + if (!name->has_wildcard) { + return pvfs_unlink_one(pvfs, req, unl, name); + } + /* get list of matching files */ status = pvfs_list_start(pvfs, name, req, &dir); if (!NT_STATUS_IS_OK(status)) { -- cgit From 58745900d30cbfa8729ce99e7110cfc5e4a78c2a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Feb 2008 09:37:22 +0100 Subject: pvfs_unlink: splitup the logic into generic and file specific functions metze (This used to be commit 7572afdc2635bdf9afbe1eda3c7498d0b5201db3) --- source4/ntvfs/posix/pvfs_unlink.c | 45 ++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 72649e646d..0763a4e48c 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -51,27 +51,13 @@ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, /* - unlink one file + unlink a file */ -static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, - struct ntvfs_request *req, - union smb_unlink *unl, - struct pvfs_filename *name) +static NTSTATUS pvfs_unlink_file(struct pvfs_state *pvfs, + struct pvfs_filename *name) { NTSTATUS status; - /* make sure its matches the given attributes */ - status = pvfs_match_attrib(pvfs, name, - unl->unlink.in.attrib, 0); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - status = pvfs_can_delete(pvfs, req, name, NULL); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { return NT_STATUS_FILE_IS_A_DIRECTORY; } @@ -98,6 +84,31 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, return status; } +/* + unlink one file +*/ +static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, + struct ntvfs_request *req, + union smb_unlink *unl, + struct pvfs_filename *name) +{ + NTSTATUS status; + + /* make sure its matches the given attributes */ + status = pvfs_match_attrib(pvfs, name, + unl->unlink.in.attrib, 0); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = pvfs_can_delete(pvfs, req, name, NULL); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return pvfs_unlink_file(pvfs, name); +} + /* delete a file - the dirtype specifies the file types to include in the search. The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) -- cgit From 599901c139e99dca26f267439c14119e6c3f2092 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Feb 2008 09:41:41 +0100 Subject: pvfs_unlink: move stream logic into pvfs_unlink_one() metze (This used to be commit 438032e12f3040fbb58488ca537e4d8da39b6124) --- source4/ntvfs/posix/pvfs_unlink.c | 42 ++++++++------------------------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 0763a4e48c..bda4014bee 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -24,32 +24,6 @@ #include "system/dir.h" -/* - unlink a stream - */ -static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, - struct ntvfs_request *req, - union smb_unlink *unl, - struct pvfs_filename *name) -{ - NTSTATUS status; - - /* make sure its matches the given attributes */ - status = pvfs_match_attrib(pvfs, name, - unl->unlink.in.attrib, 0); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - status = pvfs_can_delete(pvfs, req, name, NULL); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - return pvfs_stream_delete(pvfs, name, -1); -} - - /* unlink a file */ @@ -106,6 +80,14 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, return status; } + if (name->stream_name) { + if (!name->stream_exists) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + return pvfs_stream_delete(pvfs, name, -1); + } + return pvfs_unlink_file(pvfs, name); } @@ -141,14 +123,6 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, return NT_STATUS_FILE_IS_A_DIRECTORY; } - if (name->stream_name) { - if (!name->stream_exists) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - - return pvfs_unlink_stream(pvfs, req, unl, name); - } - if (!name->has_wildcard) { return pvfs_unlink_one(pvfs, req, unl, name); } -- cgit From 27e322bb4d5a25a2a1ebc5df36690590d86e3afd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Feb 2008 10:18:13 +0100 Subject: opendb: add odb_get_key() function to get the key back from a struct odb_lock metze (This used to be commit 11f35a2a4d383b506ced35ba06120f9531bac70c) --- source4/cluster/ctdb/opendb_ctdb.c | 11 +++++++++++ source4/ntvfs/common/opendb.c | 4 ++++ source4/ntvfs/common/opendb.h | 1 + source4/ntvfs/common/opendb_tdb.c | 7 +++++++ 4 files changed, 23 insertions(+) diff --git a/source4/cluster/ctdb/opendb_ctdb.c b/source4/cluster/ctdb/opendb_ctdb.c index aaab3aa55d..f056e21716 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 @@ -610,6 +620,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, diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 4826ca5c26..f12f23817d 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 diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h index 231ae3d7de..5472cea418 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, diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index abd9ca708b..469cf28374 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -134,6 +134,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 @@ -609,6 +615,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, -- cgit From 6cb9c1c61d8087457420a56f5296662417a25bd4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 21 Feb 2008 12:20:31 +0100 Subject: opendb: send also the oplock break level on MSG_NTVFS_OPLOCK_BREAK metze (This used to be commit 49402007f6e9e02a29792344c088e40d1a9b7acf) --- source4/ntvfs/common/opendb.h | 4 ++++ source4/ntvfs/common/opendb_tdb.c | 28 +++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h index 5472cea418..ccf6db27a0 100644 --- a/source4/ntvfs/common/opendb.h +++ b/source4/ntvfs/common/opendb.h @@ -43,6 +43,10 @@ struct opendb_ops { uint32_t access_mask); }; +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 469cf28374..25f37f5e26 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -259,12 +259,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; } /* @@ -318,7 +334,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; } } @@ -342,7 +359,8 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle, exclusive oplocks afterwards. */ for (i=0;i Date: Thu, 21 Feb 2008 16:12:27 +0100 Subject: opendb: add odb_update_oplock() call metze (This used to be commit df576d69c6981a4879a0e9447069fcfacb3588db) --- source4/cluster/ctdb/opendb_ctdb.c | 16 +++++++++++++- source4/ntvfs/common/opendb.c | 6 +++++ source4/ntvfs/common/opendb.h | 2 ++ source4/ntvfs/common/opendb_tdb.c | 45 ++++++++++++++++++++++++++++++++++++-- 4 files changed, 66 insertions(+), 3 deletions(-) diff --git a/source4/cluster/ctdb/opendb_ctdb.c b/source4/cluster/ctdb/opendb_ctdb.c index f056e21716..86dc1f50f1 100644 --- a/source4/cluster/ctdb/opendb_ctdb.c +++ b/source4/cluster/ctdb/opendb_ctdb.c @@ -450,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 @@ -628,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/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index f12f23817d..4ac10806e1 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -170,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 ccf6db27a0..c34a07d6fa 100644 --- a/source4/ntvfs/common/opendb.h +++ b/source4/ntvfs/common/opendb.h @@ -41,6 +41,8 @@ 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 { diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 25f37f5e26..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 @@ -463,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;intvfs_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;intvfs_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 @@ -641,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 }; -- cgit From 0a8b1fd092c9a64c04f6f05d41b3d7ecec7ccc6f Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 25 Feb 2008 14:03:07 -0500 Subject: Update homepages for talloc, tdb and ldb subprojects (This used to be commit 8cb07814bc6627fc8eba228eafd13336e3ca3758) --- source4/lib/ldb/web/index.html | 24 ++++++++++-------------- source4/lib/talloc/web/index.html | 20 ++++++++------------ source4/lib/tdb/web/index.html | 14 ++++++-------- 3 files changed, 24 insertions(+), 34 deletions(-) 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 ldb.h +href="http://samba.org/ftp/unpacked/ldb/include/ldb.h">ldb.h and the example code in the tools +href="http://samba.org/ftp/unpacked/ldb/tools/">tools directory. 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 samba-technical -mailing list, and the Samba -bugzilla bug tracking system. +mailing list or the ldb +mailing list, and the Samba bugzilla bug tracking system.

Download

-You can download the latest release either via rsync or anonymous -svn. To fetch via svn use the following commands: - -
-  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
-
- +You can download the latest release either via rsync or thtough git.
+
+To fetch via git see the following guide:
+Using Git for Samba Development
+Once you have cloned the tree switch to the v4-0-test branch and cd into the source/lib/ldb directory.
+
To fetch via rsync use these commands:
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.

To get started with talloc, I would recommend you read the talloc guide. +href="http://samba.org/ftp/unpacked/talloc/talloc_guide.txt">talloc guide.

Discussion and bug reports

@@ -24,20 +24,16 @@ bugzilla bug tracking system.

Download

-You can download the latest release either via rsync or git. -To fetch via git use the following command: - -
-  git-clone git://git.samba.org/samba.git samba
-  cd samba
-  git checkout -b samba4 origin/v4-0-test
-
- +You can download the latest release either via rsync or git.
+
+To fetch via git see the following guide:
+Using Git for Samba Development
+Once you have cloned the tree switch to the v4-0-test branch and cd into the source/lib/talloc directory.
+
To fetch via rsync use this command:
-  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 .
 

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 bug tracking system.

Download

-You can download the latest release either via rsync or anonymous -svn. To fetch via svn use the following commands: - -
-  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
-
- +You can download the latest release either via rsync or git.
+
+To fetch via git see the following guide:
+Using Git for Samba Development
+Once you have cloned the tree switch to the v4-0-test branch and cd into the source/lib/tdb directory.
+
To fetch via rsync use these commands:
-- 
cgit 


From 1e5ced379361fbdc0ccc48ad012f388f2e737ca7 Mon Sep 17 00:00:00 2001
From: Kai Blin 
Date: Tue, 26 Feb 2008 06:17:04 +0100
Subject: howto: We need bin/smbpython to run python provisioning (This used to
 be commit bb1107118951aa37c69b053f5cae624706966f1e)

---
 howto.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/howto.txt b/howto.txt
index 654ad658c8..16f6d02a25 100644
--- a/howto.txt
+++ b/howto.txt
@@ -78,7 +78,7 @@ Must be run as a user with permission to write to the install directory.
 ::
 
   # cd source
-  # ./setup/provision --realm=YOUR.REALM --domain=YOURDOM \
+  # bin/smbpython ./setup/provision --realm=YOUR.REALM --domain=YOURDOM \
   #  --adminpass=SOMEPASSWORD --server-role='domain controller'
 
 REMINDER: Add the "bin" directory of the path you installed to
-- 
cgit 


From 2c8415f767ca20fe90a97f8623d1617e015f183a Mon Sep 17 00:00:00 2001
From: Andrew Bartlett 
Date: Tue, 26 Feb 2008 16:19:42 +1100
Subject: Make use of smbpython clear.

Andrew Bartlett
(This used to be commit 98461d6053b9ad98a372ec59ded2c7eaade99640)
---
 howto.txt | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/howto.txt b/howto.txt
index 654ad658c8..2b020903b2 100644
--- a/howto.txt
+++ b/howto.txt
@@ -78,12 +78,11 @@ Must be run as a user with permission to write to the install directory.
 ::
 
   # cd source
-  # ./setup/provision --realm=YOUR.REALM --domain=YOURDOM \
+  # bin/smbpython ./setup/provision --realm=YOUR.REALM --domain=YOURDOM \
   #  --adminpass=SOMEPASSWORD --server-role='domain controller'
 
-REMINDER: Add the "bin" directory of the path you installed to
-          (e.g. /usr/local/samba/bin) to your path, or the provision command
-          will not work.
+REMINDER: Use the path to smbpython, as the provision command
+          will not work with the system python.
 
 'YOURDOM' is the NT4 style domain name. 'YOUR.REALM' is your kerberos
 realm, which is typically your DNS domain name.
-- 
cgit 


From 3526d1d48c86881c3fb8e54ae614d81deb242374 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett 
Date: Tue, 26 Feb 2008 16:24:09 +1100
Subject: Remove more cruft about smbscript.

Andrew Bartlett
(This used to be commit f68fc4582d446bbf48ebafcbd4a0e1862b1e9aae)
---
 howto.txt | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/howto.txt b/howto.txt
index 2b020903b2..78bed1316a 100644
--- a/howto.txt
+++ b/howto.txt
@@ -70,9 +70,7 @@ configure above to change this.
 Step 4: provision Samba4
 ------------------------
 
-The "provision" step sets up a basic user database. Make sure your smbscript
-binary is installed in a directory listed in your PATH environment variable.
-It is presumed it's available just like any other commands from your shell.
+The "provision" step sets up a basic user database. 
 Must be run as a user with permission to write to the install directory.
 
 ::
-- 
cgit 


From f94008e45a15666439766488edf84b21a86111ee Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Fri, 22 Feb 2008 16:30:13 +0100
Subject: opendb: add odb_break_oplocks() function

This send breaks to none to all level2 holders

metze
(This used to be commit bd3654500b14e4ed8d4a8bb25ff9da5035a16a8b)
---
 source4/cluster/ctdb/opendb_ctdb.c | 13 ++++++++++++-
 source4/ntvfs/common/opendb.c      |  5 +++++
 source4/ntvfs/common/opendb.h      |  1 +
 source4/ntvfs/common/opendb_tdb.c  | 40 +++++++++++++++++++++++++++++++++++++-
 4 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/source4/cluster/ctdb/opendb_ctdb.c b/source4/cluster/ctdb/opendb_ctdb.c
index 86dc1f50f1..915b760424 100644
--- a/source4/cluster/ctdb/opendb_ctdb.c
+++ b/source4/cluster/ctdb/opendb_ctdb.c
@@ -464,6 +464,16 @@ static NTSTATUS odb_ctdb_update_oplock(struct odb_lock *lck, void *file_handle,
 	return NT_STATUS_FOOBAR;
 }
 
+static NTSTATUS odb_ctdb_break_oplocks(struct odb_lock *lck)
+{
+	/*
+	 * 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
 */
@@ -642,7 +652,8 @@ static const struct opendb_ops opendb_ctdb_ops = {
 	.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_update_oplock       = odb_ctdb_update_oplock
+	.odb_update_oplock       = odb_ctdb_update_oplock,
+	.odb_break_oplocks       = odb_ctdb_break_oplocks
 };
 
 
diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c
index 4ac10806e1..3f5d7210be 100644
--- a/source4/ntvfs/common/opendb.c
+++ b/source4/ntvfs/common/opendb.c
@@ -176,3 +176,8 @@ _PUBLIC_ NTSTATUS odb_update_oplock(struct odb_lock *lck, void *file_handle,
 {
 	return ops->odb_update_oplock(lck, file_handle, oplock_level);
 }
+
+_PUBLIC_ NTSTATUS odb_break_oplocks(struct odb_lock *lck)
+{
+	return ops->odb_break_oplocks(lck);
+}
diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h
index c34a07d6fa..c46390446c 100644
--- a/source4/ntvfs/common/opendb.h
+++ b/source4/ntvfs/common/opendb.h
@@ -43,6 +43,7 @@ struct opendb_ops {
 				 uint32_t access_mask);
 	NTSTATUS (*odb_update_oplock)(struct odb_lock *lck, void *file_handle,
 				      uint32_t oplock_level);
+	NTSTATUS (*odb_break_oplocks)(struct odb_lock *lck);
 };
 
 struct opendb_oplock_break {
diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c
index 3d4a760e2e..dd2fb138d6 100644
--- a/source4/ntvfs/common/opendb_tdb.c
+++ b/source4/ntvfs/common/opendb_tdb.c
@@ -503,6 +503,43 @@ static NTSTATUS odb_tdb_update_oplock(struct odb_lock *lck, void *file_handle,
 	return odb_push_record(lck, &file);
 }
 
+/*
+  send oplocks breaks to none to all level2 holders
+*/
+static NTSTATUS odb_tdb_break_oplocks(struct odb_lock *lck)
+{
+	struct odb_context *odb = lck->odb;
+	NTSTATUS status;
+	struct opendb_file file;
+	int i;
+	bool modified = true;
+
+	status = odb_pull_record(lck, &file);
+	if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+		return NT_STATUS_OK;
+	}
+	NT_STATUS_NOT_OK_RETURN(status);
+
+	/* see if anyone has an oplock, which we need to break */
+	for (i=0;i
Date: Fri, 22 Feb 2008 17:26:40 +0100
Subject: opendb_tdb: grant level2 oplocks

metze
(This used to be commit 57f1b9d11cfcac3b5fdee1ad9e4ba81d0859c8dc)
---
 source4/ntvfs/common/opendb_tdb.c | 32 +++++++++++++++++++++++---------
 1 file changed, 23 insertions(+), 9 deletions(-)

diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c
index dd2fb138d6..3310532406 100644
--- a/source4/ntvfs/common/opendb_tdb.c
+++ b/source4/ntvfs/common/opendb_tdb.c
@@ -367,18 +367,32 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle,
 	}
 
 	/*
-	  possibly grant an exclusive or batch oplock if this is the only client
-	  with the file open. We don't yet grant levelII oplocks.
+	  possibly grant an exclusive, batch or level2 oplock
 	*/
-	if (oplock_granted != NULL) {
-		if ((oplock_level == OPLOCK_BATCH ||
-		     oplock_level == OPLOCK_EXCLUSIVE) &&
-		    file.num_entries == 0) {
-			(*oplock_granted) = oplock_level;
+	if (oplock_granted) {
+		if (oplock_level == OPLOCK_EXCLUSIVE) {
+			if (file.num_entries == 0) {
+				e.oplock_level	= OPLOCK_EXCLUSIVE;
+				*oplock_granted	= EXCLUSIVE_OPLOCK_RETURN;
+			} else {
+				e.oplock_level	= OPLOCK_NONE;
+				*oplock_granted	= NO_OPLOCK_RETURN;
+			}
+		} else if (oplock_level == OPLOCK_BATCH) {
+			if (file.num_entries == 0) {
+				e.oplock_level	= OPLOCK_BATCH;
+				*oplock_granted	= BATCH_OPLOCK_RETURN;
+			} else {
+				e.oplock_level	= OPLOCK_LEVEL_II;
+				*oplock_granted	= LEVEL_II_OPLOCK_RETURN;
+			}
+		} else if (oplock_level == OPLOCK_LEVEL_II) {
+			e.oplock_level	= OPLOCK_LEVEL_II;
+			*oplock_granted	= LEVEL_II_OPLOCK_RETURN;
 		} else {
-			(*oplock_granted) = OPLOCK_NONE;
+			e.oplock_level	= OPLOCK_NONE;
+			*oplock_granted	= NO_OPLOCK_RETURN;
 		}
-		e.oplock_level = (*oplock_granted);
 	}
 
 	/* it doesn't conflict, so add it to the end */
-- 
cgit 


From c749b66ead71af3076d4f911aa0cd65e35284ca4 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Fri, 22 Feb 2008 17:26:40 +0100
Subject: opendb_tdb: attribute only opens doesn't conflict with BATCH oplocks

metze
(This used to be commit 7872b05abe7532676c4cc25620b96ea5d59117d2)
---
 source4/ntvfs/common/opendb_tdb.c | 37 +++++++++++++++++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c
index 3310532406..b445981b57 100644
--- a/source4/ntvfs/common/opendb_tdb.c
+++ b/source4/ntvfs/common/opendb_tdb.c
@@ -189,7 +189,7 @@ static NTSTATUS share_conflict(struct opendb_entry *e1, struct opendb_entry *e2)
 		   e2->share_access, NTCREATEX_SHARE_ACCESS_DELETE);
 	CHECK_MASK(e2->access_mask, SEC_STD_DELETE,
 		   e1->share_access, NTCREATEX_SHARE_ACCESS_DELETE);
-
+#undef CHECK_MASK
 	return NT_STATUS_OK;
 }
 
@@ -284,6 +284,25 @@ static NTSTATUS odb_oplock_break_send(struct odb_context *odb,
 	return NT_STATUS_OK;
 }
 
+static bool access_attributes_only(uint32_t access_mask,
+				   uint32_t open_disposition)
+{
+	switch (open_disposition) {
+	case NTCREATEX_DISP_SUPERSEDE:
+	case NTCREATEX_DISP_OVERWRITE_IF:
+	case NTCREATEX_DISP_OVERWRITE:
+		return false;
+	default:
+		break;
+	}
+#define CHECK_MASK(m,g) ((m) && (((m) & ~(g))==0) && (((m) & (g)) != 0))
+	return CHECK_MASK(access_mask,
+			  SEC_STD_SYNCHRONIZE |
+			  SEC_FILE_READ_ATTRIBUTE |
+			  SEC_FILE_WRITE_ATTRIBUTE);
+#undef CHECK_MASK
+}
+
 /*
   register an open file in the open files database. This implements the share_access
   rules
@@ -302,6 +321,8 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle,
 	int i;
 	struct opendb_file file;
 	NTSTATUS status;
+	uint32_t open_disposition = 0;
+	bool attrs_only = false;
 
 	if (odb->oplocks == false) {
 		oplock_level = OPLOCK_NONE;
@@ -328,6 +349,15 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle,
 	/* see if anyone has an oplock, which we need to break */
 	for (i=0;i
Date: Mon, 25 Feb 2008 16:14:23 +0100
Subject: opendb_tdb: add force break to none logic

metze
(This used to be commit fbfe953ba347a902297bd8eae900ca70efd2db01)
---
 source4/ntvfs/common/opendb_tdb.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c
index b445981b57..656e113742 100644
--- a/source4/ntvfs/common/opendb_tdb.c
+++ b/source4/ntvfs/common/opendb_tdb.c
@@ -322,6 +322,7 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle,
 	struct opendb_file file;
 	NTSTATUS status;
 	uint32_t open_disposition = 0;
+	bool break_to_none = false;
 	bool attrs_only = false;
 
 	if (odb->oplocks == false) {
@@ -349,6 +350,7 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle,
 	/* see if anyone has an oplock, which we need to break */
 	for (i=0;i
Date: Mon, 25 Feb 2008 16:26:04 +0100
Subject: opendb_tdb: move sharemode, oplock logic into
 odb_tdb_open_can_internal()

metze
(This used to be commit 65cfe71b2617598f8e38d04537cfc9ce44a36680)
---
 source4/ntvfs/common/opendb_tdb.c | 191 ++++++++++++++++++++------------------
 1 file changed, 102 insertions(+), 89 deletions(-)

diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c
index 656e113742..9c273f9617 100644
--- a/source4/ntvfs/common/opendb_tdb.c
+++ b/source4/ntvfs/common/opendb_tdb.c
@@ -146,7 +146,10 @@ static DATA_BLOB odb_tdb_get_key(TALLOC_CTX *mem_ctx, struct odb_lock *lck)
 
   return NT_STATUS_OK on no conflict
 */
-static NTSTATUS share_conflict(struct opendb_entry *e1, struct opendb_entry *e2)
+static NTSTATUS share_conflict(struct opendb_entry *e1,
+			       uint32_t stream_id,
+			       uint32_t share_access,
+			       uint32_t access_mask)
 {
 	/* if either open involves no read.write or delete access then
 	   it can't conflict */
@@ -157,18 +160,18 @@ static NTSTATUS share_conflict(struct opendb_entry *e1, struct opendb_entry *e2)
 				 SEC_STD_DELETE))) {
 		return NT_STATUS_OK;
 	}
-	if (!(e2->access_mask & (SEC_FILE_WRITE_DATA |
-				 SEC_FILE_APPEND_DATA |
-				 SEC_FILE_READ_DATA |
-				 SEC_FILE_EXECUTE |
-				 SEC_STD_DELETE))) {
+	if (!(access_mask & (SEC_FILE_WRITE_DATA |
+			     SEC_FILE_APPEND_DATA |
+			     SEC_FILE_READ_DATA |
+			     SEC_FILE_EXECUTE |
+			     SEC_STD_DELETE))) {
 		return NT_STATUS_OK;
 	}
 
 	/* data IO access masks. This is skipped if the two open handles
 	   are on different streams (as in that case the masks don't
 	   interact) */
-	if (e1->stream_id != e2->stream_id) {
+	if (e1->stream_id != stream_id) {
 		return NT_STATUS_OK;
 	}
 
@@ -176,18 +179,18 @@ static NTSTATUS share_conflict(struct opendb_entry *e1, struct opendb_entry *e2)
 	if (((am) & (right)) && !((sa) & (share))) return NT_STATUS_SHARING_VIOLATION
 
 	CHECK_MASK(e1->access_mask, SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA,
-		   e2->share_access, NTCREATEX_SHARE_ACCESS_WRITE);
-	CHECK_MASK(e2->access_mask, SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA,
+		   share_access, NTCREATEX_SHARE_ACCESS_WRITE);
+	CHECK_MASK(access_mask, SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA,
 		   e1->share_access, NTCREATEX_SHARE_ACCESS_WRITE);
 	
 	CHECK_MASK(e1->access_mask, SEC_FILE_READ_DATA | SEC_FILE_EXECUTE,
-		   e2->share_access, NTCREATEX_SHARE_ACCESS_READ);
-	CHECK_MASK(e2->access_mask, SEC_FILE_READ_DATA | SEC_FILE_EXECUTE,
+		   share_access, NTCREATEX_SHARE_ACCESS_READ);
+	CHECK_MASK(access_mask, SEC_FILE_READ_DATA | SEC_FILE_EXECUTE,
 		   e1->share_access, NTCREATEX_SHARE_ACCESS_READ);
 
 	CHECK_MASK(e1->access_mask, SEC_STD_DELETE,
-		   e2->share_access, NTCREATEX_SHARE_ACCESS_DELETE);
-	CHECK_MASK(e2->access_mask, SEC_STD_DELETE,
+		   share_access, NTCREATEX_SHARE_ACCESS_DELETE);
+	CHECK_MASK(access_mask, SEC_STD_DELETE,
 		   e1->share_access, NTCREATEX_SHARE_ACCESS_DELETE);
 #undef CHECK_MASK
 	return NT_STATUS_OK;
@@ -303,53 +306,20 @@ static bool access_attributes_only(uint32_t access_mask,
 #undef CHECK_MASK
 }
 
-/*
-  register an open file in the open files database. This implements the share_access
-  rules
-
-  Note that the path is only used by the delete on close logic, not
-  for comparing with other filenames
-*/
-static NTSTATUS odb_tdb_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,
-				  const char *path, 
-				  uint32_t oplock_level, uint32_t *oplock_granted)
+static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb,
+					  const struct opendb_file *file,
+					  uint32_t stream_id, uint32_t share_access,
+					  uint32_t access_mask, bool delete_on_close,
+					  uint32_t open_disposition, bool break_to_none,
+					  bool *_attrs_only)
 {
-	struct odb_context *odb = lck->odb;
-	struct opendb_entry e;
-	int i;
-	struct opendb_file file;
 	NTSTATUS status;
-	uint32_t open_disposition = 0;
-	bool break_to_none = false;
+	uint32_t i;
 	bool attrs_only = false;
 
-	if (odb->oplocks == false) {
-		oplock_level = OPLOCK_NONE;
-	}
-
-	status = odb_pull_record(lck, &file);
-	if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
-		/* initialise a blank structure */
-		ZERO_STRUCT(file);
-		file.path = path;
-	} else {
-		NT_STATUS_NOT_OK_RETURN(status);
-	}
-
-	/* see if it conflicts */
-	e.server          = odb->ntvfs_ctx->server_id;
-	e.file_handle     = file_handle;
-	e.stream_id       = stream_id;
-	e.share_access    = share_access;
-	e.access_mask     = access_mask;
-	e.delete_on_close = delete_on_close;
-	e.oplock_level    = OPLOCK_NONE;
-		
 	/* see if anyone has an oplock, which we need to break */
-	for (i=0;inum_entries;i++) {
+		if (file->entries[i].oplock_level == OPLOCK_BATCH) {
 			bool oplock_return = OPLOCK_BREAK_TO_LEVEL_II;
 			/* if this is an attribute only access
 			 * it doesn't conflict with a BACTCH oplock
@@ -370,21 +340,22 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle,
 			if (break_to_none) {
 				oplock_return = OPLOCK_BREAK_TO_NONE;
 			}
-			odb_oplock_break_send(odb, &file.entries[i],
+			odb_oplock_break_send(odb, &file->entries[i],
 					      oplock_return);
 			return NT_STATUS_OPLOCK_NOT_GRANTED;
 		}
 	}
 
-	if (file.delete_on_close || 
-	    (file.num_entries != 0 && delete_on_close)) {
+	if (file->delete_on_close ||
+	    (file->num_entries != 0 && delete_on_close)) {
 		/* while delete on close is set, no new opens are allowed */
 		return NT_STATUS_DELETE_PENDING;
 	}
 
 	/* check for sharing violations */
-	for (i=0;inum_entries;i++) {
+		status = share_conflict(&file->entries[i], stream_id,
+					share_access, access_mask);
 		NT_STATUS_NOT_OK_RETURN(status);
 	}
 
@@ -393,14 +364,70 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle,
 	   till these are broken. Note that we check for batch oplocks
 	   before checking for sharing violations, and check for
 	   exclusive oplocks afterwards. */
-	for (i=0;inum_entries;i++) {
+		if (file->entries[i].oplock_level == OPLOCK_EXCLUSIVE) {
+			odb_oplock_break_send(odb, &file->entries[i],
 					      OPLOCK_BREAK_TO_NONE);
 			return NT_STATUS_OPLOCK_NOT_GRANTED;
 		}
 	}
 
+	if (_attrs_only) {
+		*_attrs_only = attrs_only;
+	}
+	return NT_STATUS_OK;
+}
+
+/*
+  register an open file in the open files database. This implements the share_access
+  rules
+
+  Note that the path is only used by the delete on close logic, not
+  for comparing with other filenames
+*/
+static NTSTATUS odb_tdb_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,
+				  const char *path,
+				  uint32_t oplock_level, uint32_t *oplock_granted)
+{
+	struct odb_context *odb = lck->odb;
+	struct opendb_entry e;
+	struct opendb_file file;
+	NTSTATUS status;
+	uint32_t open_disposition = 0;
+	bool break_to_none = false;
+	bool attrs_only = false;
+
+	if (odb->oplocks == false) {
+		oplock_level = OPLOCK_NONE;
+	}
+
+	status = odb_pull_record(lck, &file);
+	if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+		/* initialise a blank structure */
+		ZERO_STRUCT(file);
+		file.path = path;
+	} else {
+		NT_STATUS_NOT_OK_RETURN(status);
+	}
+
+	/* see if it conflicts */
+	status = odb_tdb_open_can_internal(odb, &file, stream_id,
+					   share_access, access_mask,
+					   delete_on_close, open_disposition,
+					   break_to_none, &attrs_only);
+	NT_STATUS_NOT_OK_RETURN(status);
+
+	/* see if it conflicts */
+	e.server          = odb->ntvfs_ctx->server_id;
+	e.file_handle     = file_handle;
+	e.stream_id       = stream_id;
+	e.share_access    = share_access;
+	e.access_mask     = access_mask;
+	e.delete_on_close = delete_on_close;
+	e.oplock_level    = OPLOCK_NONE;
+
 	/*
 	  possibly grant an exclusive, batch or level2 oplock
 	*/
@@ -719,8 +746,11 @@ static NTSTATUS odb_tdb_can_open(struct odb_lock *lck,
 	struct odb_context *odb = lck->odb;
 	NTSTATUS status;
 	struct opendb_file file;
-	struct opendb_entry e;
-	int i;
+	uint32_t stream_id = 0;
+	uint32_t open_disposition = 0;
+	bool delete_on_close = false;
+	bool break_to_none = false;
+	bool attrs_only = false;
 
 	status = odb_pull_record(lck, &file);
 	if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
@@ -728,32 +758,15 @@ static NTSTATUS odb_tdb_can_open(struct odb_lock *lck,
 	}
 	NT_STATUS_NOT_OK_RETURN(status);
 
-	if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && 
-	    file.num_entries != 0) {
-		return NT_STATUS_SHARING_VIOLATION;
+	if (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) {
+		delete_on_close = true;
 	}
 
-	if (file.delete_on_close) {
-		return NT_STATUS_DELETE_PENDING;
-	}
-
-	e.server       = odb->ntvfs_ctx->server_id;
-	e.file_handle  = NULL;
-	e.stream_id    = 0;
-	e.share_access = share_access;
-	e.access_mask  = access_mask;
-		
-	for (i=0;i
Date: Mon, 25 Feb 2008 20:20:35 +0100
Subject: opendb_tdb: only file->delete_on_close == true should give
 DELETE_PENDING

metze
(This used to be commit 5b12157e0f0f1cf6ea90503a72b56ab2032cb6e5)
---
 source4/ntvfs/common/opendb_tdb.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c
index 9c273f9617..8b5e4850d9 100644
--- a/source4/ntvfs/common/opendb_tdb.c
+++ b/source4/ntvfs/common/opendb_tdb.c
@@ -346,12 +346,15 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb,
 		}
 	}
 
-	if (file->delete_on_close ||
-	    (file->num_entries != 0 && delete_on_close)) {
+	if (file->delete_on_close) {
 		/* while delete on close is set, no new opens are allowed */
 		return NT_STATUS_DELETE_PENDING;
 	}
 
+	if (file->num_entries != 0 && delete_on_close) {
+		return NT_STATUS_SHARING_VIOLATION;
+	}
+
 	/* check for sharing violations */
 	for (i=0;inum_entries;i++) {
 		status = share_conflict(&file->entries[i], stream_id,
-- 
cgit 


From 69631a215b655415477ee0e71a08beca86dd5b2f Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Tue, 26 Feb 2008 09:14:54 +0100
Subject: pvfs_setfileinfo_rename: map DELETE_PENDING to ACCESS_DENIED

This is needed as odb_can_open/pvfs_can_delete changed the return value.

metze
(This used to be commit 1ba0b9a8f1f84c7c949b3d184843462b87446707)
---
 source4/ntvfs/posix/pvfs_setfileinfo.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c
index fbbb8c2d4b..c6d014a72f 100644
--- a/source4/ntvfs/posix/pvfs_setfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_setfileinfo.c
@@ -152,6 +152,9 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs,
 		}
 
 		status = pvfs_can_delete(pvfs, req, name2, NULL);
+		if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) {
+			return NT_STATUS_ACCESS_DENIED;
+		}
 		if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
 			return NT_STATUS_ACCESS_DENIED;
 		}
-- 
cgit 


From facdc472c7e6dbca0553a5e0dfb100be322339ce Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Mon, 25 Feb 2008 16:47:48 +0100
Subject: opendb: pass down open_disposition and break_to_none to
 odb_open_file()

metze
(This used to be commit aaaa26ae5e810495f313dfada771a8de86cedbd4)
---
 source4/cluster/ctdb/opendb_ctdb.c | 12 +++++++-----
 source4/ntvfs/common/opendb.c      | 13 +++++++------
 source4/ntvfs/common/opendb.h      |  7 ++++---
 source4/ntvfs/common/opendb_tdb.c  |  7 +++----
 4 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/source4/cluster/ctdb/opendb_ctdb.c b/source4/cluster/ctdb/opendb_ctdb.c
index 915b760424..36ae204974 100644
--- a/source4/cluster/ctdb/opendb_ctdb.c
+++ b/source4/cluster/ctdb/opendb_ctdb.c
@@ -279,11 +279,13 @@ static NTSTATUS odb_oplock_break_send(struct odb_context *odb, struct opendb_ent
   Note that the path is only used by the delete on close logic, not
   for comparing with other filenames
 */
-static NTSTATUS odb_ctdb_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,
-				  const char *path, 
-				  uint32_t oplock_level, uint32_t *oplock_granted)
+static NTSTATUS odb_ctdb_open_file(struct odb_lock *lck,
+				   void *file_handle, const char *path,
+				   uint32_t stream_id, uint32_t share_access,
+				   uint32_t access_mask, bool delete_on_close,
+				   uint32_t open_disposition, bool break_to_none,
+				   uint32_t oplock_level, uint32_t *oplock_granted)
+
 {
 	struct odb_context *odb = lck->odb;
 	struct opendb_entry e;
diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c
index 3f5d7210be..c380355466 100644
--- a/source4/ntvfs/common/opendb.c
+++ b/source4/ntvfs/common/opendb.c
@@ -93,15 +93,16 @@ _PUBLIC_ DATA_BLOB odb_get_key(TALLOC_CTX *mem_ctx, struct odb_lock *lck)
   Note that the path is only used by the delete on close logic, not
   for comparing with other filenames
 */
-_PUBLIC_ NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle,
-				uint32_t stream_id, uint32_t share_access, 
+_PUBLIC_ NTSTATUS odb_open_file(struct odb_lock *lck,
+				void *file_handle, const char *path,
+				uint32_t stream_id, uint32_t share_access,
 				uint32_t access_mask, bool delete_on_close,
-				const char *path, 
+				uint32_t open_disposition, bool break_to_none,
 				uint32_t oplock_level, uint32_t *oplock_granted)
 {
-	return ops->odb_open_file(lck, file_handle, stream_id, share_access,
-				  access_mask, delete_on_close, path, oplock_level,
-				  oplock_granted);
+	return ops->odb_open_file(lck, file_handle, path, stream_id, share_access,
+				  access_mask, delete_on_close, open_disposition,
+				  break_to_none, oplock_level, oplock_granted);
 }
 
 
diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h
index c46390446c..205d2228ea 100644
--- a/source4/ntvfs/common/opendb.h
+++ b/source4/ntvfs/common/opendb.h
@@ -25,10 +25,11 @@ struct opendb_ops {
 	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, 
+	NTSTATUS (*odb_open_file)(struct odb_lock *lck,
+				  void *file_handle, const char *path,
+				  uint32_t stream_id, uint32_t share_access,
 				  uint32_t access_mask, bool delete_on_close,
-				  const char *path, 
+				  uint32_t open_disposition, bool break_to_none,
 				  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);
diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c
index 8b5e4850d9..d41a5c371e 100644
--- a/source4/ntvfs/common/opendb_tdb.c
+++ b/source4/ntvfs/common/opendb_tdb.c
@@ -388,18 +388,17 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb,
   Note that the path is only used by the delete on close logic, not
   for comparing with other filenames
 */
-static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle,
+static NTSTATUS odb_tdb_open_file(struct odb_lock *lck,
+				  void *file_handle, const char *path,
 				  uint32_t stream_id, uint32_t share_access,
 				  uint32_t access_mask, bool delete_on_close,
-				  const char *path,
+				  uint32_t open_disposition, bool break_to_none,
 				  uint32_t oplock_level, uint32_t *oplock_granted)
 {
 	struct odb_context *odb = lck->odb;
 	struct opendb_entry e;
 	struct opendb_file file;
 	NTSTATUS status;
-	uint32_t open_disposition = 0;
-	bool break_to_none = false;
 	bool attrs_only = false;
 
 	if (odb->oplocks == false) {
-- 
cgit 


From 9852e0d31582f669179c2a8c8ebdb263fef611f2 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Mon, 25 Feb 2008 16:49:40 +0100
Subject: pvfs_open: pass down open_disposition and break_to_none to
 odb_open_file()

metze
(This used to be commit 46500983fe2f63540a67e2e963ab264fa8a090d0)
---
 source4/ntvfs/posix/pvfs_open.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index 3a8b17ab16..1b5ea56d64 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -296,9 +296,10 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
 		}
 		
 		/* see if we are allowed to open at the same time as existing opens */
-		status = odb_open_file(lck, f->handle, f->handle->name->stream_id,
+		status = odb_open_file(lck, f->handle, name->full_name, name->stream_id,
 				       share_access, access_mask, del_on_close, 
-				       name->full_name, OPLOCK_NONE, NULL);
+				       io->generic.in.open_disposition,
+				       false, OPLOCK_NONE, NULL);
 
 		if (!NT_STATUS_IS_OK(status)) {
 			talloc_free(lck);
@@ -349,9 +350,10 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
 			return NT_STATUS_INTERNAL_DB_CORRUPTION;
 		}
 
-		status = odb_open_file(lck, f->handle, f->handle->name->stream_id,
+		status = odb_open_file(lck, f->handle, name->full_name, name->stream_id,
 				       share_access, access_mask, del_on_close, 
-				       name->full_name, OPLOCK_NONE, NULL);
+				       io->generic.in.open_disposition,
+				       false, OPLOCK_NONE, NULL);
 
 		if (!NT_STATUS_IS_OK(status)) {
 			goto cleanup_delete;
@@ -669,9 +671,10 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
 		oplock_level = OPLOCK_EXCLUSIVE;
 	}
 
-	status = odb_open_file(lck, f->handle, name->stream_id,
+	status = odb_open_file(lck, f->handle, name->full_name, name->stream_id,
 			       share_access, access_mask, del_on_close, 
-			       name->full_name, oplock_level, &oplock_granted);
+			       io->generic.in.open_disposition,
+			       false, oplock_level, &oplock_granted);
 	talloc_free(lck);
 	if (!NT_STATUS_IS_OK(status)) {
 		/* bad news, we must have hit a race - we don't delete the file
@@ -1186,9 +1189,10 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
 	}
 
 	/* see if we are allowed to open at the same time as existing opens */
-	status = odb_open_file(lck, f->handle, f->handle->name->stream_id,
+	status = odb_open_file(lck, f->handle, name->full_name, name->stream_id,
 			       share_access, access_mask, del_on_close,
-			       name->full_name, oplock_level, &oplock_granted);
+			       io->generic.in.open_disposition,
+			       false, oplock_level, &oplock_granted);
 
 	/* on a sharing violation we need to retry when the file is closed by 
 	   the other user, or after 1 second */
-- 
cgit 


From 7264a8b7ca5f91120dbc30fcbe8e8402f09ae883 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Mon, 25 Feb 2008 17:48:13 +0100
Subject: opendb: unify the parameters of odb_open_file() and odb_can_open()

metze
(This used to be commit e6b708a52b0eada3fd374b66292ded3b0f6ce217)
---
 source4/cluster/ctdb/opendb_ctdb.c |  7 ++++---
 source4/ntvfs/common/opendb.c      |  8 +++++---
 source4/ntvfs/common/opendb.h      |  5 +++--
 source4/ntvfs/common/opendb_tdb.c  | 13 +++----------
 4 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/source4/cluster/ctdb/opendb_ctdb.c b/source4/cluster/ctdb/opendb_ctdb.c
index 36ae204974..3dfc6819b7 100644
--- a/source4/cluster/ctdb/opendb_ctdb.c
+++ b/source4/cluster/ctdb/opendb_ctdb.c
@@ -596,8 +596,9 @@ static NTSTATUS odb_ctdb_get_delete_on_close(struct odb_context *odb,
   create_options and access_mask
 */
 static NTSTATUS odb_ctdb_can_open(struct odb_lock *lck,
-				 uint32_t share_access, uint32_t create_options, 
-				 uint32_t access_mask)
+				  uint32_t stream_id, uint32_t share_access,
+				  uint32_t access_mask, bool delete_on_close,
+				  uint32_t open_disposition, bool break_to_none)
 {
 	struct odb_context *odb = lck->odb;
 	NTSTATUS status;
@@ -611,7 +612,7 @@ static NTSTATUS odb_ctdb_can_open(struct odb_lock *lck,
 	}
 	NT_STATUS_NOT_OK_RETURN(status);
 
-	if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && 
+	if (delete_on_close &&
 	    file.num_entries != 0) {
 		return NT_STATUS_SHARING_VIOLATION;
 	}
diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c
index c380355466..36144d0406 100644
--- a/source4/ntvfs/common/opendb.c
+++ b/source4/ntvfs/common/opendb.c
@@ -166,10 +166,12 @@ _PUBLIC_ NTSTATUS odb_get_delete_on_close(struct odb_context *odb,
   create_options and access_mask
 */
 _PUBLIC_ NTSTATUS odb_can_open(struct odb_lock *lck,
-			       uint32_t share_access, uint32_t create_options, 
-			       uint32_t access_mask)
+			       uint32_t stream_id, uint32_t share_access,
+			       uint32_t access_mask, bool delete_on_close,
+			       uint32_t open_disposition, bool break_to_none)
 {
-	return ops->odb_can_open(lck, share_access, create_options, access_mask);
+	return ops->odb_can_open(lck, stream_id, share_access, access_mask,
+				 delete_on_close, open_disposition, break_to_none);
 }
 
 _PUBLIC_ NTSTATUS odb_update_oplock(struct odb_lock *lck, void *file_handle,
diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h
index 205d2228ea..9591bcf6b9 100644
--- a/source4/ntvfs/common/opendb.h
+++ b/source4/ntvfs/common/opendb.h
@@ -40,8 +40,9 @@ struct opendb_ops {
 					    DATA_BLOB *key, bool *del_on_close, 
 					    int *open_count, char **path);
 	NTSTATUS (*odb_can_open)(struct odb_lock *lck,
-				 uint32_t share_access, uint32_t create_options, 
-				 uint32_t access_mask);
+				 uint32_t stream_id, uint32_t share_access,
+				 uint32_t access_mask, bool delete_on_close,
+				 uint32_t open_disposition, bool break_to_none);
 	NTSTATUS (*odb_update_oplock)(struct odb_lock *lck, void *file_handle,
 				      uint32_t oplock_level);
 	NTSTATUS (*odb_break_oplocks)(struct odb_lock *lck);
diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c
index d41a5c371e..73c04b7c4f 100644
--- a/source4/ntvfs/common/opendb_tdb.c
+++ b/source4/ntvfs/common/opendb_tdb.c
@@ -742,16 +742,13 @@ static NTSTATUS odb_tdb_get_delete_on_close(struct odb_context *odb,
   create_options and access_mask
 */
 static NTSTATUS odb_tdb_can_open(struct odb_lock *lck,
-				 uint32_t share_access, uint32_t create_options, 
-				 uint32_t access_mask)
+				 uint32_t stream_id, uint32_t share_access,
+				 uint32_t access_mask, bool delete_on_close,
+				 uint32_t open_disposition, bool break_to_none)
 {
 	struct odb_context *odb = lck->odb;
 	NTSTATUS status;
 	struct opendb_file file;
-	uint32_t stream_id = 0;
-	uint32_t open_disposition = 0;
-	bool delete_on_close = false;
-	bool break_to_none = false;
 	bool attrs_only = false;
 
 	status = odb_pull_record(lck, &file);
@@ -760,10 +757,6 @@ static NTSTATUS odb_tdb_can_open(struct odb_lock *lck,
 	}
 	NT_STATUS_NOT_OK_RETURN(status);
 
-	if (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) {
-		delete_on_close = true;
-	}
-
 	status = odb_tdb_open_can_internal(odb, &file, stream_id,
 					   share_access, access_mask,
 					   delete_on_close, open_disposition,
-- 
cgit 


From c93cf42d9fe4f1e382a762e7c1eafef0dff122c1 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Mon, 25 Feb 2008 17:50:22 +0100
Subject: pvfs_open: fix odb_can_open() callers after prototype change

metze
(This used to be commit 904159327b3cb80fbec6aa5a4feaa141190a3f3a)
---
 source4/ntvfs/posix/pvfs_open.c | 51 ++++++++++++++++++++++++++++-------------
 1 file changed, 35 insertions(+), 16 deletions(-)

diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index 1b5ea56d64..bbfe4ac733 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -1428,6 +1428,9 @@ NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs,
 	NTSTATUS status;
 	DATA_BLOB key;
 	struct odb_lock *lck;
+	uint32_t share_access;
+	uint32_t access_mask;
+	bool delete_on_close;
 
 	status = pvfs_locking_key(name, name, &key);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -1440,15 +1443,18 @@ NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs,
 		return NT_STATUS_INTERNAL_DB_CORRUPTION;
 	}
 
-	status = odb_can_open(lck,
-			      NTCREATEX_SHARE_ACCESS_READ |
-			      NTCREATEX_SHARE_ACCESS_WRITE | 
-			      NTCREATEX_SHARE_ACCESS_DELETE, 
-			      NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 
-			      SEC_STD_DELETE);
+	share_access	= NTCREATEX_SHARE_ACCESS_READ |
+			  NTCREATEX_SHARE_ACCESS_WRITE |
+			  NTCREATEX_SHARE_ACCESS_DELETE;
+	access_mask	= SEC_STD_DELETE;
+	delete_on_close	= true;
+
+	status = odb_can_open(lck, name->stream_id,
+			      share_access, access_mask, delete_on_close,
+			      0, false);
 
 	if (NT_STATUS_IS_OK(status)) {
-		status = pvfs_access_check_simple(pvfs, req, name, SEC_STD_DELETE);
+		status = pvfs_access_check_simple(pvfs, req, name, access_mask);
 	}
 
 	/*
@@ -1487,6 +1493,9 @@ NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs,
 	NTSTATUS status;
 	DATA_BLOB key;
 	struct odb_lock *lck;
+	uint32_t share_access;
+	uint32_t access_mask;
+	bool delete_on_close;
 
 	status = pvfs_locking_key(name, name, &key);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -1499,11 +1508,14 @@ NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs,
 		return NT_STATUS_INTERNAL_DB_CORRUPTION;
 	}
 
-	status = odb_can_open(lck,
-			      NTCREATEX_SHARE_ACCESS_READ |
-			      NTCREATEX_SHARE_ACCESS_WRITE,
-			      0,
-			      SEC_STD_DELETE);
+	share_access	= NTCREATEX_SHARE_ACCESS_READ |
+			  NTCREATEX_SHARE_ACCESS_WRITE;
+	access_mask	= SEC_STD_DELETE;
+	delete_on_close	= false;
+
+	status = odb_can_open(lck, name->stream_id,
+			      share_access, access_mask, delete_on_close,
+			      0, false);
 
 	/*
 	 * if it's a sharing violation or we got no oplock
@@ -1540,6 +1552,9 @@ NTSTATUS pvfs_can_stat(struct pvfs_state *pvfs,
 	NTSTATUS status;
 	DATA_BLOB key;
 	struct odb_lock *lck;
+	uint32_t share_access;
+	uint32_t access_mask;
+	bool delete_on_close;
 
 	status = pvfs_locking_key(name, name, &key);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -1552,10 +1567,14 @@ NTSTATUS pvfs_can_stat(struct pvfs_state *pvfs,
 		return NT_STATUS_INTERNAL_DB_CORRUPTION;
 	}
 
-	status = odb_can_open(lck,
-			      NTCREATEX_SHARE_ACCESS_READ |
-			      NTCREATEX_SHARE_ACCESS_WRITE,
-			      0, 0);
+	share_access	= NTCREATEX_SHARE_ACCESS_READ |
+			  NTCREATEX_SHARE_ACCESS_WRITE;
+	access_mask	= 0;
+	delete_on_close	= false;
+
+	status = odb_can_open(lck, name->stream_id,
+			      share_access, access_mask, delete_on_close,
+			      0, false);
 
 	if (!NT_STATUS_IS_OK(status)) {
 		talloc_free(lck);
-- 
cgit 


From d7ea52e9a3cd920f7c8a3b00f7cd28a7f605a993 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Thu, 21 Feb 2008 17:48:13 +0100
Subject: pvfs_open: make the retry logic indepdendent from open and sharing
 violations

metze
(This used to be commit 56bd63a4236ebf360d3e805c8560df86759573f7)
---
 source4/ntvfs/posix/pvfs_open.c | 149 ++++++++++++++++++++++++++--------------
 source4/ntvfs/posix/vfs_posix.h |   5 ++
 2 files changed, 104 insertions(+), 50 deletions(-)

diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index bbfe4ac733..8e1870fa70 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -751,20 +751,25 @@ cleanup_delete:
 	return status;
 }
 
-
 /*
-  state of a pending open retry
+  state of a pending retry
 */
-struct pvfs_open_retry {
+struct pvfs_odb_retry {
 	struct ntvfs_module_context *ntvfs;
 	struct ntvfs_request *req;
-	union smb_open *io;
-	struct pvfs_wait *wait_handle;
 	DATA_BLOB odb_locking_key;
+	void *io;
+	void *private_data;
+	void (*callback)(struct pvfs_odb_retry *r,
+			 struct ntvfs_module_context *ntvfs,
+			 struct ntvfs_request *req,
+			 void *io,
+			 void *private_data,
+			 enum pvfs_wait_notice reason);
 };
 
-/* destroy a pending open request */
-static int pvfs_retry_destructor(struct pvfs_open_retry *r)
+/* destroy a pending request */
+static int pvfs_odb_retry_destructor(struct pvfs_odb_retry *r)
 {
 	struct pvfs_state *pvfs = r->ntvfs->private_data;
 	if (r->odb_locking_key.data) {
@@ -778,15 +783,92 @@ static int pvfs_retry_destructor(struct pvfs_open_retry *r)
 	return 0;
 }
 
+static void pvfs_odb_retry_callback(void *_r, enum pvfs_wait_notice reason)
+{
+	struct pvfs_odb_retry *r = talloc_get_type(_r, struct pvfs_odb_retry);
+
+	if (reason == PVFS_WAIT_EVENT) {
+		/*
+		 * The pending odb entry is already removed.
+		 * We use a null locking key to indicate this
+		 * to the destructor.
+		 */
+		data_blob_free(&r->odb_locking_key);
+	}
+
+	r->callback(r, r->ntvfs, r->req, r->io, r->private_data, reason);
+}
+
 /*
-  retry an open
+  setup for a retry of a request that was rejected
+  by odb_open_file() or odb_can_open()
 */
-static void pvfs_open_retry(void *private, enum pvfs_wait_notice reason)
+NTSTATUS pvfs_odb_retry_setup(struct ntvfs_module_context *ntvfs,
+			      struct ntvfs_request *req,
+			      struct odb_lock *lck,
+			      struct timeval end_time,
+			      void *io,
+			      void *private_data,
+			      void (*callback)(struct pvfs_odb_retry *r,
+					       struct ntvfs_module_context *ntvfs,
+					       struct ntvfs_request *req,
+					       void *io,
+					       void *private_data,
+					       enum pvfs_wait_notice reason))
 {
-	struct pvfs_open_retry *r = private;
-	struct ntvfs_module_context *ntvfs = r->ntvfs;
-	struct ntvfs_request *req = r->req;
-	union smb_open *io = r->io;
+	struct pvfs_state *pvfs = ntvfs->private_data;
+	struct pvfs_odb_retry *r;
+	struct pvfs_wait *wait_handle;
+	NTSTATUS status;
+
+	r = talloc(req, struct pvfs_odb_retry);
+	NT_STATUS_HAVE_NO_MEMORY(r);
+
+	r->ntvfs = ntvfs;
+	r->req = req;
+	r->io = io;
+	r->private_data = private_data;
+	r->callback = callback;
+	r->odb_locking_key = odb_get_key(r, lck);
+	if (r->odb_locking_key.data == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	/* setup a pending lock */
+	status = odb_open_file_pending(lck, r);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	talloc_free(lck);
+
+	talloc_set_destructor(r, pvfs_odb_retry_destructor);
+
+	wait_handle = pvfs_wait_message(pvfs, req,
+					MSG_PVFS_RETRY_OPEN, end_time,
+					pvfs_odb_retry_callback, r);
+	if (wait_handle == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	talloc_steal(r, wait_handle);
+
+	talloc_steal(pvfs, r);
+
+	return NT_STATUS_OK;
+}
+
+/*
+  retry an open after a sharing violation
+*/
+static void pvfs_retry_open_sharing(struct pvfs_odb_retry *r,
+				    struct ntvfs_module_context *ntvfs,
+				    struct ntvfs_request *req,
+				    void *_io,
+				    void *private_data,
+				    enum pvfs_wait_notice reason)
+{
+	union smb_open *io = talloc_get_type(_io, union smb_open);
 	NTSTATUS status;
 
 	/* w2k3 ignores SMBntcancel for outstanding open requests. It's probably
@@ -795,8 +877,6 @@ static void pvfs_open_retry(void *private, enum pvfs_wait_notice reason)
 		return;
 	}
 
-	talloc_free(r->wait_handle);
-
 	if (reason == PVFS_WAIT_TIMEOUT) {
 		/* if it timed out, then give the failure
 		   immediately */
@@ -806,9 +886,6 @@ static void pvfs_open_retry(void *private, enum pvfs_wait_notice reason)
 		return;
 	}
 
-	/* the pending odb entry is already removed. We use a null locking
-	   key to indicate this */
-	data_blob_free(&r->odb_locking_key);
 	talloc_free(r);
 
 	/* try the open again, which could trigger another retry setup
@@ -925,7 +1002,6 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs,
 				      struct odb_lock *lck)
 {
 	struct pvfs_state *pvfs = ntvfs->private_data;
-	struct pvfs_open_retry *r;
 	NTSTATUS status;
 	struct timeval end_time;
 
@@ -939,40 +1015,13 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs,
 		}
 	}
 
-	r = talloc(req, struct pvfs_open_retry);
-	if (r == NULL) {
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	r->ntvfs = ntvfs;
-	r->req = req;
-	r->io = io;
-	r->odb_locking_key = data_blob_talloc(r, 
-					      f->handle->odb_locking_key.data, 
-					      f->handle->odb_locking_key.length);
-
-	end_time = timeval_add(&req->statistics.request_time, 0, pvfs->sharing_violation_delay);
-
-	/* setup a pending lock */
-	status = odb_open_file_pending(lck, r);
-	if (!NT_STATUS_IS_OK(status)) {
-		return status;
-	}
-
-	talloc_free(lck);
+	/* the retry should allocate a new file handle */
 	talloc_free(f);
 
-	talloc_set_destructor(r, pvfs_retry_destructor);
-
-	r->wait_handle = pvfs_wait_message(pvfs, req, MSG_PVFS_RETRY_OPEN, end_time, 
-					   pvfs_open_retry, r);
-	if (r->wait_handle == NULL) {
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	talloc_steal(pvfs, r);
+	end_time = timeval_add(&req->statistics.request_time, 0, pvfs->sharing_violation_delay);
 
-	return NT_STATUS_OK;
+	return pvfs_odb_retry_setup(ntvfs, req, lck, end_time, io, NULL,
+				    pvfs_retry_open_sharing);
 }
 
 /*
diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h
index 84c456dcfe..50875c3f9b 100644
--- a/source4/ntvfs/posix/vfs_posix.h
+++ b/source4/ntvfs/posix/vfs_posix.h
@@ -230,6 +230,11 @@ struct pvfs_dir;
 /* types of notification for pvfs wait events */
 enum pvfs_wait_notice {PVFS_WAIT_EVENT, PVFS_WAIT_TIMEOUT, PVFS_WAIT_CANCEL};
 
+/*
+  state of a pending retry
+*/
+struct pvfs_odb_retry;
+
 #define PVFS_EADB			"posix:eadb"
 #define PVFS_XATTR			"posix:xattr"
 #define PVFS_FAKE_OPLOCKS		"posix:fakeoplocks"
-- 
cgit 


From 95fafa694cbb6f695488c750d481bb1e427da6eb Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Mon, 25 Feb 2008 08:32:35 +0100
Subject: pvfs: add pvfs_setup_oplock() to receive oplock breaks and pass them
 to the client

metze
(This used to be commit b09a2b126723bd75afd245f549703a04e512e129)
---
 source4/ntvfs/posix/config.mk     |   1 +
 source4/ntvfs/posix/pvfs_oplock.c | 136 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 137 insertions(+)
 create mode 100644 source4/ntvfs/posix/pvfs_oplock.c

diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk
index 6879940337..88048c2af7 100644
--- a/source4/ntvfs/posix/config.mk
+++ b/source4/ntvfs/posix/config.mk
@@ -53,6 +53,7 @@ OBJ_FILES = \
 		pvfs_resolve.o \
 		pvfs_shortname.o \
 		pvfs_lock.o \
+		pvfs_oplock.o \
 		pvfs_wait.o \
 		pvfs_seek.o \
 		pvfs_ioctl.o \
diff --git a/source4/ntvfs/posix/pvfs_oplock.c b/source4/ntvfs/posix/pvfs_oplock.c
new file mode 100644
index 0000000000..50b1478f13
--- /dev/null
+++ b/source4/ntvfs/posix/pvfs_oplock.c
@@ -0,0 +1,136 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   POSIX NTVFS backend - oplock handling
+
+   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
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see .
+*/
+
+#include "includes.h"
+#include "lib/messaging/messaging.h"
+#include "lib/messaging/irpc.h"
+#include "vfs_posix.h"
+
+
+struct pvfs_oplock {
+	struct pvfs_file_handle *handle;
+	struct pvfs_file *file;
+	uint32_t level;
+	struct messaging_context *msg_ctx;
+};
+
+/*
+  receive oplock breaks and forward them to the client
+*/
+static void pvfs_oplock_break(struct pvfs_oplock *opl, uint8_t level)
+{
+	NTSTATUS status;
+	struct pvfs_file *f = opl->file;
+	struct pvfs_file_handle *h = opl->handle;
+	struct pvfs_state *pvfs = h->pvfs;
+
+	DEBUG(10,("pvfs_oplock_break: sending oplock break level %d for '%s' %p\n",
+		level, h->name->original_name, h));
+	status = ntvfs_send_oplock_break(pvfs->ntvfs, f->ntvfs, level);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0,("pvfs_oplock_break: sending oplock break failed: %s\n",
+			nt_errstr(status)));
+	}
+}
+
+static void pvfs_oplock_break_dispatch(struct messaging_context *msg,
+				       void *private_data, uint32_t msg_type,
+				       struct server_id src, DATA_BLOB *data)
+{
+	struct pvfs_oplock *opl = talloc_get_type(private_data,
+						  struct pvfs_oplock);
+	struct opendb_oplock_break opb;
+
+	ZERO_STRUCT(opb);
+
+	/* we need to check that this one is for us. See
+	   messaging_send_ptr() for the other side of this.
+	 */
+	if (data->length == sizeof(struct opendb_oplock_break)) {
+		struct opendb_oplock_break *p;
+		p = (struct opendb_oplock_break *)data->data;
+		opb = *p;
+	} else {
+		DEBUG(0,("%s: ignore oplock break with length[%u]\n",
+			__location__, data->length));
+		return;
+	}
+	if (opb.file_handle != opl->handle) {
+		return;
+	}
+
+	/*
+	 * maybe we should use ntvfs_setup_async()
+	 */
+	pvfs_oplock_break(opl, opb.level);
+}
+
+static int pvfs_oplock_destructor(struct pvfs_oplock *opl)
+{
+	messaging_deregister(opl->msg_ctx, MSG_NTVFS_OPLOCK_BREAK, opl);
+	return 0;
+}
+
+NTSTATUS pvfs_setup_oplock(struct pvfs_file *f, uint32_t oplock_granted)
+{
+	NTSTATUS status;
+	struct pvfs_oplock *opl;
+	uint32_t level = OPLOCK_NONE;
+
+	f->handle->oplock = NULL;
+
+	switch (oplock_granted) {
+	case EXCLUSIVE_OPLOCK_RETURN:
+		level = OPLOCK_EXCLUSIVE;
+		break;
+	case BATCH_OPLOCK_RETURN:
+		level = OPLOCK_BATCH;
+		break;
+	case LEVEL_II_OPLOCK_RETURN:
+		level = OPLOCK_LEVEL_II;
+		break;
+	}
+
+	if (level == OPLOCK_NONE) {
+		return NT_STATUS_OK;
+	}
+
+	opl = talloc(f->handle, struct pvfs_oplock);
+	NT_STATUS_HAVE_NO_MEMORY(opl);
+
+	opl->handle	= f->handle;
+	opl->file	= f;
+	opl->level	= level;
+	opl->msg_ctx	= f->pvfs->ntvfs->ctx->msg_ctx;
+
+	status = messaging_register(opl->msg_ctx,
+				    opl,
+				    MSG_NTVFS_OPLOCK_BREAK,
+				    pvfs_oplock_break_dispatch);
+	NT_STATUS_NOT_OK_RETURN(status);
+
+	/* destructor */
+	talloc_set_destructor(opl, pvfs_oplock_destructor);
+
+	f->handle->oplock = opl;
+
+	return NT_STATUS_OK;
+}
-- 
cgit 


From be1ba5b63164e7dab4bf067bc1aac4ed9cece2bc Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Mon, 25 Feb 2008 08:39:13 +0100
Subject: pvfs_open: call pvfs_setup_oplock() if an oplock was granted

This is needed to receive oplock breaks from other "processes"

metze
(This used to be commit dd56f55afdc0d114a0b0bceb0e4feb022919323a)
---
 source4/ntvfs/posix/pvfs_open.c | 22 +++++++++++++++++++---
 source4/ntvfs/posix/vfs_posix.h |  8 ++++++++
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index 8e1870fa70..8429c14d1b 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -268,6 +268,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
 	f->handle->seek_offset       = 0;
 	f->handle->position          = 0;
 	f->handle->mode              = 0;
+	f->handle->oplock            = NULL;
 	f->handle->sticky_write_time = false;
 	f->handle->open_completed    = false;
 
@@ -684,9 +685,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
 		return status;
 	}
 
-	if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) {
-		oplock_granted = OPLOCK_BATCH;
-	}
 
 	f->ntvfs             = h;
 	f->pvfs              = pvfs;
@@ -705,12 +703,23 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
 	f->handle->seek_offset       = 0;
 	f->handle->position          = 0;
 	f->handle->mode              = 0;
+	f->handle->oplock            = NULL;
 	f->handle->have_opendb_entry = true;
 	f->handle->sticky_write_time = false;
 	f->handle->open_completed    = false;
 
 	DLIST_ADD(pvfs->files.list, f);
 
+	if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) {
+		oplock_granted = OPLOCK_BATCH;
+	} else if (oplock_granted != OPLOCK_NONE) {
+		status = pvfs_setup_oplock(f, oplock_granted);
+		if (!NT_STATUS_IS_OK(status)) {
+			talloc_free(lck);
+			return status;
+		}
+	}
+
 	/* setup a destructor to avoid file descriptor leaks on
 	   abnormal termination */
 	talloc_set_destructor(f, pvfs_fnum_destructor);
@@ -1185,6 +1194,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
 	f->handle->seek_offset       = 0;
 	f->handle->position          = 0;
 	f->handle->mode              = 0;
+	f->handle->oplock            = NULL;
 	f->handle->have_opendb_entry = false;
 	f->handle->sticky_write_time = false;
 	f->handle->open_completed    = false;
@@ -1257,6 +1267,12 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
 
 	if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) {
 		oplock_granted = OPLOCK_BATCH;
+	} else if (oplock_granted != OPLOCK_NONE) {
+		status = pvfs_setup_oplock(f, oplock_granted);
+		if (!NT_STATUS_IS_OK(status)) {
+			talloc_free(lck);
+			return status;
+		}
 	}
 
 	f->handle->have_opendb_entry = true;
diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h
index 50875c3f9b..72469505cc 100644
--- a/source4/ntvfs/posix/vfs_posix.h
+++ b/source4/ntvfs/posix/vfs_posix.h
@@ -29,6 +29,7 @@
 #include "dsdb/samdb/samdb.h"
 
 struct pvfs_wait;
+struct pvfs_oplock;
 
 /* this is the private structure for the posix vfs backend. It is used
    to hold per-connection (per tree connect) state information */
@@ -154,6 +155,13 @@ struct pvfs_file_handle {
 
 	bool have_opendb_entry;
 
+	/*
+	 * we need to wait for oplock break requests from other processes,
+	 * and we need to remember the pvfs_file so we can correctly
+	 * forward the oplock break to the client
+	 */
+	struct pvfs_oplock *oplock;
+
 	/* we need this hook back to our parent for lock destruction */
 	struct pvfs_state *pvfs;
 
-- 
cgit 


From 4ee328d7d26f1a86559993f6533b8a1e12a4c6a1 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Mon, 25 Feb 2008 09:51:58 +0100
Subject: pvfs: handle oplock releases in its own function
 pvfs_oplock_release()

metze
(This used to be commit 27ec7bfc8b7f46c97e6878caf5cd694c517ce053)
---
 source4/ntvfs/posix/pvfs_lock.c   | 11 +++----
 source4/ntvfs/posix/pvfs_oplock.c | 64 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+), 7 deletions(-)

diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c
index df85b2b775..0796286b7e 100644
--- a/source4/ntvfs/posix/pvfs_lock.c
+++ b/source4/ntvfs/posix/pvfs_lock.c
@@ -294,6 +294,10 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs,
 		return ntvfs_map_lock(ntvfs, req, lck);
 	}
 
+	if (lck->lockx.in.mode & LOCKING_ANDX_OPLOCK_RELEASE) {
+		return pvfs_oplock_release(ntvfs, req, lck);
+	}
+
 	f = pvfs_find_fd(pvfs, req, lck->lockx.in.file.ntvfs);
 	if (!f) {
 		return NT_STATUS_INVALID_HANDLE;
@@ -338,13 +342,6 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs,
 		return NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks);
 	}
 
-	if (lck->lockx.in.mode & LOCKING_ANDX_OPLOCK_RELEASE) {
-		DEBUG(0,("received unexpected oplock break\n"));
-		talloc_free(pending);
-		return NT_STATUS_NOT_IMPLEMENTED;
-	}
-
-
 	/* the unlocks happen first */
 	locks = lck->lockx.in.locks;
 
diff --git a/source4/ntvfs/posix/pvfs_oplock.c b/source4/ntvfs/posix/pvfs_oplock.c
index 50b1478f13..eff9ae1f1d 100644
--- a/source4/ntvfs/posix/pvfs_oplock.c
+++ b/source4/ntvfs/posix/pvfs_oplock.c
@@ -134,3 +134,67 @@ NTSTATUS pvfs_setup_oplock(struct pvfs_file *f, uint32_t oplock_granted)
 
 	return NT_STATUS_OK;
 }
+
+NTSTATUS pvfs_oplock_release(struct ntvfs_module_context *ntvfs,
+			     struct ntvfs_request *req, union smb_lock *lck)
+{
+	struct pvfs_state *pvfs = ntvfs->private_data;
+	struct pvfs_file *f;
+	struct pvfs_file_handle *h;
+	struct odb_lock *olck;
+	uint8_t oplock_break;
+	NTSTATUS status;
+
+	f = pvfs_find_fd(pvfs, req, lck->lockx.in.file.ntvfs);
+	if (!f) {
+		return NT_STATUS_INVALID_HANDLE;
+	}
+
+	h = f->handle;
+
+	if (h->fd == -1) {
+		return NT_STATUS_FILE_IS_A_DIRECTORY;
+	}
+
+	if (!h->have_opendb_entry) {
+		return NT_STATUS_FOOBAR;
+	}
+
+	if (!h->oplock) {
+		return NT_STATUS_FOOBAR;
+	}
+
+	olck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key);
+	if (olck == NULL) {
+		DEBUG(0,("Unable to lock opendb for oplock update\n"));
+		return NT_STATUS_FOOBAR;
+	}
+
+	oplock_break = (lck->lockx.in.mode >> 8) & 0xFF;
+	if (oplock_break == OPLOCK_BREAK_TO_NONE) {
+		h->oplock->level = OPLOCK_NONE;
+	} else if (oplock_break == OPLOCK_BREAK_TO_LEVEL_II) {
+		h->oplock->level = OPLOCK_LEVEL_II;
+	} else {
+		/* fallback to level II in case of a invalid value */
+		DEBUG(1,("unexpected oplock break level[0x%02X]\n", oplock_break));
+		h->oplock->level = OPLOCK_LEVEL_II;
+	}
+	status = odb_update_oplock(olck, h, h->oplock->level);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0,("Unable to update oplock level for '%s' - %s\n",
+			 h->name->full_name, nt_errstr(status)));
+		talloc_free(olck);
+		return status;
+	}
+
+	talloc_free(olck);
+
+	/* after a break to none, we no longer have an oplock attached */
+	if (h->oplock->level == OPLOCK_NONE) {
+		talloc_free(h->oplock);
+		h->oplock = NULL;
+	}
+
+	return NT_STATUS_OK;
+}
-- 
cgit 


From 348439e9301fa3b07f5263a6dabc61557a384179 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Fri, 22 Feb 2008 16:34:50 +0100
Subject: pvfs_oplocks: add pvfs_break_level2_oplocks()

metze
(This used to be commit e0837238b6b09143970f03b6a78201c3fe55f3cd)
---
 source4/ntvfs/posix/pvfs_oplock.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/source4/ntvfs/posix/pvfs_oplock.c b/source4/ntvfs/posix/pvfs_oplock.c
index eff9ae1f1d..cf30ddbc59 100644
--- a/source4/ntvfs/posix/pvfs_oplock.c
+++ b/source4/ntvfs/posix/pvfs_oplock.c
@@ -198,3 +198,42 @@ NTSTATUS pvfs_oplock_release(struct ntvfs_module_context *ntvfs,
 
 	return NT_STATUS_OK;
 }
+
+NTSTATUS pvfs_break_level2_oplocks(struct pvfs_file *f)
+{
+	struct pvfs_file_handle *h = f->handle;
+	struct odb_lock *olck;
+	NTSTATUS status;
+
+	if (h->oplock && h->oplock->level == OPLOCK_EXCLUSIVE) {
+		return NT_STATUS_OK;
+	}
+
+	olck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key);
+	if (olck == NULL) {
+		DEBUG(0,("Unable to lock opendb for oplock update\n"));
+		return NT_STATUS_FOOBAR;
+	}
+
+	if (h->oplock && h->oplock->level == OPLOCK_BATCH) {
+		status = odb_update_oplock(olck, h, OPLOCK_LEVEL_II);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(0,("Unable to update oplock level for '%s' - %s\n",
+				 h->name->full_name, nt_errstr(status)));
+			talloc_free(olck);
+			return status;
+		}
+	}
+
+	status = odb_break_oplocks(olck);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0,("Unable to break level2 oplocks to none for '%s' - %s\n",
+			 h->name->full_name, nt_errstr(status)));
+		talloc_free(olck);
+		return status;
+	}
+
+	talloc_free(olck);
+
+	return NT_STATUS_OK;
+}
-- 
cgit 


From 4344ac6209df4be2dad6a8b1c0766101f5972f13 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Fri, 22 Feb 2008 16:34:50 +0100
Subject: pvfs: send oplock breaks to none to level2 holders on write/lock
 requests

metze
(This used to be commit b8c42a1ff8fd4131ef2a1ad92a7405a2e4d335d3)
---
 source4/ntvfs/posix/pvfs_lock.c  | 3 +++
 source4/ntvfs/posix/pvfs_write.c | 5 ++++-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c
index 0796286b7e..baa92880f1 100644
--- a/source4/ntvfs/posix/pvfs_lock.c
+++ b/source4/ntvfs/posix/pvfs_lock.c
@@ -307,6 +307,9 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs,
 		return NT_STATUS_FILE_IS_A_DIRECTORY;
 	}
 
+	status = pvfs_break_level2_oplocks(f);
+	NT_STATUS_NOT_OK_RETURN(status);
+
 	if (lck->lockx.in.timeout != 0 && 
 	    (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
 		pending = talloc(f, struct pvfs_pending_lock);
diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c
index 5a11f01952..dda8c83407 100644
--- a/source4/ntvfs/posix/pvfs_write.c
+++ b/source4/ntvfs/posix/pvfs_write.c
@@ -57,7 +57,10 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs,
 				 wr->writex.in.count,
 				 WRITE_LOCK);
 	NT_STATUS_NOT_OK_RETURN(status);
-	
+
+	status = pvfs_break_level2_oplocks(f);
+	NT_STATUS_NOT_OK_RETURN(status);
+
 	if (f->handle->name->stream_name) {
 		ret = pvfs_stream_write(pvfs,
 					f->handle,
-- 
cgit 


From ee81b7a85e8bb749a00c85bfdcf8f1e341ad2eea Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Sat, 23 Feb 2008 11:46:43 +0100
Subject: pvfs_setfileinfo: break level2 oplocks on setfileinfo()
 ALLOCATION_INFO and END_OF_FILE_INFO

metze
(This used to be commit b258f9d8d4bf3606f4884d1bff548f16dadc08aa)
---
 source4/ntvfs/posix/pvfs_setfileinfo.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c
index c6d014a72f..d1d8f819ef 100644
--- a/source4/ntvfs/posix/pvfs_setfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_setfileinfo.c
@@ -355,6 +355,9 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
 
 	case RAW_SFILEINFO_ALLOCATION_INFO:
 	case RAW_SFILEINFO_ALLOCATION_INFORMATION:
+		status = pvfs_break_level2_oplocks(f);
+		NT_STATUS_NOT_OK_RETURN(status);
+
 		newstats.dos.alloc_size = info->allocation_info.in.alloc_size;
 		if (newstats.dos.alloc_size < newstats.st.st_size) {
 			newstats.st.st_size = newstats.dos.alloc_size;
@@ -365,6 +368,9 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
 
 	case RAW_SFILEINFO_END_OF_FILE_INFO:
 	case RAW_SFILEINFO_END_OF_FILE_INFORMATION:
+		status = pvfs_break_level2_oplocks(f);
+		NT_STATUS_NOT_OK_RETURN(status);
+
 		newstats.st.st_size = info->end_of_file_info.in.size;
 		break;
 
-- 
cgit 


From c0d1543a6a5fee3d767a366186dd634a395c8146 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Mon, 25 Feb 2008 19:17:45 +0100
Subject: pvfs: add posix:oplocktimeout=30 option

metze
(This used to be commit 5abc57ddab558c13db3864d13afc2ad3b1641d1c)
---
 source4/ntvfs/posix/vfs_posix.c | 4 ++++
 source4/ntvfs/posix/vfs_posix.h | 9 +++++++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c
index e058e6f546..ca874d1db1 100644
--- a/source4/ntvfs/posix/vfs_posix.c
+++ b/source4/ntvfs/posix/vfs_posix.c
@@ -91,6 +91,10 @@ static void pvfs_setup_options(struct pvfs_state *pvfs)
 							PVFS_SHARE_DELAY,
 							PVFS_SHARE_DELAY_DEFAULT);
 
+	pvfs->oplock_break_timeout = share_int_option(scfg,
+						      PVFS_OPLOCK_TIMEOUT,
+						      PVFS_OPLOCK_TIMEOUT_DEFAULT);
+
 	pvfs->share_name = talloc_strdup(pvfs, scfg->name);
 
 	pvfs->fs_attribs = 
diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h
index 72469505cc..4d22a91714 100644
--- a/source4/ntvfs/posix/vfs_posix.h
+++ b/source4/ntvfs/posix/vfs_posix.h
@@ -52,9 +52,12 @@ struct pvfs_state {
 	   ntcancel */
 	struct pvfs_wait *wait_list;
 
-	/* the sharing violation timeout */
+	/* the sharing violation timeout (nsecs) */
 	uint_t sharing_violation_delay;
 
+	/* the oplock break timeout (secs) */
+	uint_t oplock_break_timeout;
+
 	/* filesystem attributes (see FS_ATTR_*) */
 	uint32_t fs_attribs;
 
@@ -247,6 +250,7 @@ struct pvfs_odb_retry;
 #define PVFS_XATTR			"posix:xattr"
 #define PVFS_FAKE_OPLOCKS		"posix:fakeoplocks"
 #define PVFS_SHARE_DELAY		"posix:sharedelay"
+#define PVFS_OPLOCK_TIMEOUT		"posix:oplocktimeout"
 #define PVFS_ALLOCATION_ROUNDING	"posix:allocationrounding"
 #define PVFS_SEARCH_INACTIVITY		"posix:searchinactivity"
 #define PVFS_ACL			"posix:acl"
@@ -254,7 +258,8 @@ struct pvfs_odb_retry;
 
 #define PVFS_XATTR_DEFAULT			true
 #define PVFS_FAKE_OPLOCKS_DEFAULT		false
-#define PVFS_SHARE_DELAY_DEFAULT		1000000
+#define PVFS_SHARE_DELAY_DEFAULT		1000000 /* nsecs */
+#define PVFS_OPLOCK_TIMEOUT_DEFAULT		30 /* secs */
 #define PVFS_ALLOCATION_ROUNDING_DEFAULT	512
 #define PVFS_SEARCH_INACTIVITY_DEFAULT		300
 
-- 
cgit 


From 61e17794c394d2c070ce7df9cee6c53d846e7b75 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Fri, 22 Feb 2008 11:52:17 +0100
Subject: pvfs_unlink: retry unlink after oplock not granted

metze
(This used to be commit 746e89ce2e74dbd2cea8f5575c403e4c61f82cb8)
---
 source4/ntvfs/posix/pvfs_open.c   | 26 ++++++++---
 source4/ntvfs/posix/pvfs_unlink.c | 94 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 113 insertions(+), 7 deletions(-)

diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index 8429c14d1b..4110df292d 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -1008,7 +1008,8 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs,
 				      struct ntvfs_request *req, 
 				      union smb_open *io,
 				      struct pvfs_file *f,
-				      struct odb_lock *lck)
+				      struct odb_lock *lck,
+				      NTSTATUS parent_status)
 {
 	struct pvfs_state *pvfs = ntvfs->private_data;
 	NTSTATUS status;
@@ -1027,7 +1028,15 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs,
 	/* the retry should allocate a new file handle */
 	talloc_free(f);
 
-	end_time = timeval_add(&req->statistics.request_time, 0, pvfs->sharing_violation_delay);
+	if (NT_STATUS_EQUAL(parent_status, NT_STATUS_SHARING_VIOLATION)) {
+		end_time = timeval_add(&req->statistics.request_time,
+				       0, pvfs->sharing_violation_delay);
+	} else if (NT_STATUS_EQUAL(parent_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
+		end_time = timeval_add(&req->statistics.request_time,
+				       pvfs->oplock_break_timeout, 0);
+	} else {
+		return NT_STATUS_INTERNAL_ERROR;
+	}
 
 	return pvfs_odb_retry_setup(ntvfs, req, lck, end_time, io, NULL,
 				    pvfs_retry_open_sharing);
@@ -1253,11 +1262,16 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
 			       io->generic.in.open_disposition,
 			       false, oplock_level, &oplock_granted);
 
-	/* on a sharing violation we need to retry when the file is closed by 
-	   the other user, or after 1 second */
-	if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) &&
+	/*
+	 * on a sharing violation we need to retry when the file is closed by
+	 * the other user, or after 1 second
+	 * on a non granted oplock we need to retry when the file is closed by
+	 * the other user, or after 30 seconds
+	*/
+	if ((NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||
+	     NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) &&
 	    (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
-		return pvfs_open_setup_retry(ntvfs, req, io, f, lck);
+		return pvfs_open_setup_retry(ntvfs, req, io, f, lck, status);
 	}
 
 	if (!NT_STATUS_IS_OK(status)) {
diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c
index bda4014bee..7a2d964b9d 100644
--- a/source4/ntvfs/posix/pvfs_unlink.c
+++ b/source4/ntvfs/posix/pvfs_unlink.c
@@ -23,6 +23,84 @@
 #include "vfs_posix.h"
 #include "system/dir.h"
 
+/*
+  retry an open after a sharing violation
+*/
+static void pvfs_retry_unlink(struct pvfs_odb_retry *r,
+			      struct ntvfs_module_context *ntvfs,
+			      struct ntvfs_request *req,
+			      void *_io,
+			      void *private_data,
+			      enum pvfs_wait_notice reason)
+{
+	union smb_unlink *io = talloc_get_type(_io, union smb_unlink);
+	NTSTATUS status = NT_STATUS_INTERNAL_ERROR;
+
+	talloc_free(r);
+
+	switch (reason) {
+	case PVFS_WAIT_CANCEL:
+/*TODO*/
+		status = NT_STATUS_CANCELLED;
+		break;
+	case PVFS_WAIT_TIMEOUT:
+		/* if it timed out, then give the failure
+		   immediately */
+/*TODO*/
+		status = NT_STATUS_SHARING_VIOLATION;
+		break;
+	case PVFS_WAIT_EVENT:
+
+		/* try the open again, which could trigger another retry setup
+		   if it wants to, so we have to unmark the async flag so we
+		   will know if it does a second async reply */
+		req->async_states->state &= ~NTVFS_ASYNC_STATE_ASYNC;
+
+		status = pvfs_unlink(ntvfs, req, io);
+		if (req->async_states->state & NTVFS_ASYNC_STATE_ASYNC) {
+			/* the 2nd try also replied async, so we don't send
+			   the reply yet */
+			return;
+		}
+
+		/* re-mark it async, just in case someone up the chain does
+		   paranoid checking */
+		req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC;
+		break;
+	}
+
+	/* send the reply up the chain */
+	req->async_states->status = status;
+	req->async_states->send_fn(req);
+}
+
+/*
+  setup for a unlink retry after a sharing violation
+  or a non granted oplock
+*/
+static NTSTATUS pvfs_unlink_setup_retry(struct ntvfs_module_context *ntvfs,
+					struct ntvfs_request *req,
+					union smb_unlink *io,
+					struct odb_lock *lck,
+					NTSTATUS status)
+{
+	struct pvfs_state *pvfs = ntvfs->private_data;
+	struct timeval end_time;
+
+	if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
+		end_time = timeval_add(&req->statistics.request_time,
+				       0, pvfs->sharing_violation_delay);
+	} else if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
+		end_time = timeval_add(&req->statistics.request_time,
+				       pvfs->oplock_break_timeout, 0);
+	} else {
+		return NT_STATUS_INTERNAL_ERROR;
+	}
+
+	return pvfs_odb_retry_setup(ntvfs, req, lck, end_time, io, NULL,
+				    pvfs_retry_unlink);
+}
+
 
 /*
   unlink a file
@@ -67,6 +145,7 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs,
 				struct pvfs_filename *name)
 {
 	NTSTATUS status;
+	struct odb_lock *lck = NULL;
 
 	/* make sure its matches the given attributes */
 	status = pvfs_match_attrib(pvfs, name,
@@ -75,7 +154,20 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs,
 		return status;
 	}
 
-	status = pvfs_can_delete(pvfs, req, name, NULL);
+	status = pvfs_can_delete(pvfs, req, name, &lck);
+
+	/*
+	 * on a sharing violation we need to retry when the file is closed by
+	 * the other user, or after 1 second
+	 * on a non granted oplock we need to retry when the file is closed by
+	 * the other user, or after 30 seconds
+	 */
+	if ((NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||
+	     NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) &&
+	    (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
+		return pvfs_unlink_setup_retry(pvfs->ntvfs, req, unl, lck, status);
+	}
+
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
 	}
-- 
cgit 


From 4eb0fcc5173ddf50305fa5094ec0d87d53d71a33 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Sat, 23 Feb 2008 11:49:39 +0100
Subject: pvfs_open: add pvfs_can_update_file_size()

TODO: this is not complete, we need more tests to trigger this

metze
(This used to be commit 66ad1081f2be8a0caa16fb0d614b857a5bde751c)
---
 source4/ntvfs/posix/pvfs_open.c | 62 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index 4110df292d..12b70c00fd 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -1620,6 +1620,68 @@ NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs,
 	return status;
 }
 
+/*
+  determine if the file size of a file can be changed,
+  or if it is prevented by an already open file
+*/
+NTSTATUS pvfs_can_update_file_size(struct pvfs_state *pvfs,
+				   struct ntvfs_request *req,
+				   struct pvfs_filename *name,
+				   struct odb_lock **lckp)
+{
+	NTSTATUS status;
+	DATA_BLOB key;
+	struct odb_lock *lck;
+	uint32_t share_access;
+	uint32_t access_mask;
+	bool break_to_none;
+	bool delete_on_close;
+
+	status = pvfs_locking_key(name, name, &key);
+	if (!NT_STATUS_IS_OK(status)) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	lck = odb_lock(req, pvfs->odb_context, &key);
+	if (lck == NULL) {
+		DEBUG(0,("Unable to lock opendb for can_stat\n"));
+		return NT_STATUS_INTERNAL_DB_CORRUPTION;
+	}
+
+	/* TODO: this may needs some more flags */
+	share_access	= NTCREATEX_SHARE_ACCESS_WRITE;
+	access_mask	= 0;
+	delete_on_close	= false;
+	break_to_none	= true;
+
+	status = odb_can_open(lck, name->stream_id,
+			      share_access, access_mask, delete_on_close,
+			      0, break_to_none);
+
+	/*
+	 * 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);
+		if (lckp) {
+			*lckp = NULL;
+		}
+	} else if (lckp) {
+		*lckp = lck;
+	}
+
+	return status;
+}
+
 /*
   determine if file meta data can be accessed, or if it is prevented by an
   already open file
-- 
cgit 


From fa2e4ba03cd65f850d8f118ce61d5c4a80f0e30a Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Sat, 23 Feb 2008 11:50:19 +0100
Subject: pvfs_setpathinfo: retry setpathinfo after oplock not granted on on
 setpathinfo ALLOCATION_INFO and END_OF_FILE_INFO

metze
(This used to be commit 4e27ac8c529d5a1675fb02215191a2be7913ec97)
---
 source4/ntvfs/posix/pvfs_setfileinfo.c | 107 +++++++++++++++++++++++++++++++++
 1 file changed, 107 insertions(+)

diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c
index d1d8f819ef..da1e31e639 100644
--- a/source4/ntvfs/posix/pvfs_setfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_setfileinfo.c
@@ -472,6 +472,84 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
 	return pvfs_dosattrib_save(pvfs, h->name, h->fd);
 }
 
+/*
+  retry an open after a sharing violation
+*/
+static void pvfs_retry_setpathinfo(struct pvfs_odb_retry *r,
+				   struct ntvfs_module_context *ntvfs,
+				   struct ntvfs_request *req,
+				   void *_info,
+				   void *private_data,
+				   enum pvfs_wait_notice reason)
+{
+	union smb_setfileinfo *info = talloc_get_type(_info,
+				      union smb_setfileinfo);
+	NTSTATUS status = NT_STATUS_INTERNAL_ERROR;
+
+	talloc_free(r);
+
+	switch (reason) {
+	case PVFS_WAIT_CANCEL:
+/*TODO*/
+		status = NT_STATUS_CANCELLED;
+		break;
+	case PVFS_WAIT_TIMEOUT:
+		/* if it timed out, then give the failure
+		   immediately */
+/*TODO*/
+		status = NT_STATUS_SHARING_VIOLATION;
+		break;
+	case PVFS_WAIT_EVENT:
+
+		/* try the open again, which could trigger another retry setup
+		   if it wants to, so we have to unmark the async flag so we
+		   will know if it does a second async reply */
+		req->async_states->state &= ~NTVFS_ASYNC_STATE_ASYNC;
+
+		status = pvfs_setpathinfo(ntvfs, req, info);
+		if (req->async_states->state & NTVFS_ASYNC_STATE_ASYNC) {
+			/* the 2nd try also replied async, so we don't send
+			   the reply yet */
+			return;
+		}
+
+		/* re-mark it async, just in case someone up the chain does
+		   paranoid checking */
+		req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC;
+		break;
+	}
+
+	/* send the reply up the chain */
+	req->async_states->status = status;
+	req->async_states->send_fn(req);
+}
+
+/*
+  setup for a unlink retry after a sharing violation
+  or a non granted oplock
+*/
+static NTSTATUS pvfs_setpathinfo_setup_retry(struct ntvfs_module_context *ntvfs,
+					     struct ntvfs_request *req,
+					     union smb_setfileinfo *info,
+					     struct odb_lock *lck,
+					     NTSTATUS status)
+{
+	struct pvfs_state *pvfs = ntvfs->private_data;
+	struct timeval end_time;
+
+	if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
+		end_time = timeval_add(&req->statistics.request_time,
+				       0, pvfs->sharing_violation_delay);
+	} else if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
+		end_time = timeval_add(&req->statistics.request_time,
+				       pvfs->oplock_break_timeout, 0);
+	} else {
+		return NT_STATUS_INTERNAL_ERROR;
+	}
+
+	return pvfs_odb_retry_setup(ntvfs, req, lck, end_time, info, NULL,
+				    pvfs_retry_setpathinfo);
+}
 
 /*
   set info on a pathname
@@ -486,6 +564,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
 	struct utimbuf unix_times;
 	uint32_t access_needed;
 	uint32_t change_mask = 0;
+	struct odb_lock *lck = NULL;
 
 	/* resolve the cifs name to a posix name */
 	status = pvfs_resolve_name(pvfs, req, info->generic.in.file.path, 
@@ -560,6 +639,20 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
 
 	case RAW_SFILEINFO_ALLOCATION_INFO:
 	case RAW_SFILEINFO_ALLOCATION_INFORMATION:
+		status = pvfs_can_update_file_size(pvfs, req, name, &lck);
+		/*
+		 * on a sharing violation we need to retry when the file is closed by
+		 * the other user, or after 1 second
+		 * on a non granted oplock we need to retry when the file is closed by
+		 * the other user, or after 30 seconds
+		*/
+		if ((NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||
+		     NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) &&
+		    (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
+			return pvfs_setpathinfo_setup_retry(pvfs->ntvfs, req, info, lck, status);
+		}
+		NT_STATUS_NOT_OK_RETURN(status);
+
 		if (info->allocation_info.in.alloc_size > newstats.dos.alloc_size) {
 			/* strange. Increasing the allocation size via setpathinfo 
 			   should be silently ignored */
@@ -575,6 +668,20 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
 
 	case RAW_SFILEINFO_END_OF_FILE_INFO:
 	case RAW_SFILEINFO_END_OF_FILE_INFORMATION:
+		status = pvfs_can_update_file_size(pvfs, req, name, &lck);
+		/*
+		 * on a sharing violation we need to retry when the file is closed by
+		 * the other user, or after 1 second
+		 * on a non granted oplock we need to retry when the file is closed by
+		 * the other user, or after 30 seconds
+		*/
+		if ((NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||
+		     NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) &&
+		    (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
+			return pvfs_setpathinfo_setup_retry(pvfs->ntvfs, req, info, lck, status);
+		}
+		NT_STATUS_NOT_OK_RETURN(status);
+
 		newstats.st.st_size = info->end_of_file_info.in.size;
 		break;
 
-- 
cgit 


From 9ddbdfa02cfaa0df6ce944d6dfecf6850ab0b2f8 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Sat, 23 Feb 2008 11:54:01 +0100
Subject: selftest: Samba4 passes all oplocks tests now

The support for oplocks is not completely finished
I believe we will not pass some non existing test.
But it's a good start.

metze
(This used to be commit 278eea57fa9f59908672c935187f942e7780f0aa)
---
 source4/samba4-knownfail          | 1 -
 source4/samba4-skip               | 4 ----
 source4/selftest/target/Samba4.pm | 6 ++++++
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/source4/samba4-knownfail b/source4/samba4-knownfail
index 18fb4b914b..4d850caae5 100644
--- a/source4/samba4-knownfail
+++ b/source4/samba4-knownfail
@@ -3,7 +3,6 @@ local.iconv.*.next_codepoint()
 base.delaywrite.finfo update on close
 base.delete.*.deltest20a
 base.delete.*.deltest20b
-raw.oplock.*.OPLOCK
 rpc.winreg
 local.registry.*.security # Not implemented yet
 rpc.wkssvc
diff --git a/source4/samba4-skip b/source4/samba4-skip
index 541738ecc4..4d2da6ed64 100644
--- a/source4/samba4-skip
+++ b/source4/samba4-skip
@@ -1,12 +1,10 @@
 base.delaywrite
 raw.composite
-raw.oplock
 base.iometer
 base.casetable
 base.nttrans
 .*base.bench.holdcon.*				# Very slow
 base.scan.maxfid
-raw.bench.oplock
 raw.hold.oplock
 raw.ping.pong
 rpc.samr_accessmask
@@ -25,9 +23,7 @@ ntvfs.cifs.base.scan-maxfid
 ntvfs.cifs.base.utable
 ntvfs.cifs.base.smb
 ntvfs.cifs.raw.composite
-ntvfs.cifs.raw.oplock
 ntvfs.cifs.raw.notify
-ntvfs.cifs.raw.bench-oplock
 ntvfs.cifs.raw.scan-eamax
 ntvfs.cifs.raw.context
 ntvfs.cifs.raw.qfileinfo.ipc
diff --git a/source4/selftest/target/Samba4.pm b/source4/selftest/target/Samba4.pm
index 37e3cbe354..e0be8048a0 100644
--- a/source4/selftest/target/Samba4.pm
+++ b/source4/selftest/target/Samba4.pm
@@ -562,12 +562,16 @@ sub provision($$$$$$)
 	gensec:require_pac = true
 	log level = $smbd_loglevel
 
+	# this is a global option
+	opendb:oplocks = yes
+
 [tmp]
 	path = $tmpdir
 	read only = no
 	ntvfs handler = posix
 	posix:sharedelay = 100000
 	posix:eadb = $lockdir/eadb.tdb
+	posix:oplocktimeout = 3
 
 [test1]
 	path = $tmpdir/test1
@@ -575,6 +579,7 @@ sub provision($$$$$$)
 	ntvfs handler = posix
 	posix:sharedelay = 100000
 	posix:eadb = $lockdir/eadb.tdb
+	posix:oplocktimeout = 3
 
 [test2]
 	path = $tmpdir/test2
@@ -582,6 +587,7 @@ sub provision($$$$$$)
 	ntvfs handler = posix
 	posix:sharedelay = 100000
 	posix:eadb = $lockdir/eadb.tdb
+	posix:oplocktimeout = 3
 
 [cifs]
 	read only = no
-- 
cgit 


From db2a2382d1dfcb9ace4621368feebd700b598625 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Tue, 26 Feb 2008 10:31:37 +0100
Subject: BASE-DEFER_OPEN: be less strict with to late responses

The server might be just busy.

metze
(This used to be commit 16c60cd347a42a2d98753585cbefddc948e2860f)
---
 source4/torture/basic/base.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source4/torture/basic/base.c b/source4/torture/basic/base.c
index 42d7ddaaa1..66f9359744 100644
--- a/source4/torture/basic/base.c
+++ b/source4/torture/basic/base.c
@@ -664,7 +664,7 @@ 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 * sec) || e > (1.5 * sec)) {
+				if (e < (0.5 * sec) || e > ((1.5 * sec) + 1)) {
 					torture_comment(tctx,"Timing incorrect %.2f violation 1 sec == %.2f\n",
 						e, sec);
 					return false;
-- 
cgit 


From 901addd4a18a9a166fc3518a7bce70969f884e6f Mon Sep 17 00:00:00 2001
From: Michael Adam 
Date: Tue, 26 Feb 2008 11:18:51 +0100
Subject: Fix build on VOS: socklen_t is needed for rep_inet_ntop: move it up.

Michael
(This used to be commit 8a26a6e8f11aca5119b15e304213548ad608dc5b)
---
 source4/lib/replace/system/network.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/source4/lib/replace/system/network.h b/source4/lib/replace/system/network.h
index d09e3f71f8..a84b22e5d0 100644
--- a/source4/lib/replace/system/network.h
+++ b/source4/lib/replace/system/network.h
@@ -83,6 +83,11 @@
 #include 
 #endif
 
+#ifndef HAVE_SOCKLEN_T
+#define HAVE_SOCKLEN_T
+typedef int socklen_t;
+#endif
+
 #ifdef REPLACE_INET_NTOA
 /* define is in "replace.h" */
 char *rep_inet_ntoa(struct in_addr ip);
@@ -245,11 +250,6 @@ void rep_freeifaddrs(struct ifaddrs *);
 #define HOST_NAME_MAX 256
 #endif
 
-#ifndef HAVE_SOCKLEN_T
-#define HAVE_SOCKLEN_T
-typedef int socklen_t;
-#endif
-
 #ifndef HAVE_SA_FAMILY_T
 #define HAVE_SA_FAMILY_T
 typedef unsigned short int sa_family_t;
-- 
cgit 


From 9f8fc29ea418c7ed2e2f206eb4789080ec9ab3f1 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Tue, 26 Feb 2008 10:21:39 +0100
Subject: pvfs_open: pass NTCREATEX_DISP_OPEN to odb_can_open()

As 0 is NTCREATEX_DISP_SUPERSEDE and that's not what we want here.

metze
(This used to be commit 10c42e3d4ab71a71dfe620b40841dfe98f458c1a)
---
 source4/ntvfs/posix/pvfs_open.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index 12b70c00fd..ef05db5eac 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -1530,7 +1530,7 @@ NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs,
 
 	status = odb_can_open(lck, name->stream_id,
 			      share_access, access_mask, delete_on_close,
-			      0, false);
+			      NTCREATEX_DISP_OPEN, false);
 
 	if (NT_STATUS_IS_OK(status)) {
 		status = pvfs_access_check_simple(pvfs, req, name, access_mask);
@@ -1594,7 +1594,7 @@ NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs,
 
 	status = odb_can_open(lck, name->stream_id,
 			      share_access, access_mask, delete_on_close,
-			      0, false);
+			      NTCREATEX_DISP_OPEN, false);
 
 	/*
 	 * if it's a sharing violation or we got no oplock
@@ -1656,7 +1656,7 @@ NTSTATUS pvfs_can_update_file_size(struct pvfs_state *pvfs,
 
 	status = odb_can_open(lck, name->stream_id,
 			      share_access, access_mask, delete_on_close,
-			      0, break_to_none);
+			      NTCREATEX_DISP_OPEN, break_to_none);
 
 	/*
 	 * if it's a sharing violation or we got no oplock
@@ -1715,7 +1715,7 @@ NTSTATUS pvfs_can_stat(struct pvfs_state *pvfs,
 
 	status = odb_can_open(lck, name->stream_id,
 			      share_access, access_mask, delete_on_close,
-			      0, false);
+			      NTCREATEX_DISP_OPEN, false);
 
 	if (!NT_STATUS_IS_OK(status)) {
 		talloc_free(lck);
-- 
cgit 


From b40be554e7775687a01704b9af0aa272cc9019d0 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Tue, 26 Feb 2008 10:28:07 +0100
Subject: pvfs_open: pass down an access mask in pvfs_can_stat()

metze
(This used to be commit 6c34c7bc6801e470e5ec50aa93d0a07f7ad59314)
---
 source4/ntvfs/posix/pvfs_open.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index ef05db5eac..0e4250d744 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -1710,7 +1710,7 @@ NTSTATUS pvfs_can_stat(struct pvfs_state *pvfs,
 
 	share_access	= NTCREATEX_SHARE_ACCESS_READ |
 			  NTCREATEX_SHARE_ACCESS_WRITE;
-	access_mask	= 0;
+	access_mask	= SEC_FILE_READ_ATTRIBUTE;
 	delete_on_close	= false;
 
 	status = odb_can_open(lck, name->stream_id,
-- 
cgit 


From c62faaa75e2bf2c82b7a905b27d29f70ae0c7591 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Tue, 26 Feb 2008 10:29:07 +0100
Subject: pvfs_qfileinfo: down discard the return value of pvfs_can_stat()

The odb_can_open() code returns DELETE_PENDING if
a delete is really pending.

metze
(This used to be commit 066ba3c7cfff12cb0b5298fc45eabb5fc097d056)
---
 source4/ntvfs/posix/pvfs_qfileinfo.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c
index 2f01c08fb0..8d23d707a4 100644
--- a/source4/ntvfs/posix/pvfs_qfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_qfileinfo.c
@@ -330,7 +330,7 @@ NTSTATUS pvfs_qpathinfo(struct ntvfs_module_context *ntvfs,
 
 	status = pvfs_can_stat(pvfs, req, name);
 	if (!NT_STATUS_IS_OK(status)) {
-		return NT_STATUS_DELETE_PENDING;
+		return status;
 	}
 
 	status = pvfs_access_check_simple(pvfs, req, name, 
-- 
cgit 


From 55377f0352d73fa354e8abcf3e644c63c78d0ca6 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Tue, 26 Feb 2008 10:26:33 +0100
Subject: pvfs_open: pass down an access mask to pvfs_can_update_file_size()

You just need SEC_FILE_WRITE_ATTRIBUTE to change
the filesize...

metze
(This used to be commit 27e39063a0b759c7bced1cc9d7a6cb9192820c70)
---
 source4/ntvfs/posix/pvfs_open.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index 0e4250d744..a01352f60c 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -1648,9 +1648,19 @@ NTSTATUS pvfs_can_update_file_size(struct pvfs_state *pvfs,
 		return NT_STATUS_INTERNAL_DB_CORRUPTION;
 	}
 
-	/* TODO: this may needs some more flags */
-	share_access	= NTCREATEX_SHARE_ACCESS_WRITE;
-	access_mask	= 0;
+	share_access	= NTCREATEX_SHARE_ACCESS_READ |
+			  NTCREATEX_SHARE_ACCESS_WRITE |
+			  NTCREATEX_SHARE_ACCESS_DELETE;
+	/*
+	 * I would have thought that we would need to pass
+	 * SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA here too
+	 *
+	 * But you only need SEC_FILE_WRITE_ATTRIBUTE permissions
+	 * to set the filesize.
+	 *
+	 * --metze
+	 */
+	access_mask	= SEC_FILE_WRITE_ATTRIBUTE;
 	delete_on_close	= false;
 	break_to_none	= true;
 
-- 
cgit 


From 2b94ffe5e7303c1d321b9a9c6a612f77f1ac58b2 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Tue, 26 Feb 2008 12:52:46 +0100
Subject: opendb_tdb: with break_to_none attribute only opens also break
 oplocks

metze
(This used to be commit c475353e34154eb13e35cc8b6cf553e3986f8677)
---
 source4/ntvfs/common/opendb_tdb.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c
index 73c04b7c4f..fe5a0a8864 100644
--- a/source4/ntvfs/common/opendb_tdb.c
+++ b/source4/ntvfs/common/opendb_tdb.c
@@ -288,7 +288,8 @@ static NTSTATUS odb_oplock_break_send(struct odb_context *odb,
 }
 
 static bool access_attributes_only(uint32_t access_mask,
-				   uint32_t open_disposition)
+				   uint32_t open_disposition,
+				   bool break_to_none)
 {
 	switch (open_disposition) {
 	case NTCREATEX_DISP_SUPERSEDE:
@@ -298,6 +299,11 @@ static bool access_attributes_only(uint32_t access_mask,
 	default:
 		break;
 	}
+
+	if (break_to_none) {
+		return false;
+	}
+
 #define CHECK_MASK(m,g) ((m) && (((m) & ~(g))==0) && (((m) & (g)) != 0))
 	return CHECK_MASK(access_mask,
 			  SEC_STD_SYNCHRONIZE |
@@ -326,7 +332,8 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb,
 			 * but we'll not grant the oplock below
 			 */
 			attrs_only = access_attributes_only(access_mask,
-							    open_disposition);
+							    open_disposition,
+							    break_to_none);
 			if (attrs_only) {
 				break;
 			}
-- 
cgit 


From 39eb63039163cf7625edf5c0a33112a0659c3eca Mon Sep 17 00:00:00 2001
From: Jelmer Vernooij 
Date: Tue, 26 Feb 2008 14:20:31 +0100
Subject: Rely on GNU make to build static libraries.

Conflicts:

	source/build/smb_build/makefile.pm
(This used to be commit f34a17a92bcc9a27b629a6ec9ed9a818bd13acc0)
---
 source4/build/smb_build/makefile.pm | 11 +----------
 source4/rules.mk                    |  7 +++++++
 2 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/source4/build/smb_build/makefile.pm b/source4/build/smb_build/makefile.pm
index 17474db00e..29da771353 100644
--- a/source4/build/smb_build/makefile.pm
+++ b/source4/build/smb_build/makefile.pm
@@ -281,16 +281,7 @@ sub StaticLibrary($$)
 	$self->output("$ctx->{NAME}_OUTPUT = $ctx->{OUTPUT}\n");
 	$self->_prepare_list($ctx, "FULL_OBJ_LIST");
 
-	$self->output(<< "__EOD__"
-#
-$ctx->{RESULT_STATIC_LIBRARY}: \$($ctx->{NAME}_FULL_OBJ_LIST)
-	\@echo Linking \$@
-	\@rm -f \$@
-	\@mkdir -p $ctx->{STATICDIR}
-	\@\$(STLD) \$(STLD_FLAGS) \$@ \$($ctx->{NAME}_FULL_OBJ_LIST)
-
-__EOD__
-);
+	$self->output("$ctx->{RESULT_STATIC_LIBRARY}: \$($ctx->{NAME}_FULL_OBJ_LIST)\n");
 }
 
 sub Header($$)
diff --git a/source4/rules.mk b/source4/rules.mk
index b6a54fae25..9791466712 100644
--- a/source4/rules.mk
+++ b/source4/rules.mk
@@ -100,6 +100,13 @@ check:: test
 unused_macros:
 	$(srcdir)/script/find_unused_macros.pl `find . -name "*.[ch]"` | sort
 
+# Create a static library
+%.a:
+	@echo Linking $@
+	@rm -f $@
+	@mkdir -p $(@D)
+	@$(STLD) $(STLD_FLAGS) $@ $^
+
 ###############################################################################
 # File types
 ###############################################################################
-- 
cgit 


From 9d6ce7efaabd2554519afdccd6e12fbba05930da Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher 
Date: Tue, 26 Feb 2008 14:52:50 +0100
Subject: RAW-OPLOCK: BATCH15: make sure a qpathinfo doesn't break batch
 oplocks

metze
(This used to be commit 4d17d44d3f418216a40c80f290f97a4dc29147b0)
---
 source4/torture/raw/oplock.c | 74 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/source4/torture/raw/oplock.c b/source4/torture/raw/oplock.c
index 3edd0c6820..e81b634161 100644
--- a/source4/torture/raw/oplock.c
+++ b/source4/torture/raw/oplock.c
@@ -1279,6 +1279,79 @@ done:
 	return ret;
 }
 
+static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+	const char *fname = BASEDIR "\\test_batch15.dat";
+	NTSTATUS status;
+	bool ret = true;
+	union smb_open io;
+	union smb_fileinfo qfi;
+	uint16_t fnum=0;
+
+	if (!torture_setup_dir(cli1, BASEDIR)) {
+		return false;
+	}
+
+	/* cleanup */
+	smbcli_unlink(cli1->tree, fname);
+
+	smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
+
+	/*
+	  base ntcreatex parms
+	*/
+	io.generic.level = RAW_OPEN_NTCREATEX;
+	io.ntcreatex.in.root_fid = 0;
+	io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
+	io.ntcreatex.in.alloc_size = 0;
+	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
+	io.ntcreatex.in.create_options = 0;
+	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+	io.ntcreatex.in.security_flags = 0;
+	io.ntcreatex.in.fname = fname;
+
+	/* Test if a qpathinfo all info on pathname breaks a batch oplock. */
+	torture_comment(tctx, "Test if qpathinfo all info breaks a batch oplock (should not).\n");
+
+	ZERO_STRUCT(break_info);
+	smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
+
+	io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
+		NTCREATEX_FLAGS_REQUEST_OPLOCK |
+		NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
+	io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
+	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
+		NTCREATEX_SHARE_ACCESS_WRITE|
+		NTCREATEX_SHARE_ACCESS_DELETE;
+	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
+	status = smb_raw_open(cli1->tree, tctx, &io);
+	CHECK_STATUS(tctx, status, NT_STATUS_OK);
+	fnum = io.ntcreatex.out.file.fnum;
+	CHECK_VAL(break_info.count, 0);
+	CHECK_VAL(break_info.failures, 0);
+	CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
+
+	ZERO_STRUCT(qfi);
+	qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
+	qfi.generic.in.file.path = fname;
+
+	status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
+
+	CHECK_STATUS(tctx, status, NT_STATUS_OK);
+	CHECK_VAL(break_info.count, 0);
+
+	smbcli_close(cli1->tree, fnum);
+
+done:
+	smb_raw_exit(cli1->session);
+	smb_raw_exit(cli2->session);
+	smbcli_deltree(cli1->tree, BASEDIR);
+	return ret;
+}
+
 /* 
    basic testing of oplocks
 */
@@ -1301,6 +1374,7 @@ struct torture_suite *torture_raw_oplock(TALLOC_CTX *mem_ctx)
 	torture_suite_add_2smb_test(suite, "BATCH12", test_raw_oplock_batch12);
 	torture_suite_add_2smb_test(suite, "BATCH13", test_raw_oplock_batch13);
 	torture_suite_add_2smb_test(suite, "BATCH14", test_raw_oplock_batch14);
+	torture_suite_add_2smb_test(suite, "BATCH15", test_raw_oplock_batch15);
 
 	return suite;
 }
-- 
cgit 


From bcca7d43c8dc1c96f060a3daff8f0e43c43129c2 Mon Sep 17 00:00:00 2001
From: Michael Adam 
Date: Tue, 26 Feb 2008 15:38:45 +0100
Subject: pidl: Remove superfluous semicolon in perl code.

Michael
(This used to be commit 85f707c6abc48739c0c3b423ac0b196d2b75e40c)
---
 source4/pidl/idl.yp                | 2 +-
 source4/pidl/lib/Parse/Pidl/IDL.pm | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/source4/pidl/idl.yp b/source4/pidl/idl.yp
index 028b628e18..c7ca0c7604 100644
--- a/source4/pidl/idl.yp
+++ b/source4/pidl/idl.yp
@@ -391,7 +391,7 @@ sub _Error {
 		error($_[0]->YYData, $_[0]->YYData->{ERRMSG});
 		delete $_[0]->YYData->{ERRMSG};
 		return;
-	};
+	}
 	my $last_token = $_[0]->YYData->{LAST_TOKEN};
 	
 	error($_[0]->YYData, "Syntax error near '$last_token'");
diff --git a/source4/pidl/lib/Parse/Pidl/IDL.pm b/source4/pidl/lib/Parse/Pidl/IDL.pm
index aeee69e306..4adb4dcea8 100644
--- a/source4/pidl/lib/Parse/Pidl/IDL.pm
+++ b/source4/pidl/lib/Parse/Pidl/IDL.pm
@@ -2408,7 +2408,7 @@ sub _Error {
 		error($_[0]->YYData, $_[0]->YYData->{ERRMSG});
 		delete $_[0]->YYData->{ERRMSG};
 		return;
-	};
+	}
 	my $last_token = $_[0]->YYData->{LAST_TOKEN};
 	
 	error($_[0]->YYData, "Syntax error near '$last_token'");
-- 
cgit 


From 28464179174d2c3d1c1bc124ba9c2519e08a5fc9 Mon Sep 17 00:00:00 2001
From: Michael Adam 
Date: Tue, 26 Feb 2008 13:24:54 +0100
Subject: libreplace: Add tests for connect and gethostbyname.

Provide dummy replacements when a function isnt found.
The functions are also searched for in certain libraries,
and variables SOCKET_LIBS and NSL_LIBS are set accordingly.

One purpose of this is to fix the getifaddrs tests on
systems where e.g. the socket calls require special libs
for linking.

Michael
(This used to be commit 900d17acb95f1becfc46656a12c107336c027ef7)
---
 source4/lib/replace/libreplace.m4    |  1 +
 source4/lib/replace/replace.h        | 10 +++++++++
 source4/lib/replace/socket.c         | 35 +++++++++++++++++++++++++++++++
 source4/lib/replace/socket.m4        | 40 ++++++++++++++++++++++++++++++++++++
 source4/lib/replace/system/network.h | 10 +++++++++
 5 files changed, 96 insertions(+)
 create mode 100644 source4/lib/replace/socket.c
 create mode 100644 source4/lib/replace/socket.m4

diff --git a/source4/lib/replace/libreplace.m4 b/source4/lib/replace/libreplace.m4
index 2e0cd34f4a..e0cc57f4c8 100644
--- a/source4/lib/replace/libreplace.m4
+++ b/source4/lib/replace/libreplace.m4
@@ -344,6 +344,7 @@ m4_include(getpass.m4)
 m4_include(strptime.m4)
 m4_include(win32.m4)
 m4_include(timegm.m4)
+m4_include(socket.m4)
 m4_include(inet_ntop.m4)
 m4_include(inet_pton.m4)
 m4_include(getaddrinfo.m4)
diff --git a/source4/lib/replace/replace.h b/source4/lib/replace/replace.h
index 3f91544e97..0d16f4ffd0 100644
--- a/source4/lib/replace/replace.h
+++ b/source4/lib/replace/replace.h
@@ -340,6 +340,16 @@ ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset)
 /* prototype is in "system/network.h" */
 #endif
 
+#ifndef HAVE_CONNECT
+#define connect rep_connect
+/* prototype is in "system/network.h" */
+#endif
+
+#ifndef HAVE_GETHOSTBYNAME
+#define gethostbyname rep_gethostbyname
+/* prototype is in "system/network.h" */
+#endif
+
 #ifndef HAVE_GETIFADDRS
 #define getifaddrs rep_getifaddrs
 /* prototype is in "system/network.h" */
diff --git a/source4/lib/replace/socket.c b/source4/lib/replace/socket.c
new file mode 100644
index 0000000000..35e975fce7
--- /dev/null
+++ b/source4/lib/replace/socket.c
@@ -0,0 +1,35 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Dummy replacements for socket functions.
+ *
+ * Copyright (C) Michael Adam  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
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#include "replace.h"
+#include "system/network.h"
+
+int rep_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen)
+{
+	errno = ENOSYS;
+	return -1;
+}
+
+struct hostent *rep_gethostbyname(const char *name)
+{
+	errno = ENOSYS;
+	return NULL;
+}
diff --git a/source4/lib/replace/socket.m4 b/source4/lib/replace/socket.m4
new file mode 100644
index 0000000000..c0c8f93e81
--- /dev/null
+++ b/source4/lib/replace/socket.m4
@@ -0,0 +1,40 @@
+dnl The following test is roughl taken from the cvs sources.
+dnl
+dnl If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
+dnl The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
+dnl libsocket.so which has a bad implementation of gethostbyname (it
+dnl only looks in /etc/hosts), so we only look for -lsocket if we need
+dnl it.
+AC_CHECK_FUNCS(connect)
+if test x"$ac_cv_func_connect" = x"no"; then
+	AC_CHECK_LIB_EXT(nsl_s, SOCKET_LIBS, connect)
+	AC_CHECK_LIB_EXT(nsl, SOCKET_LIBS, connect)
+	AC_CHECK_LIB_EXT(socket, SOCKET_LIBS, connect)
+	AC_CHECK_LIB_EXT(inet, SOCKET_LIBS, connect)
+	dnl We can't just call AC_CHECK_FUNCS(connect) here,
+	dnl because the value has been cached.
+	if test x"$ac_cv_lib_ext_nsl_s_connect" = x"yes" ||
+		test x"$ac_cv_lib_ext_nsl_connect" = x"yes" ||
+		test x"$ac_cv_lib_ext_socket_connect" = x"yes" ||
+		test x"$ac_cv_lib_ext_inet_connect" = x"yes"
+	then
+		AC_DEFINE(HAVE_CONNECT,1,[Whether the system has connect()])
+	fi
+fi
+
+AC_CHECK_FUNCS(gethostbyname)
+if test x"$ac_cv_func_gethostbyname" = x"no"; then
+	AC_CHECK_LIB_EXT(nsl_s, NSL_LIBS, gethostbyname)
+	AC_CHECK_LIB_EXT(nsl, NSL_LIBS, gethostbyname)
+	AC_CHECK_LIB_EXT(socket, NSL_LIBS, gethostbyname)
+	dnl We can't just call AC_CHECK_FUNCS(gethostbyname) here,
+	dnl because the value has been cached.
+	if test x"$ac_cv_lib_ext_nsl_s_gethostbyname" = x"yes" ||
+		test x"$ac_cv_lib_ext_nsl_gethostbyname" = x"yes" ||
+		test x"$ac_cv_lib_ext_socket_gethostbyname" = x"yes"
+	then
+		AC_DEFINE(HAVE_GETHOSTBYNAME,1,
+			  [Whether the system has gethostbyname()])
+	fi
+fi
+
diff --git a/source4/lib/replace/system/network.h b/source4/lib/replace/system/network.h
index a84b22e5d0..410c6d7cca 100644
--- a/source4/lib/replace/system/network.h
+++ b/source4/lib/replace/system/network.h
@@ -103,6 +103,16 @@ int rep_inet_pton(int af, const char *src, void *dst);
 const char *rep_inet_ntop(int af, const void *src, char *dst, socklen_t size);
 #endif
 
+#ifndef HAVE_CONNECT
+/* define is in "replace.h" */
+int rep_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
+#endif
+
+#ifndef HAVE_GETHOSTBYNAME
+/* define is in "replace.h" */
+struct hostent *rep_gethostbyname(const char *name);
+#endif
+
 #ifdef HAVE_IFADDRS_H
 #include 
 #endif
-- 
cgit 


From 3a90bed29f6ddb2566f73f02a59eef1b0f1b7554 Mon Sep 17 00:00:00 2001
From: Michael Adam 
Date: Wed, 27 Feb 2008 01:29:12 +0100
Subject: libreplace: fix standalone build on some systems.

getifaddr tests include system/network.h, which does not
find getaddrinfo.h without "-I.".

Michael
(This used to be commit cd95c702ed90128f659e27709c61d4c6abc969ef)
---
 source4/lib/replace/configure.ac | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/source4/lib/replace/configure.ac b/source4/lib/replace/configure.ac
index beeb77e152..72d788ddcc 100644
--- a/source4/lib/replace/configure.ac
+++ b/source4/lib/replace/configure.ac
@@ -3,6 +3,8 @@ AC_INIT(replace.c)
 AC_CONFIG_SRCDIR([replace.c])
 AC_CONFIG_HEADER(config.h)
 
+CFLAGS="$CFLAGS -I."
+
 AC_LIBREPLACE_ALL_CHECKS
 
 if test "$ac_cv_prog_gcc" = yes; then
-- 
cgit 


From b6f8132e928509e751f0dc35c93fb024105709ee Mon Sep 17 00:00:00 2001
From: Michael Adam 
Date: Wed, 27 Feb 2008 01:41:30 +0100
Subject: libreplace: fix standalone build - add necessary libs.

The libs needed for getifaddrs replacements have to be added
to LIBS and used for the testsuite target.

Michael
(This used to be commit e7c1d6513b945b205abe84b18a251d06e737e659)
---
 source4/lib/replace/Makefile.in   | 4 +++-
 source4/lib/replace/getifaddrs.m4 | 3 +++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/source4/lib/replace/Makefile.in b/source4/lib/replace/Makefile.in
index 30f39ac6cb..af9522f3a6 100644
--- a/source4/lib/replace/Makefile.in
+++ b/source4/lib/replace/Makefile.in
@@ -10,6 +10,7 @@ VPATH = @libreplacedir@
 srcdir = @srcdir@
 builddir = @builddir@
 INSTALL = @INSTALL@
+LIBS = @LIBS@
 
 .PHONY: test all showflags install installcheck clean distclean realdistclean
 
@@ -25,6 +26,7 @@ showflags:
 	@echo '  CC     = $(CC)'
 	@echo '  CFLAGS = $(CFLAGS)'
 	@echo '  LDFLAGS= $(LDFLAGS)'
+	@echo '  LIBS   = $(LIBS)'
 
 install: all
 	mkdir -p $(libdir)
@@ -41,7 +43,7 @@ installcheck: install test
 TEST_OBJS = test/testsuite.o test/os2_delete.o test/strptime.o
 
 testsuite: libreplace.a $(TEST_OBJS)
-	$(CC) -o testsuite $(TEST_OBJS) -L. -lreplace $(LDFLAGS)
+	$(CC) -o testsuite $(TEST_OBJS) -L. -lreplace $(LDFLAGS) $(LIBS)
 
 .c.o:
 	@echo Compiling $*.c
diff --git a/source4/lib/replace/getifaddrs.m4 b/source4/lib/replace/getifaddrs.m4
index dd2a95cb81..767797e8d2 100644
--- a/source4/lib/replace/getifaddrs.m4
+++ b/source4/lib/replace/getifaddrs.m4
@@ -71,6 +71,7 @@ AC_TRY_RUN([
            libreplace_cv_HAVE_IFACE_AIX=yes,libreplace_cv_HAVE_IFACE_AIX=no,libreplace_cv_HAVE_IFACE_AIX=cross)])
 if test x"$libreplace_cv_HAVE_IFACE_AIX" = x"yes"; then
     iface=yes;AC_DEFINE(HAVE_IFACE_AIX,1,[Whether iface AIX is available])
+	old_LIBS="$old_LIBS $LIBS"
 fi
 fi
 
@@ -87,6 +88,7 @@ AC_TRY_RUN([
            libreplace_cv_HAVE_IFACE_IFCONF=yes,libreplace_cv_HAVE_IFACE_IFCONF=no,libreplace_cv_HAVE_IFACE_IFCONF=cross)])
 if test x"$libreplace_cv_HAVE_IFACE_IFCONF" = x"yes"; then
     iface=yes;AC_DEFINE(HAVE_IFACE_IFCONF,1,[Whether iface ifconf is available])
+	old_LIBS="$old_LIBS $LIBS"
 fi
 fi
 
@@ -102,6 +104,7 @@ AC_TRY_RUN([
            libreplace_cv_HAVE_IFACE_IFREQ=yes,libreplace_cv_HAVE_IFACE_IFREQ=no,libreplace_cv_HAVE_IFACE_IFREQ=cross)])
 if test x"$libreplace_cv_HAVE_IFACE_IFREQ" = x"yes"; then
     iface=yes;AC_DEFINE(HAVE_IFACE_IFREQ,1,[Whether iface ifreq is available])
+	old_LIBS="$old_LIBS $LIBS"
 fi
 fi
 
-- 
cgit 


From c9009b9876e14ce9bd9e6941a8344e1f5e47dd21 Mon Sep 17 00:00:00 2001
From: Michael Adam 
Date: Wed, 27 Feb 2008 10:33:32 +0100
Subject: libreplace: standalone build: use -I$srcdir instead of -I.

Michael
(This used to be commit ff311e613226e660998824b887cb9595ffbe0275)
---
 source4/lib/replace/configure.ac | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source4/lib/replace/configure.ac b/source4/lib/replace/configure.ac
index 72d788ddcc..f5e054f476 100644
--- a/source4/lib/replace/configure.ac
+++ b/source4/lib/replace/configure.ac
@@ -3,7 +3,7 @@ AC_INIT(replace.c)
 AC_CONFIG_SRCDIR([replace.c])
 AC_CONFIG_HEADER(config.h)
 
-CFLAGS="$CFLAGS -I."
+CFLAGS="$CFLAGS -I$srcdir"
 
 AC_LIBREPLACE_ALL_CHECKS
 
-- 
cgit 


From b42e3fb232ca68e869de4b39826da861f48e6771 Mon Sep 17 00:00:00 2001
From: Matthias Dieter Wallnöfer 
Date: Wed, 27 Feb 2008 13:47:34 +0100
Subject: Fix cases, add version number. (#4935) (This used to be commit
 d2eb404ba1711abf6bb2718f8bb1dbbd104e7d4d)

---
 source4/setup/provision.reg | 39 ++++++++++++++++++++++++---------------
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/source4/setup/provision.reg b/source4/setup/provision.reg
index 892b5ec50c..b80db09c09 100644
--- a/source4/setup/provision.reg
+++ b/source4/setup/provision.reg
@@ -2,37 +2,46 @@ REGEDIT4
 
 [HKEY_LOCAL_MACHINE]
 
-[HKEY_LOCAL_MACHINE\System]
+[HKEY_LOCAL_MACHINE\SOFTWARE]
 
-[HKEY_LOCAL_MACHINE\System\CurrentControlSet]
+[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft]
 
-[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control]
+[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT]
 
-[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\ProductOptions]
+[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion]
+CurrentVersion=5.2
+
+[HKEY_LOCAL_MACHINE\SYSTEM]
+
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet]
+
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control]
+
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ProductOptions]
 ProductType=LanmanNT
 
-[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print]
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print]
 
-[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Terminal Server]
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server]
 
-[HKEY_LOCAL_MACHINE\System]
+[HKEY_LOCAL_MACHINE\SYSTEM]
 
-[HKEY_LOCAL_MACHINE\System\CurrentControlSet]
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet]
 
-[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services]
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services]
 
-[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon]
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon]
 
-[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters]
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters]
 RefusePasswordChange=REG_DWORD:0
 
-[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\REPLICATOR]
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\REPLICATOR]
 
-[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\REPLICATOR\Parameters]
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\REPLICATOR\Parameters]
 
-[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Alerter]
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Alerter]
 
-[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Alerter\Parameters]
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Alerter\Parameters]
 
 [HKEY_USERS]
 
-- 
cgit