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

📄 fsck.c

📁 MMI层OBJ不能完全编译
💻 C
📖 第 1 页 / 共 5 页
字号:

    fs.journal.i = 0;
    fs.journal.state = JOURNAL_IS_EMPTY;
    fs.journal_ram.repli = 0;
    fs.link_child = 1;   //Default link child in journal_commit()

    if (oldi == 0) {
        fs.journal.diri     = 0;
        fs.journal.oldi     = 0;
        fs.journal_ram.flags = 0xFF;
        fs.journal_ram.location = 0;
        fs.journal_ram.size     = 0;
    }
    else {
        struct inode_s *oldip = inode_addr(oldi);
        fs.journal.diri     = oldi;
        fs.journal.oldi     = oldi;
        fs.journal_ram.flags    = oldip->flags | OF_MASK;  // Clean valid flag
        fs.journal_ram.location = oldip->location;
        fs.journal_ram.size     = oldip->size;
    }
}

void journal_end(uint8 type)
{
    struct inode_s *ip = inode_addr(fs.ijournal);
    struct journal_s *addr = (struct journal_s *)
        offset2addr(location2offset(ip->location) + fs.journal_pos);
    
    tw(tr(TR_BEGIN, TrJournal, "journal_end(0x%x) {\n", type));
    tw(tr(TR_FUNC, TrJournal, "journal_pos = 0x%04x (%d)\n", fs.journal_pos,
          (fs.journal_pos - JOURNAL_POS_INITIAL) / sizeof(struct journal_s)));

    POWERFAIL_DOMAIN_BEGIN(PFM_JOURNAL);
    POWERFAIL_SET_ADDR(0);

    // If this is a create, set the object type
    if (type != 0 && fs.journal.oldi == 0)
        fs.journal_ram.flags = (fs.journal_ram.flags & OF_MASK) | type;

    // If there is no journal file, we can do without it, although we
    // certainly don't like it!
    if (fs.ijournal == 0) {
        journal_commit(0); 
        tw(tr(TR_END, TrJournal, "} No jounal file\n"));
        return;
    }
    
    POWERFAIL_BOUNDARY(JOURNAL_TEST_EMPTY);
     
    // Write RAM journal to journal file.
    if (fs.journal.state == (uint8) JOURNAL_IS_EMPTY) {
        fs.journal.state = JOURNAL_IS_WRITING;
        ffsdrv.write(addr, &fs.journal, sizeof(fs.journal));
    }
    
    POWERFAIL_BOUNDARY(JOURNAL_TEST_WRITING);
    
    // Advance journal file's state
    if (fs.journal.state == (uint8) JOURNAL_IS_WRITING) {
        fs.journal.state = JOURNAL_IS_READY;
        ffsdrv_write_byte(&addr->state, fs.journal.state);
    }
    
    POWERFAIL_BOUNDARY(JOURNAL_TEST_READY);
 
    journal_commit(0);

    // journal_commit() change the domain thus we must set it again
    POWERFAIL_DOMAIN_BEGIN(PFM_JOURNAL);
    POWERFAIL_SET_ADDR(0);
    
    POWERFAIL_BOUNDARY(JOURNAL_TEST_COMMITTED);

    // Advance journal file's state
    ffsdrv_write_byte(&addr->state, JOURNAL_IS_DONE);

    POWERFAIL_BOUNDARY(JOURNAL_TEST_DONE);

    // Advance journal
    fs.journal_pos += sizeof(struct journal_s);

    // Unless we are currently relocating the journal file itself, check if
    // journal file is near full and relocate it if it is.
    if (fs.journal_pos >= fs.journal_size - FFS_JOURNAL_MARGIN * 
		sizeof(struct journal_s) && fs.journal.oldi != fs.ijournal) {

        if (fs.journal_pos == fs.journal_size - sizeof(struct journal_s)) 
            ffs_panic(EFFS_JNLFULL);
        
        tw(tr(TR_FUNC, TrJournal, "Journal file (near) full!\n"));
        journal_create(fs.ijournal);
    }

    // Check if we have just committed the journal file itself
    if (fs.journal.oldi == fs.ijournal) {
        fs.journal_pos = JOURNAL_POS_INITIAL;
        fs.ijournal = fs.journal.i;
        tw(tr(TR_FUNC, TrJournal, "Journal file re-created, fs.ijournal = %d\n",
              fs.ijournal));
    }
    
    POWERFAIL_DOMAIN_END();
    tw(tr(TR_END, TrJournal, "}\n"));
}

// Write contents of fs.journal to FFS meta data (inodes). 
void journal_commit(uint8 type)
{
    struct inode_s *ip    = inode_addr(fs.journal.i);
    struct inode_s *oldip = inode_addr(fs.journal.oldi);
    struct inode_s *dp;
    bref_t b;

    tw(tr(TR_BEGIN, TrJournal, "journal_commit(%d) {\n", type));
    tw(tr(TR_FUNC, TrJournal, "i = %d\n", fs.journal.i));
    ttw(ttr(TTrObj, "jc(){" NL));

    POWERFAIL_DOMAIN_BEGIN(PFM_INODES);
    POWERFAIL_SET_ADDR(0);

    if (fs.journal.i)
    {
        struct inode_s ib;  // Inode buffer
        
        // Set all elements to 0xFF.. NOTEME: do this in another way?
        memcpy(&ib, ip, sizeof(ib));

#if (LINEAR_FILE_SYSTEM)
	if(fs.journal.align == 0xee) {
		ib.reserved = 0xee;
		fs.journal.align = 0xff;
	}
#endif
	
        // If this is a create, set the object type
        if (type != 0 && fs.journal.oldi == 0)
            fs.journal_ram.flags = (fs.journal_ram.flags & OF_MASK) | type;
        
        tw(tr(TR_FUNC, TrJournal, "loc   = 0x%04x, size = %d\n",
              fs.journal_ram.location, fs.journal_ram.size));
        ib.location = fs.journal_ram.location;
        ib.size = fs.journal_ram.size;

        if (fs.journal.oldi != 0 && fs.link_child != 0)
            // If this is an update, we copy the child member from old
            // inode. We must do this before we validate the new object,
            // otherwise an intermediate readdir() will detect an empty
            // directory!
            ib.child = get_child(oldip);

        tw(tr(TR_FUNC, TrJournal, "seq   = %d\n", fs.sequence));
        // We must check if sequence is already written because if this
        // commit was inititiated by journal_init(), we don't know exactly
        // what was written
        if (ip->sequence == FLASH_NULL16)
            ib.sequence = fs.sequence++;
        if (fs.journal.oldi == 0)
            ib.updates = 0;
        else
            ib.updates = oldip->updates + 1;

        // The new object is validated before the old object is deleted.
        // This is in order to avoid an interrupting stat or read operation
        // to fail with EFFS_NOTFOUND
        tw(tr(TR_FUNC,  TrJournal, "flags = 0x%02x\n", fs.journal_ram.flags));
        ib.flags = ip->flags & fs.journal_ram.flags;

        // Write the inode to flash
        ffsdrv.write(ip, &ib, sizeof(ib));

            // Insert object into directory structure. We must do this before
            // deleting old object, otherwise an intermediate readdir() will
            // fail with EFFS_NOTFOUND. Note that when the root directory is
            // created, fs.journal.diri is zero --- thus the test!
            if (fs.journal.diri != 0) {
                tw(tr(TR_FUNC,  TrJournal, "diri  = %d ", fs.journal.diri));
                if (fs.journal.diri < 0) {
                    tw(tr(TR_NULL,  TrJournal, "child\n"));
                    dp = inode_addr(get_repi(-fs.journal.diri));
                    ffsdrv.write_halfword((uint16 *) &dp->child, fs.journal.i);
                }
                else {
                    tw(tr(TR_NULL,  TrJournal, "sibling\n"));
                    dp = inode_addr(get_repi(fs.journal.diri));
                    ffsdrv.write_halfword((uint16 *) &dp->sibling, fs.journal.i);
                }
            }

        // Update bstat[] appropriately
        b = offset2block(location2offset(ip->location));
        bstat[b].objects++;
        tw(tr(TR_FUNC,  TrJournal, "bstat[%d].objects = %d\n", b, bstat[b].objects));
        POWERFAIL_BOUNDARY(JOURNAL_TEST_COMMITTING);

        // Validate the object (write valid flags)
        ffsdrv_write_byte(&ip->flags, (ip->flags & OT_VALID));
    }

    tw(tr(TR_FUNC,  TrJournal, "oldi  = %d\n", fs.journal.oldi));
    if (fs.journal.oldi != 0)
    {
        // If this is an update or an erase, we erase the old object
        ffsdrv_write_byte(&oldip->flags, OT_ERASED & oldip->flags);

        // Update bstat according to deletion of the old object.
        b = offset2block(location2offset(oldip->location));
        bstat[b].objects--;
        tw(tr(TR_FUNC,  TrJournal, "bstat[%d].objects = %d\n", b, bstat[b].objects));

        // If we moved the data (all cases, except fcontrol), update lost
        if (fs.journal_ram.location != oldip->location)
            bstat[b].lost += oldip->size;

        bstat[fs.inodes].lost++;
        
        // If we renamed a file to an existing filename, remove the replaced file. 
        if (fs.journal_ram.repli > 0)
            object_remove(fs.journal_ram.repli); // Ignore error! 
    }

    POWERFAIL_DOMAIN_END();

    tw(tr(TR_END, TrJournal, "}\n"));
    ttw(ttr(TTrObj, "}" NL));
}

// Save the current journal into "old" journal. We need this because an
// object_create() can call data_reclaim() which can call object_relocate()
// which uses the journal system.
int journal_push(void)
{
    memcpy(&fs.ojournal, &fs.journal, sizeof(struct journal_s));
    memcpy(&fs.ojournal_ram, &fs.journal_ram, sizeof(struct journal_ram_s));
    fs.journal_depth++;
    if (fs.journal_depth > 1) {
        ffs_panic(EFFS_JNLPUSH2DPTH);
		return -1;
	}

    tw(tr(TR_FUNC, TrJournal, "journal_push() to depth %d\n",
          fs.journal_depth));
	
	return EFFS_OK;
}

// Recall "old" journal into current journal
int journal_pop(void)
{
    tw(tr(TR_FUNC, TrJournal, "journal_pop() from depth %d\n",
          fs.journal_depth));

    fs.journal_depth--;
    if (fs.journal_depth < 0) {
        ffs_panic(EFFS_JNLPOP2DPTH);
		return -1;
    }
    memcpy(&fs.journal, &fs.ojournal, sizeof(struct journal_s));
    memcpy(&fs.journal_ram, &fs.ojournal_ram, sizeof(struct journal_ram_s));

	return EFFS_OK;
}

// Initialize the journalling system. Create journal file if it not already
// exist. Commit/write pending journal if such exists --- return 1 in that
// case. Otherwise, if journal file is clean (no journals pending) and all
// is fine, return EFFS_OK.
effs_t journal_init(iref_t i)
{
    int j;
    struct inode_s *ip;
    struct journal_s *addr;

    if (i == 0) {
        // Journal file does not exist, so create it
        if ((i = journal_create(0)) <= 0) {
            fs.ijournal = 0;
            return i;
        }
    }

	ip = inode_addr(i);
    fs.journal_depth = 0;
    fs.journal_pos = JOURNAL_POS_INITIAL;

    addr = (struct journal_s *)
        offset2addr(location2offset(ip->location) + fs.journal_pos);

    tw(tr(TR_BEGIN, TrJournal, "journal_init(%d) {\n", i));

    fs.ijournal = i;

    // Search for first non-completed journal entry.
    for (j = 0; /* FIXME: limit to end of journal */; j++, addr++) {
        if (addr->state != (uint8) JOURNAL_IS_DONE)
            break;
    }
    tw(tr(TR_FUNC, TrJournal, "entry %d is in state 0x%x\n", j, addr->state));

    fs.journal_pos += j * sizeof(fs.journal);
    i = EFFS_OK;

    if (addr->state == (uint8) JOURNAL_IS_EMPTY) {
        tw(tr(TR_FUNC, TrJournal, "Last journal is in EMPTY state\n"));
        // Journal file is proper, so just record position
    }
    else if (addr->state == (uint8) JOURNAL_IS_READY) {
        struct inode_s *obj_ip = inode_addr(addr->i);
        tw(tr(TR_FUNC, TrJournal, "First non-complete journal is in READY state\n"));

        // Is the object valid?
        if (is_object_valid(obj_ip)) {
            struct inode_s *ip;

            // Copy the entry into fs.journal.
            tw(tr(TR_FUNC, TrJournal, "Last journal is READY/PREVALID\n"));
            memcpy(&fs.journal, addr, sizeof(fs.journal));

            ip = inode_addr(fs.journal.i);
            // The existing fields 'flags', 'location' and 'size' is already
            // written but they are re-written in journal_commit() thus the
            // journal_ram struct must be filled with valid data.
            fs.journal_ram.flags    = ip->flags ;
            fs.journal_ram.location = ip->location;
            fs.journal_ram.size     = ip->size;                        
            journal_end(0); // Validate obj and maybe erase old obj
            i = 1;
        }
        else {
            // Skip last modify operation and replace the diri with a
            // replacement inode. Furthermore, clean the last allocated inode 
            struct inode_s ib;  
            // Clean inode
            memset(&ib, 0, sizeof(ib));
            ffsdrv.write(obj_ip, &ib, sizeof(ib));  

            create_replacementinode(addr);
            ffsdrv_write_byte(&addr->state, JOURNAL_IS_DONE); 
            i = 1;
        }
    }

    else {
        // Journal entry wasn't finished, so just ignore it after updating
        // its state to JOURNAL_IS_DONE.

⌨️ 快捷键说明

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