* Copyright (c) 2002, Trond Myklebust <trond.myklebust@fys.uio.no>
*
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/string.h>
res = 0;
} else if (rpci->flags & RPC_PIPE_WAIT_FOR_OPEN) {
if (list_empty(&rpci->pipe))
- queue_delayed_work(rpciod_workqueue,
- &rpci->queue_timeout,
+ schedule_delayed_work(&rpci->queue_timeout,
RPC_UPCALL_TIMEOUT);
list_add_tail(&msg->list, &rpci->pipe);
rpci->pipelen += msg->len;
if (ops->release_pipe)
ops->release_pipe(inode);
cancel_delayed_work(&rpci->queue_timeout);
- flush_workqueue(rpciod_workqueue);
+ flush_scheduled_work();
}
rpc_inode_setowner(inode, NULL);
mutex_unlock(&inode->i_mutex);
*/
struct rpc_filelist {
char *name;
- const struct file_operations *i_fop;
+ struct file_operations *i_fop;
int mode;
};
},
};
-struct vfsmount *rpc_get_mount(void)
+static int
+rpc_get_mount(void)
{
- int err;
-
- err = simple_pin_fs(&rpc_pipe_fs_type, &rpc_mount, &rpc_mount_count);
- if (err != 0)
- return ERR_PTR(err);
- return rpc_mount;
+ return simple_pin_fs("rpc_pipefs", &rpc_mount, &rpc_mount_count);
}
-void rpc_put_mount(void)
+static void
+rpc_put_mount(void)
{
simple_release_fs(&rpc_mount, &rpc_mount_count);
}
{
if (path[0] == '\0')
return -ENOENT;
- nd->mnt = rpc_get_mount();
- if (IS_ERR(nd->mnt)) {
+ if (rpc_get_mount()) {
printk(KERN_WARNING "%s: %s failed to mount "
"pseudofilesystem \n", __FILE__, __FUNCTION__);
- return PTR_ERR(nd->mnt);
+ return -ENODEV;
}
- mntget(nd->mnt);
+ nd->mnt = mntget(rpc_mount);
nd->dentry = dget(rpc_mount->mnt_root);
nd->last_type = LAST_ROOT;
nd->flags = LOOKUP_PARENT;
return NULL;
inode->i_mode = mode;
inode->i_uid = inode->i_gid = 0;
+ inode->i_blksize = PAGE_CACHE_SIZE;
inode->i_blocks = 0;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
switch(mode & S_IFMT) {
struct dentry *dentry, *dvec[10];
int n = 0;
- mutex_lock_nested(&dir->i_mutex, I_MUTEX_CHILD);
+ mutex_lock(&dir->i_mutex);
repeat:
spin_lock(&dcache_lock);
list_for_each_safe(pos, next, &parent->d_subdirs) {
rpc_close_pipes(dentry->d_inode);
simple_unlink(dir, dentry);
}
- inode_dir_notify(dir, DN_DELETE);
dput(dentry);
} while (n);
goto repeat;
d_instantiate(dentry, inode);
dir->i_nlink++;
inode_dir_notify(dir, DN_CREATE);
+ rpc_get_mount();
return 0;
out_err:
printk(KERN_WARNING "%s: %s failed to allocate inode for dentry %s\n",
int error;
shrink_dcache_parent(dentry);
- if (d_unhashed(dentry))
- return 0;
+ if (dentry->d_inode)
+ rpc_close_pipes(dentry->d_inode);
if ((error = simple_rmdir(dir, dentry)) != 0)
return error;
if (!error) {
inode_dir_notify(dir, DN_DELETE);
d_drop(dentry);
+ rpc_put_mount();
}
return 0;
}
if ((error = rpc_lookup_parent(path, nd)) != 0)
return ERR_PTR(error);
dir = nd->dentry->d_inode;
- mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
+ mutex_lock(&dir->i_mutex);
dentry = lookup_one_len(nd->last.name, nd->dentry, nd->last.len);
if (IS_ERR(dentry))
goto out_err;
RPCAUTH_info, RPCAUTH_EOF);
if (error)
goto err_depopulate;
- dget(dentry);
out:
mutex_unlock(&dir->i_mutex);
rpc_release_path(&nd);
}
int
-rpc_rmdir(struct dentry *dentry)
+rpc_rmdir(char *path)
{
- struct dentry *parent;
+ struct nameidata nd;
+ struct dentry *dentry;
struct inode *dir;
int error;
- parent = dget_parent(dentry);
- dir = parent->d_inode;
- mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
+ if ((error = rpc_lookup_parent(path, &nd)) != 0)
+ return error;
+ dir = nd.dentry->d_inode;
+ mutex_lock(&dir->i_mutex);
+ dentry = lookup_one_len(nd.last.name, nd.dentry, nd.last.len);
+ if (IS_ERR(dentry)) {
+ error = PTR_ERR(dentry);
+ goto out_release;
+ }
rpc_depopulate(dentry);
error = __rpc_rmdir(dir, dentry);
dput(dentry);
+out_release:
mutex_unlock(&dir->i_mutex);
- dput(parent);
+ rpc_release_path(&nd);
return error;
}
if (IS_ERR(dentry))
return dentry;
dir = nd.dentry->d_inode;
- inode = rpc_get_inode(dir->i_sb, S_IFIFO | S_IRUSR | S_IWUSR);
+ inode = rpc_get_inode(dir->i_sb, S_IFSOCK | S_IRUSR | S_IWUSR);
if (!inode)
goto err_dput;
inode->i_ino = iunique(dir->i_sb, 100);
rpci->flags = flags;
rpci->ops = ops;
inode_dir_notify(dir, DN_CREATE);
- dget(dentry);
out:
mutex_unlock(&dir->i_mutex);
rpc_release_path(&nd);
}
int
-rpc_unlink(struct dentry *dentry)
+rpc_unlink(char *path)
{
- struct dentry *parent;
+ struct nameidata nd;
+ struct dentry *dentry;
struct inode *dir;
- int error = 0;
+ int error;
- parent = dget_parent(dentry);
- dir = parent->d_inode;
- mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
- if (!d_unhashed(dentry)) {
- d_drop(dentry);
- if (dentry->d_inode) {
- rpc_close_pipes(dentry->d_inode);
- error = simple_unlink(dir, dentry);
- }
- inode_dir_notify(dir, DN_DELETE);
+ if ((error = rpc_lookup_parent(path, &nd)) != 0)
+ return error;
+ dir = nd.dentry->d_inode;
+ mutex_lock(&dir->i_mutex);
+ dentry = lookup_one_len(nd.last.name, nd.dentry, nd.last.len);
+ if (IS_ERR(dentry)) {
+ error = PTR_ERR(dentry);
+ goto out_release;
+ }
+ d_drop(dentry);
+ if (dentry->d_inode) {
+ rpc_close_pipes(dentry->d_inode);
+ error = simple_unlink(dir, dentry);
}
dput(dentry);
+ inode_dir_notify(dir, DN_DELETE);
+out_release:
mutex_unlock(&dir->i_mutex);
- dput(parent);
+ rpc_release_path(&nd);
return error;
}
return -ENOMEM;
}
-static int
+static struct super_block *
rpc_get_sb(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+ int flags, const char *dev_name, void *data)
{
- return get_sb_single(fs_type, flags, data, rpc_fill_super, mnt);
+ return get_sb_single(fs_type, flags, data, rpc_fill_super);
}
static struct file_system_type rpc_pipe_fs_type = {
int register_rpc_pipefs(void)
{
rpc_inode_cachep = kmem_cache_create("rpc_inode_cache",
- sizeof(struct rpc_inode),
- 0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|
- SLAB_MEM_SPREAD),
- init_once, NULL);
+ sizeof(struct rpc_inode),
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
+ init_once, NULL);
if (!rpc_inode_cachep)
return -ENOMEM;
register_filesystem(&rpc_pipe_fs_type);