03 Oct, 2012

1 commit

  • There's no reason to call rcu_barrier() on every
    deactivate_locked_super(). We only need to make sure that all delayed rcu
    free inodes are flushed before we destroy related cache.

    Removing rcu_barrier() from deactivate_locked_super() affects some fast
    paths. E.g. on my machine exit_group() of a last process in IPC
    namespace takes 0.07538s. rcu_barrier() takes 0.05188s of that time.

    Signed-off-by: Kirill A. Shutemov
    Cc: Al Viro
    Signed-off-by: Andrew Morton
    Signed-off-by: Al Viro

    Kirill A. Shutemov
     

14 Jul, 2012

1 commit

  • Just the flags; only NFS cares even about that, but there are
    legitimate uses for such argument. And getting rid of that
    completely would require splitting ->lookup() into a couple
    of methods (at least), so let's leave that alone for now...

    Signed-off-by: Al Viro

    Al Viro
     

31 Mar, 2012

1 commit

  • Pull MTD changes from David Woodhouse:
    - Artem's cleanup of the MTD API continues apace.
    - Fixes and improvements for ST FSMC and SuperH FLCTL NAND, amongst
    others.
    - More work on DiskOnChip G3, new driver for DiskOnChip G4.
    - Clean up debug/warning printks in JFFS2 to use pr_.

    Fix up various trivial conflicts, largely due to changes in calling
    conventions for things like dmaengine_prep_slave_sg() (new inline
    wrapper to hide new parameter, clashing with rewrite of previously last
    parameter that used to be an 'append' flag, and is now a bitmap of
    'unsigned long flags').

    (Also some header file fallout - like so many merges this merge window -
    and silly conflicts with sparse fixes)

    * tag 'for-linus-3.4' of git://git.infradead.org/mtd-2.6: (120 commits)
    mtd: docg3 add protection against concurrency
    mtd: docg3 refactor cascade floors structure
    mtd: docg3 increase write/erase timeout
    mtd: docg3 fix inbound calculations
    mtd: nand: gpmi: fix function annotations
    mtd: phram: fix section mismatch for phram_setup
    mtd: unify initialization of erase_info->fail_addr
    mtd: support ONFI multi lun NAND
    mtd: sm_ftl: fix typo in major number.
    mtd: add device-tree support to spear_smi
    mtd: spear_smi: Remove default partition information from driver
    mtd: Add device-tree support to fsmc_nand
    mtd: fix section mismatch for doc_probe_device
    mtd: nand/fsmc: Remove sparse warnings and errors
    mtd: nand/fsmc: Add DMA support
    mtd: nand/fsmc: Access the NAND device word by word whenever possible
    mtd: nand/fsmc: Use dev_err to report error scenario
    mtd: nand/fsmc: Use devm routines
    mtd: nand/fsmc: Modify fsmc driver to accept nand timing parameters via platform
    mtd: fsmc_nand: add pm callbacks to support hibernation
    ...

    Linus Torvalds
     

27 Mar, 2012

1 commit


21 Mar, 2012

1 commit


11 Jan, 2012

1 commit

  • MTD pull for 3.3

    * tag 'for-linus-3.3' of git://git.infradead.org/mtd-2.6: (113 commits)
    mtd: Fix dependency for MTD_DOC200x
    mtd: do not use mtd->block_markbad directly
    logfs: do not use 'mtd->block_isbad' directly
    mtd: introduce mtd_can_have_bb helper
    mtd: do not use mtd->suspend and mtd->resume directly
    mtd: do not use mtd->lock, unlock and is_locked directly
    mtd: do not use mtd->sync directly
    mtd: harmonize mtd_writev usage
    mtd: do not use mtd->lock_user_prot_reg directly
    mtd: mtd->write_user_prot_reg directly
    mtd: do not use mtd->read_*_prot_reg directly
    mtd: do not use mtd->get_*_prot_info directly
    mtd: do not use mtd->read_oob directly
    mtd: mtdoops: do not use mtd->panic_write directly
    romfs: do not use mtd->get_unmapped_area directly
    mtd: do not use mtd->get_unmapped_area directly
    mtd: do use mtd->point directly
    mtd: introduce mtd_has_oob helper
    mtd: mtdcore: export symbols cleanup
    mtd: clean-up the default_mtd_writev function
    ...

    Fix up trivial edit/remove conflict in drivers/staging/spectra/lld_mtd.c

    Linus Torvalds
     

10 Jan, 2012

2 commits


04 Jan, 2012

1 commit

  • Seeing that just about every destructor got that INIT_LIST_HEAD() copied into
    it, there is no point whatsoever keeping this INIT_LIST_HEAD in inode_init_once();
    the cost of taking it into inode_init_always() will be negligible for pipes
    and sockets and negative for everything else. Not to mention the removal of
    boilerplate code from ->destroy_inode() instances...

    Signed-off-by: Al Viro

    Al Viro
     

02 Nov, 2011

1 commit


28 Jun, 2011

1 commit

  • romfs_get_unmapped_area() checks argument `len' without considering
    PAGE_ALIGN which will cause do_mmap_pgoff() return -EINVAL error after
    commit f67d9b1576c ("nommu: add page_align to mmap").

    Fix the check by changing it in same way ramfs_nommu_get_unmapped_area()
    was changed in ramfs/file-nommu.c.

    Signed-off-by: Bob Liu
    Cc: David Howells
    Cc: Paul Mundt
    Acked-by: Greg Ungerer
    Cc: Geert Uytterhoeven
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Bob Liu
     

07 Jan, 2011

1 commit

  • RCU free the struct inode. This will allow:

    - Subsequent store-free path walking patch. The inode must be consulted for
    permissions when walking, so an RCU inode reference is a must.
    - sb_inode_list_lock to be moved inside i_lock because sb list walkers who want
    to take i_lock no longer need to take sb_inode_list_lock to walk the list in
    the first place. This will simplify and optimize locking.
    - Could remove some nested trylock loops in dcache code
    - Could potentially simplify things a bit in VM land. Do not need to take the
    page lock to follow page->mapping.

    The downsides of this is the performance cost of using RCU. In a simple
    creat/unlink microbenchmark, performance drops by about 10% due to inability to
    reuse cache-hot slab objects. As iterations increase and RCU freeing starts
    kicking over, this increases to about 20%.

    In cases where inode lifetimes are longer (ie. many inodes may be allocated
    during the average life span of a single inode), a lot of this cache reuse is
    not applicable, so the regression caused by this patch is smaller.

    The cache-hot regression could largely be avoided by using SLAB_DESTROY_BY_RCU,
    however this adds some complexity to list walking and store-free path walking,
    so I prefer to implement this at a later date, if it is shown to be a win in
    real situations. I haven't found a regression in any non-micro benchmark so I
    doubt it will be a problem.

    Signed-off-by: Nick Piggin

    Nick Piggin
     

29 Oct, 2010

1 commit


15 Oct, 2010

1 commit

  • All file_operations should get a .llseek operation so we can make
    nonseekable_open the default for future file operations without a
    .llseek pointer.

    The three cases that we can automatically detect are no_llseek, seq_lseek
    and default_llseek. For cases where we can we can automatically prove that
    the file offset is always ignored, we use noop_llseek, which maintains
    the current behavior of not returning an error from a seek.

    New drivers should normally not use noop_llseek but instead use no_llseek
    and call nonseekable_open at open time. Existing drivers can be converted
    to do the same when the maintainer knows for certain that no user code
    relies on calling seek on the device file.

    The generated code is often incorrectly indented and right now contains
    comments that clarify for each added line why a specific variant was
    chosen. In the version that gets submitted upstream, the comments will
    be gone and I will manually fix the indentation, because there does not
    seem to be a way to do that using coccinelle.

    Some amount of new code is currently sitting in linux-next that should get
    the same modifications, which I will do at the end of the merge window.

    Many thanks to Julia Lawall for helping me learn to write a semantic
    patch that does all this.

    ===== begin semantic patch =====
    // This adds an llseek= method to all file operations,
    // as a preparation for making no_llseek the default.
    //
    // The rules are
    // - use no_llseek explicitly if we do nonseekable_open
    // - use seq_lseek for sequential files
    // - use default_llseek if we know we access f_pos
    // - use noop_llseek if we know we don't access f_pos,
    // but we still want to allow users to call lseek
    //
    @ open1 exists @
    identifier nested_open;
    @@
    nested_open(...)
    {

    }

    @ open exists@
    identifier open_f;
    identifier i, f;
    identifier open1.nested_open;
    @@
    int open_f(struct inode *i, struct file *f)
    {

    }

    @ read disable optional_qualifier exists @
    identifier read_f;
    identifier f, p, s, off;
    type ssize_t, size_t, loff_t;
    expression E;
    identifier func;
    @@
    ssize_t read_f(struct file *f, char *p, size_t s, loff_t *off)
    {

    }

    @ read_no_fpos disable optional_qualifier exists @
    identifier read_f;
    identifier f, p, s, off;
    type ssize_t, size_t, loff_t;
    @@
    ssize_t read_f(struct file *f, char *p, size_t s, loff_t *off)
    {
    ... when != off
    }

    @ write @
    identifier write_f;
    identifier f, p, s, off;
    type ssize_t, size_t, loff_t;
    expression E;
    identifier func;
    @@
    ssize_t write_f(struct file *f, const char *p, size_t s, loff_t *off)
    {

    }

    @ write_no_fpos @
    identifier write_f;
    identifier f, p, s, off;
    type ssize_t, size_t, loff_t;
    @@
    ssize_t write_f(struct file *f, const char *p, size_t s, loff_t *off)
    {
    ... when != off
    }

    @ fops0 @
    identifier fops;
    @@
    struct file_operations fops = {
    ...
    };

    @ has_llseek depends on fops0 @
    identifier fops0.fops;
    identifier llseek_f;
    @@
    struct file_operations fops = {
    ...
    .llseek = llseek_f,
    ...
    };

    @ has_read depends on fops0 @
    identifier fops0.fops;
    identifier read_f;
    @@
    struct file_operations fops = {
    ...
    .read = read_f,
    ...
    };

    @ has_write depends on fops0 @
    identifier fops0.fops;
    identifier write_f;
    @@
    struct file_operations fops = {
    ...
    .write = write_f,
    ...
    };

    @ has_open depends on fops0 @
    identifier fops0.fops;
    identifier open_f;
    @@
    struct file_operations fops = {
    ...
    .open = open_f,
    ...
    };

    // use no_llseek if we call nonseekable_open
    ////////////////////////////////////////////
    @ nonseekable1 depends on !has_llseek && has_open @
    identifier fops0.fops;
    identifier nso ~= "nonseekable_open";
    @@
    struct file_operations fops = {
    ... .open = nso, ...
    +.llseek = no_llseek, /* nonseekable */
    };

    @ nonseekable2 depends on !has_llseek @
    identifier fops0.fops;
    identifier open.open_f;
    @@
    struct file_operations fops = {
    ... .open = open_f, ...
    +.llseek = no_llseek, /* open uses nonseekable */
    };

    // use seq_lseek for sequential files
    /////////////////////////////////////
    @ seq depends on !has_llseek @
    identifier fops0.fops;
    identifier sr ~= "seq_read";
    @@
    struct file_operations fops = {
    ... .read = sr, ...
    +.llseek = seq_lseek, /* we have seq_read */
    };

    // use default_llseek if there is a readdir
    ///////////////////////////////////////////
    @ fops1 depends on !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier readdir_e;
    @@
    // any other fop is used that changes pos
    struct file_operations fops = {
    ... .readdir = readdir_e, ...
    +.llseek = default_llseek, /* readdir is present */
    };

    // use default_llseek if at least one of read/write touches f_pos
    /////////////////////////////////////////////////////////////////
    @ fops2 depends on !fops1 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier read.read_f;
    @@
    // read fops use offset
    struct file_operations fops = {
    ... .read = read_f, ...
    +.llseek = default_llseek, /* read accesses f_pos */
    };

    @ fops3 depends on !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier write.write_f;
    @@
    // write fops use offset
    struct file_operations fops = {
    ... .write = write_f, ...
    + .llseek = default_llseek, /* write accesses f_pos */
    };

    // Use noop_llseek if neither read nor write accesses f_pos
    ///////////////////////////////////////////////////////////

    @ fops4 depends on !fops1 && !fops2 && !fops3 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier read_no_fpos.read_f;
    identifier write_no_fpos.write_f;
    @@
    // write fops use offset
    struct file_operations fops = {
    ...
    .write = write_f,
    .read = read_f,
    ...
    +.llseek = noop_llseek, /* read and write both use no f_pos */
    };

    @ depends on has_write && !has_read && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier write_no_fpos.write_f;
    @@
    struct file_operations fops = {
    ... .write = write_f, ...
    +.llseek = noop_llseek, /* write uses no f_pos */
    };

    @ depends on has_read && !has_write && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier read_no_fpos.read_f;
    @@
    struct file_operations fops = {
    ... .read = read_f, ...
    +.llseek = noop_llseek, /* read uses no f_pos */
    };

    @ depends on !has_read && !has_write && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    @@
    struct file_operations fops = {
    ...
    +.llseek = noop_llseek, /* no read or write fn */
    };
    ===== End semantic patch =====

    Signed-off-by: Arnd Bergmann
    Cc: Julia Lawall
    Cc: Christoph Hellwig

    Arnd Bergmann
     

27 Jan, 2010

1 commit


12 Oct, 2009

1 commit

  • An interestingly corrupted romfs file system exposed a problem with the
    romfs_dev_strnlen function: it's passing the wrong value to its helpers.
    Rather than limit the string to the length passed in by the callers, it
    uses the size of the device as the limit.

    Signed-off-by: Bernd Schmidt
    Signed-off-by: Mike Frysinger
    Signed-off-by: David Howells
    Signed-off-by: Linus Torvalds

    Bernd Schmidt
     

24 Sep, 2009

1 commit

  • romfs_iget returns an ERR_PTR value in an error case instead of NULL.

    A simplified version of the semantic match that finds this problem is as
    follows: (http://coccinelle.lip6.fr/)

    //
    @match exists@
    expression x, E;
    statement S1, S2;
    @@

    x = romfs_iget(...)
    ... when != x = E
    (
    * if (x == NULL || ...) S1 else S2
    |
    * if (x == NULL && ...) S1 else S2
    )
    //

    Signed-off-by: Julia Lawall
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Julia Lawall
     

22 Sep, 2009

1 commit


09 May, 2009

1 commit


25 Apr, 2009

2 commits


07 Apr, 2009

1 commit


24 Mar, 2009

2 commits

  • Fix the configuration of the RomFS to make sure that at least one
    backing store method is always selected. This is done by rendering it
    down to a choice item that selects between Block, MTD and both.

    This also works correctly in the case that CONFIG_MTD=m: MTD cannot be
    selected as a backing store unless CONFIG_ROMFS_FS is also 'm'.

    Signed-off-by: David Howells
    Signed-off-by: David Woodhouse

    David Howells
     
  • Change RomFS so that it can use MTD devices directly - without the intercession
    of the block layer - as well as using block devices.

    This permits RomFS:

    (1) to use the MTD direct mapping facility available under NOMMU conditions if
    the underlying device is directly accessible by the CPU (including XIP);

    (2) and thus to be used when the block layer is disabled.

    RomFS can be configured with support just for MTD devices, just for Block
    devices or for both. If RomFS is configured for both, then it will treat
    mtdblock device files as MTD backing stores, not block layer backing stores.

    I tested this using a CONFIG_MMU=n CONFIG_BLOCK=n kernel running on my FRV
    board with a RomFS image installed on the mtdram test device. I see my test
    program being run XIP:

    # cat /proc/maps
    ...
    c0c000b0-c0c01f8c r-xs 00000000 1f:00 144 /mnt/doshm
    ...

    GDB on the kernel can be used to show that these addresses are within the
    set-aside RAM space.

    Signed-off-by: David Howells
    Tested-by: Bernd Schmidt
    Signed-off-by: David Woodhouse

    David Howells
     

22 Jan, 2009

1 commit


09 Jan, 2009

1 commit


06 Jan, 2009

1 commit


31 Jul, 2008

1 commit

  • We zero-fill them like we are supposed to, and that's all fine. It's
    only an error if the 'romfs_copyfrom()' routine isn't able to fill the
    data that is supposed to be there.

    Most of the patch is really just re-organizing the code a bit, and using
    separate variables for the error value and for how much of the page we
    actually filled from the filesystem.

    Reported-and-tested-by: Chris Fester
    Cc: Alexander Viro
    Cc: Matt Waddel
    Cc: Greg Ungerer
    Signed-of-by: Linus Torvalds

    Linus Torvalds
     

27 Jul, 2008

1 commit

  • Kmem cache passed to constructor is only needed for constructors that are
    themselves multiplexeres. Nobody uses this "feature", nor does anybody uses
    passed kmem cache in non-trivial way, so pass only pointer to object.

    Non-trivial places are:
    arch/powerpc/mm/init_64.c
    arch/powerpc/mm/hugetlbpage.c

    This is flag day, yes.

    Signed-off-by: Alexey Dobriyan
    Acked-by: Pekka Enberg
    Acked-by: Christoph Lameter
    Cc: Jon Tollefson
    Cc: Nick Piggin
    Cc: Matt Mackall
    [akpm@linux-foundation.org: fix arch/powerpc/mm/hugetlbpage.c]
    [akpm@linux-foundation.org: fix mm/slab.c]
    [akpm@linux-foundation.org: fix ubifs]
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Alexey Dobriyan
     

20 Mar, 2008

1 commit

  • Fix up an error in iget removal in which romfs_lookup() making a successful
    call to romfs_iget() continues through the negative/error handling (previously
    the successful case jumped around the negative/error handling case):

    (1) inode is initialised to NULL at the top of the function, eliminating the
    need for specific negative-inode handling. This means the positive
    success handling now flows straight through.

    (2) Rename the labels to be clearer about what they mean.

    Also make romfs_lookup()'s result variable of type long so as to avoid
    32-bit/64-bit conversions with PTR_ERR() and friends.

    Based upon a report and patch from Adam Richter.

    Signed-off-by: David Howells
    Acked-by: "Adam J. Richter"
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    David Howells
     

08 Feb, 2008

1 commit

  • Stop the ROMFS filesystem from using iget() and read_inode(). Replace
    romfs_read_inode() with romfs_iget(), and call that instead of iget().
    romfs_iget() then uses iget_locked() directly and returns a proper error code
    instead of an inode in the event of an error.

    romfs_fill_super() returns any error incurred when getting the root inode
    instead of EINVAL.

    [akpm@linux-foundation.org: coding-style fixes]
    Signed-off-by: David Howells
    Acked-by: Christoph Hellwig
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    David Howells
     

17 Oct, 2007

2 commits

  • - There are no lists in fs/romfs/inode.c, so using list_entry
    is a bit confusing. Replace it with container_of.

    - It is unnecessary to cast the return value of
    kmem_cache_alloc, since it returns a void* pointer.

    Signed-off-by: WANG Cong
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    WANG Cong
     
  • Slab constructors currently have a flags parameter that is never used. And
    the order of the arguments is opposite to other slab functions. The object
    pointer is placed before the kmem_cache pointer.

    Convert

    ctor(void *object, struct kmem_cache *s, unsigned long flags)

    to

    ctor(struct kmem_cache *s, void *object)

    throughout the kernel

    [akpm@linux-foundation.org: coupla fixes]
    Signed-off-by: Christoph Lameter
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Lameter
     

20 Jul, 2007

1 commit

  • Slab destructors were no longer supported after Christoph's
    c59def9f222d44bb7e2f0a559f2906191a0862d7 change. They've been
    BUGs for both slab and slub, and slob never supported them
    either.

    This rips out support for the dtor pointer from kmem_cache_create()
    completely and fixes up every single callsite in the kernel (there were
    about 224, not including the slab allocator definitions themselves,
    or the documentation references).

    Signed-off-by: Paul Mundt

    Paul Mundt
     

17 May, 2007

1 commit

  • SLAB_CTOR_CONSTRUCTOR is always specified. No point in checking it.

    Signed-off-by: Christoph Lameter
    Cc: David Howells
    Cc: Jens Axboe
    Cc: Steven French
    Cc: Michael Halcrow
    Cc: OGAWA Hirofumi
    Cc: Miklos Szeredi
    Cc: Steven Whitehouse
    Cc: Roman Zippel
    Cc: David Woodhouse
    Cc: Dave Kleikamp
    Cc: Trond Myklebust
    Cc: "J. Bruce Fields"
    Cc: Anton Altaparmakov
    Cc: Mark Fasheh
    Cc: Paul Mackerras
    Cc: Christoph Hellwig
    Cc: Jan Kara
    Cc: David Chinner
    Cc: "David S. Miller"
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Lameter
     

08 May, 2007

1 commit

  • I have never seen a use of SLAB_DEBUG_INITIAL. It is only supported by
    SLAB.

    I think its purpose was to have a callback after an object has been freed
    to verify that the state is the constructor state again? The callback is
    performed before each freeing of an object.

    I would think that it is much easier to check the object state manually
    before the free. That also places the check near the code object
    manipulation of the object.

    Also the SLAB_DEBUG_INITIAL callback is only performed if the kernel was
    compiled with SLAB debugging on. If there would be code in a constructor
    handling SLAB_DEBUG_INITIAL then it would have to be conditional on
    SLAB_DEBUG otherwise it would just be dead code. But there is no such code
    in the kernel. I think SLUB_DEBUG_INITIAL is too problematic to make real
    use of, difficult to understand and there are easier ways to accomplish the
    same effect (i.e. add debug code before kfree).

    There is a related flag SLAB_CTOR_VERIFY that is frequently checked to be
    clear in fs inode caches. Remove the pointless checks (they would even be
    pointless without removeal of SLAB_DEBUG_INITIAL) from the fs constructors.

    This is the last slab flag that SLUB did not support. Remove the check for
    unimplemented flags from SLUB.

    Signed-off-by: Christoph Lameter
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Lameter
     

13 Feb, 2007

2 commits

  • This patch is inspired by Arjan's "Patch series to mark struct
    file_operations and struct inode_operations const".

    Compile tested with gcc & sparse.

    Signed-off-by: Josef 'Jeff' Sipek
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Josef 'Jeff' Sipek
     
  • Many struct inode_operations in the kernel can be "const". Marking them const
    moves these to the .rodata section, which avoids false sharing with potential
    dirty data. In addition it'll catch accidental writes at compile time to
    these shared resources.

    Signed-off-by: Arjan van de Ven
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Arjan van de Ven
     

09 Dec, 2006

1 commit


08 Dec, 2006

1 commit

  • Replace all uses of kmem_cache_t with struct kmem_cache.

    The patch was generated using the following script:

    #!/bin/sh
    #
    # Replace one string by another in all the kernel sources.
    #

    set -e

    for file in `find * -name "*.c" -o -name "*.h"|xargs grep -l $1`; do
    quilt add $file
    sed -e "1,\$s/$1/$2/g" $file >/tmp/$$
    mv /tmp/$$ $file
    quilt refresh
    done

    The script was run like this

    sh replace kmem_cache_t "struct kmem_cache"

    Signed-off-by: Christoph Lameter
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Lameter