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 (unlikely(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);
92 if (unlikely(IS_ERR(*dentry)))
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);