summaryrefslogtreecommitdiffstats
path: root/fs/efs/namei.c
diff options
context:
space:
mode:
authorMike Shaver <shaver@ingenia.com>1999-01-18 04:16:25 +0000
committerMike Shaver <shaver@ingenia.com>1999-01-18 04:16:25 +0000
commit6bafd683c6bd78f19df9a42aea24037137f913ce (patch)
tree7580dc3040c32da4048009721d60a7ac442962ca /fs/efs/namei.c
parent317b660279d583d4db3fc112e3ef2e56b20bec87 (diff)
EFS mark II. Incomplete, but much cleaner.
Diffstat (limited to 'fs/efs/namei.c')
-rw-r--r--fs/efs/namei.c211
1 files changed, 83 insertions, 128 deletions
diff --git a/fs/efs/namei.c b/fs/efs/namei.c
index 752aa5fe1..eba441e5a 100644
--- a/fs/efs/namei.c
+++ b/fs/efs/namei.c
@@ -1,141 +1,96 @@
-/* namei.c
-
- name lookup for EFS filesystem
-
- (C)95,96 Christian Vogelgsang
-*/
+/*
+ * linux/fs/efs/namei.c
+ *
+ * Copyright (C) 1998 Mike Shaver
+ *
+ * Portions derived from work (C) 1995,1996 Christian Vogelgsang.
+ * ``Inspired by'' fs/minix/namei.c.
+ */
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
#include <linux/efs_fs.h>
-#include <linux/efs_fs_i.h>
-#include <linux/efs_fs_sb.h>
-#include <linux/stat.h>
-#include <asm/uaccess.h>
+#include <linux/errno.h>
-/* ----- efs_find_entry -----
- search a raw efs dir entry for the given name
-
- dir - inode of directory
- oname - name to search for
- onamelen- length of name
-
- return - inode number of the found entry or 0 on error
-*/
-static struct buffer_head * efs_find_entry(struct inode *dir,
- const char *oname,
- int onamelen,
- struct efs_dir_entry *res_dir)
+static struct buffer_head *
+efs_find_entry(struct inode *dir, const char *oname, int onamelen,
+ struct efs_dir_entry **res_dir)
{
- struct efs_inode_info *ini = &dir->u.efs_i;
- struct buffer_head *bh = NULL;
- __u32 inode;
- __u16 i;
- __u8 *name;
- __u16 namelen;
- __u32 blknum,b;
- struct efs_dirblk *db;
-
- /* Warnings */
- if(ini->tot!=1)
- printk("efs_find: More than one extent!\n");
- if(dir->i_size & (EFS_BLOCK_SIZE-1))
- printk("efs_find: dirsize != blocklen * n\n");
+ struct buffer_head *bh;
+ struct efs_sb_info *sbi;
+ struct efs_dirblk *dirblk;
+ __u32 offset, block, maxblk;
+ __u16 i, namelen;
+ char *name;
- /* Search in every dirblock */
- inode = 0;
- blknum = dir->i_size >> EFS_BLOCK_SIZE_BITS;
-#ifdef DEBUG_EFS
- printk("EFS: directory with inode %#xd has %d blocks\n",
- dir->i_ino, blknum);
-#endif
- for(b=0;b<blknum;b++) {
- int db_offset;
-#ifdef DEBUG_EFS
- printk("EFS: trying block %d\n", b);
-#endif
- /* Read a raw dirblock */
- bh = bread(dir->i_dev,efs_bmap(dir,b),EFS_BLOCK_SIZE);
- if(!bh) {
- printk("EFS: efs_bmap returned NULL!\n");
- return 0;
- }
-
- db = (struct efs_dirblk *)bh->b_data;
- if (db->db_magic != EFS_DIRBLK_MAGIC) {
- printk("EFS: dirblk has bad magic (%#xl)!\n",
- db->db_magic);
- return NULL;
- }
-#ifdef DEBUG_EFS
- printk("EFS: db %d has %d entries, starting at offset %#x\n",
- b, db->db_slots, (__u16)db->db_firstused << 1);
-#endif
- for(i = 0 ; i < db->db_slots ; i++) {
- struct efs_dent * de;
- int entry_inode;
- db_offset = ((__u16)db->db_space[i] << 1)
- - EFS_DIRBLK_HEADERSIZE;
- de = (struct efs_dent *)(&db->db_space[db_offset]);
+ *res_dir = NULL;
+ if (!dir || !dir->i_sb)
+ return NULL;
+ sbi = &dir->i_sb->u.efs_sb;
+ bh = NULL;
+ block = offset = 0;
+ maxblk = dir->i_size >> EFS_BLOCK_SIZE_BITS;
+ DB(("EFS: dir has %d blocks\n", maxblk));
+ for (block = 0; block < maxblk; block++) {
- /* inode, namelen and name of direntry */
- entry_inode = efs_swab32(de->ud_inum.l);
- namelen = de->d_namelen;
- name = de->d_name;
-#ifdef 0
- printk("EFS: entry %d @ %#x has inode %#x, %s/%d\n",
- i, db_offset, entry_inode, name, namelen);
-#endif
- /* we found the name! */
- if((namelen==onamelen)&&
- (!memcmp(oname,name,onamelen))) {
- res_dir->inode = entry_inode;
-#ifdef DEBUG_EFS
- printk("EFS: found inode %d\n",
- entry_inode);
-#endif
- return bh;
- }
- }
+ bh = bread(dir->i_dev, efs_bmap(dir, block), EFS_BLOCK_SIZE);
+ if (!bh) {
+ DB(("EFS: find_entry: skip blk %d (ino %#lx): bread\n",
+ block, dir->i_ino));
+ continue;
}
-#ifdef DEBUG_EFS
- printk("EFS: efs_find_entry didn't find inode for \"%s\"/%d!\n",
- oname, onamelen);
-#endif
- return NULL;
- /* not reached */
-}
+ dirblk = (struct efs_dirblk *)bh->b_data;
+
+ if (efs_swab32(dirblk->db_magic) != EFS_DIRBLK_MAGIC) {
+ printk("EFS: dirblk %d (ino %#lx) has bad magic (%#x)!\n",
+ block, dir->i_ino, efs_swab32(dirblk->db_magic));
+ brelse(bh);
+ continue;
+ }
+
+ DB(("EFS: db %d has %d entries\n", block, dirblk->db_slots));
+
+ for (i = 0; i < dirblk->db_slots; i++) {
+ struct efs_dir_entry *dent;
+ __u16 off = EFS_SLOT2OFF(dirblk, i);
+ if (!off) {
+ DB(("skipping empty slot %d\n", i));
+ continue; /* skip empty slot */
+ }
+ dent = EFS_DENT4OFF(dirblk, off);
+ namelen = dent->d_namelen;
+ name = dent->d_name;
+
+ if ((namelen == onamelen) &&
+ !memcmp(oname, name, onamelen)) {
+ *res_dir = dent;
+ return bh;
+ }
+ }
-/* ----- efs_lookup -----
- lookup inode operation:
- check if a given name is in the dir directory
-
- dir - pointer to inode of directory
- name - name we must search for
- len - length of name
- result - pointer to inode struct if we found it or NULL on error
-
- return - 0 everything is ok or <0 on error
-*/
-int efs_lookup(struct inode *dir, struct dentry *dentry)
+ brelse(bh);
+ }
+ DB(("EFS: find_entry didn't find inode for \"%s\"/%d\n",
+ oname, onamelen));
+ return NULL;
+}
+
+int
+efs_lookup(struct inode *dir, struct dentry *dentry)
{
- struct inode *inode = NULL;
- struct buffer_head *bh;
- struct efs_dir_entry de;
-
- bh = efs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de);
- if (bh) {
- int ino = de.inode;
- brelse(bh);
- inode = iget(dir->i_sb, ino);
+ struct buffer_head *bh;
+ struct inode *in = NULL;
+ struct efs_dir_entry *dent;
+
+ bh = efs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &dent);
+ if (bh) {
+ int ino = efs_swab32(dent->ud_inum.l);
- if (!inode)
- return -EACCES;
- }
+ brelse(bh);
+ in = iget(dir->i_sb, ino);
+ if (!in)
+ return -EACCES;
+ }
- d_add(dentry, inode);
- return 0;
+ d_add(dentry, in);
+ return 0;
}