From: Vyacheslav Dubeyko <slava@xxxxxxxxxxx> Subject: [PATCH v2 08/15] hfsplus: introduce descriptor of block list buffer One block list (binfo array) can have size from 4KB till 16KB. Thereby, block list can be placed in several file system blocks. This patch introduces special structure that it incapsulates all necessary details and buffer's pointers for passing through binfo array, check binfo and replay transactions' blocks. Also, the patch implements functions that initialize and deinitialize hfsplus_blist_desc structure. Signed-off-by: Vyacheslav Dubeyko <slava@xxxxxxxxxxx> CC: Al Viro <viro@xxxxxxxxxxxxxxxxxx> CC: Christoph Hellwig <hch@xxxxxxxxxxxxx> CC: Hin-Tak Leung <htl10@xxxxxxxxxxxxxxxxxxxxx> --- fs/hfsplus/journal.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/fs/hfsplus/journal.c b/fs/hfsplus/journal.c index b4d059e..b81dc33 100644 --- a/fs/hfsplus/journal.c +++ b/fs/hfsplus/journal.c @@ -50,6 +50,30 @@ (le32_to_cpu(((struct hfsplus_journal_header *)(jh))->jhdr_size)) /* + * struct hfsplus_blist_desc - descriptor of block list buffer + * @start_sec: start sector of block list + * @cur_sec: current sector of block list + * @cur_index: start block index for current sector + * @available_bytes: how many bytes of block list does contain buffer? + * @blist_buf: buffer for current part of block list + * @binfo: pointer on binfo[0] + * @blhdr: cached copy of block list header + * @src_buf: pointer on source block in journal buffer + * @dst_buf: pointer on buffer for destination block + */ +struct hfsplus_blist_desc { + sector_t start_sec; + sector_t cur_sec; + u16 cur_index; + size_t available_bytes; + void *blist_buf; + struct hfsplus_block_info *binfo; + struct hfsplus_blhdr blhdr; + void *src_buf; + void *dst_buf; +}; + +/* * We want at least 8 megs of journal for each 100 gigs of * disk space. We cap the size at 512 megs (64x default), unless * the allocation block size is larger, in which case we use one @@ -227,6 +251,50 @@ static int hfsplus_create_journal(struct super_block *sb, return 0; } +static void hfsplus_deinit_block_list_desc(struct hfsplus_blist_desc *desc); + +static int hfsplus_init_block_list_desc(struct super_block *sb, + struct hfsplus_blist_desc *desc) +{ + int err; + + memset((void *)desc, 0, sizeof(*desc)); + + desc->blist_buf = kmalloc(hfsplus_min_io_size(sb), GFP_KERNEL); + if (unlikely(!desc->blist_buf)) { + pr_err("unable to allocate blist_buf\n"); + err = -ENOMEM; + goto failed_init; + } + + desc->src_buf = kmalloc(hfsplus_min_io_size(sb), GFP_KERNEL); + if (unlikely(!desc->src_buf)) { + pr_err("unable to allocate src_buf\n"); + err = -ENOMEM; + goto failed_init; + } + + desc->dst_buf = kmalloc(hfsplus_min_io_size(sb), GFP_KERNEL); + if (unlikely(!desc->dst_buf)) { + pr_err("unable to allocate dst_buf\n"); + err = -ENOMEM; + goto failed_init; + } + + return 0; + +failed_init: + hfsplus_deinit_block_list_desc(desc); + return err; +} + +static void hfsplus_deinit_block_list_desc(struct hfsplus_blist_desc *desc) +{ + kfree(desc->blist_buf); + kfree(desc->src_buf); + kfree(desc->dst_buf); +} + static inline bool hfsplus_journal_empty(struct hfsplus_journal_header *jh) { -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html