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); }
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); }
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; }
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); }
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; }
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; }
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; }