9 * Looking for an inode with the given path
11 * returns NULL for -ENOENT, ERROR for errors happend
12 * and inode for finding responding file or directory.
14 struct inode
* namei(const char *name
, uint32_t flag
)
21 FS_DEBUG("trying to open path: %s\n", name
);
23 inode
= root_fs()->root
;
25 panic("namei: Read root inode error!\n");
29 inode
= root_fs()->pwd
;
30 FS_DEBUG("pwd->inode: %d\n", inode
->i_ino
);
36 while (*name
&& *name
!= '/') {
37 if (p
>= part
+ MAX_NAME_LEN
)
38 return ERR_PTR(-ENAMETOOLONG
);
42 while (*name
&& *name
== '/')
44 if (!*name
&& (flag
& LOOKUP_PARENT
))
46 FS_DEBUG("Looking for part: %s, parent->inode: %d\n", part
, parent
->i_ino
);
47 inode
= iget(part
, parent
);
48 if (IS_ERR_OR_NULL(inode
))
57 if (PTR_ERR(inode
) == -ENOENT
&& flag
& LOOKUP_CREATE
) {
58 inode
= parent
->i_op
->mknod(parent
, part
, TFS_FILE
);
61 return ERR_CAST(inode
);
62 if (inode
->i_op
->iwrite(inode
)) {
72 * Lookup the parent inode
74 * NOTE: the parent should be directory!
76 struct inode
*namei_parent(const char *pathname
)
78 struct inode
*dir
= namei(pathname
, LOOKUP_PARENT
);
80 if (!IS_ERR_OR_NULL(dir
))
81 return dir
? ERR_CAST(dir
) : ERR_PTR(-ENOENT
);
85 return ERR_PTR(-ENOTDIR
);
92 int sys_mkdir(const char *pathname
)
95 struct inode
*dir
= namei_parent(pathname
);
101 if (dir
->i_op
&& dir
->i_op
->mkdir
)
102 err
= dir
->i_op
->mkdir(dir
, get_base_name(pathname
));
108 int sys_rmdir(const char *pathname
)
110 struct inode
*dir
= namei_parent(pathname
);
117 if (dir
->i_op
&& dir
->i_op
->rmdir
)
118 err
= dir
->i_op
->rmdir(dir
, get_base_name(pathname
));
124 int sys_chdir(const char *pathname
)
126 struct inode
* inode
;
129 while (*pathname
&& *pathname
== '.' && *(pathname
+ 1) == '/')
131 /* If we are changing to current dir, then just do nothing */
132 if (*pathname
== '.' && !*(pathname
+ 1))
135 inode
= namei(pathname
, 0);
136 if (IS_ERR_OR_NULL(inode
))
137 return inode
? PTR_ERR(inode
) : -ENOENT
;
138 if (!IS_DIR(inode
)) {
143 free_inode(root_fs()->pwd
);
144 root_fs()->pwd
= inode
;
146 cwd
= root_fs()->cwd
;
147 if (*pathname
== '/') {
148 strcpy(cwd
, pathname
);
149 } else if (strcmp(pathname
, "..") == 0) {
150 char *p
= strrchr(cwd
, '/');
152 /* At least we have a '/' char */
161 strcat(cwd
, pathname
);
168 * The sys call to get the current directory
170 int sys_getcwd(char *buf
, int size
)
172 int len
= strlen(root_fs()->cwd
);
178 strcpy(buf
, root_fs()->cwd
);
182 int sys_unlink(const char *pathname
)
184 struct inode
*dir
= namei_parent(pathname
);
191 if (dir
->i_op
&& dir
->i_op
->unlink
)
192 err
= dir
->i_op
->unlink(dir
, get_base_name(pathname
));