]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mingo/linux-2.6-sched
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Thu, 20 Dec 2007 19:53:41 +0000 (11:53 -0800)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Thu, 20 Dec 2007 19:53:41 +0000 (11:53 -0800)
* git://git.kernel.org/pub/scm/linux/kernel/git/mingo/linux-2.6-sched:
  debug: add end-of-oops marker
  sched: rt: account the cpu time during the tick

drivers/md/Kconfig
drivers/md/dm-crypt.c
drivers/md/dm-ioctl.c
drivers/md/dm-table.c
drivers/md/dm.c
drivers/md/dm.h
fs/binfmt_aout.c
include/linux/device-mapper.h

index 9b6fbf044fd803bb04836f36381ea8ec9bdc58f6..3fa7c77d9bd91479c619ee9bced6a6c42d63a654 100644 (file)
@@ -269,7 +269,7 @@ config DM_MULTIPATH_RDAC
 
 config DM_MULTIPATH_HP
         tristate "HP MSA multipath support (EXPERIMENTAL)"
-        depends on DM_MULTIPATH && BLK_DEV_DM && EXPERIMENTAL
+        depends on DM_MULTIPATH && BLK_DEV_DM && SCSI && EXPERIMENTAL
         ---help---
           Multipath support for HP MSA (Active/Passive) series hardware.
 
index 28c6ae095c560d9377aa5e182e8b8af38de11117..6b66ee46b87d5b44e0023ef3248656b3a9e7ed36 100644 (file)
@@ -398,7 +398,8 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size)
        struct bio *clone;
        unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
        gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
-       unsigned int i;
+       unsigned i, len;
+       struct page *page;
 
        clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, cc->bs);
        if (!clone)
@@ -407,10 +408,8 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size)
        clone_init(io, clone);
 
        for (i = 0; i < nr_iovecs; i++) {
-               struct bio_vec *bv = bio_iovec_idx(clone, i);
-
-               bv->bv_page = mempool_alloc(cc->page_pool, gfp_mask);
-               if (!bv->bv_page)
+               page = mempool_alloc(cc->page_pool, gfp_mask);
+               if (!page)
                        break;
 
                /*
@@ -421,15 +420,14 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size)
                if (i == (MIN_BIO_PAGES - 1))
                        gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT;
 
-               bv->bv_offset = 0;
-               if (size > PAGE_SIZE)
-                       bv->bv_len = PAGE_SIZE;
-               else
-                       bv->bv_len = size;
+               len = (size > PAGE_SIZE) ? PAGE_SIZE : size;
+
+               if (!bio_add_page(clone, page, len, 0)) {
+                       mempool_free(page, cc->page_pool);
+                       break;
+               }
 
-               clone->bi_size += bv->bv_len;
-               clone->bi_vcnt++;
-               size -= bv->bv_len;
+               size -= len;
        }
 
        if (!clone->bi_size) {
@@ -511,6 +509,9 @@ static void crypt_endio(struct bio *clone, int error)
        struct crypt_config *cc = io->target->private;
        unsigned read_io = bio_data_dir(clone) == READ;
 
+       if (unlikely(!bio_flagged(clone, BIO_UPTODATE) && !error))
+               error = -EIO;
+
        /*
         * free the processed pages
         */
@@ -519,10 +520,8 @@ static void crypt_endio(struct bio *clone, int error)
                goto out;
        }
 
-       if (unlikely(!bio_flagged(clone, BIO_UPTODATE))) {
-               error = -EIO;
+       if (unlikely(error))
                goto out;
-       }
 
        bio_put(clone);
        kcryptd_queue_crypt(io);
index 138200bf5e0befa90ff67d7ac50c231313f94380..9627fa0f9470cfdb4055199e83eb68c7f8a5f18f 100644 (file)
@@ -332,6 +332,8 @@ static int dm_hash_rename(const char *old, const char *new)
                dm_table_put(table);
        }
 
+       dm_kobject_uevent(hc->md);
+
        dm_put(hc->md);
        up_write(&_hash_lock);
        kfree(old_name);
@@ -1250,21 +1252,17 @@ static int target_message(struct dm_ioctl *param, size_t param_size)
        if (!table)
                goto out_argv;
 
-       if (tmsg->sector >= dm_table_get_size(table)) {
+       ti = dm_table_find_target(table, tmsg->sector);
+       if (!dm_target_is_valid(ti)) {
                DMWARN("Target message sector outside device.");
                r = -EINVAL;
-               goto out_table;
-       }
-
-       ti = dm_table_find_target(table, tmsg->sector);
-       if (ti->type->message)
+       } else if (ti->type->message)
                r = ti->type->message(ti, argc, argv);
        else {
                DMWARN("Target type does not support messages");
                r = -EINVAL;
        }
 
- out_table:
        dm_table_put(table);
  out_argv:
        kfree(argv);
index e298d8d11f24bb1892d959833dbd84cf4f9e16e6..47818d8249cbf16f125328d39d2be54c0241130a 100644 (file)
@@ -99,6 +99,9 @@ static void combine_restrictions_low(struct io_restrictions *lhs,
        lhs->max_segment_size =
                min_not_zero(lhs->max_segment_size, rhs->max_segment_size);
 
+       lhs->max_hw_sectors =
+               min_not_zero(lhs->max_hw_sectors, rhs->max_hw_sectors);
+
        lhs->seg_boundary_mask =
                min_not_zero(lhs->seg_boundary_mask, rhs->seg_boundary_mask);
 
@@ -189,8 +192,10 @@ static int alloc_targets(struct dm_table *t, unsigned int num)
 
        /*
         * Allocate both the target array and offset array at once.
+        * Append an empty entry to catch sectors beyond the end of
+        * the device.
         */
-       n_highs = (sector_t *) dm_vcalloc(num, sizeof(struct dm_target) +
+       n_highs = (sector_t *) dm_vcalloc(num + 1, sizeof(struct dm_target) +
                                          sizeof(sector_t));
        if (!n_highs)
                return -ENOMEM;
@@ -564,6 +569,9 @@ void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev)
        rs->max_segment_size =
                min_not_zero(rs->max_segment_size, q->max_segment_size);
 
+       rs->max_hw_sectors =
+               min_not_zero(rs->max_hw_sectors, q->max_hw_sectors);
+
        rs->seg_boundary_mask =
                min_not_zero(rs->seg_boundary_mask,
                             q->seg_boundary_mask);
@@ -701,6 +709,8 @@ static void check_for_valid_limits(struct io_restrictions *rs)
 {
        if (!rs->max_sectors)
                rs->max_sectors = SAFE_MAX_SECTORS;
+       if (!rs->max_hw_sectors)
+               rs->max_hw_sectors = SAFE_MAX_SECTORS;
        if (!rs->max_phys_segments)
                rs->max_phys_segments = MAX_PHYS_SEGMENTS;
        if (!rs->max_hw_segments)
@@ -867,6 +877,9 @@ struct dm_target *dm_table_get_target(struct dm_table *t, unsigned int index)
 
 /*
  * Search the btree for the correct target.
+ *
+ * Caller should check returned pointer with dm_target_is_valid()
+ * to trap I/O beyond end of device.
  */
 struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector)
 {
@@ -896,6 +909,7 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q)
        q->max_hw_segments = t->limits.max_hw_segments;
        q->hardsect_size = t->limits.hardsect_size;
        q->max_segment_size = t->limits.max_segment_size;
+       q->max_hw_sectors = t->limits.max_hw_sectors;
        q->seg_boundary_mask = t->limits.seg_boundary_mask;
        q->bounce_pfn = t->limits.bounce_pfn;
        if (t->limits.no_cluster)
index 07cbbb8eb3e0d5d67f5c7bed7ea399f6636e5954..88c0fd657825fb88aab0eb07611050b2546c3514 100644 (file)
@@ -672,13 +672,19 @@ static struct bio *clone_bio(struct bio *bio, sector_t sector,
        return clone;
 }
 
-static void __clone_and_map(struct clone_info *ci)
+static int __clone_and_map(struct clone_info *ci)
 {
        struct bio *clone, *bio = ci->bio;
-       struct dm_target *ti = dm_table_find_target(ci->map, ci->sector);
-       sector_t len = 0, max = max_io_len(ci->md, ci->sector, ti);
+       struct dm_target *ti;
+       sector_t len = 0, max;
        struct dm_target_io *tio;
 
+       ti = dm_table_find_target(ci->map, ci->sector);
+       if (!dm_target_is_valid(ti))
+               return -EIO;
+
+       max = max_io_len(ci->md, ci->sector, ti);
+
        /*
         * Allocate a target io object.
         */
@@ -736,6 +742,9 @@ static void __clone_and_map(struct clone_info *ci)
                do {
                        if (offset) {
                                ti = dm_table_find_target(ci->map, ci->sector);
+                               if (!dm_target_is_valid(ti))
+                                       return -EIO;
+
                                max = max_io_len(ci->md, ci->sector, ti);
 
                                tio = alloc_tio(ci->md);
@@ -759,6 +768,8 @@ static void __clone_and_map(struct clone_info *ci)
 
                ci->idx++;
        }
+
+       return 0;
 }
 
 /*
@@ -767,6 +778,7 @@ static void __clone_and_map(struct clone_info *ci)
 static int __split_bio(struct mapped_device *md, struct bio *bio)
 {
        struct clone_info ci;
+       int error = 0;
 
        ci.map = dm_get_table(md);
        if (unlikely(!ci.map))
@@ -784,11 +796,11 @@ static int __split_bio(struct mapped_device *md, struct bio *bio)
        ci.idx = bio->bi_idx;
 
        start_io_acct(ci.io);
-       while (ci.sector_count)
-               __clone_and_map(&ci);
+       while (ci.sector_count && !error)
+               error = __clone_and_map(&ci);
 
        /* drop the extra reference count */
-       dec_pending(ci.io, 0);
+       dec_pending(ci.io, error);
        dm_table_put(ci.map);
 
        return 0;
@@ -1502,7 +1514,7 @@ int dm_resume(struct mapped_device *md)
 
        dm_table_unplug_all(map);
 
-       kobject_uevent(&md->disk->kobj, KOBJ_CHANGE);
+       dm_kobject_uevent(md);
 
        r = 0;
 
@@ -1516,6 +1528,11 @@ out:
 /*-----------------------------------------------------------------
  * Event notification.
  *---------------------------------------------------------------*/
+void dm_kobject_uevent(struct mapped_device *md)
+{
+       kobject_uevent(&md->disk->kobj, KOBJ_CHANGE);
+}
+
 uint32_t dm_next_uevent_seq(struct mapped_device *md)
 {
        return atomic_add_return(1, &md->uevent_seq);
index 4b3faa45277ec81666876110423c9c0f1cb8954e..b4584a39383bdeda58fc1f16f596447648f1e110 100644 (file)
@@ -112,6 +112,11 @@ int dm_table_resume_targets(struct dm_table *t);
 int dm_table_any_congested(struct dm_table *t, int bdi_bits);
 void dm_table_unplug_all(struct dm_table *t);
 
+/*
+ * To check the return value from dm_table_find_target().
+ */
+#define dm_target_is_valid(t) ((t)->table)
+
 /*-----------------------------------------------------------------
  * A registry of target types.
  *---------------------------------------------------------------*/
@@ -182,4 +187,6 @@ union map_info *dm_get_mapinfo(struct bio *bio);
 int dm_open_count(struct mapped_device *md);
 int dm_lock_for_deletion(struct mapped_device *md);
 
+void dm_kobject_uevent(struct mapped_device *md);
+
 #endif
index e176d195e7e53982659388b970d60270f9bb695b..7596e1e94cde858df0ba7ea0907f9b86d1f4132e 100644 (file)
@@ -319,7 +319,6 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
        current->mm->free_area_cache = current->mm->mmap_base;
        current->mm->cached_hole_size = 0;
 
-       current->mm->mmap = NULL;
        compute_creds(bprm);
        current->flags &= ~PF_FORKNOEXEC;
 #ifdef __sparc__
index b8b7c51389fe0ecff2608f63b928140601347a3f..e765e191663dde89ecc150639d2d4eee1096ae88 100644 (file)
@@ -115,6 +115,7 @@ struct io_restrictions {
        unsigned short          max_hw_segments;
        unsigned short          hardsect_size;
        unsigned int            max_segment_size;
+       unsigned int            max_hw_sectors;
        unsigned long           seg_boundary_mask;
        unsigned long           bounce_pfn;
        unsigned char           no_cluster; /* inverted so that 0 is default */