lkml.org 
[lkml]   [2005]   [May]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [PATCH] Fix of dcache race leading to busy inodes on umount
    Kirill Korotaev <dev@sw.ru> wrote:
    >
    > This patch fixes dcache race between shrink_dcache_XXX functions
    > and dput().


    > -void dput(struct dentry *dentry)
    > +static void dput_recursive(struct dentry *dentry, struct dcache_shrinker *ds)
    > {
    > - if (!dentry)
    > - return;
    > -
    > -repeat:
    > if (atomic_read(&dentry->d_count) == 1)
    > might_sleep();
    > if (!atomic_dec_and_lock(&dentry->d_count, &dcache_lock))
    > return;
    > + dcache_shrinker_del(ds);
    >
    > +repeat:
    > spin_lock(&dentry->d_lock);
    > if (atomic_read(&dentry->d_count)) {
    > spin_unlock(&dentry->d_lock);
    > @@ -182,6 +253,7 @@ unhash_it:
    >
    > kill_it: {
    > struct dentry *parent;
    > + struct dcache_shrinker lds;
    >
    > /* If dentry was on d_lru list
    > * delete it from there
    > @@ -191,18 +263,43 @@ kill_it: {
    > dentry_stat.nr_unused--;
    > }
    > list_del(&dentry->d_child);
    > + parent = dentry->d_parent;
    > + dcache_shrinker_add(&lds, parent, dentry);
    > dentry_stat.nr_dentry--; /* For d_free, below */
    > /*drops the locks, at that point nobody can reach this dentry */
    > dentry_iput(dentry);
    > - parent = dentry->d_parent;
    > d_free(dentry);
    > if (dentry == parent)

    Aren't we leaving local variable `lds' on the global list here?

    > return;
    > dentry = parent;
    > - goto repeat;
    > + spin_lock(&dcache_lock);
    > + dcache_shrinker_del(&lds);
    > + if (atomic_dec_and_test(&dentry->d_count))
    > + goto repeat;
    > + spin_unlock(&dcache_lock);
    > }
    > }
    >

    --- 25/fs/dcache.c~fix-of-dcache-race-leading-to-busy-inodes-on-umount-fix 2005-05-11 19:24:23.000000000 -0700
    +++ 25-akpm/fs/dcache.c 2005-05-11 19:27:27.000000000 -0700
    @@ -269,8 +269,12 @@ kill_it: {
    /*drops the locks, at that point nobody can reach this dentry */
    dentry_iput(dentry);
    d_free(dentry);
    - if (dentry == parent)
    + if (unlikely(dentry == parent)) {
    + spin_lock(&dcache_lock);
    + dcache_shrinker_del(&lds);
    + spin_unlock(&dcache_lock);
    return;
    + }
    dentry = parent;
    spin_lock(&dcache_lock);
    dcache_shrinker_del(&lds);
    _
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-05-12 04:34    [W:0.027 / U:1.412 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site