All of lore.kernel.org
 help / color / mirror / Atom feed
From: Brian Foster <bfoster@redhat.com>
To: xfs@oss.sgi.com
Subject: [PATCH v3 4/4] xfs: fold xfs_create_tmpfile() into xfs_create()
Date: Tue, 15 Apr 2014 12:18:26 -0400	[thread overview]
Message-ID: <1397578706-5385-5-git-send-email-bfoster@redhat.com> (raw)
In-Reply-To: <1397578706-5385-1-git-send-email-bfoster@redhat.com>

xfs_create_tmpfile() duplicates most of xfs_create() with the exception
of a couple minor differences. We use a unique transaction reservation
and place the allocated inode on the unlinked list rather than create a
directory entry for it.

Fold xfs_create_tmpfile() into xfs_create() to reduce some of this
duplication. The name parameter that represents the name of the
directory entry to create is now conditional and its existence dictates
whether a directory entry is created for the inode or not.

Signed-off-by: Brian Foster <bfoster@redhat.com>
---
 fs/xfs/xfs_inode.c | 178 +++++++++++++----------------------------------------
 fs/xfs/xfs_inode.h |   2 -
 fs/xfs/xfs_iops.c  |   2 +-
 fs/xfs/xfs_trace.h |   7 ++-
 4 files changed, 47 insertions(+), 142 deletions(-)

diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index f8a232a..d82bddf 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1183,10 +1183,14 @@ xfs_create(
 		resblks = XFS_MKDIR_SPACE_RES(mp, name->len);
 		tres = &M_RES(mp)->tr_mkdir;
 		tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR);
-	} else {
+	} else if (name) {
 		resblks = XFS_CREATE_SPACE_RES(mp, name->len);
 		tres = &M_RES(mp)->tr_create;
 		tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE);
+	} else {
+		resblks = XFS_IALLOC_SPACE_RES(mp);
+		tres = &M_RES(mp)->tr_create_tmpfile;
+		tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE_TMPFILE);
 	}
 
 	cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
@@ -1213,9 +1217,6 @@ xfs_create(
 		goto out_trans_cancel;
 	}
 
-	xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
-	unlock_dp_on_error = true;
-
 	xfs_bmap_init(&free_list, &first_block);
 
 	/*
@@ -1226,9 +1227,14 @@ xfs_create(
 	if (error)
 		goto out_trans_cancel;
 
-	error = xfs_dir_canenter(tp, dp, name, resblks);
-	if (error)
-		goto out_trans_cancel;
+	if (name) {
+		xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
+		unlock_dp_on_error = true;
+
+		error = xfs_dir_canenter(tp, dp, name, resblks);
+		if (error)
+			goto out_trans_cancel;
+	}
 
 	/*
 	 * A newly created regular or special file just has one directory
@@ -1243,34 +1249,41 @@ xfs_create(
 		goto out_trans_abort;
 	}
 
-	/*
-	 * Now we join the directory inode to the transaction.  We do not do it
-	 * earlier because xfs_dir_ialloc might commit the previous transaction
-	 * (and release all the locks).  An error from here on will result in
-	 * the transaction cancel unlocking dp so don't do it explicitly in the
-	 * error path.
-	 */
-	xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
-	unlock_dp_on_error = false;
+	if (name) {
+		/*
+		 * Now we join the directory inode to the transaction. We do not
+		 * do it earlier because xfs_dir_ialloc might commit the
+		 * previous transaction (and release all the locks). An error
+		 * from here on will result in the transaction cancel unlocking
+		 * dp so don't do it explicitly in the error path.
+		 */
+		xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
+		unlock_dp_on_error = false;
 
-	error = xfs_dir_createname(tp, dp, name, ip->i_ino,
+		error = xfs_dir_createname(tp, dp, name, ip->i_ino,
 					&first_block, &free_list, resblks ?
 					resblks - XFS_IALLOC_SPACE_RES(mp) : 0);
-	if (error) {
-		ASSERT(error != ENOSPC);
-		goto out_trans_abort;
-	}
-	xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
-	xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
+		if (error) {
+			ASSERT(error != ENOSPC);
+			goto out_trans_abort;
+		}
+		xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
+		xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
 
-	if (is_dir) {
-		error = xfs_dir_init(tp, ip, dp);
-		if (error)
-			goto out_bmap_cancel;
+		if (is_dir) {
+			error = xfs_dir_init(tp, ip, dp);
+			if (error)
+				goto out_bmap_cancel;
 
-		error = xfs_bumplink(tp, dp);
+			error = xfs_bumplink(tp, dp);
+			if (error)
+				goto out_bmap_cancel;
+		}
+	} else {
+		ip->i_d.di_nlink--;
+		error = xfs_iunlink(tp, ip);
 		if (error)
-			goto out_bmap_cancel;
+			goto out_trans_abort;
 	}
 
 	/*
@@ -1328,113 +1341,6 @@ xfs_create(
 }
 
 int
-xfs_create_tmpfile(
-	struct xfs_inode	*dp,
-	umode_t			mode,
-	struct xfs_inode	**ipp)
-{
-	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--;
-	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);
-
-	*ipp = ip;
-	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,
 	xfs_inode_t		*sip,
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 4a612fd..5a7f81a 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -333,8 +333,6 @@ 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, umode_t mode,
-				   struct xfs_inode **ipp);
 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,
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 2b1d1bd..f315a38 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -1057,7 +1057,7 @@ xfs_vn_tmpfile(
 	struct xfs_inode	*ip;
 	struct inode		*inode;
 
-	error = xfs_create_tmpfile(XFS_I(dir), mode, &ip);
+	error = xfs_create(XFS_I(dir), NULL, mode, 0, &ip);
 	if (unlikely(error))
 		return -error;
 
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index a4ae41c..da46c94 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -691,13 +691,14 @@ DECLARE_EVENT_CLASS(xfs_namespace_class,
 		__field(dev_t, dev)
 		__field(xfs_ino_t, dp_ino)
 		__field(int, namelen)
-		__dynamic_array(char, name, name->len)
+		__dynamic_array(char, name, name ? name->len : 0)
 	),
 	TP_fast_assign(
 		__entry->dev = VFS_I(dp)->i_sb->s_dev;
 		__entry->dp_ino = dp->i_ino;
-		__entry->namelen = name->len;
-		memcpy(__get_str(name), name->name, name->len);
+		__entry->namelen = name ? name->len : 0;
+		if (name)
+			memcpy(__get_str(name), name->name, name->len);
 	),
 	TP_printk("dev %d:%d dp ino 0x%llx name %.*s",
 		  MAJOR(__entry->dev), MINOR(__entry->dev),
-- 
1.8.3.1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

  parent reply	other threads:[~2014-04-15 16:18 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-15 16:18 [PATCH v3 0/4] xfs: tmpfile fixes Brian Foster
2014-04-15 16:18 ` [PATCH v3 1/4] xfs: fix tmpfile/selinux ilock deadlock Brian Foster
2014-04-15 17:47   ` Christoph Hellwig
2014-04-15 16:18 ` [PATCH v3 2/4] xfs: initialize inode security on tmpfile creation Brian Foster
2014-04-15 17:50   ` Christoph Hellwig
2014-04-15 17:50     ` Christoph Hellwig
2014-04-15 20:04     ` Stephen Smalley
2014-04-15 20:16       ` Stephen Smalley
2014-04-15 20:22       ` Christoph Hellwig
2014-04-15 20:22         ` Christoph Hellwig
2014-04-15 20:21         ` Stephen Smalley
2014-04-16 12:51           ` Stephen Smalley
2014-04-16 14:14             ` Christoph Hellwig
2014-04-16 14:14               ` Christoph Hellwig
2014-04-16 14:14               ` Stephen Smalley
2014-04-16 14:14                 ` Stephen Smalley
2014-04-15 16:18 ` [PATCH v3 3/4] xfs: replace on-stack xfs_trans_res with pointer in xfs_create() Brian Foster
2014-04-15 17:50   ` Christoph Hellwig
2014-04-15 16:18 ` Brian Foster [this message]
2014-04-15 17:51   ` [PATCH v3 4/4] xfs: fold xfs_create_tmpfile() into xfs_create() Christoph Hellwig
2014-04-15 21:59 ` [PATCH v3 0/4] xfs: tmpfile fixes Dave Chinner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1397578706-5385-5-git-send-email-bfoster@redhat.com \
    --to=bfoster@redhat.com \
    --cc=xfs@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.