Commit c385d3e1 authored by Trond Myklebust's avatar Trond Myklebust Committed by Linus Torvalds

[PATCH] Support for cached lookups via readdirplus [3/6]

Cache the information about whether or not the server supports
READDIRPLUS.
parent 002d7911
......@@ -107,14 +107,16 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
again:
error = NFS_PROTO(inode)->readdir(inode, cred, desc->entry->cookie, page,
NFS_SERVER(inode)->dtsize, desc->plus);
/* We requested READDIRPLUS, but the server doesn't grok it */
if (desc->plus && error == -ENOTSUPP) {
NFS_FLAGS(inode) &= ~NFS_INO_ADVISE_RDPLUS;
desc->plus = 0;
goto again;
}
if (error < 0)
if (error < 0) {
/* We requested READDIRPLUS, but the server doesn't grok it */
if (error == -ENOTSUPP && desc->plus) {
NFS_SERVER(inode)->caps &= ~NFS_CAP_READDIRPLUS;
NFS_FLAGS(inode) &= ~NFS_INO_ADVISE_RDPLUS;
desc->plus = 0;
goto again;
}
goto error;
}
SetPageUptodate(page);
/* Ensure consistent page alignment of the data.
* Note: assumes we have exclusive access to this mapping either
......@@ -194,7 +196,6 @@ int find_dirent_page(nfs_readdir_descriptor_t *desc)
dfprintk(VFS, "NFS: find_dirent_page() searching directory page %ld\n", desc->page_index);
desc->plus = NFS_USE_READDIRPLUS(inode);
page = read_cache_page(&inode->i_data, desc->page_index,
(filler_t *)nfs_readdir_filler, desc);
if (IS_ERR(page)) {
......@@ -376,6 +377,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
desc->file = filp;
desc->target = filp->f_pos;
desc->decode = NFS_PROTO(inode)->decode_dirent;
desc->plus = NFS_USE_READDIRPLUS(inode);
my_entry.cookie = my_entry.prev_cookie = 0;
my_entry.eof = 0;
......
......@@ -283,12 +283,14 @@ int nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int sile
INIT_LIST_HEAD(&server->lru_busy);
nfsv3_try_again:
server->caps = 0;
/* Check NFS protocol revision and initialize RPC op vector
* and file handle pool. */
if (data->flags & NFS_MOUNT_VER3) {
#ifdef CONFIG_NFS_V3
server->rpc_ops = &nfs_v3_clientops;
version = 3;
server->caps |= NFS_CAP_READDIRPLUS;
if (data->version < 4) {
printk(KERN_NOTICE "NFS: NFSv3 not supported by mount program.\n");
goto out_unlock;
......
......@@ -225,8 +225,15 @@ do { \
#define NFS_FILEID(inode) (NFS_I(inode)->fileid)
/* Inode Flags */
#define NFS_USE_READDIRPLUS(inode) ((NFS_FLAGS(inode) & NFS_INO_ADVISE_RDPLUS) ? 1 : 0)
static inline int nfs_server_capable(struct inode *inode, int cap)
{
return NFS_SERVER(inode)->caps & cap;
}
static inline int NFS_USE_READDIRPLUS(struct inode *inode)
{
return NFS_FLAGS(inode) & NFS_INO_ADVISE_RDPLUS;
}
static inline
loff_t page_offset(struct page *page)
......
......@@ -10,6 +10,7 @@ struct nfs_server {
struct rpc_clnt * client; /* RPC client handle */
struct nfs_rpc_ops * rpc_ops; /* NFS protocol vector */
int flags; /* various flags */
unsigned int caps; /* server capabilities */
unsigned int rsize; /* read size */
unsigned int rpages; /* read size (in pages) */
unsigned int wsize; /* write size */
......@@ -31,4 +32,7 @@ struct nfs_server {
struct sockaddr_in addr;
};
/* Server capabilities */
#define NFS_CAP_READDIRPLUS (1)
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment