![basebuilder@powerel.org](/assets/img/avatar_default.png)
27 changed files with 2052 additions and 3 deletions
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
commit 595629131dbe6c5fb16d03e87bc2cb71ad3dcc4b |
||||
Author: Eric Sandeen <sandeen@redhat.com> |
||||
Date: Wed Feb 15 21:48:31 2017 -0600 |
||||
|
||||
xfs_metadump: ignore attr leaf with 0 entries |
||||
|
||||
Another in the ongoing saga of attribute leaves with zero |
||||
entries; in this case, if we try to metadump an inode with |
||||
a zero-entries attribute leaf, the zeroing code will go off |
||||
the rails and segfault at: |
||||
|
||||
memset(&entries[nentries], 0, |
||||
first_name - (char *)&entries[nentries]); |
||||
|
||||
because first_name is null, and we try to memset a large |
||||
(negative) number. |
||||
|
||||
Signed-off-by: Eric Sandeen <sandeen@redhat.com> |
||||
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> |
||||
Signed-off-by: Eric Sandeen <sandeen@sandeen.net> |
||||
|
||||
diff --git a/db/metadump.c b/db/metadump.c |
||||
index 38519f1..66952f6 100644 |
||||
--- a/db/metadump.c |
||||
+++ b/db/metadump.c |
||||
@@ -1654,7 +1654,8 @@ process_attr_block( |
||||
xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &hdr, leaf); |
||||
|
||||
nentries = hdr.count; |
||||
- if (nentries * sizeof(xfs_attr_leaf_entry_t) + |
||||
+ if (nentries == 0 || |
||||
+ nentries * sizeof(xfs_attr_leaf_entry_t) + |
||||
xfs_attr3_leaf_hdr_size(leaf) > |
||||
XFS_ATTR3_RMT_BUF_SPACE(mp, bs)) { |
||||
if (show_warnings) |
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
From 47e48705ed893ca9f46adb02ad15e5acddbe060a Mon Sep 17 00:00:00 2001 |
||||
From: Eric Sandeen <sandeen@redhat.com> |
||||
Date: Mon, 10 Apr 2017 17:32:04 -0500 |
||||
Subject: [PATCH] xfs_repair: warn about dirty log with -n option |
||||
|
||||
When looking at xfs_repair -n output today, we have no idea if |
||||
reported errors may be due to an un-replayed dirty log. If this |
||||
is the case, mention it in the output. |
||||
|
||||
Signed-off-by: Eric Sandeen <sandeen@redhat.com> |
||||
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> |
||||
Signed-off-by: Eric Sandeen <sandeen@sandeen.net> |
||||
--- |
||||
repair/phase2.c | 9 +++++++-- |
||||
1 file changed, 7 insertions(+), 2 deletions(-) |
||||
|
||||
Index: xfsprogs-4.5.0/repair/phase2.c |
||||
=================================================================== |
||||
--- xfsprogs-4.5.0.orig/repair/phase2.c |
||||
+++ xfsprogs-4.5.0/repair/phase2.c |
||||
@@ -89,11 +89,16 @@ zero_log( |
||||
_("zero_log: head block %" PRId64 " tail block %" PRId64 "\n"), |
||||
head_blk, tail_blk); |
||||
} |
||||
- if (!no_modify && head_blk != tail_blk) { |
||||
- if (zap_log) { |
||||
+ if (head_blk != tail_blk) { |
||||
+ if (!no_modify && zap_log) { |
||||
do_warn(_( |
||||
"ALERT: The filesystem has valuable metadata changes in a log which is being\n" |
||||
"destroyed because the -L option was used.\n")); |
||||
+ } else if (no_modify) { |
||||
+ do_warn(_( |
||||
+"ALERT: The filesystem has valuable metadata changes in a log which is being\n" |
||||
+"ignored because the -n option was used. Expect spurious inconsistencies\n" |
||||
+"which may be resolved by first mounting the filesystem to replay the log.\n")); |
||||
} else { |
||||
do_warn(_( |
||||
"ERROR: The filesystem has valuable metadata changes in a log which needs to\n" |
@ -0,0 +1,86 @@
@@ -0,0 +1,86 @@
|
||||
From 746d40a73162f942f63f6a2f612f491d107b9824 Mon Sep 17 00:00:00 2001 |
||||
From: Eric Sandeen <sandeen@redhat.com> |
||||
Date: Thu, 20 Jul 2017 10:51:34 -0500 |
||||
Subject: [PATCH] mkfs.xfs: allow specification of 0 data stripe width & unit |
||||
|
||||
The "noalign" option works for this too, but it seems reasonable |
||||
to allow explicit specification of stripe unit and stripe width |
||||
to 0; today, doing so today makes the code think it's unspecified, |
||||
and so it goes ahead and detects stripe geometry and sets it in the |
||||
superblock. That's unexpected and surprising. |
||||
|
||||
Create a new flag that tracks whtether a geometry option has been |
||||
specified, and if it's set along with 0 values, treat it the |
||||
same as if "noalign" had been specified. |
||||
|
||||
Signed-off-by: Eric Sandeen <sandeen@redhat.com> |
||||
Reviewed-by: Christoph Hellwig <hch@lst.de> |
||||
Signed-off-by: Eric Sandeen <sandeen@sandeen.net> |
||||
--- |
||||
mkfs/xfs_mkfs.c | 11 ++++++++++- |
||||
1 file changed, 10 insertions(+), 1 deletion(-) |
||||
|
||||
Index: xfsprogs-rhel7.5/mkfs/xfs_mkfs.c |
||||
=================================================================== |
||||
--- xfsprogs-rhel7.5.orig/mkfs/xfs_mkfs.c |
||||
+++ xfsprogs-rhel7.5/mkfs/xfs_mkfs.c |
||||
@@ -909,6 +909,7 @@ main( |
||||
int dsw; |
||||
int dsunit; |
||||
int dswidth; |
||||
+ int dsflag; |
||||
int force_overwrite; |
||||
struct fsxattr fsx; |
||||
int iaflag; |
||||
@@ -1012,7 +1013,7 @@ main( |
||||
dfile = logfile = rtfile = NULL; |
||||
dsize = logsize = rtsize = rtextsize = protofile = NULL; |
||||
dsu = dsw = dsunit = dswidth = lalign = lsu = lsunit = 0; |
||||
- nodsflag = norsflag = 0; |
||||
+ dsflag = nodsflag = norsflag = 0; |
||||
force_overwrite = 0; |
||||
worst_freelist = 0; |
||||
lazy_sb_counters = 1; |
||||
@@ -1137,6 +1138,7 @@ main( |
||||
exit(1); |
||||
} |
||||
dsunit = cvtnum(0, 0, value); |
||||
+ dsflag = 1; |
||||
break; |
||||
case D_SWIDTH: |
||||
if (!value || *value == '\0') |
||||
@@ -1153,6 +1155,7 @@ main( |
||||
exit(1); |
||||
} |
||||
dswidth = cvtnum(0, 0, value); |
||||
+ dsflag = 1; |
||||
break; |
||||
case D_SU: |
||||
if (!value || *value == '\0') |
||||
@@ -1164,6 +1167,7 @@ main( |
||||
D_SU); |
||||
dsu = cvtnum( |
||||
blocksize, sectorsize, value); |
||||
+ dsflag = 1; |
||||
break; |
||||
case D_SW: |
||||
if (!value || *value == '\0') |
||||
@@ -1180,6 +1184,7 @@ main( |
||||
exit(1); |
||||
} |
||||
dsw = cvtnum(0, 0, value); |
||||
+ dsflag = 1; |
||||
break; |
||||
case D_NOALIGN: |
||||
if (dsu) |
||||
@@ -2078,6 +2083,10 @@ _("warning: sparse inodes not supported |
||||
calc_stripe_factors(dsu, dsw, sectorsize, lsu, lsectorsize, |
||||
&dsunit, &dswidth, &lsunit); |
||||
|
||||
+ /* If sunit & swidth were manually specified as 0, same as noalign */ |
||||
+ if (dsflag && !dsunit && !dswidth) |
||||
+ nodsflag = 1; |
||||
+ |
||||
xi.setblksize = sectorsize; |
||||
|
||||
/* |
@ -0,0 +1,148 @@
@@ -0,0 +1,148 @@
|
||||
From db23e0f431a77d228b5f68ef0a8587c25c689133 Mon Sep 17 00:00:00 2001 |
||||
From: Bill O'Donnell <billodo@redhat.com> |
||||
Date: Thu, 29 Jun 2017 13:05:00 -0500 |
||||
Subject: [PATCH] xfs_db: improve argument naming in set_cur and set_iocur_type |
||||
|
||||
In set_cur and set_iocur_type, the current naming for arguments |
||||
type, block number, and length are t, d, and c, respectively. |
||||
Replace these with more intuitive and descriptive names: |
||||
type, blknum, and len. Fix type of blknum (xfs_daddr_t) to be |
||||
consistent with that of libxfs_readbuf where it's used. |
||||
Additionally remove extra blank line in io.c. |
||||
|
||||
Signed-off-by: Bill O'Donnell <billodo@redhat.com> |
||||
Reviewed-by: Eric Sandeen <sandeen@redhat.com> |
||||
Signed-off-by: Eric Sandeen <sandeen@sandeen.net> |
||||
--- |
||||
db/io.c | 38 +++++++++++++++++++------------------- |
||||
db/io.h | 6 +++--- |
||||
2 files changed, 22 insertions(+), 22 deletions(-) |
||||
|
||||
Index: xfsprogs-rhel7.5/db/io.c |
||||
=================================================================== |
||||
--- xfsprogs-rhel7.5.orig/db/io.c |
||||
+++ xfsprogs-rhel7.5/db/io.c |
||||
@@ -487,9 +487,9 @@ write_cur(void) |
||||
|
||||
void |
||||
set_cur( |
||||
- const typ_t *t, |
||||
- __int64_t d, |
||||
- int c, |
||||
+ const typ_t *type, |
||||
+ xfs_daddr_t blknum, |
||||
+ int len, |
||||
int ring_flag, |
||||
bbmap_t *bbmap) |
||||
{ |
||||
@@ -497,14 +497,13 @@ set_cur( |
||||
xfs_ino_t dirino; |
||||
xfs_ino_t ino; |
||||
__uint16_t mode; |
||||
- const struct xfs_buf_ops *ops = t ? t->bops : NULL; |
||||
+ const struct xfs_buf_ops *ops = type ? type->bops : NULL; |
||||
|
||||
if (iocur_sp < 0) { |
||||
dbprintf(_("set_cur no stack element to set\n")); |
||||
return; |
||||
} |
||||
|
||||
- |
||||
ino = iocur_top->ino; |
||||
dirino = iocur_top->dirino; |
||||
mode = iocur_top->mode; |
||||
@@ -514,7 +513,7 @@ set_cur( |
||||
if (bbmap) { |
||||
#ifdef DEBUG_BBMAP |
||||
int i; |
||||
- printf(_("xfs_db got a bbmap for %lld\n"), (long long)d); |
||||
+ printf(_("xfs_db got a bbmap for %lld\n"), (long long)blknum); |
||||
printf(_("\tblock map")); |
||||
for (i = 0; i < bbmap->nmaps; i++) |
||||
printf(" %lld:%d", (long long)bbmap->b[i].bm_bn, |
||||
@@ -528,7 +527,7 @@ set_cur( |
||||
bp = libxfs_readbuf_map(mp->m_ddev_targp, bbmap->b, |
||||
bbmap->nmaps, 0, ops); |
||||
} else { |
||||
- bp = libxfs_readbuf(mp->m_ddev_targp, d, c, 0, ops); |
||||
+ bp = libxfs_readbuf(mp->m_ddev_targp, blknum, len, 0, ops); |
||||
iocur_top->bbmap = NULL; |
||||
} |
||||
|
||||
@@ -544,13 +543,13 @@ set_cur( |
||||
if (!ops) |
||||
bp->b_flags |= LIBXFS_B_UNCHECKED; |
||||
|
||||
- iocur_top->bb = d; |
||||
- iocur_top->blen = c; |
||||
+ iocur_top->bb = blknum; |
||||
+ iocur_top->blen = len; |
||||
iocur_top->boff = 0; |
||||
iocur_top->data = iocur_top->buf; |
||||
- iocur_top->len = BBTOB(c); |
||||
- iocur_top->off = d << BBSHIFT; |
||||
- iocur_top->typ = cur_typ = t; |
||||
+ iocur_top->len = BBTOB(len); |
||||
+ iocur_top->off = blknum << BBSHIFT; |
||||
+ iocur_top->typ = cur_typ = type; |
||||
iocur_top->ino = ino; |
||||
iocur_top->dirino = dirino; |
||||
iocur_top->mode = mode; |
||||
@@ -564,23 +563,24 @@ set_cur( |
||||
|
||||
void |
||||
set_iocur_type( |
||||
- const typ_t *t) |
||||
+ const typ_t *type) |
||||
{ |
||||
struct xfs_buf *bp = iocur_top->bp; |
||||
|
||||
/* adjust buffer size for types with fields & hence fsize() */ |
||||
- if (t->fields) { |
||||
+ if (type->fields) { |
||||
int bb_count; /* type's size in basic blocks */ |
||||
|
||||
- bb_count = BTOBB(byteize(fsize(t->fields, iocur_top->data, 0, 0))); |
||||
- set_cur(t, iocur_top->bb, bb_count, DB_RING_IGN, NULL); |
||||
+ bb_count = BTOBB(byteize(fsize(type->fields, |
||||
+ iocur_top->data, 0, 0))); |
||||
+ set_cur(type, iocur_top->bb, bb_count, DB_RING_IGN, NULL); |
||||
} |
||||
- iocur_top->typ = t; |
||||
+ iocur_top->typ = type; |
||||
|
||||
/* verify the buffer if the type has one. */ |
||||
if (!bp) |
||||
return; |
||||
- if (!t->bops) { |
||||
+ if (!type->bops) { |
||||
bp->b_ops = NULL; |
||||
bp->b_flags |= LIBXFS_B_UNCHECKED; |
||||
return; |
||||
@@ -588,7 +588,7 @@ set_iocur_type( |
||||
if (!(bp->b_flags & LIBXFS_B_UPTODATE)) |
||||
return; |
||||
bp->b_error = 0; |
||||
- bp->b_ops = t->bops; |
||||
+ bp->b_ops = type->bops; |
||||
bp->b_ops->verify_read(bp); |
||||
bp->b_flags &= ~LIBXFS_B_UNCHECKED; |
||||
} |
||||
Index: xfsprogs-rhel7.5/db/io.h |
||||
=================================================================== |
||||
--- xfsprogs-rhel7.5.orig/db/io.h |
||||
+++ xfsprogs-rhel7.5/db/io.h |
||||
@@ -59,10 +59,10 @@ extern void print_iocur(char *tag, iocur |
||||
extern void push_cur(void); |
||||
extern int read_buf(__int64_t daddr, int count, void *bufp); |
||||
extern void write_cur(void); |
||||
-extern void set_cur(const struct typ *t, __int64_t d, int c, int ring_add, |
||||
- bbmap_t *bbmap); |
||||
+extern void set_cur(const struct typ *type, xfs_daddr_t blknum, |
||||
+ int len, int ring_add, bbmap_t *bbmap); |
||||
extern void ring_add(void); |
||||
-extern void set_iocur_type(const struct typ *t); |
||||
+extern void set_iocur_type(const struct typ *type); |
||||
extern void xfs_dummy_verify(struct xfs_buf *bp); |
||||
|
||||
/* |
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
From 533d1d229a881d5a58a232377c409a3dd7a5cd6f Mon Sep 17 00:00:00 2001 |
||||
From: Eric Sandeen <sandeen@redhat.com> |
||||
Date: Thu, 20 Jul 2017 10:51:46 -0500 |
||||
Subject: [PATCH] xfs_db: properly set inode type |
||||
|
||||
When we set the type to "inode" the verifier validates multiple |
||||
inodes in the current fs block, so setting the buffer size to |
||||
that of just one inode is not sufficient and it'll emit spurious |
||||
verifier errors for all but the first, as we read off the end: |
||||
|
||||
xfs_db> daddr 99 |
||||
xfs_db> type inode |
||||
Metadata corruption detected at xfs_inode block 0x63/0x200 |
||||
Metadata corruption detected at xfs_inode block 0x63/0x200 |
||||
Metadata corruption detected at xfs_inode block 0x63/0x200 |
||||
Metadata corruption detected at xfs_inode block 0x63/0x200 |
||||
Metadata corruption detected at xfs_inode block 0x63/0x200 |
||||
Metadata corruption detected at xfs_inode block 0x63/0x200 |
||||
Metadata corruption detected at xfs_inode block 0x63/0x200 |
||||
|
||||
Use the special set_cur_inode() function for this purpose |
||||
as is done in inode_f(). |
||||
|
||||
Signed-off-by: Eric Sandeen <sandeen@redhat.com> |
||||
Reviewed-by: Bill O'Donnell <billodo@redhat.com> |
||||
[sandeen: remove nag/warning printf for now] |
||||
Signed-off-by: Eric Sandeen <sandeen@sandeen.net> |
||||
--- |
||||
db/io.c | 16 ++++++++++++++++ |
||||
1 file changed, 16 insertions(+) |
||||
|
||||
Index: xfsprogs-rhel7.5/db/io.c |
||||
=================================================================== |
||||
--- xfsprogs-rhel7.5.orig/db/io.c |
||||
+++ xfsprogs-rhel7.5/db/io.c |
||||
@@ -567,6 +567,22 @@ set_iocur_type( |
||||
{ |
||||
struct xfs_buf *bp = iocur_top->bp; |
||||
|
||||
+ /* Inodes are special; verifier checks all inodes in the chunk */ |
||||
+ if (type->typnm == TYP_INODE) { |
||||
+ xfs_daddr_t b = iocur_top->bb; |
||||
+ xfs_ino_t ino; |
||||
+ |
||||
+ /* |
||||
+ * Note that this will back up to the beginning of the inode |
||||
+ * which contains the current disk location; daddr may change. |
||||
+ */ |
||||
+ ino = XFS_AGINO_TO_INO(mp, xfs_daddr_to_agno(mp, b), |
||||
+ ((b << BBSHIFT) >> mp->m_sb.sb_inodelog) % |
||||
+ (mp->m_sb.sb_agblocks << mp->m_sb.sb_inopblog)); |
||||
+ set_cur_inode(ino); |
||||
+ return; |
||||
+ } |
||||
+ |
||||
/* adjust buffer size for types with fields & hence fsize() */ |
||||
if (type->fields) { |
||||
int bb_count; /* type's size in basic blocks */ |
@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
|
||||
From 55f224baf83d71b3d2cc24e6387d9f1f6a5a1eda Mon Sep 17 00:00:00 2001 |
||||
From: Bill O'Donnell <billodo@redhat.com> |
||||
Date: Thu, 29 Jun 2017 13:05:00 -0500 |
||||
Subject: [PATCH] xfs_db: update buffer size when new type is set |
||||
|
||||
xfs_db doesn't take sector size into account when setting type. |
||||
This can result in an errant crc. For example, with a sector size |
||||
of 4096: |
||||
|
||||
xfs_db> agi 0 |
||||
xfs_db> p crc |
||||
crc = 0xab85043e (correct) |
||||
xfs_db> daddr |
||||
current daddr is 16 |
||||
xfs_db> daddr 42 |
||||
xfs_db> daddr 16 |
||||
xfs_db> type agi |
||||
Metadata CRC error detected at xfs_agi block 0x10/0x200 |
||||
xfs_db> p crc |
||||
crc = 0xab85043e (bad) |
||||
|
||||
When xfs_db sets the new daddr in daddr_f, it does so with one |
||||
BBSIZE sector (512). Changing the type doesn't change the size |
||||
of the current buffer in iocur_top, so the checksum is calculated |
||||
on the wrong length for the type (when the actual sector size > BBSIZE (512). |
||||
|
||||
For types with fields, reread the buffer to pick up the correct size for |
||||
the new type when it gets set. Facilitate the reread by setting the cursor |
||||
with set_cur(). |
||||
|
||||
Signed-off-by: Bill O'Donnell <billodo@redhat.com> |
||||
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> |
||||
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> |
||||
[sandeen: fix up long line, clarify subject & comments] |
||||
Signed-off-by: Eric Sandeen <sandeen@sandeen.net> |
||||
--- |
||||
db/io.c | 8 ++++++++ |
||||
1 file changed, 8 insertions(+) |
||||
|
||||
Index: xfsprogs-rhel7.5/db/io.c |
||||
=================================================================== |
||||
--- xfsprogs-rhel7.5.orig/db/io.c |
||||
+++ xfsprogs-rhel7.5/db/io.c |
||||
@@ -27,6 +27,7 @@ |
||||
#include "output.h" |
||||
#include "init.h" |
||||
#include "malloc.h" |
||||
+#include "bit.h" |
||||
|
||||
static int pop_f(int argc, char **argv); |
||||
static void pop_help(void); |
||||
@@ -567,6 +568,13 @@ set_iocur_type( |
||||
{ |
||||
struct xfs_buf *bp = iocur_top->bp; |
||||
|
||||
+ /* adjust buffer size for types with fields & hence fsize() */ |
||||
+ if (t->fields) { |
||||
+ int bb_count; /* type's size in basic blocks */ |
||||
+ |
||||
+ bb_count = BTOBB(byteize(fsize(t->fields, iocur_top->data, 0, 0))); |
||||
+ set_cur(t, iocur_top->bb, bb_count, DB_RING_IGN, NULL); |
||||
+ } |
||||
iocur_top->typ = t; |
||||
|
||||
/* verify the buffer if the type has one. */ |
@ -0,0 +1,54 @@
@@ -0,0 +1,54 @@
|
||||
From 9a106b5fbb88342f0ee02891d1bbb0e3c5a93d03 Mon Sep 17 00:00:00 2001 |
||||
From: Donald Douwsma <ddouwsma@redhat.com> |
||||
Date: Fri, 15 Sep 2017 08:33:42 -0500 |
||||
Subject: [PATCH] mkfs.xfs: Don't stagger AG for a single disk |
||||
|
||||
When sunit and swidth are used mkfs.xfs tries to avoid all allocation |
||||
groups aligning on the same stripe and will attempt to stagger them |
||||
across the stripes that make up swidth. If there is only one stripe |
||||
then there is no benefit in this optimisation. |
||||
|
||||
$ truncate -s10G xfs_10G_su256k_sw1.image |
||||
$ mkfs.xfs -d su=256k,sw=1 xfs_10G_su256k_sw1.image |
||||
meta-data=xfs_10G_su256k_sw1.image isize=512 agcount=16, agsize=163776 blks |
||||
= sectsz=512 attr=2, projid32bit=1 |
||||
= crc=1 finobt=0, sparse=0 |
||||
data = bsize=4096 blocks=2620416, imaxpct=25 |
||||
= sunit=64 swidth=64 blks |
||||
naming =version 2 bsize=4096 ascii-ci=0 ftype=1 |
||||
log =internal log bsize=4096 blocks=2560, version=2 |
||||
= sectsz=512 sunit=64 blks, lazy-count=1 |
||||
realtime =none extsz=4096 blocks=0, rtextents=0 |
||||
|
||||
A side effect of the optimisation is that the size adjustment used to stager |
||||
the allocation groups causes the last sunit of storage to be unused. |
||||
|
||||
$ echo $((2620416*4096)) |
||||
10733223936 |
||||
$ ls -l xfs_10G_su256k_sw1.image |
||||
-rw-rw-r--. 1 test test 10737418240 Aug 30 10:54 xfs_10G_su256k_sw1.image |
||||
|
||||
Skip this optimisation when sunit == swidth. |
||||
|
||||
Signed-off-by: Donald Douwsma <ddouwsma@redhat.com> |
||||
Reviewed-by: Eric Sandeen <sandeen@redhat.com> |
||||
Signed-off-by: Eric Sandeen <sandeen@sandeen.net> |
||||
--- |
||||
mkfs/xfs_mkfs.c | 4 +++- |
||||
1 file changed, 3 insertions(+), 1 deletion(-) |
||||
|
||||
Index: xfsprogs-rhel7.5/mkfs/xfs_mkfs.c |
||||
=================================================================== |
||||
--- xfsprogs-rhel7.5.orig/mkfs/xfs_mkfs.c |
||||
+++ xfsprogs-rhel7.5/mkfs/xfs_mkfs.c |
||||
@@ -2308,7 +2308,9 @@ reported by the device (%u).\n"), |
||||
} |
||||
} |
||||
} |
||||
- if (dswidth && ((agsize % dswidth) == 0) && (agcount > 1)) { |
||||
+ if (dswidth && ((agsize % dswidth) == 0) |
||||
+ && (dswidth != dsunit) |
||||
+ && (agcount > 1)) { |
||||
/* This is a non-optimal configuration because all AGs |
||||
* start on the same disk in the stripe. Changing |
||||
* the AG size by one sunit will guarantee that this |
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
From 67ea25fe9d663f69b550b39ce86b074534ae7c85 Mon Sep 17 00:00:00 2001 |
||||
From: Masatake YAMATO <yamato@redhat.com> |
||||
Date: Fri, 15 Sep 2017 13:42:18 -0500 |
||||
Subject: [PATCH] xfs_repair: don't use do_warn for normal log message |
||||
|
||||
In some case, exit status of xfs_repair -n is different even for |
||||
the same file system when -v is specified or not. This patch fixes |
||||
this behavior. |
||||
|
||||
If -v is specified, do_warn() is used in zero_log() for printing |
||||
a normal message. That makes the exit status to 1 though there |
||||
is no dirtiness in the file system. |
||||
|
||||
Signed-off-by: Masatake YAMATO <yamato@redhat.com> |
||||
Reviewed-by: Eric Sandeen <sandeen@redhat.com> |
||||
[sandeen: edit changelog for brevity] |
||||
Signed-off-by: Eric Sandeen <sandeen@sandeen.net> |
||||
--- |
||||
repair/phase2.c | 2 +- |
||||
1 file changed, 1 insertion(+), 1 deletion(-) |
||||
|
||||
Index: xfsprogs-4.5.0/repair/phase2.c |
||||
=================================================================== |
||||
--- xfsprogs-4.5.0.orig/repair/phase2.c |
||||
+++ xfsprogs-4.5.0/repair/phase2.c |
||||
@@ -85,7 +85,7 @@ zero_log( |
||||
"attempt a repair.\n")); |
||||
} else { |
||||
if (verbose) { |
||||
- do_warn( |
||||
+ do_log( |
||||
_("zero_log: head block %" PRId64 " tail block %" PRId64 "\n"), |
||||
head_blk, tail_blk); |
||||
} |
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
This patch is not yet upstream; there are missing braces under |
||||
the if (!no_modify && !zap_log) case so that a repair which fails |
||||
xlog_find_tail() will not be repairable, because -L will not be |
||||
able to zero out the log. |
||||
|
||||
Reported-by: Xiao Yang <yangx.jy@cn.fujitsu.com> |
||||
Signed-off-by: Xiao Yang <yangx.jy@cn.fujitsu.com> |
||||
Reviewed-by: Eric Sandeen <sandeen@redhat.com> |
||||
|
||||
Index: xfsprogs-4.5.0/repair/phase2.c |
||||
=================================================================== |
||||
--- xfsprogs-4.5.0.orig/repair/phase2.c |
||||
+++ xfsprogs-4.5.0/repair/phase2.c |
||||
@@ -78,12 +78,13 @@ zero_log( |
||||
do_warn( |
||||
_("zero_log: cannot find log head/tail (xlog_find_tail=%d)\n"), |
||||
error); |
||||
- if (!no_modify && !zap_log) |
||||
+ if (!no_modify && !zap_log) { |
||||
do_warn(_( |
||||
"ERROR: The log head and/or tail cannot be discovered. Attempt to mount the\n" |
||||
"filesystem to replay the log or use the -L option to destroy the log and\n" |
||||
"attempt a repair.\n")); |
||||
exit(2); |
||||
+ } |
||||
} else { |
||||
if (verbose) { |
||||
do_log( |
@ -0,0 +1,93 @@
@@ -0,0 +1,93 @@
|
||||
Disable finobt by default for compatibility w/ old RHEL7 kernels. |
||||
|
||||
Disable experimental sparse inode support entirely. |
||||
|
||||
Index: xfsprogs-4.5.0/man/man8/mkfs.xfs.8 |
||||
=================================================================== |
||||
--- xfsprogs-4.5.0.orig/man/man8/mkfs.xfs.8 |
||||
+++ xfsprogs-4.5.0/man/man8/mkfs.xfs.8 |
||||
@@ -167,9 +167,10 @@ filesystems age. |
||||
.IP |
||||
By default, |
||||
.B mkfs.xfs |
||||
-will create free inode btrees for filesystems created with the (default) |
||||
-.B \-m crc=1 |
||||
-option set. When the option |
||||
+will not create free inode btrees for filesystems. This is for backwards |
||||
+compatibility with older RHEL7 kernels. If the free inode btree is enabled, |
||||
+older RHEL7 kernels will not be able to mount the created filesystem. |
||||
+When the option |
||||
.B \-m crc=0 |
||||
is used, the free inode btree feature is not supported and is disabled. |
||||
.TP |
||||
@@ -419,21 +420,8 @@ If the value is omitted, 1 is assumed. |
||||
in release version 3.2.0.) |
||||
.TP |
||||
.BI sparse[= value ] |
||||
-Enable sparse inode chunk allocation. The |
||||
-.I value |
||||
-is either 0 or 1, with 1 signifying that sparse allocation is enabled. |
||||
-If the value is omitted, 1 is assumed. Sparse inode allocation is |
||||
-disabled by default. This feature is only available for filesystems |
||||
-formatted with |
||||
-.B \-m crc=1. |
||||
-.IP |
||||
-When enabled, sparse inode allocation allows the filesystem to allocate |
||||
-smaller than the standard 64-inode chunk when free space is severely |
||||
-limited. This feature is useful for filesystems that might fragment free |
||||
-space over time such that no free extents are large enough to |
||||
-accommodate a chunk of 64 inodes. Without this feature enabled, inode |
||||
-allocations can fail with out of space errors under severe fragmented |
||||
-free space conditions. |
||||
+Enable sparse inode chunk allocation. This experimental option is not |
||||
+available in RHEL7. |
||||
.RE |
||||
.TP |
||||
.BI \-l " log_section_options" |
||||
Index: xfsprogs-4.5.0/mkfs/xfs_mkfs.c |
||||
=================================================================== |
||||
--- xfsprogs-4.5.0.orig/mkfs/xfs_mkfs.c |
||||
+++ xfsprogs-4.5.0/mkfs/xfs_mkfs.c |
||||
@@ -105,8 +105,6 @@ char *iopts[] = { |
||||
"attr", |
||||
#define I_PROJID32BIT 6 |
||||
"projid32bit", |
||||
-#define I_SPINODES 7 |
||||
- "sparse", |
||||
NULL |
||||
}; |
||||
|
||||
@@ -1019,7 +1017,7 @@ main( |
||||
worst_freelist = 0; |
||||
lazy_sb_counters = 1; |
||||
crcs_enabled = 1; |
||||
- finobt = 1; |
||||
+ finobt = 0; |
||||
finobtflag = false; |
||||
spinodes = 0; |
||||
memset(&fsx, 0, sizeof(fsx)); |
||||
@@ -1343,6 +1341,7 @@ main( |
||||
illegal(value, "i projid32bit"); |
||||
projid16bit = c ? 0 : 1; |
||||
break; |
||||
+#if 0 |
||||
case I_SPINODES: |
||||
if (!value || *value == '\0') |
||||
value = "1"; |
||||
@@ -1350,6 +1349,7 @@ main( |
||||
if (spinodes < 0 || spinodes > 1) |
||||
illegal(value, "i spinodes"); |
||||
break; |
||||
+#endif |
||||
default: |
||||
unknown('i', value); |
||||
} |
||||
@@ -3213,7 +3213,7 @@ usage( void ) |
||||
sectlog=n|sectsize=num\n\ |
||||
/* force overwrite */ [-f]\n\ |
||||
/* inode size */ [-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,\n\ |
||||
- projid32bit=0|1,sparse=0|1]\n\ |
||||
+ projid32bit=0|1]\n\ |
||||
/* no discard */ [-K]\n\ |
||||
/* log subvol */ [-l agnum=n,internal,size=num,logdev=xxx,version=n\n\ |
||||
sunit=value|su=num,sectlog=n|sectsize=num,\n\ |
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
xfs.h: define XFS_IOC_FREEZE even if FIFREEZE is defined |
||||
|
||||
And the same for XFS_IOC_THAW. Just because we now have a common |
||||
version of the ioctl we still need to provide the old name for it |
||||
for anyone using those. |
||||
|
||||
Signed-off-by: Christoph Hellwig <hch@lst.de> |
||||
|
||||
linux.h: include <linux/fs.h> |
||||
|
||||
To reliably prevent the redefinition of struct fsxattr. |
||||
|
||||
Signed-off-by: Christoph Hellwig <hch@lst.de> |
||||
Reported-by: Jeffrey Bastian <jbastian@redhat.com> |
||||
|
||||
--- |
||||
libxfs/xfs_fs.h | 8 ++------ |
||||
2 files changed, 3 insertions(+), 6 deletions(-) |
||||
|
||||
|
||||
diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h |
||||
index b9622ba..1f17e1c 100644 |
||||
--- a/libxfs/xfs_fs.h |
||||
+++ b/libxfs/xfs_fs.h |
||||
@@ -542,12 +542,8 @@ typedef struct xfs_swapext |
||||
#define XFS_IOC_ERROR_CLEARALL _IOW ('X', 117, struct xfs_error_injection) |
||||
/* XFS_IOC_ATTRCTL_BY_HANDLE -- deprecated 118 */ |
||||
|
||||
-/* XFS_IOC_FREEZE -- FIFREEZE 119 */ |
||||
-/* XFS_IOC_THAW -- FITHAW 120 */ |
||||
-#ifndef FIFREEZE |
||||
-#define XFS_IOC_FREEZE _IOWR('X', 119, int) |
||||
-#define XFS_IOC_THAW _IOWR('X', 120, int) |
||||
-#endif |
||||
+#define XFS_IOC_FREEZE _IOWR('X', 119, int) /* aka FIFREEZE */ |
||||
+#define XFS_IOC_THAW _IOWR('X', 120, int) /* aka FITHAW */ |
||||
|
||||
#define XFS_IOC_FSSETDM_BY_HANDLE _IOW ('X', 121, struct xfs_fsop_setdm_handlereq) |
||||
#define XFS_IOC_ATTRLIST_BY_HANDLE _IOW ('X', 122, struct xfs_fsop_attrlist_handlereq) |
||||
|
||||
diff --git a/include/linux.h b/include/linux.h |
||||
index cc0f70c..0c616f4 100644 |
||||
--- a/include/linux.h |
||||
+++ b/include/linux.h |
||||
@@ -32,6 +32,7 @@ |
||||
#include <stdio.h> |
||||
#include <asm/types.h> |
||||
#include <mntent.h> |
||||
+#include <linux/fs.h> /* fsxattr defintion for new kernels */ |
||||
|
||||
static __inline__ int xfsctl(const char *path, int fd, int cmd, void *p) |
||||
{ |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
reverted: |
||||
--- b/libxfs/xfs_format.h |
||||
+++ a/libxfs/xfs_format.h |
||||
@@ -787,7 +787,7 @@ |
||||
__be64 agfl_lsn; |
||||
__be32 agfl_crc; |
||||
__be32 agfl_bno[]; /* actually XFS_AGFL_SIZE(mp) */ |
||||
+} xfs_agfl_t; |
||||
-} __attribute__((packed)) xfs_agfl_t; |
||||
|
||||
#define XFS_AGFL_CRC_OFF offsetof(struct xfs_agfl, agfl_crc) |
@ -0,0 +1,341 @@
@@ -0,0 +1,341 @@
|
||||
commit 09c93e56b5296a30507cde9c00433eb4ed2d395d |
||||
Author: Brian Foster <bfoster@redhat.com> |
||||
Date: Tue Jun 21 12:58:57 2016 +1000 |
||||
|
||||
xfs_db: Revert "xfs_db: make check work for sparse inodes" |
||||
|
||||
This reverts commit bb2f98b78f20f4abbfbbd442162d9f535c84888a which |
||||
introduced support for multi-record inode chunks in |
||||
xfs_db/xfs_check. However, it doesn't currently handle filesystems |
||||
with multi-record inode chunks correctly. For example, do the |
||||
following on a 64k page size arch such as ppc64: |
||||
|
||||
# mkfs.xfs -f -b size=64k <dev> |
||||
# xfs_db -c check <dev> |
||||
bad magic number 0 for inode 1152 |
||||
bad magic number 0 for inode 1153 |
||||
bad magic number 0 for inode 1154 |
||||
bad magic number 0 for inode 1155 |
||||
bad magic number 0 for inode 1156 |
||||
bad magic number 0 for inode 1157 |
||||
... |
||||
|
||||
This boils down to a regression in the inode record processing code |
||||
(scanfunc_ino()) in db/check.c. Specifically, the cblocks value can |
||||
end up being zero after it is shifted by mp->m_sb.sb_inopblog (i.e., |
||||
64 >> 7 == 0 for an -isize=512 -bsize=64k fs). |
||||
|
||||
Fixing this problem is easier to do from scratch, so revert the |
||||
oringial commit first. |
||||
|
||||
Signed-off-by: Brian Foster <bfoster@redhat.com> |
||||
Reviewed-by: Dave Chinner <dchinner@redhat.com> |
||||
Signed-off-by: Dave Chinner <david@fromorbit.com> |
||||
|
||||
diff --git a/db/check.c b/db/check.c |
||||
index 0871ed7..750ecc1 100644 |
||||
--- a/db/check.c |
||||
+++ b/db/check.c |
||||
@@ -4311,51 +4311,6 @@ scanfunc_cnt( |
||||
scan_sbtree(agf, be32_to_cpu(pp[i]), level, 0, scanfunc_cnt, TYP_CNTBT); |
||||
} |
||||
|
||||
-static bool |
||||
-ino_issparse( |
||||
- struct xfs_inobt_rec *rp, |
||||
- int offset) |
||||
-{ |
||||
- if (!xfs_sb_version_hassparseinodes(&mp->m_sb)) |
||||
- return false; |
||||
- |
||||
- return xfs_inobt_is_sparse_disk(rp, offset); |
||||
-} |
||||
- |
||||
-static int |
||||
-find_one_ino_bit( |
||||
- __u16 mask, |
||||
- int startino) |
||||
-{ |
||||
- int n; |
||||
- int b; |
||||
- |
||||
- startino /= XFS_INODES_PER_HOLEMASK_BIT; |
||||
- b = startino; |
||||
- mask >>= startino; |
||||
- for (n = startino; n < sizeof(mask) * NBBY && !(mask & 1); n++, mask >>= 1) |
||||
- b++; |
||||
- |
||||
- return b * XFS_INODES_PER_HOLEMASK_BIT; |
||||
-} |
||||
- |
||||
-static int |
||||
-find_zero_ino_bit( |
||||
- __u16 mask, |
||||
- int startino) |
||||
-{ |
||||
- int n; |
||||
- int b; |
||||
- |
||||
- startino /= XFS_INODES_PER_HOLEMASK_BIT; |
||||
- b = startino; |
||||
- mask >>= startino; |
||||
- for (n = startino; n < sizeof(mask) * NBBY && (mask & 1); n++, mask >>= 1) |
||||
- b++; |
||||
- |
||||
- return b * XFS_INODES_PER_HOLEMASK_BIT; |
||||
-} |
||||
- |
||||
static void |
||||
scanfunc_ino( |
||||
struct xfs_btree_block *block, |
||||
@@ -4373,13 +4328,6 @@ scanfunc_ino( |
||||
int off; |
||||
xfs_inobt_ptr_t *pp; |
||||
xfs_inobt_rec_t *rp; |
||||
- bool sparse, crc; |
||||
- int inodes_per_chunk; |
||||
- int freecount; |
||||
- int startidx, endidx; |
||||
- __u16 holemask; |
||||
- xfs_agino_t rino; |
||||
- xfs_extlen_t cblocks; |
||||
|
||||
if (be32_to_cpu(block->bb_magic) != XFS_IBT_MAGIC && |
||||
be32_to_cpu(block->bb_magic) != XFS_IBT_CRC_MAGIC) { |
||||
@@ -4407,111 +4355,59 @@ scanfunc_ino( |
||||
return; |
||||
} |
||||
rp = XFS_INOBT_REC_ADDR(mp, block, 1); |
||||
- sparse = xfs_sb_version_hassparseinodes(&mp->m_sb); |
||||
- crc = xfs_sb_version_hascrc(&mp->m_sb); |
||||
for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) { |
||||
- nfree = 0; |
||||
- |
||||
- /* First let's look at the inode chunk alignment */ |
||||
agino = be32_to_cpu(rp[i].ir_startino); |
||||
off = XFS_INO_TO_OFFSET(mp, agino); |
||||
- if (off == 0 && |
||||
- (sbversion & XFS_SB_VERSION_ALIGNBIT) && |
||||
- mp->m_sb.sb_inoalignmt && |
||||
- (XFS_INO_TO_AGBNO(mp, agino) % |
||||
- mp->m_sb.sb_inoalignmt)) { |
||||
- if (sparse || crc) { |
||||
- dbprintf(_("incorrect record %u/%u " |
||||
- "alignment in inobt block " |
||||
- "%u/%u\n"), |
||||
- seqno, agino, seqno, bno); |
||||
- error++; |
||||
- } else |
||||
+ if (off == 0) { |
||||
+ if ((sbversion & XFS_SB_VERSION_ALIGNBIT) && |
||||
+ mp->m_sb.sb_inoalignmt && |
||||
+ (XFS_INO_TO_AGBNO(mp, agino) % |
||||
+ mp->m_sb.sb_inoalignmt)) |
||||
sbversion &= ~XFS_SB_VERSION_ALIGNBIT; |
||||
+ set_dbmap(seqno, XFS_AGINO_TO_AGBNO(mp, agino), |
||||
+ (xfs_extlen_t)MAX(1, |
||||
+ XFS_INODES_PER_CHUNK >> |
||||
+ mp->m_sb.sb_inopblog), |
||||
+ DBM_INODE, seqno, bno); |
||||
} |
||||
- |
||||
- /* Move on to examining the inode chunks */ |
||||
- if (sparse) { |
||||
- inodes_per_chunk = rp[i].ir_u.sp.ir_count; |
||||
- freecount = rp[i].ir_u.sp.ir_freecount; |
||||
- holemask = be16_to_cpu(rp[i].ir_u.sp.ir_holemask); |
||||
- startidx = find_zero_ino_bit(holemask, 0); |
||||
- } else { |
||||
- inodes_per_chunk = XFS_INODES_PER_CHUNK; |
||||
- freecount = be32_to_cpu(rp[i].ir_u.f.ir_freecount); |
||||
- holemask = 0; |
||||
- startidx = 0; |
||||
- } |
||||
- |
||||
- /* For each allocated chunk, look at each inode. */ |
||||
- endidx = find_one_ino_bit(holemask, startidx); |
||||
- do { |
||||
- rino = agino + startidx; |
||||
- cblocks = (endidx - startidx) >> |
||||
- mp->m_sb.sb_inopblog; |
||||
- |
||||
- /* Check the sparse chunk alignment */ |
||||
- if (sparse && |
||||
- (XFS_INO_TO_AGBNO(mp, rino) % |
||||
- mp->m_sb.sb_spino_align)) { |
||||
- dbprintf(_("incorrect chunk %u/%u " |
||||
- "alignment in inobt block " |
||||
+ icount += XFS_INODES_PER_CHUNK; |
||||
+ agicount += XFS_INODES_PER_CHUNK; |
||||
+ ifree += be32_to_cpu(rp[i].ir_u.f.ir_freecount); |
||||
+ agifreecount += be32_to_cpu(rp[i].ir_u.f.ir_freecount); |
||||
+ push_cur(); |
||||
+ set_cur(&typtab[TYP_INODE], |
||||
+ XFS_AGB_TO_DADDR(mp, seqno, |
||||
+ XFS_AGINO_TO_AGBNO(mp, agino)), |
||||
+ (int)XFS_FSB_TO_BB(mp, mp->m_ialloc_blks), |
||||
+ DB_RING_IGN, NULL); |
||||
+ if (iocur_top->data == NULL) { |
||||
+ if (!sflag) |
||||
+ dbprintf(_("can't read inode block " |
||||
"%u/%u\n"), |
||||
- seqno, rino, seqno, bno); |
||||
- error++; |
||||
- } |
||||
- |
||||
- /* Check the block map */ |
||||
- set_dbmap(seqno, XFS_AGINO_TO_AGBNO(mp, rino), |
||||
- cblocks, DBM_INODE, seqno, bno); |
||||
- |
||||
- push_cur(); |
||||
- set_cur(&typtab[TYP_INODE], |
||||
- XFS_AGB_TO_DADDR(mp, seqno, |
||||
- XFS_AGINO_TO_AGBNO(mp, rino)), |
||||
- (int)XFS_FSB_TO_BB(mp, cblocks), |
||||
- DB_RING_IGN, NULL); |
||||
- if (iocur_top->data == NULL) { |
||||
- if (!sflag) |
||||
- dbprintf(_("can't read inode block " |
||||
- "%u/%u\n"), |
||||
- seqno, |
||||
- XFS_AGINO_TO_AGBNO(mp, agino)); |
||||
- error++; |
||||
- pop_cur(); |
||||
- continue; |
||||
- } |
||||
- |
||||
- /* Examine each inode in this chunk */ |
||||
- for (j = startidx; j < endidx; j++) { |
||||
- if (ino_issparse(&rp[i], j)) |
||||
- continue; |
||||
- isfree = XFS_INOBT_IS_FREE_DISK(&rp[i], j); |
||||
- if (isfree) |
||||
- nfree++; |
||||
- process_inode(agf, agino + j, |
||||
- (xfs_dinode_t *)((char *)iocur_top->data + ((j - startidx) << mp->m_sb.sb_inodelog)), |
||||
- isfree); |
||||
- } |
||||
+ seqno, |
||||
+ XFS_AGINO_TO_AGBNO(mp, agino)); |
||||
+ error++; |
||||
pop_cur(); |
||||
- |
||||
- startidx = find_zero_ino_bit(holemask, endidx); |
||||
- endidx = find_one_ino_bit(holemask, startidx); |
||||
- } while (endidx < XFS_INODES_PER_CHUNK); |
||||
- icount += inodes_per_chunk; |
||||
- agicount += inodes_per_chunk; |
||||
- ifree += freecount; |
||||
- agifreecount += freecount; |
||||
- |
||||
- if (nfree != freecount) { |
||||
+ continue; |
||||
+ } |
||||
+ for (j = 0, nfree = 0; j < XFS_INODES_PER_CHUNK; j++) { |
||||
+ isfree = XFS_INOBT_IS_FREE_DISK(&rp[i], j); |
||||
+ if (isfree) |
||||
+ nfree++; |
||||
+ process_inode(agf, agino + j, |
||||
+ (xfs_dinode_t *)((char *)iocur_top->data + ((off + j) << mp->m_sb.sb_inodelog)), |
||||
+ isfree); |
||||
+ } |
||||
+ if (nfree != be32_to_cpu(rp[i].ir_u.f.ir_freecount)) { |
||||
if (!sflag) |
||||
dbprintf(_("ir_freecount/free mismatch, " |
||||
"inode chunk %u/%u, freecount " |
||||
"%d nfree %d\n"), |
||||
seqno, agino, |
||||
- freecount, nfree); |
||||
+ be32_to_cpu(rp[i].ir_u.f.ir_freecount), nfree); |
||||
error++; |
||||
} |
||||
+ pop_cur(); |
||||
} |
||||
return; |
||||
} |
||||
@@ -4543,11 +4439,6 @@ scanfunc_fino( |
||||
int off; |
||||
xfs_inobt_ptr_t *pp; |
||||
struct xfs_inobt_rec *rp; |
||||
- bool sparse, crc; |
||||
- int startidx, endidx; |
||||
- __u16 holemask; |
||||
- xfs_agino_t rino; |
||||
- xfs_extlen_t cblocks; |
||||
|
||||
if (be32_to_cpu(block->bb_magic) != XFS_FIBT_MAGIC && |
||||
be32_to_cpu(block->bb_magic) != XFS_FIBT_CRC_MAGIC) { |
||||
@@ -4575,63 +4466,21 @@ scanfunc_fino( |
||||
return; |
||||
} |
||||
rp = XFS_INOBT_REC_ADDR(mp, block, 1); |
||||
- sparse = xfs_sb_version_hassparseinodes(&mp->m_sb); |
||||
- crc = xfs_sb_version_hascrc(&mp->m_sb); |
||||
for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) { |
||||
- /* First let's look at the inode chunk alignment */ |
||||
agino = be32_to_cpu(rp[i].ir_startino); |
||||
off = XFS_INO_TO_OFFSET(mp, agino); |
||||
- if (off == 0 && |
||||
- (sbversion & XFS_SB_VERSION_ALIGNBIT) && |
||||
- mp->m_sb.sb_inoalignmt && |
||||
- (XFS_INO_TO_AGBNO(mp, agino) % |
||||
- mp->m_sb.sb_inoalignmt)) { |
||||
- if (sparse || crc) { |
||||
- dbprintf(_("incorrect record %u/%u " |
||||
- "alignment in finobt block " |
||||
- "%u/%u\n"), |
||||
- seqno, agino, seqno, bno); |
||||
- error++; |
||||
- } else |
||||
+ if (off == 0) { |
||||
+ if ((sbversion & XFS_SB_VERSION_ALIGNBIT) && |
||||
+ mp->m_sb.sb_inoalignmt && |
||||
+ (XFS_INO_TO_AGBNO(mp, agino) % |
||||
+ mp->m_sb.sb_inoalignmt)) |
||||
sbversion &= ~XFS_SB_VERSION_ALIGNBIT; |
||||
+ check_set_dbmap(seqno, XFS_AGINO_TO_AGBNO(mp, agino), |
||||
+ (xfs_extlen_t)MAX(1, |
||||
+ XFS_INODES_PER_CHUNK >> |
||||
+ mp->m_sb.sb_inopblog), |
||||
+ DBM_INODE, DBM_INODE, seqno, bno); |
||||
} |
||||
- |
||||
- /* Move on to examining the inode chunks */ |
||||
- if (sparse) { |
||||
- holemask = be16_to_cpu(rp[i].ir_u.sp.ir_holemask); |
||||
- startidx = find_zero_ino_bit(holemask, 0); |
||||
- } else { |
||||
- holemask = 0; |
||||
- startidx = 0; |
||||
- } |
||||
- |
||||
- /* For each allocated chunk... */ |
||||
- endidx = find_one_ino_bit(holemask, startidx); |
||||
- do { |
||||
- rino = agino + startidx; |
||||
- cblocks = (endidx - startidx) >> |
||||
- mp->m_sb.sb_inopblog; |
||||
- |
||||
- /* Check the sparse chunk alignment */ |
||||
- if (sparse && |
||||
- (XFS_INO_TO_AGBNO(mp, rino) % |
||||
- mp->m_sb.sb_spino_align)) { |
||||
- dbprintf(_("incorrect chunk %u/%u " |
||||
- "alignment in finobt block " |
||||
- "%u/%u\n"), |
||||
- seqno, rino, seqno, bno); |
||||
- error++; |
||||
- } |
||||
- |
||||
- /* Check the block map */ |
||||
- check_set_dbmap(seqno, |
||||
- XFS_AGINO_TO_AGBNO(mp, rino), |
||||
- cblocks, DBM_INODE, DBM_INODE, |
||||
- seqno, bno); |
||||
- |
||||
- startidx = find_zero_ino_bit(holemask, endidx); |
||||
- endidx = find_one_ino_bit(holemask, startidx); |
||||
- } while (endidx < XFS_INODES_PER_CHUNK); |
||||
} |
||||
return; |
||||
} |
@ -0,0 +1,56 @@
@@ -0,0 +1,56 @@
|
||||
xfs_repair: don't mark the fs dirty just because memory possibly be low |
||||
|
||||
|
||||
|
||||
When I run "xfs_repair -n" on a 500T device with 16G memory, |
||||
xfs_repair print warning as below: |
||||
|
||||
Memory available for repair (11798MB) may not be sufficient. |
||||
At least 64048MB is needed to repair this filesystem efficiently |
||||
If repair fails due to lack of memory, please |
||||
turn prefetching off (-P) to reduce the memory footprint. |
||||
|
||||
And it return 1 at last. But xfs_repair didn't hit any error, it |
||||
just feel the memory maybe too low(not real), then return error. |
||||
There is no reason to mark the fs dirty just because it thinks it |
||||
might *possibly* be low on memory. |
||||
|
||||
do_warn() will set fs_is_dirty=1, if we only want to print warning |
||||
message(not real failure), turn to use do_log() will be better. |
||||
|
||||
Signed-off-by: Zorro Lang <zlang@redhat.com> |
||||
--- |
||||
repair/xfs_repair.c | 6 +++--- |
||||
1 file changed, 3 insertions(+), 3 deletions(-) |
||||
|
||||
diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c |
||||
index 9d91f2d..bbf0edc 100644 |
||||
--- a/repair/xfs_repair.c |
||||
+++ b/repair/xfs_repair.c |
||||
@@ -851,16 +851,16 @@ main(int argc, char **argv) |
||||
"with the -m option. Please increase it to at least %lu.\n"), |
||||
mem_used / 1024); |
||||
} |
||||
- do_warn( |
||||
+ do_log( |
||||
_("Memory available for repair (%luMB) may not be sufficient.\n" |
||||
"At least %luMB is needed to repair this filesystem efficiently\n" |
||||
"If repair fails due to lack of memory, please\n"), |
||||
max_mem / 1024, mem_used / 1024); |
||||
if (do_prefetch) |
||||
- do_warn( |
||||
+ do_log( |
||||
_("turn prefetching off (-P) to reduce the memory footprint.\n")); |
||||
else |
||||
- do_warn( |
||||
+ do_log( |
||||
_("increase system RAM and/or swap space to at least %luMB.\n"), |
||||
mem_used * 2 / 1024); |
||||
|
||||
-- |
||||
2.5.5 |
||||
|
||||
_______________________________________________ |
||||
xfs mailing list |
||||
xfs@oss.sgi.com |
||||
http://oss.sgi.com/mailman/listinfo/xfs |
@ -0,0 +1,93 @@
@@ -0,0 +1,93 @@
|
||||
[PATCH] xfs_repair: don't call xfs_sb_quota_from_disk twice |
||||
|
||||
kernel commit 5ef828c4 |
||||
xfs: avoid false quotacheck after unclean shutdown |
||||
|
||||
made xfs_sb_from_disk() also call xfs_sb_quota_from_disk |
||||
by default. |
||||
|
||||
However, when this was merged to libxfs, existing separate |
||||
calls to libxfs_sb_quota_from_disk remained, and calling it |
||||
twice in a row on a V4 superblock leads to issues, because: |
||||
|
||||
|
||||
if (sbp->sb_qflags & XFS_PQUOTA_ACCT) { |
||||
... |
||||
sbp->sb_pquotino = sbp->sb_gquotino; |
||||
sbp->sb_gquotino = NULLFSINO; |
||||
|
||||
and after the second call, we have set both pquotino and gquotino |
||||
to NULLFSINO. |
||||
|
||||
Fix this by making it safe to call twice, and also remove the extra |
||||
calls to libxfs_sb_quota_from_disk. |
||||
|
||||
This is only spotted when running xfstests with "-m crc=0" because |
||||
the sb_from_disk change came about after V5 became default, and |
||||
the above behavior only exists on a V4 superblock. |
||||
|
||||
Reported-by: Eryu Guan <eguan@redhat.com> |
||||
Signed-off-by: Eric Sandeen <sandeen@redhat.com> |
||||
--- |
||||
|
||||
|
||||
diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c |
||||
index 45db6ae..44f3e3e 100644 |
||||
--- a/libxfs/xfs_sb.c |
||||
+++ b/libxfs/xfs_sb.c |
||||
@@ -316,13 +316,16 @@ xfs_sb_quota_from_disk(struct xfs_sb *sbp) |
||||
XFS_PQUOTA_CHKD : XFS_GQUOTA_CHKD; |
||||
sbp->sb_qflags &= ~(XFS_OQUOTA_ENFD | XFS_OQUOTA_CHKD); |
||||
|
||||
- if (sbp->sb_qflags & XFS_PQUOTA_ACCT) { |
||||
+ if (sbp->sb_qflags & XFS_PQUOTA_ACCT && |
||||
+ sbp->sb_gquotino != NULLFSINO) { |
||||
/* |
||||
* In older version of superblock, on-disk superblock only |
||||
* has sb_gquotino, and in-core superblock has both sb_gquotino |
||||
* and sb_pquotino. But, only one of them is supported at any |
||||
* point of time. So, if PQUOTA is set in disk superblock, |
||||
- * copy over sb_gquotino to sb_pquotino. |
||||
+ * copy over sb_gquotino to sb_pquotino. The NULLFSINO test |
||||
+ * above is to make sure we don't do this twice and wipe them |
||||
+ * both out! |
||||
*/ |
||||
sbp->sb_pquotino = sbp->sb_gquotino; |
||||
sbp->sb_gquotino = NULLFSINO; |
||||
diff --git a/repair/sb.c b/repair/sb.c |
||||
index 3965953..8087242 100644 |
||||
--- a/repair/sb.c |
||||
+++ b/repair/sb.c |
||||
@@ -155,7 +155,6 @@ __find_secondary_sb( |
||||
for (i = 0; !done && i < bsize; i += BBSIZE) { |
||||
c_bufsb = (char *)sb + i; |
||||
libxfs_sb_from_disk(&bufsb, (xfs_dsb_t *)c_bufsb); |
||||
- libxfs_sb_quota_from_disk(&bufsb); |
||||
|
||||
if (verify_sb(c_bufsb, &bufsb, 0) != XR_OK) |
||||
continue; |
||||
@@ -568,7 +567,6 @@ get_sb(xfs_sb_t *sbp, xfs_off_t off, int size, xfs_agnumber_t agno) |
||||
do_error("%s\n", strerror(error)); |
||||
} |
||||
libxfs_sb_from_disk(sbp, buf); |
||||
- libxfs_sb_quota_from_disk(sbp); |
||||
|
||||
rval = verify_sb((char *)buf, sbp, agno == 0); |
||||
free(buf); |
||||
diff --git a/repair/scan.c b/repair/scan.c |
||||
index 964ff06..366ce16 100644 |
||||
--- a/repair/scan.c |
||||
+++ b/repair/scan.c |
||||
@@ -1622,7 +1622,6 @@ scan_ag( |
||||
goto out_free_sb; |
||||
} |
||||
libxfs_sb_from_disk(sb, XFS_BUF_TO_SBP(sbbuf)); |
||||
- libxfs_sb_quota_from_disk(sb); |
||||
|
||||
agfbuf = libxfs_readbuf(mp->m_dev, |
||||
XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), |
||||
|
||||
_______________________________________________ |
||||
xfs mailing list |
||||
xfs@oss.sgi.com |
||||
http://oss.sgi.com/mailman/listinfo/xfs |
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
commit 643f6acc4bb2d799bebd54c973949c1a90eb26a3 |
||||
Author: Eric Sandeen <sandeen@redhat.com> |
||||
Date: Tue Jun 21 12:55:15 2016 +1000 |
||||
|
||||
xfs_repair: set rsumino version to 2 |
||||
|
||||
If we run xfs/033 with "-m crc=0", the test fails with a repair |
||||
output difference: |
||||
|
||||
Phase 7 - verify and correct link counts... |
||||
+resetting inode INO nlinks from 0 to 1 |
||||
done |
||||
|
||||
This is because when we zero out the realtime summary inode and |
||||
rebuild it, we set its version to 1, then set its ip->i_d.di_nlink |
||||
to 1. This is a little odd, because v1 inodes store their link |
||||
count in di_onlink... |
||||
|
||||
Then, later in repair we call xfs_inode_from_disk(), which sees the |
||||
version one inode, and converts it to version 2 in part by copying |
||||
di_onlink to di_nlink. But we never *set* di_onlink, so di_nlink |
||||
gets reset to zero, and this error is discovered later in repair. |
||||
|
||||
Interestingly, mk_rbmino() was changed in 138659f1 to set version 2; |
||||
it looks like mk_rsumino was just missed. |
||||
|
||||
Signed-off-by: Eric Sandeen <sandeen@redhat.com> |
||||
Reviewed-by: Dave Chinner <dchinner@redhat.com> |
||||
Signed-off-by: Dave Chinner <david@fromorbit.com> |
||||
|
||||
Index: xfsprogs-4.5.0/repair/phase6.c |
||||
=================================================================== |
||||
--- xfsprogs-4.5.0.orig/repair/phase6.c |
||||
+++ xfsprogs-4.5.0/repair/phase6.c |
||||
@@ -507,7 +507,7 @@ mk_rbmino(xfs_mount_t *mp) |
||||
error); |
||||
} |
||||
|
||||
- vers = xfs_sb_version_hascrc(&mp->m_sb) ? 3 : 1; |
||||
+ vers = xfs_sb_version_hascrc(&mp->m_sb) ? 3 : 2; |
||||
memset(&ip->i_d, 0, xfs_icdinode_size(vers)); |
||||
|
||||
ip->i_d.di_magic = XFS_DINODE_MAGIC; |
||||
@@ -766,7 +766,7 @@ mk_rsumino(xfs_mount_t *mp) |
||||
error); |
||||
} |
||||
|
||||
- vers = xfs_sb_version_hascrc(&mp->m_sb) ? 3 : 1; |
||||
+ vers = xfs_sb_version_hascrc(&mp->m_sb) ? 3 : 2; |
||||
memset(&ip->i_d, 0, xfs_icdinode_size(vers)); |
||||
|
||||
ip->i_d.di_magic = XFS_DINODE_MAGIC; |
@ -0,0 +1,33 @@
@@ -0,0 +1,33 @@
|
||||
commit 027e6efd2b432232562d726f14702f79792b38cb |
||||
Author: Eric Sandeen <sandeen@sandeen.net> |
||||
Date: Mon May 30 10:35:56 2016 +1000 |
||||
|
||||
xfs_db: defang frag command |
||||
|
||||
Too many people freak out about this fictitious "fragmentation |
||||
factor." As shown in the fact, it is largely meaningless, because |
||||
the number approaches 100% extremely quickly for just a few |
||||
extents per file. |
||||
|
||||
I thought about removing it altogether, but perhaps a note |
||||
about its uselessness, and a more soothing metric (avg extents |
||||
per file) might be useful. |
||||
|
||||
Signed-off-by: Eric Sandeen <sandeen@redhat.com> |
||||
Reviewed-by: Christoph Hellwig <hch@lst.de> |
||||
Signed-off-by: Dave Chinner <david@fromorbit.com> |
||||
|
||||
Index: xfsprogs-4.5.0/db/frag.c |
||||
=================================================================== |
||||
--- xfsprogs-4.5.0.orig/db/frag.c |
||||
+++ xfsprogs-4.5.0/db/frag.c |
||||
@@ -172,6 +172,10 @@ frag_f( |
||||
answer = 0.0; |
||||
dbprintf(_("actual %llu, ideal %llu, fragmentation factor %.2f%%\n"), |
||||
extcount_actual, extcount_ideal, answer); |
||||
+ dbprintf(_("Note, this number is largely meaningless.\n")); |
||||
+ answer = (double)extcount_actual / (double)extcount_ideal; |
||||
+ dbprintf(_("Files on this filesystem average %.2f extents per file\n"), |
||||
+ answer); |
||||
return 0; |
||||
} |
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
commit 6aa32b47197828b6d014a6faf9c7450bbc16e66f |
||||
Author: Eric Sandeen <sandeen@redhat.com> |
||||
Date: Tue May 10 17:16:06 2016 +1000 |
||||
|
||||
xfs_repair: fix agf limit error messages |
||||
|
||||
Today we see errors like: |
||||
|
||||
"fllast 118 in agf 94 too large (max = 118)" |
||||
|
||||
which makes no sense. |
||||
|
||||
If we are erroring on X >= Y, Y is clearly not the maximum allowable |
||||
value. |
||||
|
||||
Signed-off-by: Eric Sandeen <sandeen@redhat.com> |
||||
Reviewed-by: Dave Chinner <dchinner@redhat.com> |
||||
Signed-off-by: Dave Chinner <david@fromorbit.com> |
||||
|
||||
Index: xfsprogs-4.5.0/repair/agheader.c |
||||
=================================================================== |
||||
--- xfsprogs-4.5.0.orig/repair/agheader.c |
||||
+++ xfsprogs-4.5.0/repair/agheader.c |
||||
@@ -94,7 +94,7 @@ verify_set_agf(xfs_mount_t *mp, xfs_agf_ |
||||
if (be32_to_cpu(agf->agf_flfirst) >= XFS_AGFL_SIZE(mp)) { |
||||
do_warn(_("flfirst %d in agf %d too large (max = %zu)\n"), |
||||
be32_to_cpu(agf->agf_flfirst), |
||||
- i, XFS_AGFL_SIZE(mp)); |
||||
+ i, XFS_AGFL_SIZE(mp) - 1); |
||||
if (!no_modify) |
||||
agf->agf_flfirst = cpu_to_be32(0); |
||||
} |
||||
@@ -102,7 +102,7 @@ verify_set_agf(xfs_mount_t *mp, xfs_agf_ |
||||
if (be32_to_cpu(agf->agf_fllast) >= XFS_AGFL_SIZE(mp)) { |
||||
do_warn(_("fllast %d in agf %d too large (max = %zu)\n"), |
||||
be32_to_cpu(agf->agf_fllast), |
||||
- i, XFS_AGFL_SIZE(mp)); |
||||
+ i, XFS_AGFL_SIZE(mp) - 1); |
||||
if (!no_modify) |
||||
agf->agf_fllast = cpu_to_be32(0); |
||||
} |
@ -0,0 +1,327 @@
@@ -0,0 +1,327 @@
|
||||
commit 52e81d72272a00c692cb6fdaa49df8b59a539c50 |
||||
Author: Zorro Lang <zlang@redhat.com> |
||||
Date: Thu Aug 4 11:29:49 2016 +1000 |
||||
|
||||
xfs_quota: fall back silently if XFS_GETNEXTQUOTA fails |
||||
|
||||
After XFS_GETNEXTQUOTA feature has been merged into linux kernel and |
||||
xfsprogs, xfs_quota use Q_XGETNEXTQUOTA for report and dump, and |
||||
fall back to old XFS_GETQUOTA ioctl if XFS_GETNEXTQUOTA fails. |
||||
|
||||
But when XFS_GETNEXTQUOTA fails, xfs_quota print a warning as |
||||
"XFS_GETQUOTA: Invalid argument". That's due to kernel can't |
||||
recognize XFS_GETNEXTQUOTA ioctl and return EINVAL. At this time, |
||||
the warning is helpless, xfs_quota just need to fall back. |
||||
|
||||
Signed-off-by: Zorro Lang <zlang@redhat.com> |
||||
Reviewed-by: Dave Chinner <dchinner@redhat.com> |
||||
Signed-off-by: Dave Chinner <david@fromorbit.com> |
||||
|
||||
commit f61be1b4401e7653b2bdcd3aac2130a4da10faa5 |
||||
Author: Eric Sandeen <sandeen@redhat.com> |
||||
Date: Fri Jun 3 11:04:15 2016 +1000 |
||||
|
||||
xfs_quota: only round up timer reporting > 1 day |
||||
|
||||
I was too hasty with: |
||||
|
||||
d1fe6ff xfs_quota: remove extra 30 seconds from time limit reporting |
||||
|
||||
The point of that extra 30s, turns out, was to allow the user |
||||
to set a limit, query it, and get back what they just set, if |
||||
it is set to more than a day. |
||||
|
||||
Without it, if we set a grace period to i.e. 3 days, and query it |
||||
1 second later, the rounding in the time_to_string function returns |
||||
"2 days" not "3 days" as it did before, because we are at |
||||
2 days 23:59:59 and it essentially applies a floor() for |
||||
brevity. I guess this was confusing. |
||||
|
||||
(I've run into this same conundrum on my stove digital timer; |
||||
if you set it to 10m, it blinks "10" at you twice so that you |
||||
know what you set, then quickly flips to 9 as it counts down). |
||||
|
||||
In some cases, however (and this is the case that prompted the |
||||
prior patch), we display a full "XYZ days hh:mm:ss" - we do this |
||||
if the verbose flag is set, or if the timer is less than one day. |
||||
In these cases, we should not add the 30s, because we are showing |
||||
full time resolution to the user. |
||||
|
||||
Reported-by: Zorro Lang <zlang@redhat.com> |
||||
Signed-off-by: Eric Sandeen <sandeen@redhat.com> |
||||
Reviewed-by: Zorro Lang <zlang@redhat.com> |
||||
Reviewed-by: Christoph Hellwig <hch@lst.de> |
||||
Signed-off-by: Dave Chinner <david@fromorbit.com> |
||||
|
||||
commit a8b6f5274724ea2413d40f452f58874a36b78499 |
||||
Author: Eric Sandeen <sandeen@sandeen.net> |
||||
Date: Mon May 30 12:21:31 2016 +1000 |
||||
|
||||
xfs_quota: check report_mount return value |
||||
|
||||
The new call to report_mount doesn't check the return value |
||||
like every other caller does... |
||||
|
||||
Returning 1 means it printed something; if the terse flag |
||||
is used and there is no usage, nothing gets printed. |
||||
If we set the NO_HEADER_FLAG anyway, then we won't see |
||||
the header for subsequent entries as we expect. |
||||
|
||||
For example, project ID 0 has no usage in this case: |
||||
|
||||
# xfs_quota -x -c "report -a" /mnt/test |
||||
Project quota on /mnt/test (/dev/sdb1) |
||||
Blocks |
||||
Project ID Used Soft Hard Warn/Grace |
||||
---------- -------------------------------------------------- |
||||
#0 0 0 0 00 [--------] |
||||
project 2048 4 4 00 [--none--] |
||||
|
||||
So using the terse flag results in no header when it prints |
||||
projects with usage: |
||||
|
||||
# xfs_quota -x -c "report -t -a" /mnt/test |
||||
project 2048 4 4 00 [--none--] |
||||
|
||||
With this fix it prints the header as expected: |
||||
|
||||
# xfs_quota -x -c "report -t -a" /mnt/test |
||||
Project quota on /mnt/test (/dev/sdb1) |
||||
Blocks |
||||
Project ID Used Soft Hard Warn/Grace |
||||
---------- -------------------------------------------------- |
||||
project 2048 4 4 00 [--none--] |
||||
|
||||
Addresses-Coverity-Id: 1361552 |
||||
Signed-off-by: Eric Sandeen <sandeen@redhat.com> |
||||
Reviewed-by: Zorro Lang <zlang@redhat.com> |
||||
Reviewed-by: Christoph Hellwig <hch@lst.de> |
||||
Signed-off-by: Dave Chinner <david@fromorbit.com> |
||||
|
||||
commit 3d607a1134c55849952412d64e7658fb00312705 |
||||
Author: Zorro Lang <zlang@redhat.com> |
||||
Date: Tue May 10 17:16:06 2016 +1000 |
||||
|
||||
xfs_quota: print quota id number if the name can't be found |
||||
|
||||
When use GETNEXTQUOTA ioctl to report project quota, it always |
||||
report an unexpected quota: |
||||
|
||||
(null) 0 0 0 00 [--------] |
||||
|
||||
The ID 0 store the default quota, even if no one set default quota, |
||||
it still have quota accounting, but not enforced. So GETNEXTQUOTA |
||||
can find and report this undefined quota. |
||||
|
||||
From this problem, I thought if others' quota name miss, (null) will |
||||
be printed too. e.g. |
||||
|
||||
# xfs_quota -xc "limit -u bsoft=300m bhard=400m test" $mnt |
||||
# xfs_quota -xc "report -u" $mnt |
||||
User ID Used Soft Hard Warn/Grace |
||||
---------- -------------------------------------------------- |
||||
root 0 0 0 00 [--------] |
||||
test 0 307200 409600 00 [--------] |
||||
# userdel -r test |
||||
# xfs_quota -xc "report -u" $mnt |
||||
User ID Used Soft Hard Warn/Grace |
||||
---------- -------------------------------------------------- |
||||
root 0 0 0 00 [--------] |
||||
(null) 0 307200 409600 00 [--------] |
||||
|
||||
So this problem same with above id 0's problem. To deal with this, |
||||
this patch will print id number if the name can't be found. |
||||
|
||||
However, if we use the old GETQUOTA ioctl, it won't print project id |
||||
0 quota information if it's not defined. That's different with |
||||
GETNEXTQUOTA. For keep consistent, this patch also print project id |
||||
0 when use old GETQUOTA. |
||||
|
||||
Signed-off-by: Zorro Lang <zlang@redhat.com> |
||||
Reviewed-by: Eric Sandeen <sandeen@redhat.com> |
||||
Reviewed-by: Christoph Hellwig <hch@lst.de> |
||||
Signed-off-by: Dave Chinner <david@fromorbit.com> |
||||
|
||||
commit cef37d5a0ef68351ea97518249b0c91746e700e3 |
||||
Author: Zorro Lang <zlang@redhat.com> |
||||
Date: Tue May 10 17:16:06 2016 +1000 |
||||
|
||||
xfs_quota: fully support users and groups beginning with digits |
||||
|
||||
A normal user or group name allow beginning with digits, but xfs_quota |
||||
can't create a limit for that user or group. The reason is 'strtoul' |
||||
function only translate digits at the beginning, it will ignore |
||||
letters after digits. |
||||
|
||||
There's a commit fd537fc50eeade63bbd2a66105f39d04a011a7f5, it try to |
||||
fix "xfsprogs: xfs_quota allow user or group names beginning with |
||||
digits". But it doesn't effect 'limit' command, so a command likes: |
||||
|
||||
xfs_quota 'limit .... 12345678-user' xxxx |
||||
|
||||
will try to create limit for username="12345678", not "12345678-user". |
||||
|
||||
This patch will fix this problem, and a test case xfs/138 in xfstests |
||||
is used to reproduce this bug. |
||||
|
||||
Signed-off-by: Zorro Lang <zlang@redhat.com> |
||||
Reviewed-by: Eric Sandeen <sandeen@redhat.com> |
||||
Signed-off-by: Dave Chinner <david@fromorbit.com> |
||||
|
||||
commit 43633a39ef424e9e867b34a5dd3ea6c44508a45c |
||||
Author: Eric Sandeen <sandeen@sandeen.net> |
||||
Date: Wed Feb 17 17:03:02 2016 +1100 |
||||
|
||||
xfs: wire up Q_XGETNEXTQUOTA / get_nextdqblk |
||||
|
||||
Source kernel commit 296c24e26ee3af2dbfecb482e6bc9560bd34c455 |
||||
|
||||
Add code to allow the Q_XGETNEXTQUOTA quotactl to quickly find |
||||
all active quotas by examining the quota inode, and skipping |
||||
over unallocated or uninitialized regions. |
||||
|
||||
Userspace can then use this interface rather than i.e. a |
||||
getpwent() loop when asked to report all active quotas. |
||||
|
||||
Signed-off-by: Eric Sandeen <sandeen@redhat.com> |
||||
Reviewed-by: Dave Chinner <dchinner@redhat.com> |
||||
Signed-off-by: Dave Chinner <david@fromorbit.com> |
||||
Index: xfsprogs-4.5.0/quota/report.c |
||||
=================================================================== |
||||
--- xfsprogs-4.5.0.orig/quota/report.c |
||||
+++ xfsprogs-4.5.0/quota/report.c |
||||
@@ -90,8 +90,10 @@ dump_file( |
||||
else |
||||
cmd = XFS_GETQUOTA; |
||||
|
||||
+ /* Fall back silently if XFS_GETNEXTQUOTA fails, warn on XFS_GETQUOTA */ |
||||
if (xfsquotactl(cmd, dev, type, id, (void *)&d) < 0) { |
||||
- if (errno != ENOENT && errno != ENOSYS && errno != ESRCH) |
||||
+ if (errno != ENOENT && errno != ENOSYS && errno != ESRCH && |
||||
+ cmd == XFS_GETQUOTA) |
||||
perror("XFS_GETQUOTA"); |
||||
return 0; |
||||
} |
||||
@@ -347,8 +349,10 @@ report_mount( |
||||
else |
||||
cmd = XFS_GETQUOTA; |
||||
|
||||
+ /* Fall back silently if XFS_GETNEXTQUOTA fails, warn on XFS_GETQUOTA*/ |
||||
if (xfsquotactl(cmd, dev, type, id, (void *)&d) < 0) { |
||||
- if (errno != ENOENT && errno != ENOSYS && errno != ESRCH) |
||||
+ if (errno != ENOENT && errno != ENOSYS && errno != ESRCH && |
||||
+ cmd == XFS_GETQUOTA) |
||||
perror("XFS_GETQUOTA"); |
||||
return 0; |
||||
} |
||||
@@ -389,7 +393,11 @@ report_mount( |
||||
name = p->pr_name; |
||||
} |
||||
} |
||||
- fprintf(fp, "%-10s", name); |
||||
+ /* If no name is found, print the id #num instead of (null) */ |
||||
+ if (name != NULL) |
||||
+ fprintf(fp, "%-10s", name); |
||||
+ else |
||||
+ fprintf(fp, "#%-9u", d.d_id); |
||||
} |
||||
|
||||
if (form & XFS_BLOCK_QUOTA) { |
||||
@@ -571,6 +579,16 @@ report_project_mount( |
||||
id = oid + 1; |
||||
} |
||||
} else { |
||||
+ if (!getprprid(0)) { |
||||
+ /* |
||||
+ * Print default project quota, even if projid 0 |
||||
+ * isn't defined |
||||
+ */ |
||||
+ if (report_mount(fp, 0, NULL, NULL, |
||||
+ form, XFS_PROJ_QUOTA, mount, flags)) |
||||
+ flags |= NO_HEADER_FLAG; |
||||
+ } |
||||
+ |
||||
setprent(); |
||||
while ((p = getprent()) != NULL) { |
||||
if (report_mount(fp, p->pr_prid, p->pr_name, NULL, |
||||
Index: xfsprogs-4.5.0/quota/util.c |
||||
=================================================================== |
||||
--- xfsprogs-4.5.0.orig/quota/util.c |
||||
+++ xfsprogs-4.5.0/quota/util.c |
||||
@@ -43,6 +43,18 @@ time_to_string( |
||||
timer = MAX(origin - now, 0); |
||||
} |
||||
|
||||
+ /* |
||||
+ * If we are in verbose mode, or if less than a day remains, we |
||||
+ * will show "X days hh:mm:ss" so the user knows the exact timer status. |
||||
+ * |
||||
+ * Otherwise, we round down to the nearest day - so we add 30s here |
||||
+ * such that setting and reporting a limit in rapid succession will |
||||
+ * show the limit which was just set, rather than immediately reporting |
||||
+ * one day less. |
||||
+ */ |
||||
+ if ((timer > SECONDS_IN_A_DAY) && !(flags & VERBOSE_FLAG)) |
||||
+ timer += 30; /* seconds */ |
||||
+ |
||||
days = timer / SECONDS_IN_A_DAY; |
||||
if (days) |
||||
timer %= SECONDS_IN_A_DAY; |
||||
Index: xfsprogs-4.5.0/man/man8/xfs_quota.8 |
||||
=================================================================== |
||||
--- xfsprogs-4.5.0.orig/man/man8/xfs_quota.8 |
||||
+++ xfsprogs-4.5.0/man/man8/xfs_quota.8 |
||||
@@ -357,7 +357,9 @@ option outputs the report to |
||||
.I file |
||||
instead of stdout. The |
||||
.B \-a |
||||
-option reports on all filesystems. The |
||||
+option reports on all filesystems. By default, outputs the name of |
||||
+the user/group/project. If no name is defined for a given ID, outputs |
||||
+the numeric ID instead. The |
||||
.B \-n |
||||
option outputs the numeric ID instead of the name. The |
||||
.B \-L |
||||
Index: xfsprogs-4.5.0/libxcmd/input.c |
||||
=================================================================== |
||||
--- xfsprogs-4.5.0.orig/libxcmd/input.c |
||||
+++ xfsprogs-4.5.0/libxcmd/input.c |
||||
@@ -366,7 +366,7 @@ uid_from_string( |
||||
char *sp; |
||||
|
||||
uid_long = strtoul(user, &sp, 10); |
||||
- if (sp != user) { |
||||
+ if (sp != user && *sp == '\0') { |
||||
if ((uid_long == ULONG_MAX && errno == ERANGE) |
||||
|| (uid_long > (uid_t)-1)) |
||||
return -1; |
||||
@@ -387,7 +387,7 @@ gid_from_string( |
||||
char *sp; |
||||
|
||||
gid_long = strtoul(group, &sp, 10); |
||||
- if (sp != group) { |
||||
+ if (sp != group && *sp == '\0') { |
||||
if ((gid_long == ULONG_MAX && errno == ERANGE) |
||||
|| (gid_long > (gid_t)-1)) |
||||
return -1; |
||||
Index: xfsprogs-4.5.0/libxfs/xfs_quota_defs.h |
||||
=================================================================== |
||||
--- xfsprogs-4.5.0.orig/libxfs/xfs_quota_defs.h |
||||
+++ xfsprogs-4.5.0/libxfs/xfs_quota_defs.h |
||||
@@ -37,7 +37,7 @@ typedef __uint16_t xfs_qwarncnt_t; |
||||
#define XFS_DQ_PROJ 0x0002 /* project quota */ |
||||
#define XFS_DQ_GROUP 0x0004 /* a group quota */ |
||||
#define XFS_DQ_DIRTY 0x0008 /* dquot is dirty */ |
||||
-#define XFS_DQ_FREEING 0x0010 /* dquot is beeing torn down */ |
||||
+#define XFS_DQ_FREEING 0x0010 /* dquot is being torn down */ |
||||
|
||||
#define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP) |
||||
|
||||
@@ -116,6 +116,7 @@ typedef __uint16_t xfs_qwarncnt_t; |
||||
#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot if damaged */ |
||||
#define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */ |
||||
#define XFS_QMOPT_ENOSPC 0x0004000 /* enospc instead of edquot (prj) */ |
||||
+#define XFS_QMOPT_DQNEXT 0x0008000 /* return next dquot >= this ID */ |
||||
|
||||
/* |
||||
* flags to xfs_trans_mod_dquot to indicate which field needs to be |
@ -0,0 +1,40 @@
@@ -0,0 +1,40 @@
|
||||
From f10a5ab0b3a4cb8a7e17a4935fb33d283c3dd31f Mon Sep 17 00:00:00 2001 |
||||
From: Eric Sandeen <sandeen@sandeen.net> |
||||
Date: Tue, 20 Sep 2016 08:48:54 +1000 |
||||
Subject: [PATCH] mkfs.xfs: clarify ftype defaults in manpage |
||||
|
||||
When CRCs were made default, a few leftovers related to its |
||||
prior non-default status remained in the manpage, in the ftype |
||||
section. Clean those up, stating the correct default for this |
||||
feature. |
||||
|
||||
Reported-by: Chris Murphy <chris@cmurf.com> |
||||
Signed-off-by: Eric Sandeen <sandeen@redhat.com> |
||||
Reviewed-by: Dave Chinner <dchinner@redhat.com> |
||||
Signed-off-by: Dave Chinner <david@fromorbit.com> |
||||
--- |
||||
man/man8/mkfs.xfs.8 | 10 ++++------ |
||||
1 file changed, 4 insertions(+), 6 deletions(-) |
||||
|
||||
Index: xfsprogs-rhel7.5/man/man8/mkfs.xfs.8 |
||||
=================================================================== |
||||
--- xfsprogs-rhel7.5.orig/man/man8/mkfs.xfs.8 |
||||
+++ xfsprogs-rhel7.5/man/man8/mkfs.xfs.8 |
||||
@@ -587,13 +587,11 @@ do not need to look up the inode to dete |
||||
|
||||
The |
||||
.I value |
||||
-is either 0 or 1, with 1 signifiying that filetype information |
||||
-will be stored in the directory structure. The default value is 0. |
||||
+is either 0 or 1, with 1 signifying that filetype information |
||||
+will be stored in the directory structure. The default value is 1. |
||||
|
||||
-When CRCs are enabled via |
||||
-.B \-m crc=1, |
||||
-the ftype functionality is always enabled. This feature can not be turned |
||||
-off for such filesystem configurations. |
||||
+When CRCs are enabled (the default), the ftype functionality is always |
||||
+enabled, and cannot be turned off. |
||||
.IP |
||||
.RE |
||||
.TP |
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
commit 4e7a824f6b34dbe0dd2e2a3870891130b937f327 |
||||
Author: Felix Janda <felix.janda@posteo.de> |
||||
Date: Thu Sep 8 10:22:28 2016 +1000 |
||||
|
||||
libxfs/linux.c: Replace use of ustat by stat |
||||
|
||||
ustat has been used to check whether a device file is mounted. |
||||
The function is deprecated and not supported by uclibc and musl. |
||||
Now do the check using the *mntent functions. |
||||
|
||||
Based on patch by Natanael Copa <ncopa@alpinelinux.org>. |
||||
|
||||
Signed-off-by: Felix Janda <felix.janda@posteo.de> |
||||
Reviewed-by: Eric Sandeen <sandeen@redhat.com> |
||||
Signed-off-by: Dave Chinner <david@fromorbit.com> |
||||
|
||||
diff --git a/libxfs/linux.c b/libxfs/linux.c |
||||
index c9f2baf..44bc1f9 100644 |
||||
--- a/libxfs/linux.c |
||||
+++ b/libxfs/linux.c |
||||
@@ -16,11 +16,8 @@ |
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
||||
*/ |
||||
|
||||
-#define ustat __kernel_ustat |
||||
#include <mntent.h> |
||||
#include <sys/stat.h> |
||||
-#undef ustat |
||||
-#include <sys/ustat.h> |
||||
#include <sys/mount.h> |
||||
#include <sys/ioctl.h> |
||||
#include <sys/sysinfo.h> |
||||
@@ -51,9 +48,10 @@ static int max_block_alignment; |
||||
int |
||||
platform_check_ismounted(char *name, char *block, struct stat64 *s, int verbose) |
||||
{ |
||||
- /* Pad ust; pre-2.6.28 linux copies out too much in 32bit compat mode */ |
||||
- struct ustat ust[2]; |
||||
- struct stat64 st; |
||||
+ FILE *f; |
||||
+ struct stat64 st, mst; |
||||
+ struct mntent *mnt; |
||||
+ char mounts[MAXPATHLEN]; |
||||
|
||||
if (!s) { |
||||
if (stat64(block, &st) < 0) |
||||
@@ -63,14 +61,27 @@ platform_check_ismounted(char *name, char *block, struct stat64 *s, int verbose) |
||||
s = &st; |
||||
} |
||||
|
||||
- if (ustat(s->st_rdev, ust) >= 0) { |
||||
+ strcpy(mounts, (!access(PROC_MOUNTED, R_OK)) ? PROC_MOUNTED : MOUNTED); |
||||
+ if ((f = setmntent(mounts, "r")) == NULL) { |
||||
+ fprintf(stderr, |
||||
+ _("%s: %s possibly contains a mounted filesystem\n"), |
||||
+ progname, name); |
||||
+ return 1; |
||||
+ } |
||||
+ while ((mnt = getmntent(f)) != NULL) { |
||||
+ if (stat64(mnt->mnt_dir, &mst) < 0) |
||||
+ continue; |
||||
+ if (mst.st_dev != s->st_rdev) |
||||
+ continue; |
||||
+ |
||||
if (verbose) |
||||
fprintf(stderr, |
||||
_("%s: %s contains a mounted filesystem\n"), |
||||
progname, name); |
||||
- return 1; |
||||
+ break; |
||||
} |
||||
- return 0; |
||||
+ endmntent(f); |
||||
+ return mnt != NULL; |
||||
} |
||||
|
||||
int |
@ -0,0 +1,79 @@
@@ -0,0 +1,79 @@
|
||||
commit cbca895541facb3a1a00fd0fe6614301a64c0e3a |
||||
Author: Eric Sandeen <sandeen@redhat.com> |
||||
Date: Fri Sep 23 09:16:52 2016 +1000 |
||||
|
||||
xfs_copy: Fix meta UUID handling on multiple copies |
||||
|
||||
Zorro reported that when making multiple copies of a V5 |
||||
filesystem with xfs_copy while generating new UUIDs, all |
||||
but the first copy were corrupt. |
||||
|
||||
Upon inspection, the corruption was related to incorrect UUIDs; |
||||
the original UUID, as stamped into every metadata structure, |
||||
was not preserved in the sb_meta_uuid field of the superblock |
||||
on any but the first copy. |
||||
|
||||
This happened because sb_update_uuid was using the UUID present in |
||||
the ag_hdr structure as the unchanging meta-uuid which is to match |
||||
existing structures, but it also /updates/ that UUID with the |
||||
new identifying UUID present in tcarg. So the newly-generated |
||||
UUIDs moved transitively from tcarg->uuid to ag_hdr->xfs_sb->sb_uuid |
||||
to ag_hdr->xfs_sb->sb_meta_uuid each time the function got called. |
||||
|
||||
Fix this by looking instead to the unchanging, original UUID |
||||
present in the xfs_sb_t we are given, which reflects the original |
||||
filesystem's metadata UUID, and copy /that/ UUID into each target |
||||
filesystem's meta_uuid field. |
||||
|
||||
Most of this patch is changing comments and re-ordering tests |
||||
to match; the functional change is to simply use the *sb rather |
||||
than the *ag_hdr to identify the proper metadata UUID. |
||||
|
||||
Reported-and-tested-by: Zorro Lang <zlang@redhat.com> |
||||
Signed-off-by: Eric Sandeen <sandeen@redhat.com> |
||||
Reviewed-by: Dave Chinner <dchinner@redhat.com> |
||||
Signed-off-by: Dave Chinner <david@fromorbit.com> |
||||
|
||||
diff --git a/copy/xfs_copy.c b/copy/xfs_copy.c |
||||
index 3c8998c..22ded6b 100644 |
||||
--- a/copy/xfs_copy.c |
||||
+++ b/copy/xfs_copy.c |
||||
@@ -494,27 +494,29 @@ write_wbuf(void) |
||||
|
||||
void |
||||
sb_update_uuid( |
||||
- xfs_sb_t *sb, |
||||
- ag_header_t *ag_hdr, |
||||
- thread_args *tcarg) |
||||
+ xfs_sb_t *sb, /* Original fs superblock */ |
||||
+ ag_header_t *ag_hdr, /* AG hdr to update for this copy */ |
||||
+ thread_args *tcarg) /* Args for this thread, with UUID */ |
||||
{ |
||||
/* |
||||
* If this filesystem has CRCs, the original UUID is stamped into |
||||
- * all metadata. If we are changing the UUID in the copy, we need |
||||
- * to copy the original UUID into the meta_uuid slot and set the |
||||
- * set the incompat flag if that hasn't already been done. |
||||
+ * all metadata. If we don't have an existing meta_uuid field in the |
||||
+ * the original filesystem and we are changing the UUID in this copy, |
||||
+ * we must copy the original sb_uuid to the sb_meta_uuid slot and set |
||||
+ * the incompat flag for the feature on this copy. |
||||
*/ |
||||
- if (!uuid_equal(&tcarg->uuid, &ag_hdr->xfs_sb->sb_uuid) && |
||||
- xfs_sb_version_hascrc(sb) && !xfs_sb_version_hasmetauuid(sb)) { |
||||
+ if (xfs_sb_version_hascrc(sb) && !xfs_sb_version_hasmetauuid(sb) && |
||||
+ !uuid_equal(&tcarg->uuid, &sb->sb_uuid)) { |
||||
__be32 feat; |
||||
|
||||
feat = be32_to_cpu(ag_hdr->xfs_sb->sb_features_incompat); |
||||
feat |= XFS_SB_FEAT_INCOMPAT_META_UUID; |
||||
ag_hdr->xfs_sb->sb_features_incompat = cpu_to_be32(feat); |
||||
platform_uuid_copy(&ag_hdr->xfs_sb->sb_meta_uuid, |
||||
- &ag_hdr->xfs_sb->sb_uuid); |
||||
+ &sb->sb_uuid); |
||||
} |
||||
|
||||
+ /* Copy the (possibly new) fs-identifier UUID into sb_uuid */ |
||||
platform_uuid_copy(&ag_hdr->xfs_sb->sb_uuid, &tcarg->uuid); |
||||
|
||||
/* We may have changed the UUID, so update the superblock CRC */ |
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
From b04647edea32dbbce0fc12ea6f54a8da706a2265 Mon Sep 17 00:00:00 2001 |
||||
From: Eric Sandeen <sandeen@redhat.com> |
||||
Date: Mon, 19 Sep 2016 16:01:14 +1000 |
||||
Subject: [PATCH] xfs_repair: exit with status 2 if log dirtiness is unknown |
||||
|
||||
This new case is mostly like the known dirty log case; the log |
||||
is corrupt, dirtiness cannot be determined, and a mount/umount |
||||
cycle or an xfs_repair -L is required. |
||||
|
||||
So exit with status 2 here as well. |
||||
|
||||
Signed-off-by: Eric Sandeen <sandeen@redhat.com> |
||||
Reviewed-by: Zorro Lang <zlang@redhat.com> |
||||
Signed-off-by: Dave Chinner <david@fromorbit.com> |
||||
--- |
||||
repair/phase2.c | 3 ++- |
||||
1 file changed, 2 insertions(+), 1 deletion(-) |
||||
|
||||
Index: xfsprogs-4.5.0/repair/phase2.c |
||||
=================================================================== |
||||
--- xfsprogs-4.5.0.orig/repair/phase2.c |
||||
+++ xfsprogs-4.5.0/repair/phase2.c |
||||
@@ -79,10 +79,11 @@ zero_log( |
||||
_("zero_log: cannot find log head/tail (xlog_find_tail=%d)\n"), |
||||
error); |
||||
if (!no_modify && !zap_log) |
||||
- do_error(_( |
||||
+ do_warn(_( |
||||
"ERROR: The log head and/or tail cannot be discovered. Attempt to mount the\n" |
||||
"filesystem to replay the log or use the -L option to destroy the log and\n" |
||||
"attempt a repair.\n")); |
||||
+ exit(2); |
||||
} else { |
||||
if (verbose) { |
||||
do_log( |
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
commit 41c702ce4b2bbea59e49384a90e17c64e46bd3ae |
||||
Author: Andreas Gruenbacher <agruenba@redhat.com> |
||||
Date: Tue Nov 1 10:38:40 2016 +1100 |
||||
|
||||
xfs_io: Fix initial -m option |
||||
|
||||
Like "open -m mode", the initial -m option requires a mode argument. |
||||
|
||||
Document these options correctly as well. |
||||
|
||||
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> |
||||
Reviewed-by: Dave Chinner <dchinner@redhat.com> |
||||
Signed-off-by: Dave Chinner <david@fromorbit.com> |
||||
|
||||
Index: xfsprogs-4.5.0/io/init.c |
||||
=================================================================== |
||||
--- xfsprogs-4.5.0.orig/io/init.c |
||||
+++ xfsprogs-4.5.0/io/init.c |
||||
@@ -32,7 +32,7 @@ void |
||||
usage(void) |
||||
{ |
||||
fprintf(stderr, |
||||
- _("Usage: %s [-adfmnrRstVx] [-p prog] [-c cmd]... file\n"), |
||||
+ _("Usage: %s [-adfnrRstVx] [-m mode] [-p prog] [-c cmd]... file\n"), |
||||
progname); |
||||
exit(1); |
||||
} |
||||
@@ -139,7 +139,7 @@ init( |
||||
pagesize = getpagesize(); |
||||
gettimeofday(&stopwatch, NULL); |
||||
|
||||
- while ((c = getopt(argc, argv, "ac:dFfmp:nrRstTVx")) != EOF) { |
||||
+ while ((c = getopt(argc, argv, "ac:dFfm:p:nrRstTVx")) != EOF) { |
||||
switch (c) { |
||||
case 'a': |
||||
flags |= IO_APPEND; |
||||
Index: xfsprogs-4.5.0/io/open.c |
||||
=================================================================== |
||||
--- xfsprogs-4.5.0.orig/io/open.c |
||||
+++ xfsprogs-4.5.0/io/open.c |
||||
@@ -759,7 +759,7 @@ open_init(void) |
||||
open_cmd.argmin = 0; |
||||
open_cmd.argmax = -1; |
||||
open_cmd.flags = CMD_NOMAP_OK | CMD_NOFILE_OK | CMD_FOREIGN_OK; |
||||
- open_cmd.args = _("[-acdrstxT] [path]"); |
||||
+ open_cmd.args = _("[-acdrstxT] [-m mode] [path]"); |
||||
open_cmd.oneline = _("open the file specified by path"); |
||||
open_cmd.help = open_help; |
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
xfs_repair: junk leaf attribute if count == 0 |
||||
|
||||
We have recently seen a case where, during log replay, the |
||||
attr3 leaf verifier reported corruption when encountering a |
||||
leaf attribute with a count of 0 in the header. |
||||
|
||||
We chalked this up to a transient state when a shortform leaf |
||||
was created, the attribute didn't fit, and we promoted the |
||||
(empty) attribute to the larger leaf form. |
||||
|
||||
I've recently been given a metadump of unknown provenance which actually |
||||
contains a leaf attribute with count 0 on disk. This causes the |
||||
verifier to fire every time xfs_repair is run: |
||||
|
||||
Metadata corruption detected at xfs_attr3_leaf block 0x480988/0x1000 |
||||
|
||||
If this 0-count state is detected, we should just junk the leaf, same |
||||
as we would do if the count was too high. With this change, we now |
||||
remedy the problem: |
||||
|
||||
Metadata corruption detected at xfs_attr3_leaf block 0x480988/0x1000 |
||||
bad attribute count 0 in attr block 0, inode 12587828 |
||||
problem with attribute contents in inode 12587828 |
||||
clearing inode 12587828 attributes |
||||
correcting nblocks for inode 12587828, was 2 - counted 1 |
||||
|
||||
Signed-off-by: Eric Sandeen <sandeen@redhat.com> |
||||
Reviewed-by: Brian Foster <bfoster@redhat.com> |
||||
--- |
||||
|
||||
diff --git a/repair/attr_repair.c b/repair/attr_repair.c |
||||
index 40cb5f7..b855a10 100644 |
||||
--- a/repair/attr_repair.c |
||||
+++ b/repair/attr_repair.c |
||||
@@ -593,7 +593,8 @@ process_leaf_attr_block( |
||||
stop = xfs_attr3_leaf_hdr_size(leaf); |
||||
|
||||
/* does the count look sorta valid? */ |
||||
- if (leafhdr.count * sizeof(xfs_attr_leaf_entry_t) + stop > |
||||
+ if (!leafhdr.count || |
||||
+ leafhdr.count * sizeof(xfs_attr_leaf_entry_t) + stop > |
||||
mp->m_sb.sb_blocksize) { |
||||
do_warn( |
||||
_("bad attribute count %d in attr block %u, inode %" PRIu64 "\n"), |
||||
-- |
||||
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in |
||||
the body of a message to majordomo@vger.kernel.org |
||||
More majordomo info at http://vger.kernel.org/majordomo-info.html |
@ -0,0 +1,33 @@
@@ -0,0 +1,33 @@
|
||||
Revert, because off64_t isn't available w/o LFS defines; |
||||
upstream this needs to be handled seamlessly but we don't |
||||
want to change existing RHEL behavior for code that includes |
||||
xfs.h |
||||
|
||||
commit cb898f157f8410a03cf5f3400baa1df9e5eecd33 |
||||
Author: Felix Janda <felix.janda@posteo.de> |
||||
Date: Fri Feb 5 08:34:06 2016 +1100 |
||||
|
||||
linux.h: Use off64_t instead of loff_t |
||||
|
||||
These are equivalent on glibc, while musl does not know loff_t. |
||||
|
||||
In the long run, it would be preferable to enable transparent LFS so |
||||
that off64_t could be replaced by off_t. |
||||
|
||||
Signed-off-by: Felix Janda <felix.janda@posteo.de> |
||||
Reviewed-by: Christoph Hellwig <hch@lst.de> |
||||
Signed-off-by: Dave Chinner <david@fromorbit.com> |
||||
|
||||
diff --git a/include/linux.h b/include/linux.h |
||||
index 674717c..a7d2f85 100644 |
||||
--- a/include/linux.h |
||||
+++ b/include/linux.h |
||||
@@ -141,7 +141,7 @@ platform_discard_blocks(int fd, uint64_t start, uint64_t len) |
||||
#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ |
||||
#define EFSBADCRC EBADMSG /* Bad CRC detected */ |
||||
|
||||
-typedef off64_t xfs_off_t; |
||||
+typedef loff_t xfs_off_t; |
||||
typedef __uint64_t xfs_ino_t; |
||||
typedef __uint32_t xfs_dev_t; |
||||
typedef __int64_t xfs_daddr_t; |
Loading…
Reference in new issue