From: Nathan Scott Date: Fri, 11 Nov 2005 14:23:54 +0000 (+0000) Subject: Provide mkfs options to easily exercise all inheritable attributes, esp. the extsize... X-Git-Tag: v2.8.0~72 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9f064b7ee30931875951c23c1b3dd1dee6592e46;p=thirdparty%2Fxfsprogs-dev.git Provide mkfs options to easily exercise all inheritable attributes, esp. the extsize allocator hint. Merge of master-melb:xfs-cmds:24370a by kenmcd. --- diff --git a/include/libxfs.h b/include/libxfs.h index 48b76c50f..3a13ffaf7 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -352,13 +352,14 @@ typedef struct xfs_inode { #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); diff --git a/libxfs/util.c b/libxfs/util.c index 96db71887..79490c157 100644 --- a/libxfs/util.c +++ b/libxfs/util.c @@ -33,63 +33,6 @@ #include #include -/* - * 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. * @@ -128,15 +71,15 @@ libxfs_ichgtime(xfs_inode_t *ip, int flags) * 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, @@ -172,7 +115,7 @@ libxfs_ialloc( 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)); /* @@ -187,6 +130,12 @@ libxfs_ialloc( /* 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); @@ -194,10 +143,10 @@ libxfs_ialloc( /* * 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: @@ -212,6 +161,30 @@ libxfs_ialloc( 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; @@ -738,3 +711,61 @@ libxfs_da_bjoin(xfs_trans_t *tp, xfs_dabuf_t *dabuf) 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; +} diff --git a/libxfs/xfs.h b/libxfs/xfs.h index 26c505552..754e8b7d6 100644 --- a/libxfs/xfs.h +++ b/libxfs/xfs.h @@ -103,7 +103,6 @@ #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 diff --git a/mkfs/proto.c b/mkfs/proto.c index 318a0511c..166759e36 100644 --- a/mkfs/proto.c +++ b/mkfs/proto.c @@ -1,32 +1,32 @@ /* - * 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/ */ @@ -37,8 +37,6 @@ /* * 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); @@ -46,7 +44,7 @@ static void getres(xfs_trans_t *tp, uint blocks); 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); @@ -355,10 +353,11 @@ newdirectory( fail(_("directory create error"), error); } -void +static void parseproto( xfs_mount_t *mp, xfs_inode_t *pip, + struct fsxattr *fsxp, char **pp, char *name) { @@ -463,7 +462,7 @@ parseproto( 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); @@ -481,7 +480,7 @@ parseproto( 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); @@ -504,7 +503,7 @@ parseproto( 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); } @@ -520,7 +519,7 @@ parseproto( 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); @@ -533,7 +532,7 @@ parseproto( 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); @@ -546,7 +545,7 @@ parseproto( 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); @@ -558,7 +557,7 @@ parseproto( 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 . */ @@ -597,7 +596,7 @@ parseproto( break; if (strcmp(name, "$") == 0) break; - parseproto(mp, ip, pp, name); + parseproto(mp, ip, fsxp, pp, name); } libxfs_iput(ip, 0); return; @@ -611,6 +610,15 @@ parseproto( 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. */ @@ -632,7 +640,8 @@ rtinit( 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. @@ -641,8 +650,9 @@ rtinit( 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); } @@ -659,8 +669,8 @@ rtinit( 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); } diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index 924923937..18baf1d47 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -84,6 +84,12 @@ char *dopts[] = { "sectsize", #define D_NOALIGN 12 "noalign", +#define D_RTINHERIT 13 + "rtinherit", +#define D_PROJINHERIT 14 + "projinherit", +#define D_EXTSZINHERIT 15 + "extszinherit", NULL }; @@ -543,6 +549,7 @@ main( int dswidth; int extent_flagging; int force_overwrite; + struct fsxattr fsx; int iaflag; int ilflag; int imaxpct; @@ -634,6 +641,7 @@ main( extent_flagging = 1; force_overwrite = 0; worst_freelist = 0; + bzero(&fsx, sizeof(fsx)); bzero(&xi, sizeof(xi)); xi.notvolok = 1; @@ -849,6 +857,24 @@ main( 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); } @@ -2265,7 +2291,7 @@ an AG size that is one stripe unit smaller, for example %llu.\n"), * 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 diff --git a/mkfs/xfs_mkfs.h b/mkfs/xfs_mkfs.h index cda57b428..d4712bae5 100644 --- a/mkfs/xfs_mkfs.h +++ b/mkfs/xfs_mkfs.h @@ -65,7 +65,7 @@ extern long long cvtnum (unsigned int blocksize, /* 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 */ diff --git a/repair/phase6.c b/repair/phase6.c index aa3d61c4b..656da2ec9 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -1,5 +1,5 @@ /* - * 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 @@ -43,7 +43,8 @@ #include "dinode.h" #include "versions.h" -static cred_t zerocr; +static struct cred zerocr; +static struct fsxattr zerofsx; static int orphanage_entered; /* @@ -753,7 +754,7 @@ mk_orphanage(xfs_mount_t *mp) 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"), @@ -3891,7 +3892,8 @@ phase6(xfs_mount_t *mp) 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"));