summaryrefslogtreecommitdiffstats
path: root/net/sunrpc/rpc_pipe.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/rpc_pipe.c')
-rw-r--r--net/sunrpc/rpc_pipe.c69
1 files changed, 37 insertions, 32 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index e7ce4b3eb0bd..406859cc68aa 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -480,6 +480,23 @@ static const struct dentry_operations rpc_dentry_operations = {
.d_delete = rpc_delete_dentry,
};
+/*
+ * Lookup the data. This is trivial - if the dentry didn't already
+ * exist, we know it is negative.
+ */
+static struct dentry *
+rpc_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
+{
+ if (dentry->d_name.len > NAME_MAX)
+ return ERR_PTR(-ENAMETOOLONG);
+ d_add(dentry, NULL);
+ return NULL;
+}
+
+static const struct inode_operations rpc_dir_inode_operations = {
+ .lookup = rpc_lookup,
+};
+
static struct inode *
rpc_get_inode(struct super_block *sb, umode_t mode)
{
@@ -492,7 +509,7 @@ rpc_get_inode(struct super_block *sb, umode_t mode)
switch (mode & S_IFMT) {
case S_IFDIR:
inode->i_fop = &simple_dir_operations;
- inode->i_op = &simple_dir_inode_operations;
+ inode->i_op = &rpc_dir_inode_operations;
inc_nlink(inode);
default:
break;
@@ -656,20 +673,17 @@ static int __rpc_rmpipe(struct inode *dir, struct dentry *dentry)
}
static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent,
- struct qstr *name)
+ const char *name)
{
- struct dentry *dentry;
-
- dentry = d_lookup(parent, name);
+ struct qstr q = QSTR_INIT(name, strlen(name));
+ struct dentry *dentry = d_hash_and_lookup(parent, &q);
if (!dentry) {
- dentry = d_alloc(parent, name);
+ dentry = d_alloc(parent, &q);
if (!dentry)
return ERR_PTR(-ENOMEM);
}
- if (dentry->d_inode == NULL) {
- d_set_d_op(dentry, &rpc_dentry_operations);
+ if (dentry->d_inode == NULL)
return dentry;
- }
dput(dentry);
return ERR_PTR(-EEXIST);
}
@@ -689,8 +703,7 @@ static void __rpc_depopulate(struct dentry *parent,
for (i = start; i < eof; i++) {
name.name = files[i].name;
name.len = strlen(files[i].name);
- name.hash = full_name_hash(name.name, name.len);
- dentry = d_lookup(parent, &name);
+ dentry = d_hash_and_lookup(parent, &name);
if (dentry == NULL)
continue;
@@ -732,12 +745,7 @@ static int rpc_populate(struct dentry *parent,
mutex_lock(&dir->i_mutex);
for (i = start; i < eof; i++) {
- struct qstr q;
-
- q.name = files[i].name;
- q.len = strlen(files[i].name);
- q.hash = full_name_hash(q.name, q.len);
- dentry = __rpc_lookup_create_exclusive(parent, &q);
+ dentry = __rpc_lookup_create_exclusive(parent, files[i].name);
err = PTR_ERR(dentry);
if (IS_ERR(dentry))
goto out_bad;
@@ -770,7 +778,7 @@ out_bad:
}
static struct dentry *rpc_mkdir_populate(struct dentry *parent,
- struct qstr *name, umode_t mode, void *private,
+ const char *name, umode_t mode, void *private,
int (*populate)(struct dentry *, void *), void *args_populate)
{
struct dentry *dentry;
@@ -841,7 +849,6 @@ struct dentry *rpc_mkpipe_dentry(struct dentry *parent, const char *name,
struct dentry *dentry;
struct inode *dir = parent->d_inode;
umode_t umode = S_IFIFO | S_IRUSR | S_IWUSR;
- struct qstr q;
int err;
if (pipe->ops->upcall == NULL)
@@ -849,12 +856,8 @@ struct dentry *rpc_mkpipe_dentry(struct dentry *parent, const char *name,
if (pipe->ops->downcall == NULL)
umode &= ~S_IWUGO;
- q.name = name;
- q.len = strlen(name);
- q.hash = full_name_hash(q.name, q.len),
-
mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
- dentry = __rpc_lookup_create_exclusive(parent, &q);
+ dentry = __rpc_lookup_create_exclusive(parent, name);
if (IS_ERR(dentry))
goto out;
err = __rpc_mkpipe_dentry(dir, dentry, umode, &rpc_pipe_fops,
@@ -925,8 +928,8 @@ static void rpc_clntdir_depopulate(struct dentry *dentry)
/**
* rpc_create_client_dir - Create a new rpc_client directory in rpc_pipefs
- * @dentry: dentry from the rpc_pipefs root to the new directory
- * @name: &struct qstr for the name
+ * @dentry: the parent of new directory
+ * @name: the name of new directory
* @rpc_client: rpc client to associate with this directory
*
* This creates a directory at the given @path associated with
@@ -935,7 +938,7 @@ static void rpc_clntdir_depopulate(struct dentry *dentry)
* later be created using rpc_mkpipe().
*/
struct dentry *rpc_create_client_dir(struct dentry *dentry,
- struct qstr *name,
+ const char *name,
struct rpc_clnt *rpc_client)
{
return rpc_mkdir_populate(dentry, name, S_IRUGO | S_IXUGO, NULL,
@@ -981,7 +984,7 @@ static void rpc_cachedir_depopulate(struct dentry *dentry)
rpc_depopulate(dentry, cache_pipefs_files, 0, 3);
}
-struct dentry *rpc_create_cache_dir(struct dentry *parent, struct qstr *name,
+struct dentry *rpc_create_cache_dir(struct dentry *parent, const char *name,
umode_t umode, struct cache_detail *cd)
{
return rpc_mkdir_populate(parent, name, umode, NULL,
@@ -1061,9 +1064,7 @@ struct dentry *rpc_d_lookup_sb(const struct super_block *sb,
const unsigned char *dir_name)
{
struct qstr dir = QSTR_INIT(dir_name, strlen(dir_name));
-
- dir.hash = full_name_hash(dir.name, dir.len);
- return d_lookup(sb->s_root, &dir);
+ return d_hash_and_lookup(sb->s_root, &dir);
}
EXPORT_SYMBOL_GPL(rpc_d_lookup_sb);
@@ -1116,6 +1117,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
sb->s_magic = RPCAUTH_GSSMAGIC;
sb->s_op = &s_ops;
+ sb->s_d_op = &rpc_dentry_operations;
sb->s_time_gran = 1;
inode = rpc_get_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO);
@@ -1126,6 +1128,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
return -ENOMEM;
dprintk("RPC: sending pipefs MOUNT notification for net %p%s\n",
net, NET_NAME(net));
+ mutex_lock(&sn->pipefs_sb_lock);
sn->pipefs_sb = sb;
err = blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
RPC_PIPEFS_MOUNT,
@@ -1133,6 +1136,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
if (err)
goto err_depopulate;
sb->s_fs_info = get_net(net);
+ mutex_unlock(&sn->pipefs_sb_lock);
return 0;
err_depopulate:
@@ -1141,6 +1145,7 @@ err_depopulate:
sb);
sn->pipefs_sb = NULL;
__rpc_depopulate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF);
+ mutex_unlock(&sn->pipefs_sb_lock);
return err;
}
@@ -1162,12 +1167,12 @@ static void rpc_kill_sb(struct super_block *sb)
goto out;
}
sn->pipefs_sb = NULL;
- mutex_unlock(&sn->pipefs_sb_lock);
dprintk("RPC: sending pipefs UMOUNT notification for net %p%s\n",
net, NET_NAME(net));
blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
RPC_PIPEFS_UMOUNT,
sb);
+ mutex_unlock(&sn->pipefs_sb_lock);
put_net(net);
out:
kill_litter_super(sb);