示例#1
0
static int copy_one_inline(struct btrfs_root *root, int fd,
				struct btrfs_path *path, u64 pos)
{
	struct extent_buffer *leaf = path->nodes[0];
	struct btrfs_file_extent_item *fi;
	char buf[4096];
	char *outbuf;
	u64 ram_size;
	ssize_t done;
	unsigned long ptr;
	int ret;
	int len;
	int inline_item_len;
	int compress;

	fi = btrfs_item_ptr(leaf, path->slots[0],
			    struct btrfs_file_extent_item);
	ptr = btrfs_file_extent_inline_start(fi);
	len = btrfs_file_extent_ram_bytes(leaf, fi);
	inline_item_len = btrfs_file_extent_inline_item_len(leaf, btrfs_item_nr(path->slots[0]));
	read_extent_buffer(leaf, buf, ptr, inline_item_len);

	compress = btrfs_file_extent_compression(leaf, fi);
	if (compress == BTRFS_COMPRESS_NONE) {
		done = pwrite(fd, buf, len, pos);
		if (done < len) {
			fprintf(stderr, "Short inline write, wanted %d, did "
				"%zd: %d\n", len, done, errno);
			return -1;
		}
		return 0;
	}

	ram_size = btrfs_file_extent_ram_bytes(leaf, fi);
	outbuf = calloc(1, ram_size);
	if (!outbuf) {
		error("not enough memory");
		return -ENOMEM;
	}

	ret = decompress(root, buf, outbuf, inline_item_len, &ram_size,
			 compress);
	if (ret) {
		free(outbuf);
		return ret;
	}

	done = pwrite(fd, outbuf, ram_size, pos);
	free(outbuf);
	if (done < ram_size) {
		fprintf(stderr, "Short compressed inline write, wanted %Lu, "
			"did %zd: %d\n", ram_size, done, errno);
		return -1;
	}

	return 0;
}
示例#2
0
文件: file-item.c 项目: ebichu/dd-wrt
int btrfs_insert_inline_extent(struct btrfs_trans_handle *trans,
			       struct btrfs_root *root, u64 objectid,
			       u64 offset, char *buffer, size_t size)
{
	struct btrfs_key key;
	struct btrfs_path *path;
	struct extent_buffer *leaf;
	unsigned long ptr;
	struct btrfs_file_extent_item *ei;
	u32 datasize;
	int err = 0;
	int ret;

	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;

	key.objectid = objectid;
	key.offset = offset;
	btrfs_set_key_type(&key, BTRFS_EXTENT_DATA_KEY);

	datasize = btrfs_file_extent_calc_inline_size(size);
	ret = btrfs_insert_empty_item(trans, root, path, &key, datasize);
	if (ret) {
		err = ret;
		goto fail;
	}

	leaf = path->nodes[0];
	ei = btrfs_item_ptr(leaf, path->slots[0],
			    struct btrfs_file_extent_item);
	btrfs_set_file_extent_generation(leaf, ei, trans->transid);
	btrfs_set_file_extent_type(leaf, ei, BTRFS_FILE_EXTENT_INLINE);
	btrfs_set_file_extent_ram_bytes(leaf, ei, size);
	btrfs_set_file_extent_compression(leaf, ei, 0);
	btrfs_set_file_extent_encryption(leaf, ei, 0);
	btrfs_set_file_extent_other_encoding(leaf, ei, 0);

	ptr = btrfs_file_extent_inline_start(ei) + offset - key.offset;
	write_extent_buffer(leaf, buffer, ptr, size);
	btrfs_mark_buffer_dirty(leaf);
fail:
	btrfs_free_path(path);
	return err;
}