ChangeSet 1.2227, 2005/03/31 08:27:05-08:00, [EMAIL PROTECTED]

        [PATCH] BDI: Provide backing device capability information [try #3]
        
        The attached patch replaces backing_dev_info::memory_backed with 
capabilitied
        bitmap. The capabilities available include:
        
          (*) BDI_CAP_NO_ACCT_DIRTY
        
              Set if the pages associated with this backing device should not be
              tracked by the dirty page accounting.
        
          (*) BDI_CAP_NO_WRITEBACK
        
              Set if dirty pages associated with this backing device should not 
have
              writepage() or writepages() invoked upon them to clean them.
        
          (*) Capability markers that indicate what a backing device is capable 
of
              with regard to memory mapping facilities. These flags indicate 
whether a
              device can be mapped directly, whether it can be copied for a 
mapping,
              and whether direct mappings can be read, written and/or executed. 
This
              information is primarily aimed at improving no-MMU private mapping
              support.
        
        The patch also provides convenience functions for determining the 
dirty-page
        capabilities available on backing devices directly or on the backing 
devices
        associated with a mapping. These are provided to keep line length down 
when
        checking for the capabilities.
        
        Signed-Off-By: David Howells <[EMAIL PROTECTED]>
        Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
        Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>



 drivers/block/ll_rw_blk.c   |    2 +-
 drivers/block/rd.c          |    4 ++--
 drivers/char/mem.c          |    6 ++++++
 fs/buffer.c                 |    2 +-
 fs/fs-writeback.c           |    4 ++--
 fs/hugetlbfs/inode.c        |    2 +-
 fs/ramfs/inode.c            |    4 +++-
 fs/sysfs/inode.c            |    2 +-
 include/linux/backing-dev.h |   41 ++++++++++++++++++++++++++++++++++++++++-
 kernel/cpuset.c             |    2 +-
 mm/filemap.c                |    6 +++---
 mm/page-writeback.c         |    6 +++---
 mm/readahead.c              |    1 +
 mm/shmem.c                  |    4 ++--
 mm/swap_state.c             |    2 +-
 15 files changed, 68 insertions(+), 20 deletions(-)


diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c 2005-03-31 10:09:21 -08:00
+++ b/drivers/block/ll_rw_blk.c 2005-03-31 10:09:21 -08:00
@@ -238,7 +238,7 @@
        q->make_request_fn = mfn;
        q->backing_dev_info.ra_pages = (VM_MAX_READAHEAD * 1024) / 
PAGE_CACHE_SIZE;
        q->backing_dev_info.state = 0;
-       q->backing_dev_info.memory_backed = 0;
+       q->backing_dev_info.capabilities = BDI_CAP_MAP_COPY;
        blk_queue_max_sectors(q, MAX_SECTORS);
        blk_queue_hardsect_size(q, 512);
        blk_queue_dma_alignment(q, 511);
diff -Nru a/drivers/block/rd.c b/drivers/block/rd.c
--- a/drivers/block/rd.c        2005-03-31 10:09:21 -08:00
+++ b/drivers/block/rd.c        2005-03-31 10:09:21 -08:00
@@ -325,7 +325,7 @@
  */
 static struct backing_dev_info rd_backing_dev_info = {
        .ra_pages       = 0,    /* No readahead */
-       .memory_backed  = 1,    /* Does not contribute to dirty memory */
+       .capabilities   = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK | 
BDI_CAP_MAP_COPY,
        .unplug_io_fn   = default_unplug_io_fn,
 };
 
@@ -336,7 +336,7 @@
  */
 static struct backing_dev_info rd_file_backing_dev_info = {
        .ra_pages       = 0,    /* No readahead */
-       .memory_backed  = 0,    /* Does contribute to dirty memory */
+       .capabilities   = BDI_CAP_MAP_COPY,     /* Does contribute to dirty 
memory */
        .unplug_io_fn   = default_unplug_io_fn,
 };
 
diff -Nru a/drivers/char/mem.c b/drivers/char/mem.c
--- a/drivers/char/mem.c        2005-03-31 10:09:21 -08:00
+++ b/drivers/char/mem.c        2005-03-31 10:09:21 -08:00
@@ -23,6 +23,7 @@
 #include <linux/devfs_fs_kernel.h>
 #include <linux/ptrace.h>
 #include <linux/device.h>
+#include <linux/backing-dev.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -758,6 +759,10 @@
        .mmap           = mmap_zero,
 };
 
+static struct backing_dev_info zero_bdi = {
+       .capabilities   = BDI_CAP_MAP_COPY,
+};
+
 static struct file_operations full_fops = {
        .llseek         = full_lseek,
        .read           = read_full,
@@ -804,6 +809,7 @@
                        break;
 #endif
                case 5:
+                       filp->f_mapping->backing_dev_info = &zero_bdi;
                        filp->f_op = &zero_fops;
                        break;
                case 7:
diff -Nru a/fs/buffer.c b/fs/buffer.c
--- a/fs/buffer.c       2005-03-31 10:09:21 -08:00
+++ b/fs/buffer.c       2005-03-31 10:09:21 -08:00
@@ -878,7 +878,7 @@
        if (!TestSetPageDirty(page)) {
                write_lock_irq(&mapping->tree_lock);
                if (page->mapping) {    /* Race with truncate? */
-                       if (!mapping->backing_dev_info->memory_backed)
+                       if (mapping_cap_account_dirty(mapping))
                                inc_page_state(nr_dirty);
                        radix_tree_tag_set(&mapping->page_tree,
                                                page_index(page),
diff -Nru a/fs/fs-writeback.c b/fs/fs-writeback.c
--- a/fs/fs-writeback.c 2005-03-31 10:09:21 -08:00
+++ b/fs/fs-writeback.c 2005-03-31 10:09:21 -08:00
@@ -315,7 +315,7 @@
                struct backing_dev_info *bdi = mapping->backing_dev_info;
                long pages_skipped;
 
-               if (bdi->memory_backed) {
+               if (!bdi_cap_writeback_dirty(bdi)) {
                        list_move(&inode->i_list, &sb->s_dirty);
                        if (sb == blockdev_superblock) {
                                /*
@@ -566,7 +566,7 @@
                .sync_mode = WB_SYNC_ALL,
        };
 
-       if (inode->i_mapping->backing_dev_info->memory_backed)
+       if (!mapping_cap_writeback_dirty(inode->i_mapping))
                return 0;
 
        might_sleep();
diff -Nru a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
--- a/fs/hugetlbfs/inode.c      2005-03-31 10:09:21 -08:00
+++ b/fs/hugetlbfs/inode.c      2005-03-31 10:09:21 -08:00
@@ -40,7 +40,7 @@
 
 static struct backing_dev_info hugetlbfs_backing_dev_info = {
        .ra_pages       = 0,    /* No readahead */
-       .memory_backed  = 1,    /* Does not contribute to dirty memory */
+       .capabilities   = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
 };
 
 int sysctl_hugetlb_shm_group;
diff -Nru a/fs/ramfs/inode.c b/fs/ramfs/inode.c
--- a/fs/ramfs/inode.c  2005-03-31 10:09:21 -08:00
+++ b/fs/ramfs/inode.c  2005-03-31 10:09:21 -08:00
@@ -45,7 +45,9 @@
 
 static struct backing_dev_info ramfs_backing_dev_info = {
        .ra_pages       = 0,    /* No readahead */
-       .memory_backed  = 1,    /* Does not contribute to dirty memory */
+       .capabilities   = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK |
+                         BDI_CAP_MAP_DIRECT | BDI_CAP_MAP_COPY |
+                         BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | 
BDI_CAP_EXEC_MAP,
 };
 
 struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev)
diff -Nru a/fs/sysfs/inode.c b/fs/sysfs/inode.c
--- a/fs/sysfs/inode.c  2005-03-31 10:09:21 -08:00
+++ b/fs/sysfs/inode.c  2005-03-31 10:09:21 -08:00
@@ -23,7 +23,7 @@
 
 static struct backing_dev_info sysfs_backing_dev_info = {
        .ra_pages       = 0,    /* No readahead */
-       .memory_backed  = 1,    /* Does not contribute to dirty memory */
+       .capabilities   = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
 };
 
 struct inode * sysfs_new_inode(mode_t mode)
diff -Nru a/include/linux/backing-dev.h b/include/linux/backing-dev.h
--- a/include/linux/backing-dev.h       2005-03-31 10:09:21 -08:00
+++ b/include/linux/backing-dev.h       2005-03-31 10:09:21 -08:00
@@ -25,13 +25,39 @@
 struct backing_dev_info {
        unsigned long ra_pages; /* max readahead in PAGE_CACHE_SIZE units */
        unsigned long state;    /* Always use atomic bitops on this */
-       int memory_backed;      /* Cannot clean pages with writepage */
+       unsigned int capabilities; /* Device capabilities */
        congested_fn *congested_fn; /* Function pointer if device is md/dm */
        void *congested_data;   /* Pointer to aux data for congested func */
        void (*unplug_io_fn)(struct backing_dev_info *, struct page *);
        void *unplug_io_data;
 };
 
+
+/*
+ * Flags in backing_dev_info::capability
+ * - The first two flags control whether dirty pages will contribute to the
+ *   VM's accounting and whether writepages() should be called for dirty pages
+ *   (something that would not, for example, be appropriate for ramfs)
+ * - These flags let !MMU mmap() govern direct device mapping vs immediate
+ *   copying more easily for MAP_PRIVATE, especially for ROM filesystems
+ */
+#define BDI_CAP_NO_ACCT_DIRTY  0x00000001      /* Dirty pages shouldn't 
contribute to accounting */
+#define BDI_CAP_NO_WRITEBACK   0x00000002      /* Don't write pages back */
+#define BDI_CAP_MAP_COPY       0x00000004      /* Copy can be mapped 
(MAP_PRIVATE) */
+#define BDI_CAP_MAP_DIRECT     0x00000008      /* Can be mapped directly 
(MAP_SHARED) */
+#define BDI_CAP_READ_MAP       0x00000010      /* Can be mapped for reading */
+#define BDI_CAP_WRITE_MAP      0x00000020      /* Can be mapped for writing */
+#define BDI_CAP_EXEC_MAP       0x00000040      /* Can be mapped for execution 
*/
+#define BDI_CAP_VMFLAGS \
+       (BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP)
+
+#if defined(VM_MAYREAD) && \
+       (BDI_CAP_READ_MAP != VM_MAYREAD || \
+        BDI_CAP_WRITE_MAP != VM_MAYWRITE || \
+        BDI_CAP_EXEC_MAP != VM_MAYEXEC)
+#error please change backing_dev_info::capabilities flags
+#endif
+
 extern struct backing_dev_info default_backing_dev_info;
 void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page);
 
@@ -61,5 +87,18 @@
        return bdi_congested(bdi, (1 << BDI_read_congested)|
                                  (1 << BDI_write_congested));
 }
+
+#define bdi_cap_writeback_dirty(bdi) \
+       (!((bdi)->capabilities & BDI_CAP_NO_WRITEBACK))
+
+#define bdi_cap_account_dirty(bdi) \
+       (!((bdi)->capabilities & BDI_CAP_NO_ACCT_DIRTY))
+
+#define mapping_cap_writeback_dirty(mapping) \
+       bdi_cap_writeback_dirty((mapping)->backing_dev_info)
+
+#define mapping_cap_account_dirty(mapping) \
+       bdi_cap_account_dirty((mapping)->backing_dev_info)
+
 
 #endif         /* _LINUX_BACKING_DEV_H */
diff -Nru a/kernel/cpuset.c b/kernel/cpuset.c
--- a/kernel/cpuset.c   2005-03-31 10:09:21 -08:00
+++ b/kernel/cpuset.c   2005-03-31 10:09:21 -08:00
@@ -193,7 +193,7 @@
 
 static struct backing_dev_info cpuset_backing_dev_info = {
        .ra_pages = 0,          /* No readahead */
-       .memory_backed = 1,     /* Does not contribute to dirty memory */
+       .capabilities   = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
 };
 
 static struct inode *cpuset_new_inode(mode_t mode)
diff -Nru a/mm/filemap.c b/mm/filemap.c
--- a/mm/filemap.c      2005-03-31 10:09:21 -08:00
+++ b/mm/filemap.c      2005-03-31 10:09:21 -08:00
@@ -172,7 +172,7 @@
                .end = end,
        };
 
-       if (mapping->backing_dev_info->memory_backed)
+       if (!mapping_cap_writeback_dirty(mapping))
                return 0;
 
        ret = do_writepages(mapping, &wbc);
@@ -269,7 +269,7 @@
        pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT;
        int ret;
 
-       if (mapping->backing_dev_info->memory_backed || !count)
+       if (!mapping_cap_writeback_dirty(mapping) || !count)
                return 0;
        ret = filemap_fdatawrite_range(mapping, pos, pos + count - 1);
        if (ret == 0) {
@@ -295,7 +295,7 @@
        pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT;
        int ret;
 
-       if (mapping->backing_dev_info->memory_backed || !count)
+       if (!mapping_cap_writeback_dirty(mapping) || !count)
                return 0;
        ret = filemap_fdatawrite_range(mapping, pos, pos + count - 1);
        if (ret == 0)
diff -Nru a/mm/page-writeback.c b/mm/page-writeback.c
--- a/mm/page-writeback.c       2005-03-31 10:09:21 -08:00
+++ b/mm/page-writeback.c       2005-03-31 10:09:21 -08:00
@@ -627,7 +627,7 @@
                        mapping2 = page_mapping(page);
                        if (mapping2) { /* Race with truncate? */
                                BUG_ON(mapping2 != mapping);
-                               if (!mapping->backing_dev_info->memory_backed)
+                               if (mapping_cap_account_dirty(mapping))
                                        inc_page_state(nr_dirty);
                                radix_tree_tag_set(&mapping->page_tree,
                                        page_index(page), PAGECACHE_TAG_DIRTY);
@@ -713,7 +713,7 @@
                                                page_index(page),
                                                PAGECACHE_TAG_DIRTY);
                        write_unlock_irqrestore(&mapping->tree_lock, flags);
-                       if (!mapping->backing_dev_info->memory_backed)
+                       if (mapping_cap_account_dirty(mapping))
                                dec_page_state(nr_dirty);
                        return 1;
                }
@@ -744,7 +744,7 @@
 
        if (mapping) {
                if (TestClearPageDirty(page)) {
-                       if (!mapping->backing_dev_info->memory_backed)
+                       if (mapping_cap_account_dirty(mapping))
                                dec_page_state(nr_dirty);
                        return 1;
                }
diff -Nru a/mm/readahead.c b/mm/readahead.c
--- a/mm/readahead.c    2005-03-31 10:09:21 -08:00
+++ b/mm/readahead.c    2005-03-31 10:09:21 -08:00
@@ -23,6 +23,7 @@
 struct backing_dev_info default_backing_dev_info = {
        .ra_pages       = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE,
        .state          = 0,
+       .capabilities   = BDI_CAP_MAP_COPY,
        .unplug_io_fn   = default_unplug_io_fn,
 };
 EXPORT_SYMBOL_GPL(default_backing_dev_info);
diff -Nru a/mm/shmem.c b/mm/shmem.c
--- a/mm/shmem.c        2005-03-31 10:09:21 -08:00
+++ b/mm/shmem.c        2005-03-31 10:09:21 -08:00
@@ -184,8 +184,8 @@
 
 static struct backing_dev_info shmem_backing_dev_info = {
        .ra_pages       = 0,    /* No readahead */
-       .memory_backed  = 1,    /* Does not contribute to dirty memory */
-       .unplug_io_fn = default_unplug_io_fn,
+       .capabilities   = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
+       .unplug_io_fn   = default_unplug_io_fn,
 };
 
 static LIST_HEAD(shmem_swaplist);
diff -Nru a/mm/swap_state.c b/mm/swap_state.c
--- a/mm/swap_state.c   2005-03-31 10:09:21 -08:00
+++ b/mm/swap_state.c   2005-03-31 10:09:21 -08:00
@@ -29,7 +29,7 @@
 };
 
 static struct backing_dev_info swap_backing_dev_info = {
-       .memory_backed  = 1,    /* Does not contribute to dirty memory */
+       .capabilities   = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
        .unplug_io_fn   = swap_unplug_io_fn,
 };
 
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to