22 May, 2010

2 commits

  • Make sure that s_umount is acquired *before* we drop the final
    active reference; we still have the fast path (atomic_dec_unless)
    and we have gotten rid of the window between the moment when
    s_active hits zero and s_umount is acquired. Which simplifies
    the living hell out of grab_super() and inotify pin_to_kill()
    stuff.

    Signed-off-by: Al Viro

    Al Viro
     
  • use atomic_inc_not_zero(&sb->s_active) instead of playing games with
    checking ->s_count > S_BIAS

    Signed-off-by: Al Viro

    Al Viro
     

15 May, 2010

1 commit


14 May, 2010

3 commits

  • inotify_new_group() receives a get_uid-ed user_struct and saves the
    reference on group->inotify_data.user. The problem is that free_uid() is
    never called on it.

    Issue seem to be introduced by 63c882a0 (inotify: reimplement inotify
    using fsnotify) after 2.6.30.

    Signed-off-by: Pavel Emelyanov
    Eric Paris
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Eric Paris

    Pavel Emelyanov
     
  • There is a race in the inotify add/rm watch code. A task can find and
    remove a mark which doesn't have all of it's references. This can
    result in a use after free/double free situation.

    Task A Task B
    ------------ -----------
    inotify_new_watch()
    allocate a mark (refcnt == 1)
    add it to the idr
    inotify_rm_watch()
    inotify_remove_from_idr()
    fsnotify_put_mark()
    refcnt hits 0, free
    take reference because we are on idr
    [at this point it is a use after free]
    [time goes on]
    refcnt may hit 0 again, double free

    The fix is to take the reference BEFORE the object can be found in the
    idr.

    Signed-off-by: Eric Paris
    Cc:

    Eric Paris
     
  • inotify_add_watch explictly frees the unused inode mark, but it can just
    use the generic code. Just do that.

    Signed-off-by: Eric Paris

    Eric Paris
     

12 May, 2010

1 commit

  • Fix:

    fs/built-in.o: In function `sys_inotify_init1':
    summary.c:(.text+0x347a4): undefined reference to `anon_inode_getfd'

    found by kautobuild with arms bcmring_defconfig, which ends up with
    INOTIFY_USER enabled (through the 'default y') but leaves ANON_INODES
    unset. However, inotify_user.c uses anon_inode_getfd().

    Signed-off-by: Russell King
    Signed-off-by: Eric Paris

    Russell King
     

01 May, 2010

1 commit

  • CONFIG_INOTIFY_USER defined but CONFIG_ANON_INODES undefined will result
    in the following build failure:

    LD vmlinux
    fs/built-in.o: In function 'sys_inotify_init1':
    (.text.sys_inotify_init1+0x22c): undefined reference to 'anon_inode_getfd'
    fs/built-in.o: In function `sys_inotify_init1':
    (.text.sys_inotify_init1+0x22c): relocation truncated to fit: R_MIPS_26 against 'anon_inode_getfd'
    make[2]: *** [vmlinux] Error 1
    make[1]: *** [sub-make] Error 2
    make: *** [all] Error 2

    Signed-off-by: Ralf Baechle
    Cc: Al Viro
    Signed-off-by: Linus Torvalds

    Ralf Baechle
     

30 Mar, 2010

1 commit

  • …it slab.h inclusion from percpu.h

    percpu.h is included by sched.h and module.h and thus ends up being
    included when building most .c files. percpu.h includes slab.h which
    in turn includes gfp.h making everything defined by the two files
    universally available and complicating inclusion dependencies.

    percpu.h -> slab.h dependency is about to be removed. Prepare for
    this change by updating users of gfp and slab facilities include those
    headers directly instead of assuming availability. As this conversion
    needs to touch large number of source files, the following script is
    used as the basis of conversion.

    http://userweb.kernel.org/~tj/misc/slabh-sweep.py

    The script does the followings.

    * Scan files for gfp and slab usages and update includes such that
    only the necessary includes are there. ie. if only gfp is used,
    gfp.h, if slab is used, slab.h.

    * When the script inserts a new include, it looks at the include
    blocks and try to put the new include such that its order conforms
    to its surrounding. It's put in the include block which contains
    core kernel includes, in the same order that the rest are ordered -
    alphabetical, Christmas tree, rev-Xmas-tree or at the end if there
    doesn't seem to be any matching order.

    * If the script can't find a place to put a new include (mostly
    because the file doesn't have fitting include block), it prints out
    an error message indicating which .h file needs to be added to the
    file.

    The conversion was done in the following steps.

    1. The initial automatic conversion of all .c files updated slightly
    over 4000 files, deleting around 700 includes and adding ~480 gfp.h
    and ~3000 slab.h inclusions. The script emitted errors for ~400
    files.

    2. Each error was manually checked. Some didn't need the inclusion,
    some needed manual addition while adding it to implementation .h or
    embedding .c file was more appropriate for others. This step added
    inclusions to around 150 files.

    3. The script was run again and the output was compared to the edits
    from #2 to make sure no file was left behind.

    4. Several build tests were done and a couple of problems were fixed.
    e.g. lib/decompress_*.c used malloc/free() wrappers around slab
    APIs requiring slab.h to be added manually.

    5. The script was run on all .h files but without automatically
    editing them as sprinkling gfp.h and slab.h inclusions around .h
    files could easily lead to inclusion dependency hell. Most gfp.h
    inclusion directives were ignored as stuff from gfp.h was usually
    wildly available and often used in preprocessor macros. Each
    slab.h inclusion directive was examined and added manually as
    necessary.

    6. percpu.h was updated not to include slab.h.

    7. Build test were done on the following configurations and failures
    were fixed. CONFIG_GCOV_KERNEL was turned off for all tests (as my
    distributed build env didn't work with gcov compiles) and a few
    more options had to be turned off depending on archs to make things
    build (like ipr on powerpc/64 which failed due to missing writeq).

    * x86 and x86_64 UP and SMP allmodconfig and a custom test config.
    * powerpc and powerpc64 SMP allmodconfig
    * sparc and sparc64 SMP allmodconfig
    * ia64 SMP allmodconfig
    * s390 SMP allmodconfig
    * alpha SMP allmodconfig
    * um on x86_64 SMP allmodconfig

    8. percpu.h modifications were reverted so that it could be applied as
    a separate patch and serve as bisection point.

    Given the fact that I had only a couple of failures from tests on step
    6, I'm fairly confident about the coverage of this conversion patch.
    If there is a breakage, it's likely to be something in one of the arch
    headers which should be easily discoverable easily on most builds of
    the specific arch.

    Signed-off-by: Tejun Heo <tj@kernel.org>
    Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org>
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>

    Tejun Heo
     

19 Feb, 2010

1 commit


16 Jan, 2010

2 commits

  • inotify will WARN() if it finds that the idr and the fsnotify internals
    somehow got out of sync. It was only supposed to do this once but due
    to this stupid bug it would warn every single time a problem was
    detected.

    Signed-off-by: Eric Paris
    Cc: stable@kernel.org
    Signed-off-by: Linus Torvalds

    Eric Paris
     
  • Since commit 7e790dd5fc937bc8d2400c30a05e32a9e9eef276 ("inotify: fix
    error paths in inotify_update_watch") inotify changed the manor in which
    it gave watch descriptors back to userspace. Previous to this commit
    inotify acted like the following:

    inotify_add_watch(X, Y, Z) = 1
    inotify_rm_watch(X, 1);
    inotify_add_watch(X, Y, Z) = 2

    but after this patch inotify would return watch descriptors like so:

    inotify_add_watch(X, Y, Z) = 1
    inotify_rm_watch(X, 1);
    inotify_add_watch(X, Y, Z) = 1

    which I saw as equivalent to opening an fd where

    open(file) = 1;
    close(1);
    open(file) = 1;

    seemed perfectly reasonable. The issue is that quite a bit of userspace
    apparently relies on the behavior in which watch descriptors will not be
    quickly reused. KDE relies on it, I know some selinux packages rely on
    it, and I have heard complaints from other random sources such as debian
    bug 558981.

    Although the man page implies what we do is ok, we broke userspace so
    this patch almost reverts us to the old behavior. It is still slightly
    racey and I have patches that would fix that, but they are rather large
    and this will fix it for all real world cases. The race is as follows:

    - task1 creates a watch and blocks in idr_new_watch() before it updates
    the hint.
    - task2 creates a watch and updates the hint.
    - task1 updates the hint with it's older wd
    - task removes the watch created by task2
    - task adds a new watch and will reuse the wd originally given to task2

    it requires moving some locking around the hint (last_wd) but this should
    solve it for the real world and be -stable safe.

    As a side effect this patch papers over a bug in the lib/idr code which
    is causing a large number WARN's to pop on people's system and many
    reports in kerneloops.org. I'm working on the root cause of that idr
    bug seperately but this should make inotify immune to that issue.

    Signed-off-by: Eric Paris
    Cc: stable@kernel.org
    Signed-off-by: Linus Torvalds

    Eric Paris
     

17 Dec, 2009

2 commits


10 Dec, 2009

1 commit

  • * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial: (42 commits)
    tree-wide: fix misspelling of "definition" in comments
    reiserfs: fix misspelling of "journaled"
    doc: Fix a typo in slub.txt.
    inotify: remove superfluous return code check
    hdlc: spelling fix in find_pvc() comment
    doc: fix regulator docs cut-and-pasteism
    mtd: Fix comment in Kconfig
    doc: Fix IRQ chip docs
    tree-wide: fix assorted typos all over the place
    drivers/ata/libata-sff.c: comment spelling fixes
    fix typos/grammos in Documentation/edac.txt
    sysctl: add missing comments
    fs/debugfs/inode.c: fix comment typos
    sgivwfb: Make use of ARRAY_SIZE.
    sky2: fix sky2_link_down copy/paste comment error
    tree-wide: fix typos "couter" -> "counter"
    tree-wide: fix typos "offest" -> "offset"
    fix kerneldoc for set_irq_msi()
    spidev: fix double "of of" in comment
    comment typo fix: sybsystem -> subsystem
    ...

    Linus Torvalds
     

04 Dec, 2009

1 commit


19 Nov, 2009

1 commit


12 Nov, 2009

1 commit


21 Oct, 2009

1 commit

  • Mask off FS_EVENT_ON_CHILD in dnotify_handle_event(). Otherwise, when there
    is more than one watch on a directory and dnotify_should_send_event()
    succeeds, events with FS_EVENT_ON_CHILD set will trigger all watches and cause
    spurious events.

    This case was overlooked in commit e42e2773.

    #define _GNU_SOURCE

    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    static void create_event(int s, siginfo_t* si, void* p)
    {
    printf("create\n");
    }

    static void delete_event(int s, siginfo_t* si, void* p)
    {
    printf("delete\n");
    }

    int main (void) {
    struct sigaction action;
    char *tmpdir, *file;
    int fd1, fd2;

    sigemptyset (&action.sa_mask);
    action.sa_flags = SA_SIGINFO;

    action.sa_sigaction = create_event;
    sigaction (SIGRTMIN + 0, &action, NULL);

    action.sa_sigaction = delete_event;
    sigaction (SIGRTMIN + 1, &action, NULL);

    # define TMPDIR "/tmp/test.XXXXXX"
    tmpdir = malloc(strlen(TMPDIR) + 1);
    strcpy(tmpdir, TMPDIR);
    mkdtemp(tmpdir);

    # define TMPFILE "/file"
    file = malloc(strlen(tmpdir) + strlen(TMPFILE) + 1);
    sprintf(file, "%s/%s", tmpdir, TMPFILE);

    fd1 = open (tmpdir, O_RDONLY);
    fcntl(fd1, F_SETSIG, SIGRTMIN);
    fcntl(fd1, F_NOTIFY, DN_MULTISHOT | DN_CREATE);

    fd2 = open (tmpdir, O_RDONLY);
    fcntl(fd2, F_SETSIG, SIGRTMIN + 1);
    fcntl(fd2, F_NOTIFY, DN_MULTISHOT | DN_DELETE);

    if (fork()) {
    /* This triggers a create event */
    creat(file, 0600);
    /* This triggers a create and delete event (!) */
    unlink(file);
    } else {
    sleep(1);
    rmdir(tmpdir);
    }

    return 0;
    }

    Signed-off-by: Andreas Gruenbacher
    Signed-off-by: Eric Paris

    Andreas Gruenbacher
     

19 Oct, 2009

2 commits

  • If we do rename a dir entry, like this:

    rename("/tmp/ino7UrgoJ.rename1", "/tmp/ino7UrgoJ.rename2")
    rename("/tmp/ino7UrgoJ.rename2", "/tmp/ino7UrgoJ")

    The duplicate events should be coalesced into a single event. But those two
    events do not be coalesced into a single event, due to some bad check in
    event_compare(). It can not match the two NULL inodes as the same event.

    Signed-off-by: Wei Yongjun
    Signed-off-by: Eric Paris

    Wei Yongjun
     
  • fsnotify_add_mark is supposed to add a mark to the g_list and i_list and to
    set the group and inode for the mark. fsnotify_destroy_mark_by_entry uses
    the fact that ->group != NULL to know if this group should be destroyed or
    if it's already been done.

    But fsnotify_add_mark sets the group and inode before it actually adds the
    mark to the i_list and g_list. This can result in a race in inotify, it
    requires 3 threads.

    sys_inotify_add_watch("file") sys_inotify_add_watch("file") sys_inotify_rm_watch([a])
    inotify_update_watch()
    inotify_new_watch()
    inotify_add_to_idr()
    ^--- returns wd = [a]
    inotfiy_update_watch()
    inotify_new_watch()
    inotify_add_to_idr()
    fsnotify_add_mark()
    ^--- returns wd = [b]
    returns to userspace;
    inotify_idr_find([a])
    ^--- gives us the pointer from task 1
    fsnotify_add_mark()
    ^--- this is going to set the mark->group and mark->inode fields, but will
    return -EEXIST because of the race with [b].
    fsnotify_destroy_mark()
    ^--- since ->group != NULL we call back
    into inotify_freeing_mark() which calls
    inotify_remove_from_idr([a])

    since fsnotify_add_mark() failed we call:
    inotify_remove_from_idr([a]) group until we are sure the mark is
    on the inode and fsnotify_add_mark will return success.

    Signed-off-by: Eric Paris

    Eric Paris
     

29 Aug, 2009

1 commit


28 Aug, 2009

2 commits

  • 0db501bd0610ee0c0 introduced a regresion in that it now sends a nul
    terminator but the length accounting when checking for space or
    reporting to userspace did not take this into account. This corrects
    all of the rounding logic.

    Signed-off-by: Eric Paris

    Eric Paris
     
  • When an event has no pathname, there's no need to pad it with a null byte and
    therefore generate an inotify_event sized block of zeros. This fixes a
    regression introduced by commit 0db501bd0610ee0c0aca84d927f90bcccd09e2bd where
    my system wouldn't finish booting because some process was being confused by
    this.

    Signed-off-by: Brian Rogers
    Signed-off-by: Eric Paris

    Brian Rogers
     

27 Aug, 2009

4 commits

  • Before the rewrite copy_event_to_user always wrote a terqminating '\0'
    byte to user space after the filename. Since the rewrite that
    terminating byte was skipped if your filename is exactly a multiple of
    event_size. Ouch!

    So add one byte to name_size before we round up and use clear_user to
    set userspace to zero like /dev/zero does instead of copying the
    strange nul_inotify_event. I can't quite convince myself len_to_zero
    will never exceed 16 and even if it doesn't clear_user should be more
    efficient and a more accurate reflection of what the code is trying to
    do.

    Signed-off-by: Eric W. Biederman
    Signed-off-by: Eric Paris

    Eric W. Biederman
     
  • The are races around the idr storage of inotify watches. It's possible
    that a watch could be found from sys_inotify_rm_watch() in the idr, but it
    could be removed from the idr before that code does it's removal. Move the
    locking and the refcnt'ing so that these have to happen atomically.

    Signed-off-by: Eric Paris

    Eric Paris
     
  • If an inotify watch is left in the idr when an fsnotify group is destroyed
    this will lead to a BUG. This is not a dangerous situation and really
    indicates a programming bug and leak of memory. This patch changes it to
    use a WARN and a printk rather than killing people's boxes.

    Signed-off-by: Eric Paris

    Eric Paris
     
  • There is nothing known wrong with the inotify watch addition/modification
    but this patch seperates the two code paths to make them each easy to
    verify as correct.

    Signed-off-by: Eric Paris

    Eric Paris
     

18 Aug, 2009

3 commits

  • The inotify_add_watch man page specifies that inotify_add_watch() will
    return a non-negative integer. However, historically the inotify
    watches started at 1, not at 0.

    Turns out that the inotifywait program provided by the inotify-tools
    package doesn't properly handle a 0 watch descriptor. In 7e790dd5 we
    changed from starting at 1 to starting at 0. This patch starts at 1,
    just like in previous kernels, but also just like in previous kernels
    it's possible for it to wrap back to 0. This preserves the kernel
    functionality exactly like it was before the patch (neither method broke
    the spec)

    Signed-off-by: Eric Paris
    Signed-off-by: Linus Torvalds

    Eric Paris
     
  • In f44aebcc the tail drop logic of events with no file backing
    (q_overflow and in_ignored) was reversed so IN_IGNORED events would
    never be tail dropped. This now means that Q_OVERFLOW events are NOT
    tail dropped. The fix is to not tail drop IN_IGNORED, but to tail drop
    Q_OVERFLOW.

    Signed-off-by: Eric Paris
    Signed-off-by: Linus Torvalds

    Eric Paris
     
  • inotify decides if private data it passed to get added to an event was
    used by checking list_empty(). But it's possible that the event may
    have been dequeued and the private event removed so it would look empty.

    The fix is to use the return code from fsnotify_add_notify_event rather
    than looking at the list.

    Signed-off-by: Eric Paris
    Signed-off-by: Linus Torvalds

    Eric Paris
     

22 Jul, 2009

7 commits

  • inotify can have a watchs removed under filesystem reclaim.

    =================================
    [ INFO: inconsistent lock state ]
    2.6.31-rc2 #16
    ---------------------------------
    inconsistent {IN-RECLAIM_FS-W} -> {RECLAIM_FS-ON-W} usage.
    khubd/217 [HC0[0]:SC0[0]:HE1:SE1] takes:
    (iprune_mutex){+.+.?.}, at: [] invalidate_inodes+0x20/0xe3
    {IN-RECLAIM_FS-W} state was registered at:
    [] __lock_acquire+0x2c9/0xac4
    [] lock_acquire+0x9f/0xc2
    [] __mutex_lock_common+0x2d/0x323
    [] mutex_lock_nested+0x2e/0x36
    [] shrink_icache_memory+0x38/0x1b2
    [] shrink_slab+0xe2/0x13c
    [] kswapd+0x3d1/0x55d
    [] kthread+0x66/0x6b
    [] kernel_thread_helper+0x7/0x10
    [] 0xffffffff

    Two things are needed to fix this. First we need a method to tell
    fsnotify_create_event() to use GFP_NOFS and second we need to stop using
    one global IN_IGNORED event and allocate them one at a time. This solves
    current issues with multiple IN_IGNORED on a queue having tail drop
    problems and simplifies the allocations since we don't have to worry about
    two tasks opperating on the IGNORED event concurrently.

    Signed-off-by: Eric Paris

    Eric Paris
     
  • fsnotify drops new events when they are the same as the tail event on the
    queue to be sent to userspace. The problem is that if the event comes with
    a path we forget to break out of the switch statement and fall into the
    code path which matches on events that do not have any type of file backed
    information (things like IN_UNMOUNT and IN_Q_OVERFLOW). The problem is
    that this code thinks all such events should be dropped. Fix is to add a
    break.

    Signed-off-by: Eric Paris

    Eric Paris
     
  • inotify drops events if the last event on the queue is the same as the
    current event. But it does 2 things wrong. First it is comparing old->inode
    with new->inode. But after an event if put on the queue the ->inode is no
    longer allowed to be used. It's possible between the last event and this new
    event the inode could be reused and we would falsely match the inode's memory
    address between two differing events.

    The second problem is that when a file is removed fsnotify is passed the
    negative dentry for the removed object rather than the postive dentry from
    immediately before the removal. This mean the (broken) inotify tail drop code
    was matching the NULL ->inode of differing events.

    The fix is to check the file name which is stored with events when doing the
    tail drop instead of wrongly checking the address of the stored ->inode.

    Reported-by: Scott James Remnant
    Signed-off-by: Eric Paris

    Eric Paris
     
  • fsnotify doens't give the user anything. If someone chooses inotify or
    dnotify it should build fsnotify, if they don't select one it shouldn't be
    built. This patch changes fsnotify to be a def_bool=n and makes everything
    else select it. Also fixes the issue people complained about on lwn where
    gdm hung because they didn't have inotify and they didn't get the inotify
    build option.....

    Signed-off-by: Eric Paris

    Eric Paris
     
  • inotify_update_watch could leave things in a horrid state on a number of
    error paths. We could try to remove idr entries that didn't exist, we
    could send an IN_IGNORED to userspace for watches that don't exist, and a
    bit of other stupidity. Clean these up by doing the idr addition before we
    put the mark on the inode since we can clean that up on error and getting
    off the inode's mark list is hard.

    Signed-off-by: Eric Paris

    Eric Paris
     
  • inotify_add_watch had a couple of problems. The biggest being that if
    inotify_add_watch was called on the same inode twice (to update or change the
    event mask) a refence was taken on the original inode mark by
    fsnotify_find_mark_entry but was not being dropped at the end of the
    inotify_add_watch call. Thus if inotify_rm_watch was called although the mark
    was removed from the inode, the refcnt wouldn't hit zero and we would leak
    memory.

    Reported-by: Catalin Marinas
    Signed-off-by: Eric Paris

    Eric Paris
     
  • The inotify rewrite forgot to drop the inotify watch use cound when a watch
    was removed. This means that a single inotify fd can only ever register a
    maximum of /proc/sys/fs/max_user_watches even if some of those had been
    freed.

    Signed-off-by: Eric Paris

    Eric Paris
     

02 Jul, 2009

1 commit


20 Jun, 2009

1 commit

  • inotify_destroy_mark_entry could get called twice for the same mark since it
    is called directly in inotify_rm_watch and when the mark is being destroyed for
    another reason. As an example assume that the file being watched was just
    deleted so inotify_destroy_mark_entry would get called from the path
    fsnotify_inoderemove() -> fsnotify_destroy_marks_by_inode() ->
    fsnotify_destroy_mark_entry() -> inotify_destroy_mark_entry(). If this
    happened at the same time as userspace tried to remove a watch via
    inotify_rm_watch we could attempt to remove the mark from the idr twice and
    could thus double dec the ref cnt and potentially could be in a use after
    free/double free situation. The fix is to have inotify_rm_watch use the
    generic recursive safe fsnotify_destroy_mark_by_entry() so we are sure the
    inotify_destroy_mark_entry() function can only be called one.

    This patch also renames the function to inotify_ingored_remove_idr() so it is
    clear what is actually going on in the function.

    Hopefully this fixes:
    [ 20.342058] idr_remove called for id=20 which is not allocated.
    [ 20.348000] Pid: 1860, comm: udevd Not tainted 2.6.30-tip #1077
    [ 20.353933] Call Trace:
    [ 20.356410] [] idr_remove+0x115/0x18f
    [ 20.361737] [] ? _spin_lock+0x6d/0x75
    [ 20.367061] [] ? inotify_destroy_mark_entry+0xa3/0xcf
    [ 20.373771] [] inotify_destroy_mark_entry+0xb7/0xcf
    [ 20.380306] [] inotify_freeing_mark+0xe/0x10
    [ 20.386238] [] fsnotify_destroy_mark_by_entry+0x143/0x170
    [ 20.393293] [] inotify_destroy_mark_entry+0x3c/0xcf
    [ 20.399829] [] sys_inotify_rm_watch+0x9b/0xc6
    [ 20.405850] [] system_call_fastpath+0x16/0x1b

    Reported-by: Peter Zijlstra
    Signed-off-by: Eric Paris
    Tested-by: Peter Ziljlstra

    Eric Paris