Coda File System

[PATCH] Re: Coda and Ext3

From: Jan Harkes <jaharkes_at_cs.cmu.edu>
Date: Wed, 19 Sep 2001 21:37:14 -0400
On Wed, Sep 19, 2001 at 10:23:36AM -0400, Sujal Shah wrote:
>      The Linux Coda drivers and the ext3 patches don't seem to get along
> very well, at least in Linux 2.4.7.  I've got a stock 2.4.7 kernel with

The attached patch should fix it. I haven't tested it against ext3, but
with tmpfs which used to have the same problem, i.e. not using
generic_file_ functions to access the container files. I'll pass it on
to Linus and Alan once I get some feedback on whether this solves all
problems. I believe this will fix the whole batch of problems that are
have been reported with ext3fs, XFS, and tmpfs.

It should apply fine for kernel versions 2.4.4 and higher (both the AC
and the Linus trees).

btw. my comment about disabling ext3 data journalling fixing it was
bogus, there was a BUG() in Coda that got triggered because f_op->write
wasn't generic_file_write.

Jan

diff -urN --exclude-from=dontdiff linux-2.4.10-pre9/fs/coda/file.c linux/fs/coda/file.c
--- linux-2.4.10-pre9/fs/coda/file.c	Thu Sep  6 20:02:24 2001
+++ linux/fs/coda/file.c	Wed Sep 19 20:26:41 2001
@@ -31,28 +31,65 @@
 int use_coda_close;
 
 static ssize_t
-coda_file_write(struct file *file,const char *buf,size_t count,loff_t *ppos)
+coda_file_read(struct file *file, char *buf, size_t count, loff_t *ppos)
 {
+	struct inode *inode = file->f_dentry->d_inode;
+	struct coda_inode_info *cii = ITOC(inode);
 	struct file *cfile;
+
+	cfile = cii->c_container;
+	if (!cfile) BUG();
+
+	if (!cfile->f_op || !cfile->f_op->read)
+		return -EINVAL;
+
+	return cfile->f_op->read(cfile, buf, count, ppos);
+}
+
+static ssize_t
+coda_file_write(struct file *file,const char *buf,size_t count,loff_t *ppos)
+{
 	struct inode *cinode, *inode = file->f_dentry->d_inode;
 	struct coda_inode_info *cii = ITOC(inode);
-	ssize_t n;
+	struct file *cfile;
+	ssize_t ret;
+	int flags;
 
 	cfile = cii->c_container;
 	if (!cfile) BUG();
 
-	if (!cfile->f_op || cfile->f_op->write != generic_file_write)
-		BUG();
+	if (!cfile->f_op || !cfile->f_op->write)
+		return -EINVAL;
 
 	cinode = cfile->f_dentry->d_inode;
-	down(&cinode->i_sem);
+	down(&inode->i_sem);
+	flags = cfile->f_flags;
+        cfile->f_flags |= file->f_flags & (O_APPEND | O_SYNC);
+
+	ret = cfile->f_op->write(cfile, buf, count, ppos);
 
-	n = generic_file_write(file, buf, count, ppos);
+	cfile->f_flags = flags;
 	inode->i_size = cinode->i_size;
+	up(&inode->i_sem);
+
+	return ret;
+}
+
+static int
+coda_file_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct inode *inode = file->f_dentry->d_inode;
+	struct coda_inode_info *cii = ITOC(inode);
+	struct file *cfile;
+
+	cfile = cii->c_container;
+
+	if (!cfile) BUG();
 
-	up(&cinode->i_sem);
+	if (!cfile->f_op || !cfile->f_op->mmap)
+		return -ENODEV;
 
-	return n;
+	return cfile->f_op->mmap(cfile, vma);
 }
 
 int coda_open(struct inode *i, struct file *f)
@@ -237,9 +274,9 @@
 
 struct file_operations coda_file_operations = {
 	llseek:		generic_file_llseek,
-	read:		generic_file_read,
+	read:		coda_file_read,
 	write:		coda_file_write,
-	mmap:		generic_file_mmap,
+	mmap:		coda_file_mmap,
 	open:		coda_open,
 	flush:  	coda_flush,
 	release:	coda_release,
diff -urN --exclude-from=dontdiff linux-2.4.10-pre9/fs/coda/psdev.c linux/fs/coda/psdev.c
--- linux-2.4.10-pre9/fs/coda/psdev.c	Wed Apr 25 19:18:54 2001
+++ linux/fs/coda/psdev.c	Wed Sep 19 18:45:46 2001
@@ -414,7 +414,7 @@
 static int __init init_coda(void)
 {
 	int status;
-	printk(KERN_INFO "Coda Kernel/Venus communications, v5.3.14, coda_at_cs.cmu.edu\n");
+	printk(KERN_INFO "Coda Kernel/Venus communications, v5.3.15, coda_at_cs.cmu.edu\n");
 
 	status = init_coda_psdev();
 	if ( status ) {
Received on 2001-09-19 21:40:29