2 * linux/fs/adfs/namei.c
4 * Copyright (C) 1997 Russell King
7 #include <linux/errno.h>
9 #include <linux/adfs_fs.h>
10 #include <linux/fcntl.h>
11 #include <linux/sched.h>
12 #include <linux/stat.h>
13 #include <linux/string.h>
14 #include <linux/locks.h>
17 * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure
19 static int adfs_match (int len
, const char * const name
, struct adfs_idir_entry
*de
)
23 if (!de
|| len
> ADFS_NAME_LEN
)
26 * "" means "." ---> so paths like "/usr/lib//libc.a" work
28 if (!len
&& de
->name_len
== 1 && de
->name
[0] == '.' &&
31 if (len
!= de
->name_len
)
34 for (i
= 0; i
< len
; i
++)
35 if ((de
->name
[i
] ^ name
[i
]) & 0x5f)
40 static int adfs_find_entry (struct inode
*dir
, const char * const name
, int namelen
,
41 struct adfs_idir_entry
*ide
)
43 struct super_block
*sb
;
44 struct buffer_head
*bh
[4];
45 union adfs_dirtail dt
;
46 unsigned long parent_object_id
, dir_object_id
;
51 if (adfs_inode_validate (dir
)) {
52 adfs_error (sb
, "adfs_find_entry",
53 "invalid inode number: %lu", dir
->i_ino
);
57 if (!(buffers
= adfs_dir_read (dir
, bh
))) {
58 adfs_error (sb
, "adfs_find_entry", "unable to read directory");
62 if (adfs_dir_check (dir
, bh
, buffers
, &dt
)) {
63 adfs_dir_free (bh
, buffers
);
67 parent_object_id
= adfs_val (dt
.new.dirparent
, 3);
68 dir_object_id
= adfs_inode_objid (dir
);
70 if (namelen
== 2 && name
[0] == '.' && name
[1] == '.') {
72 ide
->name
[0] = ide
->name
[1] = '.';
74 ide
->inode_no
= adfs_inode_generate (parent_object_id
, 0);
75 adfs_dir_free (bh
, buffers
);
82 if (!adfs_dir_get (sb
, bh
, buffers
, pos
, dir_object_id
, ide
))
85 if (adfs_match (namelen
, name
, ide
)) {
86 adfs_dir_free (bh
, buffers
);
91 adfs_dir_free (bh
, buffers
);
95 struct dentry
*adfs_lookup (struct inode
*dir
, struct dentry
*dentry
)
97 struct inode
*inode
= NULL
;
98 struct adfs_idir_entry de
;
101 if (dentry
->d_name
.len
> ADFS_NAME_LEN
)
102 return ERR_PTR(-ENAMETOOLONG
);
104 if (adfs_find_entry (dir
, dentry
->d_name
.name
, dentry
->d_name
.len
, &de
)) {
106 inode
= iget (dir
->i_sb
, ino
);
109 return ERR_PTR(-EACCES
);
111 d_add(dentry
, inode
);