linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Christoph Hellwig <hch@lst.de>
To: linux-fsdevel@vger.kernel.org
Subject: [PATCH 4/11] hfsplus: use raw bio access for partition tables
Date: Wed, 17 Nov 2010 23:22:16 +0100	[thread overview]
Message-ID: <20101117222216.GE21700@lst.de> (raw)
In-Reply-To: <20101117222117.GA21700@lst.de>

Switch the hfsplus partition table reding for cdroms to use our bio
helpers.  Again we don't rely on any caching in the buffer_heads, and
this gets rid of the last buffer_head use in hfsplus.

Signed-off-by: Christoph Hellwig <hch@tuxera.com>

Index: linux-2.6/fs/hfsplus/part_tbl.c
===================================================================
--- linux-2.6.orig/fs/hfsplus/part_tbl.c	2010-11-17 22:43:32.005254018 +0100
+++ linux-2.6/fs/hfsplus/part_tbl.c	2010-11-17 22:44:20.827005379 +0100
@@ -13,6 +13,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include "hfsplus_fs.h"
 
 /* offsets to various blocks */
@@ -65,70 +66,87 @@ struct old_pmap {
 	}	pdEntry[42];
 } __packed;
 
+static int hfs_parse_old_pmap(struct super_block *sb, struct old_pmap *pm,
+		sector_t *part_start, sector_t *part_size)
+{
+	struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
+	int i;
+
+	for (i = 0; i < 42; i++) {
+		struct old_pmap_entry *p = &pm->pdEntry[i];
+
+		if (p->pdStart && p->pdSize &&
+		    p->pdFSID == cpu_to_be32(0x54465331)/*"TFS1"*/ &&
+		    (sbi->part < 0 || sbi->part == i)) {
+			*part_start += be32_to_cpu(p->pdStart);
+			*part_size = be32_to_cpu(p->pdSize);
+			return 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
+static int hfs_parse_new_pmap(struct super_block *sb, 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 res;
+	int i = 0;
+
+	do {
+		if (!memcmp(pm->pmPartType,"Apple_HFS", 9) &&
+		    (sbi->part < 0 || sbi->part == i)) {
+			*part_start += be32_to_cpu(pm->pmPyPartStart);
+			*part_size = be32_to_cpu(pm->pmPartBlkCnt);
+			return 0;
+		}
+
+		if (++i >= size)
+			return -ENOENT;
+
+		res = hfsplus_submit_bio(sb->s_bdev,
+					 *part_start + HFS_PMAP_BLK + i,
+					 pm, READ);
+		if (res)
+			return res;
+	} while (pm->pmSig == cpu_to_be16(HFS_NEW_PMAP_MAGIC));
+
+	return -ENOENT;
+}
+
 /*
- * hfs_part_find()
- *
- * Parse the partition map looking for the
- * start and length of the 'part'th HFS partition.
+ * Parse the partition map looking for the start and length of a
+ * HFS/HFS+ partition.
  */
 int hfs_part_find(struct super_block *sb,
-		  sector_t *part_start, sector_t *part_size)
+		sector_t *part_start, sector_t *part_size)
 {
-	struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
-	struct buffer_head *bh;
-	__be16 *data;
-	int i, size, res;
-
-	res = -ENOENT;
-	bh = sb_bread512(sb, *part_start + HFS_PMAP_BLK, data);
-	if (!bh)
-		return -EIO;
+	void *data;
+	int res;
+
+	data = kmalloc(HFSPLUS_SECTOR_SIZE, GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	res = hfsplus_submit_bio(sb->s_bdev, *part_start + HFS_PMAP_BLK,
+				 data, READ);
+	if (res)
+		return res;
 
-	switch (be16_to_cpu(*data)) {
+	switch (be16_to_cpu(*((__be16 *)data))) {
 	case HFS_OLD_PMAP_MAGIC:
-	  {
-		struct old_pmap *pm;
-		struct old_pmap_entry *p;
-
-		pm = (struct old_pmap *)bh->b_data;
-		p = pm->pdEntry;
-		size = 42;
-		for (i = 0; i < size; p++, i++) {
-			if (p->pdStart && p->pdSize &&
-			    p->pdFSID == cpu_to_be32(0x54465331)/*"TFS1"*/ &&
-			    (sbi->part < 0 || sbi->part == i)) {
-				*part_start += be32_to_cpu(p->pdStart);
-				*part_size = be32_to_cpu(p->pdSize);
-				res = 0;
-			}
-		}
+		res = hfs_parse_old_pmap(sb, data, part_start, part_size);
 		break;
-	  }
 	case HFS_NEW_PMAP_MAGIC:
-	  {
-		struct new_pmap *pm;
-
-		pm = (struct new_pmap *)bh->b_data;
-		size = be32_to_cpu(pm->pmMapBlkCnt);
-		for (i = 0; i < size;) {
-			if (!memcmp(pm->pmPartType,"Apple_HFS", 9) &&
-			    (sbi->part < 0 || sbi->part == i)) {
-				*part_start += be32_to_cpu(pm->pmPyPartStart);
-				*part_size = be32_to_cpu(pm->pmPartBlkCnt);
-				res = 0;
-				break;
-			}
-			brelse(bh);
-			bh = sb_bread512(sb, *part_start + HFS_PMAP_BLK + ++i, pm);
-			if (!bh)
-				return -EIO;
-			if (pm->pmSig != cpu_to_be16(HFS_NEW_PMAP_MAGIC))
-				break;
-		}
+		res = hfs_parse_new_pmap(sb, data, part_start, part_size);
+		break;
+	default:
+		res = -ENOENT;
 		break;
-	  }
 	}
-	brelse(bh);
 
+	kfree(data);
 	return res;
 }
Index: linux-2.6/fs/hfsplus/hfsplus_fs.h
===================================================================
--- linux-2.6.orig/fs/hfsplus/hfsplus_fs.h	2010-11-17 22:43:32.011254158 +0100
+++ linux-2.6/fs/hfsplus/hfsplus_fs.h	2010-11-17 22:44:20.828003913 +0100
@@ -401,23 +401,6 @@ static inline struct hfsplus_inode_info
 	return list_entry(inode, struct hfsplus_inode_info, vfs_inode);
 }
 
-#define sb_bread512(sb, sec, data) ({			\
-	struct buffer_head *__bh;			\
-	sector_t __block;				\
-	loff_t __start;					\
-	int __offset;					\
-							\
-	__start = (loff_t)(sec) << HFSPLUS_SECTOR_SHIFT;\
-	__block = __start >> (sb)->s_blocksize_bits;	\
-	__offset = __start & ((sb)->s_blocksize - 1);	\
-	__bh = sb_bread((sb), __block);			\
-	if (likely(__bh != NULL))			\
-		data = (void *)(__bh->b_data + __offset);\
-	else						\
-		data = NULL;				\
-	__bh;						\
-})
-
 /* time macros */
 #define __hfsp_mt2ut(t)		(be32_to_cpu(t) - 2082844800U)
 #define __hfsp_ut2mt(t)		(cpu_to_be32(t + 2082844800U))

  parent reply	other threads:[~2010-11-17 22:22 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-17 22:21 hfsplus patch review Christoph Hellwig
2010-11-17 22:21 ` [PATCH 1/11] hfsplus: silence a few debug printks Christoph Hellwig
2010-11-17 22:21 ` [PATCH 2/11] hfsplus: always use hfsplus_sync_fs to write the volume header Christoph Hellwig
2010-11-17 22:22 ` [PATCH 3/11] hfsplus: use raw bio access for the volume headers Christoph Hellwig
2010-11-17 22:22 ` Christoph Hellwig [this message]
2010-11-17 22:22 ` [PATCH 5/11] hfsplus: make sure sync writes out all metadata Christoph Hellwig
2010-11-17 22:22 ` [PATCH 6/11] hfsplus: avoid useless work in hfsplus_sync_fs Christoph Hellwig
2010-11-17 22:22 ` [PATCH 7/11] hfsplus: simplify fsync Christoph Hellwig
2010-11-17 22:22 ` [PATCH 8/11] hfsplus: write up fsync for directories Christoph Hellwig
2010-11-17 22:23 ` [PATCH 9/11] hfsplus: split up inode flags Christoph Hellwig
2010-11-17 22:23 ` [PATCH 10/11] hfsplus: optimize fsync Christoph Hellwig
2010-11-18  6:40   ` Nick Piggin
2010-11-18 13:50     ` Christoph Hellwig
2010-11-18 14:13       ` Nick Piggin
2010-11-18 14:16         ` Christoph Hellwig
2010-11-22 13:03           ` Nick Piggin
2010-11-22 13:18             ` Nick Piggin
2010-11-22 13:29               ` Christoph Hellwig
2010-11-22 11:35     ` [PATCH v2] " Christoph Hellwig
2010-11-17 22:23 ` [PATCH 11/11] hfsplus: flush disk caches in sync and fsync Christoph Hellwig

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=20101117222216.GE21700@lst.de \
    --to=hch@lst.de \
    --cc=linux-fsdevel@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).