Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 22768
Collapse All | Expand All

(-)linux-2.4.20-gentoo-r5/Documentation/Configure.help (+14 lines)
Lines 2048-2053 Link Here
2048
  want), say M here and read <file:Documentation/modules.txt>.  The
2048
  want), say M here and read <file:Documentation/modules.txt>.  The
2049
  module will be called lvm-mod.o.
2049
  module will be called lvm-mod.o.
2050
2050
2051
Device-mapper support
2052
CONFIG_BLK_DEV_DM
2053
  Device-mapper is a low level volume manager.  It works by allowing
2054
  people to specify mappings for ranges of logical sectors.  Various
2055
  mapping types are available, in addition people may write their own
2056
  modules containing custom mappings if they wish.
2057
2058
  Higher level volume managers such as LVM2 use this driver.
2059
2060
  If you want to compile this as a module, say M here and read 
2061
  <file:Documentation/modules.txt>.  The module will be called dm-mod.o.
2062
2063
  If unsure, say N.
2064
2051
Multiple devices driver support (RAID and LVM)
2065
Multiple devices driver support (RAID and LVM)
2052
CONFIG_MD
2066
CONFIG_MD
2053
  Support multiple physical spindles through a single logical device.
2067
  Support multiple physical spindles through a single logical device.
(-)linux-2.4.20-gentoo-r5/MAINTAINERS (+7 lines)
Lines 441-446 Link Here
441
W:	http://www.debian.org/~dz/i8k/
441
W:	http://www.debian.org/~dz/i8k/
442
S:	Maintained
442
S:	Maintained
443
443
444
DEVICE MAPPER
445
P:	Joe Thornber
446
M:	dm@uk.sistina.com
447
L:	linux-LVM@sistina.com
448
W:	http://www.sistina.com/lvm
449
S:	Maintained
450
444
DEVICE NUMBER REGISTRY
451
DEVICE NUMBER REGISTRY
445
P:	H. Peter Anvin
452
P:	H. Peter Anvin
446
M:	hpa@zytor.com
453
M:	hpa@zytor.com
(-)linux-2.4.20-gentoo-r5/arch/mips64/kernel/ioctl32.c (+15 lines)
Lines 33-38 Link Here
33
#include <linux/auto_fs.h>
33
#include <linux/auto_fs.h>
34
#include <linux/ext2_fs.h>
34
#include <linux/ext2_fs.h>
35
#include <linux/raid/md_u.h>
35
#include <linux/raid/md_u.h>
36
#include <linux/dm-ioctl.h>
36
37
37
#include <scsi/scsi.h>
38
#include <scsi/scsi.h>
38
#undef __KERNEL__		/* This file was born to be ugly ...  */
39
#undef __KERNEL__		/* This file was born to be ugly ...  */
Lines 915-920 Link Here
915
	IOCTL32_DEFAULT(RESTART_ARRAY_RW),
916
	IOCTL32_DEFAULT(RESTART_ARRAY_RW),
916
#endif /* CONFIG_MD */
917
#endif /* CONFIG_MD */
917
918
919
#if defined(CONFIG_BLK_DEV_DM) || defined(CONFIG_BLK_DEV_DM_MODULE)
920
	IOCTL32_DEFAULT(DM_VERSION),
921
	IOCTL32_DEFAULT(DM_REMOVE_ALL),
922
	IOCTL32_DEFAULT(DM_DEV_CREATE),
923
	IOCTL32_DEFAULT(DM_DEV_REMOVE),
924
	IOCTL32_DEFAULT(DM_DEV_RELOAD),
925
	IOCTL32_DEFAULT(DM_DEV_SUSPEND),
926
	IOCTL32_DEFAULT(DM_DEV_RENAME),
927
	IOCTL32_DEFAULT(DM_DEV_DEPS),
928
	IOCTL32_DEFAULT(DM_DEV_STATUS),
929
	IOCTL32_DEFAULT(DM_TARGET_STATUS),
930
	IOCTL32_DEFAULT(DM_TARGET_WAIT),
931
#endif /* CONFIG_BLK_DEV_DM */
932
918
	IOCTL32_DEFAULT(MTIOCTOP),			/* mtio.h ioctls  */
933
	IOCTL32_DEFAULT(MTIOCTOP),			/* mtio.h ioctls  */
919
	IOCTL32_HANDLER(MTIOCGET32, mt_ioctl_trans),
934
	IOCTL32_HANDLER(MTIOCGET32, mt_ioctl_trans),
920
	IOCTL32_HANDLER(MTIOCPOS32, mt_ioctl_trans),
935
	IOCTL32_HANDLER(MTIOCPOS32, mt_ioctl_trans),
(-)linux-2.4.20-gentoo-r5/arch/parisc/kernel/ioctl32.c (+15 lines)
Lines 55-60 Link Here
55
#define max max */
55
#define max max */
56
#include <linux/lvm.h>
56
#include <linux/lvm.h>
57
#endif /* LVM */
57
#endif /* LVM */
58
#include <linux/dm-ioctl.h>
58
59
59
#include <scsi/scsi.h>
60
#include <scsi/scsi.h>
60
/* Ugly hack. */
61
/* Ugly hack. */
Lines 3419-3424 Link Here
3419
COMPATIBLE_IOCTL(LV_BMAP)
3420
COMPATIBLE_IOCTL(LV_BMAP)
3420
COMPATIBLE_IOCTL(LV_SNAPSHOT_USE_RATE)
3421
COMPATIBLE_IOCTL(LV_SNAPSHOT_USE_RATE)
3421
#endif /* LVM */
3422
#endif /* LVM */
3423
/* Device-Mapper */
3424
#if defined(CONFIG_BLK_DEV_DM) || defined(CONFIG_BLK_DEV_DM_MODULE)
3425
COMPATIBLE_IOCTL(DM_VERSION)
3426
COMPATIBLE_IOCTL(DM_REMOVE_ALL)
3427
COMPATIBLE_IOCTL(DM_DEV_CREATE)
3428
COMPATIBLE_IOCTL(DM_DEV_REMOVE)
3429
COMPATIBLE_IOCTL(DM_DEV_RELOAD)
3430
COMPATIBLE_IOCTL(DM_DEV_SUSPEND)
3431
COMPATIBLE_IOCTL(DM_DEV_RENAME)
3432
COMPATIBLE_IOCTL(DM_DEV_DEPS)
3433
COMPATIBLE_IOCTL(DM_DEV_STATUS)
3434
COMPATIBLE_IOCTL(DM_TARGET_STATUS)
3435
COMPATIBLE_IOCTL(DM_TARGET_WAIT)
3436
#endif /* CONFIG_BLK_DEV_DM */
3422
#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
3437
#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
3423
COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC)
3438
COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC)
3424
COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID)
3439
COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID)
(-)linux-2.4.20-gentoo-r5/arch/ppc64/kernel/ioctl32.c (+15 lines)
Lines 66-71 Link Here
66
#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
66
#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
67
#include <linux/lvm.h>
67
#include <linux/lvm.h>
68
#endif /* LVM */
68
#endif /* LVM */
69
#include <linux/dm-ioctl.h>
69
70
70
#include <scsi/scsi.h>
71
#include <scsi/scsi.h>
71
/* Ugly hack. */
72
/* Ugly hack. */
Lines 4366-4371 Link Here
4366
COMPATIBLE_IOCTL(NBD_PRINT_DEBUG),
4367
COMPATIBLE_IOCTL(NBD_PRINT_DEBUG),
4367
COMPATIBLE_IOCTL(NBD_SET_SIZE_BLOCKS),
4368
COMPATIBLE_IOCTL(NBD_SET_SIZE_BLOCKS),
4368
COMPATIBLE_IOCTL(NBD_DISCONNECT),
4369
COMPATIBLE_IOCTL(NBD_DISCONNECT),
4370
/* device-mapper */
4371
#if defined(CONFIG_BLK_DEV_DM) || defined(CONFIG_BLK_DEV_DM_MODULE)
4372
COMPATIBLE_IOCTL(DM_VERSION),
4373
COMPATIBLE_IOCTL(DM_REMOVE_ALL),
4374
COMPATIBLE_IOCTL(DM_DEV_CREATE),
4375
COMPATIBLE_IOCTL(DM_DEV_REMOVE),
4376
COMPATIBLE_IOCTL(DM_DEV_RELOAD),
4377
COMPATIBLE_IOCTL(DM_DEV_SUSPEND),
4378
COMPATIBLE_IOCTL(DM_DEV_RENAME),
4379
COMPATIBLE_IOCTL(DM_DEV_DEPS),
4380
COMPATIBLE_IOCTL(DM_DEV_STATUS),
4381
COMPATIBLE_IOCTL(DM_TARGET_STATUS),
4382
COMPATIBLE_IOCTL(DM_TARGET_WAIT),
4383
#endif /* CONFIG_BLK_DEV_DM */
4369
/* Remove *PRIVATE in 2.5 */
4384
/* Remove *PRIVATE in 2.5 */
4370
COMPATIBLE_IOCTL(SIOCDEVPRIVATE),
4385
COMPATIBLE_IOCTL(SIOCDEVPRIVATE),
4371
COMPATIBLE_IOCTL(SIOCDEVPRIVATE+1),
4386
COMPATIBLE_IOCTL(SIOCDEVPRIVATE+1),
(-)linux-2.4.20-gentoo-r5/arch/s390x/kernel/ioctl32.c (+13 lines)
Lines 25-30 Link Here
25
#include <linux/ext2_fs.h>
25
#include <linux/ext2_fs.h>
26
#include <linux/hdreg.h>
26
#include <linux/hdreg.h>
27
#include <linux/if_bonding.h>
27
#include <linux/if_bonding.h>
28
#include <linux/dm-ioctl.h>
28
#include <asm/types.h>
29
#include <asm/types.h>
29
#include <asm/uaccess.h>
30
#include <asm/uaccess.h>
30
#include <asm/dasd.h>
31
#include <asm/dasd.h>
Lines 508-513 Link Here
508
509
509
	IOCTL32_DEFAULT(SIOCGSTAMP),
510
	IOCTL32_DEFAULT(SIOCGSTAMP),
510
511
512
	IOCTL32_DEFAULT(DM_VERSION),
513
	IOCTL32_DEFAULT(DM_REMOVE_ALL),
514
	IOCTL32_DEFAULT(DM_DEV_CREATE),
515
	IOCTL32_DEFAULT(DM_DEV_REMOVE),
516
	IOCTL32_DEFAULT(DM_DEV_RELOAD),
517
	IOCTL32_DEFAULT(DM_DEV_SUSPEND),
518
	IOCTL32_DEFAULT(DM_DEV_RENAME),
519
	IOCTL32_DEFAULT(DM_DEV_DEPS),
520
	IOCTL32_DEFAULT(DM_DEV_STATUS),
521
	IOCTL32_DEFAULT(DM_TARGET_STATUS),
522
	IOCTL32_DEFAULT(DM_TARGET_WAIT),
523
511
	IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32),
524
	IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32),
512
	IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf),
525
	IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf),
513
	IOCTL32_HANDLER(SIOCGIFFLAGS, dev_ifsioc),
526
	IOCTL32_HANDLER(SIOCGIFFLAGS, dev_ifsioc),
(-)linux-2.4.20-gentoo-r5/arch/sparc64/kernel/ioctl32.c (+16 lines)
Lines 55-60 Link Here
55
#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
55
#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
56
#include <linux/lvm.h>
56
#include <linux/lvm.h>
57
#endif /* LVM */
57
#endif /* LVM */
58
#include <linux/dm-ioctl.h>
58
59
59
#include <scsi/scsi.h>
60
#include <scsi/scsi.h>
60
/* Ugly hack. */
61
/* Ugly hack. */
Lines 5131-5136 Link Here
5131
COMPATIBLE_IOCTL(NBD_PRINT_DEBUG)
5132
COMPATIBLE_IOCTL(NBD_PRINT_DEBUG)
5132
COMPATIBLE_IOCTL(NBD_SET_SIZE_BLOCKS)
5133
COMPATIBLE_IOCTL(NBD_SET_SIZE_BLOCKS)
5133
COMPATIBLE_IOCTL(NBD_DISCONNECT)
5134
COMPATIBLE_IOCTL(NBD_DISCONNECT)
5135
/* device-mapper */
5136
#if defined(CONFIG_BLK_DEV_DM) || defined(CONFIG_BLK_DEV_DM_MODULE)
5137
COMPATIBLE_IOCTL(DM_VERSION)
5138
COMPATIBLE_IOCTL(DM_REMOVE_ALL)
5139
COMPATIBLE_IOCTL(DM_DEV_CREATE)
5140
COMPATIBLE_IOCTL(DM_DEV_REMOVE)
5141
COMPATIBLE_IOCTL(DM_DEV_RELOAD)
5142
COMPATIBLE_IOCTL(DM_DEV_SUSPEND)
5143
COMPATIBLE_IOCTL(DM_DEV_RENAME)
5144
COMPATIBLE_IOCTL(DM_DEV_DEPS)
5145
COMPATIBLE_IOCTL(DM_DEV_STATUS)
5146
COMPATIBLE_IOCTL(DM_TARGET_STATUS)
5147
COMPATIBLE_IOCTL(DM_TARGET_WAIT)
5148
#endif /* CONFIG_BLK_DEV_DM */
5149
5134
/* SCSI Changer */
5150
/* SCSI Changer */
5135
COMPATIBLE_IOCTL(CHIOMOVE)
5151
COMPATIBLE_IOCTL(CHIOMOVE)
5136
COMPATIBLE_IOCTL(CHIOEXCHANGE)
5152
COMPATIBLE_IOCTL(CHIOEXCHANGE)
(-)linux-2.4.20-gentoo-r5/arch/x86_64/ia32/ia32_ioctl.c (+15 lines)
Lines 62-67 Link Here
62
#define max max
62
#define max max
63
#include <linux/lvm.h>
63
#include <linux/lvm.h>
64
#endif /* LVM */
64
#endif /* LVM */
65
#include <linux/dm-ioctl.h>
65
66
66
#include <scsi/scsi.h>
67
#include <scsi/scsi.h>
67
/* Ugly hack. */
68
/* Ugly hack. */
Lines 3780-3785 Link Here
3780
COMPATIBLE_IOCTL(LV_BMAP)
3781
COMPATIBLE_IOCTL(LV_BMAP)
3781
COMPATIBLE_IOCTL(LV_SNAPSHOT_USE_RATE)
3782
COMPATIBLE_IOCTL(LV_SNAPSHOT_USE_RATE)
3782
#endif /* LVM */
3783
#endif /* LVM */
3784
/* Device-Mapper */
3785
#if defined(CONFIG_BLK_DEV_DM) || defined(CONFIG_BLK_DEV_DM_MODULE)
3786
COMPATIBLE_IOCTL(DM_VERSION)
3787
COMPATIBLE_IOCTL(DM_REMOVE_ALL)
3788
COMPATIBLE_IOCTL(DM_DEV_CREATE)
3789
COMPATIBLE_IOCTL(DM_DEV_REMOVE)
3790
COMPATIBLE_IOCTL(DM_DEV_RELOAD)
3791
COMPATIBLE_IOCTL(DM_DEV_SUSPEND)
3792
COMPATIBLE_IOCTL(DM_DEV_RENAME)
3793
COMPATIBLE_IOCTL(DM_DEV_DEPS)
3794
COMPATIBLE_IOCTL(DM_DEV_STATUS)
3795
COMPATIBLE_IOCTL(DM_TARGET_STATUS)
3796
COMPATIBLE_IOCTL(DM_TARGET_WAIT)
3797
#endif /* CONFIG_BLK_DEV_DM */
3783
#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
3798
#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
3784
COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC)
3799
COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC)
3785
COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID)
3800
COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID)
(-)linux-2.4.20-gentoo-r5/drivers/md/Config.in (+3 lines)
Lines 14-18 Link Here
14
dep_tristate '  Multipath I/O support' CONFIG_MD_MULTIPATH $CONFIG_BLK_DEV_MD
14
dep_tristate '  Multipath I/O support' CONFIG_MD_MULTIPATH $CONFIG_BLK_DEV_MD
15
15
16
dep_tristate ' Logical volume manager (LVM) support' CONFIG_BLK_DEV_LVM $CONFIG_MD
16
dep_tristate ' Logical volume manager (LVM) support' CONFIG_BLK_DEV_LVM $CONFIG_MD
17
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
18
   dep_tristate ' Device-mapper support (EXPERIMENTAL)' CONFIG_BLK_DEV_DM $CONFIG_MD
19
fi
17
20
18
endmenu
21
endmenu
(-)linux-2.4.20-gentoo-r5/drivers/md/Makefile (-1 / +8 lines)
Lines 4-12 Link Here
4
4
5
O_TARGET	:= mddev.o
5
O_TARGET	:= mddev.o
6
6
7
export-objs	:= md.o xor.o
7
export-objs	:= md.o xor.o dm-table.o dm-target.o kcopyd.o
8
list-multi	:= lvm-mod.o
8
list-multi	:= lvm-mod.o
9
lvm-mod-objs	:= lvm.o lvm-snap.o lvm-fs.o
9
lvm-mod-objs	:= lvm.o lvm-snap.o lvm-fs.o
10
dm-mod-objs	:= dm.o dm-table.o dm-target.o dm-ioctl.o \
11
		   dm-linear.o dm-stripe.o dm-snapshot.o dm-exception-store.o \
12
		   kcopyd.o
10
13
11
# Note: link order is important.  All raid personalities
14
# Note: link order is important.  All raid personalities
12
# and xor.o must come before md.o, as they each initialise 
15
# and xor.o must come before md.o, as they each initialise 
Lines 20-27 Link Here
20
obj-$(CONFIG_MD_MULTIPATH)	+= multipath.o
23
obj-$(CONFIG_MD_MULTIPATH)	+= multipath.o
21
obj-$(CONFIG_BLK_DEV_MD)	+= md.o
24
obj-$(CONFIG_BLK_DEV_MD)	+= md.o
22
obj-$(CONFIG_BLK_DEV_LVM)	+= lvm-mod.o
25
obj-$(CONFIG_BLK_DEV_LVM)	+= lvm-mod.o
26
obj-$(CONFIG_BLK_DEV_DM)	+= dm-mod.o
23
27
24
include $(TOPDIR)/Rules.make
28
include $(TOPDIR)/Rules.make
25
29
26
lvm-mod.o: $(lvm-mod-objs)
30
lvm-mod.o: $(lvm-mod-objs)
27
	$(LD) -r -o $@ $(lvm-mod-objs)
31
	$(LD) -r -o $@ $(lvm-mod-objs)
32
33
dm-mod.o: $(dm-mod-objs)
34
	$(LD) -r -o $@ $(dm-mod-objs)
(-)linux-2.4.20-gentoo-r5/drivers/md/dm-exception-store.c (+704 lines)
Line 0 Link Here
1
/*
2
 * dm-snapshot.c
3
 *
4
 * Copyright (C) 2001-2002 Sistina Software (UK) Limited.
5
 *
6
 * This file is released under the GPL.
7
 */
8
9
#include "dm-snapshot.h"
10
#include "kcopyd.h"
11
12
#include <linux/mm.h>
13
#include <linux/pagemap.h>
14
#include <linux/vmalloc.h>
15
#include <linux/slab.h>
16
17
/*-----------------------------------------------------------------
18
 * Persistent snapshots, by persistent we mean that the snapshot
19
 * will survive a reboot.
20
 *---------------------------------------------------------------*/
21
22
/*
23
 * We need to store a record of which parts of the origin have
24
 * been copied to the snapshot device.  The snapshot code
25
 * requires that we copy exception chunks to chunk aligned areas
26
 * of the COW store.  It makes sense therefore, to store the
27
 * metadata in chunk size blocks.
28
 *
29
 * There is no backward or forward compatibility implemented,
30
 * snapshots with different disk versions than the kernel will
31
 * not be usable.  It is expected that "lvcreate" will blank out
32
 * the start of a fresh COW device before calling the snapshot
33
 * constructor.
34
 *
35
 * The first chunk of the COW device just contains the header.
36
 * After this there is a chunk filled with exception metadata,
37
 * followed by as many exception chunks as can fit in the
38
 * metadata areas.
39
 *
40
 * All on disk structures are in little-endian format.  The end
41
 * of the exceptions info is indicated by an exception with a
42
 * new_chunk of 0, which is invalid since it would point to the
43
 * header chunk.
44
 */
45
46
/*
47
 * Magic for persistent snapshots: "SnAp" - Feeble isn't it.
48
 */
49
#define SNAP_MAGIC 0x70416e53
50
51
/*
52
 * The on-disk version of the metadata.
53
 */
54
#define SNAPSHOT_DISK_VERSION 1
55
56
struct disk_header {
57
	uint32_t magic;
58
59
	/*
60
	 * Is this snapshot valid.  There is no way of recovering
61
	 * an invalid snapshot.
62
	 */
63
	int valid;
64
65
	/*
66
	 * Simple, incrementing version. no backward
67
	 * compatibility.
68
	 */
69
	uint32_t version;
70
71
	/* In sectors */
72
	uint32_t chunk_size;
73
};
74
75
struct disk_exception {
76
	uint64_t old_chunk;
77
	uint64_t new_chunk;
78
};
79
80
struct commit_callback {
81
	void (*callback) (void *, int success);
82
	void *context;
83
};
84
85
/*
86
 * The top level structure for a persistent exception store.
87
 */
88
struct pstore {
89
	struct dm_snapshot *snap;	/* up pointer to my snapshot */
90
	int version;
91
	int valid;
92
	uint32_t chunk_size;
93
	uint32_t exceptions_per_area;
94
95
	/*
96
	 * Now that we have an asynchronous kcopyd there is no
97
	 * need for large chunk sizes, so it wont hurt to have a
98
	 * whole chunks worth of metadata in memory at once.
99
	 */
100
	void *area;
101
	struct kiobuf *iobuf;
102
103
	/*
104
	 * Used to keep track of which metadata area the data in
105
	 * 'chunk' refers to.
106
	 */
107
	uint32_t current_area;
108
109
	/*
110
	 * The next free chunk for an exception.
111
	 */
112
	uint32_t next_free;
113
114
	/*
115
	 * The index of next free exception in the current
116
	 * metadata area.
117
	 */
118
	uint32_t current_committed;
119
120
	atomic_t pending_count;
121
	uint32_t callback_count;
122
	struct commit_callback *callbacks;
123
};
124
125
/*
126
 * For performance reasons we want to defer writing a committed
127
 * exceptions metadata to disk so that we can amortise away this
128
 * exensive operation.
129
 *
130
 * For the initial version of this code we will remain with
131
 * synchronous io.  There are some deadlock issues with async
132
 * that I haven't yet worked out.
133
 */
134
static int do_io(int rw, struct kcopyd_region *where, struct kiobuf *iobuf)
135
{
136
	int i, sectors_per_block, nr_blocks, start;
137
	int blocksize = get_hardsect_size(where->dev);
138
	int status;
139
140
	sectors_per_block = blocksize / SECTOR_SIZE;
141
142
	nr_blocks = where->count / sectors_per_block;
143
	start = where->sector / sectors_per_block;
144
145
	for (i = 0; i < nr_blocks; i++)
146
		iobuf->blocks[i] = start++;
147
148
	iobuf->length = where->count << 9;
149
	iobuf->locked = 1;
150
151
	status = brw_kiovec(rw, 1, &iobuf, where->dev, iobuf->blocks,
152
			    blocksize);
153
	if (status != (where->count << 9))
154
		return -EIO;
155
156
	return 0;
157
}
158
159
static int allocate_iobuf(struct pstore *ps)
160
{
161
	size_t i, r = -ENOMEM, len, nr_pages;
162
	struct page *page;
163
164
	len = ps->chunk_size << SECTOR_SHIFT;
165
166
	/*
167
	 * Allocate the chunk_size block of memory that will hold
168
	 * a single metadata area.
169
	 */
170
	ps->area = vmalloc(len);
171
	if (!ps->area)
172
		return r;
173
174
	if (alloc_kiovec(1, &ps->iobuf))
175
		goto bad;
176
177
	nr_pages = ps->chunk_size / (PAGE_SIZE / SECTOR_SIZE);
178
	r = expand_kiobuf(ps->iobuf, nr_pages);
179
	if (r)
180
		goto bad;
181
182
	/*
183
	 * We lock the pages for ps->area into memory since they'll be
184
	 * doing a lot of io.
185
	 */
186
	for (i = 0; i < nr_pages; i++) {
187
		page = vmalloc_to_page(ps->area + (i * PAGE_SIZE));
188
		LockPage(page);
189
		ps->iobuf->maplist[i] = page;
190
		ps->iobuf->nr_pages++;
191
	}
192
193
	ps->iobuf->nr_pages = nr_pages;
194
	ps->iobuf->offset = 0;
195
196
	return 0;
197
198
      bad:
199
	if (ps->iobuf)
200
		free_kiovec(1, &ps->iobuf);
201
202
	if (ps->area)
203
		vfree(ps->area);
204
	ps->iobuf = NULL;
205
	return r;
206
}
207
208
static void free_iobuf(struct pstore *ps)
209
{
210
	int i;
211
212
	for (i = 0; i < ps->iobuf->nr_pages; i++)
213
		UnlockPage(ps->iobuf->maplist[i]);
214
	ps->iobuf->locked = 0;
215
216
	free_kiovec(1, &ps->iobuf);
217
	vfree(ps->area);
218
}
219
220
/*
221
 * Read or write a chunk aligned and sized block of data from a device.
222
 */
223
static int chunk_io(struct pstore *ps, uint32_t chunk, int rw)
224
{
225
	int r;
226
	struct kcopyd_region where;
227
228
	where.dev = ps->snap->cow->dev;
229
	where.sector = ps->chunk_size * chunk;
230
	where.count = ps->chunk_size;
231
232
	r = do_io(rw, &where, ps->iobuf);
233
	if (r)
234
		return r;
235
236
	return 0;
237
}
238
239
/*
240
 * Read or write a metadata area.  Remembering to skip the first
241
 * chunk which holds the header.
242
 */
243
static int area_io(struct pstore *ps, uint32_t area, int rw)
244
{
245
	int r;
246
	uint32_t chunk;
247
248
	/* convert a metadata area index to a chunk index */
249
	chunk = 1 + ((ps->exceptions_per_area + 1) * area);
250
251
	r = chunk_io(ps, chunk, rw);
252
	if (r)
253
		return r;
254
255
	ps->current_area = area;
256
	return 0;
257
}
258
259
static int zero_area(struct pstore *ps, uint32_t area)
260
{
261
	memset(ps->area, 0, ps->chunk_size << SECTOR_SHIFT);
262
	return area_io(ps, area, WRITE);
263
}
264
265
static int read_header(struct pstore *ps, int *new_snapshot)
266
{
267
	int r;
268
	struct disk_header *dh;
269
270
	r = chunk_io(ps, 0, READ);
271
	if (r)
272
		return r;
273
274
	dh = (struct disk_header *) ps->area;
275
276
	if (dh->magic == 0) {
277
		*new_snapshot = 1;
278
279
	} else if (dh->magic == SNAP_MAGIC) {
280
		*new_snapshot = 0;
281
		ps->valid = dh->valid;
282
		ps->version = dh->version;
283
		ps->chunk_size = dh->chunk_size;
284
285
	} else {
286
		DMWARN("Invalid/corrupt snapshot");
287
		r = -ENXIO;
288
	}
289
290
	return r;
291
}
292
293
static int write_header(struct pstore *ps)
294
{
295
	struct disk_header *dh;
296
297
	memset(ps->area, 0, ps->chunk_size << SECTOR_SHIFT);
298
299
	dh = (struct disk_header *) ps->area;
300
	dh->magic = SNAP_MAGIC;
301
	dh->valid = ps->valid;
302
	dh->version = ps->version;
303
	dh->chunk_size = ps->chunk_size;
304
305
	return chunk_io(ps, 0, WRITE);
306
}
307
308
/*
309
 * Access functions for the disk exceptions, these do the endian conversions.
310
 */
311
static struct disk_exception *get_exception(struct pstore *ps, uint32_t index)
312
{
313
	if (index >= ps->exceptions_per_area)
314
		return NULL;
315
316
	return ((struct disk_exception *) ps->area) + index;
317
}
318
319
static int read_exception(struct pstore *ps,
320
			  uint32_t index, struct disk_exception *result)
321
{
322
	struct disk_exception *e;
323
324
	e = get_exception(ps, index);
325
	if (!e)
326
		return -EINVAL;
327
328
	/* copy it */
329
	result->old_chunk = le64_to_cpu(e->old_chunk);
330
	result->new_chunk = le64_to_cpu(e->new_chunk);
331
332
	return 0;
333
}
334
335
static int write_exception(struct pstore *ps,
336
			   uint32_t index, struct disk_exception *de)
337
{
338
	struct disk_exception *e;
339
340
	e = get_exception(ps, index);
341
	if (!e)
342
		return -EINVAL;
343
344
	/* copy it */
345
	e->old_chunk = cpu_to_le64(de->old_chunk);
346
	e->new_chunk = cpu_to_le64(de->new_chunk);
347
348
	return 0;
349
}
350
351
/*
352
 * Registers the exceptions that are present in the current area.
353
 * 'full' is filled in to indicate if the area has been
354
 * filled.
355
 */
356
static int insert_exceptions(struct pstore *ps, int *full)
357
{
358
	int i, r;
359
	struct disk_exception de;
360
361
	/* presume the area is full */
362
	*full = 1;
363
364
	for (i = 0; i < ps->exceptions_per_area; i++) {
365
		r = read_exception(ps, i, &de);
366
367
		if (r)
368
			return r;
369
370
		/*
371
		 * If the new_chunk is pointing at the start of
372
		 * the COW device, where the first metadata area
373
		 * is we know that we've hit the end of the
374
		 * exceptions.  Therefore the area is not full.
375
		 */
376
		if (de.new_chunk == 0LL) {
377
			ps->current_committed = i;
378
			*full = 0;
379
			break;
380
		}
381
382
		/*
383
		 * Keep track of the start of the free chunks.
384
		 */
385
		if (ps->next_free <= de.new_chunk)
386
			ps->next_free = de.new_chunk + 1;
387
388
		/*
389
		 * Otherwise we add the exception to the snapshot.
390
		 */
391
		r = dm_add_exception(ps->snap, de.old_chunk, de.new_chunk);
392
		if (r)
393
			return r;
394
	}
395
396
	return 0;
397
}
398
399
static int read_exceptions(struct pstore *ps)
400
{
401
	uint32_t area;
402
	int r, full = 1;
403
404
	/*
405
	 * Keeping reading chunks and inserting exceptions until
406
	 * we find a partially full area.
407
	 */
408
	for (area = 0; full; area++) {
409
		r = area_io(ps, area, READ);
410
		if (r)
411
			return r;
412
413
		r = insert_exceptions(ps, &full);
414
		if (r)
415
			return r;
416
417
		area++;
418
	}
419
420
	return 0;
421
}
422
423
static inline struct pstore *get_info(struct exception_store *store)
424
{
425
	return (struct pstore *) store->context;
426
}
427
428
static int persistent_percentfull(struct exception_store *store)
429
{
430
	struct pstore *ps = get_info(store);
431
	return (ps->next_free * store->snap->chunk_size * 100) /
432
	    get_dev_size(store->snap->cow->dev);
433
}
434
435
static void persistent_destroy(struct exception_store *store)
436
{
437
	struct pstore *ps = get_info(store);
438
439
	vfree(ps->callbacks);
440
	free_iobuf(ps);
441
	kfree(ps);
442
}
443
444
static int persistent_prepare(struct exception_store *store,
445
			      struct exception *e)
446
{
447
	struct pstore *ps = get_info(store);
448
	uint32_t stride;
449
	sector_t size = get_dev_size(store->snap->cow->dev);
450
451
	/* Is there enough room ? */
452
	if (size < ((ps->next_free + 1) * store->snap->chunk_size))
453
		return -ENOSPC;
454
455
	e->new_chunk = ps->next_free;
456
457
	/*
458
	 * Move onto the next free pending, making sure to take
459
	 * into account the location of the metadata chunks.
460
	 */
461
	stride = (ps->exceptions_per_area + 1);
462
	if ((++ps->next_free % stride) == 1)
463
		ps->next_free++;
464
465
	atomic_inc(&ps->pending_count);
466
	return 0;
467
}
468
469
static void persistent_commit(struct exception_store *store,
470
			      struct exception *e,
471
			      void (*callback) (void *, int success),
472
			      void *callback_context)
473
{
474
	int r, i;
475
	struct pstore *ps = get_info(store);
476
	struct disk_exception de;
477
	struct commit_callback *cb;
478
479
	de.old_chunk = e->old_chunk;
480
	de.new_chunk = e->new_chunk;
481
	write_exception(ps, ps->current_committed++, &de);
482
483
	/*
484
	 * Add the callback to the back of the array.  This code
485
	 * is the only place where the callback array is
486
	 * manipulated, and we know that it will never be called
487
	 * multiple times concurrently.
488
	 */
489
	cb = ps->callbacks + ps->callback_count++;
490
	cb->callback = callback;
491
	cb->context = callback_context;
492
493
	/*
494
	 * If there are no more exceptions in flight, or we have
495
	 * filled this metadata area we commit the exceptions to
496
	 * disk.
497
	 */
498
	if (atomic_dec_and_test(&ps->pending_count) ||
499
	    (ps->current_committed == ps->exceptions_per_area)) {
500
		r = area_io(ps, ps->current_area, WRITE);
501
		if (r)
502
			ps->valid = 0;
503
504
		for (i = 0; i < ps->callback_count; i++) {
505
			cb = ps->callbacks + i;
506
			cb->callback(cb->context, r == 0 ? 1 : 0);
507
		}
508
509
		ps->callback_count = 0;
510
	}
511
512
	/*
513
	 * Have we completely filled the current area ?
514
	 */
515
	if (ps->current_committed == ps->exceptions_per_area) {
516
		ps->current_committed = 0;
517
		r = zero_area(ps, ps->current_area + 1);
518
		if (r)
519
			ps->valid = 0;
520
	}
521
}
522
523
static void persistent_drop(struct exception_store *store)
524
{
525
	struct pstore *ps = get_info(store);
526
527
	ps->valid = 0;
528
	if (write_header(ps))
529
		DMWARN("write header failed");
530
}
531
532
int dm_create_persistent(struct exception_store *store, uint32_t chunk_size)
533
{
534
	int r, new_snapshot;
535
	struct pstore *ps;
536
537
	/* allocate the pstore */
538
	ps = kmalloc(sizeof(*ps), GFP_KERNEL);
539
	if (!ps)
540
		return -ENOMEM;
541
542
	ps->snap = store->snap;
543
	ps->valid = 1;
544
	ps->version = SNAPSHOT_DISK_VERSION;
545
	ps->chunk_size = chunk_size;
546
	ps->exceptions_per_area = (chunk_size << SECTOR_SHIFT) /
547
	    sizeof(struct disk_exception);
548
	ps->next_free = 2;	/* skipping the header and first area */
549
	ps->current_committed = 0;
550
551
	r = allocate_iobuf(ps);
552
	if (r)
553
		goto bad;
554
555
	/*
556
	 * Allocate space for all the callbacks.
557
	 */
558
	ps->callback_count = 0;
559
	atomic_set(&ps->pending_count, 0);
560
	ps->callbacks = vcalloc(ps->exceptions_per_area,
561
				sizeof(*ps->callbacks));
562
563
	if (!ps->callbacks)
564
		goto bad;
565
566
	/*
567
	 * Read the snapshot header.
568
	 */
569
	r = read_header(ps, &new_snapshot);
570
	if (r)
571
		goto bad;
572
573
	/*
574
	 * Do we need to setup a new snapshot ?
575
	 */
576
	if (new_snapshot) {
577
		r = write_header(ps);
578
		if (r) {
579
			DMWARN("write_header failed");
580
			goto bad;
581
		}
582
583
		r = zero_area(ps, 0);
584
		if (r) {
585
			DMWARN("zero_area(0) failed");
586
			goto bad;
587
		}
588
589
	} else {
590
		/*
591
		 * Sanity checks.
592
		 */
593
		if (!ps->valid) {
594
			DMWARN("snapshot is marked invalid");
595
			r = -EINVAL;
596
			goto bad;   
597
		}
598
599
		if (ps->chunk_size != chunk_size) {
600
			DMWARN("chunk size for existing snapshot different "
601
			       "from that requested");
602
			r = -EINVAL;
603
			goto bad;
604
		}
605
606
		if (ps->version != SNAPSHOT_DISK_VERSION) {
607
			DMWARN("unable to handle snapshot disk version %d",
608
			       ps->version);
609
			r = -EINVAL;
610
			goto bad;
611
		}
612
613
		/*
614
		 * Read the metadata.
615
		 */
616
		r = read_exceptions(ps);
617
		if (r)
618
			goto bad;
619
	}
620
621
	store->destroy = persistent_destroy;
622
	store->prepare_exception = persistent_prepare;
623
	store->commit_exception = persistent_commit;
624
	store->drop_snapshot = persistent_drop;
625
	store->percent_full = persistent_percentfull;
626
	store->context = ps;
627
628
	return r;
629
630
      bad:
631
	if (ps) {
632
		if (ps->callbacks)
633
			vfree(ps->callbacks);
634
635
		if (ps->iobuf)
636
			free_iobuf(ps);
637
638
		kfree(ps);
639
	}
640
	return r;
641
}
642
643
/*-----------------------------------------------------------------
644
 * Implementation of the store for non-persistent snapshots.
645
 *---------------------------------------------------------------*/
646
struct transient_c {
647
	sector_t next_free;
648
};
649
650
void transient_destroy(struct exception_store *store)
651
{
652
	kfree(store->context);
653
}
654
655
int transient_prepare(struct exception_store *store, struct exception *e)
656
{
657
	struct transient_c *tc = (struct transient_c *) store->context;
658
	sector_t size = get_dev_size(store->snap->cow->dev);
659
660
	if (size < (tc->next_free + store->snap->chunk_size))
661
		return -1;
662
663
	e->new_chunk = sector_to_chunk(store->snap, tc->next_free);
664
	tc->next_free += store->snap->chunk_size;
665
666
	return 0;
667
}
668
669
void transient_commit(struct exception_store *store,
670
		      struct exception *e,
671
		      void (*callback) (void *, int success),
672
		      void *callback_context)
673
{
674
	/* Just succeed */
675
	callback(callback_context, 1);
676
}
677
678
static int transient_percentfull(struct exception_store *store)
679
{
680
	struct transient_c *tc = (struct transient_c *) store->context;
681
	return (tc->next_free * 100) / get_dev_size(store->snap->cow->dev);
682
}
683
684
int dm_create_transient(struct exception_store *store,
685
			struct dm_snapshot *s, int blocksize)
686
{
687
	struct transient_c *tc;
688
689
	memset(store, 0, sizeof(*store));
690
	store->destroy = transient_destroy;
691
	store->prepare_exception = transient_prepare;
692
	store->commit_exception = transient_commit;
693
	store->percent_full = transient_percentfull;
694
	store->snap = s;
695
696
	tc = kmalloc(sizeof(struct transient_c), GFP_KERNEL);
697
	if (!tc)
698
		return -ENOMEM;
699
700
	tc->next_free = 0;
701
	store->context = tc;
702
703
	return 0;
704
}
(-)linux-2.4.20-gentoo-r5/drivers/md/dm-ioctl.c (+1160 lines)
Line 0 Link Here
1
/*
2
 * Copyright (C) 2001, 2002 Sistina Software (UK) Limited.
3
 *
4
 * This file is released under the GPL.
5
 */
6
7
#include "dm.h"
8
9
#include <linux/module.h>
10
#include <linux/vmalloc.h>
11
#include <linux/miscdevice.h>
12
#include <linux/dm-ioctl.h>
13
#include <linux/init.h>
14
#include <linux/wait.h>
15
#include <linux/blk.h>
16
#include <linux/slab.h>
17
18
#include <asm/uaccess.h>
19
20
#define DM_DRIVER_EMAIL "dm@uk.sistina.com"
21
22
/*-----------------------------------------------------------------
23
 * The ioctl interface needs to be able to look up devices by
24
 * name or uuid.
25
 *---------------------------------------------------------------*/
26
struct hash_cell {
27
	struct list_head name_list;
28
	struct list_head uuid_list;
29
30
	char *name;
31
	char *uuid;
32
	struct mapped_device *md;
33
34
	/* I hate devfs */
35
	devfs_handle_t devfs_entry;
36
};
37
38
#define NUM_BUCKETS 64
39
#define MASK_BUCKETS (NUM_BUCKETS - 1)
40
static struct list_head _name_buckets[NUM_BUCKETS];
41
static struct list_head _uuid_buckets[NUM_BUCKETS];
42
43
static devfs_handle_t _dev_dir;
44
void dm_hash_remove_all(void);
45
46
/*
47
 * Guards access to all three tables.
48
 */
49
static DECLARE_RWSEM(_hash_lock);
50
51
static void init_buckets(struct list_head *buckets)
52
{
53
	unsigned int i;
54
55
	for (i = 0; i < NUM_BUCKETS; i++)
56
		INIT_LIST_HEAD(buckets + i);
57
}
58
59
int dm_hash_init(void)
60
{
61
	init_buckets(_name_buckets);
62
	init_buckets(_uuid_buckets);
63
	_dev_dir = devfs_mk_dir(0, DM_DIR, NULL);
64
	return 0;
65
}
66
67
void dm_hash_exit(void)
68
{
69
	dm_hash_remove_all();
70
	devfs_unregister(_dev_dir);
71
}
72
73
/*-----------------------------------------------------------------
74
 * Hash function:
75
 * We're not really concerned with the str hash function being
76
 * fast since it's only used by the ioctl interface.
77
 *---------------------------------------------------------------*/
78
static unsigned int hash_str(const char *str)
79
{
80
	const unsigned int hash_mult = 2654435387U;
81
	unsigned int h = 0;
82
83
	while (*str)
84
		h = (h + (unsigned int) *str++) * hash_mult;
85
86
	return h & MASK_BUCKETS;
87
}
88
89
/*-----------------------------------------------------------------
90
 * Code for looking up a device by name
91
 *---------------------------------------------------------------*/
92
static struct hash_cell *__get_name_cell(const char *str)
93
{
94
	struct list_head *tmp;
95
	struct hash_cell *hc;
96
	unsigned int h = hash_str(str);
97
98
	list_for_each(tmp, _name_buckets + h) {
99
		hc = list_entry(tmp, struct hash_cell, name_list);
100
		if (!strcmp(hc->name, str))
101
			return hc;
102
	}
103
104
	return NULL;
105
}
106
107
static struct hash_cell *__get_uuid_cell(const char *str)
108
{
109
	struct list_head *tmp;
110
	struct hash_cell *hc;
111
	unsigned int h = hash_str(str);
112
113
	list_for_each(tmp, _uuid_buckets + h) {
114
		hc = list_entry(tmp, struct hash_cell, uuid_list);
115
		if (!strcmp(hc->uuid, str))
116
			return hc;
117
	}
118
119
	return NULL;
120
}
121
122
/*-----------------------------------------------------------------
123
 * Inserting, removing and renaming a device.
124
 *---------------------------------------------------------------*/
125
static inline char *kstrdup(const char *str)
126
{
127
	char *r = kmalloc(strlen(str) + 1, GFP_KERNEL);
128
	if (r)
129
		strcpy(r, str);
130
	return r;
131
}
132
133
static struct hash_cell *alloc_cell(const char *name, const char *uuid,
134
				    struct mapped_device *md)
135
{
136
	struct hash_cell *hc;
137
138
	hc = kmalloc(sizeof(*hc), GFP_KERNEL);
139
	if (!hc)
140
		return NULL;
141
142
	hc->name = kstrdup(name);
143
	if (!hc->name) {
144
		kfree(hc);
145
		return NULL;
146
	}
147
148
	if (!uuid)
149
		hc->uuid = NULL;
150
151
	else {
152
		hc->uuid = kstrdup(uuid);
153
		if (!hc->uuid) {
154
			kfree(hc->name);
155
			kfree(hc);
156
			return NULL;
157
		}
158
	}
159
160
	INIT_LIST_HEAD(&hc->name_list);
161
	INIT_LIST_HEAD(&hc->uuid_list);
162
	hc->md = md;
163
	return hc;
164
}
165
166
static void free_cell(struct hash_cell *hc)
167
{
168
	if (hc) {
169
		kfree(hc->name);
170
		kfree(hc->uuid);
171
		kfree(hc);
172
	}
173
}
174
175
/*
176
 * devfs stuff.
177
 */
178
static int register_with_devfs(struct hash_cell *hc)
179
{
180
	kdev_t dev = dm_kdev(hc->md);
181
182
	hc->devfs_entry =
183
	    devfs_register(_dev_dir, hc->name, DEVFS_FL_CURRENT_OWNER,
184
			   major(dev), minor(dev),
185
			   S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP,
186
			   &dm_blk_dops, NULL);
187
188
	return 0;
189
}
190
191
static int unregister_with_devfs(struct hash_cell *hc)
192
{
193
	devfs_unregister(hc->devfs_entry);
194
	return 0;
195
}
196
197
/*
198
 * The kdev_t and uuid of a device can never change once it is
199
 * initially inserted.
200
 */
201
int dm_hash_insert(const char *name, const char *uuid, struct mapped_device *md)
202
{
203
	struct hash_cell *cell;
204
205
	/*
206
	 * Allocate the new cells.
207
	 */
208
	cell = alloc_cell(name, uuid, md);
209
	if (!cell)
210
		return -ENOMEM;
211
212
	/*
213
	 * Insert the cell into all three hash tables.
214
	 */
215
	down_write(&_hash_lock);
216
	if (__get_name_cell(name))
217
		goto bad;
218
219
	list_add(&cell->name_list, _name_buckets + hash_str(name));
220
221
	if (uuid) {
222
		if (__get_uuid_cell(uuid)) {
223
			list_del(&cell->name_list);
224
			goto bad;
225
		}
226
		list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid));
227
	}
228
	register_with_devfs(cell);
229
	dm_get(md);
230
	up_write(&_hash_lock);
231
232
	return 0;
233
234
      bad:
235
	up_write(&_hash_lock);
236
	free_cell(cell);
237
	return -EBUSY;
238
}
239
240
void __hash_remove(struct hash_cell *hc)
241
{
242
	/* remove from the dev hash */
243
	list_del(&hc->uuid_list);
244
	list_del(&hc->name_list);
245
	unregister_with_devfs(hc);
246
	dm_put(hc->md);
247
}
248
249
void dm_hash_remove_all(void)
250
{
251
	int i;
252
	struct hash_cell *hc;
253
	struct list_head *tmp, *n;
254
255
	down_write(&_hash_lock);
256
	for (i = 0; i < NUM_BUCKETS; i++) {
257
		list_for_each_safe(tmp, n, _name_buckets + i) {
258
			hc = list_entry(tmp, struct hash_cell, name_list);
259
			__hash_remove(hc);
260
		}
261
	}
262
	up_write(&_hash_lock);
263
}
264
265
int dm_hash_rename(const char *old, const char *new)
266
{
267
	char *new_name, *old_name;
268
	struct hash_cell *hc;
269
270
	/*
271
	 * duplicate new.
272
	 */
273
	new_name = kstrdup(new);
274
	if (!new_name)
275
		return -ENOMEM;
276
277
	down_write(&_hash_lock);
278
279
	/*
280
	 * Is new free ?
281
	 */
282
	hc = __get_name_cell(new);
283
	if (hc) {
284
		DMWARN("asked to rename to an already existing name %s -> %s",
285
		       old, new);
286
		up_write(&_hash_lock);
287
		return -EBUSY;
288
	}
289
290
	/*
291
	 * Is there such a device as 'old' ?
292
	 */
293
	hc = __get_name_cell(old);
294
	if (!hc) {
295
		DMWARN("asked to rename a non existent device %s -> %s",
296
		       old, new);
297
		up_write(&_hash_lock);
298
		return -ENXIO;
299
	}
300
301
	/*
302
	 * rename and move the name cell.
303
	 */
304
	list_del(&hc->name_list);
305
	old_name = hc->name;
306
	hc->name = new_name;
307
	list_add(&hc->name_list, _name_buckets + hash_str(new_name));
308
309
	/* rename the device node in devfs */
310
	unregister_with_devfs(hc);
311
	register_with_devfs(hc);
312
313
	up_write(&_hash_lock);
314
	kfree(old_name);
315
	return 0;
316
}
317
318
319
/*-----------------------------------------------------------------
320
 * Implementation of the ioctl commands
321
 *---------------------------------------------------------------*/
322
323
/*
324
 * All the ioctl commands get dispatched to functions with this
325
 * prototype.
326
 */
327
typedef int (*ioctl_fn)(struct dm_ioctl *param, struct dm_ioctl *user);
328
329
/*
330
 * Check a string doesn't overrun the chunk of
331
 * memory we copied from userland.
332
 */
333
static int valid_str(char *str, void *begin, void *end)
334
{
335
	while (((void *) str >= begin) && ((void *) str < end))
336
		if (!*str++)
337
			return 0;
338
339
	return -EINVAL;
340
}
341
342
static int next_target(struct dm_target_spec *last, uint32_t next,
343
		       void *begin, void *end,
344
		       struct dm_target_spec **spec, char **params)
345
{
346
	*spec = (struct dm_target_spec *)
347
	    ((unsigned char *) last + next);
348
	*params = (char *) (*spec + 1);
349
350
	if (*spec < (last + 1) || ((void *) *spec > end))
351
		return -EINVAL;
352
353
	return valid_str(*params, begin, end);
354
}
355
356
static int populate_table(struct dm_table *table, struct dm_ioctl *args)
357
{
358
	int i = 0, r, first = 1;
359
	struct dm_target_spec *spec;
360
	char *params;
361
	void *begin, *end;
362
363
	if (!args->target_count) {
364
		DMWARN("populate_table: no targets specified");
365
		return -EINVAL;
366
	}
367
368
	begin = (void *) args;
369
	end = begin + args->data_size;
370
371
	for (i = 0; i < args->target_count; i++) {
372
373
		if (first)
374
			r = next_target((struct dm_target_spec *) args,
375
					args->data_start,
376
					begin, end, &spec, &params);
377
		else
378
			r = next_target(spec, spec->next, begin, end,
379
					&spec, &params);
380
381
		if (r) {
382
			DMWARN("unable to find target");
383
			return -EINVAL;
384
		}
385
386
		r = dm_table_add_target(table, spec->target_type,
387
					spec->sector_start, spec->length,
388
					params);
389
		if (r) {
390
			DMWARN("error adding target to table");
391
			return -EINVAL;
392
		}
393
394
		first = 0;
395
	}
396
397
	return dm_table_complete(table);
398
}
399
400
/*
401
 * Round up the ptr to the next 'align' boundary.  Obviously
402
 * 'align' must be a power of 2.
403
 */
404
static inline void *align_ptr(void *ptr, unsigned int align)
405
{
406
	align--;
407
	return (void *) (((unsigned long) (ptr + align)) & ~align);
408
}
409
410
/*
411
 * Copies a dm_ioctl and an optional additional payload to
412
 * userland.
413
 */
414
static int results_to_user(struct dm_ioctl *user, struct dm_ioctl *param,
415
			   void *data, uint32_t len)
416
{
417
	int r;
418
	void *ptr = NULL;
419
420
	if (data) {
421
		ptr = align_ptr(user + 1, sizeof(unsigned long));
422
		param->data_start = ptr - (void *) user;
423
	}
424
425
	/*
426
	 * The version number has already been filled in, so we
427
	 * just copy later fields.
428
	 */
429
	r = copy_to_user(&user->data_size, &param->data_size,
430
			 sizeof(*param) - sizeof(param->version));
431
	if (r)
432
		return -EFAULT;
433
434
	if (data) {
435
		if (param->data_start + len > param->data_size)
436
			return -ENOSPC;
437
438
		if (copy_to_user(ptr, data, len))
439
			r = -EFAULT;
440
	}
441
442
	return r;
443
}
444
445
/*
446
 * Fills in a dm_ioctl structure, ready for sending back to
447
 * userland.
448
 */
449
static int __info(struct mapped_device *md, struct dm_ioctl *param)
450
{
451
	kdev_t dev = dm_kdev(md);
452
	struct dm_table *table;
453
	struct block_device *bdev;
454
455
	param->flags = DM_EXISTS_FLAG;
456
	if (dm_suspended(md))
457
		param->flags |= DM_SUSPEND_FLAG;
458
459
	param->dev = kdev_t_to_nr(dev);
460
	bdev = bdget(param->dev);
461
	if (!bdev)
462
		return -ENXIO;
463
464
	param->open_count = bdev->bd_openers;
465
	bdput(bdev);
466
467
	if (is_read_only(dev))
468
		param->flags |= DM_READONLY_FLAG;
469
470
	table = dm_get_table(md);
471
	param->target_count = dm_table_get_num_targets(table);
472
	dm_table_put(table);
473
474
	return 0;
475
}
476
477
/*
478
 * Always use UUID for lookups if it's present, otherwise use name.
479
 */
480
static inline struct mapped_device *find_device(struct dm_ioctl *param)
481
{
482
	struct hash_cell *hc;
483
	struct mapped_device *md = NULL;
484
485
	down_read(&_hash_lock);
486
	hc = *param->uuid ? __get_uuid_cell(param->uuid) :
487
	    __get_name_cell(param->name);
488
	if (hc) {
489
		md = hc->md;
490
491
		/*
492
		 * Sneakily write in both the name and the uuid
493
		 * while we have the cell.
494
		 */
495
		strncpy(param->name, hc->name, sizeof(param->name));
496
		if (hc->uuid)
497
			strncpy(param->uuid, hc->uuid, sizeof(param->uuid) - 1);
498
		else
499
			param->uuid[0] = '\0';
500
501
		dm_get(md);
502
	}
503
	up_read(&_hash_lock);
504
505
	return md;
506
}
507
508
#define ALIGNMENT sizeof(int)
509
static void *_align(void *ptr, unsigned int a)
510
{
511
	register unsigned long align = --a;
512
513
	return (void *) (((unsigned long) ptr + align) & ~align);
514
}
515
516
/*
517
 * Copies device info back to user space, used by
518
 * the create and info ioctls.
519
 */
520
static int info(struct dm_ioctl *param, struct dm_ioctl *user)
521
{
522
	struct mapped_device *md;
523
524
	param->flags = 0;
525
526
	md = find_device(param);
527
	if (!md)
528
		/*
529
		 * Device not found - returns cleared exists flag.
530
		 */
531
		goto out;
532
533
	__info(md, param);
534
	dm_put(md);
535
536
      out:
537
	return results_to_user(user, param, NULL, 0);
538
}
539
540
static inline int get_mode(struct dm_ioctl *param)
541
{
542
	int mode = FMODE_READ | FMODE_WRITE;
543
544
	if (param->flags & DM_READONLY_FLAG)
545
		mode = FMODE_READ;
546
547
	return mode;
548
}
549
550
static int check_name(const char *name)
551
{
552
	if (strchr(name, '/')) {
553
		DMWARN("invalid device name");
554
		return -EINVAL;
555
	}
556
557
	return 0;
558
}
559
560
static int create(struct dm_ioctl *param, struct dm_ioctl *user)
561
{
562
	int r;
563
	kdev_t dev;
564
	struct dm_table *t;
565
	struct mapped_device *md;
566
	int minor;
567
568
	r = check_name(param->name);
569
	if (r)
570
		return r;
571
572
	r = dm_table_create(&t, get_mode(param));
573
	if (r)
574
		return r;
575
576
	r = populate_table(t, param);
577
	if (r) {
578
		dm_table_put(t);
579
		return r;
580
	}
581
582
	minor = (param->flags & DM_PERSISTENT_DEV_FLAG) ?
583
	    minor(to_kdev_t(param->dev)) : -1;
584
585
	r = dm_create(minor, t, &md);
586
	if (r) {
587
		dm_table_put(t);
588
		return r;
589
	}
590
	dm_table_put(t);	/* md will have grabbed its own reference */
591
592
	dev = dm_kdev(md);
593
	set_device_ro(dev, (param->flags & DM_READONLY_FLAG));
594
	r = dm_hash_insert(param->name, *param->uuid ? param->uuid : NULL, md);
595
	dm_put(md);
596
597
	return r ? r : info(param, user);
598
}
599
600
/*
601
 * Build up the status struct for each target
602
 */
603
static int __status(struct mapped_device *md, struct dm_ioctl *param,
604
		    char *outbuf, int *len)
605
{
606
	int i, num_targets;
607
	struct dm_target_spec *spec;
608
	char *outptr;
609
	status_type_t type;
610
	struct dm_table *table = dm_get_table(md);
611
612
	if (param->flags & DM_STATUS_TABLE_FLAG)
613
		type = STATUSTYPE_TABLE;
614
	else
615
		type = STATUSTYPE_INFO;
616
617
	outptr = outbuf;
618
619
	/* Get all the target info */
620
	num_targets = dm_table_get_num_targets(table);
621
	for (i = 0; i < num_targets; i++) {
622
		struct dm_target *ti = dm_table_get_target(table, i);
623
624
		if (outptr - outbuf +
625
		    sizeof(struct dm_target_spec) > param->data_size) {
626
			dm_table_put(table);
627
			return -ENOMEM;
628
		}
629
630
		spec = (struct dm_target_spec *) outptr;
631
632
		spec->status = 0;
633
		spec->sector_start = ti->begin;
634
		spec->length = ti->len;
635
		strncpy(spec->target_type, ti->type->name,
636
			sizeof(spec->target_type));
637
638
		outptr += sizeof(struct dm_target_spec);
639
640
		/* Get the status/table string from the target driver */
641
		if (ti->type->status)
642
			ti->type->status(ti, type, outptr,
643
					 outbuf + param->data_size - outptr);
644
		else
645
			outptr[0] = '\0';
646
647
		outptr += strlen(outptr) + 1;
648
		_align(outptr, ALIGNMENT);
649
		spec->next = outptr - outbuf;
650
	}
651
652
	param->target_count = num_targets;
653
	*len = outptr - outbuf;
654
	dm_table_put(table);
655
656
	return 0;
657
}
658
659
/*
660
 * Return the status of a device as a text string for each
661
 * target.
662
 */
663
static int get_status(struct dm_ioctl *param, struct dm_ioctl *user)
664
{
665
	struct mapped_device *md;
666
	int len = 0;
667
	int ret;
668
	char *outbuf = NULL;
669
670
	md = find_device(param);
671
	if (!md)
672
		/*
673
		 * Device not found - returns cleared exists flag.
674
		 */
675
		goto out;
676
677
	/* We haven't a clue how long the resultant data will be so
678
	   just allocate as much as userland has allowed us and make sure
679
	   we don't overun it */
680
	outbuf = kmalloc(param->data_size, GFP_KERNEL);
681
	if (!outbuf)
682
		goto out;
683
	/*
684
	 * Get the status of all targets
685
	 */
686
	__status(md, param, outbuf, &len);
687
688
	/*
689
	 * Setup the basic dm_ioctl structure.
690
	 */
691
	__info(md, param);
692
693
      out:
694
	if (md)
695
		dm_put(md);
696
697
	ret = results_to_user(user, param, outbuf, len);
698
699
	if (outbuf)
700
		kfree(outbuf);
701
702
	return ret;
703
}
704
705
/*
706
 * Wait for a device to report an event
707
 */
708
static int wait_device_event(struct dm_ioctl *param, struct dm_ioctl *user)
709
{
710
	struct mapped_device *md;
711
	struct dm_table *table;
712
	DECLARE_WAITQUEUE(wq, current);
713
714
	md = find_device(param);
715
	if (!md)
716
		/*
717
		 * Device not found - returns cleared exists flag.
718
		 */
719
		goto out;
720
721
	/*
722
	 * Setup the basic dm_ioctl structure.
723
	 */
724
	__info(md, param);
725
726
	/*
727
	 * Wait for a notification event
728
	 */
729
	set_current_state(TASK_INTERRUPTIBLE);
730
	table = dm_get_table(md);
731
	dm_table_add_wait_queue(table, &wq);
732
	dm_table_put(table);
733
	dm_put(md);
734
735
	yield();
736
	set_current_state(TASK_RUNNING);
737
738
      out:
739
	return results_to_user(user, param, NULL, 0);
740
}
741
742
/*
743
 * Retrieves a list of devices used by a particular dm device.
744
 */
745
static int dep(struct dm_ioctl *param, struct dm_ioctl *user)
746
{
747
	int count, r;
748
	struct mapped_device *md;
749
	struct list_head *tmp;
750
	size_t len = 0;
751
	struct dm_target_deps *deps = NULL;
752
	struct dm_table *table;
753
754
	md = find_device(param);
755
	if (!md)
756
		goto out;
757
	table = dm_get_table(md);
758
759
	/*
760
	 * Setup the basic dm_ioctl structure.
761
	 */
762
	__info(md, param);
763
764
	/*
765
	 * Count the devices.
766
	 */
767
	count = 0;
768
	list_for_each(tmp, dm_table_get_devices(table))
769
	    count++;
770
771
	/*
772
	 * Allocate a kernel space version of the dm_target_status
773
	 * struct.
774
	 */
775
	if (array_too_big(sizeof(*deps), sizeof(*deps->dev), count)) {
776
		dm_table_put(table);
777
		dm_put(md);
778
		return -ENOMEM;
779
	}
780
781
	len = sizeof(*deps) + (sizeof(*deps->dev) * count);
782
	deps = kmalloc(len, GFP_KERNEL);
783
	if (!deps) {
784
		dm_table_put(table);
785
		dm_put(md);
786
		return -ENOMEM;
787
	}
788
789
	/*
790
	 * Fill in the devices.
791
	 */
792
	deps->count = count;
793
	count = 0;
794
	list_for_each(tmp, dm_table_get_devices(table)) {
795
		struct dm_dev *dd = list_entry(tmp, struct dm_dev, list);
796
		deps->dev[count++] = dd->bdev->bd_dev;
797
	}
798
	dm_table_put(table);
799
	dm_put(md);
800
801
      out:
802
	r = results_to_user(user, param, deps, len);
803
804
	kfree(deps);
805
	return r;
806
}
807
808
static int remove(struct dm_ioctl *param, struct dm_ioctl *user)
809
{
810
	struct hash_cell *hc;
811
812
	down_write(&_hash_lock);
813
	hc = *param->uuid ? __get_uuid_cell(param->uuid) :
814
	    __get_name_cell(param->name);
815
	if (!hc) {
816
		DMWARN("device doesn't appear to be in the dev hash table.");
817
		up_write(&_hash_lock);
818
		return -EINVAL;
819
	}
820
821
	/*
822
	 * You may ask the interface to drop its reference to an
823
	 * in use device.  This is no different to unlinking a
824
	 * file that someone still has open.  The device will not
825
	 * actually be destroyed until the last opener closes it.
826
	 * The name and uuid of the device (both are interface
827
	 * properties) will be available for reuse immediately.
828
	 *
829
	 * You don't want to drop a _suspended_ device from the
830
	 * interface, since that will leave you with no way of
831
	 * resuming it.
832
	 */
833
	if (dm_suspended(hc->md)) {
834
		DMWARN("refusing to remove a suspended device.");
835
		up_write(&_hash_lock);
836
		return -EPERM;
837
	}
838
839
	__hash_remove(hc);
840
	up_write(&_hash_lock);
841
	return 0;
842
}
843
844
static int remove_all(struct dm_ioctl *param, struct dm_ioctl *user)
845
{
846
	dm_hash_remove_all();
847
	return 0;
848
}
849
850
static int suspend(struct dm_ioctl *param, struct dm_ioctl *user)
851
{
852
	int r;
853
	struct mapped_device *md;
854
855
	md = find_device(param);
856
	if (!md)
857
		return -ENXIO;
858
859
	if (param->flags & DM_SUSPEND_FLAG)
860
		r = dm_suspend(md);
861
	else
862
		r = dm_resume(md);
863
864
	dm_put(md);
865
	return r;
866
}
867
868
static int reload(struct dm_ioctl *param, struct dm_ioctl *user)
869
{
870
	int r;
871
	kdev_t dev;
872
	struct mapped_device *md;
873
	struct dm_table *t;
874
875
	r = dm_table_create(&t, get_mode(param));
876
	if (r)
877
		return r;
878
879
	r = populate_table(t, param);
880
	if (r) {
881
		dm_table_put(t);
882
		return r;
883
	}
884
885
	md = find_device(param);
886
	if (!md) {
887
		dm_table_put(t);
888
		return -ENXIO;
889
	}
890
891
	r = dm_swap_table(md, t);
892
	if (r) {
893
		dm_put(md);
894
		dm_table_put(t);
895
		return r;
896
	}
897
	dm_table_put(t);	/* md will have taken its own reference */
898
899
	dev = dm_kdev(md);
900
	set_device_ro(dev, (param->flags & DM_READONLY_FLAG));
901
	dm_put(md);
902
903
	r = info(param, user);
904
	return r;
905
}
906
907
static int rename(struct dm_ioctl *param, struct dm_ioctl *user)
908
{
909
	int r;
910
	char *new_name = (char *) param + param->data_start;
911
912
	if (valid_str(new_name, (void *) param,
913
		      (void *) param + param->data_size)) {
914
		DMWARN("Invalid new logical volume name supplied.");
915
		return -EINVAL;
916
	}
917
918
	r = check_name(new_name);
919
	if (r)
920
		return r;
921
922
	return dm_hash_rename(param->name, new_name);
923
}
924
925
926
/*-----------------------------------------------------------------
927
 * Implementation of open/close/ioctl on the special char
928
 * device.
929
 *---------------------------------------------------------------*/
930
static ioctl_fn lookup_ioctl(unsigned int cmd)
931
{
932
	static struct {
933
		int cmd;
934
		ioctl_fn fn;
935
	} _ioctls[] = {
936
		{DM_VERSION_CMD, NULL},	/* version is dealt with elsewhere */
937
		{DM_REMOVE_ALL_CMD, remove_all},
938
		{DM_DEV_CREATE_CMD, create},
939
		{DM_DEV_REMOVE_CMD, remove},
940
		{DM_DEV_RELOAD_CMD, reload},
941
		{DM_DEV_RENAME_CMD, rename},
942
		{DM_DEV_SUSPEND_CMD, suspend},
943
		{DM_DEV_DEPS_CMD, dep},
944
		{DM_DEV_STATUS_CMD, info},
945
		{DM_TARGET_STATUS_CMD, get_status},
946
		{DM_TARGET_WAIT_CMD, wait_device_event},
947
	};
948
949
	return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn;
950
}
951
952
/*
953
 * As well as checking the version compatibility this always
954
 * copies the kernel interface version out.
955
 */
956
static int check_version(int cmd, struct dm_ioctl *user)
957
{
958
	uint32_t version[3];
959
	int r = 0;
960
961
	if (copy_from_user(version, user->version, sizeof(version)))
962
		return -EFAULT;
963
964
	if ((DM_VERSION_MAJOR != version[0]) ||
965
	    (DM_VERSION_MINOR < version[1])) {
966
		DMWARN("ioctl interface mismatch: "
967
		       "kernel(%u.%u.%u), user(%u.%u.%u), cmd(%d)",
968
		       DM_VERSION_MAJOR, DM_VERSION_MINOR,
969
		       DM_VERSION_PATCHLEVEL,
970
		       version[0], version[1], version[2], cmd);
971
		r = -EINVAL;
972
	}
973
974
	/*
975
	 * Fill in the kernel version.
976
	 */
977
	version[0] = DM_VERSION_MAJOR;
978
	version[1] = DM_VERSION_MINOR;
979
	version[2] = DM_VERSION_PATCHLEVEL;
980
	if (copy_to_user(user->version, version, sizeof(version)))
981
		return -EFAULT;
982
983
	return r;
984
}
985
986
static void free_params(struct dm_ioctl *param)
987
{
988
	vfree(param);
989
}
990
991
static int copy_params(struct dm_ioctl *user, struct dm_ioctl **param)
992
{
993
	struct dm_ioctl tmp, *dmi;
994
995
	if (copy_from_user(&tmp, user, sizeof(tmp)))
996
		return -EFAULT;
997
998
	if (tmp.data_size < sizeof(tmp))
999
		return -EINVAL;
1000
1001
	dmi = (struct dm_ioctl *) vmalloc(tmp.data_size);
1002
	if (!dmi)
1003
		return -ENOMEM;
1004
1005
	if (copy_from_user(dmi, user, tmp.data_size)) {
1006
		vfree(dmi);
1007
		return -EFAULT;
1008
	}
1009
1010
	*param = dmi;
1011
	return 0;
1012
}
1013
1014
static int validate_params(uint cmd, struct dm_ioctl *param)
1015
{
1016
	/* Ignores parameters */
1017
	if (cmd == DM_REMOVE_ALL_CMD)
1018
		return 0;
1019
1020
	/* Unless creating, either name of uuid but not both */
1021
	if (cmd != DM_DEV_CREATE_CMD) {
1022
		if ((!*param->uuid && !*param->name) ||
1023
		    (*param->uuid && *param->name)) {
1024
			DMWARN("one of name or uuid must be supplied");
1025
			return -EINVAL;
1026
		}
1027
	}
1028
1029
	/* Ensure strings are terminated */
1030
	param->name[DM_NAME_LEN - 1] = '\0';
1031
	param->uuid[DM_UUID_LEN - 1] = '\0';
1032
1033
	return 0;
1034
}
1035
1036
static int ctl_ioctl(struct inode *inode, struct file *file,
1037
		     uint command, ulong u)
1038
{
1039
	int r = 0, cmd;
1040
	struct dm_ioctl *param;
1041
	struct dm_ioctl *user = (struct dm_ioctl *) u;
1042
	ioctl_fn fn = NULL;
1043
1044
	/* only root can play with this */
1045
	if (!capable(CAP_SYS_ADMIN))
1046
		return -EACCES;
1047
1048
	if (_IOC_TYPE(command) != DM_IOCTL)
1049
		return -ENOTTY;
1050
1051
	cmd = _IOC_NR(command);
1052
1053
	/*
1054
	 * Check the interface version passed in.  This also
1055
	 * writes out the kernel's interface version.
1056
	 */
1057
	r = check_version(cmd, user);
1058
	if (r)
1059
		return r;
1060
1061
	/*
1062
	 * Nothing more to do for the version command.
1063
	 */
1064
	if (cmd == DM_VERSION_CMD)
1065
		return 0;
1066
1067
	fn = lookup_ioctl(cmd);
1068
	if (!fn) {
1069
		DMWARN("dm_ctl_ioctl: unknown command 0x%x", command);
1070
		return -ENOTTY;
1071
	}
1072
1073
	/*
1074
	 * Copy the parameters into kernel space.
1075
	 */
1076
	r = copy_params(user, &param);
1077
	if (r)
1078
		return r;
1079
1080
	r = validate_params(cmd, param);
1081
	if (r) {
1082
		free_params(param);
1083
		return r;
1084
	}
1085
1086
	r = fn(param, user);
1087
	free_params(param);
1088
	return r;
1089
}
1090
1091
static struct file_operations _ctl_fops = {
1092
	.ioctl	 = ctl_ioctl,
1093
	.owner	 = THIS_MODULE,
1094
};
1095
1096
static devfs_handle_t _ctl_handle;
1097
1098
static struct miscdevice _dm_misc = {
1099
	.minor = MISC_DYNAMIC_MINOR,
1100
	.name  = DM_NAME,
1101
	.fops  = &_ctl_fops
1102
};
1103
1104
/*
1105
 * Create misc character device and link to DM_DIR/control.
1106
 */
1107
int __init dm_interface_init(void)
1108
{
1109
	int r;
1110
	char rname[64];
1111
1112
	r = dm_hash_init();
1113
	if (r)
1114
		return r;
1115
1116
	r = misc_register(&_dm_misc);
1117
	if (r) {
1118
		DMERR("misc_register failed for control device");
1119
		dm_hash_exit();
1120
		return r;
1121
	}
1122
1123
	r = devfs_generate_path(_dm_misc.devfs_handle, rname + 3,
1124
				sizeof rname - 3);
1125
	if (r == -ENOSYS)
1126
		goto done;	/* devfs not present */
1127
1128
	if (r < 0) {
1129
		DMERR("devfs_generate_path failed for control device");
1130
		goto failed;
1131
	}
1132
1133
	strncpy(rname + r, "../", 3);
1134
	r = devfs_mk_symlink(NULL, DM_DIR "/control",
1135
			     DEVFS_FL_DEFAULT, rname + r, &_ctl_handle, NULL);
1136
	if (r) {
1137
		DMERR("devfs_mk_symlink failed for control device");
1138
		goto failed;
1139
	}
1140
	devfs_auto_unregister(_dm_misc.devfs_handle, _ctl_handle);
1141
1142
      done:
1143
	DMINFO("%d.%d.%d%s initialised: %s", DM_VERSION_MAJOR,
1144
	       DM_VERSION_MINOR, DM_VERSION_PATCHLEVEL, DM_VERSION_EXTRA,
1145
	       DM_DRIVER_EMAIL);
1146
	return 0;
1147
1148
      failed:
1149
	misc_deregister(&_dm_misc);
1150
	dm_hash_exit();
1151
	return r;
1152
}
1153
1154
void dm_interface_exit(void)
1155
{
1156
	if (misc_deregister(&_dm_misc) < 0)
1157
		DMERR("misc_deregister failed for control device");
1158
1159
	dm_hash_exit();
1160
}
(-)linux-2.4.20-gentoo-r5/drivers/md/dm-linear.c (+121 lines)
Line 0 Link Here
1
/*
2
 * Copyright (C) 2001 Sistina Software (UK) Limited.
3
 *
4
 * This file is released under the GPL.
5
 */
6
7
#include "dm.h"
8
9
#include <linux/module.h>
10
#include <linux/init.h>
11
#include <linux/blkdev.h>
12
#include <linux/slab.h>
13
14
/*
15
 * Linear: maps a linear range of a device.
16
 */
17
struct linear_c {
18
	struct dm_dev *dev;
19
	sector_t start;
20
};
21
22
/*
23
 * Construct a linear mapping: <dev_path> <offset>
24
 */
25
static int linear_ctr(struct dm_target *ti, int argc, char **argv)
26
{
27
	struct linear_c *lc;
28
29
	if (argc != 2) {
30
		ti->error = "dm-linear: Not enough arguments";
31
		return -EINVAL;
32
	}
33
34
	lc = kmalloc(sizeof(*lc), GFP_KERNEL);
35
	if (lc == NULL) {
36
		ti->error = "dm-linear: Cannot allocate linear context";
37
		return -ENOMEM;
38
	}
39
40
	if (sscanf(argv[1], SECTOR_FORMAT, &lc->start) != 1) {
41
		ti->error = "dm-linear: Invalid device sector";
42
		goto bad;
43
	}
44
45
	if (dm_get_device(ti, argv[0], lc->start, ti->len,
46
			  dm_table_get_mode(ti->table), &lc->dev)) {
47
		ti->error = "dm-linear: Device lookup failed";
48
		goto bad;
49
	}
50
51
	ti->private = lc;
52
	return 0;
53
54
      bad:
55
	kfree(lc);
56
	return -EINVAL;
57
}
58
59
static void linear_dtr(struct dm_target *ti)
60
{
61
	struct linear_c *lc = (struct linear_c *) ti->private;
62
63
	dm_put_device(ti, lc->dev);
64
	kfree(lc);
65
}
66
67
static int linear_map(struct dm_target *ti, struct buffer_head *bh, int rw,
68
		      void **map_context)
69
{
70
	struct linear_c *lc = (struct linear_c *) ti->private;
71
72
	bh->b_rdev = lc->dev->dev;
73
	bh->b_rsector = lc->start + (bh->b_rsector - ti->begin);
74
75
	return 1;
76
}
77
78
static int linear_status(struct dm_target *ti, status_type_t type,
79
			 char *result, int maxlen)
80
{
81
	struct linear_c *lc = (struct linear_c *) ti->private;
82
83
	switch (type) {
84
	case STATUSTYPE_INFO:
85
		result[0] = '\0';
86
		break;
87
88
	case STATUSTYPE_TABLE:
89
		snprintf(result, maxlen, "%s " SECTOR_FORMAT,
90
			 kdevname(to_kdev_t(lc->dev->bdev->bd_dev)), lc->start);
91
		break;
92
	}
93
	return 0;
94
}
95
96
static struct target_type linear_target = {
97
	.name   = "linear",
98
	.module = THIS_MODULE,
99
	.ctr    = linear_ctr,
100
	.dtr    = linear_dtr,
101
	.map    = linear_map,
102
	.status = linear_status,
103
};
104
105
int __init dm_linear_init(void)
106
{
107
	int r = dm_register_target(&linear_target);
108
109
	if (r < 0)
110
		DMERR("linear: register failed %d", r);
111
112
	return r;
113
}
114
115
void dm_linear_exit(void)
116
{
117
	int r = dm_unregister_target(&linear_target);
118
119
	if (r < 0)
120
		DMERR("linear: unregister failed %d", r);
121
}
(-)linux-2.4.20-gentoo-r5/drivers/md/dm-snapshot.c (+1170 lines)
Line 0 Link Here
1
/*
2
 * dm-snapshot.c
3
 *
4
 * Copyright (C) 2001-2002 Sistina Software (UK) Limited.
5
 *
6
 * This file is released under the GPL.
7
 */
8
9
#include <linux/config.h>
10
#include <linux/ctype.h>
11
#include <linux/module.h>
12
#include <linux/init.h>
13
#include <linux/slab.h>
14
#include <linux/list.h>
15
#include <linux/fs.h>
16
#include <linux/blkdev.h>
17
#include <linux/mempool.h>
18
#include <linux/device-mapper.h>
19
#include <linux/vmalloc.h>
20
21
#include "dm-snapshot.h"
22
#include "kcopyd.h"
23
24
/*
25
 * FIXME: Remove this before release.
26
 */
27
#if 0
28
#define DMDEBUG(x...) DMWARN( ## x)
29
#else
30
#define DMDEBUG(x...)
31
#endif
32
33
/*
34
 * The percentage increment we will wake up users at
35
 */
36
#define WAKE_UP_PERCENT 5
37
38
/*
39
 * kcopyd priority of snapshot operations
40
 */
41
#define SNAPSHOT_COPY_PRIORITY 2
42
43
struct pending_exception {
44
	struct exception e;
45
46
	/*
47
	 * Origin buffers waiting for this to complete are held
48
	 * in a list (using b_reqnext).
49
	 */
50
	struct buffer_head *origin_bhs;
51
	struct buffer_head *snapshot_bhs;
52
53
	/*
54
	 * Other pending_exceptions that are processing this
55
	 * chunk.  When this list is empty, we know we can
56
	 * complete the origins.
57
	 */
58
	struct list_head siblings;
59
60
	/* Pointer back to snapshot context */
61
	struct dm_snapshot *snap;
62
63
	/*
64
	 * 1 indicates the exception has already been sent to
65
	 * kcopyd.
66
	 */
67
	int started;
68
};
69
70
/*
71
 * Hash table mapping origin volumes to lists of snapshots and
72
 * a lock to protect it
73
 */
74
static kmem_cache_t *exception_cache;
75
static kmem_cache_t *pending_cache;
76
static mempool_t *pending_pool;
77
78
/*
79
 * One of these per registered origin, held in the snapshot_origins hash
80
 */
81
struct origin {
82
	/* The origin device */
83
	kdev_t dev;
84
85
	struct list_head hash_list;
86
87
	/* List of snapshots for this origin */
88
	struct list_head snapshots;
89
};
90
91
/*
92
 * Size of the hash table for origin volumes. If we make this
93
 * the size of the minors list then it should be nearly perfect
94
 */
95
#define ORIGIN_HASH_SIZE 256
96
#define ORIGIN_MASK      0xFF
97
static struct list_head *_origins;
98
static struct rw_semaphore _origins_lock;
99
100
static int init_origin_hash(void)
101
{
102
	int i;
103
104
	_origins = kmalloc(ORIGIN_HASH_SIZE * sizeof(struct list_head),
105
			   GFP_KERNEL);
106
	if (!_origins) {
107
		DMERR("Device mapper: Snapshot: unable to allocate memory");
108
		return -ENOMEM;
109
	}
110
111
	for (i = 0; i < ORIGIN_HASH_SIZE; i++)
112
		INIT_LIST_HEAD(_origins + i);
113
	init_rwsem(&_origins_lock);
114
115
	return 0;
116
}
117
118
static void exit_origin_hash(void)
119
{
120
	kfree(_origins);
121
}
122
123
static inline unsigned int origin_hash(kdev_t dev)
124
{
125
	return MINOR(dev) & ORIGIN_MASK;
126
}
127
128
static struct origin *__lookup_origin(kdev_t origin)
129
{
130
	struct list_head *slist;
131
	struct list_head *ol;
132
	struct origin *o;
133
134
	ol = &_origins[origin_hash(origin)];
135
	list_for_each(slist, ol) {
136
		o = list_entry(slist, struct origin, hash_list);
137
138
		if (o->dev == origin)
139
			return o;
140
	}
141
142
	return NULL;
143
}
144
145
static void __insert_origin(struct origin *o)
146
{
147
	struct list_head *sl = &_origins[origin_hash(o->dev)];
148
	list_add_tail(&o->hash_list, sl);
149
}
150
151
/*
152
 * Make a note of the snapshot and its origin so we can look it
153
 * up when the origin has a write on it.
154
 */
155
static int register_snapshot(struct dm_snapshot *snap)
156
{
157
	struct origin *o;
158
	kdev_t dev = snap->origin->dev;
159
160
	down_write(&_origins_lock);
161
	o = __lookup_origin(dev);
162
163
	if (!o) {
164
		/* New origin */
165
		o = kmalloc(sizeof(*o), GFP_KERNEL);
166
		if (!o) {
167
			up_write(&_origins_lock);
168
			return -ENOMEM;
169
		}
170
171
		/* Initialise the struct */
172
		INIT_LIST_HEAD(&o->snapshots);
173
		o->dev = dev;
174
175
		__insert_origin(o);
176
	}
177
178
	list_add_tail(&snap->list, &o->snapshots);
179
180
	up_write(&_origins_lock);
181
	return 0;
182
}
183
184
static void unregister_snapshot(struct dm_snapshot *s)
185
{
186
	struct origin *o;
187
188
	down_write(&_origins_lock);
189
	o = __lookup_origin(s->origin->dev);
190
191
	list_del(&s->list);
192
	if (list_empty(&o->snapshots)) {
193
		list_del(&o->hash_list);
194
		kfree(o);
195
	}
196
197
	up_write(&_origins_lock);
198
}
199
200
/*
201
 * Implementation of the exception hash tables.
202
 */
203
static int init_exception_table(struct exception_table *et, uint32_t size)
204
{
205
	int i;
206
207
	et->hash_mask = size - 1;
208
	et->table = vcalloc(size, sizeof(struct list_head));
209
	if (!et->table)
210
		return -ENOMEM;
211
212
	for (i = 0; i < size; i++)
213
		INIT_LIST_HEAD(et->table + i);
214
215
	return 0;
216
}
217
218
static void exit_exception_table(struct exception_table *et, kmem_cache_t *mem)
219
{
220
	struct list_head *slot, *entry, *temp;
221
	struct exception *ex;
222
	int i, size;
223
224
	size = et->hash_mask + 1;
225
	for (i = 0; i < size; i++) {
226
		slot = et->table + i;
227
228
		list_for_each_safe(entry, temp, slot) {
229
			ex = list_entry(entry, struct exception, hash_list);
230
			kmem_cache_free(mem, ex);
231
		}
232
	}
233
234
	vfree(et->table);
235
}
236
237
/*
238
 * FIXME: check how this hash fn is performing.
239
 */
240
static inline uint32_t exception_hash(struct exception_table *et, chunk_t chunk)
241
{
242
	return chunk & et->hash_mask;
243
}
244
245
static void insert_exception(struct exception_table *eh, struct exception *e)
246
{
247
	struct list_head *l = &eh->table[exception_hash(eh, e->old_chunk)];
248
	list_add(&e->hash_list, l);
249
}
250
251
static inline void remove_exception(struct exception *e)
252
{
253
	list_del(&e->hash_list);
254
}
255
256
/*
257
 * Return the exception data for a sector, or NULL if not
258
 * remapped.
259
 */
260
static struct exception *lookup_exception(struct exception_table *et,
261
					  chunk_t chunk)
262
{
263
	struct list_head *slot, *el;
264
	struct exception *e;
265
266
	slot = &et->table[exception_hash(et, chunk)];
267
	list_for_each(el, slot) {
268
		e = list_entry(el, struct exception, hash_list);
269
		if (e->old_chunk == chunk)
270
			return e;
271
	}
272
273
	return NULL;
274
}
275
276
static inline struct exception *alloc_exception(void)
277
{
278
	struct exception *e;
279
280
	e = kmem_cache_alloc(exception_cache, GFP_NOIO);
281
	if (!e)
282
		e = kmem_cache_alloc(exception_cache, GFP_ATOMIC);
283
284
	return e;
285
}
286
287
static inline void free_exception(struct exception *e)
288
{
289
	kmem_cache_free(exception_cache, e);
290
}
291
292
static inline struct pending_exception *alloc_pending_exception(void)
293
{
294
	return mempool_alloc(pending_pool, GFP_NOIO);
295
}
296
297
static inline void free_pending_exception(struct pending_exception *pe)
298
{
299
	mempool_free(pe, pending_pool);
300
}
301
302
int dm_add_exception(struct dm_snapshot *s, chunk_t old, chunk_t new)
303
{
304
	struct exception *e;
305
306
	e = alloc_exception();
307
	if (!e)
308
		return -ENOMEM;
309
310
	e->old_chunk = old;
311
	e->new_chunk = new;
312
	insert_exception(&s->complete, e);
313
	return 0;
314
}
315
316
/*
317
 * Hard coded magic.
318
 */
319
static int calc_max_buckets(void)
320
{
321
	unsigned long mem;
322
323
	mem = num_physpages << PAGE_SHIFT;
324
	mem /= 50;
325
	mem /= sizeof(struct list_head);
326
327
	return mem;
328
}
329
330
/*
331
 * Rounds a number down to a power of 2.
332
 */
333
static inline uint32_t round_down(uint32_t n)
334
{
335
	while (n & (n - 1))
336
		n &= (n - 1);
337
	return n;
338
}
339
340
/*
341
 * Allocate room for a suitable hash table.
342
 */
343
static int init_hash_tables(struct dm_snapshot *s)
344
{
345
	sector_t hash_size, cow_dev_size, origin_dev_size, max_buckets;
346
347
	/*
348
	 * Calculate based on the size of the original volume or
349
	 * the COW volume...
350
	 */
351
	cow_dev_size = get_dev_size(s->cow->dev);
352
	origin_dev_size = get_dev_size(s->origin->dev);
353
	max_buckets = calc_max_buckets();
354
355
	hash_size = min(origin_dev_size, cow_dev_size) / s->chunk_size;
356
	hash_size = min(hash_size, max_buckets);
357
358
	/* Round it down to a power of 2 */
359
	hash_size = round_down(hash_size);
360
	if (init_exception_table(&s->complete, hash_size))
361
		return -ENOMEM;
362
363
	/*
364
	 * Allocate hash table for in-flight exceptions
365
	 * Make this smaller than the real hash table
366
	 */
367
	hash_size >>= 3;
368
	if (!hash_size)
369
		hash_size = 64;
370
371
	if (init_exception_table(&s->pending, hash_size)) {
372
		exit_exception_table(&s->complete, exception_cache);
373
		return -ENOMEM;
374
	}
375
376
	return 0;
377
}
378
379
/*
380
 * Round a number up to the nearest 'size' boundary.  size must
381
 * be a power of 2.
382
 */
383
static inline ulong round_up(ulong n, ulong size)
384
{
385
	size--;
386
	return (n + size) & ~size;
387
}
388
389
/*
390
 * Construct a snapshot mapping: <origin_dev> <COW-dev> <p/n> <chunk-size>
391
 */
392
static int snapshot_ctr(struct dm_target *ti, int argc, char **argv)
393
{
394
	struct dm_snapshot *s;
395
	unsigned long chunk_size;
396
	int r = -EINVAL;
397
	char persistent;
398
	char *origin_path;
399
	char *cow_path;
400
	char *value;
401
	int blocksize;
402
403
	if (argc < 4) {
404
		ti->error = "dm-snapshot: requires exactly 4 arguments";
405
		r = -EINVAL;
406
		goto bad;
407
	}
408
409
	origin_path = argv[0];
410
	cow_path = argv[1];
411
	persistent = toupper(*argv[2]);
412
413
	if (persistent != 'P' && persistent != 'N') {
414
		ti->error = "Persistent flag is not P or N";
415
		r = -EINVAL;
416
		goto bad;
417
	}
418
419
	chunk_size = simple_strtoul(argv[3], &value, 10);
420
	if (chunk_size == 0 || value == NULL) {
421
		ti->error = "Invalid chunk size";
422
		r = -EINVAL;
423
		goto bad;
424
	}
425
426
	s = kmalloc(sizeof(*s), GFP_KERNEL);
427
	if (s == NULL) {
428
		ti->error = "Cannot allocate snapshot context private "
429
		    "structure";
430
		r = -ENOMEM;
431
		goto bad;
432
	}
433
434
	r = dm_get_device(ti, origin_path, 0, ti->len, FMODE_READ, &s->origin);
435
	if (r) {
436
		ti->error = "Cannot get origin device";
437
		goto bad_free;
438
	}
439
440
	/* FIXME: get cow length */
441
	r = dm_get_device(ti, cow_path, 0, 0,
442
			  FMODE_READ | FMODE_WRITE, &s->cow);
443
	if (r) {
444
		dm_put_device(ti, s->origin);
445
		ti->error = "Cannot get COW device";
446
		goto bad_free;
447
	}
448
449
	/*
450
	 * Chunk size must be multiple of page size.  Silently
451
	 * round up if it's not.
452
	 */
453
	chunk_size = round_up(chunk_size, PAGE_SIZE / SECTOR_SIZE);
454
455
	/* Validate the chunk size against the device block size */
456
	blocksize = get_hardsect_size(s->cow->dev);
457
	if (chunk_size % (blocksize / SECTOR_SIZE)) {
458
		ti->error = "Chunk size is not a multiple of device blocksize";
459
		r = -EINVAL;
460
		goto bad_putdev;
461
	}
462
463
	/* Check the sizes are small enough to fit in one kiovec */
464
	if (chunk_size > KIO_MAX_SECTORS) {
465
		ti->error = "Chunk size is too big";
466
		r = -EINVAL;
467
		goto bad_putdev;
468
	}
469
470
	/* Check chunk_size is a power of 2 */
471
	if (chunk_size & (chunk_size - 1)) {
472
		ti->error = "Chunk size is not a power of 2";
473
		r = -EINVAL;
474
		goto bad_putdev;
475
	}
476
477
	s->chunk_size = chunk_size;
478
	s->chunk_mask = chunk_size - 1;
479
	s->type = persistent;
480
	for (s->chunk_shift = 0; chunk_size;
481
	     s->chunk_shift++, chunk_size >>= 1)
482
		;
483
	s->chunk_shift--;
484
485
	s->valid = 1;
486
	s->last_percent = 0;
487
	init_rwsem(&s->lock);
488
	s->table = ti->table;
489
490
	/* Allocate hash table for COW data */
491
	if (init_hash_tables(s)) {
492
		ti->error = "Unable to allocate hash table space";
493
		r = -ENOMEM;
494
		goto bad_putdev;
495
	}
496
497
	/*
498
	 * Check the persistent flag - done here because we need the iobuf
499
	 * to check the LV header
500
	 */
501
	s->store.snap = s;
502
503
	if (persistent == 'P')
504
		r = dm_create_persistent(&s->store, s->chunk_size);
505
	else
506
		r = dm_create_transient(&s->store, s, blocksize);
507
508
	if (r) {
509
		ti->error = "Couldn't create exception store";
510
		r = -EINVAL;
511
		goto bad_free1;
512
	}
513
514
	/* Flush IO to the origin device */
515
#if LVM_VFS_ENHANCEMENT
516
	fsync_dev_lockfs(s->origin->dev);
517
#else
518
	fsync_dev(s->origin->dev);
519
#endif
520
521
	/* Add snapshot to the list of snapshots for this origin */
522
	if (register_snapshot(s)) {
523
		r = -EINVAL;
524
		ti->error = "Cannot register snapshot origin";
525
		goto bad_free2;
526
	}
527
#if LVM_VFS_ENHANCEMENT
528
	unlockfs(s->origin->dev);
529
#endif
530
	kcopyd_inc_client_count();
531
532
	ti->private = s;
533
	return 0;
534
535
      bad_free2:
536
#if LVM_VFS_ENHANCEMENT
537
	unlockfs(s->origin->dev);
538
#endif
539
	s->store.destroy(&s->store);
540
541
      bad_free1:
542
	exit_exception_table(&s->pending, pending_cache);
543
	exit_exception_table(&s->complete, exception_cache);
544
545
      bad_putdev:
546
	dm_put_device(ti, s->cow);
547
	dm_put_device(ti, s->origin);
548
549
      bad_free:
550
	kfree(s);
551
552
      bad:
553
	return r;
554
}
555
556
static void snapshot_dtr(struct dm_target *ti)
557
{
558
	struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
559
560
	dm_table_event(ti->table);
561
562
	unregister_snapshot(s);
563
564
	exit_exception_table(&s->pending, pending_cache);
565
	exit_exception_table(&s->complete, exception_cache);
566
567
	/* Deallocate memory used */
568
	s->store.destroy(&s->store);
569
570
	dm_put_device(ti, s->origin);
571
	dm_put_device(ti, s->cow);
572
	kfree(s);
573
574
	kcopyd_dec_client_count();
575
}
576
577
/*
578
 * We hold lists of buffer_heads, using the b_reqnext field.
579
 */
580
static void queue_buffer(struct buffer_head **queue, struct buffer_head *bh)
581
{
582
	bh->b_reqnext = *queue;
583
	*queue = bh;
584
}
585
586
/*
587
 * Flush a list of buffers.
588
 */
589
static void flush_buffers(struct buffer_head *bh)
590
{
591
	struct buffer_head *n;
592
593
	DMDEBUG("begin flush");
594
	while (bh) {
595
		n = bh->b_reqnext;
596
		bh->b_reqnext = NULL;
597
		DMDEBUG("flushing %p", bh);
598
		generic_make_request(WRITE, bh);
599
		bh = n;
600
	}
601
602
	run_task_queue(&tq_disk);
603
}
604
605
/*
606
 * Error a list of buffers.
607
 */
608
static void error_buffers(struct buffer_head *bh)
609
{
610
	struct buffer_head *n;
611
612
	while (bh) {
613
		n = bh->b_reqnext;
614
		bh->b_reqnext = NULL;
615
		buffer_IO_error(bh);
616
		bh = n;
617
	}
618
}
619
620
static void pending_complete(struct pending_exception *pe, int success)
621
{
622
	struct exception *e;
623
	struct dm_snapshot *s = pe->snap;
624
625
	if (success) {
626
		e = alloc_exception();
627
		if (!e) {
628
			printk("Unable to allocate exception.");
629
			down_write(&s->lock);
630
			s->store.drop_snapshot(&s->store);
631
			s->valid = 0;
632
			up_write(&s->lock);
633
			return;
634
		}
635
636
		/*
637
		 * Add a proper exception, and remove the
638
		 * inflight exception from the list.
639
		 */
640
		down_write(&s->lock);
641
642
		memcpy(e, &pe->e, sizeof(*e));
643
		insert_exception(&s->complete, e);
644
		remove_exception(&pe->e);
645
646
		/* Submit any pending write BHs */
647
		up_write(&s->lock);
648
649
		flush_buffers(pe->snapshot_bhs);
650
		DMDEBUG("Exception completed successfully.");
651
652
		/* Notify any interested parties */
653
		if (s->store.percent_full) {
654
			int pc = s->store.percent_full(&s->store);
655
656
			if (pc >= s->last_percent + WAKE_UP_PERCENT) {
657
				dm_table_event(s->table);
658
				s->last_percent = pc - pc % WAKE_UP_PERCENT;
659
			}
660
		}
661
662
	} else {
663
		/* Read/write error - snapshot is unusable */
664
		DMERR("Error reading/writing snapshot");
665
666
		down_write(&s->lock);
667
		s->store.drop_snapshot(&s->store);
668
		s->valid = 0;
669
		remove_exception(&pe->e);
670
		up_write(&s->lock);
671
672
		error_buffers(pe->snapshot_bhs);
673
674
		dm_table_event(s->table);
675
		DMDEBUG("Exception failed.");
676
	}
677
678
	if (list_empty(&pe->siblings))
679
		flush_buffers(pe->origin_bhs);
680
	else
681
		list_del(&pe->siblings);
682
683
	free_pending_exception(pe);
684
}
685
686
static void commit_callback(void *context, int success)
687
{
688
	struct pending_exception *pe = (struct pending_exception *) context;
689
	pending_complete(pe, success);
690
}
691
692
/*
693
 * Called when the copy I/O has finished.  kcopyd actually runs
694
 * this code so don't block.
695
 */
696
static void copy_callback(int err, void *context)
697
{
698
	struct pending_exception *pe = (struct pending_exception *) context;
699
	struct dm_snapshot *s = pe->snap;
700
701
	if (err)
702
		pending_complete(pe, 0);
703
704
	else
705
		/* Update the metadata if we are persistent */
706
		s->store.commit_exception(&s->store, &pe->e, commit_callback,
707
					  pe);
708
}
709
710
/*
711
 * Dispatches the copy operation to kcopyd.
712
 */
713
static inline void start_copy(struct pending_exception *pe)
714
{
715
	struct dm_snapshot *s = pe->snap;
716
	struct kcopyd_region src, dest;
717
718
	src.dev = s->origin->dev;
719
	src.sector = chunk_to_sector(s, pe->e.old_chunk);
720
	src.count = s->chunk_size;
721
722
	dest.dev = s->cow->dev;
723
	dest.sector = chunk_to_sector(s, pe->e.new_chunk);
724
	dest.count = s->chunk_size;
725
726
	if (!pe->started) {
727
		/* Hand over to kcopyd */
728
		kcopyd_copy(&src, &dest, copy_callback, pe);
729
		pe->started = 1;
730
	}
731
}
732
733
/*
734
 * Looks to see if this snapshot already has a pending exception
735
 * for this chunk, otherwise it allocates a new one and inserts
736
 * it into the pending table.
737
 */
738
static struct pending_exception *find_pending_exception(struct dm_snapshot *s,
739
							struct buffer_head *bh)
740
{
741
	struct exception *e;
742
	struct pending_exception *pe;
743
	chunk_t chunk = sector_to_chunk(s, bh->b_rsector);
744
745
	/*
746
	 * Is there a pending exception for this already ?
747
	 */
748
	e = lookup_exception(&s->pending, chunk);
749
	if (e) {
750
		/* cast the exception to a pending exception */
751
		pe = list_entry(e, struct pending_exception, e);
752
753
	} else {
754
		/* Create a new pending exception */
755
		pe = alloc_pending_exception();
756
		if (!pe) {
757
			DMWARN("Couldn't allocate pending exception.");
758
			return NULL;
759
		}
760
761
		pe->e.old_chunk = chunk;
762
		pe->origin_bhs = pe->snapshot_bhs = NULL;
763
		INIT_LIST_HEAD(&pe->siblings);
764
		pe->snap = s;
765
		pe->started = 0;
766
767
		if (s->store.prepare_exception(&s->store, &pe->e)) {
768
			free_pending_exception(pe);
769
			s->valid = 0;
770
			return NULL;
771
		}
772
773
		insert_exception(&s->pending, &pe->e);
774
	}
775
776
	return pe;
777
}
778
779
static inline void remap_exception(struct dm_snapshot *s, struct exception *e,
780
				   struct buffer_head *bh)
781
{
782
	bh->b_rdev = s->cow->dev;
783
	bh->b_rsector = chunk_to_sector(s, e->new_chunk) +
784
	    (bh->b_rsector & s->chunk_mask);
785
}
786
787
static int snapshot_map(struct dm_target *ti, struct buffer_head *bh, int rw,
788
			void **map_context)
789
{
790
	struct exception *e;
791
	struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
792
	int r = 1;
793
	chunk_t chunk;
794
	struct pending_exception *pe;
795
796
	chunk = sector_to_chunk(s, bh->b_rsector);
797
798
	/* Full snapshots are not usable */
799
	if (!s->valid)
800
		return -1;
801
802
	/*
803
	 * Write to snapshot - higher level takes care of RW/RO
804
	 * flags so we should only get this if we are
805
	 * writeable.
806
	 */
807
	if (rw == WRITE) {
808
809
		down_write(&s->lock);
810
811
		/* If the block is already remapped - use that, else remap it */
812
		e = lookup_exception(&s->complete, chunk);
813
		if (e)
814
			remap_exception(s, e, bh);
815
816
		else {
817
			pe = find_pending_exception(s, bh);
818
819
			if (!pe) {
820
				s->store.drop_snapshot(&s->store);
821
				s->valid = 0;
822
			}
823
824
			queue_buffer(&pe->snapshot_bhs, bh);
825
			start_copy(pe);
826
			r = 0;
827
		}
828
829
		up_write(&s->lock);
830
831
	} else {
832
		/*
833
		 * FIXME: this read path scares me because we
834
		 * always use the origin when we have a pending
835
		 * exception.  However I can't think of a
836
		 * situation where this is wrong - ejt.
837
		 */
838
839
		/* Do reads */
840
		down_read(&s->lock);
841
842
		/* See if it it has been remapped */
843
		e = lookup_exception(&s->complete, chunk);
844
		if (e)
845
			remap_exception(s, e, bh);
846
		else
847
			bh->b_rdev = s->origin->dev;
848
849
		up_read(&s->lock);
850
	}
851
852
	return r;
853
}
854
855
static void list_merge(struct list_head *l1, struct list_head *l2)
856
{
857
	struct list_head *l1_n, *l2_p;
858
859
	l1_n = l1->next;
860
	l2_p = l2->prev;
861
862
	l1->next = l2;
863
	l2->prev = l1;
864
865
	l2_p->next = l1_n;
866
	l1_n->prev = l2_p;
867
}
868
869
static int __origin_write(struct list_head *snapshots, struct buffer_head *bh)
870
{
871
	int r = 1;
872
	struct list_head *sl;
873
	struct dm_snapshot *snap;
874
	struct exception *e;
875
	struct pending_exception *pe, *last = NULL;
876
	chunk_t chunk;
877
878
	/* Do all the snapshots on this origin */
879
	list_for_each(sl, snapshots) {
880
		snap = list_entry(sl, struct dm_snapshot, list);
881
882
		/* Only deal with valid snapshots */
883
		if (!snap->valid)
884
			continue;
885
886
		down_write(&snap->lock);
887
888
		/*
889
		 * Remember, different snapshots can have
890
		 * different chunk sizes.
891
		 */
892
		chunk = sector_to_chunk(snap, bh->b_rsector);
893
894
		/*
895
		 * Check exception table to see if block
896
		 * is already remapped in this snapshot
897
		 * and trigger an exception if not.
898
		 */
899
		e = lookup_exception(&snap->complete, chunk);
900
		if (!e) {
901
			pe = find_pending_exception(snap, bh);
902
			if (!pe) {
903
				snap->store.drop_snapshot(&snap->store);
904
				snap->valid = 0;
905
906
			} else {
907
				if (last)
908
					list_merge(&pe->siblings,
909
						   &last->siblings);
910
911
				last = pe;
912
				r = 0;
913
			}
914
		}
915
916
		up_write(&snap->lock);
917
	}
918
919
	/*
920
	 * Now that we have a complete pe list we can start the copying.
921
	 */
922
	if (last) {
923
		pe = last;
924
		do {
925
			down_write(&pe->snap->lock);
926
			queue_buffer(&pe->origin_bhs, bh);
927
			start_copy(pe);
928
			up_write(&pe->snap->lock);
929
			pe = list_entry(pe->siblings.next,
930
					struct pending_exception, siblings);
931
932
		} while (pe != last);
933
	}
934
935
	return r;
936
}
937
938
static int snapshot_status(struct dm_target *ti, status_type_t type,
939
			   char *result, int maxlen)
940
{
941
	struct dm_snapshot *snap = (struct dm_snapshot *) ti->private;
942
	char cow[16];
943
	char org[16];
944
945
	switch (type) {
946
	case STATUSTYPE_INFO:
947
		if (!snap->valid)
948
			snprintf(result, maxlen, "Invalid");
949
		else {
950
			if (snap->store.percent_full)
951
				snprintf(result, maxlen, "%d%%",
952
					 snap->store.percent_full(&snap->
953
								  store));
954
			else
955
				snprintf(result, maxlen, "Unknown");
956
		}
957
		break;
958
959
	case STATUSTYPE_TABLE:
960
		/*
961
		 * kdevname returns a static pointer so we need
962
		 * to make private copies if the output is to
963
		 * make sense.
964
		 */
965
		strncpy(cow, kdevname(snap->cow->dev), sizeof(cow));
966
		strncpy(org, kdevname(snap->origin->dev), sizeof(org));
967
		snprintf(result, maxlen, "%s %s %c %ld", org, cow,
968
			 snap->type, snap->chunk_size);
969
		break;
970
	}
971
972
	return 0;
973
}
974
975
/*
976
 * Called on a write from the origin driver.
977
 */
978
int do_origin(struct dm_dev *origin, struct buffer_head *bh)
979
{
980
	struct origin *o;
981
	int r;
982
983
	down_read(&_origins_lock);
984
	o = __lookup_origin(origin->dev);
985
	if (!o)
986
		BUG();
987
988
	r = __origin_write(&o->snapshots, bh);
989
	up_read(&_origins_lock);
990
991
	return r;
992
}
993
994
/*
995
 * Origin: maps a linear range of a device, with hooks for snapshotting.
996
 */
997
998
/*
999
 * Construct an origin mapping: <dev_path>
1000
 * The context for an origin is merely a 'struct dm_dev *'
1001
 * pointing to the real device.
1002
 */
1003
static int origin_ctr(struct dm_target *ti, int argc, char **argv)
1004
{
1005
	int r;
1006
	struct dm_dev *dev;
1007
1008
	if (argc != 1) {
1009
		ti->error = "dm-origin: incorrect number of arguments";
1010
		return -EINVAL;
1011
	}
1012
1013
	r = dm_get_device(ti, argv[0], 0, ti->len,
1014
			  dm_table_get_mode(ti->table), &dev);
1015
	if (r) {
1016
		ti->error = "Cannot get target device";
1017
		return r;
1018
	}
1019
1020
	ti->private = dev;
1021
1022
	return 0;
1023
}
1024
1025
static void origin_dtr(struct dm_target *ti)
1026
{
1027
	struct dm_dev *dev = (struct dm_dev *) ti->private;
1028
	dm_put_device(ti, dev);
1029
}
1030
1031
static int origin_map(struct dm_target *ti, struct buffer_head *bh, int rw,
1032
		      void **map_context)
1033
{
1034
	struct dm_dev *dev = (struct dm_dev *) ti->private;
1035
	bh->b_rdev = dev->dev;
1036
1037
	/* Only tell snapshots if this is a write */
1038
	return (rw == WRITE) ? do_origin(dev, bh) : 1;
1039
}
1040
1041
static int origin_status(struct dm_target *ti, status_type_t type, char *result,
1042
			 int maxlen)
1043
{
1044
	struct dm_dev *dev = (struct dm_dev *) ti->private;
1045
1046
	switch (type) {
1047
	case STATUSTYPE_INFO:
1048
		result[0] = '\0';
1049
		break;
1050
1051
	case STATUSTYPE_TABLE:
1052
		snprintf(result, maxlen, "%s", kdevname(dev->dev));
1053
		break;
1054
	}
1055
1056
	return 0;
1057
}
1058
1059
static struct target_type origin_target = {
1060
	name:	"snapshot-origin",
1061
	module:	THIS_MODULE,
1062
	ctr:	origin_ctr,
1063
	dtr:	origin_dtr,
1064
	map:	origin_map,
1065
	status:	origin_status,
1066
};
1067
1068
static struct target_type snapshot_target = {
1069
	name:	"snapshot",
1070
	module:	THIS_MODULE,
1071
	ctr:	snapshot_ctr,
1072
	dtr:	snapshot_dtr,
1073
	map:	snapshot_map,
1074
	status:	snapshot_status,
1075
};
1076
1077
int __init dm_snapshot_init(void)
1078
{
1079
	int r;
1080
1081
	r = dm_register_target(&snapshot_target);
1082
	if (r) {
1083
		DMERR("snapshot target register failed %d", r);
1084
		return r;
1085
	}
1086
1087
	r = dm_register_target(&origin_target);
1088
	if (r < 0) {
1089
		DMERR("Device mapper: Origin: register failed %d\n", r);
1090
		goto bad1;
1091
	}
1092
1093
	r = init_origin_hash();
1094
	if (r) {
1095
		DMERR("init_origin_hash failed.");
1096
		goto bad2;
1097
	}
1098
1099
	exception_cache = kmem_cache_create("dm-snapshot-ex",
1100
					    sizeof(struct exception),
1101
					    __alignof__(struct exception),
1102
					    0, NULL, NULL);
1103
	if (!exception_cache) {
1104
		DMERR("Couldn't create exception cache.");
1105
		r = -ENOMEM;
1106
		goto bad3;
1107
	}
1108
1109
	pending_cache =
1110
	    kmem_cache_create("dm-snapshot-in",
1111
			      sizeof(struct pending_exception),
1112
			      __alignof__(struct pending_exception),
1113
			      0, NULL, NULL);
1114
	if (!pending_cache) {
1115
		DMERR("Couldn't create pending cache.");
1116
		r = -ENOMEM;
1117
		goto bad4;
1118
	}
1119
1120
	pending_pool = mempool_create(128, mempool_alloc_slab,
1121
				      mempool_free_slab, pending_cache);
1122
	if (!pending_pool) {
1123
		DMERR("Couldn't create pending pool.");
1124
		r = -ENOMEM;
1125
		goto bad5;
1126
	}
1127
1128
	return 0;
1129
1130
      bad5:
1131
	kmem_cache_destroy(pending_cache);
1132
      bad4:
1133
	kmem_cache_destroy(exception_cache);
1134
      bad3:
1135
	exit_origin_hash();
1136
      bad2:
1137
	dm_unregister_target(&origin_target);
1138
      bad1:
1139
	dm_unregister_target(&snapshot_target);
1140
	return r;
1141
}
1142
1143
void dm_snapshot_exit(void)
1144
{
1145
	int r;
1146
1147
	r = dm_unregister_target(&snapshot_target);
1148
	if (r)
1149
		DMERR("snapshot unregister failed %d", r);
1150
1151
	r = dm_unregister_target(&origin_target);
1152
	if (r)
1153
		DMERR("origin unregister failed %d", r);
1154
1155
	exit_origin_hash();
1156
	mempool_destroy(pending_pool);
1157
	kmem_cache_destroy(pending_cache);
1158
	kmem_cache_destroy(exception_cache);
1159
}
1160
1161
/*
1162
 * Overrides for Emacs so that we follow Linus's tabbing style.
1163
 * Emacs will notice this stuff at the end of the file and automatically
1164
 * adjust the settings for this buffer only.  This must remain at the end
1165
 * of the file.
1166
 * ---------------------------------------------------------------------------
1167
 * Local variables:
1168
 * c-file-style: "linux"
1169
 * End:
1170
 */
(-)linux-2.4.20-gentoo-r5/drivers/md/dm-snapshot.h (+147 lines)
Line 0 Link Here
1
/*
2
 * dm-snapshot.c
3
 *
4
 * Copyright (C) 2001-2002 Sistina Software (UK) Limited.
5
 *
6
 * This file is released under the GPL.
7
 */
8
9
#ifndef DM_SNAPSHOT_H
10
#define DM_SNAPSHOT_H
11
12
#include "dm.h"
13
#include <linux/blkdev.h>
14
15
struct exception_table {
16
	uint32_t hash_mask;
17
	struct list_head *table;
18
};
19
20
/*
21
 * The snapshot code deals with largish chunks of the disk at a
22
 * time. Typically 64k - 256k.
23
 */
24
/* FIXME: can we get away with limiting these to a uint32_t ? */
25
typedef sector_t chunk_t;
26
27
/*
28
 * An exception is used where an old chunk of data has been
29
 * replaced by a new one.
30
 */
31
struct exception {
32
	struct list_head hash_list;
33
34
	chunk_t old_chunk;
35
	chunk_t new_chunk;
36
};
37
38
/*
39
 * Abstraction to handle the meta/layout of exception stores (the
40
 * COW device).
41
 */
42
struct exception_store {
43
44
	/*
45
	 * Destroys this object when you've finished with it.
46
	 */
47
	void (*destroy) (struct exception_store *store);
48
49
	/*
50
	 * Find somewhere to store the next exception.
51
	 */
52
	int (*prepare_exception) (struct exception_store *store,
53
				  struct exception *e);
54
55
	/*
56
	 * Update the metadata with this exception.
57
	 */
58
	void (*commit_exception) (struct exception_store *store,
59
				  struct exception *e,
60
				  void (*callback) (void *, int success),
61
				  void *callback_context);
62
63
	/*
64
	 * The snapshot is invalid, note this in the metadata.
65
	 */
66
	void (*drop_snapshot) (struct exception_store *store);
67
68
	/*
69
	 * Return the %age full of the snapshot
70
	 */
71
	int (*percent_full) (struct exception_store *store);
72
73
	struct dm_snapshot *snap;
74
	void *context;
75
};
76
77
struct dm_snapshot {
78
	struct rw_semaphore lock;
79
	struct dm_table *table;
80
81
	struct dm_dev *origin;
82
	struct dm_dev *cow;
83
84
	/* List of snapshots per Origin */
85
	struct list_head list;
86
87
	/* Size of data blocks saved - must be a power of 2 */
88
	chunk_t chunk_size;
89
	chunk_t chunk_mask;
90
	chunk_t chunk_shift;
91
92
	/* You can't use a snapshot if this is 0 (e.g. if full) */
93
	int valid;
94
95
	/* Used for display of table */
96
	char type;
97
98
	/* The last percentage we notified */
99
	int last_percent;
100
101
	struct exception_table pending;
102
	struct exception_table complete;
103
104
	/* The on disk metadata handler */
105
	struct exception_store store;
106
};
107
108
/*
109
 * Used by the exception stores to load exceptions hen
110
 * initialising.
111
 */
112
int dm_add_exception(struct dm_snapshot *s, chunk_t old, chunk_t new);
113
114
/*
115
 * Constructor and destructor for the default persistent
116
 * store.
117
 */
118
int dm_create_persistent(struct exception_store *store, uint32_t chunk_size);
119
120
int dm_create_transient(struct exception_store *store,
121
			struct dm_snapshot *s, int blocksize);
122
123
/*
124
 * Return the number of sectors in the device.
125
 */
126
static inline sector_t get_dev_size(kdev_t dev)
127
{
128
	int *sizes;
129
130
	sizes = blk_size[MAJOR(dev)];
131
	if (sizes)
132
		return sizes[MINOR(dev)] << 1;
133
134
	return 0;
135
}
136
137
static inline chunk_t sector_to_chunk(struct dm_snapshot *s, sector_t sector)
138
{
139
	return (sector & ~s->chunk_mask) >> s->chunk_shift;
140
}
141
142
static inline sector_t chunk_to_sector(struct dm_snapshot *s, chunk_t chunk)
143
{
144
	return chunk << s->chunk_shift;
145
}
146
147
#endif
(-)linux-2.4.20-gentoo-r5/drivers/md/dm-stripe.c (+257 lines)
Line 0 Link Here
1
/*
2
 * Copyright (C) 2001 Sistina Software (UK) Limited.
3
 *
4
 * This file is released under the GPL.
5
 */
6
7
#include "dm.h"
8
9
#include <linux/module.h>
10
#include <linux/init.h>
11
#include <linux/blkdev.h>
12
#include <linux/slab.h>
13
14
struct stripe {
15
	struct dm_dev *dev;
16
	sector_t physical_start;
17
};
18
19
struct stripe_c {
20
	uint32_t stripes;
21
22
	/* The size of this target / num. stripes */
23
	uint32_t stripe_width;
24
25
	/* stripe chunk size */
26
	uint32_t chunk_shift;
27
	sector_t chunk_mask;
28
29
	struct stripe stripe[0];
30
};
31
32
static inline struct stripe_c *alloc_context(int stripes)
33
{
34
	size_t len;
35
36
	if (array_too_big(sizeof(struct stripe_c), sizeof(struct stripe),
37
			  stripes))
38
		return NULL;
39
40
	len = sizeof(struct stripe_c) + (sizeof(struct stripe) * stripes);
41
42
	return kmalloc(len, GFP_KERNEL);
43
}
44
45
/*
46
 * Parse a single <dev> <sector> pair
47
 */
48
static int get_stripe(struct dm_target *ti, struct stripe_c *sc,
49
		      int stripe, char **argv)
50
{
51
	sector_t start;
52
53
	if (sscanf(argv[1], SECTOR_FORMAT, &start) != 1)
54
		return -EINVAL;
55
56
	if (dm_get_device(ti, argv[0], start, sc->stripe_width,
57
			  dm_table_get_mode(ti->table),
58
			  &sc->stripe[stripe].dev))
59
		return -ENXIO;
60
61
	sc->stripe[stripe].physical_start = start;
62
	return 0;
63
}
64
65
/*
66
 * FIXME: Nasty function, only present because we can't link
67
 * against __moddi3 and __divdi3.
68
 *
69
 * returns a == b * n
70
 */
71
static int multiple(sector_t a, sector_t b, sector_t *n)
72
{
73
	sector_t acc, prev, i;
74
75
	*n = 0;
76
	while (a >= b) {
77
		for (acc = b, prev = 0, i = 1;
78
		     acc <= a;
79
		     prev = acc, acc <<= 1, i <<= 1)
80
			;
81
82
		a -= prev;
83
		*n += i >> 1;
84
	}
85
86
	return a == 0;
87
}
88
89
/*
90
 * Construct a striped mapping.
91
 * <number of stripes> <chunk size (2^^n)> [<dev_path> <offset>]+
92
 */
93
static int stripe_ctr(struct dm_target *ti, int argc, char **argv)
94
{
95
	struct stripe_c *sc;
96
	sector_t width;
97
	uint32_t stripes;
98
	uint32_t chunk_size;
99
	char *end;
100
	int r, i;
101
102
	if (argc < 2) {
103
		ti->error = "dm-stripe: Not enough arguments";
104
		return -EINVAL;
105
	}
106
107
	stripes = simple_strtoul(argv[0], &end, 10);
108
	if (*end) {
109
		ti->error = "dm-stripe: Invalid stripe count";
110
		return -EINVAL;
111
	}
112
113
	chunk_size = simple_strtoul(argv[1], &end, 10);
114
	if (*end) {
115
		ti->error = "dm-stripe: Invalid chunk_size";
116
		return -EINVAL;
117
	}
118
119
	/*
120
	 * chunk_size is a power of two
121
	 */
122
	if (!chunk_size || (chunk_size & (chunk_size - 1))) {
123
		ti->error = "dm-stripe: Invalid chunk size";
124
		return -EINVAL;
125
	}
126
127
	if (!multiple(ti->len, stripes, &width)) {
128
		ti->error = "dm-stripe: Target length not divisable by "
129
		    "number of stripes";
130
		return -EINVAL;
131
	}
132
133
	/*
134
	 * Do we have enough arguments for that many stripes ?
135
	 */
136
	if (argc != (2 + 2 * stripes)) {
137
		ti->error = "dm-stripe: Not enough destinations specified";
138
		return -EINVAL;
139
	}
140
141
	sc = alloc_context(stripes);
142
	if (!sc) {
143
		ti->error = "dm-stripe: Memory allocation for striped context "
144
		    "failed";
145
		return -ENOMEM;
146
	}
147
148
	sc->stripes = stripes;
149
	sc->stripe_width = width;
150
151
	sc->chunk_mask = ((sector_t) chunk_size) - 1;
152
	for (sc->chunk_shift = 0; chunk_size; sc->chunk_shift++)
153
		chunk_size >>= 1;
154
	sc->chunk_shift--;
155
156
	/*
157
	 * Get the stripe destinations.
158
	 */
159
	for (i = 0; i < stripes; i++) {
160
		argv += 2;
161
162
		r = get_stripe(ti, sc, i, argv);
163
		if (r < 0) {
164
			ti->error = "dm-stripe: Couldn't parse stripe "
165
			    "destination";
166
			while (i--)
167
				dm_put_device(ti, sc->stripe[i].dev);
168
			kfree(sc);
169
			return r;
170
		}
171
	}
172
173
	ti->private = sc;
174
	return 0;
175
}
176
177
static void stripe_dtr(struct dm_target *ti)
178
{
179
	unsigned int i;
180
	struct stripe_c *sc = (struct stripe_c *) ti->private;
181
182
	for (i = 0; i < sc->stripes; i++)
183
		dm_put_device(ti, sc->stripe[i].dev);
184
185
	kfree(sc);
186
}
187
188
static int stripe_map(struct dm_target *ti, struct buffer_head *bh, int rw,
189
		      void **context)
190
{
191
	struct stripe_c *sc = (struct stripe_c *) ti->private;
192
193
	sector_t offset = bh->b_rsector - ti->begin;
194
	uint32_t chunk = (uint32_t) (offset >> sc->chunk_shift);
195
	uint32_t stripe = chunk % sc->stripes;	/* 32bit modulus */
196
	chunk = chunk / sc->stripes;
197
198
	bh->b_rdev = sc->stripe[stripe].dev->dev;
199
	bh->b_rsector = sc->stripe[stripe].physical_start +
200
	    (chunk << sc->chunk_shift) + (offset & sc->chunk_mask);
201
	return 1;
202
}
203
204
static int stripe_status(struct dm_target *ti,
205
			 status_type_t type, char *result, int maxlen)
206
{
207
	struct stripe_c *sc = (struct stripe_c *) ti->private;
208
	int offset;
209
	int i;
210
211
	switch (type) {
212
	case STATUSTYPE_INFO:
213
		result[0] = '\0';
214
		break;
215
216
	case STATUSTYPE_TABLE:
217
		offset = snprintf(result, maxlen, "%d " SECTOR_FORMAT,
218
				  sc->stripes, sc->chunk_mask + 1);
219
		for (i = 0; i < sc->stripes; i++) {
220
			offset +=
221
			    snprintf(result + offset, maxlen - offset,
222
				     " %s " SECTOR_FORMAT,
223
		       kdevname(to_kdev_t(sc->stripe[i].dev->bdev->bd_dev)),
224
				     sc->stripe[i].physical_start);
225
		}
226
		break;
227
	}
228
	return 0;
229
}
230
231
static struct target_type stripe_target = {
232
	.name   = "striped",
233
	.module = THIS_MODULE,
234
	.ctr    = stripe_ctr,
235
	.dtr    = stripe_dtr,
236
	.map    = stripe_map,
237
	.status = stripe_status,
238
};
239
240
int __init dm_stripe_init(void)
241
{
242
	int r;
243
244
	r = dm_register_target(&stripe_target);
245
	if (r < 0)
246
		DMWARN("striped target registration failed");
247
248
	return r;
249
}
250
251
void dm_stripe_exit(void)
252
{
253
	if (dm_unregister_target(&stripe_target))
254
		DMWARN("striped target unregistration failed");
255
256
	return;
257
}
(-)linux-2.4.20-gentoo-r5/drivers/md/dm-table.c (+666 lines)
Line 0 Link Here
1
/*
2
 * Copyright (C) 2001 Sistina Software (UK) Limited.
3
 *
4
 * This file is released under the GPL.
5
 */
6
7
#include "dm.h"
8
9
#include <linux/module.h>
10
#include <linux/vmalloc.h>
11
#include <linux/blkdev.h>
12
#include <linux/ctype.h>
13
#include <linux/slab.h>
14
#include <asm/atomic.h>
15
16
#define MAX_DEPTH 16
17
#define NODE_SIZE L1_CACHE_BYTES
18
#define KEYS_PER_NODE (NODE_SIZE / sizeof(sector_t))
19
#define CHILDREN_PER_NODE (KEYS_PER_NODE + 1)
20
21
struct dm_table {
22
	atomic_t holders;
23
24
	/* btree table */
25
	int depth;
26
	int counts[MAX_DEPTH];	/* in nodes */
27
	sector_t *index[MAX_DEPTH];
28
29
	int num_targets;
30
	int num_allocated;
31
	sector_t *highs;
32
	struct dm_target *targets;
33
34
	/*
35
	 * Indicates the rw permissions for the new logical
36
	 * device.  This should be a combination of FMODE_READ
37
	 * and FMODE_WRITE.
38
	 */
39
	int mode;
40
41
	/* a list of devices used by this table */
42
	struct list_head devices;
43
44
	/*
45
	 * A waitqueue for processes waiting for something
46
	 * interesting to happen to this table.
47
	 */
48
	wait_queue_head_t eventq;
49
};
50
51
/*
52
 * Ceiling(n / size)
53
 */
54
static inline unsigned long div_up(unsigned long n, unsigned long size)
55
{
56
	return dm_round_up(n, size) / size;
57
}
58
59
/*
60
 * Similar to ceiling(log_size(n))
61
 */
62
static unsigned int int_log(unsigned long n, unsigned long base)
63
{
64
	int result = 0;
65
66
	while (n > 1) {
67
		n = div_up(n, base);
68
		result++;
69
	}
70
71
	return result;
72
}
73
74
/*
75
 * Calculate the index of the child node of the n'th node k'th key.
76
 */
77
static inline int get_child(int n, int k)
78
{
79
	return (n * CHILDREN_PER_NODE) + k;
80
}
81
82
/*
83
 * Return the n'th node of level l from table t.
84
 */
85
static inline sector_t *get_node(struct dm_table *t, int l, int n)
86
{
87
	return t->index[l] + (n * KEYS_PER_NODE);
88
}
89
90
/*
91
 * Return the highest key that you could lookup from the n'th
92
 * node on level l of the btree.
93
 */
94
static sector_t high(struct dm_table *t, int l, int n)
95
{
96
	for (; l < t->depth - 1; l++)
97
		n = get_child(n, CHILDREN_PER_NODE - 1);
98
99
	if (n >= t->counts[l])
100
		return (sector_t) - 1;
101
102
	return get_node(t, l, n)[KEYS_PER_NODE - 1];
103
}
104
105
/*
106
 * Fills in a level of the btree based on the highs of the level
107
 * below it.
108
 */
109
static int setup_btree_index(int l, struct dm_table *t)
110
{
111
	int n, k;
112
	sector_t *node;
113
114
	for (n = 0; n < t->counts[l]; n++) {
115
		node = get_node(t, l, n);
116
117
		for (k = 0; k < KEYS_PER_NODE; k++)
118
			node[k] = high(t, l + 1, get_child(n, k));
119
	}
120
121
	return 0;
122
}
123
124
/*
125
 * highs, and targets are managed as dynamic arrays during a
126
 * table load.
127
 */
128
static int alloc_targets(struct dm_table *t, int num)
129
{
130
	sector_t *n_highs;
131
	struct dm_target *n_targets;
132
	int n = t->num_targets;
133
134
	/*
135
	 * Allocate both the target array and offset array at once.
136
	 */
137
	n_highs = (sector_t *) vcalloc(sizeof(struct dm_target) +
138
				       sizeof(sector_t), num);
139
	if (!n_highs)
140
		return -ENOMEM;
141
142
	n_targets = (struct dm_target *) (n_highs + num);
143
144
	if (n) {
145
		memcpy(n_highs, t->highs, sizeof(*n_highs) * n);
146
		memcpy(n_targets, t->targets, sizeof(*n_targets) * n);
147
	}
148
149
	memset(n_highs + n, -1, sizeof(*n_highs) * (num - n));
150
	vfree(t->highs);
151
152
	t->num_allocated = num;
153
	t->highs = n_highs;
154
	t->targets = n_targets;
155
156
	return 0;
157
}
158
159
int dm_table_create(struct dm_table **result, int mode)
160
{
161
	struct dm_table *t = kmalloc(sizeof(*t), GFP_NOIO);
162
163
	if (!t)
164
		return -ENOMEM;
165
166
	memset(t, 0, sizeof(*t));
167
	INIT_LIST_HEAD(&t->devices);
168
	atomic_set(&t->holders, 1);
169
170
	/* allocate a single nodes worth of targets to begin with */
171
	if (alloc_targets(t, KEYS_PER_NODE)) {
172
		kfree(t);
173
		t = NULL;
174
		return -ENOMEM;
175
	}
176
177
	init_waitqueue_head(&t->eventq);
178
	t->mode = mode;
179
	*result = t;
180
	return 0;
181
}
182
183
static void free_devices(struct list_head *devices)
184
{
185
	struct list_head *tmp, *next;
186
187
	for (tmp = devices->next; tmp != devices; tmp = next) {
188
		struct dm_dev *dd = list_entry(tmp, struct dm_dev, list);
189
		next = tmp->next;
190
		kfree(dd);
191
	}
192
}
193
194
void table_destroy(struct dm_table *t)
195
{
196
	int i;
197
198
	/* destroying the table counts as an event */
199
	dm_table_event(t);
200
201
	/* free the indexes (see dm_table_complete) */
202
	if (t->depth >= 2)
203
		vfree(t->index[t->depth - 2]);
204
205
	/* free the targets */
206
	for (i = 0; i < t->num_targets; i++) {
207
		struct dm_target *tgt = t->targets + i;
208
209
		if (tgt->type->dtr)
210
			tgt->type->dtr(tgt);
211
212
		dm_put_target_type(tgt->type);
213
	}
214
215
	vfree(t->highs);
216
217
	/* free the device list */
218
	if (t->devices.next != &t->devices) {
219
		DMWARN("devices still present during destroy: "
220
		       "dm_table_remove_device calls missing");
221
222
		free_devices(&t->devices);
223
	}
224
225
	kfree(t);
226
}
227
228
void dm_table_get(struct dm_table *t)
229
{
230
	atomic_inc(&t->holders);
231
}
232
233
void dm_table_put(struct dm_table *t)
234
{
235
	if (atomic_dec_and_test(&t->holders))
236
		table_destroy(t);
237
}
238
239
/*
240
 * Checks to see if we need to extend highs or targets.
241
 */
242
static inline int check_space(struct dm_table *t)
243
{
244
	if (t->num_targets >= t->num_allocated)
245
		return alloc_targets(t, t->num_allocated * 2);
246
247
	return 0;
248
}
249
250
/*
251
 * Convert a device path to a dev_t.
252
 */
253
static int lookup_device(const char *path, kdev_t *dev)
254
{
255
	int r;
256
	struct nameidata nd;
257
	struct inode *inode;
258
259
	if (!path_init(path, LOOKUP_FOLLOW, &nd))
260
		return 0;
261
262
	if ((r = path_walk(path, &nd)))
263
		goto out;
264
265
	inode = nd.dentry->d_inode;
266
	if (!inode) {
267
		r = -ENOENT;
268
		goto out;
269
	}
270
271
	if (!S_ISBLK(inode->i_mode)) {
272
		r = -ENOTBLK;
273
		goto out;
274
	}
275
276
	*dev = inode->i_rdev;
277
278
      out:
279
	path_release(&nd);
280
	return r;
281
}
282
283
/*
284
 * See if we've already got a device in the list.
285
 */
286
static struct dm_dev *find_device(struct list_head *l, kdev_t dev)
287
{
288
	struct list_head *tmp;
289
290
	list_for_each(tmp, l) {
291
		struct dm_dev *dd = list_entry(tmp, struct dm_dev, list);
292
		if (kdev_same(dd->dev, dev))
293
			return dd;
294
	}
295
296
	return NULL;
297
}
298
299
/*
300
 * Open a device so we can use it as a map destination.
301
 */
302
static int open_dev(struct dm_dev *dd)
303
{
304
	if (dd->bdev)
305
		BUG();
306
307
	dd->bdev = bdget(kdev_t_to_nr(dd->dev));
308
	if (!dd->bdev)
309
		return -ENOMEM;
310
311
	return blkdev_get(dd->bdev, dd->mode, 0, BDEV_RAW);
312
}
313
314
/*
315
 * Close a device that we've been using.
316
 */
317
static void close_dev(struct dm_dev *dd)
318
{
319
	if (!dd->bdev)
320
		return;
321
322
	blkdev_put(dd->bdev, BDEV_RAW);
323
	dd->bdev = NULL;
324
}
325
326
/*
327
 * If possible (ie. blk_size[major] is set), this checks an area
328
 * of a destination device is valid.
329
 */
330
static int check_device_area(kdev_t dev, sector_t start, sector_t len)
331
{
332
	int *sizes;
333
	sector_t dev_size;
334
335
	if (!(sizes = blk_size[major(dev)]) || !(dev_size = sizes[minor(dev)]))
336
		/* we don't know the device details,
337
		 * so give the benefit of the doubt */
338
		return 1;
339
340
	/* convert to 512-byte sectors */
341
	dev_size <<= 1;
342
343
	return ((start < dev_size) && (len <= (dev_size - start)));
344
}
345
346
/*
347
 * This upgrades the mode on an already open dm_dev.  Being
348
 * careful to leave things as they were if we fail to reopen the
349
 * device.
350
 */
351
static int upgrade_mode(struct dm_dev *dd, int new_mode)
352
{
353
	int r;
354
	struct dm_dev dd_copy;
355
356
	memcpy(&dd_copy, dd, sizeof(dd_copy));
357
358
	dd->mode |= new_mode;
359
	dd->bdev = NULL;
360
	r = open_dev(dd);
361
	if (!r)
362
		close_dev(&dd_copy);
363
	else
364
		memcpy(dd, &dd_copy, sizeof(dd_copy));
365
366
	return r;
367
}
368
369
/*
370
 * Add a device to the list, or just increment the usage count if
371
 * it's already present.
372
 */
373
int dm_get_device(struct dm_target *ti, const char *path, sector_t start,
374
		  sector_t len, int mode, struct dm_dev **result)
375
{
376
	int r;
377
	kdev_t dev;
378
	struct dm_dev *dd;
379
	int major, minor;
380
	struct dm_table *t = ti->table;
381
382
	if (!t)
383
		BUG();
384
385
	if (sscanf(path, "%x:%x", &major, &minor) == 2) {
386
		/* Extract the major/minor numbers */
387
		dev = mk_kdev(major, minor);
388
	} else {
389
		/* convert the path to a device */
390
		if ((r = lookup_device(path, &dev)))
391
			return r;
392
	}
393
394
	dd = find_device(&t->devices, dev);
395
	if (!dd) {
396
		dd = kmalloc(sizeof(*dd), GFP_KERNEL);
397
		if (!dd)
398
			return -ENOMEM;
399
400
		dd->dev = dev;
401
		dd->mode = mode;
402
		dd->bdev = NULL;
403
404
		if ((r = open_dev(dd))) {
405
			kfree(dd);
406
			return r;
407
		}
408
409
		atomic_set(&dd->count, 0);
410
		list_add(&dd->list, &t->devices);
411
412
	} else if (dd->mode != (mode | dd->mode)) {
413
		r = upgrade_mode(dd, mode);
414
		if (r)
415
			return r;
416
	}
417
	atomic_inc(&dd->count);
418
419
	if (!check_device_area(dd->dev, start, len)) {
420
		DMWARN("device %s too small for target", path);
421
		dm_put_device(ti, dd);
422
		return -EINVAL;
423
	}
424
425
	*result = dd;
426
427
	return 0;
428
}
429
430
/*
431
 * Decrement a devices use count and remove it if neccessary.
432
 */
433
void dm_put_device(struct dm_target *ti, struct dm_dev *dd)
434
{
435
	if (atomic_dec_and_test(&dd->count)) {
436
		close_dev(dd);
437
		list_del(&dd->list);
438
		kfree(dd);
439
	}
440
}
441
442
/*
443
 * Checks to see if the target joins onto the end of the table.
444
 */
445
static int adjoin(struct dm_table *table, struct dm_target *ti)
446
{
447
	struct dm_target *prev;
448
449
	if (!table->num_targets)
450
		return !ti->begin;
451
452
	prev = &table->targets[table->num_targets - 1];
453
	return (ti->begin == (prev->begin + prev->len));
454
}
455
456
/*
457
 * Destructively splits up the argument list to pass to ctr.
458
 */
459
static int split_args(int max, int *argc, char **argv, char *input)
460
{
461
	char *start, *end = input, *out;
462
	*argc = 0;
463
464
	while (1) {
465
		start = end;
466
467
		/* Skip whitespace */
468
		while (*start && isspace(*start))
469
			start++;
470
471
		if (!*start)
472
			break;	/* success, we hit the end */
473
474
		/* 'out' is used to remove any back-quotes */
475
		end = out = start;
476
		while (*end) {
477
			/* Everything apart from '\0' can be quoted */
478
			if (*end == '\\' && *(end + 1)) {
479
				*out++ = *(end + 1);
480
				end += 2;
481
				continue;
482
			}
483
484
			if (isspace(*end))
485
				break;	/* end of token */
486
487
			*out++ = *end++;
488
		}
489
490
		/* have we already filled the array ? */
491
		if ((*argc + 1) > max)
492
			return -EINVAL;
493
494
		/* we know this is whitespace */
495
		if (*end)
496
			end++;
497
498
		/* terminate the string and put it in the array */
499
		*out = '\0';
500
		argv[*argc] = start;
501
		(*argc)++;
502
	}
503
504
	return 0;
505
}
506
507
int dm_table_add_target(struct dm_table *t, const char *type,
508
			sector_t start, sector_t len, char *params)
509
{
510
	int r = -EINVAL, argc;
511
	char *argv[32];
512
	struct dm_target *tgt;
513
514
	if ((r = check_space(t)))
515
		return r;
516
517
	tgt = t->targets + t->num_targets;
518
	memset(tgt, 0, sizeof(*tgt));
519
520
	tgt->type = dm_get_target_type(type);
521
	if (!tgt->type) {
522
		tgt->error = "unknown target type";
523
		return -EINVAL;
524
	}
525
526
	tgt->table = t;
527
	tgt->begin = start;
528
	tgt->len = len;
529
	tgt->error = "Unknown error";
530
531
	/*
532
	 * Does this target adjoin the previous one ?
533
	 */
534
	if (!adjoin(t, tgt)) {
535
		tgt->error = "Gap in table";
536
		r = -EINVAL;
537
		goto bad;
538
	}
539
540
	r = split_args(ARRAY_SIZE(argv), &argc, argv, params);
541
	if (r) {
542
		tgt->error = "couldn't split parameters";
543
		goto bad;
544
	}
545
546
	r = tgt->type->ctr(tgt, argc, argv);
547
	if (r)
548
		goto bad;
549
550
	t->highs[t->num_targets++] = tgt->begin + tgt->len - 1;
551
	return 0;
552
553
      bad:
554
	printk(KERN_ERR DM_NAME ": %s\n", tgt->error);
555
	dm_put_target_type(tgt->type);
556
	return r;
557
}
558
559
static int setup_indexes(struct dm_table *t)
560
{
561
	int i, total = 0;
562
	sector_t *indexes;
563
564
	/* allocate the space for *all* the indexes */
565
	for (i = t->depth - 2; i >= 0; i--) {
566
		t->counts[i] = div_up(t->counts[i + 1], CHILDREN_PER_NODE);
567
		total += t->counts[i];
568
	}
569
570
	indexes = (sector_t *) vcalloc(total, (unsigned long) NODE_SIZE);
571
	if (!indexes)
572
		return -ENOMEM;
573
574
	/* set up internal nodes, bottom-up */
575
	for (i = t->depth - 2, total = 0; i >= 0; i--) {
576
		t->index[i] = indexes;
577
		indexes += (KEYS_PER_NODE * t->counts[i]);
578
		setup_btree_index(i, t);
579
	}
580
581
	return 0;
582
}
583
584
/*
585
 * Builds the btree to index the map.
586
 */
587
int dm_table_complete(struct dm_table *t)
588
{
589
	int leaf_nodes, r = 0;
590
591
	/* how many indexes will the btree have ? */
592
	leaf_nodes = div_up(t->num_targets, KEYS_PER_NODE);
593
	t->depth = 1 + int_log(leaf_nodes, CHILDREN_PER_NODE);
594
595
	/* leaf layer has already been set up */
596
	t->counts[t->depth - 1] = leaf_nodes;
597
	t->index[t->depth - 1] = t->highs;
598
599
	if (t->depth >= 2)
600
		r = setup_indexes(t);
601
602
	return r;
603
}
604
605
void dm_table_event(struct dm_table *t)
606
{
607
	wake_up_interruptible(&t->eventq);
608
}
609
610
sector_t dm_table_get_size(struct dm_table *t)
611
{
612
	return t->num_targets ? (t->highs[t->num_targets - 1] + 1) : 0;
613
}
614
615
struct dm_target *dm_table_get_target(struct dm_table *t, int index)
616
{
617
	if (index > t->num_targets)
618
		return NULL;
619
620
	return t->targets + index;
621
}
622
623
/*
624
 * Search the btree for the correct target.
625
 */
626
struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector)
627
{
628
	int l, n = 0, k = 0;
629
	sector_t *node;
630
631
	for (l = 0; l < t->depth; l++) {
632
		n = get_child(n, k);
633
		node = get_node(t, l, n);
634
635
		for (k = 0; k < KEYS_PER_NODE; k++)
636
			if (node[k] >= sector)
637
				break;
638
	}
639
640
	return &t->targets[(KEYS_PER_NODE * n) + k];
641
}
642
643
unsigned int dm_table_get_num_targets(struct dm_table *t)
644
{
645
	return t->num_targets;
646
}
647
648
struct list_head *dm_table_get_devices(struct dm_table *t)
649
{
650
	return &t->devices;
651
}
652
653
int dm_table_get_mode(struct dm_table *t)
654
{
655
	return t->mode;
656
}
657
658
void dm_table_add_wait_queue(struct dm_table *t, wait_queue_t *wq)
659
{
660
	add_wait_queue(&t->eventq, wq);
661
}
662
663
EXPORT_SYMBOL(dm_get_device);
664
EXPORT_SYMBOL(dm_put_device);
665
EXPORT_SYMBOL(dm_table_event);
666
EXPORT_SYMBOL(dm_table_get_mode);
(-)linux-2.4.20-gentoo-r5/drivers/md/dm-target.c (+187 lines)
Line 0 Link Here
1
/*
2
 * Copyright (C) 2001 Sistina Software (UK) Limited
3
 *
4
 * This file is released under the GPL.
5
 */
6
7
#include "dm.h"
8
9
#include <linux/module.h>
10
#include <linux/kmod.h>
11
#include <linux/slab.h>
12
13
struct tt_internal {
14
	struct target_type tt;
15
16
	struct list_head list;
17
	long use;
18
};
19
20
static LIST_HEAD(_targets);
21
static DECLARE_RWSEM(_lock);
22
23
#define DM_MOD_NAME_SIZE 32
24
25
static inline struct tt_internal *__find_target_type(const char *name)
26
{
27
	struct list_head *tih;
28
	struct tt_internal *ti;
29
30
	list_for_each(tih, &_targets) {
31
		ti = list_entry(tih, struct tt_internal, list);
32
33
		if (!strcmp(name, ti->tt.name))
34
			return ti;
35
	}
36
37
	return NULL;
38
}
39
40
static struct tt_internal *get_target_type(const char *name)
41
{
42
	struct tt_internal *ti;
43
44
	down_read(&_lock);
45
	ti = __find_target_type(name);
46
47
	if (ti) {
48
		if (ti->use == 0 && ti->tt.module)
49
			__MOD_INC_USE_COUNT(ti->tt.module);
50
		ti->use++;
51
	}
52
	up_read(&_lock);
53
54
	return ti;
55
}
56
57
static void load_module(const char *name)
58
{
59
	char module_name[DM_MOD_NAME_SIZE] = "dm-";
60
61
	/* Length check for strcat() below */
62
	if (strlen(name) > (DM_MOD_NAME_SIZE - 4))
63
		return;
64
65
	strcat(module_name, name);
66
	request_module(module_name);
67
}
68
69
struct target_type *dm_get_target_type(const char *name)
70
{
71
	struct tt_internal *ti = get_target_type(name);
72
73
	if (!ti) {
74
		load_module(name);
75
		ti = get_target_type(name);
76
	}
77
78
	return ti ? &ti->tt : NULL;
79
}
80
81
void dm_put_target_type(struct target_type *t)
82
{
83
	struct tt_internal *ti = (struct tt_internal *) t;
84
85
	down_read(&_lock);
86
	if (--ti->use == 0 && ti->tt.module)
87
		__MOD_DEC_USE_COUNT(ti->tt.module);
88
89
	if (ti->use < 0)
90
		BUG();
91
	up_read(&_lock);
92
93
	return;
94
}
95
96
static struct tt_internal *alloc_target(struct target_type *t)
97
{
98
	struct tt_internal *ti = kmalloc(sizeof(*ti), GFP_KERNEL);
99
100
	if (ti) {
101
		memset(ti, 0, sizeof(*ti));
102
		ti->tt = *t;
103
	}
104
105
	return ti;
106
}
107
108
int dm_register_target(struct target_type *t)
109
{
110
	int rv = 0;
111
	struct tt_internal *ti = alloc_target(t);
112
113
	if (!ti)
114
		return -ENOMEM;
115
116
	down_write(&_lock);
117
	if (__find_target_type(t->name))
118
		rv = -EEXIST;
119
	else
120
		list_add(&ti->list, &_targets);
121
122
	up_write(&_lock);
123
	return rv;
124
}
125
126
int dm_unregister_target(struct target_type *t)
127
{
128
	struct tt_internal *ti;
129
130
	down_write(&_lock);
131
	if (!(ti = __find_target_type(t->name))) {
132
		up_write(&_lock);
133
		return -EINVAL;
134
	}
135
136
	if (ti->use) {
137
		up_write(&_lock);
138
		return -ETXTBSY;
139
	}
140
141
	list_del(&ti->list);
142
	kfree(ti);
143
144
	up_write(&_lock);
145
	return 0;
146
}
147
148
/*
149
 * io-err: always fails an io, useful for bringing
150
 * up LVs that have holes in them.
151
 */
152
static int io_err_ctr(struct dm_target *ti, int argc, char **args)
153
{
154
	return 0;
155
}
156
157
static void io_err_dtr(struct dm_target *ti)
158
{
159
	/* empty */
160
}
161
162
static int io_err_map(struct dm_target *ti, struct buffer_head *bh, int rw,
163
		      void **map_context)
164
{
165
	return -EIO;
166
}
167
168
static struct target_type error_target = {
169
	.name = "error",
170
	.ctr  = io_err_ctr,
171
	.dtr  = io_err_dtr,
172
	.map  = io_err_map,
173
};
174
175
int dm_target_init(void)
176
{
177
	return dm_register_target(&error_target);
178
}
179
180
void dm_target_exit(void)
181
{
182
	if (dm_unregister_target(&error_target))
183
		DMWARN("error target unregistration failed");
184
}
185
186
EXPORT_SYMBOL(dm_register_target);
187
EXPORT_SYMBOL(dm_unregister_target);
(-)linux-2.4.20-gentoo-r5/drivers/md/dm.c (+878 lines)
Line 0 Link Here
1
/*
2
 * Copyright (C) 2001, 2002 Sistina Software (UK) Limited.
3
 *
4
 * This file is released under the GPL.
5
 */
6
7
#include "dm.h"
8
9
#include <linux/init.h>
10
#include <linux/module.h>
11
#include <linux/blk.h>
12
#include <linux/blkpg.h>
13
#include <linux/mempool.h>
14
#include <linux/slab.h>
15
#include <linux/kdev_t.h>
16
#include <linux/lvm.h>
17
18
#include <asm/uaccess.h>
19
20
static const char *_name = DM_NAME;
21
#define MAX_DEVICES (1 << MINORBITS)
22
#define DEFAULT_READ_AHEAD 64
23
24
static int major = 0;
25
static int _major = 0;
26
27
struct dm_io {
28
	struct mapped_device *md;
29
30
	struct dm_target *ti;
31
	int rw;
32
	void *map_context;
33
	void (*end_io) (struct buffer_head * bh, int uptodate);
34
	void *context;
35
};
36
37
struct deferred_io {
38
	int rw;
39
	struct buffer_head *bh;
40
	struct deferred_io *next;
41
};
42
43
/*
44
 * Bits for the md->flags field.
45
 */
46
#define DMF_BLOCK_IO 0
47
#define DMF_SUSPENDED 1
48
49
struct mapped_device {
50
	struct rw_semaphore lock;
51
	atomic_t holders;
52
53
	kdev_t dev;
54
	unsigned long flags;
55
56
	/*
57
	 * A list of ios that arrived while we were suspended.
58
	 */
59
	atomic_t pending;
60
	wait_queue_head_t wait;
61
	struct deferred_io *deferred;
62
63
	/*
64
	 * The current mapping.
65
	 */
66
	struct dm_table *map;
67
68
	/*
69
	 * io objects are allocated from here.
70
	 */
71
	mempool_t *io_pool;
72
};
73
74
#define MIN_IOS 256
75
static kmem_cache_t *_io_cache;
76
77
/* block device arrays */
78
static int _block_size[MAX_DEVICES];
79
static int _blksize_size[MAX_DEVICES];
80
static int _hardsect_size[MAX_DEVICES];
81
82
static struct mapped_device *get_kdev(kdev_t dev);
83
static int dm_request(request_queue_t *q, int rw, struct buffer_head *bh);
84
static int dm_user_bmap(struct inode *inode, struct lv_bmap *lvb);
85
86
static __init int local_init(void)
87
{
88
	int r;
89
90
	/* allocate a slab for the dm_ios */
91
	_io_cache = kmem_cache_create("dm io",
92
				      sizeof(struct dm_io), 0, 0, NULL, NULL);
93
94
	if (!_io_cache)
95
		return -ENOMEM;
96
97
	_major = major;
98
	r = register_blkdev(_major, _name, &dm_blk_dops);
99
	if (r < 0) {
100
		DMERR("register_blkdev failed");
101
		kmem_cache_destroy(_io_cache);
102
		return r;
103
	}
104
105
	if (!_major)
106
		_major = r;
107
108
	/* set up the arrays */
109
	read_ahead[_major] = DEFAULT_READ_AHEAD;
110
	blk_size[_major] = _block_size;
111
	blksize_size[_major] = _blksize_size;
112
	hardsect_size[_major] = _hardsect_size;
113
114
	blk_queue_make_request(BLK_DEFAULT_QUEUE(_major), dm_request);
115
116
	return 0;
117
}
118
119
static void local_exit(void)
120
{
121
	kmem_cache_destroy(_io_cache);
122
123
	if (unregister_blkdev(_major, _name) < 0)
124
		DMERR("devfs_unregister_blkdev failed");
125
126
	read_ahead[_major] = 0;
127
	blk_size[_major] = NULL;
128
	blksize_size[_major] = NULL;
129
	hardsect_size[_major] = NULL;
130
	_major = 0;
131
132
	DMINFO("cleaned up");
133
}
134
135
/*
136
 * We have a lot of init/exit functions, so it seems easier to
137
 * store them in an array.  The disposable macro 'xx'
138
 * expands a prefix into a pair of function names.
139
 */
140
static struct {
141
	int (*init) (void);
142
	void (*exit) (void);
143
144
} _inits[] = {
145
#define xx(n) {n ## _init, n ## _exit},
146
	xx(local)
147
	xx(dm_target)
148
	xx(dm_linear)
149
	xx(dm_stripe)
150
	xx(dm_snapshot)
151
	xx(dm_interface)
152
#undef xx
153
};
154
155
static int __init dm_init(void)
156
{
157
	const int count = ARRAY_SIZE(_inits);
158
159
	int r, i;
160
161
	for (i = 0; i < count; i++) {
162
		r = _inits[i].init();
163
		if (r)
164
			goto bad;
165
	}
166
167
	return 0;
168
169
      bad:
170
	while (i--)
171
		_inits[i].exit();
172
173
	return r;
174
}
175
176
static void __exit dm_exit(void)
177
{
178
	int i = ARRAY_SIZE(_inits);
179
180
	while (i--)
181
		_inits[i].exit();
182
}
183
184
/*
185
 * Block device functions
186
 */
187
static int dm_blk_open(struct inode *inode, struct file *file)
188
{
189
	struct mapped_device *md;
190
191
	md = get_kdev(inode->i_rdev);
192
	if (!md)
193
		return -ENXIO;
194
195
	return 0;
196
}
197
198
static int dm_blk_close(struct inode *inode, struct file *file)
199
{
200
	struct mapped_device *md;
201
202
	md = get_kdev(inode->i_rdev);
203
	dm_put(md);		/* put the reference gained by dm_blk_open */
204
	dm_put(md);
205
	return 0;
206
}
207
208
static inline struct dm_io *alloc_io(struct mapped_device *md)
209
{
210
	return mempool_alloc(md->io_pool, GFP_NOIO);
211
}
212
213
static inline void free_io(struct mapped_device *md, struct dm_io *io)
214
{
215
	mempool_free(io, md->io_pool);
216
}
217
218
static inline struct deferred_io *alloc_deferred(void)
219
{
220
	return kmalloc(sizeof(struct deferred_io), GFP_NOIO);
221
}
222
223
static inline void free_deferred(struct deferred_io *di)
224
{
225
	kfree(di);
226
}
227
228
/* In 512-byte units */
229
#define VOLUME_SIZE(minor) (_block_size[(minor)] << 1)
230
231
/* FIXME: check this */
232
static int dm_blk_ioctl(struct inode *inode, struct file *file,
233
			uint command, unsigned long a)
234
{
235
	int minor = MINOR(inode->i_rdev);
236
	long size;
237
238
	if (minor >= MAX_DEVICES)
239
		return -ENXIO;
240
241
	switch (command) {
242
	case BLKROSET:
243
	case BLKROGET:
244
	case BLKRASET:
245
	case BLKRAGET:
246
	case BLKFLSBUF:
247
	case BLKSSZGET:
248
		//case BLKRRPART: /* Re-read partition tables */
249
		//case BLKPG:
250
	case BLKELVGET:
251
	case BLKELVSET:
252
	case BLKBSZGET:
253
	case BLKBSZSET:
254
		return blk_ioctl(inode->i_rdev, command, a);
255
		break;
256
257
	case BLKGETSIZE:
258
		size = VOLUME_SIZE(minor);
259
		if (copy_to_user((void *) a, &size, sizeof(long)))
260
			return -EFAULT;
261
		break;
262
263
	case BLKGETSIZE64:
264
		size = VOLUME_SIZE(minor);
265
		if (put_user((u64) ((u64) size) << 9, (u64 *) a))
266
			return -EFAULT;
267
		break;
268
269
	case BLKRRPART:
270
		return -ENOTTY;
271
272
	case LV_BMAP:
273
		return dm_user_bmap(inode, (struct lv_bmap *) a);
274
275
	default:
276
		DMWARN("unknown block ioctl 0x%x", command);
277
		return -ENOTTY;
278
	}
279
280
	return 0;
281
}
282
283
/*
284
 * Add the buffer to the list of deferred io.
285
 */
286
static int queue_io(struct mapped_device *md, struct buffer_head *bh, int rw)
287
{
288
	struct deferred_io *di;
289
290
	di = alloc_deferred();
291
	if (!di)
292
		return -ENOMEM;
293
294
	down_write(&md->lock);
295
296
	if (!test_bit(DMF_BLOCK_IO, &md->flags)) {
297
		up_write(&md->lock);
298
		free_deferred(di);
299
		return 1;
300
	}
301
302
	di->bh = bh;
303
	di->rw = rw;
304
	di->next = md->deferred;
305
	md->deferred = di;
306
307
	up_write(&md->lock);
308
	return 0;		/* deferred successfully */
309
}
310
311
/*
312
 * bh->b_end_io routine that decrements the pending count
313
 * and then calls the original bh->b_end_io fn.
314
 */
315
static void dec_pending(struct buffer_head *bh, int uptodate)
316
{
317
	int r;
318
	struct dm_io *io = bh->b_private;
319
	dm_endio_fn endio = io->ti->type->end_io;
320
321
	if (endio) {
322
		r = endio(io->ti, bh, io->rw, uptodate ? 0 : -EIO,
323
			  io->map_context);
324
		if (r < 0)
325
			uptodate = 0;
326
327
		else if (r > 0)
328
			/* the target wants another shot at the io */
329
			return;
330
	}
331
332
	if (atomic_dec_and_test(&io->md->pending))
333
		/* nudge anyone waiting on suspend queue */
334
		wake_up(&io->md->wait);
335
336
	bh->b_end_io = io->end_io;
337
	bh->b_private = io->context;
338
	free_io(io->md, io);
339
340
	bh->b_end_io(bh, uptodate);
341
}
342
343
/*
344
 * Do the bh mapping for a given leaf
345
 */
346
static inline int __map_buffer(struct mapped_device *md, int rw,
347
			       struct buffer_head *bh, struct dm_io *io)
348
{
349
	struct dm_target *ti;
350
351
	ti = dm_table_find_target(md->map, bh->b_rsector);
352
	if (!ti || !ti->type)
353
		return -EINVAL;
354
355
	/* hook the end io request fn */
356
	atomic_inc(&md->pending);
357
	io->md = md;
358
	io->ti = ti;
359
	io->rw = rw;
360
	io->end_io = bh->b_end_io;
361
	io->context = bh->b_private;
362
	bh->b_end_io = dec_pending;
363
	bh->b_private = io;
364
365
	return ti->type->map(ti, bh, rw, &io->map_context);
366
}
367
368
/*
369
 * Checks to see if we should be deferring io, if so it queues it
370
 * and returns 1.
371
 */
372
static inline int __deferring(struct mapped_device *md, int rw,
373
			      struct buffer_head *bh)
374
{
375
	int r;
376
377
	/*
378
	 * If we're suspended we have to queue this io for later.
379
	 */
380
	while (test_bit(DMF_BLOCK_IO, &md->flags)) {
381
		up_read(&md->lock);
382
383
		/*
384
		 * There's no point deferring a read ahead
385
		 * request, just drop it.
386
		 */
387
		if (rw == READA) {
388
			down_read(&md->lock);
389
			return -EIO;
390
		}
391
392
		r = queue_io(md, bh, rw);
393
		down_read(&md->lock);
394
395
		if (r < 0)
396
			return r;
397
398
		if (r == 0)
399
			return 1; /* deferred successfully */
400
401
	}
402
403
	return 0;
404
}
405
406
static int dm_request(request_queue_t *q, int rw, struct buffer_head *bh)
407
{
408
	int r;
409
	struct dm_io *io;
410
	struct mapped_device *md;
411
412
	md = get_kdev(bh->b_rdev);
413
	if (!md) {
414
		buffer_IO_error(bh);
415
		return 0;
416
	}
417
418
	io = alloc_io(md);
419
	down_read(&md->lock);
420
421
	r = __deferring(md, rw, bh);
422
	if (r < 0)
423
		goto bad;
424
425
	else if (!r) {
426
		/* not deferring */
427
		r = __map_buffer(md, rw, bh, io);
428
		if (r < 0)
429
			goto bad;
430
	} else
431
		r = 0;
432
433
	up_read(&md->lock);
434
	dm_put(md);
435
	return r;
436
437
      bad:
438
	buffer_IO_error(bh);
439
	up_read(&md->lock);
440
	dm_put(md);
441
	return 0;
442
}
443
444
static int check_dev_size(kdev_t dev, unsigned long block)
445
{
446
	/* FIXME: check this */
447
	int minor = MINOR(dev);
448
	unsigned long max_sector = (_block_size[minor] << 1) + 1;
449
	unsigned long sector = (block + 1) * (_blksize_size[minor] >> 9);
450
451
	return (sector > max_sector) ? 0 : 1;
452
}
453
454
/*
455
 * Creates a dummy buffer head and maps it (for lilo).
456
 */
457
static int __bmap(struct mapped_device *md, kdev_t dev, unsigned long block,
458
		  kdev_t *r_dev, unsigned long *r_block)
459
{
460
	struct buffer_head bh;
461
	struct dm_target *ti;
462
	void *map_context;
463
	int r;
464
465
	if (test_bit(DMF_BLOCK_IO, &md->flags)) {
466
		return -EPERM;
467
	}
468
469
	if (!check_dev_size(dev, block)) {
470
		return -EINVAL;
471
	}
472
473
	/* setup dummy bh */
474
	memset(&bh, 0, sizeof(bh));
475
	bh.b_blocknr = block;
476
	bh.b_dev = bh.b_rdev = dev;
477
	bh.b_size = _blksize_size[MINOR(dev)];
478
	bh.b_rsector = block * (bh.b_size >> 9);
479
480
	/* find target */
481
	ti = dm_table_find_target(md->map, bh.b_rsector);
482
483
	/* do the mapping */
484
	r = ti->type->map(ti, &bh, READ, &map_context);
485
	ti->type->end_io(ti, &bh, READ, 0, map_context);
486
487
	if (!r) {
488
		*r_dev = bh.b_rdev;
489
		*r_block = bh.b_rsector / (bh.b_size >> 9);
490
	}
491
492
	return r;
493
}
494
495
/*
496
 * Marshals arguments and results between user and kernel space.
497
 */
498
static int dm_user_bmap(struct inode *inode, struct lv_bmap *lvb)
499
{
500
	struct mapped_device *md;
501
	unsigned long block, r_block;
502
	kdev_t r_dev;
503
	int r;
504
505
	if (get_user(block, &lvb->lv_block))
506
		return -EFAULT;
507
508
	md = get_kdev(inode->i_rdev);
509
	if (!md)
510
		return -ENXIO;
511
512
	down_read(&md->lock);
513
	r = __bmap(md, inode->i_rdev, block, &r_dev, &r_block);
514
	up_read(&md->lock);
515
	dm_put(md);
516
517
	if (!r && (put_user(kdev_t_to_nr(r_dev), &lvb->lv_dev) ||
518
		   put_user(r_block, &lvb->lv_block)))
519
		r = -EFAULT;
520
521
	return r;
522
}
523
524
/*-----------------------------------------------------------------
525
 * A bitset is used to keep track of allocated minor numbers.
526
 *---------------------------------------------------------------*/
527
static spinlock_t _minor_lock = SPIN_LOCK_UNLOCKED;
528
static struct mapped_device *_mds[MAX_DEVICES];
529
530
static void free_minor(int minor)
531
{
532
	spin_lock(&_minor_lock);
533
	_mds[minor] = NULL;
534
	spin_unlock(&_minor_lock);
535
}
536
537
/*
538
 * See if the device with a specific minor # is free.
539
 */
540
static int specific_minor(int minor, struct mapped_device *md)
541
{
542
	int r = -EBUSY;
543
544
	if (minor >= MAX_DEVICES) {
545
		DMWARN("request for a mapped_device beyond MAX_DEVICES (%d)",
546
		       MAX_DEVICES);
547
		return -EINVAL;
548
	}
549
550
	spin_lock(&_minor_lock);
551
	if (!_mds[minor]) {
552
		_mds[minor] = md;
553
		r = minor;
554
	}
555
	spin_unlock(&_minor_lock);
556
557
	return r;
558
}
559
560
static int next_free_minor(struct mapped_device *md)
561
{
562
	int i;
563
564
	spin_lock(&_minor_lock);
565
	for (i = 0; i < MAX_DEVICES; i++) {
566
		if (!_mds[i]) {
567
			_mds[i] = md;
568
			break;
569
		}
570
	}
571
	spin_unlock(&_minor_lock);
572
573
	return (i < MAX_DEVICES) ? i : -EBUSY;
574
}
575
576
static struct mapped_device *get_kdev(kdev_t dev)
577
{
578
	struct mapped_device *md;
579
580
	if (major(dev) != _major)
581
		return NULL;
582
583
	spin_lock(&_minor_lock);
584
	md = _mds[minor(dev)];
585
	if (md)
586
		dm_get(md);
587
	spin_unlock(&_minor_lock);
588
589
	return md;
590
}
591
592
/*
593
 * Allocate and initialise a blank device with a given minor.
594
 */
595
static struct mapped_device *alloc_dev(int minor)
596
{
597
	struct mapped_device *md = kmalloc(sizeof(*md), GFP_KERNEL);
598
599
	if (!md) {
600
		DMWARN("unable to allocate device, out of memory.");
601
		return NULL;
602
	}
603
604
	/* get a minor number for the dev */
605
	minor = (minor < 0) ? next_free_minor(md) : specific_minor(minor, md);
606
	if (minor < 0) {
607
		kfree(md);
608
		return NULL;
609
	}
610
611
	memset(md, 0, sizeof(*md));
612
613
	md->io_pool = mempool_create(MIN_IOS, mempool_alloc_slab,
614
				     mempool_free_slab, _io_cache);
615
	if (!md->io_pool) {
616
		free_minor(minor);
617
		kfree(md);
618
		return NULL;
619
	}
620
621
	md->dev = mk_kdev(_major, minor);
622
	init_rwsem(&md->lock);
623
	atomic_set(&md->holders, 1);
624
	atomic_set(&md->pending, 0);
625
	init_waitqueue_head(&md->wait);
626
627
	return md;
628
}
629
630
static void free_dev(struct mapped_device *md)
631
{
632
	free_minor(minor(md->dev));
633
	mempool_destroy(md->io_pool);
634
	kfree(md);
635
}
636
637
/*
638
 * The hardsect size for a mapped device is the largest hardsect size
639
 * from the devices it maps onto.
640
 */
641
static int __find_hardsect_size(struct list_head *devices)
642
{
643
	int result = 512, size;
644
	struct list_head *tmp;
645
646
	list_for_each(tmp, devices) {
647
		struct dm_dev *dd = list_entry(tmp, struct dm_dev, list);
648
		size = get_hardsect_size(dd->dev);
649
		if (size > result)
650
			result = size;
651
	}
652
653
	return result;
654
}
655
656
/*
657
 * Bind a table to the device.
658
 */
659
static int __bind(struct mapped_device *md, struct dm_table *t)
660
{
661
	int minor = minor(md->dev);
662
	md->map = t;
663
664
	/* in k */
665
	_block_size[minor] = dm_table_get_size(t) >> 1;
666
	_blksize_size[minor] = BLOCK_SIZE;
667
	_hardsect_size[minor] = __find_hardsect_size(dm_table_get_devices(t));
668
	register_disk(NULL, md->dev, 1, &dm_blk_dops, _block_size[minor]);
669
670
	dm_table_get(t);
671
	return 0;
672
}
673
674
static void __unbind(struct mapped_device *md)
675
{
676
	int minor = minor(md->dev);
677
678
	dm_table_put(md->map);
679
	md->map = NULL;
680
681
	_block_size[minor] = 0;
682
	_blksize_size[minor] = 0;
683
	_hardsect_size[minor] = 0;
684
}
685
686
/*
687
 * Constructor for a new device.
688
 */
689
int dm_create(int minor, struct dm_table *table, struct mapped_device **result)
690
{
691
	int r;
692
	struct mapped_device *md;
693
694
	md = alloc_dev(minor);
695
	if (!md)
696
		return -ENXIO;
697
698
	r = __bind(md, table);
699
	if (r) {
700
		free_dev(md);
701
		return r;
702
	}
703
704
	*result = md;
705
	return 0;
706
}
707
708
void dm_get(struct mapped_device *md)
709
{
710
	atomic_inc(&md->holders);
711
}
712
713
void dm_put(struct mapped_device *md)
714
{
715
	if (atomic_dec_and_test(&md->holders)) {
716
		__unbind(md);
717
		free_dev(md);
718
	}
719
}
720
721
/*
722
 * Requeue the deferred io by calling generic_make_request.
723
 */
724
static void flush_deferred_io(struct deferred_io *c)
725
{
726
	struct deferred_io *n;
727
728
	while (c) {
729
		n = c->next;
730
		generic_make_request(c->rw, c->bh);
731
		free_deferred(c);
732
		c = n;
733
	}
734
}
735
736
/*
737
 * Swap in a new table (destroying old one).
738
 */
739
int dm_swap_table(struct mapped_device *md, struct dm_table *table)
740
{
741
	int r;
742
743
	down_write(&md->lock);
744
745
	/* device must be suspended */
746
	if (!test_bit(DMF_SUSPENDED, &md->flags)) {
747
		up_write(&md->lock);
748
		return -EPERM;
749
	}
750
751
	__unbind(md);
752
	r = __bind(md, table);
753
	if (r)
754
		return r;
755
756
	up_write(&md->lock);
757
	return 0;
758
}
759
760
/*
761
 * We need to be able to change a mapping table under a mounted
762
 * filesystem.  For example we might want to move some data in
763
 * the background.  Before the table can be swapped with
764
 * dm_bind_table, dm_suspend must be called to flush any in
765
 * flight io and ensure that any further io gets deferred.
766
 */
767
int dm_suspend(struct mapped_device *md)
768
{
769
	DECLARE_WAITQUEUE(wait, current);
770
771
	down_write(&md->lock);
772
773
	/*
774
	 * First we set the BLOCK_IO flag so no more ios will be
775
	 * mapped.
776
	 */
777
	if (test_bit(DMF_BLOCK_IO, &md->flags)) {
778
		up_write(&md->lock);
779
		return -EINVAL;
780
	}
781
782
	set_bit(DMF_BLOCK_IO, &md->flags);
783
	add_wait_queue(&md->wait, &wait);
784
	up_write(&md->lock);
785
786
	/*
787
	 * Then we wait for the already mapped ios to
788
	 * complete.
789
	 */
790
	run_task_queue(&tq_disk);
791
	while (1) {
792
		set_current_state(TASK_INTERRUPTIBLE);
793
794
		if (!atomic_read(&md->pending))
795
			break;
796
797
		schedule();
798
	}
799
800
	current->state = TASK_RUNNING;
801
802
	down_write(&md->lock);
803
	remove_wait_queue(&md->wait, &wait);
804
	set_bit(DMF_SUSPENDED, &md->flags);
805
	up_write(&md->lock);
806
807
	return 0;
808
}
809
810
int dm_resume(struct mapped_device *md)
811
{
812
	struct deferred_io *def;
813
814
	down_write(&md->lock);
815
	if (!test_bit(DMF_SUSPENDED, &md->flags) ||
816
	    !dm_table_get_size(md->map)) {
817
		up_write(&md->lock);
818
		return -EINVAL;
819
	}
820
821
	clear_bit(DMF_SUSPENDED, &md->flags);
822
	clear_bit(DMF_BLOCK_IO, &md->flags);
823
	def = md->deferred;
824
	md->deferred = NULL;
825
	up_write(&md->lock);
826
827
	flush_deferred_io(def);
828
	run_task_queue(&tq_disk);
829
830
	return 0;
831
}
832
833
struct dm_table *dm_get_table(struct mapped_device *md)
834
{
835
	struct dm_table *t;
836
837
	down_read(&md->lock);
838
	t = md->map;
839
	dm_table_get(t);
840
	up_read(&md->lock);
841
842
	return t;
843
}
844
845
kdev_t dm_kdev(struct mapped_device *md)
846
{
847
	kdev_t dev;
848
849
	down_read(&md->lock);
850
	dev = md->dev;
851
	up_read(&md->lock);
852
853
	return dev;
854
}
855
856
int dm_suspended(struct mapped_device *md)
857
{
858
	return test_bit(DMF_SUSPENDED, &md->flags);
859
}
860
861
struct block_device_operations dm_blk_dops = {
862
	.open = dm_blk_open,
863
	.release = dm_blk_close,
864
	.ioctl = dm_blk_ioctl,
865
	.owner = THIS_MODULE
866
};
867
868
/*
869
 * module hooks
870
 */
871
module_init(dm_init);
872
module_exit(dm_exit);
873
874
MODULE_PARM(major, "i");
875
MODULE_PARM_DESC(major, "The major number of the device mapper");
876
MODULE_DESCRIPTION(DM_NAME " driver");
877
MODULE_AUTHOR("Joe Thornber <thornber@sistina.com>");
878
MODULE_LICENSE("GPL");
(-)linux-2.4.20-gentoo-r5/drivers/md/dm.h (+154 lines)
Line 0 Link Here
1
/*
2
 * Internal header file for device mapper
3
 *
4
 * Copyright (C) 2001, 2002 Sistina Software
5
 *
6
 * This file is released under the LGPL.
7
 */
8
9
#ifndef DM_INTERNAL_H
10
#define DM_INTERNAL_H
11
12
#include <linux/fs.h>
13
#include <linux/device-mapper.h>
14
#include <linux/list.h>
15
#include <linux/blkdev.h>
16
17
#define DM_NAME "device-mapper"
18
#define DMWARN(f, x...) printk(KERN_WARNING DM_NAME ": " f "\n" , ## x)
19
#define DMERR(f, x...) printk(KERN_ERR DM_NAME ": " f "\n" , ## x)
20
#define DMINFO(f, x...) printk(KERN_INFO DM_NAME ": " f "\n" , ## x)
21
22
/*
23
 * FIXME: I think this should be with the definition of sector_t
24
 * in types.h.
25
 */
26
#ifdef CONFIG_LBD
27
#define SECTOR_FORMAT "%Lu"
28
#else
29
#define SECTOR_FORMAT "%lu"
30
#endif
31
32
#define SECTOR_SHIFT 9
33
#define SECTOR_SIZE (1 << SECTOR_SHIFT)
34
35
extern struct block_device_operations dm_blk_dops;
36
37
/*
38
 * List of devices that a metadevice uses and should open/close.
39
 */
40
struct dm_dev {
41
	struct list_head list;
42
43
	atomic_t count;
44
	int mode;
45
	kdev_t dev;
46
	struct block_device *bdev;
47
};
48
49
struct dm_table;
50
struct mapped_device;
51
52
/*-----------------------------------------------------------------
53
 * Functions for manipulating a struct mapped_device.
54
 * Drop the reference with dm_put when you finish with the object.
55
 *---------------------------------------------------------------*/
56
int dm_create(int minor, struct dm_table *table, struct mapped_device **md);
57
58
/*
59
 * Reference counting for md.
60
 */
61
void dm_get(struct mapped_device *md);
62
void dm_put(struct mapped_device *md);
63
64
/*
65
 * A device can still be used while suspended, but I/O is deferred.
66
 */
67
int dm_suspend(struct mapped_device *md);
68
int dm_resume(struct mapped_device *md);
69
70
/*
71
 * The device must be suspended before calling this method.
72
 */
73
int dm_swap_table(struct mapped_device *md, struct dm_table *t);
74
75
/*
76
 * Drop a reference on the table when you've finished with the
77
 * result.
78
 */
79
struct dm_table *dm_get_table(struct mapped_device *md);
80
81
/*
82
 * Info functions.
83
 */
84
kdev_t dm_kdev(struct mapped_device *md);
85
int dm_suspended(struct mapped_device *md);
86
87
/*-----------------------------------------------------------------
88
 * Functions for manipulating a table.  Tables are also reference
89
 * counted.
90
 *---------------------------------------------------------------*/
91
int dm_table_create(struct dm_table **result, int mode);
92
93
void dm_table_get(struct dm_table *t);
94
void dm_table_put(struct dm_table *t);
95
96
int dm_table_add_target(struct dm_table *t, const char *type,
97
			sector_t start,	sector_t len, char *params);
98
int dm_table_complete(struct dm_table *t);
99
void dm_table_event(struct dm_table *t);
100
sector_t dm_table_get_size(struct dm_table *t);
101
struct dm_target *dm_table_get_target(struct dm_table *t, int index);
102
struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector);
103
unsigned int dm_table_get_num_targets(struct dm_table *t);
104
struct list_head *dm_table_get_devices(struct dm_table *t);
105
int dm_table_get_mode(struct dm_table *t);
106
void dm_table_add_wait_queue(struct dm_table *t, wait_queue_t *wq);
107
108
/*-----------------------------------------------------------------
109
 * A registry of target types.
110
 *---------------------------------------------------------------*/
111
int dm_target_init(void);
112
void dm_target_exit(void);
113
struct target_type *dm_get_target_type(const char *name);
114
void dm_put_target_type(struct target_type *t);
115
116
117
/*-----------------------------------------------------------------
118
 * Useful inlines.
119
 *---------------------------------------------------------------*/
120
static inline int array_too_big(unsigned long fixed, unsigned long obj,
121
				unsigned long num)
122
{
123
	return (num > (ULONG_MAX - fixed) / obj);
124
}
125
126
/*
127
 * ceiling(n / size) * size
128
 */
129
static inline unsigned long dm_round_up(unsigned long n, unsigned long size)
130
{
131
	unsigned long r = n % size;
132
	return n + (r ? (size - r) : 0);
133
}
134
135
/*
136
 * The device-mapper can be driven through one of two interfaces;
137
 * ioctl or filesystem, depending which patch you have applied.
138
 */
139
int dm_interface_init(void);
140
void dm_interface_exit(void);
141
142
/*
143
 * Targets for linear and striped mappings
144
 */
145
int dm_linear_init(void);
146
void dm_linear_exit(void);
147
148
int dm_stripe_init(void);
149
void dm_stripe_exit(void);
150
151
int dm_snapshot_init(void);
152
void dm_snapshot_exit(void);
153
154
#endif
(-)linux-2.4.20-gentoo-r5/drivers/md/kcopyd.c (+839 lines)
Line 0 Link Here
1
/*
2
 * Copyright (C) 2002 Sistina Software (UK) Limited.
3
 *
4
 * This file is released under the GPL.
5
 */
6
7
#include <asm/atomic.h>
8
9
#include <linux/blkdev.h>
10
#include <linux/config.h>
11
#include <linux/device-mapper.h>
12
#include <linux/fs.h>
13
#include <linux/init.h>
14
#include <linux/list.h>
15
#include <linux/locks.h>
16
#include <linux/mempool.h>
17
#include <linux/module.h>
18
#include <linux/pagemap.h>
19
#include <linux/slab.h>
20
#include <linux/vmalloc.h>
21
22
#include "kcopyd.h"
23
24
/* FIXME: this is only needed for the DMERR macros */
25
#include "dm.h"
26
27
static void wake_kcopyd(void);
28
29
/*-----------------------------------------------------------------
30
 * We reserve our own pool of preallocated pages that are
31
 * only used for kcopyd io.
32
 *---------------------------------------------------------------*/
33
34
/*
35
 * FIXME: This should be configurable.
36
 */
37
#define NUM_PAGES 512
38
39
static DECLARE_MUTEX(_pages_lock);
40
static int _num_free_pages;
41
static struct page *_pages_array[NUM_PAGES];
42
static DECLARE_MUTEX(start_lock);
43
44
static int init_pages(void)
45
{
46
	int i;
47
	struct page *p;
48
49
	for (i = 0; i < NUM_PAGES; i++) {
50
		p = alloc_page(GFP_KERNEL);
51
		if (!p)
52
			goto bad;
53
54
		LockPage(p);
55
		_pages_array[i] = p;
56
	}
57
58
	_num_free_pages = NUM_PAGES;
59
	return 0;
60
61
      bad:
62
	while (i--) {
63
		UnlockPage(_pages_array[i]);
64
		__free_page(_pages_array[i]);
65
	}
66
	return -ENOMEM;
67
}
68
69
static void exit_pages(void)
70
{
71
	int i;
72
	struct page *p;
73
74
	for (i = 0; i < NUM_PAGES; i++) {
75
		p = _pages_array[i];
76
		UnlockPage(p);
77
		__free_page(p);
78
	}
79
80
	_num_free_pages = 0;
81
}
82
83
static int kcopyd_get_pages(int num, struct page **result)
84
{
85
	int i;
86
87
	down(&_pages_lock);
88
	if (_num_free_pages < num) {
89
		up(&_pages_lock);
90
		return -ENOMEM;
91
	}
92
93
	for (i = 0; i < num; i++) {
94
		_num_free_pages--;
95
		result[i] = _pages_array[_num_free_pages];
96
	}
97
	up(&_pages_lock);
98
99
	return 0;
100
}
101
102
static void kcopyd_free_pages(int num, struct page **result)
103
{
104
	int i;
105
106
	down(&_pages_lock);
107
	for (i = 0; i < num; i++)
108
		_pages_array[_num_free_pages++] = result[i];
109
	up(&_pages_lock);
110
}
111
112
/*-----------------------------------------------------------------
113
 * We keep our own private pool of buffer_heads.  These are just
114
 * held in a list on the b_reqnext field.
115
 *---------------------------------------------------------------*/
116
117
/*
118
 * Make sure we have enough buffers to always keep the pages
119
 * occupied.  So we assume the worst case scenario where blocks
120
 * are the size of a single sector.
121
 */
122
#define NUM_BUFFERS NUM_PAGES * (PAGE_SIZE / SECTOR_SIZE)
123
124
static spinlock_t _buffer_lock = SPIN_LOCK_UNLOCKED;
125
static struct buffer_head *_all_buffers;
126
static struct buffer_head *_free_buffers;
127
128
static int init_buffers(void)
129
{
130
	int i;
131
	struct buffer_head *buffers;
132
133
	buffers = vcalloc(NUM_BUFFERS, sizeof(struct buffer_head));
134
	if (!buffers) {
135
		DMWARN("Couldn't allocate buffer heads.");
136
		return -ENOMEM;
137
	}
138
139
	for (i = 0; i < NUM_BUFFERS; i++) {
140
		if (i < NUM_BUFFERS - 1)
141
			buffers[i].b_reqnext = &buffers[i + 1];
142
		init_waitqueue_head(&buffers[i].b_wait);
143
		INIT_LIST_HEAD(&buffers[i].b_inode_buffers);
144
	}
145
146
	_all_buffers = _free_buffers = buffers;
147
	return 0;
148
}
149
150
static void exit_buffers(void)
151
{
152
	vfree(_all_buffers);
153
}
154
155
static struct buffer_head *alloc_buffer(void)
156
{
157
	struct buffer_head *r;
158
	int flags;
159
160
	spin_lock_irqsave(&_buffer_lock, flags);
161
162
	if (!_free_buffers)
163
		r = NULL;
164
	else {
165
		r = _free_buffers;
166
		_free_buffers = _free_buffers->b_reqnext;
167
		r->b_reqnext = NULL;
168
	}
169
170
	spin_unlock_irqrestore(&_buffer_lock, flags);
171
172
	return r;
173
}
174
175
/*
176
 * Only called from interrupt context.
177
 */
178
static void free_buffer(struct buffer_head *bh)
179
{
180
	int flags, was_empty;
181
182
	spin_lock_irqsave(&_buffer_lock, flags);
183
	was_empty = (_free_buffers == NULL) ? 1 : 0;
184
	bh->b_reqnext = _free_buffers;
185
	_free_buffers = bh;
186
	spin_unlock_irqrestore(&_buffer_lock, flags);
187
188
	/*
189
	 * If the buffer list was empty then kcopyd probably went
190
	 * to sleep because it ran out of buffer heads, so let's
191
	 * wake it up.
192
	 */
193
	if (was_empty)
194
		wake_kcopyd();
195
}
196
197
/*-----------------------------------------------------------------
198
 * kcopyd_jobs need to be allocated by the *clients* of kcopyd,
199
 * for this reason we use a mempool to prevent the client from
200
 * ever having to do io (which could cause a
201
 * deadlock).
202
 *---------------------------------------------------------------*/
203
#define MIN_JOBS NUM_PAGES
204
205
static kmem_cache_t *_job_cache = NULL;
206
static mempool_t *_job_pool = NULL;
207
208
/*
209
 * We maintain three lists of jobs:
210
 *
211
 * i)   jobs waiting for pages
212
 * ii)  jobs that have pages, and are waiting for the io to be issued.
213
 * iii) jobs that have completed.
214
 *
215
 * All three of these are protected by job_lock.
216
 */
217
218
static spinlock_t _job_lock = SPIN_LOCK_UNLOCKED;
219
220
static LIST_HEAD(_complete_jobs);
221
static LIST_HEAD(_io_jobs);
222
static LIST_HEAD(_pages_jobs);
223
224
static int init_jobs(void)
225
{
226
	INIT_LIST_HEAD(&_complete_jobs);
227
	INIT_LIST_HEAD(&_io_jobs);
228
	INIT_LIST_HEAD(&_pages_jobs);
229
230
	_job_cache = kmem_cache_create("kcopyd-jobs", sizeof(struct kcopyd_job),
231
				       __alignof__(struct kcopyd_job),
232
				       0, NULL, NULL);
233
	if (!_job_cache)
234
		return -ENOMEM;
235
236
	_job_pool = mempool_create(MIN_JOBS, mempool_alloc_slab,
237
				   mempool_free_slab, _job_cache);
238
	if (!_job_pool) {
239
		kmem_cache_destroy(_job_cache);
240
		return -ENOMEM;
241
	}
242
243
	return 0;
244
}
245
246
static void exit_jobs(void)
247
{
248
	mempool_destroy(_job_pool);
249
	kmem_cache_destroy(_job_cache);
250
}
251
252
struct kcopyd_job *kcopyd_alloc_job(void)
253
{
254
	struct kcopyd_job *job;
255
256
	job = mempool_alloc(_job_pool, GFP_NOIO);
257
	if (!job)
258
		return NULL;
259
260
	memset(job, 0, sizeof(*job));
261
	return job;
262
}
263
264
void kcopyd_free_job(struct kcopyd_job *job)
265
{
266
	mempool_free(job, _job_pool);
267
}
268
269
/*
270
 * Functions to push and pop a job onto the head of a given job
271
 * list.
272
 */
273
static inline struct kcopyd_job *pop(struct list_head *jobs)
274
{
275
	struct kcopyd_job *job = NULL;
276
	int flags;
277
278
	spin_lock_irqsave(&_job_lock, flags);
279
280
	if (!list_empty(jobs)) {
281
		job = list_entry(jobs->next, struct kcopyd_job, list);
282
		list_del(&job->list);
283
	}
284
	spin_unlock_irqrestore(&_job_lock, flags);
285
286
	return job;
287
}
288
289
static inline void push(struct list_head *jobs, struct kcopyd_job *job)
290
{
291
	int flags;
292
293
	spin_lock_irqsave(&_job_lock, flags);
294
	list_add(&job->list, jobs);
295
	spin_unlock_irqrestore(&_job_lock, flags);
296
}
297
298
/*
299
 * Completion function for one of our buffers.
300
 */
301
static void end_bh(struct buffer_head *bh, int uptodate)
302
{
303
	struct kcopyd_job *job = bh->b_private;
304
305
	mark_buffer_uptodate(bh, uptodate);
306
	unlock_buffer(bh);
307
308
	if (!uptodate)
309
		job->err = -EIO;
310
311
	/* are we the last ? */
312
	if (atomic_dec_and_test(&job->nr_incomplete)) {
313
		push(&_complete_jobs, job);
314
		wake_kcopyd();
315
	}
316
317
	free_buffer(bh);
318
}
319
320
static void dispatch_bh(struct kcopyd_job *job,
321
			struct buffer_head *bh, int block)
322
{
323
	int p;
324
325
	/*
326
	 * Add in the job offset
327
	 */
328
	bh->b_blocknr = (job->disk.sector >> job->block_shift) + block;
329
330
	p = block >> job->bpp_shift;
331
	block &= job->bpp_mask;
332
333
	bh->b_size = job->block_size;
334
	set_bh_page(bh, job->pages[p], ((block << job->block_shift) +
335
					job->offset) << SECTOR_SHIFT);
336
	bh->b_this_page = bh;
337
338
	init_buffer(bh, end_bh, job);
339
340
	bh->b_dev = job->disk.dev;
341
	atomic_set(&bh->b_count, 1);
342
343
	bh->b_state = ((1 << BH_Uptodate) | (1 << BH_Mapped) |
344
		       (1 << BH_Lock) | (1 << BH_Req));
345
346
	if (job->rw == WRITE)
347
		clear_bit(BH_Dirty, &bh->b_state);
348
349
	submit_bh(job->rw, bh);
350
}
351
352
/*
353
 * These three functions process 1 item from the corresponding
354
 * job list.
355
 *
356
 * They return:
357
 * < 0: error
358
 *   0: success
359
 * > 0: can't process yet.
360
 */
361
static int run_complete_job(struct kcopyd_job *job)
362
{
363
	job->callback(job);
364
	return 0;
365
}
366
367
/*
368
 * Request io on as many buffer heads as we can currently get for
369
 * a particular job.
370
 */
371
static int run_io_job(struct kcopyd_job *job)
372
{
373
	unsigned int block;
374
	struct buffer_head *bh;
375
376
	for (block = atomic_read(&job->nr_requested);
377
	     block < job->nr_blocks; block++) {
378
		bh = alloc_buffer();
379
		if (!bh)
380
			break;
381
382
		atomic_inc(&job->nr_requested);
383
		dispatch_bh(job, bh, block);
384
	}
385
386
	return (block == job->nr_blocks) ? 0 : 1;
387
}
388
389
static int run_pages_job(struct kcopyd_job *job)
390
{
391
	int r;
392
393
	job->nr_pages = (job->disk.count + job->offset) /
394
	    (PAGE_SIZE / SECTOR_SIZE);
395
	r = kcopyd_get_pages(job->nr_pages, job->pages);
396
397
	if (!r) {
398
		/* this job is ready for io */
399
		push(&_io_jobs, job);
400
		return 0;
401
	}
402
403
	if (r == -ENOMEM)
404
		/* can't complete now */
405
		return 1;
406
407
	return r;
408
}
409
410
/*
411
 * Run through a list for as long as possible.  Returns the count
412
 * of successful jobs.
413
 */
414
static int process_jobs(struct list_head *jobs, int (*fn) (struct kcopyd_job *))
415
{
416
	struct kcopyd_job *job;
417
	int r, count = 0;
418
419
	while ((job = pop(jobs))) {
420
421
		r = fn(job);
422
423
		if (r < 0) {
424
			/* error this rogue job */
425
			job->err = r;
426
			push(&_complete_jobs, job);
427
			break;
428
		}
429
430
		if (r > 0) {
431
			/*
432
			 * We couldn't service this job ATM, so
433
			 * push this job back onto the list.
434
			 */
435
			push(jobs, job);
436
			break;
437
		}
438
439
		count++;
440
	}
441
442
	return count;
443
}
444
445
/*
446
 * kcopyd does this every time it's woken up.
447
 */
448
static void do_work(void)
449
{
450
	int count;
451
452
	/*
453
	 * We loop round until there is no more work to do.
454
	 */
455
	do {
456
		count = process_jobs(&_complete_jobs, run_complete_job);
457
		count += process_jobs(&_io_jobs, run_io_job);
458
		count += process_jobs(&_pages_jobs, run_pages_job);
459
460
	} while (count);
461
462
	run_task_queue(&tq_disk);
463
}
464
465
/*-----------------------------------------------------------------
466
 * The daemon
467
 *---------------------------------------------------------------*/
468
static atomic_t _kcopyd_must_die;
469
static DECLARE_MUTEX(_run_lock);
470
static DECLARE_WAIT_QUEUE_HEAD(_job_queue);
471
472
static int kcopyd(void *arg)
473
{
474
	DECLARE_WAITQUEUE(wq, current);
475
476
	daemonize();
477
	strcpy(current->comm, "kcopyd");
478
	atomic_set(&_kcopyd_must_die, 0);
479
480
	add_wait_queue(&_job_queue, &wq);
481
482
	down(&_run_lock);
483
	up(&start_lock);
484
485
	while (1) {
486
		set_current_state(TASK_INTERRUPTIBLE);
487
488
		if (atomic_read(&_kcopyd_must_die))
489
			break;
490
491
		do_work();
492
		schedule();
493
	}
494
495
	set_current_state(TASK_RUNNING);
496
	remove_wait_queue(&_job_queue, &wq);
497
498
	up(&_run_lock);
499
500
	return 0;
501
}
502
503
static int start_daemon(void)
504
{
505
	static pid_t pid = 0;
506
507
	down(&start_lock);
508
509
	pid = kernel_thread(kcopyd, NULL, 0);
510
	if (pid <= 0) {
511
		DMERR("Failed to start kcopyd thread");
512
		return -EAGAIN;
513
	}
514
515
	/*
516
	 * wait for the daemon to up this mutex.
517
	 */
518
	down(&start_lock);
519
	up(&start_lock);
520
521
	return 0;
522
}
523
524
static int stop_daemon(void)
525
{
526
	atomic_set(&_kcopyd_must_die, 1);
527
	wake_kcopyd();
528
	down(&_run_lock);
529
	up(&_run_lock);
530
531
	return 0;
532
}
533
534
static void wake_kcopyd(void)
535
{
536
	wake_up_interruptible(&_job_queue);
537
}
538
539
static int calc_shift(unsigned int n)
540
{
541
	int s;
542
543
	for (s = 0; n; s++, n >>= 1)
544
		;
545
546
	return --s;
547
}
548
549
static void calc_block_sizes(struct kcopyd_job *job)
550
{
551
	job->block_size = get_hardsect_size(job->disk.dev);
552
	job->block_shift = calc_shift(job->block_size / SECTOR_SIZE);
553
	job->bpp_shift = PAGE_SHIFT - job->block_shift - SECTOR_SHIFT;
554
	job->bpp_mask = (1 << job->bpp_shift) - 1;
555
	job->nr_blocks = job->disk.count >> job->block_shift;
556
	atomic_set(&job->nr_requested, 0);
557
	atomic_set(&job->nr_incomplete, job->nr_blocks);
558
}
559
560
int kcopyd_io(struct kcopyd_job *job)
561
{
562
	calc_block_sizes(job);
563
	push(job->pages[0] ? &_io_jobs : &_pages_jobs, job);
564
	wake_kcopyd();
565
	return 0;
566
}
567
568
/*-----------------------------------------------------------------
569
 * The copier is implemented on top of the simpler async io
570
 * daemon above.
571
 *---------------------------------------------------------------*/
572
struct copy_info {
573
	kcopyd_notify_fn notify;
574
	void *notify_context;
575
576
	struct kcopyd_region to;
577
};
578
579
#define MIN_INFOS 128
580
static kmem_cache_t *_copy_cache = NULL;
581
static mempool_t *_copy_pool = NULL;
582
583
static int init_copier(void)
584
{
585
	_copy_cache = kmem_cache_create("kcopyd-info",
586
					sizeof(struct copy_info),
587
					__alignof__(struct copy_info),
588
					0, NULL, NULL);
589
	if (!_copy_cache)
590
		return -ENOMEM;
591
592
	_copy_pool = mempool_create(MIN_INFOS, mempool_alloc_slab,
593
				    mempool_free_slab, _copy_cache);
594
	if (!_copy_pool) {
595
		kmem_cache_destroy(_copy_cache);
596
		return -ENOMEM;
597
	}
598
599
	return 0;
600
}
601
602
static void exit_copier(void)
603
{
604
	if (_copy_pool)
605
		mempool_destroy(_copy_pool);
606
607
	if (_copy_cache)
608
		kmem_cache_destroy(_copy_cache);
609
}
610
611
static inline struct copy_info *alloc_copy_info(void)
612
{
613
	return mempool_alloc(_copy_pool, GFP_NOIO);
614
}
615
616
static inline void free_copy_info(struct copy_info *info)
617
{
618
	mempool_free(info, _copy_pool);
619
}
620
621
void copy_complete(struct kcopyd_job *job)
622
{
623
	struct copy_info *info = (struct copy_info *) job->context;
624
625
	if (info->notify)
626
		info->notify(job->err, info->notify_context);
627
628
	free_copy_info(info);
629
630
	kcopyd_free_pages(job->nr_pages, job->pages);
631
632
	kcopyd_free_job(job);
633
}
634
635
static void page_write_complete(struct kcopyd_job *job)
636
{
637
	struct copy_info *info = (struct copy_info *) job->context;
638
	int i;
639
640
	if (info->notify)
641
		info->notify(job->err, info->notify_context);
642
643
	free_copy_info(info);
644
	for (i = 0; i < job->nr_pages; i++)
645
		put_page(job->pages[i]);
646
647
	kcopyd_free_job(job);
648
}
649
650
/*
651
 * These callback functions implement the state machine that copies regions.
652
 */
653
void copy_write(struct kcopyd_job *job)
654
{
655
	struct copy_info *info = (struct copy_info *) job->context;
656
657
	if (job->err) {
658
		if (info->notify)
659
			info->notify(job->err, job->context);
660
661
		kcopyd_free_job(job);
662
		free_copy_info(info);
663
		return;
664
	}
665
666
	job->rw = WRITE;
667
	memcpy(&job->disk, &info->to, sizeof(job->disk));
668
	job->callback = copy_complete;
669
670
	/*
671
	 * Queue the write.
672
	 */
673
	kcopyd_io(job);
674
}
675
676
int kcopyd_write_pages(struct kcopyd_region *to, int nr_pages,
677
		       struct page **pages, int offset, kcopyd_notify_fn fn,
678
		       void *context)
679
{
680
	struct copy_info *info;
681
	struct kcopyd_job *job;
682
	int i;
683
684
	/*
685
	 * Allocate a new copy_info.
686
	 */
687
	info = alloc_copy_info();
688
	if (!info)
689
		return -ENOMEM;
690
691
	job = kcopyd_alloc_job();
692
	if (!job) {
693
		free_copy_info(info);
694
		return -ENOMEM;
695
	}
696
697
	/*
698
	 * set up for the write.
699
	 */
700
	info->notify = fn;
701
	info->notify_context = context;
702
	memcpy(&info->to, to, sizeof(*to));
703
704
	/* Get the pages */
705
	job->nr_pages = nr_pages;
706
	for (i = 0; i < nr_pages; i++) {
707
		get_page(pages[i]);
708
		job->pages[i] = pages[i];
709
	}
710
711
	job->rw = WRITE;
712
713
	memcpy(&job->disk, &info->to, sizeof(job->disk));
714
	job->offset = offset;
715
	job->callback = page_write_complete;
716
	job->context = info;
717
718
	/*
719
	 * Trigger job.
720
	 */
721
	kcopyd_io(job);
722
	return 0;
723
}
724
725
int kcopyd_copy(struct kcopyd_region *from, struct kcopyd_region *to,
726
		kcopyd_notify_fn fn, void *context)
727
{
728
	struct copy_info *info;
729
	struct kcopyd_job *job;
730
731
	/*
732
	 * Allocate a new copy_info.
733
	 */
734
	info = alloc_copy_info();
735
	if (!info)
736
		return -ENOMEM;
737
738
	job = kcopyd_alloc_job();
739
	if (!job) {
740
		free_copy_info(info);
741
		return -ENOMEM;
742
	}
743
744
	/*
745
	 * set up for the read.
746
	 */
747
	info->notify = fn;
748
	info->notify_context = context;
749
	memcpy(&info->to, to, sizeof(*to));
750
751
	job->rw = READ;
752
	memcpy(&job->disk, from, sizeof(*from));
753
754
	job->offset = 0;
755
	job->callback = copy_write;
756
	job->context = info;
757
758
	/*
759
	 * Trigger job.
760
	 */
761
	kcopyd_io(job);
762
	return 0;
763
}
764
765
/*-----------------------------------------------------------------
766
 * Unit setup
767
 *---------------------------------------------------------------*/
768
static struct {
769
	int (*init) (void);
770
	void (*exit) (void);
771
772
} _inits[] = {
773
#define xx(n) { init_ ## n, exit_ ## n}
774
	xx(pages),
775
	xx(buffers),
776
	xx(jobs),
777
	xx(copier)
778
#undef xx
779
};
780
781
static int _client_count = 0;
782
static DECLARE_MUTEX(_client_count_sem);
783
784
static int kcopyd_init(void)
785
{
786
	const int count = sizeof(_inits) / sizeof(*_inits);
787
788
	int r, i;
789
790
	for (i = 0; i < count; i++) {
791
		r = _inits[i].init();
792
		if (r)
793
			goto bad;
794
	}
795
796
	start_daemon();
797
	return 0;
798
799
      bad:
800
	while (i--)
801
		_inits[i].exit();
802
803
	return r;
804
}
805
806
static void kcopyd_exit(void)
807
{
808
	int i = sizeof(_inits) / sizeof(*_inits);
809
810
	if (stop_daemon())
811
		DMWARN("Couldn't stop kcopyd.");
812
813
	while (i--)
814
		_inits[i].exit();
815
}
816
817
void kcopyd_inc_client_count(void)
818
{
819
	/*
820
	 * What I need here is an atomic_test_and_inc that returns
821
	 * the previous value of the atomic...  In its absence I lock
822
	 * an int with a semaphore. :-(
823
	 */
824
	down(&_client_count_sem);
825
	if (_client_count == 0)
826
		kcopyd_init();
827
	_client_count++;
828
829
	up(&_client_count_sem);
830
}
831
832
void kcopyd_dec_client_count(void)
833
{
834
	down(&_client_count_sem);
835
	if (--_client_count == 0)
836
		kcopyd_exit();
837
838
	up(&_client_count_sem);
839
}
(-)linux-2.4.20-gentoo-r5/drivers/md/kcopyd.h (+101 lines)
Line 0 Link Here
1
/*
2
 * Copyright (C) 2001 Sistina Software
3
 *
4
 * This file is released under the GPL.
5
 */
6
7
#ifndef DM_KCOPYD_H
8
#define DM_KCOPYD_H
9
10
/*
11
 * Needed for the definition of offset_t.
12
 */
13
#include <linux/device-mapper.h>
14
#include <linux/iobuf.h>
15
16
struct kcopyd_region {
17
	kdev_t dev;
18
	sector_t sector;
19
	sector_t count;
20
};
21
22
#define MAX_KCOPYD_PAGES 128
23
24
struct kcopyd_job {
25
	struct list_head list;
26
27
	/*
28
	 * Error state of the job.
29
	 */
30
	int err;
31
32
	/*
33
	 * Either READ or WRITE
34
	 */
35
	int rw;
36
37
	/*
38
	 * The source or destination for the transfer.
39
	 */
40
	struct kcopyd_region disk;
41
42
	int nr_pages;
43
	struct page *pages[MAX_KCOPYD_PAGES];
44
45
	/*
46
	 * Shifts and masks that will be useful when dispatching
47
	 * each buffer_head.
48
	 */
49
	sector_t offset;
50
	sector_t block_size;
51
	sector_t block_shift;
52
	sector_t bpp_shift;	/* blocks per page */
53
	sector_t bpp_mask;
54
55
	/*
56
	 * nr_blocks is how many buffer heads will have to be
57
	 * displatched to service this job, nr_requested is how
58
	 * many have been dispatched and nr_complete is how many
59
	 * have come back.
60
	 */
61
	unsigned int nr_blocks;
62
	atomic_t nr_requested;
63
	atomic_t nr_incomplete;
64
65
	/*
66
	 * Set this to ensure you are notified when the job has
67
	 * completed.  'context' is for callback to use.
68
	 */
69
	void (*callback) (struct kcopyd_job * job);
70
	void *context;
71
};
72
73
/*
74
 * Low level async io routines.
75
 */
76
struct kcopyd_job *kcopyd_alloc_job(void);
77
void kcopyd_free_job(struct kcopyd_job *job);
78
79
int kcopyd_queue_job(struct kcopyd_job *job);
80
81
/*
82
 * Submit a copy job to kcopyd.  This is built on top of the
83
 * previous three fns.
84
 */
85
typedef void (*kcopyd_notify_fn) (int err, void *context);
86
87
int kcopyd_copy(struct kcopyd_region *from, struct kcopyd_region *to,
88
		kcopyd_notify_fn fn, void *context);
89
90
int kcopyd_write_pages(struct kcopyd_region *to, int nr_pages,
91
		       struct page **pages, int offset, kcopyd_notify_fn fn,
92
		       void *context);
93
94
/*
95
 * We only want kcopyd to reserve resources if someone is
96
 * actually using it.
97
 */
98
void kcopyd_inc_client_count(void);
99
void kcopyd_dec_client_count(void);
100
101
#endif
(-)linux-2.4.20-gentoo-r5/fs/buffer.c (-9 / +12 lines)
Lines 649-657 Link Here
649
void buffer_insert_inode_queue(struct buffer_head *bh, struct inode *inode)
649
void buffer_insert_inode_queue(struct buffer_head *bh, struct inode *inode)
650
{
650
{
651
	spin_lock(&lru_list_lock);
651
	spin_lock(&lru_list_lock);
652
	if (bh->b_inode)
652
	if (buffer_inode(bh))
653
		list_del(&bh->b_inode_buffers);
653
		list_del(&bh->b_inode_buffers);
654
	bh->b_inode = inode;
654
	else
655
		set_buffer_inode(bh);
655
	list_add(&bh->b_inode_buffers, &inode->i_dirty_buffers);
656
	list_add(&bh->b_inode_buffers, &inode->i_dirty_buffers);
656
	spin_unlock(&lru_list_lock);
657
	spin_unlock(&lru_list_lock);
657
}
658
}
Lines 659-667 Link Here
659
void buffer_insert_inode_data_queue(struct buffer_head *bh, struct inode *inode)
660
void buffer_insert_inode_data_queue(struct buffer_head *bh, struct inode *inode)
660
{
661
{
661
	spin_lock(&lru_list_lock);
662
	spin_lock(&lru_list_lock);
662
	if (bh->b_inode)
663
	if (buffer_inode(bh))
663
		list_del(&bh->b_inode_buffers);
664
		list_del(&bh->b_inode_buffers);
664
	bh->b_inode = inode;
665
	else
666
		set_buffer_inode(bh);
665
	list_add(&bh->b_inode_buffers, &inode->i_dirty_data_buffers);
667
	list_add(&bh->b_inode_buffers, &inode->i_dirty_data_buffers);
666
	spin_unlock(&lru_list_lock);
668
	spin_unlock(&lru_list_lock);
667
}
669
}
Lines 670-682 Link Here
670
   remove_inode_queue functions.  */
672
   remove_inode_queue functions.  */
671
static void __remove_inode_queue(struct buffer_head *bh)
673
static void __remove_inode_queue(struct buffer_head *bh)
672
{
674
{
673
	bh->b_inode = NULL;
675
	clear_buffer_inode(bh);
674
	list_del(&bh->b_inode_buffers);
676
	list_del(&bh->b_inode_buffers);
675
}
677
}
676
678
677
static inline void remove_inode_queue(struct buffer_head *bh)
679
static inline void remove_inode_queue(struct buffer_head *bh)
678
{
680
{
679
	if (bh->b_inode)
681
	if (buffer_inode(bh))
680
		__remove_inode_queue(bh);
682
		__remove_inode_queue(bh);
681
}
683
}
682
684
Lines 814-819 Link Here
814
	bh->b_list = BUF_CLEAN;
816
	bh->b_list = BUF_CLEAN;
815
	bh->b_end_io = handler;
817
	bh->b_end_io = handler;
816
	bh->b_private = private;
818
	bh->b_private = private;
819
	bh->b_journal_head = NULL;
817
}
820
}
818
821
819
static void end_buffer_io_async(struct buffer_head * bh, int uptodate)
822
static void end_buffer_io_async(struct buffer_head * bh, int uptodate)
Lines 922-930 Link Here
922
		bh = BH_ENTRY(list->next);
925
		bh = BH_ENTRY(list->next);
923
		list_del(&bh->b_inode_buffers);
926
		list_del(&bh->b_inode_buffers);
924
		if (!buffer_dirty(bh) && !buffer_locked(bh))
927
		if (!buffer_dirty(bh) && !buffer_locked(bh))
925
			bh->b_inode = NULL;
928
			clear_buffer_inode(bh);
926
		else {
929
		else {
927
			bh->b_inode = &tmp;
930
			set_buffer_inode(bh);
928
			list_add(&bh->b_inode_buffers, &tmp.i_dirty_buffers);
931
			list_add(&bh->b_inode_buffers, &tmp.i_dirty_buffers);
929
			if (buffer_dirty(bh)) {
932
			if (buffer_dirty(bh)) {
930
				get_bh(bh);
933
				get_bh(bh);
Lines 1251-1257 Link Here
1251
 */
1254
 */
1252
static void __put_unused_buffer_head(struct buffer_head * bh)
1255
static void __put_unused_buffer_head(struct buffer_head * bh)
1253
{
1256
{
1254
	if (bh->b_inode)
1257
	if (buffer_inode(bh))
1255
		BUG();
1258
		BUG();
1256
	if (nr_unused_buffer_heads >= MAX_UNUSED_BUFFERS) {
1259
	if (nr_unused_buffer_heads >= MAX_UNUSED_BUFFERS) {
1257
		kmem_cache_free(bh_cachep, bh);
1260
		kmem_cache_free(bh_cachep, bh);
(-)linux-2.4.20-gentoo-r5/fs/jbd/journal.c (-7 / +7 lines)
Lines 1664-1671 Link Here
1664
 *
1664
 *
1665
 * Whenever a buffer has an attached journal_head, its ->b_state:BH_JBD bit
1665
 * Whenever a buffer has an attached journal_head, its ->b_state:BH_JBD bit
1666
 * is set.  This bit is tested in core kernel code where we need to take
1666
 * is set.  This bit is tested in core kernel code where we need to take
1667
 * JBD-specific actions.  Testing the zeroness of ->b_private is not reliable
1667
 * JBD-specific actions.  Testing the zeroness of ->b_journal_head is not
1668
 * there.
1668
 * reliable there.
1669
 *
1669
 *
1670
 * When a buffer has its BH_JBD bit set, its ->b_count is elevated by one.
1670
 * When a buffer has its BH_JBD bit set, its ->b_count is elevated by one.
1671
 *
1671
 *
Lines 1720-1728 Link Here
1720
1720
1721
		if (buffer_jbd(bh)) {
1721
		if (buffer_jbd(bh)) {
1722
			/* Someone did it for us! */
1722
			/* Someone did it for us! */
1723
			J_ASSERT_BH(bh, bh->b_private != NULL);
1723
			J_ASSERT_BH(bh, bh->b_journal_head != NULL);
1724
			journal_free_journal_head(jh);
1724
			journal_free_journal_head(jh);
1725
			jh = bh->b_private;
1725
			jh = bh->b_journal_head;
1726
		} else {
1726
		} else {
1727
			/*
1727
			/*
1728
			 * We actually don't need jh_splice_lock when
1728
			 * We actually don't need jh_splice_lock when
Lines 1730-1736 Link Here
1730
			 */
1730
			 */
1731
			spin_lock(&jh_splice_lock);
1731
			spin_lock(&jh_splice_lock);
1732
			set_bit(BH_JBD, &bh->b_state);
1732
			set_bit(BH_JBD, &bh->b_state);
1733
			bh->b_private = jh;
1733
			bh->b_journal_head = jh;
1734
			jh->b_bh = bh;
1734
			jh->b_bh = bh;
1735
			atomic_inc(&bh->b_count);
1735
			atomic_inc(&bh->b_count);
1736
			spin_unlock(&jh_splice_lock);
1736
			spin_unlock(&jh_splice_lock);
Lines 1739-1745 Link Here
1739
	}
1739
	}
1740
	jh->b_jcount++;
1740
	jh->b_jcount++;
1741
	spin_unlock(&journal_datalist_lock);
1741
	spin_unlock(&journal_datalist_lock);
1742
	return bh->b_private;
1742
	return bh->b_journal_head;
1743
}
1743
}
1744
1744
1745
/*
1745
/*
Lines 1772-1778 Link Here
1772
			J_ASSERT_BH(bh, jh2bh(jh) == bh);
1772
			J_ASSERT_BH(bh, jh2bh(jh) == bh);
1773
			BUFFER_TRACE(bh, "remove journal_head");
1773
			BUFFER_TRACE(bh, "remove journal_head");
1774
			spin_lock(&jh_splice_lock);
1774
			spin_lock(&jh_splice_lock);
1775
			bh->b_private = NULL;
1775
			bh->b_journal_head = NULL;
1776
			jh->b_bh = NULL;	/* debug, really */
1776
			jh->b_bh = NULL;	/* debug, really */
1777
			clear_bit(BH_JBD, &bh->b_state);
1777
			clear_bit(BH_JBD, &bh->b_state);
1778
			__brelse(bh);
1778
			__brelse(bh);
(-)linux-2.4.20-gentoo-r5/include/linux/device-mapper.h (+94 lines)
Line 0 Link Here
1
/*
2
 * Copyright (C) 2001 Sistina Software (UK) Limited.
3
 *
4
 * This file is released under the LGPL.
5
 */
6
7
#ifndef _LINUX_DEVICE_MAPPER_H
8
#define _LINUX_DEVICE_MAPPER_H
9
10
typedef unsigned long sector_t;
11
12
struct dm_target;
13
struct dm_table;
14
struct dm_dev;
15
16
typedef enum { STATUSTYPE_INFO, STATUSTYPE_TABLE } status_type_t;
17
18
/*
19
 * In the constructor the target parameter will already have the
20
 * table, type, begin and len fields filled in.
21
 */
22
typedef int (*dm_ctr_fn) (struct dm_target * target, int argc, char **argv);
23
24
/*
25
 * The destructor doesn't need to free the dm_target, just
26
 * anything hidden ti->private.
27
 */
28
typedef void (*dm_dtr_fn) (struct dm_target * ti);
29
30
/*
31
 * The map function must return:
32
 * < 0: error
33
 * = 0: The target will handle the io by resubmitting it later
34
 * > 0: simple remap complete
35
 */
36
typedef int (*dm_map_fn) (struct dm_target * ti, struct buffer_head * bh,
37
			  int rw, void **map_context);
38
39
/*
40
 * Returns:
41
 * < 0 : error (currently ignored)
42
 * 0   : ended successfully
43
 * 1   : for some reason the io has still not completed (eg,
44
 *       multipath target might want to requeue a failed io).
45
 */
46
typedef int (*dm_endio_fn) (struct dm_target * ti,
47
			    struct buffer_head * bh, int rw, int error,
48
			    void *map_context);
49
typedef int (*dm_status_fn) (struct dm_target * ti, status_type_t status_type,
50
			     char *result, int maxlen);
51
52
void dm_error(const char *message);
53
54
/*
55
 * Constructors should call these functions to ensure destination devices
56
 * are opened/closed correctly.
57
 * FIXME: too many arguments.
58
 */
59
int dm_get_device(struct dm_target *ti, const char *path, sector_t start,
60
		  sector_t len, int mode, struct dm_dev **result);
61
void dm_put_device(struct dm_target *ti, struct dm_dev *d);
62
63
/*
64
 * Information about a target type
65
 */
66
struct target_type {
67
	const char *name;
68
	struct module *module;
69
	dm_ctr_fn ctr;
70
	dm_dtr_fn dtr;
71
	dm_map_fn map;
72
	dm_endio_fn end_io;
73
	dm_status_fn status;
74
};
75
76
struct dm_target {
77
	struct dm_table *table;
78
	struct target_type *type;
79
80
	/* target limits */
81
	sector_t begin;
82
	sector_t len;
83
84
	/* target specific data */
85
	void *private;
86
87
	/* Used to provide an error string from the ctr */
88
	char *error;
89
};
90
91
int dm_register_target(struct target_type *t);
92
int dm_unregister_target(struct target_type *t);
93
94
#endif				/* _LINUX_DEVICE_MAPPER_H */
(-)linux-2.4.20-gentoo-r5/include/linux/dm-ioctl.h (+149 lines)
Line 0 Link Here
1
/*
2
 * Copyright (C) 2001 Sistina Software (UK) Limited.
3
 *
4
 * This file is released under the LGPL.
5
 */
6
7
#ifndef _LINUX_DM_IOCTL_H
8
#define _LINUX_DM_IOCTL_H
9
10
#include <linux/types.h>
11
12
#define DM_DIR "mapper"		/* Slashes not supported */
13
#define DM_MAX_TYPE_NAME 16
14
#define DM_NAME_LEN 128
15
#define DM_UUID_LEN 129
16
17
/*
18
 * Implements a traditional ioctl interface to the device mapper.
19
 */
20
21
/*
22
 * All ioctl arguments consist of a single chunk of memory, with
23
 * this structure at the start.  If a uuid is specified any
24
 * lookup (eg. for a DM_INFO) will be done on that, *not* the
25
 * name.
26
 */
27
struct dm_ioctl {
28
	/*
29
	 * The version number is made up of three parts:
30
	 * major - no backward or forward compatibility,
31
	 * minor - only backwards compatible,
32
	 * patch - both backwards and forwards compatible.
33
	 *
34
	 * All clients of the ioctl interface should fill in the
35
	 * version number of the interface that they were
36
	 * compiled with.
37
	 *
38
	 * All recognised ioctl commands (ie. those that don't
39
	 * return -ENOTTY) fill out this field, even if the
40
	 * command failed.
41
	 */
42
	uint32_t version[3];	/* in/out */
43
	uint32_t data_size;	/* total size of data passed in
44
				 * including this struct */
45
46
	uint32_t data_start;	/* offset to start of data
47
				 * relative to start of this struct */
48
49
	uint32_t target_count;	/* in/out */
50
	uint32_t open_count;	/* out */
51
	uint32_t flags;		/* in/out */
52
53
	__kernel_dev_t dev;	/* in/out */
54
55
	char name[DM_NAME_LEN];	/* device name */
56
	char uuid[DM_UUID_LEN];	/* unique identifier for
57
				 * the block device */
58
};
59
60
/*
61
 * Used to specify tables.  These structures appear after the
62
 * dm_ioctl.
63
 */
64
struct dm_target_spec {
65
	int32_t status;		/* used when reading from kernel only */
66
	uint64_t sector_start;
67
	uint32_t length;
68
69
	/*
70
	 * Offset in bytes (from the start of this struct) to
71
	 * next target_spec.
72
	 */
73
	uint32_t next;
74
75
	char target_type[DM_MAX_TYPE_NAME];
76
77
	/*
78
	 * Parameter string starts immediately after this object.
79
	 * Be careful to add padding after string to ensure correct
80
	 * alignment of subsequent dm_target_spec.
81
	 */
82
};
83
84
/*
85
 * Used to retrieve the target dependencies.
86
 */
87
struct dm_target_deps {
88
	uint32_t count;
89
90
	__kernel_dev_t dev[0];	/* out */
91
};
92
93
/*
94
 * If you change this make sure you make the corresponding change
95
 * to dm-ioctl.c:lookup_ioctl()
96
 */
97
enum {
98
	/* Top level cmds */
99
	DM_VERSION_CMD = 0,
100
	DM_REMOVE_ALL_CMD,
101
102
	/* device level cmds */
103
	DM_DEV_CREATE_CMD,
104
	DM_DEV_REMOVE_CMD,
105
	DM_DEV_RELOAD_CMD,
106
	DM_DEV_RENAME_CMD,
107
	DM_DEV_SUSPEND_CMD,
108
	DM_DEV_DEPS_CMD,
109
	DM_DEV_STATUS_CMD,
110
111
	/* target level cmds */
112
	DM_TARGET_STATUS_CMD,
113
	DM_TARGET_WAIT_CMD
114
};
115
116
#define DM_IOCTL 0xfd
117
118
#define DM_VERSION       _IOWR(DM_IOCTL, DM_VERSION_CMD, struct dm_ioctl)
119
#define DM_REMOVE_ALL    _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD, struct dm_ioctl)
120
121
#define DM_DEV_CREATE    _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD, struct dm_ioctl)
122
#define DM_DEV_REMOVE    _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD, struct dm_ioctl)
123
#define DM_DEV_RELOAD    _IOWR(DM_IOCTL, DM_DEV_RELOAD_CMD, struct dm_ioctl)
124
#define DM_DEV_SUSPEND   _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD, struct dm_ioctl)
125
#define DM_DEV_RENAME    _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD, struct dm_ioctl)
126
#define DM_DEV_DEPS      _IOWR(DM_IOCTL, DM_DEV_DEPS_CMD, struct dm_ioctl)
127
#define DM_DEV_STATUS    _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, struct dm_ioctl)
128
129
#define DM_TARGET_STATUS _IOWR(DM_IOCTL, DM_TARGET_STATUS_CMD, struct dm_ioctl)
130
#define DM_TARGET_WAIT   _IOWR(DM_IOCTL, DM_TARGET_WAIT_CMD, struct dm_ioctl)
131
132
#define DM_VERSION_MAJOR	1
133
#define DM_VERSION_MINOR	0
134
#define DM_VERSION_PATCHLEVEL	10
135
#define DM_VERSION_EXTRA	"-ioctl (2003-03-27)"
136
137
/* Status bits */
138
#define DM_READONLY_FLAG	0x00000001
139
#define DM_SUSPEND_FLAG		0x00000002
140
#define DM_EXISTS_FLAG		0x00000004
141
#define DM_PERSISTENT_DEV_FLAG	0x00000008
142
143
/*
144
 * Flag passed into ioctl STATUS command to get table information
145
 * rather than current status.
146
 */
147
#define DM_STATUS_TABLE_FLAG	0x00000010
148
149
#endif				/* _LINUX_DM_IOCTL_H */
(-)linux-2.4.20-gentoo-r5/include/linux/fs.h (-2 / +17 lines)
Lines 223-228 Link Here
223
	BH_Wait_IO,	/* 1 if we should write out this buffer */
223
	BH_Wait_IO,	/* 1 if we should write out this buffer */
224
	BH_Launder,	/* 1 if we can throttle on this buffer */
224
	BH_Launder,	/* 1 if we can throttle on this buffer */
225
	BH_JBD,		/* 1 if it has an attached journal_head */
225
	BH_JBD,		/* 1 if it has an attached journal_head */
226
	BH_Inode,	/* 1 if it is attached to i_dirty[_data]_buffers */
226
227
227
	BH_PrivateStart,/* not a state bit, but the first bit available
228
	BH_PrivateStart,/* not a state bit, but the first bit available
228
			 * for private allocation by other entities
229
			 * for private allocation by other entities
Lines 265-275 Link Here
265
	struct page *b_page;		/* the page this bh is mapped to */
266
	struct page *b_page;		/* the page this bh is mapped to */
266
	void (*b_end_io)(struct buffer_head *bh, int uptodate); /* I/O completion */
267
	void (*b_end_io)(struct buffer_head *bh, int uptodate); /* I/O completion */
267
 	void *b_private;		/* reserved for b_end_io */
268
 	void *b_private;		/* reserved for b_end_io */
268
269
 	void *b_journal_head;		/* ext3 journal_heads */
269
	unsigned long b_rsector;	/* Real buffer location on disk */
270
	unsigned long b_rsector;	/* Real buffer location on disk */
270
	wait_queue_head_t b_wait;
271
	wait_queue_head_t b_wait;
271
272
272
	struct inode *	     b_inode;
273
	struct list_head     b_inode_buffers;	/* doubly linked list of inode dirty buffers */
273
	struct list_head     b_inode_buffers;	/* doubly linked list of inode dirty buffers */
274
};
274
};
275
275
Lines 1225-1230 Link Here
1225
		clear_bit(BH_Async, &bh->b_state);
1225
		clear_bit(BH_Async, &bh->b_state);
1226
}
1226
}
1227
1227
1228
static inline void set_buffer_inode(struct buffer_head *bh)
1229
{
1230
	set_bit(BH_Inode, &bh->b_state);
1231
}
1232
1233
static inline void clear_buffer_inode(struct buffer_head *bh)
1234
{
1235
	clear_bit(BH_Inode, &bh->b_state);
1236
}
1237
1238
static inline int buffer_inode(struct buffer_head *bh)
1239
{
1240
	return test_bit(BH_Inode, &bh->b_state);
1241
}
1242
1228
/*
1243
/*
1229
 * If an error happens during the make_request, this function
1244
 * If an error happens during the make_request, this function
1230
 * has to be recalled. It marks the buffer as clean and not
1245
 * has to be recalled. It marks the buffer as clean and not
(-)linux-2.4.20-gentoo-r5/include/linux/jbd.h (-1 / +1 lines)
Lines 254-260 Link Here
254
254
255
static inline struct journal_head *bh2jh(struct buffer_head *bh)
255
static inline struct journal_head *bh2jh(struct buffer_head *bh)
256
{
256
{
257
	return bh->b_private;
257
	return bh->b_journal_head;
258
}
258
}
259
259
260
#define HAVE_JOURNAL_CALLBACK_STATUS
260
#define HAVE_JOURNAL_CALLBACK_STATUS
(-)linux-2.4.20-gentoo-r5/include/linux/mempool.h (+9 lines)
Lines 4-14 Link Here
4
#ifndef _LINUX_MEMPOOL_H
4
#ifndef _LINUX_MEMPOOL_H
5
#define _LINUX_MEMPOOL_H
5
#define _LINUX_MEMPOOL_H
6
6
7
#include <linux/list.h>
7
#include <linux/wait.h>
8
#include <linux/wait.h>
8
9
9
typedef void * (mempool_alloc_t)(int gfp_mask, void *pool_data);
10
typedef void * (mempool_alloc_t)(int gfp_mask, void *pool_data);
10
typedef void (mempool_free_t)(void *element, void *pool_data);
11
typedef void (mempool_free_t)(void *element, void *pool_data);
11
12
13
struct mempool_s;
12
typedef struct mempool_s {
14
typedef struct mempool_s {
13
	spinlock_t lock;
15
	spinlock_t lock;
14
	int min_nr;		/* nr of elements at *elements */
16
	int min_nr;		/* nr of elements at *elements */
Lines 27-30 Link Here
27
extern void * mempool_alloc(mempool_t *pool, int gfp_mask);
29
extern void * mempool_alloc(mempool_t *pool, int gfp_mask);
28
extern void mempool_free(void *element, mempool_t *pool);
30
extern void mempool_free(void *element, mempool_t *pool);
29
31
32
/*
33
 * A mempool_alloc_t and mempool_free_t that get the memory from
34
 * a slab that is passed in through pool_data.
35
 */
36
void *mempool_alloc_slab(int gfp_mask, void *pool_data);
37
void mempool_free_slab(void *element, void *pool_data);
38
30
#endif /* _LINUX_MEMPOOL_H */
39
#endif /* _LINUX_MEMPOOL_H */
(-)linux-2.4.20-gentoo-r5/include/linux/vmalloc.h (+1 lines)
Lines 26-31 Link Here
26
extern void vmfree_area_pages(unsigned long address, unsigned long size);
26
extern void vmfree_area_pages(unsigned long address, unsigned long size);
27
extern int vmalloc_area_pages(unsigned long address, unsigned long size,
27
extern int vmalloc_area_pages(unsigned long address, unsigned long size,
28
                              int gfp_mask, pgprot_t prot);
28
                              int gfp_mask, pgprot_t prot);
29
extern void *vcalloc(unsigned long nmemb, unsigned long elem_size);
29
30
30
/*
31
/*
31
 *	Allocate any pages
32
 *	Allocate any pages
(-)linux-2.4.20-gentoo-r5/kernel/ksyms.c (+1 lines)
Lines 116-121 Link Here
116
EXPORT_SYMBOL(vfree);
116
EXPORT_SYMBOL(vfree);
117
EXPORT_SYMBOL(__vmalloc);
117
EXPORT_SYMBOL(__vmalloc);
118
EXPORT_SYMBOL(vmalloc_to_page);
118
EXPORT_SYMBOL(vmalloc_to_page);
119
EXPORT_SYMBOL(vcalloc);
119
EXPORT_SYMBOL(mem_map);
120
EXPORT_SYMBOL(mem_map);
120
EXPORT_SYMBOL(remap_page_range);
121
EXPORT_SYMBOL(remap_page_range);
121
EXPORT_SYMBOL(max_mapnr);
122
EXPORT_SYMBOL(max_mapnr);
(-)linux-2.4.20-gentoo-r5/mm/mempool.c (+20 lines)
Lines 266-273 Link Here
266
	pool->free(element, pool->pool_data);
266
	pool->free(element, pool->pool_data);
267
}
267
}
268
268
269
/*
270
 * A commonly used alloc and free fn.
271
 */
272
void *mempool_alloc_slab(int gfp_mask, void *pool_data)
273
{
274
       kmem_cache_t *mem = (kmem_cache_t *) pool_data;
275
       return kmem_cache_alloc(mem, gfp_mask);
276
}
277
278
void mempool_free_slab(void *element, void *pool_data)
279
{
280
       kmem_cache_t *mem = (kmem_cache_t *) pool_data;
281
       kmem_cache_free(mem, element);
282
}
283
284
285
269
EXPORT_SYMBOL(mempool_create);
286
EXPORT_SYMBOL(mempool_create);
270
EXPORT_SYMBOL(mempool_resize);
287
EXPORT_SYMBOL(mempool_resize);
271
EXPORT_SYMBOL(mempool_destroy);
288
EXPORT_SYMBOL(mempool_destroy);
272
EXPORT_SYMBOL(mempool_alloc);
289
EXPORT_SYMBOL(mempool_alloc);
273
EXPORT_SYMBOL(mempool_free);
290
EXPORT_SYMBOL(mempool_free);
291
EXPORT_SYMBOL(mempool_alloc_slab);
292
EXPORT_SYMBOL(mempool_free_slab);
293
(-)linux-2.4.20-gentoo-r5/mm/vmalloc.c (+19 lines)
Lines 327-329 Link Here
327
	read_unlock(&vmlist_lock);
327
	read_unlock(&vmlist_lock);
328
	return buf - buf_start;
328
	return buf - buf_start;
329
}
329
}
330
331
void *vcalloc(unsigned long nmemb, unsigned long elem_size)
332
{
333
	unsigned long size;
334
	void *addr;
335
336
	/*
337
	 * Check that we're not going to overflow.
338
	 */
339
	if (nmemb > (ULONG_MAX / elem_size))
340
		return NULL;
341
342
	size = nmemb * elem_size;
343
	addr = vmalloc(size);
344
	if (addr)
345
		memset(addr, 0, size);
346
347
	return addr;
348
}

Return to bug 22768