]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'moduleh/module.h-split'
authorStephen Rothwell <sfr@canb.auug.org.au>
Wed, 21 Sep 2011 05:04:27 +0000 (15:04 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Wed, 21 Sep 2011 05:04:43 +0000 (15:04 +1000)
Conflicts:
arch/arm/mach-bcmring/mm.c
arch/powerpc/mm/tlb_nohash.c
drivers/s390/char/vmur.c
drivers/scsi/libfc/fc_lport.c
include/linux/dmaengine.h

247 files changed:
1  2 
arch/arm/common/scoop.c
arch/arm/kernel/armksyms.c
arch/arm/kernel/perf_event.c
arch/arm/kernel/process.c
arch/arm/kernel/setup.c
arch/arm/mach-bcmring/mm.c
arch/arm/mach-davinci/board-dm644x-evm.c
arch/arm/mach-davinci/board-dm646x-evm.c
arch/arm/mach-imx/mach-mx31lilly.c
arch/arm/mach-imx/mach-mx31lite.c
arch/arm/mach-imx/mach-mx31moboard.c
arch/arm/mach-ixp2000/core.c
arch/arm/mach-ixp4xx/common-pci.c
arch/arm/mach-omap1/board-ams-delta.c
arch/arm/mach-omap1/board-sx1.c
arch/arm/mach-omap1/board-voiceblue.c
arch/arm/mach-omap2/board-omap3evm.c
arch/arm/mach-omap2/clockdomain.c
arch/arm/mach-omap2/display.c
arch/arm/mach-omap2/pm.c
arch/arm/mach-omap2/voltage.c
arch/arm/mach-s3c2410/mach-h1940.c
arch/arm/mach-sa1100/jornada720.c
arch/arm/mm/init.c
arch/arm/plat-samsung/dev-ts.c
arch/arm/plat-samsung/platformdata.c
arch/blackfin/mach-bf518/boards/ezbrd.c
arch/blackfin/mach-bf527/boards/ad7160eval.c
arch/blackfin/mach-bf527/boards/ezkit.c
arch/blackfin/mach-bf527/boards/tll6527m.c
arch/blackfin/mach-bf537/boards/dnp5370.c
arch/mips/bcm47xx/gpio.c
arch/mips/bcm47xx/setup.c
arch/mips/kernel/traps.c
arch/mips/kernel/vpe.c
arch/parisc/kernel/pci-dma.c
arch/powerpc/include/asm/machdep.h
arch/powerpc/kernel/dma-iommu.c
arch/powerpc/kernel/dma.c
arch/powerpc/kernel/ibmebus.c
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/smp.c
arch/powerpc/kernel/vio.c
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/mm/mem.c
arch/powerpc/mm/mmu_context_hash64.c
arch/powerpc/mm/numa.c
arch/powerpc/mm/tlb_nohash.c
arch/powerpc/platforms/ps3/system-bus.c
arch/powerpc/platforms/pseries/eeh.c
arch/powerpc/platforms/pseries/iommu.c
arch/powerpc/platforms/pseries/lpar.c
arch/powerpc/sysdev/fsl_rio.c
arch/sparc/kernel/pcic.c
arch/sparc/kernel/setup_64.c
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/pci-dma.c
block/bsg-lib.c
block/ioctl.c
drivers/ata/libata-eh.c
drivers/base/power/common.c
drivers/base/power/main.c
drivers/base/power/runtime.c
drivers/bcma/core.c
drivers/bcma/driver_chipcommon.c
drivers/bcma/driver_chipcommon_pmu.c
drivers/bcma/driver_pci.c
drivers/bcma/main.c
drivers/char/virtio_console.c
drivers/clocksource/sh_cmt.c
drivers/dca/dca-core.c
drivers/dma/intel_mid_dma.c
drivers/dma/ste_dma40.c
drivers/firmware/google/gsmi.c
drivers/gpio/gpio-ep93xx.c
drivers/gpio/gpio-mxc.c
drivers/gpio/gpio-mxs.c
drivers/hid/hid-axff.c
drivers/hid/hid-debug.c
drivers/hid/hid-picolcd.c
drivers/hid/hid-sjoy.c
drivers/hid/usbhid/hid-quirks.c
drivers/i2c/busses/i2c-pxa-pci.c
drivers/i2c/busses/i2c-tegra.c
drivers/input/input-mt.c
drivers/input/input-polldev.c
drivers/input/misc/ad714x.c
drivers/leds/leds-asic3.c
drivers/md/dm-raid.c
drivers/md/md.c
drivers/md/persistent-data/dm-btree-remove.c
drivers/md/persistent-data/dm-btree.c
drivers/md/persistent-data/dm-space-map-disk.c
drivers/md/persistent-data/dm-transaction-manager.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/media/radio/wl128x/fmdrv_v4l2.c
drivers/mfd/ab3550-core.c
drivers/mfd/asic3.c
drivers/mfd/max8997.c
drivers/mfd/twl-core.c
drivers/mfd/twl6030-irq.c
drivers/mfd/wm8400-core.c
drivers/misc/ab8500-pwm.c
drivers/misc/ti-st/st_kim.c
drivers/mmc/core/debugfs.c
drivers/mmc/core/host.c
drivers/mmc/core/mmc_ops.c
drivers/mmc/core/sd.c
drivers/mmc/core/sd_ops.c
drivers/mmc/host/sdhci-tegra.c
drivers/mmc/host/sh_mobile_sdhi.c
drivers/mtd/ar7part.c
drivers/mtd/cmdlinepart.c
drivers/mtd/mtdsuper.c
drivers/mtd/nand/cafe_nand.c
drivers/mtd/nand/cmx270_nand.c
drivers/mtd/nand/diskonchip.c
drivers/mtd/nand/nand_bbt.c
drivers/mtd/nand/omap2.c
drivers/mtd/nand/sm_common.c
drivers/mtd/onenand/onenand_bbt.c
drivers/mtd/redboot.c
drivers/net/ethernet/mellanox/mlx4/alloc.c
drivers/net/ethernet/mellanox/mlx4/catas.c
drivers/net/ethernet/mellanox/mlx4/cmd.c
drivers/net/ethernet/mellanox/mlx4/cq.c
drivers/net/ethernet/mellanox/mlx4/eq.c
drivers/net/ethernet/mellanox/mlx4/fw.c
drivers/net/ethernet/mellanox/mlx4/intf.c
drivers/net/ethernet/mellanox/mlx4/mr.c
drivers/net/ethernet/mellanox/mlx4/pd.c
drivers/net/ethernet/mellanox/mlx4/port.c
drivers/net/ethernet/mellanox/mlx4/qp.c
drivers/net/ethernet/mellanox/mlx4/srq.c
drivers/parisc/sba_iommu.c
drivers/pci/hotplug/pcihp_slot.c
drivers/pci/setup-res.c
drivers/power/max17042_battery.c
drivers/power/max8903_charger.c
drivers/power/max8997_charger.c
drivers/power/max8998_charger.c
drivers/power/power_supply_sysfs.c
drivers/regulator/88pm8607.c
drivers/regulator/mc13783-regulator.c
drivers/regulator/tps6586x-regulator.c
drivers/rtc/interface.c
drivers/s390/char/vmur.c
drivers/s390/cio/qdio_debug.c
drivers/s390/scsi/zfcp_dbf.c
drivers/s390/scsi/zfcp_scsi.c
drivers/scsi/device_handler/scsi_dh.c
drivers/scsi/device_handler/scsi_dh_alua.c
drivers/scsi/libfc/fc_exch.c
drivers/scsi/libfc/fc_lport.c
drivers/scsi/libsas/sas_scsi_host.c
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/megaraid/megaraid_mbox.c
drivers/spi/spi-dw.c
drivers/ssb/main.c
drivers/staging/brcm80211/brcmutil/wifi.c
drivers/staging/iio/industrialio-ring.c
drivers/tty/serial/jsm/jsm_driver.c
drivers/tty/serial/max3107-aava.c
drivers/tty/serial/max3107.c
drivers/uio/uio_pdrv_genirq.c
drivers/usb/core/driver.c
drivers/usb/gadget/composite.c
drivers/usb/gadget/file_storage.c
drivers/usb/gadget/fusb300_udc.c
drivers/usb/host/xhci-hub.c
drivers/usb/wusbcore/wa-hc.c
drivers/video/atmel_lcdfb.c
drivers/video/backlight/ep93xx_bl.c
drivers/video/carminefb.c
drivers/video/mb862xx/mb862xx-i2c.c
drivers/video/mb862xx/mb862xxfbdrv.c
drivers/video/msm/mdp.c
drivers/video/omap2/dss/dispc.c
drivers/video/omap2/dss/dpi.c
drivers/video/omap2/dss/dsi.c
drivers/video/omap2/dss/dss.c
drivers/video/omap2/dss/rfbi.c
drivers/video/omap2/dss/sdi.c
drivers/video/sh_mobile_lcdcfb.c
drivers/w1/w1_family.c
drivers/xen/balloon.c
drivers/xen/swiotlb-xen.c
drivers/xen/xen-selfballoon.c
drivers/xen/xenbus/xenbus_probe.c
drivers/xen/xenbus/xenbus_probe_frontend.c
fs/exofs/super.c
fs/gfs2/ops_fstype.c
fs/logfs/super.c
include/linux/bcma/bcma.h
include/linux/blkdev.h
include/linux/device.h
include/linux/dmaengine.h
include/linux/hid.h
include/linux/mtd/mtd.h
include/linux/pm_runtime.h
include/linux/regulator/driver.h
include/linux/ssb/ssb.h
include/linux/usb.h
include/net/lib80211.h
include/net/sock.h
kernel/async.c
kernel/crash_dump.c
kernel/cred.c
kernel/events/core.c
kernel/fork.c
kernel/futex.c
kernel/kprobes.c
kernel/latencytop.c
kernel/lockdep.c
kernel/pid.c
kernel/power/main.c
kernel/power/suspend.c
kernel/rcupdate.c
kernel/rcutiny.c
kernel/rcutorture.c
kernel/rcutree.c
kernel/rcutree_trace.c
kernel/rtmutex-debug.c
kernel/rtmutex.c
kernel/sched.c
kernel/semaphore.c
kernel/signal.c
kernel/sys.c
kernel/sysctl.c
kernel/trace/blktrace.c
kernel/watchdog.c
kernel/workqueue.c
lib/dma-debug.c
mm/memcontrol.c
mm/swapfile.c
security/selinux/netlink.c
sound/core/control.c
sound/drivers/mpu401/mpu401.c
sound/drivers/mpu401/mpu401_uart.c
sound/pci/als4000.c
sound/usb/midi.c

index 1cde34a080d7e688efbf019aae2e55f8e20895c2,f749e60639eeac7fbad31386ebb405f4188eb3cb..3229323eeb5700ad624a22bd5fb86bf2bb2584f1
@@@ -11,8 -11,8 +11,9 @@@
   *
   */
  
+ #include <linux/export.h>
  #include <linux/device.h>
 +#include <linux/gpio.h>
  #include <linux/string.h>
  #include <linux/slab.h>
  #include <linux/platform_device.h>
Simple merge
index e6e5d7c84f1a4330bc37e9516694f8d1797be8a9,0d6679cb95d9a05eee9b5d0906d7b820c6b71817..24e2347be6b1043ad7cf87f70ab88fe6e9a270c9
   */
  #define pr_fmt(fmt) "hw perfevents: " fmt
  
 +#include <linux/bitmap.h>
  #include <linux/interrupt.h>
  #include <linux/kernel.h>
- #include <linux/module.h>
+ #include <linux/export.h>
  #include <linux/perf_event.h>
  #include <linux/platform_device.h>
  #include <linux/spinlock.h>
Simple merge
Simple merge
index 8616876abb9f92df76fd4a53de0bdc01aefd494b,293b6d3e0d1dbc4824337e820c0f9ff50ac22fee..1adec78ec940ef7a620a23e88752a1f6c0c2d642
@@@ -13,7 -13,7 +13,8 @@@
  *****************************************************************************/
  
  #include <linux/platform_device.h>
 +#include <linux/dma-mapping.h>
+ #include <asm/page.h>
  #include <asm/mach/map.h>
  
  #include <mach/hardware.h>
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 64070ac1e761048caf85bf5fb4ebad2e06b85197,e964cfd3a3d0108fd5967a2d337fd5842eef258f..1f8fdf736e630976bc97fc781d58bfbf85704179
  
  #include <linux/delay.h>
  #include <linux/io.h>
 -#include <linux/clk.h>
  #include <linux/err.h>
+ #include <linux/export.h>
  #include <linux/debugfs.h>
  #include <linux/slab.h>
 +#include <linux/clk.h>
  
  #include <plat/common.h>
  
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 17c3d14d7c4900d5e06c5a0549a27de5db86f06e,0eda3808ee9d444fb667dff87285214154baa1bb..6084dc24b18c0ed20b315dd4522520c833eb15f0
   */
  
  #include <linux/types.h>
+ #include <linux/export.h>
  #include <linux/ssb/ssb.h>
  #include <linux/ssb/ssb_embedded.h>
 +#include <linux/bcma/bcma_soc.h>
  #include <asm/bootinfo.h>
  #include <asm/reboot.h>
  #include <asm/time.h>
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index afc95c7304ae80014ce9e9421d69bfb2f7743d0f,ab06aea8a163d11c889df794808f91e665cdc4e9..f2762556e5efd850a9df6d8041c143fdbf96133f
@@@ -36,7 -36,7 +36,8 @@@
  #include <linux/spinlock.h>
  #include <linux/memblock.h>
  #include <linux/of_fdt.h>
 +#include <linux/hugetlb.h>
+ #include <linux/export.h>
  
  #include <asm/tlbflush.h>
  #include <asm/tlb.h>
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 13c6ec81254582e69eae8b6c69b703370b25fb18,b070bde0582509896d238069963297db40279fb3..ef2e3462702d147375f85d29a04758d9bc4966e1
@@@ -1,6 -1,6 +1,7 @@@
+ #include <linux/export.h>
  #include <linux/init.h>
  #include <linux/bitops.h>
 +#include <linux/elf.h>
  #include <linux/mm.h>
  
  #include <linux/io.h>
Simple merge
diff --cc block/bsg-lib.c
index 6690e6e41037ec305e7b5cd606f96c59fb29fe17,0000000000000000000000000000000000000000..7ad49c88f6b197a04c66e05aab9facacd2781af4
mode 100644,000000..100644
--- /dev/null
@@@ -1,298 -1,0 +1,298 @@@
- #include <linux/module.h>
 +/*
 + *  BSG helper library
 + *
 + *  Copyright (C) 2008   James Smart, Emulex Corporation
 + *  Copyright (C) 2011   Red Hat, Inc.  All rights reserved.
 + *  Copyright (C) 2011   Mike Christie
 + *
 + *  This program is free software; you can redistribute it and/or modify
 + *  it under the terms of the GNU General Public License as published by
 + *  the Free Software Foundation; either version 2 of the License, or
 + *  (at your option) any later version.
 + *
 + *  This program is distributed in the hope that it will be useful,
 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + *  GNU General Public License for more details.
 + *
 + *  You should have received a copy of the GNU General Public License
 + *  along with this program; if not, write to the Free Software
 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + *
 + */
 +#include <linux/slab.h>
 +#include <linux/blkdev.h>
 +#include <linux/delay.h>
 +#include <linux/scatterlist.h>
 +#include <linux/bsg-lib.h>
++#include <linux/export.h>
 +#include <scsi/scsi_cmnd.h>
 +
 +/**
 + * bsg_destroy_job - routine to teardown/delete a bsg job
 + * @job: bsg_job that is to be torn down
 + */
 +static void bsg_destroy_job(struct bsg_job *job)
 +{
 +      put_device(job->dev);   /* release reference for the request */
 +
 +      kfree(job->request_payload.sg_list);
 +      kfree(job->reply_payload.sg_list);
 +      kfree(job);
 +}
 +
 +/**
 + * bsg_job_done - completion routine for bsg requests
 + * @job: bsg_job that is complete
 + * @result: job reply result
 + * @reply_payload_rcv_len: length of payload recvd
 + *
 + * The LLD should call this when the bsg job has completed.
 + */
 +void bsg_job_done(struct bsg_job *job, int result,
 +                unsigned int reply_payload_rcv_len)
 +{
 +      struct request *req = job->req;
 +      struct request *rsp = req->next_rq;
 +      int err;
 +
 +      err = job->req->errors = result;
 +      if (err < 0)
 +              /* we're only returning the result field in the reply */
 +              job->req->sense_len = sizeof(u32);
 +      else
 +              job->req->sense_len = job->reply_len;
 +      /* we assume all request payload was transferred, residual == 0 */
 +      req->resid_len = 0;
 +
 +      if (rsp) {
 +              WARN_ON(reply_payload_rcv_len > rsp->resid_len);
 +
 +              /* set reply (bidi) residual */
 +              rsp->resid_len -= min(reply_payload_rcv_len, rsp->resid_len);
 +      }
 +      blk_complete_request(req);
 +}
 +EXPORT_SYMBOL_GPL(bsg_job_done);
 +
 +/**
 + * bsg_softirq_done - softirq done routine for destroying the bsg requests
 + * @rq: BSG request that holds the job to be destroyed
 + */
 +static void bsg_softirq_done(struct request *rq)
 +{
 +      struct bsg_job *job = rq->special;
 +
 +      blk_end_request_all(rq, rq->errors);
 +      bsg_destroy_job(job);
 +}
 +
 +static int bsg_map_buffer(struct bsg_buffer *buf, struct request *req)
 +{
 +      size_t sz = (sizeof(struct scatterlist) * req->nr_phys_segments);
 +
 +      BUG_ON(!req->nr_phys_segments);
 +
 +      buf->sg_list = kzalloc(sz, GFP_KERNEL);
 +      if (!buf->sg_list)
 +              return -ENOMEM;
 +      sg_init_table(buf->sg_list, req->nr_phys_segments);
 +      buf->sg_cnt = blk_rq_map_sg(req->q, req, buf->sg_list);
 +      buf->payload_len = blk_rq_bytes(req);
 +      return 0;
 +}
 +
 +/**
 + * bsg_create_job - create the bsg_job structure for the bsg request
 + * @dev: device that is being sent the bsg request
 + * @req: BSG request that needs a job structure
 + */
 +static int bsg_create_job(struct device *dev, struct request *req)
 +{
 +      struct request *rsp = req->next_rq;
 +      struct request_queue *q = req->q;
 +      struct bsg_job *job;
 +      int ret;
 +
 +      BUG_ON(req->special);
 +
 +      job = kzalloc(sizeof(struct bsg_job) + q->bsg_job_size, GFP_KERNEL);
 +      if (!job)
 +              return -ENOMEM;
 +
 +      req->special = job;
 +      job->req = req;
 +      if (q->bsg_job_size)
 +              job->dd_data = (void *)&job[1];
 +      job->request = req->cmd;
 +      job->request_len = req->cmd_len;
 +      job->reply = req->sense;
 +      job->reply_len = SCSI_SENSE_BUFFERSIZE; /* Size of sense buffer
 +                                               * allocated */
 +      if (req->bio) {
 +              ret = bsg_map_buffer(&job->request_payload, req);
 +              if (ret)
 +                      goto failjob_rls_job;
 +      }
 +      if (rsp && rsp->bio) {
 +              ret = bsg_map_buffer(&job->reply_payload, rsp);
 +              if (ret)
 +                      goto failjob_rls_rqst_payload;
 +      }
 +      job->dev = dev;
 +      /* take a reference for the request */
 +      get_device(job->dev);
 +      return 0;
 +
 +failjob_rls_rqst_payload:
 +      kfree(job->request_payload.sg_list);
 +failjob_rls_job:
 +      kfree(job);
 +      return -ENOMEM;
 +}
 +
 +/*
 + * bsg_goose_queue - restart queue in case it was stopped
 + * @q: request q to be restarted
 + */
 +void bsg_goose_queue(struct request_queue *q)
 +{
 +      if (!q)
 +              return;
 +
 +      blk_run_queue_async(q);
 +}
 +EXPORT_SYMBOL_GPL(bsg_goose_queue);
 +
 +/**
 + * bsg_request_fn - generic handler for bsg requests
 + * @q: request queue to manage
 + *
 + * On error the create_bsg_job function should return a -Exyz error value
 + * that will be set to the req->errors.
 + *
 + * Drivers/subsys should pass this to the queue init function.
 + */
 +void bsg_request_fn(struct request_queue *q)
 +{
 +      struct device *dev = q->queuedata;
 +      struct request *req;
 +      struct bsg_job *job;
 +      int ret;
 +
 +      if (!get_device(dev))
 +              return;
 +
 +      while (1) {
 +              req = blk_fetch_request(q);
 +              if (!req)
 +                      break;
 +              spin_unlock_irq(q->queue_lock);
 +
 +              ret = bsg_create_job(dev, req);
 +              if (ret) {
 +                      req->errors = ret;
 +                      blk_end_request_all(req, ret);
 +                      spin_lock_irq(q->queue_lock);
 +                      continue;
 +              }
 +
 +              job = req->special;
 +              ret = q->bsg_job_fn(job);
 +              spin_lock_irq(q->queue_lock);
 +              if (ret)
 +                      break;
 +      }
 +
 +      spin_unlock_irq(q->queue_lock);
 +      put_device(dev);
 +      spin_lock_irq(q->queue_lock);
 +}
 +EXPORT_SYMBOL_GPL(bsg_request_fn);
 +
 +/**
 + * bsg_setup_queue - Create and add the bsg hooks so we can receive requests
 + * @dev: device to attach bsg device to
 + * @q: request queue setup by caller
 + * @name: device to give bsg device
 + * @job_fn: bsg job handler
 + * @dd_job_size: size of LLD data needed for each job
 + *
 + * The caller should have setup the reuqest queue with bsg_request_fn
 + * as the request_fn.
 + */
 +int bsg_setup_queue(struct device *dev, struct request_queue *q,
 +                  char *name, bsg_job_fn *job_fn, int dd_job_size)
 +{
 +      int ret;
 +
 +      q->queuedata = dev;
 +      q->bsg_job_size = dd_job_size;
 +      q->bsg_job_fn = job_fn;
 +      queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
 +      blk_queue_softirq_done(q, bsg_softirq_done);
 +      blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT);
 +
 +      ret = bsg_register_queue(q, dev, name, NULL);
 +      if (ret) {
 +              printk(KERN_ERR "%s: bsg interface failed to "
 +                     "initialize - register queue\n", dev->kobj.name);
 +              return ret;
 +      }
 +
 +      return 0;
 +}
 +EXPORT_SYMBOL_GPL(bsg_setup_queue);
 +
 +/**
 + * bsg_remove_queue - Deletes the bsg dev from the q
 + * @q:        the request_queue that is to be torn down.
 + *
 + * Notes:
 + *   Before unregistering the queue empty any requests that are blocked
 + */
 +void bsg_remove_queue(struct request_queue *q)
 +{
 +      struct request *req; /* block request */
 +      int counts; /* totals for request_list count and starved */
 +
 +      if (!q)
 +              return;
 +
 +      /* Stop taking in new requests */
 +      spin_lock_irq(q->queue_lock);
 +      blk_stop_queue(q);
 +
 +      /* drain all requests in the queue */
 +      while (1) {
 +              /* need the lock to fetch a request
 +               * this may fetch the same reqeust as the previous pass
 +               */
 +              req = blk_fetch_request(q);
 +              /* save requests in use and starved */
 +              counts = q->rq.count[0] + q->rq.count[1] +
 +                       q->rq.starved[0] + q->rq.starved[1];
 +              spin_unlock_irq(q->queue_lock);
 +              /* any requests still outstanding? */
 +              if (counts == 0)
 +                      break;
 +
 +              /* This may be the same req as the previous iteration,
 +               * always send the blk_end_request_all after a prefetch.
 +               * It is not okay to not end the request because the
 +               * prefetch started the request.
 +               */
 +              if (req) {
 +                      /* return -ENXIO to indicate that this queue is
 +                       * going away
 +                       */
 +                      req->errors = -ENXIO;
 +                      blk_end_request_all(req, -ENXIO);
 +              }
 +
 +              msleep(200); /* allow bsg to possibly finish */
 +              spin_lock_irq(q->queue_lock);
 +      }
 +      bsg_unregister_queue(q);
 +}
 +EXPORT_SYMBOL_GPL(bsg_remove_queue);
diff --cc block/ioctl.c
Simple merge
Simple merge
index 29820c3961823bdc6dbfe5d6061f1100d4c21161,0000000000000000000000000000000000000000..4af7c1cbf909b61d576bc0900df85983d2eedf9d
mode 100644,000000..100644
--- /dev/null
@@@ -1,86 -1,0 +1,86 @@@
- #include <linux/module.h>
 +/*
 + * drivers/base/power/common.c - Common device power management code.
 + *
 + * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
 + *
 + * This file is released under the GPLv2.
 + */
 +
 +#include <linux/init.h>
 +#include <linux/kernel.h>
++#include <linux/export.h>
 +#include <linux/slab.h>
 +#include <linux/pm_clock.h>
 +
 +/**
 + * dev_pm_get_subsys_data - Create or refcount power.subsys_data for device.
 + * @dev: Device to handle.
 + *
 + * If power.subsys_data is NULL, point it to a new object, otherwise increment
 + * its reference counter.  Return 1 if a new object has been created, otherwise
 + * return 0 or error code.
 + */
 +int dev_pm_get_subsys_data(struct device *dev)
 +{
 +      struct pm_subsys_data *psd;
 +      int ret = 0;
 +
 +      psd = kzalloc(sizeof(*psd), GFP_KERNEL);
 +      if (!psd)
 +              return -ENOMEM;
 +
 +      spin_lock_irq(&dev->power.lock);
 +
 +      if (dev->power.subsys_data) {
 +              dev->power.subsys_data->refcount++;
 +      } else {
 +              spin_lock_init(&psd->lock);
 +              psd->refcount = 1;
 +              dev->power.subsys_data = psd;
 +              pm_clk_init(dev);
 +              psd = NULL;
 +              ret = 1;
 +      }
 +
 +      spin_unlock_irq(&dev->power.lock);
 +
 +      /* kfree() verifies that its argument is nonzero. */
 +      kfree(psd);
 +
 +      return ret;
 +}
 +EXPORT_SYMBOL_GPL(dev_pm_get_subsys_data);
 +
 +/**
 + * dev_pm_put_subsys_data - Drop reference to power.subsys_data.
 + * @dev: Device to handle.
 + *
 + * If the reference counter of power.subsys_data is zero after dropping the
 + * reference, power.subsys_data is removed.  Return 1 if that happens or 0
 + * otherwise.
 + */
 +int dev_pm_put_subsys_data(struct device *dev)
 +{
 +      struct pm_subsys_data *psd;
 +      int ret = 0;
 +
 +      spin_lock_irq(&dev->power.lock);
 +
 +      psd = dev_to_psd(dev);
 +      if (!psd) {
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
 +      if (--psd->refcount == 0) {
 +              dev->power.subsys_data = NULL;
 +              kfree(psd);
 +              ret = 1;
 +      }
 +
 + out:
 +      spin_unlock_irq(&dev->power.lock);
 +
 +      return ret;
 +}
 +EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);
Simple merge
Simple merge
Simple merge
Simple merge
index 2968d809d49f8357cae15ef644cdd5a81cbe0a5a,fcc63db0ce7542ded6428071103315370dda11cb..800163c8c2e7a046a4aa1219e6d7c876be0be19b
@@@ -9,49 -9,22 +9,50 @@@
   */
  
  #include "bcma_private.h"
++#include <linux/export.h>
  #include <linux/bcma/bcma.h>
  
 -static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
 -                                      u32 offset, u32 mask, u32 set)
 +static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
  {
 -      u32 value;
 +      bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
 +      bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
 +      return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
 +}
  
 -      bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
 +void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value)
 +{
 +      bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
 +      bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
 +      bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value);
 +}
 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_write);
 +
 +void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
 +                           u32 set)
 +{
 +      bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
 +      bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
 +      bcma_cc_maskset32(cc, BCMA_CC_PLLCTL_DATA, mask, set);
 +}
 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_maskset);
 +
 +void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
 +                               u32 offset, u32 mask, u32 set)
 +{
        bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
        bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
 -      value = bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
 -      value &= mask;
 -      value |= set;
 -      bcma_cc_write32(cc, BCMA_CC_CHIPCTL_DATA, value);
 -      bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
 +      bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL_DATA, mask, set);
 +}
 +EXPORT_SYMBOL_GPL(bcma_chipco_chipctl_maskset);
 +
 +void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
 +                              u32 set)
 +{
 +      bcma_cc_write32(cc, BCMA_CC_REGCTL_ADDR, offset);
 +      bcma_cc_read32(cc, BCMA_CC_REGCTL_ADDR);
 +      bcma_cc_maskset32(cc, BCMA_CC_REGCTL_DATA, mask, set);
  }
 +EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
  
  static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
  {
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index b588f8a41e601dfae772ee53570eec068bf5e78c,73a177b92e84d417e220067429749982552d5ff9..0f189b34bda3bcb2c726f78fdfc086414f5fd61c
  #include <linux/basic_mmio_gpio.h>
  #include <linux/of.h>
  #include <linux/of_device.h>
+ #include <linux/module.h>
  #include <asm-generic/bug.h>
  
 +#define irq_to_gpio(irq)      ((irq) - MXC_GPIO_IRQ_START)
 +
  enum mxc_gpio_hwtype {
        IMX1_GPIO,      /* runs on i.mx1 */
        IMX21_GPIO,     /* runs on i.mx21 and i.mx27 */
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc drivers/md/md.c
Simple merge
index cdd71d67def94ddf1feb485c331fbc1d312ab2d8,0000000000000000000000000000000000000000..e7071f66dc39d18b0b241a7a5ee44b244991d6b7
mode 100644,000000..100644
--- /dev/null
@@@ -1,571 -1,0 +1,571 @@@
- #include <linux/module.h>
 +/*
 + * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
 + *
 + * This file is released under the GPL.
 + */
 +
 +#include "dm-btree.h"
 +#include "dm-btree-internal.h"
 +#include "dm-transaction-manager.h"
 +
++#include <linux/export.h>
 +
 +/*
 + * Removing an entry from a btree
 + * ==============================
 + *
 + * A very important constraint for our btree is that no node, except the
 + * root, may have fewer than a certain number of entries.
 + * (MIN_ENTRIES <= nr_entries <= MAX_ENTRIES).
 + *
 + * Ensuring this is complicated by the way we want to only ever hold the
 + * locks on 2 nodes concurrently, and only change nodes in a top to bottom
 + * fashion.
 + *
 + * Each node may have a left or right sibling.  When decending the spine,
 + * if a node contains only MIN_ENTRIES then we try and increase this to at
 + * least MIN_ENTRIES + 1.  We do this in the following ways:
 + *
 + * [A] No siblings => this can only happen if the node is the root, in which
 + *     case we copy the childs contents over the root.
 + *
 + * [B] No left sibling
 + *     ==> rebalance(node, right sibling)
 + *
 + * [C] No right sibling
 + *     ==> rebalance(left sibling, node)
 + *
 + * [D] Both siblings, total_entries(left, node, right) <= DEL_THRESHOLD
 + *     ==> delete node adding it's contents to left and right
 + *
 + * [E] Both siblings, total_entries(left, node, right) > DEL_THRESHOLD
 + *     ==> rebalance(left, node, right)
 + *
 + * After these operations it's possible that the our original node no
 + * longer contains the desired sub tree.  For this reason this rebalancing
 + * is performed on the children of the current node.  This also avoids
 + * having a special case for the root.
 + *
 + * Once this rebalancing has occurred we can then step into the child node
 + * for internal nodes.  Or delete the entry for leaf nodes.
 + */
 +
 +/*
 + * Some little utilities for moving node data around.
 + */
 +static void node_shift(struct node *n, int shift)
 +{
 +      uint32_t nr_entries = le32_to_cpu(n->header.nr_entries);
 +
 +      if (shift < 0) {
 +              shift = -shift;
 +              memmove(key_ptr(n, 0),
 +                      key_ptr(n, shift),
 +                      (nr_entries - shift) * sizeof(__le64));
 +              memmove(value_ptr(n, 0, sizeof(__le64)),
 +                      value_ptr(n, shift, sizeof(__le64)),
 +                      (nr_entries - shift) * sizeof(__le64));
 +      } else {
 +              memmove(key_ptr(n, shift),
 +                      key_ptr(n, 0),
 +                      nr_entries * sizeof(__le64));
 +              memmove(value_ptr(n, shift, sizeof(__le64)),
 +                      value_ptr(n, 0, sizeof(__le64)),
 +                      nr_entries * sizeof(__le64));
 +      }
 +}
 +
 +static void node_copy(struct node *left, struct node *right, int shift)
 +{
 +      uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
 +
 +      if (shift < 0) {
 +              shift = -shift;
 +              memcpy(key_ptr(left, nr_left),
 +                     key_ptr(right, 0),
 +                     shift * sizeof(__le64));
 +              memcpy(value_ptr(left, nr_left, sizeof(__le64)),
 +                     value_ptr(right, 0, sizeof(__le64)),
 +                     shift * sizeof(__le64));
 +      } else {
 +              memcpy(key_ptr(right, 0),
 +                     key_ptr(left, nr_left - shift),
 +                     shift * sizeof(__le64));
 +              memcpy(value_ptr(right, 0, sizeof(__le64)),
 +                     value_ptr(left, nr_left - shift, sizeof(__le64)),
 +                     shift * sizeof(__le64));
 +      }
 +}
 +
 +/*
 + * Delete a specific entry from a leaf node.
 + */
 +static void delete_at(struct node *n, unsigned index, size_t value_size)
 +{
 +      unsigned nr_entries = le32_to_cpu(n->header.nr_entries);
 +      unsigned nr_to_copy = nr_entries - (index + 1);
 +
 +      if (nr_to_copy) {
 +              memmove(key_ptr(n, index),
 +                      key_ptr(n, index + 1),
 +                      nr_to_copy * sizeof(__le64));
 +
 +              memmove(value_ptr(n, index, value_size),
 +                      value_ptr(n, index + 1, value_size),
 +                      nr_to_copy * value_size);
 +      }
 +
 +      n->header.nr_entries = cpu_to_le32(nr_entries - 1);
 +}
 +
 +static unsigned del_threshold(struct node *n)
 +{
 +      return le32_to_cpu(n->header.max_entries) / 3;
 +}
 +
 +static unsigned merge_threshold(struct node *n)
 +{
 +      /*
 +       * The extra one is because we know we're potentially going to
 +       * delete an entry.
 +       */
 +      return 2 * (le32_to_cpu(n->header.max_entries) / 3) + 1;
 +}
 +
 +struct child {
 +      unsigned index;
 +      struct dm_block *block;
 +      struct node *n;
 +};
 +
 +static struct dm_btree_value_type le64_type = {
 +      .context = NULL,
 +      .size = sizeof(__le64),
 +      .inc = NULL,
 +      .dec = NULL,
 +      .equal = NULL
 +};
 +
 +static int init_child(struct dm_btree_info *info, struct node *parent,
 +                    unsigned index, struct child *result)
 +{
 +      int r, inc;
 +      dm_block_t root;
 +
 +      result->index = index;
 +      root = value64(parent, index);
 +
 +      r = dm_tm_shadow_block(info->tm, root, &btree_node_validator,
 +                             &result->block, &inc);
 +      if (r)
 +              return r;
 +
 +      result->n = dm_block_data(result->block);
 +
 +      if (inc)
 +              inc_children(info->tm, result->n, &le64_type);
 +
 +      return 0;
 +}
 +
 +static int exit_child(struct dm_btree_info *info, struct child *c)
 +{
 +      return dm_tm_unlock(info->tm, c->block);
 +}
 +
 +static void shift(struct node *left, struct node *right, int count)
 +{
 +      if (!count)
 +              return;
 +
 +      if (count > 0) {
 +              node_shift(right, count);
 +              node_copy(left, right, count);
 +      } else {
 +              node_copy(left, right, count);
 +              node_shift(right, count);
 +      }
 +
 +      left->header.nr_entries =
 +              cpu_to_le32(le32_to_cpu(left->header.nr_entries) - count);
 +
 +      right->header.nr_entries =
 +              cpu_to_le32(le32_to_cpu(right->header.nr_entries) + count);
 +}
 +
 +static void __rebalance2(struct dm_btree_info *info, struct node *parent,
 +                       struct child *l, struct child *r)
 +{
 +      struct node *left = l->n;
 +      struct node *right = r->n;
 +      uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
 +      uint32_t nr_right = le32_to_cpu(right->header.nr_entries);
 +
 +      if (nr_left + nr_right <= merge_threshold(left)) {
 +              /*
 +               * Merge
 +               */
 +              node_copy(left, right, -nr_right);
 +              left->header.nr_entries = cpu_to_le32(nr_left + nr_right);
 +
 +              *((__le64 *) value_ptr(parent, l->index, sizeof(__le64))) =
 +                      cpu_to_le64(dm_block_location(l->block));
 +              delete_at(parent, r->index, sizeof(__le64));
 +
 +              /*
 +               * We need to decrement the right block, but not it's
 +               * children, since they're still referenced by left.
 +               */
 +              dm_tm_dec(info->tm, dm_block_location(r->block));
 +      } else {
 +              /*
 +               * Rebalance.
 +               */
 +              unsigned target_left = (nr_left + nr_right) / 2;
 +
 +              shift(left, right, nr_left - target_left);
 +              *((__le64 *) value_ptr(parent, l->index, sizeof(__le64))) =
 +                      cpu_to_le64(dm_block_location(l->block));
 +              *((__le64 *) value_ptr(parent, r->index, sizeof(__le64))) =
 +                      cpu_to_le64(dm_block_location(r->block));
 +              *key_ptr(parent, r->index) = right->keys[0];
 +      }
 +}
 +
 +static int rebalance2(struct shadow_spine *s, struct dm_btree_info *info,
 +                    unsigned left_index)
 +{
 +      int r;
 +      struct node *parent;
 +      struct child left, right;
 +
 +      parent = dm_block_data(shadow_current(s));
 +
 +      r = init_child(info, parent, left_index, &left);
 +      if (r)
 +              return r;
 +
 +      r = init_child(info, parent, left_index + 1, &right);
 +      if (r) {
 +              exit_child(info, &left);
 +              return r;
 +      }
 +
 +      __rebalance2(info, parent, &left, &right);
 +
 +      r = exit_child(info, &left);
 +      if (r) {
 +              exit_child(info, &right);
 +              return r;
 +      }
 +
 +      r = exit_child(info, &right);
 +      if (r)
 +              return r;
 +
 +      return 0;
 +}
 +
 +static void __rebalance3(struct dm_btree_info *info, struct node *parent,
 +                       struct child *l, struct child *c, struct child *r)
 +{
 +      struct node *left = l->n;
 +      struct node *center = c->n;
 +      struct node *right = r->n;
 +
 +      uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
 +      uint32_t nr_center = le32_to_cpu(center->header.nr_entries);
 +      uint32_t nr_right = le32_to_cpu(right->header.nr_entries);
 +      uint32_t max_entries = le32_to_cpu(left->header.max_entries);
 +
 +      unsigned target;
 +
 +      if (((nr_left + nr_center + nr_right) / 2) < merge_threshold(center)) {
 +              /*
 +               * Delete center node:
 +               *
 +               * We dump as many entries from center as possible into
 +               * left, then the rest in right, then rebalance2.  This
 +               * wastes some cpu, but I want something simple atm.
 +               */
 +              unsigned shift = min(max_entries - nr_left, nr_center);
 +
 +              node_copy(left, center, -shift);
 +              left->header.nr_entries = cpu_to_le32(nr_left + shift);
 +
 +              if (shift != nr_center) {
 +                      shift = nr_center - shift;
 +                      node_shift(right, shift);
 +                      node_copy(center, right, shift);
 +                      right->header.nr_entries = cpu_to_le32(nr_right + shift);
 +              }
 +
 +              *((__le64 *) value_ptr(parent, l->index, sizeof(__le64))) =
 +                      cpu_to_le64(dm_block_location(l->block));
 +              *((__le64 *) value_ptr(parent, r->index, sizeof(__le64))) =
 +                      cpu_to_le64(dm_block_location(r->block));
 +              *key_ptr(parent, r->index) = right->keys[0];
 +
 +              delete_at(parent, c->index, sizeof(__le64));
 +              r->index--;
 +
 +              dm_tm_dec(info->tm, dm_block_location(c->block));
 +              __rebalance2(info, parent, l, r);
 +
 +              return;
 +      }
 +
 +      /*
 +       * Rebalance
 +       */
 +      target = (nr_left + nr_center + nr_right) / 3;
 +      BUG_ON(target == nr_center);
 +
 +      /*
 +       * Adjust the left node
 +       */
 +      shift(left, center, nr_left - target);
 +
 +      /*
 +       * Adjust the right node
 +       */
 +      shift(center, right, target - nr_right);
 +
 +      *((__le64 *) value_ptr(parent, l->index, sizeof(__le64))) =
 +              cpu_to_le64(dm_block_location(l->block));
 +      *((__le64 *) value_ptr(parent, c->index, sizeof(__le64))) =
 +              cpu_to_le64(dm_block_location(c->block));
 +      *((__le64 *) value_ptr(parent, r->index, sizeof(__le64))) =
 +              cpu_to_le64(dm_block_location(r->block));
 +
 +      *key_ptr(parent, c->index) = center->keys[0];
 +      *key_ptr(parent, r->index) = right->keys[0];
 +}
 +
 +static int rebalance3(struct shadow_spine *s, struct dm_btree_info *info,
 +                    unsigned left_index)
 +{
 +      int r;
 +      struct node *parent = dm_block_data(shadow_current(s));
 +      struct child left, center, right;
 +
 +      /*
 +       * FIXME: fill out an array?
 +       */
 +      r = init_child(info, parent, left_index, &left);
 +      if (r)
 +              return r;
 +
 +      r = init_child(info, parent, left_index + 1, &center);
 +      if (r) {
 +              exit_child(info, &left);
 +              return r;
 +      }
 +
 +      r = init_child(info, parent, left_index + 2, &right);
 +      if (r) {
 +              exit_child(info, &left);
 +              exit_child(info, &center);
 +              return r;
 +      }
 +
 +      __rebalance3(info, parent, &left, &center, &right);
 +
 +      r = exit_child(info, &left);
 +      if (r) {
 +              exit_child(info, &center);
 +              exit_child(info, &right);
 +              return r;
 +      }
 +
 +      r = exit_child(info, &center);
 +      if (r) {
 +              exit_child(info, &right);
 +              return r;
 +      }
 +
 +      r = exit_child(info, &right);
 +      if (r)
 +              return r;
 +
 +      return 0;
 +}
 +
 +static int get_nr_entries(struct dm_transaction_manager *tm,
 +                        dm_block_t b, uint32_t *result)
 +{
 +      int r;
 +      struct dm_block *block;
 +      struct node *n;
 +
 +      r = dm_tm_read_lock(tm, b, &btree_node_validator, &block);
 +      if (r)
 +              return r;
 +
 +      n = dm_block_data(block);
 +      *result = le32_to_cpu(n->header.nr_entries);
 +
 +      return dm_tm_unlock(tm, block);
 +}
 +
 +static int rebalance_children(struct shadow_spine *s,
 +                            struct dm_btree_info *info, uint64_t key)
 +{
 +      int i, r, has_left_sibling, has_right_sibling;
 +      uint32_t child_entries;
 +      struct node *n;
 +
 +      n = dm_block_data(shadow_current(s));
 +
 +      if (le32_to_cpu(n->header.nr_entries) == 1) {
 +              struct dm_block *child;
 +              dm_block_t b = value64(n, 0);
 +
 +              r = dm_tm_read_lock(info->tm, b, &btree_node_validator, &child);
 +              if (r)
 +                      return r;
 +
 +              memcpy(n, dm_block_data(child),
 +                     dm_bm_block_size(dm_tm_get_bm(info->tm)));
 +              r = dm_tm_unlock(info->tm, child);
 +              dm_tm_dec(info->tm, dm_block_location(child));
 +
 +              return r;
 +      }
 +
 +      i = lower_bound(n, key);
 +      if (i < 0)
 +              return -ENODATA;
 +
 +      r = get_nr_entries(info->tm, value64(n, i), &child_entries);
 +      if (r)
 +              return r;
 +
 +      if (child_entries > del_threshold(n))
 +              return 0;
 +
 +      has_left_sibling = i > 0 ? 1 : 0;
 +      has_right_sibling =
 +              (i >= (le32_to_cpu(n->header.nr_entries) - 1)) ? 0 : 1;
 +
 +      if (!has_left_sibling)
 +              r = rebalance2(s, info, i);
 +
 +      else if (!has_right_sibling)
 +              r = rebalance2(s, info, i - 1);
 +
 +      else
 +              r = rebalance3(s, info, i - 1);
 +
 +      return r;
 +}
 +
 +static int do_leaf(struct node *n, uint64_t key, unsigned *index)
 +{
 +      int i = lower_bound(n, key);
 +
 +      if ((i < 0) ||
 +          (i >= le32_to_cpu(n->header.nr_entries)) ||
 +          (le64_to_cpu(n->keys[i]) != key))
 +              return -ENODATA;
 +
 +      *index = i;
 +
 +      return 0;
 +}
 +
 +/*
 + * Prepares for removal from one level of the hierarchy.  The caller must
 + * actually call delete_at() to remove the entry at index.
 + */
 +static int remove_raw(struct shadow_spine *s, struct dm_btree_info *info,
 +                    struct dm_btree_value_type *vt, dm_block_t root,
 +                    uint64_t key, unsigned *index)
 +{
 +      int i = *index, inc, r;
 +      struct node *n;
 +
 +      for (;;) {
 +              r = shadow_step(s, root, vt, &inc);
 +              if (r < 0)
 +                      break;
 +
 +              /*
 +               * We have to patch up the parent node, ugly, but I don't
 +               * see a way to do this automatically as part of the spine
 +               * op.
 +               */
 +              if (shadow_has_parent(s)) {
 +                      __le64 location = cpu_to_le64(dm_block_location(shadow_current(s)));
 +                      memcpy(value_ptr(dm_block_data(shadow_parent(s)), i, sizeof(uint64_t)),
 +                             &location, sizeof(__le64));
 +              }
 +
 +              n = dm_block_data(shadow_current(s));
 +              if (inc)
 +                      inc_children(info->tm, n, vt);
 +
 +              if (le32_to_cpu(n->header.flags) & LEAF_NODE)
 +                      return do_leaf(n, key, index);
 +
 +              r = rebalance_children(s, info, key);
 +              if (r)
 +                      break;
 +
 +              n = dm_block_data(shadow_current(s));
 +              if (le32_to_cpu(n->header.flags) & LEAF_NODE)
 +                      return do_leaf(n, key, index);
 +
 +              i = lower_bound(n, key);
 +
 +              /*
 +               * We know the key is present, or else
 +               * rebalance_children would have returned
 +               * -ENODATA
 +               */
 +              root = value64(n, i);
 +      }
 +
 +      return r;
 +}
 +
 +int dm_btree_remove(struct dm_btree_info *info, dm_block_t root,
 +                  uint64_t *keys, dm_block_t *new_root)
 +{
 +      unsigned level, last_level = info->levels - 1;
 +      int index = 0, r = 0;
 +      struct shadow_spine spine;
 +      struct node *n;
 +
 +      init_shadow_spine(&spine, info);
 +      for (level = 0; level < info->levels; level++) {
 +              r = remove_raw(&spine, info,
 +                             (level == last_level ?
 +                              &info->value_type : &le64_type),
 +                             root, keys[level], (unsigned *)&index);
 +              if (r < 0)
 +                      break;
 +
 +              n = dm_block_data(shadow_current(&spine));
 +              if (level != last_level) {
 +                      root = value64(n, index);
 +                      continue;
 +              }
 +
 +              BUG_ON(index < 0 || index >= le32_to_cpu(n->header.nr_entries));
 +
 +              if (info->value_type.dec)
 +                      info->value_type.dec(info->value_type.context,
 +                                           value_ptr(n, index, info->value_type.size));
 +
 +              delete_at(n, index, info->value_type.size);
 +
 +              r = 0;
 +              *new_root = shadow_root(&spine);
 +      }
 +
 +      exit_shadow_spine(&spine);
 +
 +      return r;
 +}
 +EXPORT_SYMBOL_GPL(dm_btree_remove);
index ca16d5b4799a3704af61403de304b3899b37b3c5,0000000000000000000000000000000000000000..408b762532a777659905ca4870dc58b131b48396
mode 100644,000000..100644
--- /dev/null
@@@ -1,861 -1,0 +1,861 @@@
- #include <linux/module.h>
 +/*
 + * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
 + *
 + * This file is released under the GPL.
 + */
 +
 +#include "dm-btree-internal.h"
 +#include "dm-space-map.h"
 +#include "dm-transaction-manager.h"
 +
++#include <linux/export.h>
 +#include <linux/device-mapper.h>
 +
 +#define DM_MSG_PREFIX "btree"
 +
 +/*----------------------------------------------------------------
 + * Array manipulation
 + *--------------------------------------------------------------*/
 +static void memcpy_disk(void *dest, const void *src, size_t len)
 +      __dm_written_to_disk(src)
 +{
 +      memcpy(dest, src, len);
 +      __dm_unbless_for_disk(src);
 +}
 +
 +static void array_insert(void *base, size_t elt_size, unsigned nr_elts,
 +                       unsigned index, void *elt)
 +      __dm_written_to_disk(elt)
 +{
 +      if (index < nr_elts)
 +              memmove(base + (elt_size * (index + 1)),
 +                      base + (elt_size * index),
 +                      (nr_elts - index) * elt_size);
 +
 +      memcpy_disk(base + (elt_size * index), elt, elt_size);
 +}
 +
 +/*----------------------------------------------------------------*/
 +
 +/* makes the assumption that no two keys are the same. */
 +static int bsearch(struct node *n, uint64_t key, int want_hi)
 +{
 +      int lo = -1, hi = le32_to_cpu(n->header.nr_entries);
 +
 +      while (hi - lo > 1) {
 +              int mid = lo + ((hi - lo) / 2);
 +              uint64_t mid_key = le64_to_cpu(n->keys[mid]);
 +
 +              if (mid_key == key)
 +                      return mid;
 +
 +              if (mid_key < key)
 +                      lo = mid;
 +              else
 +                      hi = mid;
 +      }
 +
 +      return want_hi ? hi : lo;
 +}
 +
 +int lower_bound(struct node *n, uint64_t key)
 +{
 +      return bsearch(n, key, 0);
 +}
 +
 +void inc_children(struct dm_transaction_manager *tm, struct node *n,
 +                struct dm_btree_value_type *vt)
 +{
 +      unsigned i;
 +      uint32_t nr_entries = le32_to_cpu(n->header.nr_entries);
 +
 +      if (le32_to_cpu(n->header.flags) & INTERNAL_NODE)
 +              for (i = 0; i < nr_entries; i++)
 +                      dm_tm_inc(tm, value64(n, i));
 +      else if (vt->inc)
 +              for (i = 0; i < nr_entries; i++)
 +                      vt->inc(vt->context,
 +                              value_ptr(n, i, vt->size));
 +}
 +
 +static int insert_at(size_t value_size, struct node *node, unsigned index,
 +                    uint64_t key, void *value)
 +                    __dm_written_to_disk(value)
 +{
 +      uint32_t nr_entries = le32_to_cpu(node->header.nr_entries);
 +      __le64 key_le = cpu_to_le64(key);
 +
 +      if (index > nr_entries ||
 +          index >= le32_to_cpu(node->header.max_entries)) {
 +              DMERR("too many entries in btree node for insert");
 +              __dm_unbless_for_disk(value);
 +              return -ENOMEM;
 +      }
 +
 +      __dm_bless_for_disk(&key_le);
 +
 +      array_insert(node->keys, sizeof(*node->keys), nr_entries, index, &key_le);
 +      array_insert(value_base(node), value_size, nr_entries, index, value);
 +      node->header.nr_entries = cpu_to_le32(nr_entries + 1);
 +
 +      return 0;
 +}
 +
 +/*----------------------------------------------------------------*/
 +
 +/*
 + * We want 3n entries (for some n).  This works more nicely for repeated
 + * insert remove loops than (2n + 1).
 + */
 +static uint32_t calc_max_entries(size_t value_size, size_t block_size)
 +{
 +      uint32_t total, n;
 +      size_t elt_size = sizeof(uint64_t) + value_size; /* key + value */
 +
 +      block_size -= sizeof(struct node_header);
 +      total = block_size / elt_size;
 +      n = total / 3;          /* rounds down */
 +
 +      return 3 * n;
 +}
 +
 +int dm_btree_create(struct dm_btree_info *info, dm_block_t *root)
 +{
 +      int r;
 +      struct dm_block *b;
 +      struct node *n;
 +      size_t block_size;
 +      uint32_t max_entries;
 +
 +      r = new_block(info, &b);
 +      if (r < 0)
 +              return r;
 +
 +      block_size = dm_bm_block_size(dm_tm_get_bm(info->tm));
 +      max_entries = calc_max_entries(info->value_type.size, block_size);
 +
 +      n = dm_block_data(b);
 +      memset(n, 0, block_size);
 +      n->header.flags = cpu_to_le32(LEAF_NODE);
 +      n->header.nr_entries = cpu_to_le32(0);
 +      n->header.max_entries = cpu_to_le32(max_entries);
 +      n->header.value_size = cpu_to_le32(info->value_type.size);
 +
 +      *root = dm_block_location(b);
 +
 +      return unlock_block(info, b);
 +}
 +EXPORT_SYMBOL_GPL(dm_btree_create);
 +
 +/*----------------------------------------------------------------*/
 +
 +/*
 + * Deletion uses a recursive algorithm, since we have limited stack space
 + * we explicitly manage our own stack on the heap.
 + */
 +#define MAX_SPINE_DEPTH 64
 +struct frame {
 +      struct dm_block *b;
 +      struct node *n;
 +      unsigned level;
 +      unsigned nr_children;
 +      unsigned current_child;
 +};
 +
 +struct del_stack {
 +      struct dm_transaction_manager *tm;
 +      int top;
 +      struct frame spine[MAX_SPINE_DEPTH];
 +};
 +
 +static int top_frame(struct del_stack *s, struct frame **f)
 +{
 +      if (s->top < 0) {
 +              DMERR("btree deletion stack empty");
 +              return -EINVAL;
 +      }
 +
 +      *f = s->spine + s->top;
 +
 +      return 0;
 +}
 +
 +static int unprocessed_frames(struct del_stack *s)
 +{
 +      return s->top >= 0;
 +}
 +
 +static int push_frame(struct del_stack *s, dm_block_t b, unsigned level)
 +{
 +      int r;
 +      uint32_t ref_count;
 +
 +      if (s->top >= MAX_SPINE_DEPTH - 1) {
 +              DMERR("btree deletion stack out of memory");
 +              return -ENOMEM;
 +      }
 +
 +      r = dm_tm_ref(s->tm, b, &ref_count);
 +      if (r)
 +              return r;
 +
 +      if (ref_count > 1)
 +              /*
 +               * This is a shared node, so we can just decrement its
 +               * reference counter and leave the children.
 +               */
 +              dm_tm_dec(s->tm, b);
 +
 +      else {
 +              struct frame *f = s->spine + ++s->top;
 +
 +              r = dm_tm_read_lock(s->tm, b, &btree_node_validator, &f->b);
 +              if (r) {
 +                      s->top--;
 +                      return r;
 +              }
 +
 +              f->n = dm_block_data(f->b);
 +              f->level = level;
 +              f->nr_children = le32_to_cpu(f->n->header.nr_entries);
 +              f->current_child = 0;
 +      }
 +
 +      return 0;
 +}
 +
 +static void pop_frame(struct del_stack *s)
 +{
 +      struct frame *f = s->spine + s->top--;
 +
 +      dm_tm_dec(s->tm, dm_block_location(f->b));
 +      dm_tm_unlock(s->tm, f->b);
 +}
 +
 +int dm_btree_destroy(struct dm_btree_info *info, dm_block_t root)
 +{
 +      int r;
 +      struct del_stack *s;
 +
 +      s = kmalloc(sizeof(*s), GFP_KERNEL);
 +      if (!s)
 +              return -ENOMEM;
 +
 +      s->tm = info->tm;
 +      s->top = -1;
 +
 +      r = push_frame(s, root, 1);
 +      if (r)
 +              goto out;
 +
 +      while (unprocessed_frames(s)) {
 +              uint32_t flags;
 +              struct frame *f;
 +              dm_block_t b;
 +
 +              r = top_frame(s, &f);
 +              if (r)
 +                      goto out;
 +
 +              if (f->current_child >= f->nr_children) {
 +                      pop_frame(s);
 +                      continue;
 +              }
 +
 +              flags = le32_to_cpu(f->n->header.flags);
 +              if (flags & INTERNAL_NODE) {
 +                      b = value64(f->n, f->current_child);
 +                      f->current_child++;
 +                      r = push_frame(s, b, f->level);
 +                      if (r)
 +                              goto out;
 +
 +              } else if (f->level != (info->levels - 1)) {
 +                      b = value64(f->n, f->current_child);
 +                      f->current_child++;
 +                      r = push_frame(s, b, f->level + 1);
 +                      if (r)
 +                              goto out;
 +
 +              } else {
 +                      if (info->value_type.dec) {
 +                              unsigned i;
 +
 +                              for (i = 0; i < f->nr_children; i++)
 +                                      info->value_type.dec(info->value_type.context,
 +                                                           value_ptr(f->n, i, info->value_type.size));
 +                      }
 +                      f->current_child = f->nr_children;
 +              }
 +      }
 +
 +out:
 +      kfree(s);
 +      return r;
 +}
 +EXPORT_SYMBOL_GPL(dm_btree_destroy);
 +
 +// FIXME Implement or remove this fn before final submission.
 +int dm_btree_delete_gt(struct dm_btree_info *info, dm_block_t root, uint64_t *key,
 +                  dm_block_t *new_root)
 +{
 +      /* FIXME: implement */
 +      return 0;
 +}
 +EXPORT_SYMBOL_GPL(dm_btree_delete_gt);
 +
 +/*----------------------------------------------------------------*/
 +
 +static int btree_lookup_raw(struct ro_spine *s, dm_block_t block, uint64_t key,
 +                          int (*search_fn)(struct node *, uint64_t),
 +                          uint64_t *result_key, void *v, size_t value_size)
 +{
 +      int i, r;
 +      uint32_t flags, nr_entries;
 +
 +      do {
 +              r = ro_step(s, block);
 +              if (r < 0)
 +                      return r;
 +
 +              i = search_fn(ro_node(s), key);
 +
 +              flags = le32_to_cpu(ro_node(s)->header.flags);
 +              nr_entries = le32_to_cpu(ro_node(s)->header.nr_entries);
 +              if (i < 0 || i >= nr_entries)
 +                      return -ENODATA;
 +
 +              if (flags & INTERNAL_NODE)
 +                      block = value64(ro_node(s), i);
 +
 +      } while (!(flags & LEAF_NODE));
 +
 +      *result_key = le64_to_cpu(ro_node(s)->keys[i]);
 +      memcpy(v, value_ptr(ro_node(s), i, value_size), value_size);
 +
 +      return 0;
 +}
 +
 +int dm_btree_lookup(struct dm_btree_info *info, dm_block_t root,
 +                  uint64_t *keys, void *value_le)
 +{
 +      unsigned level, last_level = info->levels - 1;
 +      int r = -ENODATA;
 +      uint64_t rkey;
 +      __le64 internal_value_le;
 +      struct ro_spine spine;
 +
 +      init_ro_spine(&spine, info);
 +      for (level = 0; level < info->levels; level++) {
 +              size_t size;
 +              void *value_p;
 +
 +              if (level == last_level) {
 +                      value_p = value_le;
 +                      size = info->value_type.size;
 +
 +              } else {
 +                      value_p = &internal_value_le;
 +                      size = sizeof(uint64_t);
 +              }
 +
 +              r = btree_lookup_raw(&spine, root, keys[level],
 +                                   lower_bound, &rkey,
 +                                   value_p, size);
 +
 +              if (!r) {
 +                      if (rkey != keys[level]) {
 +                              exit_ro_spine(&spine);
 +                              return -ENODATA;
 +                      }
 +              } else {
 +                      exit_ro_spine(&spine);
 +                      return r;
 +              }
 +
 +              root = le64_to_cpu(internal_value_le);
 +      }
 +      exit_ro_spine(&spine);
 +
 +      return r;
 +}
 +EXPORT_SYMBOL_GPL(dm_btree_lookup);
 +
 +/*
 + * Splits a node by creating a sibling node and shifting half the nodes
 + * contents across.  Assumes there is a parent node, and it has room for
 + * another child.
 + *
 + * Before:
 + *      +--------+
 + *      | Parent |
 + *      +--------+
 + *         |
 + *         v
 + *    +----------+
 + *    | A ++++++ |
 + *    +----------+
 + *
 + *
 + * After:
 + *            +--------+
 + *            | Parent |
 + *            +--------+
 + *              |     |
 + *              v     +------+
 + *        +---------+        |
 + *        | A* +++  |        v
 + *        +---------+   +-------+
 + *                      | B +++ |
 + *                      +-------+
 + *
 + * Where A* is a shadow of A.
 + */
 +static int btree_split_sibling(struct shadow_spine *s, dm_block_t root,
 +                             unsigned parent_index, uint64_t key)
 +{
 +      int r;
 +      size_t size;
 +      unsigned nr_left, nr_right;
 +      struct dm_block *left, *right, *parent;
 +      struct node *ln, *rn, *pn;
 +      __le64 location;
 +
 +      left = shadow_current(s);
 +
 +      r = new_block(s->info, &right);
 +      if (r < 0)
 +              return r;
 +
 +      ln = dm_block_data(left);
 +      rn = dm_block_data(right);
 +
 +      nr_left = le32_to_cpu(ln->header.nr_entries) / 2;
 +      nr_right = le32_to_cpu(ln->header.nr_entries) - nr_left;
 +
 +      ln->header.nr_entries = cpu_to_le32(nr_left);
 +
 +      rn->header.flags = ln->header.flags;
 +      rn->header.nr_entries = cpu_to_le32(nr_right);
 +      rn->header.max_entries = ln->header.max_entries;
 +      rn->header.value_size = ln->header.value_size;
 +      memcpy(rn->keys, ln->keys + nr_left, nr_right * sizeof(rn->keys[0]));
 +
 +      size = le32_to_cpu(ln->header.flags) & INTERNAL_NODE ?
 +              sizeof(uint64_t) : s->info->value_type.size;
 +      memcpy(value_ptr(rn, 0, size), value_ptr(ln, nr_left, size),
 +             size * nr_right);
 +
 +      /*
 +       * Patch up the parent
 +       */
 +      parent = shadow_parent(s);
 +
 +      pn = dm_block_data(parent);
 +      location = cpu_to_le64(dm_block_location(left));
 +      __dm_bless_for_disk(&location);
 +      memcpy_disk(value_ptr(pn, parent_index, sizeof(__le64)),
 +                  &location, sizeof(__le64));
 +
 +      location = cpu_to_le64(dm_block_location(right));
 +      __dm_bless_for_disk(&location);
 +
 +      r = insert_at(sizeof(__le64), pn, parent_index + 1,
 +                    le64_to_cpu(rn->keys[0]), &location);
 +      if (r)
 +              return r;
 +
 +      if (key < le64_to_cpu(rn->keys[0])) {
 +              unlock_block(s->info, right);
 +              s->nodes[1] = left;
 +      } else {
 +              unlock_block(s->info, left);
 +              s->nodes[1] = right;
 +      }
 +
 +      return 0;
 +}
 +
 +/*
 + * Splits a node by creating two new children beneath the given node.
 + *
 + * Before:
 + *      +----------+
 + *      | A ++++++ |
 + *      +----------+
 + *
 + *
 + * After:
 + *    +------------+
 + *    | A (shadow) |
 + *    +------------+
 + *        |   |
 + *   +------+ +----+
 + *   |                     |
 + *   v                     v
 + * +-------+   +-------+
 + * | B +++ |   | C +++ |
 + * +-------+   +-------+
 + */
 +static int btree_split_beneath(struct shadow_spine *s, uint64_t key)
 +{
 +      int r;
 +      size_t size;
 +      unsigned nr_left, nr_right;
 +      struct dm_block *left, *right, *new_parent;
 +      struct node *pn, *ln, *rn;
 +      __le64 val;
 +
 +      new_parent = shadow_current(s);
 +
 +      r = new_block(s->info, &left);
 +      if (r < 0)
 +              return r;
 +
 +      r = new_block(s->info, &right);
 +      if (r < 0) {
 +              /* FIXME: put left */
 +              return r;
 +      }
 +
 +      pn = dm_block_data(new_parent);
 +      ln = dm_block_data(left);
 +      rn = dm_block_data(right);
 +
 +      nr_left = le32_to_cpu(pn->header.nr_entries) / 2;
 +      nr_right = le32_to_cpu(pn->header.nr_entries) - nr_left;
 +
 +      ln->header.flags = pn->header.flags;
 +      ln->header.nr_entries = cpu_to_le32(nr_left);
 +      ln->header.max_entries = pn->header.max_entries;
 +      ln->header.value_size = pn->header.value_size;
 +
 +      rn->header.flags = pn->header.flags;
 +      rn->header.nr_entries = cpu_to_le32(nr_right);
 +      rn->header.max_entries = pn->header.max_entries;
 +      rn->header.value_size = pn->header.value_size;
 +
 +      memcpy(ln->keys, pn->keys, nr_left * sizeof(pn->keys[0]));
 +      memcpy(rn->keys, pn->keys + nr_left, nr_right * sizeof(pn->keys[0]));
 +
 +      size = le32_to_cpu(pn->header.flags) & INTERNAL_NODE ?
 +              sizeof(__le64) : s->info->value_type.size;
 +      memcpy(value_ptr(ln, 0, size), value_ptr(pn, 0, size), nr_left * size);
 +      memcpy(value_ptr(rn, 0, size), value_ptr(pn, nr_left, size),
 +             nr_right * size);
 +
 +      /* new_parent should just point to l and r now */
 +      pn->header.flags = cpu_to_le32(INTERNAL_NODE);
 +      pn->header.nr_entries = cpu_to_le32(2);
 +      pn->header.max_entries = cpu_to_le32(
 +              calc_max_entries(sizeof(__le64),
 +                               dm_bm_block_size(
 +                                       dm_tm_get_bm(s->info->tm))));
 +      pn->header.value_size = cpu_to_le32(sizeof(__le64));
 +
 +      val = cpu_to_le64(dm_block_location(left));
 +      __dm_bless_for_disk(&val);
 +      pn->keys[0] = ln->keys[0];
 +      memcpy_disk(value_ptr(pn, 0, sizeof(__le64)), &val, sizeof(__le64));
 +
 +      val = cpu_to_le64(dm_block_location(right));
 +      __dm_bless_for_disk(&val);
 +      pn->keys[1] = rn->keys[0];
 +      memcpy_disk(value_ptr(pn, 1, sizeof(__le64)), &val, sizeof(__le64));
 +
 +      /*
 +       * rejig the spine.  This is ugly, since it knows too
 +       * much about the spine
 +       */
 +      if (s->nodes[0] != new_parent) {
 +              unlock_block(s->info, s->nodes[0]);
 +              s->nodes[0] = new_parent;
 +      }
 +      if (key < le64_to_cpu(rn->keys[0])) {
 +              unlock_block(s->info, right);
 +              s->nodes[1] = left;
 +      } else {
 +              unlock_block(s->info, left);
 +              s->nodes[1] = right;
 +      }
 +      s->count = 2;
 +
 +      return 0;
 +}
 +
 +static int btree_insert_raw(struct shadow_spine *s, dm_block_t root,
 +                          struct dm_btree_value_type *vt,
 +                          uint64_t key, unsigned *index)
 +{
 +      int r, i = *index, inc, top = 1;
 +      struct node *node;
 +
 +      for (;;) {
 +              r = shadow_step(s, root, vt, &inc);
 +              if (r < 0)
 +                      return r;
 +
 +              node = dm_block_data(shadow_current(s));
 +              if (inc)
 +                      inc_children(s->info->tm, node, vt);
 +
 +              /*
 +               * We have to patch up the parent node, ugly, but I don't
 +               * see a way to do this automatically as part of the spine
 +               * op.
 +               */
 +              if (shadow_has_parent(s) && i >= 0) { /* FIXME: second clause unness. */
 +                      __le64 location = cpu_to_le64(dm_block_location(shadow_current(s)));
 +
 +                      __dm_bless_for_disk(&location);
 +                      memcpy_disk(value_ptr(dm_block_data(shadow_parent(s)), i, sizeof(uint64_t)),
 +                                  &location, sizeof(__le64));
 +              }
 +
 +              node = dm_block_data(shadow_current(s));
 +
 +              if (node->header.nr_entries == node->header.max_entries) {
 +                      if (top)
 +                              r = btree_split_beneath(s, key);
 +                      else
 +                              r = btree_split_sibling(s, root, i, key);
 +
 +                      if (r < 0)
 +                              return r;
 +              }
 +
 +              node = dm_block_data(shadow_current(s));
 +
 +              i = lower_bound(node, key);
 +
 +              if (le32_to_cpu(node->header.flags) & LEAF_NODE)
 +                      break;
 +
 +              if (i < 0) {
 +                      /* change the bounds on the lowest key */
 +                      node->keys[0] = cpu_to_le64(key);
 +                      i = 0;
 +              }
 +
 +              root = value64(node, i);
 +              top = 0;
 +      }
 +
 +      if (i < 0 || le64_to_cpu(node->keys[i]) != key)
 +              i++;
 +
 +      /* we're about to overwrite this value, so undo the increment for it */
 +      /* FIXME: shame that inc information is leaking outside the spine.
 +       * Plus inc is just plain wrong in the event of a split */
 +      if (le64_to_cpu(node->keys[i]) == key && inc)
 +              if (vt->dec)
 +                      vt->dec(vt->context, value_ptr(node, i, vt->size));
 +
 +      *index = i;
 +      return 0;
 +}
 +
 +static int insert(struct dm_btree_info *info, dm_block_t root,
 +                uint64_t *keys, void *value, dm_block_t *new_root,
 +                int *inserted)
 +                __dm_written_to_disk(value)
 +{
 +      int r, need_insert;
 +      unsigned level, index = -1, last_level = info->levels - 1;
 +      dm_block_t block = root;
 +      struct shadow_spine spine;
 +      struct node *n;
 +      struct dm_btree_value_type le64_type;
 +
 +      le64_type.context = NULL;
 +      le64_type.size = sizeof(__le64);
 +      le64_type.inc = NULL;
 +      le64_type.dec = NULL;
 +      le64_type.equal = NULL;
 +
 +      init_shadow_spine(&spine, info);
 +
 +      for (level = 0; level < (info->levels - 1); level++) {
 +              r = btree_insert_raw(&spine, block, &le64_type, keys[level], &index);
 +              if (r < 0)
 +                      goto bad;
 +
 +              n = dm_block_data(shadow_current(&spine));
 +              need_insert = ((index >= le32_to_cpu(n->header.nr_entries)) ||
 +                             (le64_to_cpu(n->keys[index]) != keys[level]));
 +
 +              if (need_insert) {
 +                      dm_block_t new_tree;
 +                      __le64 new_le;
 +
 +                      r = dm_btree_create(info, &new_tree);
 +                      if (r < 0)
 +                              goto bad;
 +
 +                      new_le = cpu_to_le64(new_tree);
 +                      __dm_bless_for_disk(&new_le);
 +
 +                      r = insert_at(sizeof(uint64_t), n, index,
 +                                    keys[level], &new_le);
 +                      if (r)
 +                              goto bad;
 +              }
 +
 +              if (level < last_level)
 +                      block = value64(n, index);
 +      }
 +
 +      r = btree_insert_raw(&spine, block, &info->value_type,
 +                           keys[level], &index);
 +      if (r < 0)
 +              goto bad;
 +
 +      n = dm_block_data(shadow_current(&spine));
 +      need_insert = ((index >= le32_to_cpu(n->header.nr_entries)) ||
 +                     (le64_to_cpu(n->keys[index]) != keys[level]));
 +
 +      if (need_insert) {
 +              if (inserted)
 +                      *inserted = 1;
 +
 +              r = insert_at(info->value_type.size, n, index,
 +                            keys[level], value);
 +              if (r)
 +                      goto bad_unblessed;
 +      } else {
 +              if (inserted)
 +                      *inserted = 0;
 +
 +              if (info->value_type.dec &&
 +                  (!info->value_type.equal ||
 +                   !info->value_type.equal(
 +                           info->value_type.context,
 +                           value_ptr(n, index, info->value_type.size),
 +                           value))) {
 +                      info->value_type.dec(info->value_type.context,
 +                                           value_ptr(n, index, info->value_type.size));
 +              }
 +              memcpy_disk(value_ptr(n, index, info->value_type.size),
 +                          value, info->value_type.size);
 +      }
 +
 +      *new_root = shadow_root(&spine);
 +      exit_shadow_spine(&spine);
 +
 +      return 0;
 +
 +bad:
 +      __dm_unbless_for_disk(value);
 +bad_unblessed:
 +      exit_shadow_spine(&spine);
 +      return r;
 +}
 +
 +int dm_btree_insert(struct dm_btree_info *info, dm_block_t root,
 +                  uint64_t *keys, void *value, dm_block_t *new_root)
 +                  __dm_written_to_disk(value)
 +{
 +      return insert(info, root, keys, value, new_root, NULL);
 +}
 +EXPORT_SYMBOL_GPL(dm_btree_insert);
 +
 +int dm_btree_insert_notify(struct dm_btree_info *info, dm_block_t root,
 +                         uint64_t *keys, void *value, dm_block_t *new_root,
 +                         int *inserted)
 +                         __dm_written_to_disk(value)
 +{
 +      return insert(info, root, keys, value, new_root, inserted);
 +}
 +EXPORT_SYMBOL_GPL(dm_btree_insert_notify);
 +
 +/*----------------------------------------------------------------*/
 +
 +int dm_btree_clone(struct dm_btree_info *info, dm_block_t root,
 +                 dm_block_t *clone)
 +{
 +      int r;
 +      struct dm_block *b, *orig_b;
 +      struct node *b_node, *orig_node;
 +
 +      /* Copy the root node */
 +      r = new_block(info, &b);
 +      if (r < 0)
 +              return r;
 +
 +      r = dm_tm_read_lock(info->tm, root, &btree_node_validator, &orig_b);
 +      if (r < 0) {
 +              dm_block_t location = dm_block_location(b);
 +
 +              unlock_block(info, b);
 +              dm_tm_dec(info->tm, location);
 +      }
 +
 +      *clone = dm_block_location(b);
 +      b_node = dm_block_data(b);
 +      orig_node = dm_block_data(orig_b);
 +
 +      memcpy(b_node, orig_node,
 +             dm_bm_block_size(dm_tm_get_bm(info->tm)));
 +      dm_tm_unlock(info->tm, orig_b);
 +      inc_children(info->tm, b_node, &info->value_type);
 +      dm_tm_unlock(info->tm, b);
 +
 +      return 0;
 +}
 +EXPORT_SYMBOL_GPL(dm_btree_clone);
 +
 +/*----------------------------------------------------------------*/
 +
 +static int find_highest_key(struct ro_spine *s, dm_block_t block,
 +                          uint64_t *result_key, dm_block_t *next_block)
 +{
 +      int i, r;
 +      uint32_t flags;
 +
 +      do {
 +              r = ro_step(s, block);
 +              if (r < 0)
 +                      return r;
 +
 +              flags = le32_to_cpu(ro_node(s)->header.flags);
 +              i = le32_to_cpu(ro_node(s)->header.nr_entries);
 +              if (!i)
 +                      return -ENODATA;
 +              else
 +                      i--;
 +
 +              *result_key = le64_to_cpu(ro_node(s)->keys[i]);
 +              if (next_block || flags & INTERNAL_NODE)
 +                      block = value64(ro_node(s), i);
 +
 +      } while (flags & INTERNAL_NODE);
 +
 +      if (next_block)
 +              *next_block = block;
 +      return 0;
 +}
 +
 +int dm_btree_find_highest_key(struct dm_btree_info *info, dm_block_t root,
 +                            uint64_t *result_keys)
 +{
 +      int r = 0, count = 0, level;
 +      struct ro_spine spine;
 +
 +      init_ro_spine(&spine, info);
 +      for (level = 0; level < info->levels; level++) {
 +              r = find_highest_key(&spine, root, result_keys + level,
 +                                   level == info->levels - 1 ? NULL : &root);
 +              if (r == -ENODATA) {
 +                      r = 0;
 +                      break;
 +
 +              } else if (r)
 +                      break;
 +
 +              count++;
 +      }
 +      exit_ro_spine(&spine);
 +
 +      return r ? r : count;
 +}
 +EXPORT_SYMBOL_GPL(dm_btree_find_highest_key);
index 6229a4e68f88ca19f65e17623c0bbc3a834c2dee,0000000000000000000000000000000000000000..e6b9d67270eed1eae4ddb21b81b243b7c06345d5
mode 100644,000000..100644
--- /dev/null
@@@ -1,663 -1,0 +1,663 @@@
- #include <linux/module.h>
 +/*
 + * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
 + *
 + * This file is released under the GPL.
 + */
 +
 +#include "dm-space-map-common.h"
 +#include "dm-space-map-disk.h"
 +#include "dm-space-map.h"
 +#include "dm-transaction-manager.h"
 +
 +#include <linux/list.h>
 +#include <linux/slab.h>
 +#include <linux/bitops.h>
++#include <linux/export.h>
 +#include <linux/device-mapper.h>
 +
 +#define DM_MSG_PREFIX "space map disk"
 +
 +/*
 + * Bitmap validator
 + */
 +static void bitmap_prepare_for_write(struct dm_block_validator *v,
 +                                   struct dm_block *b,
 +                                   size_t block_size)
 +{
 +      struct disk_bitmap_header *disk_header = dm_block_data(b);
 +
 +      disk_header->blocknr = cpu_to_le64(dm_block_location(b));
 +      disk_header->csum = cpu_to_le32(dm_block_csum_data(&disk_header->not_used, block_size - sizeof(__le32)));
 +}
 +
 +static int bitmap_check(struct dm_block_validator *v,
 +                      struct dm_block *b,
 +                      size_t block_size)
 +{
 +      struct disk_bitmap_header *disk_header = dm_block_data(b);
 +      __le32 csum_disk;
 +
 +      if (dm_block_location(b) != le64_to_cpu(disk_header->blocknr)) {
 +              DMERR("bitmap check failed blocknr %llu wanted %llu",
 +                    le64_to_cpu(disk_header->blocknr), dm_block_location(b));
 +              return -ENOTBLK;
 +      }
 +
 +      csum_disk = cpu_to_le32(dm_block_csum_data(&disk_header->not_used, block_size - sizeof(__le32)));
 +      if (csum_disk != disk_header->csum) {
 +              DMERR("bitmap check failed csum %u wanted %u",
 +                    le32_to_cpu(csum_disk), le32_to_cpu(disk_header->csum));
 +              return -EILSEQ;
 +      }
 +
 +      return 0;
 +}
 +
 +struct dm_block_validator dm_sm_bitmap_validator = {
 +      .name = "sm_bitmap",
 +      .prepare_for_write = bitmap_prepare_for_write,
 +      .check = bitmap_check
 +};
 +
 +/*----------------------------------------------------------------*/
 +
 +#define ENTRIES_PER_WORD 32
 +#define ENTRIES_SHIFT 5
 +
 +void *dm_bitmap_data(struct dm_block *b)
 +{
 +      return dm_block_data(b) + sizeof(struct disk_bitmap_header);
 +}
 +
 +#define WORD_MASK_LOW 0x5555555555555555ULL
 +#define WORD_MASK_HIGH 0xAAAAAAAAAAAAAAAAULL
 +#define WORD_MASK_ALL 0xFFFFFFFFFFFFFFFFULL
 +
 +static unsigned bitmap_word_used(void *addr, unsigned b)
 +{
 +      __le64 *words_le = addr;
 +      __le64 *w_le = words_le + (b >> ENTRIES_SHIFT);
 +
 +      uint64_t bits = le64_to_cpu(*w_le);
 +
 +      return ((bits & WORD_MASK_LOW) == WORD_MASK_LOW ||
 +              (bits & WORD_MASK_HIGH) == WORD_MASK_HIGH ||
 +              (bits & WORD_MASK_ALL) == WORD_MASK_ALL);
 +}
 +
 +unsigned sm_lookup_bitmap(void *addr, unsigned b)
 +{
 +      __le64 *words_le = addr;
 +      __le64 *w_le = words_le + (b >> ENTRIES_SHIFT);
 +
 +      b = (b & (ENTRIES_PER_WORD - 1)) << 1;
 +
 +      return (!!test_bit_le(b, (void *) w_le) << 1) |
 +              (!!test_bit_le(b + 1, (void *) w_le));
 +}
 +
 +void sm_set_bitmap(void *addr, unsigned b, unsigned val)
 +{
 +      __le64 *words_le = addr;
 +      __le64 *w_le = words_le + (b >> ENTRIES_SHIFT);
 +
 +      b = (b & (ENTRIES_PER_WORD - 1)) << 1;
 +
 +      if (val & 2)
 +              __set_bit_le(b, (void *) w_le);
 +      else
 +              __clear_bit_le(b, (void *) w_le);
 +
 +      if (val & 1)
 +              __set_bit_le(b + 1, (void *) w_le);
 +      else
 +              __clear_bit_le(b + 1, (void *) w_le);
 +}
 +
 +int sm_find_free(void *addr, unsigned begin, unsigned end,
 +               unsigned *result)
 +{
 +      while (begin < end) {
 +              if (!(begin & (ENTRIES_PER_WORD - 1)) &&
 +                  bitmap_word_used(addr, begin)) {
 +                      begin += ENTRIES_PER_WORD;
 +                      continue;
 +              }
 +
 +              if (!sm_lookup_bitmap(addr, begin)) {
 +                      *result = begin;
 +                      return 0;
 +              }
 +
 +              begin++;
 +      }
 +
 +      return -ENOSPC;
 +}
 +
 +static int disk_ll_init(struct ll_disk *io, struct dm_transaction_manager *tm)
 +{
 +      io->tm = tm;
 +      io->bitmap_info.tm = tm;
 +      io->bitmap_info.levels = 1;
 +
 +      /*
 +       * Because the new bitmap blocks are created via a shadow
 +       * operation, the old entry has already had its reference count
 +       * decremented and we don't need the btree to do any bookkeeping.
 +       */
 +      io->bitmap_info.value_type.size = sizeof(struct disk_index_entry);
 +      io->bitmap_info.value_type.inc = NULL;
 +      io->bitmap_info.value_type.dec = NULL;
 +      io->bitmap_info.value_type.equal = NULL;
 +
 +      io->ref_count_info.tm = tm;
 +      io->ref_count_info.levels = 1;
 +      io->ref_count_info.value_type.size = sizeof(uint32_t);
 +      io->ref_count_info.value_type.inc = NULL;
 +      io->ref_count_info.value_type.dec = NULL;
 +      io->ref_count_info.value_type.equal = NULL;
 +
 +      io->block_size = dm_bm_block_size(dm_tm_get_bm(tm));
 +
 +      if (io->block_size > (1 << 30)) {
 +              DMERR("block size too big to hold bitmaps");
 +              return -EINVAL;
 +      }
 +
 +      io->entries_per_block = (io->block_size - sizeof(struct disk_bitmap_header)) *
 +                              ENTRIES_PER_BYTE;
 +      io->nr_blocks = 0;
 +      io->bitmap_root = 0;
 +      io->ref_count_root = 0;
 +
 +      return 0;
 +}
 +
 +static int disk_ll_new(struct ll_disk *io, struct dm_transaction_manager *tm)
 +{
 +      int r;
 +
 +      r = disk_ll_init(io, tm);
 +      if (r < 0)
 +              return r;
 +
 +      io->nr_blocks = 0;
 +      io->nr_allocated = 0;
 +      r = dm_btree_create(&io->bitmap_info, &io->bitmap_root);
 +      if (r < 0)
 +              return r;
 +
 +      r = dm_btree_create(&io->ref_count_info, &io->ref_count_root);
 +      if (r < 0) {
 +              dm_btree_destroy(&io->bitmap_info, io->bitmap_root);
 +              return r;
 +      }
 +
 +      return 0;
 +}
 +
 +static int disk_ll_extend(struct ll_disk *io, dm_block_t extra_blocks)
 +{
 +      int r;
 +      dm_block_t i, nr_blocks;
 +      unsigned old_blocks, blocks;
 +
 +      nr_blocks = io->nr_blocks + extra_blocks;
 +      old_blocks = dm_sector_div_up(io->nr_blocks, io->entries_per_block);
 +      blocks = dm_sector_div_up(nr_blocks, io->entries_per_block);
 +
 +      for (i = old_blocks; i < blocks; i++) {
 +              struct dm_block *b;
 +              struct disk_index_entry idx;
 +
 +              r = dm_tm_new_block(io->tm, &dm_sm_bitmap_validator, &b);
 +              if (r < 0)
 +                      return r;
 +              idx.blocknr = cpu_to_le64(dm_block_location(b));
 +
 +              r = dm_tm_unlock(io->tm, b);
 +              if (r < 0)
 +                      return r;
 +
 +              idx.nr_free = cpu_to_le32(io->entries_per_block);
 +              idx.none_free_before = 0;
 +              __dm_bless_for_disk(&idx);
 +
 +              r = dm_btree_insert(&io->bitmap_info, io->bitmap_root,
 +                                  &i, &idx, &io->bitmap_root);
 +              if (r < 0)
 +                      return r;
 +      }
 +
 +      io->nr_blocks = nr_blocks;
 +      return 0;
 +}
 +
 +static int disk_ll_open(struct ll_disk *ll, struct dm_transaction_manager *tm,
 +                      void *root_le, size_t len)
 +{
 +      int r;
 +      struct disk_sm_root *smr = root_le;
 +
 +      if (len < sizeof(struct disk_sm_root)) {
 +              DMERR("sm_disk root too small");
 +              return -ENOMEM;
 +      }
 +
 +      r = disk_ll_init(ll, tm);
 +      if (r < 0)
 +              return r;
 +
 +      ll->nr_blocks = le64_to_cpu(smr->nr_blocks);
 +      ll->nr_allocated = le64_to_cpu(smr->nr_allocated);
 +      ll->bitmap_root = le64_to_cpu(smr->bitmap_root);
 +      ll->ref_count_root = le64_to_cpu(smr->ref_count_root);
 +
 +      return 0;
 +}
 +
 +static int disk_ll_lookup_bitmap(struct ll_disk *io, dm_block_t b, uint32_t *result)
 +{
 +      int r;
 +      dm_block_t index = b;
 +      struct disk_index_entry ie_disk;
 +      struct dm_block *blk;
 +
 +      do_div(index, io->entries_per_block);
 +      r = dm_btree_lookup(&io->bitmap_info, io->bitmap_root, &index, &ie_disk);
 +      if (r < 0)
 +              return r;
 +
 +      r = dm_tm_read_lock(io->tm, le64_to_cpu(ie_disk.blocknr), &dm_sm_bitmap_validator, &blk);
 +      if (r < 0)
 +              return r;
 +
 +      *result = sm_lookup_bitmap(dm_bitmap_data(blk), do_div(b, io->entries_per_block));
 +
 +      return dm_tm_unlock(io->tm, blk);
 +}
 +
 +static int disk_ll_lookup(struct ll_disk *io, dm_block_t b, uint32_t *result)
 +{
 +      __le32 rc_le;
 +      int r = disk_ll_lookup_bitmap(io, b, result);
 +
 +      if (r)
 +              return r;
 +
 +      if (*result != 3)
 +              return r;
 +
 +      r = dm_btree_lookup(&io->ref_count_info, io->ref_count_root, &b, &rc_le);
 +      if (r < 0)
 +              return r;
 +
 +      *result = le32_to_cpu(rc_le);
 +
 +      return r;
 +}
 +
 +static int disk_ll_find_free_block(struct ll_disk *io, dm_block_t begin,
 +                                 dm_block_t end, dm_block_t *result)
 +{
 +      int r;
 +      struct disk_index_entry ie_disk;
 +      dm_block_t i, index_begin = begin;
 +      dm_block_t index_end = dm_sector_div_up(end, io->entries_per_block);
 +
 +      begin = do_div(index_begin, io->entries_per_block);
 +
 +      for (i = index_begin; i < index_end; i++, begin = 0) {
 +              struct dm_block *blk;
 +              unsigned position;
 +              uint32_t bit_end;
 +
 +              r = dm_btree_lookup(&io->bitmap_info, io->bitmap_root, &i, &ie_disk);
 +              if (r < 0)
 +                      return r;
 +
 +              if (le32_to_cpu(ie_disk.nr_free) <= 0)
 +                      continue;
 +
 +              r = dm_tm_read_lock(io->tm, le64_to_cpu(ie_disk.blocknr),
 +                                  &dm_sm_bitmap_validator, &blk);
 +              if (r < 0)
 +                      return r;
 +
 +              bit_end = (i == index_end - 1) ?
 +                      do_div(end, io->entries_per_block) : io->entries_per_block;
 +
 +              r = sm_find_free(dm_bitmap_data(blk),
 +                               max((unsigned)begin, (unsigned)le32_to_cpu(ie_disk.none_free_before)),
 +                               bit_end, &position);
 +              if (r < 0) {
 +                      dm_tm_unlock(io->tm, blk);
 +                      continue;
 +              }
 +
 +              r = dm_tm_unlock(io->tm, blk);
 +              if (r < 0)
 +                      return r;
 +
 +              *result = i * io->entries_per_block + (dm_block_t) position;
 +
 +              return 0;
 +      }
 +
 +      return -ENOSPC;
 +}
 +
 +static int disk_ll_insert(struct ll_disk *io, dm_block_t b, uint32_t ref_count)
 +{
 +      int r;
 +      uint32_t bit, old;
 +      struct dm_block *nb;
 +      dm_block_t index = b;
 +      struct disk_index_entry ie_disk;
 +      void *bm_le;
 +      int inc;
 +
 +      do_div(index, io->entries_per_block);
 +      r = dm_btree_lookup(&io->bitmap_info, io->bitmap_root, &index, &ie_disk);
 +      if (r < 0)
 +              return r;
 +
 +      r = dm_tm_shadow_block(io->tm, le64_to_cpu(ie_disk.blocknr),
 +                             &dm_sm_bitmap_validator, &nb, &inc);
 +      if (r < 0) {
 +              DMERR("dm_tm_shadow_block() failed");
 +              return r;
 +      }
 +      ie_disk.blocknr = cpu_to_le64(dm_block_location(nb));
 +
 +      bm_le = dm_bitmap_data(nb);
 +      bit = do_div(b, io->entries_per_block);
 +      old = sm_lookup_bitmap(bm_le, bit);
 +
 +      if (ref_count <= 2) {
 +              sm_set_bitmap(bm_le, bit, ref_count);
 +
 +              if (old > 2) {
 +                      r = dm_btree_remove(&io->ref_count_info, io->ref_count_root,
 +                                          &b, &io->ref_count_root);
 +                      if (r) {
 +                              dm_tm_unlock(io->tm, nb);
 +                              return r;
 +                      }
 +              }
 +      } else {
 +              __le32 rc_le = cpu_to_le32(ref_count);
 +
 +              __dm_bless_for_disk(&rc_le);
 +
 +              sm_set_bitmap(bm_le, bit, 3);
 +              r = dm_btree_insert(&io->ref_count_info, io->ref_count_root,
 +                                  &b, &rc_le, &io->ref_count_root);
 +              if (r < 0) {
 +                      dm_tm_unlock(io->tm, nb);
 +                      DMERR("ref count insert failed");
 +                      return r;
 +              }
 +      }
 +
 +      r = dm_tm_unlock(io->tm, nb);
 +      if (r < 0)
 +              return r;
 +
 +      if (ref_count && !old) {
 +              io->nr_allocated++;
 +              ie_disk.nr_free = cpu_to_le32(le32_to_cpu(ie_disk.nr_free) - 1);
 +              if (le32_to_cpu(ie_disk.none_free_before) == b)
 +                      ie_disk.none_free_before = cpu_to_le32(b + 1);
 +
 +      } else if (old && !ref_count) {
 +              io->nr_allocated--;
 +              ie_disk.nr_free = cpu_to_le32(le32_to_cpu(ie_disk.nr_free) + 1);
 +              ie_disk.none_free_before = cpu_to_le32(min((dm_block_t) le32_to_cpu(ie_disk.none_free_before), b));
 +      }
 +
 +      __dm_bless_for_disk(&ie_disk);
 +
 +      r = dm_btree_insert(&io->bitmap_info, io->bitmap_root, &index, &ie_disk, &io->bitmap_root);
 +      if (r < 0)
 +              return r;
 +
 +      return 0;
 +}
 +
 +static int disk_ll_inc(struct ll_disk *ll, dm_block_t b)
 +{
 +      int r;
 +      uint32_t rc;
 +
 +      r = disk_ll_lookup(ll, b, &rc);
 +      if (r)
 +              return r;
 +
 +      return disk_ll_insert(ll, b, rc + 1);
 +}
 +
 +static int disk_ll_dec(struct ll_disk *ll, dm_block_t b)
 +{
 +      int r;
 +      uint32_t rc;
 +
 +      r = disk_ll_lookup(ll, b, &rc);
 +      if (r)
 +              return r;
 +
 +      if (!rc)
 +              return -EINVAL;
 +
 +      return disk_ll_insert(ll, b, rc - 1);
 +}
 +
 +/*--------------------------------------------------------------*/
 +
 +/*
 + * Space map interface.
 + */
 +struct sm_disk {
 +      struct dm_space_map sm;
 +
 +      struct ll_disk ll;
 +};
 +
 +static void sm_disk_destroy(struct dm_space_map *sm)
 +{
 +      struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
 +
 +      kfree(smd);
 +}
 +
 +static int sm_disk_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
 +{
 +      struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
 +
 +      return disk_ll_extend(&smd->ll, extra_blocks);
 +}
 +
 +static int sm_disk_get_nr_blocks(struct dm_space_map *sm, dm_block_t *count)
 +{
 +      struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
 +
 +      *count = smd->ll.nr_blocks;
 +
 +      return 0;
 +}
 +
 +static int sm_disk_get_nr_free(struct dm_space_map *sm, dm_block_t *count)
 +{
 +      struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
 +
 +      *count = smd->ll.nr_blocks - smd->ll.nr_allocated;
 +
 +      return 0;
 +}
 +
 +static int sm_disk_get_count(struct dm_space_map *sm, dm_block_t b,
 +                           uint32_t *result)
 +{
 +      struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
 +
 +      return disk_ll_lookup(&smd->ll, b, result);
 +}
 +
 +static int sm_disk_count_is_more_than_one(struct dm_space_map *sm, dm_block_t b,
 +                                        int *result)
 +{
 +      int r;
 +      uint32_t count;
 +
 +      r = sm_disk_get_count(sm, b, &count);
 +      if (r)
 +              return r;
 +
 +      return count > 1;
 +}
 +
 +static int sm_disk_set_count(struct dm_space_map *sm, dm_block_t b,
 +                           uint32_t count)
 +{
 +      struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
 +
 +      return disk_ll_insert(&smd->ll, b, count);
 +}
 +
 +static int sm_disk_inc_block(struct dm_space_map *sm, dm_block_t b)
 +{
 +      struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
 +
 +      return disk_ll_inc(&smd->ll, b);
 +}
 +
 +static int sm_disk_dec_block(struct dm_space_map *sm, dm_block_t b)
 +{
 +      struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
 +
 +      return disk_ll_dec(&smd->ll, b);
 +}
 +
 +static int sm_disk_new_block(struct dm_space_map *sm, dm_block_t *b)
 +{
 +      int r;
 +      struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
 +
 +      /*
 +       * FIXME: We should start the search where we left off.
 +       */
 +      r = disk_ll_find_free_block(&smd->ll, 0, smd->ll.nr_blocks, b);
 +      if (r)
 +              return r;
 +
 +      return disk_ll_inc(&smd->ll, *b);
 +}
 +
 +static int sm_disk_commit(struct dm_space_map *sm)
 +{
 +      return 0;
 +}
 +
 +static int sm_disk_root_size(struct dm_space_map *sm, size_t *result)
 +{
 +      *result = sizeof(struct disk_sm_root);
 +
 +      return 0;
 +}
 +
 +static int sm_disk_copy_root(struct dm_space_map *sm, void *where_le, size_t max)
 +{
 +      struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
 +      struct disk_sm_root root_le;
 +
 +      root_le.nr_blocks = cpu_to_le64(smd->ll.nr_blocks);
 +      root_le.nr_allocated = cpu_to_le64(smd->ll.nr_allocated);
 +      root_le.bitmap_root = cpu_to_le64(smd->ll.bitmap_root);
 +      root_le.ref_count_root = cpu_to_le64(smd->ll.ref_count_root);
 +
 +      if (max < sizeof(root_le))
 +              return -ENOSPC;
 +
 +      memcpy(where_le, &root_le, sizeof(root_le));
 +
 +      return 0;
 +}
 +
 +/*----------------------------------------------------------------*/
 +
 +static struct dm_space_map ops = {
 +      .destroy = sm_disk_destroy,
 +      .extend = sm_disk_extend,
 +      .get_nr_blocks = sm_disk_get_nr_blocks,
 +      .get_nr_free = sm_disk_get_nr_free,
 +      .get_count = sm_disk_get_count,
 +      .count_is_more_than_one = sm_disk_count_is_more_than_one,
 +      .set_count = sm_disk_set_count,
 +      .inc_block = sm_disk_inc_block,
 +      .dec_block = sm_disk_dec_block,
 +      .new_block = sm_disk_new_block,
 +      .commit = sm_disk_commit,
 +      .root_size = sm_disk_root_size,
 +      .copy_root = sm_disk_copy_root
 +};
 +
 +struct dm_space_map *dm_sm_disk_create(struct dm_transaction_manager *tm,
 +                                     dm_block_t nr_blocks)
 +{
 +      int r;
 +      struct sm_disk *smd;
 +
 +      smd = kmalloc(sizeof(*smd), GFP_KERNEL);
 +      if (!smd)
 +              return ERR_PTR(-ENOMEM);
 +
 +      memcpy(&smd->sm, &ops, sizeof(smd->sm));
 +
 +      r = disk_ll_new(&smd->ll, tm);
 +      if (r)
 +              goto bad;
 +
 +      r = disk_ll_extend(&smd->ll, nr_blocks);
 +      if (r)
 +              goto bad;
 +
 +      r = sm_disk_commit(&smd->sm);
 +      if (r)
 +              goto bad;
 +
 +      return &smd->sm;
 +
 +bad:
 +      kfree(smd);
 +      return ERR_PTR(r);
 +}
 +EXPORT_SYMBOL_GPL(dm_sm_disk_create);
 +
 +struct dm_space_map *dm_sm_disk_open(struct dm_transaction_manager *tm,
 +                                   void *root_le, size_t len)
 +{
 +      int r;
 +      struct sm_disk *smd;
 +
 +      smd = kmalloc(sizeof(*smd), GFP_KERNEL);
 +      if (!smd)
 +              return ERR_PTR(-ENOMEM);
 +
 +      memcpy(&smd->sm, &ops, sizeof(smd->sm));
 +
 +      r = disk_ll_open(&smd->ll, tm, root_le, len);
 +      if (r)
 +              goto bad;
 +
 +      r = sm_disk_commit(&smd->sm);
 +      if (r)
 +              goto bad;
 +
 +      return &smd->sm;
 +
 +bad:
 +      kfree(smd);
 +      return ERR_PTR(r);
 +}
 +EXPORT_SYMBOL_GPL(dm_sm_disk_open);
index be594dd0a12d9afe6762d615ec27babd7ebc3166,0000000000000000000000000000000000000000..e58e89ecfd6760426485f008f5d6e56f2ab1f38b
mode 100644,000000..100644
--- /dev/null
@@@ -1,414 -1,0 +1,414 @@@
- #include <linux/module.h>
 +/*
 + * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
 + *
 + * This file is released under the GPL.
 + */
 +#include "dm-transaction-manager.h"
 +#include "dm-space-map.h"
 +#include "dm-space-map-disk.h"
 +#include "dm-space-map-metadata.h"
 +#include "dm-persistent-data-internal.h"
 +
++#include <linux/export.h>
 +#include <linux/slab.h>
 +#include <linux/device-mapper.h>
 +
 +#define DM_MSG_PREFIX "transaction manager"
 +
 +/*----------------------------------------------------------------*/
 +
 +struct shadow_info {
 +      struct hlist_node hlist;
 +      dm_block_t where;
 +};
 +
 +/*
 + * It would be nice if we scaled with the size of transaction.
 + */
 +#define HASH_SIZE 256
 +#define HASH_MASK (HASH_SIZE - 1)
 +
 +struct dm_transaction_manager {
 +      int is_clone;
 +      struct dm_transaction_manager *real;
 +
 +      struct dm_block_manager *bm;
 +      struct dm_space_map *sm;
 +
 +      spinlock_t lock;
 +      struct hlist_head buckets[HASH_SIZE];
 +};
 +
 +/*----------------------------------------------------------------*/
 +
 +static int is_shadow(struct dm_transaction_manager *tm, dm_block_t b)
 +{
 +      int r = 0;
 +      unsigned bucket = dm_hash_block(b, HASH_MASK);
 +      struct shadow_info *si;
 +      struct hlist_node *n;
 +
 +      spin_lock(&tm->lock);
 +
 +      hlist_for_each_entry(si, n, tm->buckets + bucket, hlist)
 +              if (si->where == b) {
 +                      r = 1;
 +                      break;
 +              }
 +
 +      spin_unlock(&tm->lock);
 +
 +      return r;
 +}
 +
 +/*
 + * This can silently fail if there's no memory.  We're ok with this since
 + * creating redundant shadows causes no harm.
 + */
 +static void insert_shadow(struct dm_transaction_manager *tm, dm_block_t b)
 +{
 +      unsigned bucket;
 +      struct shadow_info *si;
 +
 +      si = kmalloc(sizeof(*si), GFP_NOIO);
 +      if (si) {
 +              si->where = b;
 +              bucket = dm_hash_block(b, HASH_MASK);
 +
 +              spin_lock(&tm->lock);
 +              hlist_add_head(&si->hlist, tm->buckets + bucket);
 +              spin_unlock(&tm->lock);
 +      }
 +}
 +
 +static void wipe_shadow_table(struct dm_transaction_manager *tm)
 +{
 +      struct shadow_info *si;
 +      struct hlist_node *n, *tmp;
 +      struct hlist_head *bucket;
 +      int i;
 +
 +      spin_lock(&tm->lock);
 +      for (i = 0; i < HASH_SIZE; i++) {
 +              bucket = tm->buckets + i;
 +              hlist_for_each_entry_safe(si, n, tmp, bucket, hlist)
 +                      kfree(si);
 +
 +              INIT_HLIST_HEAD(bucket);
 +      }
 +      spin_unlock(&tm->lock);
 +}
 +
 +/*----------------------------------------------------------------*/
 +
 +static struct dm_transaction_manager *dm_tm_create(struct dm_block_manager *bm,
 +                                                 struct dm_space_map *sm)
 +{
 +      int i;
 +      struct dm_transaction_manager *tm;
 +
 +      tm = kmalloc(sizeof(*tm), GFP_KERNEL);
 +      if (!tm)
 +              return ERR_PTR(-ENOMEM);
 +
 +      tm->is_clone = 0;
 +      tm->real = NULL;
 +      tm->bm = bm;
 +      tm->sm = sm;
 +
 +      spin_lock_init(&tm->lock);
 +      for (i = 0; i < HASH_SIZE; i++)
 +              INIT_HLIST_HEAD(tm->buckets + i);
 +
 +      return tm;
 +}
 +
 +struct dm_transaction_manager *dm_tm_create_non_blocking_clone(struct dm_transaction_manager *real)
 +{
 +      struct dm_transaction_manager *tm;
 +
 +      tm = kmalloc(sizeof(*tm), GFP_KERNEL);
 +      if (tm) {
 +              tm->is_clone = 1;
 +              tm->real = real;
 +      }
 +
 +      return tm;
 +}
 +EXPORT_SYMBOL_GPL(dm_tm_create_non_blocking_clone);
 +
 +void dm_tm_destroy(struct dm_transaction_manager *tm)
 +{
 +      kfree(tm);
 +}
 +EXPORT_SYMBOL_GPL(dm_tm_destroy);
 +
 +int dm_tm_pre_commit(struct dm_transaction_manager *tm)
 +{
 +      int r;
 +
 +      if (tm->is_clone)
 +              return -EWOULDBLOCK;
 +
 +      r = dm_sm_commit(tm->sm);
 +      if (r < 0)
 +              return r;
 +
 +      return 0;
 +}
 +EXPORT_SYMBOL_GPL(dm_tm_pre_commit);
 +
 +int dm_tm_commit(struct dm_transaction_manager *tm, struct dm_block *root)
 +{
 +      if (tm->is_clone)
 +              return -EWOULDBLOCK;
 +
 +      wipe_shadow_table(tm);
 +
 +      return dm_bm_flush_and_unlock(tm->bm, root);
 +}
 +EXPORT_SYMBOL_GPL(dm_tm_commit);
 +
 +int dm_tm_new_block(struct dm_transaction_manager *tm,
 +                  struct dm_block_validator *v,
 +                  struct dm_block **result)
 +{
 +      int r;
 +      dm_block_t new_block;
 +
 +      if (tm->is_clone)
 +              return -EWOULDBLOCK;
 +
 +      r = dm_sm_new_block(tm->sm, &new_block);
 +      if (r < 0)
 +              return r;
 +
 +      r = dm_bm_write_lock_zero(tm->bm, new_block, v, result);
 +      if (r < 0) {
 +              dm_sm_dec_block(tm->sm, new_block);
 +              return r;
 +      }
 +
 +      /*
 +       * New blocks count as shadows in that they don't need to be
 +       * shadowed again.
 +       */
 +      insert_shadow(tm, new_block);
 +
 +      return 0;
 +}
 +
 +static int __shadow_block(struct dm_transaction_manager *tm, dm_block_t orig,
 +                        struct dm_block_validator *v,
 +                        struct dm_block **result, int *inc_children)
 +{
 +      int r;
 +      dm_block_t new;
 +      uint32_t count;
 +      struct dm_block *orig_block;
 +
 +      r = dm_sm_new_block(tm->sm, &new);
 +      if (r < 0)
 +              return r;
 +
 +      r = dm_bm_write_lock_zero(tm->bm, new, v, result);
 +      if (r < 0)
 +              goto bad_dec_block;
 +
 +      r = dm_bm_read_lock(tm->bm, orig, v, &orig_block);
 +      if (r < 0)
 +              goto bad_dec_block;
 +
 +      memcpy(dm_block_data(*result), dm_block_data(orig_block),
 +             dm_bm_block_size(tm->bm));
 +
 +      r = dm_bm_unlock(orig_block);
 +      if (r < 0)
 +              goto bad_dec_block;
 +
 +      r = dm_sm_get_count(tm->sm, orig, &count);
 +      if (r < 0)
 +              goto bad;
 +
 +      r = dm_sm_dec_block(tm->sm, orig);
 +      if (r < 0)
 +              goto bad;
 +
 +      *inc_children = count > 1;
 +
 +      return 0;
 +
 +bad:
 +      dm_bm_unlock(*result);
 +bad_dec_block:
 +      dm_sm_dec_block(tm->sm, new);
 +
 +      return r;
 +}
 +
 +int dm_tm_shadow_block(struct dm_transaction_manager *tm, dm_block_t orig,
 +                     struct dm_block_validator *v, struct dm_block **result,
 +                     int *inc_children)
 +{
 +      int r, more_than_one;
 +
 +      if (tm->is_clone)
 +              return -EWOULDBLOCK;
 +
 +      if (is_shadow(tm, orig)) {
 +              r = dm_sm_count_is_more_than_one(tm->sm, orig, &more_than_one);
 +              if (r < 0)
 +                      return r;
 +
 +              if (!more_than_one) {
 +                      *inc_children = 0;
 +                      return dm_bm_write_lock(tm->bm, orig, v, result);
 +              }
 +              /* fall through */
 +      }
 +
 +      r = __shadow_block(tm, orig, v, result, inc_children);
 +      if (r < 0)
 +              return r;
 +
 +      insert_shadow(tm, dm_block_location(*result));
 +
 +      return r;
 +}
 +
 +int dm_tm_read_lock(struct dm_transaction_manager *tm, dm_block_t b,
 +                  struct dm_block_validator *v,
 +                  struct dm_block **blk)
 +{
 +      if (tm->is_clone)
 +              return dm_bm_read_try_lock(tm->real->bm, b, v, blk);
 +
 +      return dm_bm_read_lock(tm->bm, b, v, blk);
 +}
 +
 +int dm_tm_unlock(struct dm_transaction_manager *tm, struct dm_block *b)
 +{
 +      return dm_bm_unlock(b);
 +}
 +EXPORT_SYMBOL_GPL(dm_tm_unlock);
 +
 +void dm_tm_inc(struct dm_transaction_manager *tm, dm_block_t b)
 +{
 +      /*
 +       * The non-blocking clone doesn't support this.
 +       */
 +      BUG_ON(tm->is_clone);
 +
 +      dm_sm_inc_block(tm->sm, b);
 +}
 +EXPORT_SYMBOL_GPL(dm_tm_inc);
 +
 +void dm_tm_dec(struct dm_transaction_manager *tm, dm_block_t b)
 +{
 +      /*
 +       * The non-blocking clone doesn't support this.
 +       */
 +      BUG_ON(tm->is_clone);
 +
 +      dm_sm_dec_block(tm->sm, b);
 +}
 +
 +int dm_tm_ref(struct dm_transaction_manager *tm, dm_block_t b,
 +            uint32_t *result)
 +{
 +      if (tm->is_clone)
 +              return -EWOULDBLOCK;
 +
 +      return dm_sm_get_count(tm->sm, b, result);
 +}
 +
 +struct dm_block_manager *dm_tm_get_bm(struct dm_transaction_manager *tm)
 +{
 +      return tm->bm;
 +}
 +
 +/*----------------------------------------------------------------*/
 +
 +static int dm_tm_create_internal(struct dm_block_manager *bm,
 +                               dm_block_t sb_location,
 +                               struct dm_block_validator *sb_validator,
 +                               size_t root_offset, size_t root_max_len,
 +                               struct dm_transaction_manager **tm,
 +                               struct dm_space_map **sm,
 +                               struct dm_block **sblock,
 +                               int create)
 +{
 +      int r;
 +
 +      *sm = dm_sm_metadata_init();
 +      if (IS_ERR(*sm))
 +              return PTR_ERR(*sm);
 +
 +      *tm = dm_tm_create(bm, *sm);
 +      if (IS_ERR(*tm)) {
 +              dm_sm_destroy(*sm);
 +              return PTR_ERR(*tm);
 +      }
 +
 +      if (create) {
 +              r = dm_bm_write_lock_zero(dm_tm_get_bm(*tm), sb_location,
 +                                        sb_validator, sblock);
 +              if (r < 0) {
 +                      DMERR("couldn't lock superblock");
 +                      goto bad1;
 +              }
 +
 +              r = dm_sm_metadata_create(*sm, *tm, dm_bm_nr_blocks(bm),
 +                                        sb_location);
 +              if (r) {
 +                      DMERR("couldn't create metadata space map");
 +                      goto bad2;
 +              }
 +
 +      } else {
 +              r = dm_bm_write_lock(dm_tm_get_bm(*tm), sb_location,
 +                                   sb_validator, sblock);
 +              if (r < 0) {
 +                      DMERR("couldn't lock superblock");
 +                      goto bad1;
 +              }
 +
 +              r = dm_sm_metadata_open(*sm, *tm,
 +                                      dm_block_data(*sblock) + root_offset,
 +                                      root_max_len);
 +              if (IS_ERR(*sm)) {
 +                      DMERR("couldn't open metadata space map");
 +                      goto bad2;
 +              }
 +      }
 +
 +      return 0;
 +
 +bad2:
 +      dm_tm_unlock(*tm, *sblock);
 +bad1:
 +      dm_tm_destroy(*tm);
 +      dm_sm_destroy(*sm);
 +      return r;
 +}
 +
 +int dm_tm_create_with_sm(struct dm_block_manager *bm, dm_block_t sb_location,
 +                       struct dm_block_validator *sb_validator,
 +                       struct dm_transaction_manager **tm,
 +                       struct dm_space_map **sm, struct dm_block **sblock)
 +{
 +      return dm_tm_create_internal(bm, sb_location, sb_validator,
 +                                   0, 0, tm, sm, sblock, 1);
 +}
 +EXPORT_SYMBOL_GPL(dm_tm_create_with_sm);
 +
 +int dm_tm_open_with_sm(struct dm_block_manager *bm, dm_block_t sb_location,
 +                     struct dm_block_validator *sb_validator,
 +                     size_t root_offset, size_t root_max_len,
 +                     struct dm_transaction_manager **tm,
 +                     struct dm_space_map **sm, struct dm_block **sblock)
 +{
 +      return dm_tm_create_internal(bm, sb_location, sb_validator, root_offset,
 +                                   root_max_len, tm, sm, sblock, 0);
 +}
 +EXPORT_SYMBOL_GPL(dm_tm_open_with_sm);
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index dc58750bb71bbfc52c45fd8afe93be1d5d288be7,77032e43af4fd5f4580d1a2d48766624be00a812..5be53ae9b61cf2a6d6c318c881e43605b3dee526
@@@ -23,8 -23,8 +23,9 @@@
  
  #include <linux/slab.h>
  #include <linux/i2c.h>
 +#include <linux/interrupt.h>
  #include <linux/pm_runtime.h>
+ #include <linux/module.h>
  #include <linux/mutex.h>
  #include <linux/mfd/core.h>
  #include <linux/mfd/max8997.h>
Simple merge
Simple merge
index e06ba9440cdbea2c7143b7dcbe9f752e9d47936c,b49b91eb44ec2b0b4e042dd046dba97ec3cb3258..36de271ba0e3a9f69ed58801ff91201e0b9d422e
@@@ -19,8 -18,8 +19,9 @@@
  #include <linux/mfd/core.h>
  #include <linux/mfd/wm8400-private.h>
  #include <linux/mfd/wm8400-audio.h>
 +#include <linux/regmap.h>
  #include <linux/slab.h>
+ #include <linux/module.h>
  
  static struct {
        u16  readable;    /* Mask of readable bits */
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 47cee772f00ad249cc0828e28384b1f1b870d6bd,93da9405b4a159df27f7997548b015723915b649..67176afcf2db3ac9d6889b593458ea9c4b459a3f
@@@ -22,8 -20,9 +22,9 @@@
  #include <linux/gpio.h>
  #include <linux/mmc/card.h>
  #include <linux/mmc/host.h>
+ #include <linux/module.h>
  
 -#include <mach/gpio.h>
 +#include <asm/gpio.h>
  #include <mach/sdhci.h>
  
  #include "sdhci-pltfm.h"
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index e12b4a2a0be2a621899f7e23b970fb951a705544,11ec2a3ec1e30e5875417c92ca5a9ee634e360a4..36fca3c6b3680a9a8005072ebfdbddca16038720
@@@ -19,8 -19,8 +19,9 @@@
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   */
  
+ #include <linux/module.h>
  #include <linux/err.h>
 +#include <linux/module.h>
  #include <linux/slab.h>
  #include <linux/platform_device.h>
  #include <linux/power_supply.h>
index 6f5ffc3e2f03676828b0ce79ab9002e79e35da27,e08b8c6e84113f2898d4bb014d7c43e78d750e79..0737302af1d202f6803ba633f341340696a3a56e
@@@ -19,8 -19,8 +19,9 @@@
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   */
  
+ #include <linux/module.h>
  #include <linux/err.h>
 +#include <linux/module.h>
  #include <linux/slab.h>
  #include <linux/platform_device.h>
  #include <linux/power_supply.h>
Simple merge
Simple merge
Simple merge
Simple merge
index d291a54acfad5f94ec127cfdbff6e37d5b8cf85d,c9782ff042e1e21f8facadb42d8e5028794fcdf9..6803b468d06dea709493ec0d8490fb939db72492
@@@ -11,6 -11,8 +11,7 @@@
  #define KMSG_COMPONENT "vmur"
  #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
  
 -#include <linux/kernel_stat.h>
+ #include <linux/module.h>
  #include <linux/cdev.h>
  #include <linux/slab.h>
  
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 628f347404f9b355e1fbe14bd58fdae3f0d7171d,f4e4885f71b79bbae3ca927e53326bde6b450717..31018a8465ab840020f0518a3a7fec8bf5d36ed7
@@@ -88,7 -88,7 +88,8 @@@
   */
  
  #include <linux/timer.h>
 +#include <linux/delay.h>
+ #include <linux/module.h>
  #include <linux/slab.h>
  #include <asm/unaligned.h>
  
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index dce50b1a4ee99bd6cc4ff7d99398643046d75656,704da4a9265356583fef0b31550fb59ce9ad15d0..859961608c994d9038ca64e90d1aaddb66f20d78
  #include <linux/cdev.h>
  #include <linux/slab.h>
  #include <linux/poll.h>
+ #include <linux/export.h>
  
  #include "iio.h"
 +#include "iio_core.h"
  #include "ring_generic.h"
  
  /**
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index b0582917f0c8f71e879ed1be66e84897fb00ca38,00c142c41e84c88bc4d0d265c34a6778a967e12a..c74a6f4baa127a313ea8eea5bf16adde62856b2a
@@@ -11,8 -11,9 +11,9 @@@
   * BRIGHT, on the Cirrus EP9307, EP9312, and EP9315 processors.
   */
  
 -
 +#include <linux/module.h>
  #include <linux/platform_device.h>
+ #include <linux/module.h>
  #include <linux/io.h>
  #include <linux/fb.h>
  #include <linux/backlight.h>
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 97ab8bac24945545630cf648eacdcab1d8c9d325,499d5489201754d1c99a1166395d564363ca3b7f..4636f9dc30b00088991179c8b8005cfa9e8f6507
@@@ -23,8 -23,8 +23,9 @@@
  #include <linux/console.h>
  #include <linux/backlight.h>
  #include <linux/gpio.h>
+ #include <linux/module.h>
  #include <video/sh_mobile_lcdc.h>
 +#include <video/sh_mobile_meram.h>
  #include <linux/atomic.h>
  
  #include "sh_mobile_lcdcfb.h"
Simple merge
Simple merge
Simple merge
index 6ea852e251629518cc8d808a087bbc9d4c87fb31,9172e10790c9c4855b1533a28b7d2da305acc23b..e21e3cee68faa884b52b3081a9562a9ea163a634
   */
  
  #include <linux/kernel.h>
+ #include <linux/stat.h>
+ #include <linux/module.h>
  #include <linux/mm.h>
  #include <linux/mman.h>
 +#include <linux/module.h>
  #include <linux/workqueue.h>
  #include <xen/balloon.h>
  #include <xen/tmem.h>
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index ace51af4369f668ea647f47c2d87f76d4478b121,1ceff5ae9d31c2df27b1e6bcc46df342a5b43125..75f53f874b24a0c0abb790f501f2f60ace48e17e
  #include <linux/device.h>
  #include <linux/uio.h>
  #include <linux/dma-direction.h>
 +#include <linux/scatterlist.h>
+ #include <linux/bitmap.h>
+ #include <asm/page.h>
  
 -struct scatterlist;
 -
  /**
   * typedef dma_cookie_t - an opaque DMA cookie
   *
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc kernel/async.c
Simple merge
Simple merge
diff --cc kernel/cred.c
Simple merge
Simple merge
diff --cc kernel/fork.c
Simple merge
diff --cc kernel/futex.c
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc kernel/pid.c
Simple merge
Simple merge
Simple merge
index 1a491edd9c09b39a42afb90561b230c00bef32d5,3c82e32d67f99bfb0216880d04c3a82dbbc625a9..f63ea4022d785e68a1565bbc6a28615e0a99740b
  #include <linux/notifier.h>
  #include <linux/cpu.h>
  #include <linux/mutex.h>
- #include <linux/module.h>
+ #include <linux/export.h>
  #include <linux/hardirq.h>
  
 +#define CREATE_TRACE_POINTS
 +#include <trace/events/rcu.h>
 +
 +#include "rcu.h"
 +
  #ifdef CONFIG_DEBUG_LOCK_ALLOC
  static struct lock_class_key rcu_lock_key;
  struct lockdep_map rcu_lock_map =
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc kernel/sched.c
Simple merge
Simple merge
diff --cc kernel/signal.c
Simple merge
diff --cc kernel/sys.c
Simple merge
diff --cc kernel/sysctl.c
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc lib/dma-debug.c
Simple merge
diff --cc mm/memcontrol.c
Simple merge
diff --cc mm/swapfile.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge