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

Commit fe986f9d authored by Dave Chinner's avatar Dave Chinner
Browse files

Merge branch 'xfs-O_TMPFILE-support' into for-next

Conflicts:
	fs/xfs/xfs_trans_resv.c
	- fix for XFS_INODE_CLUSTER_SIZE macro removal
parents 5f44e4c1 ab297431
Loading
Loading
Loading
Loading
+117 −6
Original line number Diff line number Diff line
@@ -42,7 +42,6 @@
#include "xfs_bmap_util.h"
#include "xfs_error.h"
#include "xfs_quota.h"
#include "xfs_dinode.h"
#include "xfs_filestream.h"
#include "xfs_cksum.h"
#include "xfs_trace.h"
@@ -62,6 +61,8 @@ kmem_zone_t *xfs_inode_zone;

STATIC int xfs_iflush_int(xfs_inode_t *, xfs_buf_t *);

STATIC int xfs_iunlink_remove(xfs_trans_t *, xfs_inode_t *);

/*
 * helper function to extract extent size hint from inode
 */
@@ -1115,7 +1116,7 @@ xfs_bumplink(
{
	xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);

	ASSERT(ip->i_d.di_nlink > 0);
	ASSERT(ip->i_d.di_nlink > 0 || (VFS_I(ip)->i_state & I_LINKABLE));
	ip->i_d.di_nlink++;
	inc_nlink(VFS_I(ip));
	if ((ip->i_d.di_version == 1) &&
@@ -1165,10 +1166,7 @@ xfs_create(
	if (XFS_FORCED_SHUTDOWN(mp))
		return XFS_ERROR(EIO);

	if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
		prid = xfs_get_projid(dp);
	else
		prid = XFS_PROJID_DEFAULT;
	prid = xfs_get_initial_prid(dp);

	/*
	 * Make sure that we have allocated dquot(s) on disk.
@@ -1332,6 +1330,113 @@ xfs_create(
	return error;
}

int
xfs_create_tmpfile(
	struct xfs_inode	*dp,
	struct dentry		*dentry,
	umode_t			mode)
{
	struct xfs_mount	*mp = dp->i_mount;
	struct xfs_inode	*ip = NULL;
	struct xfs_trans	*tp = NULL;
	int			error;
	uint			cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
	prid_t                  prid;
	struct xfs_dquot	*udqp = NULL;
	struct xfs_dquot	*gdqp = NULL;
	struct xfs_dquot	*pdqp = NULL;
	struct xfs_trans_res	*tres;
	uint			resblks;

	if (XFS_FORCED_SHUTDOWN(mp))
		return XFS_ERROR(EIO);

	prid = xfs_get_initial_prid(dp);

	/*
	 * Make sure that we have allocated dquot(s) on disk.
	 */
	error = xfs_qm_vop_dqalloc(dp, xfs_kuid_to_uid(current_fsuid()),
				xfs_kgid_to_gid(current_fsgid()), prid,
				XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT,
				&udqp, &gdqp, &pdqp);
	if (error)
		return error;

	resblks = XFS_IALLOC_SPACE_RES(mp);
	tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE_TMPFILE);

	tres = &M_RES(mp)->tr_create_tmpfile;
	error = xfs_trans_reserve(tp, tres, resblks, 0);
	if (error == ENOSPC) {
		/* No space at all so try a "no-allocation" reservation */
		resblks = 0;
		error = xfs_trans_reserve(tp, tres, 0, 0);
	}
	if (error) {
		cancel_flags = 0;
		goto out_trans_cancel;
	}

	error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp,
						pdqp, resblks, 1, 0);
	if (error)
		goto out_trans_cancel;

	error = xfs_dir_ialloc(&tp, dp, mode, 1, 0,
				prid, resblks > 0, &ip, NULL);
	if (error) {
		if (error == ENOSPC)
			goto out_trans_cancel;
		goto out_trans_abort;
	}

	if (mp->m_flags & XFS_MOUNT_WSYNC)
		xfs_trans_set_sync(tp);

	/*
	 * Attach the dquot(s) to the inodes and modify them incore.
	 * These ids of the inode couldn't have changed since the new
	 * inode has been locked ever since it was created.
	 */
	xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);

	ip->i_d.di_nlink--;
	d_tmpfile(dentry, VFS_I(ip));
	error = xfs_iunlink(tp, ip);
	if (error)
		goto out_trans_abort;

	error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
	if (error)
		goto out_release_inode;

	xfs_qm_dqrele(udqp);
	xfs_qm_dqrele(gdqp);
	xfs_qm_dqrele(pdqp);

	return 0;

 out_trans_abort:
	cancel_flags |= XFS_TRANS_ABORT;
 out_trans_cancel:
	xfs_trans_cancel(tp, cancel_flags);
 out_release_inode:
	/*
	 * Wait until after the current transaction is aborted to
	 * release the inode.  This prevents recursive transactions
	 * and deadlocks from xfs_inactive.
	 */
	if (ip)
		IRELE(ip);

	xfs_qm_dqrele(udqp);
	xfs_qm_dqrele(gdqp);
	xfs_qm_dqrele(pdqp);

	return error;
}

int
xfs_link(
	xfs_inode_t		*tdp,
@@ -1397,6 +1502,12 @@ xfs_link(

	xfs_bmap_init(&free_list, &first_block);

	if (sip->i_d.di_nlink == 0) {
		error = xfs_iunlink_remove(tp, sip);
		if (error)
			goto abort_return;
	}

	error = xfs_dir_createname(tp, tdp, target_name, sip->i_ino,
					&first_block, &free_list, resblks);
	if (error)
+12 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@

#include "xfs_inode_buf.h"
#include "xfs_inode_fork.h"
#include "xfs_dinode.h"

/*
 * Kernel only inode definitions
@@ -192,6 +193,15 @@ xfs_set_projid(struct xfs_inode *ip,
	ip->i_d.di_projid_lo = (__uint16_t) (projid & 0xffff);
}

static inline prid_t
xfs_get_initial_prid(struct xfs_inode *dp)
{
	if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
		return xfs_get_projid(dp);

	return XFS_PROJID_DEFAULT;
}

/*
 * In-core inode flags.
 */
@@ -323,6 +333,8 @@ int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name,
			   struct xfs_inode **ipp, struct xfs_name *ci_name);
int		xfs_create(struct xfs_inode *dp, struct xfs_name *name,
			   umode_t mode, xfs_dev_t rdev, struct xfs_inode **ipp);
int		xfs_create_tmpfile(struct xfs_inode *dp, struct dentry *dentry,
			   umode_t mode);
int		xfs_remove(struct xfs_inode *dp, struct xfs_name *name,
			   struct xfs_inode *ip);
int		xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip,
+16 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#include "xfs_da_btree.h"
#include "xfs_dir2_priv.h"
#include "xfs_dinode.h"
#include "xfs_trans_space.h"

#include <linux/capability.h>
#include <linux/xattr.h>
@@ -1046,6 +1047,19 @@ xfs_vn_fiemap(
	return 0;
}

STATIC int
xfs_vn_tmpfile(
	struct inode	*dir,
	struct dentry	*dentry,
	umode_t		mode)
{
	int		error;

	error = xfs_create_tmpfile(XFS_I(dir), dentry, mode);

	return -error;
}

static const struct inode_operations xfs_inode_operations = {
	.get_acl		= xfs_get_acl,
	.set_acl		= xfs_set_acl,
@@ -1084,6 +1098,7 @@ static const struct inode_operations xfs_dir_inode_operations = {
	.removexattr		= generic_removexattr,
	.listxattr		= xfs_vn_listxattr,
	.update_time		= xfs_vn_update_time,
	.tmpfile		= xfs_vn_tmpfile,
};

static const struct inode_operations xfs_dir_ci_inode_operations = {
@@ -1111,6 +1126,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
	.removexattr		= generic_removexattr,
	.listxattr		= xfs_vn_listxattr,
	.update_time		= xfs_vn_update_time,
	.tmpfile		= xfs_vn_tmpfile,
};

static const struct inode_operations xfs_symlink_inode_operations = {
+3 −1
Original line number Diff line number Diff line
@@ -104,7 +104,8 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops;
#define	XFS_TRANS_SB_COUNT		41
#define	XFS_TRANS_CHECKPOINT		42
#define	XFS_TRANS_ICREATE		43
#define	XFS_TRANS_TYPE_MAX		43
#define	XFS_TRANS_CREATE_TMPFILE	44
#define	XFS_TRANS_TYPE_MAX		44
/* new transaction types need to be reflected in xfs_logprint(8) */

#define XFS_TRANS_TYPES \
@@ -112,6 +113,7 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops;
	{ XFS_TRANS_SETATTR_SIZE,	"SETATTR_SIZE" }, \
	{ XFS_TRANS_INACTIVE,		"INACTIVE" }, \
	{ XFS_TRANS_CREATE,		"CREATE" }, \
	{ XFS_TRANS_CREATE_TMPFILE,	"CREATE_TMPFILE" }, \
	{ XFS_TRANS_CREATE_TRUNC,	"CREATE_TRUNC" }, \
	{ XFS_TRANS_TRUNCATE_FILE,	"TRUNCATE_FILE" }, \
	{ XFS_TRANS_REMOVE,		"REMOVE" }, \
+1 −4
Original line number Diff line number Diff line
@@ -212,10 +212,7 @@ xfs_symlink(
		return XFS_ERROR(ENAMETOOLONG);

	udqp = gdqp = NULL;
	if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
		prid = xfs_get_projid(dp);
	else
		prid = XFS_PROJID_DEFAULT;
	prid = xfs_get_initial_prid(dp);

	/*
	 * Make sure that we have allocated dquot(s) on disk.
Loading