From: Vyacheslav Dubeyko <slava@dubeyko.com>
To: Linux FS devel list <linux-fsdevel@vger.kernel.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>,
Christoph Hellwig <hch@infradead.org>,
Hin-Tak Leung <htl10@users.sourceforge.net>,
Andrew Morton <akpm@linux-foundation.org>
Subject: [PATCH 2/3] hfsplus: implement attributes file's header node initialization code
Date: Fri, 20 Sep 2013 14:04:09 +0400 [thread overview]
Message-ID: <1379671449.2280.28.camel@slavad-ubuntu> (raw)
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
next reply other threads:[~2013-09-20 10:04 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-09-20 10:04 Vyacheslav Dubeyko [this message]
2013-09-25 22:54 ` [PATCH 2/3] hfsplus: implement attributes file's header node initialization code Andrew Morton
2013-09-26 0:07 ` Al Viro
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=1379671449.2280.28.camel@slavad-ubuntu \
--to=slava@dubeyko.com \
--cc=akpm@linux-foundation.org \
--cc=hch@infradead.org \
--cc=htl10@users.sourceforge.net \
--cc=linux-fsdevel@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
/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).