Implements host filesystem support


Index: linux-2.6.33-source/fs/cofusefs/Kconfig
===================================================================
--- /dev/null
+++ linux-2.6.33-source/fs/cofusefs/Kconfig
@@ -0,0 +1,13 @@
+config COFUSE_FS
+	tristate "Cooperative Host file system support (COFUSE)"
+	depends on COOPERATIVE
+	default y
+	help
+	  In Cooperative mode, this file system allows you to mount an host
+	  directory structure to a local mountpoint.
+	  COFUSE (Cooperative FUSE) is based on the original FUSE
+	  (File System in User Space).
+
+	  To compile the cofuse support as a module, choose M here: the
+	  module will be called cofusefs.
+
Index: linux-2.6.33-source/fs/Kconfig
===================================================================
--- linux-2.6.33-source.orig/fs/Kconfig
+++ linux-2.6.33-source/fs/Kconfig
@@ -62,6 +62,7 @@
 source "fs/autofs/Kconfig"
 source "fs/autofs4/Kconfig"
 source "fs/fuse/Kconfig"
+source "fs/cofusefs/Kconfig"
 
 config CUSE
 	tristate "Character device in Userpace support"
Index: linux-2.6.33-source/fs/Makefile
===================================================================
--- linux-2.6.33-source.orig/fs/Makefile
+++ linux-2.6.33-source/fs/Makefile
@@ -108,6 +108,7 @@
 obj-$(CONFIG_AUTOFS4_FS)	+= autofs4/
 obj-$(CONFIG_ADFS_FS)		+= adfs/
 obj-$(CONFIG_FUSE_FS)		+= fuse/
+obj-$(CONFIG_COFUSE_FS)		+= cofusefs/
 obj-$(CONFIG_UDF_FS)		+= udf/
 obj-$(CONFIG_SUN_OPENPROMFS)	+= openpromfs/
 obj-$(CONFIG_OMFS_FS)		+= omfs/
Index: linux-2.6.33-source/fs/cofusefs/Makefile
===================================================================
--- /dev/null
+++ linux-2.6.33-source/fs/cofusefs/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the Linux cofuse filesystem routines.
+#
+
+obj-$(CONFIG_COFUSE_FS) += cofusefs.o
+
+cofusefs-objs := inode.o dir.o file.o util.o dev.o
+
Index: linux-2.6.33-source/fs/cofusefs/dir.c
===================================================================
--- linux-2.6.33-source.orig/fs/cofusefs/dir.c
+++ linux-2.6.33-source/fs/cofusefs/dir.c
@@ -28,7 +28,7 @@
 static void change_attributes(struct inode *inode, struct fuse_attr *attr)
 {
 	if(S_ISREG(inode->i_mode) && i_size_read(inode) != attr->size)
-		invalidate_mapping_pages(inode->i_mapping, 0, -1);
+		invalidate_inode_pages2(inode->i_mapping);
 
 	inode->i_mode    = (inode->i_mode & S_IFMT) + (attr->mode & 07777);
 	inode->i_nlink   = attr->nlink;
@@ -388,7 +388,7 @@
 
 	if(inode->i_ino == FUSE_ROOT_INO) {
 		if(!(fc->flags & FUSE_ALLOW_OTHER) &&
-		   current->fsuid != fc->uid)
+		   current_fsuid() != fc->uid)
 			return -EACCES;
 	} else if(!(fc->flags & COFS_MOUNT_NOCACHE) &&
 		  time_before_eq(jiffies, entry->d_time + FUSE_REVALIDATE_TIME))
@@ -397,11 +397,11 @@
 	return fuse_do_getattr(inode);
 }
 
-static int _fuse_permission(struct inode *inode, int mask)
+static int fuse_permission(struct inode *inode, int mask)
 {
 	struct fuse_conn *fc = INO_FC(inode);
 
-	if(!(fc->flags & FUSE_ALLOW_OTHER) && current->fsuid != fc->uid)
+	if(!(fc->flags & FUSE_ALLOW_OTHER) && current_fsuid() != fc->uid)
 		return -EACCES;
 	else if(fc->flags & FUSE_DEFAULT_PERMISSIONS) {
 		int err = generic_permission(inode, mask, NULL);
@@ -758,12 +758,6 @@
 	return _fuse_create(dir, entry, mode);
 }
 
-static int fuse_permission(struct inode *inode, int mask,
-			    struct nameidata *nd)
-{
-	return _fuse_permission(inode, mask);
-}
-
 static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
 {
 	return _fuse_dentry_revalidate(entry);
Index: linux-2.6.33-source/fs/cofusefs/file.c
===================================================================
--- linux-2.6.33-source.orig/fs/cofusefs/file.c
+++ linux-2.6.33-source/fs/cofusefs/file.c
@@ -42,7 +42,7 @@
 	in.args[0].value = &inarg;
 	request_send(fc, &in, &out);
 	if(!out.h.error && !(fc->flags & FUSE_KERNEL_CACHE)) {
-		invalidate_mapping_pages(inode->i_mapping, 0, -1);
+		invalidate_inode_pages2(inode->i_mapping);
 	}
 
 	return out.h.error;
@@ -385,28 +385,54 @@
 	return err;
 }
 
-static int fuse_prepare_write(struct file *file, struct page *page,
-			      unsigned offset, unsigned to)
+static int fuse_write_begin(struct file *file, struct address_space *mapping,
+			loff_t pos, unsigned len, unsigned flags,
+			struct page **pagep, void **fsdata)
 {
-	/* No op */
+	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+
+	*pagep = grab_cache_page_write_begin(mapping, index, flags);
+	if (!*pagep)
+		return -ENOMEM;
 	return 0;
 }
 
-static int fuse_commit_write(struct file *file, struct page *page,
-			     unsigned offset, unsigned to)
+static int fuse_buffered_write(struct file *file, struct inode *inode,
+			       loff_t pos, unsigned count, struct page *page)
 {
 	int err;
-	struct inode *inode = page->mapping->host;
+	unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
+
+	if (is_bad_inode(inode))
+		return -EIO;
 
-	err = write_buffer(inode, page, offset, to - offset);
-	if(!err) {
-		loff_t pos = (page->index << PAGE_CACHE_SHIFT) + to;
+	err = write_buffer(inode, page, offset, count);
+	if (!err) {
+		pos += count;
 		if(pos > i_size_read(inode))
 			i_size_write(inode, pos);
+		if (count == PAGE_CACHE_SIZE)
+			SetPageUptodate(page);
 	}
-	return err;
+	return err ? err : count;
+}
+
+static int fuse_write_end(struct file *file, struct address_space *mapping,
+			loff_t pos, unsigned len, unsigned copied,
+			struct page *page, void *fsdata)
+{
+	struct inode *inode = mapping->host;
+	int res = 0;
+
+	if (copied)
+		res = fuse_buffered_write(file, inode, pos, copied, page);
+
+	unlock_page(page);
+	page_cache_release(page);
+	return res;
 }
 
+
 static struct file_operations fuse_file_operations = {
 	.llseek		= generic_file_llseek,
 	.read		= fuse_file_read,
@@ -421,10 +447,10 @@
 };
 
 static struct address_space_operations fuse_file_aops  = {
-	.readpage =		fuse_readpage,
-	.writepage =		fuse_writepage,
-	.prepare_write =	fuse_prepare_write,
-	.commit_write =		fuse_commit_write,
+	.readpage	= fuse_readpage,
+	.writepage	= fuse_writepage,
+	.write_begin	= fuse_write_begin,
+	.write_end	= fuse_write_end,
 };
 
 void fuse_init_file_inode(struct inode *inode)
Index: linux-2.6.33-source/fs/cofusefs/fuse_i.h
===================================================================
--- linux-2.6.33-source.orig/fs/cofusefs/fuse_i.h
+++ linux-2.6.33-source/fs/cofusefs/fuse_i.h
@@ -85,7 +85,7 @@
 	struct fuse_out_arg args[3];
 };
 
-#define FUSE_IN_INIT { {0, 0, 0, current->fsuid, current->fsgid}, 0}
+#define FUSE_IN_INIT { {0, 0, 0, current_fsuid(), current_fsgid()}, 0}
 #define FUSE_OUT_INIT { {0, 0}, 0, 0}
 
 struct fuse_req;
Index: linux-2.6.33-source/fs/cofusefs/inode.c
===================================================================
--- linux-2.6.33-source.orig/fs/cofusefs/inode.c
+++ linux-2.6.33-source/fs/cofusefs/inode.c
@@ -355,8 +355,8 @@
 	struct fuse_mount_data md = {0, };
 	int ret;
 
-	co_md.uid = current->uid;
-	co_md.gid = current->gid;
+	co_md.uid = current_uid();
+	co_md.gid = current_gid();
 	co_md.dir_mode = FUSE_S_IRWXU | FUSE_S_IRGRP | FUSE_S_IXGRP |
 		FUSE_S_IROTH | FUSE_S_IXOTH | S_IFDIR;
 	co_md.file_mode = FUSE_S_IRWXU | FUSE_S_IRGRP | FUSE_S_IXGRP |
