[PATCH] Cleanups & notify preparations
Volker Lendecke
Volker.Lendecke at SerNet.DE
Mon Dec 8 09:16:49 MST 2014
Hi!
Review&push appreciated!
Thanks,
Volker
--
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de, mailto:kontakt at sernet.de
-------------- next part --------------
From 91d938bcaf55a30f5129161b38d2348da7b76eaf Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Sun, 7 Dec 2014 14:09:29 +0100
Subject: [PATCH 01/16] lib: Fix a typo
Signed-off-by: Volker Lendecke <vl at samba.org>
---
lib/util/charset/iconv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/util/charset/iconv.c b/lib/util/charset/iconv.c
index c5b45fe..f4815f1 100644
--- a/lib/util/charset/iconv.c
+++ b/lib/util/charset/iconv.c
@@ -219,7 +219,7 @@ _PUBLIC_ smb_iconv_t smb_iconv_open_ex(TALLOC_CTX *mem_ctx, const char *tocode,
}
#ifdef HAVE_NATIVE_ICONV
- /* the from and to varaibles indicate a samba module or
+ /* the from and to variables indicate a samba module or
* internal conversion, ret->pull and ret->push are
* initialised only in this block for iconv based
* conversions */
--
1.9.1
From 57ed6e62948f03bc8335627a9be58d49d5ed681a Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Sun, 7 Dec 2014 14:13:51 +0100
Subject: [PATCH 02/16] lib: Fix blank line endings
Signed-off-by: Volker Lendecke <vl at samba.org>
---
lib/util/charset/iconv.c | 68 ++++++++++++++++++++++++------------------------
lib/util/idtree.c | 16 ++++++------
lib/util/util_file.c | 26 +++++++++---------
3 files changed, 55 insertions(+), 55 deletions(-)
diff --git a/lib/util/charset/iconv.c b/lib/util/charset/iconv.c
index f4815f1..bf561f2 100644
--- a/lib/util/charset/iconv.c
+++ b/lib/util/charset/iconv.c
@@ -1,19 +1,19 @@
-/*
+/*
Unix SMB/CIFS implementation.
minimal iconv implementation
Copyright (C) Andrew Tridgell 2001
Copyright (C) Jelmer Vernooij 2002
-
+
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 <http://www.gnu.org/licenses/>.
*/
@@ -80,7 +80,7 @@ static const struct charset_functions builtin_functions[] = {
{"ASCII", ascii_pull, ascii_push},
{"646", ascii_pull, ascii_push},
{"ISO-8859-1", latin1_pull, latin1_push},
-#ifdef DEVELOPER
+#ifdef DEVELOPER
{"WEIRD", weird_pull, weird_push, true},
#endif
#ifdef DARWINOS
@@ -94,12 +94,12 @@ static const struct charset_functions builtin_functions[] = {
/* if there was an error then reset the internal state,
this ensures that we don't have a shift state remaining for
character sets like SJIS */
-static size_t sys_iconv(void *cd,
+static size_t sys_iconv(void *cd,
const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
- size_t ret = iconv((iconv_t)cd,
- discard_const_p(char *, inbuf), inbytesleft,
+ size_t ret = iconv((iconv_t)cd,
+ discard_const_p(char *, inbuf), inbytesleft,
outbuf, outbytesleft);
if (ret == (size_t)-1) iconv(cd, NULL, NULL, NULL, NULL);
return ret;
@@ -112,13 +112,13 @@ static size_t sys_iconv(void *cd,
* It only knows about a very small number of character sets - just
* enough that Samba works on systems that don't have iconv.
**/
-_PUBLIC_ size_t smb_iconv(smb_iconv_t cd,
+_PUBLIC_ size_t smb_iconv(smb_iconv_t cd,
const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
/* in many cases we can go direct */
if (cd->direct) {
- return cd->direct(cd->cd_direct,
+ return cd->direct(cd->cd_direct,
inbuf, inbytesleft, outbuf, outbytesleft);
}
@@ -189,7 +189,7 @@ _PUBLIC_ smb_iconv_t smb_iconv_open_ex(TALLOC_CTX *mem_ctx, const char *tocode,
int i;
ret = (smb_iconv_t)talloc_named(mem_ctx,
- sizeof(*ret),
+ sizeof(*ret),
"iconv(%s,%s)", tocode, fromcode);
if (!ret) {
errno = ENOMEM;
@@ -211,7 +211,7 @@ _PUBLIC_ smb_iconv_t smb_iconv_open_ex(TALLOC_CTX *mem_ctx, const char *tocode,
from = &builtin_functions[i];
}
}
- if (strcasecmp(tocode, builtin_functions[i].name) == 0) {
+ if (strcasecmp(tocode, builtin_functions[i].name) == 0) {
if (use_builtin_handlers || builtin_functions[i].samba_internal_charset) {
to = &builtin_functions[i];
}
@@ -232,7 +232,7 @@ _PUBLIC_ smb_iconv_t smb_iconv_open_ex(TALLOC_CTX *mem_ctx, const char *tocode,
ret->pull = sys_iconv;
}
}
-
+
if (to == NULL) {
ret->cd_push = iconv_open(tocode, "UTF-16LE");
if (ret->cd_push == (iconv_t)-1)
@@ -246,7 +246,7 @@ _PUBLIC_ smb_iconv_t smb_iconv_open_ex(TALLOC_CTX *mem_ctx, const char *tocode,
if (ret->pull == NULL && from == NULL) {
goto failed;
}
-
+
if (ret->push == NULL && to == NULL) {
goto failed;
}
@@ -340,7 +340,7 @@ static size_t ascii_pull(void *cd, const char **inbuf, size_t *inbytesleft,
errno = E2BIG;
return -1;
}
-
+
return 0;
}
@@ -379,7 +379,7 @@ static size_t ascii_push(void *cd, const char **inbuf, size_t *inbytesleft,
errno = E2BIG;
return -1;
}
-
+
return ir_count;
}
@@ -469,7 +469,7 @@ static size_t ucs2hex_pull(void *cd, const char **inbuf, size_t *inbytesleft,
errno = EINVAL;
return -1;
}
-
+
if (sscanf(&(*inbuf)[1], "%04x", &v) != 1) {
errno = EILSEQ;
return -1;
@@ -487,7 +487,7 @@ static size_t ucs2hex_pull(void *cd, const char **inbuf, size_t *inbytesleft,
errno = E2BIG;
return -1;
}
-
+
return 0;
}
@@ -497,7 +497,7 @@ static size_t ucs2hex_push(void *cd, const char **inbuf, size_t *inbytesleft,
while (*inbytesleft >= 2 && *outbytesleft >= 1) {
char buf[6];
- if ((*inbuf)[1] == 0 &&
+ if ((*inbuf)[1] == 0 &&
((*inbuf)[0] & 0x80) == 0 &&
(*inbuf)[0] != '@') {
(*outbuf)[0] = (*inbuf)[0];
@@ -528,7 +528,7 @@ static size_t ucs2hex_push(void *cd, const char **inbuf, size_t *inbytesleft,
errno = E2BIG;
return -1;
}
-
+
return 0;
}
@@ -618,7 +618,7 @@ static size_t utf8_pull(void *cd, const char **inbuf, size_t *inbytesleft,
if ((c[0] & 0xf0) == 0xe0) {
if (in_left < 3 ||
- (c[1] & 0xc0) != 0x80 ||
+ (c[1] & 0xc0) != 0x80 ||
(c[2] & 0xc0) != 0x80) {
errno = EILSEQ;
goto error;
@@ -635,15 +635,15 @@ static size_t utf8_pull(void *cd, const char **inbuf, size_t *inbytesleft,
if ((c[0] & 0xf8) == 0xf0) {
unsigned int codepoint;
if (in_left < 4 ||
- (c[1] & 0xc0) != 0x80 ||
+ (c[1] & 0xc0) != 0x80 ||
(c[2] & 0xc0) != 0x80 ||
(c[3] & 0xc0) != 0x80) {
errno = EILSEQ;
goto error;
}
- codepoint =
- (c[3]&0x3f) |
- ((c[2]&0x3f)<<6) |
+ codepoint =
+ (c[3]&0x3f) |
+ ((c[2]&0x3f)<<6) |
((c[1]&0x3f)<<12) |
((c[0]&0x7)<<18);
if (codepoint < 0x10000) {
@@ -758,7 +758,7 @@ static size_t utf8_push(void *cd, const char **inbuf, size_t *inbytesleft,
c[0] = 0xe0 | (codepoint >> 12);
c[1] = 0x80 | ((codepoint >> 6) & 0x3f);
c[2] = 0x80 | (codepoint & 0x3f);
-
+
in_left -= 2;
out_left -= 3;
uc += 2;
@@ -775,9 +775,9 @@ static size_t utf8_push(void *cd, const char **inbuf, size_t *inbytesleft,
errno = EILSEQ;
goto error;
}
- codepoint = 0x10000 + (uc[2] | ((uc[3] & 0x3)<<8) |
+ codepoint = 0x10000 + (uc[2] | ((uc[3] & 0x3)<<8) |
(uc[0]<<10) | ((uc[1] & 0x3)<<18));
-
+
if (out_left < 4) {
errno = E2BIG;
goto error;
@@ -786,7 +786,7 @@ static size_t utf8_push(void *cd, const char **inbuf, size_t *inbytesleft,
c[1] = 0x80 | ((codepoint >> 12) & 0x3f);
c[2] = 0x80 | ((codepoint >> 6) & 0x3f);
c[3] = 0x80 | (codepoint & 0x3f);
-
+
in_left -= 4;
out_left -= 4;
uc += 4;
@@ -807,7 +807,7 @@ static size_t utf8_push(void *cd, const char **inbuf, size_t *inbytesleft,
*outbytesleft = out_left;
*inbuf = (const char *)uc;
*outbuf = (char *)c;
-
+
return 0;
error:
@@ -853,7 +853,7 @@ static size_t utf16_munged_pull(void *cd, const char **inbuf, size_t *inbyteslef
unsigned int codepoint2;
if (in_left < 4) {
codepoint = 0xfffd;
- goto codepoint16;
+ goto codepoint16;
}
codepoint2 = uc[2] | (uc[3]<<8);
if ((codepoint2 & 0xfc00) != 0xdc00) {
@@ -883,12 +883,12 @@ static size_t utf16_munged_pull(void *cd, const char **inbuf, size_t *inbyteslef
codepoint16:
c[0] = codepoint & 0xFF;
c[1] = (codepoint>>8) & 0xFF;
-
+
in_left -= 2;
out_left -= 2;
uc += 2;
c += 2;
- continue;
+ continue;
}
if (in_left == 1) {
@@ -905,7 +905,7 @@ static size_t utf16_munged_pull(void *cd, const char **inbuf, size_t *inbyteslef
*outbytesleft = out_left;
*inbuf = (const char *)uc;
*outbuf = (char *)c;
-
+
return 0;
error:
diff --git a/lib/util/idtree.c b/lib/util/idtree.c
index 6f1a4ac..0056c09 100644
--- a/lib/util/idtree.c
+++ b/lib/util/idtree.c
@@ -1,4 +1,4 @@
-/*
+/*
Unix SMB/CIFS implementation.
very efficient functions to manage mapping a id (such as a fnum) to
@@ -6,20 +6,20 @@
Copyright (C) Andrew Tridgell 2004
- This code is derived from lib/idr.c in the 2.6 Linux kernel, which was
+ This code is derived from lib/idr.c in the 2.6 Linux kernel, which was
written by Jim Houston jim.houston at ccur.com, and is
Copyright (C) 2002 by Concurrent Computer Corporation
-
+
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 2 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 <http://www.gnu.org/licenses/>.
*/
@@ -53,7 +53,7 @@
#define set_bit(bit, v) (v) |= (1<<(bit))
#define clear_bit(bit, v) (v) &= ~(1<<(bit))
#define test_bit(bit, v) ((v) & (1<<(bit)))
-
+
struct idr_layer {
uint32_t bitmap;
struct idr_layer *ary[IDR_SIZE];
@@ -195,7 +195,7 @@ static int idr_get_new_above_int(struct idr_context *idp, void *ptr, int startin
int layers, v, id;
idr_pre_get(idp);
-
+
id = starting_id;
build_up:
p = idp->top;
@@ -309,7 +309,7 @@ static int _idr_remove(struct idr_context *idp, int id)
return -1;
}
- if ( idp->top && idp->top->count == 1 &&
+ if ( idp->top && idp->top->count == 1 &&
(idp->layers > 1) &&
idp->top->ary[0]) {
/* We can drop a layer */
diff --git a/lib/util/util_file.c b/lib/util/util_file.c
index 886bcae..83c746b 100644
--- a/lib/util/util_file.c
+++ b/lib/util/util_file.c
@@ -4,17 +4,17 @@
* Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
*
* Added afdgets() Jelmer Vernooij 2005
- *
+ *
* 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 <http://www.gnu.org/licenses/>.
*/
@@ -32,7 +32,7 @@
*/
/**
-read a line from a file with possible \ continuation chars.
+read a line from a file with possible \ continuation chars.
Blanks at the start or end of a line are stripped.
The string will be allocated if s2 is NULL
**/
@@ -78,7 +78,7 @@ _PUBLIC_ char *fgets_slash(char *s2,int maxlen,XFILE *f)
}
return(s);
case EOF:
- if (len <= 0 && !s2)
+ if (len <= 0 && !s2)
SAFE_FREE(s);
return(len>0?s:NULL);
case ' ':
@@ -93,7 +93,7 @@ _PUBLIC_ char *fgets_slash(char *s2,int maxlen,XFILE *f)
if (!s2 && len > maxlen-3)
{
char *t;
-
+
maxlen *= 2;
t = realloc_p(s, char, maxlen);
if (!t) {
@@ -107,7 +107,7 @@ _PUBLIC_ char *fgets_slash(char *s2,int maxlen,XFILE *f)
}
/**
- * Read one line (data until next newline or eof) and allocate it
+ * Read one line (data until next newline or eof) and allocate it
*/
_PUBLIC_ char *afdgets(int fd, TALLOC_CTX *mem_ctx, size_t hint)
{
@@ -200,7 +200,7 @@ _PUBLIC_ char *file_load(const char *fname, size_t *size, size_t maxsize, TALLOC
char *p;
if (!fname || !*fname) return NULL;
-
+
fd = open(fname,O_RDONLY);
if (fd == -1) return NULL;
@@ -256,7 +256,7 @@ bool unmap_file(void *start, size_t size)
#ifdef HAVE_MMAP
if (munmap( start, size ) != 0) {
DEBUG( 1, ("map_file: Failed to unmap address %p "
- "of size %u - %s\n",
+ "of size %u - %s\n",
start, (unsigned int)size, strerror(errno) ));
return false;
}
@@ -286,10 +286,10 @@ char **file_lines_parse(char *p, size_t size, int *numlines, TALLOC_CTX *mem_ctx
if (!ret) {
talloc_free(p);
return NULL;
- }
-
+ }
+
talloc_steal(ret, p);
-
+
memset(ret, 0, sizeof(ret[0])*(i+2));
ret[0] = p;
@@ -315,7 +315,7 @@ char **file_lines_parse(char *p, size_t size, int *numlines, TALLOC_CTX *mem_ctx
/**
load a file into memory and return an array of pointers to lines in the file
-must be freed with talloc_free().
+must be freed with talloc_free().
**/
_PUBLIC_ char **file_lines_load(const char *fname, int *numlines, size_t maxsize, TALLOC_CTX *mem_ctx)
{
--
1.9.1
From 757b1b204d29b64c3324e05f716335942a029057 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Thu, 13 Nov 2014 10:38:40 +0000
Subject: [PATCH 03/16] messaging3: Avoid self-send complexity
With the notify code I've hit another case where self-sends caused
a problem. This time messages were lost because we tried to do
multiple dispatch_rec calls from within a single inotify callback.
Only the first one was being taken care of, the others did not find
receivers.
This patch makes self-sends go through the kernel as well, the
kernel queues everything nicely for us. With dgram messaging this
should be pretty fast. If it turns out to be a performance problem,
we can solve it later by doing proper queueing in user space. We
need to completely decouple any processing from callbacks.
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/lib/messages.c | 113 +---------------------------
source3/torture/test_messaging_fd_passing.c | 2 +-
source3/torture/test_messaging_read.c | 2 +-
3 files changed, 5 insertions(+), 112 deletions(-)
diff --git a/source3/lib/messages.c b/source3/lib/messages.c
index 5b4daa2..1fd7601 100644
--- a/source3/lib/messages.c
+++ b/source3/lib/messages.c
@@ -507,36 +507,6 @@ NTSTATUS messaging_send_iov(struct messaging_context *msg_ctx,
return NT_STATUS_OK;
}
- if (server_id_same_process(&msg_ctx->id, &server)) {
- struct messaging_rec rec;
- uint8_t *buf;
-
- /*
- * Self-send, directly dispatch
- */
-
- if (num_fds > 0) {
- return NT_STATUS_NOT_SUPPORTED;
- }
-
- buf = iov_buf(talloc_tos(), iov, iovlen);
- if (buf == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
-
- rec = (struct messaging_rec) {
- .msg_version = MESSAGE_VERSION,
- .msg_type = msg_type & MSG_TYPE_MASK,
- .dest = server,
- .src = msg_ctx->id,
- .buf = data_blob_const(buf, talloc_get_size(buf)),
- };
-
- messaging_dispatch_rec(msg_ctx, &rec);
- TALLOC_FREE(buf);
- return NT_STATUS_OK;
- }
-
ZERO_STRUCT(hdr);
hdr = (struct messaging_hdr) {
.msg_type = msg_type,
@@ -826,68 +796,6 @@ static bool messaging_append_new_waiters(struct messaging_context *msg_ctx)
return true;
}
-struct messaging_defer_callback_state {
- struct messaging_context *msg_ctx;
- struct messaging_rec *rec;
- void (*fn)(struct messaging_context *msg, void *private_data,
- uint32_t msg_type, struct server_id server_id,
- DATA_BLOB *data);
- void *private_data;
-};
-
-static void messaging_defer_callback_trigger(struct tevent_context *ev,
- struct tevent_immediate *im,
- void *private_data);
-
-static void messaging_defer_callback(
- struct messaging_context *msg_ctx, struct messaging_rec *rec,
- void (*fn)(struct messaging_context *msg, void *private_data,
- uint32_t msg_type, struct server_id server_id,
- DATA_BLOB *data),
- void *private_data)
-{
- struct messaging_defer_callback_state *state;
- struct tevent_immediate *im;
-
- state = talloc(msg_ctx, struct messaging_defer_callback_state);
- if (state == NULL) {
- DEBUG(1, ("talloc failed\n"));
- return;
- }
- state->msg_ctx = msg_ctx;
- state->fn = fn;
- state->private_data = private_data;
-
- state->rec = messaging_rec_dup(state, rec);
- if (state->rec == NULL) {
- DEBUG(1, ("talloc failed\n"));
- TALLOC_FREE(state);
- return;
- }
-
- im = tevent_create_immediate(state);
- if (im == NULL) {
- DEBUG(1, ("tevent_create_immediate failed\n"));
- TALLOC_FREE(state);
- return;
- }
- tevent_schedule_immediate(im, msg_ctx->event_ctx,
- messaging_defer_callback_trigger, state);
-}
-
-static void messaging_defer_callback_trigger(struct tevent_context *ev,
- struct tevent_immediate *im,
- void *private_data)
-{
- struct messaging_defer_callback_state *state = talloc_get_type_abort(
- private_data, struct messaging_defer_callback_state);
- struct messaging_rec *rec = state->rec;
-
- state->fn(state->msg_ctx, state->private_data, rec->msg_type, rec->src,
- &rec->buf);
- TALLOC_FREE(state);
-}
-
/*
Dispatch one messaging_rec
*/
@@ -914,24 +822,9 @@ void messaging_dispatch_rec(struct messaging_context *msg_ctx,
rec->num_fds = 0;
rec->fds = NULL;
- if (server_id_same_process(&rec->src, &rec->dest)) {
- /*
- * This is a self-send. We are called here from
- * messaging_send(), and we don't want to directly
- * recurse into the callback but go via a
- * tevent_loop_once
- */
- messaging_defer_callback(msg_ctx, rec, cb->fn,
- cb->private_data);
- } else {
- /*
- * This comes from a different process. we are called
- * from the event loop, so we should call back
- * directly.
- */
- cb->fn(msg_ctx, cb->private_data, rec->msg_type,
- rec->src, &rec->buf);
- }
+ cb->fn(msg_ctx, cb->private_data, rec->msg_type,
+ rec->src, &rec->buf);
+
/*
* we continue looking for matching messages after finding
* one. This matters for subsystems like the internal notify
diff --git a/source3/torture/test_messaging_fd_passing.c b/source3/torture/test_messaging_fd_passing.c
index abd142f..7bee41b 100644
--- a/source3/torture/test_messaging_fd_passing.c
+++ b/source3/torture/test_messaging_fd_passing.c
@@ -63,7 +63,7 @@ bool run_messaging_fdpass1(int dummy)
status = messaging_send_iov(msg_ctx, dst, MSG_PING, NULL, 0,
pass_fds, 1);
- if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
fprintf(stderr,
"messaging_send_iov gave: %s\n", nt_errstr(status));
goto fail;
diff --git a/source3/torture/test_messaging_read.c b/source3/torture/test_messaging_read.c
index 9c4017c..802b4fe 100644
--- a/source3/torture/test_messaging_read.c
+++ b/source3/torture/test_messaging_read.c
@@ -122,7 +122,7 @@ bool run_messaging_read1(int dummy)
goto fail;
}
- for (i=0; i<2; i++) {
+ for (i=0; i<3; i++) {
if (tevent_loop_once(ev) != 0) {
fprintf(stderr, "tevent_loop_once failed\n");
goto fail;
--
1.9.1
From 0142ed2967c54147c215e8435cc48041ae021abc Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Sat, 6 Dec 2014 11:22:35 +0100
Subject: [PATCH 04/16] lib: Simplify iov_buf[len]
This makes iov_buf independent of talloc
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/lib/iov_buf.c | 46 +++++++++++++++++---------------------------
source3/lib/iov_buf.h | 4 +++-
source3/lib/messages_ctdbd.c | 11 +++++++++--
source3/wscript_build | 2 +-
4 files changed, 31 insertions(+), 32 deletions(-)
diff --git a/source3/lib/iov_buf.c b/source3/lib/iov_buf.c
index dd99da3..e05dfc9 100644
--- a/source3/lib/iov_buf.c
+++ b/source3/lib/iov_buf.c
@@ -23,43 +23,33 @@
ssize_t iov_buflen(const struct iovec *iov, int iovcnt)
{
- size_t buflen = 0;
+ return iov_buf(iov, iovcnt, NULL, 0);
+}
+
+ssize_t iov_buf(const struct iovec *iov, int iovcnt,
+ uint8_t *buf, size_t buflen)
+{
+ size_t needed = 0;
+ uint8_t *p = buf;
int i;
for (i=0; i<iovcnt; i++) {
size_t thislen = iov[i].iov_len;
- size_t tmp = buflen + thislen;
+ size_t tmp;
+
+ tmp = needed + thislen;
- if ((tmp < buflen) || (tmp < thislen)) {
+ if ((tmp < needed) || (tmp < thislen)) {
/* overflow */
return -1;
}
- buflen = tmp;
- }
- return buflen;
-}
-
-uint8_t *iov_buf(TALLOC_CTX *mem_ctx, const struct iovec *iov, int iovcnt)
-{
- int i;
- ssize_t buflen;
- uint8_t *buf, *p;
+ needed = tmp;
- buflen = iov_buflen(iov, iovcnt);
- if (buflen == -1) {
- return NULL;
- }
- buf = talloc_array(mem_ctx, uint8_t, buflen);
- if (buf == NULL) {
- return NULL;
+ if (needed <= buflen) {
+ memcpy(p, iov[i].iov_base, thislen);
+ p += thislen;
+ }
}
- p = buf;
- for (i=0; i<iovcnt; i++) {
- size_t len = iov[i].iov_len;
-
- memcpy(p, iov[i].iov_base, len);
- p += len;
- }
- return buf;
+ return needed;
}
diff --git a/source3/lib/iov_buf.h b/source3/lib/iov_buf.h
index a884bdb..ec82909 100644
--- a/source3/lib/iov_buf.h
+++ b/source3/lib/iov_buf.h
@@ -22,8 +22,10 @@
#include <unistd.h>
#include <talloc.h>
+#include <stdint.h>
ssize_t iov_buflen(const struct iovec *iov, int iovlen);
-uint8_t *iov_buf(TALLOC_CTX *mem_ctx, const struct iovec *iov, int iovcnt);
+ssize_t iov_buf(const struct iovec *iov, int iovcnt,
+ uint8_t *buf, size_t buflen);
#endif
diff --git a/source3/lib/messages_ctdbd.c b/source3/lib/messages_ctdbd.c
index 59f5976..53aeb1f 100644
--- a/source3/lib/messages_ctdbd.c
+++ b/source3/lib/messages_ctdbd.c
@@ -100,16 +100,23 @@ static int messaging_ctdb_send(struct server_id src,
backend->private_data, struct messaging_ctdbd_context);
struct messaging_rec msg;
uint8_t *buf;
+ ssize_t buflen;
NTSTATUS status;
if (num_fds > 0) {
return ENOSYS;
}
- buf = iov_buf(talloc_tos(), iov, iovlen);
- if (buf == NULL) {
+ buflen = iov_buflen(iov, iovlen);
+ if (buflen == -1) {
+ return EMSGSIZE;
+ }
+
+ buf = talloc_array(talloc_tos(), uint8_t, buflen);
+ if (buflen == NULL) {
return ENOMEM;
}
+ iov_buf(iov, iovlen, buf, buflen);
msg = (struct messaging_rec) {
.msg_version = MESSAGE_VERSION,
diff --git a/source3/wscript_build b/source3/wscript_build
index 18f6b6d..51d72e7 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -260,7 +260,7 @@ bld.SAMBA3_LIBRARY('sys_rw',
bld.SAMBA3_LIBRARY('iov_buf',
source='lib/iov_buf.c',
- deps='replace talloc',
+ deps='replace',
private_library=True)
bld.SAMBA3_SUBSYSTEM('samba3util',
--
1.9.1
From 76a6ccbff87bb11926ef0128de248601c380666a Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Sat, 6 Dec 2014 11:28:16 +0100
Subject: [PATCH 05/16] lib: Use iov_buf in unix_msg
Now that iov_buf does not pull in talloc we can use it
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/lib/unix_msg/unix_msg.c | 25 ++-----------------------
source3/lib/unix_msg/wscript_build | 2 +-
2 files changed, 3 insertions(+), 24 deletions(-)
diff --git a/source3/lib/unix_msg/unix_msg.c b/source3/lib/unix_msg/unix_msg.c
index 7ca506a..78b29c2 100644
--- a/source3/lib/unix_msg/unix_msg.c
+++ b/source3/lib/unix_msg/unix_msg.c
@@ -23,6 +23,7 @@
#include "system/network.h"
#include "dlinklist.h"
#include "pthreadpool/pthreadpool.h"
+#include "lib/iov_buf.h"
#include <fcntl.h>
/*
@@ -77,7 +78,6 @@ struct unix_dgram_ctx {
char path[];
};
-static ssize_t iov_buflen(const struct iovec *iov, int iovlen);
static void unix_dgram_recv_handler(struct poll_watch *w, int fd, short events,
void *private_data);
@@ -583,10 +583,7 @@ static int queue_msg(struct unix_dgram_send_queue *q,
}
#endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
- for (i=0; i<iovlen; i++) {
- memcpy(data_buf, iov[i].iov_base, iov[i].iov_len);
- data_buf += iov[i].iov_len;
- }
+ iov_buf(iov, iovlen, data_buf, data_len);
DLIST_ADD_END(q->msgs, msg, struct unix_dgram_msg);
return 0;
@@ -1106,21 +1103,3 @@ int unix_msg_free(struct unix_msg_ctx *ctx)
free(ctx);
return 0;
}
-
-static ssize_t iov_buflen(const struct iovec *iov, int iovlen)
-{
- size_t buflen = 0;
- int i;
-
- for (i=0; i<iovlen; i++) {
- size_t thislen = iov[i].iov_len;
- size_t tmp = buflen + thislen;
-
- if ((tmp < buflen) || (tmp < thislen)) {
- /* overflow */
- return -1;
- }
- buflen = tmp;
- }
- return buflen;
-}
diff --git a/source3/lib/unix_msg/wscript_build b/source3/lib/unix_msg/wscript_build
index 200840d..e638ea6 100644
--- a/source3/lib/unix_msg/wscript_build
+++ b/source3/lib/unix_msg/wscript_build
@@ -2,7 +2,7 @@
bld.SAMBA3_SUBSYSTEM('UNIX_MSG',
source='unix_msg.c',
- deps='replace PTHREADPOOL')
+ deps='replace PTHREADPOOL iov_buf')
bld.SAMBA3_BINARY('unix_msg_test',
source='tests.c',
--
1.9.1
From 7d1b677093c6cf309b5dba8875b87a7e11b62dc7 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 27 Oct 2014 10:26:46 +0000
Subject: [PATCH 06/16] smbd: Move lp_parm_bool out of notify_inotify.c
Notifyd should be as independent of Samba infrastructure as possible,
and it will call notify_inotify
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/modules/vfs_default.c | 3 +++
source3/smbd/notify_inotify.c | 4 ----
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index f5b8f9b..dad6bb7 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -2119,6 +2119,9 @@ static NTSTATUS vfswrap_notify_watch(vfs_handle_struct *vfs_handle,
*/
#ifdef HAVE_INOTIFY
if (lp_kernel_change_notify(vfs_handle->conn->params)) {
+ if (!lp_parm_bool(-1, "notify", "inotify", True)) {
+ return NT_STATUS_INVALID_SYSTEM_SERVICE;
+ }
return inotify_watch(ctx, path, filter, subdir_filter,
callback, private_data, handle);
}
diff --git a/source3/smbd/notify_inotify.c b/source3/smbd/notify_inotify.c
index 5fbc7f2..554277c 100644
--- a/source3/smbd/notify_inotify.c
+++ b/source3/smbd/notify_inotify.c
@@ -255,10 +255,6 @@ static NTSTATUS inotify_setup(struct sys_notify_context *ctx)
{
struct inotify_private *in;
- if (!lp_parm_bool(-1, "notify", "inotify", True)) {
- return NT_STATUS_INVALID_SYSTEM_SERVICE;
- }
-
in = talloc(ctx, struct inotify_private);
NT_STATUS_HAVE_NO_MEMORY(in);
in->fd = inotify_init();
--
1.9.1
From 18c11a2494a48128ad2f08f330959fce624cd3f4 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Sun, 26 Oct 2014 09:13:41 +0000
Subject: [PATCH 07/16] notify_inotify: Simplify filter_match
Early returns make code simpler
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/smbd/notify_inotify.c | 39 +++++++++++++++++++--------------------
1 file changed, 19 insertions(+), 20 deletions(-)
diff --git a/source3/smbd/notify_inotify.c b/source3/smbd/notify_inotify.c
index 554277c..2425bb4 100644
--- a/source3/smbd/notify_inotify.c
+++ b/source3/smbd/notify_inotify.c
@@ -75,6 +75,8 @@ static int inotify_destructor(struct inotify_private *in)
static bool filter_match(struct inotify_watch_context *w,
struct inotify_event *e)
{
+ bool ok;
+
DEBUG(10, ("filter_match: e->mask=%x, w->mask=%x, w->filter=%x\n",
e->mask, w->mask, w->filter));
@@ -86,28 +88,25 @@ static bool filter_match(struct inotify_watch_context *w,
/* SMB separates the filters for files and directories */
if (e->mask & IN_ISDIR) {
- if ((w->filter & FILE_NOTIFY_CHANGE_DIR_NAME) == 0) {
- return False;
- }
- } else {
- if ((e->mask & IN_ATTRIB) &&
- (w->filter & (FILE_NOTIFY_CHANGE_ATTRIBUTES|
- FILE_NOTIFY_CHANGE_LAST_WRITE|
- FILE_NOTIFY_CHANGE_LAST_ACCESS|
- FILE_NOTIFY_CHANGE_EA|
- FILE_NOTIFY_CHANGE_SECURITY))) {
- return True;
- }
- if ((e->mask & IN_MODIFY) &&
- (w->filter & FILE_NOTIFY_CHANGE_ATTRIBUTES)) {
- return True;
- }
- if ((w->filter & FILE_NOTIFY_CHANGE_FILE_NAME) == 0) {
- return False;
- }
+ ok = ((w->filter & FILE_NOTIFY_CHANGE_DIR_NAME) != 0);
+ return ok;
+ }
+
+ if ((e->mask & IN_ATTRIB) &&
+ (w->filter & (FILE_NOTIFY_CHANGE_ATTRIBUTES|
+ FILE_NOTIFY_CHANGE_LAST_WRITE|
+ FILE_NOTIFY_CHANGE_LAST_ACCESS|
+ FILE_NOTIFY_CHANGE_EA|
+ FILE_NOTIFY_CHANGE_SECURITY))) {
+ return True;
+ }
+ if ((e->mask & IN_MODIFY) &&
+ (w->filter & FILE_NOTIFY_CHANGE_ATTRIBUTES)) {
+ return True;
}
- return True;
+ ok = ((w->filter & FILE_NOTIFY_CHANGE_FILE_NAME) != 0);
+ return ok;
}
--
1.9.1
From 6288720b74a218a8547030601707f12e2442d3e8 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 27 Oct 2014 13:07:03 +0000
Subject: [PATCH 08/16] notify_inotify: Add a NULL check
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/smbd/notify_inotify.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/source3/smbd/notify_inotify.c b/source3/smbd/notify_inotify.c
index 2425bb4..56f4941 100644
--- a/source3/smbd/notify_inotify.c
+++ b/source3/smbd/notify_inotify.c
@@ -253,6 +253,7 @@ static void inotify_handler(struct tevent_context *ev, struct tevent_fd *fde,
static NTSTATUS inotify_setup(struct sys_notify_context *ctx)
{
struct inotify_private *in;
+ struct tevent_fd *fde;
in = talloc(ctx, struct inotify_private);
NT_STATUS_HAVE_NO_MEMORY(in);
@@ -269,7 +270,13 @@ static NTSTATUS inotify_setup(struct sys_notify_context *ctx)
talloc_set_destructor(in, inotify_destructor);
/* add a event waiting for the inotify fd to be readable */
- tevent_add_fd(ctx->ev, in, in->fd, TEVENT_FD_READ, inotify_handler, in);
+ fde = tevent_add_fd(ctx->ev, in, in->fd, TEVENT_FD_READ,
+ inotify_handler, in);
+ if (fde == NULL) {
+ ctx->private_data = NULL;
+ TALLOC_FREE(in);
+ return NT_STATUS_NO_MEMORY;
+ }
return NT_STATUS_OK;
}
--
1.9.1
From 6436d775e7a3e395a2273b229c42cf3e06a7487f Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 27 Oct 2014 13:09:44 +0000
Subject: [PATCH 09/16] notify_inotify: Make inotify_setup return 0/errno
This gets rid of one NT_STATUS_HAVE_NO_MEMORY with its implicit return; :-)
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/smbd/notify_inotify.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/source3/smbd/notify_inotify.c b/source3/smbd/notify_inotify.c
index 56f4941..613b038 100644
--- a/source3/smbd/notify_inotify.c
+++ b/source3/smbd/notify_inotify.c
@@ -250,18 +250,22 @@ static void inotify_handler(struct tevent_context *ev, struct tevent_fd *fde,
setup the inotify handle - called the first time a watch is added on
this context
*/
-static NTSTATUS inotify_setup(struct sys_notify_context *ctx)
+static int inotify_setup(struct sys_notify_context *ctx)
{
struct inotify_private *in;
struct tevent_fd *fde;
in = talloc(ctx, struct inotify_private);
- NT_STATUS_HAVE_NO_MEMORY(in);
+ if (in == NULL) {
+ return ENOMEM;
+ }
+
in->fd = inotify_init();
if (in->fd == -1) {
- DEBUG(0,("Failed to init inotify - %s\n", strerror(errno)));
+ int ret = errno;
+ DEBUG(0, ("Failed to init inotify - %s\n", strerror(ret)));
talloc_free(in);
- return map_nt_error_from_unix(errno);
+ return ret;
}
in->ctx = ctx;
in->watches = NULL;
@@ -275,10 +279,9 @@ static NTSTATUS inotify_setup(struct sys_notify_context *ctx)
if (fde == NULL) {
ctx->private_data = NULL;
TALLOC_FREE(in);
- return NT_STATUS_NO_MEMORY;
+ return ENOMEM;
}
-
- return NT_STATUS_OK;
+ return 0;
}
@@ -360,9 +363,11 @@ NTSTATUS inotify_watch(struct sys_notify_context *ctx,
/* maybe setup the inotify fd */
if (ctx->private_data == NULL) {
- NTSTATUS status;
- status = inotify_setup(ctx);
- NT_STATUS_NOT_OK_RETURN(status);
+ int ret;
+ ret = inotify_setup(ctx);
+ if (ret != 0) {
+ return map_nt_error_from_unix(ret);
+ }
}
in = talloc_get_type(ctx->private_data, struct inotify_private);
--
1.9.1
From 0ec5087d0bb28ce353fa47940a0476ce5e88f052 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 27 Oct 2014 13:15:12 +0000
Subject: [PATCH 10/16] notify_inotify: Slightly simplify inotify_watch
tallocing first avoids having to call inotify_rm_watch
This even fixes a real error: We share inotifies between different instances,
so the rm_watch in the error paths destroys other legitimate watches
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/smbd/notify_inotify.c | 28 +++++++++++++---------------
1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/source3/smbd/notify_inotify.c b/source3/smbd/notify_inotify.c
index 613b038..b141b92 100644
--- a/source3/smbd/notify_inotify.c
+++ b/source3/smbd/notify_inotify.c
@@ -355,7 +355,6 @@ NTSTATUS inotify_watch(struct sys_notify_context *ctx,
void *handle_p)
{
struct inotify_private *in;
- int wd;
uint32_t mask;
struct inotify_watch_context *w;
uint32_t orig_filter = *filter;
@@ -382,38 +381,37 @@ NTSTATUS inotify_watch(struct sys_notify_context *ctx,
watch descriptor for multiple watches on the same path */
mask |= (IN_MASK_ADD | IN_ONLYDIR);
- /* get a new watch descriptor for this path */
- wd = inotify_add_watch(in->fd, path, mask);
- if (wd == -1) {
- *filter = orig_filter;
- DEBUG(1, ("inotify_add_watch returned %s\n", strerror(errno)));
- return map_nt_error_from_unix(errno);
- }
-
- DEBUG(10, ("inotify_add_watch for %s mask %x returned wd %d\n",
- path, mask, wd));
-
w = talloc(in, struct inotify_watch_context);
if (w == NULL) {
- inotify_rm_watch(in->fd, wd);
*filter = orig_filter;
return NT_STATUS_NO_MEMORY;
}
w->in = in;
- w->wd = wd;
w->callback = callback;
w->private_data = private_data;
w->mask = mask;
w->filter = orig_filter;
w->path = talloc_strdup(w, path);
if (w->path == NULL) {
- inotify_rm_watch(in->fd, wd);
*filter = orig_filter;
TALLOC_FREE(w);
return NT_STATUS_NO_MEMORY;
}
+ /* get a new watch descriptor for this path */
+ w->wd = inotify_add_watch(in->fd, path, mask);
+ if (w->wd == -1) {
+ int err = errno;
+ *filter = orig_filter;
+ TALLOC_FREE(w);
+ DEBUG(1, ("inotify_add_watch returned %s\n", strerror(err)));
+ return map_nt_error_from_unix(err);
+ }
+
+ DEBUG(10, ("inotify_add_watch for %s mask %x returned wd %d\n",
+ path, mask, w->wd));
+
(*handle) = w;
DLIST_ADD(in->watches, w);
--
1.9.1
From c97323cd63b5c94774724ef739210adbe031d717 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 27 Oct 2014 13:20:15 +0000
Subject: [PATCH 11/16] notify_inotify: Slightly simplify watch_destructor
Another case of an early return
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/smbd/notify_inotify.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/source3/smbd/notify_inotify.c b/source3/smbd/notify_inotify.c
index b141b92..3e4e2e6 100644
--- a/source3/smbd/notify_inotify.c
+++ b/source3/smbd/notify_inotify.c
@@ -324,17 +324,19 @@ static int watch_destructor(struct inotify_watch_context *w)
int wd = w->wd;
DLIST_REMOVE(w->in->watches, w);
- /* only rm the watch if its the last one with this wd */
for (w=in->watches;w;w=w->next) {
- if (w->wd == wd) break;
- }
- if (w == NULL) {
- DEBUG(10, ("Deleting inotify watch %d\n", wd));
- if (inotify_rm_watch(in->fd, wd) == -1) {
- DEBUG(1, ("inotify_rm_watch returned %s\n",
- strerror(errno)));
+ if (w->wd == wd) {
+ /*
+ * Another inotify_watch_context listens on this path,
+ * leave the kernel level watch in place
+ */
+ return 0;
}
+ }
+ DEBUG(10, ("Deleting inotify watch %d\n", wd));
+ if (inotify_rm_watch(in->fd, wd) == -1) {
+ DEBUG(1, ("inotify_rm_watch returned %s\n", strerror(errno)));
}
return 0;
}
--
1.9.1
From f3ca18c05e05c37d6dac6e534f7d7dbf55a52253 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 27 Oct 2014 13:26:35 +0000
Subject: [PATCH 12/16] notify_inotify: Make inotify_watch return 0/errno
More like a cleanup, but I want to use inotify_watch in notifyd
that I would like to keep as light as possible
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/modules/vfs_default.c | 9 +++++++--
source3/smbd/notify_inotify.c | 30 +++++++++++++++---------------
source3/smbd/proto.h | 18 +++++++++---------
3 files changed, 31 insertions(+), 26 deletions(-)
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index dad6bb7..eaa1c2b 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -2119,11 +2119,16 @@ static NTSTATUS vfswrap_notify_watch(vfs_handle_struct *vfs_handle,
*/
#ifdef HAVE_INOTIFY
if (lp_kernel_change_notify(vfs_handle->conn->params)) {
+ int ret;
if (!lp_parm_bool(-1, "notify", "inotify", True)) {
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
- return inotify_watch(ctx, path, filter, subdir_filter,
- callback, private_data, handle);
+ ret = inotify_watch(ctx, path, filter, subdir_filter,
+ callback, private_data, handle);
+ if (ret != 0) {
+ return map_nt_error_from_unix(ret);
+ }
+ return NT_STATUS_OK;
}
#endif
/*
diff --git a/source3/smbd/notify_inotify.c b/source3/smbd/notify_inotify.c
index 3e4e2e6..ad670af 100644
--- a/source3/smbd/notify_inotify.c
+++ b/source3/smbd/notify_inotify.c
@@ -346,15 +346,15 @@ static int watch_destructor(struct inotify_watch_context *w)
add a watch. The watch is removed when the caller calls
talloc_free() on *handle
*/
-NTSTATUS inotify_watch(struct sys_notify_context *ctx,
- const char *path,
- uint32_t *filter,
- uint32_t *subdir_filter,
- void (*callback)(struct sys_notify_context *ctx,
- void *private_data,
- struct notify_event *ev),
- void *private_data,
- void *handle_p)
+int inotify_watch(struct sys_notify_context *ctx,
+ const char *path,
+ uint32_t *filter,
+ uint32_t *subdir_filter,
+ void (*callback)(struct sys_notify_context *ctx,
+ void *private_data,
+ struct notify_event *ev),
+ void *private_data,
+ void *handle_p)
{
struct inotify_private *in;
uint32_t mask;
@@ -367,7 +367,7 @@ NTSTATUS inotify_watch(struct sys_notify_context *ctx,
int ret;
ret = inotify_setup(ctx);
if (ret != 0) {
- return map_nt_error_from_unix(ret);
+ return ret;
}
}
@@ -376,7 +376,7 @@ NTSTATUS inotify_watch(struct sys_notify_context *ctx,
mask = inotify_map(filter);
if (mask == 0) {
/* this filter can't be handled by inotify */
- return NT_STATUS_INVALID_PARAMETER;
+ return EINVAL;
}
/* using IN_MASK_ADD allows us to cope with inotify() returning the same
@@ -386,7 +386,7 @@ NTSTATUS inotify_watch(struct sys_notify_context *ctx,
w = talloc(in, struct inotify_watch_context);
if (w == NULL) {
*filter = orig_filter;
- return NT_STATUS_NO_MEMORY;
+ return ENOMEM;
}
w->in = in;
@@ -398,7 +398,7 @@ NTSTATUS inotify_watch(struct sys_notify_context *ctx,
if (w->path == NULL) {
*filter = orig_filter;
TALLOC_FREE(w);
- return NT_STATUS_NO_MEMORY;
+ return ENOMEM;
}
/* get a new watch descriptor for this path */
@@ -408,7 +408,7 @@ NTSTATUS inotify_watch(struct sys_notify_context *ctx,
*filter = orig_filter;
TALLOC_FREE(w);
DEBUG(1, ("inotify_add_watch returned %s\n", strerror(err)));
- return map_nt_error_from_unix(err);
+ return err;
}
DEBUG(10, ("inotify_add_watch for %s mask %x returned wd %d\n",
@@ -421,7 +421,7 @@ NTSTATUS inotify_watch(struct sys_notify_context *ctx,
/* the caller frees the handle to stop watching */
talloc_set_destructor(w, watch_destructor);
- return NT_STATUS_OK;
+ return 0;
}
#endif
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 9980d03..0e43aaf 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -531,15 +531,15 @@ struct sys_notify_context *sys_notify_context_create(TALLOC_CTX *mem_ctx,
/* The following definitions come from smbd/notify_inotify.c */
-NTSTATUS inotify_watch(struct sys_notify_context *ctx,
- const char *path,
- uint32_t *filter,
- uint32_t *subdir_filter,
- void (*callback)(struct sys_notify_context *ctx,
- void *private_data,
- struct notify_event *ev),
- void *private_data,
- void *handle_p);
+int inotify_watch(struct sys_notify_context *ctx,
+ const char *path,
+ uint32_t *filter,
+ uint32_t *subdir_filter,
+ void (*callback)(struct sys_notify_context *ctx,
+ void *private_data,
+ struct notify_event *ev),
+ void *private_data,
+ void *handle_p);
/* The following definitions come from smbd/notify_internal.c */
--
1.9.1
From 63362494c8243415e8ccab3d54767f6284c5b8b6 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Wed, 5 Nov 2014 11:44:42 +0000
Subject: [PATCH 13/16] notify: Add "dir" to notify_event
"notify_event" only reports names relative to some path that is only
implicitly known via "private_data". Right now "private_data" is the fsp
of the directory holding this notify. I want to use inotify_watch in a
notify-daemon that does not have a fsp available and has more problems
getting the path right out of "private_data". notify_inotify has the
directory under which the event happened available, so make it known to
the callback. Right now no caller uses it yet.
Signed-off-by: Volker Lendecke <vl at samba.org>
---
librpc/idl/notify.idl | 1 +
source3/smbd/notify_inotify.c | 2 ++
source3/smbd/notify_internal.c | 10 +++++++---
source4/ntvfs/common/notify.c | 1 +
source4/ntvfs/sysdep/inotify.c | 2 ++
5 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/librpc/idl/notify.idl b/librpc/idl/notify.idl
index ec81e8c..66422ec 100644
--- a/librpc/idl/notify.idl
+++ b/librpc/idl/notify.idl
@@ -65,6 +65,7 @@ interface notify
/* structure sent between servers in notify messages */
typedef [public] struct {
uint32 action;
+ utf8string dir;
utf8string path;
pointer private_data;
} notify_event;
diff --git a/source3/smbd/notify_inotify.c b/source3/smbd/notify_inotify.c
index ad670af..a3c30f1 100644
--- a/source3/smbd/notify_inotify.c
+++ b/source3/smbd/notify_inotify.c
@@ -165,6 +165,7 @@ static void inotify_dispatch(struct inotify_private *in,
for (w=in->watches;w;w=next) {
next = w->next;
if (w->wd == e->wd && filter_match(w, e)) {
+ ne.dir = w->path;
w->callback(in->ctx, w->private_data, &ne);
}
}
@@ -184,6 +185,7 @@ static void inotify_dispatch(struct inotify_private *in,
next = w->next;
if (w->wd == e->wd && filter_match(w, e) &&
!(w->filter & FILE_NOTIFY_CHANGE_CREATION)) {
+ ne.dir = w->path;
w->callback(in->ctx, w->private_data, &ne);
}
}
diff --git a/source3/smbd/notify_internal.c b/source3/smbd/notify_internal.c
index 9d54891..9c0b190 100644
--- a/source3/smbd/notify_internal.c
+++ b/source3/smbd/notify_internal.c
@@ -831,9 +831,13 @@ static void notify_handler(struct messaging_context *msg_ctx,
}
m = (struct notify_msg *)data->data;
- e.action = m->action;
- e.path = m->path;
- e.private_data = m->private_data;
+
+ e = (struct notify_event) {
+ .action = m->action,
+ .path = m->path,
+ .private_data = m->private_data,
+ .dir = discard_const_p(char, "")
+ };
for (listel=notify->list;listel;listel=listel->next) {
if (listel->private_data == m->private_data) {
diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c
index 57142c7..61da0b8 100644
--- a/source4/ntvfs/common/notify.c
+++ b/source4/ntvfs/common/notify.c
@@ -550,6 +550,7 @@ static void notify_send(struct notify_context *notify, struct notify_entry *e,
TALLOC_CTX *tmp_ctx;
ev.action = action;
+ ev.dir = discard_const_p(char, "");
ev.path = path;
ev.private_data = e->private_data;
diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c
index 0680b4b..091ca1d 100644
--- a/source4/ntvfs/sysdep/inotify.c
+++ b/source4/ntvfs/sysdep/inotify.c
@@ -144,6 +144,7 @@ static void inotify_dispatch(struct inotify_private *in,
for (w=in->watches;w;w=next) {
next = w->next;
if (w->wd == e->wd && filter_match(w, e)) {
+ ne.dir = w->path;
w->callback(in->ctx, w->private_data, &ne);
}
}
@@ -163,6 +164,7 @@ static void inotify_dispatch(struct inotify_private *in,
next = w->next;
if (w->wd == e->wd && filter_match(w, e) &&
!(w->filter & FILE_NOTIFY_CHANGE_CREATION)) {
+ ne.dir = w->path;
w->callback(in->ctx, w->private_data, &ne);
}
}
--
1.9.1
From 51f672292f61cd5a0009b25bfdc35cb43eed42d9 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Wed, 5 Nov 2014 12:18:31 +0000
Subject: [PATCH 14/16] notify_inotify: inotify_watch now takes a mem_ctx
This will make it easier to integrate into proper memory hierarchies.
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/modules/vfs_default.c | 9 ++++++++-
source3/smbd/notify_inotify.c | 5 +++--
source3/smbd/proto.h | 3 ++-
3 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index eaa1c2b..5634cc0 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -2123,7 +2123,14 @@ static NTSTATUS vfswrap_notify_watch(vfs_handle_struct *vfs_handle,
if (!lp_parm_bool(-1, "notify", "inotify", True)) {
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
- ret = inotify_watch(ctx, path, filter, subdir_filter,
+ /*
+ * "ctx->private_data" is not obvious as a talloc context
+ * here. Without modifying the VFS we don't have a mem_ctx
+ * available here, and ctx->private_data was used by
+ * inotify_watch before it got a real talloc parent.
+ */
+ ret = inotify_watch(ctx->private_data, ctx,
+ path, filter, subdir_filter,
callback, private_data, handle);
if (ret != 0) {
return map_nt_error_from_unix(ret);
diff --git a/source3/smbd/notify_inotify.c b/source3/smbd/notify_inotify.c
index a3c30f1..fedf9b5 100644
--- a/source3/smbd/notify_inotify.c
+++ b/source3/smbd/notify_inotify.c
@@ -348,7 +348,8 @@ static int watch_destructor(struct inotify_watch_context *w)
add a watch. The watch is removed when the caller calls
talloc_free() on *handle
*/
-int inotify_watch(struct sys_notify_context *ctx,
+int inotify_watch(TALLOC_CTX *mem_ctx,
+ struct sys_notify_context *ctx,
const char *path,
uint32_t *filter,
uint32_t *subdir_filter,
@@ -385,7 +386,7 @@ int inotify_watch(struct sys_notify_context *ctx,
watch descriptor for multiple watches on the same path */
mask |= (IN_MASK_ADD | IN_ONLYDIR);
- w = talloc(in, struct inotify_watch_context);
+ w = talloc(mem_ctx, struct inotify_watch_context);
if (w == NULL) {
*filter = orig_filter;
return ENOMEM;
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 0e43aaf..44ea6f0 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -531,7 +531,8 @@ struct sys_notify_context *sys_notify_context_create(TALLOC_CTX *mem_ctx,
/* The following definitions come from smbd/notify_inotify.c */
-int inotify_watch(struct sys_notify_context *ctx,
+int inotify_watch(TALLOC_CTX *mem_ctx,
+ struct sys_notify_context *ctx,
const char *path,
uint32_t *filter,
uint32_t *subdir_filter,
--
1.9.1
From 5f7669980891bccca2b2b0b7f3ea0600bbc218d9 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 18 Nov 2014 11:28:20 +0000
Subject: [PATCH 15/16] smbd: Compile notify_inotify only if available
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/smbd/notify_inotify.c | 4 ----
source3/wscript_build | 8 ++++++--
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/source3/smbd/notify_inotify.c b/source3/smbd/notify_inotify.c
index fedf9b5..944f27a 100644
--- a/source3/smbd/notify_inotify.c
+++ b/source3/smbd/notify_inotify.c
@@ -26,8 +26,6 @@
#include "smbd/smbd.h"
#include "lib/sys_rw_data.h"
-#ifdef HAVE_INOTIFY
-
#include <sys/inotify.h>
/* glibc < 2.5 headers don't have these defines */
@@ -426,5 +424,3 @@ int inotify_watch(TALLOC_CTX *mem_ctx,
return 0;
}
-
-#endif
diff --git a/source3/wscript_build b/source3/wscript_build
index 51d72e7..5128b96 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -506,6 +506,11 @@ bld.SAMBA3_SUBSYSTEM('sysquotas',
allow_warnings=True,
deps='samba3-util samba-util')
+NOTIFY_SOURCES=''
+
+if bld.CONFIG_SET("HAVE_INOTIFY"):
+ NOTIFY_SOURCES += ' smbd/notify_inotify.c'
+
bld.SAMBA3_LIBRARY('smbd_base',
source='''
smbd/server_reload.c
@@ -595,9 +600,8 @@ bld.SAMBA3_LIBRARY('smbd_base',
smbd/oplock_irix.c
smbd/oplock_linux.c
smbd/notify.c
- smbd/notify_inotify.c
smbd/notify_internal.c
- smbd/build_options.c''',
+ smbd/build_options.c''' + NOTIFY_SOURCES,
deps='''
talloc
tevent
--
1.9.1
From fa92217edacce4720a08ab742ddb9bdedd72d078 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Thu, 4 Dec 2014 16:01:17 +0000
Subject: [PATCH 16/16] notify_inotify: Simplify inotify_dispatch
Normally, I'm trying to simplify things with early returns. But in
this case I think the reverse makes the if-condition easier to
understand
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/smbd/notify_inotify.c | 32 +++++++++++++++++---------------
1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/source3/smbd/notify_inotify.c b/source3/smbd/notify_inotify.c
index 944f27a..8f47124 100644
--- a/source3/smbd/notify_inotify.c
+++ b/source3/smbd/notify_inotify.c
@@ -168,23 +168,25 @@ static void inotify_dispatch(struct inotify_private *in,
}
}
- /* SMB expects a file rename to generate three events, two for
- the rename and the other for a modify of the
- destination. Strange! */
- if (ne.action != NOTIFY_ACTION_NEW_NAME ||
- (e->mask & IN_ISDIR) != 0) {
- return;
- }
+ if ((ne.action == NOTIFY_ACTION_NEW_NAME) &&
+ ((e->mask & IN_ISDIR) == 0)) {
- ne.action = NOTIFY_ACTION_MODIFIED;
- e->mask = IN_ATTRIB;
+ /*
+ * SMB expects a file rename to generate three events, two for
+ * the rename and the other for a modify of the
+ * destination. Strange!
+ */
- for (w=in->watches;w;w=next) {
- next = w->next;
- if (w->wd == e->wd && filter_match(w, e) &&
- !(w->filter & FILE_NOTIFY_CHANGE_CREATION)) {
- ne.dir = w->path;
- w->callback(in->ctx, w->private_data, &ne);
+ ne.action = NOTIFY_ACTION_MODIFIED;
+ e->mask = IN_ATTRIB;
+
+ for (w=in->watches;w;w=next) {
+ next = w->next;
+ if (w->wd == e->wd && filter_match(w, e) &&
+ !(w->filter & FILE_NOTIFY_CHANGE_CREATION)) {
+ ne.dir = w->path;
+ w->callback(in->ctx, w->private_data, &ne);
+ }
}
}
}
--
1.9.1
More information about the samba-technical
mailing list