patch-2.1.80 linux/fs/adfs/namei.c
Next file: linux/fs/adfs/super.c
Previous file: linux/fs/adfs/map.c
Back to the patch index
Back to the overall index
- Lines: 120
- Date:
Tue Jan 20 16:44:58 1998
- Orig file:
v2.1.79/linux/fs/adfs/namei.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -u --recursive --new-file v2.1.79/linux/fs/adfs/namei.c linux/fs/adfs/namei.c
@@ -0,0 +1,119 @@
+/*
+ * linux/fs/adfs/namei.c
+ *
+ * Copyright (C) 1997 Russell King
+ */
+
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/adfs_fs.h>
+#include <linux/fcntl.h>
+#include <linux/sched.h>
+#include <linux/stat.h>
+#include <linux/string.h>
+#include <linux/locks.h>
+
+/*
+ * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure
+ */
+static int adfs_match (int len, const char * const name, struct adfs_idir_entry *de)
+{
+ int i;
+
+ if (!de || len > ADFS_NAME_LEN)
+ return 0;
+ /*
+ * "" means "." ---> so paths like "/usr/lib//libc.a" work
+ */
+ if (!len && de->name_len == 1 && de->name[0] == '.' &&
+ de->name[1] == '\0')
+ return 1;
+ if (len != de->name_len)
+ return 0;
+
+ for (i = 0; i < len; i++)
+ if ((de->name[i] ^ name[i]) & 0x5f)
+ return 0;
+ return 1;
+}
+
+static int adfs_find_entry (struct inode *dir, const char * const name, int namelen,
+ struct adfs_idir_entry *ide)
+{
+ struct super_block *sb;
+ struct buffer_head *bh[4];
+ union adfs_dirtail dt;
+ unsigned long parent_object_id, dir_object_id;
+ int buffers, pos;
+
+ if (!dir || !S_ISDIR(dir->i_mode))
+ return 0;
+
+ sb = dir->i_sb;
+
+ if (adfs_inode_validate (dir)) {
+ adfs_error (sb, "adfs_find_entry",
+ "invalid inode number: %lu", dir->i_ino);
+ return 0;
+ }
+
+ if (namelen > ADFS_NAME_LEN)
+ return 0;
+
+ if (!(buffers = adfs_dir_read (dir, bh))) {
+ adfs_error (sb, "adfs_find_entry", "unable to read directory");
+ return 0;
+ }
+
+ if (adfs_dir_check (dir, bh, buffers, &dt)) {
+ adfs_dir_free (bh, buffers);
+ return 0;
+ }
+
+ parent_object_id = adfs_val (dt.new.dirparent, 3);
+ dir_object_id = adfs_inode_objid (dir);
+
+ if (namelen == 2 && name[0] == '.' && name[1] == '.') {
+ ide->name_len = 2;
+ ide->name[0] = ide->name[1] = '.';
+ ide->name[2] = '\0';
+ ide->inode_no = adfs_inode_generate (parent_object_id, 0);
+ adfs_dir_free (bh, buffers);
+ return 1;
+ }
+
+ pos = 5;
+
+ do {
+ if (!adfs_dir_get (sb, bh, buffers, pos, dir_object_id, ide))
+ break;
+
+ if (adfs_match (namelen, name, ide)) {
+ adfs_dir_free (bh, buffers);
+ return pos;
+ }
+ pos += 26;
+ } while (1);
+ adfs_dir_free (bh, buffers);
+ return 0;
+}
+
+int adfs_lookup (struct inode *dir, struct dentry *dentry)
+{
+ struct inode *inode = NULL;
+ struct adfs_idir_entry de;
+ unsigned long ino;
+
+ if (dentry->d_name.len > ADFS_NAME_LEN)
+ return -ENAMETOOLONG;
+
+ if (adfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de)) {
+ ino = de.inode_no;
+ inode = iget (dir->i_sb, ino);
+
+ if (!inode)
+ return -EACCES;
+ }
+ d_add(dentry, inode);
+ return 0;
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov