예제 #1
0
static errcode_t ocfs2_try_to_write_inline_data(ocfs2_cached_inode *ci,
						void *buf, uint32_t count,
						uint64_t offset)
{
	int ret;
	uint64_t end = offset + count;
	ocfs2_filesys *fs = ci->ci_fs;
	struct ocfs2_dinode *di = ci->ci_inode;

	/* Handle inodes which already have inline data 1st. */
	if (di->i_dyn_features & OCFS2_INLINE_DATA_FL) {
		if (ocfs2_size_fits_inline_data(ci->ci_inode, end))
			goto do_inline_write;

		/*
		 * The write won't fit - we have to give this inode an
		 * inline extent list now.
		 */
		ret = ocfs2_convert_inline_data_to_extents(ci);
		if (!ret)
			ret = OCFS2_ET_CANNOT_INLINE_DATA;
		goto out;
	}

	if (di->i_clusters > 0 || end > ocfs2_max_inline_data(fs->fs_blocksize))
		return OCFS2_ET_CANNOT_INLINE_DATA;

	ocfs2_set_inode_data_inline(fs, ci->ci_inode);
	ci->ci_inode->i_dyn_features |= OCFS2_INLINE_DATA_FL;

do_inline_write:
	ret = ocfs2_inline_data_write(di, buf, count, offset);
	if (ret)
		goto out;

	ret = ocfs2_write_cached_inode(fs, ci);
out:
	return ret;
}
예제 #2
0
파일: aops.c 프로젝트: Tigrouzen/k1099
int ocfs2_read_inline_data(struct inode *inode, struct page *page,
			   struct buffer_head *di_bh)
{
	void *kaddr;
	loff_t size;
	struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;

	if (!(le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL)) {
		ocfs2_error(inode->i_sb, "Inode %llu lost inline data flag",
			    (unsigned long long)OCFS2_I(inode)->ip_blkno);
		return -EROFS;
	}

	size = i_size_read(inode);

	if (size > PAGE_CACHE_SIZE ||
	    size > ocfs2_max_inline_data(inode->i_sb)) {
		ocfs2_error(inode->i_sb,
			    "Inode %llu has with inline data has bad size: %Lu",
			    (unsigned long long)OCFS2_I(inode)->ip_blkno,
			    (unsigned long long)size);
		return -EROFS;
	}

	kaddr = kmap_atomic(page, KM_USER0);
	if (size)
		memcpy(kaddr, di->id2.i_data.id_data, size);
	/* Clear the remaining part of the page */
	memset(kaddr + size, 0, PAGE_CACHE_SIZE - size);
	flush_dcache_page(page);
	kunmap_atomic(kaddr, KM_USER0);

	SetPageUptodate(page);

	return 0;
}