The branch, v3-2-test has been updated
       via  71b1e6ff1595fbaa8dd49b996c45541531c7e98c (commit)
       via  10b6f52910b4d29da4ea74740a174654dd1d8e8e (commit)
       via  85fe7f3f6ed4aae76e5cf31ab689b2dfacfd74de (commit)
       via  9ff79f231f1206631662b5c521ecddf5df9141c0 (commit)
      from  8809eaeb154ea12543455f589e31172dc905d83a (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-2-test


- Log -----------------------------------------------------------------
commit 71b1e6ff1595fbaa8dd49b996c45541531c7e98c
Author: Volker Lendecke <[EMAIL PROTECTED]>
Date:   Sat Jan 12 10:38:17 2008 +0100

    Restructure dbwrap_rbt
    
    In this low-level code, play tricks to reduce the number of allocations to 
the
    possible minimum. I would not recommend this for higher-level code, but 
here it
    pays off.

commit 10b6f52910b4d29da4ea74740a174654dd1d8e8e
Author: Volker Lendecke <[EMAIL PROTECTED]>
Date:   Fri Jan 11 12:02:56 2008 +0100

    One more empty line

commit 85fe7f3f6ed4aae76e5cf31ab689b2dfacfd74de
Author: Volker Lendecke <[EMAIL PROTECTED]>
Date:   Fri Jan 11 12:35:04 2008 +0100

    delete on close even prevents stat opens

commit 9ff79f231f1206631662b5c521ecddf5df9141c0
Author: Volker Lendecke <[EMAIL PROTECTED]>
Date:   Fri Jan 11 21:53:29 2008 +0100

    There's no point in calling FLOCK on a non-existing fd

-----------------------------------------------------------------------

Summary of changes:
 source/Makefile.in      |    4 +-
 source/lib/dbwrap_rbt.c |  186 ++++++++++++++++++++++++++++++++---------------
 source/smbd/open.c      |   28 ++++---
 3 files changed, 144 insertions(+), 74 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/Makefile.in b/source/Makefile.in
index 5257b6f..f03bd19 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -1529,8 +1529,8 @@ bin/[EMAIL PROTECTED]@: $(BINARY_PREREQS) $(RPC_ECHO_OBJ)
 bin/[EMAIL PROTECTED]@: $(BINARY_PREREQS) $(WINBINDD_OBJ) @BUILD_POPT@ 
@LIBWBCLIENT_SHARED@
        @echo "Linking $@"
        @$(CC) $(FLAGS) -o $@ $(WINBINDD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \
-               @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(PASSDB_LIBS) \
-               @WINBIND_LIBS@
+               @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) \
+               $(PASSDB_LIBS) @WINBIND_LIBS@
 
 bin/[EMAIL PROTECTED]@: $(BINARY_PREREQS) $(VLP_OBJ) @LIBWBCLIENT_SHARED@
        @echo "Linking $@"
diff --git a/source/lib/dbwrap_rbt.c b/source/lib/dbwrap_rbt.c
index 93d73f2..633b695 100644
--- a/source/lib/dbwrap_rbt.c
+++ b/source/lib/dbwrap_rbt.c
@@ -1,7 +1,7 @@
 /*
    Unix SMB/CIFS implementation.
    Database interface wrapper around red-black trees
-   Copyright (C) Volker Lendecke 2007
+   Copyright (C) Volker Lendecke 2007, 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
@@ -20,6 +20,8 @@
 #include "includes.h"
 #include "rbtree.h"
 
+#define ALIGN(_size_) (((_size_)+15)&~15)
+
 struct db_rbt_ctx {
        struct rb_root tree;
 };
@@ -44,6 +46,35 @@ struct db_rbt_node {
 };
 
 /*
+ * Hide the ugly pointer calculations in a function
+ */
+
+static struct db_rbt_node *db_rbt2node(struct rb_node *node)
+{
+       return (struct db_rbt_node *)
+               ((char *)node - offsetof(struct db_rbt_node, rb_node));
+}
+
+/*
+ * Compare two keys
+ */
+
+static int db_rbt_compare(TDB_DATA a, TDB_DATA b)
+{
+       int res;
+
+       res = memcmp(a.dptr, b.dptr, MIN(a.dsize, b.dsize));
+
+       if ((res < 0) || ((res == 0) && (a.dsize < b.dsize))) {
+               return -1;
+       }
+       if ((res > 0) || ((res == 0) && (a.dsize > b.dsize))) {
+               return 1;
+       }
+       return 0;
+}
+
+/*
  * dissect a db_rbt_node into its implicit key and value parts
  */
 
@@ -58,9 +89,7 @@ static void db_rbt_parse_node(struct db_rbt_node *node,
 
 static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
 {
-       struct db_rbt_rec *rec_priv = talloc_get_type_abort(
-               rec->private_data, struct db_rbt_rec);
-
+       struct db_rbt_rec *rec_priv = (struct db_rbt_rec *)rec->private_data;
        struct db_rbt_node *node;
 
        struct rb_node ** p;
@@ -133,22 +162,16 @@ static NTSTATUS db_rbt_store(struct db_record *rec, 
TDB_DATA data, int flag)
 
                parent = (*p);
 
-               r = (struct db_rbt_node *)
-                       ((char *)(*p) - offsetof(struct db_rbt_node, rb_node));
+               r = db_rbt2node(*p);
 
                db_rbt_parse_node(r, &search_key, &search_val);
 
-               res = memcmp(this_key.dptr, search_key.dptr,
-                            MIN(this_key.dsize, search_key.dsize));
+               res = db_rbt_compare(this_key, search_key);
 
-               if ((res < 0)
-                   || ((res == 0)
-                       && (this_key.dsize < search_key.dsize))) {
+               if (res == -1) {
                        p = &(*p)->rb_left;
                }
-               else if ((res > 0)
-                        || ((res == 0)
-                            && (this_key.dsize > search_key.dsize))) {
+               else if (res == 1) {
                        p = &(*p)->rb_right;
                }
                else {
@@ -164,8 +187,7 @@ static NTSTATUS db_rbt_store(struct db_record *rec, 
TDB_DATA data, int flag)
 
 static NTSTATUS db_rbt_delete(struct db_record *rec)
 {
-       struct db_rbt_rec *rec_priv = talloc_get_type_abort(
-               rec->private_data, struct db_rbt_rec);
+       struct db_rbt_rec *rec_priv = (struct db_rbt_rec *)rec->private_data;
 
        if (rec_priv->node == NULL) {
                return NT_STATUS_OK;
@@ -187,85 +209,128 @@ static struct db_record *db_rbt_fetch_locked(struct 
db_context *db_ctx,
        struct db_rbt_rec *rec_priv;
        struct db_record *result;
        struct rb_node *n;
+       size_t size;
+       bool found = false;
+       struct db_rbt_node *r = NULL;
+       TDB_DATA search_key = tdb_null, search_val = tdb_null;
 
-       result = talloc(mem_ctx, struct db_record);
+       n = ctx->tree.rb_node;
 
-       if (result == NULL) {
-               return NULL;
+       while (n != NULL) {
+               int res;
+
+               r = db_rbt2node(n);
+
+               db_rbt_parse_node(r, &search_key, &search_val);
+
+               res = db_rbt_compare(key, search_key);
+
+               if (res == -1) {
+                       n = n->rb_left;
+               }
+               else if (res == 1) {
+                       n = n->rb_right;
+               }
+               else {
+                       found = true;
+                       break;
+               }
        }
 
-       rec_priv = talloc(result, struct db_rbt_rec);
+       /*
+        * In this low-level routine, play tricks to reduce the number of
+        * tallocs to one. Not recommened for general use, but here it pays
+        * off.
+        */
 
-       if (rec_priv == NULL) {
-               TALLOC_FREE(result);
+       size = ALIGN(sizeof(struct db_record)) + sizeof(struct db_rbt_rec);
+
+       if (!found) {
+               /*
+                * We need to keep the key around for later store
+                */
+               size += key.dsize;
+       }
+
+       result = (struct db_record *)talloc_size(mem_ctx, size);
+       if (result == NULL) {
                return NULL;
        }
 
+       rec_priv = (struct db_rbt_rec *)
+               ((char *)result + ALIGN(sizeof(struct db_record)));
        rec_priv->db_ctx = ctx;
 
        result->store = db_rbt_store;
        result->delete_rec = db_rbt_delete;
        result->private_data = rec_priv;
 
+       if (found) {
+               rec_priv->node = r;
+               result->key = search_key;
+               result->value = search_val;
+       }
+       else {
+               rec_priv->node = NULL;
+               result->key.dptr = (uint8 *)
+                       ((char *)rec_priv + sizeof(*rec_priv));
+               result->key.dsize = key.dsize;
+               memcpy(result->key.dptr, key.dptr, key.dsize);
+
+               result->value = tdb_null;
+       }
+
+       return result;
+}
+
+static int db_rbt_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
+                       TDB_DATA key, TDB_DATA *data)
+{
+       struct db_rbt_ctx *ctx = talloc_get_type_abort(
+               db->private_data, struct db_rbt_ctx);
+
+       struct rb_node *n;
+       bool found = false;
+       struct db_rbt_node *r = NULL;
+       TDB_DATA search_key, search_val;
+       uint8_t *result;
+
        n = ctx->tree.rb_node;
 
        while (n != NULL) {
-               struct db_rbt_node *r;
-               TDB_DATA search_key, search_val;
                int res;
 
-               r = (struct db_rbt_node *)
-                       ((char *)n - offsetof(struct db_rbt_node, rb_node));
+               r = db_rbt2node(n);
 
                db_rbt_parse_node(r, &search_key, &search_val);
 
-               res = memcmp(key.dptr, search_key.dptr,
-                            MIN(key.dsize, search_key.dsize));
+               res = db_rbt_compare(key, search_key);
 
-               if ((res < 0)
-                   || ((res == 0) && (key.dsize < search_key.dsize))) {
+               if (res == -1) {
                        n = n->rb_left;
                }
-               else if ((res > 0)
-                        || ((res == 0) && (key.dsize > search_key.dsize))) {
+               else if (res == 1) {
                        n = n->rb_right;
                }
                else {
-                       rec_priv->node = r;
-                       result->key = search_key;
-                       result->value = search_val;
-                       return result;
+                       found = true;
+                       break;
                }
        }
 
-       result->key.dsize = key.dsize;
-       result->key.dptr = (uint8_t *)talloc_memdup(
-               result, key.dptr, key.dsize);
-
-       if (result->key.dptr == NULL) {
-               TALLOC_FREE(result);
-               return NULL;
+       if (!found) {
+               *data = tdb_null;
+               return 0;
        }
 
-       rec_priv->node = NULL;
-       result->value.dsize = 0;
-       result->value.dptr = NULL;
-       return result;
-}
-
-static int db_rbt_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
-                       TDB_DATA key, TDB_DATA *data)
-{
-       struct db_record *rec;
-
-       if (!(rec = db->fetch_locked(db, mem_ctx, key))) {
+       result = (uint8 *)talloc_memdup(mem_ctx, search_val.dptr,
+                                       search_val.dsize);
+       if (result == NULL) {
                return -1;
        }
 
-       data->dsize = rec->value.dsize;
-       data->dptr = (uint8 *)talloc_memdup(mem_ctx, rec->value.dptr,
-                                           rec->value.dsize);
-       TALLOC_FREE(rec);
+       data->dptr = result;
+       data->dsize = search_val.dsize;
        return 0;
 }
 
@@ -275,6 +340,9 @@ static int db_rbt_traverse(struct db_context *db,
                                    void *private_data),
                           void *private_data)
 {
+       /*
+        * Nobody uses this so far, and unused code is broken code :-)
+        */
        return -1;
 }
 
diff --git a/source/smbd/open.c b/source/smbd/open.c
index 59699df..9d48bcc 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -598,12 +598,6 @@ static NTSTATUS open_mode_check(connection_struct *conn,
        }
 
        *file_existed = True;
-       
-       if (is_stat_open(access_mask)) {
-               /* Stat open that doesn't trigger oplock breaks or share mode
-                * checks... ! JRA. */
-               return NT_STATUS_OK;
-       }
 
        /* A delete on close prohibits everything */
 
@@ -611,6 +605,12 @@ static NTSTATUS open_mode_check(connection_struct *conn,
                return NT_STATUS_DELETE_PENDING;
        }
 
+       if (is_stat_open(access_mask)) {
+               /* Stat open that doesn't trigger oplock breaks or share mode
+                * checks... ! JRA. */
+               return NT_STATUS_OK;
+       }
+
        /*
         * Check if the share modes will give us access.
         */
@@ -1761,14 +1761,16 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
            the kernel refuses the operations then the kernel is wrong.
           note that GPFS supports it as well - jmcd */
 
-       ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access);
-       if(ret_flock == -1 ){
+       if (fsp->fh->fd != -1) {
+               ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access);
+               if(ret_flock == -1 ){
 
-               TALLOC_FREE(lck);
-               fd_close(fsp);
-               file_free(fsp);
-               
-               return NT_STATUS_SHARING_VIOLATION;
+                       TALLOC_FREE(lck);
+                       fd_close(fsp);
+                       file_free(fsp);
+
+                       return NT_STATUS_SHARING_VIOLATION;
+               }
        }
 
        /*


-- 
Samba Shared Repository

Reply via email to