Merge branch 'akpm' (patches from Andrew)
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 7 Nov 2015 22:32:45 +0000 (14:32 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 7 Nov 2015 22:32:45 +0000 (14:32 -0800)
Merge second patch-bomb from Andrew Morton:

 - most of the rest of MM

 - procfs

 - lib/ updates

 - printk updates

 - bitops infrastructure tweaks

 - checkpatch updates

 - nilfs2 update

 - signals

 - various other misc bits: coredump, seqfile, kexec, pidns, zlib, ipc,
   dma-debug, dma-mapping, ...

* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (102 commits)
  ipc,msg: drop dst nil validation in copy_msg
  include/linux/zutil.h: fix usage example of zlib_adler32()
  panic: release stale console lock to always get the logbuf printed out
  dma-debug: check nents in dma_sync_sg*
  dma-mapping: tidy up dma_parms default handling
  pidns: fix set/getpriority and ioprio_set/get in PRIO_USER mode
  kexec: use file name as the output message prefix
  fs, seqfile: always allow oom killer
  seq_file: reuse string_escape_str()
  fs/seq_file: use seq_* helpers in seq_hex_dump()
  coredump: change zap_threads() and zap_process() to use for_each_thread()
  coredump: ensure all coredumping tasks have SIGNAL_GROUP_COREDUMP
  signal: remove jffs2_garbage_collect_thread()->allow_signal(SIGCONT)
  signal: introduce kernel_signal_stop() to fix jffs2_garbage_collect_thread()
  signal: turn dequeue_signal_lock() into kernel_dequeue_signal()
  signals: kill block_all_signals() and unblock_all_signals()
  nilfs2: fix gcc uninitialized-variable warnings in powerpc build
  nilfs2: fix gcc unused-but-set-variable warnings
  MAINTAINERS: nilfs2: add header file for tracing
  nilfs2: add tracepoints for analyzing reading and writing metadata files
  ...

18 files changed:
1  2 
MAINTAINERS
drivers/block/drbd/drbd_bitmap.c
drivers/block/pktcdvd.c
drivers/infiniband/core/sa_query.c
drivers/mtd/mtdcore.c
drivers/nvme/host/pci.c
fs/btrfs/compression.c
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/extent_io.c
fs/btrfs/free-space-cache.c
fs/btrfs/volumes.c
fs/ext4/inode.c
fs/ext4/readpage.c
fs/ext4/super.c
fs/jffs2/wbuf.c
fs/namei.c
mm/huge_memory.c

diff --combined MAINTAINERS
index 4c5446a6a4a27d9b145e35086ab04a86b3e7d6e6,eabf3d35a49d8ff4600baf91df165417a6e3d28d..7af7f4a01f0b83224b50f3a7f52eac58cc751b3e
@@@ -2757,10 -2757,9 +2757,10 @@@ S:    Supporte
  F:    drivers/net/ethernet/cisco/enic/
  
  CISCO VIC LOW LATENCY NIC DRIVER
 -M:    Upinder Malhi <umalhi@cisco.com>
 +M:    Christian Benvenuti <benve@cisco.com>
 +M:    Dave Goodell <dgoodell@cisco.com>
  S:    Supported
 -F:    drivers/infiniband/hw/usnic
 +F:    drivers/infiniband/hw/usnic/
  
  CIRRUS LOGIC EP93XX ETHERNET DRIVER
  M:    Hartley Sweeten <hsweeten@visionengravers.com>
@@@ -3404,7 -3403,6 +3404,7 @@@ M:      Support Opensource <support.opensour
  W:    http://www.dialog-semiconductor.com/products
  S:    Supported
  F:    Documentation/hwmon/da90??
 +F:    Documentation/devicetree/bindings/sound/da[79]*.txt
  F:    drivers/gpio/gpio-da90??.c
  F:    drivers/hwmon/da90??-hwmon.c
  F:    drivers/iio/adc/da91??-*.c
@@@ -3617,7 -3615,7 +3617,7 @@@ S:      Maintaine
  F:    drivers/gpu/drm/drm_panel.c
  F:    drivers/gpu/drm/panel/
  F:    include/drm/drm_panel.h
 -F:    Documentation/devicetree/bindings/panel/
 +F:    Documentation/devicetree/bindings/display/panel/
  
  INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets)
  M:    Daniel Vetter <daniel.vetter@intel.com>
@@@ -3656,15 -3654,15 +3656,15 @@@ M:   Alison Wang <alison.wang@freescale.c
  L:    dri-devel@lists.freedesktop.org
  S:    Supported
  F:    drivers/gpu/drm/fsl-dcu/
 -F:    Documentation/devicetree/bindings/video/fsl,dcu.txt
 -F:    Documentation/devicetree/bindings/panel/nec,nl4827hc19_05b.txt
 +F:    Documentation/devicetree/bindings/display/fsl,dcu.txt
 +F:    Documentation/devicetree/bindings/display/panel/nec,nl4827hc19_05b.txt
  
  DRM DRIVERS FOR FREESCALE IMX
  M:    Philipp Zabel <p.zabel@pengutronix.de>
  L:    dri-devel@lists.freedesktop.org
  S:    Maintained
  F:    drivers/gpu/drm/imx/
 -F:    Documentation/devicetree/bindings/drm/imx/
 +F:    Documentation/devicetree/bindings/display/imx/
  
  DRM DRIVERS FOR GMA500 (Poulsbo, Moorestown and derivative chipsets)
  M:    Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
@@@ -3685,7 -3683,7 +3685,7 @@@ F:      drivers/gpu/drm/tegra
  F:    drivers/gpu/host1x/
  F:    include/linux/host1x.h
  F:    include/uapi/drm/tegra_drm.h
 -F:    Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt
 +F:    Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
  
  DRM DRIVERS FOR RENESAS
  M:    Laurent Pinchart <laurent.pinchart@ideasonboard.com>
@@@ -3702,7 -3700,7 +3702,7 @@@ M:      Mark Yao <mark.yao@rock-chips.com
  L:    dri-devel@lists.freedesktop.org
  S:    Maintained
  F:    drivers/gpu/drm/rockchip/
 -F:    Documentation/devicetree/bindings/video/rockchip*
 +F:    Documentation/devicetree/bindings/display/rockchip*
  
  DRM DRIVERS FOR STI
  M:    Benjamin Gaignard <benjamin.gaignard@linaro.org>
@@@ -3711,7 -3709,7 +3711,7 @@@ L:      dri-devel@lists.freedesktop.or
  T:    git http://git.linaro.org/people/benjamin.gaignard/kernel.git
  S:    Maintained
  F:    drivers/gpu/drm/sti
 -F:    Documentation/devicetree/bindings/gpu/st,stih4xx.txt
 +F:    Documentation/devicetree/bindings/display/st,stih4xx.txt
  
  DSBR100 USB FM RADIO DRIVER
  M:    Alexey Klimov <klimov.linux@gmail.com>
@@@ -4209,7 -4207,10 +4209,10 @@@ L:    linux-kernel@vger.kernel.or
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon.git
  S:    Maintained
  F:    drivers/extcon/
+ F:    include/linux/extcon/
+ F:    include/linux/extcon.h
  F:    Documentation/extcon/
+ F:    Documentation/devicetree/bindings/extcon/
  
  EXYNOS DP DRIVER
  M:    Jingoo Han <jingoohan1@gmail.com>
@@@ -4404,6 -4405,7 +4407,6 @@@ Q:      http://patchwork.kernel.org/project/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/plagnioj/linux-fbdev.git
  S:    Maintained
  F:    Documentation/fb/
 -F:    Documentation/devicetree/bindings/fb/
  F:    drivers/video/
  F:    include/video/
  F:    include/linux/fb.h
@@@ -6967,7 -6969,6 +6970,7 @@@ S:      Supporte
  F:    arch/metag/
  F:    Documentation/metag/
  F:    Documentation/devicetree/bindings/metag/
 +F:    Documentation/devicetree/bindings/interrupt-controller/img,*
  F:    drivers/clocksource/metag_generic.c
  F:    drivers/irqchip/irq-metag.c
  F:    drivers/irqchip/irq-metag-ext.c
@@@ -7490,6 -7491,7 +7493,7 @@@ S:      Supporte
  F:    Documentation/filesystems/nilfs2.txt
  F:    fs/nilfs2/
  F:    include/linux/nilfs2_fs.h
+ F:    include/trace/events/nilfs2.h
  
  NINJA SCSI-3 / NINJA SCSI-32Bi (16bit/CardBus) PCMCIA SCSI HOST ADAPTER DRIVER
  M:    YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
@@@ -8064,14 -8066,6 +8068,14 @@@ F:    include/linux/pci
  F:    arch/x86/pci/
  F:    arch/x86/kernel/quirks.c
  
 +PCI DRIVER FOR ALTERA PCIE IP
 +M:    Ley Foon Tan <lftan@altera.com>
 +L:    rfi@lists.rocketboards.org (moderated for non-subscribers)
 +L:    linux-pci@vger.kernel.org
 +S:    Supported
 +F:    Documentation/devicetree/bindings/pci/altera-pcie.txt
 +F:    drivers/pci/host/pcie-altera.c
 +
  PCI DRIVER FOR ARM VERSATILE PLATFORM
  M:    Rob Herring <robh@kernel.org>
  L:    linux-pci@vger.kernel.org
@@@ -8173,14 -8167,6 +8177,14 @@@ L:    linux-pci@vger.kernel.or
  S:    Maintained
  F:    drivers/pci/host/*spear*
  
 +PCI MSI DRIVER FOR ALTERA MSI IP
 +M:    Ley Foon Tan <lftan@altera.com>
 +L:    rfi@lists.rocketboards.org (moderated for non-subscribers)
 +L:    linux-pci@vger.kernel.org
 +S:    Supported
 +F:    Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
 +F:    drivers/pci/host/pcie-altera-msi.c
 +
  PCI MSI DRIVER FOR APPLIEDMICRO XGENE
  M:    Duc Dang <dhdang@apm.com>
  L:    linux-pci@vger.kernel.org
@@@ -8189,13 -8175,6 +8193,13 @@@ S:    Maintaine
  F:    Documentation/devicetree/bindings/pci/xgene-pci-msi.txt
  F:    drivers/pci/host/pci-xgene-msi.c
  
 +PCIE DRIVER FOR HISILICON
 +M:    Zhou Wang <wangzhou1@hisilicon.com>
 +L:    linux-pci@vger.kernel.org
 +S:    Maintained
 +F:    Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
 +F:    drivers/pci/host/pcie-hisi.c
 +
  PCMCIA SUBSYSTEM
  P:    Linux PCMCIA Team
  L:    linux-pcmcia@lists.infradead.org
@@@ -9635,7 -9614,7 +9639,7 @@@ SIMPLEFB FB DRIVE
  M:    Hans de Goede <hdegoede@redhat.com>
  L:    linux-fbdev@vger.kernel.org
  S:    Maintained
 -F:    Documentation/devicetree/bindings/video/simple-framebuffer.txt
 +F:    Documentation/devicetree/bindings/display/simple-framebuffer.txt
  F:    drivers/video/fbdev/simplefb.c
  F:    include/linux/platform_data/simplefb.h
  
@@@ -10266,7 -10245,6 +10270,7 @@@ L:   linux-snps-arc@lists.infraded.or
  S:    Supported
  F:    arch/arc/
  F:    Documentation/devicetree/bindings/arc/*
 +F:    Documentation/devicetree/bindings/interrupt-controller/snps,arc*
  F:    drivers/tty/serial/arc_uart.c
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git
  
@@@ -11272,12 -11250,6 +11276,12 @@@ S: Maintaine
  F:    Documentation/fb/uvesafb.txt
  F:    drivers/video/fbdev/uvesafb.*
  
 +VF610 NAND DRIVER
 +M:    Stefan Agner <stefan@agner.ch>
 +L:    linux-mtd@lists.infradead.org
 +S:    Supported
 +F:    drivers/mtd/nand/vf610_nfc.c
 +
  VFAT/FAT/MSDOS FILESYSTEM
  M:    OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
  S:    Maintained
@@@ -11308,12 -11280,6 +11312,12 @@@ S: Maintaine
  F:    drivers/media/v4l2-core/videobuf2-*
  F:    include/media/videobuf2-*
  
 +VIRTUAL SERIO DEVICE DRIVER
 +M:    Stephen Chandler Paul <thatslyude@gmail.com>
 +S:    Maintained
 +F:    drivers/input/serio/userio.c
 +F:    include/uapi/linux/userio.h
 +
  VIRTIO CONSOLE DRIVER
  M:    Amit Shah <amit.shah@redhat.com>
  L:    virtualization@lists.linux-foundation.org
index d3d73d114a4615e124e89bd6d4196ba5be35f415,3dc53a16ed3aaf14dfd30311c16e0dc14f6623a0..9462d27528507d693d8e4efe0e6464597ab1768b
@@@ -29,7 -29,7 +29,7 @@@
  #include <linux/string.h>
  #include <linux/drbd.h>
  #include <linux/slab.h>
 -#include <asm/kmap_types.h>
 +#include <linux/highmem.h>
  
  #include "drbd_int.h"
  
@@@ -1007,7 -1007,7 +1007,7 @@@ static void bm_page_io_async(struct drb
        bm_set_page_unchanged(b->bm_pages[page_nr]);
  
        if (ctx->flags & BM_AIO_COPY_PAGES) {
-               page = mempool_alloc(drbd_md_io_page_pool, __GFP_HIGHMEM|__GFP_WAIT);
+               page = mempool_alloc(drbd_md_io_page_pool, __GFP_HIGHMEM|__GFP_RECLAIM);
                copy_highpage(page, b->bm_pages[page_nr]);
                bm_store_page_idx(page, page_nr);
        } else
diff --combined drivers/block/pktcdvd.c
index cd813f9110bfc99314604fcf0ae93e58242ac413,5959c2981cc7d18efbbec56615db1d29b2698064..2f477d45d6cfa42d586080db8c293d41406055ae
@@@ -704,14 -704,14 +704,14 @@@ static int pkt_generic_packet(struct pk
        int ret = 0;
  
        rq = blk_get_request(q, (cgc->data_direction == CGC_DATA_WRITE) ?
-                            WRITE : READ, __GFP_WAIT);
+                            WRITE : READ, __GFP_RECLAIM);
        if (IS_ERR(rq))
                return PTR_ERR(rq);
        blk_rq_set_block_pc(rq);
  
        if (cgc->buflen) {
                ret = blk_rq_map_kern(q, rq, cgc->buffer, cgc->buflen,
-                                     __GFP_WAIT);
+                                     __GFP_RECLAIM);
                if (ret)
                        goto out;
        }
@@@ -2803,7 -2803,8 +2803,7 @@@ out_new_dev
  out_mem2:
        put_disk(disk);
  out_mem:
 -      if (pd->rb_pool)
 -              mempool_destroy(pd->rb_pool);
 +      mempool_destroy(pd->rb_pool);
        kfree(pd);
  out_mutex:
        mutex_unlock(&ctl_mutex);
index dcdaa79e3f0faa0dcd9288a0f14cf9e4e996210c,59ab264c99c4f4a87c92cf654f14cc0806539cd6..2aba774f835b9caca8e9e1645d1efd6cf6f08bf9
@@@ -1007,29 -1007,26 +1007,29 @@@ int ib_init_ah_from_path(struct ib_devi
        force_grh = rdma_cap_eth_ah(device, port_num);
  
        if (rec->hop_limit > 1 || force_grh) {
 +              struct net_device *ndev = ib_get_ndev_from_path(rec);
 +
                ah_attr->ah_flags = IB_AH_GRH;
                ah_attr->grh.dgid = rec->dgid;
  
 -              ret = ib_find_cached_gid(device, &rec->sgid, &port_num,
 +              ret = ib_find_cached_gid(device, &rec->sgid, ndev, &port_num,
                                         &gid_index);
 -              if (ret)
 +              if (ret) {
 +                      if (ndev)
 +                              dev_put(ndev);
                        return ret;
 +              }
  
                ah_attr->grh.sgid_index    = gid_index;
                ah_attr->grh.flow_label    = be32_to_cpu(rec->flow_label);
                ah_attr->grh.hop_limit     = rec->hop_limit;
                ah_attr->grh.traffic_class = rec->traffic_class;
 +              if (ndev)
 +                      dev_put(ndev);
        }
        if (force_grh) {
                memcpy(ah_attr->dmac, rec->dmac, ETH_ALEN);
 -              ah_attr->vlan_id = rec->vlan_id;
 -      } else {
 -              ah_attr->vlan_id = 0xffff;
        }
 -
        return 0;
  }
  EXPORT_SYMBOL(ib_init_ah_from_path);
@@@ -1086,7 -1083,7 +1086,7 @@@ static void init_mad(struct ib_sa_mad *
  
  static int send_mad(struct ib_sa_query *query, int timeout_ms, gfp_t gfp_mask)
  {
-       bool preload = !!(gfp_mask & __GFP_WAIT);
+       bool preload = gfpflags_allow_blocking(gfp_mask);
        unsigned long flags;
        int ret, id;
  
@@@ -1153,9 -1150,9 +1153,9 @@@ static void ib_sa_path_rec_callback(str
  
                ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table),
                          mad->data, &rec);
 -              rec.vlan_id = 0xffff;
 +              rec.net = NULL;
 +              rec.ifindex = 0;
                memset(rec.dmac, 0, ETH_ALEN);
 -              memset(rec.smac, 0, ETH_ALEN);
                query->callback(status, &rec, query->context);
        } else
                query->callback(status, NULL, query->context);
diff --combined drivers/mtd/mtdcore.c
index a91cee90aef9e8d5793cc064d501324ea2c5e45d,2dfb291a47c6da6e64caa1788f1329305658b9c5..95c13b2ffa799e59f453e8a95813171cd56a13fc
@@@ -387,14 -387,6 +387,14 @@@ int add_mtd_device(struct mtd_info *mtd
        struct mtd_notifier *not;
        int i, error;
  
 +      /*
 +       * May occur, for instance, on buggy drivers which call
 +       * mtd_device_parse_register() multiple times on the same master MTD,
 +       * especially with CONFIG_MTD_PARTITIONED_MASTER=y.
 +       */
 +      if (WARN_ONCE(mtd->backing_dev_info, "MTD already registered\n"))
 +              return -EEXIST;
 +
        mtd->backing_dev_info = &mtd_bdi;
  
        BUG_ON(mtd->writesize == 0);
        mtd->erasesize_mask = (1 << mtd->erasesize_shift) - 1;
        mtd->writesize_mask = (1 << mtd->writesize_shift) - 1;
  
 +      if (mtd->dev.parent) {
 +              if (!mtd->owner && mtd->dev.parent->driver)
 +                      mtd->owner = mtd->dev.parent->driver->owner;
 +              if (!mtd->name)
 +                      mtd->name = dev_name(mtd->dev.parent);
 +      } else {
 +              pr_debug("mtd device won't show a device symlink in sysfs\n");
 +      }
 +
        /* Some chips always power up locked. Unlock them now */
        if ((mtd->flags & MTD_WRITEABLE) && (mtd->flags & MTD_POWERUP_LOCK)) {
                error = mtd_unlock(mtd, 0, mtd->size);
        }
  
        /* Caller should have set dev.parent to match the
 -       * physical device.
 +       * physical device, if appropriate.
         */
        mtd->dev.type = &mtd_devtype;
        mtd->dev.class = &mtd_class;
@@@ -596,17 -579,9 +596,17 @@@ int mtd_device_parse_register(struct mt
                else
                        ret = nr_parts;
        }
 +      /* Didn't come up with either parsed OR fallback partitions */
 +      if (ret < 0) {
 +              pr_info("mtd: failed to find partitions; one or more parsers reports errors (%d)\n",
 +                      ret);
 +              /* Don't abort on errors; we can still use unpartitioned MTD */
 +              ret = 0;
 +      }
  
 -      if (ret >= 0)
 -              ret = mtd_add_device_partitions(mtd, real_parts, ret);
 +      ret = mtd_add_device_partitions(mtd, real_parts, ret);
 +      if (ret)
 +              goto out;
  
        /*
         * FIXME: some drivers unfortunately call this function more than once.
         * does cause problems with parse_mtd_partitions() above (e.g.,
         * cmdlineparts will register partitions more than once).
         */
 +      WARN_ONCE(mtd->_reboot && mtd->reboot_notifier.notifier_call,
 +                "MTD already registered\n");
        if (mtd->_reboot && !mtd->reboot_notifier.notifier_call) {
                mtd->reboot_notifier.notifier_call = mtd_reboot_notifier;
                register_reboot_notifier(&mtd->reboot_notifier);
        }
  
 +out:
        kfree(real_parts);
        return ret;
  }
@@@ -1216,8 -1188,7 +1216,7 @@@ EXPORT_SYMBOL_GPL(mtd_writev)
   */
  void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size)
  {
-       gfp_t flags = __GFP_NOWARN | __GFP_WAIT |
-                      __GFP_NORETRY | __GFP_NO_KSWAPD;
+       gfp_t flags = __GFP_NOWARN | __GFP_DIRECT_RECLAIM | __GFP_NORETRY;
        size_t min_alloc = max_t(size_t, mtd->writesize, PAGE_SIZE);
        void *kbuf;
  
@@@ -1329,7 -1300,6 +1328,7 @@@ static void __exit cleanup_mtd(void
                remove_proc_entry("mtd", NULL);
        class_unregister(&mtd_class);
        bdi_destroy(&mtd_bdi);
 +      idr_destroy(&mtd_idr);
  }
  
  module_init(init_mtd);
diff --combined drivers/nvme/host/pci.c
index 9f4fe3a5f41e459624ee245874c9b2d50bad2404,6c195554d94ac9d690c5ffadb8fa47badc123816..97b6640a3745922fe030bbf04525a4b6de6566d6
@@@ -41,7 -41,7 +41,7 @@@
  #include <linux/types.h>
  #include <linux/pr.h>
  #include <scsi/sg.h>
 -#include <asm-generic/io-64-nonatomic-lo-hi.h>
 +#include <linux/io-64-nonatomic-lo-hi.h>
  #include <asm/unaligned.h>
  
  #include <uapi/linux/nvme_ioctl.h>
@@@ -1025,11 -1025,13 +1025,13 @@@ int __nvme_submit_sync_cmd(struct reque
        req->special = (void *)0;
  
        if (buffer && bufflen) {
-               ret = blk_rq_map_kern(q, req, buffer, bufflen, __GFP_WAIT);
+               ret = blk_rq_map_kern(q, req, buffer, bufflen,
+                                     __GFP_DIRECT_RECLAIM);
                if (ret)
                        goto out;
        } else if (ubuffer && bufflen) {
-               ret = blk_rq_map_user(q, req, NULL, ubuffer, bufflen, __GFP_WAIT);
+               ret = blk_rq_map_user(q, req, NULL, ubuffer, bufflen,
+                                     __GFP_DIRECT_RECLAIM);
                if (ret)
                        goto out;
                bio = req->bio;
diff --combined fs/btrfs/compression.c
index 97b049ad0594cc3a3b79f1b8222def5e132d73ae,36dfeff2c1f443aade91be4ccbce56bec9317008..c473c42d7d6c4d559dbe1587491cd2fb93804145
@@@ -482,13 -482,12 +482,12 @@@ static noinline int add_ra_bio_pages(st
                        goto next;
                }
  
-               page = __page_cache_alloc(mapping_gfp_mask(mapping) &
-                                                               ~__GFP_FS);
+               page = __page_cache_alloc(mapping_gfp_constraint(mapping,
+                                                                ~__GFP_FS));
                if (!page)
                        break;
  
-               if (add_to_page_cache_lru(page, mapping, pg_index,
-                                                               GFP_NOFS)) {
+               if (add_to_page_cache_lru(page, mapping, pg_index, GFP_NOFS)) {
                        page_cache_release(page);
                        goto next;
                }
@@@ -745,13 -744,11 +744,13 @@@ out
        return ret;
  }
  
 -static struct list_head comp_idle_workspace[BTRFS_COMPRESS_TYPES];
 -static spinlock_t comp_workspace_lock[BTRFS_COMPRESS_TYPES];
 -static int comp_num_workspace[BTRFS_COMPRESS_TYPES];
 -static atomic_t comp_alloc_workspace[BTRFS_COMPRESS_TYPES];
 -static wait_queue_head_t comp_workspace_wait[BTRFS_COMPRESS_TYPES];
 +static struct {
 +      struct list_head idle_ws;
 +      spinlock_t ws_lock;
 +      int num_ws;
 +      atomic_t alloc_ws;
 +      wait_queue_head_t ws_wait;
 +} btrfs_comp_ws[BTRFS_COMPRESS_TYPES];
  
  static const struct btrfs_compress_op * const btrfs_compress_op[] = {
        &btrfs_zlib_compress,
@@@ -763,10 -760,10 +762,10 @@@ void __init btrfs_init_compress(void
        int i;
  
        for (i = 0; i < BTRFS_COMPRESS_TYPES; i++) {
 -              INIT_LIST_HEAD(&comp_idle_workspace[i]);
 -              spin_lock_init(&comp_workspace_lock[i]);
 -              atomic_set(&comp_alloc_workspace[i], 0);
 -              init_waitqueue_head(&comp_workspace_wait[i]);
 +              INIT_LIST_HEAD(&btrfs_comp_ws[i].idle_ws);
 +              spin_lock_init(&btrfs_comp_ws[i].ws_lock);
 +              atomic_set(&btrfs_comp_ws[i].alloc_ws, 0);
 +              init_waitqueue_head(&btrfs_comp_ws[i].ws_wait);
        }
  }
  
@@@ -780,38 -777,38 +779,38 @@@ static struct list_head *find_workspace
        int cpus = num_online_cpus();
        int idx = type - 1;
  
 -      struct list_head *idle_workspace        = &comp_idle_workspace[idx];
 -      spinlock_t *workspace_lock              = &comp_workspace_lock[idx];
 -      atomic_t *alloc_workspace               = &comp_alloc_workspace[idx];
 -      wait_queue_head_t *workspace_wait       = &comp_workspace_wait[idx];
 -      int *num_workspace                      = &comp_num_workspace[idx];
 +      struct list_head *idle_ws       = &btrfs_comp_ws[idx].idle_ws;
 +      spinlock_t *ws_lock             = &btrfs_comp_ws[idx].ws_lock;
 +      atomic_t *alloc_ws              = &btrfs_comp_ws[idx].alloc_ws;
 +      wait_queue_head_t *ws_wait      = &btrfs_comp_ws[idx].ws_wait;
 +      int *num_ws                     = &btrfs_comp_ws[idx].num_ws;
  again:
 -      spin_lock(workspace_lock);
 -      if (!list_empty(idle_workspace)) {
 -              workspace = idle_workspace->next;
 +      spin_lock(ws_lock);
 +      if (!list_empty(idle_ws)) {
 +              workspace = idle_ws->next;
                list_del(workspace);
 -              (*num_workspace)--;
 -              spin_unlock(workspace_lock);
 +              (*num_ws)--;
 +              spin_unlock(ws_lock);
                return workspace;
  
        }
 -      if (atomic_read(alloc_workspace) > cpus) {
 +      if (atomic_read(alloc_ws) > cpus) {
                DEFINE_WAIT(wait);
  
 -              spin_unlock(workspace_lock);
 -              prepare_to_wait(workspace_wait, &wait, TASK_UNINTERRUPTIBLE);
 -              if (atomic_read(alloc_workspace) > cpus && !*num_workspace)
 +              spin_unlock(ws_lock);
 +              prepare_to_wait(ws_wait, &wait, TASK_UNINTERRUPTIBLE);
 +              if (atomic_read(alloc_ws) > cpus && !*num_ws)
                        schedule();
 -              finish_wait(workspace_wait, &wait);
 +              finish_wait(ws_wait, &wait);
                goto again;
        }
 -      atomic_inc(alloc_workspace);
 -      spin_unlock(workspace_lock);
 +      atomic_inc(alloc_ws);
 +      spin_unlock(ws_lock);
  
        workspace = btrfs_compress_op[idx]->alloc_workspace();
        if (IS_ERR(workspace)) {
 -              atomic_dec(alloc_workspace);
 -              wake_up(workspace_wait);
 +              atomic_dec(alloc_ws);
 +              wake_up(ws_wait);
        }
        return workspace;
  }
  static void free_workspace(int type, struct list_head *workspace)
  {
        int idx = type - 1;
 -      struct list_head *idle_workspace        = &comp_idle_workspace[idx];
 -      spinlock_t *workspace_lock              = &comp_workspace_lock[idx];
 -      atomic_t *alloc_workspace               = &comp_alloc_workspace[idx];
 -      wait_queue_head_t *workspace_wait       = &comp_workspace_wait[idx];
 -      int *num_workspace                      = &comp_num_workspace[idx];
 -
 -      spin_lock(workspace_lock);
 -      if (*num_workspace < num_online_cpus()) {
 -              list_add(workspace, idle_workspace);
 -              (*num_workspace)++;
 -              spin_unlock(workspace_lock);
 +      struct list_head *idle_ws       = &btrfs_comp_ws[idx].idle_ws;
 +      spinlock_t *ws_lock             = &btrfs_comp_ws[idx].ws_lock;
 +      atomic_t *alloc_ws              = &btrfs_comp_ws[idx].alloc_ws;
 +      wait_queue_head_t *ws_wait      = &btrfs_comp_ws[idx].ws_wait;
 +      int *num_ws                     = &btrfs_comp_ws[idx].num_ws;
 +
 +      spin_lock(ws_lock);
 +      if (*num_ws < num_online_cpus()) {
 +              list_add(workspace, idle_ws);
 +              (*num_ws)++;
 +              spin_unlock(ws_lock);
                goto wake;
        }
 -      spin_unlock(workspace_lock);
 +      spin_unlock(ws_lock);
  
        btrfs_compress_op[idx]->free_workspace(workspace);
 -      atomic_dec(alloc_workspace);
 +      atomic_dec(alloc_ws);
  wake:
 +      /*
 +       * Make sure counter is updated before we wake up waiters.
 +       */
        smp_mb();
 -      if (waitqueue_active(workspace_wait))
 -              wake_up(workspace_wait);
 +      if (waitqueue_active(ws_wait))
 +              wake_up(ws_wait);
  }
  
  /*
@@@ -858,11 -852,11 +857,11 @@@ static void free_workspaces(void
        int i;
  
        for (i = 0; i < BTRFS_COMPRESS_TYPES; i++) {
 -              while (!list_empty(&comp_idle_workspace[i])) {
 -                      workspace = comp_idle_workspace[i].next;
 +              while (!list_empty(&btrfs_comp_ws[i].idle_ws)) {
 +                      workspace = btrfs_comp_ws[i].idle_ws.next;
                        list_del(workspace);
                        btrfs_compress_op[i]->free_workspace(workspace);
 -                      atomic_dec(&comp_alloc_workspace[i]);
 +                      atomic_dec(&btrfs_comp_ws[i].alloc_ws);
                }
        }
  }
diff --combined fs/btrfs/ctree.h
index a2e73f6053a853698bef78b8d5ed776a695933c5,eb90f0f1a12428827ad84a52fcb32f44ee3d289d..8c58191249cc14c33c376bb0c8c0a469cb95b894
@@@ -823,18 -823,8 +823,18 @@@ struct btrfs_disk_balance_args 
         */
        __le64 profiles;
  
 -      /* usage filter */
 -      __le64 usage;
 +      /*
 +       * usage filter
 +       * BTRFS_BALANCE_ARGS_USAGE with a single value means '0..N'
 +       * BTRFS_BALANCE_ARGS_USAGE_RANGE - range syntax, min..max
 +       */
 +      union {
 +              __le64 usage;
 +              struct {
 +                      __le32 usage_min;
 +                      __le32 usage_max;
 +              };
 +      };
  
        /* devid filter */
        __le64 devid;
        /* BTRFS_BALANCE_ARGS_* */
        __le64 flags;
  
 -      /* BTRFS_BALANCE_ARGS_LIMIT value */
 -      __le64 limit;
 +      /*
 +       * BTRFS_BALANCE_ARGS_LIMIT with value 'limit'
 +       * BTRFS_BALANCE_ARGS_LIMIT_RANGE - the extend version can use minimum
 +       * and maximum
 +       */
 +      union {
 +              __le64 limit;
 +              struct {
 +                      __le32 limit_min;
 +                      __le32 limit_max;
 +              };
 +      };
  
 -      __le64 unused[7];
 +      /*
 +       * Process chunks that cross stripes_min..stripes_max devices,
 +       * BTRFS_BALANCE_ARGS_STRIPES_RANGE
 +       */
 +      __le32 stripes_min;
 +      __le32 stripes_max;
 +
 +      __le64 unused[6];
  } __attribute__ ((__packed__));
  
  /*
@@@ -1181,10 -1154,6 +1181,10 @@@ struct btrfs_space_info 
                                   delalloc/allocations */
        u64 bytes_readonly;     /* total bytes that are read only */
  
 +      u64 max_extent_size;    /* This will hold the maximum extent size of
 +                                 the space info if we had an ENOSPC in the
 +                                 allocator. */
 +
        unsigned int full:1;    /* indicates that we cannot allocate any more
                                   chunks for this space */
        unsigned int chunk_alloc:1;     /* set if we are allocating a chunk */
@@@ -1259,9 -1228,6 +1259,9 @@@ struct btrfs_free_cluster 
        /* first extent starting offset */
        u64 window_start;
  
 +      /* We did a full search and couldn't create a cluster */
 +      bool fragmented;
 +
        struct btrfs_block_group_cache *block_group;
        /*
         * when a cluster is allocated from a block group, we put the
@@@ -1977,9 -1943,6 +1977,9 @@@ struct btrfs_root 
        int send_in_progress;
        struct btrfs_subvolume_writers *subv_writers;
        atomic_t will_be_snapshoted;
 +
 +      /* For qgroup metadata space reserve */
 +      atomic_t qgroup_meta_rsv;
  };
  
  struct btrfs_ioctl_defrag_range_args {
  #define BTRFS_MOUNT_CHECK_INTEGRITY_INCLUDING_EXTENT_DATA (1 << 21)
  #define BTRFS_MOUNT_PANIC_ON_FATAL_ERROR      (1 << 22)
  #define BTRFS_MOUNT_RESCAN_UUID_TREE  (1 << 23)
 +#define BTRFS_MOUNT_FRAGMENT_DATA     (1 << 24)
 +#define BTRFS_MOUNT_FRAGMENT_METADATA (1 << 25)
  
  #define BTRFS_DEFAULT_COMMIT_INTERVAL (30)
  #define BTRFS_DEFAULT_MAX_INLINE      (8192)
        btrfs_clear_opt(root->fs_info->mount_opt, opt);                 \
  }
  
 +#ifdef CONFIG_BTRFS_DEBUG
 +static inline int
 +btrfs_should_fragment_free_space(struct btrfs_root *root,
 +                               struct btrfs_block_group_cache *block_group)
 +{
 +      return (btrfs_test_opt(root, FRAGMENT_METADATA) &&
 +              block_group->flags & BTRFS_BLOCK_GROUP_METADATA) ||
 +             (btrfs_test_opt(root, FRAGMENT_DATA) &&
 +              block_group->flags &  BTRFS_BLOCK_GROUP_DATA);
 +}
 +#endif
 +
  /*
   * Requests for changes that need to be done during transaction commit.
   *
@@@ -3367,7 -3316,7 +3367,7 @@@ static inline bool btrfs_mixed_space_in
  
  static inline gfp_t btrfs_alloc_write_mask(struct address_space *mapping)
  {
-       return mapping_gfp_mask(mapping) & ~__GFP_FS;
+       return mapping_gfp_constraint(mapping, ~__GFP_FS);
  }
  
  /* extent-tree.c */
@@@ -3430,8 -3379,7 +3430,8 @@@ void btrfs_free_tree_block(struct btrfs
  int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
                                     struct btrfs_root *root,
                                     u64 root_objectid, u64 owner,
 -                                   u64 offset, struct btrfs_key *ins);
 +                                   u64 offset, u64 ram_bytes,
 +                                   struct btrfs_key *ins);
  int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
                                   struct btrfs_root *root,
                                   u64 root_objectid, u64 owner, u64 offset,
@@@ -3450,7 -3398,7 +3450,7 @@@ int btrfs_set_disk_extent_flags(struct 
  int btrfs_free_extent(struct btrfs_trans_handle *trans,
                      struct btrfs_root *root,
                      u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid,
 -                    u64 owner, u64 offset, int no_quota);
 +                    u64 owner, u64 offset);
  
  int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len,
                               int delalloc);
@@@ -3463,7 -3411,7 +3463,7 @@@ int btrfs_finish_extent_commit(struct b
  int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
                         struct btrfs_root *root,
                         u64 bytenr, u64 num_bytes, u64 parent,
 -                       u64 root_objectid, u64 owner, u64 offset, int no_quota);
 +                       u64 root_objectid, u64 owner, u64 offset);
  
  int btrfs_start_dirty_block_groups(struct btrfs_trans_handle *trans,
                                   struct btrfs_root *root);
@@@ -3501,11 -3449,8 +3501,11 @@@ enum btrfs_reserve_flush_enum 
        BTRFS_RESERVE_FLUSH_ALL,
  };
  
 -int btrfs_check_data_free_space(struct inode *inode, u64 bytes, u64 write_bytes);
 -void btrfs_free_reserved_data_space(struct inode *inode, u64 bytes);
 +int btrfs_check_data_free_space(struct inode *inode, u64 start, u64 len);
 +int btrfs_alloc_data_chunk_ondemand(struct inode *inode, u64 bytes);
 +void btrfs_free_reserved_data_space(struct inode *inode, u64 start, u64 len);
 +void btrfs_free_reserved_data_space_noquota(struct inode *inode, u64 start,
 +                                          u64 len);
  void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans,
                                struct btrfs_root *root);
  void btrfs_trans_release_chunk_metadata(struct btrfs_trans_handle *trans);
@@@ -3521,8 -3466,8 +3521,8 @@@ void btrfs_subvolume_release_metadata(s
                                      u64 qgroup_reserved);
  int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes);
  void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes);
 -int btrfs_delalloc_reserve_space(struct inode *inode, u64 num_bytes);
 -void btrfs_delalloc_release_space(struct inode *inode, u64 num_bytes);
 +int btrfs_delalloc_reserve_space(struct inode *inode, u64 start, u64 len);
 +void btrfs_delalloc_release_space(struct inode *inode, u64 start, u64 len);
  void btrfs_init_block_rsv(struct btrfs_block_rsv *rsv, unsigned short type);
  struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root,
                                              unsigned short type);
@@@ -4059,8 -4004,8 +4059,8 @@@ int btrfs_defrag_leaves(struct btrfs_tr
  /* sysfs.c */
  int btrfs_init_sysfs(void);
  void btrfs_exit_sysfs(void);
 -int btrfs_sysfs_add_one(struct btrfs_fs_info *fs_info);
 -void btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info);
 +int btrfs_sysfs_add_mounted(struct btrfs_fs_info *fs_info);
 +void btrfs_sysfs_remove_mounted(struct btrfs_fs_info *fs_info);
  
  /* xattr.c */
  ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
@@@ -4094,102 -4039,14 +4094,102 @@@ void btrfs_printk(const struct btrfs_fs
  #define btrfs_info(fs_info, fmt, args...) \
        btrfs_printk(fs_info, KERN_INFO fmt, ##args)
  
 +/*
 + * Wrappers that use printk_in_rcu
 + */
 +#define btrfs_emerg_in_rcu(fs_info, fmt, args...) \
 +      btrfs_printk_in_rcu(fs_info, KERN_EMERG fmt, ##args)
 +#define btrfs_alert_in_rcu(fs_info, fmt, args...) \
 +      btrfs_printk_in_rcu(fs_info, KERN_ALERT fmt, ##args)
 +#define btrfs_crit_in_rcu(fs_info, fmt, args...) \
 +      btrfs_printk_in_rcu(fs_info, KERN_CRIT fmt, ##args)
 +#define btrfs_err_in_rcu(fs_info, fmt, args...) \
 +      btrfs_printk_in_rcu(fs_info, KERN_ERR fmt, ##args)
 +#define btrfs_warn_in_rcu(fs_info, fmt, args...) \
 +      btrfs_printk_in_rcu(fs_info, KERN_WARNING fmt, ##args)
 +#define btrfs_notice_in_rcu(fs_info, fmt, args...) \
 +      btrfs_printk_in_rcu(fs_info, KERN_NOTICE fmt, ##args)
 +#define btrfs_info_in_rcu(fs_info, fmt, args...) \
 +      btrfs_printk_in_rcu(fs_info, KERN_INFO fmt, ##args)
 +
 +/*
 + * Wrappers that use a ratelimited printk_in_rcu
 + */
 +#define btrfs_emerg_rl_in_rcu(fs_info, fmt, args...) \
 +      btrfs_printk_rl_in_rcu(fs_info, KERN_EMERG fmt, ##args)
 +#define btrfs_alert_rl_in_rcu(fs_info, fmt, args...) \
 +      btrfs_printk_rl_in_rcu(fs_info, KERN_ALERT fmt, ##args)
 +#define btrfs_crit_rl_in_rcu(fs_info, fmt, args...) \
 +      btrfs_printk_rl_in_rcu(fs_info, KERN_CRIT fmt, ##args)
 +#define btrfs_err_rl_in_rcu(fs_info, fmt, args...) \
 +      btrfs_printk_rl_in_rcu(fs_info, KERN_ERR fmt, ##args)
 +#define btrfs_warn_rl_in_rcu(fs_info, fmt, args...) \
 +      btrfs_printk_rl_in_rcu(fs_info, KERN_WARNING fmt, ##args)
 +#define btrfs_notice_rl_in_rcu(fs_info, fmt, args...) \
 +      btrfs_printk_rl_in_rcu(fs_info, KERN_NOTICE fmt, ##args)
 +#define btrfs_info_rl_in_rcu(fs_info, fmt, args...) \
 +      btrfs_printk_rl_in_rcu(fs_info, KERN_INFO fmt, ##args)
 +
 +/*
 + * Wrappers that use a ratelimited printk
 + */
 +#define btrfs_emerg_rl(fs_info, fmt, args...) \
 +      btrfs_printk_ratelimited(fs_info, KERN_EMERG fmt, ##args)
 +#define btrfs_alert_rl(fs_info, fmt, args...) \
 +      btrfs_printk_ratelimited(fs_info, KERN_ALERT fmt, ##args)
 +#define btrfs_crit_rl(fs_info, fmt, args...) \
 +      btrfs_printk_ratelimited(fs_info, KERN_CRIT fmt, ##args)
 +#define btrfs_err_rl(fs_info, fmt, args...) \
 +      btrfs_printk_ratelimited(fs_info, KERN_ERR fmt, ##args)
 +#define btrfs_warn_rl(fs_info, fmt, args...) \
 +      btrfs_printk_ratelimited(fs_info, KERN_WARNING fmt, ##args)
 +#define btrfs_notice_rl(fs_info, fmt, args...) \
 +      btrfs_printk_ratelimited(fs_info, KERN_NOTICE fmt, ##args)
 +#define btrfs_info_rl(fs_info, fmt, args...) \
 +      btrfs_printk_ratelimited(fs_info, KERN_INFO fmt, ##args)
  #ifdef DEBUG
  #define btrfs_debug(fs_info, fmt, args...) \
        btrfs_printk(fs_info, KERN_DEBUG fmt, ##args)
 +#define btrfs_debug_in_rcu(fs_info, fmt, args...) \
 +      btrfs_printk_in_rcu(fs_info, KERN_DEBUG fmt, ##args)
 +#define btrfs_debug_rl_in_rcu(fs_info, fmt, args...) \
 +      btrfs_printk_rl_in_rcu(fs_info, KERN_DEBUG fmt, ##args)
 +#define btrfs_debug_rl(fs_info, fmt, args...) \
 +      btrfs_printk_ratelimited(fs_info, KERN_DEBUG fmt, ##args)
  #else
  #define btrfs_debug(fs_info, fmt, args...) \
      no_printk(KERN_DEBUG fmt, ##args)
 +#define btrfs_debug_in_rcu(fs_info, fmt, args...) \
 +      no_printk(KERN_DEBUG fmt, ##args)
 +#define btrfs_debug_rl_in_rcu(fs_info, fmt, args...) \
 +      no_printk(KERN_DEBUG fmt, ##args)
 +#define btrfs_debug_rl(fs_info, fmt, args...) \
 +      no_printk(KERN_DEBUG fmt, ##args)
  #endif
  
 +#define btrfs_printk_in_rcu(fs_info, fmt, args...)    \
 +do {                                                  \
 +      rcu_read_lock();                                \
 +      btrfs_printk(fs_info, fmt, ##args);             \
 +      rcu_read_unlock();                              \
 +} while (0)
 +
 +#define btrfs_printk_ratelimited(fs_info, fmt, args...)               \
 +do {                                                          \
 +      static DEFINE_RATELIMIT_STATE(_rs,                      \
 +              DEFAULT_RATELIMIT_INTERVAL,                     \
 +              DEFAULT_RATELIMIT_BURST);                       \
 +      if (__ratelimit(&_rs))                                  \
 +              btrfs_printk(fs_info, fmt, ##args);             \
 +} while (0)
 +
 +#define btrfs_printk_rl_in_rcu(fs_info, fmt, args...)         \
 +do {                                                          \
 +      rcu_read_lock();                                        \
 +      btrfs_printk_ratelimited(fs_info, fmt, ##args);         \
 +      rcu_read_unlock();                                      \
 +} while (0)
 +
  #ifdef CONFIG_BTRFS_ASSERT
  
  __cold
@@@ -4270,7 -4127,14 +4270,7 @@@ do {                                                           
                                  __LINE__, (errno));           \
  } while (0)
  
 -#define btrfs_std_error(fs_info, errno)                               \
 -do {                                                          \
 -      if ((errno))                                            \
 -              __btrfs_std_error((fs_info), __func__,          \
 -                                 __LINE__, (errno), NULL);    \
 -} while (0)
 -
 -#define btrfs_error(fs_info, errno, fmt, args...)             \
 +#define btrfs_std_error(fs_info, errno, fmt, args...)         \
  do {                                                          \
        __btrfs_std_error((fs_info), __func__, __LINE__,        \
                          (errno), fmt, ##args);                \
diff --combined fs/btrfs/disk-io.c
index 2d4667594681133ba4e4c4c80ec583ce212e3787,c339d561e59654935378fb8c23593f418aee2c8f..640598c0d0e7585ff125b1a63ed9e74c2c42eaed
@@@ -319,9 -319,9 +319,9 @@@ static int csum_tree_block(struct btrfs
                        memcpy(&found, result, csum_size);
  
                        read_extent_buffer(buf, &val, 0, csum_size);
 -                      printk_ratelimited(KERN_WARNING
 -                              "BTRFS: %s checksum verify failed on %llu wanted %X found %X "
 -                              "level %d\n",
 +                      btrfs_warn_rl(fs_info,
 +                              "%s checksum verify failed on %llu wanted %X found %X "
 +                              "level %d",
                                fs_info->sb->s_id, buf->start,
                                val, found, btrfs_header_level(buf));
                        if (result != (char *)&inline_result)
@@@ -368,9 -368,9 +368,9 @@@ static int verify_parent_transid(struc
                ret = 0;
                goto out;
        }
 -      printk_ratelimited(KERN_ERR
 -          "BTRFS (device %s): parent transid verify failed on %llu wanted %llu found %llu\n",
 -                      eb->fs_info->sb->s_id, eb->start,
 +      btrfs_err_rl(eb->fs_info,
 +              "parent transid verify failed on %llu wanted %llu found %llu",
 +                      eb->start,
                        parent_transid, btrfs_header_generation(eb));
        ret = 1;
  
@@@ -629,14 -629,15 +629,14 @@@ static int btree_readpage_end_io_hook(s
  
        found_start = btrfs_header_bytenr(eb);
        if (found_start != eb->start) {
 -              printk_ratelimited(KERN_ERR "BTRFS (device %s): bad tree block start "
 -                             "%llu %llu\n",
 -                             eb->fs_info->sb->s_id, found_start, eb->start);
 +              btrfs_err_rl(eb->fs_info, "bad tree block start %llu %llu",
 +                             found_start, eb->start);
                ret = -EIO;
                goto err;
        }
        if (check_tree_block_fsid(root->fs_info, eb)) {
 -              printk_ratelimited(KERN_ERR "BTRFS (device %s): bad fsid on block %llu\n",
 -                             eb->fs_info->sb->s_id, eb->start);
 +              btrfs_err_rl(eb->fs_info, "bad fsid on block %llu",
 +                             eb->start);
                ret = -EIO;
                goto err;
        }
@@@ -801,9 -802,6 +801,9 @@@ static void run_one_async_done(struct b
        limit = btrfs_async_submit_limit(fs_info);
        limit = limit * 2 / 3;
  
 +      /*
 +       * atomic_dec_return implies a barrier for waitqueue_active
 +       */
        if (atomic_dec_return(&fs_info->nr_async_submits) < limit &&
            waitqueue_active(&fs_info->async_submit_wait))
                wake_up(&fs_info->async_submit_wait);
@@@ -1267,7 -1265,6 +1267,7 @@@ static void __setup_root(u32 nodesize, 
        atomic_set(&root->orphan_inodes, 0);
        atomic_set(&root->refs, 1);
        atomic_set(&root->will_be_snapshoted, 0);
 +      atomic_set(&root->qgroup_meta_rsv, 0);
        root->log_transid = 0;
        root->log_transid_committed = -1;
        root->last_log_commit = 0;
@@@ -1762,7 -1759,6 +1762,7 @@@ static int cleaner_kthread(void *arg
        int again;
        struct btrfs_trans_handle *trans;
  
 +      set_freezable();
        do {
                again = 0;
  
@@@ -2352,7 -2348,8 +2352,7 @@@ static int btrfs_replay_log(struct btrf
        u64 bytenr = btrfs_super_log_root(disk_super);
  
        if (fs_devices->rw_devices == 0) {
 -              printk(KERN_WARNING "BTRFS: log replay required "
 -                     "on RO media\n");
 +              btrfs_warn(fs_info, "log replay required on RO media");
                return -EIO;
        }
  
        log_tree_root->node = read_tree_block(tree_root, bytenr,
                        fs_info->generation + 1);
        if (IS_ERR(log_tree_root->node)) {
 -              printk(KERN_ERR "BTRFS: failed to read log tree\n");
 +              btrfs_warn(fs_info, "failed to read log tree");
                ret = PTR_ERR(log_tree_root->node);
                kfree(log_tree_root);
                return ret;
        } else if (!extent_buffer_uptodate(log_tree_root->node)) {
 -              printk(KERN_ERR "BTRFS: failed to read log tree\n");
 +              btrfs_err(fs_info, "failed to read log tree");
                free_extent_buffer(log_tree_root->node);
                kfree(log_tree_root);
                return -EIO;
        /* returns with log_tree_root freed on success */
        ret = btrfs_recover_log_trees(log_tree_root);
        if (ret) {
 -              btrfs_error(tree_root->fs_info, ret,
 +              btrfs_std_error(tree_root->fs_info, ret,
                            "Failed to recover log tree");
                free_extent_buffer(log_tree_root->node);
                kfree(log_tree_root);
@@@ -2575,7 -2572,7 +2575,7 @@@ int open_ctree(struct super_block *sb
        fs_info->commit_interval = BTRFS_DEFAULT_COMMIT_INTERVAL;
        fs_info->avg_delayed_ref_runtime = NSEC_PER_SEC >> 6; /* div by 64 */
        /* readahead state */
-       INIT_RADIX_TREE(&fs_info->reada_tree, GFP_NOFS & ~__GFP_WAIT);
+       INIT_RADIX_TREE(&fs_info->reada_tree, GFP_NOFS & ~__GFP_DIRECT_RECLAIM);
        spin_lock_init(&fs_info->reada_lock);
  
        fs_info->thread_pool_size = min_t(unsigned long,
         * Read super block and check the signature bytes only
         */
        bh = btrfs_read_dev_super(fs_devices->latest_bdev);
 -      if (!bh) {
 -              err = -EINVAL;
 +      if (IS_ERR(bh)) {
 +              err = PTR_ERR(bh);
                goto fail_alloc;
        }
  
@@@ -2940,7 -2937,7 +2940,7 @@@ retry_root_backup
                goto fail_fsdev_sysfs;
        }
  
 -      ret = btrfs_sysfs_add_one(fs_info);
 +      ret = btrfs_sysfs_add_mounted(fs_info);
        if (ret) {
                pr_err("BTRFS: failed to init sysfs interface: %d\n", ret);
                goto fail_fsdev_sysfs;
@@@ -3120,7 -3117,7 +3120,7 @@@ fail_cleaner
        filemap_write_and_wait(fs_info->btree_inode->i_mapping);
  
  fail_sysfs:
 -      btrfs_sysfs_remove_one(fs_info);
 +      btrfs_sysfs_remove_mounted(fs_info);
  
  fail_fsdev_sysfs:
        btrfs_sysfs_remove_fsid(fs_info->fs_devices);
@@@ -3182,8 -3179,8 +3182,8 @@@ static void btrfs_end_buffer_write_sync
                struct btrfs_device *device = (struct btrfs_device *)
                        bh->b_private;
  
 -              printk_ratelimited_in_rcu(KERN_WARNING "BTRFS: lost page write due to "
 -                                        "I/O error on %s\n",
 +              btrfs_warn_rl_in_rcu(device->dev_root->fs_info,
 +                              "lost page write due to IO error on %s",
                                          rcu_str_deref(device->name));
                /* note, we dont' set_buffer_write_io_error because we have
                 * our own ways of dealing with the IO errors
        put_bh(bh);
  }
  
 +int btrfs_read_dev_one_super(struct block_device *bdev, int copy_num,
 +                      struct buffer_head **bh_ret)
 +{
 +      struct buffer_head *bh;
 +      struct btrfs_super_block *super;
 +      u64 bytenr;
 +
 +      bytenr = btrfs_sb_offset(copy_num);
 +      if (bytenr + BTRFS_SUPER_INFO_SIZE >= i_size_read(bdev->bd_inode))
 +              return -EINVAL;
 +
 +      bh = __bread(bdev, bytenr / 4096, BTRFS_SUPER_INFO_SIZE);
 +      /*
 +       * If we fail to read from the underlying devices, as of now
 +       * the best option we have is to mark it EIO.
 +       */
 +      if (!bh)
 +              return -EIO;
 +
 +      super = (struct btrfs_super_block *)bh->b_data;
 +      if (btrfs_super_bytenr(super) != bytenr ||
 +                  btrfs_super_magic(super) != BTRFS_MAGIC) {
 +              brelse(bh);
 +              return -EINVAL;
 +      }
 +
 +      *bh_ret = bh;
 +      return 0;
 +}
 +
 +
  struct buffer_head *btrfs_read_dev_super(struct block_device *bdev)
  {
        struct buffer_head *bh;
        struct btrfs_super_block *super;
        int i;
        u64 transid = 0;
 -      u64 bytenr;
 +      int ret = -EINVAL;
  
        /* we would like to check all the supers, but that would make
         * a btrfs mount succeed after a mkfs from a different FS.
         * later supers, using BTRFS_SUPER_MIRROR_MAX instead
         */
        for (i = 0; i < 1; i++) {
 -              bytenr = btrfs_sb_offset(i);
 -              if (bytenr + BTRFS_SUPER_INFO_SIZE >=
 -                                      i_size_read(bdev->bd_inode))
 -                      break;
 -              bh = __bread(bdev, bytenr / 4096,
 -                                      BTRFS_SUPER_INFO_SIZE);
 -              if (!bh)
 +              ret = btrfs_read_dev_one_super(bdev, i, &bh);
 +              if (ret)
                        continue;
  
                super = (struct btrfs_super_block *)bh->b_data;
 -              if (btrfs_super_bytenr(super) != bytenr ||
 -                  btrfs_super_magic(super) != BTRFS_MAGIC) {
 -                      brelse(bh);
 -                      continue;
 -              }
  
                if (!latest || btrfs_super_generation(super) > transid) {
                        brelse(latest);
                        brelse(bh);
                }
        }
 +
 +      if (!latest)
 +              return ERR_PTR(ret);
 +
        return latest;
  }
  
@@@ -3327,9 -3299,8 +3327,9 @@@ static int write_dev_supers(struct btrf
                        bh = __getblk(device->bdev, bytenr / 4096,
                                      BTRFS_SUPER_INFO_SIZE);
                        if (!bh) {
 -                              printk(KERN_ERR "BTRFS: couldn't get super "
 -                                     "buffer head for bytenr %Lu\n", bytenr);
 +                              btrfs_err(device->dev_root->fs_info,
 +                                  "couldn't get super buffer head for bytenr %llu",
 +                                  bytenr);
                                errors++;
                                continue;
                        }
@@@ -3478,31 -3449,22 +3478,31 @@@ static int barrier_all_devices(struct b
  
  int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags)
  {
 -      if ((flags & (BTRFS_BLOCK_GROUP_DUP |
 -                    BTRFS_BLOCK_GROUP_RAID0 |
 -                    BTRFS_AVAIL_ALLOC_BIT_SINGLE)) ||
 -          ((flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) == 0))
 -              return 0;
 +      int raid_type;
 +      int min_tolerated = INT_MAX;
  
 -      if (flags & (BTRFS_BLOCK_GROUP_RAID1 |
 -                   BTRFS_BLOCK_GROUP_RAID5 |
 -                   BTRFS_BLOCK_GROUP_RAID10))
 -              return 1;
 +      if ((flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) == 0 ||
 +          (flags & BTRFS_AVAIL_ALLOC_BIT_SINGLE))
 +              min_tolerated = min(min_tolerated,
 +                                  btrfs_raid_array[BTRFS_RAID_SINGLE].
 +                                  tolerated_failures);
  
 -      if (flags & BTRFS_BLOCK_GROUP_RAID6)
 -              return 2;
 +      for (raid_type = 0; raid_type < BTRFS_NR_RAID_TYPES; raid_type++) {
 +              if (raid_type == BTRFS_RAID_SINGLE)
 +                      continue;
 +              if (!(flags & btrfs_raid_group[raid_type]))
 +                      continue;
 +              min_tolerated = min(min_tolerated,
 +                                  btrfs_raid_array[raid_type].
 +                                  tolerated_failures);
 +      }
  
 -      pr_warn("BTRFS: unknown raid type: %llu\n", flags);
 -      return 0;
 +      if (min_tolerated == INT_MAX) {
 +              pr_warn("BTRFS: unknown raid flag: %llu\n", flags);
 +              min_tolerated = 0;
 +      }
 +
 +      return min_tolerated;
  }
  
  int btrfs_calc_num_tolerated_disk_barrier_failures(
@@@ -3586,7 -3548,7 +3586,7 @@@ static int write_all_supers(struct btrf
                if (ret) {
                        mutex_unlock(
                                &root->fs_info->fs_devices->device_list_mutex);
 -                      btrfs_error(root->fs_info, ret,
 +                      btrfs_std_error(root->fs_info, ret,
                                    "errors while submitting device barriers.");
                        return ret;
                }
                mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
  
                /* FUA is masked off if unsupported and can't be the reason */
 -              btrfs_error(root->fs_info, -EIO,
 +              btrfs_std_error(root->fs_info, -EIO,
                            "%d errors while writing supers", total_errors);
                return -EIO;
        }
        }
        mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
        if (total_errors > max_errors) {
 -              btrfs_error(root->fs_info, -EIO,
 +              btrfs_std_error(root->fs_info, -EIO,
                            "%d errors while writing supers", total_errors);
                return -EIO;
        }
@@@ -3830,7 -3792,7 +3830,7 @@@ void close_ctree(struct btrfs_root *roo
                       percpu_counter_sum(&fs_info->delalloc_bytes));
        }
  
 -      btrfs_sysfs_remove_one(fs_info);
 +      btrfs_sysfs_remove_mounted(fs_info);
        btrfs_sysfs_remove_fsid(fs_info->fs_devices);
  
        btrfs_free_fs_roots(fs_info);
@@@ -4328,6 -4290,25 +4328,6 @@@ again
        return 0;
  }
  
 -static void btrfs_free_pending_ordered(struct btrfs_transaction *cur_trans,
 -                                     struct btrfs_fs_info *fs_info)
 -{
 -      struct btrfs_ordered_extent *ordered;
 -
 -      spin_lock(&fs_info->trans_lock);
 -      while (!list_empty(&cur_trans->pending_ordered)) {
 -              ordered = list_first_entry(&cur_trans->pending_ordered,
 -                                         struct btrfs_ordered_extent,
 -                                         trans_list);
 -              list_del_init(&ordered->trans_list);
 -              spin_unlock(&fs_info->trans_lock);
 -
 -              btrfs_put_ordered_extent(ordered);
 -              spin_lock(&fs_info->trans_lock);
 -      }
 -      spin_unlock(&fs_info->trans_lock);
 -}
 -
  void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans,
                                   struct btrfs_root *root)
  {
        cur_trans->state = TRANS_STATE_UNBLOCKED;
        wake_up(&root->fs_info->transaction_wait);
  
 -      btrfs_free_pending_ordered(cur_trans, root->fs_info);
        btrfs_destroy_delayed_inodes(root);
        btrfs_assert_delayed_root_empty(root);
  
diff --combined fs/btrfs/extent_io.c
index 33a01ea414651d217349940ca6c0e2ed7bea6f4c,032abfbebe76e6e4ba41e25d7c9326079ed71f68..9abe18763a7fb001632246fd712a64fdffcc0225
@@@ -96,8 -96,8 +96,8 @@@ static inline void __btrfs_debug_check_
        inode = tree->mapping->host;
        isize = i_size_read(inode);
        if (end >= PAGE_SIZE && (end % 2) == 0 && end != isize - 1) {
 -              printk_ratelimited(KERN_DEBUG
 -                  "BTRFS: %s: ino %llu isize %llu odd range [%llu,%llu]\n",
 +              btrfs_debug_rl(BTRFS_I(inode)->root->fs_info,
 +                  "%s: ino %llu isize %llu odd range [%llu,%llu]",
                                caller, btrfs_ino(inode), isize, start, end);
        }
  }
@@@ -131,25 -131,6 +131,25 @@@ struct extent_page_data 
        unsigned int sync_io:1;
  };
  
 +static void add_extent_changeset(struct extent_state *state, unsigned bits,
 +                               struct extent_changeset *changeset,
 +                               int set)
 +{
 +      int ret;
 +
 +      if (!changeset)
 +              return;
 +      if (set && (state->state & bits) == bits)
 +              return;
 +      if (!set && (state->state & bits) == 0)
 +              return;
 +      changeset->bytes_changed += state->end - state->start + 1;
 +      ret = ulist_add(changeset->range_changed, state->start, state->end,
 +                      GFP_ATOMIC);
 +      /* ENOMEM */
 +      BUG_ON(ret < 0);
 +}
 +
  static noinline void flush_write_bio(void *data);
  static inline struct btrfs_fs_info *
  tree_fs_info(struct extent_io_tree *tree)
@@@ -429,8 -410,7 +429,8 @@@ static void clear_state_cb(struct exten
  }
  
  static void set_state_bits(struct extent_io_tree *tree,
 -                         struct extent_state *state, unsigned *bits);
 +                         struct extent_state *state, unsigned *bits,
 +                         struct extent_changeset *changeset);
  
  /*
   * insert an extent_state struct into the tree.  'bits' are set on the
@@@ -446,7 -426,7 +446,7 @@@ static int insert_state(struct extent_i
                        struct extent_state *state, u64 start, u64 end,
                        struct rb_node ***p,
                        struct rb_node **parent,
 -                      unsigned *bits)
 +                      unsigned *bits, struct extent_changeset *changeset)
  {
        struct rb_node *node;
  
        state->start = start;
        state->end = end;
  
 -      set_state_bits(tree, state, bits);
 +      set_state_bits(tree, state, bits, changeset);
  
        node = tree_insert(&tree->state, NULL, end, &state->rb_node, p, parent);
        if (node) {
@@@ -531,8 -511,7 +531,8 @@@ static struct extent_state *next_state(
   */
  static struct extent_state *clear_state_bit(struct extent_io_tree *tree,
                                            struct extent_state *state,
 -                                          unsigned *bits, int wake)
 +                                          unsigned *bits, int wake,
 +                                          struct extent_changeset *changeset)
  {
        struct extent_state *next;
        unsigned bits_to_clear = *bits & ~EXTENT_CTLBITS;
                tree->dirty_bytes -= range;
        }
        clear_state_cb(tree, state, bits);
 +      add_extent_changeset(state, bits_to_clear, changeset, 0);
        state->state &= ~bits_to_clear;
        if (wake)
                wake_up(&state->wq);
@@@ -591,10 -569,10 +591,10 @@@ static void extent_io_tree_panic(struc
   *
   * This takes the tree lock, and returns 0 on success and < 0 on error.
   */
 -int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
 -                   unsigned bits, int wake, int delete,
 -                   struct extent_state **cached_state,
 -                   gfp_t mask)
 +static int __clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
 +                            unsigned bits, int wake, int delete,
 +                            struct extent_state **cached_state,
 +                            gfp_t mask, struct extent_changeset *changeset)
  {
        struct extent_state *state;
        struct extent_state *cached;
        if (bits & (EXTENT_IOBITS | EXTENT_BOUNDARY))
                clear = 1;
  again:
-       if (!prealloc && (mask & __GFP_WAIT)) {
+       if (!prealloc && gfpflags_allow_blocking(mask)) {
                /*
                 * Don't care for allocation failure here because we might end
                 * up not needing the pre-allocated extent state at all, which
@@@ -693,8 -671,7 +693,8 @@@ hit_next
                if (err)
                        goto out;
                if (state->end <= end) {
 -                      state = clear_state_bit(tree, state, &bits, wake);
 +                      state = clear_state_bit(tree, state, &bits, wake,
 +                                              changeset);
                        goto next;
                }
                goto search_again;
                if (wake)
                        wake_up(&state->wq);
  
 -              clear_state_bit(tree, prealloc, &bits, wake);
 +              clear_state_bit(tree, prealloc, &bits, wake, changeset);
  
                prealloc = NULL;
                goto out;
        }
  
 -      state = clear_state_bit(tree, state, &bits, wake);
 +      state = clear_state_bit(tree, state, &bits, wake, changeset);
  next:
        if (last_end == (u64)-1)
                goto out;
@@@ -741,7 -718,7 +741,7 @@@ search_again
        if (start > end)
                goto out;
        spin_unlock(&tree->lock);
-       if (mask & __GFP_WAIT)
+       if (gfpflags_allow_blocking(mask))
                cond_resched();
        goto again;
  }
@@@ -812,7 -789,7 +812,7 @@@ out
  
  static void set_state_bits(struct extent_io_tree *tree,
                           struct extent_state *state,
 -                         unsigned *bits)
 +                         unsigned *bits, struct extent_changeset *changeset)
  {
        unsigned bits_to_set = *bits & ~EXTENT_CTLBITS;
  
                u64 range = state->end - state->start + 1;
                tree->dirty_bytes += range;
        }
 +      add_extent_changeset(state, bits_to_set, changeset, 1);
        state->state |= bits_to_set;
  }
  
@@@ -859,7 -835,7 +859,7 @@@ static int __must_chec
  __set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
                 unsigned bits, unsigned exclusive_bits,
                 u64 *failed_start, struct extent_state **cached_state,
 -               gfp_t mask)
 +               gfp_t mask, struct extent_changeset *changeset)
  {
        struct extent_state *state;
        struct extent_state *prealloc = NULL;
  
        bits |= EXTENT_FIRST_DELALLOC;
  again:
-       if (!prealloc && (mask & __GFP_WAIT)) {
+       if (!prealloc && gfpflags_allow_blocking(mask)) {
                prealloc = alloc_extent_state(mask);
                BUG_ON(!prealloc);
        }
                prealloc = alloc_extent_state_atomic(prealloc);
                BUG_ON(!prealloc);
                err = insert_state(tree, prealloc, start, end,
 -                                 &p, &parent, &bits);
 +                                 &p, &parent, &bits, changeset);
                if (err)
                        extent_io_tree_panic(tree, err);
  
@@@ -923,7 -899,7 +923,7 @@@ hit_next
                        goto out;
                }
  
 -              set_state_bits(tree, state, &bits);
 +              set_state_bits(tree, state, &bits, changeset);
                cache_state(state, cached_state);
                merge_state(tree, state);
                if (last_end == (u64)-1)
                if (err)
                        goto out;
                if (state->end <= end) {
 -                      set_state_bits(tree, state, &bits);
 +                      set_state_bits(tree, state, &bits, changeset);
                        cache_state(state, cached_state);
                        merge_state(tree, state);
                        if (last_end == (u64)-1)
                 * the later extent.
                 */
                err = insert_state(tree, prealloc, start, this_end,
 -                                 NULL, NULL, &bits);
 +                                 NULL, NULL, &bits, changeset);
                if (err)
                        extent_io_tree_panic(tree, err);
  
                if (err)
                        extent_io_tree_panic(tree, err);
  
 -              set_state_bits(tree, prealloc, &bits);
 +              set_state_bits(tree, prealloc, &bits, changeset);
                cache_state(prealloc, cached_state);
                merge_state(tree, prealloc);
                prealloc = NULL;
@@@ -1052,7 -1028,7 +1052,7 @@@ search_again
        if (start > end)
                goto out;
        spin_unlock(&tree->lock);
-       if (mask & __GFP_WAIT)
+       if (gfpflags_allow_blocking(mask))
                cond_resched();
        goto again;
  }
@@@ -1062,7 -1038,7 +1062,7 @@@ int set_extent_bit(struct extent_io_tre
                   struct extent_state **cached_state, gfp_t mask)
  {
        return __set_extent_bit(tree, start, end, bits, 0, failed_start,
 -                              cached_state, mask);
 +                              cached_state, mask, NULL);
  }
  
  
@@@ -1100,7 -1076,7 +1100,7 @@@ int convert_extent_bit(struct extent_io
        btrfs_debug_check_extent_io_range(tree, start, end);
  
  again:
-       if (!prealloc && (mask & __GFP_WAIT)) {
+       if (!prealloc && gfpflags_allow_blocking(mask)) {
                /*
                 * Best effort, don't worry if extent state allocation fails
                 * here for the first iteration. We might have a cached state
                        goto out;
                }
                err = insert_state(tree, prealloc, start, end,
 -                                 &p, &parent, &bits);
 +                                 &p, &parent, &bits, NULL);
                if (err)
                        extent_io_tree_panic(tree, err);
                cache_state(prealloc, cached_state);
@@@ -1154,9 -1130,9 +1154,9 @@@ hit_next
         * Just lock what we found and keep going
         */
        if (state->start == start && state->end <= end) {
 -              set_state_bits(tree, state, &bits);
 +              set_state_bits(tree, state, &bits, NULL);
                cache_state(state, cached_state);
 -              state = clear_state_bit(tree, state, &clear_bits, 0);
 +              state = clear_state_bit(tree, state, &clear_bits, 0, NULL);
                if (last_end == (u64)-1)
                        goto out;
                start = last_end + 1;
                if (err)
                        goto out;
                if (state->end <= end) {
 -                      set_state_bits(tree, state, &bits);
 +                      set_state_bits(tree, state, &bits, NULL);
                        cache_state(state, cached_state);
 -                      state = clear_state_bit(tree, state, &clear_bits, 0);
 +                      state = clear_state_bit(tree, state, &clear_bits, 0,
 +                                              NULL);
                        if (last_end == (u64)-1)
                                goto out;
                        start = last_end + 1;
                 * the later extent.
                 */
                err = insert_state(tree, prealloc, start, this_end,
 -                                 NULL, NULL, &bits);
 +                                 NULL, NULL, &bits, NULL);
                if (err)
                        extent_io_tree_panic(tree, err);
                cache_state(prealloc, cached_state);
                if (err)
                        extent_io_tree_panic(tree, err);
  
 -              set_state_bits(tree, prealloc, &bits);
 +              set_state_bits(tree, prealloc, &bits, NULL);
                cache_state(prealloc, cached_state);
 -              clear_state_bit(tree, prealloc, &clear_bits, 0);
 +              clear_state_bit(tree, prealloc, &clear_bits, 0, NULL);
                prealloc = NULL;
                goto out;
        }
@@@ -1278,7 -1253,7 +1278,7 @@@ search_again
        if (start > end)
                goto out;
        spin_unlock(&tree->lock);
-       if (mask & __GFP_WAIT)
+       if (gfpflags_allow_blocking(mask))
                cond_resched();
        first_iteration = false;
        goto again;
@@@ -1299,30 -1274,6 +1299,30 @@@ int set_extent_bits(struct extent_io_tr
                              NULL, mask);
  }
  
 +int set_record_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
 +                         unsigned bits, gfp_t mask,
 +                         struct extent_changeset *changeset)
 +{
 +      /*
 +       * We don't support EXTENT_LOCKED yet, as current changeset will
 +       * record any bits changed, so for EXTENT_LOCKED case, it will
 +       * either fail with -EEXIST or changeset will record the whole
 +       * range.
 +       */
 +      BUG_ON(bits & EXTENT_LOCKED);
 +
 +      return __set_extent_bit(tree, start, end, bits, 0, NULL, NULL, mask,
 +                              changeset);
 +}
 +
 +int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
 +                   unsigned bits, int wake, int delete,
 +                   struct extent_state **cached, gfp_t mask)
 +{
 +      return __clear_extent_bit(tree, start, end, bits, wake, delete,
 +                                cached, mask, NULL);
 +}
 +
  int clear_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
                      unsigned bits, gfp_t mask)
  {
        return clear_extent_bit(tree, start, end, bits, wake, 0, NULL, mask);
  }
  
 +int clear_record_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
 +                           unsigned bits, gfp_t mask,
 +                           struct extent_changeset *changeset)
 +{
 +      /*
 +       * Don't support EXTENT_LOCKED case, same reason as
 +       * set_record_extent_bits().
 +       */
 +      BUG_ON(bits & EXTENT_LOCKED);
 +
 +      return __clear_extent_bit(tree, start, end, bits, 0, 0, NULL, mask,
 +                                changeset);
 +}
 +
  int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end,
                        struct extent_state **cached_state, gfp_t mask)
  {
@@@ -1406,7 -1343,7 +1406,7 @@@ int lock_extent_bits(struct extent_io_t
        while (1) {
                err = __set_extent_bit(tree, start, end, EXTENT_LOCKED | bits,
                                       EXTENT_LOCKED, &failed_start,
 -                                     cached_state, GFP_NOFS);
 +                                     cached_state, GFP_NOFS, NULL);
                if (err == -EEXIST) {
                        wait_extent_bit(tree, failed_start, end, EXTENT_LOCKED);
                        start = failed_start;
@@@ -1428,7 -1365,7 +1428,7 @@@ int try_lock_extent(struct extent_io_tr
        u64 failed_start;
  
        err = __set_extent_bit(tree, start, end, EXTENT_LOCKED, EXTENT_LOCKED,
 -                             &failed_start, NULL, GFP_NOFS);
 +                             &failed_start, NULL, GFP_NOFS, NULL);
        if (err == -EEXIST) {
                if (failed_start > start)
                        clear_extent_bit(tree, start, failed_start - 1,
@@@ -2141,8 -2078,8 +2141,8 @@@ int repair_io_failure(struct inode *ino
                return -EIO;
        }
  
 -      printk_ratelimited_in_rcu(KERN_INFO
 -                                "BTRFS: read error corrected: ino %llu off %llu (dev %s sector %llu)\n",
 +      btrfs_info_rl_in_rcu(fs_info,
 +              "read error corrected: ino %llu off %llu (dev %s sector %llu)",
                                  btrfs_ino(inode), start,
                                  rcu_str_deref(dev->name), sector);
        bio_put(bio);
@@@ -3133,12 -3070,8 +3133,12 @@@ static int __do_readpage(struct extent_
  
                        set_extent_uptodate(tree, cur, cur + iosize - 1,
                                            &cached, GFP_NOFS);
 -                      unlock_extent_cached(tree, cur, cur + iosize - 1,
 -                                           &cached, GFP_NOFS);
 +                      if (parent_locked)
 +                              free_extent_state(cached);
 +                      else
 +                              unlock_extent_cached(tree, cur,
 +                                                   cur + iosize - 1,
 +                                                   &cached, GFP_NOFS);
                        cur = cur + iosize;
                        pg_offset += iosize;
                        continue;
@@@ -4386,7 -4319,7 +4386,7 @@@ int try_release_extent_mapping(struct e
        u64 start = page_offset(page);
        u64 end = start + PAGE_CACHE_SIZE - 1;
  
-       if ((mask & __GFP_WAIT) &&
+       if (gfpflags_allow_blocking(mask) &&
            page->mapping->host->i_size > 16 * 1024 * 1024) {
                u64 len;
                while (start <= end) {
@@@ -5633,15 -5566,13 +5633,15 @@@ void memcpy_extent_buffer(struct extent
        unsigned long src_i;
  
        if (src_offset + len > dst->len) {
 -              printk(KERN_ERR "BTRFS: memmove bogus src_offset %lu move "
 -                     "len %lu dst len %lu\n", src_offset, len, dst->len);
 +              btrfs_err(dst->fs_info,
 +                      "memmove bogus src_offset %lu move "
 +                     "len %lu dst len %lu", src_offset, len, dst->len);
                BUG_ON(1);
        }
        if (dst_offset + len > dst->len) {
 -              printk(KERN_ERR "BTRFS: memmove bogus dst_offset %lu move "
 -                     "len %lu dst len %lu\n", dst_offset, len, dst->len);
 +              btrfs_err(dst->fs_info,
 +                      "memmove bogus dst_offset %lu move "
 +                     "len %lu dst len %lu", dst_offset, len, dst->len);
                BUG_ON(1);
        }
  
@@@ -5681,13 -5612,13 +5681,13 @@@ void memmove_extent_buffer(struct exten
        unsigned long src_i;
  
        if (src_offset + len > dst->len) {
 -              printk(KERN_ERR "BTRFS: memmove bogus src_offset %lu move "
 -                     "len %lu len %lu\n", src_offset, len, dst->len);
 +              btrfs_err(dst->fs_info, "memmove bogus src_offset %lu move "
 +                     "len %lu len %lu", src_offset, len, dst->len);
                BUG_ON(1);
        }
        if (dst_offset + len > dst->len) {
 -              printk(KERN_ERR "BTRFS: memmove bogus dst_offset %lu move "
 -                     "len %lu len %lu\n", dst_offset, len, dst->len);
 +              btrfs_err(dst->fs_info, "memmove bogus dst_offset %lu move "
 +                     "len %lu len %lu", dst_offset, len, dst->len);
                BUG_ON(1);
        }
        if (dst_offset < src_offset) {
index 0948d34cb84a5f24cb2221f54b1fe5a426f451eb,ed05da1b977e59f6ca54ecfe95be81e85bc631ba..85a1f8621b51f09f0893abae9ffab90382efdcfc
@@@ -85,8 -85,8 +85,8 @@@ static struct inode *__lookup_free_spac
        }
  
        mapping_set_gfp_mask(inode->i_mapping,
-                       mapping_gfp_mask(inode->i_mapping) &
-                       ~(__GFP_FS | __GFP_HIGHMEM));
+                       mapping_gfp_constraint(inode->i_mapping,
+                       ~(__GFP_FS | __GFP_HIGHMEM)));
  
        return inode;
  }
@@@ -450,9 -450,9 +450,9 @@@ static int io_ctl_check_generation(stru
  
        gen = io_ctl->cur;
        if (le64_to_cpu(*gen) != generation) {
 -              printk_ratelimited(KERN_ERR "BTRFS: space cache generation "
 -                                 "(%Lu) does not match inode (%Lu)\n", *gen,
 -                                 generation);
 +              btrfs_err_rl(io_ctl->root->fs_info,
 +                      "space cache generation (%llu) does not match inode (%llu)",
 +                              *gen, generation);
                io_ctl_unmap_page(io_ctl);
                return -EIO;
        }
@@@ -506,8 -506,8 +506,8 @@@ static int io_ctl_check_crc(struct btrf
                              PAGE_CACHE_SIZE - offset);
        btrfs_csum_final(crc, (char *)&crc);
        if (val != crc) {
 -              printk_ratelimited(KERN_ERR "BTRFS: csum mismatch on free "
 -                                 "space cache\n");
 +              btrfs_err_rl(io_ctl->root->fs_info,
 +                      "csum mismatch on free space cache");
                io_ctl_unmap_page(io_ctl);
                return -EIO;
        }
@@@ -1215,7 -1215,7 +1215,7 @@@ out
   * @offset - the offset for the key we'll insert
   *
   * This function writes out a free space cache struct to disk for quick recovery
 - * on mount.  This will return 0 if it was successfull in writing the cache out,
 + * on mount.  This will return 0 if it was successful in writing the cache out,
   * or an errno if it was not.
   */
  static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
@@@ -1730,7 -1730,7 +1730,7 @@@ static void bitmap_set_bits(struct btrf
   */
  static int search_bitmap(struct btrfs_free_space_ctl *ctl,
                         struct btrfs_free_space *bitmap_info, u64 *offset,
 -                       u64 *bytes)
 +                       u64 *bytes, bool for_alloc)
  {
        unsigned long found_bits = 0;
        unsigned long max_bits = 0;
        unsigned long next_zero;
        unsigned long extent_bits;
  
 +      /*
 +       * Skip searching the bitmap if we don't have a contiguous section that
 +       * is large enough for this allocation.
 +       */
 +      if (for_alloc &&
 +          bitmap_info->max_extent_size &&
 +          bitmap_info->max_extent_size < *bytes) {
 +              *bytes = bitmap_info->max_extent_size;
 +              return -1;
 +      }
 +
        i = offset_to_bit(bitmap_info->offset, ctl->unit,
                          max_t(u64, *offset, bitmap_info->offset));
        bits = bytes_to_bits(*bytes, ctl->unit);
  
        for_each_set_bit_from(i, bitmap_info->bitmap, BITS_PER_BITMAP) {
 +              if (for_alloc && bits == 1) {
 +                      found_bits = 1;
 +                      break;
 +              }
                next_zero = find_next_zero_bit(bitmap_info->bitmap,
                                               BITS_PER_BITMAP, i);
                extent_bits = next_zero - i;
        }
  
        *bytes = (u64)(max_bits) * ctl->unit;
 +      bitmap_info->max_extent_size = *bytes;
        return -1;
  }
  
@@@ -1829,7 -1813,7 +1829,7 @@@ find_free_space(struct btrfs_free_space
                if (entry->bitmap) {
                        u64 size = *bytes;
  
 -                      ret = search_bitmap(ctl, entry, &tmp, &size);
 +                      ret = search_bitmap(ctl, entry, &tmp, &size, true);
                        if (!ret) {
                                *offset = tmp;
                                *bytes = size;
@@@ -1890,8 -1874,7 +1890,8 @@@ again
        search_start = *offset;
        search_bytes = ctl->unit;
        search_bytes = min(search_bytes, end - search_start + 1);
 -      ret = search_bitmap(ctl, bitmap_info, &search_start, &search_bytes);
 +      ret = search_bitmap(ctl, bitmap_info, &search_start, &search_bytes,
 +                          false);
        if (ret < 0 || search_start != *offset)
                return -EINVAL;
  
                search_start = *offset;
                search_bytes = ctl->unit;
                ret = search_bitmap(ctl, bitmap_info, &search_start,
 -                                  &search_bytes);
 +                                  &search_bytes, false);
                if (ret < 0 || search_start != *offset)
                        return -EAGAIN;
  
@@@ -1960,12 -1943,6 +1960,12 @@@ static u64 add_bytes_to_bitmap(struct b
  
        bitmap_set_bits(ctl, info, offset, bytes_to_set);
  
 +      /*
 +       * We set some bytes, we have no idea what the max extent size is
 +       * anymore.
 +       */
 +      info->max_extent_size = 0;
 +
        return bytes_to_set;
  
  }
@@@ -1974,19 -1951,12 +1974,19 @@@ static bool use_bitmap(struct btrfs_fre
                      struct btrfs_free_space *info)
  {
        struct btrfs_block_group_cache *block_group = ctl->private;
 +      bool forced = false;
 +
 +#ifdef CONFIG_BTRFS_DEBUG
 +      if (btrfs_should_fragment_free_space(block_group->fs_info->extent_root,
 +                                           block_group))
 +              forced = true;
 +#endif
  
        /*
         * If we are below the extents threshold then we can add this as an
         * extent, and don't have to deal with the bitmap
         */
 -      if (ctl->free_extents < ctl->extents_thresh) {
 +      if (!forced && ctl->free_extents < ctl->extents_thresh) {
                /*
                 * If this block group has some small extents we don't want to
                 * use up all of our free slots in the cache with them, we want
@@@ -2691,7 -2661,7 +2691,7 @@@ static u64 btrfs_alloc_from_bitmap(stru
        search_start = min_start;
        search_bytes = bytes;
  
 -      err = search_bitmap(ctl, entry, &search_start, &search_bytes);
 +      err = search_bitmap(ctl, entry, &search_start, &search_bytes, true);
        if (err) {
                if (search_bytes > *max_extent_size)
                        *max_extent_size = search_bytes;
@@@ -2805,7 -2775,6 +2805,7 @@@ static int btrfs_bitmap_cluster(struct 
        unsigned long want_bits;
        unsigned long min_bits;
        unsigned long found_bits;
 +      unsigned long max_bits = 0;
        unsigned long start = 0;
        unsigned long total_found = 0;
        int ret;
        want_bits = bytes_to_bits(bytes, ctl->unit);
        min_bits = bytes_to_bits(min_bytes, ctl->unit);
  
 +      /*
 +       * Don't bother looking for a cluster in this bitmap if it's heavily
 +       * fragmented.
 +       */
 +      if (entry->max_extent_size &&
 +          entry->max_extent_size < cont1_bytes)
 +              return -ENOSPC;
  again:
        found_bits = 0;
        for_each_set_bit_from(i, entry->bitmap, BITS_PER_BITMAP) {
                                               BITS_PER_BITMAP, i);
                if (next_zero - i >= min_bits) {
                        found_bits = next_zero - i;
 +                      if (found_bits > max_bits)
 +                              max_bits = found_bits;
                        break;
                }
 +              if (next_zero - i > max_bits)
 +                      max_bits = next_zero - i;
                i = next_zero;
        }
  
 -      if (!found_bits)
 +      if (!found_bits) {
 +              entry->max_extent_size = (u64)max_bits * ctl->unit;
                return -ENOSPC;
 +      }
  
        if (!total_found) {
                start = i;
@@@ -3100,7 -3056,6 +3100,7 @@@ void btrfs_init_free_cluster(struct btr
        spin_lock_init(&cluster->refill_lock);
        cluster->root = RB_ROOT;
        cluster->max_size = 0;
 +      cluster->fragmented = false;
        INIT_LIST_HEAD(&cluster->block_group_list);
        cluster->block_group = NULL;
  }
@@@ -3268,7 -3223,7 +3268,7 @@@ static int trim_bitmaps(struct btrfs_bl
                }
  
                bytes = minlen;
 -              ret2 = search_bitmap(ctl, entry, &start, &bytes);
 +              ret2 = search_bitmap(ctl, entry, &start, &bytes, false);
                if (ret2 || start >= end) {
                        spin_unlock(&ctl->tree_lock);
                        mutex_unlock(&ctl->cache_writeout_mutex);
@@@ -3421,7 -3376,7 +3421,7 @@@ u64 btrfs_find_ino_for_alloc(struct btr
                u64 count = 1;
                int ret;
  
 -              ret = search_bitmap(ctl, entry, &offset, &count);
 +              ret = search_bitmap(ctl, entry, &offset, &count, true);
                /* Logic error; Should be empty if it can't find anything */
                ASSERT(!ret);
  
@@@ -3577,7 -3532,6 +3577,7 @@@ again
                spin_lock(&ctl->tree_lock);
                info->offset = offset;
                info->bytes = bytes;
 +              info->max_extent_size = 0;
                ret = link_free_space(ctl, info);
                spin_unlock(&ctl->tree_lock);
                if (ret)
        }
  
        bytes_added = add_bytes_to_bitmap(ctl, bitmap_info, offset, bytes);
 +
        bytes -= bytes_added;
        offset += bytes_added;
        spin_unlock(&ctl->tree_lock);
@@@ -3649,7 -3602,7 +3649,7 @@@ have_info
  
                bit_off = offset;
                bit_bytes = ctl->unit;
 -              ret = search_bitmap(ctl, info, &bit_off, &bit_bytes);
 +              ret = search_bitmap(ctl, info, &bit_off, &bit_bytes, false);
                if (!ret) {
                        if (bit_off == offset) {
                                ret = 1;
diff --combined fs/btrfs/volumes.c
index 17ed76d18eb6e99a9b6c931a90371015f1eae6d4,e023919b447064cbc6fad6984065731cbbde68c3..9b2dafa5ba59178644c6c01879583cc2769a52e8
  #include "dev-replace.h"
  #include "sysfs.h"
  
 +const struct btrfs_raid_attr btrfs_raid_array[BTRFS_NR_RAID_TYPES] = {
 +      [BTRFS_RAID_RAID10] = {
 +              .sub_stripes    = 2,
 +              .dev_stripes    = 1,
 +              .devs_max       = 0,    /* 0 == as many as possible */
 +              .devs_min       = 4,
 +              .tolerated_failures = 1,
 +              .devs_increment = 2,
 +              .ncopies        = 2,
 +      },
 +      [BTRFS_RAID_RAID1] = {
 +              .sub_stripes    = 1,
 +              .dev_stripes    = 1,
 +              .devs_max       = 2,
 +              .devs_min       = 2,
 +              .tolerated_failures = 1,
 +              .devs_increment = 2,
 +              .ncopies        = 2,
 +      },
 +      [BTRFS_RAID_DUP] = {
 +              .sub_stripes    = 1,
 +              .dev_stripes    = 2,
 +              .devs_max       = 1,
 +              .devs_min       = 1,
 +              .tolerated_failures = 0,
 +              .devs_increment = 1,
 +              .ncopies        = 2,
 +      },
 +      [BTRFS_RAID_RAID0] = {
 +              .sub_stripes    = 1,
 +              .dev_stripes    = 1,
 +              .devs_max       = 0,
 +              .devs_min       = 2,
 +              .tolerated_failures = 0,
 +              .devs_increment = 1,
 +              .ncopies        = 1,
 +      },
 +      [BTRFS_RAID_SINGLE] = {
 +              .sub_stripes    = 1,
 +              .dev_stripes    = 1,
 +              .devs_max       = 1,
 +              .devs_min       = 1,
 +              .tolerated_failures = 0,
 +              .devs_increment = 1,
 +              .ncopies        = 1,
 +      },
 +      [BTRFS_RAID_RAID5] = {
 +              .sub_stripes    = 1,
 +              .dev_stripes    = 1,
 +              .devs_max       = 0,
 +              .devs_min       = 2,
 +              .tolerated_failures = 1,
 +              .devs_increment = 1,
 +              .ncopies        = 2,
 +      },
 +      [BTRFS_RAID_RAID6] = {
 +              .sub_stripes    = 1,
 +              .dev_stripes    = 1,
 +              .devs_max       = 0,
 +              .devs_min       = 3,
 +              .tolerated_failures = 2,
 +              .devs_increment = 1,
 +              .ncopies        = 3,
 +      },
 +};
 +
 +const u64 const btrfs_raid_group[BTRFS_NR_RAID_TYPES] = {
 +      [BTRFS_RAID_RAID10] = BTRFS_BLOCK_GROUP_RAID10,
 +      [BTRFS_RAID_RAID1]  = BTRFS_BLOCK_GROUP_RAID1,
 +      [BTRFS_RAID_DUP]    = BTRFS_BLOCK_GROUP_DUP,
 +      [BTRFS_RAID_RAID0]  = BTRFS_BLOCK_GROUP_RAID0,
 +      [BTRFS_RAID_SINGLE] = 0,
 +      [BTRFS_RAID_RAID5]  = BTRFS_BLOCK_GROUP_RAID5,
 +      [BTRFS_RAID_RAID6]  = BTRFS_BLOCK_GROUP_RAID6,
 +};
 +
  static int init_first_rw_device(struct btrfs_trans_handle *trans,
                                struct btrfs_root *root,
                                struct btrfs_device *device);
@@@ -232,8 -156,8 +232,8 @@@ static struct btrfs_device *__alloc_dev
        spin_lock_init(&dev->reada_lock);
        atomic_set(&dev->reada_in_flight, 0);
        atomic_set(&dev->dev_stats_ccnt, 0);
-       INIT_RADIX_TREE(&dev->reada_zones, GFP_NOFS & ~__GFP_WAIT);
-       INIT_RADIX_TREE(&dev->reada_extents, GFP_NOFS & ~__GFP_WAIT);
+       INIT_RADIX_TREE(&dev->reada_zones, GFP_NOFS & ~__GFP_DIRECT_RECLAIM);
+       INIT_RADIX_TREE(&dev->reada_extents, GFP_NOFS & ~__GFP_DIRECT_RECLAIM);
  
        return dev;
  }
@@@ -274,6 -198,7 +274,6 @@@ btrfs_get_bdev_and_sb(const char *devic
  
        if (IS_ERR(*bdev)) {
                ret = PTR_ERR(*bdev);
 -              printk(KERN_INFO "BTRFS: open %s failed\n", device_path);
                goto error;
        }
  
        }
        invalidate_bdev(*bdev);
        *bh = btrfs_read_dev_super(*bdev);
 -      if (!*bh) {
 -              ret = -EINVAL;
 +      if (IS_ERR(*bh)) {
 +              ret = PTR_ERR(*bh);
                blkdev_put(*bdev, flags);
                goto error;
        }
@@@ -420,9 -345,6 +420,9 @@@ loop_lock
                pending = pending->bi_next;
                cur->bi_next = NULL;
  
 +              /*
 +               * atomic_dec_return implies a barrier for waitqueue_active
 +               */
                if (atomic_dec_return(&fs_info->nr_async_bios) < limit &&
                    waitqueue_active(&fs_info->async_submit_wait))
                        wake_up(&fs_info->async_submit_wait);
@@@ -843,7 -765,36 +843,7 @@@ static int __btrfs_close_devices(struc
  
        mutex_lock(&fs_devices->device_list_mutex);
        list_for_each_entry_safe(device, tmp, &fs_devices->devices, dev_list) {
 -              struct btrfs_device *new_device;
 -              struct rcu_string *name;
 -
 -              if (device->bdev)
 -                      fs_devices->open_devices--;
 -
 -              if (device->writeable &&
 -                  device->devid != BTRFS_DEV_REPLACE_DEVID) {
 -                      list_del_init(&device->dev_alloc_list);
 -                      fs_devices->rw_devices--;
 -              }
 -
 -              if (device->missing)
 -                      fs_devices->missing_devices--;
 -
 -              new_device = btrfs_alloc_device(NULL, &device->devid,
 -                                              device->uuid);
 -              BUG_ON(IS_ERR(new_device)); /* -ENOMEM */
 -
 -              /* Safe because we are under uuid_mutex */
 -              if (device->name) {
 -                      name = rcu_string_strdup(device->name->str, GFP_NOFS);
 -                      BUG_ON(!name); /* -ENOMEM */
 -                      rcu_assign_pointer(new_device->name, name);
 -              }
 -
 -              list_replace_rcu(&device->dev_list, &new_device->dev_list);
 -              new_device->fs_devices = device->fs_devices;
 -
 -              call_rcu(&device->rcu, free_device);
 +              btrfs_close_one_device(device);
        }
        mutex_unlock(&fs_devices->device_list_mutex);
  
@@@ -1451,7 -1402,7 +1451,7 @@@ again
                extent = btrfs_item_ptr(leaf, path->slots[0],
                                        struct btrfs_dev_extent);
        } else {
 -              btrfs_error(root->fs_info, ret, "Slot search failed");
 +              btrfs_std_error(root->fs_info, ret, "Slot search failed");
                goto out;
        }
  
  
        ret = btrfs_del_item(trans, root, path);
        if (ret) {
 -              btrfs_error(root->fs_info, ret,
 +              btrfs_std_error(root->fs_info, ret,
                            "Failed to remove dev extent item");
        } else {
 -              trans->transaction->have_free_bgs = 1;
 +              set_bit(BTRFS_TRANS_HAVE_FREE_BGS, &trans->transaction->flags);
        }
  out:
        btrfs_free_path(path);
@@@ -1850,7 -1801,7 +1850,7 @@@ int btrfs_rm_device(struct btrfs_root *
        if (device->bdev) {
                device->fs_devices->open_devices--;
                /* remove sysfs entry */
 -              btrfs_kobj_rm_device(root->fs_info->fs_devices, device);
 +              btrfs_sysfs_rm_device_link(root->fs_info->fs_devices, device);
        }
  
        call_rcu(&device->rcu, free_device);
@@@ -1973,8 -1924,7 +1973,8 @@@ void btrfs_rm_dev_replace_remove_srcdev
        if (srcdev->writeable) {
                fs_devices->rw_devices--;
                /* zero out the old super if it is writable */
 -              btrfs_scratch_superblock(srcdev);
 +              btrfs_scratch_superblocks(srcdev->bdev,
 +                                      rcu_str_deref(srcdev->name));
        }
  
        if (srcdev->bdev)
@@@ -2021,11 -1971,10 +2021,11 @@@ void btrfs_destroy_dev_replace_tgtdev(s
        WARN_ON(!tgtdev);
        mutex_lock(&fs_info->fs_devices->device_list_mutex);
  
 -      btrfs_kobj_rm_device(fs_info->fs_devices, tgtdev);
 +      btrfs_sysfs_rm_device_link(fs_info->fs_devices, tgtdev);
  
        if (tgtdev->bdev) {
 -              btrfs_scratch_superblock(tgtdev);
 +              btrfs_scratch_superblocks(tgtdev->bdev,
 +                                      rcu_str_deref(tgtdev->name));
                fs_info->fs_devices->open_devices--;
        }
        fs_info->fs_devices->num_devices--;
@@@ -2092,8 -2041,10 +2092,8 @@@ int btrfs_find_device_missing_or_by_pat
                        }
                }
  
 -              if (!*device) {
 -                      btrfs_err(root->fs_info, "no missing device found");
 -                      return -ENOENT;
 -              }
 +              if (!*device)
 +                      return BTRFS_ERROR_DEV_MISSING_NOT_FOUND;
  
                return 0;
        } else {
@@@ -2358,7 -2309,7 +2358,7 @@@ int btrfs_init_new_device(struct btrfs_
                                    tmp + 1);
  
        /* add sysfs device entry */
 -      btrfs_kobj_add_device(root->fs_info->fs_devices, device);
 +      btrfs_sysfs_add_device_link(root->fs_info->fs_devices, device);
  
        /*
         * we've got more storage, clear any full flags on the space
                 */
                snprintf(fsid_buf, BTRFS_UUID_UNPARSED_SIZE, "%pU",
                                                root->fs_info->fsid);
 -              if (kobject_rename(&root->fs_info->fs_devices->super_kobj,
 +              if (kobject_rename(&root->fs_info->fs_devices->fsid_kobj,
                                                                fsid_buf))
 -                      pr_warn("BTRFS: sysfs: failed to create fsid for sprout\n");
 +                      btrfs_warn(root->fs_info,
 +                              "sysfs: failed to create fsid for sprout");
        }
  
        root->fs_info->num_tolerated_disk_barrier_failures =
  
                ret = btrfs_relocate_sys_chunks(root);
                if (ret < 0)
 -                      btrfs_error(root->fs_info, ret,
 +                      btrfs_std_error(root->fs_info, ret,
                                    "Failed to relocate sys chunks after "
                                    "device initialization. This can be fixed "
                                    "using the \"btrfs balance\" command.");
  error_trans:
        btrfs_end_transaction(trans, root);
        rcu_string_free(device->name);
 -      btrfs_kobj_rm_device(root->fs_info->fs_devices, device);
 +      btrfs_sysfs_rm_device_link(root->fs_info->fs_devices, device);
        kfree(device);
  error:
        blkdev_put(bdev, FMODE_EXCL);
@@@ -2663,7 -2613,7 +2663,7 @@@ static int btrfs_free_chunk(struct btrf
        if (ret < 0)
                goto out;
        else if (ret > 0) { /* Logic error or corruption */
 -              btrfs_error(root->fs_info, -ENOENT,
 +              btrfs_std_error(root->fs_info, -ENOENT,
                            "Failed lookup while freeing chunk.");
                ret = -ENOENT;
                goto out;
  
        ret = btrfs_del_item(trans, root, path);
        if (ret < 0)
 -              btrfs_error(root->fs_info, ret,
 +              btrfs_std_error(root->fs_info, ret,
                            "Failed to delete chunk item.");
  out:
        btrfs_free_path(path);
@@@ -2856,7 -2806,7 +2856,7 @@@ static int btrfs_relocate_chunk(struct 
        trans = btrfs_start_transaction(root, 0);
        if (IS_ERR(trans)) {
                ret = PTR_ERR(trans);
 -              btrfs_std_error(root->fs_info, ret);
 +              btrfs_std_error(root->fs_info, ret, NULL);
                return ret;
        }
  
@@@ -3059,19 -3009,16 +3059,19 @@@ static void update_balance_args(struct 
         * (albeit full) chunks.
         */
        if (!(bctl->data.flags & BTRFS_BALANCE_ARGS_USAGE) &&
 +          !(bctl->data.flags & BTRFS_BALANCE_ARGS_USAGE_RANGE) &&
            !(bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT)) {
                bctl->data.flags |= BTRFS_BALANCE_ARGS_USAGE;
                bctl->data.usage = 90;
        }
        if (!(bctl->sys.flags & BTRFS_BALANCE_ARGS_USAGE) &&
 +          !(bctl->sys.flags & BTRFS_BALANCE_ARGS_USAGE_RANGE) &&
            !(bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT)) {
                bctl->sys.flags |= BTRFS_BALANCE_ARGS_USAGE;
                bctl->sys.usage = 90;
        }
        if (!(bctl->meta.flags & BTRFS_BALANCE_ARGS_USAGE) &&
 +          !(bctl->meta.flags & BTRFS_BALANCE_ARGS_USAGE_RANGE) &&
            !(bctl->meta.flags & BTRFS_BALANCE_ARGS_CONVERT)) {
                bctl->meta.flags |= BTRFS_BALANCE_ARGS_USAGE;
                bctl->meta.usage = 90;
@@@ -3125,39 -3072,6 +3125,39 @@@ static int chunk_profiles_filter(u64 ch
  
  static int chunk_usage_filter(struct btrfs_fs_info *fs_info, u64 chunk_offset,
                              struct btrfs_balance_args *bargs)
 +{
 +      struct btrfs_block_group_cache *cache;
 +      u64 chunk_used;
 +      u64 user_thresh_min;
 +      u64 user_thresh_max;
 +      int ret = 1;
 +
 +      cache = btrfs_lookup_block_group(fs_info, chunk_offset);
 +      chunk_used = btrfs_block_group_used(&cache->item);
 +
 +      if (bargs->usage_min == 0)
 +              user_thresh_min = 0;
 +      else
 +              user_thresh_min = div_factor_fine(cache->key.offset,
 +                                      bargs->usage_min);
 +
 +      if (bargs->usage_max == 0)
 +              user_thresh_max = 1;
 +      else if (bargs->usage_max > 100)
 +              user_thresh_max = cache->key.offset;
 +      else
 +              user_thresh_max = div_factor_fine(cache->key.offset,
 +                                      bargs->usage_max);
 +
 +      if (user_thresh_min <= chunk_used && chunk_used < user_thresh_max)
 +              ret = 0;
 +
 +      btrfs_put_block_group(cache);
 +      return ret;
 +}
 +
 +static int chunk_usage_range_filter(struct btrfs_fs_info *fs_info,
 +              u64 chunk_offset, struct btrfs_balance_args *bargs)
  {
        struct btrfs_block_group_cache *cache;
        u64 chunk_used, user_thresh;
        cache = btrfs_lookup_block_group(fs_info, chunk_offset);
        chunk_used = btrfs_block_group_used(&cache->item);
  
 -      if (bargs->usage == 0)
 +      if (bargs->usage_min == 0)
                user_thresh = 1;
        else if (bargs->usage > 100)
                user_thresh = cache->key.offset;
@@@ -3256,19 -3170,6 +3256,19 @@@ static int chunk_vrange_filter(struct e
        return 1;
  }
  
 +static int chunk_stripes_range_filter(struct extent_buffer *leaf,
 +                             struct btrfs_chunk *chunk,
 +                             struct btrfs_balance_args *bargs)
 +{
 +      int num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
 +
 +      if (bargs->stripes_min <= num_stripes
 +                      && num_stripes <= bargs->stripes_max)
 +              return 0;
 +
 +      return 1;
 +}
 +
  static int chunk_soft_convert_filter(u64 chunk_type,
                                     struct btrfs_balance_args *bargs)
  {
@@@ -3315,9 -3216,6 +3315,9 @@@ static int should_balance_chunk(struct 
        if ((bargs->flags & BTRFS_BALANCE_ARGS_USAGE) &&
            chunk_usage_filter(bctl->fs_info, chunk_offset, bargs)) {
                return 0;
 +      } else if ((bargs->flags & BTRFS_BALANCE_ARGS_USAGE_RANGE) &&
 +          chunk_usage_range_filter(bctl->fs_info, chunk_offset, bargs)) {
 +              return 0;
        }
  
        /* devid filter */
                return 0;
        }
  
 +      /* stripes filter */
 +      if ((bargs->flags & BTRFS_BALANCE_ARGS_STRIPES_RANGE) &&
 +          chunk_stripes_range_filter(leaf, chunk, bargs)) {
 +              return 0;
 +      }
 +
        /* soft profile changing mode */
        if ((bargs->flags & BTRFS_BALANCE_ARGS_SOFT) &&
            chunk_soft_convert_filter(chunk_type, bargs)) {
                        return 0;
                else
                        bargs->limit--;
 +      } else if ((bargs->flags & BTRFS_BALANCE_ARGS_LIMIT_RANGE)) {
 +              /*
 +               * Same logic as the 'limit' filter; the minimum cannot be
 +               * determined here because we do not have the global informatoin
 +               * about the count of all chunks that satisfy the filters.
 +               */
 +              if (bargs->limit_max == 0)
 +                      return 0;
 +              else
 +                      bargs->limit_max--;
        }
  
        return 1;
@@@ -3382,7 -3264,6 +3382,7 @@@ static int __btrfs_balance(struct btrfs
        struct btrfs_device *device;
        u64 old_size;
        u64 size_to_free;
 +      u64 chunk_type;
        struct btrfs_chunk *chunk;
        struct btrfs_path *path;
        struct btrfs_key key;
        int ret;
        int enospc_errors = 0;
        bool counting = true;
 +      /* The single value limit and min/max limits use the same bytes in the */
        u64 limit_data = bctl->data.limit;
        u64 limit_meta = bctl->meta.limit;
        u64 limit_sys = bctl->sys.limit;
 +      u32 count_data = 0;
 +      u32 count_meta = 0;
 +      u32 count_sys = 0;
  
        /* step one make some room on all the devices */
        devices = &fs_info->fs_devices->devices;
        spin_unlock(&fs_info->balance_lock);
  again:
        if (!counting) {
 +              /*
 +               * The single value limit and min/max limits use the same bytes
 +               * in the
 +               */
                bctl->data.limit = limit_data;
                bctl->meta.limit = limit_meta;
                bctl->sys.limit = limit_sys;
                }
  
                chunk = btrfs_item_ptr(leaf, slot, struct btrfs_chunk);
 +              chunk_type = btrfs_chunk_type(leaf, chunk);
  
                if (!counting) {
                        spin_lock(&fs_info->balance_lock);
                        spin_lock(&fs_info->balance_lock);
                        bctl->stat.expected++;
                        spin_unlock(&fs_info->balance_lock);
 +
 +                      if (chunk_type & BTRFS_BLOCK_GROUP_DATA)
 +                              count_data++;
 +                      else if (chunk_type & BTRFS_BLOCK_GROUP_SYSTEM)
 +                              count_sys++;
 +                      else if (chunk_type & BTRFS_BLOCK_GROUP_METADATA)
 +                              count_meta++;
 +
 +                      goto loop;
 +              }
 +
 +              /*
 +               * Apply limit_min filter, no need to check if the LIMITS
 +               * filter is used, limit_min is 0 by default
 +               */
 +              if (((chunk_type & BTRFS_BLOCK_GROUP_DATA) &&
 +                                      count_data < bctl->data.limit_min)
 +                              || ((chunk_type & BTRFS_BLOCK_GROUP_METADATA) &&
 +                                      count_meta < bctl->meta.limit_min)
 +                              || ((chunk_type & BTRFS_BLOCK_GROUP_SYSTEM) &&
 +                                      count_sys < bctl->sys.limit_min)) {
 +                      mutex_unlock(&fs_info->delete_unused_bgs_mutex);
                        goto loop;
                }
  
@@@ -3611,20 -3461,11 +3611,20 @@@ static void __cancel_balance(struct btr
        unset_balance_control(fs_info);
        ret = del_balance_item(fs_info->tree_root);
        if (ret)
 -              btrfs_std_error(fs_info, ret);
 +              btrfs_std_error(fs_info, ret, NULL);
  
        atomic_set(&fs_info->mutually_exclusive_operation_running, 0);
  }
  
 +/* Non-zero return value signifies invalidity */
 +static inline int validate_convert_profile(struct btrfs_balance_args *bctl_arg,
 +              u64 allowed)
 +{
 +      return ((bctl_arg->flags & BTRFS_BALANCE_ARGS_CONVERT) &&
 +              (!alloc_profile_is_valid(bctl_arg->target, 1) ||
 +               (bctl_arg->target & ~allowed)));
 +}
 +
  /*
   * Should be called with both balance and volume mutexes held
   */
@@@ -3682,21 -3523,27 +3682,21 @@@ int btrfs_balance(struct btrfs_balance_
        if (num_devices > 3)
                allowed |= (BTRFS_BLOCK_GROUP_RAID10 |
                            BTRFS_BLOCK_GROUP_RAID6);
 -      if ((bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT) &&
 -          (!alloc_profile_is_valid(bctl->data.target, 1) ||
 -           (bctl->data.target & ~allowed))) {
 +      if (validate_convert_profile(&bctl->data, allowed)) {
                btrfs_err(fs_info, "unable to start balance with target "
                           "data profile %llu",
                       bctl->data.target);
                ret = -EINVAL;
                goto out;
        }
 -      if ((bctl->meta.flags & BTRFS_BALANCE_ARGS_CONVERT) &&
 -          (!alloc_profile_is_valid(bctl->meta.target, 1) ||
 -           (bctl->meta.target & ~allowed))) {
 +      if (validate_convert_profile(&bctl->meta, allowed)) {
                btrfs_err(fs_info,
                           "unable to start balance with target metadata profile %llu",
                       bctl->meta.target);
                ret = -EINVAL;
                goto out;
        }
 -      if ((bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) &&
 -          (!alloc_profile_is_valid(bctl->sys.target, 1) ||
 -           (bctl->sys.target & ~allowed))) {
 +      if (validate_convert_profile(&bctl->sys, allowed)) {
                btrfs_err(fs_info,
                           "unable to start balance with target system profile %llu",
                       bctl->sys.target);
@@@ -4438,6 -4285,65 +4438,6 @@@ static int btrfs_cmp_device_info(const 
        return 0;
  }
  
 -static const struct btrfs_raid_attr btrfs_raid_array[BTRFS_NR_RAID_TYPES] = {
 -      [BTRFS_RAID_RAID10] = {
 -              .sub_stripes    = 2,
 -              .dev_stripes    = 1,
 -              .devs_max       = 0,    /* 0 == as many as possible */
 -              .devs_min       = 4,
 -              .devs_increment = 2,
 -              .ncopies        = 2,
 -      },
 -      [BTRFS_RAID_RAID1] = {
 -              .sub_stripes    = 1,
 -              .dev_stripes    = 1,
 -              .devs_max       = 2,
 -              .devs_min       = 2,
 -              .devs_increment = 2,
 -              .ncopies        = 2,
 -      },
 -      [BTRFS_RAID_DUP] = {
 -              .sub_stripes    = 1,
 -              .dev_stripes    = 2,
 -              .devs_max       = 1,
 -              .devs_min       = 1,
 -              .devs_increment = 1,
 -              .ncopies        = 2,
 -      },
 -      [BTRFS_RAID_RAID0] = {
 -              .sub_stripes    = 1,
 -              .dev_stripes    = 1,
 -              .devs_max       = 0,
 -              .devs_min       = 2,
 -              .devs_increment = 1,
 -              .ncopies        = 1,
 -      },
 -      [BTRFS_RAID_SINGLE] = {
 -              .sub_stripes    = 1,
 -              .dev_stripes    = 1,
 -              .devs_max       = 1,
 -              .devs_min       = 1,
 -              .devs_increment = 1,
 -              .ncopies        = 1,
 -      },
 -      [BTRFS_RAID_RAID5] = {
 -              .sub_stripes    = 1,
 -              .dev_stripes    = 1,
 -              .devs_max       = 0,
 -              .devs_min       = 2,
 -              .devs_increment = 1,
 -              .ncopies        = 2,
 -      },
 -      [BTRFS_RAID_RAID6] = {
 -              .sub_stripes    = 1,
 -              .dev_stripes    = 1,
 -              .devs_max       = 0,
 -              .devs_min       = 3,
 -              .devs_increment = 1,
 -              .ncopies        = 3,
 -      },
 -};
 -
  static u32 find_raid56_stripe_len(u32 data_devices, u32 dev_stripe_target)
  {
        /* TODO allow them to set a preferred stripe size */
@@@ -6688,8 -6594,8 +6688,8 @@@ static int update_dev_stat_item(struct 
        BUG_ON(!path);
        ret = btrfs_search_slot(trans, dev_root, &key, path, -1, 1);
        if (ret < 0) {
 -              printk_in_rcu(KERN_WARNING "BTRFS: "
 -                      "error %d while searching for dev_stats item for device %s!\n",
 +              btrfs_warn_in_rcu(dev_root->fs_info,
 +                      "error %d while searching for dev_stats item for device %s",
                              ret, rcu_str_deref(device->name));
                goto out;
        }
                /* need to delete old one and insert a new one */
                ret = btrfs_del_item(trans, dev_root, path);
                if (ret != 0) {
 -                      printk_in_rcu(KERN_WARNING "BTRFS: "
 -                              "delete too small dev_stats item for device %s failed %d!\n",
 +                      btrfs_warn_in_rcu(dev_root->fs_info,
 +                              "delete too small dev_stats item for device %s failed %d",
                                      rcu_str_deref(device->name), ret);
                        goto out;
                }
                ret = btrfs_insert_empty_item(trans, dev_root, path,
                                              &key, sizeof(*ptr));
                if (ret < 0) {
 -                      printk_in_rcu(KERN_WARNING "BTRFS: "
 -                                        "insert dev_stats item for device %s failed %d!\n",
 -                                    rcu_str_deref(device->name), ret);
 +                      btrfs_warn_in_rcu(dev_root->fs_info,
 +                              "insert dev_stats item for device %s failed %d",
 +                              rcu_str_deref(device->name), ret);
                        goto out;
                }
        }
@@@ -6769,8 -6675,8 +6769,8 @@@ static void btrfs_dev_stat_print_on_err
  {
        if (!dev->dev_stats_valid)
                return;
 -      printk_ratelimited_in_rcu(KERN_ERR "BTRFS: "
 -                         "bdev %s errs: wr %u, rd %u, flush %u, corrupt %u, gen %u\n",
 +      btrfs_err_rl_in_rcu(dev->dev_root->fs_info,
 +              "bdev %s errs: wr %u, rd %u, flush %u, corrupt %u, gen %u",
                           rcu_str_deref(dev->name),
                           btrfs_dev_stat_read(dev, BTRFS_DEV_STAT_WRITE_ERRS),
                           btrfs_dev_stat_read(dev, BTRFS_DEV_STAT_READ_ERRS),
@@@ -6789,8 -6695,8 +6789,8 @@@ static void btrfs_dev_stat_print_on_loa
        if (i == BTRFS_DEV_STAT_VALUES_MAX)
                return; /* all values == 0, suppress message */
  
 -      printk_in_rcu(KERN_INFO "BTRFS: "
 -                 "bdev %s errs: wr %u, rd %u, flush %u, corrupt %u, gen %u\n",
 +      btrfs_info_in_rcu(dev->dev_root->fs_info,
 +              "bdev %s errs: wr %u, rd %u, flush %u, corrupt %u, gen %u",
               rcu_str_deref(dev->name),
               btrfs_dev_stat_read(dev, BTRFS_DEV_STAT_WRITE_ERRS),
               btrfs_dev_stat_read(dev, BTRFS_DEV_STAT_READ_ERRS),
@@@ -6834,34 -6740,22 +6834,34 @@@ int btrfs_get_dev_stats(struct btrfs_ro
        return 0;
  }
  
 -int btrfs_scratch_superblock(struct btrfs_device *device)
 +void btrfs_scratch_superblocks(struct block_device *bdev, char *device_path)
  {
        struct buffer_head *bh;
        struct btrfs_super_block *disk_super;
 +      int copy_num;
  
 -      bh = btrfs_read_dev_super(device->bdev);
 -      if (!bh)
 -              return -EINVAL;
 -      disk_super = (struct btrfs_super_block *)bh->b_data;
 +      if (!bdev)
 +              return;
  
 -      memset(&disk_super->magic, 0, sizeof(disk_super->magic));
 -      set_buffer_dirty(bh);
 -      sync_dirty_buffer(bh);
 -      brelse(bh);
 +      for (copy_num = 0; copy_num < BTRFS_SUPER_MIRROR_MAX;
 +              copy_num++) {
  
 -      return 0;
 +              if (btrfs_read_dev_one_super(bdev, copy_num, &bh))
 +                      continue;
 +
 +              disk_super = (struct btrfs_super_block *)bh->b_data;
 +
 +              memset(&disk_super->magic, 0, sizeof(disk_super->magic));
 +              set_buffer_dirty(bh);
 +              sync_dirty_buffer(bh);
 +              brelse(bh);
 +      }
 +
 +      /* Notify udev that device has changed */
 +      btrfs_kobject_uevent(bdev, KOBJ_CHANGE);
 +
 +      /* Update ctime/mtime for device path for libblkid */
 +      update_dev_time(device_path);
  }
  
  /*
@@@ -6929,38 -6823,3 +6929,38 @@@ void btrfs_reset_fs_info_ptr(struct btr
                fs_devices = fs_devices->seed;
        }
  }
 +
 +void btrfs_close_one_device(struct btrfs_device *device)
 +{
 +      struct btrfs_fs_devices *fs_devices = device->fs_devices;
 +      struct btrfs_device *new_device;
 +      struct rcu_string *name;
 +
 +      if (device->bdev)
 +              fs_devices->open_devices--;
 +
 +      if (device->writeable &&
 +          device->devid != BTRFS_DEV_REPLACE_DEVID) {
 +              list_del_init(&device->dev_alloc_list);
 +              fs_devices->rw_devices--;
 +      }
 +
 +      if (device->missing)
 +              fs_devices->missing_devices--;
 +
 +      new_device = btrfs_alloc_device(NULL, &device->devid,
 +                                      device->uuid);
 +      BUG_ON(IS_ERR(new_device)); /* -ENOMEM */
 +
 +      /* Safe because we are under uuid_mutex */
 +      if (device->name) {
 +              name = rcu_string_strdup(device->name->str, GFP_NOFS);
 +              BUG_ON(!name); /* -ENOMEM */
 +              rcu_assign_pointer(new_device->name, name);
 +      }
 +
 +      list_replace_rcu(&device->dev_list, &new_device->dev_list);
 +      new_device->fs_devices = device->fs_devices;
 +
 +      call_rcu(&device->rcu, free_device);
 +}
diff --combined fs/ext4/inode.c
index e8d620a484f6a86bb684ce432888c329a429e948,60aaecd5598b32798cb114cbd473d5818af7c692..7d1aad1d9313155f3780cde3923710fe7f60ea1c
@@@ -378,7 -378,7 +378,7 @@@ static int __check_block_validity(struc
                                 "lblock %lu mapped to illegal pblock "
                                 "(length %d)", (unsigned long) map->m_lblk,
                                 map->m_len);
 -              return -EIO;
 +              return -EFSCORRUPTED;
        }
        return 0;
  }
@@@ -480,7 -480,7 +480,7 @@@ int ext4_map_blocks(handle_t *handle, s
  
        /* We can handle the block number less than EXT_MAX_BLOCKS */
        if (unlikely(map->m_lblk >= EXT_MAX_BLOCKS))
 -              return -EIO;
 +              return -EFSCORRUPTED;
  
        /* Lookup extent status tree firstly */
        if (ext4_es_lookup_extent(inode, map->m_lblk, &es)) {
@@@ -965,7 -965,7 +965,7 @@@ static int ext4_block_write_begin(struc
        if (unlikely(err))
                page_zero_new_buffers(page, from, to);
        else if (decrypt)
 -              err = ext4_decrypt_one(inode, page);
 +              err = ext4_decrypt(page);
        return err;
  }
  #endif
@@@ -1181,38 -1181,6 +1181,38 @@@ errout
        return ret ? ret : copied;
  }
  
 +/*
 + * This is a private version of page_zero_new_buffers() which doesn't
 + * set the buffer to be dirty, since in data=journalled mode we need
 + * to call ext4_handle_dirty_metadata() instead.
 + */
 +static void zero_new_buffers(struct page *page, unsigned from, unsigned to)
 +{
 +      unsigned int block_start = 0, block_end;
 +      struct buffer_head *head, *bh;
 +
 +      bh = head = page_buffers(page);
 +      do {
 +              block_end = block_start + bh->b_size;
 +              if (buffer_new(bh)) {
 +                      if (block_end > from && block_start < to) {
 +                              if (!PageUptodate(page)) {
 +                                      unsigned start, size;
 +
 +                                      start = max(from, block_start);
 +                                      size = min(to, block_end) - start;
 +
 +                                      zero_user(page, start, size);
 +                                      set_buffer_uptodate(bh);
 +                              }
 +                              clear_buffer_new(bh);
 +                      }
 +              }
 +              block_start = block_end;
 +              bh = bh->b_this_page;
 +      } while (bh != head);
 +}
 +
  static int ext4_journalled_write_end(struct file *file,
                                     struct address_space *mapping,
                                     loff_t pos, unsigned len, unsigned copied,
                if (copied < len) {
                        if (!PageUptodate(page))
                                copied = 0;
 -                      page_zero_new_buffers(page, from+copied, to);
 +                      zero_new_buffers(page, from+copied, to);
                }
  
                ret = ext4_walk_page_buffers(handle, page_buffers(page), from,
@@@ -1847,22 -1815,11 +1847,22 @@@ static int ext4_writepage(struct page *
         * the page. But we may reach here when we do a journal commit via
         * journal_submit_inode_data_buffers() and in that case we must write
         * allocated buffers to achieve data=ordered mode guarantees.
 +       *
 +       * Also, if there is only one buffer per page (the fs block
 +       * size == the page size), if one buffer needs block
 +       * allocation or needs to modify the extent tree to clear the
 +       * unwritten flag, we know that the page can't be written at
 +       * all, so we might as well refuse the write immediately.
 +       * Unfortunately if the block size != page size, we can't as
 +       * easily detect this case using ext4_walk_page_buffers(), but
 +       * for the extremely common case, this is an optimization that
 +       * skips a useless round trip through ext4_bio_write_page().
         */
        if (ext4_walk_page_buffers(NULL, page_bufs, 0, len, NULL,
                                   ext4_bh_delay_or_unwritten)) {
                redirty_page_for_writepage(wbc, page);
 -              if (current->flags & PF_MEMALLOC) {
 +              if ((current->flags & PF_MEMALLOC) ||
 +                  (inode->i_sb->s_blocksize == PAGE_CACHE_SIZE)) {
                        /*
                         * For memory cleaning there's no point in writing only
                         * some buffers. So just bail out. Warn if we came here
@@@ -2642,7 -2599,8 +2642,7 @@@ static int ext4_nonda_switch(struct sup
  /* We always reserve for an inode update; the superblock could be there too */
  static int ext4_da_write_credits(struct inode *inode, loff_t pos, unsigned len)
  {
 -      if (likely(EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
 -                              EXT4_FEATURE_RO_COMPAT_LARGE_FILE)))
 +      if (likely(ext4_has_feature_large_file(inode->i_sb)))
                return 1;
  
        if (pos + len <= 0x7fffffffULL)
@@@ -3386,7 -3344,7 +3386,7 @@@ static int __ext4_block_zero_page_range
        int err = 0;
  
        page = find_or_create_page(mapping, from >> PAGE_CACHE_SHIFT,
-                                  mapping_gfp_mask(mapping) & ~__GFP_FS);
+                                  mapping_gfp_constraint(mapping, ~__GFP_FS));
        if (!page)
                return -ENOMEM;
  
                        /* We expect the key to be set. */
                        BUG_ON(!ext4_has_encryption_key(inode));
                        BUG_ON(blocksize != PAGE_CACHE_SIZE);
 -                      WARN_ON_ONCE(ext4_decrypt_one(inode, page));
 +                      WARN_ON_ONCE(ext4_decrypt(page));
                }
        }
        if (ext4_should_journal_data(inode)) {
@@@ -3862,7 -3820,7 +3862,7 @@@ static int __ext4_get_inode_loc(struct 
  
        iloc->bh = NULL;
        if (!ext4_valid_inum(sb, inode->i_ino))
 -              return -EIO;
 +              return -EFSCORRUPTED;
  
        iloc->block_group = (inode->i_ino - 1) / EXT4_INODES_PER_GROUP(sb);
        gdp = ext4_get_group_desc(sb, iloc->block_group, NULL);
@@@ -4048,7 -4006,8 +4048,7 @@@ static blkcnt_t ext4_inode_blocks(struc
        struct inode *inode = &(ei->vfs_inode);
        struct super_block *sb = inode->i_sb;
  
 -      if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
 -                              EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
 +      if (ext4_has_feature_huge_file(sb)) {
                /* we are using combined 48 bit field */
                i_blocks = ((u64)le16_to_cpu(raw_inode->i_blocks_high)) << 32 |
                                        le32_to_cpu(raw_inode->i_blocks_lo);
@@@ -4109,7 -4068,7 +4109,7 @@@ struct inode *ext4_iget(struct super_bl
                        EXT4_ERROR_INODE(inode, "bad extra_isize (%u != %u)",
                                EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize,
                                EXT4_INODE_SIZE(inode->i_sb));
 -                      ret = -EIO;
 +                      ret = -EFSCORRUPTED;
                        goto bad_inode;
                }
        } else
  
        if (!ext4_inode_csum_verify(inode, raw_inode, ei)) {
                EXT4_ERROR_INODE(inode, "checksum invalid");
 -              ret = -EIO;
 +              ret = -EFSBADCRC;
                goto bad_inode;
        }
  
        ei->i_flags = le32_to_cpu(raw_inode->i_flags);
        inode->i_blocks = ext4_inode_blocks(raw_inode, ei);
        ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl_lo);
 -      if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT))
 +      if (ext4_has_feature_64bit(sb))
                ei->i_file_acl |=
                        ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32;
        inode->i_size = ext4_isize(raw_inode);
            !ext4_data_block_valid(EXT4_SB(sb), ei->i_file_acl, 1)) {
                EXT4_ERROR_INODE(inode, "bad extended attribute block %llu",
                                 ei->i_file_acl);
 -              ret = -EIO;
 +              ret = -EFSCORRUPTED;
                goto bad_inode;
        } else if (!ext4_has_inline_data(inode)) {
                if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
        } else if (ino == EXT4_BOOT_LOADER_INO) {
                make_bad_inode(inode);
        } else {
 -              ret = -EIO;
 +              ret = -EFSCORRUPTED;
                EXT4_ERROR_INODE(inode, "bogus i_mode (%o)", inode->i_mode);
                goto bad_inode;
        }
@@@ -4313,7 -4272,7 +4313,7 @@@ bad_inode
  struct inode *ext4_iget_normal(struct super_block *sb, unsigned long ino)
  {
        if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)
 -              return ERR_PTR(-EIO);
 +              return ERR_PTR(-EFSCORRUPTED);
        return ext4_iget(sb, ino);
  }
  
@@@ -4335,7 -4294,7 +4335,7 @@@ static int ext4_inode_blocks_set(handle
                ext4_clear_inode_flag(inode, EXT4_INODE_HUGE_FILE);
                return 0;
        }
 -      if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE))
 +      if (!ext4_has_feature_huge_file(sb))
                return -EFBIG;
  
        if (i_blocks <= 0xffffffffffffULL) {
@@@ -4496,7 -4455,8 +4496,7 @@@ static int ext4_do_update_inode(handle_
                need_datasync = 1;
        }
        if (ei->i_disksize > 0x7fffffffULL) {
 -              if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
 -                              EXT4_FEATURE_RO_COMPAT_LARGE_FILE) ||
 +              if (!ext4_has_feature_large_file(sb) ||
                                EXT4_SB(sb)->s_es->s_rev_level ==
                    cpu_to_le32(EXT4_GOOD_OLD_REV))
                        set_large_file = 1;
                if (err)
                        goto out_brelse;
                ext4_update_dynamic_rev(sb);
 -              EXT4_SET_RO_COMPAT_FEATURE(sb,
 -                                         EXT4_FEATURE_RO_COMPAT_LARGE_FILE);
 +              ext4_set_feature_large_file(sb);
                ext4_handle_sync(handle);
                err = ext4_handle_dirty_super(handle, sb);
        }
diff --combined fs/ext4/readpage.c
index d94af71a4e7fcabd1783f28cccb86363473fe3ae,1061611ae14dd6c66878584820528d757cfea399..5dc5e95063de2a7e42749a94464f00f7c50be4b8
@@@ -62,7 -62,7 +62,7 @@@ static void completion_pages(struct wor
        bio_for_each_segment_all(bv, bio, i) {
                struct page *page = bv->bv_page;
  
 -              int ret = ext4_decrypt(ctx, page);
 +              int ret = ext4_decrypt(page);
                if (ret) {
                        WARN_ON_ONCE(1);
                        SetPageError(page);
@@@ -166,7 -166,7 +166,7 @@@ int ext4_mpage_readpages(struct address
                        page = list_entry(pages->prev, struct page, lru);
                        list_del(&page->lru);
                        if (add_to_page_cache_lru(page, mapping, page->index,
-                                       GFP_KERNEL & mapping_gfp_mask(mapping)))
+                                 mapping_gfp_constraint(mapping, GFP_KERNEL)))
                                goto next_page;
                }
  
diff --combined fs/ext4/super.c
index 04d0f1b334096525030674c6d818e124a1bd81f3,49f6c78ee3afe26aa45941d443c5ea242ef95676..753f4e68b820da0dd78fc7a7e3a66e529846ea0b
@@@ -34,6 -34,7 +34,6 @@@
  #include <linux/namei.h>
  #include <linux/quotaops.h>
  #include <linux/seq_file.h>
 -#include <linux/proc_fs.h>
  #include <linux/ctype.h>
  #include <linux/log2.h>
  #include <linux/crc16.h>
  #define CREATE_TRACE_POINTS
  #include <trace/events/ext4.h>
  
 -static struct proc_dir_entry *ext4_proc_root;
 -static struct kset *ext4_kset;
  static struct ext4_lazy_init *ext4_li_info;
  static struct mutex ext4_li_mtx;
 -static struct ext4_features *ext4_feat;
  static int ext4_mballoc_ready;
  static struct ratelimit_state ext4_mount_msg_ratelimit;
  
@@@ -79,6 -83,7 +79,6 @@@ static int ext4_feature_set_ok(struct s
  static void ext4_destroy_lazyinit_thread(void);
  static void ext4_unregister_li_request(struct super_block *sb);
  static void ext4_clear_request_list(void);
 -static int ext4_reserve_clusters(struct ext4_sb_info *, ext4_fsblk_t);
  
  #if !defined(CONFIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT2)
  static struct file_system_type ext2_fs_type = {
@@@ -110,7 -115,8 +110,7 @@@ MODULE_ALIAS("ext3")
  static int ext4_verify_csum_type(struct super_block *sb,
                                 struct ext4_super_block *es)
  {
 -      if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
 -                                      EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
 +      if (!ext4_has_feature_metadata_csum(sb))
                return 1;
  
        return es->s_checksum_type == EXT4_CRC32C_CHKSUM;
@@@ -388,13 -394,9 +388,13 @@@ static void ext4_handle_error(struct su
                smp_wmb();
                sb->s_flags |= MS_RDONLY;
        }
 -      if (test_opt(sb, ERRORS_PANIC))
 +      if (test_opt(sb, ERRORS_PANIC)) {
 +              if (EXT4_SB(sb)->s_journal &&
 +                !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR))
 +                      return;
                panic("EXT4-fs (device %s): panic forced after error\n",
                        sb->s_id);
 +      }
  }
  
  #define ext4_error_ratelimit(sb)                                      \
@@@ -493,12 -495,6 +493,12 @@@ const char *ext4_decode_error(struct su
        char *errstr = NULL;
  
        switch (errno) {
 +      case -EFSCORRUPTED:
 +              errstr = "Corrupt filesystem";
 +              break;
 +      case -EFSBADCRC:
 +              errstr = "Filesystem failed CRC";
 +              break;
        case -EIO:
                errstr = "IO failure";
                break;
@@@ -589,12 -585,8 +589,12 @@@ void __ext4_abort(struct super_block *s
                        jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO);
                save_error_info(sb, function, line);
        }
 -      if (test_opt(sb, ERRORS_PANIC))
 +      if (test_opt(sb, ERRORS_PANIC)) {
 +              if (EXT4_SB(sb)->s_journal &&
 +                !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR))
 +                      return;
                panic("EXT4-fs panic from previous error\n");
 +      }
  }
  
  void __ext4_msg(struct super_block *sb,
@@@ -808,7 -800,6 +808,7 @@@ static void ext4_put_super(struct super
                        ext4_abort(sb, "Couldn't clean up the journal");
        }
  
 +      ext4_unregister_sysfs(sb);
        ext4_es_unregister_shrinker(sbi);
        del_timer_sync(&sbi->s_err_report);
        ext4_release_system_zone(sb);
        ext4_xattr_put_super(sb);
  
        if (!(sb->s_flags & MS_RDONLY)) {
 -              EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
 +              ext4_clear_feature_journal_needs_recovery(sb);
                es->s_state = cpu_to_le16(sbi->s_mount_state);
        }
        if (!(sb->s_flags & MS_RDONLY))
                ext4_commit_super(sb, 1);
  
 -      if (sbi->s_proc) {
 -              remove_proc_entry("options", sbi->s_proc);
 -              remove_proc_entry(sb->s_id, ext4_proc_root);
 -      }
 -      kobject_del(&sbi->s_kobj);
 -
        for (i = 0; i < sbi->s_gdb_count; i++)
                brelse(sbi->s_group_desc[i]);
        kvfree(sbi->s_group_desc);
@@@ -1061,7 -1058,7 +1061,7 @@@ static int bdev_try_to_free_page(struc
                return 0;
        if (journal)
                return jbd2_journal_try_to_free_buffers(journal, page,
-                                                       wait & ~__GFP_WAIT);
+                                               wait & ~__GFP_DIRECT_RECLAIM);
        return try_to_free_buffers(page);
  }
  
@@@ -1291,7 -1288,7 +1291,7 @@@ static int set_qf_name(struct super_blo
                        "quota options when quota turned on");
                return -1;
        }
 -      if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA)) {
 +      if (ext4_has_feature_quota(sb)) {
                ext4_msg(sb, KERN_ERR, "Cannot set journaled quota options "
                         "when QUOTA feature is enabled");
                return -1;
@@@ -1384,10 -1381,10 +1384,10 @@@ static const struct mount_opts 
        {Opt_nojournal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM,
         MOPT_EXT4_ONLY | MOPT_CLEAR},
        {Opt_journal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM,
 -       MOPT_EXT4_ONLY | MOPT_SET},
 +       MOPT_EXT4_ONLY | MOPT_SET | MOPT_EXPLICIT},
        {Opt_journal_async_commit, (EXT4_MOUNT_JOURNAL_ASYNC_COMMIT |
                                    EXT4_MOUNT_JOURNAL_CHECKSUM),
 -       MOPT_EXT4_ONLY | MOPT_SET},
 +       MOPT_EXT4_ONLY | MOPT_SET | MOPT_EXPLICIT},
        {Opt_noload, EXT4_MOUNT_NOLOAD, MOPT_NO_EXT2 | MOPT_SET},
        {Opt_err_panic, EXT4_MOUNT_ERRORS_PANIC, MOPT_SET | MOPT_CLEAR_ERR},
        {Opt_err_ro, EXT4_MOUNT_ERRORS_RO, MOPT_SET | MOPT_CLEAR_ERR},
@@@ -1516,14 -1513,8 +1516,14 @@@ static int handle_mount_opt(struct supe
                return -1;
        if (args->from && (m->flags & MOPT_GTE0) && (arg < 0))
                return -1;
 -      if (m->flags & MOPT_EXPLICIT)
 -              set_opt2(sb, EXPLICIT_DELALLOC);
 +      if (m->flags & MOPT_EXPLICIT) {
 +              if (m->mount_opt & EXT4_MOUNT_DELALLOC) {
 +                      set_opt2(sb, EXPLICIT_DELALLOC);
 +              } else if (m->mount_opt & EXT4_MOUNT_JOURNAL_CHECKSUM) {
 +                      set_opt2(sb, EXPLICIT_JOURNAL_CHECKSUM);
 +              } else
 +                      return -1;
 +      }
        if (m->flags & MOPT_CLEAR_ERR)
                clear_opt(sb, ERRORS_MASK);
        if (token == Opt_noquota && sb_any_quota_loaded(sb)) {
                                 "quota options when quota turned on");
                        return -1;
                }
 -              if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
 -                                             EXT4_FEATURE_RO_COMPAT_QUOTA)) {
 +              if (ext4_has_feature_quota(sb)) {
                        ext4_msg(sb, KERN_ERR,
                                 "Cannot set journaled quota options "
                                 "when QUOTA feature is enabled");
@@@ -1715,7 -1707,7 +1715,7 @@@ static int parse_options(char *options
                        return 0;
        }
  #ifdef CONFIG_QUOTA
 -      if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA) &&
 +      if (ext4_has_feature_quota(sb) &&
            (test_opt(sb, USRQUOTA) || test_opt(sb, GRPQUOTA))) {
                ext4_msg(sb, KERN_ERR, "Cannot set quota options when QUOTA "
                         "feature is enabled");
@@@ -1888,7 -1880,7 +1888,7 @@@ static int ext4_show_options(struct seq
        return _ext4_show_options(seq, root->d_sb, 0);
  }
  
 -static int options_seq_show(struct seq_file *seq, void *offset)
 +int ext4_seq_options_show(struct seq_file *seq, void *offset)
  {
        struct super_block *sb = seq->private;
        int rc;
        return rc;
  }
  
 -static int options_open_fs(struct inode *inode, struct file *file)
 -{
 -      return single_open(file, options_seq_show, PDE_DATA(inode));
 -}
 -
 -static const struct file_operations ext4_seq_options_fops = {
 -      .owner = THIS_MODULE,
 -      .open = options_open_fs,
 -      .read = seq_read,
 -      .llseek = seq_lseek,
 -      .release = single_release,
 -};
 -
  static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
                            int read_only)
  {
        es->s_mtime = cpu_to_le32(get_seconds());
        ext4_update_dynamic_rev(sb);
        if (sbi->s_journal)
 -              EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
 +              ext4_set_feature_journal_needs_recovery(sb);
  
        ext4_commit_super(sb, 1);
  done:
@@@ -2022,13 -2027,12 +2022,13 @@@ failed
        return 0;
  }
  
 -static __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group,
 +static __le16 ext4_group_desc_csum(struct super_block *sb, __u32 block_group,
                                   struct ext4_group_desc *gdp)
  {
        int offset;
        __u16 crc = 0;
        __le32 le_group = cpu_to_le32(block_group);
 +      struct ext4_sb_info *sbi = EXT4_SB(sb);
  
        if (ext4_has_metadata_csum(sbi->s_sb)) {
                /* Use new metadata_csum algorithm */
        }
  
        /* old crc16 code */
 -      if (!(sbi->s_es->s_feature_ro_compat &
 -            cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)))
 +      if (!ext4_has_feature_gdt_csum(sb))
                return 0;
  
        offset = offsetof(struct ext4_group_desc, bg_checksum);
        crc = crc16(crc, (__u8 *)gdp, offset);
        offset += sizeof(gdp->bg_checksum); /* skip checksum */
        /* for checksum of struct ext4_group_desc do the rest...*/
 -      if ((sbi->s_es->s_feature_incompat &
 -           cpu_to_le32(EXT4_FEATURE_INCOMPAT_64BIT)) &&
 +      if (ext4_has_feature_64bit(sb) &&
            offset < le16_to_cpu(sbi->s_es->s_desc_size))
                crc = crc16(crc, (__u8 *)gdp + offset,
                            le16_to_cpu(sbi->s_es->s_desc_size) -
@@@ -2072,7 -2078,8 +2072,7 @@@ int ext4_group_desc_csum_verify(struct 
                                struct ext4_group_desc *gdp)
  {
        if (ext4_has_group_desc_csum(sb) &&
 -          (gdp->bg_checksum != ext4_group_desc_csum(EXT4_SB(sb),
 -                                                    block_group, gdp)))
 +          (gdp->bg_checksum != ext4_group_desc_csum(sb, block_group, gdp)))
                return 0;
  
        return 1;
@@@ -2083,7 -2090,7 +2083,7 @@@ void ext4_group_desc_csum_set(struct su
  {
        if (!ext4_has_group_desc_csum(sb))
                return;
 -      gdp->bg_checksum = ext4_group_desc_csum(EXT4_SB(sb), block_group, gdp);
 +      gdp->bg_checksum = ext4_group_desc_csum(sb, block_group, gdp);
  }
  
  /* Called at mount-time, super-block is locked */
@@@ -2099,7 -2106,7 +2099,7 @@@ static int ext4_check_descriptors(struc
        int flexbg_flag = 0;
        ext4_group_t i, grp = sbi->s_groups_count;
  
 -      if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
 +      if (ext4_has_feature_flex_bg(sb))
                flexbg_flag = 1;
  
        ext4_debug("Checking group descriptors");
                if (!ext4_group_desc_csum_verify(sb, i, gdp)) {
                        ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
                                 "Checksum for group %u failed (%u!=%u)",
 -                               i, le16_to_cpu(ext4_group_desc_csum(sbi, i,
 +                               i, le16_to_cpu(ext4_group_desc_csum(sb, i,
                                     gdp)), le16_to_cpu(gdp->bg_checksum));
                        if (!(sb->s_flags & MS_RDONLY)) {
                                ext4_unlock_group(sb, i);
@@@ -2406,7 -2413,8 +2406,7 @@@ static ext4_fsblk_t descriptor_loc(stru
  
        first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg);
  
 -      if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG) ||
 -          nr < first_meta_bg)
 +      if (!ext4_has_feature_meta_bg(sb) || nr < first_meta_bg)
                return logical_sb_block + nr + 1;
        bg = sbi->s_desc_per_block * nr;
        if (ext4_bg_has_super(sb, bg))
@@@ -2462,6 -2470,335 +2462,6 @@@ static unsigned long ext4_get_stripe_si
        return ret;
  }
  
 -/* sysfs supprt */
 -
 -struct ext4_attr {
 -      struct attribute attr;
 -      ssize_t (*show)(struct ext4_attr *, struct ext4_sb_info *, char *);
 -      ssize_t (*store)(struct ext4_attr *, struct ext4_sb_info *,
 -                       const char *, size_t);
 -      union {
 -              int offset;
 -              int deprecated_val;
 -      } u;
 -};
 -
 -static int parse_strtoull(const char *buf,
 -              unsigned long long max, unsigned long long *value)
 -{
 -      int ret;
 -
 -      ret = kstrtoull(skip_spaces(buf), 0, value);
 -      if (!ret && *value > max)
 -              ret = -EINVAL;
 -      return ret;
 -}
 -
 -static ssize_t delayed_allocation_blocks_show(struct ext4_attr *a,
 -                                            struct ext4_sb_info *sbi,
 -                                            char *buf)
 -{
 -      return snprintf(buf, PAGE_SIZE, "%llu\n",
 -              (s64) EXT4_C2B(sbi,
 -                      percpu_counter_sum(&sbi->s_dirtyclusters_counter)));
 -}
 -
 -static ssize_t session_write_kbytes_show(struct ext4_attr *a,
 -                                       struct ext4_sb_info *sbi, char *buf)
 -{
 -      struct super_block *sb = sbi->s_buddy_cache->i_sb;
 -
 -      if (!sb->s_bdev->bd_part)
 -              return snprintf(buf, PAGE_SIZE, "0\n");
 -      return snprintf(buf, PAGE_SIZE, "%lu\n",
 -                      (part_stat_read(sb->s_bdev->bd_part, sectors[1]) -
 -                       sbi->s_sectors_written_start) >> 1);
 -}
 -
 -static ssize_t lifetime_write_kbytes_show(struct ext4_attr *a,
 -                                        struct ext4_sb_info *sbi, char *buf)
 -{
 -      struct super_block *sb = sbi->s_buddy_cache->i_sb;
 -
 -      if (!sb->s_bdev->bd_part)
 -              return snprintf(buf, PAGE_SIZE, "0\n");
 -      return snprintf(buf, PAGE_SIZE, "%llu\n",
 -                      (unsigned long long)(sbi->s_kbytes_written +
 -                      ((part_stat_read(sb->s_bdev->bd_part, sectors[1]) -
 -                        EXT4_SB(sb)->s_sectors_written_start) >> 1)));
 -}
 -
 -static ssize_t inode_readahead_blks_store(struct ext4_attr *a,
 -                                        struct ext4_sb_info *sbi,
 -                                        const char *buf, size_t count)
 -{
 -      unsigned long t;
 -      int ret;
 -
 -      ret = kstrtoul(skip_spaces(buf), 0, &t);
 -      if (ret)
 -              return ret;
 -
 -      if (t && (!is_power_of_2(t) || t > 0x40000000))
 -              return -EINVAL;
 -
 -      sbi->s_inode_readahead_blks = t;
 -      return count;
 -}
 -
 -static ssize_t sbi_ui_show(struct ext4_attr *a,
 -                         struct ext4_sb_info *sbi, char *buf)
 -{
 -      unsigned int *ui = (unsigned int *) (((char *) sbi) + a->u.offset);
 -
 -      return snprintf(buf, PAGE_SIZE, "%u\n", *ui);
 -}
 -
 -static ssize_t sbi_ui_store(struct ext4_attr *a,
 -                          struct ext4_sb_info *sbi,
 -                          const char *buf, size_t count)
 -{
 -      unsigned int *ui = (unsigned int *) (((char *) sbi) + a->u.offset);
 -      unsigned long t;
 -      int ret;
 -
 -      ret = kstrtoul(skip_spaces(buf), 0, &t);
 -      if (ret)
 -              return ret;
 -      *ui = t;
 -      return count;
 -}
 -
 -static ssize_t es_ui_show(struct ext4_attr *a,
 -                         struct ext4_sb_info *sbi, char *buf)
 -{
 -
 -      unsigned int *ui = (unsigned int *) (((char *) sbi->s_es) +
 -                         a->u.offset);
 -
 -      return snprintf(buf, PAGE_SIZE, "%u\n", *ui);
 -}
 -
 -static ssize_t reserved_clusters_show(struct ext4_attr *a,
 -                                struct ext4_sb_info *sbi, char *buf)
 -{
 -      return snprintf(buf, PAGE_SIZE, "%llu\n",
 -              (unsigned long long) atomic64_read(&sbi->s_resv_clusters));
 -}
 -
 -static ssize_t reserved_clusters_store(struct ext4_attr *a,
 -                                 struct ext4_sb_info *sbi,
 -                                 const char *buf, size_t count)
 -{
 -      unsigned long long val;
 -      int ret;
 -
 -      if (parse_strtoull(buf, -1ULL, &val))
 -              return -EINVAL;
 -      ret = ext4_reserve_clusters(sbi, val);
 -
 -      return ret ? ret : count;
 -}
 -
 -static ssize_t trigger_test_error(struct ext4_attr *a,
 -                                struct ext4_sb_info *sbi,
 -                                const char *buf, size_t count)
 -{
 -      int len = count;
 -
 -      if (!capable(CAP_SYS_ADMIN))
 -              return -EPERM;
 -
 -      if (len && buf[len-1] == '\n')
 -              len--;
 -
 -      if (len)
 -              ext4_error(sbi->s_sb, "%.*s", len, buf);
 -      return count;
 -}
 -
 -static ssize_t sbi_deprecated_show(struct ext4_attr *a,
 -                                 struct ext4_sb_info *sbi, char *buf)
 -{
 -      return snprintf(buf, PAGE_SIZE, "%d\n", a->u.deprecated_val);
 -}
 -
 -#define EXT4_ATTR_OFFSET(_name,_mode,_show,_store,_elname) \
 -static struct ext4_attr ext4_attr_##_name = {                 \
 -      .attr = {.name = __stringify(_name), .mode = _mode },   \
 -      .show   = _show,                                        \
 -      .store  = _store,                                       \
 -      .u = {                                                  \
 -              .offset = offsetof(struct ext4_sb_info, _elname),\
 -      },                                                      \
 -}
 -
 -#define EXT4_ATTR_OFFSET_ES(_name,_mode,_show,_store,_elname)         \
 -static struct ext4_attr ext4_attr_##_name = {                         \
 -      .attr = {.name = __stringify(_name), .mode = _mode },           \
 -      .show   = _show,                                                \
 -      .store  = _store,                                               \
 -      .u = {                                                          \
 -              .offset = offsetof(struct ext4_super_block, _elname),   \
 -      },                                                              \
 -}
 -
 -#define EXT4_ATTR(name, mode, show, store) \
 -static struct ext4_attr ext4_attr_##name = __ATTR(name, mode, show, store)
 -
 -#define EXT4_INFO_ATTR(name) EXT4_ATTR(name, 0444, NULL, NULL)
 -#define EXT4_RO_ATTR(name) EXT4_ATTR(name, 0444, name##_show, NULL)
 -#define EXT4_RW_ATTR(name) EXT4_ATTR(name, 0644, name##_show, name##_store)
 -
 -#define EXT4_RO_ATTR_ES_UI(name, elname)      \
 -      EXT4_ATTR_OFFSET_ES(name, 0444, es_ui_show, NULL, elname)
 -#define EXT4_RW_ATTR_SBI_UI(name, elname)     \
 -      EXT4_ATTR_OFFSET(name, 0644, sbi_ui_show, sbi_ui_store, elname)
 -
 -#define ATTR_LIST(name) &ext4_attr_##name.attr
 -#define EXT4_DEPRECATED_ATTR(_name, _val)     \
 -static struct ext4_attr ext4_attr_##_name = {                 \
 -      .attr = {.name = __stringify(_name), .mode = 0444 },    \
 -      .show   = sbi_deprecated_show,                          \
 -      .u = {                                                  \
 -              .deprecated_val = _val,                         \
 -      },                                                      \
 -}
 -
 -EXT4_RO_ATTR(delayed_allocation_blocks);
 -EXT4_RO_ATTR(session_write_kbytes);
 -EXT4_RO_ATTR(lifetime_write_kbytes);
 -EXT4_RW_ATTR(reserved_clusters);
 -EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, sbi_ui_show,
 -               inode_readahead_blks_store, s_inode_readahead_blks);
 -EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal);
 -EXT4_RW_ATTR_SBI_UI(mb_stats, s_mb_stats);
 -EXT4_RW_ATTR_SBI_UI(mb_max_to_scan, s_mb_max_to_scan);
 -EXT4_RW_ATTR_SBI_UI(mb_min_to_scan, s_mb_min_to_scan);
 -EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs);
 -EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request);
 -EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc);
 -EXT4_DEPRECATED_ATTR(max_writeback_mb_bump, 128);
 -EXT4_RW_ATTR_SBI_UI(extent_max_zeroout_kb, s_extent_max_zeroout_kb);
 -EXT4_ATTR(trigger_fs_error, 0200, NULL, trigger_test_error);
 -EXT4_RW_ATTR_SBI_UI(err_ratelimit_interval_ms, s_err_ratelimit_state.interval);
 -EXT4_RW_ATTR_SBI_UI(err_ratelimit_burst, s_err_ratelimit_state.burst);
 -EXT4_RW_ATTR_SBI_UI(warning_ratelimit_interval_ms, s_warning_ratelimit_state.interval);
 -EXT4_RW_ATTR_SBI_UI(warning_ratelimit_burst, s_warning_ratelimit_state.burst);
 -EXT4_RW_ATTR_SBI_UI(msg_ratelimit_interval_ms, s_msg_ratelimit_state.interval);
 -EXT4_RW_ATTR_SBI_UI(msg_ratelimit_burst, s_msg_ratelimit_state.burst);
 -EXT4_RO_ATTR_ES_UI(errors_count, s_error_count);
 -EXT4_RO_ATTR_ES_UI(first_error_time, s_first_error_time);
 -EXT4_RO_ATTR_ES_UI(last_error_time, s_last_error_time);
 -
 -static struct attribute *ext4_attrs[] = {
 -      ATTR_LIST(delayed_allocation_blocks),
 -      ATTR_LIST(session_write_kbytes),
 -      ATTR_LIST(lifetime_write_kbytes),
 -      ATTR_LIST(reserved_clusters),
 -      ATTR_LIST(inode_readahead_blks),
 -      ATTR_LIST(inode_goal),
 -      ATTR_LIST(mb_stats),
 -      ATTR_LIST(mb_max_to_scan),
 -      ATTR_LIST(mb_min_to_scan),
 -      ATTR_LIST(mb_order2_req),
 -      ATTR_LIST(mb_stream_req),
 -      ATTR_LIST(mb_group_prealloc),
 -      ATTR_LIST(max_writeback_mb_bump),
 -      ATTR_LIST(extent_max_zeroout_kb),
 -      ATTR_LIST(trigger_fs_error),
 -      ATTR_LIST(err_ratelimit_interval_ms),
 -      ATTR_LIST(err_ratelimit_burst),
 -      ATTR_LIST(warning_ratelimit_interval_ms),
 -      ATTR_LIST(warning_ratelimit_burst),
 -      ATTR_LIST(msg_ratelimit_interval_ms),
 -      ATTR_LIST(msg_ratelimit_burst),
 -      ATTR_LIST(errors_count),
 -      ATTR_LIST(first_error_time),
 -      ATTR_LIST(last_error_time),
 -      NULL,
 -};
 -
 -/* Features this copy of ext4 supports */
 -EXT4_INFO_ATTR(lazy_itable_init);
 -EXT4_INFO_ATTR(batched_discard);
 -EXT4_INFO_ATTR(meta_bg_resize);
 -EXT4_INFO_ATTR(encryption);
 -
 -static struct attribute *ext4_feat_attrs[] = {
 -      ATTR_LIST(lazy_itable_init),
 -      ATTR_LIST(batched_discard),
 -      ATTR_LIST(meta_bg_resize),
 -      ATTR_LIST(encryption),
 -      NULL,
 -};
 -
 -static ssize_t ext4_attr_show(struct kobject *kobj,
 -                            struct attribute *attr, char *buf)
 -{
 -      struct ext4_sb_info *sbi = container_of(kobj, struct ext4_sb_info,
 -                                              s_kobj);
 -      struct ext4_attr *a = container_of(attr, struct ext4_attr, attr);
 -
 -      return a->show ? a->show(a, sbi, buf) : 0;
 -}
 -
 -static ssize_t ext4_attr_store(struct kobject *kobj,
 -                             struct attribute *attr,
 -                             const char *buf, size_t len)
 -{
 -      struct ext4_sb_info *sbi = container_of(kobj, struct ext4_sb_info,
 -                                              s_kobj);
 -      struct ext4_attr *a = container_of(attr, struct ext4_attr, attr);
 -
 -      return a->store ? a->store(a, sbi, buf, len) : 0;
 -}
 -
 -static void ext4_sb_release(struct kobject *kobj)
 -{
 -      struct ext4_sb_info *sbi = container_of(kobj, struct ext4_sb_info,
 -                                              s_kobj);
 -      complete(&sbi->s_kobj_unregister);
 -}
 -
 -static const struct sysfs_ops ext4_attr_ops = {
 -      .show   = ext4_attr_show,
 -      .store  = ext4_attr_store,
 -};
 -
 -static struct kobj_type ext4_ktype = {
 -      .default_attrs  = ext4_attrs,
 -      .sysfs_ops      = &ext4_attr_ops,
 -      .release        = ext4_sb_release,
 -};
 -
 -static void ext4_feat_release(struct kobject *kobj)
 -{
 -      complete(&ext4_feat->f_kobj_unregister);
 -}
 -
 -static ssize_t ext4_feat_show(struct kobject *kobj,
 -                            struct attribute *attr, char *buf)
 -{
 -      return snprintf(buf, PAGE_SIZE, "supported\n");
 -}
 -
 -/*
 - * We can not use ext4_attr_show/store because it relies on the kobject
 - * being embedded in the ext4_sb_info structure which is definitely not
 - * true in this case.
 - */
 -static const struct sysfs_ops ext4_feat_ops = {
 -      .show   = ext4_feat_show,
 -      .store  = NULL,
 -};
 -
 -static struct kobj_type ext4_feat_ktype = {
 -      .default_attrs  = ext4_feat_attrs,
 -      .sysfs_ops      = &ext4_feat_ops,
 -      .release        = ext4_feat_release,
 -};
 -
  /*
   * Check whether this filesystem can be mounted based on
   * the features present and the RDONLY/RDWR mount requested.
   */
  static int ext4_feature_set_ok(struct super_block *sb, int readonly)
  {
 -      if (EXT4_HAS_INCOMPAT_FEATURE(sb, ~EXT4_FEATURE_INCOMPAT_SUPP)) {
 +      if (ext4_has_unknown_ext4_incompat_features(sb)) {
                ext4_msg(sb, KERN_ERR,
                        "Couldn't mount because of "
                        "unsupported optional features (%x)",
        if (readonly)
                return 1;
  
 -      if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_READONLY)) {
 +      if (ext4_has_feature_readonly(sb)) {
                ext4_msg(sb, KERN_INFO, "filesystem is read-only");
                sb->s_flags |= MS_RDONLY;
                return 1;
        }
  
        /* Check that feature set is OK for a read-write mount */
 -      if (EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT4_FEATURE_RO_COMPAT_SUPP)) {
 +      if (ext4_has_unknown_ext4_ro_compat_features(sb)) {
                ext4_msg(sb, KERN_ERR, "couldn't mount RDWR because of "
                         "unsupported optional features (%x)",
                         (le32_to_cpu(EXT4_SB(sb)->s_es->s_feature_ro_compat) &
         * Large file size enabled file system can only be mounted
         * read-write on 32-bit systems if kernel is built with CONFIG_LBDAF
         */
 -      if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
 +      if (ext4_has_feature_huge_file(sb)) {
                if (sizeof(blkcnt_t) < sizeof(u64)) {
                        ext4_msg(sb, KERN_ERR, "Filesystem with huge files "
                                 "cannot be mounted RDWR without "
                        return 0;
                }
        }
 -      if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_BIGALLOC) &&
 -          !EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
 +      if (ext4_has_feature_bigalloc(sb) && !ext4_has_feature_extents(sb)) {
                ext4_msg(sb, KERN_ERR,
                         "Can't support bigalloc feature without "
                         "extents feature\n");
        }
  
  #ifndef CONFIG_QUOTA
 -      if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA) &&
 -          !readonly) {
 +      if (ext4_has_feature_quota(sb) && !readonly) {
                ext4_msg(sb, KERN_ERR,
                         "Filesystem with quota feature cannot be mounted RDWR "
                         "without CONFIG_QUOTA");
@@@ -2973,7 -3312,7 +2973,7 @@@ static int count_overhead(struct super_
        ext4_group_t            i, ngroups = ext4_get_groups_count(sb);
        int                     s, j, count = 0;
  
 -      if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_BIGALLOC))
 +      if (!ext4_has_feature_bigalloc(sb))
                return (ext4_bg_has_super(sb, grp) + ext4_bg_num_gdb(sb, grp) +
                        sbi->s_itb_per_group + 2);
  
@@@ -3064,10 -3403,10 +3064,10 @@@ int ext4_calculate_overhead(struct supe
        return 0;
  }
  
 -
 -static ext4_fsblk_t ext4_calculate_resv_clusters(struct super_block *sb)
 +static void ext4_set_resv_clusters(struct super_block *sb)
  {
        ext4_fsblk_t resv_clusters;
 +      struct ext4_sb_info *sbi = EXT4_SB(sb);
  
        /*
         * There's no need to reserve anything when we aren't using extents.
         * hole punching doesn't need new metadata... This is needed especially
         * to keep ext2/3 backward compatibility.
         */
 -      if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS))
 -              return 0;
 +      if (!ext4_has_feature_extents(sb))
 +              return;
        /*
         * By default we reserve 2% or 4096 clusters, whichever is smaller.
         * This should cover the situations where we can not afford to run
         * allocation would require 1, or 2 blocks, higher numbers are
         * very rare.
         */
 -      resv_clusters = ext4_blocks_count(EXT4_SB(sb)->s_es) >>
 -                      EXT4_SB(sb)->s_cluster_bits;
 +      resv_clusters = (ext4_blocks_count(sbi->s_es) >>
 +                       sbi->s_cluster_bits);
  
        do_div(resv_clusters, 50);
        resv_clusters = min_t(ext4_fsblk_t, resv_clusters, 4096);
  
 -      return resv_clusters;
 -}
 -
 -
 -static int ext4_reserve_clusters(struct ext4_sb_info *sbi, ext4_fsblk_t count)
 -{
 -      ext4_fsblk_t clusters = ext4_blocks_count(sbi->s_es) >>
 -                              sbi->s_cluster_bits;
 -
 -      if (count >= clusters)
 -              return -EINVAL;
 -
 -      atomic64_set(&sbi->s_resv_clusters, count);
 -      return 0;
 +      atomic64_set(&sbi->s_resv_clusters, resv_clusters);
  }
  
  static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        sbi->s_kbytes_written = le64_to_cpu(es->s_kbytes_written);
  
        /* Warn if metadata_csum and gdt_csum are both set. */
 -      if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
 -                                     EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) &&
 -          EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
 +      if (ext4_has_feature_metadata_csum(sb) &&
 +          ext4_has_feature_gdt_csum(sb))
                ext4_warning(sb, "metadata_csum and uninit_bg are "
                             "redundant flags; please run fsck.");
  
        }
  
        /* Load the checksum driver */
 -      if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
 -                                     EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
 +      if (ext4_has_feature_metadata_csum(sb)) {
                sbi->s_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
                if (IS_ERR(sbi->s_chksum_driver)) {
                        ext4_msg(sb, KERN_ERR, "Cannot load crc32c driver.");
                ext4_msg(sb, KERN_ERR, "VFS: Found ext4 filesystem with "
                         "invalid superblock checksum.  Run e2fsck?");
                silent = 1;
 +              ret = -EFSBADCRC;
                goto cantfind_ext4;
        }
  
        /* Precompute checksum seed for all metadata */
 -      if (ext4_has_metadata_csum(sb))
 +      if (ext4_has_feature_csum_seed(sb))
 +              sbi->s_csum_seed = le32_to_cpu(es->s_checksum_seed);
 +      else if (ext4_has_metadata_csum(sb))
                sbi->s_csum_seed = ext4_chksum(sbi, ~0, es->s_uuid,
                                               sizeof(es->s_uuid));
  
                (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
  
        if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV &&
 -          (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) ||
 -           EXT4_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
 -           EXT4_HAS_INCOMPAT_FEATURE(sb, ~0U)))
 +          (ext4_has_compat_features(sb) ||
 +           ext4_has_ro_compat_features(sb) ||
 +           ext4_has_incompat_features(sb)))
                ext4_msg(sb, KERN_WARNING,
                       "feature flags set on rev 0 fs, "
                       "running e2fsck is recommended");
  
        if (es->s_creator_os == cpu_to_le32(EXT4_OS_HURD)) {
                set_opt2(sb, HURD_COMPAT);
 -              if (EXT4_HAS_INCOMPAT_FEATURE(sb,
 -                                            EXT4_FEATURE_INCOMPAT_64BIT)) {
 +              if (ext4_has_feature_64bit(sb)) {
                        ext4_msg(sb, KERN_ERR,
                                 "The Hurd can't support 64-bit file systems");
                        goto failed_mount;
                }
        }
  
 -      if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_ENCRYPT) &&
 -          es->s_encryption_level) {
 +      if (ext4_has_feature_encrypt(sb) && es->s_encryption_level) {
                ext4_msg(sb, KERN_ERR, "Unsupported encryption level %d",
                         es->s_encryption_level);
                goto failed_mount;
                }
        }
  
 -      has_huge_files = EXT4_HAS_RO_COMPAT_FEATURE(sb,
 -                              EXT4_FEATURE_RO_COMPAT_HUGE_FILE);
 +      has_huge_files = ext4_has_feature_huge_file(sb);
        sbi->s_bitmap_maxbytes = ext4_max_bitmap_size(sb->s_blocksize_bits,
                                                      has_huge_files);
        sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits, has_huge_files);
        }
  
        sbi->s_desc_size = le16_to_cpu(es->s_desc_size);
 -      if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT)) {
 +      if (ext4_has_feature_64bit(sb)) {
                if (sbi->s_desc_size < EXT4_MIN_DESC_SIZE_64BIT ||
                    sbi->s_desc_size > EXT4_MAX_DESC_SIZE ||
                    !is_power_of_2(sbi->s_desc_size)) {
        for (i = 0; i < 4; i++)
                sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
        sbi->s_def_hash_version = es->s_def_hash_version;
 -      if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
 +      if (ext4_has_feature_dir_index(sb)) {
                i = le32_to_cpu(es->s_flags);
                if (i & EXT2_FLAGS_UNSIGNED_HASH)
                        sbi->s_hash_unsigned = 3;
  
        /* Handle clustersize */
        clustersize = BLOCK_SIZE << le32_to_cpu(es->s_log_cluster_size);
 -      has_bigalloc = EXT4_HAS_RO_COMPAT_FEATURE(sb,
 -                              EXT4_FEATURE_RO_COMPAT_BIGALLOC);
 +      has_bigalloc = ext4_has_feature_bigalloc(sb);
        if (has_bigalloc) {
                if (clustersize < blocksize) {
                        ext4_msg(sb, KERN_ERR,
                goto failed_mount;
        }
  
 -      if (ext4_proc_root)
 -              sbi->s_proc = proc_mkdir(sb->s_id, ext4_proc_root);
 -
 -      if (sbi->s_proc)
 -              proc_create_data("options", S_IRUGO, sbi->s_proc,
 -                               &ext4_seq_options_fops, sb);
 -
        bgl_lock_init(sbi->s_blockgroup_lock);
  
        for (i = 0; i < db_count; i++) {
        }
        if (!ext4_check_descriptors(sb, &first_not_zeroed)) {
                ext4_msg(sb, KERN_ERR, "group descriptors corrupted!");
 +              ret = -EFSCORRUPTED;
                goto failed_mount2;
        }
  
        sb->s_xattr = ext4_xattr_handlers;
  #ifdef CONFIG_QUOTA
        sb->dq_op = &ext4_quota_operations;
 -      if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA))
 +      if (ext4_has_feature_quota(sb))
                sb->s_qcop = &dquot_quotactl_sysfile_ops;
        else
                sb->s_qcop = &ext4_qctl_operations;
        sb->s_root = NULL;
  
        needs_recovery = (es->s_last_orphan != 0 ||
 -                        EXT4_HAS_INCOMPAT_FEATURE(sb,
 -                                  EXT4_FEATURE_INCOMPAT_RECOVER));
 +                        ext4_has_feature_journal_needs_recovery(sb));
  
 -      if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_MMP) &&
 -          !(sb->s_flags & MS_RDONLY))
 +      if (ext4_has_feature_mmp(sb) && !(sb->s_flags & MS_RDONLY))
                if (ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block)))
                        goto failed_mount3a;
  
         * The first inode we look at is the journal inode.  Don't try
         * root first: it may be modified in the journal!
         */
 -      if (!test_opt(sb, NOLOAD) &&
 -          EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) {
 +      if (!test_opt(sb, NOLOAD) && ext4_has_feature_journal(sb)) {
                if (ext4_load_journal(sb, es, journal_devnum))
                        goto failed_mount3a;
        } else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) &&
 -            EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) {
 +                 ext4_has_feature_journal_needs_recovery(sb)) {
                ext4_msg(sb, KERN_ERR, "required journal recovery "
                       "suppressed and not mounted read-only");
                goto failed_mount_wq;
        } else {
 +              /* Nojournal mode, all journal mount options are illegal */
 +              if (test_opt2(sb, EXPLICIT_JOURNAL_CHECKSUM)) {
 +                      ext4_msg(sb, KERN_ERR, "can't mount with "
 +                               "journal_checksum, fs mounted w/o journal");
 +                      goto failed_mount_wq;
 +              }
 +              if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) {
 +                      ext4_msg(sb, KERN_ERR, "can't mount with "
 +                               "journal_async_commit, fs mounted w/o journal");
 +                      goto failed_mount_wq;
 +              }
 +              if (sbi->s_commit_interval != JBD2_DEFAULT_MAX_COMMIT_AGE*HZ) {
 +                      ext4_msg(sb, KERN_ERR, "can't mount with "
 +                               "commit=%lu, fs mounted w/o journal",
 +                               sbi->s_commit_interval / HZ);
 +                      goto failed_mount_wq;
 +              }
 +              if (EXT4_MOUNT_DATA_FLAGS &
 +                  (sbi->s_mount_opt ^ sbi->s_def_mount_opt)) {
 +                      ext4_msg(sb, KERN_ERR, "can't mount with "
 +                               "data=, fs mounted w/o journal");
 +                      goto failed_mount_wq;
 +              }
 +              sbi->s_def_mount_opt &= EXT4_MOUNT_JOURNAL_CHECKSUM;
 +              clear_opt(sb, JOURNAL_CHECKSUM);
                clear_opt(sb, DATA_FLAGS);
                sbi->s_journal = NULL;
                needs_recovery = 0;
                goto no_journal;
        }
  
 -      if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT) &&
 +      if (ext4_has_feature_64bit(sb) &&
            !jbd2_journal_set_features(EXT4_SB(sb)->s_journal, 0, 0,
                                       JBD2_FEATURE_INCOMPAT_64BIT)) {
                ext4_msg(sb, KERN_ERR, "Failed to set 64-bit journal feature");
@@@ -3762,16 -4101,18 +3762,16 @@@ no_journal
                }
        }
  
 -      if ((DUMMY_ENCRYPTION_ENABLED(sbi) ||
 -           EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_ENCRYPT)) &&
 +      if ((DUMMY_ENCRYPTION_ENABLED(sbi) || ext4_has_feature_encrypt(sb)) &&
            (blocksize != PAGE_CACHE_SIZE)) {
                ext4_msg(sb, KERN_ERR,
                         "Unsupported blocksize for fs encryption");
                goto failed_mount_wq;
        }
  
 -      if (DUMMY_ENCRYPTION_ENABLED(sbi) &&
 -          !(sb->s_flags & MS_RDONLY) &&
 -          !EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_ENCRYPT)) {
 -              EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_ENCRYPT);
 +      if (DUMMY_ENCRYPTION_ENABLED(sbi) && !(sb->s_flags & MS_RDONLY) &&
 +          !ext4_has_feature_encrypt(sb)) {
 +              ext4_set_feature_encrypt(sb);
                ext4_commit_super(sb, 1);
        }
  
        if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) {
                sbi->s_want_extra_isize = sizeof(struct ext4_inode) -
                                                     EXT4_GOOD_OLD_INODE_SIZE;
 -              if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
 -                                     EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)) {
 +              if (ext4_has_feature_extra_isize(sb)) {
                        if (sbi->s_want_extra_isize <
                            le16_to_cpu(es->s_want_extra_isize))
                                sbi->s_want_extra_isize =
                         "available");
        }
  
 -      err = ext4_reserve_clusters(sbi, ext4_calculate_resv_clusters(sb));
 -      if (err) {
 -              ext4_msg(sb, KERN_ERR, "failed to reserve %llu clusters for "
 -                       "reserved pool", ext4_calculate_resv_clusters(sb));
 -              goto failed_mount4a;
 -      }
 +      ext4_set_resv_clusters(sb);
  
        err = ext4_setup_system_zone(sb);
        if (err) {
                goto failed_mount6;
        }
  
 -      if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
 +      if (ext4_has_feature_flex_bg(sb))
                if (!ext4_fill_flex_info(sb)) {
                        ext4_msg(sb, KERN_ERR,
                               "unable to initialize "
        if (err)
                goto failed_mount6;
  
 -      sbi->s_kobj.kset = ext4_kset;
 -      init_completion(&sbi->s_kobj_unregister);
 -      err = kobject_init_and_add(&sbi->s_kobj, &ext4_ktype, NULL,
 -                                 "%s", sb->s_id);
 +      err = ext4_register_sysfs(sb);
        if (err)
                goto failed_mount7;
  
  #ifdef CONFIG_QUOTA
        /* Enable quota usage during mount. */
 -      if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA) &&
 -          !(sb->s_flags & MS_RDONLY)) {
 +      if (ext4_has_feature_quota(sb) && !(sb->s_flags & MS_RDONLY)) {
                err = ext4_enable_quotas(sb);
                if (err)
                        goto failed_mount8;
@@@ -3962,7 -4313,7 +3962,7 @@@ cantfind_ext4
  
  #ifdef CONFIG_QUOTA
  failed_mount8:
 -      kobject_del(&sbi->s_kobj);
 +      ext4_unregister_sysfs(sb);
  #endif
  failed_mount7:
        ext4_unregister_li_request(sb);
@@@ -4002,6 -4353,10 +4002,6 @@@ failed_mount2
  failed_mount:
        if (sbi->s_chksum_driver)
                crypto_free_shash(sbi->s_chksum_driver);
 -      if (sbi->s_proc) {
 -              remove_proc_entry("options", sbi->s_proc);
 -              remove_proc_entry(sb->s_id, ext4_proc_root);
 -      }
  #ifdef CONFIG_QUOTA
        for (i = 0; i < EXT4_MAXQUOTAS; i++)
                kfree(sbi->s_qf_names[i]);
@@@ -4048,7 -4403,7 +4048,7 @@@ static journal_t *ext4_get_journal(stru
        struct inode *journal_inode;
        journal_t *journal;
  
 -      BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL));
 +      BUG_ON(!ext4_has_feature_journal(sb));
  
        /* First, test for the existence of a valid inode on disk.  Bad
         * things happen if we iget() an unused inode, as the subsequent
@@@ -4098,7 -4453,7 +4098,7 @@@ static journal_t *ext4_get_dev_journal(
        struct ext4_super_block *es;
        struct block_device *bdev;
  
 -      BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL));
 +      BUG_ON(!ext4_has_feature_journal(sb));
  
        bdev = ext4_blkdev_get(j_dev, sb);
        if (bdev == NULL)
@@@ -4190,7 -4545,7 +4190,7 @@@ static int ext4_load_journal(struct sup
        int err = 0;
        int really_read_only;
  
 -      BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL));
 +      BUG_ON(!ext4_has_feature_journal(sb));
  
        if (journal_devnum &&
            journal_devnum != le32_to_cpu(es->s_journal_dev)) {
         * crash?  For recovery, we need to check in advance whether we
         * can get read-write access to the device.
         */
 -      if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) {
 +      if (ext4_has_feature_journal_needs_recovery(sb)) {
                if (sb->s_flags & MS_RDONLY) {
                        ext4_msg(sb, KERN_INFO, "INFO: recovery "
                                        "required on readonly filesystem");
        if (!(journal->j_flags & JBD2_BARRIER))
                ext4_msg(sb, KERN_INFO, "barriers disabled");
  
 -      if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER))
 +      if (!ext4_has_feature_journal_needs_recovery(sb))
                err = jbd2_journal_wipe(journal, !really_read_only);
        if (!err) {
                char *save = kmalloc(EXT4_S_ERR_LEN, GFP_KERNEL);
@@@ -4352,7 -4707,7 +4352,7 @@@ static void ext4_mark_recovery_complete
  {
        journal_t *journal = EXT4_SB(sb)->s_journal;
  
 -      if (!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) {
 +      if (!ext4_has_feature_journal(sb)) {
                BUG_ON(journal != NULL);
                return;
        }
        if (jbd2_journal_flush(journal) < 0)
                goto out;
  
 -      if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) &&
 +      if (ext4_has_feature_journal_needs_recovery(sb) &&
            sb->s_flags & MS_RDONLY) {
 -              EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
 +              ext4_clear_feature_journal_needs_recovery(sb);
                ext4_commit_super(sb, 1);
        }
  
@@@ -4382,7 -4737,7 +4382,7 @@@ static void ext4_clear_journal_err(stru
        int j_errno;
        const char *errstr;
  
 -      BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL));
 +      BUG_ON(!ext4_has_feature_journal(sb));
  
        journal = EXT4_SB(sb)->s_journal;
  
@@@ -4497,7 -4852,7 +4497,7 @@@ static int ext4_freeze(struct super_blo
                        goto out;
  
                /* Journal blocked and flushed, clear needs_recovery flag. */
 -              EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
 +              ext4_clear_feature_journal_needs_recovery(sb);
        }
  
        error = ext4_commit_super(sb, 1);
@@@ -4519,7 -4874,7 +4519,7 @@@ static int ext4_unfreeze(struct super_b
  
        if (EXT4_SB(sb)->s_journal) {
                /* Reset the needs_recovery flag before the fs is unlocked. */
 -              EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
 +              ext4_set_feature_journal_needs_recovery(sb);
        }
  
        ext4_commit_super(sb, 1);
@@@ -4672,7 -5027,8 +4672,7 @@@ static int ext4_remount(struct super_bl
                                ext4_mark_recovery_complete(sb, es);
                } else {
                        /* Make sure we can mount this feature set readwrite */
 -                      if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
 -                                      EXT4_FEATURE_RO_COMPAT_READONLY) ||
 +                      if (ext4_has_feature_readonly(sb) ||
                            !ext4_feature_set_ok(sb, 0)) {
                                err = -EROFS;
                                goto restore_opts;
                                if (!ext4_group_desc_csum_verify(sb, g, gdp)) {
                                        ext4_msg(sb, KERN_ERR,
               "ext4_remount: Checksum for group %u failed (%u!=%u)",
 -              g, le16_to_cpu(ext4_group_desc_csum(sbi, g, gdp)),
 +              g, le16_to_cpu(ext4_group_desc_csum(sb, g, gdp)),
                                               le16_to_cpu(gdp->bg_checksum));
 -                                      err = -EINVAL;
 +                                      err = -EFSBADCRC;
                                        goto restore_opts;
                                }
                        }
                        sbi->s_mount_state = le16_to_cpu(es->s_state);
                        if (!ext4_setup_super(sb, es, 0))
                                sb->s_flags &= ~MS_RDONLY;
 -                      if (EXT4_HAS_INCOMPAT_FEATURE(sb,
 -                                                   EXT4_FEATURE_INCOMPAT_MMP))
 +                      if (ext4_has_feature_mmp(sb))
                                if (ext4_multi_mount_protect(sb,
                                                le64_to_cpu(es->s_mmp_block))) {
                                        err = -EROFS;
        if (enable_quota) {
                if (sb_any_quota_suspended(sb))
                        dquot_resume(sb, -1);
 -              else if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
 -                                      EXT4_FEATURE_RO_COMPAT_QUOTA)) {
 +              else if (ext4_has_feature_quota(sb)) {
                        err = ext4_enable_quotas(sb);
                        if (err)
                                goto restore_opts;
@@@ -4897,7 -5255,7 +4897,7 @@@ static int ext4_mark_dquot_dirty(struc
        struct ext4_sb_info *sbi = EXT4_SB(sb);
  
        /* Are we journaling quotas? */
 -      if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA) ||
 +      if (ext4_has_feature_quota(sb) ||
            sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
                dquot_mark_dquot_dirty(dquot);
                return ext4_write_dquot(dquot);
@@@ -4985,7 -5343,7 +4985,7 @@@ static int ext4_quota_enable(struct sup
                le32_to_cpu(EXT4_SB(sb)->s_es->s_grp_quota_inum)
        };
  
 -      BUG_ON(!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA));
 +      BUG_ON(!ext4_has_feature_quota(sb));
  
        if (!qf_inums[type])
                return -EPERM;
@@@ -5179,11 -5537,11 +5179,11 @@@ static inline void unregister_as_ext2(v
  
  static inline int ext2_feature_set_ok(struct super_block *sb)
  {
 -      if (EXT4_HAS_INCOMPAT_FEATURE(sb, ~EXT2_FEATURE_INCOMPAT_SUPP))
 +      if (ext4_has_unknown_ext2_incompat_features(sb))
                return 0;
        if (sb->s_flags & MS_RDONLY)
                return 1;
 -      if (EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT2_FEATURE_RO_COMPAT_SUPP))
 +      if (ext4_has_unknown_ext2_ro_compat_features(sb))
                return 0;
        return 1;
  }
@@@ -5208,13 -5566,13 +5208,13 @@@ static inline void unregister_as_ext3(v
  
  static inline int ext3_feature_set_ok(struct super_block *sb)
  {
 -      if (EXT4_HAS_INCOMPAT_FEATURE(sb, ~EXT3_FEATURE_INCOMPAT_SUPP))
 +      if (ext4_has_unknown_ext3_incompat_features(sb))
                return 0;
 -      if (!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
 +      if (!ext4_has_feature_journal(sb))
                return 0;
        if (sb->s_flags & MS_RDONLY)
                return 1;
 -      if (EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT3_FEATURE_RO_COMPAT_SUPP))
 +      if (ext4_has_unknown_ext3_ro_compat_features(sb))
                return 0;
        return 1;
  }
@@@ -5228,6 -5586,37 +5228,6 @@@ static struct file_system_type ext4_fs_
  };
  MODULE_ALIAS_FS("ext4");
  
 -static int __init ext4_init_feat_adverts(void)
 -{
 -      struct ext4_features *ef;
 -      int ret = -ENOMEM;
 -
 -      ef = kzalloc(sizeof(struct ext4_features), GFP_KERNEL);
 -      if (!ef)
 -              goto out;
 -
 -      ef->f_kobj.kset = ext4_kset;
 -      init_completion(&ef->f_kobj_unregister);
 -      ret = kobject_init_and_add(&ef->f_kobj, &ext4_feat_ktype, NULL,
 -                                 "features");
 -      if (ret) {
 -              kfree(ef);
 -              goto out;
 -      }
 -
 -      ext4_feat = ef;
 -      ret = 0;
 -out:
 -      return ret;
 -}
 -
 -static void ext4_exit_feat_adverts(void)
 -{
 -      kobject_put(&ext4_feat->f_kobj);
 -      wait_for_completion(&ext4_feat->f_kobj_unregister);
 -      kfree(ext4_feat);
 -}
 -
  /* Shared across all ext4 file systems */
  wait_queue_head_t ext4__ioend_wq[EXT4_WQ_HASH_SZ];
  struct mutex ext4__aio_mutex[EXT4_WQ_HASH_SZ];
@@@ -5254,15 -5643,21 +5254,15 @@@ static int __init ext4_init_fs(void
  
        err = ext4_init_pageio();
        if (err)
 -              goto out7;
 +              goto out5;
  
        err = ext4_init_system_zone();
        if (err)
 -              goto out6;
 -      ext4_kset = kset_create_and_add("ext4", NULL, fs_kobj);
 -      if (!ext4_kset) {
 -              err = -ENOMEM;
 -              goto out5;
 -      }
 -      ext4_proc_root = proc_mkdir("fs/ext4", NULL);
 +              goto out4;
  
 -      err = ext4_init_feat_adverts();
 +      err = ext4_init_sysfs();
        if (err)
 -              goto out4;
 +              goto out3;
  
        err = ext4_init_mballoc();
        if (err)
@@@ -5287,12 -5682,16 +5287,12 @@@ out1
        ext4_mballoc_ready = 0;
        ext4_exit_mballoc();
  out2:
 -      ext4_exit_feat_adverts();
 -out4:
 -      if (ext4_proc_root)
 -              remove_proc_entry("fs/ext4", NULL);
 -      kset_unregister(ext4_kset);
 -out5:
 +      ext4_exit_sysfs();
 +out3:
        ext4_exit_system_zone();
 -out6:
 +out4:
        ext4_exit_pageio();
 -out7:
 +out5:
        ext4_exit_es();
  
        return err;
@@@ -5307,7 -5706,9 +5307,7 @@@ static void __exit ext4_exit_fs(void
        unregister_filesystem(&ext4_fs_type);
        destroy_inodecache();
        ext4_exit_mballoc();
 -      ext4_exit_feat_adverts();
 -      remove_proc_entry("fs/ext4", NULL);
 -      kset_unregister(ext4_kset);
 +      ext4_exit_sysfs();
        ext4_exit_system_zone();
        ext4_exit_pageio();
        ext4_exit_es();
diff --combined fs/jffs2/wbuf.c
index 63f31c0733c51e5e1e8cc0b51425dc07bb59cc3e,955da626ba6b7f74d02a7d7dd5badb5e2a031430..f3a4857ff0718794b967836e796b8f9c9e345ae7
@@@ -1264,7 -1264,7 +1264,7 @@@ int jffs2_dataflash_setup(struct jffs2_
        if ((c->flash_size % c->sector_size) != 0) {
                c->flash_size = (c->flash_size / c->sector_size) * c->sector_size;
                pr_warn("flash size adjusted to %dKiB\n", c->flash_size);
-       };
+       }
  
        c->wbuf_ofs = 0xFFFFFFFF;
        c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
  #ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
        c->wbuf_verify = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
        if (!c->wbuf_verify) {
 -              kfree(c->oobbuf);
                kfree(c->wbuf);
                return -ENOMEM;
        }
diff --combined fs/namei.c
index 6f567347f14f750377dae5e22a793fc8d7cded90,3c18970a8899464fc1eaaf3d02585acd2a2a6330..d84d7c7515fc44415f11488f192e52ef3c9c9990
@@@ -1966,7 -1966,7 +1966,7 @@@ OK
                if (err) {
                        const char *s = get_link(nd);
  
 -                      if (unlikely(IS_ERR(s)))
 +                      if (IS_ERR(s))
                                return PTR_ERR(s);
                        err = 0;
                        if (unlikely(!s)) {
@@@ -3380,7 -3380,7 +3380,7 @@@ struct file *do_file_open_root(struct d
                return ERR_PTR(-ELOOP);
  
        filename = getname_kernel(name);
 -      if (unlikely(IS_ERR(filename)))
 +      if (IS_ERR(filename))
                return ERR_CAST(filename);
  
        set_nameidata(&nd, -1, filename);
@@@ -4604,7 -4604,7 +4604,7 @@@ EXPORT_SYMBOL(__page_symlink)
  int page_symlink(struct inode *inode, const char *symname, int len)
  {
        return __page_symlink(inode, symname, len,
-                       !(mapping_gfp_mask(inode->i_mapping) & __GFP_FS));
+                       !mapping_gfp_constraint(inode->i_mapping, __GFP_FS));
  }
  EXPORT_SYMBOL(page_symlink);
  
diff --combined mm/huge_memory.c
index 00cfd1ae2271cf8113475c3c7bc9a07eb687bce7,e1ccc83f73d3b3cdaf0f07fd6db346d44d1d7476..c29ddebc870509e7e35b69da5cce5a7d9988542d
@@@ -116,7 -116,7 +116,7 @@@ static void set_recommended_min_free_kb
        for_each_populated_zone(zone)
                nr_zones++;
  
-       /* Make sure at least 2 hugepages are free for MIGRATE_RESERVE */
+       /* Ensure 2 pageblocks are free to assist fragmentation avoidance */
        recommended_min = pageblock_nr_pages * nr_zones * 2;
  
        /*
@@@ -151,7 -151,7 +151,7 @@@ static int start_stop_khugepaged(void
                if (!khugepaged_thread)
                        khugepaged_thread = kthread_run(khugepaged, NULL,
                                                        "khugepaged");
 -              if (unlikely(IS_ERR(khugepaged_thread))) {
 +              if (IS_ERR(khugepaged_thread)) {
                        pr_err("khugepaged: kthread_run(khugepaged) failed\n");
                        err = PTR_ERR(khugepaged_thread);
                        khugepaged_thread = NULL;
@@@ -786,7 -786,7 +786,7 @@@ static int __do_huge_pmd_anonymous_page
  
  static inline gfp_t alloc_hugepage_gfpmask(int defrag, gfp_t extra_gfp)
  {
-       return (GFP_TRANSHUGE & ~(defrag ? 0 : __GFP_WAIT)) | extra_gfp;
+       return (GFP_TRANSHUGE & ~(defrag ? 0 : __GFP_RECLAIM)) | extra_gfp;
  }
  
  /* Caller must hold page table lock. */
@@@ -1755,8 -1755,7 +1755,7 @@@ static void __split_huge_page_refcount(
                                      (1L << PG_unevictable)));
                page_tail->flags |= (1L << PG_dirty);
  
-               /* clear PageTail before overwriting first_page */
-               smp_wmb();
+               clear_compound_head(page_tail);
  
                if (page_is_young(page))
                        set_page_young(page_tail);
@@@ -2413,8 -2412,7 +2412,7 @@@ static bool khugepaged_prealloc_page(st
  
  static struct page *
  khugepaged_alloc_page(struct page **hpage, gfp_t gfp, struct mm_struct *mm,
-                      struct vm_area_struct *vma, unsigned long address,
-                      int node)
+                      unsigned long address, int node)
  {
        VM_BUG_ON_PAGE(*hpage, *hpage);
  
@@@ -2481,8 -2479,7 +2479,7 @@@ static bool khugepaged_prealloc_page(st
  
  static struct page *
  khugepaged_alloc_page(struct page **hpage, gfp_t gfp, struct mm_struct *mm,
-                      struct vm_area_struct *vma, unsigned long address,
-                      int node)
+                      unsigned long address, int node)
  {
        up_read(&mm->mmap_sem);
        VM_BUG_ON(!*hpage);
@@@ -2530,7 -2527,7 +2527,7 @@@ static void collapse_huge_page(struct m
                __GFP_THISNODE;
  
        /* release the mmap_sem read lock. */
-       new_page = khugepaged_alloc_page(hpage, gfp, mm, vma, address, node);
+       new_page = khugepaged_alloc_page(hpage, gfp, mm, address, node);
        if (!new_page)
                return;