ported support_barriers_on_single_device_dm_devices and ext3_mount_default_to_barrier...
authorS.Çağlar Onur <caglar@cs.princeton.edu>
Sat, 3 Apr 2010 02:44:39 +0000 (02:44 +0000)
committerS.Çağlar Onur <caglar@cs.princeton.edu>
Sat, 3 Apr 2010 02:44:39 +0000 (02:44 +0000)
kernel-2.6.spec
linux-2.6-900-ext3_mount_default_to_barrier.patch [new file with mode: 0644]
linux-2.6-910-support_barriers_on_single_device_dm_devices.patch [new file with mode: 0644]

index 6edea17..50e88d6 100644 (file)
@@ -184,6 +184,9 @@ Patch710: linux-2.6-710-avoid-64bits-addr-pcmcia.patch
 Patch800: linux-2.6-800-rename-ext4dev-to-ext4.patch
 Patch810: linux-2.6-810-ext4-cap-check-delay.patch
 
+Patch900: linux-2.6-900-ext3_mount_default_to_barrier.patch
+Patch910: linux-2.6-910-support_barriers_on_single_device_dm_devices.patch
+
 BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
 
 %description
@@ -383,6 +386,9 @@ KERNEL_PREVIOUS=vanilla
 %ApplyPatch 800
 %ApplyPatch 810
 
+%ApplyPatch 900
+%ApplyPatch 910
+
 # NetNS conflict-resolving patch for VINI. Will work with patch vini_pl_patch-1 but may
 # break with later patches.
 
diff --git a/linux-2.6-900-ext3_mount_default_to_barrier.patch b/linux-2.6-900-ext3_mount_default_to_barrier.patch
new file mode 100644 (file)
index 0000000..2bf48dc
--- /dev/null
@@ -0,0 +1,42 @@
+commit 412e7b7a7e5804e0e04ad31b98db52314cc6168a
+Author: S.Çağlar Onur <caglar@cs.princeton.edu>
+Date:   Fri Apr 2 18:35:07 2010 -0400
+
+    ext3_mount_default_to_barrier.patch
+
+diff --git a/fs/ext3/fsync.c b/fs/ext3/fsync.c
+index d336341..737f9ed 100644
+--- a/fs/ext3/fsync.c
++++ b/fs/ext3/fsync.c
+@@ -27,6 +27,7 @@
+ #include <linux/sched.h>
+ #include <linux/writeback.h>
+ #include <linux/jbd.h>
++#include <linux/blkdev.h>
+ #include <linux/ext3_fs.h>
+ #include <linux/ext3_jbd.h>
+@@ -84,7 +85,10 @@ int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync)
+                       .sync_mode = WB_SYNC_ALL,
+                       .nr_to_write = 0, /* sys_fsync did this */
+               };
++              journal_t *journal = EXT3_SB(inode->i_sb)->s_journal;
+               ret = sync_inode(inode, &wbc);
++              if (journal && (journal->j_flags & JFS_BARRIER))
++                      blkdev_issue_flush(inode->i_sb->s_bdev, NULL);
+       }
+ out:
+       return ret;
+diff --git a/fs/ext3/super.c b/fs/ext3/super.c
+index fc4df0d..af90937 100644
+--- a/fs/ext3/super.c
++++ b/fs/ext3/super.c
+@@ -1621,6 +1621,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
+       sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
+       sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
++      /* enable barriers by default */
++      set_opt(sbi->s_mount_opt, BARRIER);
+       set_opt(sbi->s_mount_opt, RESERVATION);
+       if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum,
diff --git a/linux-2.6-910-support_barriers_on_single_device_dm_devices.patch b/linux-2.6-910-support_barriers_on_single_device_dm_devices.patch
new file mode 100644 (file)
index 0000000..329404c
--- /dev/null
@@ -0,0 +1,140 @@
+commit 6b2ba85752b8123d68ceb8770c94ebf4ba1dbb94
+Author: S.Çağlar Onur <caglar@cs.princeton.edu>
+Date:   Fri Apr 2 18:33:58 2010 -0400
+
+    support_barriers_on_single_device_dm_devices.patch
+
+diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
+index 6449bcd..2d50fff 100644
+--- a/drivers/md/dm-linear.c
++++ b/drivers/md/dm-linear.c
+@@ -151,6 +151,7 @@ static struct target_type linear_target = {
+       .status = linear_status,
+       .ioctl  = linear_ioctl,
+       .merge  = linear_merge,
++      .features = DM_TARGET_SUPPORTS_BARRIERS,
+ };
+ int __init dm_linear_init(void)
+diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
+index 61f4414..a27cce2 100644
+--- a/drivers/md/dm-table.c
++++ b/drivers/md/dm-table.c
+@@ -38,6 +38,8 @@ struct dm_table {
+       sector_t *highs;
+       struct dm_target *targets;
++      unsigned barriers_supported:1;
++
+       /*
+        * Indicates the rw permissions for the new logical
+        * device.  This should be a combination of FMODE_READ
+@@ -227,6 +229,7 @@ int dm_table_create(struct dm_table **result, int mode,
+       INIT_LIST_HEAD(&t->devices);
+       atomic_set(&t->holders, 1);
++      t->barriers_supported = 1;
+       if (!num_targets)
+               num_targets = KEYS_PER_NODE;
+@@ -723,6 +726,10 @@ int dm_table_add_target(struct dm_table *t, const char *type,
+       /* FIXME: the plan is to combine high here and then have
+        * the merge fn apply the target level restrictions. */
+       combine_restrictions_low(&t->limits, &tgt->limits);
++
++      if (!(tgt->type->features & DM_TARGET_SUPPORTS_BARRIERS))
++              t->barriers_supported = 0;
++
+       return 0;
+  bad:
+@@ -767,6 +774,12 @@ int dm_table_complete(struct dm_table *t)
+       check_for_valid_limits(&t->limits);
++      /*
++       * We only support barriers if there is exactly one underlying device.
++       */
++      if (!list_is_singular(&t->devices))
++              t->barriers_supported = 0;
++
+       /* how many indexes will the btree have ? */
+       leaf_nodes = dm_div_up(t->num_targets, KEYS_PER_NODE);
+       t->depth = 1 + int_log(leaf_nodes, CHILDREN_PER_NODE);
+@@ -968,6 +981,11 @@ struct mapped_device *dm_table_get_md(struct dm_table *t)
+       return t->md;
+ }
++int dm_table_barrier_ok(struct dm_table *t)
++{
++      return t->barriers_supported;
++}
++EXPORT_SYMBOL(dm_table_barrier_ok);
+ EXPORT_SYMBOL(dm_vcalloc);
+ EXPORT_SYMBOL(dm_get_device);
+ EXPORT_SYMBOL(dm_put_device);
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index 191f56d..8b11f14 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -816,6 +816,12 @@ static int __split_bio(struct mapped_device *md, struct bio *bio)
+       if (unlikely(!ci.map))
+               return -EIO;
++      if (unlikely(bio_barrier(bio) && !dm_table_barrier_ok(ci.map))) {
++              dm_table_put(ci.map);
++              bio_endio(bio, -EOPNOTSUPP);
++              return;
++      }
++
+       ci.md = md;
+       ci.bio = bio;
+       ci.io = alloc_io(md);
+@@ -898,15 +904,6 @@ static int dm_request(struct request_queue *q, struct bio *bio)
+       int rw = bio_data_dir(bio);
+       struct mapped_device *md = q->queuedata;
+-      /*
+-       * There is no use in forwarding any barrier request since we can't
+-       * guarantee it is (or can be) handled by the targets correctly.
+-       */
+-      if (unlikely(bio_barrier(bio))) {
+-              bio_endio(bio, -EOPNOTSUPP);
+-              return 0;
+-      }
+-
+       down_read(&md->io_lock);
+       disk_stat_inc(dm_disk(md), ios[rw]);
+diff --git a/drivers/md/dm.h b/drivers/md/dm.h
+index a72d6d7..cd82816 100644
+--- a/drivers/md/dm.h
++++ b/drivers/md/dm.h
+@@ -50,6 +50,7 @@ void dm_table_postsuspend_targets(struct dm_table *t);
+ int dm_table_resume_targets(struct dm_table *t);
+ int dm_table_any_congested(struct dm_table *t, int bdi_bits);
+ void dm_table_unplug_all(struct dm_table *t);
++int dm_table_barrier_ok(struct dm_table *t);
+ /*
+  * To check the return value from dm_table_find_target().
+diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
+index a90222e..3854a3e 100644
+--- a/include/linux/device-mapper.h
++++ b/include/linux/device-mapper.h
+@@ -94,9 +94,15 @@ int dm_get_device(struct dm_target *ti, const char *path, sector_t start,
+ void dm_put_device(struct dm_target *ti, struct dm_dev *d);
+ /*
++ * Target features
++ */
++#define DM_TARGET_SUPPORTS_BARRIERS 0x00000001
++
++/*
+  * Information about a target type
+  */
+ struct target_type {
++      uint64_t features;
+       const char *name;
+       struct module *module;
+       unsigned version[3];