lvm-snap.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:20k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * kernel/lvm-snap.c
  3.  *
  4.  * Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
  5.  *               2000 - 2002 Heinz Mauelshagen, Sistina Software
  6.  *
  7.  * LVM snapshot driver is free software; you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License as published by
  9.  * the Free Software Foundation; either version 2, or (at your option)
  10.  * any later version.
  11.  *
  12.  * LVM snapshot driver is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  * GNU General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU General Public License
  18.  * along with GNU CC; see the file COPYING.  If not, write to
  19.  * the Free Software Foundation, 59 Temple Place - Suite 330,
  20.  * Boston, MA 02111-1307, USA.
  21.  *
  22.  */
  23. /*
  24.  * Changelog
  25.  *
  26.  *    05/07/2000 - implemented persistent snapshot support
  27.  *    23/11/2000 - used cpu_to_le64 rather than my own macro
  28.  *    25/01/2001 - Put LockPage back in
  29.  *    01/02/2001 - A dropped snapshot is now set as inactive
  30.  *    14/02/2001 - tidied debug statements
  31.  *    19/02/2001 - changed rawio calls to pass in preallocated buffer_heads
  32.  *    26/02/2001 - introduced __brw_kiovec to remove a lot of conditional
  33.  *                 compiles.
  34.  *    07/03/2001 - fixed COW exception table not persistent on 2.2 (HM)
  35.  *    12/03/2001 - lvm_pv_get_number changes:
  36.  *                 o made it static
  37.  *                 o renamed it to _pv_get_number
  38.  *                 o pv number is returned in new uint * arg
  39.  *                 o -1 returned on error
  40.  *                 lvm_snapshot_fill_COW_table has a return value too.
  41.  *    15/10/2001 - fix snapshot alignment problem [CM]
  42.  *               - fix snapshot full oops (always check lv_block_exception) [CM]
  43.  *    26/06/2002 - support for new list_move macro [patch@luckynet.dynu.com]
  44.  *
  45.  */
  46. #include <linux/kernel.h>
  47. #include <linux/vmalloc.h>
  48. #include <linux/blkdev.h>
  49. #include <linux/smp_lock.h>
  50. #include <linux/types.h>
  51. #include <linux/iobuf.h>
  52. #include <linux/lvm.h>
  53. #include <linux/devfs_fs_kernel.h>
  54. #include "lvm-internal.h"
  55. static char *lvm_snap_version __attribute__ ((unused)) = "LVM "LVM_RELEASE_NAME" snapshot code ("LVM_RELEASE_DATE")n";
  56. extern const char *const lvm_name;
  57. extern int lvm_blocksizes[];
  58. void lvm_snapshot_release(lv_t *);
  59. static int _write_COW_table_block(vg_t *vg, lv_t *lv, int idx,
  60.   const char **reason);
  61. static void _disable_snapshot(vg_t *vg, lv_t *lv);
  62. static inline int __brw_kiovec(int rw, int nr, struct kiobuf *iovec[],
  63.        kdev_t dev, unsigned long b[], int size,
  64.        lv_t *lv) {
  65. return brw_kiovec(rw, nr, iovec, dev, b, size);
  66. }
  67. static int _pv_get_number(vg_t * vg, kdev_t rdev, uint *pvn)
  68. {
  69. uint p;
  70. for (p = 0; p < vg->pv_max; p++) {
  71. if (vg->pv[p] == NULL)
  72. continue;
  73. if (vg->pv[p]->pv_dev == rdev)
  74. break;
  75. }
  76. if (p >= vg->pv_max) {
  77. /* bad news, the snapshot COW table is probably corrupt */
  78. printk(KERN_ERR
  79.        "%s -- _pv_get_number failed for rdev = %un",
  80.        lvm_name, rdev);
  81. return -1;
  82. }
  83. *pvn = vg->pv[p]->pv_number;
  84. return 0;
  85. }
  86. #define hashfn(dev,block,mask,chunk_size) 
  87. ((HASHDEV(dev)^((block)/(chunk_size))) & (mask))
  88. static inline lv_block_exception_t *
  89. lvm_find_exception_table(kdev_t org_dev, unsigned long org_start, lv_t * lv)
  90. {
  91. struct list_head * hash_table = lv->lv_snapshot_hash_table, * next;
  92. unsigned long mask = lv->lv_snapshot_hash_mask;
  93. int chunk_size = lv->lv_chunk_size;
  94. lv_block_exception_t * ret;
  95. int i = 0;
  96. hash_table = &hash_table[hashfn(org_dev, org_start, mask, chunk_size)];
  97. ret = NULL;
  98. for (next = hash_table->next; next != hash_table; next = next->next)
  99. {
  100. lv_block_exception_t * exception;
  101. exception = list_entry(next, lv_block_exception_t, hash);
  102. if (exception->rsector_org == org_start &&
  103.     exception->rdev_org == org_dev)
  104. {
  105. if (i)
  106. {
  107. /* fun, isn't it? :) */
  108. #ifdef list_move
  109. list_move(next, hash_table);
  110. #else
  111. list_del(next);
  112. list_add(next, hash_table);
  113. #endif
  114. }
  115. ret = exception;
  116. break;
  117. }
  118. i++;
  119. }
  120. return ret;
  121. }
  122. inline void lvm_hash_link(lv_block_exception_t * exception,
  123.   kdev_t org_dev, unsigned long org_start,
  124.   lv_t * lv)
  125. {
  126. struct list_head * hash_table = lv->lv_snapshot_hash_table;
  127. unsigned long mask = lv->lv_snapshot_hash_mask;
  128. int chunk_size = lv->lv_chunk_size;
  129. if (!hash_table)
  130. BUG();
  131. hash_table = &hash_table[hashfn(org_dev, org_start, mask, chunk_size)];
  132. list_add(&exception->hash, hash_table);
  133. }
  134. /*
  135.  * Determine if we already have a snapshot chunk for this block.
  136.  * Return: 1 if it the chunk already exists
  137.  *         0 if we need to COW this block and allocate a new chunk
  138.  *        -1 if the snapshot was disabled because it ran out of space
  139.  *
  140.  * We need to be holding at least a read lock on lv->lv_lock.
  141.  */
  142. int lvm_snapshot_remap_block(kdev_t * org_dev, unsigned long * org_sector,
  143.      unsigned long pe_start, lv_t * lv)
  144. {
  145. int ret;
  146. unsigned long pe_off, pe_adjustment, __org_start;
  147. kdev_t __org_dev;
  148. int chunk_size = lv->lv_chunk_size;
  149. lv_block_exception_t * exception;
  150. if (!lv->lv_block_exception)
  151. return -1;
  152. pe_off = pe_start % chunk_size;
  153. pe_adjustment = (*org_sector-pe_off) % chunk_size;
  154. __org_start = *org_sector - pe_adjustment;
  155. __org_dev = *org_dev;
  156. ret = 0;
  157. exception = lvm_find_exception_table(__org_dev, __org_start, lv);
  158. if (exception)
  159. {
  160. *org_dev = exception->rdev_new;
  161. *org_sector = exception->rsector_new + pe_adjustment;
  162. ret = 1;
  163. }
  164. return ret;
  165. }
  166. void lvm_drop_snapshot(vg_t *vg, lv_t *lv_snap, const char *reason)
  167. {
  168. kdev_t last_dev;
  169. int i;
  170. /* no exception storage space available for this snapshot
  171.    or error on this snapshot --> release it */
  172. invalidate_buffers(lv_snap->lv_dev);
  173. /* wipe the snapshot since it's inconsistent now */
  174. _disable_snapshot(vg, lv_snap);
  175. for (i = last_dev = 0; i < lv_snap->lv_remap_ptr; i++) {
  176. if ( lv_snap->lv_block_exception[i].rdev_new != last_dev) {
  177. last_dev = lv_snap->lv_block_exception[i].rdev_new;
  178. invalidate_buffers(last_dev);
  179. }
  180. }
  181. lvm_snapshot_release(lv_snap);
  182. lv_snap->lv_status &= ~LV_ACTIVE;
  183. printk(KERN_INFO
  184.        "%s -- giving up to snapshot %s on %s: %sn",
  185.        lvm_name, lv_snap->lv_snapshot_org->lv_name, lv_snap->lv_name,
  186.        reason);
  187. }
  188. static inline int lvm_snapshot_prepare_blocks(unsigned long *blocks,
  189.        unsigned long start,
  190.        int nr_sectors,
  191.        int blocksize)
  192. {
  193. int i, sectors_per_block, nr_blocks;
  194. sectors_per_block = blocksize / SECTOR_SIZE;
  195. if (start & (sectors_per_block - 1))
  196. return 0;
  197. nr_blocks = nr_sectors / sectors_per_block;
  198. start /= sectors_per_block;
  199. for (i = 0; i < nr_blocks; i++)
  200. blocks[i] = start++;
  201. return 1;
  202. }
  203. inline int lvm_get_blksize(kdev_t dev)
  204. {
  205. int correct_size = BLOCK_SIZE, i, major;
  206. major = MAJOR(dev);
  207. if (blksize_size[major])
  208. {
  209. i = blksize_size[major][MINOR(dev)];
  210. if (i)
  211. correct_size = i;
  212. }
  213. return correct_size;
  214. }
  215. #ifdef DEBUG_SNAPSHOT
  216. static inline void invalidate_snap_cache(unsigned long start, unsigned long nr,
  217.  kdev_t dev)
  218. {
  219. struct buffer_head * bh;
  220. int sectors_per_block, i, blksize, minor;
  221. minor = MINOR(dev);
  222. blksize = lvm_blocksizes[minor];
  223. sectors_per_block = blksize >> 9;
  224. nr /= sectors_per_block;
  225. start /= sectors_per_block;
  226. for (i = 0; i < nr; i++)
  227. {
  228. bh = get_hash_table(dev, start++, blksize);
  229. if (bh)
  230. bforget(bh);
  231. }
  232. }
  233. #endif
  234. int lvm_snapshot_fill_COW_page(vg_t * vg, lv_t * lv_snap)
  235. {
  236. int id = 0, is = lv_snap->lv_remap_ptr;
  237. ulong blksize_snap;
  238. lv_COW_table_disk_t * lv_COW_table = (lv_COW_table_disk_t *)
  239. page_address(lv_snap->lv_COW_table_iobuf->maplist[0]);
  240. if (is == 0)
  241. return 0;
  242. is--;
  243. blksize_snap =
  244. lvm_get_blksize(lv_snap->lv_block_exception[is].rdev_new);
  245. is -= is % (blksize_snap / sizeof(lv_COW_table_disk_t));
  246. memset(lv_COW_table, 0, blksize_snap);
  247. for ( ; is < lv_snap->lv_remap_ptr; is++, id++) {
  248. /* store new COW_table entry */
  249. lv_block_exception_t *be = lv_snap->lv_block_exception + is;
  250. uint pvn;
  251. if (_pv_get_number(vg, be->rdev_org, &pvn))
  252. goto bad;
  253. lv_COW_table[id].pv_org_number = cpu_to_le64(pvn);
  254. lv_COW_table[id].pv_org_rsector = cpu_to_le64(be->rsector_org);
  255. if (_pv_get_number(vg, be->rdev_new, &pvn))
  256. goto bad;
  257. lv_COW_table[id].pv_snap_number = cpu_to_le64(pvn);
  258. lv_COW_table[id].pv_snap_rsector = cpu_to_le64(be->rsector_new);
  259. }
  260. return 0;
  261.  bad:
  262. printk(KERN_ERR "%s -- lvm_snapshot_fill_COW_page failed", lvm_name);
  263. return -1;
  264. }
  265. /*
  266.  * writes a COW exception table sector to disk (HM)
  267.  *
  268.  * We need to hold a write lock on lv_snap->lv_lock.
  269.  */
  270. int lvm_write_COW_table_block(vg_t * vg, lv_t *lv_snap)
  271. {
  272. int r;
  273. const char *err;
  274. if((r = _write_COW_table_block(vg, lv_snap,
  275.        lv_snap->lv_remap_ptr - 1, &err)))
  276. lvm_drop_snapshot(vg, lv_snap, err);
  277. return r;
  278. }
  279. /*
  280.  * copy on write handler for one snapshot logical volume
  281.  *
  282.  * read the original blocks and store it/them on the new one(s).
  283.  * if there is no exception storage space free any longer --> release snapshot.
  284.  *
  285.  * this routine gets called for each _first_ write to a physical chunk.
  286.  *
  287.  * We need to hold a write lock on lv_snap->lv_lock.  It is assumed that
  288.  * lv->lv_block_exception is non-NULL (checked by lvm_snapshot_remap_block())
  289.  * when this function is called.
  290.  */
  291. int lvm_snapshot_COW(kdev_t org_phys_dev,
  292.      unsigned long org_phys_sector,
  293.      unsigned long org_pe_start,
  294.      unsigned long org_virt_sector,
  295.      vg_t *vg, lv_t* lv_snap)
  296. {
  297. const char * reason;
  298. unsigned long org_start, snap_start, snap_phys_dev, virt_start, pe_off;
  299. unsigned long phys_start;
  300. int idx = lv_snap->lv_remap_ptr, chunk_size = lv_snap->lv_chunk_size;
  301. struct kiobuf * iobuf = lv_snap->lv_iobuf;
  302. unsigned long *blocks = iobuf->blocks;
  303. int blksize_snap, blksize_org, min_blksize, max_blksize;
  304. int max_sectors, nr_sectors;
  305. /* check if we are out of snapshot space */
  306. if (idx >= lv_snap->lv_remap_end)
  307. goto fail_out_of_space;
  308. /* calculate physical boundaries of source chunk */
  309. pe_off = org_pe_start % chunk_size;
  310. org_start = org_phys_sector - ((org_phys_sector-pe_off) % chunk_size);
  311. virt_start = org_virt_sector - (org_phys_sector - org_start);
  312. /* calculate physical boundaries of destination chunk */
  313. snap_phys_dev = lv_snap->lv_block_exception[idx].rdev_new;
  314. snap_start = lv_snap->lv_block_exception[idx].rsector_new;
  315. #ifdef DEBUG_SNAPSHOT
  316. printk(KERN_INFO
  317.        "%s -- COW: "
  318.        "org %s faulting %lu start %lu, snap %s start %lu, "
  319.        "size %d, pe_start %lu pe_off %lu, virt_sec %lun",
  320.        lvm_name,
  321.        kdevname(org_phys_dev), org_phys_sector, org_start,
  322.        kdevname(snap_phys_dev), snap_start,
  323.        chunk_size,
  324.        org_pe_start, pe_off,
  325.        org_virt_sector);
  326. #endif
  327. blksize_org = lvm_sectsize(org_phys_dev);
  328. blksize_snap = lvm_sectsize(snap_phys_dev);
  329. max_blksize = max(blksize_org, blksize_snap);
  330. min_blksize = min(blksize_org, blksize_snap);
  331. max_sectors = KIO_MAX_SECTORS * (min_blksize>>9);
  332. if (chunk_size % (max_blksize>>9))
  333. goto fail_blksize;
  334. /* Don't change org_start, we need it to fill in the exception table */
  335. phys_start = org_start;
  336. while (chunk_size)
  337. {
  338. nr_sectors = min(chunk_size, max_sectors);
  339. chunk_size -= nr_sectors;
  340. iobuf->length = nr_sectors << 9;
  341. if (!lvm_snapshot_prepare_blocks(blocks, phys_start,
  342.  nr_sectors, blksize_org))
  343. goto fail_prepare;
  344. if (__brw_kiovec(READ, 1, &iobuf, org_phys_dev, blocks,
  345.  blksize_org, lv_snap) != (nr_sectors<<9))
  346. goto fail_raw_read;
  347. if (!lvm_snapshot_prepare_blocks(blocks, snap_start,
  348.  nr_sectors, blksize_snap))
  349. goto fail_prepare;
  350. if (__brw_kiovec(WRITE, 1, &iobuf, snap_phys_dev, blocks,
  351.  blksize_snap, lv_snap) != (nr_sectors<<9))
  352. goto fail_raw_write;
  353. phys_start += nr_sectors;
  354. snap_start += nr_sectors;
  355. }
  356. #ifdef DEBUG_SNAPSHOT
  357. /* invalidate the logical snapshot buffer cache */
  358. invalidate_snap_cache(virt_start, lv_snap->lv_chunk_size,
  359.       lv_snap->lv_dev);
  360. #endif
  361. /* the original chunk is now stored on the snapshot volume
  362.    so update the execption table */
  363. lv_snap->lv_block_exception[idx].rdev_org = org_phys_dev;
  364. lv_snap->lv_block_exception[idx].rsector_org = org_start;
  365. lvm_hash_link(lv_snap->lv_block_exception + idx,
  366.       org_phys_dev, org_start, lv_snap);
  367. lv_snap->lv_remap_ptr = idx + 1;
  368. if (lv_snap->lv_snapshot_use_rate > 0) {
  369. if (lv_snap->lv_remap_ptr * 100 / lv_snap->lv_remap_end >= lv_snap->lv_snapshot_use_rate)
  370. wake_up_interruptible(&lv_snap->lv_snapshot_wait);
  371. }
  372. return 0;
  373. /* slow path */
  374. out:
  375. lvm_drop_snapshot(vg, lv_snap, reason);
  376. return 1;
  377. fail_out_of_space:
  378. reason = "out of space";
  379. goto out;
  380. fail_raw_read:
  381. reason = "read error";
  382. goto out;
  383. fail_raw_write:
  384. reason = "write error";
  385. goto out;
  386. fail_blksize:
  387. reason = "blocksize error";
  388. goto out;
  389. fail_prepare:
  390. reason = "couldn't prepare kiovec blocks "
  391. "(start probably isn't block aligned)";
  392. goto out;
  393. }
  394. int lvm_snapshot_alloc_iobuf_pages(struct kiobuf * iobuf, int sectors)
  395. {
  396. int bytes, nr_pages, err, i;
  397. bytes = sectors * SECTOR_SIZE;
  398. nr_pages = (bytes + ~PAGE_MASK) >> PAGE_SHIFT;
  399. err = expand_kiobuf(iobuf, nr_pages);
  400. if (err) goto out;
  401. err = -ENOMEM;
  402. iobuf->locked = 1;
  403. iobuf->nr_pages = 0;
  404. for (i = 0; i < nr_pages; i++)
  405. {
  406. struct page * page;
  407. page = alloc_page(GFP_KERNEL);
  408. if (!page) goto out;
  409. iobuf->maplist[i] = page;
  410. LockPage(page);
  411. iobuf->nr_pages++;
  412. }
  413. iobuf->offset = 0;
  414. err = 0;
  415. out:
  416. return err;
  417. }
  418. static int calc_max_buckets(void)
  419. {
  420. unsigned long mem;
  421. mem = num_physpages << PAGE_SHIFT;
  422. mem /= 100;
  423. mem *= 2;
  424. mem /= sizeof(struct list_head);
  425. return mem;
  426. }
  427. int lvm_snapshot_alloc_hash_table(lv_t * lv)
  428. {
  429. int err;
  430. unsigned long buckets, max_buckets, size;
  431. struct list_head * hash;
  432. buckets = lv->lv_remap_end;
  433. max_buckets = calc_max_buckets();
  434. buckets = min(buckets, max_buckets);
  435. while (buckets & (buckets-1))
  436. buckets &= (buckets-1);
  437. size = buckets * sizeof(struct list_head);
  438. err = -ENOMEM;
  439. hash = vmalloc(size);
  440. lv->lv_snapshot_hash_table = hash;
  441. if (!hash)
  442. goto out;
  443. lv->lv_snapshot_hash_table_size = size;
  444. lv->lv_snapshot_hash_mask = buckets-1;
  445. while (buckets--)
  446. INIT_LIST_HEAD(hash+buckets);
  447. err = 0;
  448. out:
  449. return err;
  450. }
  451. int lvm_snapshot_alloc(lv_t * lv_snap)
  452. {
  453. int ret, max_sectors;
  454. /* allocate kiovec to do chunk io */
  455. ret = alloc_kiovec(1, &lv_snap->lv_iobuf);
  456. if (ret) goto out;
  457. max_sectors = KIO_MAX_SECTORS << (PAGE_SHIFT-9);
  458. ret = lvm_snapshot_alloc_iobuf_pages(lv_snap->lv_iobuf, max_sectors);
  459. if (ret) goto out_free_kiovec;
  460. /* allocate kiovec to do exception table io */
  461. ret = alloc_kiovec(1, &lv_snap->lv_COW_table_iobuf);
  462. if (ret) goto out_free_kiovec;
  463. ret = lvm_snapshot_alloc_iobuf_pages(lv_snap->lv_COW_table_iobuf,
  464.      PAGE_SIZE/SECTOR_SIZE);
  465. if (ret) goto out_free_both_kiovecs;
  466. ret = lvm_snapshot_alloc_hash_table(lv_snap);
  467. if (ret) goto out_free_both_kiovecs;
  468. out:
  469. return ret;
  470. out_free_both_kiovecs:
  471. unmap_kiobuf(lv_snap->lv_COW_table_iobuf);
  472. free_kiovec(1, &lv_snap->lv_COW_table_iobuf);
  473. lv_snap->lv_COW_table_iobuf = NULL;
  474. out_free_kiovec:
  475. unmap_kiobuf(lv_snap->lv_iobuf);
  476. free_kiovec(1, &lv_snap->lv_iobuf);
  477. lv_snap->lv_iobuf = NULL;
  478. vfree(lv_snap->lv_snapshot_hash_table);
  479. lv_snap->lv_snapshot_hash_table = NULL;
  480. goto out;
  481. }
  482. void lvm_snapshot_release(lv_t * lv)
  483. {
  484. if (lv->lv_block_exception)
  485. {
  486. vfree(lv->lv_block_exception);
  487. lv->lv_block_exception = NULL;
  488. }
  489. if (lv->lv_snapshot_hash_table)
  490. {
  491. vfree(lv->lv_snapshot_hash_table);
  492. lv->lv_snapshot_hash_table = NULL;
  493. lv->lv_snapshot_hash_table_size = 0;
  494. }
  495. if (lv->lv_iobuf)
  496. {
  497.         kiobuf_wait_for_io(lv->lv_iobuf);
  498. unmap_kiobuf(lv->lv_iobuf);
  499. free_kiovec(1, &lv->lv_iobuf);
  500. lv->lv_iobuf = NULL;
  501. }
  502. if (lv->lv_COW_table_iobuf)
  503. {
  504.         kiobuf_wait_for_io(lv->lv_COW_table_iobuf);
  505. unmap_kiobuf(lv->lv_COW_table_iobuf);
  506. free_kiovec(1, &lv->lv_COW_table_iobuf);
  507. lv->lv_COW_table_iobuf = NULL;
  508. }
  509. }
  510. static int _write_COW_table_block(vg_t *vg, lv_t *lv_snap,
  511.   int idx, const char **reason) {
  512. int blksize_snap;
  513. int end_of_table;
  514. int idx_COW_table;
  515. uint pvn;
  516. ulong snap_pe_start, COW_table_sector_offset,
  517.       COW_entries_per_pe, COW_chunks_per_pe, COW_entries_per_block;
  518. ulong blocks[1];
  519. kdev_t snap_phys_dev;
  520. lv_block_exception_t *be;
  521. struct kiobuf *COW_table_iobuf = lv_snap->lv_COW_table_iobuf;
  522. lv_COW_table_disk_t * lv_COW_table =
  523.    ( lv_COW_table_disk_t *) page_address(lv_snap->lv_COW_table_iobuf->maplist[0]);
  524. COW_chunks_per_pe = LVM_GET_COW_TABLE_CHUNKS_PER_PE(vg, lv_snap);
  525. COW_entries_per_pe = LVM_GET_COW_TABLE_ENTRIES_PER_PE(vg, lv_snap);
  526. /* get physical addresse of destination chunk */
  527. snap_phys_dev = lv_snap->lv_block_exception[idx].rdev_new;
  528. snap_pe_start = lv_snap->lv_block_exception[idx - (idx % COW_entries_per_pe)].rsector_new - lv_snap->lv_chunk_size;
  529. blksize_snap = lvm_sectsize(snap_phys_dev);
  530.         COW_entries_per_block = blksize_snap / sizeof(lv_COW_table_disk_t);
  531.         idx_COW_table = idx % COW_entries_per_pe % COW_entries_per_block;
  532. if ( idx_COW_table == 0) memset(lv_COW_table, 0, blksize_snap);
  533. /* sector offset into the on disk COW table */
  534. COW_table_sector_offset = (idx % COW_entries_per_pe) / (SECTOR_SIZE / sizeof(lv_COW_table_disk_t));
  535.         /* COW table block to write next */
  536. blocks[0] = (snap_pe_start + COW_table_sector_offset) >> (blksize_snap >> 10);
  537. /* store new COW_table entry */
  538. be = lv_snap->lv_block_exception + idx;
  539. if(_pv_get_number(vg, be->rdev_org, &pvn))
  540. goto fail_pv_get_number;
  541. lv_COW_table[idx_COW_table].pv_org_number = cpu_to_le64(pvn);
  542. lv_COW_table[idx_COW_table].pv_org_rsector =
  543. cpu_to_le64(be->rsector_org);
  544. if(_pv_get_number(vg, snap_phys_dev, &pvn))
  545. goto fail_pv_get_number;
  546. lv_COW_table[idx_COW_table].pv_snap_number = cpu_to_le64(pvn);
  547. lv_COW_table[idx_COW_table].pv_snap_rsector =
  548. cpu_to_le64(be->rsector_new);
  549. COW_table_iobuf->length = blksize_snap;
  550. /* COW_table_iobuf->nr_pages = 1; */
  551. if (__brw_kiovec(WRITE, 1, &COW_table_iobuf, snap_phys_dev,
  552.  blocks, blksize_snap, lv_snap) != blksize_snap)
  553. goto fail_raw_write;
  554. /* initialization of next COW exception table block with zeroes */
  555. end_of_table = idx % COW_entries_per_pe == COW_entries_per_pe - 1;
  556. if (idx_COW_table % COW_entries_per_block == COW_entries_per_block - 1 || end_of_table)
  557. {
  558. /* don't go beyond the end */
  559. if (idx + 1 >= lv_snap->lv_remap_end) goto out;
  560. memset(lv_COW_table, 0, blksize_snap);
  561. if (end_of_table)
  562. {
  563. idx++;
  564. snap_phys_dev = lv_snap->lv_block_exception[idx].rdev_new;
  565. snap_pe_start = lv_snap->lv_block_exception[idx - (idx % COW_entries_per_pe)].rsector_new - lv_snap->lv_chunk_size;
  566. blksize_snap = lvm_sectsize(snap_phys_dev);
  567. blocks[0] = snap_pe_start >> (blksize_snap >> 10);
  568. } else blocks[0]++;
  569. if (__brw_kiovec(WRITE, 1, &COW_table_iobuf, snap_phys_dev,
  570.                                  blocks, blksize_snap, lv_snap) !=
  571.                     blksize_snap)
  572. goto fail_raw_write;
  573. }
  574. out:
  575. return 0;
  576. fail_raw_write:
  577. *reason = "write error";
  578. return 1;
  579. fail_pv_get_number:
  580. *reason = "_pv_get_number failed";
  581. return 1;
  582. }
  583. /*
  584.  * FIXME_1.2
  585.  * This function is a bit of a hack; we need to ensure that the
  586.  * snapshot is never made active again, because it will surely be
  587.  * corrupt.  At the moment we do not have access to the LVM metadata
  588.  * from within the kernel.  So we set the first exception to point to
  589.  * sector 1 (which will always be within the metadata, and as such
  590.  * invalid).  User land tools will check for this when they are asked
  591.  * to activate the snapshot and prevent this from happening.
  592.  */
  593. static void _disable_snapshot(vg_t *vg, lv_t *lv) {
  594. const char *err;
  595. lv->lv_block_exception[0].rsector_org = LVM_SNAPSHOT_DROPPED_SECTOR;
  596. if(_write_COW_table_block(vg, lv, 0, &err) < 0) {
  597. printk(KERN_ERR "%s -- couldn't disable snapshot: %sn",
  598.        lvm_name, err);
  599. }
  600. }