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