아무것도 몰라요

DeNOVA Test

9. Dedup Queue remove (dedup-queue 3부)

telomere37 2021. 7. 21. 22:29
// fs/nova/dedup.c

// Get next write entry to dedup
u64 nova_dedup_queue_get_next_entry(void){
  struct nova_dedup_queue *ptr;
  u64 ret = 0;
  if(!list_empty(&nova_dedup_queue_head.list)){
    ptr = list_entry(nova_dedup_queue_head.list.next, struct nova_dedup_queue, list);
    ret = ptr->write_entry_address;
    list_del(nova_dedup_queue_head.list.next);
    kfree(ptr);
    printk("POP from queue: %llu\n",ret);
  }
  return ret;
}



int nova_dedup_test(struct file *filp){
...

// for write entry 
  struct nova_file_write_entry *target_entry;
  u64 entry_address;
  char *buf;
  unsigned long left;
  pgoff_t index;
  int i, data_page_number =0;
  unsigned long nvmm;
  void *dax_mem = NULL;
  
  // Pop Write Entry
  buf = kmalloc(DATABLOCK_SIZE,GFP_KERNEL);
  entry_address = nova_dedup_queue_get_next_entry();
  if(entry_address!=0){
    // Read write_entry
    target_entry = nova_get_block(sb, entry_address);
    printk("write entries block info: num_pages:%d, block: %lld, pgoff: %lld\n",target_entry->num_pages, target_entry->block, target_entry->pgoff);
    // Read 4096Bytes from a write entry
    index = target_entry->pgoff;
    data_page_number = target_entry->num_pages;
    for(i=0;i<data_page_number;i++){
      nvmm = (unsigned long) (target_entry->block >> PAGE_SHIFT) + index - target_entry->pgoff;
      dax_mem = nova_get_block(sb,(nvmm << PAGE_SHIFT));
      left  = __copy_to_user(buf,dax_mem,DATABLOCK_SIZE);
      if(left){
        nova_dbg("%s ERROR!: left %lu\n",__func__,left);
        return 0;
      }


      printk("%c %c %c\n",buf[0],buf[1],buf[2]);


      index++;
    }
  }
  else printk("no entry!\n");
 ...
 }

Read Path, Write Path를 뜯어보았다. Dedup queue에서 write entry를 저장하고 있는 offset을 얻어오고, 이를 nova_get_block을 통해 읽어온다. dax_read의 개념을 아직 완벽하게 이해하지 못하겠다. pmem에 있는 것을 읽어오기 위해 특별한 것 없이 그냥 dram에 있는 것처럼 주소로 접근할 수 있는 것인가? 그게 dax의 개념이긴 하다. 아무튼, 제대로 읽혀오는 것을 확인하였고 이제 write entry에 딸린 data page들을 DATABLOCK_SIZE단위로 읽어온다. 이를 for문을 통해 반복하였다. 이를 buf에 저장하였고 이제 이를 MD5알고리즘을 통해 fingerprinting을 할 것이다. 하지만 여기서 <openssl/md5.h>를 사용하지 못한다는 것을 알았다. Kernel Crypto header를 새로 구하거나 나만의 함수를 따로 선언해야겠다.