[Ocfs2-tools-commits] smushran commits r488 - in trunk: debugfs.ocfs2 debugfs.ocfs2/include libocfs2 libocfs2/include

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Tue Dec 14 17:36:23 CST 2004


Author: smushran
Date: 2004-12-14 17:36:21 -0600 (Tue, 14 Dec 2004)
New Revision: 488

Modified:
   trunk/debugfs.ocfs2/commands.c
   trunk/debugfs.ocfs2/include/main.h
   trunk/debugfs.ocfs2/include/utils.h
   trunk/debugfs.ocfs2/utils.c
   trunk/libocfs2/fileio.c
   trunk/libocfs2/include/ocfs2.h
Log:
ocfs2_file_read added to lib
dump facility added in debugfs

Modified: trunk/debugfs.ocfs2/commands.c
===================================================================
--- trunk/debugfs.ocfs2/commands.c	2004-12-14 23:22:42 UTC (rev 487)
+++ trunk/debugfs.ocfs2/commands.c	2004-12-14 23:36:21 UTC (rev 488)
@@ -127,7 +127,7 @@
 			return &commands[i];
 
 	return NULL;
-}					/* find_command */
+}
 
 /*
  * do_command()
@@ -148,10 +148,10 @@
 	if (command)
 		command->func (args);
 	else
-		printf ("Unrecognized command: %s\n", args[0]);
+		fprintf(stderr, "%s: Unrecognized command\n", args[0]);
 
 	g_strfreev (args);
-}					/* do_command */
+}
 
 /*
  * check_device_open()
@@ -174,56 +174,64 @@
 static int process_inode_args(char **args, uint64_t *blkno)
 {
 	errcode_t ret;
+	char *opts = args[1];
+	char *def = ".";
 
 	if (check_device_open())
 		return -1;
 
-	if (!args[1]) {
-		fprintf(stderr, "usage: %s [filespec]\n", args[0]);
-		return -1;
+	if (!opts) {
+		if (!strncasecmp(args[0], "ls", 2))
+			opts = def;
+		else {
+			fprintf(stderr, "usage: %s <filepath>\n", args[0]);
+			return -1;
+		}
 	}
 
 	ret = string_to_inode(gbls.fs, gbls.root_blkno, gbls.cwd_blkno,
-			      args[1], blkno);
+			      opts, blkno);
 	if (ret) {
-		com_err(gbls.progname, ret, " ");
+		com_err(args[0], ret, " ");
 		return -1;
 	}
 
 	if (*blkno >= gbls.max_blocks) {
-		fprintf(stderr, "Block number is larger than volume size\n");
-		ret = -1;
+		fprintf(stderr, "%s: Block number is larger than volume size\n",
+			args[0]);
+		return -1;
 	}
 
 	return 0;
 }
 
-/* only called by do_dump which is preprocessed out.. */
-#if 0
 /*
- * get_blknum()
+ * process_inodestr_args()
  *
  */
-static errcode_t get_blknum(char *blkstr, uint64_t *blkno)
+static int process_inodestr_args(char **args, uint64_t *blkno)
 {
-	errcode_t ret = OCFS2_ET_INVALID_ARGUMENT;
-	char *endptr;
+	if (check_device_open())
+		return -1;
 
-	if (blkstr) {
-		*blkno = strtoull(blkstr, &endptr, 0);
-		if (!*endptr) {
-			if (*blkno < gbls.max_blocks)
-				ret = 0;
-			else
-				printf("Block number is too large\n");
-		} else
-			printf("Invalid block number\n");
-	} else
-		printf("No block number specified\n");
+	if (!args[1]) {
+		fprintf(stderr, "usage: %s <inode#>\n", args[0]);
+		return -1;
+	}
 
-	return ret;
+	if (inodestr_to_inode(args[1], blkno)) {
+		fprintf(stderr, "usage: %s <inode#>\n", args[0]);
+		return -1;
+	}
+
+	if (*blkno >= gbls.max_blocks) {
+		fprintf(stderr, "%s: Block number is larger than volume size\n",
+			args[0]);
+		return -1;
+	}
+
+	return 0;
 }
-#endif
 
 /*
  * get_nodenum()
@@ -253,7 +261,7 @@
  * traverse_extents()
  *
  */
-static int traverse_extents (ocfs2_filesys *fs, ocfs2_extent_list *el, FILE *out)
+static errcode_t traverse_extents (ocfs2_filesys *fs, ocfs2_extent_list *el, FILE *out)
 {
 	ocfs2_extent_block *eb;
 	ocfs2_extent_rec *rec;
@@ -267,10 +275,8 @@
 		rec = &(el->l_recs[i]);
 		if (el->l_tree_depth) {
 			ret = ocfs2_malloc_block(gbls.fs->fs_io, &buf);
-			if (ret) {
-				com_err(gbls.progname, ret, "while allocating a block");
+			if (ret)
 				goto bail;
-			}
 
 			ret = ocfs2_read_extent_block(fs, rec->e_blkno, buf);
 			if (ret)
@@ -280,7 +286,9 @@
 
 			dump_extent_block (out, eb);
 
-			traverse_extents (fs, &(eb->h_list), out);
+			ret = traverse_extents (fs, &(eb->h_list), out);
+			if (ret)
+				goto bail;
 		}
 	}
 
@@ -288,13 +296,13 @@
 	if (buf)
 		ocfs2_free(&buf);
 	return ret;
-}				/* traverse_extents */
+}
 
 /*
  * traverse_chains()
  *
  */
-static int traverse_chains (ocfs2_filesys *fs, ocfs2_chain_list *cl, FILE *out)
+static errcode_t traverse_chains (ocfs2_filesys *fs, ocfs2_chain_list *cl, FILE *out)
 {
 	ocfs2_group_desc *grp;
 	ocfs2_chain_rec *rec;
@@ -307,10 +315,8 @@
 	dump_chain_list (out, cl);
 
 	ret = ocfs2_malloc_block(gbls.fs->fs_io, &buf);
-	if (ret) {
-		com_err(gbls.progname, ret, "while allocating a block");
+	if (ret)
 		goto bail;
-	}
 
 	for (i = 0; i < cl->cl_next_free_rec; ++i) {
 		rec = &(cl->cl_recs[i]);
@@ -333,7 +339,7 @@
 	if (buf)
 		ocfs2_free(&buf);
 	return ret;
-}				/* traverse_chains */
+}
 
 
 /*
@@ -361,14 +367,14 @@
 	ret = ocfs2_open(dev, flags, 0, 0, &gbls.fs);
 	if (ret) {
 		gbls.fs = NULL;
-		com_err(gbls.progname, ret, "while opening \"%s\"", dev);
+		com_err(args[0], ret, " ");
 		return ;
 	}
 
 	/* allocate blocksize buffer */
 	ret = ocfs2_malloc_block(gbls.fs->fs_io, &gbls.blockbuf);
 	if (ret) {
-		com_err(gbls.progname, ret, "while allocating a block");
+		com_err(args[0], ret, " ");
 		return ;
 	}
 
@@ -405,7 +411,7 @@
 
 	return ;
 	
-}					/* do_open */
+}
 
 /*
  * do_close()
@@ -420,7 +426,7 @@
 
 	ret = ocfs2_close(gbls.fs);
 	if (ret)
-		com_err(gbls.progname, ret, "while closing \"%s\"", gbls.device);
+		com_err(args[0], ret, " ");
 	gbls.fs = NULL;
 
 	if (gbls.blockbuf)
@@ -430,7 +436,7 @@
 	gbls.device = NULL;
 
 	return ;
-}					/* do_close */
+}
 
 /*
  * do_cd()
@@ -446,14 +452,14 @@
 
 	ret = ocfs2_check_directory(gbls.fs, blkno);
 	if (ret) {
-		com_err(gbls.progname, ret, " ");
+		com_err(args[0], ret, " ");
 		return ;
 	}
 
 	gbls.cwd_blkno = blkno;
 
 	return ;
-}					/* do_cd */
+}
 
 /*
  * do_chroot()
@@ -469,7 +475,7 @@
 
 	ret = ocfs2_check_directory(gbls.fs, blkno);
 	if (ret) {
-		com_err(gbls.progname, ret, " ");
+		com_err(args[0], ret, " ");
 		return ;
 	}
 
@@ -493,7 +499,7 @@
 
 	ret = ocfs2_check_directory(gbls.fs, blkno);
 	if (ret) {
-		com_err(gbls.progname, ret, " ");
+		com_err(args[0], ret, " ");
 		return ;
 	}
 
@@ -504,14 +510,12 @@
 	ret = ocfs2_dir_iterate(gbls.fs, blkno, 0, NULL,
 				dump_dir_entry, out);
 	if (ret)
-		com_err(gbls.progname, ret,
-			"while listing inode %"PRIu64" on \"%s\"\n",
-			blkno, gbls.device);
+		com_err(args[0], ret, " ");
 
 	close_pager (out);
 
 	return ;
-}					/* do_ls */
+}
 
 /*
  * do_pwd()
@@ -520,7 +524,7 @@
 static void do_pwd (char **args)
 {
 	printf ("%s\n", __FUNCTION__);
-}					/* do_pwd */
+}
 
 /*
  * do_mkdir()
@@ -529,7 +533,7 @@
 static void do_mkdir (char **args)
 {
 	printf ("%s\n", __FUNCTION__);
-}					/* do_mkdir */
+}
 
 /*
  * do_rmdir()
@@ -538,7 +542,7 @@
 static void do_rmdir (char **args)
 {
 	printf ("%s\n", __FUNCTION__);
-}					/* do_rmdir */
+}
 
 /*
  * do_rm()
@@ -546,8 +550,8 @@
  */
 static void do_rm (char **args)
 {
-  printf ("%s\n", __FUNCTION__);
-}					/* do_rm */
+	printf ("%s\n", __FUNCTION__);
+}
 
 /*
  * do_read()
@@ -556,7 +560,7 @@
 static void do_read (char **args)
 {
 
-}					/* do_read */
+}
 
 /*
  * do_write()
@@ -565,7 +569,7 @@
 static void do_write (char **args)
 {
 
-}					/* do_write */
+}
 
 /*
  * do_help()
@@ -573,26 +577,26 @@
  */
 static void do_help (char **args)
 {
-	printf ("curdev\t\t\tShow current device\n");
-	printf ("open\t\t\tOpen a device\n");
-	printf ("close\t\t\tClose a device\n");
-	printf ("show_super_stats, stats\tShow superblock\n");
-	printf ("show_inode_info, stat\tShow inode\n");
+	printf ("curdev\t\t\t\t\tShow current device\n");
+	printf ("open <device>\t\t\t\tOpen a device\n");
+	printf ("close\t\t\t\t\tClose a device\n");
+	printf ("stats [-h]\t\t\t\tShow superblock\n");
+	printf ("stat <filepath>\t\t\t\tShow inode\n");
 //	printf ("pwd\t\t\t\tPrint working directory\n");
-	printf ("ls\t\t\tList directory\n");
-	printf ("cd\t\t\tChange directory\n");
-	printf ("chroot\t\t\tChange root\n");
+	printf ("ls <filepath>\t\t\t\tList directory\n");
+	printf ("cd <filepath>\t\t\t\tChange directory\n");
+	printf ("chroot <filepath>\t\t\tChange root\n");
 //	printf ("cat <blknum> [outfile]\t\tPrints or concatenates file to stdout/outfile\n");
-//	printf ("dump <blknum> <outfile>\t\tDumps file to outfile\n");
+	printf ("dump [-p] <filepath> <outfile>\t\tDumps file to outfile on a mounted fs\n");
 //	printf ("nodes\t\t\t\tList of nodes\n");
 //	printf ("publish\t\t\t\tPublish blocks\n");
 //	printf ("vote\t\t\t\tVote blocks\n");
-	printf ("logdump\t\t\tPrints journal file for the node\n");
-	printf ("extent\t\t\tShow extent block\n");
-	printf ("group\t\t\tShow chain group\n");
-	printf ("help, ?\t\t\tThis information\n");
-	printf ("quit, q\t\t\tExit the program\n");
-}					/* do_help */
+	printf ("logdump <node#>\t\t\t\tPrints journal file for the node\n");
+	printf ("extent <inode#>\t\t\t\tShow extent block\n");
+	printf ("group <inode#>\t\t\t\tShow chain group\n");
+	printf ("help, ?\t\t\t\t\tThis information\n");
+	printf ("quit, q\t\t\t\t\tExit the program\n");
+}
 
 /*
  * do_quit()
@@ -603,7 +607,7 @@
 	if (gbls.device)
 		do_close (NULL);
 	exit (0);
-}					/* do_quit */
+}
 
 /*
  * do_lcd()
@@ -612,7 +616,7 @@
 static void do_lcd (char **args)
 {
 
-}					/* do_lcd */
+}
 
 /*
  * do_curdev()
@@ -621,7 +625,7 @@
 static void do_curdev (char **args)
 {
 	printf ("%s\n", gbls.device ? gbls.device : "No device");
-}					/* do_curdev */
+}
 
 /*
  * do_super()
@@ -649,7 +653,7 @@
 
 bail:
 	return ;
-}					/* do_super */
+}
 
 /*
  * do_inode()
@@ -669,8 +673,7 @@
 	buf = gbls.blockbuf;
 	ret = ocfs2_read_inode(gbls.fs, blkno, buf);
 	if (ret) {
-		com_err(gbls.progname, ret,
-			"while reading inode in block %"PRIu64, blkno);
+		com_err(args[0], ret, " ");
 		return ;
 	}
 
@@ -682,14 +685,17 @@
 	if ((inode->i_flags & OCFS2_LOCAL_ALLOC_FL))
 		dump_local_alloc(out, &(inode->id2.i_lab));
 	else if ((inode->i_flags & OCFS2_CHAIN_FL))
-		traverse_chains(gbls.fs, &(inode->id2.i_chain), out);
+		ret = traverse_chains(gbls.fs, &(inode->id2.i_chain), out);
 	else
-		traverse_extents(gbls.fs, &(inode->id2.i_list), out);
+		ret = traverse_extents(gbls.fs, &(inode->id2.i_list), out);
 
+	if (ret)
+		com_err(args[0], ret, " ");
+
 	close_pager(out);
 
 	return ;
-}					/* do_inode */
+}
 
 /*
  * do_hb()
@@ -710,7 +716,7 @@
 
 	ret = ocfs2_read_whole_file(gbls.fs, gbls.hb_blkno, &hbbuf, &len);
 	if (ret) {
-		com_err(gbls.progname, ret, "while reading hb file");
+		com_err(args[0], ret, " ");
 		goto bail;
 	}
 
@@ -723,7 +729,7 @@
 		ocfs2_free(&hbbuf);
 
 	return ;
-}					/* do_hb */
+}
 
 /*
  * do_dump()
@@ -731,56 +737,50 @@
  */
 static void do_dump (char **args)
 {
-#if 0
-	uint64_t blkno = 0;
-	int32_t outfd = -1;
-	FILE *out = NULL;
-	int flags;
-	int op = 0;  /* 0 = dump, 1 = cat */
-	char *outfile = NULL;
+	uint64_t blkno;
+	int preserve = 0;
+	int ind;
+	const char *dump_usage = "Usage: dump [-p] <file> <output_file>";
+	char *in_fn;
+	char *out_fn;
 	errcode_t ret;
+	
+	if (check_device_open())
+		return;
 
-	if (!gbls.fs == -1) {
-		printf ("device not open\n");
-		goto bail;
+	ind = 1;
+	if (!args[ind]) {
+		fprintf(stderr, "%s\n", dump_usage);
+		return ;
 	}
 
-	if (!strncasecmp (args[0], "cat", 3)) {
-		out = open_pager ();
-		outfd = fileno(out);
-		op = 1;
+	if (!strncasecmp(args[ind], "-p", 2)) {
+		++preserve;
+		++ind;
 	}
 
-	ret = get_blknum(args[1], &blkno);
-	if (ret)
-		goto bail;
+	in_fn = args[ind];
+	out_fn = args[ind + 1];
 
-	if (args[2]) {
-		outfile = args[2];
-		flags = O_WRONLY| O_CREAT | O_LARGEFILE;
-		flags |= ((op) ? O_APPEND : O_TRUNC);
-		if ((outfd = open (outfile, flags)) == -1) {
-			printf ("unable to open file %s\n", outfile);
-			goto bail;
-		}
+	if (!in_fn || !out_fn) {
+		fprintf(stderr, "usage: dump <file> <output_file>\n");
+		return ;
 	}
-#if 0
-	/* TODO */
-	read_file (gbls.dev_fd, blknum, outfd, NULL);
-#endif
 
-bail:
-	if (out) {
-		close_pager (out);
-		outfd = -1;
+	ret = string_to_inode(gbls.fs, gbls.root_blkno, gbls.cwd_blkno,
+			      in_fn, &blkno);
+	if (ret) {
+		com_err(args[0], ret, " ");
+		return ;
 	}
-	
-	if (outfd > 2)
-		close (outfd);
-#endif
-	return ;
-}					/* do_dump */
 
+	ret = dump_file(gbls.fs, blkno, out_fn, preserve);
+	if (ret)
+		com_err(args[0], ret, " ");
+
+	return;
+}
+
 /*
  * do_journal()
  *
@@ -804,7 +804,7 @@
 
 	ret = ocfs2_read_whole_file(gbls.fs, blkno, &logbuf, &len);
 	if (ret) {
-		com_err(gbls.progname, ret, "while reading journal file");
+		com_err(args[0], ret, " ");
 		goto bail;
 	}
 
@@ -817,7 +817,7 @@
 		ocfs2_free(&logbuf);
 
 	return ;
-}					/* do_journal */
+}
 
 /*
  * do_group()
@@ -832,17 +832,15 @@
 	errcode_t ret = 0;
 	int index = 0;
 
-	if (process_inode_args(args, &blkno))
+	if (process_inodestr_args(args, &blkno))
 		return ;
 
 	buf = gbls.blockbuf;
-
 	out = open_pager();
 	while (blkno) {
 		ret = ocfs2_read_group_desc(gbls.fs, blkno, buf);
 		if (ret) {
-			com_err(gbls.progname, ret,
-				"while reading chain group in block %"PRIu64, blkno);
+			com_err(args[0], ret, " ");
 			close_pager (out);
 			return ;
 		}
@@ -856,7 +854,7 @@
 	close_pager (out);
 
 	return ;
-}					/* do_group */
+}
 
 /*
  * do_extent()
@@ -870,14 +868,13 @@
 	FILE *out;
 	errcode_t ret = 0;
 
-	if (process_inode_args(args, &blkno))
+	if (process_inodestr_args(args, &blkno))
 		return ;
 
 	buf = gbls.blockbuf;
 	ret = ocfs2_read_extent_block(gbls.fs, blkno, buf);
 	if (ret) {
-		com_err(gbls.progname, ret,
-			"while reading extent in block %"PRIu64, blkno);
+		com_err(args[0], ret, " ");
 		return ;
 	}
 
@@ -889,7 +886,7 @@
 	close_pager(out);
 
 	return ;
-}					/* do_extent */
+}
 
 /*
  * handle_signal()
@@ -906,5 +903,4 @@
 	}
 
 	return ;
-}					/* handle_signal */
-
+}

Modified: trunk/debugfs.ocfs2/include/main.h
===================================================================
--- trunk/debugfs.ocfs2/include/main.h	2004-12-14 23:22:42 UTC (rev 487)
+++ trunk/debugfs.ocfs2/include/main.h	2004-12-14 23:36:21 UTC (rev 488)
@@ -47,6 +47,7 @@
 #include <sys/raw.h>
 #include <linux/kdev_t.h>
 #include <inttypes.h>
+#include <utime.h>
 
 #include <glib.h>
 

Modified: trunk/debugfs.ocfs2/include/utils.h
===================================================================
--- trunk/debugfs.ocfs2/include/utils.h	2004-12-14 23:22:42 UTC (rev 487)
+++ trunk/debugfs.ocfs2/include/utils.h	2004-12-14 23:36:21 UTC (rev 488)
@@ -32,7 +32,10 @@
 void get_tag_flag (__u32 flags, GString *str);
 FILE *open_pager(void);
 void close_pager(FILE *stream);
+int inodestr_to_inode(char *str, uint64_t *blkno);
 errcode_t string_to_inode(ocfs2_filesys *fs, uint64_t root_blkno,
 			  uint64_t cwd_blkno, char *str, uint64_t *blkno);
+errcode_t dump_file(ocfs2_filesys *fs, uint64_t ino, char *out_file,
+		    int preserve);
 
 #endif		/* __UTILS_H__ */

Modified: trunk/debugfs.ocfs2/utils.c
===================================================================
--- trunk/debugfs.ocfs2/utils.c	2004-12-14 23:22:42 UTC (rev 487)
+++ trunk/debugfs.ocfs2/utils.c	2004-12-14 23:36:21 UTC (rev 488)
@@ -236,7 +236,29 @@
 	if (stream && stream != stdout) pclose(stream);
 }
 
+/*
+ * inodestr_to_inode()
+ *
+ * Returns ino if string is of the form <ino>
+ *
+ * Copyright (C) 1993, 1994 Theodore Ts'o.  This file may be
+ * redistributed under the terms of the GNU Public License.
+ */
+int inodestr_to_inode(char *str, uint64_t *blkno)
+{
+	int len;
+	char *end;
 
+	len = strlen(str);
+	if ((len > 2) && (str[0] == '<') && (str[len-1] == '>')) {
+		*blkno = strtoul(str+1, &end, 0);
+		if (*end=='>')
+			return 0;
+	}
+
+	return -1;
+}
+
 /*
  * string_to_inode()
  *
@@ -249,19 +271,118 @@
 errcode_t string_to_inode(ocfs2_filesys *fs, uint64_t root_blkno,
 			  uint64_t cwd_blkno, char *str, uint64_t *blkno)
 {
-	int len;
-	char *end;
-
 	/*
 	 * If the string is of the form <ino>, then treat it as an
 	 * inode number.
 	 */
-	len = strlen(str);
-	if ((len > 2) && (str[0] == '<') && (str[len-1] == '>')) {
-		*blkno = strtoul(str+1, &end, 0);
-		if (*end=='>')
-			return 0;
-	}
+	if (!inodestr_to_inode(str, blkno))
+		return 0;
 
 	return ocfs2_namei(fs, root_blkno, cwd_blkno, str, blkno);
 }
+
+/*
+ * fix_perms()
+ *
+ */
+static errcode_t fix_perms(const ocfs2_dinode *di, int *fd, char *out_file)
+{
+	struct utimbuf ut;
+	int i;
+	errcode_t ret = 0;
+
+	i = fchmod(*fd, di->i_mode);
+	if (i == -1) {
+		ret = errno;
+		goto bail;
+	}
+
+	i = fchown(*fd, di->i_uid, di->i_gid);
+	if (i == -1) {
+		ret = errno;
+		goto bail;
+	}
+
+	close(*fd);
+	*fd = -1;
+
+	ut.actime = di->i_atime;
+	ut.modtime = di->i_mtime;
+	if (utime(out_file, &ut) == -1) {
+		ret = errno;
+		goto bail;
+	}
+bail:
+	return ret;
+}
+
+/*
+ * dump_file()
+ *
+ */
+errcode_t dump_file(ocfs2_filesys *fs, uint64_t ino, char *out_file, int preserve)
+{
+	errcode_t ret;
+	char *buf = NULL;
+	int buflen;
+	uint32_t got;
+	uint32_t wrote;
+	ocfs2_cached_inode *ci = NULL;
+	uint64_t offset = 0;
+	uint64_t filesize;
+	int fd = -1;
+
+	fd = open(out_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
+	if (fd < 0) {
+		ret = errno;
+		goto bail;
+	}
+
+	ret = ocfs2_read_cached_inode(fs, ino, &ci);
+	if (ret)
+		goto bail;
+
+	ret = ocfs2_extent_map_init(fs, ci);
+	if (ret)
+		goto bail;
+
+	buflen = fs->fs_clustersize;
+
+	ret = ocfs2_malloc_blocks(fs->fs_io,
+				  (buflen >>
+				   OCFS2_RAW_SB(fs->fs_super)->s_blocksize_bits),
+				  &buf);
+	if (ret)
+		goto bail;
+
+	filesize = ci->ci_inode->i_size;
+
+	while (filesize) {
+		ret = ocfs2_file_read(ci, buf, buflen, offset, &got);
+		if (ret)
+			goto bail;
+
+		if (filesize < got)
+			got = filesize;
+
+		wrote = write(fd, buf, got);
+		if (wrote != got) {
+			ret = errno;
+			goto bail;
+		}
+		offset += got;
+		filesize -= got;
+	}
+
+	if (preserve)
+		ret = fix_perms(ci->ci_inode, &fd, out_file);
+
+bail:
+	if (fd > 0)
+		close(fd);
+	if (buf)
+		ocfs2_free(&buf);
+	if (ci)
+		ocfs2_free_cached_inode(fs, ci);
+	return ret;
+}

Modified: trunk/libocfs2/fileio.c
===================================================================
--- trunk/libocfs2/fileio.c	2004-12-14 23:22:42 UTC (rev 487)
+++ trunk/libocfs2/fileio.c	2004-12-14 23:36:21 UTC (rev 488)
@@ -120,6 +120,54 @@
 	return ctx.errcode;
 }
 
+
+errcode_t ocfs2_file_read(ocfs2_cached_inode *ci, void *buf, uint32_t count,
+			  uint64_t offset, uint32_t *got)
+{
+	ocfs2_filesys	*fs = ci->ci_fs;
+	errcode_t	ret = 0;
+	char		*ptr = (char *) buf;
+	uint32_t	wanted_blocks;
+	uint32_t	contig_blocks;
+	uint64_t	v_blkno;
+	uint64_t	p_blkno;
+	uint32_t	tmp;
+
+	/* o_direct requires aligned io */
+	tmp = fs->fs_blocksize - 1;
+	if ((count & tmp) || (offset & (uint64_t)tmp) || ((uint32_t)ptr & tmp))
+		return OCFS2_ET_INVALID_ARGUMENT;
+
+	wanted_blocks = count >> OCFS2_RAW_SB(fs->fs_super)->s_blocksize_bits;
+	v_blkno = offset >> OCFS2_RAW_SB(fs->fs_super)->s_blocksize_bits;
+	*got = 0;
+
+	while(wanted_blocks) {
+		ret = ocfs2_extent_map_get_blocks(ci, v_blkno, 1,
+						  &p_blkno, &contig_blocks);
+		if (ret)
+			return ret;
+
+		if (contig_blocks > wanted_blocks)
+			contig_blocks = wanted_blocks;
+
+		ret = io_read_block(fs->fs_io, p_blkno, contig_blocks, ptr);
+		if (ret)
+			return ret;
+
+		tmp = contig_blocks << OCFS2_RAW_SB(fs->fs_super)->s_blocksize_bits;
+		*got += tmp;
+		wanted_blocks -= contig_blocks;
+
+		if (wanted_blocks) {
+			ptr += tmp;
+			v_blkno += (uint64_t)contig_blocks;
+		}
+	}
+
+	return ret;
+}
+
 /*
  * FIXME: port the reset of e2fsprogs/lib/ext2fs/fileio.c
  */

Modified: trunk/libocfs2/include/ocfs2.h
===================================================================
--- trunk/libocfs2/include/ocfs2.h	2004-12-14 23:22:42 UTC (rev 487)
+++ trunk/libocfs2/include/ocfs2.h	2004-12-14 23:36:21 UTC (rev 488)
@@ -525,6 +525,9 @@
 errcode_t ocfs2_follow_link(ocfs2_filesys *fs, uint64_t root, uint64_t cwd,
 			    uint64_t inode, uint64_t *res_inode);
 
+errcode_t ocfs2_file_read(ocfs2_cached_inode *ci, void *buf, uint32_t count,
+			  uint64_t offset, uint32_t *got);
+
 /* 
  * ${foo}_to_${bar} is a floor function.  blocks_to_clusters will
  * returns the cluster that contains a block, not the number of clusters



More information about the Ocfs2-tools-commits mailing list