/* The file offset position is now represented as a true offset into the * page cache as is the case in most of the other filesystems. */ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) { struct dentry *dentry = filp->f_dentry; struct inode *inode = dentry->d_inode; nfs_readdir_descriptor_t my_desc, *desc = &my_desc; struct nfs_entry my_entry; long res; res = nfs_revalidate(dentry); if (res < 0) return res; /* * filp->f_pos points to the file offset in the page cache. * but if the cache has meanwhile been zapped, we need to * read from the last dirent to revalidate f_pos * itself. */ memset(desc, 0, sizeof(*desc)); memset(&my_entry, 0, sizeof(my_entry)); desc->file = filp; desc->target = filp->f_pos; desc->entry = &my_entry; desc->decode = NFS_PROTO(inode)->decode_dirent; while(!desc->entry->eof) { res = readdir_search_pagecache(desc); if (res == -EBADCOOKIE) { /* This means either end of directory */ if (desc->entry->cookie != desc->target) { /* Or that the server has 'lost' a cookie */ res = uncached_readdir(desc, dirent, filldir); if (res >= 0) continue; } res = 0; break; } else if (res < 0) break; res = nfs_do_filldir(desc, dirent, filldir); if (res < 0) { res = 0; break; } } if (desc->error < 0) return desc->error; if (res < 0) return res; return 0; }
/* The file offset position is now represented as a true offset into the * page cache as is the case in most of the other filesystems. */ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) { struct dentry *dentry = filp->f_dentry; struct inode *inode = dentry->d_inode; nfs_readdir_descriptor_t my_desc, *desc = &my_desc; struct nfs_entry my_entry; struct nfs_fh fh; struct nfs_fattr fattr; long res; lock_kernel(); res = nfs_revalidate_inode(NFS_SERVER(inode), inode); if (res < 0) { unlock_kernel(); return res; } /* * filp->f_pos points to the file offset in the page cache. * but if the cache has meanwhile been zapped, we need to * read from the last dirent to revalidate f_pos * itself. */ memset(desc, 0, sizeof(*desc)); 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; my_entry.fh = &fh; my_entry.fattr = &fattr; desc->entry = &my_entry; while(!desc->entry->eof) { res = readdir_search_pagecache(desc); if (res == -EBADCOOKIE) { /* This means either end of directory */ if (desc->entry->cookie != desc->target) { /* Or that the server has 'lost' a cookie */ res = uncached_readdir(desc, dirent, filldir); if (res >= 0) continue; } res = 0; break; } if (res == -ETOOSMALL && desc->plus) { NFS_FLAGS(inode) &= ~NFS_INO_ADVISE_RDPLUS; nfs_zap_caches(inode); desc->plus = 0; desc->entry->eof = 0; continue; } if (res < 0) break; res = nfs_do_filldir(desc, dirent, filldir); if (res < 0) { res = 0; break; } } unlock_kernel(); if (desc->error < 0) return desc->error; if (res < 0) return res; return 0; }