@@ -233,6 +233,31 @@ xfs_inode_inherit_flags2(
}
}
+/*
+ * If we need to create attributes immediately after allocating the inode,
+ * initialise an empty attribute fork right now. We use the default fork offset
+ * for attributes here as we don't know exactly what size or how many
+ * attributes we might be adding. We can do this safely here because we know
+ * the data fork is completely empty and this saves us from needing to run a
+ * separate transaction to set the fork offset in the immediate future.
+ *
+ * If we have parent pointers and the caller hasn't told us that the file will
+ * never be linked into a directory tree, we /must/ create the attr fork.
+ */
+static inline bool
+xfs_icreate_want_attrfork(
+ struct xfs_mount *mp,
+ const struct xfs_icreate_args *args)
+{
+ if (args->flags & XFS_ICREATE_INIT_XATTRS)
+ return true;
+
+ if (!(args->flags & XFS_ICREATE_UNLINKABLE) && xfs_has_parent(mp))
+ return true;
+
+ return false;
+}
+
/* Initialise an inode's attributes. */
void
xfs_inode_init(
@@ -325,16 +350,7 @@ xfs_inode_init(
ASSERT(0);
}
- /*
- * If we need to create attributes immediately after allocating the
- * inode, initialise an empty attribute fork right now. We use the
- * default fork offset for attributes here as we don't know exactly what
- * size or how many attributes we might be adding. We can do this
- * safely here because we know the data fork is completely empty and
- * this saves us from needing to run a separate transaction to set the
- * fork offset in the immediate future.
- */
- if (args->flags & XFS_ICREATE_INIT_XATTRS) {
+ if (xfs_icreate_want_attrfork(mp, args)) {
ip->i_forkoff = xfs_default_attroffset(ip) >> 3;
xfs_ifork_init_attr(ip, XFS_DINODE_FMT_EXTENTS, 0);
@@ -32,6 +32,7 @@ struct xfs_icreate_args {
#define XFS_ICREATE_TMPFILE (1U << 0) /* create an unlinked file */
#define XFS_ICREATE_INIT_XATTRS (1U << 1) /* will set xattrs immediately */
+#define XFS_ICREATE_UNLINKABLE (1U << 2) /* cannot link into dir tree */
uint16_t flags;
};
@@ -43,7 +43,7 @@ xrep_tempfile_create(
struct xfs_icreate_args args = {
.pip = sc->mp->m_rootip,
.mode = mode,
- .flags = XFS_ICREATE_TMPFILE,
+ .flags = XFS_ICREATE_TMPFILE | XFS_ICREATE_UNLINKABLE,
};
struct xfs_mount *mp = sc->mp;
struct xfs_trans *tp = NULL;
@@ -2512,9 +2512,6 @@ xfs_rename_alloc_whiteout(
struct qstr name;
int error;
- if (xfs_has_parent(dp->i_mount))
- args.flags |= XFS_ICREATE_INIT_XATTRS;
-
error = xfs_create_tmpfile(&args, &tmpfile);
if (error)
return error;
@@ -158,8 +158,6 @@ xfs_create_need_xattr(
if (dir->i_sb->s_security)
return true;
#endif
- if (xfs_has_parent(XFS_I(dir)->i_mount))
- return true;
return false;
}
@@ -215,12 +213,11 @@ xfs_generic_create(
args.flags |= XFS_ICREATE_TMPFILE;
/*
- * If this temporary file will be linkable, set up the file
- * with an attr fork to receive a parent pointer.
+ * If this temporary file will not be linkable, don't bother
+ * creating an attr fork to receive a parent pointer.
*/
- if (!(tmpfile->f_flags & O_EXCL) &&
- xfs_has_parent(XFS_I(dir)->i_mount))
- args.flags |= XFS_ICREATE_INIT_XATTRS;
+ if (tmpfile->f_flags & O_EXCL)
+ args.flags |= XFS_ICREATE_UNLINKABLE;
error = xfs_create_tmpfile(&args, &ip);
}
@@ -795,6 +795,7 @@ xfs_qm_qino_alloc(
if (need_alloc) {
struct xfs_icreate_args args = {
.mode = S_IFREG,
+ .flags = XFS_ICREATE_UNLINKABLE,
};
xfs_ino_t ino;
@@ -115,9 +115,6 @@ xfs_symlink(
if (xfs_is_shutdown(mp))
return -EIO;
- if (xfs_has_parent(mp))
- args.flags |= XFS_ICREATE_INIT_XATTRS;
-
/*
* Check component lengths of the target path name.
*/