Example #1
0
/* truncate the file to the specified length */
static int ftruncate_internal(struct filestr_desc *file, file_size_t size,
                              bool write_now)
{
    int rc = 0, rc2 = 1;

    file_size_t cursize = *file->sizep;
    file_size_t truncsize = MIN(size, cursize);

    if (write_now)
    {
        unsigned long sector = filesize_sectors(truncsize);
        struct filestr_cache *const cachep = file->stream.cachep;

        if (cachep->flags == (FSC_NEW|FSC_DIRTY) &&
            cachep->sector + 1 == sector)
        {
            /* sector created but may have never been added to the cluster
               chain; flush it now or the subsequent may fail */
            rc2 = flush_cache(file);
            if (rc2 == FAT_RC_ENOSPC)
            {
                /* no space left on device; further truncation needed */
                discard_cache(file);
                truncsize = ALIGN_DOWN(truncsize - 1, SECTOR_SIZE);
                sector--;
                rc = rc2;
            }
            else if (rc2 < 0)
                FILE_ERROR(ERRNO, rc2 * 10 - 1);
        }

        rc2 = fat_seek(&file->stream.fatstr, sector);
        if (rc2 < 0)
            FILE_ERROR(EIO, rc2 * 10 - 2);

        rc2 = fat_truncate(&file->stream.fatstr);
        if (rc2 < 0)
            FILE_ERROR(EIO, rc2 * 10 - 3);
    }
    /* else just change the cached file size */

    if (truncsize < cursize)
    {
        *file->sizep = truncsize;
        fileop_ontruncate_internal(&file->stream);
    }

    /* if truncation was partially successful, it effectively destroyed
       everything after the truncation point; still, indicate failure
       after adjusting size */
    if (rc2 == 0)
        FILE_ERROR(EIO, -4);
    else if (rc2 < 0)
        FILE_ERROR(ERRNO, rc2);

file_error:
    return rc;
}
Example #2
0
/*
 * Truncate a file to 0 length.
 */
static void UMSDOS_truncate (struct inode *inode)
{
    Printk (("UMSDOS_truncate\n"));
    if (!IS_RDONLY (inode)) {
        fat_truncate (inode);
        inode->i_ctime = inode->i_mtime = CURRENT_TIME;
        mark_inode_dirty(inode);
    }
}