Commit d897166d authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull vfs 'struct file' related updates from Al Viro:
 "A bit more of 'this fget() would be better off as fdget()'
  whack-a-mole + a couple of ->f_count-related cleanups"

* 'work.file' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  media: switch to fdget()
  drm_syncobj: switch to fdget()
  amdgpu: switch to fdget()
  don't open-code file_count()
  fs: drop unused fput_atomic definition
parents 40091325 3b85d302
Loading
Loading
Loading
Loading
+11 −12
Original line number Diff line number Diff line
@@ -53,26 +53,25 @@ static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev,
						  int fd,
						  enum drm_sched_priority priority)
{
	struct file *filp = fget(fd);
	struct fd f = fdget(fd);
	struct amdgpu_fpriv *fpriv;
	struct amdgpu_ctx *ctx;
	uint32_t id;
	int r;

	if (!filp)
	if (!f.file)
		return -EINVAL;

	r = amdgpu_file_to_fpriv(filp, &fpriv);
	r = amdgpu_file_to_fpriv(f.file, &fpriv);
	if (r) {
		fput(filp);
		fdput(f);
		return r;
	}

	idr_for_each_entry(&fpriv->ctx_mgr.ctx_handles, ctx, id)
		amdgpu_ctx_priority_override(ctx, priority);

	fput(filp);

	fdput(f);
	return 0;
}

@@ -81,30 +80,30 @@ static int amdgpu_sched_context_priority_override(struct amdgpu_device *adev,
						  unsigned ctx_id,
						  enum drm_sched_priority priority)
{
	struct file *filp = fget(fd);
	struct fd f = fdget(fd);
	struct amdgpu_fpriv *fpriv;
	struct amdgpu_ctx *ctx;
	int r;

	if (!filp)
	if (!f.file)
		return -EINVAL;

	r = amdgpu_file_to_fpriv(filp, &fpriv);
	r = amdgpu_file_to_fpriv(f.file, &fpriv);
	if (r) {
		fput(filp);
		fdput(f);
		return r;
	}

	ctx = amdgpu_ctx_get(fpriv, ctx_id);

	if (!ctx) {
		fput(filp);
		fdput(f);
		return -EINVAL;
	}

	amdgpu_ctx_priority_override(ctx, priority);
	amdgpu_ctx_put(ctx);
	fput(filp);
	fdput(f);

	return 0;
}
+6 −7
Original line number Diff line number Diff line
@@ -388,20 +388,19 @@ static int drm_syncobj_fd_to_handle(struct drm_file *file_private,
				    int fd, u32 *handle)
{
	struct drm_syncobj *syncobj;
	struct file *file;
	struct fd f = fdget(fd);
	int ret;

	file = fget(fd);
	if (!file)
	if (!f.file)
		return -EINVAL;

	if (file->f_op != &drm_syncobj_file_fops) {
		fput(file);
	if (f.file->f_op != &drm_syncobj_file_fops) {
		fdput(f);
		return -EINVAL;
	}

	/* take a reference to put in the idr */
	syncobj = file->private_data;
	syncobj = f.file->private_data;
	drm_syncobj_get(syncobj);

	idr_preload(GFP_KERNEL);
@@ -416,7 +415,7 @@ static int drm_syncobj_fd_to_handle(struct drm_file *file_private,
	} else
		drm_syncobj_put(syncobj);

	fput(file);
	fdput(f);
	return ret;
}

+1 −1
Original line number Diff line number Diff line
@@ -4354,7 +4354,7 @@ static bool discard_backing_storage(struct drm_i915_gem_object *obj)
	 * acquiring such a reference whilst we are in the middle of
	 * freeing the object.
	 */
	return atomic_long_read(&obj->base.filp->f_count) == 1;
	return file_count(obj->base.filp) == 1;
}

static void __i915_gem_free_objects(struct drm_i915_private *i915,
+8 −8
Original line number Diff line number Diff line
@@ -246,38 +246,38 @@ static const struct file_operations request_fops = {
struct media_request *
media_request_get_by_fd(struct media_device *mdev, int request_fd)
{
	struct file *filp;
	struct fd f;
	struct media_request *req;

	if (!mdev || !mdev->ops ||
	    !mdev->ops->req_validate || !mdev->ops->req_queue)
		return ERR_PTR(-EACCES);

	filp = fget(request_fd);
	if (!filp)
	f = fdget(request_fd);
	if (!f.file)
		goto err_no_req_fd;

	if (filp->f_op != &request_fops)
	if (f.file->f_op != &request_fops)
		goto err_fput;
	req = filp->private_data;
	req = f.file->private_data;
	if (req->mdev != mdev)
		goto err_fput;

	/*
	 * Note: as long as someone has an open filehandle of the request,
	 * the request can never be released. The fget() above ensures that
	 * the request can never be released. The fdget() above ensures that
	 * even if userspace closes the request filehandle, the release()
	 * fop won't be called, so the media_request_get() always succeeds
	 * and there is no race condition where the request was released
	 * before media_request_get() is called.
	 */
	media_request_get(req);
	fput(filp);
	fdput(f);

	return req;

err_fput:
	fput(filp);
	fdput(f);

err_no_req_fd:
	dev_dbg(mdev->dev, "cannot find request_fd %d\n", request_fd);
+0 −1
Original line number Diff line number Diff line
@@ -975,7 +975,6 @@ static inline struct file *get_file(struct file *f)
#define get_file_rcu_many(x, cnt)	\
	atomic_long_add_unless(&(x)->f_count, (cnt), 0)
#define get_file_rcu(x) get_file_rcu_many((x), 1)
#define fput_atomic(x)	atomic_long_add_unless(&(x)->f_count, -1, 1)
#define file_count(x)	atomic_long_read(&(x)->f_count)

#define	MAX_NON_LFS	((1UL<<31) - 1)