コード例 #1
0
ファイル: xattr.c プロジェクト: ANFS/ANFS-kernel
int __btrfs_setxattr(struct btrfs_trans_handle *trans,
		     struct inode *inode, const char *name,
		     const void *value, size_t size, int flags)
{
	struct btrfs_root *root = BTRFS_I(inode)->root;
	int ret;

	if (trans)
		return do_setxattr(trans, inode, name, value, size, flags);

	trans = btrfs_start_transaction(root, 2);
	if (IS_ERR(trans))
		return PTR_ERR(trans);

	btrfs_set_trans_block_group(trans, inode);

	ret = do_setxattr(trans, inode, name, value, size, flags);
	if (ret)
		goto out;

	inode->i_ctime = CURRENT_TIME;
	ret = btrfs_update_inode(trans, root, inode);
	BUG_ON(ret);
out:
	btrfs_end_transaction_throttle(trans, root);
	return ret;
}
コード例 #2
0
ファイル: file.c プロジェクト: AppEngine/linux-2.6
/*
 * after copy_from_user, pages need to be dirtied and we need to make
 * sure holes are created between the current EOF and the start of
 * any next extents (if required).
 *
 * this also makes the decision about creating an inline extent vs
 * doing real data extents, marking pages dirty and delalloc as required.
 */
static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans,
				   struct btrfs_root *root,
				   struct file *file,
				   struct page **pages,
				   size_t num_pages,
				   loff_t pos,
				   size_t write_bytes)
{
	int err = 0;
	int i;
	struct inode *inode = fdentry(file)->d_inode;
	struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
	u64 hint_byte;
	u64 num_bytes;
	u64 start_pos;
	u64 end_of_last_block;
	u64 end_pos = pos + write_bytes;
	loff_t isize = i_size_read(inode);

	start_pos = pos & ~((u64)root->sectorsize - 1);
	num_bytes = (write_bytes + pos - start_pos +
		    root->sectorsize - 1) & ~((u64)root->sectorsize - 1);

	end_of_last_block = start_pos + num_bytes - 1;

	lock_extent(io_tree, start_pos, end_of_last_block, GFP_NOFS);
	trans = btrfs_join_transaction(root, 1);
	if (!trans) {
		err = -ENOMEM;
		goto out_unlock;
	}
	btrfs_set_trans_block_group(trans, inode);
	hint_byte = 0;

	set_extent_uptodate(io_tree, start_pos, end_of_last_block, GFP_NOFS);

	/* check for reserved extents on each page, we don't want
	 * to reset the delalloc bit on things that already have
	 * extents reserved.
	 */
	btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block);
	for (i = 0; i < num_pages; i++) {
		struct page *p = pages[i];
		SetPageUptodate(p);
		ClearPageChecked(p);
		set_page_dirty(p);
	}
	if (end_pos > isize) {
		i_size_write(inode, end_pos);
		/* we've only changed i_size in ram, and we haven't updated
		 * the disk i_size.  There is no need to log the inode
		 * at this time.
		 */
	}
	err = btrfs_end_transaction(trans, root);
out_unlock:
	unlock_extent(io_tree, start_pos, end_of_last_block, GFP_NOFS);
	return err;
}
コード例 #3
0
ファイル: xattr.c プロジェクト: laudarch/simcom-linux-kernel
int __btrfs_setxattr(struct inode *inode, const char *name,
			    const void *value, size_t size, int flags)
{
	struct btrfs_dir_item *di;
	struct btrfs_root *root = BTRFS_I(inode)->root;
	struct btrfs_trans_handle *trans;
	struct btrfs_path *path;
	int ret = 0, mod = 0;

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

	trans = btrfs_join_transaction(root, 1);
	btrfs_set_trans_block_group(trans, inode);

	/* first lets see if we already have this xattr */
	di = btrfs_lookup_xattr(trans, root, path, inode->i_ino, name,
				strlen(name), -1);
	if (IS_ERR(di)) {
		ret = PTR_ERR(di);
		goto out;
	}

	/* ok we already have this xattr, lets remove it */
	if (di) {
		/* if we want create only exit */
		if (flags & XATTR_CREATE) {
			ret = -EEXIST;
			goto out;
		}

		ret = btrfs_delete_one_dir_name(trans, root, path, di);
		if (ret)
			goto out;
		btrfs_release_path(root, path);

		/* if we don't have a value then we are removing the xattr */
		if (!value) {
			mod = 1;
			goto out;
		}
	} else {
		btrfs_release_path(root, path);

		if (flags & XATTR_REPLACE) {
			/* we couldn't find the attr to replace */
			ret = -ENODATA;
			goto out;
		}
	}

	/* ok we have to create a completely new xattr */
	ret = btrfs_insert_xattr_item(trans, root, name, strlen(name),
				      value, size, inode->i_ino);
	if (ret)
		goto out;
	mod = 1;

out:
	if (mod) {
		inode->i_ctime = CURRENT_TIME;
		ret = btrfs_update_inode(trans, root, inode);
	}

	btrfs_end_transaction(trans, root);
	btrfs_free_path(path);
	return ret;
}