欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

device-mapper塊級(jí)重刪(dmdedup)<3>代碼結(jié)構(gòu)(4)

六、代碼結(jié)構(gòu)(4) I/O “小”寫(xiě)流程

創(chuàng)新互聯(lián)建站服務(wù)項(xiàng)目包括普陀網(wǎng)站建設(shè)、普陀網(wǎng)站制作、普陀網(wǎng)頁(yè)制作以及普陀網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,普陀網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到普陀省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!


上一篇,介紹了dm dedup的寫(xiě)流程,這一篇,介紹它的一個(gè)特殊流程

如果我們接收到的對(duì)齊bio但是它的size < block_size,那么這時(shí)候是不能直接進(jìn)行hash的。

需要將它的缺少的部分讀出來(lái),填充成一個(gè)完整的block_size才能計(jì)算hash。

接下來(lái)我們就介紹這一部分的代碼流程。

static int handle_write(struct dedup_config *dc, struct bio *bio)
{
    u64 lbn;
    u8 hash[MAX_DIGEST_SIZE];
    struct hash_pbn_value hashpbn_value;
    u32 vsize;
    struct bio *new_bio = NULL;
    int r;
    /* If there is a data corruption make the device read-only */
    if (dc->corrupted_blocks > dc->fec_fixed)
    return -EIO;
    dc->writes++;
    /* Read-on-write handling */
    if (bio->bi_iter.bi_size < dc->block_size) {
        dc->reads_on_writes++;
        new_bio = prepare_bio_on_write(dc, bio);
        if (!new_bio || IS_ERR(new_bio))
        return -ENOMEM;
        bio = new_bio;
    }
    /*.....*/
}

對(duì)于“小”寫(xiě)這種操作,也被叫做reads_on_writes,或者read_motify_write

一起看看這個(gè)new_bio是如何被構(gòu)造出來(lái)的。

struct bio *prepare_bio_on_write(struct dedup_config *dc, struct bio *bio)
{
    int r;
    sector_t lbn;
    uint32_t vsize;
    struct lbn_pbn_value lbnpbn_value;
    struct bio *clone;
    //DMINFO("\nEntered prepare bio on write");
    lbn = compute_sector(bio, dc);
    (void) sector_div(lbn, dc->sectors_per_block);
    /* check for old or new lbn and fetch the appropriate pbn */
    r = dc->kvs_lbn_pbn->kvs_lookup(dc->kvs_lbn_pbn, (void *)&lbn,
    sizeof(lbn), (void *)&lbnpbn_value, &vsize);
    if (r == -ENODATA)
    clone = prepare_bio_without_pbn(dc, bio);
    else if (r == 0)
    clone = prepare_bio_with_pbn(dc, bio,
         lbnpbn_value.pbn * dc->sectors_per_block);
    else
    return ERR_PTR(r);
    //DMINFO("\nExiting prpare_bio_on_write");
    return clone;
}

我們注意:這里compute_sector算出來(lái)的,是bio sector的lbn

①:它有以下幾種情況:

[x---y]
[x--------z]   ->   x/block_size=lbn
 
    [x----y]
[a--------y]   ->   x/block_size=lbn
 
    [x--y]
[a----------z]  ->   x/block_size=lbn

他們都會(huì)得到相同的lbn=x/block_size

        ② dc->kvs_lbn_pbn->kvs_lookup

這里需要將剛才算出來(lái)的lbn來(lái)求出是否存在,不存在填充zero。

接下啦就是兩種情況了,這個(gè)lbn是否存在pbn。

    一、 lbn without pbn  "clone 

         prepare_bio_without_pbn(dc, bio);"

static struct bio *prepare_bio_without_pbn(struct dedup_config *dc,
   struct bio *bio)
{
    int r = 0;
    struct bio *clone = NULL;
    clone = create_bio(dc, bio);
    if (!clone)
    goto out;
    zero_fill_bio(clone);
    r = merge_data(dc, bio_page(clone), bio);
    if (r < 0)
    return ERR_PTR(r);
    out:
    return clone;
}

這個(gè)很容易理解,既然不存在lbn_pbn的對(duì)應(yīng)關(guān)系,那么這里就是直接填充zero。

這里用了內(nèi)核提供的函數(shù)zero_fill_bio。如果我做,我可能不知道這個(gè)函數(shù),大家要利用這個(gè)函數(shù)。

那么這里很簡(jiǎn)單,就是先創(chuàng)建一個(gè)null的bio,然后把這個(gè)bio的page全部填充成zero。

在和bio的進(jìn)行合并。這里merge_data是代碼實(shí)現(xiàn)的,我們看一下。

static int merge_data(struct dedup_config *dc, struct page *page,
      struct bio *bio)
{
    sector_t bi_sector = bio->bi_iter.bi_sector;
    void *src_page_vaddr, *dest_page_vaddr;
    int position, err = 0;
    struct bvec_iter iter;
    struct bio_vec bvec;
    /* Relative offset in terms of sector size */
    position = sector_div(bi_sector, dc->sectors_per_block);
    if (!page || !bio_page(bio)) {
        err = -EINVAL;
        goto out;
    }
    /* Locating the right sector to merge */
    dest_page_vaddr = page_address(page) + to_bytes(position);
    bio_for_each_segment(bvec, bio, iter) {
        src_page_vaddr = page_address(bio_iter_page(bio, iter)) + bio_iter_offset(bio, iter);
        /* Merging Data */
        memmove(dest_page_vaddr, src_page_vaddr, bio_iter_len(bio, iter));
        /* Updating destinaion address */
        dest_page_vaddr += bio_iter_len(bio, iter);
    }
    out:
    return err;
}

我們做塊級(jí)功能研發(fā)的人,要對(duì)內(nèi)存和bio sectors操作也要熟悉,

我曾經(jīng)有段時(shí)間自己寫(xiě)代碼就被segments和sectors各種對(duì)應(yīng)繞暈。

這個(gè)代碼寫(xiě)的還是比較鮮明的,先找出bi_sector在block_size內(nèi)的位置

比如                       

sector [01234567]     [01234567]
s         <data>           free<>  
page   <00000000>    ---><000data0>

                   

                               position就是3

        這時(shí)候,用page_address將[position]的數(shù)據(jù)轉(zhuǎn)換成ptr

        然后將data memmove到3456的<0-0>的ptr上面就可以了。

        那么有一點(diǎn)復(fù)雜的是<  data >他也可能是割裂的比如:

       

sector   [01234567]      [01234567]      [01234567]
s1          <da>        free<s1>        free<s1>
s2            <ta>             <ta>       free<s2>
page     <00000000>   --><000da000>    --><000data0>

                

       這里需要將多個(gè)segments的page,s1和s2的內(nèi)容,分別memmove到page里。

  一、 lbn without pbn  "clone 

         prepare_bio_with_pbn(dc, bio);"

    這里實(shí)現(xiàn)的思路,是既然發(fā)現(xiàn)了pbn,那么就把pbn讀出來(lái),然后把新的內(nèi)容覆蓋再寫(xiě)

這種方式就是標(biāo)準(zhǔn)的讀-改-寫(xiě),通常在I/O小于region_size的情況下,需要這么做。

因?yàn)樾枰猙lock_size對(duì)齊,所以從pbn讀一整個(gè)block_size出來(lái)。

static int fetch_whole_block(struct dedup_config *dc,
     uint64_t pbn, struct page_list *pl)
{
    struct dm_io_request iorq;
    struct dm_io_region where;
    unsigned long error_bits;
    where.bdev = dc->data_dev->bdev;
    where.sector = pbn;
    where.count = dc->sectors_per_block;
    iorq.bi_op = REQ_OP_READ;
    iorq.bi_op_flags = 0;
    iorq.mem.type = DM_IO_PAGE_LIST;
    iorq.mem.ptr.pl = pl;
    iorq.mem.offset = 0;
    iorq.notify.fn = NULL;
    iorq.client = dc->io_client;
    return dm_io(&iorq, 1, &where, &error_bits);
}
static struct bio *prepare_bio_with_pbn(struct dedup_config *dc,
struct bio *bio, uint64_t pbn)
{
    int r = 0;
    struct page_list *pl;
    struct bio *clone = NULL;
    pl = kmalloc(sizeof(*pl), GFP_NOIO);
    if (!pl)
        goto out;
    /*
     * Since target I/O size is 4KB currently, we need only one page to
     * store the data. However, if the target I/O size increases, we need
     * to allocate more pages and set this linked list correctly.
     */
    pl->page = alloc_pages(GFP_NOIO, 0);
    if (!pl->page)
        goto out_allocfail;
    pl->next = NULL;
    r = fetch_whole_block(dc, pbn, pl);
    if (r < 0)
        goto out_fail;
    
    r = merge_data(dc, pl->page, bio);
    if (r < 0)
        goto out_fail;
    
    clone = create_bio(dc, bio);
    if (!clone)
        goto out_fail;
    
    copy_pages(pl->page, clone);
out_fail:
    free_pages((unsigned long) page_address(pl->page), 0);
    out_allocfail:
    kfree(pl);
out:
    if (r < 0)
        return ERR_PTR(r);
    return clone;
}

已經(jīng)讀出來(lái)的pl->page的pbn的內(nèi)容和bio做merge,這個(gè)和上面zero的情況一下。

最后再將merge好的,數(shù)據(jù)拷貝到bio_new中,去做下一輪handle_write處理,也就是上一篇的內(nèi)容。


這一篇的內(nèi)容比較簡(jiǎn)單,所以沒(méi)有圖示,


--------------未完待續(xù)--------------

【本文只在51cto博客作者 “底層存儲(chǔ)技術(shù)” https://blog.51cto.com/12580077 個(gè)人發(fā)布,公眾號(hào)發(fā)布:存儲(chǔ)之谷】,如需轉(zhuǎn)載,請(qǐng)于本人聯(lián)系,謝謝。

分享題目:device-mapper塊級(jí)重刪(dmdedup)<3>代碼結(jié)構(gòu)(4)
網(wǎng)站路徑:http://aaarwkj.com/article22/pcddcc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機(jī)微信公眾號(hào)、全網(wǎng)營(yíng)銷推廣、網(wǎng)站排名、手機(jī)網(wǎng)站建設(shè)、電子商務(wù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化
国产怡红院在线视频观看| 亚洲av男人电影天堂| 国产精品人成在线观看不卡| 一区不卡在线视频免费国产| 国产我和子的乱视频亲生| 久久亚洲av电影网站| 97福利影院在线观看| 偷拍福利视频一区二区三区| 久久久久国产综合精品| 日本中文字幕激情在线| 久久综合激情亚洲欧美专区| 色哟哟亚洲精品一区二区| 欧美伦理片三级在线观看| 成人av在线天堂一区二区三区| 女人的天堂av免费在线观看| 亚洲国产黄片在线播放| 日本理论高清在线观看| 日本最新一区二区三区视频| 日本久久在线观看视频| 国产一级无码免费视频| 精品福利视频一区二区| 国语少妇高潮对白在线| 精品一区二区久久久久久网精| 琪琪精品免费一区二区三区 | 嫩草网站国产精品一区二 | 久久激情日本人妻av免费| 中文字幕一区精品日韩| 精品一区二区人妻乱交| 日韩精品一区二区三区人妻视频 | 2020中文字字幕在线不卡| 精品欧美激情精品一区| 国产亚洲av综合人人精品| 中文字幕日韩高清乱码| 亚洲天堂av成人在线观看| 欧美日韩台湾一区二区| 91久久国产综合久久91| 国产精品国产三级区| 青青草原激情综合网| av欧美激情在线观看| 日日狠狠久久偷偷综合色| 欧美黑人在线一区二区|