Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2179d372 authored by David Elliott's avatar David Elliott Committed by Linus Torvalds
Browse files

[PATCH] hfs: add HFSX support



Add support for HFSX, which allows for case-sensitive filenames.

Signed-off-by: default avatarRoman Zippel <zippel@linux-m68k.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 7cf3cc30
Loading
Loading
Loading
Loading
+14 −9
Original line number Diff line number Diff line
@@ -31,17 +31,8 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id)

	init_MUTEX(&tree->tree_lock);
	spin_lock_init(&tree->hash_lock);
	/* Set the correct compare function */
	tree->sb = sb;
	tree->cnid = id;
	if (id == HFSPLUS_EXT_CNID) {
		tree->keycmp = hfsplus_ext_cmp_key;
	} else if (id == HFSPLUS_CAT_CNID) {
		tree->keycmp = hfsplus_cat_cmp_key;
	} else {
		printk(KERN_ERR "hfs: unknown B*Tree requested\n");
		goto free_tree;
	}
	tree->inode = iget(sb, id);
	if (!tree->inode)
		goto free_tree;
@@ -64,6 +55,20 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id)
	tree->max_key_len = be16_to_cpu(head->max_key_len);
	tree->depth = be16_to_cpu(head->depth);

	/* Set the correct compare function */
	if (id == HFSPLUS_EXT_CNID) {
		tree->keycmp = hfsplus_ext_cmp_key;
	} else if (id == HFSPLUS_CAT_CNID) {
		if ((HFSPLUS_SB(sb).flags & HFSPLUS_SB_HFSX) &&
		    (head->key_type == HFSPLUS_KEY_BINARY))
			tree->keycmp = hfsplus_cat_bin_cmp_key;
		else
			tree->keycmp = hfsplus_cat_case_cmp_key;
	} else {
		printk(KERN_ERR "hfs: unknown B*Tree requested\n");
		goto fail_page;
	}

	size = tree->node_size;
	if (!size || size & (size - 1))
		goto fail_page;
+16 −2
Original line number Diff line number Diff line
@@ -13,7 +13,8 @@
#include "hfsplus_fs.h"
#include "hfsplus_raw.h"

int hfsplus_cat_cmp_key(hfsplus_btree_key *k1, hfsplus_btree_key *k2)
int hfsplus_cat_case_cmp_key(const hfsplus_btree_key *k1,
			     const hfsplus_btree_key *k2)
{
	__be32 k1p, k2p;

@@ -22,7 +23,20 @@ int hfsplus_cat_cmp_key(hfsplus_btree_key *k1, hfsplus_btree_key *k2)
	if (k1p != k2p)
		return be32_to_cpu(k1p) < be32_to_cpu(k2p) ? -1 : 1;

	return hfsplus_unistrcmp(&k1->cat.name, &k2->cat.name);
	return hfsplus_strcasecmp(&k1->cat.name, &k2->cat.name);
}

int hfsplus_cat_bin_cmp_key(const hfsplus_btree_key *k1,
			    const hfsplus_btree_key *k2)
{
	__be32 k1p, k2p;

	k1p = k1->cat.parent;
	k2p = k2->cat.parent;
	if (k1p != k2p)
		return be32_to_cpu(k1p) < be32_to_cpu(k2p) ? -1 : 1;

	return hfsplus_strcmp(&k1->cat.name, &k2->cat.name);
}

void hfsplus_cat_build_key(struct super_block *sb, hfsplus_btree_key *key,
+2 −1
Original line number Diff line number Diff line
@@ -16,7 +16,8 @@
#include "hfsplus_raw.h"

/* Compare two extents keys, returns 0 on same, pos/neg for difference */
int hfsplus_ext_cmp_key(hfsplus_btree_key *k1, hfsplus_btree_key *k2)
int hfsplus_ext_cmp_key(const hfsplus_btree_key *k1,
			const hfsplus_btree_key *k2)
{
	__be32 k1id, k2id;
	__be32 k1s, k2s;
+7 −4
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@
#define HFSPLUS_TYPE_DATA 0x00
#define HFSPLUS_TYPE_RSRC 0xFF

typedef int (*btree_keycmp)(hfsplus_btree_key *, hfsplus_btree_key *);
typedef int (*btree_keycmp)(const hfsplus_btree_key *, const hfsplus_btree_key *);

#define NODE_HASH_SIZE	256

@@ -149,6 +149,7 @@ struct hfsplus_sb_info {
#define HFSPLUS_SB_WRITEBACKUP	0x0001
#define HFSPLUS_SB_NODECOMPOSE	0x0002
#define HFSPLUS_SB_FORCE	0x0004
#define HFSPLUS_SB_HFSX		0x0008


struct hfsplus_inode_info {
@@ -303,7 +304,8 @@ int hfs_brec_read(struct hfs_find_data *, void *, int);
int hfs_brec_goto(struct hfs_find_data *, int);

/* catalog.c */
int hfsplus_cat_cmp_key(hfsplus_btree_key *, hfsplus_btree_key *);
int hfsplus_cat_case_cmp_key(const hfsplus_btree_key *, const hfsplus_btree_key *);
int hfsplus_cat_bin_cmp_key(const hfsplus_btree_key *, const hfsplus_btree_key *);
void hfsplus_cat_build_key(struct super_block *sb, hfsplus_btree_key *, u32, struct qstr *);
int hfsplus_find_cat(struct super_block *, u32, struct hfs_find_data *);
int hfsplus_create_cat(u32, struct inode *, struct qstr *, struct inode *);
@@ -312,7 +314,7 @@ int hfsplus_rename_cat(u32, struct inode *, struct qstr *,
		       struct inode *, struct qstr *);

/* extents.c */
int hfsplus_ext_cmp_key(hfsplus_btree_key *, hfsplus_btree_key *);
int hfsplus_ext_cmp_key(const hfsplus_btree_key *, const hfsplus_btree_key *);
void hfsplus_ext_write_extent(struct inode *);
int hfsplus_get_block(struct inode *, sector_t, struct buffer_head *, int);
int hfsplus_free_fork(struct super_block *, u32, struct hfsplus_fork_raw *, int);
@@ -350,7 +352,8 @@ extern u16 hfsplus_decompose_table[];
extern u16 hfsplus_compose_table[];

/* unicode.c */
int hfsplus_unistrcmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *);
int hfsplus_strcasecmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *);
int hfsplus_strcmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *);
int hfsplus_uni2asc(struct super_block *, const struct hfsplus_unistr *, char *, int *);
int hfsplus_asc2uni(struct super_block *, struct hfsplus_unistr *, const char *, int);

+8 −2
Original line number Diff line number Diff line
@@ -22,8 +22,10 @@
#define HFSPLUS_SECTOR_SHIFT         9
#define HFSPLUS_VOLHEAD_SECTOR       2
#define HFSPLUS_VOLHEAD_SIG     0x482b
#define HFSPLUS_VOLHEAD_SIGX    0x4858
#define HFSPLUS_SUPER_MAGIC     0x482b
#define HFSPLUS_CURRENT_VERSION      4
#define HFSPLUS_MIN_VERSION          4
#define HFSPLUS_CURRENT_VERSION      5

#define HFSP_WRAP_MAGIC         0x4244
#define HFSP_WRAP_ATTRIB_SLOCK  0x8000
@@ -161,7 +163,7 @@ struct hfs_btree_header_rec {
	u16 reserved1;
	__be32 clump_size;
	u8 btree_type;
	u8 reserved2;
	u8 key_type;
	__be32 attributes;
	u32 reserved3[16];
} __packed;
@@ -186,6 +188,10 @@ struct hfs_btree_header_rec {
#define HFSPLUS_EXCH_CNID		15	/* ExchangeFiles temp id */
#define HFSPLUS_FIRSTUSER_CNID		16	/* first available user id */

/* btree key type */
#define HFSPLUS_KEY_CASEFOLDING		0xCF	/* case-insensitive */
#define HFSPLUS_KEY_BINARY		0xBC	/* case-sensitive */

/* HFS+ catalog entry key */
struct hfsplus_cat_key {
	__be16 key_len;
Loading