#if defined(AFS_LINUX24_ENV)
#include "h/smp_lock.h"
#endif
-#if defined(AFS_CACHE_BYPASS)
#include "afs/lock.h"
#include "afs/afs_bypasscache.h"
-#endif
-
-#include "osi_pagecopy.h"
#ifdef pgoff2loff
#define pageoff(pp) pgoff2loff((pp)->index)
#define pageoff(pp) pp->offset
#endif
-#ifndef HAVE_PAGEVEC_LRU_ADD_FILE
-#define __pagevec_lru_add_file __pagevec_lru_add
-#endif
-
#ifndef MAX_ERRNO
#define MAX_ERRNO 1000L
#endif
{
ssize_t code = 0;
struct vcache *vcp = VTOAFS(fp->f_dentry->d_inode);
-#if defined(AFS_CACHE_BYPASS) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
afs_size_t isize, offindex;
#endif
code = afs_linux_VerifyVCache(vcp, NULL);
if (code == 0) {
-#if defined(AFS_CACHE_BYPASS) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
isize = (i_size_read(fp->f_mapping->host) - 1) >> PAGE_CACHE_SHIFT;
offindex = *offp >> PAGE_CACHE_SHIFT;
if(offindex > isize) {
* so we optimise by not using it */
osi_FlushPages(vcp, NULL); /* ensure stale pages are gone */
AFS_GUNLOCK();
-#ifdef DO_SYNC_READ
+#ifdef HAVE_LINUX_DO_SYNC_READ
code = do_sync_read(fp, buf, count, offp);
#else
code = generic_file_read(fp, buf, count, offp);
afs_Trace4(afs_iclSetp, CM_TRACE_READOP, ICL_TYPE_POINTER, vcp,
ICL_TYPE_OFFSET, offp, ICL_TYPE_INT32, count, ICL_TYPE_INT32,
code);
-#if defined(AFS_CACHE_BYPASS) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
done:
#endif
AFS_GUNLOCK();
{
struct vcache *avc = VTOAFS(FILE_INODE(fp));
struct vrequest treq;
- register struct dcache *tdc;
+ struct dcache *tdc;
int code;
int offset;
int dirpos;
if (!dirpos)
break;
- de = afs_dir_GetBlob(tdc, dirpos);
- if (!de)
+ code = afs_dir_GetBlob(tdc, dirpos, &entry);
+ if (code)
break;
+ de = (struct DirEntry *)entry.data;
- ino = afs_calc_inum (avc->f.fid.Fid.Volume, ntohl(de->fid.vnode));
+ ino = afs_calc_inum(avc->f.fid.Cell, avc->f.fid.Fid.Volume,
+ ntohl(de->fid.vnode));
if (de->name)
len = strlen(de->name);
flock.l_pid = flp->fl_pid;
flock.l_whence = 0;
flock.l_start = flp->fl_start;
- flock.l_len = flp->fl_end - flp->fl_start + 1;
+ if (flp->fl_end == OFFSET_MAX)
+ flock.l_len = 0; /* Lock to end of file */
+ else
+ flock.l_len = flp->fl_end - flp->fl_start + 1;
/* Safe because there are no large files, yet */
#if defined(F_GETLK64) && (F_GETLK != F_GETLK64)
#endif /* F_GETLK64 && F_GETLK != F_GETLK64 */
AFS_GLOCK();
- code = afs_lockctl(vcp, &flock, cmd, credp);
+ code = afs_convert_code(afs_lockctl(vcp, &flock, cmd, credp));
AFS_GUNLOCK();
#ifdef AFS_LINUX24_ENV
if ((conflict = posix_test_lock(fp, flp))) {
locks_copy_lock(flp, conflict);
flp->fl_type = F_UNLCK;
- crfee(credp);
+ crfree(credp);
return 0;
}
# else
flp->fl_type = flock.l_type;
flp->fl_pid = flock.l_pid;
flp->fl_start = flock.l_start;
- flp->fl_end = flock.l_start + flock.l_len - 1;
+ if (flock.l_len == 0)
+ flp->fl_end = OFFSET_MAX; /* Lock to end of file */
+ else
+ flp->fl_end = flock.l_start + flock.l_len - 1;
crfree(credp);
- return afs_convert_code(code);
+ return code;
}
#ifdef STRUCT_FILE_OPERATIONS_HAS_FLOCK
flock.l_pid = flp->fl_pid;
flock.l_whence = 0;
flock.l_start = 0;
- flock.l_len = OFFSET_MAX;
+ flock.l_len = 0;
/* Safe because there are no large files, yet */
#if defined(F_GETLK64) && (F_GETLK != F_GETLK64)
#endif /* F_GETLK64 && F_GETLK != F_GETLK64 */
AFS_GLOCK();
- code = afs_lockctl(vcp, &flock, cmd, credp);
+ code = afs_convert_code(afs_lockctl(vcp, &flock, cmd, credp));
AFS_GUNLOCK();
if ((code == 0 || flp->fl_type == F_UNLCK) &&
flp->fl_pid = flock.l_pid;
crfree(credp);
- return afs_convert_code(code);
+ return code;
}
#endif
struct vcache *vcp;
cred_t *credp;
int code;
-#if defined(AFS_CACHE_BYPASS)
int bypasscache;
-#endif
AFS_GLOCK();
code = afs_InitReq(&treq, credp);
if (code)
goto out;
-#if defined(AFS_CACHE_BYPASS)
/* If caching is bypassed for this file, or globally, just return 0 */
if(cache_bypass_strategy == ALWAYS_BYPASS_CACHE)
bypasscache = 1;
/* future proof: don't rely on 0 return from afs_InitReq */
code = 0; goto out;
}
-#endif
ObtainSharedLock(&vcp->lock, 535);
if ((vcp->execsOrWriters > 0) && (file_count(fp) == 1)) {
struct file_operations afs_file_fops = {
.read = afs_linux_read,
.write = afs_linux_write,
-#ifdef GENERIC_FILE_AIO_READ
+#ifdef HAVE_LINUX_GENERIC_FILE_AIO_READ
.aio_read = generic_file_aio_read,
.aio_write = generic_file_aio_write,
#endif
*/
if (vcp->f.states & CStatd &&
(!afs_fakestat_enable || vcp->mvstat != 1) &&
- !afs_nfsexporter) {
+ !afs_nfsexporter &&
+ (vType(vcp) == VDIR || vType(vcp) == VLNK)) {
code = afs_CopyOutAttrs(vcp, &vattr);
} else {
credp = crref();
afs_getattr(vcp, &vattr, credp);
afs_fill_inode(ip, &vattr);
if (
-#ifdef HAVE_KERNEL_HLIST_UNHASHED
+#ifdef HAVE_LINUX_HLIST_UNHASHED
hlist_unhashed(&ip->i_hash)
#else
ip->i_hash.prev == NULL
{
int code;
cred_t *credp = crref();
- uio_t tuio;
+ struct uio tuio;
struct iovec iov;
setup_uio(&tuio, &iov, target, (afs_offs_t) 0, maxlen, UIO_READ, seg);
#endif /* AFS_LINUX24_ENV */
#endif /* USABLE_KERNEL_PAGE_SYMLINK_CACHE */
-#if defined(AFS_CACHE_BYPASS)
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-
static inline int
afs_linux_can_bypass(struct inode *ip) {
switch(cache_bypass_strategy) {
if(i_size_read(ip) > cache_bypass_threshold)
return 1;
default:
+ return 0;
}
- return 0;
-}
-
-static int
-afs_linux_cache_bypass_read(struct file *fp, struct address_space *mapping,
- struct list_head *page_list, unsigned num_pages)
-{
- afs_int32 page_ix;
- uio_t *auio;
- afs_offs_t offset;
- struct iovec* iovecp;
- struct nocache_read_request *ancr;
- struct page *pp, *ppt;
- struct pagevec lrupv;
- afs_int32 code = 0;
-
- cred_t *credp;
- struct inode *ip = FILE_INODE(fp);
- struct vcache *avc = VTOAFS(ip);
- afs_int32 bypasscache = 0; /* bypass for this read */
- afs_int32 base_index = 0;
- afs_int32 page_count = 0;
- afs_int32 isize;
-
- /* background thread must free: iovecp, auio, ancr */
- iovecp = osi_Alloc(num_pages * sizeof(struct iovec));
-
- auio = osi_Alloc(sizeof(uio_t));
- auio->uio_iov = iovecp;
- auio->uio_iovcnt = num_pages;
- auio->uio_flag = UIO_READ;
- auio->uio_seg = AFS_UIOSYS;
- auio->uio_resid = num_pages * PAGE_SIZE;
-
- ancr = osi_Alloc(sizeof(struct nocache_read_request));
- ancr->auio = auio;
- ancr->offset = auio->uio_offset;
- ancr->length = auio->uio_resid;
-
- pagevec_init(&lrupv, 0);
-
- for(page_ix = 0; page_ix < num_pages; ++page_ix) {
-
- if(list_empty(page_list))
- break;
-
- pp = list_entry(page_list->prev, struct page, lru);
- /* If we allocate a page and don't remove it from page_list,
- * the page cache gets upset. */
- list_del(&pp->lru);
- isize = (i_size_read(fp->f_mapping->host) - 1) >> PAGE_CACHE_SHIFT;
- if(pp->index > isize) {
- if(PageLocked(pp))
- UnlockPage(pp);
- continue;
- }
-
- if(page_ix == 0) {
- offset = ((loff_t) pp->index) << PAGE_CACHE_SHIFT;
- auio->uio_offset = offset;
- base_index = pp->index;
- }
- iovecp[page_ix].iov_len = PAGE_SIZE;
- code = add_to_page_cache(pp, mapping, pp->index, GFP_KERNEL);
- if(base_index != pp->index) {
- if(PageLocked(pp))
- UnlockPage(pp);
- page_cache_release(pp);
- iovecp[page_ix].iov_base = (void *) 0;
- base_index++;
- continue;
- }
- base_index++;
- if(code) {
- if(PageLocked(pp))
- UnlockPage(pp);
- page_cache_release(pp);
- iovecp[page_ix].iov_base = (void *) 0;
- } else {
- page_count++;
- if(!PageLocked(pp)) {
- LockPage(pp);
- }
-
- /* save the page for background map */
- iovecp[page_ix].iov_base = (void*) pp;
-
- /* and put it on the LRU cache */
- if (!pagevec_add(&lrupv, pp))
- __pagevec_lru_add(&lrupv);
- }
- }
-
- /* If there were useful pages in the page list, make sure all pages
- * are in the LRU cache, then schedule the read */
- if(page_count) {
- pagevec_lru_add(&lrupv);
- credp = crref();
- code = afs_ReadNoCache(avc, ancr, credp);
- crfree(credp);
- } else {
- /* If there is nothing for the background thread to handle,
- * it won't be freeing the things that we never gave it */
- osi_Free(iovecp, num_pages * sizeof(struct iovec));
- osi_Free(auio, sizeof(uio_t));
- osi_Free(ancr, sizeof(struct nocache_read_request));
- }
- /* we do not flush, release, or unmap pages--that will be
- * done for us by the background thread as each page comes in
- * from the fileserver */
-out:
- return afs_convert_code(code);
-}
-
-#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */
-#endif /* defined(AFS_CACHE_BYPASS */
-
-static int
-afs_linux_read_cache(struct file *cachefp, struct page *page,
- int chunk, struct pagevec *lrupv,
- struct afs_pagecopy_task *task) {
- loff_t offset = page_offset(page);
- struct page *newpage, *cachepage;
- struct address_space *cachemapping;
- int pageindex;
- int code = 0;
-
- cachemapping = cachefp->f_dentry->d_inode->i_mapping;
- newpage = NULL;
- cachepage = NULL;
-
- /* From our offset, we now need to work out which page in the disk
- * file it corresponds to. This will be fun ... */
- pageindex = (offset - AFS_CHUNKTOBASE(chunk)) >> PAGE_CACHE_SHIFT;
-
- while (cachepage == NULL) {
- cachepage = find_get_page(cachemapping, pageindex);
- if (!cachepage) {
- if (!newpage)
- newpage = page_cache_alloc_cold(cachemapping);
- if (!newpage) {
- code = -ENOMEM;
- goto out;
- }
-
- code = add_to_page_cache(newpage, cachemapping,
- pageindex, GFP_KERNEL);
- if (code == 0) {
- cachepage = newpage;
- newpage = NULL;
-
- page_cache_get(cachepage);
- if (!pagevec_add(lrupv, cachepage))
- __pagevec_lru_add_file(lrupv);
-
- } else {
- page_cache_release(newpage);
- newpage = NULL;
- if (code != -EEXIST)
- goto out;
- }
- } else {
- lock_page(cachepage);
- }
- }
-
- if (!PageUptodate(cachepage)) {
- ClearPageError(cachepage);
- code = cachemapping->a_ops->readpage(NULL, cachepage);
- if (!code && !task) {
- wait_on_page_locked(cachepage);
- }
- } else {
- unlock_page(cachepage);
- }
-
- if (!code) {
- if (PageUptodate(cachepage)) {
- copy_highpage(page, cachepage);
- flush_dcache_page(page);
- SetPageUptodate(page);
- UnlockPage(page);
- } else if (task) {
- afs_pagecopy_queue_page(task, cachepage, page);
- } else {
- code = -EIO;
- }
- }
-
- if (code) {
- UnlockPage(page);
- }
-
-out:
- if (cachepage)
- page_cache_release(cachepage);
-
- return code;
-}
-
-static int inline
-afs_linux_readpage_fastpath(struct file *fp, struct page *pp, int *codep)
-{
- loff_t offset = page_offset(pp);
- struct inode *ip = FILE_INODE(fp);
- struct vcache *avc = VTOAFS(ip);
- struct dcache *tdc;
- struct file *cacheFp = NULL;
- int code;
- int dcLocked = 0;
- struct pagevec lrupv;
-
- /* Not a UFS cache, don't do anything */
- if (cacheDiskType != AFS_FCACHE_TYPE_UFS)
- return 0;
-
- /* Can't do anything if the vcache isn't statd , or if the read
- * crosses a chunk boundary.
- */
- if (!(avc->f.states & CStatd) ||
- AFS_CHUNK(offset) != AFS_CHUNK(offset + PAGE_SIZE)) {
- return 0;
- }
-
- ObtainWriteLock(&avc->lock, 911);
-
- /* XXX - See if hinting actually makes things faster !!! */
-
- /* See if we have a suitable entry already cached */
- tdc = avc->dchint;
-
- if (tdc) {
- /* We need to lock xdcache, then dcache, to handle situations where
- * the hint is on the free list. However, we can't safely do this
- * according to the locking hierarchy. So, use a non blocking lock.
- */
- ObtainReadLock(&afs_xdcache);
- dcLocked = ( 0 == NBObtainReadLock(&tdc->lock));
-
- if (dcLocked && (tdc->index != NULLIDX)
- && !FidCmp(&tdc->f.fid, &avc->f.fid)
- && tdc->f.chunk == AFS_CHUNK(offset)
- && !(afs_indexFlags[tdc->index] & (IFFree | IFDiscarded))) {
- /* Bonus - the hint was correct */
- afs_RefDCache(tdc);
- } else {
- /* Only destroy the hint if its actually invalid, not if there's
- * just been a locking failure */
- if (dcLocked) {
- ReleaseReadLock(&tdc->lock);
- avc->dchint = NULL;
- }
-
- tdc = NULL;
- dcLocked = 0;
- }
- ReleaseReadLock(&afs_xdcache);
- }
-
- /* No hint, or hint is no longer valid - see if we can get something
- * directly from the dcache
- */
- if (!tdc)
- tdc = afs_FindDCache(avc, offset);
-
- if (!tdc) {
- ReleaseWriteLock(&avc->lock);
- return 0;
- }
-
- if (!dcLocked)
- ObtainReadLock(&tdc->lock);
-
- /* Is the dcache we've been given currently up to date */
- if (!hsame(avc->f.m.DataVersion, tdc->f.versionNo) ||
- (tdc->dflags & DFFetching)) {
- ReleaseWriteLock(&avc->lock);
- ReleaseReadLock(&tdc->lock);
- afs_PutDCache(tdc);
- return 0;
- }
-
- /* Update our hint for future abuse */
- avc->dchint = tdc;
-
- /* Okay, so we've now got a cache file that is up to date */
-
- /* XXX - I suspect we should be locking the inodes before we use them! */
- AFS_GUNLOCK();
- cacheFp = afs_linux_raw_open(&tdc->f.inode, NULL);
- pagevec_init(&lrupv, 0);
-
- code = afs_linux_read_cache(cacheFp, pp, tdc->f.chunk, &lrupv, NULL);
-
- if (pagevec_count(&lrupv))
- __pagevec_lru_add_file(&lrupv);
-
- filp_close(cacheFp, NULL);
- AFS_GLOCK();
-
- ReleaseReadLock(&tdc->lock);
- ReleaseWriteLock(&avc->lock);
- afs_PutDCache(tdc);
-
- *codep = code;
- return 1;
}
/* afs_linux_readpage
ulong address = afs_linux_page_address(pp);
afs_offs_t offset = pageoff(pp);
#endif
-#if defined(AFS_CACHE_BYPASS)
afs_int32 bypasscache = 0; /* bypass for this read */
struct nocache_read_request *ancr;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
afs_int32 isize;
#endif
-#endif
- uio_t *auio;
+ struct uio *auio;
struct iovec *iovecp;
struct inode *ip = FILE_INODE(fp);
afs_int32 cnt = page_count(pp);
struct vcache *avc = VTOAFS(ip);
cred_t *credp;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- AFS_GLOCK();
- if (afs_linux_readpage_fastpath(fp, pp, &code)) {
- AFS_GUNLOCK();
- return code;
- }
- AFS_GUNLOCK();
-#endif
-
credp = crref();
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
address = kmap(pp);
set_bit(PG_locked, &pp->flags); /* other bits? See mm.h */
clear_bit(PG_error, &pp->flags);
#endif
-#if defined(AFS_CACHE_BYPASS)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- /* If the page is past the end of the file, skip it */
- isize = (i_size_read(fp->f_mapping->host) - 1) >> PAGE_CACHE_SHIFT;
- if(pp->index > isize) {
- if(PageLocked(pp))
- UnlockPage(pp);
- goto done;
- }
-#endif
-#endif
/* if bypasscache, receiver frees, else we do */
- auio = osi_Alloc(sizeof(uio_t));
+ auio = osi_Alloc(sizeof(struct uio));
iovecp = osi_Alloc(sizeof(struct iovec));
setup_uio(auio, iovecp, (char *)address, offset, PAGE_SIZE, UIO_READ,
AFS_UIOSYS);
-#if defined(AFS_CACHE_BYPASS)
bypasscache = afs_linux_can_bypass(ip);
/* In the new incarnation of selective caching, a file's caching policy
goto done; /* skips release page, doing it in bg thread */
}
-#endif
#ifdef AFS_LINUX24_ENV
maybe_lock_kernel();
free_page(address);
#endif
-#if defined(AFS_CACHE_BYPASS)
/* do not call afs_GetDCache if cache is bypassed */
if(bypasscache)
goto done;
-#endif
/* free if not bypassing cache */
- osi_Free(auio, sizeof(uio_t));
+ osi_Free(auio, sizeof(struct uio));
osi_Free(iovecp, sizeof(struct iovec));
if (!code && AFS_CHUNKOFFSET(offset) == 0) {
AFS_GUNLOCK();
}
-#if defined(AFS_CACHE_BYPASS)
done:
-#endif
crfree(credp);
return afs_convert_code(code);
}
-/* Readpages reads a number of pages for a particular file. We use
- * this to optimise the reading, by limiting the number of times upon which
- * we have to lookup, lock and open vcaches and dcaches
- */
-
-static int
-afs_linux_readpages(struct file *fp, struct address_space *mapping,
- struct list_head *page_list, unsigned int num_pages)
-{
- struct inode *inode = mapping->host;
- struct vcache *avc = VTOAFS(inode);
- struct dcache *tdc;
- struct file *cacheFp = NULL;
- int code;
- unsigned int page_idx;
- loff_t offset;
- struct pagevec lrupv;
- struct afs_pagecopy_task *task;
-
-#if defined(AFS_CACHE_BYPASS)
- bypasscache = afs_linux_can_bypass(ip);
-
- /* In the new incarnation of selective caching, a file's caching policy
- * can change, eg because file size exceeds threshold, etc. */
- trydo_cache_transition(avc, credp, bypasscache);
-
- if (bypasscache)
- return afs_linux_cache_bypass_read(ip, mapping, page_list, num_pages);
-#endif
-
- AFS_GLOCK();
- if ((code = afs_linux_VerifyVCache(avc, NULL))) {
- AFS_GUNLOCK();
- return code;
- }
-
- ObtainWriteLock(&avc->lock, 912);
- AFS_GUNLOCK();
-
- task = afs_pagecopy_init_task();
-
- tdc = NULL;
- pagevec_init(&lrupv, 0);
- for (page_idx = 0; page_idx < num_pages; page_idx++) {
- struct page *page = list_entry(page_list->prev, struct page, lru);
- list_del(&page->lru);
- offset = page_offset(page);
-
- if (tdc && tdc->f.chunk != AFS_CHUNK(offset)) {
- AFS_GLOCK();
- ReleaseReadLock(&tdc->lock);
- afs_PutDCache(tdc);
- AFS_GUNLOCK();
- tdc = NULL;
- if (cacheFp)
- filp_close(cacheFp, NULL);
- }
-
- if (!tdc) {
- AFS_GLOCK();
- if ((tdc = afs_FindDCache(avc, offset))) {
- ObtainReadLock(&tdc->lock);
- if (!hsame(avc->f.m.DataVersion, tdc->f.versionNo) ||
- (tdc->dflags & DFFetching)) {
- ReleaseReadLock(&tdc->lock);
- afs_PutDCache(tdc);
- tdc = NULL;
- }
- }
- AFS_GUNLOCK();
- if (tdc)
- cacheFp = afs_linux_raw_open(&tdc->f.inode, NULL);
- }
-
- if (tdc && !add_to_page_cache(page, mapping, page->index,
- GFP_KERNEL)) {
- page_cache_get(page);
- if (!pagevec_add(&lrupv, page))
- __pagevec_lru_add_file(&lrupv);
-
- afs_linux_read_cache(cacheFp, page, tdc->f.chunk, &lrupv, task);
- }
- page_cache_release(page);
- }
- if (pagevec_count(&lrupv))
- __pagevec_lru_add_file(&lrupv);
-
- if (tdc)
- filp_close(cacheFp, NULL);
-
- afs_pagecopy_put_task(task);
-
- AFS_GLOCK();
- if (tdc) {
- ReleaseReadLock(&tdc->lock);
- afs_PutDCache(tdc);
- }
-
- ReleaseWriteLock(&avc->lock);
- AFS_GUNLOCK();
- return 0;
-}
-
#if defined(AFS_LINUX24_ENV)
static int
afs_linux_writepage_sync(struct inode *ip, struct page *pp,
afs_offs_t base;
int code = 0;
cred_t *credp;
- uio_t tuio;
+ struct uio tuio;
struct iovec iovec;
int f_flags = 0;
u8 *page_addr = (u8 *) afs_linux_page_address(pp);
int code = 0;
cred_t *credp;
- uio_t tuio;
+ struct uio tuio;
struct iovec iovec;
set_bit(PG_locked, &pp->flags);
return afs_convert_code(code);
}
-#if defined(AFS_LINUX24_ENV) && !defined(HAVE_WRITE_BEGIN)
+#if defined(AFS_LINUX24_ENV) && !defined(STRUCT_ADDRESS_SPACE_OPERATIONS_HAS_WRITE_BEGIN)
static int
afs_linux_commit_write(struct file *file, struct page *page, unsigned offset,
unsigned to)
}
#endif
-#if defined(HAVE_WRITE_BEGIN)
+#if defined(STRUCT_ADDRESS_SPACE_OPERATIONS_HAS_WRITE_BEGIN)
static int
afs_linux_write_end(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
{
struct page *page;
pgoff_t index = pos >> PAGE_CACHE_SHIFT;
-#if defined(HAVE_GRAB_CACHE_PAGE_WRITE_BEGIN)
+#if defined(HAVE_LINUX_GRAB_CACHE_PAGE_WRITE_BEGIN)
page = grab_cache_page_write_begin(mapping, index, flags);
#else
page = __grab_cache_page(mapping, index);
#if defined(AFS_LINUX24_ENV)
static struct address_space_operations afs_file_aops = {
.readpage = afs_linux_readpage,
- .readpages = afs_linux_readpages,
.writepage = afs_linux_writepage,
-#if defined (HAVE_WRITE_BEGIN)
+#if defined (STRUCT_ADDRESS_SPACE_OPERATIONS_HAS_WRITE_BEGIN)
.write_begin = afs_linux_write_begin,
.write_end = afs_linux_write_end,
#else