[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