Skip to contentSkip to conversation

reiser4: granulate rw-serialization when accessing file conversion set

PATCH New Edward Shishkin 1 participant 1 message Jan 6, 2008

lore
Share & tools
lore
#0 lore raw

PATCH 2/4 reiser4: granulate rw-serialization when accessing file conversion set

Granulate RW-serialization of file conversion set.

Split common file plugin conversion procedure into . plugin scheduling part
. plugin conversion part
Move the last one to the plugin-independent file operation (reiser4_write_careful) with active protection of file conversion set (conv_sem held).

---
 linux-2.6.24-rc6-mm1/fs/reiser4/plugin/cluster.h              |    2 
 linux-2.6.24-rc6-mm1/fs/reiser4/plugin/file/cryptcompress.c   |  102 +--
 linux-2.6.24-rc6-mm1/fs/reiser4/plugin/file/cryptcompress.h   |   16 
 linux-2.6.24-rc6-mm1/fs/reiser4/plugin/file/file.c            |   31 -
 linux-2.6.24-rc6-mm1/fs/reiser4/plugin/file/file.h            |   21 
 linux-2.6.24-rc6-mm1/fs/reiser4/plugin/file/file_conversion.c |  296 +++++-----
 linux-2.6.24-rc6-mm1/fs/reiser4/plugin/file/tail_conversion.c |    4 
 linux-2.6.24-rc6-mm1/fs/reiser4/plugin/object.c               |    2 
 linux-2.6.24-rc6-mm1/fs/reiser4/plugin/plugin.h               |    9 
 9 files changed, 253 insertions(+), 230 deletions(-)
fs/reiser4/plugin/cluster.h renamed from fs/reiser4/plugin/cluster.h.orig +2 -0
@@ -333,6 +333,8 @@
 			int count);
 int prepare_page_cluster(struct inode *inode, struct cluster_handle * clust,
 			 rw_op rw);
+void __put_page_cluster(int from, int count,
+			struct page ** pages, struct inode  * inode);
 void put_page_cluster(struct cluster_handle * clust,
 		      struct inode  * inode, rw_op rw);
 void put_cluster_handle(struct cluster_handle * clust);
fs/reiser4/plugin/file/cryptcompress.c renamed from fs/reiser4/plugin/file/cryptcompress.c.orig +47 -55

175 lines not on this page · raw message

fs/reiser4/plugin/file/cryptcompress.h renamed from fs/reiser4/plugin/file/cryptcompress.h.orig +14 -2
@@ -448,6 +448,16 @@
 	return 0;
 }
 
+static inline void move_cluster_pgset(struct cluster_handle *clust,
+				      struct page ***pages, int * nr_pages)
+{
+	assert("edward-1545", clust != NULL && clust->pages != NULL);
+	assert("edward-1546", pages != NULL && *pages == NULL);
+	*pages = clust->pages;
+	*nr_pages = clust->nr_pages;
+	clust->pages = NULL;
+}
+
 static inline void free_cluster_pgset(struct cluster_handle * clust)
 {
 	assert("edward-951", clust->pages != NULL);
@@ -552,8 +562,10 @@
 void destroy_inode_cryptcompress(struct inode * inode);
 int grab_page_cluster(struct inode *inode, struct cluster_handle * clust,
 		      rw_op rw);
-int write_conversion_hook(struct file *file, struct inode * inode, loff_t pos,
- 			  struct cluster_handle * clust, int * progress);
+int write_pschedule_hook(struct file *file, struct inode * inode,
+			 loff_t pos, struct cluster_handle * clust,
+			 struct psched_context * cont);
+int setattr_pschedule_hook(struct inode * inode);
 struct reiser4_crypto_info * inode_crypto_info(struct inode * inode);
 void inherit_crypto_info_common(struct inode * parent, struct inode * object,
 				int (*can_inherit)(struct inode * child,
fs/reiser4/plugin/file/file.c renamed from fs/reiser4/plugin/file/file.c.orig +8 -23
@@ -2077,17 +2077,17 @@
 			      __FILE__, __LINE__, __FUNCTION__, ## __VA_ARGS__)
 
 /**
- * write_unix_file - write of struct file_operations
+ * write_unix_file - private ->write() method of unix_file plugin.
+ *
  * @file: file to write to
  * @buf: address of user-space buffer
- * @write_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
- * unix file plugin.
+ * @count: number of bytes to write
+ * @pos: position in file to write to
+ * @cont: unused argument, as we don't perform plugin conversion when being
+ * managed by unix_file plugin.
  */
 ssize_t write_unix_file(struct file *file, const char __user *buf,
-			size_t count, loff_t *pos, int *conv)
+			size_t count, loff_t *pos, struct psched_context *cont)
 {
 	int result;
 	reiser4_context *ctx;
@@ -2102,12 +2102,8 @@
 	int ea;
 	loff_t new_size;
 
+	ctx = get_current_context();
 	inode = file->f_dentry->d_inode;
-	ctx = reiser4_init_context(inode->i_sb);
-	if (IS_ERR(ctx))
-		return PTR_ERR(ctx);
-
-	mutex_lock(&inode->i_mutex);
 
 	assert("vs-947", !reiser4_inode_get_flag(inode, REISER4_NO_SD));
 	assert("vs-9471", (!reiser4_inode_get_flag(inode, REISER4_PART_MIXED)));
@@ -2115,17 +2111,13 @@
 	/* check amount of bytes to write and writing position */
 	result = generic_write_checks(file, pos, &count, 0);
 	if (result) {
-		mutex_unlock(&inode->i_mutex);
 		context_set_commit_async(ctx);
-		reiser4_exit_context(ctx);
 		return result;
 	}
 
 	result = remove_suid(file->f_dentry);
 	if (result) {
-		mutex_unlock(&inode->i_mutex);
 		context_set_commit_async(ctx);
-		reiser4_exit_context(ctx);
 		return result;
 	}
 	/* remove_suid might create a transaction */
@@ -2249,11 +2241,9 @@
 		file_update_time(file);
 		result = reiser4_update_sd(inode);
 		if (result) {
-			mutex_unlock(&inode->i_mutex);
 			current->backing_dev_info = NULL;
 			drop_access(uf_info);
 			context_set_commit_async(ctx);
-			reiser4_exit_context(ctx);
 			return result;
 		}
 		drop_access(uf_info);
@@ -2272,9 +2262,6 @@
 		buf += written;
 		*pos += written;
 	}
-
-	mutex_unlock(&inode->i_mutex);
-
 	if (result == 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
 		reiser4_txn_restart_current();
 		grab_space_enable();
@@ -2287,8 +2274,6 @@
 
 	current->backing_dev_info = NULL;
 
-	reiser4_exit_context(ctx);
-
 	/*
 	 * return number of written bytes or error code if nothing is
 	 * written. Note, that it does not work correctly in case when
fs/reiser4/plugin/file/file.h renamed from fs/reiser4/plugin/file/file.h.orig +18 -3
@@ -8,6 +8,20 @@
 #if !defined( __REISER4_FILE_H__ )
 #define __REISER4_FILE_H__
 
+/* possible states when scheduling a new file plugin */
+typedef enum {
+	PSCHED_INVAL_STATE,    /* invalid state */
+	PSCHED_SCHED_POINT,    /* scheduling point has been achieved */
+	PSCHED_REMAINS_OLD,    /* made a decision to be managed by old plugin */
+	PSCHED_ASSIGNED_NEW    /* new plugin has been scheduled */
+} psched_state;
+
+struct psched_context {
+	int nr_pages;
+	struct page **pages;
+	psched_state state;
+};
+
 /**
  * Declarations of common/careful/generic methods.
  * Suppose ->foo() is a vs method (of f_ops, i_ops, or a_ops);
@@ -26,7 +40,7 @@
  */
 
 /* inode operations */
-int reiser4_setattr_careful(struct dentry *, struct iattr *);
+int reiser4_setattr(struct dentry *, struct iattr *);
 
 /* file operations */
 ssize_t reiser4_read_careful(struct file *, char __user *buf,
@@ -64,7 +78,7 @@
 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, int * conv);
+			loff_t * off, struct psched_context * cont);
 int ioctl_unix_file(struct inode *, struct file *, unsigned int cmd,
 		    unsigned long arg);
 int mmap_unix_file(struct file *, struct vm_area_struct *);
@@ -101,7 +115,8 @@
 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);
+			    size_t count, loff_t * off,
+			    struct psched_context *cont);
 int ioctl_cryptcompress(struct inode *, struct file *, unsigned int cmd,
 			unsigned long arg);
 int mmap_cryptcompress(struct file *, struct vm_area_struct *);
fs/reiser4/plugin/file/file_conversion.c renamed from fs/reiser4/plugin/file/file_conversion.c.orig +156 -140

450 lines not on this page · raw message

fs/reiser4/plugin/file/tail_conversion.c renamed from fs/reiser4/plugin/file/tail_conversion.c.orig +2 -2
@@ -646,9 +646,9 @@
 		while (count) {
 			loff_t pos = start_byte;
 
-			assert("edward-1533",
+			assert("edward-1537",
 			       file != NULL && file->f_dentry != NULL);
-			assert("edward-1534",
+			assert("edward-1538",
 			       file->f_dentry->d_inode == inode);
 
 			result = reiser4_write_tail(file,
fs/reiser4/plugin/object.c renamed from fs/reiser4/plugin/object.c.orig +1 -1
@@ -91,7 +91,7 @@
 /* VFS methods for regular files */
 static struct inode_operations regular_file_i_ops = {
 	.permission = reiser4_permission_common,
-	.setattr = reiser4_setattr_careful,
+	.setattr = reiser4_setattr,
 	.getattr = reiser4_getattr_common
 };
 static struct file_operations regular_file_f_ops = {
fs/reiser4/plugin/plugin.h renamed from fs/reiser4/plugin/plugin.h.orig +5 -4
@@ -228,11 +228,12 @@
 	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 */
+	/* write as much as possible bytes from nominated @write_amount
+	 * before plugin scheduling is occurred. Save scheduling state
+	 * in @cont */
 	ssize_t (*write) (struct file *, const char __user *buf,
-			  size_t write_amount, loff_t * off, int * conv);
+			  size_t write_amount, loff_t * off,
+			  struct psched_context * cont);
 	int (*ioctl) (struct inode *inode, struct file *filp,
 		      unsigned int cmd, unsigned long arg);
 	int (*mmap) (struct file *, struct vm_area_struct *);