From cb576d892a237e089d8945e47ddaeb6fe4430805 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Tue, 15 Oct 2013 13:35:28 +0400 Subject: [PATCH] inotify: Sort marks by wd before collecting them The inotify_add_watch generates wd-s one-by one. We cannot request for one, thus we call this syscall till the required wd is generated. Thus, if we want to restore several wd-s for an inotify, we have to put them in ascending order. Otherwise we may restore watch with higher wd earlier and will thus not be able to generate the lower wd in a reasonable time. Signed-off-by: Pavel Emelyanov --- fsnotify.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/fsnotify.c b/fsnotify.c index 00d34e36b..3a9cf645e 100644 --- a/fsnotify.c +++ b/fsnotify.c @@ -417,20 +417,38 @@ static struct file_desc_ops fanotify_desc_ops = { .open = open_fanotify_fd, }; -static int collect_inotify_mark(struct fsnotify_mark_info *mark) +static struct fsnotify_file_info *find_inotify_info(unsigned id) { struct fsnotify_file_info *p; - list_for_each_entry(p, &inotify_info_head, list) { - if (p->ife->id == mark->iwe->id) { - list_add(&mark->list, &p->marks); - mark->remap = lookup_ghost_remap(mark->iwe->s_dev, mark->iwe->i_ino); - return 0; - } - } + list_for_each_entry(p, &inotify_info_head, list) + if (p->ife->id == id) + return p; - pr_err("Can't find inotify with id 0x%08x\n", mark->iwe->id); - return -1; + pr_err("Can't find inotify with id 0x%08x\n", id); + return NULL; +} + +static int collect_inotify_mark(struct fsnotify_mark_info *mark) +{ + struct fsnotify_file_info *p; + struct fsnotify_mark_info *m; + + p = find_inotify_info(mark->iwe->id); + if (!p) + return -1; + + /* + * We should put marks in wd ascending order. See comment + * in restore_one_inotify() for explanation. + */ + list_for_each_entry(m, &p->marks, list) + if (m->iwe->wd > mark->iwe->wd) + break; + + list_add_tail(&mark->list, &m->list); + mark->remap = lookup_ghost_remap(mark->iwe->s_dev, mark->iwe->i_ino); + return 0; } static int collect_fanotify_mark(struct fsnotify_mark_info *mark)