[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;