linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / net / sunrpc / rpc_pipe.c
index 0573df5..a5c0c7b 100644 (file)
@@ -8,6 +8,7 @@
  * 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>
@@ -90,8 +91,7 @@ rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg)
                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;
@@ -132,7 +132,7 @@ rpc_close_pipes(struct inode *inode)
                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);
@@ -394,7 +394,7 @@ enum {
  */
 struct rpc_filelist {
        char *name;
-       const struct file_operations *i_fop;
+       struct file_operations *i_fop;
        int mode;
 };
 
@@ -434,17 +434,14 @@ static struct rpc_filelist authfiles[] = {
        },
 };
 
-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);
 }
@@ -454,13 +451,12 @@ rpc_lookup_parent(char *path, struct nameidata *nd)
 {
        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;
@@ -490,6 +486,7 @@ rpc_get_inode(struct super_block *sb, int mode)
                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) {
@@ -514,7 +511,7 @@ rpc_depopulate(struct dentry *parent)
        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) {
@@ -538,7 +535,6 @@ repeat:
                                rpc_close_pipes(dentry->d_inode);
                                simple_unlink(dir, dentry);
                        }
-                       inode_dir_notify(dir, DN_DELETE);
                        dput(dentry);
                } while (n);
                goto repeat;
@@ -597,6 +593,7 @@ __rpc_mkdir(struct inode *dir, struct dentry *dentry)
        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",
@@ -610,13 +607,14 @@ __rpc_rmdir(struct inode *dir, struct dentry *dentry)
        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;
 }
@@ -631,7 +629,7 @@ rpc_lookup_negative(char *path, struct nameidata *nd)
        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;
@@ -667,7 +665,6 @@ rpc_mkdir(char *path, struct rpc_clnt *rpc_client)
                        RPCAUTH_info, RPCAUTH_EOF);
        if (error)
                goto err_depopulate;
-       dget(dentry);
 out:
        mutex_unlock(&dir->i_mutex);
        rpc_release_path(&nd);
@@ -684,20 +681,28 @@ err_dput:
 }
 
 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;
 }
 
@@ -713,7 +718,7 @@ rpc_mkpipe(char *path, void *private, struct rpc_pipe_ops *ops, int flags)
        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);
@@ -724,7 +729,6 @@ rpc_mkpipe(char *path, void *private, struct rpc_pipe_ops *ops, int flags)
        rpci->flags = flags;
        rpci->ops = ops;
        inode_dir_notify(dir, DN_CREATE);
-       dget(dentry);
 out:
        mutex_unlock(&dir->i_mutex);
        rpc_release_path(&nd);
@@ -738,26 +742,32 @@ err_dput:
 }
 
 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;
 }
 
@@ -802,11 +812,11 @@ out:
        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 = {
@@ -839,10 +849,9 @@ init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
 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);