linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 2/3] hfsplus: implement attributes file's header node initialization code
@ 2013-09-20 10:04 Vyacheslav Dubeyko
  2013-09-25 22:54 ` Andrew Morton
  0 siblings, 1 reply; 3+ messages in thread
From: Vyacheslav Dubeyko @ 2013-09-20 10:04 UTC (permalink / raw)
  To: Linux FS devel list
  Cc: Al Viro, Christoph Hellwig, Hin-Tak Leung, Andrew Morton

From: Vyacheslav Dubeyko <slava@dubeyko.com>
Subject: [PATCH 2/3] hfsplus: implement attributes file's header node initialization code

This patch implements functionality of AttributesFile's header
node initialization.

Signed-off-by: Vyacheslav Dubeyko <slava@dubeyko.com>
CC: Al Viro <viro@zeniv.linux.org.uk>
CC: Christoph Hellwig <hch@infradead.org>
CC: Hin-Tak Leung <htl10@users.sourceforge.net>
---
 fs/hfsplus/hfsplus_raw.h |    3 +++
 fs/hfsplus/xattr.c       |   63 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/fs/hfsplus/hfsplus_raw.h b/fs/hfsplus/hfsplus_raw.h
index 452ede0..c28d178 100644
--- a/fs/hfsplus/hfsplus_raw.h
+++ b/fs/hfsplus/hfsplus_raw.h
@@ -187,6 +187,9 @@ struct hfs_btree_header_rec {
 /* HFS+ BTree misc info */
 #define HFSPLUS_TREE_HEAD 0
 #define HFSPLUS_NODE_MXSZ 32768
+#define HFSPLUS_ATTR_TREE_NODE_SIZE		8192
+#define HFSPLUS_BTREE_HDR_NODE_RECS_COUNT	3
+#define HFSPLUS_BTREE_HDR_USER_BYTES		128
 
 /* Some special File ID numbers (stolen from hfs.h) */
 #define HFSPLUS_POR_CNID		1	/* Parent Of the Root */
diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c
index bd8471f..31f70f5 100644
--- a/fs/hfsplus/xattr.c
+++ b/fs/hfsplus/xattr.c
@@ -127,6 +127,69 @@ static int can_set_xattr(struct inode *inode, const char *name,
 	return 0;
 }
 
+#define SETOFFSET(buf, ndsiz, offset, rec) \
+	(*(u16 *)((u8 *)(buf) + (ndsiz) + (-2 * (rec))) = (cpu_to_be16(offset)))
+
+static void hfsplus_init_header_node(struct inode *attr_file,
+					u32 clump_size,
+					char *buf, size_t node_size)
+{
+	struct hfs_bnode_desc *desc;
+	struct hfs_btree_header_rec *head;
+	u16 offset;
+	u32 hdr_node_map_rec_bits;
+	char *bmp;
+	u32 temp;
+
+	hfs_dbg(ATTR_MOD, "init_hdr_attr_file: clump %u, node_size %zu\n",
+				clump_size, node_size);
+
+	desc = (struct hfs_bnode_desc *)buf;
+	desc->type = HFS_NODE_HEADER;
+	desc->num_recs = cpu_to_be16(HFSPLUS_BTREE_HDR_NODE_RECS_COUNT);
+	offset = sizeof(struct hfs_bnode_desc);
+	SETOFFSET(buf, node_size, offset, 1);
+
+	head = (struct hfs_btree_header_rec *)(buf + offset);
+	head->node_size = cpu_to_be16(node_size);
+	head->node_count = cpu_to_be32(i_size_read(attr_file) / node_size);
+	head->free_nodes = cpu_to_be32(be32_to_cpu(head->node_count) - 1);
+	head->clump_size = cpu_to_be32(clump_size);
+	head->attributes |= cpu_to_be32(HFS_TREE_BIGKEYS | HFS_TREE_VARIDXKEYS);
+	head->max_key_len = cpu_to_be16(HFSPLUS_ATTR_KEYLEN - sizeof(u16));
+	offset += sizeof(struct hfs_btree_header_rec);
+	SETOFFSET(buf, node_size, offset, 2);
+
+	offset += HFSPLUS_BTREE_HDR_USER_BYTES;
+	SETOFFSET(buf, node_size, offset, 3);
+
+	hdr_node_map_rec_bits = 8 * (node_size - offset - (4 * sizeof(u16)));
+	if (be32_to_cpu(head->node_count) > hdr_node_map_rec_bits) {
+		u32 map_node_bits;
+		u32 map_nodes;
+
+		desc->next = cpu_to_be32(be32_to_cpu(head->leaf_tail) + 1);
+		map_node_bits = 8 * (node_size - sizeof(struct hfs_bnode_desc) -
+					(2 * sizeof(u16)) - 2);
+		map_nodes = (be32_to_cpu(head->node_count) -
+				hdr_node_map_rec_bits +
+				(map_node_bits - 1)) / map_node_bits;
+		be32_add_cpu(&head->free_nodes, 0 - map_nodes);
+	}
+
+	bmp = buf + offset;
+	temp = be32_to_cpu(head->node_count) - be32_to_cpu(head->free_nodes);
+
+	/* Working a byte at a time is endian safe */
+	while (temp >= 8) {
+		*bmp = 0xFF; temp -= 8; bmp++;
+	}
+	*bmp = ~(0xFF >> temp);
+	offset += hdr_node_map_rec_bits / 8;
+
+	SETOFFSET(buf, node_size, offset, 4);
+}
+
 int __hfsplus_setxattr(struct inode *inode, const char *name,
 			const void *value, size_t size, int flags)
 {
-- 
1.7.9.5




^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 2/3] hfsplus: implement attributes file's header node initialization code
  2013-09-20 10:04 [PATCH 2/3] hfsplus: implement attributes file's header node initialization code Vyacheslav Dubeyko
@ 2013-09-25 22:54 ` Andrew Morton
  2013-09-26  0:07   ` Al Viro
  0 siblings, 1 reply; 3+ messages in thread
From: Andrew Morton @ 2013-09-25 22:54 UTC (permalink / raw)
  To: slava; +Cc: Linux FS devel list, Al Viro, Christoph Hellwig, Hin-Tak Leung

On Fri, 20 Sep 2013 14:04:09 +0400 Vyacheslav Dubeyko <slava@dubeyko.com> wrote:

> From: Vyacheslav Dubeyko <slava@dubeyko.com>
> Subject: [PATCH 2/3] hfsplus: implement attributes file's header node initialization code
> 
> This patch implements functionality of AttributesFile's header
> node initialization.
> 
> ...
>
> --- a/fs/hfsplus/hfsplus_raw.h
> +++ b/fs/hfsplus/hfsplus_raw.h
> @@ -187,6 +187,9 @@ struct hfs_btree_header_rec {
>  /* HFS+ BTree misc info */
>  #define HFSPLUS_TREE_HEAD 0
>  #define HFSPLUS_NODE_MXSZ 32768
> +#define HFSPLUS_ATTR_TREE_NODE_SIZE		8192
> +#define HFSPLUS_BTREE_HDR_NODE_RECS_COUNT	3
> +#define HFSPLUS_BTREE_HDR_USER_BYTES		128
>  
>  /* Some special File ID numbers (stolen from hfs.h) */
>  #define HFSPLUS_POR_CNID		1	/* Parent Of the Root */
> diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c
> index bd8471f..31f70f5 100644
> --- a/fs/hfsplus/xattr.c
> +++ b/fs/hfsplus/xattr.c
> @@ -127,6 +127,69 @@ static int can_set_xattr(struct inode *inode, const char *name,
>  	return 0;
>  }
>  
> +#define SETOFFSET(buf, ndsiz, offset, rec) \
> +	(*(u16 *)((u8 *)(buf) + (ndsiz) + (-2 * (rec))) = (cpu_to_be16(offset)))

This is pretty ghastly.  Can you take a look at reimplementing it in a C
function?  Add any necessary comments to explain what's happening and I
expect you will find that it produces a much nicer result.

I'd also suggest taking a look at the type of `buf' and `bmp'.  They're
never really *used* as char*'s, so why not make them u8* or even void*
and avoid some typecasting?

> +static void hfsplus_init_header_node(struct inode *attr_file,
> +					u32 clump_size,
> +					char *buf, size_t node_size)
> +{
> +	struct hfs_bnode_desc *desc;
> +	struct hfs_btree_header_rec *head;
> +	u16 offset;
> +	u32 hdr_node_map_rec_bits;
> +	char *bmp;
> +	u32 temp;
> +
>
> ...
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 2/3] hfsplus: implement attributes file's header node initialization code
  2013-09-25 22:54 ` Andrew Morton
@ 2013-09-26  0:07   ` Al Viro
  0 siblings, 0 replies; 3+ messages in thread
From: Al Viro @ 2013-09-26  0:07 UTC (permalink / raw)
  To: Andrew Morton
  Cc: slava, Linux FS devel list, Christoph Hellwig, Hin-Tak Leung

On Wed, Sep 25, 2013 at 03:54:39PM -0700, Andrew Morton wrote:

> > +#define SETOFFSET(buf, ndsiz, offset, rec) \
> > +	(*(u16 *)((u8 *)(buf) + (ndsiz) + (-2 * (rec))) = (cpu_to_be16(offset)))
> 
> This is pretty ghastly.  Can you take a look at reimplementing it in a C
> function?  Add any necessary comments to explain what's happening and I
> expect you will find that it produces a much nicer result.

Take a look at the callers - buf and ndsiz remain unchanged, rec runs from
1 to 4.  IOW, what should be done is

	/* last 8 bytes contain offsets */
	__be16 *offsets = (__be16 *)(buf + node_size);
	...
	offset = sizeof(struct hfs_bnode_desc);
	*--offsets = cpu_to_be16(offset);
	...
	offset += sizeof(struct hfs_btree_header_rec);
	*--offsets = cpu_to_be16(offset);
	offset += HFSPLUS_BTREE_HDR_USER_BYTES;
	*--offsets = cpu_to_be16(offset);
	...
	offset += hdr_node_map_rec_bits / 8;
	*--offsets = cpu_to_be16(offset);
and to hell with that macro.

Speaking of another thing in the patch, there's that useful function called
"memset"...

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-09-26  0:07 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-20 10:04 [PATCH 2/3] hfsplus: implement attributes file's header node initialization code Vyacheslav Dubeyko
2013-09-25 22:54 ` Andrew Morton
2013-09-26  0:07   ` Al Viro

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).