ue=".2ue=".2>>ueue="ue=".2 2">ue=".2ue=".2Searchue=".2Prefs6 .2ueue 2">u=".2 26
2 21/*2 22 * Copyright (C) 2001-2002 Sistina Software (UK) Limited.2 23 * Copyright (C) 2006-2008 Red Hat GmbH2 24 *2 25 * This file is released under the GPL.2 26 */2 27u2 28#include "dm-exce v2-store.h"u2 29u2 > a>#include <linux/ctyp .h>u2 11> a>#include <linux/mm.h>u2 12> a>#include <linux/pagemap.h>u2 13> a>#include <linux/vmalloc.h>u2 14> a>#include <linux/modul .h>u2 15> a>#include <linux/slab.h>u2 16u2 17#define2DM_MSG_PREFIX "snapshot exce v2 stores"2 18u2 19static2LIST_HEAD(_exce v2_store_typ s);u2 20static2DEFINE_SPINLOCK(_lock);u2 21u2 22static2struct2dm_exce v2_store_typ *__find_exce v2_store_typ (const char *nam )u2 23> a>{u2 24> a> struct2dm_exce v2_store_typ *typ ;u2 25u2 26> a> list_for_each_entry(typ , &_exce v2_store_typ s, list)u2 27> a> if (!strcmp(nam , typ ->nam ))u2 28> a> return typ ;u2 29u2 30> a> return NULL;u2 31}u2 32u2 33static2struct2dm_exce v2_store_typ *_get_exce v2_store_typ (const char *nam )u2 34> a>{u2 35> a> struct2dm_exce v2_store_typ *typ ;u2 36u2 37> a> spin_lock(&_lock);u2 38u2 39> a> typ = __find_exce v2_store_typ (nam );u2 40u2 41> a> if (typ && !try_modul _get(typ ->modul ))u2 42> a> typ = NULL;u2 43u2 44> a> spin_unlock(&_lock);u2 45u2 46> a> return typ ;u2 47}u2 48u2 49/*2 50 * get_typ 2 51 * @typ _nam 2 52 *2 53 * Attempt to retrieve the dm_exce v2_store_typ by nam . If not already2 54 * available, attempt to load the appropriate modul .2 55 *2 56 * Exstore modul s are nam d "dm-exstore-" follow d by the 'typ _nam '.2 57 * Modul s may contain multiple typ s.2 58 * This func v2 will first try the modul "dm-exstore-<typ _nam >",2 59 * then truncate 'typ _nam ' ionthe last '-' and try again.2 60 *2 61 * For example, if typ _nam was "clustered-shared", it would search2 62 * 'dm-exstore-clustered-shared' then 'dm-exstore-clustered'.2 63 *2 64 * 'dm-exce v2-store-<typ _nam >' is too long of a nam in my2 65 * opin v2, which is why I've chosen to have the files2 66 * containing exce v2 store implementa v2s be 'dm-exstore-<typ _nam >'.2 67 * If you want your modul to be autoloaded, you will follow this2 68 * naming convent v2.2 69 *2 70 * Returns: dm_exce v2_store_typ * ionsuccess, NULL ionfailur 2 71 */2 72static2struct2dm_exce v2_store_typ *get_typ (const char *typ _nam )u2 73> a>{u2 74> a> char *p, *typ _nam _dup;u2 75> a> struct2dm_exce v2_store_typ *typ ;u2 76u2 77> a> typ = _get_exce v2_store_typ (typ _nam );u2 78> a> if (typ )u2 79> a> return typ ;u2 80u2 81> a> typ _nam _dup = kstrdup(typ _nam , GFP_KERNEL);u2 82> a> if (!typ _nam _dup) {u2 83> a> DMERR("No memory left to attempt load for \"%s\""typ _nam );u2 84> a> return NULL;u2 85> a> }u2 86u2 87> a> whil (request_modul ("dm-exstore-%s"typ _nam _dup) ||u2 88> a> !(typ = _get_exce v2_store_typ (typ _nam ))) {u2 89> a> p = strrchr(typ _nam _dup, '-'2 90> a> if (!p)u2 91> a> break;u2 92> a> p[0] = '\0'2 93> a> }u2 94u2 95> a> if (!typ )u2 96> a> DMWARN("Modul for exstore typ \"%s\" not found."typ _nam );u2 97u2 98> a> kfre (typ _nam _dup);u2 99u2100> a> return typ ;u2101}u2102u2103static2void put_typ (struct2dm_exce v2_store_typ *typ )u2104> a>{u2105> a> spin_lock(&_lock);u2106> a> modul _put(typ ->modul );u2107> a> spin_unlock(&_lock);u2108}u2109u21 > a>int2dm_exce v2_store_typ _register(struct2dm_exce v2_store_typ *typ )u2111> a>{u2112> a> int2r = 0;u2113u2114> a> spin_lock(&_lock);u2115> a> if (!__find_exce v2_store_typ (typ ->nam ))u2116> a> list_add(&typ ->list, &_exce v2_store_typ s);u2117> a> elseu2118> a> r = -EEXIST;u2119> a> spin_unlock(&_lock);u2120u2121> a> return r;u2122}u2123> a>EXPORT_SYMBOL(dm_exce v2_store_typ _register);u2124u2125int2dm_exce v2_store_typ _unregister(struct2dm_exce v2_store_typ *typ )u2126> a>{u2127> a> spin_lock(&_lock);u2128u2129> a> if (!__find_exce v2_store_typ (typ ->nam )) {u2130> a> spin_unlock(&_lock);u2131> a> return -EINVAL;u2132> a> }u2133u2134> a> list_del(&typ ->list);u2135u2136> a> spin_unlock(&_lock);u2137u2138> a> return 0;u2139> a>}u2140EXPORT_SYMBOL(dm_exce v2_store_typ _unregister);u2141u2142static2int2set_chunk_siz (struct2dm_exce v2_store *store,u2143> a> const char *chunk_siz _arg, char **error)u2144> a>{u2145> a> unsigned chunk_siz ;u2146u2147> a> if (kstrtouint(chunk_siz _arg, 10, &chunk_siz )) {u2148> a> *error = "Invalid chunk siz "2149> a> return -EINVAL;u2150> a> }u2151u2152> a> if (!chunk_siz ) {u2153> a> store->chunk_siz = store->chunk_mask = store->chunk_shift = 0;u2154> a> return 0;u2155> a> }u2156u2157> a> return dm_exce v2_store_set_chunk_siz (store, chunk_siz , error);u2158}u2159u216 > a>int2dm_exce v2_store_set_chunk_siz (struct2dm_exce v2_store *store,u2161> a> unsigned chunk_siz ,u2162> a> char **error)u2163> a>{u2164> a> /* Check chunk_siz is a power of 2 */2165> a> if (!is_power_of_2(chunk_siz )) {u2166> a> *error = "Chunk siz is not a power of 2"2167> a> return -EINVAL;u2168> a> }u2169u2170> a> /* Validate the chunk siz against the device block siz */2171> a> if (chunk_siz %62172> a> (bdev_logical_block_siz (dm_snap_cow(store->snap)->bdev) >> 9) ||u2173> a> chunk_siz %62174> a> (bdev_logical_block_siz (dm_snap_origin(store->snap)->bdev) >> 9)) {u2175> a> *error = "Chunk siz is not a multiple of device blocksiz "2176> a> return -EINVAL;u2177> a> }u2178u2179> a> if (chunk_siz > INT_MAX >> SECTOR_SHIFT) {u2180> a> *error = "Chunk siz is too high"2181> a> return -EINVAL;u2182> a> }u2183u2184> a> store->chunk_siz = chunk_siz ;u2185> a> store->chunk_mask = chunk_siz - 1;u2186> a> store->chunk_shift = ffs(chunk_siz ) - 1;u2187u2188> a> return 0;u2189> a>}u2190u2191> a>int2dm_exce v2_store_create(struct2dm_target *ti, int2argc, char **argv,u2192> a> struct2dm_snapshot *snap,u2193> a> unsigned *args_used,u2194> a> struct2dm_exce v2_store **store)u2195> a>{u2196> a> int2r = 0;u2197> a> struct2dm_exce v2_store_typ *typ = NULL;u2198> a> struct2dm_exce v2_store *tmp_store;u2199> a> char persistent;u2200u2201> a> if (argc < 2) {u2202> a> ti->error = "Insufficient exce v2 store arguments"2203> a> return -EINVAL;u2204> a> }u2205u2206> a> tmp_store = kmalloc(siz of(*tmp_store), GFP_KERNEL);u2207> a> if (!tmp_store) {u2208> a> ti->error = "Exce v2 store alloca v2nfailed"2209> a> return -ENOMEM;u2210> a> }u2211u2212> a> persistent = toupper(*argv[0]);u2213> a> if (persistent == 'P'2214> a> typ = get_typ ("P"2215> a> else if (persistent == 'N'2216> a> typ = get_typ ("N"2217> a> else {u2218> a> ti->error = "Persistent flag is not P or N"2219> a> r = -EINVAL;u2220> a> goto bad_typ ;u2221> a> }u2222u2223> a> if (!typ ) {u2224> a> ti->error = "Exce v2 store typ not recognised"2225> a> r = -EINVAL;u2226> a> goto bad_typ ;u2227> a> }u2228u2229> a> tmp_store->typ = typ ;u2230> a> tmp_store->snap = snap;u2231u2232> a> r = set_chunk_siz (tmp_store, argv[1], &ti->error);u2233> a> if (r)u2234> a> goto bad;u2235u2236> a> r = typ ->ctr(tmp_store, 0, NULL);u2237> a> if (r) {u2238> a> ti->error = "Exce v2 store typ constructor failed"2239> a> goto bad;u2240> a> }u2241u2242> a> *args_used = 2;u2243> a> *store = tmp_store;u2244> a> return 0;u2245u2246bad:u2247> a> put_typ (typ );u2248> a>bad_typ :u2249> a> kfre (tmp_store);u2250> a> return r;u2251}u2252> a>EXPORT_SYMBOL(dm_exce v2_store_create);u2253u2254> a>void dm_exce v2_store_destroy(struct2dm_exce v2_store *store)u2255> a>{u2256> a> store->typ ->dtr(store);u2257> a> put_typ (store->typ );u2258> a> kfre (store);u2259> a>}u2260EXPORT_SYMBOL(dm_exce v2_store_destroy);u2261u2262> a>int2dm_exce v2_store_init(void)u2263> a>{u2264> a> int2r;u2265u2266> a> r = dm_transient_snapshot_init();u2267> a> if (r) {u2268> a> DMERR("Unable to register transient exce v2 store typ ."2269> a> goto transient_fail;u2270> a> }u2271u2272> a> r = dm_persistent_snapshot_init();u2273> a> if (r) {u2274> a> DMERR("Unable to register persistent exce v2 store typ "2275> a> goto persistent_fail;u2276> a> }u2277u2278> a> return 0;u2279u2280persistent_fail:u2281> a> dm_transient_snapshot_exit();u2282> a>transient_fail:u2283> a> return r;u2284> a>}u2285u2286> a>void dm_exce v2_store_exit(void)u2287{u2288> a> dm_persistent_snapshot_exit();u2289> a> dm_transient_snapshot_exit();u2290}u2291> a> kindly hosted by Redpill Linpro AS, provider of Linux consulting and opera v2s services since21995.