summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/mount.c48
-rw-r--r--src/core/path.c32
2 files changed, 38 insertions, 42 deletions
diff --git a/src/core/mount.c b/src/core/mount.c
index 5f268c6ddc..66de85b578 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1616,14 +1616,18 @@ static int mount_enumerate(Manager *m) {
if (m->utab_inotify_fd < 0) {
m->utab_inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
- if (m->utab_inotify_fd < 0)
- goto fail_with_errno;
+ if (m->utab_inotify_fd < 0) {
+ r = -errno;
+ goto fail;
+ }
(void) mkdir_p_label("/run/mount", 0755);
r = inotify_add_watch(m->utab_inotify_fd, "/run/mount", IN_MOVED_TO);
- if (r < 0)
- goto fail_with_errno;
+ if (r < 0) {
+ r = -errno;
+ goto fail;
+ }
r = sd_event_add_io(m->event, &m->mount_utab_event_source, m->utab_inotify_fd, EPOLLIN, mount_dispatch_io, m);
if (r < 0)
@@ -1640,8 +1644,6 @@ static int mount_enumerate(Manager *m) {
return 0;
-fail_with_errno:
- r = -errno;
fail:
mount_shutdown(m);
return r;
@@ -1661,22 +1663,32 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
* for mount options. */
if (fd == m->utab_inotify_fd) {
- char inotify_buffer[sizeof(struct inotify_event) + NAME_MAX + 1];
- struct inotify_event *event;
- char *p;
bool rescan = false;
- while ((r = read(fd, inotify_buffer, sizeof(inotify_buffer))) > 0)
- for (p = inotify_buffer; p < inotify_buffer + r; ) {
- event = (struct inotify_event *) p;
- /* only care about changes to utab, but we have
- * to monitor the directory to reliably get
- * notifications about when utab is replaced
- * using rename(2) */
- if ((event->mask & IN_Q_OVERFLOW) || streq(event->name, "utab"))
+ for (;;) {
+ uint8_t buffer[INOTIFY_EVENT_MAX] _alignas_(struct inotify_event);
+ struct inotify_event *e;
+ ssize_t l;
+
+ l = read(fd, buffer, sizeof(buffer));
+ if (l < 0) {
+ if (errno == EAGAIN || errno == EINTR)
+ break;
+
+ log_error_errno(errno, "Failed to read utab inotify: %m");
+ break;
+ }
+
+ FOREACH_INOTIFY_EVENT(e, buffer, l) {
+ /* Only care about changes to utab,
+ * but we have to monitor the
+ * directory to reliably get
+ * notifications about when utab is
+ * replaced using rename(2) */
+ if ((e->mask & IN_Q_OVERFLOW) || streq(e->name, "utab"))
rescan = true;
- p += sizeof(struct inotify_event) + event->len;
}
+ }
if (!rescan)
return 0;
diff --git a/src/core/path.c b/src/core/path.c
index 3624bfcac7..656ed6941d 100644
--- a/src/core/path.c
+++ b/src/core/path.c
@@ -157,10 +157,9 @@ void path_spec_unwatch(PathSpec *s) {
}
int path_spec_fd_event(PathSpec *s, uint32_t revents) {
- _cleanup_free_ uint8_t *buf = NULL;
+ uint8_t buffer[INOTIFY_EVENT_MAX] _alignas_(struct inotify_event);
struct inotify_event *e;
- ssize_t k;
- int l;
+ ssize_t l;
int r = 0;
if (revents != EPOLLIN) {
@@ -168,33 +167,18 @@ int path_spec_fd_event(PathSpec *s, uint32_t revents) {
return -EINVAL;
}
- if (ioctl(s->inotify_fd, FIONREAD, &l) < 0)
- return log_error_errno(errno, "FIONREAD failed: %m");
+ l = read(s->inotify_fd, buffer, sizeof(buffer));
+ if (l < 0) {
+ if (errno == EAGAIN || errno == EINTR)
+ return 0;
- assert(l > 0);
-
- buf = malloc(l);
- if (!buf)
- return log_oom();
-
- k = read(s->inotify_fd, buf, l);
- if (k < 0)
return log_error_errno(errno, "Failed to read inotify event: %m");
+ }
- e = (struct inotify_event*) buf;
-
- while (k > 0) {
- size_t step;
-
+ FOREACH_INOTIFY_EVENT(e, buffer, l) {
if ((s->type == PATH_CHANGED || s->type == PATH_MODIFIED) &&
s->primary_wd == e->wd)
r = 1;
-
- step = sizeof(struct inotify_event) + e->len;
- assert(step <= (size_t) k);
-
- e = (struct inotify_event*) ((uint8_t*) e + step);
- k -= step;
}
return r;