[OpenAFS-devel] patches to 1.0.1 for linux 2.4.0 final
Chas Williams
chas@cmf.nrl.navy.mil
Tue, 9 Jan 2001 12:39:05 -0500 (EST)
the following patches should get openafs 1.0.1 running with the 'final'
2.4.0 kernel release. i renamed _updatepage, to _writepage_sync, etc etc
so that it better matches the other filesystem code in hopes of making
this code a little easier to maintain. i would like to completely do
away with the set_bit() clear_bit() since the latest 2.2 series support
the ...Page...() macros.
Index: openafs/src/afs/afs_vcache.c
diff -u openafs/src/afs/afs_vcache.c:1.1.1.2 openafs/src/afs/afs_vcache.c:1.4
--- openafs/src/afs/afs_vcache.c:1.1.1.2 Tue Jan 9 12:27:11 2001
+++ openafs/src/afs/afs_vcache.c Tue Jan 9 12:27:11 2001
@@ -923,7 +923,10 @@
sema_init(&ip->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
Index: openafs/src/afs/LINUX/osi_vfs.h
diff -u openafs/src/afs/LINUX/osi_vfs.h:1.1.1.2 openafs/src/afs/LINUX/osi_vfs.h:1.3
--- openafs/src/afs/LINUX/osi_vfs.h:1.1.1.2 Tue Jan 9 12:27:16 2001
+++ openafs/src/afs/LINUX/osi_vfs.h Tue Jan 9 12:27:16 2001
@@ -26,6 +26,8 @@
struct list_head i_list;
struct list_head i_dentry;
+ struct list_head i_dirty_buffers;
+
unsigned long i_ino;
unsigned int i_count;
kdev_t i_dev;
@@ -76,6 +78,9 @@
#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;
Index: openafs/src/afs/LINUX/osi_vfsops.c
diff -u openafs/src/afs/LINUX/osi_vfsops.c:1.1.1.2 openafs/src/afs/LINUX/osi_vfsops.c:1.4
--- openafs/src/afs/LINUX/osi_vfsops.c:1.1.1.2 Tue Jan 9 12:27:16 2001
+++ openafs/src/afs/LINUX/osi_vfsops.c Tue Jan 9 12:27:16 2001
@@ -210,7 +210,11 @@
* 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);
Index: openafs/src/afs/LINUX/osi_vnodeops.c
diff -u openafs/src/afs/LINUX/osi_vnodeops.c:1.1.1.2 openafs/src/afs/LINUX/osi_vnodeops.c:1.7
--- openafs/src/afs/LINUX/osi_vnodeops.c:1.1.1.2 Tue Jan 9 12:27:17 2001
+++ openafs/src/afs/LINUX/osi_vnodeops.c Tue Jan 9 12:27:17 2001
@@ -160,7 +160,6 @@
AFS_GLOCK();
AFS_STATCNT(afs_readdir);
-
code = afs_InitReq(&treq, credp);
crfree(credp);
if (code) {
@@ -823,7 +822,6 @@
const char *comp = dp->d_name.name;
AFS_GLOCK();
code = afs_lookup((struct vcache *)dip, comp, &vcp, credp);
-
if (vcp) {
struct inode *ip = (struct inode*)vcp;
/* Reset ops if symlink or directory. */
@@ -955,7 +953,6 @@
vattr.va_mask = ATTR_MODE;
vattr.va_mode = mode;
code = afs_mkdir((struct vcache*)dip, name, &vattr, &tvcp, credp);
-
if (tvcp) {
tvcp->v.v_op = &afs_dir_iops;
#if defined(AFS_LINUX24_ENV)
@@ -1095,6 +1092,7 @@
}
else {
name[code] = '\0';
+
res = lookup_dentry(name, basep, follow);
}
@@ -1125,8 +1123,12 @@
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,
@@ -1147,10 +1149,18 @@
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);
@@ -1165,25 +1175,30 @@
}
#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
@@ -1230,6 +1245,56 @@
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
@@ -1239,32 +1304,23 @@
unsigned long offset,
unsigned int count, int sync)
{
- struct vcache *vcp = (struct vcache *)FILE_INODE(fp);
+ struct vcache *vcp = (struct vcache *) FILE_INODE(fp);
u8 *page_addr = (u8*) afs_linux_page_address(pp);
int code = 0;
cred_t *credp;
uio_t tuio;
struct iovec iovec;
-
+
set_bit(PG_locked, &pp->flags);
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);
@@ -1276,23 +1332,22 @@
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<<PAGE_CACHE_SHIFT) + to;
- status = afs_linux_updatepage(file, page, offset, to-offset, 1);
+ /* lock_kernel(); */
+ status = afs_linux_updatepage(file, page, offset, to-offset);
+ /* unlock_kernel(); */
kunmap(page);
return status;