]> sourceware.org Git - dm.git/commitdiff
Sync some fixes with bitkeeper repository.
authorAlasdair Kergon <agk@redhat.com>
Wed, 14 Aug 2002 13:24:27 +0000 (13:24 +0000)
committerAlasdair Kergon <agk@redhat.com>
Wed, 14 Aug 2002 13:24:27 +0000 (13:24 +0000)
12 files changed:
VERSION
kernel/common/device-mapper.h
kernel/common/dm-linear.c
kernel/common/dm-mirror.c
kernel/common/dm-snapshot.c
kernel/common/dm-stripe.c
kernel/common/dm-table.c
kernel/common/dm.c
kernel/common/dm.h
kernel/common/kcopyd.c
kernel/ioctl/dm-ioctl.c
kernel/ioctl/dm-ioctl.h

diff --git a/VERSION b/VERSION
index 79301ee0b07a08a54ba3f7f4ff6dc271122ae5fb..cabb3e4d3acf05f6b2b3ce1c98dc51fbde2c8bb0 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.96.03-cvs (2002-06-27)
+0.96.04-cvs (2002-08-14)
index 047cbdab6d0a0367056b15e746d9136327e4d584..c6651efb6400e423aea5990d50d7d0aa0bb2e397 100644 (file)
@@ -38,7 +38,8 @@ void dm_error(const char *message);
  * are opened/closed correctly
  */
 int dm_table_get_device(struct dm_table *t, const char *path,
-                       offset_t start, offset_t len, struct dm_dev **result);
+                       offset_t start, offset_t len,
+                       int mode, struct dm_dev **result);
 void dm_table_put_device(struct dm_table *table, struct dm_dev *d);
 
 /*
index d6a91f7f7872f9f982c919da4452d2548bb071d8..f240bf72dc3d55f7d1a34e1a5ec80c3ca8487dd5 100644 (file)
@@ -46,7 +46,7 @@ static int linear_ctr(struct dm_table *t, offset_t b, offset_t l,
                goto bad;
        }
 
-       if (dm_table_get_device(t, argv[0], start, l, &lc->dev)) {
+       if (dm_table_get_device(t, argv[0], start, l, t->mode, &lc->dev)) {
                *context = "dm-linear: Device lookup failed";
                goto bad;
        }
index 64a53370b2afa5531e1e4d183b8d3ef34d7d8c95..ee8ba752a05565a9454dd7f2cf98510458a48293 100644 (file)
@@ -66,8 +66,8 @@ static void mirror_bh(struct mirror_c *mc, struct buffer_head *bh)
        dest.sector = bh->b_rsector - mc->from_delta + mc->to_delta;
        dest.count = bh->b_size / 512;
        kcopyd_write_pages(&dest, 1, &bh->b_page,
-                          ((long) bh->b_data -
-                           (long) page_address(bh->b_page)) / 512,
+                          ((long)bh->b_data -
+                           (long)page_address(bh->b_page)) / 512,
                           mirror_callback, mc);
 }
 
@@ -77,6 +77,7 @@ static void copy_callback(int err, void *context)
        struct mirror_c *lc = (struct mirror_c *) context;
        struct buffer_head *bh;
 
+
        /* Submit, and mirror any pending BHs */
        down_write(&lc->lock);
 
@@ -112,7 +113,7 @@ static void copy_callback(int err, void *context)
 
                src.dev = lc->fromdev->dev;
                src.sector = lc->frompos + lc->got_to;
-               src.count = min((unsigned long) lc->chunksize, 
+               src.count = min((unsigned long)lc->chunksize,
                                lc->size - lc->got_to);
 
                dest.dev = lc->todev->dev;
@@ -154,7 +155,7 @@ static int mirror_ctr(struct dm_table *t, offset_t b, offset_t l,
                return -ENOMEM;
        }
 
-       if (dm_table_get_device(t, argv[0], 0, l, &lc->fromdev)) {
+       if (dm_table_get_device(t, argv[0], 0, l, t->mode, &lc->fromdev)) {
                *context = "dm-mirror: Device lookup failed";
                goto bad;
        }
@@ -166,7 +167,7 @@ static int mirror_ctr(struct dm_table *t, offset_t b, offset_t l,
                goto bad;
        }
 
-       if (dm_table_get_device(t, argv[2], 0, l, &lc->todev)) {
+       if (dm_table_get_device(t, argv[2], 0, l, t->mode, &lc->todev)) {
                *context = "dm-mirror: Device lookup failed";
                dm_table_put_device(t, lc->fromdev);
                goto bad;
@@ -209,7 +210,7 @@ static int mirror_ctr(struct dm_table *t, offset_t b, offset_t l,
        /* Tell kcopyd to do the biz */
        src.dev = lc->fromdev->dev;
        src.sector = offset1;
-       src.count = min((unsigned long) chunksize, lc->size);
+       src.count = min((unsigned long)chunksize, lc->size);
 
        dest.dev = lc->todev->dev;
        dest.sector = offset2;
index 536184772a3d7109053121ed14062d21e1d1c364..7ec19f5101a0f670baec3734fdc7227bc921be3d 100644 (file)
@@ -379,6 +379,16 @@ static int init_hash_tables(struct dm_snapshot *s)
        return 0;
 }
 
+/*
+ * Round a number up to the nearest 'size' boundary.  size must
+ * be a power of 2.
+ */
+static inline ulong round_up(ulong n, ulong size)
+{
+       size--;
+       return (n + size) & ~size;
+}
+
 /*
  * Construct a snapshot mapping: <origin_dev> <COW-dev> <p/n> <chunk-size>
  */
@@ -424,22 +434,25 @@ static int snapshot_ctr(struct dm_table *t, offset_t b, offset_t l,
                goto bad;
        }
 
-       r = dm_table_get_device(t, origin_path, 0, 0, &s->origin);
+       r = dm_table_get_device(t, origin_path, 0, 0, FMODE_READ, &s->origin);
        if (r) {
                *context = "Cannot get origin device";
                goto bad_free;
        }
 
-       r = dm_table_get_device(t, cow_path, 0, 0, &s->cow);
+       r = dm_table_get_device(t, cow_path, 0, 0,
+                               FMODE_READ | FMODE_WRITE, &s->cow);
        if (r) {
                dm_table_put_device(t, s->origin);
                *context = "Cannot get COW device";
                goto bad_free;
        }
 
-       /* Chunk size must be multiple of page size. If it's wrong, fix it */
-       if (chunk_size < (PAGE_SIZE / SECTOR_SIZE))
-               chunk_size = PAGE_SIZE / SECTOR_SIZE;
+       /*
+        * Chunk size must be multiple of page size.  Silently
+        * round up if it's not.
+        */
+       chunk_size = round_up(chunk_size, PAGE_SIZE / SECTOR_SIZE);
 
        /* Validate the chunk size against the device block size */
        blocksize = get_hardsect_size(s->cow->dev);
@@ -996,7 +1009,7 @@ static int origin_ctr(struct dm_table *t, offset_t b, offset_t l,
                return -EINVAL;
        }
 
-       r = dm_table_get_device(t, argv[0], 0, l, &dev);
+       r = dm_table_get_device(t, argv[0], 0, l, t->mode, &dev);
        if (r) {
                *context = "Cannot get target device";
                return r;
index a05ee7901126cf4cbe7807224c6c9429bcdf499c..92a7bcfd2bbb29ea075d9a98423581a37b07b62e 100644 (file)
@@ -56,7 +56,7 @@ static int get_stripe(struct dm_table *t, struct stripe_c *sc,
                return -EINVAL;
 
        if (dm_table_get_device(t, argv[0], start, sc->stripe_width,
-                               &sc->stripe[stripe].dev))
+                               t->mode, &sc->stripe[stripe].dev))
                return -ENXIO;
 
        sc->stripe[stripe].physical_start = start;
index 786996f1e19c1e4c4b988ba8d056fc8af2f8dd97..1282680297b3d059bb6fb88bd80e013a3585a64a 100644 (file)
@@ -104,7 +104,7 @@ static int alloc_targets(struct dm_table *t, int num)
        return 0;
 }
 
-int dm_table_create(struct dm_table **result)
+int dm_table_create(struct dm_table **result, int mode)
 {
        struct dm_table *t = kmalloc(sizeof(*t), GFP_NOIO);
 
@@ -122,6 +122,7 @@ int dm_table_create(struct dm_table **result)
        }
 
        init_waitqueue_head(&t->eventq);
+       t->mode = mode;
        *result = t;
        return 0;
 }
@@ -244,7 +245,7 @@ static int open_dev(struct dm_dev *d)
        if (!(d->bd = bdget(kdev_t_to_nr(d->dev))))
                return -ENOMEM;
 
-       if ((err = blkdev_get(d->bd, FMODE_READ | FMODE_WRITE, 0, BDEV_FILE)))
+       if ((err = blkdev_get(d->bd, d->mode, 0, BDEV_FILE)))
                return err;
 
        return 0;
@@ -283,12 +284,36 @@ static int check_device_area(kdev_t dev, offset_t start, offset_t len)
        return ((start < dev_size) && (len <= (dev_size - start)));
 }
 
+/*
+ * This upgrades the mode on an already open dm_dev.  Being
+ * careful to leave things as they were if we fail to reopen the
+ * device.
+ */
+static int upgrade_mode(struct dm_dev *dd, int new_mode)
+{
+       int r;
+       struct dm_dev dd_copy;
+
+       memcpy(&dd_copy, dd, sizeof(dd_copy));
+
+       dd->mode |= new_mode;
+       dd->bd = NULL;
+       r = open_dev(dd);
+       if (!r)
+               close_dev(&dd_copy);
+       else
+               memcpy(dd, &dd_copy, sizeof(dd_copy));
+
+       return r;
+}
+
 /*
  * Add a device to the list, or just increment the usage count
  * if it's already present.
  */
 int dm_table_get_device(struct dm_table *t, const char *path,
-                       offset_t start, offset_t len, struct dm_dev **result)
+                       offset_t start, offset_t len, int mode,
+                       struct dm_dev **result)
 {
        int r;
        kdev_t dev;
@@ -310,6 +335,7 @@ int dm_table_get_device(struct dm_table *t, const char *path,
                if (!dd)
                        return -ENOMEM;
 
+               dd->mode = mode;
                dd->dev = dev;
                dd->bd = NULL;
 
@@ -320,6 +346,11 @@ int dm_table_get_device(struct dm_table *t, const char *path,
 
                atomic_set(&dd->count, 0);
                list_add(&dd->list, &t->devices);
+
+       } else if (dd->mode != (mode | dd->mode)) {
+               r = upgrade_mode(dd, mode);
+               if (r)
+                       return r;
        }
        atomic_inc(&dd->count);
 
index f58b89695ca9a8282f4c6774ccee302f0ec5c8a5..6c2ff987e4babb915535777747ce7f24250e4a3b 100644 (file)
@@ -5,7 +5,6 @@
  */
 
 #include "dm.h"
-#include "kcopyd.h"
 
 #include <linux/blk.h>
 #include <linux/blkpg.h>
@@ -437,7 +436,7 @@ static inline int call_err_fn(struct io_hook *ih, struct buffer_head *bh)
  */
 static void dec_pending(struct buffer_head *bh, int uptodate)
 {
-       struct io_hook *ih = bh->b_bdev_private;
+       struct io_hook *ih = bh->b_private;
 
        if (!uptodate && call_err_fn(ih, bh))
                return;
@@ -447,7 +446,7 @@ static void dec_pending(struct buffer_head *bh, int uptodate)
                wake_up(&ih->md->wait);
 
        bh->b_end_io = ih->end_io;
-       bh->b_bdev_private = ih->context;
+       bh->b_private = ih->context;
        free_io_hook(ih);
 
        bh->b_end_io(bh, uptodate);
@@ -510,7 +509,7 @@ static inline int __map_buffer(struct mapped_device *md,
        ih->rw = rw;
        ih->target = ti;
        ih->end_io = bh->b_end_io;
-       ih->context = bh->b_bdev_private;
+       ih->context = bh->b_private;
 
        r = fn(bh, rw, context);
 
@@ -518,7 +517,7 @@ static inline int __map_buffer(struct mapped_device *md,
                /* hook the end io request fn */
                atomic_inc(&md->pending);
                bh->b_end_io = dec_pending;
-               bh->b_bdev_private = ih;
+               bh->b_private = ih;
 
        } else if (r == 0)
                /* we don't need to hook */
index 6ba0bb51f44ec08a2ecc8a514f451eb6c6c8eea3..a9ca3f442ef81a18e92c4ce96c8d94e40fffa925 100644 (file)
@@ -41,6 +41,8 @@ struct dm_dev {
        atomic_t count;
        struct list_head list;
 
+       int mode;
+
        kdev_t dev;
        struct block_device *bd;
 };
@@ -76,6 +78,13 @@ struct dm_table {
        offset_t *highs;
        struct target *targets;
 
+       /*
+        * Indicates the rw permissions for the new logical
+        * device.  This should be a combination of FMODE_READ
+        * and FMODE_WRITE.
+        */
+       int mode;
+
        /* a list of devices used by this table */
        struct list_head devices;
 
@@ -167,7 +176,7 @@ int dm_suspend(struct mapped_device *md);
 int dm_resume(struct mapped_device *md);
 
 /* dm-table.c */
-int dm_table_create(struct dm_table **result);
+int dm_table_create(struct dm_table **result, int mode);
 void dm_table_destroy(struct dm_table *t);
 
 int dm_table_add_target(struct dm_table *t, offset_t highs,
@@ -179,14 +188,6 @@ int dm_table_complete(struct dm_table *t);
  */
 void dm_table_event(struct dm_table *t);
 
-/* Snapshots */
-int dm_snapshot_init(void);
-void dm_snapshot_exit(void);
-
-/* dm-mirror.c */
-int dm_mirror_init(void);
-void dm_mirror_exit(void);
-
 #define DMWARN(f, x...) printk(KERN_WARNING DM_NAME ": " f "\n" , ## x)
 #define DMERR(f, x...) printk(KERN_ERR DM_NAME ": " f "\n" , ## x)
 #define DMINFO(f, x...) printk(KERN_INFO DM_NAME ": " f "\n" , ## x)
@@ -214,20 +215,27 @@ static inline int array_too_big(unsigned long fixed, unsigned long obj,
 }
 
 /*
- * The device-mapper can be driven through one of two interfaces;
- * ioctl or filesystem, depending which patch you have applied.
+ * Targets
  */
-int __init dm_interface_init(void);
-void dm_interface_exit(void);
-
-/*
- * Targets for linear and striped mappings
- */
-
 int dm_linear_init(void);
 void dm_linear_exit(void);
 
 int dm_stripe_init(void);
 void dm_stripe_exit(void);
 
+int dm_snapshot_init(void);
+void dm_snapshot_exit(void);
+
+int dm_mirror_init(void);
+void dm_mirror_exit(void);
+
+/*
+ * Init functions for the user interface to device-mapper.  At
+ * the moment an ioctl interface on a special char device is
+ * used.  A filesystem based interface would be a nicer way to
+ * go.
+ */
+int __init dm_interface_init(void);
+void dm_interface_exit(void);
+
 #endif
index b7d2af8b367e3f911fa03b5af2f7f383f99e9062..328ba5ae28c1a48dc7b36e59986e989b860c8f86 100644 (file)
@@ -179,12 +179,21 @@ static struct buffer_head *alloc_buffer(void)
  */
 static void free_buffer(struct buffer_head *bh)
 {
-       int flags;
+       int flags, was_empty;
 
        spin_lock_irqsave(&_buffer_lock, flags);
+       was_empty = (_free_buffers == NULL) ? 1 : 0;
        bh->b_reqnext = _free_buffers;
        _free_buffers = bh;
        spin_unlock_irqrestore(&_buffer_lock, flags);
+
+       /*
+        * If the buffer list was empty then kcopyd probably went
+        * to sleep because it ran out of buffer heads, so let's
+        * wake it up.
+        */
+       if (was_empty)
+               wake_kcopyd();
 }
 
 /*-----------------------------------------------------------------
index 258b75ee773b19d6a84ec9be208372784d5bbe9b..4109bf43cc9e375c6efcc643d3750d7e18d6e6c9 100644 (file)
@@ -252,13 +252,23 @@ static int info(struct dm_ioctl *param, struct dm_ioctl *user)
        return results_to_user(user, param, NULL, 0);
 }
 
+static inline int get_mode(struct dm_ioctl *param)
+{
+       int mode = FMODE_READ | FMODE_WRITE;
+
+       if (param->flags & DM_READONLY_FLAG)
+               mode = FMODE_READ;
+
+       return mode;
+}
+
 static int create(struct dm_ioctl *param, struct dm_ioctl *user)
 {
        int r, ro;
        struct dm_table *t;
        int minor;
 
-       r = dm_table_create(&t);
+       r = dm_table_create(&t, get_mode(param));
        if (r)
                return r;
 
@@ -523,7 +533,7 @@ static int reload(struct dm_ioctl *param, struct dm_ioctl *user)
        struct mapped_device *md;
        struct dm_table *t;
 
-       r = dm_table_create(&t);
+       r = dm_table_create(&t, get_mode(param));
        if (r)
                return r;
 
index 3b3f1dcc9db5d7c325460b83e7c1dfe42776159f..385df6a48b100b7db9b2a90aa7b36025757905e6 100644 (file)
@@ -127,8 +127,8 @@ enum {
 
 #define DM_VERSION_MAJOR       1
 #define DM_VERSION_MINOR       0
-#define DM_VERSION_PATCHLEVEL  2
-#define DM_VERSION_EXTRA       "-ioctl-cvs (2002-07-17)"
+#define DM_VERSION_PATCHLEVEL  3
+#define DM_VERSION_EXTRA       "-ioctl-cvs (2002-08-14)"
 
 /* Status bits */
 #define DM_READONLY_FLAG       0x00000001
This page took 0.045226 seconds and 5 git commands to generate.