@@ -268,17 +268,6 @@ static inline bool xfs_is_always_cow_inode(struct xfs_inode *ip)
return false;
}
-/* Always set the child's GID to this value, even if the parent is setgid. */
-#define CRED_FORCE_GID (1U << 0)
-struct cred {
- uid_t cr_uid;
- gid_t cr_gid;
- unsigned int cr_flags;
-};
-
-extern int libxfs_dir_ialloc (struct xfs_trans **, struct xfs_inode *,
- mode_t, nlink_t, xfs_dev_t, struct cred *,
- struct fsxattr *, struct xfs_inode **);
extern void libxfs_trans_inode_alloc_buf (struct xfs_trans *,
struct xfs_buf *);
@@ -286,6 +275,10 @@ extern void libxfs_trans_ichgtime(struct xfs_trans *,
struct xfs_inode *, int);
extern int libxfs_iflush_int (struct xfs_inode *, struct xfs_buf *);
+int libxfs_icreate(struct xfs_trans *tp, xfs_ino_t ino,
+ const struct xfs_icreate_args *args, struct xfs_inode **ipp);
+void libxfs_icreate_args_rootfile(struct xfs_icreate_args *args, umode_t mode);
+
extern struct timespec64 current_time(struct inode *inode);
/* Inode Cache Interfaces */
@@ -179,7 +179,7 @@ xfs_inode_init(
* Initialise a newly allocated inode and return the in-core inode to the
* caller locked exclusively.
*/
-static int
+int
libxfs_icreate(
struct xfs_trans *tp,
xfs_ino_t ino,
@@ -198,6 +198,22 @@ libxfs_icreate(
return 0;
}
+/* Set up inode attributes for newly created internal files. */
+void
+libxfs_icreate_args_rootfile(
+ struct xfs_icreate_args *args,
+ umode_t mode)
+{
+ args->mnt_userns = NULL;
+ args->uid = make_kuid(0);
+ args->gid = make_kgid(0);
+ args->prid = 0;
+ args->mode = mode;
+ args->flags = XFS_ICREATE_ARGS_FORCE_UID |
+ XFS_ICREATE_ARGS_FORCE_GID |
+ XFS_ICREATE_ARGS_FORCE_MODE;
+}
+
/*
* Writes a modified inode's changes out to the inode's on disk home.
* Originally based on xfs_iflush_int() from xfs_inode.c in the kernel.
@@ -265,67 +281,6 @@ libxfs_iflush_int(
return 0;
}
-/*
- * Wrapper around call to libxfs_ialloc. Takes care of committing and
- * allocating a new transaction as needed.
- *
- * Originally there were two copies of this code - one in mkfs, the
- * other in repair - now there is just the one.
- */
-int
-libxfs_dir_ialloc(
- struct xfs_trans **tpp,
- struct xfs_inode *dp,
- mode_t mode,
- nlink_t nlink,
- xfs_dev_t rdev,
- struct cred *cr,
- struct fsxattr *fsx,
- struct xfs_inode **ipp)
-{
- struct xfs_icreate_args args = {
- .pip = dp,
- .uid = make_kuid(cr->cr_uid),
- .gid = make_kgid(cr->cr_gid),
- .prid = dp ? libxfs_get_initial_prid(dp) : 0,
- .nlink = nlink,
- .rdev = rdev,
- .mode = mode,
- .flags = XFS_ICREATE_ARGS_FORCE_UID |
- XFS_ICREATE_ARGS_FORCE_GID |
- XFS_ICREATE_ARGS_FORCE_MODE,
- };
- struct xfs_inode *ip;
- xfs_ino_t parent_ino = dp ? dp->i_ino : 0;
- xfs_ino_t ino;
- int error;
-
- /*
- * Call the space management code to pick the on-disk inode to be
- * allocated.
- */
- error = xfs_dialloc(tpp, parent_ino, mode, &ino);
- if (error)
- return error;
-
- error = libxfs_icreate(*tpp, ino, &args, ipp);
- if (error || dp)
- return error;
-
- /* If there is no parent dir, initialize the file from fsxattr data. */
- ip = *ipp;
- ip->i_projid = fsx->fsx_projid;
- ip->i_extsize = fsx->fsx_extsize;
- ip->i_diflags = xfs_flags2diflags(ip, fsx->fsx_xflags);
-
- if (xfs_has_v3inodes(ip->i_mount)) {
- ip->i_diflags2 = xfs_flags2diflags2(ip, fsx->fsx_xflags);
- ip->i_cowextsize = fsx->fsx_cowextsize;
- }
- xfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE);
- return 0;
-}
-
/*
* Inode cache stubs.
*/
@@ -91,6 +91,7 @@
#define xfs_da_shrink_inode libxfs_da_shrink_inode
#define xfs_defer_cancel libxfs_defer_cancel
#define xfs_defer_finish libxfs_defer_finish
+#define xfs_dialloc libxfs_dialloc
#define xfs_dinode_calc_crc libxfs_dinode_calc_crc
#define xfs_dinode_good_version libxfs_dinode_good_version
#define xfs_dinode_verify libxfs_dinode_verify
@@ -351,6 +351,65 @@ newdirectory(
fail(_("directory create error"), error);
}
+struct cred {
+ uid_t cr_uid;
+ gid_t cr_gid;
+};
+
+static int
+creatproto(
+ struct xfs_trans **tpp,
+ struct xfs_inode *dp,
+ mode_t mode,
+ nlink_t nlink,
+ xfs_dev_t rdev,
+ struct cred *cr,
+ struct fsxattr *fsx,
+ struct xfs_inode **ipp)
+{
+ struct xfs_icreate_args args = {
+ .pip = dp,
+ .uid = make_kuid(cr->cr_uid),
+ .gid = make_kgid(cr->cr_gid),
+ .prid = dp ? libxfs_get_initial_prid(dp) : 0,
+ .nlink = nlink,
+ .rdev = rdev,
+ .mode = mode,
+ .flags = XFS_ICREATE_ARGS_FORCE_UID |
+ XFS_ICREATE_ARGS_FORCE_GID |
+ XFS_ICREATE_ARGS_FORCE_MODE,
+ };
+ struct xfs_inode *ip;
+ xfs_ino_t parent_ino = dp ? dp->i_ino : 0;
+ xfs_ino_t ino;
+ int error;
+
+ /*
+ * Call the space management code to pick the on-disk inode to be
+ * allocated.
+ */
+ error = -libxfs_dialloc(tpp, parent_ino, mode, &ino);
+ if (error)
+ return error;
+
+ error = -libxfs_icreate(*tpp, ino, &args, ipp);
+ if (error || dp)
+ return error;
+
+ /* If there is no parent dir, initialize the file from fsxattr data. */
+ ip = *ipp;
+ ip->i_projid = fsx->fsx_projid;
+ ip->i_extsize = fsx->fsx_extsize;
+ ip->i_diflags = xfs_flags2diflags(ip, fsx->fsx_xflags);
+
+ if (xfs_has_v3inodes(ip->i_mount)) {
+ ip->i_diflags2 = xfs_flags2diflags2(ip, fsx->fsx_xflags);
+ ip->i_cowextsize = fsx->fsx_cowextsize;
+ }
+ libxfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE);
+ return 0;
+}
+
static void
parseproto(
xfs_mount_t *mp,
@@ -450,7 +509,6 @@ parseproto(
mode |= val;
creds.cr_uid = (int)getnum(getstr(pp), 0, 0, false);
creds.cr_gid = (int)getnum(getstr(pp), 0, 0, false);
- creds.cr_flags = CRED_FORCE_GID;
xname.name = (unsigned char *)name;
xname.len = name ? strlen(name) : 0;
xname.type = 0;
@@ -459,8 +517,8 @@ parseproto(
case IF_REGULAR:
buf = newregfile(pp, &len);
tp = getres(mp, XFS_B_TO_FSB(mp, len));
- error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFREG, 1, 0,
- &creds, fsxp, &ip);
+ error = creatproto(&tp, pip, mode | S_IFREG, 1, 0, &creds,
+ fsxp, &ip);
if (error)
fail(_("Inode allocation failed"), error);
writefile(tp, ip, buf, len);
@@ -483,8 +541,8 @@ parseproto(
}
tp = getres(mp, XFS_B_TO_FSB(mp, llen));
- error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFREG, 1, 0,
- &creds, fsxp, &ip);
+ error = creatproto(&tp, pip, mode | S_IFREG, 1, 0, &creds,
+ fsxp, &ip);
if (error)
fail(_("Inode pre-allocation failed"), error);
@@ -504,7 +562,7 @@ parseproto(
tp = getres(mp, 0);
majdev = getnum(getstr(pp), 0, 0, false);
mindev = getnum(getstr(pp), 0, 0, false);
- error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFBLK, 1,
+ error = creatproto(&tp, pip, mode | S_IFBLK, 1,
IRIX_MKDEV(majdev, mindev), &creds, fsxp, &ip);
if (error) {
fail(_("Inode allocation failed"), error);
@@ -519,7 +577,7 @@ parseproto(
tp = getres(mp, 0);
majdev = getnum(getstr(pp), 0, 0, false);
mindev = getnum(getstr(pp), 0, 0, false);
- error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFCHR, 1,
+ error = creatproto(&tp, pip, mode | S_IFCHR, 1,
IRIX_MKDEV(majdev, mindev), &creds, fsxp, &ip);
if (error)
fail(_("Inode allocation failed"), error);
@@ -531,8 +589,8 @@ parseproto(
case IF_FIFO:
tp = getres(mp, 0);
- error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFIFO, 1, 0,
- &creds, fsxp, &ip);
+ error = creatproto(&tp, pip, mode | S_IFIFO, 1, 0, &creds,
+ fsxp, &ip);
if (error)
fail(_("Inode allocation failed"), error);
libxfs_trans_ijoin(tp, pip, 0);
@@ -543,8 +601,8 @@ parseproto(
buf = getstr(pp);
len = (int)strlen(buf);
tp = getres(mp, XFS_B_TO_FSB(mp, len));
- error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFLNK, 1, 0,
- &creds, fsxp, &ip);
+ error = creatproto(&tp, pip, mode | S_IFLNK, 1, 0, &creds,
+ fsxp, &ip);
if (error)
fail(_("Inode allocation failed"), error);
writesymlink(tp, ip, buf, len);
@@ -554,8 +612,8 @@ parseproto(
break;
case IF_DIRECTORY:
tp = getres(mp, 0);
- error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFDIR, 1, 0,
- &creds, fsxp, &ip);
+ error = creatproto(&tp, pip, mode | S_IFDIR, 1, 0, &creds,
+ fsxp, &ip);
if (error)
fail(_("Inode allocation failed"), error);
inc_nlink(VFS_I(ip)); /* account for . */
@@ -646,14 +704,14 @@ rtinit(
memset(&creds, 0, sizeof(creds));
memset(&fsxattrs, 0, sizeof(fsxattrs));
- error = -libxfs_dir_ialloc(&tp, NULL, S_IFREG, 1, 0,
- &creds, &fsxattrs, &rbmip);
+ error = creatproto(&tp, NULL, S_IFREG, 1, 0, &creds, &fsxattrs,
+ &rbmip);
if (error) {
fail(_("Realtime bitmap inode allocation failed"), error);
}
/*
* Do our thing with rbmip before allocating rsumip,
- * because the next call to ialloc() may
+ * because the next call to createproto may
* commit the transaction in which rbmip was allocated.
*/
mp->m_sb.sb_rbmino = rbmip->i_ino;
@@ -663,8 +721,8 @@ rtinit(
libxfs_trans_log_inode(tp, rbmip, XFS_ILOG_CORE);
libxfs_log_sb(tp);
mp->m_rbmip = rbmip;
- error = -libxfs_dir_ialloc(&tp, NULL, S_IFREG, 1, 0,
- &creds, &fsxattrs, &rsumip);
+ error = creatproto(&tp, NULL, S_IFREG, 1, 0, &creds, &fsxattrs,
+ &rsumip);
if (error) {
fail(_("Realtime summary inode allocation failed"), error);
}
@@ -19,8 +19,6 @@
#include "progress.h"
#include "versions.h"
-static struct cred zerocr;
-static struct fsxattr zerofsx;
static xfs_ino_t orphanage_ino;
/*
@@ -873,19 +871,25 @@ mk_root_dir(xfs_mount_t *mp)
* orphanage name == lost+found
*/
static xfs_ino_t
-mk_orphanage(xfs_mount_t *mp)
+mk_orphanage(
+ struct xfs_mount *mp)
{
- xfs_ino_t ino;
- xfs_trans_t *tp;
- xfs_inode_t *ip;
- xfs_inode_t *pip;
- ino_tree_node_t *irec;
- int ino_offset = 0;
- int i;
- int error;
- const int mode = 0755;
- int nres;
- struct xfs_name xname;
+ struct xfs_icreate_args args = {
+ .nlink = 2,
+ };
+ struct xfs_trans *tp;
+ struct xfs_inode *ip;
+ struct xfs_inode *pip;
+ struct ino_tree_node *irec;
+ xfs_ino_t ino;
+ int ino_offset = 0;
+ int i;
+ int error;
+ int nres;
+ const umode_t mode = S_IFDIR | 0755;
+ struct xfs_name xname;
+
+ libxfs_icreate_args_rootfile(&args, mode);
/*
* check for an existing lost+found first, if it exists, return
@@ -898,6 +902,7 @@ mk_orphanage(xfs_mount_t *mp)
do_error(_("%d - couldn't iget root inode to obtain %s\n"),
i, ORPHANAGE);
+ args.pip = pip;
xname.name = (unsigned char *)ORPHANAGE;
xname.len = strlen(ORPHANAGE);
xname.type = XFS_DIR3_FT_DIR;
@@ -922,14 +927,15 @@ mk_orphanage(xfs_mount_t *mp)
do_error(_("%d - couldn't iget root inode to make %s\n"),
i, ORPHANAGE);*/
- error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFDIR,
- 1, 0, &zerocr, &zerofsx, &ip);
- if (error) {
+ error = -libxfs_dialloc(&tp, mp->m_sb.sb_rootino, mode, &ino);
+ if (error)
do_error(_("%s inode allocation failed %d\n"),
ORPHANAGE, error);
- }
- inc_nlink(VFS_I(ip)); /* account for . */
- ino = ip->i_ino;
+
+ error = -libxfs_icreate(tp, ino, &args, &ip);
+ if (error)
+ do_error(_("%s inode initialization failed %d\n"),
+ ORPHANAGE, error);
irec = find_inode_rec(mp,
XFS_INO_TO_AGNO(mp, ino),
@@ -3207,8 +3213,6 @@ phase6(xfs_mount_t *mp)
ino_tree_node_t *irec;
int i;
- memset(&zerocr, 0, sizeof(struct cred));
- memset(&zerofsx, 0, sizeof(struct fsxattr));
orphanage_ino = 0;
do_log(_("Phase 6 - check inode connectivity...\n"));