--- /dev/null
+From a0f9354b1a319cb29c331bfd2e5a15d7f9b87fa4 Mon Sep 17 00:00:00 2001
+From: Randy Dunlap <rdunlap@infradead.org>
+Date: Wed, 8 May 2013 17:28:13 -0300
+Subject: media: media/usb: fix kconfig dependencies
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+commit a0f9354b1a319cb29c331bfd2e5a15d7f9b87fa4 upstream.
+
+(a.k.a. Kconfig bool depending on a tristate considered harmful)
+Fix various build errors when CONFIG_USB=m and media USB drivers
+are builtin. In this case, CONFIG_USB_ZR364XX=y,
+CONFIG_VIDEO_PVRUSB2=y, and CONFIG_VIDEO_STK1160=y.
+This is caused by (from drivers/media/usb/Kconfig):
+menuconfig MEDIA_USB_SUPPORT
+ bool "Media USB Adapters"
+ depends on USB && MEDIA_SUPPORT
+ =m =y
+so MEDIA_USB_SUPPORT=y and all following Kconfig 'source' lines
+are included. By adding an "if USB" guard around most of this file,
+the needed dependencies are enforced.
+drivers/built-in.o: In function `zr364xx_start_readpipe':
+zr364xx.c:(.text+0xc726a): undefined reference to `usb_alloc_urb'
+zr364xx.c:(.text+0xc72bb): undefined reference to `usb_submit_urb'
+drivers/built-in.o: In function `zr364xx_stop_readpipe':
+zr364xx.c:(.text+0xc72fd): undefined reference to `usb_kill_urb'
+zr364xx.c:(.text+0xc7309): undefined reference to `usb_free_urb'
+drivers/built-in.o: In function `read_pipe_completion':
+zr364xx.c:(.text+0xc7acc): undefined reference to `usb_submit_urb'
+drivers/built-in.o: In function `send_control_msg.constprop.12':
+zr364xx.c:(.text+0xc7d2f): undefined reference to `usb_control_msg'
+drivers/built-in.o: In function `pvr2_ctl_timeout':
+pvrusb2-hdw.c:(.text+0xcadb6): undefined reference to `usb_unlink_urb'
+pvrusb2-hdw.c:(.text+0xcadcb): undefined reference to `usb_unlink_urb'
+drivers/built-in.o: In function `pvr2_hdw_create':
+(.text+0xcc42c): undefined reference to `usb_alloc_urb'
+drivers/built-in.o: In function `pvr2_hdw_create':
+(.text+0xcc448): undefined reference to `usb_alloc_urb'
+drivers/built-in.o: In function `pvr2_hdw_create':
+(.text+0xcc5f9): undefined reference to `usb_set_interface'
+drivers/built-in.o: In function `pvr2_hdw_create':
+(.text+0xcc65a): undefined reference to `usb_free_urb'
+drivers/built-in.o: In function `pvr2_hdw_create':
+(.text+0xcc666): undefined reference to `usb_free_urb'
+drivers/built-in.o: In function `pvr2_send_request_ex.part.22':
+pvrusb2-hdw.c:(.text+0xccbe3): undefined reference to `usb_submit_urb'
+pvrusb2-hdw.c:(.text+0xccc83): undefined reference to `usb_submit_urb'
+drivers/built-in.o: In function `pvr2_hdw_remove_usb_stuff.part.25':
+pvrusb2-hdw.c:(.text+0xcd3f9): undefined reference to `usb_kill_urb'
+pvrusb2-hdw.c:(.text+0xcd405): undefined reference to `usb_free_urb'
+pvrusb2-hdw.c:(.text+0xcd421): undefined reference to `usb_kill_urb'
+pvrusb2-hdw.c:(.text+0xcd42d): undefined reference to `usb_free_urb'
+drivers/built-in.o: In function `pvr2_hdw_device_reset':
+(.text+0xcd658): undefined reference to `usb_lock_device_for_reset'
+drivers/built-in.o: In function `pvr2_hdw_device_reset':
+(.text+0xcd664): undefined reference to `usb_reset_device'
+drivers/built-in.o: In function `pvr2_hdw_cpureset_assert':
+(.text+0xcd6f9): undefined reference to `usb_control_msg'
+drivers/built-in.o: In function `pvr2_hdw_cpufw_set_enabled':
+(.text+0xcd84e): undefined reference to `usb_control_msg'
+drivers/built-in.o: In function `pvr2_upload_firmware1':
+pvrusb2-hdw.c:(.text+0xcda47): undefined reference to `usb_clear_halt'
+pvrusb2-hdw.c:(.text+0xcdb04): undefined reference to `usb_control_msg'
+drivers/built-in.o: In function `pvr2_upload_firmware2':
+(.text+0xce7dc): undefined reference to `usb_bulk_msg'
+drivers/built-in.o: In function `pvr2_stream_buffer_count':
+pvrusb2-io.c:(.text+0xd2e05): undefined reference to `usb_alloc_urb'
+pvrusb2-io.c:(.text+0xd2e5b): undefined reference to `usb_kill_urb'
+pvrusb2-io.c:(.text+0xd2e9f): undefined reference to `usb_free_urb'
+drivers/built-in.o: In function `pvr2_stream_internal_flush':
+pvrusb2-io.c:(.text+0xd2f9b): undefined reference to `usb_kill_urb'
+drivers/built-in.o: In function `pvr2_buffer_queue':
+(.text+0xd3328): undefined reference to `usb_kill_urb'
+drivers/built-in.o: In function `pvr2_buffer_queue':
+(.text+0xd33ea): undefined reference to `usb_submit_urb'
+drivers/built-in.o: In function `stk1160_read_reg':
+(.text+0xd3efa): undefined reference to `usb_control_msg'
+drivers/built-in.o: In function `stk1160_write_reg':
+(.text+0xd3f4f): undefined reference to `usb_control_msg'
+drivers/built-in.o: In function `stop_streaming':
+stk1160-v4l.c:(.text+0xd4997): undefined reference to `usb_set_interface'
+drivers/built-in.o: In function `start_streaming':
+stk1160-v4l.c:(.text+0xd4a9f): undefined reference to `usb_set_interface'
+stk1160-v4l.c:(.text+0xd4afa): undefined reference to `usb_submit_urb'
+stk1160-v4l.c:(.text+0xd4ba3): undefined reference to `usb_set_interface'
+drivers/built-in.o: In function `stk1160_isoc_irq':
+stk1160-video.c:(.text+0xd509b): undefined reference to `usb_submit_urb'
+drivers/built-in.o: In function `stk1160_cancel_isoc':
+(.text+0xd50ef): undefined reference to `usb_kill_urb'
+drivers/built-in.o: In function `stk1160_free_isoc':
+(.text+0xd5155): undefined reference to `usb_free_coherent'
+drivers/built-in.o: In function `stk1160_free_isoc':
+(.text+0xd515d): undefined reference to `usb_free_urb'
+drivers/built-in.o: In function `stk1160_alloc_isoc':
+(.text+0xd5278): undefined reference to `usb_alloc_urb'
+drivers/built-in.o: In function `stk1160_alloc_isoc':
+(.text+0xd52c2): undefined reference to `usb_alloc_coherent'
+drivers/built-in.o: In function `stk1160_alloc_isoc':
+(.text+0xd53c4): undefined reference to `usb_free_urb'
+drivers/built-in.o: In function `zr364xx_driver_init':
+zr364xx.c:(.init.text+0x463e): undefined reference to `usb_register_driver'
+drivers/built-in.o: In function `pvr_init':
+pvrusb2-main.c:(.init.text+0x4662): undefined reference to `usb_register_driver'
+drivers/built-in.o: In function `stk1160_usb_driver_init':
+stk1160-core.c:(.init.text+0x467d): undefined reference to `usb_register_driver'
+drivers/built-in.o: In function `zr364xx_driver_exit':
+zr364xx.c:(.exit.text+0x1377): undefined reference to `usb_deregister'
+drivers/built-in.o: In function `pvr_exit':
+pvrusb2-main.c:(.exit.text+0x1389): undefined reference to `usb_deregister'
+drivers/built-in.o: In function `stk1160_usb_driver_exit':
+stk1160-core.c:(.exit.text+0x13a0): undefined reference to `usb_deregister'
+
+Suggested-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/usb/Kconfig | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/media/usb/Kconfig
++++ b/drivers/media/usb/Kconfig
+@@ -1,6 +1,8 @@
++if USB
++
+ menuconfig MEDIA_USB_SUPPORT
+ bool "Media USB Adapters"
+- depends on USB && MEDIA_SUPPORT
++ depends on MEDIA_SUPPORT
+ help
+ Enable media drivers for USB bus.
+ If you have such devices, say Y.
+@@ -52,3 +54,4 @@ source "drivers/media/usb/em28xx/Kconfig
+ endif
+
+ endif #MEDIA_USB_SUPPORT
++endif #USB
--- /dev/null
+From 7cb2ef56e6a8b7b368b2e883a0a47d02fed66911 Mon Sep 17 00:00:00 2001
+From: Khalid Aziz <khalid.aziz@oracle.com>
+Date: Wed, 11 Sep 2013 14:22:20 -0700
+Subject: mm: fix aio performance regression for database caused by THP
+
+From: Khalid Aziz <khalid.aziz@oracle.com>
+
+commit 7cb2ef56e6a8b7b368b2e883a0a47d02fed66911 upstream.
+
+I am working with a tool that simulates oracle database I/O workload.
+This tool (orion to be specific -
+<http://docs.oracle.com/cd/E11882_01/server.112/e16638/iodesign.htm#autoId24>)
+allocates hugetlbfs pages using shmget() with SHM_HUGETLB flag. It then
+does aio into these pages from flash disks using various common block
+sizes used by database. I am looking at performance with two of the most
+common block sizes - 1M and 64K. aio performance with these two block
+sizes plunged after Transparent HugePages was introduced in the kernel.
+Here are performance numbers:
+
+ pre-THP 2.6.39 3.11-rc5
+1M read 8384 MB/s 5629 MB/s 6501 MB/s
+64K read 7867 MB/s 4576 MB/s 4251 MB/s
+
+I have narrowed the performance impact down to the overheads introduced by
+THP in __get_page_tail() and put_compound_page() routines. perf top shows
+>40% of cycles being spent in these two routines. Every time direct I/O
+to hugetlbfs pages starts, kernel calls get_page() to grab a reference to
+the pages and calls put_page() when I/O completes to put the reference
+away. THP introduced significant amount of locking overhead to get_page()
+and put_page() when dealing with compound pages because hugepages can be
+split underneath get_page() and put_page(). It added this overhead
+irrespective of whether it is dealing with hugetlbfs pages or transparent
+hugepages. This resulted in 20%-45% drop in aio performance when using
+hugetlbfs pages.
+
+Since hugetlbfs pages can not be split, there is no reason to go through
+all the locking overhead for these pages from what I can see. I added
+code to __get_page_tail() and put_compound_page() to bypass all the
+locking code when working with hugetlbfs pages. This improved performance
+significantly. Performance numbers with this patch:
+
+ pre-THP 3.11-rc5 3.11-rc5 + Patch
+1M read 8384 MB/s 6501 MB/s 8371 MB/s
+64K read 7867 MB/s 4251 MB/s 6510 MB/s
+
+Performance with 64K read is still lower than what it was before THP, but
+still a 53% improvement. It does mean there is more work to be done but I
+will take a 53% improvement for now.
+
+Please take a look at the following patch and let me know if it looks
+reasonable.
+
+[akpm@linux-foundation.org: tweak comments]
+Signed-off-by: Khalid Aziz <khalid.aziz@oracle.com>
+Cc: Pravin B Shelar <pshelar@nicira.com>
+Cc: Christoph Lameter <cl@linux.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Mel Gorman <mel@csn.ul.ie>
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: Andi Kleen <andi@firstfloor.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/swap.c | 77 +++++++++++++++++++++++++++++++++++++++++---------------------
+ 1 file changed, 52 insertions(+), 25 deletions(-)
+
+--- a/mm/swap.c
++++ b/mm/swap.c
+@@ -31,6 +31,7 @@
+ #include <linux/memcontrol.h>
+ #include <linux/gfp.h>
+ #include <linux/uio.h>
++#include <linux/hugetlb.h>
+
+ #include "internal.h"
+
+@@ -78,6 +79,19 @@ static void __put_compound_page(struct p
+
+ static void put_compound_page(struct page *page)
+ {
++ /*
++ * hugetlbfs pages cannot be split from under us. If this is a
++ * hugetlbfs page, check refcount on head page and release the page if
++ * the refcount becomes zero.
++ */
++ if (PageHuge(page)) {
++ page = compound_head(page);
++ if (put_page_testzero(page))
++ __put_compound_page(page);
++
++ return;
++ }
++
+ if (unlikely(PageTail(page))) {
+ /* __split_huge_page_refcount can run under us */
+ struct page *page_head = compound_trans_head(page);
+@@ -181,38 +195,51 @@ bool __get_page_tail(struct page *page)
+ * proper PT lock that already serializes against
+ * split_huge_page().
+ */
+- unsigned long flags;
+ bool got = false;
+- struct page *page_head = compound_trans_head(page);
++ struct page *page_head;
+
+- if (likely(page != page_head && get_page_unless_zero(page_head))) {
++ /*
++ * If this is a hugetlbfs page it cannot be split under us. Simply
++ * increment refcount for the head page.
++ */
++ if (PageHuge(page)) {
++ page_head = compound_head(page);
++ atomic_inc(&page_head->_count);
++ got = true;
++ } else {
++ unsigned long flags;
++
++ page_head = compound_trans_head(page);
++ if (likely(page != page_head &&
++ get_page_unless_zero(page_head))) {
++
++ /* Ref to put_compound_page() comment. */
++ if (PageSlab(page_head)) {
++ if (likely(PageTail(page))) {
++ __get_page_tail_foll(page, false);
++ return true;
++ } else {
++ put_page(page_head);
++ return false;
++ }
++ }
+
+- /* Ref to put_compound_page() comment. */
+- if (PageSlab(page_head)) {
++ /*
++ * page_head wasn't a dangling pointer but it
++ * may not be a head page anymore by the time
++ * we obtain the lock. That is ok as long as it
++ * can't be freed from under us.
++ */
++ flags = compound_lock_irqsave(page_head);
++ /* here __split_huge_page_refcount won't run anymore */
+ if (likely(PageTail(page))) {
+ __get_page_tail_foll(page, false);
+- return true;
+- } else {
+- put_page(page_head);
+- return false;
++ got = true;
+ }
++ compound_unlock_irqrestore(page_head, flags);
++ if (unlikely(!got))
++ put_page(page_head);
+ }
+-
+- /*
+- * page_head wasn't a dangling pointer but it
+- * may not be a head page anymore by the time
+- * we obtain the lock. That is ok as long as it
+- * can't be freed from under us.
+- */
+- flags = compound_lock_irqsave(page_head);
+- /* here __split_huge_page_refcount won't run anymore */
+- if (likely(PageTail(page))) {
+- __get_page_tail_foll(page, false);
+- got = true;
+- }
+- compound_unlock_irqrestore(page_head, flags);
+- if (unlikely(!got))
+- put_page(page_head);
+ }
+ return got;
+ }
--- /dev/null
+From d759bfa4e7919b89357de50a2e23817079889195 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 25 Jul 2013 19:10:59 +0200
+Subject: udf: Standardize return values in mount sequence
+
+From: Jan Kara <jack@suse.cz>
+
+commit d759bfa4e7919b89357de50a2e23817079889195 upstream.
+
+Change all function used in filesystem discovery during mount to user
+standard kernel return values - -errno on error, 0 on success instead
+of 1 on failure and 0 on success. This allows us to pass error number
+(not just failure / success) so we can abort device scanning earlier
+in case of errors like EIO or ENOMEM . Also we will be able to return
+EROFS in case writeable mount is requested but writing isn't supported.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Cc: Hui Wang <hui.wang@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/udf/super.c | 300 ++++++++++++++++++++++++++++++++++-----------------------
+ 1 file changed, 183 insertions(+), 117 deletions(-)
+
+--- a/fs/udf/super.c
++++ b/fs/udf/super.c
+@@ -843,27 +843,38 @@ static int udf_find_fileset(struct super
+ return 1;
+ }
+
++/*
++ * Load primary Volume Descriptor Sequence
++ *
++ * Return <0 on error, 0 on success. -EAGAIN is special meaning next sequence
++ * should be tried.
++ */
+ static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
+ {
+ struct primaryVolDesc *pvoldesc;
+ struct ustr *instr, *outstr;
+ struct buffer_head *bh;
+ uint16_t ident;
+- int ret = 1;
++ int ret = -ENOMEM;
+
+ instr = kmalloc(sizeof(struct ustr), GFP_NOFS);
+ if (!instr)
+- return 1;
++ return -ENOMEM;
+
+ outstr = kmalloc(sizeof(struct ustr), GFP_NOFS);
+ if (!outstr)
+ goto out1;
+
+ bh = udf_read_tagged(sb, block, block, &ident);
+- if (!bh)
++ if (!bh) {
++ ret = -EAGAIN;
+ goto out2;
++ }
+
+- BUG_ON(ident != TAG_IDENT_PVD);
++ if (ident != TAG_IDENT_PVD) {
++ ret = -EIO;
++ goto out_bh;
++ }
+
+ pvoldesc = (struct primaryVolDesc *)bh->b_data;
+
+@@ -889,8 +900,9 @@ static int udf_load_pvoldesc(struct supe
+ if (udf_CS0toUTF8(outstr, instr))
+ udf_debug("volSetIdent[] = '%s'\n", outstr->u_name);
+
+- brelse(bh);
+ ret = 0;
++out_bh:
++ brelse(bh);
+ out2:
+ kfree(outstr);
+ out1:
+@@ -947,7 +959,7 @@ static int udf_load_metadata_files(struc
+
+ if (mdata->s_mirror_fe == NULL) {
+ udf_err(sb, "Both metadata and mirror metadata inode efe can not found\n");
+- goto error_exit;
++ return -EIO;
+ }
+ }
+
+@@ -964,23 +976,18 @@ static int udf_load_metadata_files(struc
+ addr.logicalBlockNum, addr.partitionReferenceNum);
+
+ mdata->s_bitmap_fe = udf_iget(sb, &addr);
+-
+ if (mdata->s_bitmap_fe == NULL) {
+ if (sb->s_flags & MS_RDONLY)
+ udf_warn(sb, "bitmap inode efe not found but it's ok since the disc is mounted read-only\n");
+ else {
+ udf_err(sb, "bitmap inode efe not found and attempted read-write mount\n");
+- goto error_exit;
++ return -EIO;
+ }
+ }
+ }
+
+ udf_debug("udf_load_metadata_files Ok\n");
+-
+ return 0;
+-
+-error_exit:
+- return 1;
+ }
+
+ static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh,
+@@ -1069,7 +1076,7 @@ static int udf_fill_partdesc_info(struct
+ if (!map->s_uspace.s_table) {
+ udf_debug("cannot load unallocSpaceTable (part %d)\n",
+ p_index);
+- return 1;
++ return -EIO;
+ }
+ map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_TABLE;
+ udf_debug("unallocSpaceTable (part %d) @ %ld\n",
+@@ -1079,7 +1086,7 @@ static int udf_fill_partdesc_info(struct
+ if (phd->unallocSpaceBitmap.extLength) {
+ struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, p_index);
+ if (!bitmap)
+- return 1;
++ return -ENOMEM;
+ map->s_uspace.s_bitmap = bitmap;
+ bitmap->s_extPosition = le32_to_cpu(
+ phd->unallocSpaceBitmap.extPosition);
+@@ -1102,7 +1109,7 @@ static int udf_fill_partdesc_info(struct
+ if (!map->s_fspace.s_table) {
+ udf_debug("cannot load freedSpaceTable (part %d)\n",
+ p_index);
+- return 1;
++ return -EIO;
+ }
+
+ map->s_partition_flags |= UDF_PART_FLAG_FREED_TABLE;
+@@ -1113,7 +1120,7 @@ static int udf_fill_partdesc_info(struct
+ if (phd->freedSpaceBitmap.extLength) {
+ struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, p_index);
+ if (!bitmap)
+- return 1;
++ return -ENOMEM;
+ map->s_fspace.s_bitmap = bitmap;
+ bitmap->s_extPosition = le32_to_cpu(
+ phd->freedSpaceBitmap.extPosition);
+@@ -1165,7 +1172,7 @@ static int udf_load_vat(struct super_blo
+ udf_find_vat_block(sb, p_index, type1_index, blocks - 1);
+ }
+ if (!sbi->s_vat_inode)
+- return 1;
++ return -EIO;
+
+ if (map->s_partition_type == UDF_VIRTUAL_MAP15) {
+ map->s_type_specific.s_virtual.s_start_offset = 0;
+@@ -1177,7 +1184,7 @@ static int udf_load_vat(struct super_blo
+ pos = udf_block_map(sbi->s_vat_inode, 0);
+ bh = sb_bread(sb, pos);
+ if (!bh)
+- return 1;
++ return -EIO;
+ vat20 = (struct virtualAllocationTable20 *)bh->b_data;
+ } else {
+ vat20 = (struct virtualAllocationTable20 *)
+@@ -1195,6 +1202,12 @@ static int udf_load_vat(struct super_blo
+ return 0;
+ }
+
++/*
++ * Load partition descriptor block
++ *
++ * Returns <0 on error, 0 on success, -EAGAIN is special - try next descriptor
++ * sequence.
++ */
+ static int udf_load_partdesc(struct super_block *sb, sector_t block)
+ {
+ struct buffer_head *bh;
+@@ -1204,13 +1217,15 @@ static int udf_load_partdesc(struct supe
+ int i, type1_idx;
+ uint16_t partitionNumber;
+ uint16_t ident;
+- int ret = 0;
++ int ret;
+
+ bh = udf_read_tagged(sb, block, block, &ident);
+ if (!bh)
+- return 1;
+- if (ident != TAG_IDENT_PD)
++ return -EAGAIN;
++ if (ident != TAG_IDENT_PD) {
++ ret = 0;
+ goto out_bh;
++ }
+
+ p = (struct partitionDesc *)bh->b_data;
+ partitionNumber = le16_to_cpu(p->partitionNumber);
+@@ -1229,10 +1244,13 @@ static int udf_load_partdesc(struct supe
+ if (i >= sbi->s_partitions) {
+ udf_debug("Partition (%d) not found in partition map\n",
+ partitionNumber);
++ ret = 0;
+ goto out_bh;
+ }
+
+ ret = udf_fill_partdesc_info(sb, p, i);
++ if (ret < 0)
++ goto out_bh;
+
+ /*
+ * Now rescan for VIRTUAL or METADATA partitions when SPARABLE and
+@@ -1249,23 +1267,25 @@ static int udf_load_partdesc(struct supe
+ break;
+ }
+
+- if (i >= sbi->s_partitions)
++ if (i >= sbi->s_partitions) {
++ ret = 0;
+ goto out_bh;
++ }
+
+ ret = udf_fill_partdesc_info(sb, p, i);
+- if (ret)
++ if (ret < 0)
+ goto out_bh;
+
+ if (map->s_partition_type == UDF_METADATA_MAP25) {
+ ret = udf_load_metadata_files(sb, i);
+- if (ret) {
++ if (ret < 0) {
+ udf_err(sb, "error loading MetaData partition map %d\n",
+ i);
+ goto out_bh;
+ }
+ } else {
+ ret = udf_load_vat(sb, i, type1_idx);
+- if (ret)
++ if (ret < 0)
+ goto out_bh;
+ /*
+ * Mark filesystem read-only if we have a partition with
+@@ -1275,6 +1295,7 @@ static int udf_load_partdesc(struct supe
+ sb->s_flags |= MS_RDONLY;
+ pr_notice("Filesystem marked read-only because writing to pseudooverwrite partition is not implemented\n");
+ }
++ ret = 0;
+ out_bh:
+ /* In case loading failed, we handle cleanup in udf_fill_super */
+ brelse(bh);
+@@ -1340,11 +1361,11 @@ static int udf_load_logicalvol(struct su
+ uint16_t ident;
+ struct buffer_head *bh;
+ unsigned int table_len;
+- int ret = 0;
++ int ret;
+
+ bh = udf_read_tagged(sb, block, block, &ident);
+ if (!bh)
+- return 1;
++ return -EAGAIN;
+ BUG_ON(ident != TAG_IDENT_LVD);
+ lvd = (struct logicalVolDesc *)bh->b_data;
+ table_len = le32_to_cpu(lvd->mapTableLength);
+@@ -1352,7 +1373,7 @@ static int udf_load_logicalvol(struct su
+ udf_err(sb, "error loading logical volume descriptor: "
+ "Partition table too long (%u > %lu)\n", table_len,
+ sb->s_blocksize - sizeof(*lvd));
+- ret = 1;
++ ret = -EIO;
+ goto out_bh;
+ }
+
+@@ -1396,11 +1417,10 @@ static int udf_load_logicalvol(struct su
+ } else if (!strncmp(upm2->partIdent.ident,
+ UDF_ID_SPARABLE,
+ strlen(UDF_ID_SPARABLE))) {
+- if (udf_load_sparable_map(sb, map,
+- (struct sparablePartitionMap *)gpm) < 0) {
+- ret = 1;
++ ret = udf_load_sparable_map(sb, map,
++ (struct sparablePartitionMap *)gpm);
++ if (ret < 0)
+ goto out_bh;
+- }
+ } else if (!strncmp(upm2->partIdent.ident,
+ UDF_ID_METADATA,
+ strlen(UDF_ID_METADATA))) {
+@@ -1465,7 +1485,7 @@ static int udf_load_logicalvol(struct su
+ }
+ if (lvd->integritySeqExt.extLength)
+ udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt));
+-
++ ret = 0;
+ out_bh:
+ brelse(bh);
+ return ret;
+@@ -1503,22 +1523,18 @@ static void udf_load_logicalvolint(struc
+ }
+
+ /*
+- * udf_process_sequence
+- *
+- * PURPOSE
+- * Process a main/reserve volume descriptor sequence.
++ * Process a main/reserve volume descriptor sequence.
++ * @block First block of first extent of the sequence.
++ * @lastblock Lastblock of first extent of the sequence.
++ * @fileset There we store extent containing root fileset
+ *
+- * PRE-CONDITIONS
+- * sb Pointer to _locked_ superblock.
+- * block First block of first extent of the sequence.
+- * lastblock Lastblock of first extent of the sequence.
+- *
+- * HISTORY
+- * July 1, 1997 - Andrew E. Mileski
+- * Written, tested, and released.
++ * Returns <0 on error, 0 on success. -EAGAIN is special - try next descriptor
++ * sequence
+ */
+-static noinline int udf_process_sequence(struct super_block *sb, long block,
+- long lastblock, struct kernel_lb_addr *fileset)
++static noinline int udf_process_sequence(
++ struct super_block *sb,
++ sector_t block, sector_t lastblock,
++ struct kernel_lb_addr *fileset)
+ {
+ struct buffer_head *bh = NULL;
+ struct udf_vds_record vds[VDS_POS_LENGTH];
+@@ -1529,6 +1545,7 @@ static noinline int udf_process_sequence
+ uint32_t vdsn;
+ uint16_t ident;
+ long next_s = 0, next_e = 0;
++ int ret;
+
+ memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH);
+
+@@ -1543,7 +1560,7 @@ static noinline int udf_process_sequence
+ udf_err(sb,
+ "Block %llu of volume descriptor sequence is corrupted or we could not read it\n",
+ (unsigned long long)block);
+- return 1;
++ return -EAGAIN;
+ }
+
+ /* Process each descriptor (ISO 13346 3/8.3-8.4) */
+@@ -1616,14 +1633,19 @@ static noinline int udf_process_sequence
+ */
+ if (!vds[VDS_POS_PRIMARY_VOL_DESC].block) {
+ udf_err(sb, "Primary Volume Descriptor not found!\n");
+- return 1;
++ return -EAGAIN;
++ }
++ ret = udf_load_pvoldesc(sb, vds[VDS_POS_PRIMARY_VOL_DESC].block);
++ if (ret < 0)
++ return ret;
++
++ if (vds[VDS_POS_LOGICAL_VOL_DESC].block) {
++ ret = udf_load_logicalvol(sb,
++ vds[VDS_POS_LOGICAL_VOL_DESC].block,
++ fileset);
++ if (ret < 0)
++ return ret;
+ }
+- if (udf_load_pvoldesc(sb, vds[VDS_POS_PRIMARY_VOL_DESC].block))
+- return 1;
+-
+- if (vds[VDS_POS_LOGICAL_VOL_DESC].block && udf_load_logicalvol(sb,
+- vds[VDS_POS_LOGICAL_VOL_DESC].block, fileset))
+- return 1;
+
+ if (vds[VDS_POS_PARTITION_DESC].block) {
+ /*
+@@ -1632,19 +1654,27 @@ static noinline int udf_process_sequence
+ */
+ for (block = vds[VDS_POS_PARTITION_DESC].block;
+ block < vds[VDS_POS_TERMINATING_DESC].block;
+- block++)
+- if (udf_load_partdesc(sb, block))
+- return 1;
++ block++) {
++ ret = udf_load_partdesc(sb, block);
++ if (ret < 0)
++ return ret;
++ }
+ }
+
+ return 0;
+ }
+
++/*
++ * Load Volume Descriptor Sequence described by anchor in bh
++ *
++ * Returns <0 on error, 0 on success
++ */
+ static int udf_load_sequence(struct super_block *sb, struct buffer_head *bh,
+ struct kernel_lb_addr *fileset)
+ {
+ struct anchorVolDescPtr *anchor;
+- long main_s, main_e, reserve_s, reserve_e;
++ sector_t main_s, main_e, reserve_s, reserve_e;
++ int ret;
+
+ anchor = (struct anchorVolDescPtr *)bh->b_data;
+
+@@ -1662,18 +1692,26 @@ static int udf_load_sequence(struct supe
+
+ /* Process the main & reserve sequences */
+ /* responsible for finding the PartitionDesc(s) */
+- if (!udf_process_sequence(sb, main_s, main_e, fileset))
+- return 1;
++ ret = udf_process_sequence(sb, main_s, main_e, fileset);
++ if (ret != -EAGAIN)
++ return ret;
+ udf_sb_free_partitions(sb);
+- if (!udf_process_sequence(sb, reserve_s, reserve_e, fileset))
+- return 1;
+- udf_sb_free_partitions(sb);
+- return 0;
++ ret = udf_process_sequence(sb, reserve_s, reserve_e, fileset);
++ if (ret < 0) {
++ udf_sb_free_partitions(sb);
++ /* No sequence was OK, return -EIO */
++ if (ret == -EAGAIN)
++ ret = -EIO;
++ }
++ return ret;
+ }
+
+ /*
+ * Check whether there is an anchor block in the given block and
+ * load Volume Descriptor Sequence if so.
++ *
++ * Returns <0 on error, 0 on success, -EAGAIN is special - try next anchor
++ * block
+ */
+ static int udf_check_anchor_block(struct super_block *sb, sector_t block,
+ struct kernel_lb_addr *fileset)
+@@ -1685,33 +1723,40 @@ static int udf_check_anchor_block(struct
+ if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) &&
+ udf_fixed_to_variable(block) >=
+ sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits)
+- return 0;
++ return -EAGAIN;
+
+ bh = udf_read_tagged(sb, block, block, &ident);
+ if (!bh)
+- return 0;
++ return -EAGAIN;
+ if (ident != TAG_IDENT_AVDP) {
+ brelse(bh);
+- return 0;
++ return -EAGAIN;
+ }
+ ret = udf_load_sequence(sb, bh, fileset);
+ brelse(bh);
+ return ret;
+ }
+
+-/* Search for an anchor volume descriptor pointer */
+-static sector_t udf_scan_anchors(struct super_block *sb, sector_t lastblock,
+- struct kernel_lb_addr *fileset)
++/*
++ * Search for an anchor volume descriptor pointer.
++ *
++ * Returns < 0 on error, 0 on success. -EAGAIN is special - try next set
++ * of anchors.
++ */
++static int udf_scan_anchors(struct super_block *sb, sector_t *lastblock,
++ struct kernel_lb_addr *fileset)
+ {
+ sector_t last[6];
+ int i;
+ struct udf_sb_info *sbi = UDF_SB(sb);
+ int last_count = 0;
++ int ret;
+
+ /* First try user provided anchor */
+ if (sbi->s_anchor) {
+- if (udf_check_anchor_block(sb, sbi->s_anchor, fileset))
+- return lastblock;
++ ret = udf_check_anchor_block(sb, sbi->s_anchor, fileset);
++ if (ret != -EAGAIN)
++ return ret;
+ }
+ /*
+ * according to spec, anchor is in either:
+@@ -1720,39 +1765,46 @@ static sector_t udf_scan_anchors(struct
+ * lastblock
+ * however, if the disc isn't closed, it could be 512.
+ */
+- if (udf_check_anchor_block(sb, sbi->s_session + 256, fileset))
+- return lastblock;
++ ret = udf_check_anchor_block(sb, sbi->s_session + 256, fileset);
++ if (ret != -EAGAIN)
++ return ret;
+ /*
+ * The trouble is which block is the last one. Drives often misreport
+ * this so we try various possibilities.
+ */
+- last[last_count++] = lastblock;
+- if (lastblock >= 1)
+- last[last_count++] = lastblock - 1;
+- last[last_count++] = lastblock + 1;
+- if (lastblock >= 2)
+- last[last_count++] = lastblock - 2;
+- if (lastblock >= 150)
+- last[last_count++] = lastblock - 150;
+- if (lastblock >= 152)
+- last[last_count++] = lastblock - 152;
++ last[last_count++] = *lastblock;
++ if (*lastblock >= 1)
++ last[last_count++] = *lastblock - 1;
++ last[last_count++] = *lastblock + 1;
++ if (*lastblock >= 2)
++ last[last_count++] = *lastblock - 2;
++ if (*lastblock >= 150)
++ last[last_count++] = *lastblock - 150;
++ if (*lastblock >= 152)
++ last[last_count++] = *lastblock - 152;
+
+ for (i = 0; i < last_count; i++) {
+ if (last[i] >= sb->s_bdev->bd_inode->i_size >>
+ sb->s_blocksize_bits)
+ continue;
+- if (udf_check_anchor_block(sb, last[i], fileset))
+- return last[i];
++ ret = udf_check_anchor_block(sb, last[i], fileset);
++ if (ret != -EAGAIN) {
++ if (!ret)
++ *lastblock = last[i];
++ return ret;
++ }
+ if (last[i] < 256)
+ continue;
+- if (udf_check_anchor_block(sb, last[i] - 256, fileset))
+- return last[i];
++ ret = udf_check_anchor_block(sb, last[i] - 256, fileset);
++ if (ret != -EAGAIN) {
++ if (!ret)
++ *lastblock = last[i];
++ return ret;
++ }
+ }
+
+ /* Finally try block 512 in case media is open */
+- if (udf_check_anchor_block(sb, sbi->s_session + 512, fileset))
+- return last[0];
+- return 0;
++ return udf_check_anchor_block(sb, sbi->s_session + 512, fileset);
+ }
+
+ /*
+@@ -1760,54 +1812,59 @@ static sector_t udf_scan_anchors(struct
+ * area specified by it. The function expects sbi->s_lastblock to be the last
+ * block on the media.
+ *
+- * Return 1 if ok, 0 if not found.
+- *
++ * Return <0 on error, 0 if anchor found. -EAGAIN is special meaning anchor
++ * was not found.
+ */
+ static int udf_find_anchor(struct super_block *sb,
+ struct kernel_lb_addr *fileset)
+ {
+- sector_t lastblock;
+ struct udf_sb_info *sbi = UDF_SB(sb);
++ sector_t lastblock = sbi->s_last_block;
++ int ret;
+
+- lastblock = udf_scan_anchors(sb, sbi->s_last_block, fileset);
+- if (lastblock)
++ ret = udf_scan_anchors(sb, &lastblock, fileset);
++ if (ret != -EAGAIN)
+ goto out;
+
+ /* No anchor found? Try VARCONV conversion of block numbers */
+ UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
++ lastblock = udf_variable_to_fixed(sbi->s_last_block);
+ /* Firstly, we try to not convert number of the last block */
+- lastblock = udf_scan_anchors(sb,
+- udf_variable_to_fixed(sbi->s_last_block),
+- fileset);
+- if (lastblock)
++ ret = udf_scan_anchors(sb, &lastblock, fileset);
++ if (ret != -EAGAIN)
+ goto out;
+
++ lastblock = sbi->s_last_block;
+ /* Secondly, we try with converted number of the last block */
+- lastblock = udf_scan_anchors(sb, sbi->s_last_block, fileset);
+- if (!lastblock) {
++ ret = udf_scan_anchors(sb, &lastblock, fileset);
++ if (ret < 0) {
+ /* VARCONV didn't help. Clear it. */
+ UDF_CLEAR_FLAG(sb, UDF_FLAG_VARCONV);
+- return 0;
+ }
+ out:
+- sbi->s_last_block = lastblock;
+- return 1;
++ if (ret == 0)
++ sbi->s_last_block = lastblock;
++ return ret;
+ }
+
+ /*
+ * Check Volume Structure Descriptor, find Anchor block and load Volume
+- * Descriptor Sequence
++ * Descriptor Sequence.
++ *
++ * Returns < 0 on error, 0 on success. -EAGAIN is special meaning anchor
++ * block was not found.
+ */
+ static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt,
+ int silent, struct kernel_lb_addr *fileset)
+ {
+ struct udf_sb_info *sbi = UDF_SB(sb);
+ loff_t nsr_off;
++ int ret;
+
+ if (!sb_set_blocksize(sb, uopt->blocksize)) {
+ if (!silent)
+ udf_warn(sb, "Bad block size\n");
+- return 0;
++ return -EINVAL;
+ }
+ sbi->s_last_block = uopt->lastblock;
+ if (!uopt->novrs) {
+@@ -1828,12 +1885,13 @@ static int udf_load_vrs(struct super_blo
+
+ /* Look for anchor block and load Volume Descriptor Sequence */
+ sbi->s_anchor = uopt->anchor;
+- if (!udf_find_anchor(sb, fileset)) {
+- if (!silent)
++ ret = udf_find_anchor(sb, fileset);
++ if (ret < 0) {
++ if (!silent && ret == -EAGAIN)
+ udf_warn(sb, "No anchor found\n");
+- return 0;
++ return ret;
+ }
+- return 1;
++ return 0;
+ }
+
+ static void udf_open_lvid(struct super_block *sb)
+@@ -1939,7 +1997,7 @@ u64 lvid_get_unique_id(struct super_bloc
+
+ static int udf_fill_super(struct super_block *sb, void *options, int silent)
+ {
+- int ret;
++ int ret = -EINVAL;
+ struct inode *inode = NULL;
+ struct udf_options uopt;
+ struct kernel_lb_addr rootdir, fileset;
+@@ -2011,7 +2069,7 @@ static int udf_fill_super(struct super_b
+ } else {
+ uopt.blocksize = bdev_logical_block_size(sb->s_bdev);
+ ret = udf_load_vrs(sb, &uopt, silent, &fileset);
+- if (!ret && uopt.blocksize != UDF_DEFAULT_BLOCKSIZE) {
++ if (ret == -EAGAIN && uopt.blocksize != UDF_DEFAULT_BLOCKSIZE) {
+ if (!silent)
+ pr_notice("Rescanning with blocksize %d\n",
+ UDF_DEFAULT_BLOCKSIZE);
+@@ -2021,8 +2079,11 @@ static int udf_fill_super(struct super_b
+ ret = udf_load_vrs(sb, &uopt, silent, &fileset);
+ }
+ }
+- if (!ret) {
+- udf_warn(sb, "No partition found (1)\n");
++ if (ret < 0) {
++ if (ret == -EAGAIN) {
++ udf_warn(sb, "No partition found (1)\n");
++ ret = -EINVAL;
++ }
+ goto error_out;
+ }
+
+@@ -2040,6 +2101,7 @@ static int udf_fill_super(struct super_b
+ udf_err(sb, "minUDFReadRev=%x (max is %x)\n",
+ le16_to_cpu(lvidiu->minUDFReadRev),
+ UDF_MAX_READ_VERSION);
++ ret = -EINVAL;
+ goto error_out;
+ } else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION)
+ sb->s_flags |= MS_RDONLY;
+@@ -2054,6 +2116,7 @@ static int udf_fill_super(struct super_b
+
+ if (!sbi->s_partitions) {
+ udf_warn(sb, "No partition found (2)\n");
++ ret = -EINVAL;
+ goto error_out;
+ }
+
+@@ -2065,6 +2128,7 @@ static int udf_fill_super(struct super_b
+
+ if (udf_find_fileset(sb, &fileset, &rootdir)) {
+ udf_warn(sb, "No fileset found\n");
++ ret = -EINVAL;
+ goto error_out;
+ }
+
+@@ -2086,6 +2150,7 @@ static int udf_fill_super(struct super_b
+ if (!inode) {
+ udf_err(sb, "Error in udf_iget, block=%d, partition=%d\n",
+ rootdir.logicalBlockNum, rootdir.partitionReferenceNum);
++ ret = -EIO;
+ goto error_out;
+ }
+
+@@ -2093,6 +2158,7 @@ static int udf_fill_super(struct super_b
+ sb->s_root = d_make_root(inode);
+ if (!sb->s_root) {
+ udf_err(sb, "Couldn't allocate root dentry\n");
++ ret = -ENOMEM;
+ goto error_out;
+ }
+ sb->s_maxbytes = MAX_LFS_FILESIZE;
+@@ -2113,7 +2179,7 @@ error_out:
+ kfree(sbi);
+ sb->s_fs_info = NULL;
+
+- return -EINVAL;
++ return ret;
+ }
+
+ void _udf_err(struct super_block *sb, const char *function,