diff options
author | Andrew Tridgell <tridge@samba.org> | 2006-04-05 08:52:55 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 14:00:17 -0500 |
commit | 1dee94c333a06857de2981e1d8e019c8e430bc06 (patch) | |
tree | 90324146d715bef57c9aceda7da8b29161280990 /source4 | |
parent | 930e247d5692cc776c434f9caafa90f2ca1a70b1 (diff) | |
download | samba-1dee94c333a06857de2981e1d8e019c8e430bc06.tar.gz samba-1dee94c333a06857de2981e1d8e019c8e430bc06.tar.bz2 samba-1dee94c333a06857de2981e1d8e019c8e430bc06.zip |
r14926: change the inotify backend to implement the rather unusual semantics
for rename. The cookies in inotify tell us (indirectly!) if its a
rename between directories or not
(This used to be commit 13574a8d0c7228bf36a6debe4853f693c9f8f543)
Diffstat (limited to 'source4')
-rw-r--r-- | source4/ntvfs/sysdep/inotify.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index c95c39ff01..70ef4918cb 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -90,8 +90,13 @@ static int inotify_destructor(void *ptr) /* dispatch one inotify event + + the cookies are used to correctly handle renames */ -static void inotify_dispatch(struct inotify_private *in, struct inotify_event *e) +static void inotify_dispatch(struct inotify_private *in, + struct inotify_event *e, + uint32_t prev_cookie, + uint32_t next_cookie) { struct watch_context *w; struct notify_event ne; @@ -101,11 +106,24 @@ static void inotify_dispatch(struct inotify_private *in, struct inotify_event *e return; } - /* map the inotify mask to a action */ + /* map the inotify mask to a action. This gets complicated for + renames */ if (e->mask & IN_CREATE) { ne.action = NOTIFY_ACTION_ADDED; } else if (e->mask & IN_DELETE) { ne.action = NOTIFY_ACTION_REMOVED; + } else if (e->mask & IN_MOVED_FROM) { + if (e->cookie == next_cookie) { + ne.action = NOTIFY_ACTION_OLD_NAME; + } else { + ne.action = NOTIFY_ACTION_REMOVED; + } + } else if (e->mask & IN_MOVED_TO) { + if (e->cookie == prev_cookie) { + ne.action = NOTIFY_ACTION_NEW_NAME; + } else { + ne.action = NOTIFY_ACTION_ADDED; + } } else { ne.action = NOTIFY_ACTION_MODIFIED; } @@ -129,6 +147,7 @@ static void inotify_handler(struct event_context *ev, struct fd_event *fde, struct inotify_private *in = talloc_get_type(private, struct inotify_private); int bufsize = 0; struct inotify_event *e0, *e; + uint32_t prev_cookie=0; /* we must use FIONREAD as we cannot predict the length of the @@ -152,9 +171,14 @@ static void inotify_handler(struct event_context *ev, struct fd_event *fde, /* we can get more than one event in the buffer */ while (bufsize >= sizeof(*e)) { - inotify_dispatch(in, e); + struct inotify_event *e2 = NULL; bufsize -= e->len + sizeof(*e); - e = (struct inotify_event *)(e->len + sizeof(*e) + (char *)e); + if (bufsize >= sizeof(*e)) { + e2 = (struct inotify_event *)(e->len + sizeof(*e) + (char *)e); + } + inotify_dispatch(in, e, prev_cookie, e2?e2->cookie:0); + prev_cookie = e->cookie; + e = e2; } talloc_free(e0); |