All pastes #1711955 Raw Edit

Someone

public diff v1 · immutable
#1711955 ·published 2009-12-12 09:00 UTC
rendered paste body
diff --git a/fs/fuse/control.c b/fs/fuse/control.cindex 99c99df..8f0b537 100644Binary files a/fs/fuse/control.c and b/fs/fuse/control.c differdiff --git a/fs/fuse/dev.c b/fs/fuse/dev.cindex 6484eb7..51d9e33 100644--- a/fs/fuse/dev.c+++ b/fs/fuse/dev.c@@ -250,7 +250,7 @@ static void queue_request(struct fuse_conn *fc, struct fuse_req *req)  static void flush_bg_queue(struct fuse_conn *fc) {-	while (fc->active_background < FUSE_MAX_BACKGROUND &&+	while (fc->active_background < fc->max_background && 	       !list_empty(&fc->bg_queue)) { 		struct fuse_req *req; @@ -280,11 +280,11 @@ __releases(&fc->lock) 	list_del(&req->intr_entry); 	req->state = FUSE_REQ_FINISHED; 	if (req->background) {-		if (fc->num_background == FUSE_MAX_BACKGROUND) {+		if (fc->num_background == fc->max_background) { 			fc->blocked = 0; 			wake_up_all(&fc->blocked_waitq); 		}-		if (fc->num_background == FUSE_CONGESTION_THRESHOLD &&+		if (fc->num_background == fc->congestion_threshold && 		    fc->connected && fc->bdi_initialized) { 			clear_bdi_congested(&fc->bdi, BLK_RW_SYNC); 			clear_bdi_congested(&fc->bdi, BLK_RW_ASYNC);@@ -410,9 +410,9 @@ static void fuse_request_send_nowait_locked(struct fuse_conn *fc, { 	req->background = 1; 	fc->num_background++;-	if (fc->num_background == FUSE_MAX_BACKGROUND)+	if (fc->num_background == fc->max_background) 		fc->blocked = 1;-	if (fc->num_background == FUSE_CONGESTION_THRESHOLD &&+	if (fc->num_background == fc->congestion_threshold && 	    fc->bdi_initialized) { 		set_bdi_congested(&fc->bdi, BLK_RW_SYNC); 		set_bdi_congested(&fc->bdi, BLK_RW_ASYNC);diff --git a/fs/fuse/dir.c b/fs/fuse/dir.cindex 573437c..beb8a4b 100644--- a/fs/fuse/dir.c+++ b/fs/fuse/dir.c@@ -718,8 +718,10 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent, 			fuse_invalidate_attr(newdir);  		/* newent will end up negative */-		if (newent->d_inode)+		if (newent->d_inode) {+			fuse_invalidate_attr(newent->d_inode); 			fuse_invalidate_entry_cache(newent);+		} 	} else if (err == -EINTR) { 		/* If request was interrupted, DEITY only knows if the 		   rename actually took place.  If the invalidation@@ -1282,14 +1284,19 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, 		return 0;  	if (attr->ia_valid & ATTR_SIZE) {-		unsigned long limit;-		if (IS_SWAPFILE(inode))-			return -ETXTBSY;-		limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;-		if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) {-			send_sig(SIGXFSZ, current, 0);-			return -EFBIG;-		}+                unsigned long limit;+                if (IS_SWAPFILE(inode))+                        return -ETXTBSY;+                limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;+                if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) {+                        send_sig(SIGXFSZ, current, 0);+                        return -EFBIG;+                }+                /* Enable this in 2.6.32 +                err = inode_newsize_ok(inode, attr->ia_size);+                if (err)+                        return err;+                */ 		is_truncate = true; 	} @@ -1356,8 +1363,11 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, 	 * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock. 	 */ 	if (S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {-		if (outarg.attr.size < oldsize)-			fuse_truncate(inode->i_mapping, outarg.attr.size);+                if (outarg.attr.size < oldsize)+                        fuse_truncate(inode->i_mapping, outarg.attr.size);+                /* Enable this in 2.6.32+		truncate_pagecache(inode, oldsize, outarg.attr.size);+                */ 		invalidate_inode_pages2(inode->i_mapping); 	} diff --git a/fs/fuse/file.c b/fs/fuse/file.cindex dedc81b..cbdbe6f 100644--- a/fs/fuse/file.c+++ b/fs/fuse/file.c@@ -1492,7 +1492,8 @@ ssize_t fuse_direct_io(struct file *file, const char __user *buf, 				break; 		} 	}-	fuse_put_request(fc, req);+	if (!IS_ERR(req))+		fuse_put_request(fc, req); 	if (res > 0) 		*ppos = pos; @@ -1733,7 +1734,7 @@ static int fuse_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) 	return 0; } -static struct vm_operations_struct fuse_file_vm_ops = {+static const struct vm_operations_struct fuse_file_vm_ops = { 	.close		= fuse_vma_close, 	.fault		= filemap_fault, 	.page_mkwrite	= fuse_page_mkwrite,@@ -2033,7 +2034,7 @@ static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov, 			kaddr += copy; 		} -		kunmap(map);+		kunmap(page); 	}  	return 0;diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.hindex d430ba5..5fdde74 100644--- a/fs/fuse/fuse_i.h+++ b/fs/fuse/fuse_i.h@@ -25,12 +25,6 @@ /** Max number of pages that can be used in a single read request */ #define FUSE_MAX_PAGES_PER_REQ 32 -/** Maximum number of outstanding background requests */-#define FUSE_MAX_BACKGROUND 12--/** Congestion starts at 75% of maximum */-#define FUSE_CONGESTION_THRESHOLD (FUSE_MAX_BACKGROUND * 75 / 100)- /** Bias for fi->writectr, meaning new writepages must not be sent */ #define FUSE_NOWRITE INT_MIN @@ -38,7 +32,7 @@ #define FUSE_NAME_MAX 1024  /** Number of dentries for each connection in the control filesystem */-#define FUSE_CTL_NUM_DENTRIES 3+#define FUSE_CTL_NUM_DENTRIES 5  /** If the FUSE_DEFAULT_PERMISSIONS flag is given, the filesystem     module will check permissions based on the file mode.  Otherwise no@@ -55,6 +49,10 @@ extern struct list_head fuse_conn_list; /** Global mutex protecting fuse_conn_list and the control filesystem */ extern struct mutex fuse_mutex; +/** Module parameters */+extern unsigned max_user_bgreq; +extern unsigned max_user_congthresh;+ /** number of fcntl calls to fuse */ extern unsigned fuse_fcntl_count; @@ -374,6 +372,12 @@ struct fuse_conn { 	/** rbtree of fuse_files waiting for poll events indexed by ph */ 	struct rb_root polled_files; +	/** Maximum number of outstanding background requests */+	unsigned max_background;++	/** Number of background requests at which congestion starts */+	unsigned congestion_threshold;+ 	/** Number of requests currently in the background */ 	unsigned num_background; @@ -628,6 +632,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, 				   u64 attr_valid); +/* Added for 2.6.31 compatibility */ void fuse_truncate(struct address_space *mapping, loff_t offset);  /**diff --git a/fs/fuse/inode.c b/fs/fuse/inode.cindex 96b1c94..71fdd6d 100644--- a/fs/fuse/inode.c+++ b/fs/fuse/inode.c@@ -14,6 +14,7 @@ #include <linux/seq_file.h> #include <linux/init.h> #include <linux/module.h>+#include <linux/moduleparam.h> #include <linux/parser.h> #include <linux/statfs.h> #include <linux/random.h>@@ -27,13 +28,39 @@ MODULE_LICENSE("GPL"); static struct kmem_cache *fuse_inode_cachep; struct list_head fuse_conn_list; DEFINE_MUTEX(fuse_mutex);-+/* Enable for 2.6.32+static int set_global_limit(const char *val, struct kernel_param *kp);+*/+unsigned max_user_bgreq;+/*+module_param_call(max_user_bgreq, set_global_limit, param_get_uint,+		  &max_user_bgreq, 0644);+__MODULE_PARM_TYPE(max_user_bgreq, "uint");+MODULE_PARM_DESC(max_user_bgreq,+ "Global limit for the maximum number of backgrounded requests an "+ "unprivileged user can set");+*/+unsigned max_user_congthresh;+/*+module_param_call(max_user_congthresh, set_global_limit, param_get_uint,+		  &max_user_congthresh, 0644);+__MODULE_PARM_TYPE(max_user_congthresh, "uint");+MODULE_PARM_DESC(max_user_congthresh,+ "Global limit for the maximum congestion threshold an "+ "unprivileged user can set");+*/ unsigned fuse_fcntl_count;  #define FUSE_SUPER_MAGIC 0x65735546  #define FUSE_DEFAULT_BLKSIZE 512 +/** Maximum number of outstanding background requests */+#define FUSE_DEFAULT_MAX_BACKGROUND 12++/** Congestion starts at 75% of maximum */+#define FUSE_DEFAULT_CONGESTION_THRESHOLD (FUSE_DEFAULT_MAX_BACKGROUND * 3 / 4)+ struct fuse_mount_data { 	int fd; 	unsigned rootmode;@@ -123,14 +150,16 @@ static int fuse_remount_fs(struct super_block *sb, int *flags, char *data) 	return 0; } +/* Added for 2.6.31 backward compatibility */ void fuse_truncate(struct address_space *mapping, loff_t offset) {-	/* See vmtruncate() */-	unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);-	truncate_inode_pages(mapping, offset);-	unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);+        /* See vmtruncate() */+        unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);+        truncate_inode_pages(mapping, offset);+        unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); } + void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, 				   u64 attr_valid) {@@ -188,8 +217,10 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, 	spin_unlock(&fc->lock);  	if (S_ISREG(inode->i_mode) && oldsize != attr->size) {-		if (attr->size < oldsize)-			fuse_truncate(inode->i_mapping, attr->size);+                if (attr->size < oldsize)+                        fuse_truncate(inode->i_mapping, attr->size);+                /* Enable for 2.6.32 */+		/* truncate_pagecache(inode, oldsize, attr->size); */ 		invalidate_inode_pages2(inode->i_mapping); 	} }@@ -525,6 +556,10 @@ void fuse_conn_init(struct fuse_conn *fc) 	INIT_LIST_HEAD(&fc->bg_queue); 	INIT_LIST_HEAD(&fc->entry); 	atomic_set(&fc->num_waiting, 0);+        /* Enable this in 2.6.32+	fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND;+	fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD;+        */  	fc->khctr = 0; 	fc->polled_files = RB_ROOT; 	fc->reqctr = 0;@@ -735,6 +770,57 @@ static const struct super_operations fuse_super_operations = { 	.show_options	= fuse_show_options, }; +/*  Enable for 2.6.32+static void sanitize_global_limit(unsigned *limit)+{+	if (*limit == 0)+		*limit = ((num_physpages << PAGE_SHIFT) >> 13) /+			 sizeof(struct fuse_req);++	if (*limit >= 1 << 16)+		*limit = (1 << 16) - 1;+}++static int set_global_limit(const char *val, struct kernel_param *kp)+{+	int rv;++	rv = param_set_uint(val, kp);+	if (rv)+		return rv;++	sanitize_global_limit((unsigned *)kp->arg);++	return 0;+}+++static void process_init_limits(struct fuse_conn *fc, struct fuse_init_out *arg)+{+	int cap_sys_admin = capable(CAP_SYS_ADMIN);++	if (arg->minor < 13)+		return;++	sanitize_global_limit(&max_user_bgreq);+	sanitize_global_limit(&max_user_congthresh);++	if (arg->max_background) {+		fc->max_background = arg->max_background;++		if (!cap_sys_admin && fc->max_background > max_user_bgreq)+			fc->max_background = max_user_bgreq;+	}+	if (arg->congestion_threshold) {+		fc->congestion_threshold = arg->congestion_threshold;++		if (!cap_sys_admin &&+		    fc->congestion_threshold > max_user_congthresh)+			fc->congestion_threshold = max_user_congthresh;+	}+}+*/+ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) { 	struct fuse_init_out *arg = &req->misc.init_out;@@ -744,6 +830,9 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) 	else { 		unsigned long ra_pages; +                /* Enable this in 2.6.32 */+		/* process_init_limits(fc, arg); */+ 		if (arg->minor >= 6) { 			ra_pages = arg->max_readahead / PAGE_CACHE_SIZE; 			if (arg->flags & FUSE_ASYNC_READ)@@ -808,7 +897,8 @@ static void fuse_free_conn(struct fuse_conn *fc) static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb) { 	int err;-+        /* Enable for kernel 2.6.32 */+	/* fc->bdi.name = "fuse"; */ 	fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; 	fc->bdi.unplug_io_fn = default_unplug_io_fn; 	/* fuse does it's own writeback accounting */@@ -901,6 +991,9 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) 	if (err) 		goto err_put_conn; +        /* Enable this in 2.6.32 */+	/* sb->s_bdi = &fc->bdi; */+ 	/* Handle umasking inside the fuse code */ 	if (sb->s_flags & MS_POSIXACL) 		fc->dont_mask = 1;@@ -1157,6 +1250,11 @@ static int __init fuse_init(void) 	if (res) 		goto err_sysfs_cleanup; +        /* Enable 2.6.32+	sanitize_global_limit(&max_user_bgreq);+	sanitize_global_limit(&max_user_congthresh);+        */+ 	return 0;   err_sysfs_cleanup: