Commit 5b1b229f authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] random fixes

- I changed the sector_t thing in max_block to use davem's approach.
  I agree with Anton, but making it explicit doesn't hurt.

- Remove a dead comment in copy_strings.

Old stuff:

- Remove the IO error warning in end_buffer_io_sync().  Failed READA
  attempts trigger it.

- Emit a warning when an ext2 is mounting an ext3 filesystem.

  We have had quite a few problem reports related to this, mainly
  arising from initrd problems.  And mount(8) tends to report the
  fstype from /etc/fstab rather than reporting what has really
  happened.

Fixes some bogosity which I added to max_block():

- `size' doesn't need to be sector_t

- `retval' should not be initialised to "~0UL" because that is
  0x00000000ffffffff with 64-bit sector_t.

- Allocate task_structs with GFP_KERNEL, as discussed.

- Convert the EXPORT_SYMBOL for generic_file_direct_IO() to
  EXPORT_SYMBOL_GPL.  That was only exported as a practicality for the
  raw driver.

- Make the loop thread run balance_dirty_pages() after dirtying the
  backing file.  So it will perform writeback of the backing file when
  dirty memory levels are high.  Export balance_dirty_pages to GPL
  modules for this.

  This makes loop work a lot better - I suspect it broke when callers
  of balance_dirty_pages() started writing back only their own queue.

  There are many page allocation failures under heavy loop writeout.
  Coming from blk_queue_bounce()'s allocation from the page_pool
  mempool.  So...

- Disable page allocation warnings around the initial atomic
  allocation attempt in mempool_alloc() - the one where __GFP_WAIT and
  __GFP_IO were turned off.  That one can easily fail.

- Add some commentary in block_write_full_page()
parent 5803a3a6
...@@ -74,6 +74,7 @@ ...@@ -74,6 +74,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/loop.h> #include <linux/loop.h>
#include <linux/suspend.h> #include <linux/suspend.h>
#include <linux/writeback.h>
#include <linux/buffer_head.h> /* for invalidate_bdev() */ #include <linux/buffer_head.h> /* for invalidate_bdev() */
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -235,6 +236,7 @@ do_lo_send(struct loop_device *lo, struct bio_vec *bvec, int bsize, loff_t pos) ...@@ -235,6 +236,7 @@ do_lo_send(struct loop_device *lo, struct bio_vec *bvec, int bsize, loff_t pos)
up(&mapping->host->i_sem); up(&mapping->host->i_sem);
out: out:
kunmap(bvec->bv_page); kunmap(bvec->bv_page);
balance_dirty_pages(mapping);
return ret; return ret;
unlock: unlock:
......
...@@ -26,12 +26,12 @@ ...@@ -26,12 +26,12 @@
static sector_t max_block(struct block_device *bdev) static sector_t max_block(struct block_device *bdev)
{ {
sector_t retval = ~0U; sector_t retval = ~((sector_t)0);
loff_t sz = bdev->bd_inode->i_size; loff_t sz = bdev->bd_inode->i_size;
if (sz) { if (sz) {
sector_t size = block_size(bdev); unsigned int size = block_size(bdev);
unsigned sizebits = blksize_bits(size); unsigned int sizebits = blksize_bits(size);
retval = (sz >> sizebits); retval = (sz >> sizebits);
} }
return retval; return retval;
......
...@@ -180,7 +180,10 @@ void end_buffer_io_sync(struct buffer_head *bh, int uptodate) ...@@ -180,7 +180,10 @@ void end_buffer_io_sync(struct buffer_head *bh, int uptodate)
if (uptodate) { if (uptodate) {
set_buffer_uptodate(bh); set_buffer_uptodate(bh);
} else { } else {
buffer_io_error(bh); /*
* This happens, due to failed READA attempts.
* buffer_io_error(bh);
*/
clear_buffer_uptodate(bh); clear_buffer_uptodate(bh);
} }
unlock_buffer(bh); unlock_buffer(bh);
...@@ -2307,7 +2310,13 @@ int block_write_full_page(struct page *page, get_block_t *get_block) ...@@ -2307,7 +2310,13 @@ int block_write_full_page(struct page *page, get_block_t *get_block)
return -EIO; return -EIO;
} }
/* The page straddles i_size */ /*
* The page straddles i_size. It must be zeroed out on each and every
* writepage invokation because it may be mmapped. "A file is mapped
* in multiples of the page size. For a file that is not a multiple of
* the page size, the remaining memory is zeroed when mapped, and
* writes to that region are not written out to the file."
*/
kaddr = kmap(page); kaddr = kmap(page);
memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset); memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset);
flush_dcache_page(page); flush_dcache_page(page);
......
...@@ -209,11 +209,6 @@ int copy_strings(int argc,char ** argv, struct linux_binprm *bprm) ...@@ -209,11 +209,6 @@ int copy_strings(int argc,char ** argv, struct linux_binprm *bprm)
/* XXX: add architecture specific overflow check here. */ /* XXX: add architecture specific overflow check here. */
pos = bprm->p; pos = bprm->p;
/*
* The only sleeping function which we are allowed to call in
* this loop is copy_from_user(). Otherwise, copy_user_state
* could get trashed.
*/
while (len > 0) { while (len > 0) {
int i, new, err; int i, new, err;
int offset, bytes_to_copy; int offset, bytes_to_copy;
......
...@@ -698,6 +698,9 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) ...@@ -698,6 +698,9 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
printk(KERN_ERR "EXT2-fs: get root inode failed\n"); printk(KERN_ERR "EXT2-fs: get root inode failed\n");
goto failed_mount2; goto failed_mount2;
} }
if (EXT2_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL))
ext2_warning(sb, __FUNCTION__,
"mounting ext3 filesystem as ext2\n");
ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY); ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY);
return 0; return 0;
failed_mount2: failed_mount2:
......
...@@ -131,9 +131,10 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) ...@@ -131,9 +131,10 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
struct thread_info *ti; struct thread_info *ti;
ti = alloc_thread_info(); ti = alloc_thread_info();
if (!ti) return NULL; if (!ti)
return NULL;
tsk = kmem_cache_alloc(task_struct_cachep,GFP_ATOMIC); tsk = kmem_cache_alloc(task_struct_cachep, GFP_KERNEL);
if (!tsk) { if (!tsk) {
free_thread_info(ti); free_thread_info(ti);
return NULL; return NULL;
......
...@@ -344,7 +344,7 @@ EXPORT_SYMBOL(register_disk); ...@@ -344,7 +344,7 @@ EXPORT_SYMBOL(register_disk);
EXPORT_SYMBOL(read_dev_sector); EXPORT_SYMBOL(read_dev_sector);
EXPORT_SYMBOL(init_buffer); EXPORT_SYMBOL(init_buffer);
EXPORT_SYMBOL(wipe_partitions); EXPORT_SYMBOL(wipe_partitions);
EXPORT_SYMBOL(generic_file_direct_IO); EXPORT_SYMBOL_GPL(generic_file_direct_IO);
/* tty routines */ /* tty routines */
EXPORT_SYMBOL(tty_hangup); EXPORT_SYMBOL(tty_hangup);
......
...@@ -189,7 +189,9 @@ void * mempool_alloc(mempool_t *pool, int gfp_mask) ...@@ -189,7 +189,9 @@ void * mempool_alloc(mempool_t *pool, int gfp_mask)
int gfp_nowait = gfp_mask & ~(__GFP_WAIT | __GFP_IO); int gfp_nowait = gfp_mask & ~(__GFP_WAIT | __GFP_IO);
repeat_alloc: repeat_alloc:
current->flags |= PF_NOWARN;
element = pool->alloc(gfp_nowait, pool->pool_data); element = pool->alloc(gfp_nowait, pool->pool_data);
current->flags &= ~PF_NOWARN;
if (likely(element != NULL)) if (likely(element != NULL))
return element; return element;
......
...@@ -136,6 +136,7 @@ void balance_dirty_pages(struct address_space *mapping) ...@@ -136,6 +136,7 @@ void balance_dirty_pages(struct address_space *mapping)
if (!writeback_in_progress(bdi) && ps.nr_dirty > background_thresh) if (!writeback_in_progress(bdi) && ps.nr_dirty > background_thresh)
pdflush_operation(background_writeout, 0); pdflush_operation(background_writeout, 0);
} }
EXPORT_SYMBOL_GPL(balance_dirty_pages);
/** /**
* balance_dirty_pages_ratelimited - balance dirty memory state * balance_dirty_pages_ratelimited - balance dirty memory state
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment