patch-2.1.71 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: 214
- Date:
Wed Dec 3 06:18:33 1997
- Orig file:
v2.1.70/linux/fs/ufs/ufs_namei.c
- Orig date:
Mon Aug 4 16:25:39 1997
diff -u --recursive --new-file v2.1.70/linux/fs/ufs/ufs_namei.c linux/fs/ufs/ufs_namei.c
@@ -6,48 +6,62 @@
* Laboratory for Computer Science Research Computing Facility
* Rutgers, The State University of New Jersey
*
- * $Id: ufs_namei.c,v 1.9 1997/07/22 06:40:12 davem Exp $
+ * Clean swab support by Francois-Rene Rideau <rideau@ens.fr> 19970406
+ * Ported to 2.1.62 by Francois-Rene Rideau <rideau@issy.cnet.fr> 19971109
*
*/
#include <linux/fs.h>
#include <linux/ufs_fs.h>
-
#include <linux/string.h>
+#include "ufs_swab.h"
/*
* 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 ufs_direct * d)
+static int ufs_match (int len, const char * const name, struct ufs_direct * d, __u32 bytesex)
{
if (!d || len > UFS_MAXNAMLEN) /* XXX - name space */
return 0;
/*
* "" means "." ---> so paths like "/usr/lib//libc.a" work
*/
- if (!len && (ufs_swab16(d->d_namlen) == 1) && (d->d_name[0] == '.') &&
- (d->d_name[1] == '\0'))
- return 1;
- if (len != ufs_swab16(d->d_namlen))
+ if (!len && (SWAB16(d->d_namlen) == 1) && (d->d_name[0] == '.') &&
+ (d->d_name[1] == '\0'))
+ return 1;
+ if (len != SWAB16(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, struct qstr *qname,
- struct inode ** result)
+int ufs_lookup (struct inode *dir, struct dentry *dentry)
{
+ /* XXX - this is all fucked up! */
+ /* XXX - and it's been broken since linux has this new dentry interface:
+ * allows reading of files, but screws the whole dcache, even outside
+ * of the ufs partition, so that umount'ing won't suffice to fix it --
+ * reboot needed
+ */
unsigned long int lfragno, fragno;
struct buffer_head * bh;
struct ufs_direct * d;
- const char *name = qname->name;
- int len = qname->len;
+ const char *name = dentry->d_name.name;
+ int len = dentry->d_name.len;
+ __u32 bytesex;
+ struct inode *inode;
+
+ /* XXX - isn't that already done by the upper layer? */
+ if (!dir || !S_ISDIR(dir->i_mode))
+ return -EBADF;
+
+ bytesex = dir->i_sb->u.ufs_sb.s_flags & UFS_BYTESEX;
if (dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG)
printk("Passed name: %s\nPassed length: %d\n", name, len);
- /*
+
+ /* debugging hacks:
* Touching /xyzzy in a filesystem toggles debugging messages.
*/
if ((len == 5) && !(memcmp(name, "xyzzy", len)) &&
@@ -56,8 +70,8 @@
printk("UFS debugging %s\n",
(dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) ?
"on": "off");
- iput(dir);
- return(-ENOENT);
+ goto not_found;
+ /*return(-ENOENT);*/
}
/*
@@ -69,8 +83,8 @@
printk("UFS inode debugging %s\n",
(dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG_INODE) ?
"on": "off");
- iput(dir);
- return(-ENOENT);
+ goto not_found;
+ /*return(-ENOENT);*/
}
if ((len == 7) && !(memcmp(name, "xyzzy.n", len)) &&
@@ -79,8 +93,8 @@
printk("UFS namei debugging %s\n",
(dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG_NAMEI) ?
"on": "off");
- iput(dir);
- return(-ENOENT);
+ goto not_found;
+ /*return(-ENOENT);*/
}
if ((len == 7) && !(memcmp(name, "xyzzy.l", len)) &&
@@ -89,10 +103,13 @@
printk("UFS symlink debugging %s\n",
(dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG_LINKS) ?
"on": "off");
- iput(dir);
- return(-ENOENT);
+ goto not_found;
+ /*return(-ENOENT);*/
}
+
+ /* Now for the real thing */
+
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);
@@ -109,21 +126,22 @@
}
if (fragno == 0) {
/* XXX - bug bug bug */
- iput(dir);
- return(-ENOENT);
+ goto not_found;
+ /*return(-ENOENT);*/
}
bh = bread(dir->i_dev, fragno, dir->i_sb->s_blocksize);
if (bh == NULL) {
- printk("ufs_lookup: bread failed: ino %lu, lfragno %lu",
+ printk("ufs_lookup: bread failed: "
+ "ino %lu, lfragno %lu",
dir->i_ino, lfragno);
- iput(dir);
return(-EIO);
}
d = (struct ufs_direct *)(bh->b_data);
- while (((char *)d - bh->b_data + ufs_swab16(d->d_reclen)) <=
+ while (((char *)d - bh->b_data + SWAB16(d->d_reclen)) <=
dir->i_sb->s_blocksize) {
/* XXX - skip block if d_reclen or d_namlen is 0 */
- if ((ufs_swab16(d->d_reclen) == 0) || (ufs_swab16(d->d_namlen) == 0)) {
+ if ((d->d_reclen == 0) || (d->d_namlen == 0)) {
+ /* no need to SWAB16(): test against 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);
@@ -131,32 +149,43 @@
break;
}
if (dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {
- printk("lfragno 0x%lx direct d 0x%x d_ino %u "
- "d_reclen %u d_namlen %u d_name `%s'\n",
- lfragno, (unsigned int)((unsigned long)d),
- ufs_swab32(d->d_ino), ufs_swab16(d->d_reclen),
- ufs_swab16(d->d_namlen), d->d_name);
+ printk("lfragno 0x%lx "
+ "direct d 0x%x "
+ "d_ino %u "
+ "d_reclen %u "
+ "d_namlen %u d_name `%s'\n",
+ lfragno,
+ (unsigned int)((unsigned long)d),
+ SWAB32(d->d_ino),
+ SWAB16(d->d_reclen),
+ SWAB16(d->d_namlen),d->d_name);
}
- if ((ufs_swab16(d->d_namlen) == len) &&
+ if ((SWAB16(d->d_namlen) == len) &&
/* XXX - don't use strncmp() - see ext2fs */
- (ufs_match(len, name, d))) {
+ (ufs_match(len, name, d, bytesex))) {
/* We have a match */
- *result = iget(dir->i_sb, ufs_swab32(d->d_ino));
- brelse(bh);
- iput(dir);
+/* XXX - I only superficially understand how things work,
+ * so use at your own risk... -- Fare'
+ */
+ inode = iget(dir->i_sb, SWAB32(d->d_ino));
+ brelse(bh);
+ if(!inode) { return -EACCES; }
+ d_add(dentry,inode);
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, ufs_swab16(d->d_namlen));
+ printk("ufs_lookup: "
+ "wanted (%s,%d) got (%s,%d)\n",
+ name, len,
+ d->d_name, SWAB16(d->d_namlen));
}
}
- d = (struct ufs_direct *)((char *)d + ufs_swab16(d->d_reclen));
+ d = (struct ufs_direct *)((char *)d + SWAB16(d->d_reclen));
}
brelse(bh);
}
- iput(dir);
- return(-ENOENT);
+ not_found:
+ d_add(dentry,NULL);
+ return(0);
}
-
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov