summaryrefslogtreecommitdiffstats
path: root/freed-ora/current/f15/hfsplus-ensure-bio-requests-are-not-smaller-than-the.patch
diff options
context:
space:
mode:
Diffstat (limited to 'freed-ora/current/f15/hfsplus-ensure-bio-requests-are-not-smaller-than-the.patch')
-rw-r--r--freed-ora/current/f15/hfsplus-ensure-bio-requests-are-not-smaller-than-the.patch315
1 files changed, 0 insertions, 315 deletions
diff --git a/freed-ora/current/f15/hfsplus-ensure-bio-requests-are-not-smaller-than-the.patch b/freed-ora/current/f15/hfsplus-ensure-bio-requests-are-not-smaller-than-the.patch
deleted file mode 100644
index c81bf91d1..000000000
--- a/freed-ora/current/f15/hfsplus-ensure-bio-requests-are-not-smaller-than-the.patch
+++ /dev/null
@@ -1,315 +0,0 @@
-From 6596528e391ad978a6a120142cba97a1d7324cb6 Mon Sep 17 00:00:00 2001
-From: Seth Forshee <seth.forshee@canonical.com>
-Date: Mon, 18 Jul 2011 08:06:23 -0700
-Subject: [PATCH] hfsplus: ensure bio requests are not smaller than the
- hardware sectors
-
-Currently all bio requests are 512 bytes, which may fail for media
-whose physical sector size is larger than this. Ensure these
-requests are not smaller than the block device logical block size.
-
-BugLink: http://bugs.launchpad.net/bugs/734883
-Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
-Signed-off-by: Christoph Hellwig <hch@lst.de>
----
- fs/hfsplus/hfsplus_fs.h | 16 ++++++++-
- fs/hfsplus/part_tbl.c | 32 ++++++++++--------
- fs/hfsplus/super.c | 12 +++---
- fs/hfsplus/wrapper.c | 83 +++++++++++++++++++++++++++++++++++-----------
- 4 files changed, 101 insertions(+), 42 deletions(-)
-
-diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
-index 0bebf74..81dfd1e 100644
---- a/fs/hfsplus/hfsplus_fs.h
-+++ b/fs/hfsplus/hfsplus_fs.h
-@@ -13,6 +13,7 @@
- #include <linux/fs.h>
- #include <linux/mutex.h>
- #include <linux/buffer_head.h>
-+#include <linux/blkdev.h>
- #include "hfsplus_raw.h"
-
- #define DBG_BNODE_REFS 0x00000001
-@@ -110,7 +111,9 @@ struct hfsplus_vh;
- struct hfs_btree;
-
- struct hfsplus_sb_info {
-+ void *s_vhdr_buf;
- struct hfsplus_vh *s_vhdr;
-+ void *s_backup_vhdr_buf;
- struct hfsplus_vh *s_backup_vhdr;
- struct hfs_btree *ext_tree;
- struct hfs_btree *cat_tree;
-@@ -258,6 +261,15 @@ struct hfsplus_readdir_data {
- struct hfsplus_cat_key key;
- };
-
-+/*
-+ * Find minimum acceptible I/O size for an hfsplus sb.
-+ */
-+static inline unsigned short hfsplus_min_io_size(struct super_block *sb)
-+{
-+ return max_t(unsigned short, bdev_logical_block_size(sb->s_bdev),
-+ HFSPLUS_SECTOR_SIZE);
-+}
-+
- #define hfs_btree_open hfsplus_btree_open
- #define hfs_btree_close hfsplus_btree_close
- #define hfs_btree_write hfsplus_btree_write
-@@ -436,8 +448,8 @@ int hfsplus_compare_dentry(const struct dentry *parent,
- /* wrapper.c */
- int hfsplus_read_wrapper(struct super_block *);
- int hfs_part_find(struct super_block *, sector_t *, sector_t *);
--int hfsplus_submit_bio(struct block_device *bdev, sector_t sector,
-- void *data, int rw);
-+int hfsplus_submit_bio(struct super_block *sb, sector_t sector,
-+ void *buf, void **data, int rw);
-
- /* time macros */
- #define __hfsp_mt2ut(t) (be32_to_cpu(t) - 2082844800U)
-diff --git a/fs/hfsplus/part_tbl.c b/fs/hfsplus/part_tbl.c
-index 40ad88c..eb355d8 100644
---- a/fs/hfsplus/part_tbl.c
-+++ b/fs/hfsplus/part_tbl.c
-@@ -88,11 +88,12 @@ static int hfs_parse_old_pmap(struct super_block *sb, struct old_pmap *pm,
- return -ENOENT;
- }
-
--static int hfs_parse_new_pmap(struct super_block *sb, struct new_pmap *pm,
-- sector_t *part_start, sector_t *part_size)
-+static int hfs_parse_new_pmap(struct super_block *sb, void *buf,
-+ struct new_pmap *pm, sector_t *part_start, sector_t *part_size)
- {
- struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
- int size = be32_to_cpu(pm->pmMapBlkCnt);
-+ int buf_size = hfsplus_min_io_size(sb);
- int res;
- int i = 0;
-
-@@ -107,11 +108,14 @@ static int hfs_parse_new_pmap(struct super_block *sb, struct new_pmap *pm,
- if (++i >= size)
- return -ENOENT;
-
-- res = hfsplus_submit_bio(sb->s_bdev,
-- *part_start + HFS_PMAP_BLK + i,
-- pm, READ);
-- if (res)
-- return res;
-+ pm = (struct new_pmap *)((u8 *)pm + HFSPLUS_SECTOR_SIZE);
-+ if ((u8 *)pm - (u8 *)buf >= buf_size) {
-+ res = hfsplus_submit_bio(sb,
-+ *part_start + HFS_PMAP_BLK + i,
-+ buf, (void **)&pm, READ);
-+ if (res)
-+ return res;
-+ }
- } while (pm->pmSig == cpu_to_be16(HFS_NEW_PMAP_MAGIC));
-
- return -ENOENT;
-@@ -124,15 +128,15 @@ static int hfs_parse_new_pmap(struct super_block *sb, struct new_pmap *pm,
- int hfs_part_find(struct super_block *sb,
- sector_t *part_start, sector_t *part_size)
- {
-- void *data;
-+ void *buf, *data;
- int res;
-
-- data = kmalloc(HFSPLUS_SECTOR_SIZE, GFP_KERNEL);
-- if (!data)
-+ buf = kmalloc(hfsplus_min_io_size(sb), GFP_KERNEL);
-+ if (!buf)
- return -ENOMEM;
-
-- res = hfsplus_submit_bio(sb->s_bdev, *part_start + HFS_PMAP_BLK,
-- data, READ);
-+ res = hfsplus_submit_bio(sb, *part_start + HFS_PMAP_BLK,
-+ buf, &data, READ);
- if (res)
- goto out;
-
-@@ -141,13 +145,13 @@ int hfs_part_find(struct super_block *sb,
- res = hfs_parse_old_pmap(sb, data, part_start, part_size);
- break;
- case HFS_NEW_PMAP_MAGIC:
-- res = hfs_parse_new_pmap(sb, data, part_start, part_size);
-+ res = hfs_parse_new_pmap(sb, buf, data, part_start, part_size);
- break;
- default:
- res = -ENOENT;
- break;
- }
- out:
-- kfree(data);
-+ kfree(buf);
- return res;
- }
-diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
-index 84f56e1..c106ca2 100644
---- a/fs/hfsplus/super.c
-+++ b/fs/hfsplus/super.c
-@@ -203,17 +203,17 @@ int hfsplus_sync_fs(struct super_block *sb, int wait)
- write_backup = 1;
- }
-
-- error2 = hfsplus_submit_bio(sb->s_bdev,
-+ error2 = hfsplus_submit_bio(sb,
- sbi->part_start + HFSPLUS_VOLHEAD_SECTOR,
-- sbi->s_vhdr, WRITE_SYNC);
-+ sbi->s_vhdr_buf, NULL, WRITE_SYNC);
- if (!error)
- error = error2;
- if (!write_backup)
- goto out;
-
-- error2 = hfsplus_submit_bio(sb->s_bdev,
-+ error2 = hfsplus_submit_bio(sb,
- sbi->part_start + sbi->sect_count - 2,
-- sbi->s_backup_vhdr, WRITE_SYNC);
-+ sbi->s_backup_vhdr_buf, NULL, WRITE_SYNC);
- if (!error)
- error2 = error;
- out:
-@@ -257,8 +257,8 @@ static void hfsplus_put_super(struct super_block *sb)
- hfs_btree_close(sbi->ext_tree);
- iput(sbi->alloc_file);
- iput(sbi->hidden_dir);
-- kfree(sbi->s_vhdr);
-- kfree(sbi->s_backup_vhdr);
-+ kfree(sbi->s_vhdr_buf);
-+ kfree(sbi->s_backup_vhdr_buf);
- unload_nls(sbi->nls);
- kfree(sb->s_fs_info);
- sb->s_fs_info = NULL;
-diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c
-index 2f933e8..10e515a 100644
---- a/fs/hfsplus/wrapper.c
-+++ b/fs/hfsplus/wrapper.c
-@@ -31,25 +31,67 @@ static void hfsplus_end_io_sync(struct bio *bio, int err)
- complete(bio->bi_private);
- }
-
--int hfsplus_submit_bio(struct block_device *bdev, sector_t sector,
-- void *data, int rw)
-+/*
-+ * hfsplus_submit_bio - Perfrom block I/O
-+ * @sb: super block of volume for I/O
-+ * @sector: block to read or write, for blocks of HFSPLUS_SECTOR_SIZE bytes
-+ * @buf: buffer for I/O
-+ * @data: output pointer for location of requested data
-+ * @rw: direction of I/O
-+ *
-+ * The unit of I/O is hfsplus_min_io_size(sb), which may be bigger than
-+ * HFSPLUS_SECTOR_SIZE, and @buf must be sized accordingly. On reads
-+ * @data will return a pointer to the start of the requested sector,
-+ * which may not be the same location as @buf.
-+ *
-+ * If @sector is not aligned to the bdev logical block size it will
-+ * be rounded down. For writes this means that @buf should contain data
-+ * that starts at the rounded-down address. As long as the data was
-+ * read using hfsplus_submit_bio() and the same buffer is used things
-+ * will work correctly.
-+ */
-+int hfsplus_submit_bio(struct super_block *sb, sector_t sector,
-+ void *buf, void **data, int rw)
- {
- DECLARE_COMPLETION_ONSTACK(wait);
- struct bio *bio;
- int ret = 0;
-+ unsigned int io_size;
-+ loff_t start;
-+ int offset;
-+
-+ /*
-+ * Align sector to hardware sector size and find offset. We
-+ * assume that io_size is a power of two, which _should_
-+ * be true.
-+ */
-+ io_size = hfsplus_min_io_size(sb);
-+ start = (loff_t)sector << HFSPLUS_SECTOR_SHIFT;
-+ offset = start & (io_size - 1);
-+ sector &= ~((io_size >> HFSPLUS_SECTOR_SHIFT) - 1);
-
- bio = bio_alloc(GFP_NOIO, 1);
- bio->bi_sector = sector;
-- bio->bi_bdev = bdev;
-+ bio->bi_bdev = sb->s_bdev;
- bio->bi_end_io = hfsplus_end_io_sync;
- bio->bi_private = &wait;
-
-- /*
-- * We always submit one sector at a time, so bio_add_page must not fail.
-- */
-- if (bio_add_page(bio, virt_to_page(data), HFSPLUS_SECTOR_SIZE,
-- offset_in_page(data)) != HFSPLUS_SECTOR_SIZE)
-- BUG();
-+ if (!(rw & WRITE) && data)
-+ *data = (u8 *)buf + offset;
-+
-+ while (io_size > 0) {
-+ unsigned int page_offset = offset_in_page(buf);
-+ unsigned int len = min_t(unsigned int, PAGE_SIZE - page_offset,
-+ io_size);
-+
-+ ret = bio_add_page(bio, virt_to_page(buf), len, page_offset);
-+ if (ret != len) {
-+ ret = -EIO;
-+ goto out;
-+ }
-+ io_size -= len;
-+ buf = (u8 *)buf + len;
-+ }
-
- submit_bio(rw, bio);
- wait_for_completion(&wait);
-@@ -57,8 +99,9 @@ int hfsplus_submit_bio(struct block_device *bdev, sector_t sector,
- if (!bio_flagged(bio, BIO_UPTODATE))
- ret = -EIO;
-
-+out:
- bio_put(bio);
-- return ret;
-+ return ret < 0 ? ret : 0;
- }
-
- static int hfsplus_read_mdb(void *bufptr, struct hfsplus_wd *wd)
-@@ -143,17 +186,17 @@ int hfsplus_read_wrapper(struct super_block *sb)
- goto out;
-
- error = -ENOMEM;
-- sbi->s_vhdr = kmalloc(HFSPLUS_SECTOR_SIZE, GFP_KERNEL);
-- if (!sbi->s_vhdr)
-+ sbi->s_vhdr_buf = kmalloc(hfsplus_min_io_size(sb), GFP_KERNEL);
-+ if (!sbi->s_vhdr_buf)
- goto out;
-- sbi->s_backup_vhdr = kmalloc(HFSPLUS_SECTOR_SIZE, GFP_KERNEL);
-- if (!sbi->s_backup_vhdr)
-+ sbi->s_backup_vhdr_buf = kmalloc(hfsplus_min_io_size(sb), GFP_KERNEL);
-+ if (!sbi->s_backup_vhdr_buf)
- goto out_free_vhdr;
-
- reread:
-- error = hfsplus_submit_bio(sb->s_bdev,
-- part_start + HFSPLUS_VOLHEAD_SECTOR,
-- sbi->s_vhdr, READ);
-+ error = hfsplus_submit_bio(sb, part_start + HFSPLUS_VOLHEAD_SECTOR,
-+ sbi->s_vhdr_buf, (void **)&sbi->s_vhdr,
-+ READ);
- if (error)
- goto out_free_backup_vhdr;
-
-@@ -183,9 +226,9 @@ reread:
- goto reread;
- }
-
-- error = hfsplus_submit_bio(sb->s_bdev,
-- part_start + part_size - 2,
-- sbi->s_backup_vhdr, READ);
-+ error = hfsplus_submit_bio(sb, part_start + part_size - 2,
-+ sbi->s_backup_vhdr_buf,
-+ (void **)&sbi->s_backup_vhdr, READ);
- if (error)
- goto out_free_backup_vhdr;
-
---
-1.7.6
-
OpenPOWER on IntegriCloud