Commit 7a3353c5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull vfs file updates from Al Viro:
 "struct file-related stuff"

* tag 'pull-file' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  dma_buf_getfile(): don't bother with ->f_flags reassignments
  Change calling conventions for filldir_t
  locks: fix TOCTOU race when granting write lease
parents 70df64d6 47091e4e
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -922,3 +922,14 @@ is provided - file_open_root_mnt(). In-tree users adjusted.
no_llseek is gone; don't set .llseek to that - just leave it NULL instead.
Checks for "does that file have llseek(2), or should it fail with ESPIPE"
should be done by looking at FMODE_LSEEK in file->f_mode.

---

*mandatory*

filldir_t (readdir callbacks) calling conventions have changed.  Instead of
returning 0 or -E... it returns bool now.  false means "no more" (as -E... used
to) and true - "keep going" (as 0 in old calling conventions).  Rationale:
callers never looked at specific -E... values anyway.  ->iterate() and
->iterate_shared() instance require no changes at all, all filldir_t ones in
the tree converted.
+5 −5
Original line number Diff line number Diff line
@@ -108,7 +108,7 @@ struct osf_dirent_callback {
	int error;
};

static int
static bool
osf_filldir(struct dir_context *ctx, const char *name, int namlen,
	    loff_t offset, u64 ino, unsigned int d_type)
{
@@ -120,11 +120,11 @@ osf_filldir(struct dir_context *ctx, const char *name, int namlen,

	buf->error = -EINVAL;	/* only used if we fail */
	if (reclen > buf->count)
		return -EINVAL;
		return false;
	d_ino = ino;
	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
		buf->error = -EOVERFLOW;
		return -EOVERFLOW;
		return false;
	}
	if (buf->basep) {
		if (put_user(offset, buf->basep))
@@ -141,10 +141,10 @@ osf_filldir(struct dir_context *ctx, const char *name, int namlen,
	dirent = (void __user *)dirent + reclen;
	buf->dirent = dirent;
	buf->count -= reclen;
	return 0;
	return true;
Efault:
	buf->error = -EFAULT;
	return -EFAULT;
	return false;
}

SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,
+1 −1
Original line number Diff line number Diff line
@@ -531,11 +531,11 @@ static struct file *dma_buf_getfile(struct dma_buf *dmabuf, int flags)
	 * value.
	 */
	inode->i_ino = atomic64_add_return(1, &dmabuf_inode);
	flags &= O_ACCMODE | O_NONBLOCK;
	file = alloc_file_pseudo(inode, dma_buf_mnt, "dmabuf",
				 flags, &dma_buf_fops);
	if (IS_ERR(file))
		goto err_alloc_file;
	file->f_flags = flags & (O_ACCMODE | O_NONBLOCK);
	file->private_data = dmabuf;
	file->f_path.dentry->d_fsdata = dmabuf;

+10 −13
Original line number Diff line number Diff line
@@ -24,9 +24,9 @@ static int afs_readdir(struct file *file, struct dir_context *ctx);
static int afs_d_revalidate(struct dentry *dentry, unsigned int flags);
static int afs_d_delete(const struct dentry *dentry);
static void afs_d_iput(struct dentry *dentry, struct inode *inode);
static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name, int nlen,
static bool afs_lookup_one_filldir(struct dir_context *ctx, const char *name, int nlen,
				  loff_t fpos, u64 ino, unsigned dtype);
static int afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen,
static bool afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen,
			      loff_t fpos, u64 ino, unsigned dtype);
static int afs_create(struct user_namespace *mnt_userns, struct inode *dir,
		      struct dentry *dentry, umode_t mode, bool excl);
@@ -568,7 +568,7 @@ static int afs_readdir(struct file *file, struct dir_context *ctx)
 * - if afs_dir_iterate_block() spots this function, it'll pass the FID
 *   uniquifier through dtype
 */
static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name,
static bool afs_lookup_one_filldir(struct dir_context *ctx, const char *name,
				  int nlen, loff_t fpos, u64 ino, unsigned dtype)
{
	struct afs_lookup_one_cookie *cookie =
@@ -584,16 +584,16 @@ static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name,

	if (cookie->name.len != nlen ||
	    memcmp(cookie->name.name, name, nlen) != 0) {
		_leave(" = 0 [no]");
		return 0;
		_leave(" = true [keep looking]");
		return true;
	}

	cookie->fid.vnode = ino;
	cookie->fid.unique = dtype;
	cookie->found = 1;

	_leave(" = -1 [found]");
	return -1;
	_leave(" = false [found]");
	return false;
}

/*
@@ -636,12 +636,11 @@ static int afs_do_lookup_one(struct inode *dir, struct dentry *dentry,
 * - if afs_dir_iterate_block() spots this function, it'll pass the FID
 *   uniquifier through dtype
 */
static int afs_lookup_filldir(struct dir_context *ctx, const char *name,
static bool afs_lookup_filldir(struct dir_context *ctx, const char *name,
			      int nlen, loff_t fpos, u64 ino, unsigned dtype)
{
	struct afs_lookup_cookie *cookie =
		container_of(ctx, struct afs_lookup_cookie, ctx);
	int ret;

	_enter("{%s,%u},%s,%u,,%llu,%u",
	       cookie->name.name, cookie->name.len, name, nlen,
@@ -663,12 +662,10 @@ static int afs_lookup_filldir(struct dir_context *ctx, const char *name,
		cookie->fids[1].unique	= dtype;
		cookie->found = 1;
		if (cookie->one_only)
			return -1;
			return false;
	}

	ret = cookie->nr_fids >= 50 ? -1 : 0;
	_leave(" = %d", ret);
	return ret;
	return cookie->nr_fids < 50;
}

/*
+16 −22
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ struct ecryptfs_getdents_callback {
};

/* Inspired by generic filldir in fs/readdir.c */
static int
static bool
ecryptfs_filldir(struct dir_context *ctx, const char *lower_name,
		 int lower_namelen, loff_t offset, u64 ino, unsigned int d_type)
{
@@ -61,18 +61,19 @@ ecryptfs_filldir(struct dir_context *ctx, const char *lower_name,
		container_of(ctx, struct ecryptfs_getdents_callback, ctx);
	size_t name_size;
	char *name;
	int rc;
	int err;
	bool res;

	buf->filldir_called++;
	rc = ecryptfs_decode_and_decrypt_filename(&name, &name_size,
	err = ecryptfs_decode_and_decrypt_filename(&name, &name_size,
						   buf->sb, lower_name,
						   lower_namelen);
	if (rc) {
		if (rc != -EINVAL) {
	if (err) {
		if (err != -EINVAL) {
			ecryptfs_printk(KERN_DEBUG,
					"%s: Error attempting to decode and decrypt filename [%s]; rc = [%d]\n",
					__func__, lower_name, rc);
			return rc;
					__func__, lower_name, err);
			return false;
		}

		/* Mask -EINVAL errors as these are most likely due a plaintext
@@ -81,16 +82,15 @@ ecryptfs_filldir(struct dir_context *ctx, const char *lower_name,
		 * the "lost+found" dentry in the root directory of an Ext4
		 * filesystem.
		 */
		return 0;
		return true;
	}

	buf->caller->pos = buf->ctx.pos;
	rc = !dir_emit(buf->caller, name, name_size, ino, d_type);
	res = dir_emit(buf->caller, name, name_size, ino, d_type);
	kfree(name);
	if (!rc)
	if (res)
		buf->entries_written++;

	return rc;
	return res;
}

/**
@@ -111,14 +111,8 @@ static int ecryptfs_readdir(struct file *file, struct dir_context *ctx)
	lower_file = ecryptfs_file_to_lower(file);
	rc = iterate_dir(lower_file, &buf.ctx);
	ctx->pos = buf.ctx.pos;
	if (rc < 0)
		goto out;
	if (buf.filldir_called && !buf.entries_written)
		goto out;
	if (rc >= 0)
		fsstack_copy_attr_atime(inode,
					file_inode(lower_file));
out:
	if (rc >= 0 && (buf.entries_written || !buf.filldir_called))
		fsstack_copy_attr_atime(inode, file_inode(lower_file));
	return rc;
}

Loading