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

📄 drobj.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    FINODE *pfi;

    /* We have to be a subdir   */
    if (!pc_isadir(pdotdot))
        return(0);

    /* If ..->cluster is zero then parent is root   */
    if (!pc_finode_cluster(pdrive,pdotdot->finode)) /* FAT32 */
        return(pc_get_root(pdrive));

    /* Otherwise : cluster points to the beginning of our parent.
                    we also need the position of our parent in it's parent  */

    pmom = pc_allocobj();
    if (!pmom)
        return (0);

    pmom->pdrive = pdrive;
    /* Find .. in our parent's directory   */
    sectorno = pc_cl2sector(pdrive,pc_finode_cluster(pdrive,pdotdot->finode)); /*FAT32*/
    /* We found .. in our parents dir.   */
    pmom->pdrive = pdrive;
    pmom->blkinfo.my_frstblock =  sectorno; 
    pmom->blkinfo.my_block  =  sectorno;
    pmom->blkinfo.my_index  =  0;
    pmom->isroot = FALSE;
    pd = &pmom->blkinfo;


    pmom->pblkbuff = rbuf = pc_read_blk(pdrive, pmom->blkinfo.my_block);
    if (rbuf)
    {
        pi = (DOSINODE *) &rbuf->data[0];
        OS_CLAIM_FSCRITICAL()
        pc_dos2inode(pmom->finode , pi );
        OS_RELEASE_FSCRITICAL()

        pc_free_buf(rbuf,FALSE);

        /* See if the inode is in the buffers   */
        pfi = pc_scani(pdrive, sectorno, 0);
        if (pfi)
        {
            pc_freei(pmom->finode);
            pmom->finode = pfi;
        }
        else
        {
            pc_marki(pmom->finode , pmom->pdrive , pd->my_block, 
                    pd->my_index);
        }
        return (pmom);

    }
    else    /* Error, something didn't work */
    {
        pc_freeobj(pmom);
        return (0);
    }   
}
#endif

RTFS_FILE(mkchild.c, pc_mkchild)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif

/**************************************************************************
    PC_MKCHILD -  Allocate a DROBJ and fill in based on parent object.

 Description
    Allocate an object and fill in as much of the the block pointer section 
    as possible based on the parent.

 Returns
    Returns a partially initialized DROBJ if enough core available and 
    pmom was a valid subdirectory.
                
****************************************************************************/

DROBJ *pc_mkchild( DROBJ *pmom)                                     /*__fn__*/
{
    DROBJ *pobj;
    DIRBLK *pd;

    /* Mom must be a directory   */
    if (!pc_isadir(pmom))
        return(0);

    /* init the object -   */
    pobj = pc_allocobj();
    if (!pobj)
        return (0);

    pd = &pobj->blkinfo;

    pobj->isroot = FALSE;               /* Child can not be root */
    pobj->pdrive =  pmom->pdrive;   /* Child inherets moms drive */

    /* Now initialize the fields storing where the child inode lives   */
    pd->my_index = 0;
    pd->my_block = pd->my_frstblock = pc_firstblock(pmom);
    if (!pd->my_block)
    {
        pc_freeobj(pobj);
        return (0);
    }

    return (pobj);
}

RTFS_FILE(mknode.c, pc_mknode)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
#if (RTFS_WRITE)

/**************************************************************************
    PC_MKNODE -  Create an empty subdirectory or file.

 Description
    Creates a file or subdirectory ("inode") depending on the flag values in
    attributes. A pointer to an inode is returned for further processing. See
    po_open(),po_close(), pc_mkdir() et al for examples.

    Note: After processing, the DROBJ must be released by calling pc_freeobj.

 Returns
    Returns a pointer to a DROBJ structure for further use, or NULL if the
    inode name already exists or path not found.
**************************************************************************/

/* Make a node from path and attribs create and fill in pobj             */
/* Note: the parent directory is locked before this routine is called    */
DROBJ *pc_mknode(DROBJ *pmom ,char *filename, char *fileext, byte attributes) /*__fn__*/
{
    DROBJ *pobj;
    BOOLEAN ret_val;
    DOSINODE *pdinodes;
    FINODE lfinode;
    CLUSTERTYPE cluster;
    CLUSTERTYPE cltemp;
    DATESTR crdate;
    BLKBUFF *pbuff;
    DDRIVE *pdrive;
    byte attr;
#if (VFAT)
    char vffilename[9],vffileext[4];
#endif

    ret_val = TRUE;
    
    if (!pmom)
        return (0);

    pdrive = pmom->pdrive;
    cluster = 0;

    if (!pdrive)
        ret_val = FALSE;
#if (RTFS_SUBDIRS)
    else if (attributes & ADIRENT)
    {
        /* Grab a new cluster and clear it. We optimize here (10/27/90).
            To minimize fragmentation we give clalloc a hint where to 
            start looking for new clusters */
        CLUSTERTYPE clbase = 0;
        if (!pmom->isroot)
            clbase = pc_finode_cluster(pmom->pdrive,pmom->finode); /* FAT32 */

        /*Grab a cluster for a new dir and cleaer it   */
        cluster = pc_clalloc(pdrive, clbase);

        if (!cluster)
            ret_val = FALSE;
        else if (!pc_clzero( pdrive , cluster ) )
        {
            pc_clrelease(pdrive , cluster);
            ret_val = FALSE;
        }
    }
#endif
    
    if (!ret_val)
    {
        return (0);
    }

    /* For a subdirectory. First make it a simple file. We will change the
        attribute after all is clean */
    attr = attributes;
#if (RTFS_SUBDIRS)
    if (attr & ADIRENT)
        attr = ANORMAL;
#endif
    /* Allocate an empty DROBJ and FINODE to hold the new file   */

    pobj = pc_allocobj();
    if (!pobj)
    {
        return (0);
    }

    /* Load the inode copy name,ext,attr,cluster, size,datetime  */
#if (VFAT)
    pc_malias(vffilename,vffileext, (byte *)filename,pmom);
    pc_init_inode( pobj->finode, vffilename, vffileext,  
                    attr, cluster, /*size*/ 0L ,pc_getsysdate(&crdate) );
#else
    pc_init_inode( pobj->finode, filename, fileext,
                    attr, cluster, /*size*/ 0L ,pc_getsysdate(&crdate) );
#endif

    /* Convert pobj to native and stitch it in to mom   */
#if (VFAT)
    ARGSUSED_PVOID((PFVOID) fileext);
    if (!pc_insert_inode(pobj , pmom, filename))
#else
    if (!pc_insert_inode(pobj , pmom))
#endif
    {
        pc_clrelease(pdrive , cluster);
        pc_freeobj(pobj);
        return (0);
    }

#if (RTFS_SUBDIRS)
    /* 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   */
        pbuff = pc_init_blk( pdrive , pc_cl2sector(pdrive , cluster));
        if (!pbuff)
        {
            pc_freeobj(pobj);
            pc_clrelease(pdrive , cluster);
            return (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, string_dot,string_null, ADIRENT|ARCHIVE, 
                            cluster, /*size*/ 0L ,&crdate);
        /* And to the buffer in intel form   */
        pc_ino2dos (pdinodes, &lfinode);
        /* Now DOTDOT points to mom's cluster   */

#if (FAT32)
        if ((pdrive->fasize == 8) && 
            (pobj->blkinfo.my_frstblock == pdrive->rootblock))
            cltemp = 0;
        else
#endif
            cltemp = pc_sec2cluster(pdrive,pobj->blkinfo.my_frstblock);

        pc_init_inode( &lfinode, string_dot_dot, string_null, ADIRENT|ARCHIVE, cltemp,
                    /*size*/ 0L ,&crdate);
        /* And to the buffer in intel form   */
        pc_ino2dos (++pdinodes, &lfinode );
        /* Write the cluster out   */
        if ( !pc_write_blk ( pbuff ) )
        {
            pc_free_buf(pbuff,TRUE);        /* Error. Chuck the buffer */
            pc_freeobj(pobj);
            pc_clrelease(pdrive , cluster);
            return (0);
        }
        else
            pc_free_buf(pbuff,FALSE);

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

        /* Convert to native. Overwrite the existing inode.Set archive/date  */
        if (!pc_update_inode(pobj, TRUE, TRUE))
        {
            pc_freeobj(pobj);
            pc_clrelease(pdrive , cluster);
            return (0);
        }
    }
#endif
    ret_val = pc_flushfat(pdrive->driveno);

    if (ret_val)
    {
        return (pobj);
    }
    else
    {
        pc_freeobj(pobj);
        return (0);
    }
}
#endif
RTFS_FILE(insinode.c, pc_insert_inode)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
#if (RTFS_WRITE)

/***************************************************************************
    PC_INSERT_INODE - Insert a new inode into an existing directory 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. (see also pc_mknode() )


Returns
    Returns TRUE if all went well, FALSE on a write error, disk full error or 
    root directory full.

**************************************************************************/
/* Note: the parent directory is locked before this routine is called   */

#if (VFAT)
BOOLEAN pc_insert_inode( DROBJ *pobj, DROBJ *pmom, char *lfn)                      /*__fn__*/
#else
BOOLEAN pc_insert_inode( DROBJ *pobj, DROBJ *pmom)                      /*__fn__*/
#endif
{
    BLKBUFF *pbuff;
    DIRBLK *pd;
    DOSINODE *pi;
    int i;
    BOOLEAN retval;
    CLUSTERTYPE cluster;
#if (VFAT)
    byte cksum;
    BOOLEAN end_of_dir; 
    int n_segs;
    /* How many segments do we need   */
//DM: 3/14/99: This has been changed back and forth several times.
//    The correct statement does NOT have the +1. The correct formula
//    is (length+12)/13. The +1 was in anticipation of the NUL character
//    terminator, but that is only used when the filename is not an
//    even multiple of 13. Examples:
//                  1-char name:  (1+12)/13 == 1
//                 13-char name: (13+12)/13 == 1 not 2
//
//    If there are still problems with LFN's, the problem is elsewhere --
//    do not change this again!
//
    n_segs = (tc_strlen(lfn) + 12 )/13;
//  n_segs = ((tc_strlen(lfn) + 1) + 12 )/13;   WRONG -- delete +1 
#endif

    /* Set up pobj      */
    pobj->pdrive = pmom->pdrive;
    pobj->isroot = FALSE;
    pd = &pobj->blkinfo;

    /* Now get the start of the dir   */
    pd->my_block = pd->my_frstblock = pc_firstblock(pmom);

    if (!pd->my_block)
    {
        return (FALSE);
    }
    else
        pd->my_index = 0;

    /* Read the data   */
    pobj->pblkbuff = pbuff = pc_read_blk(pobj->pdrive, pobj->blkinfo.my_block);
    if (!pbuff)
        return(FALSE);
#if (VFAT)
    cksum = pc_cksum((byte*)pobj->finode);  
    end_of_dir = FALSE;
    pc_zeroseglist(&pobj->finode->s);
    pobj->finode->s.ncksum = cksum;
#endif /* VFAT */
    while (pbuff)
    {
        i = pd->my_index = 0;
        pi = (DOSINODE *) &pbuff->data[0];
        /* look for a slot   */
        while ( i < INOPBLOCK )
        {
#if (VFAT)
            if (pi->fname[0] == '\0')
                end_of_dir = TRUE;

            if (pi->fname[0] == PCDELETE || end_of_dir)
            {
                /* Note that we fake an allocation of n_segs + 1 segments.
                   this scheme makes sure that there is room for the DOSINODE
                   immediately after the segment list. We reduce the segment
                   count before we write the segments */
                if (pobj->finode->s.nsegs != (n_segs +1))
                {
                    pc_addtoseglist(&pobj->finode->s, pd->my_block, i);
                }
                /* Write the lfn and dos inode if we have the space   */
                if (pobj->finode->s.nsegs == (n_segs +1))
                {
                    /* Write the long file name entries to their respective 
                        locations */
                    /* Drop the segment count by one before we write.
                       with this scheme we fall out of the loop and 
                       put the DOSINODE in the correct location */
                    pc_reduceseglist(&pobj->finode->s);
                    if (!pc_seglist2disk(pobj->pdrive, &pobj->finode->s, lfn))
                    {
                        pc_free_buf(pbuff, TRUE);
                        goto clean_and_fail;
                    }
                    pd->my_index = i;

⌨️ 快捷键说明

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