Esempio n. 1
0
ssize_t ext2_write_r (struct _reent *r, int fd, const char *ptr, size_t len)
{
    //ext2_log_trace("fd %p, ptr %p, len %i\n", (void *) fd, ptr, len);

    ext2_file_state* file = STATE(fd);

    // Sanity check
    if (!file || !file->vd || !file->fd) {
        r->_errno = EINVAL;
        return -1;
    }

    // Short circuit cases where we don't actually have to do anything
    if (!ptr || len <= 0) {
        return 0;
    }

    // Check that we are allowed to write to this file
    if (!file->write) {
        r->_errno = EACCES;
        return -1;
    }
    
    // Lock
    ext2Lock(file->vd);

    errcode_t err = 0;
    u32 written = 0;

    // Write to the files data atrribute
    while (len > 0)
    {
        u32 wrote = 0;

        err = ext2fs_file_write(file->fd, ptr, len, &wrote);
        if (err)
            break;

        len -= wrote;
        ptr += wrote;
        written += wrote;
    }

    // Check for errors
    if (err) {
        ext2Unlock(file->vd);
        r->_errno = errno;
        return (err ? err : -1);
    }

    // Unlock
    ext2Unlock(file->vd);

    return (written == 0 ? -1 : written);
}
Esempio n. 2
0
static errcode_t inode_write_byte(io_channel channel, unsigned long offset,
				 int size, const void *buf)
{
	struct inode_private_data *data;
	errcode_t	retval = 0;

	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
	data = (struct inode_private_data *) channel->private_data;
	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);

	if ((retval = ext2fs_file_lseek(data->file, offset,
					EXT2_SEEK_SET, 0)))
		return retval;

	return ext2fs_file_write(data->file, buf, size, 0);
}
Esempio n. 3
0
size_t do_write (ext2_file_t efile, const char *buf, size_t size, off_t offset)
{
	int rt;
	const char *tmp;
	unsigned int wr;
	unsigned long long npos;
	unsigned long long fsize;

	debugf("enter");

	rt = ext2fs_file_get_lsize(efile, &fsize);
	if (rt != 0) {
		debugf("ext2fs_file_get_lsize(efile, &fsize); failed");
		return rt;
	}
	if (offset + size > fsize) {
		rt = ext2fs_file_set_size2(efile, offset + size);
		if (rt) {
			debugf("extfs_file_set_size(efile, %lld); failed", offset + size);
			return rt;
		}
	}

	rt = ext2fs_file_llseek(efile, offset, SEEK_SET, &npos);
	if (rt) {
		debugf("ext2fs_file_lseek(efile, %lld, SEEK_SET, &npos); failed", offset);
		return rt;
	}

	for (rt = 0, wr = 0, tmp = buf; size > 0 && rt == 0; size -= wr, tmp += wr) {
		rt = ext2fs_file_write(efile, tmp, size, &wr);
		debugf("rt: %d, size: %u, written: %u", rt, size, wr);
	}
	if (rt) {
		debugf("ext2fs_file_write(edile, tmp, size, &wr); failed");
		return rt;
	}

	rt = ext2fs_file_flush(efile);
	if (rt) {
		debugf("ext2_file_flush(efile); failed");
		return rt;
	}

	debugf("leave");
	return wr;
}
Esempio n. 4
0
static errcode_t inode_write_blk64(io_channel channel,
				unsigned long long block, int count, const void *buf)
{
	struct inode_private_data *data;
	errcode_t	retval;

	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
	data = (struct inode_private_data *) channel->private_data;
	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);

	if ((retval = ext2fs_file_lseek(data->file,
					block * channel->block_size,
					EXT2_SEEK_SET, 0)))
		return retval;

	count = (count < 0) ? -count : (count * channel->block_size);

	return ext2fs_file_write(data->file, buf, count, 0);
}
Esempio n. 5
0
size_t do_write (ext2_file_t efile, const char *buf, size_t size, off_t offset)
{
	int rt;
	const char *tmp;
	unsigned int wr;
	unsigned long long npos;
	unsigned long long fsize;

	debugf("enter");

	rt = ext2fs_file_get_lsize(efile, &fsize);
	if (rt != 0) {
		debugf("ext2fs_file_get_lsize(efile, &fsize); failed");
		return rt;
	}
	if (offset + size > fsize) {
		rt = ext2fs_file_set_lsize(efile, offset + size);
		if (rt) {
			debugf("extfs_file_set_size(efile, %lld); failed", offset + size);
			return rt;
		}
	}

	char c[] = "10";
 	rt = ext2fs_file_write(efile, c, 2, &wr);

	if (rt) {
		debugf("ext2fs_file_write(edile, tmp, size, &wr); failed");
		return rt;
	}

	rt = ext2fs_file_flush(efile);
	if (rt) {
		debugf("ext2_file_flush(efile); failed");
		return rt;
	}

	debugf("leave");
	return size;
}
Esempio n. 6
0
static errcode_t
ext2fs_inline_data_file_expand(ext2_filsys fs, ext2_ino_t ino,
                               struct ext2_inode *inode, char *buf, size_t size)
{
    ext2_file_t e2_file;
    errcode_t retval;

    /* Update inode */
    if (EXT2_HAS_INCOMPAT_FEATURE(fs->super,
                                  EXT3_FEATURE_INCOMPAT_EXTENTS)) {
        int i;
        struct ext3_extent_header *eh;

        eh = (struct ext3_extent_header *) &inode->i_block[0];
        eh->eh_depth = 0;
        eh->eh_entries = 0;
        eh->eh_magic = ext2fs_cpu_to_le16(EXT3_EXT_MAGIC);
        i = (sizeof(inode->i_block) - sizeof(*eh)) /
            sizeof(struct ext3_extent);
        eh->eh_max = ext2fs_cpu_to_le16(i);
        inode->i_flags |= EXT4_EXTENTS_FL;
    }
    inode->i_flags &= ~EXT4_INLINE_DATA_FL;
    inode->i_size = 0;
    retval = ext2fs_write_inode(fs, ino, inode);
    if (retval)
        return retval;

    /* Write out the block buffer */
    retval = ext2fs_file_open(fs, ino, EXT2_FILE_WRITE, &e2_file);
    if (retval)
        return retval;
    retval = ext2fs_file_write(e2_file, buf, size, 0);
    ext2fs_file_close(e2_file);
    return retval;
}
Esempio n. 7
0
static errcode_t copy_file(ext2_filsys fs, int fd, ext2_ino_t newfile,
			   int bufsize, int make_holes)
{
	ext2_file_t	e2_file;
	errcode_t	retval, close_ret;
	int		got;
	unsigned int	written;
	char		*buf;
	char		*ptr;
	char		*zero_buf;
	int		cmp;

	retval = ext2fs_file_open(fs, newfile,
				  EXT2_FILE_WRITE, &e2_file);
	if (retval)
		return retval;

	retval = ext2fs_get_mem(bufsize, &buf);
	if (retval) {
		com_err("copy_file", retval, "can't allocate buffer\n");
		goto out_close;
	}

	/* This is used for checking whether the whole block is zero */
	retval = ext2fs_get_memzero(bufsize, &zero_buf);
	if (retval) {
		com_err("copy_file", retval, "can't allocate zero buffer\n");
		goto out_free_buf;
	}

	while (1) {
		got = read(fd, buf, bufsize);
		if (got == 0)
			break;
		if (got < 0) {
			retval = errno;
			goto fail;
		}
		ptr = buf;

		/* Sparse copy */
		if (make_holes) {
			/* Check whether all is zero */
			cmp = memcmp(ptr, zero_buf, got);
			if (cmp == 0) {
				 /* The whole block is zero, make a hole */
				retval = ext2fs_file_lseek(e2_file, got,
							   EXT2_SEEK_CUR,
							   NULL);
				if (retval)
					goto fail;
				got = 0;
			}
		}

		/* Normal copy */
		while (got > 0) {
			retval = ext2fs_file_write(e2_file, ptr,
						   got, &written);
			if (retval)
				goto fail;

			got -= written;
			ptr += written;
		}
	}

fail:
	ext2fs_free_mem(&zero_buf);
out_free_buf:
	ext2fs_free_mem(&buf);
out_close:
	close_ret = ext2fs_file_close(e2_file);
	if (retval == 0)
		retval = close_ret;
	return retval;
}