summaryrefslogtreecommitdiffstats
path: root/source/ntvfs
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2006-04-05 08:52:55 +0000
committerAndrew Tridgell <tridge@samba.org>2006-04-05 08:52:55 +0000
commite87324cfbe497d21f545d569e96356bf75f982ac (patch)
tree5aff9f9ad1339a1c0e76d442bf742ed8fb9ba20f /source/ntvfs
parentdfa409ad9c3900ac3ffea3c5d230db917d5af111 (diff)
downloadsamba-e87324cfbe497d21f545d569e96356bf75f982ac.tar.gz
samba-e87324cfbe497d21f545d569e96356bf75f982ac.tar.xz
samba-e87324cfbe497d21f545d569e96356bf75f982ac.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
Diffstat (limited to 'source/ntvfs')
-rw-r--r--source/ntvfs/sysdep/inotify.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/source/ntvfs/sysdep/inotify.c b/source/ntvfs/sysdep/inotify.c
index c95c39ff01a..70ef4918cb7 100644
--- a/source/ntvfs/sysdep/inotify.c
+++ b/source/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);