[kernel] r15747 - in dists/trunk/linux-2.6/debian: . patches/bugfix/all patches/series

Maximilian Attems maks at alioth.debian.org
Tue May 18 14:24:36 UTC 2010


Author: maks
Date: Tue May 18 14:24:31 2010
New Revision: 15747

Log:
Explicitly pass in whether sb is pinned or not

fix famous Kees Cook bug,
patches are scheduled for 2.6.35-rc1 and will go into stable.
this is the first that fixes original issue.

Added:
   dists/trunk/linux-2.6/debian/patches/bugfix/all/fs-explicitly-pass-in-whether-sb-is-pinned-or-not.patch
Modified:
   dists/trunk/linux-2.6/debian/changelog
   dists/trunk/linux-2.6/debian/patches/series/base

Modified: dists/trunk/linux-2.6/debian/changelog
==============================================================================
--- dists/trunk/linux-2.6/debian/changelog	Tue May 18 14:23:01 2010	(r15746)
+++ dists/trunk/linux-2.6/debian/changelog	Tue May 18 14:24:31 2010	(r15747)
@@ -20,6 +20,7 @@
   * Fix backlight support on some recent Thinkpads.
   * Enable autosuspend on UVC by default.
   * acpi: Fall back to manually changing SCI_EN.
+  * Explicitly pass in whether sb is pinned or not.
   
   [ Ben Hutchings ]
   * Prepare debconf templates for translation (Closes: #576758)

Added: dists/trunk/linux-2.6/debian/patches/bugfix/all/fs-explicitly-pass-in-whether-sb-is-pinned-or-not.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/all/fs-explicitly-pass-in-whether-sb-is-pinned-or-not.patch	Tue May 18 14:24:31 2010	(r15747)
@@ -0,0 +1,196 @@
+From: Jens Axboe <axboe at kernel.dk>
+Date: 2010-05-06 07:08:55
+Subject: Explicitly pass in whether sb is pinned or not
+
+
+Revision two of this patch. I got rid of WB_SYNC_NONE_PIN, since we should not
+further muddy the sync type and whether or not the sb is pinned. Instead lets
+add a specific flag for this.
+
+BZ: 15906, Launchpad: 543617
+
+diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
+index 4b37f7c..c9ac9cb 100644
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -45,6 +45,7 @@ struct wb_writeback_args {
+ 	int for_kupdate:1;
+ 	int range_cyclic:1;
+ 	int for_background:1;
++	int sb_pinned:1;
+ };
+ 
+ /*
+@@ -230,6 +231,11 @@ static void bdi_sync_writeback(struct backing_dev_info *bdi,
+ 		.sync_mode	= WB_SYNC_ALL,
+ 		.nr_pages	= LONG_MAX,
+ 		.range_cyclic	= 0,
++		/*
++		 * Setting sb_pinned is not necessary for WB_SYNC_ALL, but
++		 * lets make it explicitly clear.
++		 */
++		.sb_pinned	= 1,
+ 	};
+ 	struct bdi_work work;
+ 
+@@ -245,21 +251,23 @@ static void bdi_sync_writeback(struct backing_dev_info *bdi,
+  * @bdi: the backing device to write from
+  * @sb: write inodes from this super_block
+  * @nr_pages: the number of pages to write
++ * @sb_locked: caller already holds sb umount sem.
+  *
+  * Description:
+  *   This does WB_SYNC_NONE opportunistic writeback. The IO is only
+  *   started when this function returns, we make no guarentees on
+- *   completion. Caller need not hold sb s_umount semaphore.
++ *   completion. Caller specifies whether sb umount sem is held already or not.
+  *
+  */
+ void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb,
+-			 long nr_pages)
++			 long nr_pages, int sb_locked)
+ {
+ 	struct wb_writeback_args args = {
+ 		.sb		= sb,
+ 		.sync_mode	= WB_SYNC_NONE,
+ 		.nr_pages	= nr_pages,
+ 		.range_cyclic	= 1,
++		.sb_pinned	= sb_locked,
+ 	};
+ 
+ 	/*
+@@ -577,7 +585,7 @@ static enum sb_pin_state pin_sb_for_writeback(struct writeback_control *wbc,
+ 	/*
+ 	 * Caller must already hold the ref for this
+ 	 */
+-	if (wbc->sync_mode == WB_SYNC_ALL) {
++	if (wbc->sync_mode == WB_SYNC_ALL || wbc->sb_pinned) {
+ 		WARN_ON(!rwsem_is_locked(&sb->s_umount));
+ 		return SB_NOT_PINNED;
+ 	}
+@@ -751,6 +759,7 @@ static long wb_writeback(struct bdi_writeback *wb,
+ 		.for_kupdate		= args->for_kupdate,
+ 		.for_background		= args->for_background,
+ 		.range_cyclic		= args->range_cyclic,
++		.sb_pinned		= args->sb_pinned,
+ 	};
+ 	unsigned long oldest_jif;
+ 	long wrote = 0;
+@@ -1183,6 +1192,18 @@ static void wait_sb_inodes(struct super_block *sb)
+ 	iput(old_inode);
+ }
+ 
++static void __writeback_inodes_sb(struct super_block *sb, int sb_locked)
++{
++	unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY);
++	unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS);
++	long nr_to_write;
++
++	nr_to_write = nr_dirty + nr_unstable +
++			(inodes_stat.nr_inodes - inodes_stat.nr_unused);
++
++	bdi_start_writeback(sb->s_bdi, sb, nr_to_write, sb_locked);
++}
++
+ /**
+  * writeback_inodes_sb	-	writeback dirty inodes from given super_block
+  * @sb: the superblock
+@@ -1194,18 +1215,23 @@ static void wait_sb_inodes(struct super_block *sb)
+  */
+ void writeback_inodes_sb(struct super_block *sb)
+ {
+-	unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY);
+-	unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS);
+-	long nr_to_write;
+-
+-	nr_to_write = nr_dirty + nr_unstable +
+-			(inodes_stat.nr_inodes - inodes_stat.nr_unused);
+-
+-	bdi_start_writeback(sb->s_bdi, sb, nr_to_write);
++	__writeback_inodes_sb(sb, 0);
+ }
+ EXPORT_SYMBOL(writeback_inodes_sb);
+ 
+ /**
++ * writeback_inodes_sb_locked	- writeback dirty inodes from given super_block
++ * @sb: the superblock
++ *
++ * Like writeback_inodes_sb(), except the caller already holds the
++ * sb umount sem.
++ */
++void writeback_inodes_sb_locked(struct super_block *sb)
++{
++	__writeback_inodes_sb(sb, 1);
++}
++
++/**
+  * writeback_inodes_sb_if_idle	-	start writeback if none underway
+  * @sb: the superblock
+  *
+diff --git a/fs/sync.c b/fs/sync.c
+index 92b2281..de6a441 100644
+--- a/fs/sync.c
++++ b/fs/sync.c
+@@ -42,7 +42,7 @@ static int __sync_filesystem(struct super_block *sb, int wait)
+ 	if (wait)
+ 		sync_inodes_sb(sb);
+ 	else
+-		writeback_inodes_sb(sb);
++		writeback_inodes_sb_locked(sb);
+ 
+ 	if (sb->s_op->sync_fs)
+ 		sb->s_op->sync_fs(sb, wait);
+diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
+index bd0e3c6..90e677a 100644
+--- a/include/linux/backing-dev.h
++++ b/include/linux/backing-dev.h
+@@ -103,7 +103,7 @@ int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev);
+ void bdi_unregister(struct backing_dev_info *bdi);
+ int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int);
+ void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb,
+-				long nr_pages);
++				long nr_pages, int sb_locked);
+ int bdi_writeback_task(struct bdi_writeback *wb);
+ int bdi_has_dirty_io(struct backing_dev_info *bdi);
+ 
+diff --git a/include/linux/writeback.h b/include/linux/writeback.h
+index 36520de..3790165 100644
+--- a/include/linux/writeback.h
++++ b/include/linux/writeback.h
+@@ -65,6 +65,15 @@ struct writeback_control {
+ 	 * so we use a single control to update them
+ 	 */
+ 	unsigned no_nrwrite_index_update:1;
++
++	/*
++	 * For WB_SYNC_ALL, the sb must always be pinned. For WB_SYNC_NONE,
++	 * the writeback code will pin the sb for the caller. However,
++	 * for eg umount, the caller does WB_SYNC_NONE but already has
++	 * the sb pinned. If the below is set, caller already has the
++	 * sb pinned.
++	 */
++	unsigned sb_pinned:1;
+ };
+ 
+ /*
+@@ -73,6 +82,7 @@ struct writeback_control {
+ struct bdi_writeback;
+ int inode_wait(void *);
+ void writeback_inodes_sb(struct super_block *);
++void writeback_inodes_sb_locked(struct super_block *);
+ int writeback_inodes_sb_if_idle(struct super_block *);
+ void sync_inodes_sb(struct super_block *);
+ void writeback_inodes_wbc(struct writeback_control *wbc);
+diff --git a/mm/page-writeback.c b/mm/page-writeback.c
+index 0b19943..49d3508 100644
+--- a/mm/page-writeback.c
++++ b/mm/page-writeback.c
+@@ -597,7 +597,7 @@ static void balance_dirty_pages(struct address_space *mapping,
+ 	    (!laptop_mode && ((global_page_state(NR_FILE_DIRTY)
+ 			       + global_page_state(NR_UNSTABLE_NFS))
+ 					  > background_thresh)))
+-		bdi_start_writeback(bdi, NULL, 0);
++		bdi_start_writeback(bdi, NULL, 0, 0);
+ }
+ 
+ void set_page_dirty_balance(struct page *page, int page_mkwrite)

Modified: dists/trunk/linux-2.6/debian/patches/series/base
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/base	Tue May 18 14:23:01 2010	(r15746)
+++ dists/trunk/linux-2.6/debian/patches/series/base	Tue May 18 14:24:31 2010	(r15747)
@@ -68,3 +68,4 @@
 + bugfix/all/thinkpad-acpi-fix-backlight.patch
 + bugfix/all/linux-2.6-usb-uvc-autosuspend.diff
 + bugfix/all/linux-2.6-acpi-sleep-live-sci-live.patch
++ bugfix/all/fs-explicitly-pass-in-whether-sb-is-pinned-or-not.patch



More information about the Kernel-svn-changes mailing list