[Ocfs2-tools-commits] manish commits r797 - in trunk/libocfs2: . include

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Tue Apr 12 17:40:16 CDT 2005


Author: manish
Date: 2005-04-12 17:40:14 -0500 (Tue, 12 Apr 2005)
New Revision: 797

Added:
   trunk/libocfs2/dir_scan.c
   trunk/libocfs2/include/dir_util.h
Modified:
   trunk/libocfs2/Makefile
   trunk/libocfs2/dir_iterate.c
   trunk/libocfs2/include/ocfs2.h
Log:
Add directory scan functions


Modified: trunk/libocfs2/Makefile
===================================================================
--- trunk/libocfs2/Makefile	2005-04-12 22:19:38 UTC (rev 796)
+++ trunk/libocfs2/Makefile	2005-04-12 22:40:14 UTC (rev 797)
@@ -43,55 +43,57 @@
 endif
 
 CFILES = 		\
-	unix_io.c	\
-	memory.c	\
-	openfs.c	\
+	alloc.c		\
+	bitmap.c	\
+	bitops.c	\
+	cached_inode.c	\
+	chain.c		\
+	chainalloc.c	\
+	checkhb.c	\
 	closefs.c	\
+	dirblock.c	\
+	dir_iterate.c	\
+	dir_scan.c	\
+	dlm.c		\
+	fileio.c	\
 	freefs.c	\
+	expanddir.c	\
+	extend_file.c	\
+	extents.c	\
+	extent_map.c	\
 	getsize.c	\
+	heartbeat.c	\
 	inode.c		\
 	inode_scan.c	\
 	ismounted.c	\
-	cached_inode.c	\
-	extent_map.c	\
+	kernel-rbtree.c	\
+	link.c		\
+	lookup.c	\
+	memory.c	\
 	mkjournal.c	\
-	extents.c	\
-	dirblock.c	\
-	dir_iterate.c	\
-	lookup.c	\
+	namei.c		\
+	newdir.c	\
+	openfs.c	\
 	sysfile.c	\
-	link.c		\
-	unlink.c	\
-	bitmap.c	\
-	fileio.c	\
-	chain.c		\
-	chainalloc.c	\
-	alloc.c		\
-	checkhb.c	\
-	kernel-rbtree.c	\
-	bitops.c	\
-	expanddir.c	\
-	newdir.c	\
-	extend_file.c	\
-	namei.c		\
 	truncate.c	\
-	dlm.c		\
-	heartbeat.c
+	unix_io.c	\
+	unlink.c
 
 HFILES =				\
+	include/bitmap.h		\
+	include/bitops.h		\
+	include/byteorder.h		\
+	include/dir_iterate.h		\
+	include/dir_util.h		\
+	include/extent_map.h		\
+	include/jfs_compat.h		\
 	include/jfs_user.h		\
-	include/jfs_compat.h		\
 	include/kernel-jbd.h		\
 	include/kernel-list.h		\
 	include/kernel-rbtree.h		\
+	include/ocfs1_fs_compat.h	\
 	include/ocfs2_fs.h		\
-	include/ocfs1_fs_compat.h	\
-	include/byteorder.h		\
-	include/ocfs2.h			\
-	include/dir_iterate.h		\
-	include/extent_map.h		\
-	include/bitmap.h		\
-	include/bitops.h
+	include/ocfs2.h
 
 HFILES_GEN =		\
 	include/ocfs2_err.h

Modified: trunk/libocfs2/dir_iterate.c
===================================================================
--- trunk/libocfs2/dir_iterate.c	2005-04-12 22:19:38 UTC (rev 796)
+++ trunk/libocfs2/dir_iterate.c	2005-04-12 22:40:14 UTC (rev 797)
@@ -33,6 +33,7 @@
 #include "ocfs2.h"
 
 #include "dir_iterate.h"
+#include "dir_util.h"
 
 /*
  * This function checks to see whether or not a potential deleted
@@ -137,22 +138,6 @@
 				  xlate_func, &xl);
 }
 
-/* make this a helper.. */
-static int is_dots(char *name, unsigned int len)
-{
-	if (len == 0)
-		return 0;
-
-	if (name[0] == '.') {
-		if (len == 1)
-			return 1;
-		if (len == 2 && name[1] == '.')
-			return 1;
-	}
-
-	return 0;
-}
-
 /*
  * Helper function which is private to this module.  Used by
  * ocfs2_dir_iterate() and ocfs2_dblist_dir_iterate()
@@ -193,8 +178,8 @@
 		if (!dirent->inode &&
 		    !(ctx->flags & OCFS2_DIRENT_FLAG_INCLUDE_EMPTY))
 			goto next;
-		if (is_dots(dirent->name, dirent->name_len) && 
-		    (ctx->flags & OCFS2_DIRENT_FLAG_EXCLUDE_DOTS))
+		if ((ctx->flags & OCFS2_DIRENT_FLAG_EXCLUDE_DOTS) &&
+		    is_dots(dirent->name, dirent->name_len))
 			goto next;
 
 		ret = (ctx->func)(ctx->dir,
@@ -300,7 +285,7 @@
 	ocfs2_filesys *fs;
 	ocfs2_dinode *di;
 
-	blkno = OCFS2_SUPER_BLOCK_BLKNO;
+	blkno = 0;
 
 	initialize_ocfs_error_table();
 
@@ -345,6 +330,8 @@
 		goto out_close;
 	}
 
+	if (blkno == 0)
+		blkno = fs->fs_root_blkno;
 
 	ret = ocfs2_read_inode(fs, blkno, buf);
 	if (ret) {

Added: trunk/libocfs2/dir_scan.c
===================================================================
--- trunk/libocfs2/dir_scan.c	2005-04-12 22:19:38 UTC (rev 796)
+++ trunk/libocfs2/dir_scan.c	2005-04-12 22:40:14 UTC (rev 797)
@@ -0,0 +1,312 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dir_scan.c
+ *
+ * Read all the entries in a directory.  For the OCFS2 userspace
+ * library.
+ *
+ * Copyright (C) 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License, version 2,  as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Authors: Manish Singh
+ */
+
+#include <string.h>
+#include <inttypes.h>
+
+#include "ocfs2.h"
+
+#include "dir_util.h"
+
+
+struct _ocfs2_dir_scan {
+	ocfs2_filesys *fs;
+	int flags;
+	char *buf;
+	unsigned int bufsize;
+	unsigned int total_bufsize;
+	ocfs2_cached_inode *inode;
+	uint64_t total_blocks;
+	uint64_t blocks_read;
+	unsigned int offset;
+};
+
+
+static errcode_t get_more_dir_blocks(ocfs2_dir_scan *scan)
+{
+	errcode_t ret;
+	uint64_t blkno;
+	int cblocks;
+
+	if (scan->blocks_read == scan->total_blocks)
+		return OCFS2_ET_ITERATION_COMPLETE;
+
+	ret = ocfs2_extent_map_get_blocks(scan->inode,
+					  scan->blocks_read, 1,
+					  &blkno, &cblocks);
+	if (ret)
+		return ret;
+
+	ret = ocfs2_read_dir_block(scan->fs, blkno, scan->buf);
+	if (ret)
+		return ret;
+
+	scan->blocks_read++;
+
+	scan->bufsize = scan->total_bufsize;
+	scan->offset = 0;
+
+	return 0;
+}
+
+static inline int valid_dirent(ocfs2_dir_scan *scan,
+			       struct ocfs2_dir_entry *dirent)
+{
+	if (dirent->inode) {
+		if ((scan->flags & OCFS2_DIR_SCAN_FLAG_EXCLUDE_DOTS) &&
+		    is_dots(dirent->name, dirent->name_len))
+			return 0;
+		else
+			return 1;
+	}
+
+	return 0;
+}
+
+errcode_t ocfs2_get_next_dir_entry(ocfs2_dir_scan *scan,
+				   struct ocfs2_dir_entry *out_dirent)
+{
+	errcode_t ret;
+	struct ocfs2_dir_entry *dirent;
+
+	do {
+		if (scan->offset == scan->bufsize) {
+			ret = get_more_dir_blocks(scan);
+			if (ret == OCFS2_ET_ITERATION_COMPLETE) {
+				memset(out_dirent, 0,
+				       sizeof(struct ocfs2_dir_entry));
+				return 0;
+			}
+			if (ret)
+				return ret;
+		}
+
+		dirent = (struct ocfs2_dir_entry *) (scan->buf + scan->offset);
+
+		if (((scan->offset + dirent->rec_len) > scan->fs->fs_blocksize) ||
+		    (dirent->rec_len < 8) ||
+		    ((dirent->rec_len % 4) != 0) ||
+		    (((dirent->name_len & 0xFF)+8) > dirent->rec_len))
+			return OCFS2_ET_DIR_CORRUPTED;
+
+		scan->offset += dirent->rec_len;
+	} while (!valid_dirent(scan, dirent));
+
+	memcpy(out_dirent, dirent, sizeof(struct ocfs2_dir_entry));
+
+	return 0;
+}
+
+errcode_t ocfs2_open_dir_scan(ocfs2_filesys *fs, uint64_t dir, int flags,
+			      ocfs2_dir_scan **ret_scan)
+{
+	ocfs2_dir_scan *scan;
+	errcode_t ret;
+
+	ret = ocfs2_check_directory(fs, dir);
+	if (ret)
+		return ret;
+
+	ret = ocfs2_malloc0(sizeof(struct _ocfs2_dir_scan), &scan);
+	if (ret)
+		return ret;
+
+	scan->fs = fs;
+	scan->flags = flags;
+
+	ret = ocfs2_malloc_block(fs->fs_io, &scan->buf);
+	if (ret)
+		goto bail_scan;
+
+	ret = ocfs2_read_cached_inode(fs, dir, &scan->inode);
+	if (ret)
+		goto bail_dir_block;
+
+	ret = ocfs2_extent_map_init(fs, scan->inode);
+	if (ret)
+		goto bail_inode;
+
+	scan->total_blocks =
+		ocfs2_clusters_to_blocks(fs, scan->inode->ci_inode->i_clusters);
+
+	scan->total_bufsize = fs->fs_blocksize;
+
+	*ret_scan = scan;
+
+	return 0;
+
+bail_inode:
+	ocfs2_free_cached_inode(scan->fs, scan->inode);
+
+bail_dir_block:
+	ocfs2_free(&scan->buf);
+
+bail_scan:
+	ocfs2_free(&scan);
+	return ret;
+}
+
+void ocfs2_close_dir_scan(ocfs2_dir_scan *scan)
+{
+	if (!scan)
+		return;
+
+	ocfs2_free_cached_inode(scan->fs, scan->inode);
+	ocfs2_free(&scan->buf);
+	ocfs2_free(&scan);
+
+	return;
+}
+
+
+
+#ifdef DEBUG_EXE
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+static uint64_t read_number(const char *num)
+{
+	uint64_t val;
+	char *ptr;
+
+	val = strtoull(num, &ptr, 0);
+	if (!ptr || *ptr)
+		return 0;
+
+	return val;
+}
+
+static void print_usage(void)
+{
+	fprintf(stderr,
+		"Usage: dir_scan -i <inode_blkno> <filename>\n");
+}
+
+
+extern int opterr, optind;
+extern char *optarg;
+
+int main(int argc, char *argv[])
+{
+	errcode_t ret;
+	char *filename;
+	uint64_t blkno;
+	int c;
+	ocfs2_filesys *fs;
+	ocfs2_dir_scan *scan;
+	int done;
+	struct ocfs2_dir_entry *dirent;
+
+	blkno = 0;
+
+	initialize_ocfs_error_table();
+
+	while ((c = getopt(argc, argv, "i:")) != EOF) {
+		switch (c) {
+			case 'i':
+				blkno = read_number(optarg);
+				if (blkno <= OCFS2_SUPER_BLOCK_BLKNO) {
+					fprintf(stderr,
+						"Invalid inode block: %s\n",
+						optarg);
+					print_usage();
+					return 1;
+				}
+				break;
+
+			default:
+				print_usage();
+				return 1;
+				break;
+		}
+	}
+
+	if (optind >= argc) {
+		fprintf(stderr, "Missing filename\n");
+		print_usage();
+		return 1;
+	}
+	filename = argv[optind];
+	
+	ret = ocfs2_open(filename, OCFS2_FLAG_RO, 0, 0, &fs);
+	if (ret) {
+		com_err(argv[0], ret,
+			"while opening file \"%s\"", filename);
+		goto out;
+	}
+
+	ret = ocfs2_malloc0(sizeof(struct ocfs2_dir_entry), &dirent);
+	if (ret) {
+		com_err(argv[0], ret,
+			"while allocating dirent buffer");
+		goto out_close;
+	}
+
+	if (blkno == 0)
+		blkno = fs->fs_root_blkno;
+
+	ret = ocfs2_open_dir_scan(fs, blkno, 0, &scan);
+	if (ret) {
+		com_err(argv[0], ret,
+			"while opening dir scan");
+		goto out_free;
+	}
+
+	done = 0;
+	while (!done) {
+		ret = ocfs2_get_next_dir_entry(scan, dirent);
+		if (ret) {
+			com_err(argv[0], ret,
+				"while getting next dirent");
+			goto out_close_scan;
+		}
+		if (dirent->rec_len) {
+			dirent->name[dirent->name_len] = '\0';
+			fprintf(stdout, "%s\n", dirent->name);
+		}
+		else
+			done = 1;
+	}
+
+out_close_scan:
+	ocfs2_close_dir_scan(scan);
+
+out_free:
+	ocfs2_free(&dirent);
+
+out_close:
+	ret = ocfs2_close(fs);
+	if (ret) {
+		com_err(argv[0], ret,
+			"while closing file \"%s\"", filename);
+	}
+
+out:
+	return 0;
+}
+#endif  /* DEBUG_EXE */

Added: trunk/libocfs2/include/dir_util.h
===================================================================
--- trunk/libocfs2/include/dir_util.h	2005-04-12 22:19:38 UTC (rev 796)
+++ trunk/libocfs2/include/dir_util.h	2005-04-12 22:40:14 UTC (rev 797)
@@ -0,0 +1,45 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dir_util.h
+ *
+ * Structures for dir iteration for the OCFS2 userspace library.
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License, version 2,  as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Authors: Joel Becker
+ */
+
+#ifndef _DIR_UTIL_H
+#define _DIR_UTIL_H
+
+static inline int is_dots(const char *name, unsigned int len)
+{
+	if (len == 0)
+		return 0;
+
+	if (name[0] == '.') {
+		if (len == 1)
+			return 1;
+		if (len == 2 && name[1] == '.')
+			return 1;
+	}
+
+	return 0;
+}
+
+#endif  /* _DIR_UTIL_H */

Modified: trunk/libocfs2/include/ocfs2.h
===================================================================
--- trunk/libocfs2/include/ocfs2.h	2005-04-12 22:19:38 UTC (rev 796)
+++ trunk/libocfs2/include/ocfs2.h	2005-04-12 22:40:14 UTC (rev 797)
@@ -139,13 +139,15 @@
 #define OCFS2_CHAIN_ABORT	0x02
 #define OCFS2_CHAIN_ERROR	0x04
 
-
 /* Directory constants */
 #define OCFS2_DIRENT_DOT_FILE		1
 #define OCFS2_DIRENT_DOT_DOT_FILE	2
 #define OCFS2_DIRENT_OTHER_FILE		3
 #define OCFS2_DIRENT_DELETED_FILE	4
 
+/* Directory scan flags */
+#define OCFS2_DIR_SCAN_FLAG_EXCLUDE_DOTS	0x01
+
 /* Check if mounted flags */
 #define OCFS2_MF_MOUNTED         0x01
 #define OCFS2_MF_ISROOT          0x02
@@ -169,6 +171,7 @@
 typedef struct _io_channel io_channel;
 typedef struct _ocfs2_extent_map ocfs2_extent_map;
 typedef struct _ocfs2_inode_scan ocfs2_inode_scan;
+typedef struct _ocfs2_dir_scan ocfs2_dir_scan;
 typedef struct _ocfs2_bitmap ocfs2_bitmap;
 typedef struct _ocfs2_nodes ocfs2_nodes;
 typedef struct _ocfs2_devices ocfs2_devices;
@@ -393,6 +396,12 @@
 errcode_t ocfs2_get_next_inode(ocfs2_inode_scan *scan,
 			       uint64_t *blkno, char *inode);
 
+errcode_t ocfs2_open_dir_scan(ocfs2_filesys *fs, uint64_t dir, int flags,
+			      ocfs2_dir_scan **ret_scan);
+void ocfs2_close_dir_scan(ocfs2_dir_scan *scan);
+errcode_t ocfs2_get_next_dir_entry(ocfs2_dir_scan *scan,
+				   struct ocfs2_dir_entry *dirent);
+
 errcode_t ocfs2_cluster_bitmap_new(ocfs2_filesys *fs,
 				   const char *description,
 				   ocfs2_bitmap **ret_bitmap);



More information about the Ocfs2-tools-commits mailing list