- reiser4-make-methods-supplied-to-vfs-invariant.patch removed from -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled
     reiser4: make methods supplied to vfs invariant
has been removed from the -mm tree.  Its filename was
     reiser4-make-methods-supplied-to-vfs-invariant.patch

This patch was dropped because it was folded into reiser4.patch

The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/

------------------------------------------------------
Subject: reiser4: make methods supplied to vfs invariant
From: Edward Shishkin <edward.shishkin@xxxxxxxxx>

Problem:
hangs when writing to reiser4 partition exported via nfs
(found by Roc Vallès Domènech <rvalles@xxxxxxxxxx>).

Bug:
vfs (which is not aware of reiser4 plugin conversion) uses
obsolete copy of @file->f_op, whereas old methods are not
aware about new structures. It leads to memory corruption.

Fixup:
Prevent collisions with vfs:
Make inode_ops, file_ops and a_ops supplied to vfs
invariant with respect to plugin conversion.

Signed-off-by: Edward Shishkin <edward.shishkin@xxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
---

 fs/reiser4/as_ops.c                      |   40 ++
 fs/reiser4/inode.c                       |   20 -
 fs/reiser4/plugin/file/cryptcompress.c   |  107 +++----
 fs/reiser4/plugin/file/file.c            |   44 ---
 fs/reiser4/plugin/file/file.h            |  166 +++++++----
 fs/reiser4/plugin/file/file_conversion.c |  204 +++++++++-----
 fs/reiser4/plugin/file_ops.c             |   37 ++
 fs/reiser4/plugin/object.c               |  299 +++++++++++----------
 fs/reiser4/plugin/plugin.h               |   73 +++--
 9 files changed, 590 insertions(+), 400 deletions(-)

diff -puN fs/reiser4/as_ops.c~reiser4-make-methods-supplied-to-vfs-invariant fs/reiser4/as_ops.c
--- a/fs/reiser4/as_ops.c~reiser4-make-methods-supplied-to-vfs-invariant
+++ a/fs/reiser4/as_ops.c
@@ -326,6 +326,46 @@ int reiser4_releasepage(struct page *pag
 	}
 }
 
+int reiser4_readpage(struct file *file, struct page *page)
+{
+	assert("edward-1533", PageLocked(page));
+	assert("edward-1534", !PageUptodate(page));
+	assert("edward-1535", page->mapping && page->mapping->host);
+
+	return inode_file_plugin(page->mapping->host)->readpage(file, page);
+}
+
+int reiser4_readpages(struct file *file, struct address_space *mapping,
+		      struct list_head *pages, unsigned nr_pages)
+{
+	return inode_file_plugin(mapping->host)->readpages(file, mapping,
+							   pages, nr_pages);
+}
+
+int reiser4_writepages(struct address_space *mapping,
+		       struct writeback_control *wbc)
+{
+	return inode_file_plugin(mapping->host)->writepages(mapping, wbc);
+}
+
+int reiser4_prepare_write(struct file *file, struct page *page,
+			  unsigned from, unsigned to)
+{
+	return inode_file_plugin(file->f_dentry->d_inode)->prepare_write(file,
+									 page,
+									 from,
+									 to);
+}
+
+int reiser4_commit_write(struct file *file, struct page *page,
+			 unsigned from, unsigned to)
+{
+	return inode_file_plugin(file->f_dentry->d_inode)->commit_write(file,
+									page,
+									from,
+									to);
+}
+
 /* Make Linus happy.
    Local variables:
    c-indentation-style: "K&R"
diff -puN fs/reiser4/inode.c~reiser4-make-methods-supplied-to-vfs-invariant fs/reiser4/inode.c
--- a/fs/reiser4/inode.c~reiser4-make-methods-supplied-to-vfs-invariant
+++ a/fs/reiser4/inode.c
@@ -151,38 +151,38 @@ int setup_inode_ops(struct inode *inode 
 				rdev = data->rdev;
 			inode->i_blocks = 0;
 			assert("vs-42", fplug->h.id == SPECIAL_FILE_PLUGIN_ID);
-			inode->i_op = &file_plugins[fplug->h.id].inode_ops;
+			inode->i_op = file_plugins[fplug->h.id].inode_ops;
 			/* initialize inode->i_fop and inode->i_rdev for block and char
 			   devices */
 			init_special_inode(inode, inode->i_mode, rdev);
 			/* all address space operations are null */
 			inode->i_mapping->a_ops =
-			    &file_plugins[fplug->h.id].as_ops;
+			    file_plugins[fplug->h.id].as_ops;
 			break;
 		}
 	case S_IFLNK:
 		assert("vs-46", fplug != NULL);
 		assert("vs-42", fplug->h.id == SYMLINK_FILE_PLUGIN_ID);
-		inode->i_op = &file_plugins[fplug->h.id].inode_ops;
+		inode->i_op = file_plugins[fplug->h.id].inode_ops;
 		inode->i_fop = NULL;
 		/* all address space operations are null */
-		inode->i_mapping->a_ops = &file_plugins[fplug->h.id].as_ops;
+		inode->i_mapping->a_ops = file_plugins[fplug->h.id].as_ops;
 		break;
 	case S_IFDIR:
 		assert("vs-46", dplug != NULL);
 		assert("vs-43", (dplug->h.id == HASHED_DIR_PLUGIN_ID ||
 				 dplug->h.id == SEEKABLE_HASHED_DIR_PLUGIN_ID));
-		inode->i_op = &dir_plugins[dplug->h.id].inode_ops;
-		inode->i_fop = &dir_plugins[dplug->h.id].file_ops;
-		inode->i_mapping->a_ops = &dir_plugins[dplug->h.id].as_ops;
+		inode->i_op = dir_plugins[dplug->h.id].inode_ops;
+		inode->i_fop = dir_plugins[dplug->h.id].file_ops;
+		inode->i_mapping->a_ops = dir_plugins[dplug->h.id].as_ops;
 		break;
 	case S_IFREG:
 		assert("vs-46", fplug != NULL);
 		assert("vs-43", (fplug->h.id == UNIX_FILE_PLUGIN_ID ||
 				 fplug->h.id == CRYPTCOMPRESS_FILE_PLUGIN_ID));
-		inode->i_op = &file_plugins[fplug->h.id].inode_ops;
-		inode->i_fop = &file_plugins[fplug->h.id].file_ops;
-		inode->i_mapping->a_ops = &file_plugins[fplug->h.id].as_ops;
+		inode->i_op = file_plugins[fplug->h.id].inode_ops;
+		inode->i_fop = file_plugins[fplug->h.id].file_ops;
+		inode->i_mapping->a_ops = file_plugins[fplug->h.id].as_ops;
 		break;
 	default:
 		warning("nikita-291", "wrong file mode: %o for %llu",
diff -puN fs/reiser4/plugin/file/cryptcompress.c~reiser4-make-methods-supplied-to-vfs-invariant fs/reiser4/plugin/file/cryptcompress.c
--- a/fs/reiser4/plugin/file/cryptcompress.c~reiser4-make-methods-supplied-to-vfs-invariant
+++ a/fs/reiser4/plugin/file/cryptcompress.c
@@ -264,6 +264,7 @@ static void uninstantiate_crypto_info(st
 	info->inst = 0;
 }
 
+#if 0
 static int is_crypto_info_instantiated(struct reiser4_crypto_info * info)
 {
 	return info->inst;
@@ -275,6 +276,7 @@ static int inode_has_cipher_key(struct i
 	return inode_crypto_info(inode) &&
 		is_crypto_info_instantiated(inode_crypto_info(inode));
 }
+#endif
 
 static void free_crypto_info (struct inode * inode)
 {
@@ -465,7 +467,7 @@ static int inode_check_cluster(struct in
 	return 0;
 }
 
-/* ->destroy_inode() method of the cryptcompress plugin */
+/* plugin->destroy_inode() */
 void destroy_inode_cryptcompress(struct inode * inode)
 {
 	assert("edward-1464", INODE_PGCOUNT(inode) == 0);
@@ -473,15 +475,14 @@ void destroy_inode_cryptcompress(struct 
 	return;
 }
 
-/* ->create() method of the cryptcompress plugin
-
+/* plugin->create_object():
 . install plugins
 . attach crypto info if specified
 . attach compression info if specified
 . attach cluster info
 */
-int create_cryptcompress(struct inode *object, struct inode *parent,
-			 reiser4_object_create_data * data)
+int create_object_cryptcompress(struct inode *object, struct inode *parent,
+				reiser4_object_create_data * data)
 {
 	int result;
 	reiser4_inode *info;
@@ -521,33 +522,9 @@ int create_cryptcompress(struct inode *o
 	return result;
 }
 
-/* ->open_object() method of the cryptcompress plugin */
-int open_object_cryptcompress(struct inode * inode, struct file * file)
+/* plugin->open() */
+int open_cryptcompress(struct inode * inode, struct file * file)
 {
-	int result;
-	struct inode * parent;
-
-	assert("edward-1394", inode != NULL);
-	assert("edward-1395", file != NULL);
-	assert("edward-1396", file != NULL);
-	assert("edward-1397", file->f_dentry->d_inode == inode);
-	assert("edward-1398", file->f_dentry->d_parent != NULL);
-	assert("edward-1399", file->f_dentry->d_parent->d_inode != NULL);
-	assert("edward-698",
-	       inode_file_plugin(inode) ==
-	       file_plugin_by_id(CRYPTCOMPRESS_FILE_PLUGIN_ID));
-	result = inode_check_cluster(inode);
-	if (result)
-		return result;
-	result = inode_init_compression(inode);
-	if (result)
-		return result;
-	if (!need_cipher(inode))
-		/* the file is not to be ciphered */
-		return 0;
-	parent = file->f_dentry->d_parent->d_inode;
-	if (!inode_has_cipher_key(inode))
-		return RETERR(-EINVAL);
 	return 0;
 }
 
@@ -2657,6 +2634,7 @@ void reset_cluster_params(struct cluster
 	clust->tc.len = 0;
 }
 
+/* the heart of write_cryptcompress */
 static loff_t do_write_cryptcompress(struct file *file, struct inode *inode,
 				     const char __user *buf, size_t to_write,
 				     loff_t pos, int *conv_occured)
@@ -2817,14 +2795,11 @@ static loff_t do_write_cryptcompress(str
 }
 
 /**
- * write_cryptcompress - write of struct file_operations
+ * plugin->write()
  * @file: file to write to
  * @buf: address of user-space buffer
  * @read_amount: number of bytes to write
  * @off: position in file to write to
- *
- * This is implementation of vfs's write method of struct file_operations for
- * cryptcompress plugin.
  */
 ssize_t write_cryptcompress(struct file *file, const char __user *buf,
 			    size_t count, loff_t *off, int *conv)
@@ -2873,6 +2848,7 @@ ssize_t write_cryptcompress(struct file 
 	return result;
 }
 
+/* plugin->readpages */
 int readpages_cryptcompress(struct file *file, struct address_space *mapping,
 			    struct list_head *pages, unsigned nr_pages)
 {
@@ -2905,14 +2881,11 @@ static reiser4_block_nr cryptcompress_es
 }
 
 /**
- * read_cryptcompress - read of struct file_operations
+ * plugin->read
  * @file: file to read from
  * @buf: address of user-space buffer
  * @read_amount: number of bytes to read
  * @off: position in file to read from
- *
- * This is implementation of vfs's read method of struct file_operations for
- * cryptcompress plugin.
  */
 ssize_t read_cryptcompress(struct file * file, char __user *buf, size_t size,
 			   loff_t * off)
@@ -3046,6 +3019,8 @@ static void adjust_left_coord(coord_t * 
 }
 
 #define CRC_CUT_TREE_MIN_ITERATIONS 64
+
+/* plugin->cut_tree_worker */
 int cut_tree_worker_cryptcompress(tap_t * tap, const reiser4_key * from_key,
 				  const reiser4_key * to_key,
 				  reiser4_key * smallest_removed,
@@ -3405,8 +3380,10 @@ static int start_truncate_fake(struct in
 	return result;
 }
 
-/* This is called in setattr_cryptcompress when it is used to truncate,
- * and in delete_cryptcompress */
+/**
+ * This is called in setattr_cryptcompress when it is used to truncate,
+ * and in delete_object_cryptcompress
+ */
 static int cryptcompress_truncate(struct inode *inode,	/* old size */
 				  loff_t new_size,	/* new size */
 				  int update_sd)
@@ -3569,8 +3546,7 @@ static int cryptcompress_inode_has_anon_
 	return result;
 }
 
-/* This is implementation of vfs's writepages method of struct
-   address_space_operations */
+/* plugin->writepages */
 int writepages_cryptcompress(struct address_space *mapping,
 			     struct writeback_control *wbc)
 {
@@ -3647,7 +3623,14 @@ int writepages_cryptcompress(struct addr
 	return result;
 }
 
-/* plugin->u.file.mmap */
+/* plugin->ioctl */
+int ioctl_cryptcompress(struct inode *inode, struct file *filp,
+			unsigned int cmd, unsigned long arg)
+{
+	return 0;
+}
+
+/* plugin->mmap */
 int mmap_cryptcompress(struct file *file, struct vm_area_struct *vma)
 {
 	int result;
@@ -3674,12 +3657,7 @@ int mmap_cryptcompress(struct file *file
 	return result;
 }
 
-/* plugin->u.file.release */
-/* plugin->u.file.get_block */
-
-/* this is implementation of delete method of file plugin for
- * cryptcompress objects
- */
+/* plugin->delete_object */
 int delete_object_cryptcompress(struct inode *inode)
 {
 	int result;
@@ -3706,8 +3684,10 @@ int delete_object_cryptcompress(struct i
 	return reiser4_delete_object_common(inode);
 }
 
-/* plugin->u.file.setattr method
-   This implements actual truncate (see comments in reiser4/page_cache.c) */
+/*
+ * plugin->setattr
+ * This implements actual truncate (see comments in reiser4/page_cache.c)
+ */
 int setattr_cryptcompress(struct dentry *dentry, struct iattr *attr)
 {
 	int result;
@@ -3751,11 +3731,7 @@ int setattr_cryptcompress(struct dentry 
 	return result;
 }
 
-/*
- * release_cryptcompress - release of struct file_operations
- * @inode: inode of released file
- * @file: file to release
- */
+/* plugin->release */
 int release_cryptcompress(struct inode *inode, struct file *file)
 {
 	reiser4_context *ctx = reiser4_init_context(inode->i_sb);
@@ -3767,14 +3743,25 @@ int release_cryptcompress(struct inode *
 	return 0;
 }
 
-#if 0
+/* plugin->prepare_write */
 int prepare_write_cryptcompress(struct file *file, struct page *page,
 				unsigned from, unsigned to)
 {
-	return prepare_write_common(file, page, from, to);
+	return 0;
 }
-#endif  /*  0  */
 
+/* plugin->commit_write */
+int commit_write_cryptcompress(struct file *file, struct page *page,
+			       unsigned from, unsigned to)
+{
+	return 0;
+}
+
+/* plugin->bmap */
+sector_t bmap_cryptcompress(struct address_space *mapping, sector_t lblock)
+{
+	return -EINVAL;
+}
 
 /*
   Local variables:
diff -puN fs/reiser4/plugin/file/file.c~reiser4-make-methods-supplied-to-vfs-invariant fs/reiser4/plugin/file/file.c
--- a/fs/reiser4/plugin/file/file.c~reiser4-make-methods-supplied-to-vfs-invariant
+++ a/fs/reiser4/plugin/file/file.c
@@ -1372,42 +1372,6 @@ int writepages_unix_file(struct address_
 	return result;
 }
 
-/*
- * ->sync() method for unix file.
- *
- * We are trying to be smart here. Instead of committing all atoms (original
- * solution), we scan dirty pages of this file and commit all atoms they are
- * part of.
- *
- * Situation is complicated by anonymous pages: i.e., extent-less pages
- * dirtied through mmap. Fortunately sys_fsync() first calls
- * filemap_fdatawrite() that will ultimately call reiser4_writepages(), insert
- * all missing extents and capture anonymous pages.
- */
-int sync_unix_file(struct file *file, struct dentry *dentry, int datasync)
-{
-	reiser4_context *ctx;
-	txn_atom *atom;
-	reiser4_block_nr reserve;
-
-	ctx = reiser4_init_context(dentry->d_inode->i_sb);
-	if (IS_ERR(ctx))
-		return PTR_ERR(ctx);
-
-	reserve = estimate_update_common(dentry->d_inode);
-	if (reiser4_grab_space(reserve, BA_CAN_COMMIT)) {
-		reiser4_exit_context(ctx);
-		return RETERR(-ENOSPC);
-	}
-	write_sd_by_inode_common(dentry->d_inode);
-
-	atom = get_current_atom_locked();
-	spin_lock_txnh(ctx->trans);
-	force_commit_atom(ctx->trans);
-	reiser4_exit_context(ctx);
-	return 0;
-}
-
 /**
  * readpage_unix_file_nolock - readpage of struct address_space_operations
  * @file:
@@ -2126,7 +2090,7 @@ static void drop_access(struct unix_file
  * unix file plugin.
  */
 ssize_t write_unix_file(struct file *file, const char __user *buf,
-			size_t count, loff_t *pos)
+			size_t count, loff_t *pos, int *conv)
 {
 	int result;
 	reiser4_context *ctx;
@@ -2317,8 +2281,8 @@ ssize_t write_unix_file(struct file *fil
 	if (result == 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
 		reiser4_txn_restart_current();
 		grab_space_enable();
-		result = sync_unix_file(file, file->f_dentry,
-					0 /* data and stat data */ );
+		result = reiser4_sync_file_common(file, file->f_dentry,
+						  0 /* data and stat data */);
 		if (result)
 			warning("reiser4-7", "failed to sync file %llu",
 				(unsigned long long)get_inode_oid(inode));
@@ -2703,7 +2667,7 @@ init_inode_data_unix_file(struct inode *
 }
 
 /**
- * delete_object_unix_file - delete_object of file_plugin
+ * delete_unix_file - delete_object of file_plugin
  * @inode: inode to be deleted
  *
  * Truncates file to length 0, removes stat data and safe link.
diff -puN fs/reiser4/plugin/file/file.h~reiser4-make-methods-supplied-to-vfs-invariant fs/reiser4/plugin/file/file.h
--- a/fs/reiser4/plugin/file/file.h~reiser4-make-methods-supplied-to-vfs-invariant
+++ a/fs/reiser4/plugin/file/file.h
@@ -8,24 +8,70 @@
 #if !defined( __REISER4_FILE_H__ )
 #define __REISER4_FILE_H__
 
-/* declarations of functions implementing UNIX_FILE_PLUGIN_ID file plugin */
+/**
+ * Declarations of common/careful/generic methods.
+ * Suppose ->foo() is a vs method (of f_ops, i_ops, or a_ops);
+ * Then common reiser4 method for foo looks like reiser4_foo_common;
+ * careful method looks like reiser4_foo_careful;
+ * generic method looks like reiser4_foo.
+ *
+ * Common method is a simple instruction set eligible for more
+ * then one plugin id.
+ *
+ * Generic method looks at the plugin installed in inode's
+ * plugin set and calls its appropriate method.
+ *
+ * Careful method looks like generic method with protected pset
+ * (see plugin/file/file_conversion.c for details).
+ */
 
 /* inode operations */
-int setattr_unix_file(struct dentry *, struct iattr *);
+int reiser4_setattr_careful(struct dentry *, struct iattr *);
 
 /* file operations */
+ssize_t reiser4_read_careful(struct file *, char __user *buf,
+			     size_t count, loff_t *off);
+ssize_t reiser4_write_careful(struct file *, const char __user *buf,
+			      size_t count, loff_t * off);
+int reiser4_ioctl_careful(struct inode *inode, struct file *filp,
+			  unsigned int cmd, unsigned long arg);
+int reiser4_mmap_careful(struct file *, struct vm_area_struct *);
+int reiser4_open_careful(struct inode *inode, struct file *file);
+int reiser4_release_careful(struct inode *, struct file *);
+int reiser4_sync_file_common(struct file *, struct dentry *, int datasync);
+
+/* address space operations */
+int reiser4_readpage(struct file *, struct page *);
+int reiser4_readpages(struct file*, struct address_space*, struct list_head*,
+		      unsigned);
+int reiser4_writepages(struct address_space *, struct writeback_control *);
+int reiser4_prepare_write(struct file *, struct page *, unsigned from,
+			  unsigned to);
+int reiser4_commit_write(struct file *, struct page *, unsigned from,
+			 unsigned to);
+sector_t reiser4_bmap_careful(struct address_space *, sector_t lblock);
+
+/*
+ * Private methods of unix-file plugin
+ * (UNIX_FILE_PLUGIN_ID)
+ */
+
+/* private inode operations */
+int setattr_unix_file(struct dentry *, struct iattr *);
+
+/* private file operations */
+
 ssize_t read_unix_file(struct file *, char __user *buf, size_t read_amount,
 		       loff_t *off);
 ssize_t write_unix_file(struct file *, const char __user *buf, size_t write_amount,
-			loff_t * off);
+			loff_t * off, int * conv);
 int ioctl_unix_file(struct inode *, struct file *, unsigned int cmd,
 		    unsigned long arg);
 int mmap_unix_file(struct file *, struct vm_area_struct *);
 int open_unix_file(struct inode *, struct file *);
 int release_unix_file(struct inode *, struct file *);
-int sync_unix_file(struct file *, struct dentry *, int datasync);
 
-/* address space operations */
+/* private address space operations */
 int readpage_unix_file(struct file *, struct page *);
 int readpages_unix_file(struct file*, struct address_space*, struct list_head*, unsigned);
 int writepages_unix_file(struct address_space *, struct writeback_control *);
@@ -35,13 +81,68 @@ int commit_write_unix_file(struct file *
 			   unsigned to);
 sector_t bmap_unix_file(struct address_space *, sector_t lblock);
 
-/* file plugin operations */
+/* other private methods */
+int delete_object_unix_file(struct inode *);
 int flow_by_inode_unix_file(struct inode *, const char __user *buf,
 			    int user, loff_t, loff_t, rw_op, flow_t *);
 int owns_item_unix_file(const struct inode *, const coord_t *);
 void init_inode_data_unix_file(struct inode *, reiser4_object_create_data *,
 			       int create);
-int delete_object_unix_file(struct inode *);
+
+/*
+ * Private methods of cryptcompress file plugin
+ * (CRYPTCOMPRESS_FILE_PLUGIN_ID)
+ */
+
+/* private inode operations */
+int setattr_cryptcompress(struct dentry *, struct iattr *);
+
+/* private file operations */
+ssize_t read_cryptcompress(struct file *, char __user *buf,
+			   size_t count, loff_t *off);
+ssize_t write_cryptcompress(struct file *, const char __user *buf,
+			    size_t count, loff_t * off, int *conv);
+int ioctl_cryptcompress(struct inode *, struct file *, unsigned int cmd,
+			unsigned long arg);
+int mmap_cryptcompress(struct file *, struct vm_area_struct *);
+int open_cryptcompress(struct inode *, struct file *);
+int release_cryptcompress(struct inode *, struct file *);
+
+/* private address space operations */
+int readpage_cryptcompress(struct file *, struct page *);
+int readpages_cryptcompress(struct file*, struct address_space*,
+			    struct list_head*, unsigned);
+int writepages_cryptcompress(struct address_space *,
+			     struct writeback_control *);
+int prepare_write_cryptcompress(struct file *, struct page *, unsigned from,
+				unsigned to);
+int commit_write_cryptcompress(struct file *, struct page *, unsigned from,
+			       unsigned to);
+sector_t bmap_cryptcompress(struct address_space *, sector_t lblock);
+
+/* other private methods */
+int flow_by_inode_cryptcompress(struct inode *, const char __user *buf,
+				int user, loff_t, loff_t, rw_op, flow_t *);
+int key_by_inode_cryptcompress(struct inode *, loff_t off, reiser4_key *);
+int create_object_cryptcompress(struct inode *, struct inode *,
+				reiser4_object_create_data *);
+int delete_object_cryptcompress(struct inode *);
+void init_inode_data_cryptcompress(struct inode *, reiser4_object_create_data *,
+				   int create);
+int cut_tree_worker_cryptcompress(tap_t *, const reiser4_key * from_key,
+				  const reiser4_key * to_key,
+				  reiser4_key * smallest_removed,
+				  struct inode *object, int truncate,
+				  int *progress);
+void destroy_inode_cryptcompress(struct inode *);
+
+/*
+ * Private methods of symlink file plugin
+ * (SYMLINK_FILE_PLUGIN_ID)
+ */
+int reiser4_create_symlink(struct inode *symlink, struct inode *dir,
+			   reiser4_object_create_data *);
+void destroy_inode_symlink(struct inode *);
 
 /*
  * all the write into unix file is performed by item write method. Write method
@@ -183,57 +284,6 @@ static inline int ea_obtained(struct uni
 
 #endif
 
-/* declarations of functions implementing SYMLINK_FILE_PLUGIN_ID file plugin */
-int reiser4_create_symlink(struct inode *symlink, struct inode *dir,
-			   reiser4_object_create_data *);
-void destroy_inode_symlink(struct inode *);
-
-/* declarations of functions implementing CRYPTCOMPRESS_FILE_PLUGIN_ID
-   file plugin */
-
-/* inode operations */
-int setattr_cryptcompress(struct dentry *, struct iattr *);
-int prot_setattr_cryptcompress(struct dentry *, struct iattr *);
-
-/* file operations */
-ssize_t read_cryptcompress(struct file *, char __user *buf, size_t read_amount,
-			   loff_t * off);
-ssize_t prot_read_cryptcompress(struct file *, char __user *buf,
-				size_t read_amount, loff_t * off);
-
-ssize_t write_cryptcompress(struct file *, const char __user *buf, size_t write_amount,
-			    loff_t * off, int * conv);
-ssize_t prot_write_cryptcompress(struct file *, const char __user *buf, size_t write_amount,
-				 loff_t * off);
-int mmap_cryptcompress(struct file *, struct vm_area_struct *);
-int prot_mmap_cryptcompress(struct file *, struct vm_area_struct *);
-
-int release_cryptcompress(struct inode *, struct file *);
-int prot_release_cryptcompress(struct inode *, struct file *);
-
-/* address space operations */
-extern int readpage_cryptcompress(struct file *, struct page *);
-extern int writepages_cryptcompress(struct address_space *,
-				     struct writeback_control *);
-/* file plugin operations */
-int flow_by_inode_cryptcompress(struct inode *, const char __user *buf,
-				int user, loff_t, loff_t, rw_op, flow_t *);
-int key_by_inode_cryptcompress(struct inode *, loff_t off, reiser4_key *);
-int create_cryptcompress(struct inode *, struct inode *,
-			 reiser4_object_create_data *);
-int delete_object_cryptcompress(struct inode *);
-void init_inode_data_cryptcompress(struct inode *, reiser4_object_create_data *,
-				   int create);
-int cut_tree_worker_cryptcompress(tap_t *, const reiser4_key * from_key,
-				  const reiser4_key * to_key,
-				  reiser4_key * smallest_removed,
-				  struct inode *object, int truncate,
-				  int *progress);
-void destroy_inode_cryptcompress(struct inode *);
-int open_object_cryptcompress(struct inode * inode, struct file * file);
-
-extern reiser4_plugin_ops cryptcompress_plugin_ops;
-
 #define WRITE_GRANULARITY 32
 
 int tail2extent(struct unix_file_info *);
diff -puN fs/reiser4/plugin/file/file_conversion.c~reiser4-make-methods-supplied-to-vfs-invariant fs/reiser4/plugin/file/file_conversion.c
--- a/fs/reiser4/plugin/file/file_conversion.c~reiser4-make-methods-supplied-to-vfs-invariant
+++ a/fs/reiser4/plugin/file/file_conversion.c
@@ -1,22 +1,30 @@
 /* Copyright 2001, 2002, 2003 by Hans Reiser,
    licensing governed by reiser4/README */
 
-/* This file contains hooks that converts (*) cryptcompress files to unix-files,
-   and a set of protected (**) methods of a cryptcompress file plugin to perform
-   such conversion.
-
-(*)
-   The conversion is performed for incompressible files to reduce cpu and memory
-   usage. If first logical cluster (64K by default) of a file is incompressible,
-   then we make a desicion, that the whole file is incompressible.
-   The conversion can be enabled via installing a special compression mode
-   plugin (CONVX_COMPRESSION_MODE_ID, see plugin/compress/compress_mode.c for
-   details).
-
-(**)
-   The protection means serialization of critical sections (readers and writers
-   of @pset->file)
-*/
+/* *
+ * This file contains a converter cryptcompress->unix_file, and O(1)-heuristic,
+ * which allows to assign for a regular file the most reasonable plugin to be
+ * managed by. Note, that we don't use back conversion because of compatibility
+ * reasons (see http://dev.namesys.com/Version4.X.Y for details).
+ *
+ * Currently used heuristic is very simple: if first complete logical cluster
+ * (64K by default) of a file is incompressible, then we make a decision, that
+ * the whole file is incompressible (*). When creating a file the conversion
+ * is enabled by default via installing a special "permitting" compression mode
+ * plugin (**) (CONVX_COMPRESSION_MODE_ID, see plugin/compress/compress_mode.c
+ * for details).
+ *
+ * The conversion is accompanied by rebuilding disk structures of a file, so it
+ * is important to protect them from being interacted with other plugins which
+ * don't expect them to be in such inconsistent state. For this to be protected
+ * we serialize readers and writers of pset. Writers are the processes which can
+ * change it with conversion purposes; other ones are readers. Serialization is
+ * performed via acquiring per-inode rw-semaphore (conv_sem).
+ *
+ * (*)  This heuristic can be easily changed as soon as we have a new,
+ *      better one.
+ * (**) Such solution allows to keep enable/disable state on disk.
+ */
 
 #include "../../inode.h"
 #include "../cluster.h"
@@ -26,26 +34,24 @@
 	 (inode_compression_mode_plugin(inode) ==		       \
 	  compression_mode_plugin_by_id(CONVX_COMPRESSION_MODE_ID))
 
-
-/* Located sections (readers and writers of @pset->file) are not
-   permanently critical: cryptcompress file can be converted only
-   if the conversion is enabled (see the macrio above). And we don't
-   convert unix files at all.
-   The following helper macro is a sanity check to decide if we
-   need to protect a located section.
-*/
+/**
+ * Located sections (readers and writers of @pset) are not permanently
+ * critical: cryptcompress file can be converted only if the conversion
+ * is enabled (see the macrio above). Also we don't perform back
+ * conversion. The following helper macro is a sanity check to decide
+ * if we need the protection (locks are always additional overheads).
+ */
 #define should_protect(inode)						\
 	(inode_file_plugin(inode) ==					\
 	 file_plugin_by_id(CRYPTCOMPRESS_FILE_PLUGIN_ID) &&		\
 	 conversion_enabled(inode))
-
-/* All protected methods have prefix "prot" in their names.
-   It is convenient to construct them by usual (unprotected) ones
-   using the following common macros:
-*/
-
+/**
+ * We'll speak about "passive" protection for readers and "active"
+ * protection for writers. All methods with active or passive protection
+ * has suffix "careful".
+ */
 /* Macro for passive protection.
-   method_cryptcompress contains only readers */
+   method_foo contains only readers */
 #define PROT_PASSIVE(type, method, args)				\
 ({							                \
 	type _result;							\
@@ -86,9 +92,11 @@
 		up_read(guard);						\
 })
 
-/* Macro for active protection.
-   active_expr contains readers and writers; after its
-   evaluation conversion should be disabled */
+/**
+ * Macro for active protection.
+ * active_expr contains writers of pset;
+ * NOTE: after evaluating active_expr conversion should be disabled.
+ */
 #define PROT_ACTIVE(type, method, args, active_expr)			\
 ({	                 						\
 	type _result = 0;						\
@@ -154,13 +162,12 @@ static int __cryptcompress2unixfile(stru
 	uf->ea_owner = NULL;
 	atomic_set(&uf->nr_neas, 0);
 #endif
-	inode->i_op =
-		&file_plugin_by_id(UNIX_FILE_PLUGIN_ID)->inode_ops;
-	inode->i_fop =
-		&file_plugin_by_id(UNIX_FILE_PLUGIN_ID)->file_ops;
-	inode->i_mapping->a_ops =
-		&file_plugin_by_id(UNIX_FILE_PLUGIN_ID)->as_ops;
-	file->f_op = inode->i_fop;
+	/**
+	 * we was carefull for file_ops, inode_ops and as_ops
+	 * to be invariant for plugin conversion, so there is
+	 * no need to update ones already installed in the
+	 * vfs's residence.
+	 */
 	return 0;
 }
 
@@ -278,9 +285,12 @@ static int prepped_dclust_ok(hint_t * hi
 #define data_is_compressible(osize, isize)		\
 	(osize < fifty_persent(isize))
 
-/* This is called only once per file life.
-   Read first logical cluster (of index #0) and estimate its compressibility.
-   Save estimation result in @compressible */
+/**
+ * A simple O(1)-heuristic for compressibility.
+ * This is called not more then one time per file's life.
+ * Read first logical cluster (of index #0) and estimate its compressibility.
+ * Save estimation result in @compressible.
+ */
 static int read_check_compressibility(struct inode * inode,
 				      struct cluster_handle * clust,
 				      int * compressible)
@@ -443,7 +453,7 @@ static int cryptcompress2unixfile(struct
 	assert("edward-1516", clust->pages[0]->index == 0);
 	assert("edward-1517", clust->hint != NULL);
 
-	/* release all cryptcompress-specific recources */
+	/* release all cryptcompress-specific resources */
 	cr_info = cryptcompress_inode_data(inode);
 	result = reserve_cryptcompress2unixfile(inode);
 	if (result)
@@ -523,40 +533,69 @@ static int setattr_conversion_hook(struc
 	return (attr->ia_valid & ATTR_SIZE ? disable_conversion(inode) : 0);
 }
 
-/* Protected methods of cryptcompress file plugin constructed
-   by the macros above */
+/**
+ * Here are wrappers with "protection", aka Reiser4 "careful" methods.
+ * They are used by vfs (as methods of file_ops, inode_ops or as_ops),
+ * which is not aware of plugin conversion performed by Reiser4.
+ */
 
-/* Wrappers with active protection for:
-   . write_cryptcompress;
-   . setattr_cryptcompress;
-*/
+/*
+ * Wrappers with active protection for:
+ *
+ * ->write();
+ * ->setattr();
+ */
 
-ssize_t prot_write_cryptcompress(struct file *file, const char __user *buf,
-				 size_t count, loff_t *off)
+/*
+ * Reiser4 write "careful" method.  Write a file in 2 steps:
+ *  . start write with initial file plugin,
+ *    switch to a new (more resonable) file plugin (if any);
+ *  . finish write with the new plugin.
+ */
+ssize_t reiser4_write_careful(struct file *file, const char __user *buf,
+			      size_t count, loff_t *off)
 {
 	int prot = 0;
 	int conv = 0;
-	ssize_t written_cr = 0;
-	ssize_t written_uf = 0;
+	ssize_t written_old = 0; /* bytes written with old plugin */
+	ssize_t written_new = 0; /* bytes written with new plugin */
 	struct inode * inode = file->f_dentry->d_inode;
 	struct rw_semaphore * guard = &reiser4_inode_data(inode)->conv_sem;
 
+	/**
+	 * First step.
+	 * Sanity check: if conversion is possible,
+	 * then protect pset.
+	 */
 	if (should_protect(inode)) {
 		prot = 1;
 		down_write(guard);
 	}
-	written_cr = write_cryptcompress(file, buf, count, off, &conv);
+	written_old = inode_file_plugin(inode)->write(file,
+						      buf,
+						      count,
+						      off, &conv);
 	if (prot)
 		up_write(guard);
-	if (written_cr < 0)
-		return written_cr;
-	if (conv)
-		written_uf = write_unix_file(file, buf + written_cr,
-					     count - written_cr, off);
-	return written_cr + (written_uf < 0 ? 0 : written_uf);
+	if (written_old < 0 || conv == 0)
+		return written_old;
+	/**
+	 * Conversion occurred.
+	 * Back conversion is impossible,
+	 * so don't protect at this step.
+	 */
+	assert("edward-1532",
+	       inode_file_plugin(inode) ==
+	       file_plugin_by_id(UNIX_FILE_PLUGIN_ID));
+
+	written_new = inode_file_plugin(inode)->write(file,
+						      buf + written_old,
+						      count - written_old,
+						      off, NULL);
+	return written_old + (written_new < 0 ? 0 : written_new);
 }
 
-int prot_setattr_cryptcompress(struct dentry *dentry, struct iattr *attr)
+int reiser4_setattr_careful(struct dentry *dentry, struct iattr *attr)
 {
 	struct inode * inode = dentry->d_inode;
 	return PROT_ACTIVE(int, setattr, (dentry, attr),
@@ -564,29 +603,50 @@ int prot_setattr_cryptcompress(struct de
 }
 
 /* Wrappers with passive protection for:
-   . read_cryptcomperess;
-   . mmap_cryptcompress;
-   . release_cryptcompress;
-   . delete_object_cryptcompress.
-*/
-ssize_t prot_read_cryptcompress(struct file * file, char __user * buf,
-				size_t size, loff_t * off)
+ *
+ * ->open();
+ * ->read();
+ * ->ioctl();
+ * ->mmap();
+ * ->release();
+ * ->bmap().
+ */
+
+int reiser4_open_careful(struct inode *inode, struct file *file)
+{
+	return PROT_PASSIVE(int, open, (inode, file));
+}
+
+ssize_t reiser4_read_careful(struct file * file, char __user * buf,
+			     size_t size, loff_t * off)
 {
 	struct inode * inode = file->f_dentry->d_inode;
 	return PROT_PASSIVE(ssize_t, read, (file, buf, size, off));
 }
 
-int prot_mmap_cryptcompress(struct file *file, struct vm_area_struct *vma)
+int reiser4_ioctl_careful(struct inode *inode, struct file *filp,
+			  unsigned int cmd, unsigned long arg)
+{
+	return PROT_PASSIVE(int, ioctl, (inode, filp, cmd, arg));
+}
+
+int reiser4_mmap_careful(struct file *file, struct vm_area_struct *vma)
 {
 	struct inode *inode = file->f_dentry->d_inode;
 	return PROT_PASSIVE(int, mmap, (file, vma));
 }
 
-int prot_release_cryptcompress(struct inode *inode, struct file *file)
+int reiser4_release_careful(struct inode *inode, struct file *file)
 {
 	return PROT_PASSIVE(int, release, (inode, file));
 }
 
+sector_t reiser4_bmap_careful(struct address_space * mapping, sector_t lblock)
+{
+	struct inode *inode = mapping->host;
+	return PROT_PASSIVE(sector_t, bmap, (mapping, lblock));
+}
+
 /*
   Local variables:
   c-indentation-style: "K&R"
diff -puN fs/reiser4/plugin/file_ops.c~reiser4-make-methods-supplied-to-vfs-invariant fs/reiser4/plugin/file_ops.c
--- a/fs/reiser4/plugin/file_ops.c~reiser4-make-methods-supplied-to-vfs-invariant
+++ a/fs/reiser4/plugin/file_ops.c
@@ -58,6 +58,43 @@ int reiser4_sync_common(struct file *fil
 	return result;
 }
 
+/*
+ * common sync method for regular files.
+ *
+ * We are trying to be smart here. Instead of committing all atoms (original
+ * solution), we scan dirty pages of this file and commit all atoms they are
+ * part of.
+ *
+ * Situation is complicated by anonymous pages: i.e., extent-less pages
+ * dirtied through mmap. Fortunately sys_fsync() first calls
+ * filemap_fdatawrite() that will ultimately call reiser4_writepages(), insert
+ * all missing extents and capture anonymous pages.
+ */
+int reiser4_sync_file_common(struct file *file,
+			     struct dentry *dentry, int datasync)
+{
+	reiser4_context *ctx;
+	txn_atom *atom;
+	reiser4_block_nr reserve;
+
+	ctx = reiser4_init_context(dentry->d_inode->i_sb);
+	if (IS_ERR(ctx))
+		return PTR_ERR(ctx);
+
+	reserve = estimate_update_common(dentry->d_inode);
+	if (reiser4_grab_space(reserve, BA_CAN_COMMIT)) {
+		reiser4_exit_context(ctx);
+		return RETERR(-ENOSPC);
+	}
+	write_sd_by_inode_common(dentry->d_inode);
+
+	atom = get_current_atom_locked();
+	spin_lock_txnh(ctx->trans);
+	force_commit_atom(ctx->trans);
+	reiser4_exit_context(ctx);
+	return 0;
+}
+
 /* this is common implementation of vfs's sendfile method of struct
    file_operations
 
diff -puN fs/reiser4/plugin/object.c~reiser4-make-methods-supplied-to-vfs-invariant fs/reiser4/plugin/object.c
--- a/fs/reiser4/plugin/object.c~reiser4-make-methods-supplied-to-vfs-invariant
+++ a/fs/reiser4/plugin/object.c
@@ -84,6 +84,92 @@ static reiser4_plugin_ops file_plugin_op
 	.change = change_file
 };
 
+static struct inode_operations         null_i_ops = {.create = NULL};
+static struct file_operations          null_f_ops = {.owner = NULL};
+static struct address_space_operations null_a_ops = {.writepage = NULL};
+
+/* VFS methods for regular files */
+static struct inode_operations regular_file_i_ops = {
+	.permission = reiser4_permission_common,
+	.setattr = reiser4_setattr_careful,
+	.getattr = reiser4_getattr_common
+};
+static struct file_operations regular_file_f_ops = {
+	.llseek = generic_file_llseek,
+	.read = reiser4_read_careful,
+	.write = reiser4_write_careful,
+	.aio_read = generic_file_aio_read,
+	.ioctl = reiser4_ioctl_careful,
+	.mmap = reiser4_mmap_careful,
+	.open = reiser4_open_careful,
+	.release = reiser4_release_careful,
+	.fsync = reiser4_sync_file_common
+};
+static struct address_space_operations regular_file_a_ops = {
+	.writepage = reiser4_writepage,
+	.readpage = reiser4_readpage,
+	.sync_page = block_sync_page,
+	.writepages = reiser4_writepages,
+	.set_page_dirty = reiser4_set_page_dirty,
+	.readpages = reiser4_readpages,
+	.prepare_write = reiser4_prepare_write,
+	.commit_write =	reiser4_commit_write,
+	.bmap = reiser4_bmap_careful,
+	.invalidatepage = reiser4_invalidatepage,
+	.releasepage = reiser4_releasepage
+};
+
+/* VFS methods for symlink files */
+static struct inode_operations symlink_file_i_ops = {
+	.readlink = generic_readlink,
+	.follow_link = reiser4_follow_link_common,
+	.permission = reiser4_permission_common,
+	.setattr = reiser4_setattr_common,
+	.getattr = reiser4_getattr_common
+};
+
+/* VFS methods for special files */
+static struct inode_operations special_file_i_ops = {
+	.permission = reiser4_permission_common,
+	.setattr = reiser4_setattr_common,
+	.getattr = reiser4_getattr_common
+};
+
+/* VFS methods for directories */
+static struct inode_operations directory_i_ops = {
+	.create = reiser4_create_common,
+	.lookup = reiser4_lookup_common,
+	.link = reiser4_link_common,
+	.unlink = reiser4_unlink_common,
+	.symlink = reiser4_symlink_common,
+	.mkdir = reiser4_mkdir_common,
+	.rmdir = reiser4_unlink_common,
+	.mknod = reiser4_mknod_common,
+	.rename = reiser4_rename_common,
+	.permission = reiser4_permission_common,
+	.setattr = reiser4_setattr_common,
+	.getattr = reiser4_getattr_common
+};
+static struct file_operations directory_f_ops = {
+	.llseek = reiser4_llseek_dir_common,
+	.read = generic_read_dir,
+	.readdir = reiser4_readdir_common,
+	.release = reiser4_release_dir_common,
+	.fsync = reiser4_sync_common
+};
+static struct address_space_operations directory_a_ops = {
+	.writepage = bugop,
+	.sync_page = bugop,
+	.writepages = dummyop,
+	.set_page_dirty = bugop,
+	.readpages = bugop,
+	.prepare_write = bugop,
+	.commit_write = bugop,
+	.bmap = bugop,
+	.invalidatepage = bugop,
+	.releasepage = bugop
+};
+
 /*
  * Definitions of object plugins.
  */
@@ -99,35 +185,37 @@ file_plugin file_plugins[LAST_FILE_PLUGI
 			.desc = "regular file",
 			.linkage = {NULL, NULL},
 		},
-		.inode_ops = {
-			.permission = reiser4_permission_common,
-			.setattr = setattr_unix_file,
-			.getattr = reiser4_getattr_common
-		},
-		.file_ops = {
-			.llseek = generic_file_llseek,
-			.read = read_unix_file,
-			.write = write_unix_file,
-			.aio_read = generic_file_aio_read,
-			.ioctl = ioctl_unix_file,
-			.mmap = mmap_unix_file,
-			.open = open_unix_file,
-			.release = release_unix_file,
-			.fsync = sync_unix_file,
-		},
-		.as_ops = {
-			.writepage = reiser4_writepage,
-			.readpage = readpage_unix_file,
-			.sync_page = block_sync_page,
-			.writepages = writepages_unix_file,
-			.set_page_dirty = reiser4_set_page_dirty,
-			.readpages = readpages_unix_file,
-			.prepare_write = prepare_write_unix_file,
-			.commit_write =	commit_write_unix_file,
-			.bmap = bmap_unix_file,
-			.invalidatepage = reiser4_invalidatepage,
-			.releasepage = reiser4_releasepage
-		},
+		/*
+		 * invariant vfs ops
+		 */
+		.inode_ops = &regular_file_i_ops,
+		.file_ops = &regular_file_f_ops,
+		.as_ops = &regular_file_a_ops,
+		/*
+		 * private i_ops
+		 */
+		.setattr = setattr_unix_file,
+		.open = open_unix_file,
+		.read = read_unix_file,
+		.write = write_unix_file,
+		.ioctl = ioctl_unix_file,
+		.mmap = mmap_unix_file,
+		.release = release_unix_file,
+		/*
+		 * private f_ops
+		 */
+		.readpage = readpage_unix_file,
+		.readpages = readpages_unix_file,
+		.writepages = writepages_unix_file,
+		.prepare_write = prepare_write_unix_file,
+		.commit_write = commit_write_unix_file,
+		/*
+		 * private a_ops
+		 */
+		.bmap = bmap_unix_file,
+		/*
+		 * other private methods
+		 */
 		.write_sd_by_inode = write_sd_by_inode_common,
 		.flow_by_inode = flow_by_inode_unix_file,
 		.key_by_inode = key_by_inode_and_offset_common,
@@ -167,9 +255,9 @@ file_plugin file_plugins[LAST_FILE_PLUGI
 			.desc = "directory",
 			.linkage = {NULL, NULL}
 		},
-		.inode_ops = {.create = NULL},
-		.file_ops = {.owner = NULL},
-		.as_ops = {.writepage = NULL},
+		.inode_ops = &null_i_ops,
+		.file_ops = &null_f_ops,
+		.as_ops = &null_a_ops,
 
 		.write_sd_by_inode = write_sd_by_inode_common,
 		.flow_by_inode = bugop,
@@ -211,16 +299,11 @@ file_plugin file_plugins[LAST_FILE_PLUGI
 			.desc = "symbolic link",
 			.linkage = {NULL,NULL}
 		},
-		.inode_ops = {
-			.readlink = generic_readlink,
-			.follow_link = reiser4_follow_link_common,
-			.permission = reiser4_permission_common,
-			.setattr = reiser4_setattr_common,
-			.getattr = reiser4_getattr_common
-		},
-		/* inode->i_fop of symlink is initialized by NULL in setup_inode_ops */
-		.file_ops = {.owner = NULL},
-		.as_ops = {.writepage = NULL},
+		.inode_ops = &symlink_file_i_ops,
+		/* inode->i_fop of symlink is initialized
+		   by NULL in setup_inode_ops */
+		.file_ops = &null_f_ops,
+		.as_ops = &null_a_ops,
 
 		.write_sd_by_inode = write_sd_by_inode_common,
 		.set_plug_in_inode = set_plug_in_inode_common,
@@ -260,15 +343,11 @@ file_plugin file_plugins[LAST_FILE_PLUGI
 			"special: fifo, device or socket",
 			.linkage = {NULL, NULL}
 		},
-		.inode_ops = {
-			.permission = reiser4_permission_common,
-			.setattr = reiser4_setattr_common,
-			.getattr = reiser4_getattr_common
-		},
+		.inode_ops = &special_file_i_ops,
 		/* file_ops of special files (sockets, block, char, fifo) are
 		   initialized by init_special_inode. */
-		.file_ops = {.owner = NULL},
-		.as_ops = {.writepage = NULL},
+		.file_ops = &null_f_ops,
+		.as_ops = &null_a_ops,
 
 		.write_sd_by_inode = write_sd_by_inode_common,
 		.set_plug_in_inode = set_plug_in_inode_common,
@@ -307,38 +386,32 @@ file_plugin file_plugins[LAST_FILE_PLUGI
 			.desc = "cryptcompress file",
 			.linkage = {NULL, NULL}
 		},
-		.inode_ops = {
-			.permission = reiser4_permission_common,
-			.setattr = prot_setattr_cryptcompress,
-			.getattr = reiser4_getattr_common
-		},
-		.file_ops = {
-			.llseek = generic_file_llseek,
-			.read = prot_read_cryptcompress,
-			.write = prot_write_cryptcompress,
-			.aio_read = generic_file_aio_read,
-			.mmap = prot_mmap_cryptcompress,
-			.release = prot_release_cryptcompress,
-			.fsync = reiser4_sync_common,
-		},
-		.as_ops = {
-			.writepage = reiser4_writepage,
-			.readpage = readpage_cryptcompress,
-			.sync_page = block_sync_page,
-			.writepages = writepages_cryptcompress,
-			.set_page_dirty = reiser4_set_page_dirty,
-			.readpages = readpages_cryptcompress,
-			.prepare_write = prepare_write_common,
-			.invalidatepage = reiser4_invalidatepage,
-			.releasepage = reiser4_releasepage
-		},
+		.inode_ops = &regular_file_i_ops,
+		.file_ops = &regular_file_f_ops,
+		.as_ops = &regular_file_a_ops,
+
+		.setattr = setattr_cryptcompress,
+		.open = open_cryptcompress,
+		.read = read_cryptcompress,
+		.write = write_cryptcompress,
+		.ioctl = ioctl_cryptcompress,
+		.mmap = mmap_cryptcompress,
+		.release = release_cryptcompress,
+
+		.readpage = readpage_cryptcompress,
+		.readpages = readpages_cryptcompress,
+		.writepages = writepages_cryptcompress,
+		.prepare_write = prepare_write_cryptcompress,
+		.commit_write = commit_write_cryptcompress,
+
+		.bmap = bmap_cryptcompress,
+
 		.write_sd_by_inode = write_sd_by_inode_common,
 		.flow_by_inode = flow_by_inode_cryptcompress,
 		.key_by_inode = key_by_inode_cryptcompress,
 		.set_plug_in_inode = set_plug_in_inode_common,
 		.adjust_to_parent = adjust_to_parent_cryptcompress,
-		.create_object = create_cryptcompress,
-		.open_object = open_object_cryptcompress,
+		.create_object = create_object_cryptcompress,
 		.delete_object = delete_object_cryptcompress,
 		.add_link = reiser4_add_link_common,
 		.rem_link = reiser4_rem_link_common,
@@ -392,39 +465,10 @@ dir_plugin dir_plugins[LAST_DIR_ID] = {
 			.desc = "hashed directory",
 			.linkage = {NULL, NULL}
 		},
-		.inode_ops = {
-			.create = reiser4_create_common,
-			.lookup = reiser4_lookup_common,
-			.link = reiser4_link_common,
-			.unlink = reiser4_unlink_common,
-			.symlink = reiser4_symlink_common,
-			.mkdir = reiser4_mkdir_common,
-			.rmdir = reiser4_unlink_common,
-			.mknod = reiser4_mknod_common,
-			.rename = reiser4_rename_common,
-			.permission = reiser4_permission_common,
-			.setattr = reiser4_setattr_common,
-			.getattr = reiser4_getattr_common
-		},
-		.file_ops = {
-			.llseek = reiser4_llseek_dir_common,
-			.read = generic_read_dir,
-			.readdir = reiser4_readdir_common,
-			.release = reiser4_release_dir_common,
-			.fsync = reiser4_sync_common
-		},
-		.as_ops = {
-			.writepage = bugop,
-			.sync_page = bugop,
-			.writepages = dummyop,
-			.set_page_dirty = bugop,
-			.readpages = bugop,
-			.prepare_write = bugop,
-			.commit_write = bugop,
-			.bmap = bugop,
-			.invalidatepage = bugop,
-			.releasepage = bugop
-		},
+		.inode_ops = &directory_i_ops,
+		.file_ops = &directory_f_ops,
+		.as_ops = &directory_a_ops,
+
 		.get_parent = get_parent_common,
 		.is_name_acceptable = is_name_acceptable_common,
 		.build_entry_key = build_entry_key_hashed,
@@ -452,39 +496,10 @@ dir_plugin dir_plugins[LAST_DIR_ID] = {
 			.desc = "directory hashed with 31 bit hash",
 			.linkage = {NULL, NULL}
 		},
-		.inode_ops = {
-			.create = reiser4_create_common,
-			.lookup = reiser4_lookup_common,
-			.link = reiser4_link_common,
-			.unlink = reiser4_unlink_common,
-			.symlink = reiser4_symlink_common,
-			.mkdir = reiser4_mkdir_common,
-			.rmdir = reiser4_unlink_common,
-			.mknod = reiser4_mknod_common,
-			.rename = reiser4_rename_common,
-			.permission = reiser4_permission_common,
-			.setattr = reiser4_setattr_common,
-			.getattr = reiser4_getattr_common
-		},
-		.file_ops = {
-			.llseek = reiser4_llseek_dir_common,
-			.read =	generic_read_dir,
-			.readdir = reiser4_readdir_common,
-			.release = reiser4_release_dir_common,
-			.fsync = reiser4_sync_common
-		},
-		.as_ops = {
-			.writepage = bugop,
-			.sync_page = bugop,
-			.writepages = dummyop,
-			.set_page_dirty = bugop,
-			.readpages = bugop,
-			.prepare_write = bugop,
-			.commit_write = bugop,
-			.bmap = bugop,
-			.invalidatepage = bugop,
-			.releasepage = bugop
-		},
+		.inode_ops = &directory_i_ops,
+		.file_ops = &directory_f_ops,
+		.as_ops = &directory_a_ops,
+
 		.get_parent = get_parent_common,
 		.is_name_acceptable = is_name_acceptable_common,
 		.build_entry_key = build_entry_key_seekable,
diff -puN fs/reiser4/plugin/plugin.h~reiser4-make-methods-supplied-to-vfs-invariant fs/reiser4/plugin/plugin.h
--- a/fs/reiser4/plugin/plugin.h~reiser4-make-methods-supplied-to-vfs-invariant
+++ a/fs/reiser4/plugin/plugin.h
@@ -199,20 +199,61 @@ typedef struct file_plugin {
 	/* generic fields */
 	plugin_header h;
 
-	struct inode_operations inode_ops;
-	struct file_operations file_ops;
-	struct address_space_operations as_ops;
-
+	/* VFS methods.
+	 * Must be invariant with respect to plugin conversion.
+	 * It can be achieved by using "common" methods, which
+	 * are the same for all plugins that take participation in
+	 * conversion, or by using "generic" or "careful" methods,
+	 * which provide automatic redirection to proper private
+	 * plugin methods ("careful" are the same as "generic",
+	 * but with protection of pset and other disk structures
+	 * from being rebuilt during conversion.
+	 */
+	struct inode_operations * inode_ops;
+	struct file_operations * file_ops;
+	struct address_space_operations * as_ops;
+	/**
+	 * Private methods. These are optional. If used they will allow you
+	 * to minimize the amount of code needed to implement a deviation
+	 * from some other method that also uses them.
+	 */
+	/*
+	 * private inode_ops
+	 */
+	int (*setattr)(struct dentry *, struct iattr *);
+	/*
+	 * private file_ops
+	 */
+	/* do whatever is necessary to do when object is opened */
+	int (*open) (struct inode * inode, struct file * file);
+	ssize_t (*read) (struct file *, char __user *buf, size_t read_amount,
+			loff_t *off);
+	/* write a file;
+	 * perform file plugin conversion (if needed);
+	 * set @*conv to 1, if the conversion occurred */
+	ssize_t (*write) (struct file *, const char __user *buf,
+			  size_t write_amount, loff_t * off, int * conv);
+	int (*ioctl) (struct inode *inode, struct file *filp,
+		      unsigned int cmd, unsigned long arg);
+	int (*mmap) (struct file *, struct vm_area_struct *);
+	int (*release) (struct inode *, struct file *);
+	/*
+	 * private a_ops
+	 */
+	int (*readpage) (struct file *file, struct page *page);
+	int (*readpages)(struct file *file, struct address_space *mapping,
+			  struct list_head *pages, unsigned nr_pages);
+	int (*writepages)(struct address_space *mapping,
+			  struct writeback_control *wbc);
+	int (*prepare_write)(struct file *file, struct page *page,
+			     unsigned from, unsigned to);
+	int (*commit_write)(struct file *file, struct page *page,
+			    unsigned from, unsigned to);
+	sector_t (*bmap) (struct address_space * mapping, sector_t lblock);
+	/* other private methods */
 	/* save inode cached stat-data onto disk. It was called
 	   reiserfs_update_sd() in 3.x */
 	int (*write_sd_by_inode) (struct inode *);
-
-	/*
-	 * private methods: These are optional.  If used they will allow you to
-	 * minimize the amount of code needed to implement a deviation from
-	 * some other method that also uses them.
-	 */
-
 	/*
 	 * Construct flow into @flow according to user-supplied data.
 	 *
@@ -242,7 +283,6 @@ typedef struct file_plugin {
 	int (*flow_by_inode) (struct inode *, const char __user *buf,
 			      int user, loff_t size,
 			      loff_t off, rw_op op, flow_t *);
-
 	/*
 	 * Return the key used to retrieve an offset of a file. It is used by
 	 * default implementation of ->flow_by_inode() method
@@ -273,9 +313,6 @@ typedef struct file_plugin {
 	 */
 	int (*create_object) (struct inode *object, struct inode *parent,
 			      reiser4_object_create_data *);
-
-	/* this does whatever is necessary to do when object is opened */
-	int (*open_object) (struct inode * inode, struct file * file);
 	/*
 	 * this method should check REISER4_NO_SD and set REISER4_NO_SD on
 	 * success. Deletion of an object usually includes removal of items
@@ -397,9 +434,9 @@ typedef struct dir_plugin {
 	/* generic fields */
 	plugin_header h;
 
-	struct inode_operations inode_ops;
-	struct file_operations file_ops;
-	struct address_space_operations as_ops;
+	struct inode_operations * inode_ops;
+	struct file_operations * file_ops;
+	struct address_space_operations * as_ops;
 
 	/*
 	 * private methods: These are optional.  If used they will allow you to
_

Patches currently in -mm which might be from edward.shishkin@xxxxxxxxx are

origin.patch
reiser4.patch
reiser4-make-methods-supplied-to-vfs-invariant.patch
reiser4-new-export-ops.patch
reiser4-new-export-ops-update.patch
reiser4-new-export_ops-fixup.patch
reiser4-specify-splice-file-operations.patch
reiser4-fix-dummy-ioctl_cryptcompress.patch
reiser4-granulate-rw-serialization-when-accessing-file-conversion-set.patch
reiser4-fix-disk-cluster-synchronization.patch
reiser4-use-balance_dirty_pages_ratelimited_nr.patch
reiser4-correct-references-to-filemap_nopage.patch
reiser4-fix-null-pointer-dereference-in-reiser4_write_extent.patch
reiser4-code-cleanups.patch

--
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux