⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dstream.c

📁 be文件系统实现的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (mi->data.size >= MAX_INDIRECT_RANGE) {        /* XXXdbg -- growing double indirect blocks! */        printf("grow the double indirect blocks....\n");        return E2BIG;    }    return -1;}static voidshrink_double_indirect(myfs_info *myfs, myfs_inode *mi,                       fs_off_t new_size_rounded){    int       bsize = myfs->dsb.block_size, free_block, free_block2;    fs_off_t  i, j, max_index = bsize / sizeof(fs_off_t);    fs_off_t *block, *block2;    block = get_block(myfs->fd, mi->data.double_indirect, bsize);    if (block == NULL) {        myfs_die("error getting double indirect block %ld for inode %ld\n",                 mi->data.double_indirect, mi->inode_num);    }    if (new_size_rounded < MAX_INDIRECT_RANGE) {        i = 0;        j = 0;    } else {        i = ((new_size_rounded-MAX_INDIRECT_RANGE) / INDIRECT_SIZE);        j = ((new_size_rounded-MAX_INDIRECT_RANGE) % INDIRECT_SIZE) /bsize;    }    free_block  = (i == 0);    free_block2 = (j == 0);            for(; i < max_index; i++) {        if (block[i] == 0)            break;                        block2 = get_block(myfs->fd, block[i], bsize);        if (block2) {            for (; j < max_index; j++) {                if (myfs_free_blocks(myfs, block2[j], 1) != 0)                    printf("1: error freeing double indirect block %ld "                           "for inode %ld\n", block2[j],mi->inode_num);            }                        release_block(myfs->fd, block[i]);        }                if (free_block2) {            if (myfs_free_blocks(myfs, block[i], 1) != 0)                printf("1: error freeing double indirect block %ld "                       "for inode %ld\n", block[i], mi->inode_num);        }                j = 0;                /* for the next time through the loop */        free_block2 = 1;    }            release_block(myfs->fd, mi->data.double_indirect);        if (free_block) {        if (myfs_free_blocks(myfs, mi->data.double_indirect, 1) != 0)            printf("3: error freeing double indirect block %ld for "                   "inode %ld\n",mi->data.double_indirect,mi->inode_num);        mi->data.double_indirect = 0;    }}static intshrink_dstream(myfs_info *myfs, myfs_inode *mi, fs_off_t new_size){    int       bsize = myfs->dsb.block_size, free_block, free_block2;    fs_off_t  i, j, max_index = bsize / sizeof(fs_off_t);    fs_off_t  addr, offset;    fs_off_t  cur_size_rounded, new_size_rounded;    fs_off_t *block, *block2;        if (new_size > MAX_DOUBLE_INDIRECT_RANGE)        return E2BIG;    /* round up the current file size to the next block boundary */    cur_size_rounded = (mi->data.size + bsize - 1) & ~(bsize - 1);    /* round up the new file size to the next block boundary */    new_size_rounded = (new_size - 1 + bsize - 1) & ~(bsize - 1);    if (cur_size_rounded == new_size_rounded) {  /* can shrink in-place */        mi->data.size = new_size;        return 0;    }    /*       start trimming the fat at the double indirect blocks and work       backwards from there.    */       if (new_size_rounded < MAX_DOUBLE_INDIRECT_RANGE &&        mi->data.double_indirect) {        shrink_double_indirect(myfs, mi, new_size_rounded);    }        /* now see if we have to trim off indirect blocks */    if (new_size_rounded < MAX_INDIRECT_RANGE && mi->data.indirect) {        if (new_size_rounded > MAX_DIRECT_RANGE)            i = (new_size_rounded - MAX_DIRECT_RANGE) / bsize;        else            i = 0;                free_block = (i == 0);        block = get_block(myfs->fd, mi->data.indirect, bsize);        for(; i < max_index; i++) {            if (block[i] == 0)                break;            if (myfs_free_blocks(myfs, block[i], 1) != 0)                printf("1: error freeing indirect block %ld for inode %ld\n",                       block[i], mi->inode_num);        }        release_block(myfs->fd, mi->data.indirect);        if (free_block) {            if (myfs_free_blocks(myfs, mi->data.indirect, 1) != 0)                printf("1: error freeing indirect block %ld for inode %ld\n",                       mi->data.indirect, mi->inode_num);            mi->data.indirect = 0;        }    }        /* now we trim the indirect blocks */    if (new_size_rounded < DIRECT_SIZE) {        i = new_size_rounded / bsize;        for(; i < NUM_DIRECT_BLOCKS; i++){            if (mi->data.direct[i] == 0)                break;                        if (myfs_free_blocks(myfs, mi->data.direct[i], 1) != 0)                printf("error free'ing direct data block %ld\n",                       mi->data.direct[i]);            mi->data.direct[i] = 0;        }    }    mi->data.size = new_size;    return 0;}intmyfs_write_data_stream(myfs_info *myfs, myfs_inode *mi,                           fs_off_t pos, const char *buf, size_t *_len){    int       i, offset, bsize = myfs->dsb.block_size, err;    size_t    len = *_len, amt;    fs_off_t  addr;    char     *block;        if (len == 0)    /* just a quick check */        return 0;    if (pos < 0)        pos = 0;        if (pos + len > mi->data.size) {        err = grow_dstream(myfs, mi, pos + len);        if (err) {            printf("grow dstream failed!\n");            return err;        }        mi->last_modified_time = time(NULL);        update_inode(myfs, mi);        write_super_block(myfs);    }    *_len = 0;    /* this will now count up */        addr = file_pos_to_disk_addr(myfs, mi, pos);    if (addr < 0)        return EINVAL;    if ((pos % bsize) != 0) { /* then we have to work up to a block boundary */        block = get_block(myfs->fd, addr, bsize);        if (block == NULL)            return EINVAL;        offset = (pos % bsize);        if (len < (bsize - offset))            amt = len;        else            amt = (bsize - offset);        memcpy(&block[offset], buf, amt);        buf   += amt;        pos   += amt;        *_len += amt;        mark_blocks_dirty(myfs->fd, addr, 1);        release_block(myfs->fd, addr);    }    /* this is the main data writing loop */    for(; *_len < len; *_len+=amt) {        addr = file_pos_to_disk_addr(myfs, mi, pos);        if (addr < 0)            return EINVAL;        block = get_block(myfs->fd, addr, bsize);        if (block == NULL)            return EINVAL;        if ((len - *_len) < bsize)            amt = len - *_len;        else            amt = bsize;        memcpy(block, buf, amt);        buf   += amt;        pos   += amt;        mark_blocks_dirty(myfs->fd, addr, 1);        release_block(myfs->fd, addr);    }    mi->last_modified_time = time(NULL);    update_inode(myfs, mi);    return 0;}intmyfs_set_file_size(myfs_info *myfs, myfs_inode *mi, fs_off_t new_size){    int err = 0;        if (new_size == mi->data.size)        return 0;    if (new_size < mi->data.size)        err = shrink_dstream(myfs, mi, new_size);    else        err = grow_dstream(myfs, mi, new_size);                if (err == 0) {        mi->last_modified_time = time(NULL);        update_inode(myfs, mi);        write_super_block(myfs);    }            return err;}intmyfs_free_data_stream(myfs_info *myfs, myfs_inode *mi){    shrink_dstream(myfs, mi, 0);    write_super_block(myfs);        return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -