Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 50f2d407 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of git://github.com/chrismason/linux

* 'for-linus' of git://github.com/chrismason/linux:
  Btrfs: only clear the need lookup flag after the dentry is setup
  BTRFS: Fix lseek return value for error
  Btrfs: don't change inode flag of the dest clone file
  Btrfs: don't make a file partly checksummed through file clone
  Btrfs: fix pages truncation in btrfs_ioctl_clone()
  btrfs: fix d_off in the first dirent
parents c2d7b49f a66e7cc6
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -1817,6 +1817,11 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int origin)
		goto out;
	case SEEK_DATA:
	case SEEK_HOLE:
		if (offset >= i_size_read(inode)) {
			mutex_unlock(&inode->i_mutex);
			return -ENXIO;
		}

		ret = find_desired_extent(inode, &offset, origin);
		if (ret) {
			mutex_unlock(&inode->i_mutex);
@@ -1825,11 +1830,11 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int origin)
	}

	if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) {
		ret = -EINVAL;
		offset = -EINVAL;
		goto out;
	}
	if (offset > inode->i_sb->s_maxbytes) {
		ret = -EINVAL;
		offset = -EINVAL;
		goto out;
	}

+14 −4
Original line number Diff line number Diff line
@@ -4018,7 +4018,8 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
		memcpy(&location, dentry->d_fsdata, sizeof(struct btrfs_key));
		kfree(dentry->d_fsdata);
		dentry->d_fsdata = NULL;
		d_clear_need_lookup(dentry);
		/* This thing is hashed, drop it for now */
		d_drop(dentry);
	} else {
		ret = btrfs_inode_by_name(dir, dentry, &location);
	}
@@ -4085,7 +4086,15 @@ static void btrfs_dentry_release(struct dentry *dentry)
static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
				   struct nameidata *nd)
{
	return d_splice_alias(btrfs_lookup_dentry(dir, dentry), dentry);
	struct dentry *ret;

	ret = d_splice_alias(btrfs_lookup_dentry(dir, dentry), dentry);
	if (unlikely(d_need_lookup(dentry))) {
		spin_lock(&dentry->d_lock);
		dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
		spin_unlock(&dentry->d_lock);
	}
	return ret;
}

unsigned char btrfs_filetype_table[] = {
@@ -4125,7 +4134,8 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,

	/* special case for "." */
	if (filp->f_pos == 0) {
		over = filldir(dirent, ".", 1, 1, btrfs_ino(inode), DT_DIR);
		over = filldir(dirent, ".", 1,
			       filp->f_pos, btrfs_ino(inode), DT_DIR);
		if (over)
			return 0;
		filp->f_pos = 1;
@@ -4134,7 +4144,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
	if (filp->f_pos == 1) {
		u64 pino = parent_ino(filp->f_path.dentry);
		over = filldir(dirent, "..", 2,
			       2, pino, DT_DIR);
			       filp->f_pos, pino, DT_DIR);
		if (over)
			return 0;
		filp->f_pos = 2;
+9 −5
Original line number Diff line number Diff line
@@ -2177,6 +2177,11 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
	if (!(src_file->f_mode & FMODE_READ))
		goto out_fput;

	/* don't make the dst file partly checksummed */
	if ((BTRFS_I(src)->flags & BTRFS_INODE_NODATASUM) !=
	    (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM))
		goto out_fput;

	ret = -EISDIR;
	if (S_ISDIR(src->i_mode) || S_ISDIR(inode->i_mode))
		goto out_fput;
@@ -2226,6 +2231,10 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
			goto out_unlock;
	}

	/* truncate page cache pages from target inode range */
	truncate_inode_pages_range(&inode->i_data, destoff,
				   PAGE_CACHE_ALIGN(destoff + len) - 1);

	/* do any pending delalloc/csum calc on src, one way or
	   another, and lock file content */
	while (1) {
@@ -2242,10 +2251,6 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
		btrfs_wait_ordered_range(src, off, len);
	}

	/* truncate page cache pages from target inode range */
	truncate_inode_pages_range(&inode->i_data, off,
				   ALIGN(off + len, PAGE_CACHE_SIZE) - 1);

	/* clone data */
	key.objectid = btrfs_ino(src);
	key.type = BTRFS_EXTENT_DATA_KEY;
@@ -2442,7 +2447,6 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
			if (endoff > inode->i_size)
				btrfs_i_size_write(inode, endoff);

			BTRFS_I(inode)->flags = BTRFS_I(src)->flags;
			ret = btrfs_update_inode(trans, root, inode);
			BUG_ON(ret);
			btrfs_end_transaction(trans, root);