diff options
| author | Andrew Morton <akpm@osdl.org> | 2003-08-18 18:32:54 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.osdl.org> | 2003-08-18 18:32:54 -0700 |
| commit | fcad2b42fc2e15a94ba1a1ba8535681a735bfd16 (patch) | |
| tree | fc973782eac7c4c1ea377831c499c0a3492b0656 /include/linux | |
| parent | fe7e689f489459a99e9f66f9f0a81aa62491b646 (diff) | |
[PATCH] async write errors: use flags in address space
From: Oliver Xymoron <oxymoron@waste.org>
This patch just saves a few bytes in the inode by turning mapping->gfp_mask
into an unsigned long mapping->flags.
The mapping's gfp mask is placed in the 16 high bits of mapping->flags and
two of the remaining 16 bits are used for tracking EIO and ENOSPC errors.
This leaves 14 bits in the mapping for future use. They should be accessed
with the atomic bitops.
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/fs.h | 3 | ||||
| -rw-r--r-- | include/linux/gfp.h | 3 | ||||
| -rw-r--r-- | include/linux/pagemap.h | 29 |
3 files changed, 30 insertions, 5 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h index 3d97b77c5bc6..8df205c7ba14 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -327,12 +327,11 @@ struct address_space { struct semaphore i_shared_sem; /* protect both above lists */ atomic_t truncate_count; /* Cover race condition with truncate */ 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 --git a/include/linux/gfp.h b/include/linux/gfp.h index aa3705a9a21e..c9695427a435 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -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 --git a/include/linux/pagemap.h b/include/linux/pagemap.h index c1edd5e720e1..8fc118dc90cc 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -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 @@ void release_pages(struct page **pages, int nr, int cold); 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 @@ extern unsigned int find_get_pages(struct address_space *mapping, */ 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, |
