Merge of master-melb:xfs-cmds:24370a by kenmcd.
#define LIBXFS_ATTR_CREATE 0x0010 /* create, but fail if attr exists */
#define LIBXFS_ATTR_REPLACE 0x0020 /* set, but fail if attr not exists */
-typedef struct {
+typedef struct cred {
uid_t cr_uid;
gid_t cr_gid;
} cred_t;
extern int libxfs_inode_alloc (xfs_trans_t **, xfs_inode_t *, mode_t,
- ushort, xfs_dev_t, cred_t *, xfs_inode_t **);
+ nlink_t, xfs_dev_t, struct cred *,
+ struct fsxattr *, xfs_inode_t **);
extern void libxfs_trans_inode_alloc_buf (xfs_trans_t *, xfs_buf_t *);
extern void libxfs_idata_realloc (xfs_inode_t *, int, int);
#include <xfs.h>
#include <time.h>
-/*
- * 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_inode_alloc(
- xfs_trans_t **tp,
- xfs_inode_t *pip,
- mode_t mode,
- ushort nlink,
- xfs_dev_t rdev,
- cred_t *cr,
- xfs_inode_t **ipp)
-{
- boolean_t call_again;
- int i;
- xfs_buf_t *ialloc_context;
- xfs_inode_t *ip;
- xfs_trans_t *ntp;
- int error;
-
- call_again = B_FALSE;
- ialloc_context = (xfs_buf_t *)0;
- error = libxfs_ialloc(*tp, pip, mode, nlink, rdev, cr, (xfs_prid_t) 0,
- 1, &ialloc_context, &call_again, &ip);
- if (error)
- return error;
-
- if (call_again) {
- xfs_trans_bhold(*tp, ialloc_context);
- ntp = xfs_trans_dup(*tp);
- xfs_trans_commit(*tp, 0, NULL);
- *tp = ntp;
- if ((i = xfs_trans_reserve(*tp, 0, 0, 0, 0, 0))) {
- fprintf(stderr, _("%s: cannot reserve space: %s\n"),
- progname, strerror(errno));
- exit(1);
- }
- xfs_trans_bjoin(*tp, ialloc_context);
- error = libxfs_ialloc(*tp, pip, mode, nlink, rdev, cr,
- (xfs_prid_t) 0, 1, &ialloc_context,
- &call_again, &ip);
- if (!ip)
- error = ENOSPC;
- if (error)
- return error;
- }
- if (!ip)
- error = ENOSPC;
-
- *ipp = ip;
- return error;
-}
-
/*
* Change the requested timestamp in the given inode.
*
* This was once shared with the kernel, but has diverged to the point
* where its no longer worth the hassle of maintaining common code.
*/
-int
+static int
libxfs_ialloc(
xfs_trans_t *tp,
xfs_inode_t *pip,
mode_t mode,
nlink_t nlink,
xfs_dev_t rdev,
- cred_t *cr,
- xfs_prid_t prid,
+ struct cred *cr,
+ struct fsxattr *fsx,
int okalloc,
xfs_buf_t **ialloc_context,
boolean_t *call_again,
ASSERT(ip->i_d.di_nlink == nlink);
ip->i_d.di_uid = cr->cr_uid;
ip->i_d.di_gid = cr->cr_gid;
- ip->i_d.di_projid = prid;
+ ip->i_d.di_projid = pip ? 0 : fsx->fsx_projid;
memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
/*
/* old link count, projid field, pad field already zeroed */
}
+ if (pip && (pip->i_d.di_mode & S_ISGID)) {
+ ip->i_d.di_gid = pip->i_d.di_gid;
+ if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR)
+ ip->i_d.di_mode |= S_ISGID;
+ }
+
ip->i_d.di_size = 0;
ip->i_d.di_nextents = 0;
ASSERT(ip->i_d.di_nblocks == 0);
/*
* di_gen will have been taken care of in xfs_iread.
*/
- ip->i_d.di_extsize = 0;
+ ip->i_d.di_extsize = pip ? 0 : fsx->fsx_extsize;
ip->i_d.di_dmevmask = 0;
ip->i_d.di_dmstate = 0;
- ip->i_d.di_flags = 0;
+ ip->i_d.di_flags = pip ? 0 : fsx->fsx_xflags;
flags = XFS_ILOG_CORE;
switch (mode & S_IFMT) {
case S_IFIFO:
break;
case S_IFREG:
case S_IFDIR:
+ if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) {
+ uint di_flags = 0;
+
+ if ((mode & S_IFMT) == S_IFDIR) {
+ if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT)
+ di_flags |= XFS_DIFLAG_RTINHERIT;
+ if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) {
+ di_flags |= XFS_DIFLAG_EXTSZINHERIT;
+ ip->i_d.di_extsize = pip->i_d.di_extsize;
+ }
+ } else {
+ if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) {
+ di_flags |= XFS_DIFLAG_REALTIME;
+ }
+ if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) {
+ di_flags |= XFS_DIFLAG_EXTSIZE;
+ ip->i_d.di_extsize = pip->i_d.di_extsize;
+ }
+ }
+ if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
+ di_flags |= XFS_DIFLAG_PROJINHERIT;
+ ip->i_d.di_flags |= di_flags;
+ }
+ /* FALLTHROUGH */
case S_IFLNK:
ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS;
ip->i_df.if_flags = XFS_IFEXTENTS;
for (i = 0; i < dabuf->nbuf; i++)
xfs_trans_bjoin(tp, dabuf->bps[i]);
}
+
+/*
+ * 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_inode_alloc(
+ xfs_trans_t **tp,
+ xfs_inode_t *pip,
+ mode_t mode,
+ nlink_t nlink,
+ xfs_dev_t rdev,
+ struct cred *cr,
+ struct fsxattr *fsx,
+ xfs_inode_t **ipp)
+{
+ boolean_t call_again;
+ int i;
+ xfs_buf_t *ialloc_context;
+ xfs_inode_t *ip;
+ xfs_trans_t *ntp;
+ int error;
+
+ call_again = B_FALSE;
+ ialloc_context = (xfs_buf_t *)0;
+ error = libxfs_ialloc(*tp, pip, mode, nlink, rdev, cr, fsx,
+ 1, &ialloc_context, &call_again, &ip);
+ if (error)
+ return error;
+
+ if (call_again) {
+ xfs_trans_bhold(*tp, ialloc_context);
+ ntp = xfs_trans_dup(*tp);
+ xfs_trans_commit(*tp, 0, NULL);
+ *tp = ntp;
+ if ((i = xfs_trans_reserve(*tp, 0, 0, 0, 0, 0))) {
+ fprintf(stderr, _("%s: cannot reserve space: %s\n"),
+ progname, strerror(errno));
+ exit(1);
+ }
+ xfs_trans_bjoin(*tp, ialloc_context);
+ error = libxfs_ialloc(*tp, pip, mode, nlink, rdev, cr,
+ fsx, 1, &ialloc_context,
+ &call_again, &ip);
+ if (!ip)
+ error = ENOSPC;
+ if (error)
+ return error;
+ }
+ if (!ip)
+ error = ENOSPC;
+
+ *ipp = ip;
+ return error;
+}
#define xfs_rtmount_init libxfs_rtmount_init
#define xfs_alloc_fix_freelist libxfs_alloc_fix_freelist
#define xfs_iread libxfs_iread
-#define xfs_ialloc libxfs_ialloc
#define xfs_idata_realloc libxfs_idata_realloc
#define xfs_idestroy_fork libxfs_idestroy_fork
#define xfs_itobp libxfs_itobp
/*
- * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
- *
+ * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. All Rights Reserved.
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
- *
+ *
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
+ *
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
- *
+ *
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
+ *
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
/*
* Prototypes for internal functions.
*/
-extern void parseproto(xfs_mount_t *mp, xfs_inode_t *pip, char **pp,
- char *name);
static long getnum(char **pp);
static char *getstr(char **pp);
static void fail(char *msg, int i);
static void rsvfile(xfs_mount_t *mp, xfs_inode_t *ip, long long len);
static int newfile(xfs_trans_t *tp, xfs_inode_t *ip, xfs_bmap_free_t *flist,
xfs_fsblock_t *first, int dolocal, int logit, char *buf, int len);
-static char *newregfile(char **pp, int *len);
+static char *newregfile(char **pp, int *len);
static void rtinit(xfs_mount_t *mp);
static long filesize(int fd);
fail(_("directory create error"), error);
}
-void
+static void
parseproto(
xfs_mount_t *mp,
xfs_inode_t *pip,
+ struct fsxattr *fsxp,
char **pp,
char *name)
{
buf = newregfile(pp, &len);
getres(tp, XFS_B_TO_FSB(mp, len));
error = libxfs_inode_alloc(&tp, pip, mode|S_IFREG, 1, 0,
- &creds, &ip);
+ &creds, fsxp, &ip);
if (error)
fail(_("Inode allocation failed"), error);
flags |= newfile(tp, ip, &flist, &first, 0, 0, buf, len);
getres(tp, XFS_B_TO_FSB(mp, llen));
error = libxfs_inode_alloc(&tp, pip, mode|S_IFREG, 1, 0,
- &creds, &ip);
+ &creds, fsxp, &ip);
if (error)
fail(_("Inode pre-allocation failed"), error);
majdev = (int)getnum(pp);
mindev = (int)getnum(pp);
error = libxfs_inode_alloc(&tp, pip, mode|S_IFBLK, 1,
- IRIX_MKDEV(majdev, mindev), &creds, &ip);
+ IRIX_MKDEV(majdev, mindev), &creds, fsxp, &ip);
if (error) {
fail(_("Inode allocation failed"), error);
}
majdev = (int)getnum(pp);
mindev = (int)getnum(pp);
error = libxfs_inode_alloc(&tp, pip, mode|S_IFCHR, 1,
- IRIX_MKDEV(majdev, mindev), &creds, &ip);
+ IRIX_MKDEV(majdev, mindev), &creds, fsxp, &ip);
if (error)
fail(_("Inode allocation failed"), error);
libxfs_trans_ijoin(tp, pip, 0);
case IF_FIFO:
getres(tp, 0);
error = libxfs_inode_alloc(&tp, pip, mode|S_IFIFO, 1, 0,
- &creds, &ip);
+ &creds, fsxp, &ip);
if (error)
fail(_("Inode allocation failed"), error);
libxfs_trans_ijoin(tp, pip, 0);
len = (int)strlen(buf);
getres(tp, XFS_B_TO_FSB(mp, len));
error = libxfs_inode_alloc(&tp, pip, mode|S_IFLNK, 1, 0,
- &creds, &ip);
+ &creds, fsxp, &ip);
if (error)
fail(_("Inode allocation failed"), error);
flags |= newfile(tp, ip, &flist, &first, 1, 1, buf, len);
case IF_DIRECTORY:
getres(tp, 0);
error = libxfs_inode_alloc(&tp, pip, mode|S_IFDIR, 1, 0,
- &creds, &ip);
+ &creds, fsxp, &ip);
if (error)
fail(_("Inode allocation failed"), error);
ip->i_d.di_nlink++; /* account for . */
break;
if (strcmp(name, "$") == 0)
break;
- parseproto(mp, ip, pp, name);
+ parseproto(mp, ip, fsxp, pp, name);
}
libxfs_iput(ip, 0);
return;
libxfs_trans_commit(tp, 0, NULL);
}
+void
+parse_proto(
+ xfs_mount_t *mp,
+ struct fsxattr *fsx,
+ char **pp)
+{
+ parseproto(mp, NULL, fsx, pp, NULL);
+}
+
/*
* Allocate the realtime bitmap and summary inodes, and fill in data if any.
*/
xfs_inode_t *rbmip;
xfs_inode_t *rsumip;
xfs_trans_t *tp;
- cred_t creds;
+ struct cred creds;
+ struct fsxattr fsxattrs;
/*
* First, allocate the inodes.
if ((i = libxfs_trans_reserve(tp, MKFS_BLOCKRES_INODE, 0, 0, 0, 0)))
res_failed(i);
bzero(&creds, sizeof(creds));
- error = libxfs_inode_alloc(&tp, mp->m_rootip, S_IFREG, 1, 0,
- &creds, &rbmip);
+ bzero(&fsxattrs, sizeof(fsxattrs));
+ error = libxfs_inode_alloc(&tp, NULL, S_IFREG, 1, 0,
+ &creds, &fsxattrs, &rbmip);
if (error) {
fail(_("Realtime bitmap inode allocation failed"), error);
}
libxfs_mod_sb(tp, XFS_SB_RBMINO);
libxfs_trans_ihold(tp, rbmip);
mp->m_rbmip = rbmip;
- error = libxfs_inode_alloc(&tp, mp->m_rootip, S_IFREG, 1, 0,
- &creds, &rsumip);
+ error = libxfs_inode_alloc(&tp, NULL, S_IFREG, 1, 0,
+ &creds, &fsxattrs, &rsumip);
if (error) {
fail(_("Realtime summary inode allocation failed"), error);
}
"sectsize",
#define D_NOALIGN 12
"noalign",
+#define D_RTINHERIT 13
+ "rtinherit",
+#define D_PROJINHERIT 14
+ "projinherit",
+#define D_EXTSZINHERIT 15
+ "extszinherit",
NULL
};
int dswidth;
int extent_flagging;
int force_overwrite;
+ struct fsxattr fsx;
int iaflag;
int ilflag;
int imaxpct;
extent_flagging = 1;
force_overwrite = 0;
worst_freelist = 0;
+ bzero(&fsx, sizeof(fsx));
bzero(&xi, sizeof(xi));
xi.notvolok = 1;
libxfs_highbit32(sectorsize);
ssflag = 1;
break;
+ case D_RTINHERIT:
+ fsx.fsx_xflags |= \
+ XFS_DIFLAG_RTINHERIT;
+ break;
+ case D_PROJINHERIT:
+ if (!value)
+ reqval('d', dopts, D_PROJINHERIT);
+ fsx.fsx_projid = atoi(value);
+ fsx.fsx_xflags |= \
+ XFS_DIFLAG_PROJINHERIT;
+ break;
+ case D_EXTSZINHERIT:
+ if (!value)
+ reqval('d', dopts, D_EXTSZINHERIT);
+ fsx.fsx_extsize = atoi(value);
+ fsx.fsx_xflags |= \
+ XFS_DIFLAG_EXTSZINHERIT;
+ break;
default:
unknown('d', value);
}
* Allocate the root inode and anything else in the proto file.
*/
mp->m_rootip = NULL;
- parseproto(mp, NULL, &protostring, NULL);
+ parse_proto(mp, &fsx, &protostring);
/*
* Protect ourselves against possible stupidity
/* proto.c */
extern char *setup_proto (char *fname);
-extern void parseproto (xfs_mount_t *mp, xfs_inode_t *pip, char **pp, char *n);
+extern void parse_proto (xfs_mount_t *mp, struct fsxattr *fsx, char **pp);
extern void res_failed (int err);
/* maxtrres.c */
/*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
#include "dinode.h"
#include "versions.h"
-static cred_t zerocr;
+static struct cred zerocr;
+static struct fsxattr zerofsx;
static int orphanage_entered;
/*
i, ORPHANAGE);
error = libxfs_inode_alloc(&tp, pip, mode|S_IFDIR,
- 1, 0, &zerocr, &ip);
+ 1, 0, &zerocr, &zerofsx, &ip);
if (error) {
do_error(_("%s inode allocation failed %d\n"),
int i;
int j;
- bzero(&zerocr, sizeof(cred_t));
+ bzero(&zerocr, sizeof(struct cred));
+ bzero(&zerofsx, sizeof(struct fsxattr));
do_log(_("Phase 6 - check inode connectivity...\n"));