X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fsunrpc%2Frpc_pipe.c;fp=net%2Fsunrpc%2Frpc_pipe.c;h=a5c0c7b6e151b4a8712ec67d3c3cdbf32308497c;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=0573df512f44fdf5fc2e373e39610295547168e8;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 0573df512..a5c0c7b6e 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -8,6 +8,7 @@ * Copyright (c) 2002, Trond Myklebust * */ +#include #include #include #include @@ -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);