[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