From: Volker Lendecke Date: Fri, 23 May 2025 13:22:39 +0000 (+0200) Subject: smbd: Simplify inotify_handler() X-Git-Tag: tevent-0.17.0~65 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2b317dd80002b7f87710317118bca35a20e85f4c;p=thirdparty%2Fsamba.git smbd: Simplify inotify_handler() [sizeof(struct inotify_event) + NAME_MAX + 1] is the recommended buffer size in "man 7 inotify". Pulling everything out of the inotify buffer makes sense if we would reliably get the two rename events in the same read-call. Unfortunately this is not the case, even with a buffer size of 64k I've seen MOVED_FROM and MOVED_to in separate reads from the socket. We'll have to take care of this situation next. Until then, we don't have to FIONREAD and then read everything that's there. Rather go through another event loop, replacing the ioctl with a epoll_wait syscall. Bug: https://bugzilla.samba.org/show_bug.cgi?id=15864 Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme --- diff --git a/source3/smbd/notify_inotify.c b/source3/smbd/notify_inotify.c index 5c57ffd46fb..5873de75c6c 100644 --- a/source3/smbd/notify_inotify.c +++ b/source3/smbd/notify_inotify.c @@ -24,7 +24,7 @@ #include "includes.h" #include "../librpc/gen_ndr/notify.h" #include "smbd/smbd.h" -#include "lib/util/sys_rw_data.h" +#include "lib/util/sys_rw.h" #include @@ -258,38 +258,25 @@ static void inotify_handler(struct tevent_context *ev, struct tevent_fd *fde, { struct inotify_private *in = talloc_get_type(private_data, struct inotify_private); + char buf[sizeof(struct inotify_event) + NAME_MAX + 1]; int bufsize = 0; - struct inotify_event *e0, *e; + struct inotify_event *e = NULL; uint32_t prev_cookie=0; int prev_wd = -1; ssize_t ret; - /* - we must use FIONREAD as we cannot predict the length of the - filenames, and thus can't know how much to allocate - otherwise - */ - if (ioctl(in->fd, FIONREAD, &bufsize) != 0 || - bufsize == 0) { - DEBUG(0,("No data on inotify fd?!\n")); - TALLOC_FREE(fde); - return; - } - - e0 = e = (struct inotify_event *)TALLOC_SIZE(in, bufsize + 1); - if (e == NULL) return; - ((uint8_t *)e)[bufsize] = '\0'; - - ret = read_data(in->fd, e0, bufsize); - if (ret != bufsize) { + ret = sys_read(in->fd, buf, sizeof(buf)); + if (ret == -1) { DEBUG(0, ("Failed to read all inotify data - %s\n", strerror(errno))); - talloc_free(e0); /* the inotify fd will now be out of sync, * can't keep reading data off it */ TALLOC_FREE(fde); return; } + bufsize = ret; + + e = (struct inotify_event *)buf; /* we can get more than one event in the buffer */ while (e && (bufsize >= sizeof(*e))) { @@ -303,8 +290,6 @@ static void inotify_handler(struct tevent_context *ev, struct tevent_fd *fde, prev_cookie = e->cookie; e = e2; } - - talloc_free(e0); } /*