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

📄 drobj.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 5 页
字号:
                    /* Update the DOS disk   */
                    pc_ino2dos( pi, pobj->finode );
                    /* Write the data   */
                    retval = pc_write_blk(pobj->pblkbuff);

                    /* Mark the inode in the inode buffer   */
                    if (retval)
                        pc_marki(pobj->finode , pobj->pdrive , pd->my_block, 
                               pd->my_index );
                    pc_free_buf(pbuff, (BOOLEAN)!retval);
                    return (retval);
                }
            }
            else
            {
                pc_zeroseglist(&pobj->finode->s);
            }
#else /* IF NOT VFAT */
            /* End of dir if name is 0   */
            if ( (pi->fname[0] == '\0') || (pi->fname[0] == PCDELETE) )
            {
                pd->my_index = (word)i;

                /* Update the DOS disk   */
                pc_ino2dos( pi, pobj->finode );
                /* Write the data   */
                retval = pc_write_blk(pobj->pblkbuff);

                /* Mark the inode in the inode buffer   */
                if (retval)
                    pc_marki(pobj->finode , pobj->pdrive , pd->my_block, 
                            pd->my_index );
                pc_free_buf(pbuff, (BOOLEAN)(!retval));
                return (retval);
            }
#endif /* VFAT */
            i++;
            pi++;
        }
        /* Not in that block. Try again   */
        pc_free_buf(pbuff,FALSE);
        /* Update the objects block pointer   */
        if (!pc_next_block(pobj))
#if (VFAT)
        {
#if (FAT32)
        if (pmom->pdrive->fasize != 8)
#endif
            if  (pc_isroot(pmom))   
                return (FALSE);

#if RTFS_SUBDIRS
               /* Ok:There ar no slots in mom. We have to make one. And copy our stuf in  */
#if (FAT32)
        if (pobj->pdrive->fasize == 8)
        {
            dword tmpcl = pc_finode_cluster(pobj->pdrive,pmom->finode);
            if (tmpcl == 0)
                tmpcl = pc_sec2cluster(pobj->pdrive, pmom->pdrive->rootblock);
            cluster = pc_clgrow(pobj->pdrive , tmpcl);
        }
        else
#endif
            cluster = pc_clgrow(pobj->pdrive, pc_finode_cluster(pobj->pdrive,pmom->finode)); /* FAT32 */

        if (!cluster)
            return (FALSE);

        /* Don't forget where the new item is   */
        pd->my_block = pc_cl2sector(pobj->pdrive , cluster);
        pd->my_index = 0;

        /* Zero out the cluster    */
        if (!pc_clzero( pobj->pdrive , cluster ) )
            goto clean_and_fail;

        /* Copy the item into the first block   */
        pobj->pblkbuff = pbuff = pc_init_blk( pobj->pdrive , pd->my_block);
        if (!pbuff)
            goto clean_and_fail;
#endif /* Subdir */
        }
        else
#else   /* IF NOT VFAT */
            break;
#endif /* VFAT */
        pobj->pblkbuff = pbuff = pc_read_blk(pobj->pdrive, pobj->blkinfo.my_block);
    }

#if (!VFAT)
    /* Hmmm - root full ??. This is a problem   */
#if (FAT32)
    if (pmom->pdrive->fasize != 8)
#endif
    if (pc_isroot(pmom))
        return (FALSE);
#if RTFS_SUBDIRS
    /* Ok:There ar no slots in mom. We have to make one. And copy our stuf in  */
#if (FAT32)
    if (pobj->pdrive->fasize == 8)
    {
        dword tmpcl = pc_finode_cluster(pobj->pdrive,pmom->finode);
        if (tmpcl == 0)
            tmpcl = pc_sec2cluster(pobj->pdrive, pmom->pdrive->rootblock);
        cluster = pc_clgrow(pobj->pdrive , tmpcl);
    }
    else
#endif
        cluster = pc_clgrow(pobj->pdrive, pc_finode_cluster(pobj->pdrive,pmom->finode)); /*FAT32 */

    if (!cluster)
        return (FALSE);
    /* Don't forget where the new item is   */
    pd->my_block = pc_cl2sector(pobj->pdrive , cluster);
    pd->my_index = 0;

    /* Zero out the cluster    */
    if (!pc_clzero( pobj->pdrive , cluster ) )
        goto clean_and_fail;
    /* Copy the item into the first block   */
    pbuff = pc_init_blk( pobj->pdrive , pd->my_block);
    if (!pbuff)
        goto clean_and_fail;

    pc_ino2dos (  (DOSINODE *) &pbuff->data[0] ,  pobj->finode ) ;
    /* Write it out   */
    if ( !pc_write_blk ( pbuff ) )
    {
        pc_free_buf(pbuff,TRUE);
        goto clean_and_fail;
    }

    /* We made a new slot. Mark the inode as belonging there   */
    pc_marki(pobj->finode , pobj->pdrive , pd->my_block, pd->my_index );
    pc_free_buf(pbuff,FALSE);
    return (TRUE);
#endif /* Subdir */
#endif /* VFAT */
clean_and_fail:
#if RTFS_SUBDIRS
#if (FAT32)
    if (pobj->pdrive->fasize == 8)
    {
        dword tmpcl = pc_finode_cluster(pobj->pdrive,pmom->finode);
        if (tmpcl == 0)
            tmpcl = pc_sec2cluster(pmom->pdrive, pmom->pdrive->rootblock);
        pc_cl_truncate(pobj->pdrive, tmpcl, cluster);
    }
    else      
#endif /* FAT32 */
        pc_cl_truncate(pobj->pdrive, pc_finode_cluster(pobj->pdrive,pmom->finode), cluster); /* FAT32 */
#endif /* Subdir */
    return (FALSE);
}
#endif

RTFS_FILE(rmnode.c, pc_rmnode)

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

/***************************************************************************
    PC_RMNODE - Delete an inode unconditionally.

 Description
    Delete the inode at pobj and flush the file allocation table. Does not
    check file permissions or if the file is already open. (see also pc_unlink
    and pc_rmdir). The inode is marked deleted on the disk and the cluster
    chain associated with the inode is freed. (Un-delete won't work)

 Returns
    Returns TRUE if it successfully deleted the inode an flushed the fat.

*****************************************************************************/


/* Delete a file / dir or volume. Don't check for write access et al     */
/* Note: the parent directory is locked before this routine is called    */
BOOLEAN pc_rmnode( DROBJ *pobj)                                         /*__fn__*/
{
    CLUSTERTYPE cluster;
    BOOLEAN ret_val;
    /* Don't delete anything that has multiple links   */
    if (pobj->finode->opencount > 1)
    {
#if (VFAT)
err_ex:
#endif
        pc_report_error(PCERR_REMINODE);
        return (FALSE);
    }

    /* Mark it deleted and unlink the cluster chain   */
    pobj->finode->fname[0] = PCDELETE;
#if (VFAT)
     if (!pc_deleteseglist(pobj->pdrive, &pobj->finode->s))
        goto err_ex;
#endif
    cluster = pc_finode_cluster(pobj->pdrive,pobj->finode); /* FAT32 */

    /* We free up store right away. Don't leave cluster pointer 
    hanging around to cause problems. */
    pc_pfinode_cluster(pobj->pdrive,pobj->finode,0); /* FAT32 */
    /* Convert to native. Overwrite the existing inode.Set archive/date  */
    if (pc_update_inode(pobj, TRUE, TRUE))
    {
        /* And clear up the space   */
        pc_freechain(pobj->pdrive, cluster);
        ret_val = pc_flushfat(pobj->pdrive->driveno);
        return (ret_val);
    }
    /* If it gets here we had a probblem   */
    return(FALSE);
}
#endif

RTFS_FILE(updinode.c, pc_update_inode)

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

/**************************************************************************
    PC_UPDATE_INODE - Flush an inode to disk
                        
Summary

Description
    Read the disk inode information stored in pobj and write it to
    the block and offset on the disk where it belongs. The disk is
    first read to get the block and then the inode info is merged in
    and the block is written. (see also pc_mknode() )

Returns
    Returns TRUE if all went well, no on a write error.

*****************************************************************************
*/

/* Take a DROBJ that contains correct my_index & my_block. And an inode.
    Load the block. Copy the inode in and write it back out */
BOOLEAN pc_update_inode(DROBJ *pobj, BOOLEAN set_archive, BOOLEAN set_date) /*__fn__*/
{
    BLKBUFF *pbuff;
    DOSINODE *pi;
    int i;
    BOOLEAN retval;
    DIRBLK *pd;
    DATESTR crdate;

    pd = &pobj->blkinfo;
    i   = pd->my_index;
    if ( i >= INOPBLOCK || i < 0 )  /* Index into block */
        return (FALSE);

    OS_CLAIM_FSCRITICAL()
    /* Set the archive bit and the date   */
    if (set_archive)
        pobj->finode->fattribute |= ARCHIVE;

    if (set_date)
    {
        pc_getsysdate(&crdate);
        pobj->finode->ftime = crdate.time;
        pobj->finode->fdate = crdate.date;
    }
    OS_RELEASE_FSCRITICAL()
    /* Read the data   */
    pobj->pblkbuff = pbuff = pc_read_blk(pobj->pdrive, pobj->blkinfo.my_block);
    if (pbuff)
    {
        pi = (DOSINODE *) &pbuff->data[0];
        /* Copy it off and write it   */
        pc_ino2dos( (pi+i), pobj->finode );
        retval = pc_write_blk(pobj->pblkbuff);
        /* Free the buff. If retval == FALSE(fail), pass a TRUE to
            freebuf so it will discard the buffer. */
        pc_free_buf(pbuff, (BOOLEAN)!retval);
        return (retval);
    }
    return (FALSE);
}
#endif

RTFS_FILE(getroot.c, pc_get_root)

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

/*************************************************************************
    PC_GET_ROOT -  Create the special ROOT object for a drive.
 Description
    Use the information in pdrive to create a special object for accessing
    files in the root directory.

 Returns
    Returns a pointer to a DROBJ, or NULL if no core available.
****************************************************************************/

/* Initialize the special "root" object 
    Note: We do not read any thing in here we just set up 
    the block pointers. */

DROBJ *pc_get_root( DDRIVE *pdrive)                                 /*__fn__*/
{
    DIRBLK *pd;
    DROBJ *pobj;
    FINODE *pfi;

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

    pfi = pc_scani(pdrive, 0, 0);

    if (pfi)
    {
        pc_freei(pobj->finode);
        pobj->finode = pfi;
    }
    else    /* No inode in the inode list. Copy the data over
                and mark where it came from */
    {
        pc_marki(pobj->finode , pdrive , 0, 0);
    }


    /* Add a TEST FOR DRIVE INIT Here later   */
    pobj->pdrive = pdrive;
    /* Set up the tree stuf so we know it is the root   */
    pd = &pobj->blkinfo;
    pd->my_frstblock = pdrive->rootblock;
    pd->my_block = pdrive->rootblock;
    pd->my_index = 0;
    pobj->isroot = TRUE;
    return (pobj);
}

RTFS_FILE(firstblk.c, pc_firstblock)

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

/****************************************************************************
    PC_FIRSTBLOCK -  Return the absolute block number of a directory's 
                    contents.
 Description
    Returns the block number of the first inode in the subdirectory. If
    pobj is the root directory the first block of the root will be returned.

 Returns
    Returns 0 if the obj does not point to a directory, otherwise the
    first block in the directory is returned.

*****************************************************************************/

/* Get  the first block of a root or subdir   */
BLOCKT pc_firstblock( DROBJ *pobj)                                  /*__fn__*/
{
    if (!pc_isadir(pobj))
        return (BLOCKEQ0);

    /* Root dir ?   */
#if (RTFS_SUBDIRS)
    if (!pobj->isroot)
        return (pc_cl2sector(pobj->pdrive , pc_finode_cluster(pobj->pdrive, pobj->finode)) );
    else
#endif
        return (pobj->blkinfo.my_frstblock);
}

RTFS_FILE(nextblk.c, pc_next_block)

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

/***************************************************************************
    PC_NEXT_BLOCK - Calculate the next block owned by an object.

 Description
    Find the next block owned by an object in either the root or a cluster
    chain and update the blockinfo section of the object.

 Returns
    Returns TRUE or FALSE on end of chain.
                
*****************************************************************************/


/* Calculate the next block in an object   */
BOOLEAN pc_next_block( DROBJ *pobj)                                 /*__fn__*/
{
    BLOCKT nxt;

    nxt = pc_l_next_block(pobj->pdrive, pobj->blkinfo.my_block);

    if (nxt)
    {
        pobj->blkinfo.my_block = nxt;
        return (TRUE);
    }
    else
        return (FALSE);
}
RTFS_FILE(lnextblk.c, pc_l_next_block)

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

/**************************************************************************
    PC_L_NEXT_BLOCK - Calculate the next block in a chain.

⌨️ 快捷键说明

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