2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
6 * Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved.
8 * Portions based on Adam Richter's smalldevfs and thus
9 * Copyright 2002-2003 Yggdrasil Computing, Inc.
12 #include <linux/module.h>
13 #include <linux/kernel.h>
15 #include <linux/mount.h>
16 #include <linux/namei.h>
17 #include <linux/string.h>
18 #include <linux/slab.h>
19 #include <asm/sn/hwgfs.h>
22 extern struct vfsmount
*hwgfs_vfsmount
;
31 char buf
[strlen(*path
)+1];
34 while ((slash
= strchr(*path
, '/')) != NULL
) {
35 int len
= slash
- *path
;
36 memcpy(buf
, *path
, len
);
39 error
= path_walk(buf
, nd
);
43 nd
->dentry
= lookup_create(nd
, is_dir
);
44 nd
->flags
|= LOOKUP_PARENT
;
45 if (IS_ERR(nd
->dentry
))
46 return PTR_ERR(nd
->dentry
);
48 if (!nd
->dentry
->d_inode
)
49 error
= vfs_mkdir(nd
->dentry
->d_parent
->d_inode
,
52 up(&nd
->dentry
->d_parent
->d_inode
->i_sem
);
62 /* On success, returns with parent_inode->i_sem taken. */
68 struct inode
**parent_inode
,
69 struct dentry
**dentry
)
75 dir
= hwgfs_vfsmount
->mnt_sb
->s_root
;
77 memset(&nd
, 0, sizeof(nd
));
78 nd
.flags
= LOOKUP_PARENT
;
79 nd
.mnt
= mntget(hwgfs_vfsmount
);
80 nd
.dentry
= dget(dir
);
82 error
= walk_parents_mkdir(&name
, &nd
, is_dir
);
86 error
= path_walk(name
, &nd
);
90 *dentry
= lookup_create(&nd
, is_dir
);
93 return PTR_ERR(*dentry
);
94 *parent_inode
= (*dentry
)->d_parent
->d_inode
;
106 len
+= de
->d_name
.len
+ 1; /* count the '/' */
109 return len
; /* -1 because we omit the leading '/',
110 +1 because we include trailing '\0' */
119 struct dentry
*hwgfs_root
;
121 char *path_orig
= path
;
123 if (unlikely(de
== NULL
))
126 hwgfs_root
= hwgfs_vfsmount
->mnt_sb
->s_root
;
127 if (unlikely(de
== hwgfs_root
))
130 spin_lock(&dcache_lock
);
131 len
= path_len(de
, hwgfs_root
);
133 spin_unlock(&dcache_lock
);
134 return -ENAMETOOLONG
;
141 path
-= de
->d_name
.len
;
142 memcpy(path
, de
->d_name
.name
, de
->d_name
.len
);
144 if (de
== hwgfs_root
)
149 spin_unlock(&dcache_lock
);
150 BUG_ON(path
!= path_orig
);
165 dev_t devnum
= MKDEV(major
, minor
);
166 struct inode
*parent_inode
;
167 struct dentry
*dentry
;
170 error
= hwgfs_decode(dir
, name
, 0, &parent_inode
, &dentry
);
171 if (likely(!error
)) {
172 error
= vfs_mknod(parent_inode
, dentry
, mode
, devnum
);
173 if (likely(!error
)) {
175 * Do this inside parents i_sem to avoid racing
179 dentry
->d_inode
->i_fop
= ops
;
180 dentry
->d_fsdata
= info
;
181 up(&parent_inode
->i_sem
);
183 up(&parent_inode
->i_sem
);
198 hwgfs_handle_t
*handle
,
201 struct inode
*parent_inode
;
202 struct dentry
*dentry
;
205 error
= hwgfs_decode(dir
, name
, 0, &parent_inode
, &dentry
);
206 if (likely(!error
)) {
207 error
= vfs_symlink(parent_inode
, dentry
, link
, S_IALLUGO
);
208 dentry
->d_fsdata
= info
;
211 up(&parent_inode
->i_sem
);
223 struct inode
*parent_inode
;
224 struct dentry
*dentry
;
227 error
= hwgfs_decode(dir
, name
, 1, &parent_inode
, &dentry
);
228 if (likely(!error
)) {
229 error
= vfs_mkdir(parent_inode
, dentry
, 0755);
230 up(&parent_inode
->i_sem
);
232 if (unlikely(error
)) {
236 dentry
->d_fsdata
= info
;
246 struct inode
*parent_inode
= de
->d_parent
->d_inode
;
248 if (S_ISDIR(de
->d_inode
->i_mode
))
249 vfs_rmdir(parent_inode
, de
);
251 vfs_unlink(parent_inode
, de
);
254 /* XXX: this function is utterly bogus. Every use of it is racy and the
255 prototype is stupid. You have been warned. --hch. */
260 unsigned int major
, /* IGNORED */
261 unsigned int minor
, /* IGNORED */
262 char type
, /* IGNORED */
263 int traverse_symlinks
)
265 struct dentry
*dentry
= NULL
;
271 memset(&nd
, 0, sizeof(nd
));
273 nd
.mnt
= mntget(hwgfs_vfsmount
);
274 nd
.dentry
= dget(base
? base
: hwgfs_vfsmount
->mnt_sb
->s_root
);
275 nd
.flags
= (traverse_symlinks
? LOOKUP_FOLLOW
: 0);
277 error
= path_walk(name
, &nd
);
278 if (likely(!error
)) {
280 path_release(&nd
); /* stale data from here! */
290 struct dentry
*parent
;
292 spin_lock(&de
->d_lock
);
293 parent
= de
->d_parent
;
294 spin_unlock(&de
->d_lock
);
304 if (unlikely(de
== NULL
))
317 EXPORT_SYMBOL(hwgfs_generate_path
);
318 EXPORT_SYMBOL(hwgfs_register
);
319 EXPORT_SYMBOL(hwgfs_unregister
);
320 EXPORT_SYMBOL(hwgfs_mk_symlink
);
321 EXPORT_SYMBOL(hwgfs_mk_dir
);
322 EXPORT_SYMBOL(hwgfs_find_handle
);
323 EXPORT_SYMBOL(hwgfs_get_parent
);
324 EXPORT_SYMBOL(hwgfs_set_info
);
325 EXPORT_SYMBOL(hwgfs_get_info
);