/* * dm-snapshot.c * * Copyright (C) 2001-2002 Sistina Software (UK) Limited. * * This file is released under the GPL. */#include<linux/blkdev.h>#include<linux/ctype.h>#include<linux/device-mapper.h>#include<linux/fs.h>#include<linux/init.h>#include<linux/kdev_t.h>#include<linux/list.h>#include<linux/mempool.h>#include<linux/module.h>#include<linux/slab.h>#include<linux/vmalloc.h>#include"dm-snap.h"#include"dm-bio-list.h"#include"kcopyd.h"#define DM_MSG_PREFIX "snapshots"/* * The percentage increment we will wake up users at */#define WAKE_UP_PERCENT 5/* * kcopyd priority of snapshot operations */#define SNAPSHOT_COPY_PRIORITY 2/* * Each snapshot reserves this many pages for io */#define SNAPSHOT_PAGES 256staticstructworkqueue_struct*ksnapd;staticvoidflush_queued_bios(structwork_struct*work);structdm_snap_pending_exception{structdm_snap_exceptione;/* * Origin buffers waiting for this to complete are held * in a bio list */structbio_listorigin_bios;structbio_listsnapshot_bios;/* * Short-term queue of pending exceptions prior to submission. */structlist_headlist;/* * The primary pending_exception is the one that holds * the ref_count and the list of origin_bios for a * group of pending_exceptions. It is always last to get freed. * These fields get set up when writing to the origin. */structdm_snap_pending_exception*primary_pe;/* * Number of pending_exceptions processing this chunk. * When this drops to zero we must complete the origin bios. * If incrementing or decrementing this, hold pe->snap->lock for * the sibling concerned and not pe->primary_pe->snap->lock unless * they are the same. */atomic_tref_count;/* Pointer back to snapshot context */structdm_snapshot*snap;/* * 1 indicates the exception has already been sent to * kcopyd. */intstarted;};/* * Hash table mapping origin volumes to lists of snapshots and * a lock to protect it */staticstructkmem_cache*exception_cache;staticstructkmem_cache*pending_cache;staticmempool_t*pending_pool;/* * One of these per registered origin, held in the snapshot_origins hash */structorigin{/* The origin device */structblock_device*bdev;structlist_headhash_list;/* List of snapshots for this origin */structlist_headsnapshots;};/* * Size of the hash table for origin volumes. If we make this * the size of the minors list then it should be nearly perfect */#define ORIGIN_HASH_SIZE 256#define ORIGIN_MASK 0xFFstaticstructlist_head*_origins;staticstructrw_semaphore_origins_lock;staticintinit_origin_hash(void){inti;_origins=kmalloc(ORIGIN_HASH_SIZE*sizeof(structlist_head),GFP_KERNEL);if(!_origins){DMERR("unable to allocate memory");return-ENOMEM;}for(i=0;i<ORIGIN_HASH_SIZE;i++)INIT_LIST_HEAD(_origins+i);init_rwsem(&