Exemplo n.º 1
0
/*===========================================================================
FUNCTION DSMI_VERIFY_PACKET()

DESCRIPTION 
  This will verify the correctness of a packet.  

  Check that a packet isn't linked to itself.  The algorythm is as
  follows.  Start 2 pointers at the beggining of the list (lead
  pointer and chase pointer).  On every iteration through the loop
  move the lead pointer down the list by one node, verify that it
  isn't pointing to the chase pointer.  On every other iteration
  through the loop move the chase pointer down the list.  If the
  packet is linked to itself, eventually these will meet.  If the
  packet is not linked to itself, eventually the lead pointer will get
  to the end of the packet.

DEPENDENCIES 
  item_ptr should be non-null and pointing at a dsm item allocated
  from dsm.
  
PARAMETERS
  item_ptr - Pointer to packet to verify

RETURN VALUE
  None (This function won't return if the check fails)

SIDE EFFECTS
  If the item_ptr fails a check then ERR_FATAL is called, otherwise none.
===========================================================================*/
void dsmi_verify_packet
(
  dsm_item_type *item_ptr
)
{
  uint32 cnt = 0;
  dsm_item_type *lead_ptr = item_ptr;
  dsm_item_type *chase_ptr = item_ptr;

  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  DSM_ASSERT(item_ptr != NULL);

  while(lead_ptr != NULL)
  {
    /*-----------------------------------------------------------------
      Count buffers in packet 
    -----------------------------------------------------------------*/
    cnt ++;

    dsmi_verify_buffer(lead_ptr);
    /*-----------------------------------------------------------------
      Check for packet looped to self 
    -----------------------------------------------------------------*/
    lead_ptr = lead_ptr->pkt_ptr;
    if(lead_ptr == chase_ptr)
    {
      ERR_FATAL("dsm_verify_packet: Packet Linked to Self",0,0,0);
    }
    if((cnt & 0x1) == 0)
    {
      chase_ptr = chase_ptr->pkt_ptr;
    }
  }
}
Exemplo n.º 2
0
// 将指定的i节点跟fat缓存绑定、关联起来。
INT32 fat_relate_inode_with_fatcache(FAT_CACHE *psFATCache, struct inode *psInode)
{
    PFILE_INODE_LIST psTmpNode = NULL;

    if (NULL == psFATCache || NULL == psInode)
    {
        D( ( DL_FATERROR, "in fat_relate_inode_with_fatcache, input parameter is NULL.\n") );
        return _ERR_FAT_PARAM_ERROR;
    }

    psTmpNode = psFATCache->psFileInodeList;

    while (psTmpNode)
    {
        // 查找该i节点是否已经跟FAT缓存相关联。
        if (psTmpNode->psInode == psInode)
        {
            return _ERR_FAT_SUCCESS;
        }
        psTmpNode = psTmpNode->next;
    }
    
    if (NULL == (psTmpNode = DSM_MAlloc(sizeof(FILE_INODE_LIST))))
    {
        DSM_ASSERT(0,"fat_relate_inode_with_fatcache: 1.malloc(0x%x) failed.",(sizeof(FAT_CACHE))); 
        return _ERR_FAT_MALLOC_FAILED;
    }

    psTmpNode->psInode = psInode;
    psTmpNode->next = psFATCache->psFileInodeList;
    psFATCache->psFileInodeList = psTmpNode;
    return _ERR_FAT_SUCCESS;
    
}
Exemplo n.º 3
0
/*===========================================================================
FUNCTION DSMI_VERIFY_POOL_ID()

DESCRIPTION 
  This function verifies that the pool ID handed in is a valid one.
  (ie. in the set of pools we are currently managing.

DEPENDENCIES
  None
  
PARAMETERS
  pool_id - Pool id to check range of. 

RETURN VALUE
  None (This function won't return in pool_id is bogus.)

SIDE EFFECTS
  If the pool_id is bogus ERR_FATAL is called, otherwise none.
===========================================================================*/
void dsmi_verify_pool_id
(
  dsm_mempool_id_type pool_id 
)
{
  dsm_pool_mgmt_table_type *table=(dsm_pool_mgmt_table_type*)pool_id;  
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  DSM_ASSERT(table!=NULL);
  DSM_ASSERT((unsigned int)table > 256);

#ifdef FEATURE_DSM_MEM_CHK
  if(table->cookie != DSM_POOL_MGMT_TABLE_COOKIE)
  {
    ERR_FATAL("dsm: Invalid Pool ID = %d", (int)pool_id, 0, 0);
  }
#endif /* FEATURE_DSM_MEM_CHK */
}
Exemplo n.º 4
0
// 同步与FAT表缓存相关联的i节点,将i节点的目录项信息写回磁盘。
// 因为系统异常(例如掉电)会引起缓存信息的丢失,
// FAT 表可能没有被写回磁盘,导致文件的目录项使用的FAT表项
// 跟FAT表不一致,所以现在将对目录项的操作跟FAT缓存绑定在一起。
INT32 fat_synch_relating_file(FAT_SB_INFO *sb_info, FAT_CACHE *psFATCache)
{
    INT32 iRet = _ERR_FAT_SUCCESS;
    PFILE_INODE_LIST psRelatingInode = NULL;
    PFILE_INODE_LIST psTmpNode = NULL;
    UINT8*  secbuf = NULL;

    if (NULL == sb_info || NULL == psFATCache)
    {
        D( ( DL_FATERROR, "in fat_synch_relating_file, input parameter is NULL.\n") );
        return _ERR_FAT_PARAM_ERROR;
    }
    
    secbuf = FAT_SECT_BUF_ALLOC();
    if(NULL == secbuf)
    {
        D(( DL_FATERROR,"in fat_synch_relating_file,1.FAT_SECT_BUF_ALLOC() failed.")); 
        DSM_ASSERT(0,"in fat_synch_relating_file,1.FAT_SECT_BUF_ALLOC() failed.");
        return _ERR_FAT_MALLOC_FAILED;        
    }

    psRelatingInode = psFATCache->psFileInodeList;
    
    while (psRelatingInode)
    {
        if(psRelatingInode->psInode)
        {
            iRet = fat_update_dentry(psRelatingInode->psInode, secbuf);
            if (_ERR_FAT_SUCCESS != iRet)
            {
                FAT_SECT_BUF_FREE((SECT_BUF*)secbuf);
                psTmpNode = psRelatingInode;
                psRelatingInode = psRelatingInode->next;          
                DSM_Free(psTmpNode);
          psFATCache->psFileInodeList = psRelatingInode;    
            }
            else
            {
                psTmpNode = psRelatingInode;
                psRelatingInode = psRelatingInode->next;          
                DSM_Free(psTmpNode);
          psFATCache->psFileInodeList = psRelatingInode;    
            }
         }
         else
         {
            psTmpNode = psRelatingInode;
            psRelatingInode = psRelatingInode->next;
            DSM_Free(psTmpNode);
         }
    }
    psFATCache->psFileInodeList = NULL;
    FAT_SECT_BUF_FREE((SECT_BUF*)secbuf);
    return _ERR_FAT_SUCCESS;
    
}
Exemplo n.º 5
0
/*===========================================================================
FUNCTION DSMI_REF_INC()

DESCRIPTION 
  Increment the reference count on a dsm item.

DEPENDENCIES
  None
  
PARAMETERS
  item_ptr - Pointer to item to act on. 

RETURN VALUE

SIDE EFFECTS
===========================================================================*/
uint8 dsmi_ref_inc(dsm_item_type *item_ptr)
{
  uint8 ret;
  DSM_ASSERT(item_ptr != NULL);
  DSMI_POOL_LOCK(item_ptr->pool_id);
#ifdef FEATURE_DSM_MEM_CHK
  if(item_ptr->references == 0)
  {
    ERR_FATAL("dsmi_ref_inc: Reference count is zero for item 0x%x",
              (int)item_ptr,0,0);
  }
#endif /* FEATURE_DSM_MEM_CHK */
  ret = ++item_ptr->references;
  DSMI_POOL_UNLOCK(item_ptr->pool_id);
  return ret;
}
Exemplo n.º 6
0
/*===========================================================================
FUNCTION DSMI_REF_DEC()
  INTFREE();

DESCRIPTION 
  Deccrement the reference count on a dsm item.

DEPENDENCIES
  None
  
PARAMETERS
  item_ptr - Pointer to item to act on. 

RETURN VALUE

SIDE EFFECTS
===========================================================================*/
uint8 dsmi_ref_dec(dsm_item_type *item_ptr)
{
  uint8 ret = (uint8)~0;
  
  DSM_ASSERT(item_ptr != NULL);
  DSMI_POOL_LOCK(item_ptr->pool_id);
  if(item_ptr->references == 0) 
  {
#ifdef FEATURE_DSM_MEM_CHK
#ifndef FEATURE_DSM_MEM_CHK_ALLOW_DOUBLE_FREE
    ERR_FATAL("dsmi_ref_dec: Reference count already zero for item 0x%x",
              (int)item_ptr,0,0);
#endif /* FEATURE_DSM_MEM_CHK_ALLOW_DOUBLE_FREE */
#endif /* FEATURE_DSM_MEM_CHK */
  }
  else
  {
    ret = --item_ptr->references;
  }
  DSMI_POOL_UNLOCK(item_ptr->pool_id);
  return ret;
}
Exemplo n.º 7
0
INT32 fat_file_read(struct inode *inode, 
                    struct file * filp, INT8 * buf, INT32 len)
{
    FAT_DIR_ENTRY d_entry = {0,};
    FAT_SB_INFO* sb = NULL;
    UINT32 fpos = 0;
    UINT32 fsize = 0;
    UINT32 secperclu = 0;
    
    INT32 rcount = 0;
    UINT32 rsize = 0;
    UINT32  cursec, secnum;
    UINT32 clunum, secoff;
    UINT8* secbuf;
    INT8* bufp = NULL;
    
    INT32 iResult = _ERR_FAT_SUCCESS;


     d_entry = inode->u.fat_i.entry;
     sb = &(inode->i_sb->u.fat_sb);
     fpos = filp->f_pos;
     fsize = d_entry.DIR_FileSize;
     secperclu = (UINT32)sb->iSecPerClus;
     bufp = buf;

    
    // set the rsize.
    if(fpos > fsize)
    {
        D( ( DL_FATERROR, "in fat_file_read. fpos(%d) >  fsize(%d).\n",fpos,fsize) );
        return _ERR_FAT_READ_EXCEED;
    }
    else if(fpos+len > fsize)
    {
        rsize = fsize - fpos;
    }
    else
    {
        rsize = len;
    }
    
    // malloc the secbuf for read sector.
    secbuf = FAT_SECT_BUF_ALLOC();
    if(NULL == secbuf)
    {        
        D(( DL_FATERROR,"in fat_file_read,1.FAT_SECT_BUF_ALLOC() failed.")); 
        DSM_ASSERT(0,"in fat_file_read,1.FAT_SECT_BUF_ALLOC() failed.");
        return _ERR_FAT_MALLOC_FAILED;
    }  
    
    // get the wcluser number.
    iResult = fat_fpos2CSO(filp->f_inode, fpos, &clunum, &secnum, &secoff, (UINT32*)NULL);
    if (iResult != _ERR_FAT_SUCCESS)
    {
        // Out of file size,error.
        D( ( DL_FATERROR, "fat_file_read: fat_fpos2CSO error!!!\n") );
        g_TstFsErrCode = 1019;
        iResult = _ERR_FAT_ERROR;
        goto end;
    }
    
    cursec = secnum; 
    
    while(!fat_is_last_cluster(sb, clunum))
    {
        for(cursec = secnum; cursec < secperclu; cursec++)
        {
            // DSM_MemSet(secbuf, 0x00, DEFAULT_SECSIZE);
            iResult = fat_read_cluster(sb, clunum, cursec, secbuf);
            if(_ERR_FAT_SUCCESS != iResult)
            {
                D( ( DL_FATERROR, "Call fat_read_cluster() failed. Local error code:%d. clunum = 0x%x, secnum = 0x%x.\n",iResult, clunum, cursec) );
                iResult = _ERR_FAT_READ_SEC_FAILED;
                goto end;
            }
            
            if(0 == secoff)
            {
                if(rsize > DEFAULT_SECSIZE)
                {
                    DSM_MemCpy(bufp, secbuf, DEFAULT_SECSIZE);
                    
                    filp->f_pos += DEFAULT_SECSIZE;
                    bufp += DEFAULT_SECSIZE;
                    rsize -= DEFAULT_SECSIZE;
                    rcount += DEFAULT_SECSIZE;
                    secoff = 0;
                }
                else if (rsize == DEFAULT_SECSIZE)
                {
                    DSM_MemCpy(bufp, secbuf, DEFAULT_SECSIZE);
                    
                    filp->f_pos += DEFAULT_SECSIZE;
                    bufp += DEFAULT_SECSIZE;
                    rsize -= DEFAULT_SECSIZE;
                    rcount += DEFAULT_SECSIZE;
                    secoff = 0;

                    goto end;
                }
                else //secoff + rsize <= DEFAULT_SECSIZE (1)
                {
                    DSM_MemCpy(bufp, secbuf, rsize);
                    
                    filp->f_pos += rsize;
                    bufp += rsize;
                    secoff = secoff + rsize;
                    rcount += rsize;
                    rsize = 0;

                    goto end;
                }
            }
            else // secoff > 0
            {
                if(secoff + rsize > DEFAULT_SECSIZE)
                {
                    DSM_MemCpy(bufp, secbuf+secoff, DEFAULT_SECSIZE-secoff);
                    
                    filp->f_pos += (DEFAULT_SECSIZE-secoff);
                    bufp += (DEFAULT_SECSIZE-secoff);
                    rsize -= (DEFAULT_SECSIZE-secoff);
                    rcount += (DEFAULT_SECSIZE-secoff);
                    secoff = 0;
                }
                else //secoff + rsize <= DEFAULT_SECSIZE (1)
                {
                    DSM_MemCpy(bufp, secbuf+secoff, rsize);
                    
                    filp->f_pos += rsize;
                    bufp += rsize;
                    secoff = secoff + rsize;
                    rcount += rsize;
                    rsize = 0;
                    goto end;
                }
            }
            
        }

        // Get next cluster, secnum, secoff
        iResult = fat_fpos2CSO(filp->f_inode, filp->f_pos, &clunum, &secnum, &secoff, (UINT32*)NULL);
        if (iResult != _ERR_FAT_SUCCESS)
        {
           // Out of file size,error.
            D( ( DL_FATERROR, "fat_file_read: fat_fpos2CSO error2 !!!\n") );
            iResult = _ERR_FAT_ERROR;
            g_TstFsErrCode = 1020;
            goto end;
        }                
        DSM_ASSERT((BOOL)(clunum >= 2),"clunum = %d.",clunum);    
            
    }
    
end:

    if(NULL != secbuf) 
    {
        FAT_SECT_BUF_FREE((SECT_BUF*)secbuf);
    }

    rcount = _ERR_FAT_SUCCESS == iResult ? rcount: iResult;
    return rcount;
}
Exemplo n.º 8
0
/*===========================================================================
FUNCTION DSMBIT_PACK32_TAIL

DESCRIPTION
  Packs a given value (up to thirty-two bits) into a given dsm item at a
  specified offset.  

DEPENDENCIES
  Data must be packed into the last used byte or the byte immediately
  following it.

  item_ptr can not be NULL.
  
PARAMETERS
  item_ptr  - Pointer to dsm item where packed data should be placed.
  pack_data - Data to be packed
  offset    - Number of bits to skip before placing this data
  len       - Number of bits of pack_data to pack (LSB of the variable)

RETURN VALUE
  Number of bits successfully packed

SIDE_EFFECTS
  A new dsm item may be acquired and linked.

===========================================================================*/
uint16 dsmbiti_pack32_tail
(
  dsm_item_type * item_ptr,
  uint32 pack_data,
  uint16 offset,
  uint16 len,
  dsm_mempool_id_type pool_id,
  const char * file,
  uint32 line
)
{
  uint32 bit_pack_data;          /* data to bit_pack into last byte */

  uint16 byte_offset;            /* Position in terms of bytes of reqd field */

  uint16 num_pushed_bits = 0;    /* stores number of bits pushed */

  uint16 length_packet;          /* stores the length of the passed packet */

  uint16 pushdown_bytes;          /* number of bytes to push down */

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  byte_offset = (uint16) offset / 8;
  offset = offset % 8;

  /* have to be writing bits into the last used byte, or to the byte
     immediately following.
     dsm_length_packet starts counting at 1, byte_offset starts counting at 0,
     thus the apparent off-by-1 discrepancy. */

  DSM_ASSERT (NULL != item_ptr);

  length_packet = (uint16)dsm_length_packet(item_ptr);

  if (offset == 0)
  {
    DSM_ASSERT( length_packet == byte_offset);
  }
  else //offset != 0
  {
    DSM_ASSERT (length_packet == (byte_offset + 1));
  }

  /* if we are packing some bits into the last used byte, go to it directly
     and pack those bits in */
  if (offset != 0)
  {
    while (item_ptr->pkt_ptr != NULL)
    {
      byte_offset -= item_ptr->used;
      item_ptr = item_ptr->pkt_ptr;
    }

    /* move the bits to be packed into the LSB of the temporary variable */
    bit_pack_data = pack_data >> MAX((len + offset - 8), 0);

    /* pack the bits into the last used byte */
    b_packd (bit_pack_data, (item_ptr->data_ptr + byte_offset),
             offset, (word) MIN(8-offset, len));

    /* count the number of pushed bits */
    num_pushed_bits += MIN(8 - offset, len);

    /* decrease the remaining length by the number of bits pushed */
    len = MAX((len + offset - 8), 0);
  }

  /* len is number of bits to pushdown_tail.  It may have changed from
     the top of the function, as a result of packing some bits directly */
  if (len != 0)
  {
    /* shift out the bits that have already been packed */
    pack_data = pack_data << (32 - len);

    /* swap big-endian to little-endian in 16-bit and 32-bit values
       before pushing down */
    pack_data = NTOHL(pack_data);

    pushdown_bytes = 1 + ((len - 1) / 8);

    /* if the pushdown was successful */
    if (dsmi_pushdown_tail(&item_ptr, &pack_data, pushdown_bytes, pool_id, file, line) ==
        pushdown_bytes)
    {
      /* assume all bits were pushed and increment the counter */
      num_pushed_bits += len;
    }
  }

  return num_pushed_bits;
} /* dsmbit_pack32_tail() */