Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 217070
b: refs/heads/master
c: d39ab9d
h: refs/heads/master
v: v3
  • Loading branch information
Bryan Schumaker authored and Trond Myklebust committed Oct 23, 2010
1 parent fe48124 commit 0ed55f2
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: baf57a09e9d87b14be5e2788828169394a2525ab
refs/heads/master: d39ab9de3b80da5835049b1c3b49da4e84e01c07
67 changes: 67 additions & 0 deletions trunk/fs/nfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,71 @@ int xdr_decode(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, __be32 *
return 0;
}

static
int nfs_same_file(struct dentry *dentry, struct nfs_entry *entry)
{
struct nfs_inode *node;
if (dentry->d_inode == NULL)
goto different;
node = NFS_I(dentry->d_inode);
if (node->fh.size != entry->fh->size)
goto different;
if (strncmp(node->fh.data, entry->fh->data, node->fh.size) != 0)
goto different;
return 1;
different:
return 0;
}

static
void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry)
{
struct qstr filename;
struct dentry *dentry = NULL;
struct dentry *alias = NULL;
struct inode *dir = parent->d_inode;
struct inode *inode;

nfs_readdir_make_qstr(&filename, entry->name, entry->len);
if (filename.len == 1 && filename.name[0] == '.')
dentry = dget(parent);
else if (filename.len == 2 && filename.name[0] == '.'
&& filename.name[1] == '.')
dentry = dget_parent(parent);
else
dentry = d_lookup(parent, &filename);

if (dentry != NULL) {
if (nfs_same_file(dentry, entry)) {
nfs_refresh_inode(dentry->d_inode, entry->fattr);
goto out;
} else {
d_drop(dentry);
dput(dentry);
}
}

dentry = d_alloc(parent, &filename);
dentry->d_op = NFS_PROTO(dir)->dentry_ops;
inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr);
if (IS_ERR(inode))
goto out;

alias = d_materialise_unique(dentry, inode);
if (IS_ERR(alias))
goto out;
else if (alias) {
nfs_set_verifier(alias, nfs_save_change_attribute(dir));
dput(alias);
} else
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));

out:
dput(dentry);
kfree(filename.name);
return;
}

/* Perform conversion from xdr to cache array */
static
void nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry,
Expand All @@ -379,6 +444,8 @@ void nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *e
while (xdr_decode(desc, entry, &ptr) == 0) {
if (nfs_readdir_add_to_array(entry, page) == -1)
break;
if (desc->plus == 1)
nfs_prime_dcache(desc->file->f_path.dentry, entry);
}
kunmap(xdr_page);
}
Expand Down

0 comments on commit 0ed55f2

Please sign in to comment.