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

📄 core.c

📁 MMI层OBJ不能完全编译
💻 C
📖 第 1 页 / 共 5 页
字号:
    case Q_DEV_BASE:         *(uint32*)p = (uint32) dev.base; break;

		// FFS versions
    case Q_FFS_API_VERSION:  *(uint16*)p = FFS_API_VERSION; break;
    case Q_FFS_DRV_VERSION:  *(uint16*)p = FFS_DRV_VERSION; break;
    case Q_FFS_REVISION:     *(uint16*)p = ffs_revision; break;
    case Q_FFS_FORMAT_WRITE: *(uint16*)p = FFS_FORMAT_VERSION; break;
    case Q_FFS_FORMAT_READ:  *(uint16*)p = fs.format; break;
    case Q_FFS_LASTERROR:    *(int16*)p  = fs.initerror; break;
	case Q_FFS_TM_VERSION:   *(int16*)p  = FFS_TM_VERSION; break;

		// File system queries
    case Q_FILENAME_MAX:     *(uint16*)p = fs.filename_max; break;
    case Q_PATH_DEPTH_MAX:   *(uint16*)p = fs.path_depth_max; break;

    case Q_OBJECTS_FREE:     *(uint16*)p = fs.objects_max - 
                                 (bstat[fs.inodes].used -
                                  bstat[fs.inodes].lost); break;
    case Q_INODES_USED:      *(uint16*)p = bstat[fs.inodes].used; break;
    case Q_INODES_LOST:      *(uint16*)p = bstat[fs.inodes].lost; break;
    case Q_OBJECTS_MAX:      *(uint16*)p = fs.objects_max; break;

    case Q_INODES_MAX:       *(uint16*)p = fs.inodes_max; break;
    case Q_CHUNK_SIZE_MAX:   *(uint16*)p = fs.chunk_size_max; break;

		// File descriptor queris 
    case Q_FD_BUF_SIZE:      *(uint32*)p = fs.fd_buf_size; break;  
    case Q_FD_MAX:           *(uint16*)p = fs.fd_max; break;
	
		// device queries
    case Q_DEV_MANUFACTURER: *(uint16*)p = dev.manufact; break;
    case Q_DEV_DEVICE:       *(uint16*)p = dev.device; break;
    case Q_DEV_BLOCKS:       *(uint16*)p = dev.numblocks; break;
    case Q_DEV_ATOMSIZE:     *(uint16*)p = dev.atomsize; break;
    case Q_DEV_DRIVER:       *(uint16*)p = dev.driver; break;

		// Miscellaneous/Internal
    case Q_BLOCKS_FREE_MIN:  *(uint16*)p = fs.blocks_free_min; break;

		// Debug queries
    case Q_FS_FLAGS:         *(uint16*)p = fs.flags; break;
    case Q_FS_INODES:        *(uint16*)p = fs.inodes; break;
    case Q_FS_ROOT:          *(uint16*)p = fs.root; break;

    case Q_STATS_DRECLAIMS:        *(uint32*)p = stats.drec.most_lost + 
                                       stats.drec.youngest; break;
    case Q_STATS_IRECLAIMS:        *(uint32*)p = stats.irec.num; break;
    case Q_STATS_DATA_RECLAIMED:   *(uint32*)p = stats.drec.valid[0] + 
                                       stats.drec.lost[0]; break;
    case Q_STATS_INODES_RECLAIMED: *(uint32*)p = stats.irec.valid + stats.irec.lost;
        break;
    case Q_STATS_DATA_ALLOCATED:   *(uint32*)p = stats.data_allocated; break;
    case Q_REQUEST_ID_LAST:        *(uint32*)p = request_id_last; break;

    default:
        if (query >= Q_BSTAT && (query - Q_BSTAT) < dev.numblocks)
        {
            struct block_header_s *bhp;
            uint32 *myp = p;
            
            query -= Q_BSTAT;
            bhp = (struct block_header_s *) offset2addr(dev.binfo[query].offset);

            *myp++ = bstat[query].used;
            *myp++ = bstat[query].lost;
            // If we are in READ mode or this block is not lost, we can
            // safely read the age. Otherwise it is maybe currently erasing
            // and thus we cannot read the age.
			// NOTEME: Should this not have been handled by a driver function?
            if (dev.state == DEV_READ || !is_block_flag(query, BF_LOST))
                *myp++ = (bhp->age << 16) | bstat[query].flags;
            else 
                *myp++ = (  0xFFFE << 16) | bstat[query].flags;
            *myp++ = bstat[query].objects;
        }
        else if (query >= Q_DEBUG_FIRST && query < Q_DEBUG_LAST) {
            *(uint32*)p = fs.debug[query - Q_DEBUG_FIRST];
        }
        else
            return EFFS_INVALID;
    }

    return EFFS_OK;
}


/******************************************************************************
 * Miscellaneous Helper Functions
 ******************************************************************************/

// Handle FATAL core errors
void ffs_panic(int error)
{
    tw(tr(TR_FUNC, TrAll, "** FATAL core error: %d **\n", error));
    ttw(ttr(TTrTest, "** FATAL core error: %d **" NL, error));

#if (TARGET == 0)
    exit(1);
#endif
    fs.initerror = error;
}

iref_t lookup_repi(iref_t i)
{
    iref_t j;
    struct inode_s *rep_ip;

    tw(tr(TR_NULL, TrLookup, "Lookup repi.."));

    for (j = 0; j < FFS_REPLACEMENT_INODES_MAX; j++) {
        rep_ip = inode_addr(fs.repi_table[j]);
        if (i == rep_ip->location) {
            tw(tr(TR_NULL, TrLookup, "found repi %d\n", i));
            return fs.repi_table[j];
        }
    }

    ffs_panic(EFFS_NOREPINODE);

    return 0;
}

// If ip points to a inode which is marked as replaced (child 0x0), lookup
// the replacement inode in the ram table and return the replacement inodes
// child.
iref_t lookup_child(struct inode_s *ip)
{
    struct inode_s *rep_ip;
    iref_t i;

    // The object is marked as replaced thus the replacement inode must be
    // found. Note the replacement inode can also be replaced thus it is
    // necessary to continue lookup until a valid repi is found
    i = ip - fs.inodes_addr;
    do {
        i = lookup_repi(i);
        if (i == 0)         
            return 0;     // FIXME howto handle this internal error?
            
        rep_ip = inode_addr(i);
    } while (rep_ip->child == 0);

    return rep_ip->child;
}

iref_t lookup_sibling(struct inode_s *ip)
{
    struct inode_s *rep_ip;
    iref_t i;

    // The object is marked as replaced thus the replacement inode must be
    // found. Note the replacement inode can also be replaced thus it is
    // necessary to continue lookup until a valid repi is found
    i = ip - fs.inodes_addr;
    do {
        i = lookup_repi(i);
        if (i == 0)         
            return 0;     // FIXME howto handle this internal error?
            
        rep_ip = inode_addr(i);
    } while (rep_ip->sibling == 0);

    return rep_ip->sibling;
}

// If the object has a replacement inode then return it else return i
iref_t get_repi(iref_t i)
{
    struct inode_s *ip;
    
    if (i > 0)
        ip = inode_addr(i);
    else
        ip = inode_addr(-i);

    while (ip->child == 0) {
        i = lookup_repi(i);
        if (i == 0)         
            return 0;     // FIXME howto handle this internal error?

        ip = inode_addr(i);
    }

    return i;
}

// Check if an object is read-only. Note that the root inode is always
// readonly, no matter what! Returns error or original <i>.
iref_t is_readonly(iref_t i, const char *path)
{
    struct inode_s *ip = inode_addr(i);

    tw(tr(TR_FUNC, TrObject, "is_readonly(%d, '%s') ", i, path));

    if (i == fs.root || i == fs.ijournal ||
        (IS_BIT_SET(ip->flags, OFE_READONLY) && !ffs_is_modifiable(path)))
        i = EFFS_ACCESS;

    tw(tr(TR_NULL, TrObject, "(0x%X) %d\n", ip->flags, i));

    return i;
}

// Check if filename is valid. Return EFFS_BADNAME if name contains
// invalid chars. Return RFFS_NAMETOOLONG if name is too
// long. Otherwise return filename length.
effs_t is_filename(const char *s)
{
    char *p = (char *) s;
    int n = 0;
    
    while ( (*s >= 'a' && *s <= 'z') ||
            (*s >= 'A' && *s <= 'Z') ||
            (*s >= '0' && *s <= '9') ||
            *s == '.' ||
            *s == ',' ||
            *s == '_' ||
            *s == '-' ||
            *s == '+' ||
            *s == '%' ||
            *s == '$' ||
            *s == '#' )
    {
        s++;
    }
    
    if (*s != 0)
        n = EFFS_BADNAME;  // invalid file name character found
    else {
        n = s - p;
        if (n > fs.filename_max)
            n = EFFS_NAMETOOLONG;
        if (n == 0)
            n = EFFS_BADNAME;
    }

    tw(tr(TR_FUNC, TrUtil, "is_filename('%s') %d\n", p, n));

    return n;
}

int ffs_strlen(const char *s)
{
    const char *p = s;

    while (*p++)
        ;

    tw(tr(TR_FUNC, TrUtil, "strlen('%s') %d\n", s, p-s-1));

    return p-s-1;
}

// Return zero if strings are equal, otherwise return non-zero.
int ffs_strcmp(const char *s, const char *p)
{
    int8 n = 1;

    tw(tr(TR_FUNC, TrUtil, "strcmp('%s', '%s') ", s, p));

    while (*s == *p && *p != 0) {
        s++;
        p++;
    }
    if (*s == *p)
        n = 0;

    tw(tr(TR_NULL, TrUtil, "(%d)\n", n));

    return n;
}

fd_t get_fdi(iref_t i)
{
    int j;

    tw(tr(TR_FUNC, TrUtil, "get_fdi(%d)\n", i));
    
	if (i > 0) {
		for (j = 0; j < fs.fd_max; j++) {
			if (i == fs.fd[j].seghead) {
				return j;  // Return fdi without offset
			}
		}
	}
    return -1;
}    


effs_t is_fd_valid(fd_t fdi)
{
    if (fdi >= fs.fd_max || fdi < 0 || fs.fd[fdi].options == 0)
        return 0;  // Not valid!
    return 1;
}

effs_t is_offset_in_buf(int offset, fd_t fdi)
{
    if (fs.fd[fdi].dirty == 1)
        if (offset >= fs.fd[fdi].wfp && 
            offset < fs.fd[fdi].wfp + fs.chunk_size_max)
        return 1;
    return 0;
}

/******************************************************************************
 * Chunk Operations
 ******************************************************************************/

iref_t segment_create(const char *buf, int size, iref_t dir)
{
    iref_t i;
    struct inode_s *ip;
    int realsize;
    offset_t offset;
    char *dataaddr;


   ttw(ttr(TTrObj, "segc(%d, %d){" NL, size, dir));
   tw(tr(TR_BEGIN, TrObject, "segment_create( ?, %d, %d) {\n", size, dir));

    fs.journal_ram.size = realsize = atomalign(size + 1);

    // Init journal.diri before chunk_alloc() because it might trigger a
    // data_reclaim() which can relocate the dir inode
    fs.journal.diri = dir;

    if ((i = chunk_alloc(realsize, 0, &offset)) < 0)
        return i;

    ip = inode_addr(i);
    dataaddr = offset2addr(offset);

    // Write data and null terminator.  We null-terminate the data block,
    // such that blocks_fsck() can determine the amount of used data block
    // space correctly. 
    ffsdrv.write(dataaddr, buf, size);
    dataaddr += size;
    ffsdrv_write_byte(dataaddr, 0);
   
    // Segments is linked together by the child link(create) or by the
    // sibling link(update or relocate). A negativ dir indicate that it is a
    // update or relocate and the sign must be reversed so the journal
    // system will use the sibling link to link the inode together. 
    if (dir > 0)
        fs.journal.diri = chunk_traverse(fs.journal.diri);
    
    fs.journal.diri = -fs.journal.diri;
   
    tw(tr(TR_END, TrObject, "} %d\n", i));
    ttw(ttr(TTrObj, "} %d" NL,i));

    return i;
}

#if (FFS_READ_CACHE_ENBALE == 1)
/* Segment read with read buffering */
int segment_read_cache(fd_t fdi,iref_t i, char *buf, int size, int offset)
{
    struct inode_s *ip;
	char *p;	

   if (buf == NULL) {
        tw(tr(TR_END, TrObject, "} %d\n", EFFS_INVALID));
        return EFFS_INVALID;
    }

 
 
 if((fs.fd[fdi].cache_i == i) &&(fs.fd[fdi].cache_read_buf != NULL))
 	{
 	   /* The data is avilable in read buffer */
	     if (size > fs.fd[fdi].cache_read_buf_size - offset)
	        size = fs.fd[fdi].cache_read_buf_size - offset;   
		 memcpy(buf, &(fs.fd[fdi].cache_read_buf[offset]), size);
 	}
 else
 	{
 	   
 	   ip = inode_addr(i);

	   fs.fd[fdi].cache_i = i;   /* Cache the inode */
 	   fs.fd[fdi].cache_read_buf_size = segment_datasize(ip);

	   p = offset2addr(location2offset(ip->location));    
       p = addr2data(p, ip);

	//OMAPS78600 start
       // On first call to segment_read_cache() for a file the cache buffer has not been created yet,
       // so if cache_read_buf is NULL then do not free it. 
       if (fs.fd[fdi].cache_read_buf != NULL)
        {
	       target_free(fs.fd[fdi].cache_read_buf);
		   fs.fd[fdi].cache_read_buf = NULL;
         }
	   //OMAPS78600 end
		 /* check the size   */
    	if (size > fs.fd[fdi].cache_read_buf_size - offset)
    		{
    		    /* Filling the buffer is not required , here */
    		    /* saturate the size */
		        size = fs.fd[fdi].cache_read_buf_size - offset;
   
				memcpy(buf, &p[offset], size);
    		}	
		else   /* read size is less than chunk size, so buffer the chunk data */
			{
		  		/*  Allocate a memory for the buffer */
				fs.fd[fdi].cache_read_buf = (char*)target_malloc(fs.fd[fdi].cache_read_buf_size);
				
				if(fs.fd[fdi].cache_read_buf == NULL)
					{

						ttw(ttr(TTrMisc,"segment_read_cache: Memory Error \n\r")); 

					  /* No RAM memory , read it from Nor flash it self */
			    		memcpy(buf, &p[offset], size);
			  
					}
				else

⌨️ 快捷键说明

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