Re: [PATCH] Per-superblock unused dentry LRU lists V3

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> David Chinner <[email protected]> wrote:
>
> +/*
> + * Shrink the dentry LRU on a given superblock.
> + *
> + * If flags is non-zero, we need to do special processing based on
> + * which flags are set. This means we don't need to maintain multiple
> + * similar copies of this loop.
> + */
> +static void __shrink_dcache_sb(struct super_block *sb, int *count, int 
> flags)
> +{
> +       struct dentry *dentry;
> +       int cnt = *count;
> +
> +       spin_lock(&dcache_lock);
> +       while (!list_empty(&sb->s_dentry_lru) && cnt--) {
> +               dentry = list_entry(sb->s_dentry_lru.prev,
> +                                       struct dentry, d_lru);
> +               dentry_lru_del_init(dentry);
> +               BUG_ON(dentry->d_sb != sb);
> +               prefetch(sb->s_dentry_lru.prev);
> +
> +               spin_lock(&dentry->d_lock);
> +               /*
> +                * We found an inuse dentry which was not removed from
> +                * the LRU because of laziness during lookup.  Do not free
> +                * it - just keep it off the LRU list.
> +                */
> +               if (atomic_read(&dentry->d_count)) {
> +                       spin_unlock(&dentry->d_lock);
> +                       continue;
> +               }
> +               /*
> +                * If we are honouring the DCACHE_REFERENCED flag and the
> +                * dentry has this flag set, don't free it. Clear the flag
> +                * and put it back on the LRU
> +                */
> +               if ((flags & DCACHE_REFERENCED) &&
> +                   (dentry->d_flags & DCACHE_REFERENCED)) {
> +                       dentry->d_flags &= ~DCACHE_REFERENCED;
> +                       dentry_lru_add(dentry);
> +                       spin_unlock(&dentry->d_lock);
> +                       continue;
> +               }
> +               prune_one_dentry(dentry);
> +       }
> +       spin_unlock(&dcache_lock);
> +       *count = cnt;
> +}
> +
> /**
>  * shrink_dcache_sb - shrink dcache for a superblock
>  * @sb: superblock
> @@ -507,44 +529,9 @@ static void prune_dcache(int count, stru
>  * is used to free the dcache before unmounting a file
>  * system
>  */
> -
> void shrink_dcache_sb(struct super_block * sb)
> {
> -       struct list_head *tmp, *next;
> -       struct dentry *dentry;
> -
> -       /*
> -        * Pass one ... move the dentries for the specified
> -        * superblock to the most recent end of the unused list.
> -        */
> -       spin_lock(&dcache_lock);
> -       list_for_each_safe(tmp, next, &dentry_unused) {
> -               dentry = list_entry(tmp, struct dentry, d_lru);
> -               if (dentry->d_sb != sb)
> -                       continue;
> -               list_move(tmp, &dentry_unused);
> -       }
> -
> -       /*
> -        * Pass two ... free the dentries for this superblock.
> -        */
> -repeat:
> -       list_for_each_safe(tmp, next, &dentry_unused) {
> -               dentry = list_entry(tmp, struct dentry, d_lru);
> -               if (dentry->d_sb != sb)
> -                       continue;
> -               dentry_stat.nr_unused--;
> -               list_del_init(tmp);
> -               spin_lock(&dentry->d_lock);
> -               if (atomic_read(&dentry->d_count)) {
> -                       spin_unlock(&dentry->d_lock);
> -                       continue;
> -               }
> -               prune_one_dentry(dentry);
> -               cond_resched_lock(&dcache_lock);
> -               goto repeat;
> -       }
> -       spin_unlock(&dcache_lock);
> +       __shrink_dcache_sb(sb, &sb->s_dentry_lru_nr, 0);
> }

This doesn't prune all the dentries on the unused list. The parents of the
pruned dentries are added to the unused list. Therefore just shrinking
sb->s_dentry_lru_nr dentries isn't enough.

Jan
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux