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

📄 drobj.c

📁 NUcleus plus 支持的文件系统。 是学习文件系统的很好参考资料。
💻 C
📖 第 1 页 / 共 5 页
字号:
*                                                                       
*       Takahiro Takahashi                         
*                                                                       
* INPUTS                                                                
*                                                                       
*       **pobj                              Create file's DROBJ pointer 
*       *pmom                               Drive object                
*       *filename                           Create file name            
*       *fileext                            Create file extension       
*       attributes                          Create file attributes      
*                                                                       
*                                                                       
* OUTPUTS                                                               
*                                                                       
*       NU_SUCCESS                          If service is successful.   
*       NUF_ROOT_FULL                       Root directry full.         
*       NUF_INVNAME                         Path or filename includes   
*                                            invalid character.         
*       NUF_NOSPC                           No space to create directory
*                                             in this disk.             
*       NUF_NO_BLOCK                        No block buffer available.  
*       NUF_NO_FINODE                       No FINODE buffer available. 
*       NUF_NO_DROBJ                        No DROBJ buffer available.  
*       NUF_IO_ERROR                        Driver IO error.            
*       NUF_INTERNAL                        Nucleus FILE internal error.
*                                                                       
*************************************************************************/
STATUS pc_mknode(DROBJ **pobj, DROBJ *pmom, UINT8 *filename, 
                  UINT8 *fileext, UINT8 attributes)
{
STATUS      ret_stat;
DOSINODE    *pdinodes;
FINODE      lfinode;
UINT32      cluster;
DATESTR     crdate;
BLKBUFF     *pbuff;
DDRIVE      *pdrive;
DROBJ       *psobj;
UINT8       attr;
UINT8       fname[9];
UINT8       fext[4];
UINT8       shortname[13];
INT         longfile;
STATUS      status;


    *pobj = NULL;
    pdrive = pmom->pdrive;
    ret_stat = NU_SUCCESS;

    if (attributes & ADIRENT)
    {
        /*Grab a cluster for a new dir and cleaer it */
        PC_FAT_ENTER(pdrive->driveno)
        ret_stat = pc_clalloc(&cluster, pdrive);

#ifdef DEBUG1
        DEBUG_PRINT("pc_mknode  allocate directory cluster number %d\r\n", cluster);
#endif

        PC_FAT_EXIT(pdrive->driveno)

        if (ret_stat == NU_SUCCESS)
        {
            ret_stat = pc_clzero(pdrive, cluster);
            if (ret_stat != NU_SUCCESS)
            {
                PC_FAT_ENTER(pdrive->driveno)
                pc_clrelease(pdrive, cluster);
                PC_FAT_EXIT(pdrive->driveno)
            }
        }
    }
    else
        cluster = 0L;

    if (ret_stat != NU_SUCCESS)
    {
        return(ret_stat);
    }

    /* For a subdirectory. First make it a simple file. We will change the
       attribute after all is clean */

    attr = attributes;
    if (attr & ADIRENT)
        attr = ANORMAL;

    /* Allocate an empty DROBJ and FINODE to hold the new file */
    *pobj = pc_allocobj();
    if (!(*pobj))
    {
        if (cluster)
        {
            PC_FAT_ENTER(pdrive->driveno)
            pc_clrelease(pdrive, cluster);
            PC_FAT_EXIT(pdrive->driveno)
        }
        return(NUF_NO_DROBJ);
    }

    /* Take a short file name and extension. */
    longfile = pc_fileparse(fname, fext, filename, fileext);
    if (longfile < 0)
    {
        ret_stat = (STATUS)longfile;
    }
    else
    {
        /* Upperbar short file name ?  */
        while( (longfile == FUSE_UPBAR) && (ret_stat == NU_SUCCESS) )
        {
            /* Search the short file name */
            pc_cre_shortname((UINT8 *)shortname, fname, fext);
            psobj = NULL;
            ret_stat = pc_get_inode(&psobj, pmom, (UINT8 *)shortname);
            /* File not found. We can use this short filename. */
            if (ret_stat == NUF_NOFILE)
            {
                ret_stat = NU_SUCCESS;
                break;
            }
            else if (ret_stat == NU_SUCCESS)
            {
                /* Free the short filename object */
                pc_freeobj(psobj);
                /* Get the next short filename */
                pc_next_fparse(fname);
            }
        }
    }

    if (ret_stat != NU_SUCCESS)
    {
        pc_freeobj(*pobj);
        if (cluster)
        {
            PC_FAT_ENTER(pdrive->driveno)   /* claim the fat for alloc */
            pc_clrelease(pdrive, cluster);
            PC_FAT_EXIT(pdrive->driveno)
        }
        return(ret_stat);
    }

    /* Load the inode copy name,ext,attr,cluster, size,datetime*/
    pc_init_inode( (*pobj)->finode, fname, fext, 
                    attr, cluster, /*size*/ 0L, pc_getsysdate(&crdate) );

    /* Convert pobj to native and stitch it in to mom */
    ret_stat = pc_insert_inode(*pobj, pmom, filename, longfile);
    if (ret_stat != NU_SUCCESS)
    {
        /* Root directory entry full or Disk full ? */
        if ( (ret_stat == NUF_ROOT_FULL) || (ret_stat == NUF_NOSPC) )
        {
            /* Try again */
            ret_stat = pc_insert_inode(*pobj, pmom, filename, longfile);
            if (ret_stat != NU_SUCCESS) 
            {
                pc_freeobj(*pobj);
                if (cluster)
                {
                    PC_FAT_ENTER(pdrive->driveno)
                    pc_clrelease(pdrive, cluster);
                    PC_FAT_EXIT(pdrive->driveno)
                }
                return(ret_stat);
            }
        }
        else
        {
            pc_freeobj(*pobj);
            if (cluster)
            {
                PC_FAT_ENTER(pdrive->driveno)
                pc_clrelease(pdrive, cluster);
                PC_FAT_EXIT(pdrive->driveno)
            }
            return(ret_stat);
        }
    }

    /* Now if we are creating subdirectory we have to make the DOT and DOT DOT
      inodes and then change pobj's attribute to ADIRENT
      The DOT and DOTDOT are not buffered inodes. We are simply putting
      the to disk  */
    if (attributes & ADIRENT)
    {
        /* Set up a buffer to do surgery */
        status = pc_alloc_blk(&pbuff, pdrive, pc_cl2sector(pdrive, cluster));
        if (status < 0)
        {
            pc_freeobj(*pobj);
            PC_FAT_ENTER(pdrive->driveno)    /* claim the fat for alloc */
            pc_clrelease(pdrive, cluster);
            PC_FAT_EXIT(pdrive->driveno)
            return((STATUS)status);
        }
        pc_memfill(pbuff->data, 512, '\0');

        pdinodes = (DOSINODE *) &pbuff->data[0];
        /* Load DOT and DOTDOT in native form */
        /* DOT first. It points to the begining of this sector */
        pc_init_inode(&lfinode, (UINT8 *)".", (UINT8 *)"", ADIRENT, cluster, /*size*/ 0L, &crdate);

        /* And to the buffer in intel form */
        pc_ino2dos (pdinodes, &lfinode);

        /* Now DOTDOT points to mom's cluster */
        if (pmom->isroot)
        {
            pc_init_inode(&lfinode, (UINT8 *)"..", (UINT8 *)"", ADIRENT, 0L, /*size*/ 0L, &crdate);
        }
        else
        {
            pc_init_inode(&lfinode, (UINT8 *)"..", (UINT8 *)"", ADIRENT, 
                          pc_sec2cluster(pdrive, (*pobj)->blkinfo.my_frstblock),
                         /*size*/ 0L, &crdate);
        }
        /* And to the buffer in intel form */
        pc_ino2dos (++pdinodes, &lfinode);

        /* Write the cluster out */
        ret_stat = pc_write_blk(pbuff);
        if (ret_stat != NU_SUCCESS)
        {
            pc_free_buf(pbuff, YES);         /* Error. Chuck the buffer */
            pc_freeobj(*pobj);
            PC_FAT_ENTER(pdrive->driveno)   /* claim the fat for alloc */
            pc_clrelease(pdrive, cluster);
            PC_FAT_EXIT(pdrive->driveno)
            return(ret_stat);
        }
        else
            pc_free_buf(pbuff, NO);

        /* And write the node out with the original attributes */
        (*pobj)->finode->fattribute = attributes;

        /* Convert to native and overwrite the existing inode*/
        ret_stat = pc_update_inode(*pobj, DSET_CREATE);
        if (ret_stat != NU_SUCCESS)
        {
            pc_freeobj(*pobj);
            PC_FAT_ENTER(pdrive->driveno)   /* claim the fat for alloc */
            pc_clrelease(pdrive, cluster);
            PC_FAT_EXIT(pdrive->driveno)
            return(ret_stat);
        }
    }

    PC_FAT_ENTER(pdrive->driveno)
    ret_stat = pc_flushfat(pdrive);
    PC_FAT_EXIT(pdrive->driveno)

    if (ret_stat != NU_SUCCESS)
    {
        pc_freeobj(*pobj);
        PC_FAT_ENTER(pdrive->driveno)   /* claim the fat for alloc */
        pc_clrelease(pdrive, cluster);
        PC_FAT_EXIT(pdrive->driveno)
    }

    return(ret_stat);
}


/************************************************************************
* FUNCTION                                                              
*                                                                       
*       pc_insert_inode                                                 
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*       Take mom , a fully defined DROBJ, and pobj, a DROBJ with a      
*       finode containing name, ext, etc, but not yet stitched into the 
*       inode buffer pool, and fill in pobj and its inode, write it to  
*       disk and make the inode visible in the inode buffer pool.       
*                                                                       
* AUTHOR                                                                
*                                                                       
*       Takahiro Takahashi                         
*                                                                       
* INPUTS                                                                
*                                                                       
*       *pobj                               Create file's DROBJ         
*       *pmom                               Drive object                
*       *filename                           Create file name            
*       longfile                            If 1, long file name is     
*                                            given.                     
*                                                                       
* OUTPUTS                                                               
*                                                                       
*       NU_SUCCESS                          If service is successful.   
*       NUF_ROOT_FULL                       Root directry full.         
*       NUF_NOSPC                           No space to create directory
*                                             in this disk.             
*       NUF_NO_BLOCK                        No block buffer available.  
*       NUF_IO_ERROR                        Driver IO error.            
*       NUF_INTERNAL                        Nucleus FILE internal error.
*                                                                       
**********************

⌨️ 快捷键说明

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