From: Matt Mackall <mpm@selenic.com>
To: Andrew Morton <akpm@digeo.com>
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH] write errors [2/3] flags
Date: Thu, 29 May 2003 14:44:10 -0500 [thread overview]
Message-ID: <20030529194410.GZ23715@waste.org> (raw)
In-Reply-To: <20030529194232.GY23715@waste.org>
Combine mapping->error and ->gfp_mask into ->flags
diff -urN -x genksyms -x '*.ver' -x '.patch*' -x '*.orig' orig/drivers/block/loop.c patched/drivers/block/loop.c
--- orig/drivers/block/loop.c 2003-05-29 12:49:24.000000000 -0500
+++ patched/drivers/block/loop.c 2003-05-29 12:52:28.000000000 -0500
@@ -714,8 +714,8 @@
fput(file);
goto out_putf;
}
- lo->old_gfp_mask = inode->i_mapping->gfp_mask;
- inode->i_mapping->gfp_mask = GFP_NOIO;
+ lo->old_gfp_mask = mapping_gfp_mask(inode->i_mapping);
+ mapping_set_gfp_mask(inode->i_mapping, GFP_NOIO);
set_blocksize(bdev, lo_blocksize);
@@ -823,7 +823,7 @@
memset(lo->lo_name, 0, LO_NAME_SIZE);
invalidate_bdev(bdev, 0);
set_capacity(disks[lo->lo_number], 0);
- filp->f_dentry->d_inode->i_mapping->gfp_mask = gfp;
+ mapping_set_gfp_mask(filp->f_dentry->d_inode->i_mapping, gfp);
lo->lo_state = Lo_unbound;
fput(filp);
/* This is safe: open() is still holding a reference. */
diff -urN -x genksyms -x '*.ver' -x '.patch*' -x '*.orig' orig/fs/block_dev.c patched/fs/block_dev.c
--- orig/fs/block_dev.c 2003-05-29 12:49:42.000000000 -0500
+++ patched/fs/block_dev.c 2003-05-29 12:52:28.000000000 -0500
@@ -318,7 +318,7 @@
inode->i_rdev = kdev;
inode->i_bdev = new_bdev;
inode->i_data.a_ops = &def_blk_aops;
- inode->i_data.gfp_mask = GFP_USER;
+ mapping_set_gfp_mask(&inode->i_data, GFP_USER);
inode->i_data.backing_dev_info = &default_backing_dev_info;
spin_lock(&bdev_lock);
bdev = bdfind(dev, head);
diff -urN -x genksyms -x '*.ver' -x '.patch*' -x '*.orig' orig/fs/buffer.c patched/fs/buffer.c
--- orig/fs/buffer.c 2003-05-29 12:52:33.000000000 -0500
+++ patched/fs/buffer.c 2003-05-29 12:52:28.000000000 -0500
@@ -600,7 +600,7 @@
buffer_io_error(bh);
printk(KERN_WARNING "lost page write due to I/O error on %s\n",
bdevname(bh->b_bdev, b));
- page->mapping->error = -EIO;
+ set_bit(AS_EIO, &page->mapping->flags);
clear_buffer_uptodate(bh);
SetPageError(page);
}
@@ -2846,7 +2846,7 @@
do {
check_ttfb_buffer(page, bh);
if (buffer_write_io_error(bh))
- page->mapping->error = -EIO;
+ set_bit(AS_EIO, &page->mapping->flags);
if (buffer_busy(bh))
goto failed;
if (!buffer_uptodate(bh) && !buffer_req(bh))
diff -urN -x genksyms -x '*.ver' -x '.patch*' -x '*.orig' orig/fs/inode.c patched/fs/inode.c
--- orig/fs/inode.c 2003-05-29 12:52:33.000000000 -0500
+++ patched/fs/inode.c 2003-05-29 12:53:07.000000000 -0500
@@ -18,6 +18,7 @@
#include <linux/hash.h>
#include <linux/swap.h>
#include <linux/security.h>
+#include <linux/pagemap.h>
#include <linux/cdev.h>
/*
@@ -142,11 +143,11 @@
mapping->a_ops = &empty_aops;
mapping->host = inode;
- mapping->gfp_mask = GFP_HIGHUSER;
+ mapping->flags = 0;
+ mapping_set_gfp_mask(mapping, GFP_HIGHUSER);
mapping->dirtied_when = 0;
mapping->assoc_mapping = NULL;
mapping->backing_dev_info = &default_backing_dev_info;
- mapping->error = 0;
if (sb->s_bdev)
mapping->backing_dev_info = sb->s_bdev->bd_inode->i_mapping->backing_dev_info;
memset(&inode->u, 0, sizeof(inode->u));
diff -urN -x genksyms -x '*.ver' -x '.patch*' -x '*.orig' orig/fs/jfs/inode.c patched/fs/jfs/inode.c
--- orig/fs/jfs/inode.c 2003-04-19 21:48:46.000000000 -0500
+++ patched/fs/jfs/inode.c 2003-05-29 12:52:28.000000000 -0500
@@ -20,6 +20,7 @@
#include <linux/fs.h>
#include <linux/mpage.h>
#include <linux/buffer_head.h>
+#include <linux/pagemap.h>
#include "jfs_incore.h"
#include "jfs_filsys.h"
#include "jfs_imap.h"
@@ -57,7 +58,7 @@
inode->i_op = &jfs_dir_inode_operations;
inode->i_fop = &jfs_dir_operations;
inode->i_mapping->a_ops = &jfs_aops;
- inode->i_mapping->gfp_mask = GFP_NOFS;
+ mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
} else if (S_ISLNK(inode->i_mode)) {
if (inode->i_size >= IDATASIZE) {
inode->i_op = &page_symlink_inode_operations;
diff -urN -x genksyms -x '*.ver' -x '.patch*' -x '*.orig' orig/fs/jfs/jfs_imap.c patched/fs/jfs/jfs_imap.c
--- orig/fs/jfs/jfs_imap.c 2003-04-19 21:48:53.000000000 -0500
+++ patched/fs/jfs/jfs_imap.c 2003-05-29 12:52:28.000000000 -0500
@@ -43,6 +43,7 @@
#include <linux/fs.h>
#include <linux/buffer_head.h>
+#include <linux/pagemap.h>
#include "jfs_incore.h"
#include "jfs_filsys.h"
@@ -504,7 +505,7 @@
}
ip->i_mapping->a_ops = &jfs_aops;
- ip->i_mapping->gfp_mask = GFP_NOFS;
+ mapping_set_gfp_mask(ip->i_mapping, GFP_NOFS);
if ((inum == FILESYSTEM_I) && (JFS_IP(ip)->ipimap == sbi->ipaimap)) {
sbi->gengen = le32_to_cpu(dp->di_gengen);
diff -urN -x genksyms -x '*.ver' -x '.patch*' -x '*.orig' orig/fs/jfs/namei.c patched/fs/jfs/namei.c
--- orig/fs/jfs/namei.c 2003-04-19 21:50:35.000000000 -0500
+++ patched/fs/jfs/namei.c 2003-05-29 12:52:28.000000000 -0500
@@ -257,7 +257,7 @@
ip->i_op = &jfs_dir_inode_operations;
ip->i_fop = &jfs_dir_operations;
ip->i_mapping->a_ops = &jfs_aops;
- ip->i_mapping->gfp_mask = GFP_NOFS;
+ mapping_set_gfp_mask(ip->i_mapping, GFP_NOFS);
insert_inode_hash(ip);
mark_inode_dirty(ip);
diff -urN -x genksyms -x '*.ver' -x '.patch*' -x '*.orig' orig/fs/mpage.c patched/fs/mpage.c
--- orig/fs/mpage.c 2003-05-29 12:52:33.000000000 -0500
+++ patched/fs/mpage.c 2003-05-29 12:52:28.000000000 -0500
@@ -570,8 +570,12 @@
* mapping.
*/
lock_page(page);
- if (page->mapping == mapping)
- mapping->error = *ret;
+ if (page->mapping == mapping) {
+ if (*ret == -EIO)
+ set_bit(AS_EIO, &mapping->flags);
+ else if (*ret == -ENOSPC)
+ set_bit(AS_ENOSPC, &mapping->flags);
+ }
unlock_page(page);
}
out:
@@ -684,8 +688,12 @@
* mapping.
*/
lock_page(page);
- if (page->mapping == mapping)
- mapping->error = ret;
+ if (page->mapping == mapping) {
+ if (ret == -EIO)
+ set_bit(AS_EIO, &mapping->flags);
+ else if (ret == -ENOSPC)
+ set_bit(AS_ENOSPC, &mapping->flags);
+ }
unlock_page(page);
}
} else {
diff -urN -x genksyms -x '*.ver' -x '.patch*' -x '*.orig' orig/fs/open.c patched/fs/open.c
--- orig/fs/open.c 2003-05-29 12:52:33.000000000 -0500
+++ patched/fs/open.c 2003-05-29 12:52:28.000000000 -0500
@@ -20,6 +20,7 @@
#include <linux/mount.h>
#include <linux/vfs.h>
#include <asm/uaccess.h>
+#include <linux/pagemap.h>
#define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
@@ -852,11 +853,10 @@
retval = err;
}
- err = mapping->error;
- if (err && !retval) {
- mapping->error = 0;
- retval = err;
- }
+ if (test_and_clear_bit(AS_ENOSPC, &mapping->flags))
+ retval = -ENOSPC;
+ if (test_and_clear_bit(AS_EIO, &mapping->flags))
+ retval = -EIO;
if (!file_count(filp)) {
printk(KERN_ERR "VFS: Close: file count is 0\n");
diff -urN -x genksyms -x '*.ver' -x '.patch*' -x '*.orig' orig/include/linux/fs.h patched/include/linux/fs.h
--- orig/include/linux/fs.h 2003-05-29 12:52:33.000000000 -0500
+++ patched/include/linux/fs.h 2003-05-29 12:52:28.000000000 -0500
@@ -324,12 +324,11 @@
struct list_head i_mmap_shared; /* list of shared mappings */
struct semaphore i_shared_sem; /* protect both above lists */
unsigned long dirtied_when; /* jiffies of first page dirtying */
- int gfp_mask; /* how to allocate the pages */
+ unsigned long flags; /* error bits/gfp mask */
struct backing_dev_info *backing_dev_info; /* device readahead, etc */
spinlock_t private_lock; /* for use by the address_space */
struct list_head private_list; /* ditto */
struct address_space *assoc_mapping; /* ditto */
- int error; /* write error for fsync */
};
struct block_device {
diff -urN -x genksyms -x '*.ver' -x '.patch*' -x '*.orig' orig/include/linux/gfp.h patched/include/linux/gfp.h
--- orig/include/linux/gfp.h 2003-05-12 14:34:35.000000000 -0500
+++ patched/include/linux/gfp.h 2003-05-29 12:52:28.000000000 -0500
@@ -33,6 +33,9 @@
#define __GFP_NORETRY 0x1000 /* Do not retry. Might fail */
#define __GFP_NO_GROW 0x2000 /* Slab internal usage */
+#define __GFP_BITS_SHIFT 16 /* Room for 16 __GFP_FOO bits */
+#define __GFP_BITS_MASK ((1 << __GFP_BITS_SHIFT) - 1)
+
#define GFP_ATOMIC (__GFP_HIGH)
#define GFP_NOIO (__GFP_WAIT)
#define GFP_NOFS (__GFP_WAIT | __GFP_IO)
diff -urN -x genksyms -x '*.ver' -x '.patch*' -x '*.orig' orig/include/linux/pagemap.h patched/include/linux/pagemap.h
--- orig/include/linux/pagemap.h 2003-05-29 12:52:33.000000000 -0500
+++ patched/include/linux/pagemap.h 2003-05-29 12:52:28.000000000 -0500
@@ -8,7 +8,30 @@
#include <linux/fs.h>
#include <linux/list.h>
#include <linux/highmem.h>
+#include <linux/pagemap.h>
#include <asm/uaccess.h>
+#include <linux/gfp.h>
+
+/*
+ * Bits in mapping->flags. The lower __GFP_BITS_SHIFT bits are the page
+ * allocation mode flags.
+ */
+#define AS_EIO (__GFP_BITS_SHIFT + 0) /* IO error on async write */
+#define AS_ENOSPC (__GFP_BITS_SHIFT + 1) /* ENOSPC on async write */
+
+static inline int mapping_gfp_mask(struct address_space * mapping)
+{
+ return mapping->flags & __GFP_BITS_MASK;
+}
+
+/*
+ * This is non-atomic. Only to be used before the mapping is activated.
+ * Probably needs a barrier...
+ */
+static inline void mapping_set_gfp_mask(struct address_space *m, int mask)
+{
+ m->flags = (m->flags & ~__GFP_BITS_MASK) | mask;
+}
/*
* The page cache can done in larger chunks than
@@ -29,12 +52,12 @@
static inline struct page *page_cache_alloc(struct address_space *x)
{
- return alloc_pages(x->gfp_mask, 0);
+ return alloc_pages(mapping_gfp_mask(x), 0);
}
static inline struct page *page_cache_alloc_cold(struct address_space *x)
{
- return alloc_pages(x->gfp_mask|__GFP_COLD, 0);
+ return alloc_pages(mapping_gfp_mask(x)|__GFP_COLD, 0);
}
typedef int filler_t(void *, struct page *);
@@ -56,7 +79,7 @@
*/
static inline struct page *grab_cache_page(struct address_space *mapping, unsigned long index)
{
- return find_or_create_page(mapping, index, mapping->gfp_mask);
+ return find_or_create_page(mapping, index, mapping_gfp_mask(mapping));
}
extern struct page * grab_cache_page_nowait(struct address_space *mapping,
diff -urN -x genksyms -x '*.ver' -x '.patch*' -x '*.orig' orig/mm/filemap.c patched/mm/filemap.c
--- orig/mm/filemap.c 2003-05-29 12:52:33.000000000 -0500
+++ patched/mm/filemap.c 2003-05-29 12:52:28.000000000 -0500
@@ -201,11 +201,10 @@
spin_unlock(&mapping->page_lock);
/* Check for outstanding write errors */
- if (mapping->error)
- {
- ret = mapping->error;
- mapping->error = 0;
- }
+ if (test_and_clear_bit(AS_ENOSPC, &mapping->flags))
+ ret = -ENOSPC;
+ if (test_and_clear_bit(AS_EIO, &mapping->flags))
+ ret = -EIO;
return ret;
}
@@ -591,7 +590,7 @@
page_cache_release(page);
return NULL;
}
- gfp_mask = mapping->gfp_mask & ~__GFP_FS;
+ gfp_mask = mapping_gfp_mask(mapping) & ~__GFP_FS;
page = alloc_pages(gfp_mask, 0);
if (page && add_to_page_cache_lru(page, mapping, index, gfp_mask)) {
page_cache_release(page);
diff -urN -x genksyms -x '*.ver' -x '.patch*' -x '*.orig' orig/mm/shmem.c patched/mm/shmem.c
--- orig/mm/shmem.c 2003-05-29 12:49:55.000000000 -0500
+++ patched/mm/shmem.c 2003-05-29 12:52:28.000000000 -0500
@@ -318,7 +318,7 @@
spin_unlock(&sbinfo->stat_lock);
spin_unlock(&info->lock);
- page = shmem_dir_alloc(inode->i_mapping->gfp_mask);
+ page = shmem_dir_alloc(mapping_gfp_mask(inode->i_mapping));
if (page) {
clear_highpage(page);
page->nr_swapped = 0;
diff -urN -x genksyms -x '*.ver' -x '.patch*' -x '*.orig' orig/mm/vmscan.c patched/mm/vmscan.c
--- orig/mm/vmscan.c 2003-05-29 12:52:34.000000000 -0500
+++ patched/mm/vmscan.c 2003-05-29 12:52:28.000000000 -0500
@@ -347,13 +347,14 @@
* mapping.
*/
lock_page(page);
- if (page->mapping == mapping)
- mapping->error = res;
+ if (page->mapping == mapping) {
+ if (res == -EIO)
+ set_bit(AS_EIO, &mapping->flags);
+ else if (res == -ENOSPC)
+ set_bit(AS_ENOSPC, &mapping->flags);
+ }
unlock_page(page);
}
- if (res < 0) {
- mapping->error = res;
- }
if (res == WRITEPAGE_ACTIVATE) {
ClearPageReclaim(page);
goto activate_locked;
--
Matt Mackall : http://www.selenic.com : of or relating to the moon
next prev parent reply other threads:[~2003-05-29 19:31 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-05-14 10:27 2.6 must-fix list, v3 Andrew Morton
2003-05-14 10:27 ` Andrew Morton
2003-05-14 10:28 ` Jens Axboe
2003-05-14 16:41 ` Tom Rini
2003-05-14 16:57 ` Greg KH
2003-05-14 17:10 ` Matt Mackall
2003-05-14 17:44 ` Andrew Morton
2003-05-29 19:42 ` [PATCH] write errors [1/3] async-write-errors Matt Mackall
2003-05-29 19:44 ` Matt Mackall [this message]
2003-05-29 19:45 ` [PATCH] write errors [3/3] fs-writepage-truncate Matt Mackall
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20030529194410.GZ23715@waste.org \
--to=mpm@selenic.com \
--cc=akpm@digeo.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.