示例#1
0
文件: lessfsck.c 项目: crass/lessfs
void check_inodes()
{
    char *key, *value;
    int size;
    int ksize;
    DDSTAT *ddstat;
    DBT *data;
    unsigned long long inode;
    char *nfi = "NFI";
    CRYPTO *crypto;
    struct stat stbuf;
    char *blockdatadir;

    if (NULL == config->blockdatabs) {
        blockdatadir = s_dirname(config->blockdata);
        stat(blockdatadir, &stbuf);
        free(blockdatadir);
    } else {
        stat(config->blockdata, &stbuf);
    }
    /* traverse records */
    tchdbiterinit(dbp);
    while ((key = tchdbiternext(dbp, &ksize)) != NULL) {
        show_progress();
        if (0 == memcmp(key, nfi, 3)) {
            value = tchdbget(dbp, key, strlen(key), &size);
            memcpy(&inode, value, sizeof(unsigned long long));
            free(value);
        } else {
            memcpy(&inode, key, sizeof(unsigned long long));
            data = search_dbdata(dbp, &inode, sizeof(unsigned long long));
            if (inode == 0) {
                crypto = (CRYPTO *) data->data;
            } else {
                ddstat = value_to_ddstat(data);
                if ( 0 == check_inode_orphaned(ddstat)) {
                   if (S_ISREG(ddstat->stbuf.st_mode)) {
                      if ( NULL != config->blockdatabs ) { 
                        check_inode_structure(ddstat);   
                      } else {
                        file_check_inode_structure(ddstat);   
                      }    
                   }
                } else {
                   printf("Deleting corrupted inode %llu\n",(unsigned long long)ddstat->stbuf.st_ino);
                   search_and_delete_dbdirent(ddstat);
                   delete_key(dbp, key, ksize);
                }
                ddstatfree(ddstat);
            }
            DBTfree(data);
        }
        free(key);
    }

}
示例#2
0
文件: lessfsck.c 项目: crass/lessfs
void file_check_inode_structure(DDSTAT *ddstat)
{
   INOBNO inobno;
   bool found=0;
   DBT *data;
   DBT *blockdata;
   DBT *ddbuf;

   unsigned long long real_size;

   inobno.blocknr=0;
   inobno.inode=ddstat->stbuf.st_ino;

   while (1){
     data=fscheck_block_exists(inobno);
     if ( NULL != data ) {
        blockdata=file_tgr_read_data(data->data);
        if ( NULL == blockdata ) {
           printf("inode %llu-%llu\n",inobno.inode,inobno.blocknr);
           inobno.blocknr--;
           printhash ("hash not found, file is truncated",data->data);
           purge_dbb_beyond(&inobno);
           break;
        }
        file_get_or_set_dbu(data);
        DBTfree(blockdata);
        DBTfree(data);
        found=1;
     } else break;
     inobno.blocknr++;
   }
   real_size=BLKSIZE * inobno.blocknr;
   if ( found  && real_size>ddstat->stbuf.st_size+BLKSIZE ) {
     printf("inode %llu size %llu mismatch, restore size to %llu bytes\n",(unsigned long long)ddstat->stbuf.st_ino,(unsigned long long)ddstat->stbuf.st_size,real_size);
     ddstat->stbuf.st_size=real_size;
     ddbuf = create_ddbuf(ddstat->stbuf, ddstat->filename, real_size);
     bin_write_dbdata(dbp, &inobno.inode,
                      sizeof(unsigned long long), (void *) ddbuf->data,
                      ddbuf->size);
     DBTfree(ddbuf);
   }
   return;
}
示例#3
0
文件: lessfsck.c 项目: crass/lessfs
/* return 1 when the symlink has no reference */
int relink_symlink(DDSTAT *ddstat)
{
    int ret=1;
    DBT *data;

    printf("Moving orphaned symlink inode %llu to lost_found\n",(unsigned long long)ddstat->stbuf.st_ino);
    /* traverse records */
    data=search_dbdata(dbs,&ddstat->stbuf.st_ino,sizeof(unsigned long long));
    if ( NULL != data ) {
      DBTfree(data);
      ret=0;
    }
    return(ret);
}
示例#4
0
文件: lessfsck.c 项目: crass/lessfs
unsigned long long check_inuse(unsigned char *lfshash)
{
    unsigned long long counter;
    DBT *data;

    if (NULL == lfshash)
        return (0);

    data = search_dbdata(dbu, lfshash, config->hashlen);
    if (NULL == data) {
        LDEBUG("check_inuse nothing found return 0.");
        return (0);
    }
    memcpy(&counter, data->data, sizeof(counter));
    DBTfree(data);
    return counter;
}
示例#5
0
文件: lessfsck.c 项目: crass/lessfs
void check_directory_structure()
{
    BDBCUR *cur;
    char *key, *value;
    int size;
    int hasparent;
    unsigned long long dir;
    unsigned long long lastdir=0;
    unsigned long long ent;
    int multi=0;
    DBT *data;
    

    /* traverse records */
recheck:
    cur = tcbdbcurnew(dbdirent);
    tcbdbcurfirst(cur);
    while ((key = tcbdbcurkey2(cur)) != NULL) {
        show_progress(); 
        memcpy(&dir, key, sizeof(dir));
        if ( lastdir == dir ) {
           if ( multi == 2 ) {
              tcbdbcurnext(cur);
              continue;
           } else {
              multi=1;
           }
        } else multi=0;
        value = tcbdbcurval(cur, &size);;
        if (value) {
            memcpy(&ent, value, sizeof(ent));
            data = search_dbdata(dbp, &ent, sizeof(unsigned long long));
            if (NULL == data) {
                printf("%ccheck_directory_structure : delete inode %llu present in dbdirent but not found in dbp.\n", BACKSPACE,ent);
                btdelete_curkey(dbdirent, &dir, sizeof(unsigned long long),
                                &ent, sizeof(unsigned long long));
                free(value);
                free(key);
                tcbdbcurdel(cur);
                goto recheck;
            } 
            DBTfree(data);
            free(value);
            if ( multi == 1 ) {
               multi++;
               if ( dir > 1 ) { // Skip the root directory.
               // This is a directory, check if it is linked.
                  hasparent=check_directory_has_parent(dir);
                  if ( hasparent == 0 ) {
                     printf("Directory with inode number %llu is orphaned, relink to lost+found\n", dir);
                     btbin_write_dup(dbdirent, &lafinode, sizeof(unsigned long long),
                            &dir, sizeof(unsigned long long));
                  }
               }
            }
        }
        lastdir=dir;
        free(key);
        tcbdbcurnext(cur);
    }
    tcbdbcurdel(cur);
}
示例#6
0
int file_unlink_file(const char *path)
{
    int res = 0;
    int haslinks = 0;
    int dir_links = 0;
    struct stat st;
    struct stat dirst;
    char *dname;
    char *bname;
    unsigned char *stiger;
    unsigned long long inode;
    unsigned long long counter = 0;
    INUSE *inuse;
    unsigned long long done = 0;
    time_t thetime;
    void *vdirnode;
    DBT *bdata;
    DBT *ddbuf;
    DBT *dataptr;
    DDSTAT *ddstat;
    DINOINO dinoino;
    INOBNO inobno;
    char *filename;

    FUNC;

    LDEBUG("unlink_file %s", path);
    res = dbstat(path, &st);
    if (res == -ENOENT)
        return (res);
    inode = st.st_ino;
    //release_global_lock();
    //wait_io_pending(inode);
    //sync_flush_dtaq();
    haslinks = st.st_nlink;
    thetime = time(NULL);
    dname = s_dirname((char *) path);
    /* Change ctime and mtime of the parentdir Posix std posix behavior */
    res = update_parent_time(dname,0);
    bname = s_basename((char *) path);
    res = dbstat(dname, &dirst);
    if (S_ISLNK(st.st_mode) && haslinks == 1) {
        LDEBUG("unlink symlink %s inode %llu", path, inode);
        delete_key(dbs, &inode, sizeof(unsigned long long));
        LDEBUG("unlink symlink done %s", path);
    }
    inobno.inode = inode;
    inobno.blocknr = counter;
    while (done < st.st_size) {
        get_dbb_lock();
        bdata = search_memhash(dbbm, &inobno, sizeof(INOBNO));
        if ( NULL == bdata ) {
           bdata = search_dbdata(dbb, &inobno, sizeof(INOBNO));
        }
        release_dbb_lock();
        if (bdata == NULL) {
            LDEBUG("%llu is sparse", counter);
            done = done + BLKSIZE;
            counter++;
            inobno.blocknr = counter;
            continue;
        }
        stiger = s_malloc(bdata->size);
        memcpy(stiger, bdata->data, bdata->size);
        loghash("search inuse for ", stiger);
        inuse = file_get_inuse(stiger);
        if (NULL != inuse) {
           if (haslinks == 1) {
               if (inuse->inuse == 1) {
                   loghash("unlink_file delete dbu,dbdta for ", stiger);
                   delete_inuse(stiger);
                   put_on_freelist(inuse);
               } else {
                   if (inuse->inuse > 1)
                       inuse->inuse--;
                   loghash("updateInUse dbu,dbdta for ", stiger);
                   file_update_inuse(stiger, inuse);
               }
           }
           free(inuse);
        } else log_fatal_hash("unlink_file inuse not found",stiger);
        free(stiger);
        DBTfree(bdata);
        if (haslinks == 1) {
            LDEBUG("unlink_file : delete inode %llu - %llu", inobno.inode,
                   inobno.blocknr);
            delete_dbb(&inobno);
        }
        counter++;
        inobno.blocknr = counter;
        done = done + BLKSIZE;
    }
    if (haslinks == 1) {
        if (0 !=
            (res =
             btdelete_curkey(dbdirent, &dirst.st_ino,
                             sizeof(unsigned long long), &inode,
                             sizeof(unsigned long long)))) {
            free(bname);
            free(dname);
            return (res);
        }
        delete_key(dbp, (unsigned char *) &inode,
                   sizeof(unsigned long long));
    } else {
        dataptr =
            search_dbdata(dbp, (unsigned char *) &inode,
                          sizeof(unsigned long long));
        if (dataptr == NULL) {
            die_dataerr("Failed to find file %llu", inode);
        }
        ddstat = value_to_ddstat(dataptr);
        ddstat->stbuf.st_nlink--;
        ddstat->stbuf.st_ctim.tv_sec = thetime;
        ddstat->stbuf.st_ctim.tv_nsec=0;
        ddstat->stbuf.st_mtim.tv_sec = thetime;
        ddstat->stbuf.st_mtim.tv_nsec=0;
        dinoino.dirnode = dirst.st_ino;
        dinoino.inode = ddstat->stbuf.st_ino;
        dir_links = count_dirlinks(&dinoino, sizeof(DINOINO));
        res =
            btdelete_curkey(dbl, &dinoino, sizeof(DINOINO), bname,
                            strlen(bname));
        btdelete_curkey(dbl, &ddstat->stbuf.st_ino,
                        sizeof(unsigned long long), &dinoino,
                        sizeof(DINOINO));
// Restore to regular file settings and clean up.
        if (ddstat->stbuf.st_nlink == 1) {
            vdirnode =
                btsearch_keyval(dbl, &ddstat->stbuf.st_ino,
                                sizeof(unsigned long long), NULL, 0);
            memcpy(&dinoino, vdirnode, sizeof(DINOINO));
            free(vdirnode);
            filename =
                (char *) btsearch_keyval(dbl, &dinoino, sizeof(DINOINO),
                                         NULL, 0);
            memcpy(&ddstat->filename, filename, strlen(filename) + 1);
            free(filename);
            LDEBUG
                ("unlink_file : Restore %s to regular file settings and clean up.",
                 ddstat->filename);
            btdelete_curkey(dbl, &dinoino, sizeof(DINOINO),
                            ddstat->filename, strlen(ddstat->filename));
            btdelete_curkey(dbl, &ddstat->stbuf.st_ino,
                            sizeof(unsigned long long), &dinoino,
                            sizeof(DINOINO));
            btdelete_curkey(dbl, &inode, sizeof(unsigned long long),
                            &dinoino, sizeof(DINOINO));
            res = 0;
        }
        if (dir_links == 1) {
            if (0 !=
                (res =
                 btdelete_curkey(dbdirent, &dirst.st_ino,
                                 sizeof(unsigned long long), &inode,
                                 sizeof(unsigned long long)))) {
                die_dataerr("unlink_file : Failed to delete record.");
            }
        }
        ddbuf = create_ddbuf(ddstat->stbuf, ddstat->filename);
        bin_write_dbdata(dbp, &inode,
                         sizeof(unsigned long long), (void *) ddbuf->data,
                         ddbuf->size);
        DBTfree(dataptr);
        DBTfree(ddbuf);
        ddstatfree(ddstat);
    }
    free(bname);
    free(dname);
    EFUNC;
    return (res);
}
示例#7
0
void file_partial_truncate_block(struct stat *stbuf, 
				unsigned long long blocknr, unsigned int offset)
{
    unsigned char *blockdata;
    compr *uncompdata;
    INOBNO inobno;
    DBT *data;
	OFFHASH *offhash;
	off_t offsetfile;
    unsigned char *stiger;
    INUSE *inuse;
    DBT cachedata;
    QDTA *dta;

    FUNC;
    LDEBUG("file_partial_truncate_block : inode %llu, blocknr %llu, offset %u",
           stbuf->st_ino, blocknr, offset);
    inobno.inode = stbuf->st_ino;
    inobno.blocknr = blocknr;
    get_dbb_lock();
    data = search_memhash(dbbm, &inobno, sizeof(INOBNO));
    if ( NULL == data ) {
       data = search_dbdata(dbb, &inobno, sizeof(INOBNO));
    }
    release_dbb_lock();
    if (NULL == data) {
        LDEBUG("file_partial_truncate_block : deletion of non existent block.");
        return;
    }
	offhash = (OFFHASH *) data->data;
    stiger = s_malloc(data->size);
    loghash("file_partial_truncate_block : search tiger ", stiger);
    memcpy(stiger, offhash->stiger, config->hashlen);
	offsetfile = offhash->offset;
    DBTfree(data);

    blockdata = s_malloc(BLKSIZE);
    memset(blockdata, 0, BLKSIZE);
// First try the cache
    get_moddb_lock();
       data = search_memhash(dbdtaq, stiger, config->hashlen);
       if ( NULL != data ) die_dataerr("file_partial_truncate_block : not data in cache expected");
    release_moddb_lock();
    if ( NULL == data ) {
       data = file_tgr_read_data(stiger);
       if ( NULL != data ) {
          LDEBUG("file_partial_truncate_block : clz_decompress");
          if (data->size != BLKSIZE) {
#ifdef LZO
              uncompdata = lzo_decompress(data->data, data->size);
#else
              uncompdata = clz_decompress(data->data, data->size);
#endif
              memcpy(blockdata, uncompdata->data, offset);
              comprfree(uncompdata);
          } else {
              memcpy(blockdata, data->data, offset);
          }
       }
    } else {
       dta = (QDTA *)data->data;
       cachedata.data=s_malloc(dta->size);
       memcpy(cachedata.data, dta->data, dta->size);
       cachedata.size = dta->size;
       memcpy(blockdata, cachedata.data, offset);
       free(cachedata.data);
    }
    file_commit_block(blockdata, inobno, offsetfile);
    DBTfree(data);
    free(blockdata);

    inuse = file_get_inuse(stiger);
    if (NULL == inuse)
        die_dataerr
            ("file_partial_truncate_block : unexpected block not found");
    if (inuse->inuse == 1) {
        loghash("file_partial_truncate_block : delete hash", stiger);
        put_on_freelist(inuse);
        delete_inuse(stiger);
    } else {
        if (inuse->inuse > 1)
            inuse->inuse--;
        file_update_inuse(stiger, inuse);
    }
    free(inuse);
    free(stiger);
    return;
}
示例#8
0
int file_fs_truncate(struct stat *stbuf, off_t size, char *bname)
{
    unsigned int offsetblock;
	unsigned long long inode;
    unsigned long long blocknr;
    unsigned long long lastblocknr;
    INUSE *inuse;
    unsigned char *stiger;
    off_t oldsize;
    DBT *data;
	OFFHASH *offhash;
    INOBNO inobno;
    time_t thetime;

    FUNC;
    LDEBUG("file_fs_truncate inode %llu - size %llu", stbuf->st_ino,
           (unsigned long long) size);
    thetime = time(NULL);
	inode = stbuf->st_ino;
	
    if (-1 == (blocknr = get_blocknr(inode, size - 1)))
		die_dataerr("%s: get blocknr failed.", __FUNCTION__);
	if (NULL == (offhash = get_offhash(inode, blocknr)))
		die_dataerr("%s: offhash of %llu-%llu not found.", __FUNCTION__, inode, 
			blocknr);
	
    offsetblock = size - offhash->offset;
	free(offhash);
    oldsize = stbuf->st_size;
    if (-1 == (lastblocknr = get_blocknr(inode, oldsize - 1)))
		die_dataerr("%s: get blocknr failed.", __FUNCTION__);
	
    update_filesize_cache(stbuf, size);
    LDEBUG("file_fs_truncate : truncate new block %llu, oldblock %llu",
           blocknr, lastblocknr);
    while (lastblocknr >= blocknr) {
        if ( offsetblock != 0 && lastblocknr == blocknr ) break;
        LDEBUG
            ("file_fs_truncate : Enter loop lastblocknr %llu : blocknr %llu",
             lastblocknr, blocknr);
        inobno.inode = stbuf->st_ino;
        inobno.blocknr = lastblocknr;
        get_dbb_lock();
        data = search_memhash(dbbm, &inobno, sizeof(INOBNO));
        if ( NULL == data ) {
            data = search_dbdata(dbb, &inobno, sizeof(INOBNO));
        }
        release_dbb_lock();
        if (NULL == data) {
            LDEBUG
                ("file_fs_truncate: deletion of non existent block inode : %llu, blocknr %llu",
                 inobno.inode, inobno.blocknr);
            if (lastblocknr > 0)
                lastblocknr--;
            else
                break;
// Need to continue in case of a sparse file.
            continue;
        }
		offhash = (OFFHASH *) data->data;
        stiger = s_malloc(data->size);
        memcpy(stiger, offhash->stiger, config->hashlen);
        LDEBUG("file_fs_truncate : lessfs_truncate Search to delete blocknr %llu:",
             lastblocknr);
        loghash("file_fs_truncate : tiger :", stiger);
        DBTfree(data);
        inuse = file_get_inuse(stiger);
        if (NULL == inuse)
            die_dataerr("file_fs_truncate : unexpected data error.");
        if (inuse->inuse == 1) {
            sync_flush_dtaq();
            put_on_freelist(inuse);
            loghash("file_fs_truncate : delete_inuse ",stiger); 
            delete_inuse(stiger);
            LDEBUG("file_fs_truncate : delete dbb %llu-%llu", inobno.inode, 
				inobno.blocknr);
            delete_dbb(&inobno);
        } else {
            if (inuse->inuse > 1)
                inuse->inuse--;
            LDEBUG("file_fs_truncate : delete dbb %llu-%llu", inobno.inode, 
				inobno.blocknr);
            delete_dbb(&inobno);
            file_update_inuse(stiger, inuse);
        }
        free(inuse);
        if (lastblocknr > 0)
            lastblocknr--;
        free(stiger);
    }
    LDEBUG("offsetblock = %u", offsetblock);
    if (0 != offsetblock)
        file_partial_truncate_block(stbuf, lastblocknr, offsetblock);
    return (0);
}
示例#9
0
void file_update_block(const char *blockdata, unsigned long long blocknr,
                       unsigned int offsetblock, unsigned long long size, 
                       unsigned long long inode, unsigned char *chksum, 
                       off_t offset)
{
    DBT *data = NULL;
    DBT *decrypted = NULL;
    DBT *cachedata;
    unsigned char *dbdata;
    INOBNO inobno;
    compr *uncompdata;
    BLKCACHE *blk;
    unsigned char *dtiger;
    INUSE *inuse;
    bool compressed = 1;
    QDTA *dta;
#ifndef SHA3
    word64 res[3];
#endif

    FUNC;
    LDEBUG
        ("file_update_block : inode %llu blocknr %llu offsetblock %llu, size %llu",
         inode, blocknr, (unsigned long long) offsetblock,
         (unsigned long long) size);
    inobno.inode = inode;
    inobno.blocknr = blocknr;

    dbdata = (unsigned char *) s_malloc(BLKSIZE);
    memset(dbdata, 0, BLKSIZE);
    data = try_block_cache(inode, blocknr, 0);
    if (NULL != data) {
        LDEBUG("try_block_cache : HIT");
        memcpy(dbdata, data->data, data->size);
        memcpy(dbdata + offsetblock, blockdata, size);
        add_blk_to_cache(inode, blocknr, offsetblock + size, dbdata, offset);
        update_filesize(inode, size, offsetblock, blocknr, 0, 0, 0);
        free(dbdata);
        DBTfree(data);
        return;
    } else
        LDEBUG("%s: block not found in cache.", __FUNCTION__);

// We don't need the old blockdata when we overwrite it completely anyway.
    if (offsetblock > 0 || size < BLKSIZE) {
        get_moddb_lock();
// First read the cache
        decrypted = search_memhash(dbdtaq, chksum, config->hashlen);
        if (NULL == decrypted) {
            LDEBUG("%s: Not in dbdtaq", __FUNCTION__);
            data = file_tgr_read_data(chksum);
            if (NULL == data) {
                LDEBUG("%s: Not found", __FUNCTION__);
                cachedata =
                    search_memhash(blkcache, &inobno.inode,
                                   sizeof(unsigned long long));
                if (NULL != cachedata) {
                    blk = (BLKCACHE *) cachedata->data;
#ifdef SHA3
                    dtiger=sha_binhash(blk->blockdata, BLKSIZE);
#else
                    binhash(blk->blockdata, BLKSIZE, res);
                    dtiger=(unsigned char *)&res;
#endif
                    if (0 == memcmp(dtiger, chksum, config->hashlen)) {
                        LDEBUG("%s: data alloc here", __FUNCTION__);
                        data = s_malloc(sizeof(DBT));
                        data->data = s_malloc(BLKSIZE);
                        data->size = BLKSIZE;
                        memcpy(data->data, blk->blockdata, BLKSIZE);
                        DBTfree(cachedata);
                        compressed = 0;
                    } else {
                        LDEBUG
                            ("updateBlock : Not in dbcache, out of luck.");
                        loghash("updateBlock : No data found to read ",
                                chksum);
                        die_dataerr
                            ("file_update_block : No data found to read - this should never happen: inode :%llu: blocknr :%llu",
                             inode, blocknr);
                    }
#ifdef SHA3
                    free(dtiger);
#endif
                } else {
                    log_fatal_hash("file_update_block : No data found to read ",
                            chksum);
                    die_dataerr
                        ("file_update_block : No data found to read, this should never happen: inode :%llu: blocknr :%llu",
                         inode, blocknr);
                }
            }
        } else {
            data = s_malloc(sizeof(DBT));
            dta = (QDTA *) decrypted->data;
            data->data = s_malloc(dta->size);
            memcpy(data->data, dta->data, dta->size);
            data->size = dta->size;
            DBTfree(decrypted);
            LDEBUG("data->size = %lu", data->size);
        }
        release_moddb_lock();
        if (compressed && data->size < BLKSIZE) {
#ifdef LZO
            uncompdata = lzo_decompress(data->data, data->size);
#else
            uncompdata = clz_decompress(data->data, data->size);
#endif
            memcpy(dbdata, uncompdata->data, uncompdata->size);
            comprfree(uncompdata);
        } else {
            memcpy(dbdata, data->data, data->size);
        }
        DBTfree(data);
    }
    memcpy(dbdata + offsetblock, blockdata, size);
    add_blk_to_cache(inode, blocknr, offsetblock + size, dbdata, offset);
    inuse = file_get_inuse(chksum);
    if (NULL == inuse)
        die_dataerr("file_update_block : hash not found");
    if (inuse->inuse <= 1) {
        file_delete_data_cache(chksum, &inobno);
        put_on_freelist(inuse);
        delete_inuse(chksum);
    } else {
        inuse->inuse--;
        file_update_inuse(chksum, inuse);
    }
    free(inuse);
    update_filesize(inode, size, offsetblock, blocknr, 0, 0, 0);
    free(dbdata);
    EFUNC;
    return;
}
示例#10
0
unsigned long long file_read_block(unsigned long long blocknr,
                                   const char *filename, char *blockdata,
                                   unsigned long long inode)
{
    unsigned long long ret = 0;
    DBT *data = NULL;
    DBT *decrypted = NULL;
    DBT *cachedata;
    unsigned char *stiger;
    unsigned char *dtiger;
    compr *uncompdata = NULL;
    INOBNO inobno;
    BLKCACHE *blk;
    bool compressed = 1;
    QDTA *dta;
#ifndef SHA3
    word64 res[3];
#endif

    FUNC;
    inobno.inode = inode;
    inobno.blocknr = blocknr;
    data = try_block_cache(inode, blocknr, 0);
    if (NULL != data) {
        LDEBUG("file_read_block : block %llu - %llu found in cache", inode,
               blocknr);
        memcpy(blockdata, data->data, data->size);
        ret = data->size;
        DBTfree(data);
        return (ret);
    }
    data = check_block_exists(inobno);
    if (NULL == data) {
        LDEBUG("check_block_exists : Nothing found for inode %llu - %llu",
               inobno.inode, inobno.blocknr);
        LDEBUG("DONE ret = %llu",ret);
        return (ret);
    }
// Not needed to copy this.
    stiger = s_malloc(data->size);
    memcpy(stiger, data->data, data->size);
    DBTfree(data);
// First try the cache
    get_moddb_lock();
    data = search_memhash(dbdtaq, stiger, config->hashlen);
    if (NULL == data) {
        decrypted = file_tgr_read_data(stiger);
        if (NULL != decrypted) {
            LDEBUG
                ("file_read_block : found inode %llu - %llu file_io",
                 inobno.inode, inobno.blocknr);
        } else {

            cachedata =
                search_memhash(blkcache, &inobno.inode,
                               sizeof(unsigned long long));
            if (NULL != cachedata) {
                blk = (BLKCACHE *) cachedata->data;
#ifdef SHA3
                dtiger=sha_binhash(blk->blockdata, BLKSIZE);
#else
                binhash(blk->blockdata, BLKSIZE,res);
                dtiger=(unsigned char *)&res;
#endif
                if (0 == memcmp(dtiger, stiger, config->hashlen)) {
                    decrypted = s_malloc(sizeof(DBT));
                    decrypted->data = s_malloc(BLKSIZE);
                    decrypted->size = BLKSIZE;
                    memcpy(decrypted->data, blk->blockdata, BLKSIZE);
                    compressed = 0;
                }
#ifdef SHA3
                free(dtiger);
#endif
                DBTfree(cachedata);
            }
        }
    } else {
        decrypted = s_malloc(sizeof(DBT));
        dta = (QDTA *) data->data;
        decrypted->data = s_malloc(dta->size);
        memcpy(decrypted->data, dta->data, dta->size);
        decrypted->size = dta->size;
        DBTfree(data);
    }
    release_moddb_lock();
    if (decrypted->size > BLKSIZE)
        die_dataerr("file_read_block : data has grown beyond blocksize %lu",
                    decrypted->size);
    if (compressed && decrypted->size != BLKSIZE) {
#ifdef LZO
        uncompdata = lzo_decompress(decrypted->data, decrypted->size);
#else
        uncompdata = clz_decompress(decrypted->data, decrypted->size);
#endif
        memcpy(blockdata, uncompdata->data, uncompdata->size);
        ret = uncompdata->size;
        comprfree(uncompdata);
    } else {
        memcpy(blockdata, decrypted->data, decrypted->size);
        ret = decrypted->size;
    }
    DBTfree(decrypted);
    free(stiger);
    EFUNC;
    return (ret);
}
示例#11
0
void add_file_block(BLKDTA * blkdta)
{
    INOBNO inobno;
    DBT *cachedata = NULL;
    INUSE *inuse;
	OFFHASH *offhash;

    inobno.inode = blkdta->inode;
    inobno.blocknr = blkdta->blocknr;

    FUNC;
    LDEBUG("add_file_block : inode %llu - %llu", inobno.inode,
           inobno.blocknr);
    if (blkdta->bsize + blkdta->offsetblock < BLKSIZE) {
// Flush the blockcache before overwriting.
        cachedata = try_block_cache(blkdta->inode, blkdta->blocknr, 0);
        if (cachedata)
            DBTfree(cachedata);
        add_blk_to_cache(blkdta->inode, blkdta->blocknr, 
			blkdta->bsize + blkdta->offsetblock, blkdta->blockfiller, 
			blkdta->offsetfile);
        LDEBUG
            ("add_file_block : wrote with add_blk_to_cache  : inode %llu - %llu size %i",
             inobno.inode, inobno.blocknr, blkdta->bsize);
        update_filesize(blkdta->inode, blkdta->bsize, blkdta->offsetblock,
                        blkdta->blocknr, blkdta->sparse, 0, 0);
        return;
    }
    inuse = file_get_inuse(blkdta->stiger);
    if (inuse == NULL) {
        if (NULL == blkdta->compressed) {
#ifdef LZO
            blkdta->compressed =
                lzo_compress(blkdta->blockfiller, BLKSIZE);
#else
            blkdta->compressed =
                clz_compress(blkdta->blockfiller, BLKSIZE);
#endif
        }
        LDEBUG("Compressed %i bytes to %lu bytes", BLKSIZE,
               blkdta->compressed->size);
        loghash("add_file_block call qdta for hash :", blkdta->stiger);
        inuse = s_malloc(sizeof(INUSE));
        inuse->inuse = 0;
        inuse->offset = get_offset(blkdta->compressed->size);
        LDEBUG("add to offset %llu", inuse->offset);
        inuse->size = blkdta->compressed->size;
        file_qdta(&inobno, blkdta->stiger, blkdta->compressed->data,
                  blkdta->compressed->size, inuse->offset);
        loghash("add_file_block queued with qdta", blkdta->stiger);
        update_filesize(blkdta->inode, blkdta->bsize, blkdta->offsetblock,
                        blkdta->blocknr, blkdta->sparse,
                        blkdta->compressed->size, 0);
    } else {
        update_filesize(blkdta->inode, blkdta->bsize, blkdta->offsetblock,
                        blkdta->blocknr, blkdta->sparse, 0, 1);
    }
    if (NULL != blkdta->compressed)
        comprfree(blkdta->compressed);
    inuse->inuse = inuse->inuse + 1;
    file_update_inuse(blkdta->stiger, inuse);
	offhash = s_malloc(sizeof(OFFHASH));
	offhash->offset = blkdta->offsetfile;
	memcpy(offhash->stiger, blkdta->stiger, config->hashlen);
    write_dbb_to_cache(&inobno, offhash);
	free(offhash);
    free(inuse);
    EFUNC;
    return;
}