From 1b0a7f95e9451da9c7d55fa8204fdc1c2949cd34 Mon Sep 17 00:00:00 2001 From: Chas Williams Date: Thu, 11 Jan 2001 06:15:52 +0000 Subject: [PATCH] update-for-linux-240-final-20010111 Update Linux 2.4 support for the 2.4.0 release kernel. --- src/afs/LINUX/osi_vfs.h | 6 ++- src/afs/LINUX/osi_vfsops.c | 4 ++ src/afs/LINUX/osi_vnodeops.c | 101 +++++++++++++++++++++++++++-------- src/afs/afs_vcache.c | 5 +- 4 files changed, 92 insertions(+), 24 deletions(-) diff --git a/src/afs/LINUX/osi_vfs.h b/src/afs/LINUX/osi_vfs.h index 74f7515b7..77b7bcff9 100644 --- a/src/afs/LINUX/osi_vfs.h +++ b/src/afs/LINUX/osi_vfs.h @@ -25,7 +25,9 @@ typedef struct vnode { struct list_head i_hash; struct list_head i_list; struct list_head i_dentry; - +#if defined(AFS_LINUX24_ENV) + struct list_head i_dirty_buffers; +#endif unsigned long i_ino; unsigned int i_count; kdev_t i_dev; @@ -76,6 +78,8 @@ typedef struct vnode { #if defined(AFS_LINUX24_ENV) struct pipe_inode_info *i_pipe; struct block_device *i_bdev; + unsigned long i_dnotify_mask; + struct dnotify_struct *i_dnotify; #endif unsigned long i_state; diff --git a/src/afs/LINUX/osi_vfsops.c b/src/afs/LINUX/osi_vfsops.c index 3e9faa1e1..d1939581a 100644 --- a/src/afs/LINUX/osi_vfsops.c +++ b/src/afs/LINUX/osi_vfsops.c @@ -210,7 +210,11 @@ static LIST_HEAD(dummy_inode_list); * pages to disk. So it needs an inode syncing function to update metadata when it * has synced some pages of a file to disk. */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +void afs_write_inode(struct inode *ip, int unused) +#else void afs_write_inode(struct inode *ip) +#endif { /* and put it back on our dummy list. */ list_del(&ip->i_list); diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 2bc82879a..05cfc8ae2 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -1126,8 +1126,12 @@ int afs_linux_readpage(struct file *fp, struct page *pp) ICL_TYPE_INT32, cnt, ICL_TYPE_INT32, 99999); /* not a possible code value */ atomic_add(1, &pp->count); +#if defined(AFS_LINUX24_ENV) + ClearPageError(pp); +#else set_bit(PG_locked, &pp->flags); /* other bits? See mm.h */ clear_bit(PG_error, &pp->flags); +#endif #if defined(AFS_LINUX24_ENV) setup_uio(&tuio, &iovec, (char*)address, pp->index << PAGE_CACHE_SHIFT, @@ -1148,10 +1152,18 @@ int afs_linux_readpage(struct file *fp, struct page *pp) if (tuio.uio_resid) /* zero remainder of page */ memset((void*)(address+(PAGESIZE-tuio.uio_resid)), 0, tuio.uio_resid); +#if defined(AFS_LINUX24_ENV) + SetPageUptodate(pp); +#else set_bit(PG_uptodate, &pp->flags); +#endif } +#if defined(AFS_LINUX24_ENV) + UnlockPage(pp); +#else clear_bit(PG_locked, &pp->flags); +#endif wake_up(&pp->wait); free_page(address); @@ -1166,25 +1178,30 @@ int afs_linux_readpage(struct file *fp, struct page *pp) } #if defined(AFS_LINUX24_ENV) -int afs_linux_writepage(struct file *file, struct page *page) +int afs_linux_writepage(struct page *pp) { - struct dentry *dentry = file->f_dentry; - struct inode *inode = dentry->d_inode; - unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT; + struct address_space *mapping = pp->mapping; + struct inode *inode; + unsigned long end_index; unsigned offset = PAGE_CACHE_SIZE; long status; + inode = (struct inode *) mapping->host; + end_index = inode->i_size >> PAGE_CACHE_SHIFT; + /* easy case */ - if (page->index < end_index) + if (pp->index < end_index) goto do_it; /* things got complicated... */ offset = inode->i_size & (PAGE_CACHE_SIZE-1); /* OK, are we completely out? */ - if (page->index >= end_index+1 || !offset) + if (pp->index >= end_index+1 || !offset) return -EIO; do_it: - status = afs_linux_updatepage(file, page, 0, offset, 1); - kunmap(page); + status = afs_linux_writepage_sync(inode, pp, 0, offset); + SetPageUptodate(pp); + UnlockPage(pp); + /* kunmap(pp); */ if (status == offset) return 0; else @@ -1231,6 +1248,56 @@ int afs_linux_permission(struct inode *ip, int mode) int afs_linux_smap(struct inode *ip, int) { return -EINVAL; } #endif +#if defined(AFS_LINUX24_ENV) +int afs_linux_writepage_sync(struct inode *ip, struct page *pp, + unsigned long offset, + unsigned int count) +{ + struct vcache *vcp = (struct vcache *) ip; + u8 *page_addr = (u8*) afs_linux_page_address(pp); + int code = 0; + cred_t *credp; + uio_t tuio; + struct iovec iovec; + int f_flags = 0; + + credp = crref(); + AFS_GLOCK(); + lock_kernel(); + afs_Trace4(afs_iclSetp, CM_TRACE_UPDATEPAGE, ICL_TYPE_POINTER, vcp, + ICL_TYPE_POINTER, pp, + ICL_TYPE_INT32, atomic_read(&pp->count), + ICL_TYPE_INT32, 99999); + setup_uio(&tuio, &iovec, page_addr + offset, + (pp->index << PAGE_CACHE_SHIFT) + offset, count, + UIO_WRITE, AFS_UIOSYS); + + code = afs_write(vcp, &tuio, f_flags, credp, 0); + + vcache2inode(vcp); + + code = code ? -code : count - tuio.uio_resid; + afs_Trace4(afs_iclSetp, CM_TRACE_UPDATEPAGE, ICL_TYPE_POINTER, vcp, + ICL_TYPE_POINTER, pp, + ICL_TYPE_INT32, atomic_read(&pp->count), + ICL_TYPE_INT32, code); + + unlock_kernel(); + AFS_GUNLOCK(); + crfree(credp); + + return code; +} + +static int +afs_linux_updatepage(struct file *file, struct page *page, + unsigned long offset, unsigned int count) +{ + struct dentry *dentry = file->f_dentry; + + return afs_linux_writepage_sync(dentry->d_inode, page, offset, count); +} +#else /* afs_linux_updatepage * What one would have thought was writepage - write dirty page to file. * Called from generic_file_write. buffer is still in user space. pagep @@ -1251,21 +1318,12 @@ int afs_linux_updatepage(struct file *fp, struct page *pp, credp = crref(); AFS_GLOCK(); -#ifdef AFS_LINUX24_ENV - lock_kernel(); -#endif afs_Trace4(afs_iclSetp, CM_TRACE_UPDATEPAGE, ICL_TYPE_POINTER, vcp, ICL_TYPE_POINTER, pp, ICL_TYPE_INT32, atomic_read(&pp->count), ICL_TYPE_INT32, 99999); -#if defined(AFS_LINUX24_ENV) - setup_uio(&tuio, &iovec, page_addr + offset, - (pp->index << PAGE_CACHE_SHIFT) + offset, count, - UIO_WRITE, AFS_UIOSYS); -#else setup_uio(&tuio, &iovec, page_addr + offset, pp->offset + offset, count, UIO_WRITE, AFS_UIOSYS); -#endif code = afs_write(vcp, &tuio, fp->f_flags, credp, 0); @@ -1277,23 +1335,22 @@ int afs_linux_updatepage(struct file *fp, struct page *pp, ICL_TYPE_INT32, atomic_read(&pp->count), ICL_TYPE_INT32, code); -#ifdef AFS_LINUX24_ENV - unlock_kernel(); -#endif AFS_GUNLOCK(); crfree(credp); clear_bit(PG_locked, &pp->flags); return code; } +#endif #if defined(AFS_LINUX24_ENV) static int afs_linux_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to) { long status; - loff_t pos = ((loff_t)page->index<i_zombie, 1); init_waitqueue_head(&ip->i_wait); spin_lock_init(&ip->i_data.i_shared_lock); - INIT_LIST_HEAD(&ip->i_data.pages); + INIT_LIST_HEAD(&ip->i_data.clean_pages); + INIT_LIST_HEAD(&ip->i_data.dirty_pages); + INIT_LIST_HEAD(&ip->i_data.locked_pages); + INIT_LIST_HEAD(&ip->i_dirty_buffers); ip->i_data.host = (void*) ip; ip->i_mapping = &ip->i_data; #else -- 2.39.5