Unverified Commit 993f3046 authored by Christian Brauner's avatar Christian Brauner
Browse files

xfs: convert xfs_open_by_handle() to FD_PREPARE()

parent 39f6e758
Loading
Loading
Loading
Loading
+17 −39
Original line number Diff line number Diff line
@@ -233,14 +233,11 @@ xfs_open_by_handle(
	xfs_fsop_handlereq_t	*hreq)
{
	const struct cred	*cred = current_cred();
	int			error;
	int			fd;
	int			permflag;
	struct file		*filp;
	struct inode		*inode;
	struct dentry		*dentry;
	fmode_t			fmode;
	struct path		path;
	struct path		path __free(path_put) = {};

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;
@@ -249,12 +246,11 @@ xfs_open_by_handle(
	if (IS_ERR(dentry))
		return PTR_ERR(dentry);
	inode = d_inode(dentry);
	path.dentry = dentry;

	/* Restrict xfs_open_by_handle to directories & regular files. */
	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
		error = -EPERM;
		goto out_dput;
	}
	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)))
		return -EPERM;

#if BITS_PER_LONG != 32
	hreq->oflags |= O_LARGEFILE;
@@ -263,48 +259,30 @@ xfs_open_by_handle(
	permflag = hreq->oflags;
	fmode = OPEN_FMODE(permflag);
	if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) &&
	    (fmode & FMODE_WRITE) && IS_APPEND(inode)) {
		error = -EPERM;
		goto out_dput;
	}
	    (fmode & FMODE_WRITE) && IS_APPEND(inode))
		return -EPERM;

	if ((fmode & FMODE_WRITE) && IS_IMMUTABLE(inode)) {
		error = -EPERM;
		goto out_dput;
	}
	if ((fmode & FMODE_WRITE) && IS_IMMUTABLE(inode))
		return -EPERM;

	/* Can't write directories. */
	if (S_ISDIR(inode->i_mode) && (fmode & FMODE_WRITE)) {
		error = -EISDIR;
		goto out_dput;
	}
	if (S_ISDIR(inode->i_mode) && (fmode & FMODE_WRITE))
		return -EISDIR;

	fd = get_unused_fd_flags(0);
	if (fd < 0) {
		error = fd;
		goto out_dput;
	}
	path.mnt = mntget(parfilp->f_path.mnt);

	path.mnt = parfilp->f_path.mnt;
	path.dentry = dentry;
	filp = dentry_open(&path, hreq->oflags, cred);
	dput(dentry);
	if (IS_ERR(filp)) {
		put_unused_fd(fd);
		return PTR_ERR(filp);
	}
	FD_PREPARE(fdf, 0, dentry_open(&path, hreq->oflags, cred));
	if (fdf.err)
		return fdf.err;

	if (S_ISREG(inode->i_mode)) {
		struct file *filp = fd_prepare_file(fdf);

		filp->f_flags |= O_NOATIME;
		filp->f_mode |= FMODE_NOCMTIME;
	}

	fd_install(fd, filp);
	return fd;

 out_dput:
	dput(dentry);
	return error;
	return fd_publish(fdf);
}

int