[Ocfs2-tools-commits] smushran commits r479 - in trunk:
debugfs.ocfs2 debugfs.ocfs2/include libocfs2 libocfs2/include
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Fri Dec 10 20:28:27 CST 2004
Author: smushran
Date: 2004-12-10 20:28:25 -0600 (Fri, 10 Dec 2004)
New Revision: 479
Added:
trunk/libocfs2/namei.c
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/Makefile
trunk/libocfs2/include/ocfs2.h
trunk/libocfs2/ocfs2_err.et.in
Log:
namei.c added in libocfs2 to parse pathnames
ls/cd/chroot added in debugfs
Modified: trunk/debugfs.ocfs2/commands.c
===================================================================
--- trunk/debugfs.ocfs2/commands.c 2004-12-11 02:10:10 UTC (rev 478)
+++ trunk/debugfs.ocfs2/commands.c 2004-12-11 02:28:25 UTC (rev 479)
@@ -62,6 +62,7 @@
static void do_journal (char **args);
static void do_group (char **args);
static void do_extent (char **args);
+static void do_chroot (char **args);
extern gboolean allow_write;
@@ -74,6 +75,7 @@
{ "cd", do_cd },
{ "ls", do_ls },
{ "pwd", do_pwd },
+ { "chroot", do_chroot },
{ "mkdir", do_mkdir },
{ "rmdir", do_rmdir },
@@ -152,6 +154,51 @@
} /* do_command */
/*
+ * check_device_open()
+ *
+ */
+static int check_device_open(void)
+{
+ if (!gbls.fs) {
+ fprintf(stderr, "Device not open\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * process_inode_args()
+ *
+ */
+static int process_inode_args(char **args, uint64_t *blkno)
+{
+ errcode_t ret;
+
+ if (check_device_open())
+ return -1;
+
+ if (!args[1]) {
+ fprintf(stderr, "usage: %s [filespec]\n", args[0]);
+ return -1;
+ }
+
+ ret = string_to_inode(gbls.fs, gbls.root_blkno, gbls.cwd_blkno,
+ args[1], blkno);
+ if (ret) {
+ com_err(gbls.progname, ret, "");
+ return -1;
+ }
+
+ if (*blkno >= gbls.max_blocks) {
+ fprintf(stderr, "Block number is larger than volume size\n");
+ ret = -1;
+ }
+
+ return 0;
+}
+
+/*
* get_blknum()
*
*/
@@ -179,25 +226,24 @@
* get_nodenum()
*
*/
-static errcode_t get_nodenum(char *nodestr, uint16_t *nodenum)
+static int get_nodenum(char **args, uint16_t *nodenum)
{
- errcode_t ret = OCFS2_ET_INVALID_ARGUMENT;
ocfs2_super_block *sb = OCFS2_RAW_SB(gbls.fs->fs_super);
char *endptr;
- if (nodestr) {
- *nodenum = strtoul(nodestr, &endptr, 0);
+ if (args[1]) {
+ *nodenum = strtoul(args[1], &endptr, 0);
if (!*endptr) {
if (*nodenum < sb->s_max_nodes)
- ret = 0;
+ return 0;
else
- printf("node number is too large\n");
+ fprintf(stderr, "Node number is too large\n");
} else
- printf("Invalid node number\n");
+ fprintf(stderr, "usage: %s [nodenum]\n", args[0]);
} else
- printf("no node number specified\n");
+ fprintf(stderr, "usage: %s [nodenum]\n", args[0]);
- return ret;
+ return -1;
}
/*
@@ -304,8 +350,8 @@
do_close (NULL);
if (dev == NULL) {
- printf ("no device specified\n");
- goto bail;
+ fprintf (stderr, "usage: %s [device]\n", args[0]);
+ return ;
}
flags = allow_write ? OCFS2_FLAG_RW : OCFS2_FLAG_RO;
@@ -313,14 +359,14 @@
if (ret) {
gbls.fs = NULL;
com_err(gbls.progname, ret, "while opening \"%s\"", dev);
- goto bail;
+ 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");
- goto bail;
+ return ;
}
sb = OCFS2_RAW_SB(gbls.fs->fs_super);
@@ -331,10 +377,10 @@
gbls.max_blocks = ocfs2_clusters_to_blocks(gbls.fs, gbls.max_clusters);
gbls.root_blkno = sb->s_root_blkno;
gbls.sysdir_blkno = sb->s_system_dir_blkno;
- gbls.curdir_blkno = sb->s_root_blkno;
- if (gbls.curdir)
- free(gbls.curdir);
- gbls.curdir = strdup("/");
+ gbls.cwd_blkno = sb->s_root_blkno;
+ if (gbls.cwd)
+ free(gbls.cwd);
+ gbls.cwd = strdup("/");
/* lookup heartbeat file */
snprintf (sysfile, sizeof(sysfile),
@@ -354,7 +400,6 @@
gbls.jrnl_blkno[i] = 0;
}
-bail:
return ;
} /* do_open */
@@ -367,10 +412,8 @@
{
errcode_t ret = 0;
- if (!gbls.device) {
- printf ("device not open\n");
+ if (check_device_open())
return ;
- }
ret = ocfs2_close(gbls.fs);
if (ret)
@@ -392,61 +435,76 @@
*/
static void do_cd (char **args)
{
+ uint64_t blkno;
+ errcode_t ret;
+ if (process_inode_args(args, &blkno))
+ return ;
+
+ ret = ocfs2_check_directory(gbls.fs, blkno);
+ if (ret) {
+ com_err(gbls.progname, ret, "");
+ return ;
+ }
+
+ gbls.cwd_blkno = blkno;
+
+ return ;
} /* do_cd */
/*
+ * do_chroot()
+ *
+ */
+static void do_chroot (char **args)
+{
+ uint64_t blkno;
+ errcode_t ret;
+
+ if (process_inode_args(args, &blkno))
+ return ;
+
+ ret = ocfs2_check_directory(gbls.fs, blkno);
+ if (ret) {
+ com_err(gbls.progname, ret, "");
+ return ;
+ }
+
+ gbls.root_blkno = blkno;
+
+ return ;
+}
+
+/*
* do_ls()
*
*/
static void do_ls (char **args)
{
- ocfs2_dinode *di;
uint64_t blkno;
- char *buf = NULL;
FILE *out = NULL;
errcode_t ret = 0;
- if (!gbls.fs) {
- printf ("device not open\n");
- goto bail;
- }
+ if (process_inode_args(args, &blkno))
+ return ;
- if (args[1]) {
- ret = get_blknum(args[1], &blkno);
- if (ret)
- goto bail;
- } else
- blkno = gbls.curdir_blkno;
-
- buf = gbls.blockbuf;
- ret = ocfs2_read_inode(gbls.fs, blkno, buf);
+ ret = ocfs2_check_directory(gbls.fs, blkno);
if (ret) {
- com_err(gbls.progname, ret, "while reading inode %"PRIu64, blkno);
- goto bail;
+ com_err(gbls.progname, ret, "");
+ return ;
}
- di = (ocfs2_dinode *)buf;
-
- if (!S_ISDIR(di->i_mode)) {
- printf("Not a dir\n");
- goto bail;
- }
-
out = open_pager ();
fprintf(out, "\t%-15s %-4s %-4s %-2s %-4s\n",
"Inode", "Rlen", "Nlen", "Ty", "Name");
ret = ocfs2_dir_iterate(gbls.fs, blkno, 0, NULL,
dump_dir_entry, out);
- if (ret) {
+ if (ret)
com_err(gbls.progname, ret,
"while listing inode %"PRIu64" on \"%s\"\n",
blkno, gbls.device);
- goto bail;
- }
-bail:
close_pager (out);
return ;
@@ -458,7 +516,7 @@
*/
static void do_pwd (char **args)
{
- printf ("%s\n", gbls.curdir ? gbls.curdir : "No dir");
+ printf ("%s\n", __FUNCTION__);
} /* do_pwd */
/*
@@ -512,23 +570,25 @@
*/
static void do_help (char **args)
{
- printf ("curdev\t\t\t\tShow current device\n");
- printf ("open <device>\t\t\tOpen a device\n");
- printf ("close\t\t\t\tClose a device\n");
- printf ("show_super_stats, stats [-h]\tShow superblock\n");
- printf ("show_inode_info, stat <blknum>\tShow inode\n");
- printf ("pwd\t\t\t\tPrint working directory\n");
- printf ("ls <blknum>\t\t\tList directory\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 ("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 <nodenum>\t\tPrints journal file for the node\n");
- printf ("extent <blknum>\t\t\tShow extent block\n");
- printf ("group <blknum>\t\t\tShow chain group\n");
- printf ("help, ?\t\t\t\tThis information\n");
- printf ("quit, q\t\t\t\tExit the program\n");
+ 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 ("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 ("cat <blknum> [outfile]\t\tPrints or concatenates file to stdout/outfile\n");
+// printf ("dump <blknum> <outfile>\t\tDumps file to outfile\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 */
/*
@@ -571,10 +631,8 @@
ocfs2_dinode *in;
ocfs2_super_block *sb;
- if (!gbls.fs) {
- printf ("device not open\n");
+ if (check_device_open())
goto bail;
- }
out = open_pager ();
in = gbls.fs->fs_super;
@@ -602,21 +660,15 @@
FILE *out;
errcode_t ret = 0;
- if (!gbls.fs) {
- printf ("device not open\n");
- goto bail;
- }
+ if (process_inode_args(args, &blkno))
+ return ;
- ret = get_blknum(args[1], &blkno);
- if (ret)
- goto bail;
-
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);
- goto bail;
+ return ;
}
inode = (ocfs2_dinode *)buf;
@@ -633,8 +685,6 @@
close_pager(out);
-bail:
-
return ;
} /* do_inode */
@@ -650,10 +700,8 @@
errcode_t ret;
void (*dump_func) (FILE *out, char *buf);
- if (!gbls.fs) {
- printf ("device not open\n");
- goto bail;
- }
+ if (check_device_open())
+ return ;
DBGFS_FATAL("internal");
@@ -680,6 +728,7 @@
*/
static void do_dump (char **args)
{
+#if 0
uint64_t blkno = 0;
int32_t outfd = -1;
FILE *out = NULL;
@@ -725,7 +774,7 @@
if (outfd > 2)
close (outfd);
-
+#endif
return ;
} /* do_dump */
@@ -742,14 +791,11 @@
uint16_t nodenum;
errcode_t ret = 0;
- if (!gbls.fs) {
- printf ("device not open\n");
- goto bail;
- }
+ if (check_device_open())
+ return ;
- ret = get_nodenum(args[1], &nodenum);
- if (ret)
- goto bail;
+ if (get_nodenum(args, &nodenum))
+ return ;
blkno = gbls.jrnl_blkno[nodenum];
@@ -783,15 +829,9 @@
errcode_t ret = 0;
int index = 0;
- if (!gbls.fs) {
- printf ("device not open\n");
- goto bail;
- }
+ if (process_inode_args(args, &blkno))
+ return ;
- ret = get_blknum(args[1], &blkno);
- if (ret)
- goto bail;
-
buf = gbls.blockbuf;
out = open_pager();
@@ -800,7 +840,8 @@
if (ret) {
com_err(gbls.progname, ret,
"while reading chain group in block %"PRIu64, blkno);
- goto close;
+ close_pager (out);
+ return ;
}
grp = (ocfs2_group_desc *)buf;
@@ -808,9 +849,8 @@
blkno = grp->bg_next_group;
index++;
}
-close:
+
close_pager (out);
-bail:
return ;
} /* do_group */
@@ -827,37 +867,24 @@
FILE *out;
errcode_t ret = 0;
- if (!gbls.fs) {
- printf ("device not open\n");
- goto bail;
- }
+ if (process_inode_args(args, &blkno))
+ return ;
- ret = get_blknum(args[1], &blkno);
- if (ret)
- goto bail;
-
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);
- goto bail;
+ return ;
}
eb = (ocfs2_extent_block *)buf;
- if (memcmp(eb->h_signature, OCFS2_EXTENT_BLOCK_SIGNATURE,
- sizeof(OCFS2_EXTENT_BLOCK_SIGNATURE))) {
- printf("Not an extent block\n");
- goto bail;
- }
out = open_pager();
dump_extent_block(out, eb);
dump_extent_list(out, &eb->h_list);
close_pager(out);
-bail:
-
return ;
} /* do_extent */
Modified: trunk/debugfs.ocfs2/include/main.h
===================================================================
--- trunk/debugfs.ocfs2/include/main.h 2004-12-11 02:10:10 UTC (rev 478)
+++ trunk/debugfs.ocfs2/include/main.h 2004-12-11 02:28:25 UTC (rev 479)
@@ -69,8 +69,8 @@
char *progname;
char *device;
ocfs2_filesys *fs;
- char *curdir;
- uint64_t curdir_blkno;
+ char *cwd;
+ uint64_t cwd_blkno;
char *blockbuf;
uint64_t max_clusters;
uint64_t max_blocks;
Modified: trunk/debugfs.ocfs2/include/utils.h
===================================================================
--- trunk/debugfs.ocfs2/include/utils.h 2004-12-11 02:10:10 UTC (rev 478)
+++ trunk/debugfs.ocfs2/include/utils.h 2004-12-11 02:28:25 UTC (rev 479)
@@ -26,13 +26,13 @@
#ifndef __UTILS_H__
#define __UTILS_H__
-void add_extent_rec (GArray *arr, ocfs2_extent_rec *rec);
-void add_dir_rec (GArray *arr, struct ocfs2_dir_entry *rec);
void get_vote_flag (__u32 flag, GString *str);
void get_publish_flag (__u32 flag, GString *str);
void get_journal_blktyp (__u32 jtype, GString *str);
void get_tag_flag (__u32 flags, GString *str);
FILE *open_pager(void);
void close_pager(FILE *stream);
+errcode_t string_to_inode(ocfs2_filesys *fs, uint64_t root_blkno,
+ uint64_t cwd_blkno, char *str, uint64_t *blkno);
#endif /* __UTILS_H__ */
Modified: trunk/debugfs.ocfs2/utils.c
===================================================================
--- trunk/debugfs.ocfs2/utils.c 2004-12-11 02:10:10 UTC (rev 478)
+++ trunk/debugfs.ocfs2/utils.c 2004-12-11 02:28:25 UTC (rev 479)
@@ -26,54 +26,6 @@
#include <main.h>
/*
- * add_extent_rec()
- *
- */
-void add_extent_rec (GArray *arr, ocfs2_extent_rec *rec)
-{
- ocfs2_extent_rec *new;
-
- if (!arr)
- return ;
-
- if (!(new = malloc(sizeof(ocfs2_extent_rec))))
- DBGFS_FATAL("%s", strerror(errno));
-
- memcpy(new, rec, sizeof(ocfs2_extent_rec));
- g_array_append_vals(arr, new, 1);
-
- return ;
-} /* add_extent_rec */
-
-/*
- * add_dir_rec()
- *
- */
-void add_dir_rec (GArray *arr, struct ocfs2_dir_entry *rec)
-{
- struct ocfs2_dir_entry *new;
-
- if (!arr)
- return ;
-
- if (!(new = malloc(sizeof(struct ocfs2_dir_entry))))
- DBGFS_FATAL("%s", strerror(errno));
-
- memset(new, 0, sizeof(struct ocfs2_dir_entry));
-
- new->inode = rec->inode;
- new->rec_len = rec->rec_len;
- new->name_len = rec->name_len;
- new->file_type = rec->file_type;
- strncpy(new->name, rec->name, rec->name_len);
- new->name[rec->name_len] = '\0';
-
- g_array_append_vals(arr, new, 1);
-
- return ;
-} /* add_dir_rec */
-
-/*
* get_vote_flag()
*
*/
@@ -103,7 +55,7 @@
g_string_append (str, "none");
return ;
-} /* get_vote_flag */
+}
/*
* get_publish_flag()
@@ -189,7 +141,7 @@
g_string_append (str, "none");
return ;
-} /* get_publish_flag */
+}
/*
* get_journal_blktyp()
@@ -219,7 +171,7 @@
g_string_append (str, "none");
return ;
-} /* get_journal_blktyp */
+}
/*
* get_tag_flag()
@@ -246,7 +198,7 @@
done:
return ;
-} /* get_tag_flag */
+}
/*
* open_pager() -- copied from e2fsprogs-1.32/debugfs/util.c
@@ -271,7 +223,7 @@
outfile = popen(pager, "w");
return (outfile ? outfile : stdout);
-} /* open_pager */
+}
/*
* close_pager() -- copied from e2fsprogs-1.32/debugfs/util.c
@@ -282,4 +234,34 @@
void close_pager(FILE *stream)
{
if (stream && stream != stdout) pclose(stream);
-} /* close_pager */
+}
+
+
+/*
+ * string_to_inode()
+ *
+ * This routine is used whenever a command needs to turn a string into
+ * an inode.
+ *
+ * Copyright (C) 1993, 1994 Theodore Ts'o. This file may be
+ * redistributed under the terms of the GNU Public License.
+ */
+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;
+ }
+
+ return ocfs2_namei(fs, root_blkno, cwd_blkno, str, blkno);
+}
Modified: trunk/libocfs2/Makefile
===================================================================
--- trunk/libocfs2/Makefile 2004-12-11 02:10:10 UTC (rev 478)
+++ trunk/libocfs2/Makefile 2004-12-11 02:28:25 UTC (rev 479)
@@ -66,7 +66,8 @@
bitops.c \
expanddir.c \
newdir.c \
- extend_file.c
+ extend_file.c \
+ namei.c
HFILES = \
include/jfs_user.h \
Modified: trunk/libocfs2/include/ocfs2.h
===================================================================
--- trunk/libocfs2/include/ocfs2.h 2004-12-11 02:10:10 UTC (rev 478)
+++ trunk/libocfs2/include/ocfs2.h 2004-12-11 02:28:25 UTC (rev 479)
@@ -513,6 +513,18 @@
uint32_t len,
uint64_t start_blkno);
+errcode_t ocfs2_lookup(ocfs2_filesys *fs, uint64_t dir, const char *name,
+ int namelen, char *buf, uint64_t *inode);
+
+errcode_t ocfs2_namei(ocfs2_filesys *fs, uint64_t root, uint64_t cwd,
+ const char *name, uint64_t *inode);
+
+errcode_t ocfs2_namei_follow(ocfs2_filesys *fs, uint64_t root, uint64_t cwd,
+ const char *name, uint64_t *inode);
+
+errcode_t ocfs2_follow_link(ocfs2_filesys *fs, uint64_t root, uint64_t cwd,
+ uint64_t inode, uint64_t *res_inode);
+
/*
* ${foo}_to_${bar} is a floor function. blocks_to_clusters will
* returns the cluster that contains a block, not the number of clusters
Added: trunk/libocfs2/namei.c
===================================================================
--- trunk/libocfs2/namei.c 2004-12-11 02:10:10 UTC (rev 478)
+++ trunk/libocfs2/namei.c 2004-12-11 02:28:25 UTC (rev 479)
@@ -0,0 +1,268 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * namei.c
+ *
+ * ocfs2 directory lookup operations
+ *
+ * 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.
+ *
+ * This code is a port of e2fsprogs/lib/ext2fs/namei.c
+ * Copyright (C) 1993, 1994, 1994, 1995 Theodore Ts'o.
+ */
+
+#define _XOPEN_SOURCE 600 /* Triggers magic in features.h */
+#define _LARGEFILE64_SOURCE
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "ocfs2.h"
+
+static errcode_t open_namei(ocfs2_filesys *fs, uint64_t root, uint64_t base,
+ const char *pathname, size_t pathlen, int follow,
+ int link_count, char *buf, uint64_t *res_inode);
+
+/*
+ * follow_link()
+ *
+ */
+static errcode_t follow_link(ocfs2_filesys *fs, uint64_t root, uint64_t dir,
+ uint64_t inode, int link_count,
+ char *buf, uint64_t *res_inode)
+{
+ char *pathname;
+ char *buffer = NULL;
+ errcode_t ret;
+ ocfs2_dinode *di = NULL;
+ ocfs2_extent_list *el;
+ uint64_t blkno;
+
+#ifdef NAMEI_DEBUG
+ printf("follow_link: root=%lu, dir=%lu, inode=%lu, lc=%d\n",
+ root, dir, inode, link_count);
+
+#endif
+
+ ret = ocfs2_malloc_block(fs->fs_io, (void **)&di);
+ if (ret)
+ goto bail;
+
+ ret = ocfs2_read_inode(fs, inode, (char *)di);
+ if (ret)
+ goto bail;
+
+ if (!S_ISLNK(di->i_mode)) {
+ *res_inode = inode;
+ ret = 0;
+ goto bail;
+ }
+
+ if (link_count++ > 5) {
+ ret = OCFS2_ET_SYMLINK_LOOP;
+ goto bail;
+ }
+
+ el = &(di->id2.i_list);
+
+ if (!di->i_clusters || !el->l_next_free_rec) {
+ ret = OCFS2_ET_INTERNAL_FAILURE;
+ goto bail;
+ }
+
+ blkno = el->l_recs[0].e_blkno;
+
+ ret = ocfs2_malloc_block(fs->fs_io, (void **) &buffer);
+ if (ret)
+ goto bail;
+
+ ret = io_read_block(fs->fs_io, blkno, 1, buffer);
+ if (ret)
+ goto bail;
+
+ pathname = buffer;
+
+ ret = open_namei(fs, root, dir, pathname, di->i_size, 1,
+ link_count, buf, res_inode);
+
+bail:
+ if (buffer)
+ ocfs2_free((void **) &buffer);
+
+ if (di)
+ ocfs2_free(&di);
+
+ return ret;
+}
+
+/*
+ * dir_namei()
+ *
+ * This routine interprets a pathname in the context of the current
+ * directory and the root directory, and returns the inode of the
+ * containing directory, and a pointer to the filename of the file
+ * (pointing into the pathname) and the length of the filename.
+ */
+static errcode_t dir_namei(ocfs2_filesys *fs, uint64_t root, uint64_t dir,
+ const char *pathname, int pathlen,
+ int link_count, char *buf,
+ const char **name, int *namelen,
+ uint64_t *res_inode)
+{
+ char c;
+ const char *thisname;
+ int len;
+ uint64_t inode;
+ errcode_t ret;
+
+ if ((c = *pathname) == '/') {
+ dir = root;
+ pathname++;
+ pathlen--;
+ }
+ while (1) {
+ thisname = pathname;
+ for (len=0; --pathlen >= 0;len++) {
+ c = *(pathname++);
+ if (c == '/')
+ break;
+ }
+
+ if (pathlen < 0)
+ break;
+
+ ret = ocfs2_lookup (fs, dir, thisname, len, buf, &inode);
+ if (ret)
+ return ret;
+
+ ret = follow_link (fs, root, dir, inode, link_count, buf, &dir);
+ if (ret)
+ return ret;
+ }
+
+ *name = thisname;
+ *namelen = len;
+ *res_inode = dir;
+ return 0;
+}
+
+/*
+ * open_namei()
+ *
+ */
+static errcode_t open_namei(ocfs2_filesys *fs, uint64_t root, uint64_t base,
+ const char *pathname, size_t pathlen, int follow,
+ int link_count, char *buf, uint64_t *res_inode)
+{
+ const char *basename;
+ int namelen;
+ uint64_t dir, inode;
+ errcode_t ret;
+
+#ifdef NAMEI_DEBUG
+ printf("open_namei: root=%lu, dir=%lu, path=%*s, lc=%d\n",
+ root, base, pathlen, pathname, link_count);
+#endif
+ ret = dir_namei(fs, root, base, pathname, pathlen,
+ link_count, buf, &basename, &namelen, &dir);
+ if (ret)
+ return ret;
+
+ if (!namelen) { /* special case: '/usr/' etc */
+ *res_inode=dir;
+ return 0;
+ }
+
+ ret = ocfs2_lookup (fs, dir, basename, namelen, buf, &inode);
+ if (ret)
+ return ret;
+
+ if (follow) {
+ ret = follow_link(fs, root, dir, inode, link_count, buf, &inode);
+ if (ret)
+ return ret;
+ }
+#ifdef NAMEI_DEBUG
+ printf("open_namei: (link_count=%d) returns %lu\n",
+ link_count, inode);
+#endif
+ *res_inode = inode;
+ return 0;
+}
+
+/*
+ * ocfs2_namei()
+ *
+ */
+errcode_t ocfs2_namei(ocfs2_filesys *fs, uint64_t root, uint64_t cwd,
+ const char *name, uint64_t *inode)
+{
+ char *buf;
+ errcode_t ret;
+
+ ret = ocfs2_malloc_block(fs->fs_io, (void **) &buf);
+ if (ret)
+ return ret;
+
+ ret = open_namei(fs, root, cwd, name, strlen(name), 0, 0, buf, inode);
+
+ ocfs2_free((void **) &buf);
+ return ret;
+}
+
+/*
+ * ocfs2_namei_follow()
+ *
+ */
+errcode_t ocfs2_namei_follow(ocfs2_filesys *fs, uint64_t root, uint64_t cwd,
+ const char *name, uint64_t *inode)
+{
+ char *buf;
+ errcode_t ret;
+
+ ret = ocfs2_malloc_block(fs->fs_io, (void **) &buf);
+ if (ret)
+ return ret;
+
+ ret = open_namei(fs, root, cwd, name, strlen(name), 1, 0, buf, inode);
+
+ ocfs2_free((void **) &buf);
+ return ret;
+}
+
+/*
+ * ocfs2_follow_link()
+ *
+ */
+errcode_t ocfs2_follow_link(ocfs2_filesys *fs, uint64_t root, uint64_t cwd,
+ uint64_t inode, uint64_t *res_inode)
+{
+ char *buf;
+ errcode_t ret;
+
+ ret = ocfs2_malloc_block(fs->fs_io, (void **) &buf);
+ if (ret)
+ return ret;
+
+ ret = follow_link(fs, root, cwd, inode, 0, buf, res_inode);
+
+ ocfs2_free((void **) &buf);
+ return ret;
+}
Modified: trunk/libocfs2/ocfs2_err.et.in
===================================================================
--- trunk/libocfs2/ocfs2_err.et.in 2004-12-11 02:10:10 UTC (rev 478)
+++ trunk/libocfs2/ocfs2_err.et.in 2004-12-11 02:28:25 UTC (rev 479)
@@ -144,4 +144,7 @@
ec OCFS2_ET_ITERATION_COMPLETE,
"Iteration complete"
+ec OCFS2_ET_SYMLINK_LOOP,
+ "Too many symbolic links encountered"
+
end
More information about the Ocfs2-tools-commits
mailing list