[SCM] Samba Shared Repository - branch v3-2-test updated - initial-v3-2-unstable-1309-g71b1e6f

Volker Lendecke vl at samba.org
Sat Jan 12 19:37:14 GMT 2008


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 <vl at samba.org>
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 <vl at samba.org>
Date:   Fri Jan 11 12:02:56 2008 +0100

    One more empty line

commit 85fe7f3f6ed4aae76e5cf31ab689b2dfacfd74de
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Jan 11 12:35:04 2008 +0100

    delete on close even prevents stat opens

commit 9ff79f231f1206631662b5c521ecddf5df9141c0
Author: Volker Lendecke <vl at samba.org>
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/librpc_echo. at SHLIBEXT@: $(BINARY_PREREQS) $(RPC_ECHO_OBJ)
 bin/winbindd at EXEEXT@: $(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/vlp at EXEEXT@: $(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


More information about the samba-cvs mailing list