[PATCH 1/6] nilfs2: add helper function to go through all entries of meta data file

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <andreas.rohner@xxxxxxx>
---
 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;
+
+	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)
+			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);
+			if (!m)
+				continue;
+
+			ret = nilfs_palloc_get_bitmap_block(
+				inode, group, 0, &bitmap_bh);
+			if (ret == -ENOENT) {
+				ret = 0;
+				goto out_desc;
+			} 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);
+					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 */
-- 
1.9.0

--
To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Filesystem Development]     [Linux BTRFS]     [Linux CIFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux