|
@@ -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;
|
|
|
+}
|
|
|
+
|
|
|
+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;
|
|
@@ -666,11 +683,8 @@ static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent,
|
|
|
if (!dentry)
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
}
|
|
|
- if (dentry->d_inode == NULL) {
|
|
|
- if (!dentry->d_op)
|
|
|
- d_set_d_op(dentry, &rpc_dentry_operations);
|
|
|
+ if (dentry->d_inode == NULL)
|
|
|
return dentry;
|
|
|
- }
|
|
|
dput(dentry);
|
|
|
return ERR_PTR(-EEXIST);
|
|
|
}
|
|
@@ -1117,6 +1131,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);
|