patch-1.3.94 linux/fs/ufs/ufs_namei.c
Next file: linux/fs/ufs/ufs_super.c
Previous file: linux/fs/ufs/ufs_inode.c
Back to the patch index
Back to the overall index
- Lines: 155
- Date:
Mon Apr 22 10:59:39 1996
- Orig file:
v1.3.93/linux/fs/ufs/ufs_namei.c
- Orig date:
Thu Jan 1 02:00:00 1970
diff -u --recursive --new-file v1.3.93/linux/fs/ufs/ufs_namei.c linux/fs/ufs/ufs_namei.c
@@ -0,0 +1,154 @@
+/*
+ * linux/fs/ufs/ufs_namei.c
+ *
+ * Copyright (C) 1996
+ * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
+ * Laboratory for Computer Science Research Computing Facility
+ * Rutgers, The State University of New Jersey
+ *
+ * $Id: ufs_namei.c,v 1.1 1996/04/21 14:41:15 davem Exp $
+ *
+ */
+
+#include <linux/fs.h>
+
+extern unsigned int ufs_bmap(struct inode * inode, int block); /* XXX */
+
+/*
+ * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure.
+ * stolen from ext2fs
+ */
+static int ufs_match (int len, const char * const name, struct direct * d)
+{
+ if (!d || len > MAXNAMLEN) /* XXX - name space */
+ return 0;
+ /*
+ * "" means "." ---> so paths like "/usr/lib//libc.a" work
+ */
+ if (!len && (d->d_namlen == 1) && (d->d_name[0] == '.') &&
+ (d->d_name[1] == '\0'))
+ return 1;
+ if (len != d->d_namlen)
+ return 0;
+ return !memcmp(name, d->d_name, len);
+}
+
+/* XXX - this is a mess, especially for endianity */
+int ufs_lookup (struct inode * dir, const char * name, int len,
+ struct inode ** result)
+{
+ unsigned long int lfragno, fragno;
+ struct buffer_head * bh;
+ struct direct * d;
+
+ /*
+ * Touching /xyzzy in a filesystem toggles debugging messages.
+ */
+ if ((len == 5) && !(memcmp(name, "xyzzy", len)) &&
+ (dir->i_ino == UFS_ROOTINO)) {
+ dir->i_sb->u.ufs_sb.s_flags ^= UFS_DEBUG;
+ printk("UFS debugging %s\n",
+ (dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) ?
+ "on": "off");
+ return(-ENOENT);
+ }
+
+ /*
+ * Touching /xyzzy.i in a filesystem toggles debugging for ufs_inode.c.
+ */
+ if ((len == 7) && !(memcmp(name, "xyzzy.i", len)) &&
+ (dir->i_ino == UFS_ROOTINO)) {
+ dir->i_sb->u.ufs_sb.s_flags ^= UFS_DEBUG_INODE;
+ printk("UFS inode debugging %s\n",
+ (dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG_INODE) ?
+ "on": "off");
+ return(-ENOENT);
+ }
+
+ if ((len == 7) && !(memcmp(name, "xyzzy.n", len)) &&
+ (dir->i_ino == UFS_ROOTINO)) {
+ dir->i_sb->u.ufs_sb.s_flags ^= UFS_DEBUG_NAMEI;
+ printk("UFS namei debugging %s\n",
+ (dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG_NAMEI) ?
+ "on": "off");
+ return(-ENOENT);
+ }
+
+ if ((len == 7) && !(memcmp(name, "xyzzy.l", len)) &&
+ (dir->i_ino == UFS_ROOTINO)) {
+ dir->i_sb->u.ufs_sb.s_flags ^= UFS_DEBUG_LINKS;
+ printk("UFS symlink debugging %s\n",
+ (dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG_LINKS) ?
+ "on": "off");
+ return(-ENOENT);
+ }
+
+ if (dir->i_sb->u.ufs_sb.s_flags & (UFS_DEBUG|UFS_DEBUG_NAMEI)) {
+ printk("ufs_lookup: called for ino %lu name %s\n",
+ dir->i_ino, name);
+ }
+
+ /* XXX - do I want i_blocks in 512-blocks or 1024-blocks? */
+ for (lfragno = 0; lfragno < (dir->i_blocks)>>1; lfragno++) {
+ fragno = ufs_bmap(dir, lfragno);
+ /* XXX - ufs_bmap() call needs error checking */
+ /* XXX - s_blocksize is actually the UFS frag size */
+ if (dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {
+ printk("ufs_lookup: ino %lu lfragno %lu fragno %lu\n",
+ dir->i_ino, lfragno, fragno);
+ }
+ if (fragno == 0) {
+ /* XXX - bug bug bug */
+ return(-ENOENT);
+ }
+ bh = bread(dir->i_dev, fragno, dir->i_sb->s_blocksize);
+ if (bh == NULL) {
+ printk("ufs_lookup: bread failed: ino %lu, lfragno %u",
+ dir->i_ino, lfragno);
+ return(-EIO);
+ }
+ d = (struct direct *)(bh->b_data);
+ while (((char *)d - bh->b_data + d->d_reclen) <=
+ dir->i_sb->s_blocksize) {
+ /* XXX - skip block if d_reclen or d_namlen is 0 */
+ if ((d->d_reclen == 0) || (d->d_namlen == 0)) {
+ if (dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {
+ printk("ufs_lookup: skipped space in directory, ino %lu\n",
+ dir->i_ino);
+ }
+ break;
+ }
+ if (dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {
+ printk("lfragno 0x%x direct d 0x%x d_ino %u d_reclen %u d_namlen %u d_name `%s'\n",
+ lfragno, (unsigned int)d, d->d_ino, d->d_reclen, d->d_namlen, d->d_name);
+ }
+ if ((d->d_namlen == len) &&
+ /* XXX - don't use strncmp() - see ext2fs */
+ (ufs_match(len, name, d))) {
+ /* We have a match */
+ *result = iget(dir->i_sb, d->d_ino);
+ brelse(bh);
+ return(0);
+ } else {
+ /* XXX - bounds checking */
+ if (dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {
+ printk("ufs_lookup: wanted (%s,%d) got (%s,%d)\n",
+ name, len, d->d_name, d->d_namlen);
+ }
+ }
+ d = (struct direct *)((char *)d + d->d_reclen);
+ }
+ brelse(bh);
+ }
+ return(-ENOENT);
+}
+
+/*
+ * Local Variables: ***
+ * c-indent-level: 8 ***
+ * c-continued-statement-offset: 8 ***
+ * c-brace-offset: -8 ***
+ * c-argdecl-indent: 0 ***
+ * c-label-offset: -8 ***
+ * End: ***
+ */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this