On Sun, 2014-03-16 at 11:47 +0100, Andreas Rohner wrote:
> This patch introduces the nilfs_palloc_scan_entries() function,
> which takes an inode of one of nilfs' meta data files and iterates
> through all of its entries. For each entry the callback function
> pointer that is given as a parameter is called. The data parameter
> is passed to the callback function, so that it may receive
> parameters and return results.
>
> Signed-off-by: Andreas Rohner <[email protected]>
> ---
> fs/nilfs2/alloc.c | 121
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> fs/nilfs2/alloc.h | 6 +++
> 2 files changed, 127 insertions(+)
>
> diff --git a/fs/nilfs2/alloc.c b/fs/nilfs2/alloc.c
> index 741fd02..0edd85a 100644
> --- a/fs/nilfs2/alloc.c
> +++ b/fs/nilfs2/alloc.c
> @@ -545,6 +545,127 @@ int nilfs_palloc_prepare_alloc_entry(struct inode
> *inode,
> }
>
> /**
> + * nilfs_palloc_scan_entries - scan through every entry and execute dofunc
> + * @inode: inode of metadata file using this allocator
> + * @dofunc: function executed for every entry
> + * @data: data pointer passed to dofunc
> + *
> + * Description: nilfs_palloc_scan_entries() walks through every allocated
> entry
> + * of a metadata file and executes dofunc on it. It passes a data pointer to
> + * dofunc, which can be used as an input parameter or for returning of
> results.
> + *
> + * Return Value: On success, 0 is returned. On error, a
> + * negative error code is returned.
> + */
> +int nilfs_palloc_scan_entries(struct inode *inode,
> + void (*dofunc)(struct inode *,
> + struct nilfs_palloc_req *,
> + void *),
> + void *data)
> +{
> + struct buffer_head *desc_bh, *bitmap_bh;
> + struct nilfs_palloc_group_desc *desc;
> + struct nilfs_palloc_req req;
> + unsigned char *bitmap;
> + void *desc_kaddr, *bitmap_kaddr;
> + unsigned long group, maxgroup, ngroups;
> + unsigned long n, m, entries_per_group, groups_per_desc_block;
> + unsigned long i, j, pos;
> + unsigned long blkoff, prev_blkoff;
> + int ret;
> +
I think that it really makes sense to split this function's code between
several small functions. It improves code style and readability of
function. Moreover, it makes function more easy understandable.
> + ngroups = nilfs_palloc_groups_count(inode);
> + maxgroup = ngroups - 1;
> + entries_per_group = nilfs_palloc_entries_per_group(inode);
> + groups_per_desc_block = nilfs_palloc_groups_per_desc_block(inode);
> +
> + for (group = 0; group < ngroups;) {
> + ret = nilfs_palloc_get_desc_block(inode, group, 0, &desc_bh);
> + if (ret == -ENOENT)
I suggest to add comment here.
> + return 0;
> + else if (ret < 0)
> + return ret;
> + req.pr_desc_bh = desc_bh;
> + desc_kaddr = kmap(desc_bh->b_page);
> + desc = nilfs_palloc_block_get_group_desc(inode, group,
> + desc_bh, desc_kaddr);
> + n = nilfs_palloc_rest_groups_in_desc_block(inode, group,
> + maxgroup);
> +
> + for (i = 0; i < n; i++, desc++, group++) {
> + m = entries_per_group -
> + nilfs_palloc_group_desc_nfrees(inode,
> + group, desc);
Looks weird. It makes sense to split on several functions or to use
variable.
> + if (!m)
> + continue;
> +
> + ret = nilfs_palloc_get_bitmap_block(
> + inode, group, 0, &bitmap_bh);
Ditto. Looks weird.
> + if (ret == -ENOENT) {
> + ret = 0;
> + goto out_desc;
It needs to add comment here. Otherwise, it looks weird because anyway
we go to out_desc. Maybe to combine:
if (unlikely(ret < 0)) {
if (ret == -ENOENT)
ret = 0;
goto out_desc;
}
Anyway, it needs to comment why we assign zero for the case of -ENOENT.
> + } else if (ret < 0)
> + goto out_desc;
> +
> + req.pr_bitmap_bh = bitmap_bh;
> + bitmap_kaddr = kmap(bitmap_bh->b_page);
> + bitmap = bitmap_kaddr + bh_offset(bitmap_bh);
> + /* entry blkoff is always bigger than 0 */
> + blkoff = 0;
> + pos = 0;
> +
> + for (j = 0; j < m; ++j, ++pos) {
> + pos = nilfs_find_next_bit(bitmap,
> + entries_per_group, pos);
> +
> + if (pos >= entries_per_group)
> + break;
> +
> + /* found an entry */
> + req.pr_entry_nr =
> + entries_per_group * group + pos;
> +
> + prev_blkoff = blkoff;
> + blkoff = nilfs_palloc_entry_blkoff(inode,
> + req.pr_entry_nr);
> +
> + if (blkoff != prev_blkoff) {
> + if (prev_blkoff)
> + brelse(req.pr_entry_bh);
> +
> + ret = nilfs_palloc_get_entry_block(
> + inode, req.pr_entry_nr,
> + 0, &req.pr_entry_bh);
Ahhhh. Look weird. :) Split on small functions with clear names, anyway.
It really improves the code from any point of view.
Thanks,
Vyacheslav Dubeyko.
> + if (ret < 0)
> + goto out_entry;
> + }
> +
> + dofunc(inode, &req, data);
> + }
> +
> + if (blkoff)
> + brelse(req.pr_entry_bh);
> + kunmap(bitmap_bh->b_page);
> + brelse(bitmap_bh);
> + }
> +
> + kunmap(desc_bh->b_page);
> + brelse(desc_bh);
> + }
> +
> + return 0;
> +
> +out_entry:
> + kunmap(bitmap_bh->b_page);
> + brelse(bitmap_bh);
> +
> +out_desc:
> + kunmap(desc_bh->b_page);
> + brelse(desc_bh);
> + return ret;
> +}
> +
> +/**
> * nilfs_palloc_commit_alloc_entry - finish allocation of a persistent object
> * @inode: inode of metadata file using this allocator
> * @req: nilfs_palloc_req structure exchanged for the allocation
> diff --git a/fs/nilfs2/alloc.h b/fs/nilfs2/alloc.h
> index 4bd6451..0592035 100644
> --- a/fs/nilfs2/alloc.h
> +++ b/fs/nilfs2/alloc.h
> @@ -77,6 +77,7 @@ int nilfs_palloc_freev(struct inode *, __u64 *, size_t);
> #define nilfs_set_bit_atomic ext2_set_bit_atomic
> #define nilfs_clear_bit_atomic ext2_clear_bit_atomic
> #define nilfs_find_next_zero_bit find_next_zero_bit_le
> +#define nilfs_find_next_bit find_next_bit_le
>
> /**
> * struct nilfs_bh_assoc - block offset and buffer head association
> @@ -106,5 +107,10 @@ void nilfs_palloc_setup_cache(struct inode *inode,
> struct nilfs_palloc_cache *cache);
> void nilfs_palloc_clear_cache(struct inode *inode);
> void nilfs_palloc_destroy_cache(struct inode *inode);
> +int nilfs_palloc_scan_entries(struct inode *,
> + void (*dofunc)(struct inode *,
> + struct nilfs_palloc_req *,
> + void *),
> + void *);
>
> #endif /* _NILFS_ALLOC_H */
--
To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html