/* * Handle completion of a page being read from the cache. * - Called in process (keventd) context. */ static void nfs_readpage_from_fscache_complete(struct page *page, void *context, int error) { // dfprintk(FSCACHE, // "NFS: readpage_from_fscache_complete (0x%p/0x%p/%d)\n", ; /* if the read completes with an error, we just unlock the page and let * the VM reissue the readpage */ if (!error) { SetPageUptodate(page); unlock_page(page); } else { error = nfs_readpage_async(context, page->mapping->host, page); if (error) unlock_page(page); } }
/* * Read a page over NFS. * We read the page synchronously in the following cases: * - The file is a swap file. Swap-ins are always sync operations, * so there's no need bothering to make async reads 100% fail-safe. * - The NFS rsize is smaller than PAGE_SIZE. We could kludge our way * around this by creating several consecutive read requests, but * that's hardly worth it. * - The error flag is set for this page. This happens only when a * previous async read operation failed. * - The server is congested. */ int nfs_readpage(struct file *file, struct page *page) { struct dentry *dentry = file->f_dentry; struct inode *inode = dentry->d_inode; int error; dprintk("NFS: nfs_readpage (%p %ld@%ld)\n", page, PAGE_SIZE, page->offset); atomic_inc(&page->count); set_bit(PG_locked, &page->flags); /* * Try to flush any pending writes to the file.. * * NOTE! Because we own the page lock, there cannot * be any new pending writes generated at this point * for this page (other pages can be written to). */ error = nfs_wb_page(inode, page); if (error) goto out_error; error = -1; if (!IS_SWAPFILE(inode) && !PageError(page) && NFS_SERVER(inode)->rsize >= PAGE_SIZE) error = nfs_readpage_async(dentry, inode, page); if (error >= 0) goto out; error = nfs_readpage_sync(dentry, inode, page); if (error < 0 && IS_SWAPFILE(inode)) printk("Aiee.. nfs swap-in of page failed!\n"); goto out_free; out_error: clear_bit(PG_locked, &page->flags); out_free: free_page(page_address(page)); out: return error; }