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

📄 inode.c

📁 be文件系统实现的源码
💻 C
字号:
/*  This file contains the routines that manipulate inodes.     THIS CODE COPYRIGHT DOMINIC GIAMPAOLO.  NO WARRANTY IS EXPRESSED   OR IMPLIED.  YOU MAY USE THIS CODE AND FREELY DISTRIBUTE IT FOR  NON-COMMERCIAL USE AS LONG AS THIS NOTICE REMAINS ATTACHED.  FOR COMMERCIAL USE, CONTACT DOMINIC GIAMPAOLO (dbg@be.com).  Dominic Giampaolo  dbg@be.com*/#include "myfs.h"intmyfs_create_inodes(myfs_info *myfs){    int       bsize = myfs->dsb.block_size;    fs_off_t  map_start;    fs_off_t  inodes_start;    fs_off_t  num_inodes;    fs_off_t  num_map_blocks;    fs_off_t  num_inode_blocks;    fs_off_t  i;    void     *block;    /* we allocate 1 inode for every 4 disk blocks */    num_inodes       = (myfs->dsb.num_blocks >> 2);    num_inode_blocks = (num_inodes * sizeof(myfs_inode)) / bsize;    num_map_blocks   = (num_inode_blocks / 8 / bsize) + 1;    printf("num inodes %ld num_map_blocks %ld num_inode blocks %ld\n",           num_inodes, num_map_blocks, num_inode_blocks);        if (pre_allocate_blocks(myfs, &num_map_blocks, &map_start) != 0) {        printf("failed to allocate inode map blocks\n");        return ENOSPC;    }    if (map_start != myfs->bbm.num_bitmap_blocks + 1)        printf("that's weird... map_start == %ld, not %ld\n",               map_start, myfs->bbm.num_bitmap_blocks);    if (pre_allocate_blocks(myfs, &num_inode_blocks, &inodes_start) != 0) {        printf("failed to allocate inode data blocks\n");        return ENOSPC;    }        if (inodes_start != map_start+num_map_blocks)        printf("that's weird inode_start == %ld not %ld\n", inodes_start,               map_start+num_map_blocks);            /* now we go through and zero out the inode map and the inode table */    block = get_tmp_blocks(myfs, 1);    memset(block, 0, bsize);        for(i=0; i < num_map_blocks; i++) {        if (write_blocks(myfs, map_start+i, block, 1) != 1) {            printf("error writing inode map block %ld\n", map_start+i);            break;        }    }    for(i=0; i < num_inode_blocks; i++) {        if (write_blocks(myfs, inodes_start+i, block, 1) != 1) {            printf("error writing inode data block %ld\n", inodes_start+i);            break;        }    }    free_tmp_blocks(myfs, block, 1);    myfs->dsb.num_inodes           = num_inodes;    myfs->dsb.inodes_start         = inodes_start;    myfs->dsb.num_inode_blocks     = num_inode_blocks;    myfs->dsb.inode_map_start      = map_start;    myfs->dsb.num_inode_map_blocks = num_map_blocks;    myfs->inode_map.bits    = calloc(1, num_map_blocks * bsize);    myfs->inode_map.numbits = num_inodes;    if (myfs->inode_map.bits == NULL) {        printf("couldn't allocate space for the in memory inode map\n");        return ENOMEM;    }    /* allocate inode 0 so no one else gets (to enable better error checks) */    GetFreeRangeOfBits(&myfs->inode_map, 1, NULL);    write_blocks(myfs, map_start, myfs->inode_map.bits, 1);    return 0;}intmyfs_init_inodes(myfs_info *myfs){    int bsize = myfs->dsb.block_size;    int amt;        myfs->inode_map.bits    = calloc(1, myfs->dsb.num_inode_map_blocks*bsize);    myfs->inode_map.numbits = myfs->dsb.num_inodes;    if (myfs->inode_map.bits == NULL)        return ENOMEM;    amt = read_blocks(myfs, myfs->dsb.inode_map_start,                      myfs->inode_map.bits, myfs->dsb.num_inode_map_blocks);    if (amt != myfs->dsb.num_inode_map_blocks) {        printf("failed to read the inode map!\n");        return EINVAL;    }    return 0;}voidmyfs_shutdown_inodes(myfs_info *myfs){    free(myfs->inode_map.bits);    myfs->inode_map.bits    = NULL;    myfs->inode_map.numbits = 0;}myfs_inode *myfs_allocate_inode(myfs_info *myfs, myfs_inode *parent, int mode){    int         bsize = myfs->dsb.block_size;    int         offset;    char        tmp[IDENT_NAME_LENGTH];    char       *block;    inode_addr  ia;    myfs_inode *mi;    mi = (myfs_inode *)calloc(1, sizeof(myfs_inode));    if (mi == NULL)        return NULL;    mi->etc = calloc(1, sizeof(myfs_inode_etc));    if (mi->etc == NULL) {        free(mi);        return NULL;    }    ia = GetFreeRangeOfBits(&myfs->inode_map, 1, NULL);    if (ia < 0) {        free(mi->etc);        free(mi);        printf("no inodes left!\n");        return NULL;    }        mi->magic1      = INODE_MAGIC1;    mi->uid         = getuid();    mi->gid         = getgid();    mi->mode        = mode;    mi->inode_num   = ia;    mi->create_time = time(NULL);    mi->last_modified_time = mi->create_time;    sprintf(tmp, "ino#%ld", ia);    new_lock(&mi->etc->lock, tmp);    /*      now we write the updated inode map back to disk.  we only write      the changed inode map block.  the inode itself will be written      later in update_inode().    */    block = (char *)myfs->inode_map.bits;    offset = (ia / 8 / bsize);    if (offset >= myfs->dsb.num_inode_map_blocks) {        myfs_die("inode map offset %d is too big (max %ld)\n",                 offset, myfs->dsb.num_inode_map_blocks);    }        write_blocks(myfs, myfs->dsb.inode_map_start+offset,                 &block[offset*bsize], 1);    return mi;}intmyfs_free_inode(myfs_info *myfs, inode_addr ia){    int   bsize = myfs->dsb.block_size;    int   offset;    char *block;        UnSetBV(&myfs->inode_map, ia);        /* now update the on-disk inode map. */    block = (char *)myfs->inode_map.bits;    offset = (ia / 8 / bsize);    write_blocks(myfs, myfs->dsb.inode_map_start+offset,                 &block[offset*bsize], 1);    return 0;}intupdate_inode(myfs_info *myfs, myfs_inode *mi){    int       bsize = myfs->dsb.block_size, offset;    char     *block;    fs_off_t  addr;         addr = myfs->dsb.inodes_start + ((mi->inode_num*sizeof(myfs_inode))/bsize);    offset = (mi->inode_num % (bsize / sizeof(myfs_inode)))*sizeof(myfs_inode);        if (addr > myfs->dsb.inodes_start + myfs->dsb.num_inode_blocks)        myfs_die("error updating inode %ld: addr %ld out of range (max %ld)\n",                 mi->inode_num,                 addr,                 myfs->dsb.inodes_start + myfs->dsb.num_inode_blocks);    block = get_block(myfs->fd, addr, bsize);        memcpy(&block[offset], mi, sizeof(myfs_inode));    mark_blocks_dirty(myfs->fd, addr, 1);    release_block(myfs->fd, addr);    return 0;}

⌨️ 快捷键说明

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