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@cs.cmu.edu\n");
+ printk(KERN_INFO "Coda Kernel/Venus communications, v5.3.15, coda@cs.cmu.edu\n");
status = init_coda_psdev();
if ( status ) {
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/