Compare commits

...

No commits in common. "c9-beta" and "c8" have entirely different histories.
c9-beta ... c8

89 changed files with 7164 additions and 1446 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/xfsprogs-6.4.0.tar.xz SOURCES/xfsprogs-5.0.0.tar.xz

View File

@ -1 +0,0 @@
04935475fff6580d7e1919bf9a19331951edf529 SOURCES/xfsprogs-6.4.0.tar.xz

View File

@ -1,174 +0,0 @@
pub ed25519 2022-05-27 [C]
4020459E58C1A52511F5399113F703E6C11CF6F0
uid Carlos Eduardo Maiolino <carlos@maiolino.me>
uid Carlos Eduardo Maiolino <cmaiolino@redhat.com>
uid Carlos Eduardo Maiolino <cem@kernel.org>
sub ed25519 2022-05-27 [A]
36C5DFE1ECA79D1D444FDD904E5621A566959599
sub ed25519 2022-05-27 [S]
FA406E206AFF7873897C6864B45618C36A24FD23
sub cv25519 2022-05-27 [E]
5AE98D09B21AFBDE62EE571EE01E05EA81B10D5C
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEYpDWzRYJKwYBBAHaRw8BAQdALRUYJSJQyHn8o9318h7Pj4KYIOPF6a+6Z13A
bBReh6C0LENhcmxvcyBFZHVhcmRvIE1haW9saW5vIDxjYXJsb3NAbWFpb2xpbm8u
bWU+iJYEExYKAD4FCwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4ACGQEWIQRAIEWe
WMGlJRH1OZET9wPmwRz28AUCYpERyAIbAQAKCRAT9wPmwRz28PBCAQDsBVWWrXVJ
CUVfRDPkjN3zIGqDI4lZO9gXztG88NODvAD/bicVG0GsxDsq1VOzSXz0NbwnrVmO
Z92IQcuqQcB3rAGJAjMEEgEIAB0WIQQrgYWRno0kiYGGne0grhaS4T3e4AUCYqDM
MAAKCRAgrhaS4T3e4EOXD/9x84x/fajZ1jCd9jB3CBGrfmchHDTpKmsgEaPh+px/
U/JGmU2ni/3mOtLH9XjBTwZ0etnF7qy+h1c01kIzxjX7J81RjneSD/t8cl0sxIlC
xGvAGFNGAAKYhNOY2qffZ2BcWkq2qlyFQxr9wG66Ir1nC6O4Mtl+8qRhLMiNlpMU
XOurcb7/SLtnvpIqCv2t/myMhJbDnxtRjdBtWElLrEB45C3CWE2AuXJ8RANogPV5
iTgbu/GQ/IPnyloYx9SUapLLK7qXzyVd/r3fCbVyX4tGxykPy0w5vkRVVXmNrdxE
kyTvjYp9MTPREiNrbSh+7V77b+VKWWth+Zd9JbKq/6+shBR6w7wEULttsToFB/dh
HjaiFp8USJHii2/NATaCREF1K5rVGJy3+xAfqZ7/GdZilpCtU7DedBwGSWmiqWt9
82XrTZIqCL66c7DfWqlvGWRFWsC6PNnaAYqboIg42lxvFmPNdEFqvu8KI5aUxBmS
v/irbVWd5bgmD4LimJRdpunnHlfu+6GUyDEXl+4VbUn9WJ0dGgdq4I71sVabznp7
4Oo7TQ8OtidSb60Z2/RRRVR2Lq8d0IM+jrXnkgSN9/i993/d5CbQ2j0w1wR1pPem
L0rSolRztOKxJ0BLzV5OrxqOVup1HoHMaspWiCO/27KpJjblzH0xbn8da62XMX7f
q4kCMwQSAQoAHRYhBFM2gMaDHkKuptozFfh/dxk0SrTrBQJioMvmAAoJEPh/dxk0
SrTrv8sP/2fyl6Ceq0RJuU/TJCfaJjCHqrnY5ilIb+Zk86wKfmN/OWO6M7iquMCH
iKzDOIkUe9H0uUD1CvZrGYRRmc8F7YtoQEXaw3DDpZeahqOj8hOGocurl9c80jkS
UUptHPjFghbTFL93eXmAw7qGNDQ1eAN1L1/7u0qytuDDhbcc+NHW1bHeOvvMLQlS
6Q4rOjDEnaayVH51tXHrMhd/wFgV7CCzd5YM/AdkSciuoewHugWAz0CcHp7uLg+f
oXGtAaBAAY8x8HRaJ180tnsLje4Oh2zmHPM2BprjDP61QOYH1S6rijgrrf/bROqU
M5YGgKbI/20b5/X7++1dgvYtbjTyj45r51dlkPCBXeoHQmqEaqh/MRcs743peY+G
EUnxO42Rkt7AgnWTzWRaYqE/eW6hWYPoYCKRW9u+RFMtayV7oF3I6/1AgtLHM0s6
Kk2GG0WPwFL/Wr1p8hUJVuBFH9xtlbpi/GruF+jB+YBwLdY8NK9GDJv0xCH3AiR4
Pou1RPXcI2gbGypJmSgVuwY3bAs8qB8qSPzj2+wEakdHl6Nmjtp/k1QewuX2IcFu
UfkLN3FY5fj64z+MU5CpScTrjpcgVT8B00SvDIvJxEq2X1CNnT2yKGX/tlb0I0ix
vzvxQ0qdW4PD2VMPktOgVMwF5IvoA0QC4hPgWWrSM+7ykdIkyit/iQIyBBABCAAd
FiEEqG5UsNXhtOCrfGQP+7dXa6fLC2sFAmKh0akACgkQ+7dXa6fLC2vrMg/3a0TK
iXo0ZL4Sr+VvwX9IHZjZiylCjklIm3b4luYKsQNwgIZcalj4tRR0O3o061rOdvnc
/8YUDZE7Tt/3PgJUGqLnZHlZZo7cCMtmEOXX405UgdWJyyDietfwMsJj7tLd4zoW
nfMVxgi5DNPAklw88FLUWhfETBACJ3KG5rrn76hZ9jqzPK/BdkItDNvB73GTKRkV
Ph7Mw36/dNiDTMumPKGBfYq2yU1+t2kR1yk8SZtA9UsUr0WFXxJ6gGJrG9XwVtxg
LTTIM2hwHs85Nlyc4wvH9ehh2OHeK0QbfgUhhCRuI9LD6DxMzuBGkRHcqTTtTxU2
DHX1MyuRoobI5myl1/K4bWhXquVOklYnWR97UPepl5rGsvuyYIkE8WRhNEX1qfoT
6ZXiJ1V29xC2GKilioFsWGhmAU94ZKgkZSqvfTrXpoiqCYPA5SkcZVqQ8Genj5Pu
LQ54Ul7wsAjwGrlr2T9z15bffCwHyWU/au4VVWUXmpfUiFzNuD5LWL+oEoc5xxCE
VqvhD0/9KDC+v8D6HuAFaIG4dWa2r/ovcjjE5SWXCYMrhqZ3lR0M0AmYjiJ2vc2b
Dl21W64PcwUCC+mxeWSMJrBlBob+JpBNtpjmZxgxcrits5bVHtOuPDPxHSX/WAVk
Y23Nql6nsaQDP6t7OfoqSc8IX7zRZWolhhKR8IkCMwQSAQgAHRYhBEvA17JEcbKh
hOr10wAOaEEZVoIVBQJiodrNAAoJEAAOaEEZVoIVO+0QAIHzndQhQH/k5J4Qu5st
MYrVgKNN8dZdEHEIetT/x/jd2NUESosKTrmSLx/l3HAz0a9EuWDz7vtQQoDUa/jd
9citadZ4mPCddi8CNYbFwTuJiPi+r5e2GthOxEiSKSNEjSb+j2Sr2RV84r5EQckr
CTad/I0po/6ewokrNwky2+SSA5sYg8qYchVhhkSYPYCxgt35mrTFl4gXFmccWn7I
PzwD+khTZI2eYmmw9+qsC3dx4kCYbBQTOpsPfV+waXHYYUXG3C/z0SqEyTIHuJUp
273BLButjmmm76TliR5UgrIocqCPw7vZYAr8htzNRyL2owFcz0j4SE6AY8cCasOO
fgGO4wS7fTkN1SsOj6gUEQJBVjCgWjXcu76cVixsGKl9i8pYkXLBE3u6yyN7oJiU
IANW9WvFQIXJpnQqDOVoaQBuTZo/eGOBf9nx+tz+akLjI//RGXh99L250JB0otus
nT+Rciy+Buf5VXpv8EZxwPmi5qLMo+lRoa5kRXGmJlP60tgXHSKcXw1MhN8WHBNi
MyKuQlnInPggY7hdMFVIVYvO8sQmGb8NqmCWdR70EEv74DOU2WlvnGMFet6De/f7
YmLV4dA4ksz8rk5sWBVE5EmaewDyw6EhkVc80xEdPtlD4V7vdbJ6L5Qba/mfRIhs
nEOlhv8sEakSDGvPfF6kyALViQIzBBMBCAAdFiEEJZs3krPW0xkhLMTc1b+f6wMT
ZToFAmKh7fwACgkQ1b+f6wMTZTrVqw//XAGNKanjoylppZRv8S5x9mGryWuTUh2C
1LEPcusOwi+o2Q5vIgkUwn/zRtmpHexi9gnUtVEf0A1Vk+39ao8Swu5Xlze8CmRV
suh0KAeF2i/CGh30FC0EYj/UoATP1k76r6vmWeXZpNZ4rOIXecXLMV5x4R7NSqk4
YJvo0hTiXou/O/CaXxcC3J/I2k2Qtt5zub6oVu+zCF6cOU4f5Q/aAN/tHUnqhcDY
d3OP9hO/VliQ1xrVDnx9kQ4SRTdrXKFBJLMkO1h+CA5ad9OUTFsuq87R7+qspt/z
jngY6X41HDm5jLRxgZMId5k+XHEqfbiMg6Z7uiKXbXsgCd8AP8vcizAPn8JnSa2n
erL7bz4UAQhZ7JBqEnKSIFiO+Gba0h8lwsvNKPPLFiNXZNCL78q05jk4q28HMZn3
m0qWCcJq7bZy6wmPchUFsy0uDbLYnYbyqP53UgZGUZSY+XAIgLa8rgkceGMm8jhc
qjd22c6yNSZ1z11Vzbu5rtVAK91/7iisBKHbnLWYozYxlApo4zASv7XsL9cms8Ey
94Gm4UKdCTzjtgqsKpBZkerCkZTRdC5Um/SROKsUcFh2/xZoypUJMMTvCMyzJHKs
7iTXCqlivKMR2etHTOJllMLLErTCi7iKs9HtTC+bu1hanzEHaC5DmtvZkOdZQPGT
oZKn1eB+P9SJATMEEAEIAB0WIQQl9ZRfhSpnjHU7bCLFI/EKLZ0DWgUCYqNERAAK
CRDFI/EKLZ0DWtaIB/9qt9xa7q3zJl6d71kuBU1UuJgrTk6VcX81UzI5UJ/3QMEg
CdGHqhzmggEiFnkpWsxgvgCAUrG0U7xBv3i1ZRHRJ+LqYaDOxNKEQ6cuxZpQKCFw
ECt6063qCzoViSK85rwdnBgfAGZTiwnyhy+05rlwPVof8omZx0wu+CXUFhAWYfxx
IYeHCCMa/0oMret8Se/kwHhwULClxese2CDtCrZYjG23W+NXuGtehZUaP+MAFz6c
dfqFhHU6YBKwS4kA0SrnwPvUplQ59Cybt2ZnGE+E2mFrDmWxSU0XjyqtcN20e9Qi
I1YEUzaqnM3795rQ2M0ojCSCyMe9fCU/JW7PEUletC5DYXJsb3MgRWR1YXJkbyBN
YWlvbGlubyA8Y21haW9saW5vQHJlZGhhdC5jb20+iJMEExYKADsCGwMFCwkIBwIC
IgIGFQoJCAsCBBYCAwECHgcCF4AWIQRAIEWeWMGlJRH1OZET9wPmwRz28AUCYpEQ
cwAKCRAT9wPmwRz28MxzAP48BnMnktHxFcO4KMe6mjjwNuGV0Nfz2w5qs5KUzc0i
zAD/c1zW1wOIes86mZZU8oPtCeRRjtcPKqOQ2d61uAM55ACJAjMEEgEIAB0WIQQr
gYWRno0kiYGGne0grhaS4T3e4AUCYqDMMAAKCRAgrhaS4T3e4NjzEACZA7iziscG
HRTQkviyyd4hqpWaUXNG7S+6NAWfmbTXQYHQNN9LnMjKZ7S3xAilOdtNDR4pQsU+
fj+++mbZ5cD41ey0/bAatdExgg2DwJ0LE89aWd6yIrayBs+fCWg/AAtuL94plORk
/yjziM1Qn9eUiXO8+ttxbMinKevbdPuTp7dmXUuzVe2vZANp7qfssGJR32wMrZHG
40p6YVqyw5CHd1ObU+uAXHJ7KSjx2D658jMvneoo6Zd2h5GmfnCYjyhAGuOzq9UC
4JhzBQWRuf1j3YkzR2I0K5jLC/LsVAfp7F6llhHckH2GPM0urjWQXUgmyLWQJ1NM
u/Je8vmXK7Pb4j+K8jWO4qrfIFISqCw2qXV0Txz+LcjMu6wLxvdnSbp5LzZGMw52
rGF6UFAhibiaFO+Ydpp/rC/cyZPI9QK0Gt7IIclKUFL6kDE9pFa1HyBlY2X36lfa
WCjnKF/grssL76XNOEQO9VVmlp1Gf24FYkLgGkmh6/EwyIu+CBSdUtz9TGEwPcn8
mJK4fdjo0dHz//+nBIlhmkApnSiCVFVEAiuygK1qUTyzOnK1gcELzzwiscsWinxL
yiiTYatQhAeOMCZRWDvtd+aPruyv0Tj6sPlbwbJrwXgWm2kskLsbJ7lxw+MpyX47
oG4l4E+lzDwQNKSzEA3TLmnbecWjT9AzOIkCMgQSAQoAHRYhBFM2gMaDHkKuptoz
Ffh/dxk0SrTrBQJioMvmAAoJEPh/dxk0SrTrPOUP+ItH661bW7yY7qiZcPq+X59m
77ML5l2po52yhDIvxwNFx3DUBeeADXEHgbd1qcUTULvWq6j/974UzsjXejfiIDNC
g0RFJUMIBAE2XKUNXUWgS1O5fpuz+A47NqFPGV0rFGgJwSCmxYDY8bmtMK2OtS2r
GKixzfqm8SRPsqFY5sIwv4f7Ml2XlH3BA3ppIYnVz4TdTd3XPSMe2vOnsYrHA62M
zELnog1UMU/Y6T6OwBnHRZm2gxkBEzJqFrvCAnjPkj7mlZtRK+w0MnSstoVhY520
am+Zld7ZJ9FgPaAfPg+dNlDj0beHo7T8avbjoUwoZKgjVE5lgWyS0IoXE5Pln+iZ
y3GSHIV2c9D9BNUw/whCvt2PUBD9zJDI0J+h32L3J+qomrm/k2jEjNoX4YWL3y00
/mK0lDpig54/w41743lYSjKEcS/F/i64XFwlT01XujQzM+cihW/a76CR1EwHsVRy
UAm3C4XmFpol2i2Vyjq6XXTGzuRjZRwG7lGVdAAjppzkMbc7zj46o3D6t+OsGw0R
yMDedW51gTE8M6KteODuADYHrceHRLfczht54m+4W+g42/Oy/GG/rrSM2EZ+peQU
rAYaZmI/V1cj1dYSu8vJw4Umj2TiP20+SBhjF5GXmAbfsOkKhLOA3IDKL5krScYU
6D7Mr3uUVCFheFppX4eJAjMEEAEIAB0WIQSoblSw1eG04Kt8ZA/7t1drp8sLawUC
YqHRsgAKCRD7t1drp8sLa2deD/4q6oIrUKAyZqPeuRqNqvpWynBkoGA7zF7cDd4z
CANSdVXAMXEz92yqan1QKoxHaoyom7G33o0gJci2yoHU2NxZuIvLs/o1ejIh4xE8
kfncRT/OvJIlBCm13SEG8oFjkz1xwZfbrpckYX9IRO/4Zcwc7C1NipDYgbK11bT4
pF5mIQGkYA7M4lOLlqWfkBaJ+t+cOHpbL0KWvnw6GV67Pbn0P2SInNs71iKWjrWM
OIPmxi3YfLR0BcNiz7CD8hCsRrOnOlKsm/FNkuKFt0H78nNvXPOjw9e8j8Mu7ByN
D6ZGsYUfmK8wzIPN5DQ5gar4GxbTKU0WoZgdLgXTegCnAnDAf7aGyIXTvPgMzcwP
hOaeZCFU6eC7McuLLGFL8QWR6P/JgfT53Zr1a5j7haQBPBNhoZTOvZE58cDF4AEq
SGZwtvnTs993DswGfQqUH9jNzZv0IK3y4heOOC7sCqPoFowVVxPHYX20jjUdTERc
cv+q2axQrF1Jp/XGk+J7g/uFCN+vlcymqr6reLuoJqp8VJIYkIRinq74m2s/K7SP
KxCAkaWgC5zvP1PZo73BbaRBiJR6B+wEKaRZLCuzlyCjqpl4Xyo9voJRFjVbRGSJ
pcwdiZKLrP45jwIfsK2OxoyxbwHjoqTwSpa6w+U87c/v2j6HorBbZnfSVQE9d1WL
83GrJIkCMwQSAQgAHRYhBEvA17JEcbKhhOr10wAOaEEZVoIVBQJiodrUAAoJEAAO
aEEZVoIVpXkQAIlc/NZPYlSc6yyof7rpYW8vuhekphszYut48dwr4rcyxkQX3oRP
9mNOT5NiO+O7Yfzr2ZC1v48RhjIz4jXbxHMEraH6W+/+Yh+F3bt8HBZIeLNm47R8
dqji8I6koveJoIcC2ljVmPg5nIo1drUy1WGUgHy5tIW7YcF+eQpg+PPUjQPKTJdD
3aC40L4jBM78BnhAZ9+RocjRP+O7XN3FVlnfQdjbGV4l/HuWhf6kmq7MlPkptDBe
Q7QsVa33sv+GQf714FOxPH7/+N1pCn9OcH4Vew7FaWw45lvPX6GVWiXmBUDmGlLt
jmNSRx85AFFSid8Si9tOQaKt8kzUCBQZMxoqOkrPwgEqmjJORl8WVlsCgKqX6AzZ
8fiE/H7TIgg3PYGp7VwH3R5AfW45Ign1yP0Re5ehC8LJjOyMxybCzINWqP5BL4oP
DZNxmWJcLj5KELRVE4yoslGJG2ZCckksCH550sgZlCbslWg2pgc9Oy88Mkt/6JBx
FL4TGuVa/LXhUkiRCNMLf1hPpqV6/gyImYVw0geozGoK6L1W33DGlCxyQuJQly5D
9etWvcfiOrptjnlee8h5jCTyAq2BNVXNVOQj+dZtf0c4MpZehrQfypClX99bG0I6
jNWr7n7UzRXbNqTjewNA9AcvM1exHwCE9LN4j4XryewVogAcCu/rEsPNiQIzBBMB
CAAdFiEEJZs3krPW0xkhLMTc1b+f6wMTZToFAmKh7f0ACgkQ1b+f6wMTZTqn5BAA
v5MgSuJxK8Im8sFWihJmeacpeVFQxYwL5CCmLPhM6VgLk5T5Bj5HnNydP9iPjqFo
sMWvoHZ8AuSJ84X8xHohq7VSBjtfI+j7cLiQc8RCE5J/gTNsz3Hio5vZy0Glh0/V
WR7rpEMdUVsttBSWSicsYXy5lJTFoxxp5w8tzehFiQStlIngdp7EDe71o+1UPM5X
WH/TOisRaJu3ezYIHxzS3aXAAQIFiyJrhn4IG8XZr/LqPgZEAqtjd53qr0QHf3fT
SyPToGNJEPSajibhSzP9ILuH0sTPg1JS0WGjjeOubDrNKx+v8558wlVs4LPPcjBk
vn8zJwnY28CFYvumbVGJooQ5b7WkAE8eLEEuJtXifyK4RBEFIYgLtVEPhWSykAnQ
NI3YFcbiVUm9CK7cTUJZseLHqA3zjOcFLPA3Ovng/PIumiBh+HMGiTDsGP1FgeAC
TjGFYbQiSbmUS5Ywe4kwhfHx5hC4bPtRIiRu8vQcahXRLOb/M9UBFV1TL+l51jy9
8xjhSMeXjXWJQ+74sn1H0bQYgU07hKk1OzNRJKKxGbp3lcUuW3FG8d8xamsjbuhh
YAym9mqMbQ6zie1uLyrl5AnjwmwSHO8Dw0ySlDJwdVB3WMSJEOQEiFanHd+ch+mV
AUnYac/917Qtl2CXL2j7kignxHV0g5C7MeCubKrAujSJATMEEAEIAB0WIQQl9ZRf
hSpnjHU7bCLFI/EKLZ0DWgUCYqNERQAKCRDFI/EKLZ0DWoGuB/9HuNS6hoqrJ1p1
pQFFpILirDXPKWadvDT2M/QmNq0dsDja1OT7AW5wDhOz4lROlE4L4JxxfBkWh4kr
NaChnGr9rkqt0fKpxDtHGwtzNM0UJcrYZtVpF2k+wdp0KFVo9Acjlb18lJR+jkwo
m3b3+uIfkF6TMU4hzz/TAnzjq0pwK6uHPFyc48XffXtk5xaINzcFMpdkOED86dfj
Av1vbBDLqD3k2CiLpJOOZ677pRnoTHxDv0VwHu32q4IQck+gU+q3xJXFPtJ9++M8
LHPL7Bj5c0AEsgxXIa1kLZXbuHcgxx3bJ1R1IGf7SUTwoe1IRe8MED3oDlqxH9n3
rMm5dpT5tChDYXJsb3MgRWR1YXJkbyBNYWlvbGlubyA8Y2VtQGtlcm5lbC5vcmc+
iJMEExYKADsWIQRAIEWeWMGlJRH1OZET9wPmwRz28AUCYqh7RQIbAQULCQgHAgIi
AgYVCgkICwIEFgIDAQIeBwIXgAAKCRAT9wPmwRz28IFHAP9VLxxFNn2qyEbli9lf
vOpACRPt5l8Go+ESjcY95NSx+wEA7WSeImb3zxdbuY7/RwHtpvbI9irRkRuagkzN
ZHRr1gm4MwRikOWbFgkrBgEEAdpHDwEBB0BSjwUNPerAlVvTQrWyCpizN5rM/XcO
djbJQ93oGMOr8oh4BBgWCgAgFiEEQCBFnljBpSUR9TmRE/cD5sEc9vAFAmKQ5ZsC
GyAACgkQE/cD5sEc9vAaZAEAkmjdywpS4+NumIgelWw297pBIs3d2A9zz1vMQAX6
lNsA/jah5B7M8eVpze4weTuoDp5bagM+PCTiGZ1REPQlZ+oJuDMEYpDloxYJKwYB
BAHaRw8BAQdAzioYD3NyX1Tpdd33vXEI+G8KQWrxVqfkAgKKB/aAKPKI7wQYFgoA
IBYhBEAgRZ5YwaUlEfU5kRP3A+bBHPbwBQJikOWjAhsCAIEJEBP3A+bBHPbwdiAE
GRYKAB0WIQT6QG4gav94c4l8aGS0VhjDaiT9IwUCYpDlowAKCRC0VhjDaiT9I9Ck
AQDaUcr2BDm7wheWX8bJ98Er92zJr03/i3xmJW/87th18gEAvsO0OhK3D2p+Kq0g
2vV2mgyRxK8loYs8o/00NYSbsQla6gEA4rnkGRQR3v4MByijGhq1ljaPMTQbILiT
PbUqA3k1tssBAIDzUC7pDWJaWiJ2yDTVhBBvM+y+MnoJV5DqTt/L+KMHuDgEYpDm
YBIKKwYBBAGXVQEFAQEHQNoBmGzRsHk6qWKBPtnr6vlO7ABo/HvkeoLUUZU2r/Q9
AwEIB4h4BBgWCgAgFiEEQCBFnljBpSUR9TmRE/cD5sEc9vAFAmKQ5mACGwwACgkQ
E/cD5sEc9vC+xAD/fgk/sVQrkfgur7ZvjsovfrjHbHC4tWeg3V8YVHIOdcoA/1Qt
oTLMZzwt7Ckd+vFGfqSSs5D1FMmwaE4Z/WVoqPkD
=n3Wp
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -1,9 +0,0 @@
# This is a sample mkfs.xfs config file that creates rhel-8 compatible
# XFS filesystem on rhel-9
# Usage:
# mkfs.xfs -c options=rhel8.0.conf device
#
[metadata]
inobtcount=0
bigtime=0

View File

@ -0,0 +1,74 @@
Index: xfsprogs-4.19.0/mkfs/xfs_mkfs.c
===================================================================
--- xfsprogs-4.19.0.orig/mkfs/xfs_mkfs.c
+++ xfsprogs-4.19.0/mkfs/xfs_mkfs.c
@@ -1973,15 +1973,15 @@ _("Directory ftype field always enabled
usage();
}
- } else {
+ } else { /* !crcs_enabled */
/*
- * The kernel doesn't currently support crc=0,finobt=1
- * filesystems. If crcs are not enabled and the user has not
- * explicitly turned finobt on, then silently turn it off to
- * avoid an unnecessary warning.
+ * The kernel doesn't support crc=0,finobt=1 filesystems.
+ * If crcs are not enabled and the user has not explicitly
+ * turned finobt on, then silently turn it off to avoid an
+ * unnecessary warning.
* If the user explicitly tried to use crc=0,finobt=1,
* then issue an error.
- * The same is also for sparse inodes.
+ * The same is also true for sparse inodes and reflink.
*/
if (cli->sb_feat.finobt && cli_opt_set(&mopts, M_FINOBT)) {
fprintf(stderr,
@@ -2004,7 +2004,7 @@ _("rmapbt not supported without CRC supp
}
cli->sb_feat.rmapbt = false;
- if (cli->sb_feat.reflink) {
+ if (cli->sb_feat.reflink && cli_opt_set(&mopts, M_REFLINK)) {
fprintf(stderr,
_("reflink not supported without CRC support\n"));
usage();
@@ -3788,7 +3788,7 @@ main(
.finobt = true,
.spinodes = true,
.rmapbt = false,
- .reflink = false,
+ .reflink = true,
.parent_pointers = false,
.nodalign = false,
.nortalign = false,
Index: xfsprogs-4.19.0/man/man8/mkfs.xfs.8
===================================================================
--- xfsprogs-4.19.0.orig/man/man8/mkfs.xfs.8
+++ xfsprogs-4.19.0/man/man8/mkfs.xfs.8
@@ -229,9 +229,9 @@ mapping will be changed to the new block
enables the creation of per-file snapshots and deduplication. It is only
available for the data forks of regular files.
.IP
-By default,
+By default in Red Hat Enterprise Linux 8,
.B mkfs.xfs
-will not create reference count btrees and therefore will not enable the
+will create reference count btrees and therefore will enable the
reflink feature. This feature is only available for filesystems created with
the (default)
.B \-m crc=1
@@ -239,6 +239,13 @@ option set. When the option
.B \-m crc=0
is used, the reference count btree feature is not supported and reflink is
disabled.
+.IP
+Note: the filesystem DAX mount option (
+.B \-o dax
+) is incompatible with
+reflink-enabled XFS filesystems. To use filesystem DAX with XFS, specify the
+.B \-m reflink=0
+option to mkfs.xfs to disable the reflink feature.
.RE
.TP
.BI \-d " data_section_options"

View File

@ -0,0 +1,106 @@
From b192e77cc38473964c718bd035502b702c6a6e34 Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sandeen@redhat.com>
Date: Tue, 21 May 2019 11:03:43 -0500
Subject: [PATCH] libxfs: create current_time helper and sync
xfs_trans_ichgtime
Make xfs_trans_ichgtime() almost match kernelspace by creating a
new current_time() helper to match the kernel utility.
This reduces still more cosmetic change. We may want to sync the
creation flag over to the kernel even though it's not used today.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/include/xfs_inode.h b/include/xfs_inode.h
index 52d79f3..76f9ac7 100644
--- a/include/xfs_inode.h
+++ b/include/xfs_inode.h
@@ -16,6 +16,16 @@ struct xfs_mount;
struct xfs_inode_log_item;
struct xfs_dir_ops;
+/*
+ * These are not actually used, they are only for userspace build
+ * compatibility in code that looks at i_state
+ */
+#define I_DIRTY_TIME 0
+#define I_DIRTY_TIME_EXPIRED 0
+
+#define IS_I_VERSION(inode) (0)
+#define inode_maybe_inc_iversion(inode,flags) (0)
+
/*
* Inode interface. This fakes up a "VFS inode" to make the xfs_inode appear
* similar to the kernel which now is used tohold certain parts of the on-disk
@@ -25,6 +35,7 @@ struct inode {
mode_t i_mode;
uint32_t i_nlink;
xfs_dev_t i_rdev; /* This actually holds xfs_dev_t */
+ unsigned long i_state; /* Not actually used in userspace */
uint32_t i_generation;
uint64_t i_version;
struct timespec i_atime;
@@ -150,6 +161,9 @@ extern void libxfs_trans_ichgtime(struct xfs_trans *,
struct xfs_inode *, int);
extern int libxfs_iflush_int (struct xfs_inode *, struct xfs_buf *);
+#define timespec64 timespec
+extern struct timespec64 current_time(struct inode *inode);
+
/* Inode Cache Interfaces */
extern bool libxfs_inode_verify_forks(struct xfs_inode *ip);
extern int libxfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
diff --git a/libxfs/util.c b/libxfs/util.c
index 9fe9a36..951f7cf 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -136,11 +136,21 @@ xfs_log_calc_unit_res(
return unit_bytes;
}
+struct timespec64
+current_time(struct inode *inode)
+{
+ struct timespec64 tv;
+ struct timeval stv;
+
+ gettimeofday(&stv, (struct timezone *)0);
+ tv.tv_sec = stv.tv_sec;
+ tv.tv_nsec = stv.tv_usec * 1000;
+
+ return tv;
+}
+
/*
* Change the requested timestamp in the given inode.
- *
- * This was once shared with the kernel, but has diverged to the point
- * where it's no longer worth the hassle of maintaining common code.
*/
void
libxfs_trans_ichgtime(
@@ -148,12 +158,14 @@ libxfs_trans_ichgtime(
struct xfs_inode *ip,
int flags)
{
- struct timespec tv;
- struct timeval stv;
+ struct inode *inode = VFS_I(ip);
+ struct timespec64 tv;
+
+ ASSERT(tp);
+ ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+
+ tv = current_time(inode);
- gettimeofday(&stv, (struct timezone *)0);
- tv.tv_sec = stv.tv_sec;
- tv.tv_nsec = stv.tv_usec * 1000;
if (flags & XFS_ICHGTIME_MOD)
VFS_I(ip)->i_mtime = tv;
if (flags & XFS_ICHGTIME_CHG)

View File

@ -0,0 +1,60 @@
From 9c726ef0d2d829ae83756d3817f271e9c2c8777a Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sandeen@redhat.com>
Date: Wed, 10 Jul 2019 11:35:07 -0400
Subject: [PATCH] mkfs: don't use xfs_verify_fsbno() before m_sb is fully set
up
Commit 8da5298 mkfs: validate start and end of aligned logs stopped
open-coding log end block checks, and used xfs_verify_fsbno() instead.
It also used xfs_verify_fsbno() to validate the log start. This
seemed to make sense, but then xfs/306 started failing on 4k sector
filesystems, which leads to a log striep unite being set on a single
AG filesystem.
As it turns out, if xfs_verify_fsbno() is testing a block in the
last AG, it needs to have mp->m_sb.sb_dblocks set, which isn't done
until later. With sb_dblocks unset we can't know how many blocks
are in the last AG, and hence can't validate it.
To fix all this, go back to open-coding the checks; note that this
/does/ rely on m_sb.sb_agblklog being set, but that /is/ already
done in the early call to start_superblock_setup().
Fixes: 8da5298 ("mkfs: validate start and end of aligned logs")
Reported-by: Dave Chinner <david@fromorbit.com>
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>
---
mkfs/xfs_mkfs.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 468b8fde..4e576a5c 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -3040,7 +3040,7 @@ align_internal_log(
cfg->logstart = ((cfg->logstart + (sunit - 1)) / sunit) * sunit;
/* If our log start overlaps the next AG's metadata, fail. */
- if (!xfs_verify_fsbno(mp, cfg->logstart)) {
+ if (XFS_FSB_TO_AGBNO(mp, cfg->logstart) <= XFS_AGFL_BLOCK(mp)) {
fprintf(stderr,
_("Due to stripe alignment, the internal log start (%lld) cannot be aligned\n"
"within an allocation group.\n"),
@@ -3051,10 +3051,9 @@ _("Due to stripe alignment, the internal log start (%lld) cannot be aligned\n"
/* round up/down the log size now */
align_log_size(cfg, sunit);
- /* check the aligned log still fits in an AG. */
+ /* check the aligned log still starts and ends in the same AG. */
logend = cfg->logstart + cfg->logblocks - 1;
- if (XFS_FSB_TO_AGNO(mp, cfg->logstart) != XFS_FSB_TO_AGNO(mp, logend) ||
- !xfs_verify_fsbno(mp, logend)) {
+ if (XFS_FSB_TO_AGNO(mp, cfg->logstart) != XFS_FSB_TO_AGNO(mp, logend)) {
fprintf(stderr,
_("Due to stripe alignment, the internal log size (%lld) is too large.\n"
"Must fit within an allocation group.\n"),
--
2.17.0

View File

@ -0,0 +1,52 @@
From 8da52988ad210958f21c178620bb1e44f1188cd0 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Tue, 25 Jun 2019 17:04:42 -0400
Subject: [PATCH] mkfs: validate start and end of aligned logs
Validate that the start and end of the log stay within a single AG if
we adjust either end to align to stripe units.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
mkfs/xfs_mkfs.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index ddb25ecc..468b8fde 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -3033,15 +3033,28 @@ align_internal_log(
struct xfs_mount *mp,
int sunit)
{
+ uint64_t logend;
+
/* round up log start if necessary */
if ((cfg->logstart % sunit) != 0)
cfg->logstart = ((cfg->logstart + (sunit - 1)) / sunit) * sunit;
+ /* If our log start overlaps the next AG's metadata, fail. */
+ if (!xfs_verify_fsbno(mp, cfg->logstart)) {
+ fprintf(stderr,
+_("Due to stripe alignment, the internal log start (%lld) cannot be aligned\n"
+ "within an allocation group.\n"),
+ (long long) cfg->logstart);
+ usage();
+ }
+
/* round up/down the log size now */
align_log_size(cfg, sunit);
/* check the aligned log still fits in an AG. */
- if (cfg->logblocks > cfg->agsize - XFS_FSB_TO_AGBNO(mp, cfg->logstart)) {
+ logend = cfg->logstart + cfg->logblocks - 1;
+ if (XFS_FSB_TO_AGNO(mp, cfg->logstart) != XFS_FSB_TO_AGNO(mp, logend) ||
+ !xfs_verify_fsbno(mp, logend)) {
fprintf(stderr,
_("Due to stripe alignment, the internal log size (%lld) is too large.\n"
"Must fit within an allocation group.\n"),
--
2.17.0

View File

@ -0,0 +1,42 @@
From 59cf967983f6aaff4ce33a50135ae57032ebd8f2 Mon Sep 17 00:00:00 2001
From: Allison Collins <allison.henderson@oracle.com>
Date: Wed, 10 Jul 2019 11:38:04 -0400
Subject: [PATCH] xfsprogs: Fix uninitialized cfg->lsunit
While investigating another mkfs bug, noticed that cfg->lsunit is sometimes
left uninitialized when it should not. This is because calc_stripe_factors
in some cases needs cfg->loginternal to be set first. This is done in
validate_logdev. So move calc_stripe_factors below validate_logdev while
parsing configs.
Signed-off-by: Allison Collins <allison.henderson@oracle.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
mkfs/xfs_mkfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 79377b12..65cf1e0f 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -4007,7 +4007,6 @@ main(
cfg.rtblocks = calc_dev_size(cli.rtsize, &cfg, &ropts, R_SIZE, "rt");
validate_rtextsize(&cfg, &cli, &ft);
- calc_stripe_factors(&cfg, &cli, &ft);
/*
* Open and validate the device configurations
@@ -4017,6 +4016,7 @@ main(
validate_datadev(&cfg, &cli);
validate_logdev(&cfg, &cli, &logfile);
validate_rtdev(&cfg, &cli, &rtfile);
+ calc_stripe_factors(&cfg, &cli, &ft);
/*
* At this point when know exactly what size all the devices are,
--
2.17.0

View File

@ -0,0 +1,81 @@
From bf6d4cf988176ad7efd0089830bfbf200a5e0196 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 20 Nov 2020 17:03:27 -0500
Subject: [PATCH] libfrog: convert cvttime to return time64_t
Change the cvttime function to return 64-bit time values so that we can
put them to use with the bigtime feature.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/include/convert.h b/include/convert.h
index 0489a1d..2b427df 100644
--- a/include/convert.h
+++ b/include/convert.h
@@ -16,7 +16,7 @@ extern uint16_t cvt_u16(char *s, int base);
extern long long cvtnum(size_t blocksize, size_t sectorsize, char *s);
extern void cvtstr(double value, char *str, size_t sz);
-extern unsigned long cvttime(char *s);
+extern time64_t cvttime(char *s);
extern uid_t uid_from_string(char *user);
extern gid_t gid_from_string(char *group);
diff --git a/libfrog/convert.c b/libfrog/convert.c
index ed4cae7..209b874 100644
--- a/libfrog/convert.c
+++ b/libfrog/convert.c
@@ -267,14 +267,14 @@ cvtstr(
#define DAYS_TO_SECONDS(d) ((d) * HOURS_TO_SECONDS(24))
#define WEEKS_TO_SECONDS(w) ((w) * DAYS_TO_SECONDS(7))
-unsigned long
+time64_t
cvttime(
char *s)
{
- unsigned long i;
+ time64_t i;
char *sp;
- i = strtoul(s, &sp, 0);
+ i = strtoll(s, &sp, 0);
if (i == 0 && sp == s)
return 0;
if (*sp == '\0')
diff --git a/quota/edit.c b/quota/edit.c
index 01d358f..b3cad02 100644
--- a/quota/edit.c
+++ b/quota/edit.c
@@ -419,13 +419,13 @@ restore_f(
static void
set_timer(
- uint32_t id,
- uint type,
- uint mask,
- char *dev,
- uint value)
+ uint32_t id,
+ uint type,
+ uint mask,
+ char *dev,
+ time64_t value)
{
- fs_disk_quota_t d;
+ struct fs_disk_quota d;
memset(&d, 0, sizeof(d));
@@ -476,7 +476,7 @@ timer_f(
int argc,
char **argv)
{
- uint value;
+ time64_t value;
char *name = NULL;
uint32_t id = 0;
int c, flags = 0, type = 0, mask = 0;

View File

@ -0,0 +1,61 @@
From 0160c1490d4b49889c9ed01a39f760cba762eac5 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 20 Nov 2020 17:03:28 -0500
Subject: [PATCH] libfrog: list the bigtime feature when reporting geometry
When we're reporting on a filesystem's geometry, report if the bigtime
feature is enabled on this filesystem.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/libfrog/fsgeom.c b/libfrog/fsgeom.c
index 8879d16..ddacd59 100644
--- a/libfrog/fsgeom.c
+++ b/libfrog/fsgeom.c
@@ -25,6 +25,7 @@ xfs_report_geom(
int spinodes;
int rmapbt_enabled;
int reflink_enabled;
+ int bigtime_enabled;
isint = geo->logstart > 0;
lazycount = geo->flags & XFS_FSOP_GEOM_FLAGS_LAZYSB ? 1 : 0;
@@ -40,12 +41,13 @@ xfs_report_geom(
spinodes = geo->flags & XFS_FSOP_GEOM_FLAGS_SPINODES ? 1 : 0;
rmapbt_enabled = geo->flags & XFS_FSOP_GEOM_FLAGS_RMAPBT ? 1 : 0;
reflink_enabled = geo->flags & XFS_FSOP_GEOM_FLAGS_REFLINK ? 1 : 0;
+ bigtime_enabled = geo->flags & XFS_FSOP_GEOM_FLAGS_BIGTIME ? 1 : 0;
printf(_(
"meta-data=%-22s isize=%-6d agcount=%u, agsize=%u blks\n"
" =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n"
" =%-22s crc=%-8u finobt=%u, sparse=%u, rmapbt=%u\n"
-" =%-22s reflink=%u\n"
+" =%-22s reflink=%-4u bigtime=%u\n"
"data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n"
" =%-22s sunit=%-6u swidth=%u blks\n"
"naming =version %-14u bsize=%-6u ascii-ci=%d, ftype=%d\n"
@@ -55,7 +57,7 @@ xfs_report_geom(
mntpoint, geo->inodesize, geo->agcount, geo->agblocks,
"", geo->sectsize, attrversion, projid32bit,
"", crcs_enabled, finobt_enabled, spinodes, rmapbt_enabled,
- "", reflink_enabled,
+ "", reflink_enabled, bigtime_enabled,
"", geo->blocksize, (unsigned long long)geo->datablocks,
geo->imaxpct,
"", geo->sunit, geo->swidth,
diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index 00f367e..a0452c2 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -115,6 +115,7 @@
#define xfs_calc_dquots_per_chunk libxfs_calc_dquots_per_chunk
#define xfs_dquot_verify libxfs_dquot_verify
#define xfs_dqblk_repair libxfs_dqblk_repair
+#define xfs_dquot_from_disk_ts libxfs_dquot_from_disk_ts
#define xfs_symlink_blocks libxfs_symlink_blocks
#define xfs_symlink_hdr_ok libxfs_symlink_hdr_ok

View File

@ -0,0 +1,89 @@
From ec24f6fa05f695af02b4e0fca5bc27cb1cab49b7 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Tue, 10 Nov 2020 12:05:32 -0500
Subject: [PATCH] libxfs: create a real struct timespec64
Create a real struct timespec64 that supports 64-bit seconds counts.
The C library struct timespec doesn't support this on 32-bit
architectures and we cannot lose the upper bits in the incore inode.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/include/libxfs.h b/include/libxfs.h
index 731561c..2bdef70 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -36,8 +36,6 @@ extern uint32_t crc32c_le(uint32_t crc, unsigned char const *p, size_t len);
#include "xfs_cksum.h"
-#define timespec64 timespec
-
/*
* This mirrors the kernel include for xfs_buf.h - it's implicitly included in
* every files via a similar include in the kernel xfs_linux.h.
diff --git a/include/xfs_inode.h b/include/xfs_inode.h
index e03d1cb..ddd48be 100644
--- a/include/xfs_inode.h
+++ b/include/xfs_inode.h
@@ -32,15 +32,15 @@ struct xfs_dir_ops;
* metadata.
*/
struct inode {
- mode_t i_mode;
- uint32_t i_nlink;
- xfs_dev_t i_rdev; /* This actually holds xfs_dev_t */
- unsigned long i_state; /* Not actually used in userspace */
- uint32_t i_generation;
- uint64_t i_version;
- struct timespec i_atime;
- struct timespec i_mtime;
- struct timespec i_ctime;
+ mode_t i_mode;
+ uint32_t i_nlink;
+ xfs_dev_t i_rdev; /* This actually holds xfs_dev_t */
+ unsigned long i_state; /* Not actually used in userspace */
+ uint32_t i_generation;
+ uint64_t i_version;
+ struct timespec64 i_atime;
+ struct timespec64 i_mtime;
+ struct timespec64 i_ctime;
};
typedef struct xfs_inode {
diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h
index 8232f89..b45d07e 100644
--- a/libxfs/libxfs_priv.h
+++ b/libxfs/libxfs_priv.h
@@ -62,8 +62,6 @@ extern kmem_zone_t *xfs_buf_zone;
extern kmem_zone_t *xfs_inode_zone;
extern kmem_zone_t *xfs_trans_zone;
-#define timespec64 timespec
-
/* CRC stuff, buffer API dependent on it */
#define crc32c(c,p,l) crc32c_le((c),(unsigned char const *)(p),(l))
diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index c8a3b12..fbc9031 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -686,6 +686,14 @@ struct xfs_extent_data {
#define XFS_IOC_CLONE_RANGE _IOW (0x94, 13, struct xfs_clone_args)
#define XFS_IOC_FILE_EXTENT_SAME _IOWR(0x94, 54, struct xfs_extent_data)
+/* 64-bit seconds counter that works independently of the C library time_t. */
+typedef long long int time64_t;
+
+struct timespec64 {
+ time64_t tv_sec; /* seconds */
+ long tv_nsec; /* nanoseconds */
+};
+
#ifndef HAVE_BBMACROS
/*
* Block I/O parameterization. A basic block (BB) is the lowest size of

View File

@ -0,0 +1,53 @@
From c0e580154e1469f1bcef132b1a7585409f66e1e5 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Tue, 10 Nov 2020 14:52:31 -0500
Subject: [PATCH] libxfs: refactor NSEC_PER_SEC
Clean up all the open-coded and duplicate definitions of time unit
conversion factors.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
NOTE: scrub is not present in rhel8, so that hunk is omitted
diff --git a/include/platform_defs.h.in b/include/platform_defs.h.in
index d111ec6..0b7214e 100644
--- a/include/platform_defs.h.in
+++ b/include/platform_defs.h.in
@@ -77,4 +77,7 @@ typedef unsigned short umode_t;
# define ASSERT(EX) ((void) 0)
#endif
+#define NSEC_PER_SEC (1000000000ULL)
+#define NSEC_PER_USEC (1000ULL)
+
#endif /* __XFS_PLATFORM_DEFS_H__ */
diff --git a/repair/dinode.c b/repair/dinode.c
index 77f78f1..8fa5f88 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -2216,7 +2216,7 @@ check_nsec(
struct xfs_timestamp *t,
int *dirty)
{
- if (be32_to_cpu(t->t_nsec) < 1000000000)
+ if (be32_to_cpu(t->t_nsec) < NSEC_PER_SEC)
return;
do_warn(
diff --git a/scrub/progress.c b/scrub/progress.c
index d0afe90..2058f59 100644
--- a/scrub/progress.c
+++ b/scrub/progress.c
@@ -110,7 +110,6 @@ progress_report(
fflush(pt.fp);
}
-#define NSEC_PER_SEC (1000000000)
static void *
progress_report_thread(void *arg)
{

View File

@ -0,0 +1,139 @@
From 9eb0d6eb9066daa621e710139c8c8d50fedbabcf Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 20 Nov 2020 17:03:27 -0500
Subject: [PATCH] mkfs: enable the inode btree counter feature
Teach mkfs how to enable the inode btree counter feature.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/man/man8/mkfs.xfs.8 b/man/man8/mkfs.xfs.8
index 9d6f315..45b150f 100644
--- a/man/man8/mkfs.xfs.8
+++ b/man/man8/mkfs.xfs.8
@@ -188,6 +188,21 @@ option set. When the option
.B \-m crc=0
is used, the free inode btree feature is not supported and is disabled.
.TP
+.BI inobtcount= value
+This option causes the filesystem to record the number of blocks used by
+the inode btree and the free inode btree.
+This can be used to reduce mount times when the free inode btree is enabled.
+.IP
+By default,
+.B mkfs.xfs
+will not enable this option.
+This feature is only available for filesystems created with the (default)
+.B \-m finobt=1
+option set.
+When the option
+.B \-m finobt=0
+is used, the inode btree counter feature is not supported and is disabled.
+.TP
.BI uuid= value
Use the given value as the filesystem UUID for the newly created filesystem.
The default is to generate a random UUID.
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 16819d8..87f15f4 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -117,6 +117,7 @@ enum {
M_UUID,
M_RMAPBT,
M_REFLINK,
+ M_INOBTCNT,
M_MAX_OPTS,
};
@@ -651,6 +652,7 @@ static struct opt_params mopts = {
[M_UUID] = "uuid",
[M_RMAPBT] = "rmapbt",
[M_REFLINK] = "reflink",
+ [M_INOBTCNT] = "inobtcount",
},
.subopt_params = {
{ .index = M_CRC,
@@ -681,6 +683,12 @@ static struct opt_params mopts = {
.maxval = 1,
.defaultval = 1,
},
+ { .index = M_INOBTCNT,
+ .conflicts = { { NULL, LAST_CONFLICT } },
+ .minval = 0,
+ .maxval = 1,
+ .defaultval = 1,
+ },
},
};
@@ -731,6 +739,7 @@ struct sb_feat_args {
bool spinodes; /* XFS_SB_FEAT_INCOMPAT_SPINODES */
bool rmapbt; /* XFS_SB_FEAT_RO_COMPAT_RMAPBT */
bool reflink; /* XFS_SB_FEAT_RO_COMPAT_REFLINK */
+ bool inobtcnt; /* XFS_SB_FEAT_RO_COMPAT_INOBTCNT */
bool nodalign;
bool nortalign;
};
@@ -853,7 +862,8 @@ usage( void )
{
fprintf(stderr, _("Usage: %s\n\
/* blocksize */ [-b size=num]\n\
-/* metadata */ [-m crc=0|1,finobt=0|1,uuid=xxx,rmapbt=0|1,reflink=0|1]\n\
+/* metadata */ [-m crc=0|1,finobt=0|1,uuid=xxx,rmapbt=0|1,reflink=0|1,\n\
+ inobtcnt=0|1]\n\
/* data subvol */ [-d agcount=n,agsize=n,file,name=xxx,size=num,\n\
(sunit=value,swidth=value|su=num,sw=num|noalign),\n\
sectsize=num\n\
@@ -1607,6 +1617,9 @@ meta_opts_parser(
case M_REFLINK:
cli->sb_feat.reflink = getnum(value, opts, subopt);
break;
+ case M_INOBTCNT:
+ cli->sb_feat.inobtcnt = getnum(value, opts, subopt);
+ break;
default:
return -EINVAL;
}
@@ -2037,6 +2050,22 @@ _("reflink not supported without CRC support\n"));
usage();
}
cli->sb_feat.reflink = false;
+
+ if (cli->sb_feat.inobtcnt && cli_opt_set(&mopts, M_INOBTCNT)) {
+ fprintf(stderr,
+_("inode btree counters not supported without CRC support\n"));
+ usage();
+ }
+ cli->sb_feat.inobtcnt = false;
+ }
+
+ if (!cli->sb_feat.finobt) {
+ if (cli->sb_feat.inobtcnt && cli_opt_set(&mopts, M_INOBTCNT)) {
+ fprintf(stderr,
+_("inode btree counters not supported without finobt support\n"));
+ usage();
+ }
+ cli->sb_feat.inobtcnt = false;
}
if ((cli->fsx.fsx_xflags & FS_XFLAG_COWEXTSIZE) &&
@@ -3002,6 +3031,8 @@ sb_set_features(
sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_RMAPBT;
if (fp->reflink)
sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_REFLINK;
+ if (fp->inobtcnt)
+ sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_INOBTCNT;
/*
* Sparse inode chunk support has two main inode alignment requirements.
@@ -3917,6 +3948,7 @@ main(
.spinodes = true,
.rmapbt = false,
.reflink = true,
+ .inobtcnt = false,
.parent_pointers = false,
.nodalign = false,
.nortalign = false,

View File

@ -0,0 +1,130 @@
From e9601810beb7d5b36a5fbd03c593cf63f685bfff Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 20 Nov 2020 17:03:28 -0500
Subject: [PATCH] mkfs: format bigtime filesystems
Allow formatting with large timestamps.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/man/man8/mkfs.xfs.8 b/man/man8/mkfs.xfs.8
index 45b150f..0a115cb 100644
--- a/man/man8/mkfs.xfs.8
+++ b/man/man8/mkfs.xfs.8
@@ -154,6 +154,22 @@ valid
are:
.RS 1.2i
.TP
+.BI bigtime= value
+This option enables filesystems that can handle inode timestamps from December
+1901 to July 2486, and quota timer expirations from January 1970 to July 2486.
+The value is either 0 to disable the feature, or 1 to enable large timestamps.
+.IP
+If this feature is not enabled, the filesystem can only handle timestamps from
+December 1901 to January 2038, and quota timers from January 1970 to February
+2106.
+.IP
+By default,
+.B mkfs.xfs
+will not enable this feature.
+If the option
+.B \-m crc=0
+is used, the large timestamp feature is not supported and is disabled.
+.TP
.BI crc= value
This is used to create a filesystem which maintains and checks CRC information
in all metadata objects on disk. The value is either 0 to disable the feature,
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 87f15f4..b74a00b 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -118,6 +118,7 @@ enum {
M_RMAPBT,
M_REFLINK,
M_INOBTCNT,
+ M_BIGTIME,
M_MAX_OPTS,
};
@@ -653,6 +654,7 @@ static struct opt_params mopts = {
[M_RMAPBT] = "rmapbt",
[M_REFLINK] = "reflink",
[M_INOBTCNT] = "inobtcount",
+ [M_BIGTIME] = "bigtime",
},
.subopt_params = {
{ .index = M_CRC,
@@ -689,6 +691,12 @@ static struct opt_params mopts = {
.maxval = 1,
.defaultval = 1,
},
+ { .index = M_BIGTIME,
+ .conflicts = { { NULL, LAST_CONFLICT } },
+ .minval = 0,
+ .maxval = 1,
+ .defaultval = 1,
+ },
},
};
@@ -740,6 +748,7 @@ struct sb_feat_args {
bool rmapbt; /* XFS_SB_FEAT_RO_COMPAT_RMAPBT */
bool reflink; /* XFS_SB_FEAT_RO_COMPAT_REFLINK */
bool inobtcnt; /* XFS_SB_FEAT_RO_COMPAT_INOBTCNT */
+ bool bigtime; /* XFS_SB_FEAT_INCOMPAT_BIGTIME */
bool nodalign;
bool nortalign;
};
@@ -863,7 +872,7 @@ usage( void )
fprintf(stderr, _("Usage: %s\n\
/* blocksize */ [-b size=num]\n\
/* metadata */ [-m crc=0|1,finobt=0|1,uuid=xxx,rmapbt=0|1,reflink=0|1,\n\
- inobtcnt=0|1]\n\
+ inobtcnt=0|1,bigtime=0|1]\n\
/* data subvol */ [-d agcount=n,agsize=n,file,name=xxx,size=num,\n\
(sunit=value,swidth=value|su=num,sw=num|noalign),\n\
sectsize=num\n\
@@ -1620,6 +1629,9 @@ meta_opts_parser(
case M_INOBTCNT:
cli->sb_feat.inobtcnt = getnum(value, opts, subopt);
break;
+ case M_BIGTIME:
+ cli->sb_feat.bigtime = getnum(value, opts, subopt);
+ break;
default:
return -EINVAL;
}
@@ -2057,6 +2069,13 @@ _("inode btree counters not supported without CRC support\n"));
usage();
}
cli->sb_feat.inobtcnt = false;
+
+ if (cli->sb_feat.bigtime && cli_opt_set(&mopts, M_BIGTIME)) {
+ fprintf(stderr,
+_("timestamps later than 2038 not supported without CRC support\n"));
+ usage();
+ }
+ cli->sb_feat.bigtime = false;
}
if (!cli->sb_feat.finobt) {
@@ -3033,6 +3052,8 @@ sb_set_features(
sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_REFLINK;
if (fp->inobtcnt)
sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_INOBTCNT;
+ if (fp->bigtime)
+ sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_BIGTIME;
/*
* Sparse inode chunk support has two main inode alignment requirements.
@@ -3952,6 +3973,7 @@ main(
.parent_pointers = false,
.nodalign = false,
.nortalign = false,
+ .bigtime = false,
},
};

View File

@ -0,0 +1,32 @@
From cac80700d88a32c1835cb37f982e98ddd73021e5 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 20 Nov 2020 17:03:28 -0500
Subject: [PATCH] xfs: enable big timestamps
Source kernel commit: 29887a22713192509cfc6068ea3b200cdb8856da
Enable the big timestamp feature.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Allison Collins <allison.henderson@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Gao Xiang <hsiangkao@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index 4848de8..722c9de 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -471,7 +471,8 @@ xfs_sb_has_ro_compat_feature(
#define XFS_SB_FEAT_INCOMPAT_ALL \
(XFS_SB_FEAT_INCOMPAT_FTYPE| \
XFS_SB_FEAT_INCOMPAT_SPINODES| \
- XFS_SB_FEAT_INCOMPAT_META_UUID)
+ XFS_SB_FEAT_INCOMPAT_META_UUID| \
+ XFS_SB_FEAT_INCOMPAT_BIGTIME)
#define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL
static inline bool

View File

@ -0,0 +1,28 @@
From 46da703382fa31bb02049a4131602f8a40002dbb Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 20 Nov 2020 17:03:27 -0500
Subject: [PATCH] xfs: enable new inode btree counters feature
Source kernel commit: b896a39faa5a2f97dadfb347928466afb12cc63a
Enable the new inode btree counters feature.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index 9ba65e5..4848de8 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -453,7 +453,8 @@ xfs_sb_has_compat_feature(
#define XFS_SB_FEAT_RO_COMPAT_ALL \
(XFS_SB_FEAT_RO_COMPAT_FINOBT | \
XFS_SB_FEAT_RO_COMPAT_RMAPBT | \
- XFS_SB_FEAT_RO_COMPAT_REFLINK)
+ XFS_SB_FEAT_RO_COMPAT_REFLINK| \
+ XFS_SB_FEAT_RO_COMPAT_INOBTCNT)
#define XFS_SB_FEAT_RO_COMPAT_UNKNOWN ~XFS_SB_FEAT_RO_COMPAT_ALL
static inline bool
xfs_sb_has_ro_compat_feature(

View File

@ -0,0 +1,74 @@
From 18e3b8c234fac67c6c96e9ff34f0ab4598220fa1 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Tue, 10 Nov 2020 15:11:09 -0500
Subject: [PATCH] xfs: explicitly define inode timestamp range
Source kernel commit: 876fdc7c4f366a709ac272ef3336ae7dce58f2af
Formally define the inode timestamp ranges that existing filesystems
support, and switch the vfs timetamp ranges to use it.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Allison Collins <allison.henderson@oracle.com>
Reviewed-by: Gao Xiang <hsiangkao@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
NOTE: we hvae no xfs_compat.h so S32_MAX etc went in xfs_fs.h
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index 7f7b03a..5712aa0 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -839,11 +839,33 @@ typedef struct xfs_agfl {
ASSERT(xfs_daddr_to_agno(mp, d) == \
xfs_daddr_to_agno(mp, (d) + (len) - 1)))
+/*
+ * XFS Timestamps
+ * ==============
+ *
+ * Traditional ondisk inode timestamps consist of signed 32-bit counters for
+ * seconds and nanoseconds; time zero is the Unix epoch, Jan 1 00:00:00 UTC
+ * 1970, which means that the timestamp epoch is the same as the Unix epoch.
+ * Therefore, the ondisk min and max defined here can be used directly to
+ * constrain the incore timestamps on a Unix system.
+ */
typedef struct xfs_timestamp {
__be32 t_sec; /* timestamp seconds */
__be32 t_nsec; /* timestamp nanoseconds */
} xfs_timestamp_t;
+/*
+ * Smallest possible ondisk seconds value with traditional timestamps. This
+ * corresponds exactly with the incore timestamp Dec 13 20:45:52 UTC 1901.
+ */
+#define XFS_LEGACY_TIME_MIN ((int64_t)S32_MIN)
+
+/*
+ * Largest possible ondisk seconds value with traditional timestamps. This
+ * corresponds exactly with the incore timestamp Jan 19 03:14:07 UTC 2038.
+ */
+#define XFS_LEGACY_TIME_MAX ((int64_t)S32_MAX)
+
/*
* On-disk inode structure.
*
diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index fbc9031..4fa9852 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -694,6 +694,10 @@ struct timespec64 {
long tv_nsec; /* nanoseconds */
};
+#define U32_MAX ((uint32_t)~0U)
+#define S32_MAX ((int32_t)(U32_MAX >> 1))
+#define S32_MIN ((int32_t)(-S32_MAX - 1))
+
#ifndef HAVE_BBMACROS
/*
* Block I/O parameterization. A basic block (BB) is the lowest size of

View File

@ -0,0 +1,94 @@
From acaa814953273827f380262ba900f0d50a95bee2 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Tue, 10 Nov 2020 15:13:50 -0500
Subject: [PATCH] xfs: move xfs_log_dinode_to_disk to the log recovery code
Source kernel commit: 88947ea0ba713c9b74b212755b3b58242f0e7a56
Move this function to xfs_inode_item_recover.c since there's only one
caller of it.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Allison Collins <allison.henderson@oracle.com>
Reviewed-by: Gao Xiang <hsiangkao@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index 975f097..f80ce10 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -318,58 +318,6 @@ xfs_inode_to_disk(
}
}
-void
-xfs_log_dinode_to_disk(
- struct xfs_log_dinode *from,
- struct xfs_dinode *to)
-{
- to->di_magic = cpu_to_be16(from->di_magic);
- to->di_mode = cpu_to_be16(from->di_mode);
- to->di_version = from->di_version;
- to->di_format = from->di_format;
- to->di_onlink = 0;
- to->di_uid = cpu_to_be32(from->di_uid);
- to->di_gid = cpu_to_be32(from->di_gid);
- to->di_nlink = cpu_to_be32(from->di_nlink);
- to->di_projid_lo = cpu_to_be16(from->di_projid_lo);
- to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
- memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
-
- to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec);
- to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec);
- to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec);
- to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec);
- to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec);
- to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec);
-
- to->di_size = cpu_to_be64(from->di_size);
- to->di_nblocks = cpu_to_be64(from->di_nblocks);
- to->di_extsize = cpu_to_be32(from->di_extsize);
- to->di_nextents = cpu_to_be32(from->di_nextents);
- to->di_anextents = cpu_to_be16(from->di_anextents);
- to->di_forkoff = from->di_forkoff;
- to->di_aformat = from->di_aformat;
- to->di_dmevmask = cpu_to_be32(from->di_dmevmask);
- to->di_dmstate = cpu_to_be16(from->di_dmstate);
- to->di_flags = cpu_to_be16(from->di_flags);
- to->di_gen = cpu_to_be32(from->di_gen);
-
- if (from->di_version == 3) {
- to->di_changecount = cpu_to_be64(from->di_changecount);
- to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.t_sec);
- to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.t_nsec);
- to->di_flags2 = cpu_to_be64(from->di_flags2);
- to->di_cowextsize = cpu_to_be32(from->di_cowextsize);
- to->di_ino = cpu_to_be64(from->di_ino);
- to->di_lsn = cpu_to_be64(from->di_lsn);
- memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2));
- uuid_copy(&to->di_uuid, &from->di_uuid);
- to->di_flushiter = 0;
- } else {
- to->di_flushiter = cpu_to_be16(from->di_flushiter);
- }
-}
-
static xfs_failaddr_t
xfs_dinode_verify_fork(
struct xfs_dinode *dip,
diff --git a/libxfs/xfs_inode_buf.h b/libxfs/xfs_inode_buf.h
index c9ac69c..0343368 100644
--- a/libxfs/xfs_inode_buf.h
+++ b/libxfs/xfs_inode_buf.h
@@ -59,8 +59,6 @@ void xfs_dinode_calc_crc(struct xfs_mount *, struct xfs_dinode *);
void xfs_inode_to_disk(struct xfs_inode *ip, struct xfs_dinode *to,
xfs_lsn_t lsn);
void xfs_inode_from_disk(struct xfs_inode *ip, struct xfs_dinode *from);
-void xfs_log_dinode_to_disk(struct xfs_log_dinode *from,
- struct xfs_dinode *to);
bool xfs_dinode_good_version(struct xfs_mount *mp, __u8 version);

View File

@ -0,0 +1,101 @@
From fc3e21db4a30d0d81158938cabba0fb59fc57ad8 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Wed, 11 Nov 2020 13:48:47 -0500
Subject: [PATCH] xfs: redefine xfs_ictimestamp_t
Source kernel commit: 30e05599219f3c15bd5f24190af0e33cdb4a00e5
Redefine xfs_ictimestamp_t as a uint64_t typedef in preparation for the
bigtime functionality. Preserve the legacy structure format so that we
can let the compiler take care of the masking and shifting.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Gao Xiang <hsiangkao@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h
index e5f97c6..8dc0df0 100644
--- a/libxfs/xfs_log_format.h
+++ b/libxfs/xfs_log_format.h
@@ -368,10 +368,13 @@ static inline int xfs_ilog_fdata(int w)
* directly mirrors the xfs_dinode structure as it must contain all the same
* information.
*/
-typedef struct xfs_ictimestamp {
+typedef uint64_t xfs_ictimestamp_t;
+
+/* Legacy timestamp encoding format. */
+struct xfs_legacy_ictimestamp {
int32_t t_sec; /* timestamp seconds */
int32_t t_nsec; /* timestamp nanoseconds */
-} xfs_ictimestamp_t;
+};
/*
* Define the format of the inode core that is logged. This structure must be
diff --git a/logprint/log_misc.c b/logprint/log_misc.c
index c325f04..4fad82b 100644
--- a/logprint/log_misc.c
+++ b/logprint/log_misc.c
@@ -446,8 +446,10 @@ xlog_print_trans_inode_core(
(int)ip->di_format);
printf(_("nlink %hd uid %d gid %d\n"),
ip->di_nlink, ip->di_uid, ip->di_gid);
- printf(_("atime 0x%x mtime 0x%x ctime 0x%x\n"),
- ip->di_atime.t_sec, ip->di_mtime.t_sec, ip->di_ctime.t_sec);
+ printf(_("atime 0x%llx mtime 0x%llx ctime 0x%llx\n"),
+ xlog_extract_dinode_ts(ip->di_atime),
+ xlog_extract_dinode_ts(ip->di_mtime),
+ xlog_extract_dinode_ts(ip->di_ctime));
printf(_("size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n"),
(unsigned long long)ip->di_size, (unsigned long long)ip->di_nblocks,
ip->di_extsize, ip->di_nextents);
@@ -739,6 +741,16 @@ xlog_print_trans_icreate(
******************************************************************************
*/
+time64_t
+xlog_extract_dinode_ts(
+ const xfs_ictimestamp_t its)
+{
+ struct xfs_legacy_ictimestamp *lits;
+
+ lits = (struct xfs_legacy_ictimestamp *)&its;
+ return (time64_t)lits->t_sec;
+}
+
void
xlog_print_lseek(struct xlog *log, int fd, xfs_daddr_t blkno, int whence)
{
diff --git a/logprint/log_print_all.c b/logprint/log_print_all.c
index eafffe2..3ca01b1 100644
--- a/logprint/log_print_all.c
+++ b/logprint/log_print_all.c
@@ -249,8 +249,10 @@ xlog_recover_print_inode_core(
printf(_(" uid:%d gid:%d nlink:%d projid:0x%04x%04x\n"),
di->di_uid, di->di_gid, di->di_nlink,
di->di_projid_hi, di->di_projid_lo);
- printf(_(" atime:%d mtime:%d ctime:%d\n"),
- di->di_atime.t_sec, di->di_mtime.t_sec, di->di_ctime.t_sec);
+ printf(_(" atime:%lld mtime:%lld ctime:%lld\n"),
+ xlog_extract_dinode_ts(di->di_atime),
+ xlog_extract_dinode_ts(di->di_mtime),
+ xlog_extract_dinode_ts(di->di_ctime));
printf(_(" flushiter:%d\n"), di->di_flushiter);
printf(_(" size:0x%llx nblks:0x%llx exsize:%d "
"nextents:%d anextents:%d\n"), (unsigned long long)
diff --git a/logprint/logprint.h b/logprint/logprint.h
index 98ac0d4..0061d5a 100644
--- a/logprint/logprint.h
+++ b/logprint/logprint.h
@@ -18,6 +18,7 @@ extern int print_no_data;
extern int print_no_print;
/* exports */
+extern time64_t xlog_extract_dinode_ts(const xfs_ictimestamp_t);
extern void xlog_print_lseek(struct xlog *, int, xfs_daddr_t, int);
extern void xfs_log_copy(struct xlog *, int, char *);

View File

@ -0,0 +1,196 @@
From a252aadfc977473e0851acf0d529c930c6e8e181 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Tue, 10 Nov 2020 16:29:40 -0500
Subject: [PATCH] xfs: redefine xfs_timestamp_t
Source kernel commit: 5a0bb066f60fa02f453d7721844eae59f505c06e
Redefine xfs_timestamp_t as a __be64 typedef in preparation for the
bigtime functionality. Preserve the legacy structure format so that we
can let the compiler take care of masking and shifting.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Gao Xiang <hsiangkao@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/db/field.c b/db/field.c
index 66fa37e..4a45c66 100644
--- a/db/field.c
+++ b/db/field.c
@@ -350,7 +350,7 @@ const ftattr_t ftattrtab[] = {
{ FLDT_TIME, "time", fp_time, NULL, SI(bitsz(int32_t)), FTARG_SIGNED,
NULL, NULL },
{ FLDT_TIMESTAMP, "timestamp", NULL, (char *)timestamp_flds,
- SI(bitsz(xfs_timestamp_t)), 0, NULL, timestamp_flds },
+ SI(bitsz(struct xfs_legacy_timestamp)), 0, NULL, timestamp_flds },
{ FLDT_UINT1, "uint1", fp_num, "%u", SI(1), 0, NULL, NULL },
{ FLDT_UINT16D, "uint16d", fp_num, "%u", SI(bitsz(uint16_t)), 0, NULL,
NULL },
diff --git a/db/inode.c b/db/inode.c
index 697f7fe..b308538 100644
--- a/db/inode.c
+++ b/db/inode.c
@@ -176,7 +176,7 @@ const field_t inode_v3_flds[] = {
};
-#define TOFF(f) bitize(offsetof(xfs_timestamp_t, t_ ## f))
+#define TOFF(f) bitize(offsetof(struct xfs_legacy_timestamp, t_ ## f))
const field_t timestamp_flds[] = {
{ "sec", FLDT_TIME, OI(TOFF(sec)), C1, 0, TYP_NONE },
{ "nsec", FLDT_NSEC, OI(TOFF(nsec)), C1, 0, TYP_NONE },
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index 8858341..371f5cd 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -847,12 +847,16 @@ typedef struct xfs_agfl {
* seconds and nanoseconds; time zero is the Unix epoch, Jan 1 00:00:00 UTC
* 1970, which means that the timestamp epoch is the same as the Unix epoch.
* Therefore, the ondisk min and max defined here can be used directly to
- * constrain the incore timestamps on a Unix system.
+ * constrain the incore timestamps on a Unix system. Note that we actually
+ * encode a __be64 value on disk.
*/
-typedef struct xfs_timestamp {
+typedef __be64 xfs_timestamp_t;
+
+/* Legacy timestamp encoding format. */
+struct xfs_legacy_timestamp {
__be32 t_sec; /* timestamp seconds */
__be32 t_nsec; /* timestamp nanoseconds */
-} xfs_timestamp_t;
+};
/*
* Smallest possible ondisk seconds value with traditional timestamps. This
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index f80ce10..d8831a1 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -195,6 +195,21 @@ xfs_imap_to_bp(
return 0;
}
+/* Convert an ondisk timestamp to an incore timestamp. */
+struct timespec64
+xfs_inode_from_disk_ts(
+ const xfs_timestamp_t ts)
+{
+ struct timespec64 tv;
+ struct xfs_legacy_timestamp *lts;
+
+ lts = (struct xfs_legacy_timestamp *)&ts;
+ tv.tv_sec = (int)be32_to_cpu(lts->t_sec);
+ tv.tv_nsec = (int)be32_to_cpu(lts->t_nsec);
+
+ return tv;
+}
+
void
xfs_inode_from_disk(
struct xfs_inode *ip,
@@ -231,12 +246,10 @@ xfs_inode_from_disk(
* a time before epoch is converted to a time long after epoch
* on 64 bit systems.
*/
- inode->i_atime.tv_sec = (int)be32_to_cpu(from->di_atime.t_sec);
- inode->i_atime.tv_nsec = (int)be32_to_cpu(from->di_atime.t_nsec);
- inode->i_mtime.tv_sec = (int)be32_to_cpu(from->di_mtime.t_sec);
- inode->i_mtime.tv_nsec = (int)be32_to_cpu(from->di_mtime.t_nsec);
- inode->i_ctime.tv_sec = (int)be32_to_cpu(from->di_ctime.t_sec);
- inode->i_ctime.tv_nsec = (int)be32_to_cpu(from->di_ctime.t_nsec);
+ inode->i_atime = xfs_inode_from_disk_ts(from->di_atime);
+ inode->i_mtime = xfs_inode_from_disk_ts(from->di_mtime);
+ inode->i_ctime = xfs_inode_from_disk_ts(from->di_ctime);
+
inode->i_generation = be32_to_cpu(from->di_gen);
inode->i_mode = be16_to_cpu(from->di_mode);
@@ -254,13 +267,27 @@ xfs_inode_from_disk(
if (to->di_version == 3) {
inode_set_iversion_queried(inode,
be64_to_cpu(from->di_changecount));
- to->di_crtime.tv_sec = be32_to_cpu(from->di_crtime.t_sec);
- to->di_crtime.tv_nsec = be32_to_cpu(from->di_crtime.t_nsec);
+ to->di_crtime = xfs_inode_from_disk_ts(from->di_crtime);
to->di_flags2 = be64_to_cpu(from->di_flags2);
to->di_cowextsize = be32_to_cpu(from->di_cowextsize);
}
}
+/* Convert an incore timestamp to an ondisk timestamp. */
+static inline xfs_timestamp_t
+xfs_inode_to_disk_ts(
+ const struct timespec64 tv)
+{
+ struct xfs_legacy_timestamp *lts;
+ xfs_timestamp_t ts;
+
+ lts = (struct xfs_legacy_timestamp *)&ts;
+ lts->t_sec = cpu_to_be32(tv.tv_sec);
+ lts->t_nsec = cpu_to_be32(tv.tv_nsec);
+
+ return ts;
+}
+
void
xfs_inode_to_disk(
struct xfs_inode *ip,
@@ -281,12 +308,9 @@ xfs_inode_to_disk(
to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
memset(to->di_pad, 0, sizeof(to->di_pad));
- to->di_atime.t_sec = cpu_to_be32(inode->i_atime.tv_sec);
- to->di_atime.t_nsec = cpu_to_be32(inode->i_atime.tv_nsec);
- to->di_mtime.t_sec = cpu_to_be32(inode->i_mtime.tv_sec);
- to->di_mtime.t_nsec = cpu_to_be32(inode->i_mtime.tv_nsec);
- to->di_ctime.t_sec = cpu_to_be32(inode->i_ctime.tv_sec);
- to->di_ctime.t_nsec = cpu_to_be32(inode->i_ctime.tv_nsec);
+ to->di_atime = xfs_inode_to_disk_ts(inode->i_atime);
+ to->di_mtime = xfs_inode_to_disk_ts(inode->i_mtime);
+ to->di_ctime = xfs_inode_to_disk_ts(inode->i_ctime);
to->di_nlink = cpu_to_be32(inode->i_nlink);
to->di_gen = cpu_to_be32(inode->i_generation);
to->di_mode = cpu_to_be16(inode->i_mode);
@@ -304,8 +328,7 @@ xfs_inode_to_disk(
if (from->di_version == 3) {
to->di_changecount = cpu_to_be64(inode_peek_iversion(inode));
- to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.tv_sec);
- to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.tv_nsec);
+ to->di_crtime = xfs_inode_to_disk_ts(from->di_crtime);
to->di_flags2 = cpu_to_be64(from->di_flags2);
to->di_cowextsize = cpu_to_be32(from->di_cowextsize);
to->di_ino = cpu_to_be64(ip->i_ino);
diff --git a/libxfs/xfs_inode_buf.h b/libxfs/xfs_inode_buf.h
index 0343368..6147f42 100644
--- a/libxfs/xfs_inode_buf.h
+++ b/libxfs/xfs_inode_buf.h
@@ -76,4 +76,6 @@ xfs_failaddr_t xfs_inode_validate_cowextsize(struct xfs_mount *mp,
uint32_t cowextsize, uint16_t mode, uint16_t flags,
uint64_t flags2);
+struct timespec64 xfs_inode_from_disk_ts(const xfs_timestamp_t ts);
+
#endif /* __XFS_INODE_BUF_H__ */
diff --git a/repair/dinode.c b/repair/dinode.c
index 8fa5f88..0c40f2a 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -2213,9 +2213,12 @@ static void
check_nsec(
const char *name,
xfs_ino_t lino,
- struct xfs_timestamp *t,
+ xfs_timestamp_t *ts,
int *dirty)
{
+ struct xfs_legacy_timestamp *t;
+
+ t = (struct xfs_legacy_timestamp *)ts;
if (be32_to_cpu(t->t_nsec) < NSEC_PER_SEC)
return;

View File

@ -0,0 +1,49 @@
From abc0f20536e3bc1505f575f452c55585c34f6e06 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Tue, 10 Nov 2020 15:11:43 -0500
Subject: [PATCH] xfs: refactor default quota grace period setting code
Source kernel commit: ccc8e771aa7a80eb047fc263780816ca76dd02a6
Refactor the code that sets the default quota grace period into a helper
function so that we can override the ondisk behavior later.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Allison Collins <allison.henderson@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index c67bd61..8858341 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -1190,6 +1190,11 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
* been reached, and therefore no expiration has been set. Therefore, the
* ondisk min and max defined here can be used directly to constrain the incore
* quota expiration timestamps on a Unix system.
+ *
+ * The grace period for each quota type is stored in the root dquot (id = 0)
+ * and is applied to a non-root dquot when it exceeds the soft or hard limits.
+ * The length of quota grace periods are unsigned 32-bit quantities measured in
+ * units of seconds. A value of zero means to use the default period.
*/
/*
@@ -1204,6 +1209,14 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
*/
#define XFS_DQ_LEGACY_EXPIRY_MAX ((int64_t)U32_MAX)
+/*
+ * Default quota grace periods, ranging from zero (use the compiled defaults)
+ * to ~136 years. These are applied to a non-root dquot that has exceeded
+ * either limit.
+ */
+#define XFS_DQ_GRACE_MIN ((int64_t)0)
+#define XFS_DQ_GRACE_MAX ((int64_t)U32_MAX)
+
/*
* This is the main portion of the on-disk representation of quota
* information for a user. This is the q_core of the xfs_dquot_t that

View File

@ -0,0 +1,54 @@
From 94c5482a7e0cbb6fd289745a4b5f49a133a4f5e8 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Tue, 10 Nov 2020 15:11:09 -0500
Subject: [PATCH] xfs: refactor quota expiration timer modification
Source kernel commit: 11d8a9190275855f79d62093d789e962cc7228fb
Define explicit limits on the range of quota grace period expiration
timeouts and refactor the code that modifies the timeouts into helpers
that clamp the values appropriately. Note that we'll refactor the
default grace period timer separately.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Allison Collins <allison.henderson@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index 5712aa0..c67bd61 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -1180,6 +1180,30 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
#define XFS_DQUOT_MAGIC 0x4451 /* 'DQ' */
#define XFS_DQUOT_VERSION (uint8_t)0x01 /* latest version number */
+/*
+ * XFS Quota Timers
+ * ================
+ *
+ * Traditional quota grace period expiration timers are an unsigned 32-bit
+ * seconds counter; time zero is the Unix epoch, Jan 1 00:00:01 UTC 1970.
+ * Note that an expiration value of zero means that the quota limit has not
+ * been reached, and therefore no expiration has been set. Therefore, the
+ * ondisk min and max defined here can be used directly to constrain the incore
+ * quota expiration timestamps on a Unix system.
+ */
+
+/*
+ * Smallest possible ondisk quota expiration value with traditional timestamps.
+ * This corresponds exactly with the incore expiration Jan 1 00:00:01 UTC 1970.
+ */
+#define XFS_DQ_LEGACY_EXPIRY_MIN ((int64_t)1)
+
+/*
+ * Largest possible ondisk quota expiration value with traditional timestamps.
+ * This corresponds exactly with the incore expiration Feb 7 06:28:15 UTC 2106.
+ */
+#define XFS_DQ_LEGACY_EXPIRY_MAX ((int64_t)U32_MAX)
+
/*
* This is the main portion of the on-disk representation of quota
* information for a user. This is the q_core of the xfs_dquot_t that

View File

@ -0,0 +1,58 @@
From 68879320b482e73e6ce202a8e680c8ab7e6a2af4 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Tue, 10 Nov 2020 15:12:50 -0500
Subject: [PATCH] xfs: refactor quota timestamp coding
Source kernel commit: 9f99c8fe551a056c0929dff13cbce62b6b150156
Refactor quota timestamp encoding and decoding into helper functions so
that we can add extra behavior in the next patch.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Allison Collins <allison.henderson@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/libxfs/xfs_dquot_buf.c b/libxfs/xfs_dquot_buf.c
index 324f528..963f8ea 100644
--- a/libxfs/xfs_dquot_buf.c
+++ b/libxfs/xfs_dquot_buf.c
@@ -286,3 +286,21 @@ const struct xfs_buf_ops xfs_dquot_buf_ra_ops = {
.verify_read = xfs_dquot_buf_readahead_verify,
.verify_write = xfs_dquot_buf_write_verify,
};
+
+/* Convert an on-disk timer value into an incore timer value. */
+time64_t
+xfs_dquot_from_disk_ts(
+ struct xfs_disk_dquot *ddq,
+ __be32 dtimer)
+{
+ return be32_to_cpu(dtimer);
+}
+
+/* Convert an incore timer value into an on-disk timer value. */
+__be32
+xfs_dquot_to_disk_ts(
+ struct xfs_dquot *dqp,
+ time64_t timer)
+{
+ return cpu_to_be32(timer);
+}
diff --git a/libxfs/xfs_quota_defs.h b/libxfs/xfs_quota_defs.h
index c69dba4..2f61cd3 100644
--- a/libxfs/xfs_quota_defs.h
+++ b/libxfs/xfs_quota_defs.h
@@ -149,4 +149,9 @@ extern int xfs_calc_dquots_per_chunk(unsigned int nbblks);
extern int xfs_dqblk_repair(struct xfs_mount *mp, struct xfs_dqblk *dqb,
xfs_dqid_t id, uint type);
+struct xfs_dquot;
+time64_t xfs_dquot_from_disk_ts(struct xfs_disk_dquot *ddq,
+ __be32 dtimer);
+__be32 xfs_dquot_to_disk_ts(struct xfs_dquot *ddq, time64_t timer);
+
#endif /* __XFS_QUOTA_H__ */

View File

@ -0,0 +1,159 @@
From 177c81e25b763c90f9815b1f4055d9d5c515a845 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Tue, 10 Nov 2020 15:11:09 -0500
Subject: [PATCH] xfs: store inode btree block counts in AGI header
Source kernel commit: 2a39946c984464e4aac82c556ba9915589be7323
Add a btree block usage counters for both inode btrees to the AGI header
so that we don't have to walk the entire finobt at mount time to create
the per-AG reservations.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
NOTE: kernel routines are not used to initialize AGIs in this
version, so I added to the open-coded function in xfs_mkfs.c
diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c
index a7d1a0d..850d6e3 100644
--- a/libxfs/xfs_ag.c
+++ b/libxfs/xfs_ag.c
@@ -258,6 +258,11 @@ xfs_agiblock_init(
}
for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++)
agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
+ if (xfs_sb_version_hasinobtcounts(&mp->m_sb)) {
+ agi->agi_iblocks = cpu_to_be32(1);
+ if (xfs_sb_version_hasfinobt(&mp->m_sb))
+ agi->agi_fblocks = cpu_to_be32(1);
+ }
}
typedef void (*aghdr_init_work_f)(struct xfs_mount *mp, struct xfs_buf *bp,
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index 23eca3b..7f7b03a 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -449,6 +449,7 @@ xfs_sb_has_compat_feature(
#define XFS_SB_FEAT_RO_COMPAT_FINOBT (1 << 0) /* free inode btree */
#define XFS_SB_FEAT_RO_COMPAT_RMAPBT (1 << 1) /* reverse map btree */
#define XFS_SB_FEAT_RO_COMPAT_REFLINK (1 << 2) /* reflinked files */
+#define XFS_SB_FEAT_RO_COMPAT_INOBTCNT (1 << 3) /* inobt block counts */
#define XFS_SB_FEAT_RO_COMPAT_ALL \
(XFS_SB_FEAT_RO_COMPAT_FINOBT | \
XFS_SB_FEAT_RO_COMPAT_RMAPBT | \
@@ -546,6 +547,17 @@ static inline bool xfs_sb_version_hasreflink(struct xfs_sb *sbp)
(sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_REFLINK);
}
+/*
+ * Inode btree block counter. We record the number of inobt and finobt blocks
+ * in the AGI header so that we can skip the finobt walk at mount time when
+ * setting up per-AG reservations.
+ */
+static inline bool xfs_sb_version_hasinobtcounts(struct xfs_sb *sbp)
+{
+ return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 &&
+ (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_INOBTCNT);
+}
+
/*
* end of superblock version macros
*/
@@ -750,6 +762,9 @@ typedef struct xfs_agi {
__be32 agi_free_root; /* root of the free inode btree */
__be32 agi_free_level;/* levels in free inode btree */
+ __be32 agi_iblocks; /* inobt blocks used */
+ __be32 agi_fblocks; /* finobt blocks used */
+
/* structure must be padded to 64 bit alignment */
} xfs_agi_t;
@@ -770,7 +785,8 @@ typedef struct xfs_agi {
#define XFS_AGI_ALL_BITS_R1 ((1 << XFS_AGI_NUM_BITS_R1) - 1)
#define XFS_AGI_FREE_ROOT (1 << 11)
#define XFS_AGI_FREE_LEVEL (1 << 12)
-#define XFS_AGI_NUM_BITS_R2 13
+#define XFS_AGI_IBLOCKS (1 << 13) /* both inobt/finobt block counters */
+#define XFS_AGI_NUM_BITS_R2 14
/* disk block (xfs_daddr_t) in the AG */
#define XFS_AGI_DADDR(mp) ((xfs_daddr_t)(2 << (mp)->m_sectbb_log))
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index a600c03..9d380f9 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -2451,6 +2451,7 @@ xfs_ialloc_log_agi(
offsetof(xfs_agi_t, agi_unlinked),
offsetof(xfs_agi_t, agi_free_root),
offsetof(xfs_agi_t, agi_free_level),
+ offsetof(xfs_agi_t, agi_iblocks),
sizeof(xfs_agi_t)
};
#ifdef DEBUG
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index 716a81f..9db87e9 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -68,6 +68,25 @@ xfs_finobt_set_root(
XFS_AGI_FREE_ROOT | XFS_AGI_FREE_LEVEL);
}
+/* Update the inode btree block counter for this btree. */
+static inline void
+xfs_inobt_mod_blockcount(
+ struct xfs_btree_cur *cur,
+ int howmuch)
+{
+ struct xfs_buf *agbp = cur->bc_private.a.agbp;
+ struct xfs_agi *agi = agbp->b_addr;
+
+ if (!xfs_sb_version_hasinobtcounts(&cur->bc_mp->m_sb))
+ return;
+
+ if (cur->bc_btnum == XFS_BTNUM_FINO)
+ be32_add_cpu(&agi->agi_fblocks, howmuch);
+ else if (cur->bc_btnum == XFS_BTNUM_INO)
+ be32_add_cpu(&agi->agi_iblocks, howmuch);
+ xfs_ialloc_log_agi(cur->bc_tp, agbp, XFS_AGI_IBLOCKS);
+}
+
STATIC int
__xfs_inobt_alloc_block(
struct xfs_btree_cur *cur,
@@ -103,6 +122,7 @@ __xfs_inobt_alloc_block(
new->s = cpu_to_be32(XFS_FSB_TO_AGBNO(args.mp, args.fsbno));
*stat = 1;
+ xfs_inobt_mod_blockcount(cur, 1);
return 0;
}
@@ -135,6 +155,7 @@ __xfs_inobt_free_block(
struct xfs_buf *bp,
enum xfs_ag_resv_type resv)
{
+ xfs_inobt_mod_blockcount(cur, -1);
return xfs_free_extent(cur->bc_tp,
XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(bp)), 1,
&XFS_RMAP_OINFO_INOBT, resv);
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 16819d8..992224d 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -3588,6 +3588,11 @@ initialise_ag_headers(
platform_uuid_copy(&agi->agi_uuid, &sbp->sb_uuid);
for (c = 0; c < XFS_AGI_UNLINKED_BUCKETS; c++)
agi->agi_unlinked[c] = cpu_to_be32(NULLAGINO);
+ if (xfs_sb_version_hasinobtcounts(&mp->m_sb)) {
+ agi->agi_iblocks = cpu_to_be32(1);
+ if (xfs_sb_version_hasfinobt(&mp->m_sb))
+ agi->agi_fblocks = cpu_to_be32(1);
+ }
libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
/*

View File

@ -0,0 +1,61 @@
From eb2c6897f36d560f84ed5124b246f2759c470f11 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Tue, 10 Nov 2020 15:11:09 -0500
Subject: [PATCH] xfs: use the finobt block counts to speed up mount times
Source kernel commit: 1ac35f061af011442eeb731632f6daae991ecf7c
Now that we have reliable finobt block counts, use them to speed up the
per-AG block reservation calculations at mount time.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c
index 9db87e9..b1adc80 100644
--- a/libxfs/xfs_ialloc_btree.c
+++ b/libxfs/xfs_ialloc_btree.c
@@ -593,6 +593,28 @@ xfs_inobt_count_blocks(
return error;
}
+/* Read finobt block count from AGI header. */
+static int
+xfs_finobt_read_blocks(
+ struct xfs_mount *mp,
+ struct xfs_trans *tp,
+ xfs_agnumber_t agno,
+ xfs_extlen_t *tree_blocks)
+{
+ struct xfs_buf *agbp;
+ struct xfs_agi *agi;
+ int error;
+
+ error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
+ if (error)
+ return error;
+
+ agi = agbp->b_addr;
+ *tree_blocks = be32_to_cpu(agi->agi_fblocks);
+ xfs_trans_brelse(tp, agbp);
+ return 0;
+}
+
/*
* Figure out how many blocks to reserve and how many are used by this btree.
*/
@@ -610,7 +632,11 @@ xfs_finobt_calc_reserves(
if (!xfs_sb_version_hasfinobt(&mp->m_sb))
return 0;
- error = xfs_inobt_count_blocks(mp, tp, agno, XFS_BTNUM_FINO, &tree_len);
+ if (xfs_sb_version_hasinobtcounts(&mp->m_sb))
+ error = xfs_finobt_read_blocks(mp, tp, agno, &tree_len);
+ else
+ error = xfs_inobt_count_blocks(mp, tp, agno, XFS_BTNUM_FINO,
+ &tree_len);
if (error)
return error;

View File

@ -0,0 +1,371 @@
From e7e3beb95efd751f227a0ced4c83fc5b88582e2e Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Wed, 11 Nov 2020 20:08:14 -0500
Subject: [PATCH] xfs: widen ondisk inode timestamps to deal with y2038+
Source kernel commit: f93e5436f0ee5a85eaa3a86d2614d215873fb18b
Redesign the ondisk inode timestamps to be a simple unsigned 64-bit
counter of nanoseconds since 14 Dec 1901 (i.e. the minimum time in the
32-bit unix time epoch). This enables us to handle dates up to 2486,
which solves the y2038 problem.
sandeen: update xfs_flags2diflags2() as well, to match
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Gao Xiang <hsiangkao@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
NOTE: xfs_trans_inode.c was not brought over in this version, so code
landed in trans.c
We also do not have the pre-computed geometry, so that needs to be
explicitly added to libxfs_ialloc rather than inheriting from igeo.
diff --git a/include/xfs_inode.h b/include/xfs_inode.h
index ddd48be..25f2eac 100644
--- a/include/xfs_inode.h
+++ b/include/xfs_inode.h
@@ -146,6 +146,11 @@ static inline bool xfs_is_reflink_inode(struct xfs_inode *ip)
return ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK;
}
+static inline bool xfs_inode_has_bigtime(struct xfs_inode *ip)
+{
+ return ip->i_d.di_flags2 & XFS_DIFLAG2_BIGTIME;
+}
+
typedef struct cred {
uid_t cr_uid;
gid_t cr_gid;
diff --git a/libxfs/trans.c b/libxfs/trans.c
index db90624..54e4dd6 100644
--- a/libxfs/trans.c
+++ b/libxfs/trans.c
@@ -415,6 +415,17 @@ xfs_trans_log_inode(
tp->t_flags |= XFS_TRANS_DIRTY;
set_bit(XFS_LI_DIRTY, &ip->i_itemp->ili_item.li_flags);
+ /*
+ * If we're updating the inode core or the timestamps and it's possible
+ * to upgrade this inode to bigtime format, do so now.
+ */
+ if ((flags & (XFS_ILOG_CORE | XFS_ILOG_TIMESTAMP)) &&
+ xfs_sb_version_hasbigtime(&ip->i_mount->m_sb) &&
+ !xfs_inode_has_bigtime(ip)) {
+ ip->i_d.di_flags2 |= XFS_DIFLAG2_BIGTIME;
+ flags |= XFS_ILOG_CORE;
+ }
+
/*
* Always OR in the bits from the ili_last_fields field.
* This is to coordinate with the xfs_iflush() and xfs_iflush_done()
diff --git a/libxfs/util.c b/libxfs/util.c
index 9383bb8..7a8729f 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -222,7 +222,8 @@ xfs_flags2diflags2(
unsigned int xflags)
{
uint64_t di_flags2 =
- (ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK);
+ (ip->i_d.di_flags2 & (XFS_DIFLAG2_REFLINK |
+ XFS_DIFLAG2_BIGTIME));
if (xflags & FS_XFLAG_DAX)
di_flags2 |= XFS_DIFLAG2_DAX;
@@ -317,8 +318,14 @@ libxfs_ialloc(
ASSERT(ip->i_d.di_ino == ino);
ASSERT(uuid_equal(&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid));
VFS_I(ip)->i_version = 1;
- ip->i_d.di_flags2 = pip ? 0 : xfs_flags2diflags2(ip,
- fsx->fsx_xflags);
+ if (pip) {
+ ip->i_d.di_flags2 = 0;
+ if (xfs_sb_version_hasbigtime(&ip->i_mount->m_sb))
+ ip->i_d.di_flags2 |= XFS_DIFLAG2_BIGTIME;
+ } else {
+ ip->i_d.di_flags2 = xfs_flags2diflags2(ip, fsx->fsx_xflags);
+ }
+
ip->i_d.di_crtime.tv_sec = (int32_t)VFS_I(ip)->i_mtime.tv_sec;
ip->i_d.di_crtime.tv_nsec = (int32_t)VFS_I(ip)->i_mtime.tv_nsec;
ip->i_d.di_cowextsize = pip ? 0 : fsx->fsx_cowextsize;
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index 371f5cd..b1f6219 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -466,6 +466,7 @@ xfs_sb_has_ro_compat_feature(
#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */
#define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */
#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */
+#define XFS_SB_FEAT_INCOMPAT_BIGTIME (1 << 3) /* large timestamps */
#define XFS_SB_FEAT_INCOMPAT_ALL \
(XFS_SB_FEAT_INCOMPAT_FTYPE| \
XFS_SB_FEAT_INCOMPAT_SPINODES| \
@@ -580,6 +581,12 @@ xfs_is_quota_inode(struct xfs_sb *sbp, xfs_ino_t ino)
#define XFS_FSB_TO_DADDR(mp,fsbno) XFS_AGB_TO_DADDR(mp, \
XFS_FSB_TO_AGNO(mp,fsbno), XFS_FSB_TO_AGBNO(mp,fsbno))
+static inline bool xfs_sb_version_hasbigtime(struct xfs_sb *sbp)
+{
+ return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 &&
+ (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_BIGTIME);
+}
+
/*
* File system sector to basic block conversions.
*/
@@ -849,6 +856,13 @@ typedef struct xfs_agfl {
* Therefore, the ondisk min and max defined here can be used directly to
* constrain the incore timestamps on a Unix system. Note that we actually
* encode a __be64 value on disk.
+ *
+ * When the bigtime feature is enabled, ondisk inode timestamps become an
+ * unsigned 64-bit nanoseconds counter. This means that the bigtime inode
+ * timestamp epoch is the start of the classic timestamp range, which is
+ * Dec 31 20:45:52 UTC 1901. Because the epochs are not the same, callers
+ * /must/ use the bigtime conversion functions when encoding and decoding raw
+ * timestamps.
*/
typedef __be64 xfs_timestamp_t;
@@ -870,6 +884,50 @@ struct xfs_legacy_timestamp {
*/
#define XFS_LEGACY_TIME_MAX ((int64_t)S32_MAX)
+/*
+ * Smallest possible ondisk seconds value with bigtime timestamps. This
+ * corresponds (after conversion to a Unix timestamp) with the traditional
+ * minimum timestamp of Dec 13 20:45:52 UTC 1901.
+ */
+#define XFS_BIGTIME_TIME_MIN ((int64_t)0)
+
+/*
+ * Largest supported ondisk seconds value with bigtime timestamps. This
+ * corresponds (after conversion to a Unix timestamp) with an incore timestamp
+ * of Jul 2 20:20:24 UTC 2486.
+ *
+ * We round down the ondisk limit so that the bigtime quota and inode max
+ * timestamps will be the same.
+ */
+#define XFS_BIGTIME_TIME_MAX ((int64_t)((-1ULL / NSEC_PER_SEC) & ~0x3ULL))
+
+/*
+ * Bigtime epoch is set exactly to the minimum time value that a traditional
+ * 32-bit timestamp can represent when using the Unix epoch as a reference.
+ * Hence the Unix epoch is at a fixed offset into the supported bigtime
+ * timestamp range.
+ *
+ * The bigtime epoch also matches the minimum value an on-disk 32-bit XFS
+ * timestamp can represent so we will not lose any fidelity in converting
+ * to/from unix and bigtime timestamps.
+ *
+ * The following conversion factor converts a seconds counter from the Unix
+ * epoch to the bigtime epoch.
+ */
+#define XFS_BIGTIME_EPOCH_OFFSET (-(int64_t)S32_MIN)
+
+/* Convert a timestamp from the Unix epoch to the bigtime epoch. */
+static inline uint64_t xfs_unix_to_bigtime(time64_t unix_seconds)
+{
+ return (uint64_t)unix_seconds + XFS_BIGTIME_EPOCH_OFFSET;
+}
+
+/* Convert a timestamp from the bigtime epoch to the Unix epoch. */
+static inline time64_t xfs_bigtime_to_unix(uint64_t ondisk_seconds)
+{
+ return (time64_t)ondisk_seconds - XFS_BIGTIME_EPOCH_OFFSET;
+}
+
/*
* On-disk inode structure.
*
@@ -1096,12 +1154,22 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
#define XFS_DIFLAG2_DAX_BIT 0 /* use DAX for this inode */
#define XFS_DIFLAG2_REFLINK_BIT 1 /* file's blocks may be shared */
#define XFS_DIFLAG2_COWEXTSIZE_BIT 2 /* copy on write extent size hint */
+#define XFS_DIFLAG2_BIGTIME_BIT 3 /* big timestamps */
+
#define XFS_DIFLAG2_DAX (1 << XFS_DIFLAG2_DAX_BIT)
#define XFS_DIFLAG2_REFLINK (1 << XFS_DIFLAG2_REFLINK_BIT)
#define XFS_DIFLAG2_COWEXTSIZE (1 << XFS_DIFLAG2_COWEXTSIZE_BIT)
+#define XFS_DIFLAG2_BIGTIME (1 << XFS_DIFLAG2_BIGTIME_BIT)
#define XFS_DIFLAG2_ANY \
- (XFS_DIFLAG2_DAX | XFS_DIFLAG2_REFLINK | XFS_DIFLAG2_COWEXTSIZE)
+ (XFS_DIFLAG2_DAX | XFS_DIFLAG2_REFLINK | XFS_DIFLAG2_COWEXTSIZE | \
+ XFS_DIFLAG2_BIGTIME)
+
+static inline bool xfs_dinode_has_bigtime(const struct xfs_dinode *dip)
+{
+ return dip->di_version >= 3 &&
+ (dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_BIGTIME));
+}
/*
* Inode number format:
diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index 4fa9852..714dba1 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -231,6 +231,7 @@ typedef struct xfs_fsop_resblks {
#define XFS_FSOP_GEOM_FLAGS_SPINODES 0x40000 /* sparse inode chunks */
#define XFS_FSOP_GEOM_FLAGS_RMAPBT 0x80000 /* reverse mapping btree */
#define XFS_FSOP_GEOM_FLAGS_REFLINK 0x100000 /* files can share blocks */
+#define XFS_FSOP_GEOM_FLAGS_BIGTIME 0x200000 /* 64-bit nsec timestamps */
/*
* Minimum and maximum sizes need for growth checks.
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index d8831a1..8cd16bf 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -195,14 +195,29 @@ xfs_imap_to_bp(
return 0;
}
+static inline struct timespec64 xfs_inode_decode_bigtime(uint64_t ts)
+{
+ struct timespec64 tv;
+ uint32_t n;
+
+ tv.tv_sec = xfs_bigtime_to_unix(div_u64_rem(ts, NSEC_PER_SEC, &n));
+ tv.tv_nsec = n;
+
+ return tv;
+}
+
/* Convert an ondisk timestamp to an incore timestamp. */
struct timespec64
xfs_inode_from_disk_ts(
+ struct xfs_dinode *dip,
const xfs_timestamp_t ts)
{
struct timespec64 tv;
struct xfs_legacy_timestamp *lts;
+ if (xfs_dinode_has_bigtime(dip))
+ return xfs_inode_decode_bigtime(be64_to_cpu(ts));
+
lts = (struct xfs_legacy_timestamp *)&ts;
tv.tv_sec = (int)be32_to_cpu(lts->t_sec);
tv.tv_nsec = (int)be32_to_cpu(lts->t_nsec);
@@ -246,9 +261,9 @@ xfs_inode_from_disk(
* a time before epoch is converted to a time long after epoch
* on 64 bit systems.
*/
- inode->i_atime = xfs_inode_from_disk_ts(from->di_atime);
- inode->i_mtime = xfs_inode_from_disk_ts(from->di_mtime);
- inode->i_ctime = xfs_inode_from_disk_ts(from->di_ctime);
+ inode->i_atime = xfs_inode_from_disk_ts(from, from->di_atime);
+ inode->i_mtime = xfs_inode_from_disk_ts(from, from->di_mtime);
+ inode->i_ctime = xfs_inode_from_disk_ts(from, from->di_ctime);
inode->i_generation = be32_to_cpu(from->di_gen);
inode->i_mode = be16_to_cpu(from->di_mode);
@@ -267,7 +282,7 @@ xfs_inode_from_disk(
if (to->di_version == 3) {
inode_set_iversion_queried(inode,
be64_to_cpu(from->di_changecount));
- to->di_crtime = xfs_inode_from_disk_ts(from->di_crtime);
+ to->di_crtime = xfs_inode_from_disk_ts(from, from->di_crtime);
to->di_flags2 = be64_to_cpu(from->di_flags2);
to->di_cowextsize = be32_to_cpu(from->di_cowextsize);
}
@@ -276,11 +291,15 @@ xfs_inode_from_disk(
/* Convert an incore timestamp to an ondisk timestamp. */
static inline xfs_timestamp_t
xfs_inode_to_disk_ts(
+ struct xfs_inode *ip,
const struct timespec64 tv)
{
struct xfs_legacy_timestamp *lts;
xfs_timestamp_t ts;
+ if (xfs_inode_has_bigtime(ip))
+ return cpu_to_be64(xfs_inode_encode_bigtime(tv));
+
lts = (struct xfs_legacy_timestamp *)&ts;
lts->t_sec = cpu_to_be32(tv.tv_sec);
lts->t_nsec = cpu_to_be32(tv.tv_nsec);
@@ -308,9 +327,9 @@ xfs_inode_to_disk(
to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
memset(to->di_pad, 0, sizeof(to->di_pad));
- to->di_atime = xfs_inode_to_disk_ts(inode->i_atime);
- to->di_mtime = xfs_inode_to_disk_ts(inode->i_mtime);
- to->di_ctime = xfs_inode_to_disk_ts(inode->i_ctime);
+ to->di_atime = xfs_inode_to_disk_ts(ip, inode->i_atime);
+ to->di_mtime = xfs_inode_to_disk_ts(ip, inode->i_mtime);
+ to->di_ctime = xfs_inode_to_disk_ts(ip, inode->i_ctime);
to->di_nlink = cpu_to_be32(inode->i_nlink);
to->di_gen = cpu_to_be32(inode->i_generation);
to->di_mode = cpu_to_be16(inode->i_mode);
@@ -328,7 +347,7 @@ xfs_inode_to_disk(
if (from->di_version == 3) {
to->di_changecount = cpu_to_be64(inode_peek_iversion(inode));
- to->di_crtime = xfs_inode_to_disk_ts(from->di_crtime);
+ to->di_crtime = xfs_inode_to_disk_ts(ip, from->di_crtime);
to->di_flags2 = cpu_to_be64(from->di_flags2);
to->di_cowextsize = cpu_to_be32(from->di_cowextsize);
to->di_ino = cpu_to_be64(ip->i_ino);
@@ -547,6 +566,11 @@ xfs_dinode_verify(
if (fa)
return fa;
+ /* bigtime iflag can only happen on bigtime filesystems */
+ if (xfs_dinode_has_bigtime(dip) &&
+ !xfs_sb_version_hasbigtime(&mp->m_sb))
+ return __this_address;
+
return NULL;
}
diff --git a/libxfs/xfs_inode_buf.h b/libxfs/xfs_inode_buf.h
index 6147f42..2b91e60 100644
--- a/libxfs/xfs_inode_buf.h
+++ b/libxfs/xfs_inode_buf.h
@@ -40,6 +40,11 @@ struct xfs_icdinode {
struct timespec64 di_crtime; /* time created */
};
+static inline bool xfs_icdinode_has_bigtime(const struct xfs_icdinode *icd)
+{
+ return icd->di_flags2 & XFS_DIFLAG2_BIGTIME;
+}
+
/*
* Inode location information. Stored in the inode and passed to
* xfs_imap_to_bp() to get a buffer and dinode for a given inode.
@@ -76,6 +81,12 @@ xfs_failaddr_t xfs_inode_validate_cowextsize(struct xfs_mount *mp,
uint32_t cowextsize, uint16_t mode, uint16_t flags,
uint64_t flags2);
-struct timespec64 xfs_inode_from_disk_ts(const xfs_timestamp_t ts);
+static inline uint64_t xfs_inode_encode_bigtime(struct timespec64 tv)
+{
+ return xfs_unix_to_bigtime(tv.tv_sec) * NSEC_PER_SEC + tv.tv_nsec;
+}
+
+struct timespec64 xfs_inode_from_disk_ts(struct xfs_dinode *dip,
+ const xfs_timestamp_t ts);
#endif /* __XFS_INODE_BUF_H__ */
diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c
index cee77a6..d11545b 100644
--- a/libxfs/xfs_sb.c
+++ b/libxfs/xfs_sb.c
@@ -1124,6 +1124,8 @@ xfs_fs_geometry(
geo->flags |= XFS_FSOP_GEOM_FLAGS_RMAPBT;
if (xfs_sb_version_hasreflink(sbp))
geo->flags |= XFS_FSOP_GEOM_FLAGS_REFLINK;
+ if (xfs_sb_version_hasbigtime(sbp))
+ geo->flags |= XFS_FSOP_GEOM_FLAGS_BIGTIME;
if (xfs_sb_version_hassector(sbp))
geo->logsectsize = sbp->sb_logsectsize;
else

View File

@ -0,0 +1,170 @@
From 06963ef0d4ff9a6736f699d1ca8ef5a0c194799b Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Thu, 12 Nov 2020 16:49:42 -0500
Subject: [PATCH] xfs: widen ondisk quota expiration timestamps to handle
y2038+
Source kernel commit: 4ea1ff3b49681af45a4a8c14baf7f0b3d11aa74a
Enable the bigtime feature for quota timers. We decrease the accuracy
of the timers to ~4s in exchange for being able to set timers up to the
bigtime maximum.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Allison Collins <allison.henderson@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
NOTE: Again, slightly different macro names due to lack of the
quota type/flags split.
diff --git a/include/xfs_mount.h b/include/xfs_mount.h
index 8651d6a..beb2328 100644
--- a/include/xfs_mount.h
+++ b/include/xfs_mount.h
@@ -202,4 +202,8 @@ extern xfs_mount_t *libxfs_mount (xfs_mount_t *, xfs_sb_t *,
extern void libxfs_umount (xfs_mount_t *);
extern void libxfs_rtmount_destroy (xfs_mount_t *);
+/* Dummy xfs_dquot so that libxfs compiles. */
+struct xfs_dquot {
+ int q_type;
+};
#endif /* __XFS_MOUNT_H__ */
diff --git a/libxfs/xfs_dquot_buf.c b/libxfs/xfs_dquot_buf.c
index 963f8ea..db93dda 100644
--- a/libxfs/xfs_dquot_buf.c
+++ b/libxfs/xfs_dquot_buf.c
@@ -69,6 +69,13 @@ xfs_dquot_verify(
ddq_type != XFS_DQ_GROUP)
return __this_address;
+ if ((ddq->d_flags & XFS_DQ_BIGTIME) &&
+ !xfs_sb_version_hasbigtime(&mp->m_sb))
+ return __this_address;
+
+ if ((ddq->d_flags & XFS_DQ_BIGTIME) && !ddq->d_id)
+ return __this_address;
+
if (id != -1 && id != be32_to_cpu(ddq->d_id))
return __this_address;
@@ -293,7 +300,12 @@ xfs_dquot_from_disk_ts(
struct xfs_disk_dquot *ddq,
__be32 dtimer)
{
- return be32_to_cpu(dtimer);
+ uint32_t t = be32_to_cpu(dtimer);
+
+ if (t != 0 && (ddq->d_flags & XFS_DQ_BIGTIME))
+ return xfs_dq_bigtime_to_unix(t);
+
+ return t;
}
/* Convert an incore timer value into an on-disk timer value. */
@@ -302,5 +314,10 @@ xfs_dquot_to_disk_ts(
struct xfs_dquot *dqp,
time64_t timer)
{
- return cpu_to_be32(timer);
+ uint32_t t = timer;
+
+ if (timer != 0 && (dqp->q_type & XFS_DQ_BIGTIME))
+ t = xfs_dq_unix_to_bigtime(timer);
+
+ return cpu_to_be32(t);
}
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index b1f6219..9ba65e5 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -1263,6 +1263,10 @@ static inline bool xfs_dinode_has_bigtime(const struct xfs_dinode *dip)
* ondisk min and max defined here can be used directly to constrain the incore
* quota expiration timestamps on a Unix system.
*
+ * When bigtime is enabled, we trade two bits of precision to expand the
+ * expiration timeout range to match that of big inode timestamps. The min and
+ * max recorded here are the on-disk limits, not a Unix timestamp.
+ *
* The grace period for each quota type is stored in the root dquot (id = 0)
* and is applied to a non-root dquot when it exceeds the soft or hard limits.
* The length of quota grace periods are unsigned 32-bit quantities measured in
@@ -1281,6 +1285,48 @@ static inline bool xfs_dinode_has_bigtime(const struct xfs_dinode *dip)
*/
#define XFS_DQ_LEGACY_EXPIRY_MAX ((int64_t)U32_MAX)
+/*
+ * Smallest possible ondisk quota expiration value with bigtime timestamps.
+ * This corresponds (after conversion to a Unix timestamp) with the incore
+ * expiration of Jan 1 00:00:04 UTC 1970.
+ */
+#define XFS_DQ_BIGTIME_EXPIRY_MIN (XFS_DQ_LEGACY_EXPIRY_MIN)
+
+/*
+ * Largest supported ondisk quota expiration value with bigtime timestamps.
+ * This corresponds (after conversion to a Unix timestamp) with an incore
+ * expiration of Jul 2 20:20:24 UTC 2486.
+ *
+ * The ondisk field supports values up to -1U, which corresponds to an incore
+ * expiration in 2514. This is beyond the maximum the bigtime inode timestamp,
+ * so we cap the maximum bigtime quota expiration to the max inode timestamp.
+ */
+#define XFS_DQ_BIGTIME_EXPIRY_MAX ((int64_t)4074815106U)
+
+/*
+ * The following conversion factors assist in converting a quota expiration
+ * timestamp between the incore and ondisk formats.
+ */
+#define XFS_DQ_BIGTIME_SHIFT (2)
+#define XFS_DQ_BIGTIME_SLACK ((int64_t)(1ULL << XFS_DQ_BIGTIME_SHIFT) - 1)
+
+/* Convert an incore quota expiration timestamp to an ondisk bigtime value. */
+static inline uint32_t xfs_dq_unix_to_bigtime(time64_t unix_seconds)
+{
+ /*
+ * Round the expiration timestamp up to the nearest bigtime timestamp
+ * that we can store, to give users the most time to fix problems.
+ */
+ return ((uint64_t)unix_seconds + XFS_DQ_BIGTIME_SLACK) >>
+ XFS_DQ_BIGTIME_SHIFT;
+}
+
+/* Convert an ondisk bigtime quota expiration value to an incore timestamp. */
+static inline time64_t xfs_dq_bigtime_to_unix(uint32_t ondisk_seconds)
+{
+ return (time64_t)ondisk_seconds << XFS_DQ_BIGTIME_SHIFT;
+}
+
/*
* Default quota grace periods, ranging from zero (use the compiled defaults)
* to ~136 years. These are applied to a non-root dquot that has exceeded
diff --git a/libxfs/xfs_quota_defs.h b/libxfs/xfs_quota_defs.h
index 2f61cd3..70d89cc 100644
--- a/libxfs/xfs_quota_defs.h
+++ b/libxfs/xfs_quota_defs.h
@@ -28,17 +28,20 @@ typedef uint16_t xfs_qwarncnt_t;
#define XFS_DQ_GROUP 0x0004 /* a group quota */
#define XFS_DQ_DIRTY 0x0008 /* dquot is dirty */
#define XFS_DQ_FREEING 0x0010 /* dquot is being torn down */
+#define XFS_DQ_BIGTIME 0x0080 /* large expiry timestamps */
#define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
-#define XFS_DQTYPE_ANY (XFS_DQ_ALLTYPES)
+#define XFS_DQTYPE_ANY (XFS_DQ_ALLTYPES | \
+ XFS_DQ_BIGTIME)
#define XFS_DQ_FLAGS \
{ XFS_DQ_USER, "USER" }, \
{ XFS_DQ_PROJ, "PROJ" }, \
{ XFS_DQ_GROUP, "GROUP" }, \
{ XFS_DQ_DIRTY, "DIRTY" }, \
- { XFS_DQ_FREEING, "FREEING" }
+ { XFS_DQ_FREEING, "FREEING" }, \
+ { XFS_DQ_BIGTIME, "BIGTIME" }
/*
* We have the possibility of all three quota types being active at once, and

View File

@ -0,0 +1,122 @@
From a9a32fcb9176c82aed6d85f209e7279b76c8b55f Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 20 Nov 2020 17:03:28 -0500
Subject: [PATCH] xfs_db: refactor quota timer printing
Introduce type-specific printing functions to xfs_db to print a quota
timer instead of printing a raw int32 value. This is needed to stay
ahead of changes that we're going to make to the quota timer format in
the following patches.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/db/dquot.c b/db/dquot.c
index dd9e83f..5c82456 100644
--- a/db/dquot.c
+++ b/db/dquot.c
@@ -60,8 +60,8 @@ const field_t disk_dquot_flds[] = {
TYP_NONE },
{ "bcount", FLDT_QCNT, OI(DOFF(bcount)), C1, 0, TYP_NONE },
{ "icount", FLDT_QCNT, OI(DOFF(icount)), C1, 0, TYP_NONE },
- { "itimer", FLDT_INT32D, OI(DOFF(itimer)), C1, 0, TYP_NONE },
- { "btimer", FLDT_INT32D, OI(DOFF(btimer)), C1, 0, TYP_NONE },
+ { "itimer", FLDT_QTIMER, OI(DOFF(itimer)), C1, 0, TYP_NONE },
+ { "btimer", FLDT_QTIMER, OI(DOFF(btimer)), C1, 0, TYP_NONE },
{ "iwarns", FLDT_QWARNCNT, OI(DOFF(iwarns)), C1, 0, TYP_NONE },
{ "bwarns", FLDT_QWARNCNT, OI(DOFF(bwarns)), C1, 0, TYP_NONE },
{ "pad0", FLDT_UINT32X, OI(DOFF(pad0)), C1, FLD_SKIPALL, TYP_NONE },
@@ -70,7 +70,7 @@ const field_t disk_dquot_flds[] = {
{ "rtb_softlimit", FLDT_QCNT, OI(DOFF(rtb_softlimit)), C1, 0,
TYP_NONE },
{ "rtbcount", FLDT_QCNT, OI(DOFF(rtbcount)), C1, 0, TYP_NONE },
- { "rtbtimer", FLDT_INT32D, OI(DOFF(rtbtimer)), C1, 0, TYP_NONE },
+ { "rtbtimer", FLDT_QTIMER, OI(DOFF(rtbtimer)), C1, 0, TYP_NONE },
{ "rtbwarns", FLDT_QWARNCNT, OI(DOFF(rtbwarns)), C1, 0, TYP_NONE },
{ "pad", FLDT_UINT16X, OI(DOFF(pad)), C1, FLD_SKIPALL, TYP_NONE },
{ NULL }
diff --git a/db/field.c b/db/field.c
index a187a72..770acda 100644
--- a/db/field.c
+++ b/db/field.c
@@ -351,6 +351,8 @@ const ftattr_t ftattrtab[] = {
FTARG_SIGNED, NULL, NULL },
{ FLDT_TIMESTAMP, "timestamp", NULL, (char *)timestamp_flds,
SI(bitsz(xfs_timestamp_t)), 0, NULL, timestamp_flds },
+ { FLDT_QTIMER, "qtimer", fp_qtimer, NULL, SI(bitsz(uint32_t)), 0,
+ NULL, NULL },
{ FLDT_UINT1, "uint1", fp_num, "%u", SI(1), 0, NULL, NULL },
{ FLDT_UINT16D, "uint16d", fp_num, "%u", SI(bitsz(uint16_t)), 0, NULL,
NULL },
diff --git a/db/field.h b/db/field.h
index 1506537..387c189 100644
--- a/db/field.h
+++ b/db/field.h
@@ -170,6 +170,7 @@ typedef enum fldt {
FLDT_TIME,
FLDT_TIMESTAMP,
+ FLDT_QTIMER,
FLDT_UINT1,
FLDT_UINT16D,
FLDT_UINT16O,
diff --git a/db/fprint.c b/db/fprint.c
index 6e72bf0..72ed55f 100644
--- a/db/fprint.c
+++ b/db/fprint.c
@@ -180,6 +180,40 @@ fp_nsec(
return 1;
}
+int
+fp_qtimer(
+ void *obj,
+ int bit,
+ int count,
+ char *fmtstr,
+ int size,
+ int arg,
+ int base,
+ int array)
+{
+ uint32_t sec;
+ __be32 *t;
+ int bitpos;
+ int i;
+
+ ASSERT(bitoffs(bit) == 0);
+ for (i = 0, bitpos = bit;
+ i < count && !seenint();
+ i++, bitpos += size) {
+ if (array)
+ dbprintf("%d:", i + base);
+
+ t = obj + byteize(bitpos);
+ sec = be32_to_cpu(*t);
+
+ dbprintf("%u", sec);
+
+ if (i < count - 1)
+ dbprintf(" ");
+ }
+ return 1;
+}
+
/*ARGSUSED*/
int
fp_uuid(
diff --git a/db/fprint.h b/db/fprint.h
index bfeed15..a1ea935 100644
--- a/db/fprint.h
+++ b/db/fprint.h
@@ -17,6 +17,8 @@ extern int fp_time(void *obj, int bit, int count, char *fmtstr, int size,
int arg, int base, int array);
extern int fp_nsec(void *obj, int bit, int count, char *fmtstr, int size,
int arg, int base, int array);
+extern int fp_qtimer(void *obj, int bit, int count, char *fmtstr, int size,
+ int arg, int base, int array);
extern int fp_uuid(void *obj, int bit, int count, char *fmtstr, int size,
int arg, int base, int array);
extern int fp_crc(void *obj, int bit, int count, char *fmtstr, int size,

View File

@ -0,0 +1,176 @@
From 300422226c423222e78d82d54b09d0ae27c7d4af Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 20 Nov 2020 17:03:27 -0500
Subject: [PATCH] xfs_db: refactor timestamp printing
Introduce type-specific printing functions to xfs_db to print an
xfs_timestamp instead of open-coding the timestamp decoding. This is
needed to stay ahead of changes that we're going to make to
xfs_timestamp_t in the following patches.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/db/field.c b/db/field.c
index 4a45c66..a187a72 100644
--- a/db/field.c
+++ b/db/field.c
@@ -334,8 +334,8 @@ const ftattr_t ftattrtab[] = {
FTARG_SIGNED, NULL, NULL },
{ FLDT_INT8D, "int8d", fp_num, "%d", SI(bitsz(int8_t)), FTARG_SIGNED,
NULL, NULL },
- { FLDT_NSEC, "nsec", fp_num, "%09d", SI(bitsz(int32_t)), FTARG_SIGNED,
- NULL, NULL },
+ { FLDT_NSEC, "nsec", fp_nsec, NULL, SI(bitsz(xfs_timestamp_t)),
+ FTARG_SIGNED, NULL, NULL },
{ FLDT_QCNT, "qcnt", fp_num, "%llu", SI(bitsz(xfs_qcnt_t)), 0, NULL,
NULL },
{ FLDT_QWARNCNT, "qwarncnt", fp_num, "%u", SI(bitsz(xfs_qwarncnt_t)), 0,
@@ -347,10 +347,10 @@ const ftattr_t ftattrtab[] = {
{ FLDT_SYMLINK_CRC, "symlink", NULL, (char *)symlink_crc_flds,
symlink_size, FTARG_SIZE, NULL, symlink_crc_flds },
- { FLDT_TIME, "time", fp_time, NULL, SI(bitsz(int32_t)), FTARG_SIGNED,
- NULL, NULL },
+ { FLDT_TIME, "time", fp_time, NULL, SI(bitsz(xfs_timestamp_t)),
+ FTARG_SIGNED, NULL, NULL },
{ FLDT_TIMESTAMP, "timestamp", NULL, (char *)timestamp_flds,
- SI(bitsz(struct xfs_legacy_timestamp)), 0, NULL, timestamp_flds },
+ SI(bitsz(xfs_timestamp_t)), 0, NULL, timestamp_flds },
{ FLDT_UINT1, "uint1", fp_num, "%u", SI(1), 0, NULL, NULL },
{ FLDT_UINT16D, "uint16d", fp_num, "%u", SI(bitsz(uint16_t)), 0, NULL,
NULL },
diff --git a/db/fprint.c b/db/fprint.c
index c9d07e1..6e72bf0 100644
--- a/db/fprint.c
+++ b/db/fprint.c
@@ -112,22 +112,21 @@ fp_sarray(
return 1;
}
-/*ARGSUSED*/
int
fp_time(
- void *obj,
- int bit,
- int count,
- char *fmtstr,
- int size,
- int arg,
- int base,
- int array)
+ void *obj,
+ int bit,
+ int count,
+ char *fmtstr,
+ int size,
+ int arg,
+ int base,
+ int array)
{
- int bitpos;
- char *c;
- int i;
- time_t t;
+ struct timespec64 tv;
+ xfs_timestamp_t *ts;
+ int bitpos;
+ int i;
ASSERT(bitoffs(bit) == 0);
for (i = 0, bitpos = bit;
@@ -135,10 +134,46 @@ fp_time(
i++, bitpos += size) {
if (array)
dbprintf("%d:", i + base);
- t = (time_t)getbitval((char *)obj + byteize(bitpos), 0,
- sizeof(int32_t) * 8, BVSIGNED);
- c = ctime(&t);
- dbprintf("%24.24s", c);
+
+ ts = obj + byteize(bitpos);
+ tv = libxfs_inode_from_disk_ts(obj, *ts);
+
+ dbprintf("%24.24s", tv.tv_sec);
+
+ if (i < count - 1)
+ dbprintf(" ");
+ }
+ return 1;
+}
+
+int
+fp_nsec(
+ void *obj,
+ int bit,
+ int count,
+ char *fmtstr,
+ int size,
+ int arg,
+ int base,
+ int array)
+{
+ struct timespec64 tv;
+ xfs_timestamp_t *ts;
+ int bitpos;
+ int i;
+
+ ASSERT(bitoffs(bit) == 0);
+ for (i = 0, bitpos = bit;
+ i < count && !seenint();
+ i++, bitpos += size) {
+ if (array)
+ dbprintf("%d:", i + base);
+
+ ts = obj + byteize(bitpos);
+ tv = libxfs_inode_from_disk_ts(obj, *ts);
+
+ dbprintf("%u", tv.tv_nsec);
+
if (i < count - 1)
dbprintf(" ");
}
diff --git a/db/fprint.h b/db/fprint.h
index c958dca..bfeed15 100644
--- a/db/fprint.h
+++ b/db/fprint.h
@@ -15,6 +15,8 @@ extern int fp_sarray(void *obj, int bit, int count, char *fmtstr, int size,
int arg, int base, int array);
extern int fp_time(void *obj, int bit, int count, char *fmtstr, int size,
int arg, int base, int array);
+extern int fp_nsec(void *obj, int bit, int count, char *fmtstr, int size,
+ int arg, int base, int array);
extern int fp_uuid(void *obj, int bit, int count, char *fmtstr, int size,
int arg, int base, int array);
extern int fp_crc(void *obj, int bit, int count, char *fmtstr, int size,
diff --git a/db/inode.c b/db/inode.c
index b308538..bbfee74 100644
--- a/db/inode.c
+++ b/db/inode.c
@@ -176,10 +176,9 @@ const field_t inode_v3_flds[] = {
};
-#define TOFF(f) bitize(offsetof(struct xfs_legacy_timestamp, t_ ## f))
const field_t timestamp_flds[] = {
- { "sec", FLDT_TIME, OI(TOFF(sec)), C1, 0, TYP_NONE },
- { "nsec", FLDT_NSEC, OI(TOFF(nsec)), C1, 0, TYP_NONE },
+ { "sec", FLDT_TIME, OI(0), C1, 0, TYP_NONE },
+ { "nsec", FLDT_NSEC, OI(0), C1, 0, TYP_NONE },
{ NULL }
};
diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index f4f7626..00f367e 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -89,6 +89,7 @@
#define xfs_da_get_buf libxfs_da_get_buf
#define xfs_inode_from_disk libxfs_inode_from_disk
+#define xfs_inode_from_disk_ts libxfs_inode_from_disk_ts
#define xfs_inode_to_disk libxfs_inode_to_disk
#define xfs_dinode_calc_crc libxfs_dinode_calc_crc
#define xfs_idata_realloc libxfs_idata_realloc

View File

@ -0,0 +1,122 @@
From 344f38a9e5d0f938dae337c8c769853e6368d480 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 20 Nov 2020 17:03:28 -0500
Subject: [PATCH] xfs_db: report bigtime format timestamps
Report the large format timestamps in a human-readable manner if it is
possible to do so without loss of information.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/db/fprint.c b/db/fprint.c
index 72ed55f..65accfd 100644
--- a/db/fprint.c
+++ b/db/fprint.c
@@ -112,6 +112,35 @@ fp_sarray(
return 1;
}
+static void
+fp_time64(
+ time64_t sec)
+{
+ time_t tt = sec;
+ time64_t tt_sec = tt;
+ char *c;
+
+ /*
+ * Stupid time_t shenanigans -- POSIX.1-2017 only requires that this
+ * type represent a time in seconds. Since we have no idea if our
+ * time64_t filesystem timestamps can actually be represented by the C
+ * library, we resort to converting the input value from time64_t to
+ * time_t and back to time64_t to check for information loss. If so,
+ * we print the raw value; otherwise we print a human-readable value.
+ */
+ if (tt_sec != sec)
+ goto raw;
+
+ c = ctime(&tt);
+ if (!c)
+ goto raw;
+
+ dbprintf("%24.24s", c);
+ return;
+raw:
+ dbprintf("%lld", sec);
+}
+
int
fp_time(
void *obj,
@@ -138,7 +167,7 @@ fp_time(
ts = obj + byteize(bitpos);
tv = libxfs_inode_from_disk_ts(obj, *ts);
- dbprintf("%24.24s", tv.tv_sec);
+ fp_time64(tv.tv_sec);
if (i < count - 1)
dbprintf(" ");
@@ -191,7 +220,8 @@ fp_qtimer(
int base,
int array)
{
- uint32_t sec;
+ struct xfs_disk_dquot *ddq = obj;
+ time64_t sec;
__be32 *t;
int bitpos;
int i;
@@ -204,9 +234,16 @@ fp_qtimer(
dbprintf("%d:", i + base);
t = obj + byteize(bitpos);
- sec = be32_to_cpu(*t);
+ sec = libxfs_dquot_from_disk_ts(ddq, *t);
- dbprintf("%u", sec);
+ /*
+ * Display the raw value if it's the default grace expiration
+ * period (root dquot) or if the quota has not expired.
+ */
+ if (ddq->d_id == 0 || sec == 0)
+ dbprintf("%lld", sec);
+ else
+ fp_time64(sec);
if (i < count - 1)
dbprintf(" ");
diff --git a/db/inode.c b/db/inode.c
index bbfee74..37c7dc0 100644
--- a/db/inode.c
+++ b/db/inode.c
@@ -172,10 +172,12 @@ const field_t inode_v3_flds[] = {
{ "cowextsz", FLDT_UINT1,
OI(COFF(flags2) + bitsz(uint64_t) - XFS_DIFLAG2_COWEXTSIZE_BIT-1), C1,
0, TYP_NONE },
+ { "bigtime", FLDT_UINT1,
+ OI(COFF(flags2) + bitsz(uint64_t) - XFS_DIFLAG2_BIGTIME_BIT - 1), C1,
+ 0, TYP_NONE },
{ NULL }
};
-
const field_t timestamp_flds[] = {
{ "sec", FLDT_TIME, OI(0), C1, 0, TYP_NONE },
{ "nsec", FLDT_NSEC, OI(0), C1, 0, TYP_NONE },
diff --git a/db/sb.c b/db/sb.c
index d63fc71..109fdc3 100644
--- a/db/sb.c
+++ b/db/sb.c
@@ -689,6 +689,8 @@ version_string(
strcat(s, ",REFLINK");
if (xfs_sb_version_hasinobtcounts(sbp))
strcat(s, ",INOBTCNT");
+ if (xfs_sb_version_hasbigtime(sbp))
+ strcat(s, ",BIGTIME");
return s;
}

View File

@ -0,0 +1,39 @@
From 13b8917251601e06660ed6ebe6bdeafa4c431ca3 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 20 Nov 2020 17:03:27 -0500
Subject: [PATCH] xfs_db: support displaying inode btree block counts in AGI
header
Fix up xfs_db to support displaying the btree block counts.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/db/agi.c b/db/agi.c
index bf21b2d..cfb4f7b 100644
--- a/db/agi.c
+++ b/db/agi.c
@@ -48,6 +48,8 @@ const field_t agi_flds[] = {
{ "lsn", FLDT_UINT64X, OI(OFF(lsn)), C1, 0, TYP_NONE },
{ "free_root", FLDT_AGBLOCK, OI(OFF(free_root)), C1, 0, TYP_FINOBT },
{ "free_level", FLDT_UINT32D, OI(OFF(free_level)), C1, 0, TYP_NONE },
+ { "ino_blocks", FLDT_UINT32D, OI(OFF(iblocks)), C1, 0, TYP_NONE },
+ { "fino_blocks", FLDT_UINT32D, OI(OFF(fblocks)), C1, 0, TYP_NONE },
{ NULL }
};
diff --git a/db/sb.c b/db/sb.c
index 5059b26..d63fc71 100644
--- a/db/sb.c
+++ b/db/sb.c
@@ -687,6 +687,8 @@ version_string(
strcat(s, ",RMAPBT");
if (xfs_sb_version_hasreflink(sbp))
strcat(s, ",REFLINK");
+ if (xfs_sb_version_hasinobtcounts(sbp))
+ strcat(s, ",INOBTCNT");
return s;
}

View File

@ -0,0 +1,245 @@
From 4893718570dac172f639cc5e8687e782c4f759ee Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 20 Nov 2020 17:03:28 -0500
Subject: [PATCH] xfs_db: support printing time limits
Support printing the minimum and maxium timestamp limits on this
filesystem.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/db/Makefile b/db/Makefile
index 8fecfc1..68ab659 100644
--- a/db/Makefile
+++ b/db/Makefile
@@ -14,7 +14,7 @@ HFILES = addr.h agf.h agfl.h agi.h attr.h attrshort.h bit.h block.h bmap.h \
io.h logformat.h malloc.h metadump.h output.h print.h quit.h sb.h \
sig.h strvec.h text.h type.h write.h attrset.h symlink.h fsmap.h \
fuzz.h
-CFILES = $(HFILES:.h=.c) btdump.c info.c
+CFILES = $(HFILES:.h=.c) btdump.c info.c timelimit.c
LSRCFILES = xfs_admin.sh xfs_ncheck.sh xfs_metadump.sh
LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBFROG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD)
diff --git a/db/command.c b/db/command.c
index c7c5234..73b06a7 100644
--- a/db/command.c
+++ b/db/command.c
@@ -139,4 +139,5 @@ init_commands(void)
write_init();
dquot_init();
fuzz_init();
+ timelimit_init();
}
diff --git a/db/command.h b/db/command.h
index eacfd46..1a9b4d2 100644
--- a/db/command.h
+++ b/db/command.h
@@ -30,3 +30,4 @@ extern void init_commands(void);
extern void btdump_init(void);
extern void info_init(void);
+extern void timelimit_init(void);
diff --git a/db/timelimit.c b/db/timelimit.c
new file mode 100644
index 0000000..53a0a39
--- /dev/null
+++ b/db/timelimit.c
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2020 Oracle. All Rights Reserved.
+ * Author: Darrick J. Wong <darrick.wong@oracle.com>
+ */
+#include "libxfs.h"
+#include "command.h"
+#include "output.h"
+#include "init.h"
+
+enum show_what {
+ SHOW_AUTO,
+ SHOW_CLASSIC,
+ SHOW_BIGTIME,
+};
+
+
+enum print_how {
+ PRINT_RAW,
+ PRINT_PRETTY,
+ PRINT_COMPACT,
+};
+
+static void
+show_limit(
+ const char *tag,
+ int64_t limit,
+ enum print_how how)
+{
+ if (how == PRINT_COMPACT) {
+ dbprintf("%" PRId64 " ", limit);
+ return;
+ }
+
+ if (how == PRINT_PRETTY && limit <= LONG_MAX && limit >= LONG_MIN) {
+ time_t tt = limit;
+ char *c;
+
+ c = ctime(&tt);
+ if (c) {
+ dbprintf("%s = %24.24s\n", tag, c);
+ return;
+ }
+ }
+
+ dbprintf("%s = %" PRId64 "\n", tag, limit);
+}
+
+static void
+show_limits(
+ enum show_what whatkind,
+ enum print_how how)
+{
+ enum print_how grace_how = how;
+
+ switch (whatkind) {
+ case SHOW_AUTO:
+ /* should never get here */
+ break;
+ case SHOW_CLASSIC:
+ show_limit("time.min", XFS_LEGACY_TIME_MIN, how);
+ show_limit("time.max", XFS_LEGACY_TIME_MAX, how);
+ show_limit("dqtimer.min", XFS_DQ_LEGACY_EXPIRY_MIN, how);
+ show_limit("dqtimer.max", XFS_DQ_LEGACY_EXPIRY_MAX, how);
+ break;
+ case SHOW_BIGTIME:
+ show_limit("time.min",
+ xfs_bigtime_to_unix(XFS_BIGTIME_TIME_MIN), how);
+ show_limit("time.max",
+ xfs_bigtime_to_unix(XFS_BIGTIME_TIME_MAX), how);
+ show_limit("dqtimer.min",
+ xfs_dq_bigtime_to_unix(XFS_DQ_BIGTIME_EXPIRY_MIN),
+ how);
+ show_limit("dqtimer.max",
+ xfs_dq_bigtime_to_unix(XFS_DQ_BIGTIME_EXPIRY_MAX),
+ how);
+ break;
+ }
+
+ /* grace periods are always integers */
+ if (grace_how != PRINT_COMPACT)
+ grace_how = PRINT_RAW;
+ show_limit("dqgrace.min", XFS_DQ_GRACE_MIN, grace_how);
+ show_limit("dqgrace.min", XFS_DQ_GRACE_MAX, grace_how);
+
+ if (how == PRINT_COMPACT)
+ dbprintf("\n");
+}
+
+static int
+timelimit_f(
+ int argc,
+ char **argv)
+{
+ enum show_what whatkind = SHOW_AUTO;
+ enum print_how how = PRINT_RAW;
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ if (!strcmp("--classic", argv[i]))
+ whatkind = SHOW_CLASSIC;
+ else if (!strcmp("--bigtime", argv[i]))
+ whatkind = SHOW_BIGTIME;
+ else if (!strcmp("--pretty", argv[i]))
+ how = PRINT_PRETTY;
+ else if (!strcmp("--compact", argv[i]))
+ how = PRINT_COMPACT;
+ else {
+ dbprintf(_("%s: bad option for timelimit command\n"),
+ argv[i]);
+ return 1;
+ }
+ }
+
+ if (whatkind == SHOW_AUTO) {
+ if (xfs_sb_version_hasbigtime(&mp->m_sb))
+ whatkind = SHOW_BIGTIME;
+ else
+ whatkind = SHOW_CLASSIC;
+ }
+
+ show_limits(whatkind, how);
+ return 0;
+}
+
+static void
+timelimit_help(void)
+{
+ dbprintf(_(
+"\n"
+" Print the minimum and maximum supported values for inode timestamps,\n"
+" disk quota expiration timers, and disk quota grace periods supported\n"
+" by this filesystem.\n"
+"\n"
+" Options:\n"
+" --classic -- Force printing of the classic time limits.\n"
+" --bigtime -- Force printing of the bigtime limits.\n"
+" --pretty -- Pretty-print the time limits.\n"
+" --compact -- Print the limits in a single line.\n"
+"\n"
+));
+
+}
+
+static const cmdinfo_t timelimit_cmd = {
+ .name = "timelimit",
+ .cfunc = timelimit_f,
+ .argmin = 0,
+ .argmax = -1,
+ .canpush = 0,
+ .args = N_("[--classic|--bigtime] [--pretty]"),
+ .oneline = N_("display timestamp limits"),
+ .help = timelimit_help,
+};
+
+void
+timelimit_init(void)
+{
+ add_command(&timelimit_cmd);
+}
diff --git a/man/man8/xfs_db.8 b/man/man8/xfs_db.8
index a1ee351..f46e936 100644
--- a/man/man8/xfs_db.8
+++ b/man/man8/xfs_db.8
@@ -785,6 +785,29 @@ The possible data types are:
.BR rtsummary ", " sb ", " symlink " and " text .
See the TYPES section below for more information on these data types.
.TP
+.BI "timelimit [" OPTIONS ]
+Print the minimum and maximum supported values for inode timestamps,
+quota expiration timers, and quota grace periods supported by this
+filesystem.
+Options include:
+.RS 1.0i
+.TP 0.4i
+.B \--bigtime
+Print the time limits of an XFS filesystem with the
+.B bigtime
+feature enabled.
+.TP 0.4i
+.B \--classic
+Print the time limits of a classic XFS filesystem.
+.TP 0.4i
+.B \--compact
+Print all limits as raw values on a single line.
+.TP 0.4i
+.B \--pretty
+Print the timestamps in the current locale's date and time format instead of
+raw seconds since the Unix epoch.
+.RE
+.TP
.BI "uuid [" uuid " | " generate " | " rewrite " | " restore ]
Set the filesystem universally unique identifier (UUID).
The filesystem UUID can be used by

View File

@ -0,0 +1,199 @@
From 219285adf56da85171fa90f42714341484750856 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 20 Nov 2020 17:03:27 -0500
Subject: [PATCH] xfs_quota: convert time_to_string to use time64_t
Rework the time_to_string helper to be capable of dealing with 64-bit
timestamps.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/quota/quota.c b/quota/quota.c
index 9545cc4..8ba0995 100644
--- a/quota/quota.c
+++ b/quota/quota.c
@@ -48,6 +48,7 @@ quota_mount(
uint flags)
{
fs_disk_quota_t d;
+ time64_t timer;
char *dev = mount->fs_name;
char c[8], h[8], s[8];
uint qflags;
@@ -100,6 +101,7 @@ quota_mount(
}
if (form & XFS_BLOCK_QUOTA) {
+ timer = d.d_btimer;
qflags = (flags & HUMAN_FLAG);
if (d.d_blk_hardlimit && d.d_bcount > d.d_blk_hardlimit)
qflags |= LIMIT_FLAG;
@@ -111,16 +113,17 @@ quota_mount(
bbs_to_string(d.d_blk_softlimit, s, sizeof(s)),
bbs_to_string(d.d_blk_hardlimit, h, sizeof(h)),
d.d_bwarns,
- time_to_string(d.d_btimer, qflags));
+ time_to_string(timer, qflags));
else
fprintf(fp, " %10llu %10llu %10llu %02d %9s ",
(unsigned long long)d.d_bcount >> 1,
(unsigned long long)d.d_blk_softlimit >> 1,
(unsigned long long)d.d_blk_hardlimit >> 1,
d.d_bwarns,
- time_to_string(d.d_btimer, qflags));
+ time_to_string(timer, qflags));
}
if (form & XFS_INODE_QUOTA) {
+ timer = d.d_itimer;
qflags = (flags & HUMAN_FLAG);
if (d.d_ino_hardlimit && d.d_icount > d.d_ino_hardlimit)
qflags |= LIMIT_FLAG;
@@ -132,16 +135,17 @@ quota_mount(
num_to_string(d.d_ino_softlimit, s, sizeof(s)),
num_to_string(d.d_ino_hardlimit, h, sizeof(h)),
d.d_iwarns,
- time_to_string(d.d_itimer, qflags));
+ time_to_string(timer, qflags));
else
fprintf(fp, " %10llu %10llu %10llu %02d %9s ",
(unsigned long long)d.d_icount,
(unsigned long long)d.d_ino_softlimit,
(unsigned long long)d.d_ino_hardlimit,
d.d_iwarns,
- time_to_string(d.d_itimer, qflags));
+ time_to_string(timer, qflags));
}
if (form & XFS_RTBLOCK_QUOTA) {
+ timer = d.d_rtbtimer;
qflags = (flags & HUMAN_FLAG);
if (d.d_rtb_hardlimit && d.d_rtbcount > d.d_rtb_hardlimit)
qflags |= LIMIT_FLAG;
@@ -153,14 +157,14 @@ quota_mount(
bbs_to_string(d.d_rtb_softlimit, s, sizeof(s)),
bbs_to_string(d.d_rtb_hardlimit, h, sizeof(h)),
d.d_rtbwarns,
- time_to_string(d.d_rtbtimer, qflags));
+ time_to_string(timer, qflags));
else
fprintf(fp, " %10llu %10llu %10llu %02d %9s ",
(unsigned long long)d.d_rtbcount >> 1,
(unsigned long long)d.d_rtb_softlimit >> 1,
(unsigned long long)d.d_rtb_hardlimit >> 1,
d.d_rtbwarns,
- time_to_string(d.d_rtbtimer, qflags));
+ time_to_string(timer, qflags));
}
fprintf(fp, "%s\n", mount->fs_dir);
return 1;
diff --git a/quota/quota.h b/quota/quota.h
index b7f259e..13ae450 100644
--- a/quota/quota.h
+++ b/quota/quota.h
@@ -40,7 +40,7 @@ enum {
*/
extern char *type_to_string(uint __type);
extern char *form_to_string(uint __form);
-extern char *time_to_string(time_t __time, uint __flags);
+extern char *time_to_string(time64_t __time, uint __flags);
extern char *bbs_to_string(uint64_t __v, char *__c, uint __size);
extern char *num_to_string(uint64_t __v, char *__c, uint __size);
extern char *pct_to_string(uint64_t __v, uint64_t __t, char *__c, uint __s);
diff --git a/quota/report.c b/quota/report.c
index e6def91..2d5024e 100644
--- a/quota/report.c
+++ b/quota/report.c
@@ -330,6 +330,7 @@ report_mount(
uint flags)
{
fs_disk_quota_t d;
+ time64_t timer;
char *dev = mount->fs_name;
char c[8], h[8], s[8];
uint qflags;
@@ -397,6 +398,7 @@ report_mount(
}
if (form & XFS_BLOCK_QUOTA) {
+ timer = d.d_btimer;
qflags = (flags & HUMAN_FLAG);
if (d.d_blk_hardlimit && d.d_bcount > d.d_blk_hardlimit)
qflags |= LIMIT_FLAG;
@@ -408,16 +410,17 @@ report_mount(
bbs_to_string(d.d_blk_softlimit, s, sizeof(s)),
bbs_to_string(d.d_blk_hardlimit, h, sizeof(h)),
d.d_bwarns,
- time_to_string(d.d_btimer, qflags));
+ time_to_string(timer, qflags));
else
fprintf(fp, " %10llu %10llu %10llu %02d %9s",
(unsigned long long)d.d_bcount >> 1,
(unsigned long long)d.d_blk_softlimit >> 1,
(unsigned long long)d.d_blk_hardlimit >> 1,
d.d_bwarns,
- time_to_string(d.d_btimer, qflags));
+ time_to_string(timer, qflags));
}
if (form & XFS_INODE_QUOTA) {
+ timer = d.d_itimer;
qflags = (flags & HUMAN_FLAG);
if (d.d_ino_hardlimit && d.d_icount > d.d_ino_hardlimit)
qflags |= LIMIT_FLAG;
@@ -429,16 +432,17 @@ report_mount(
num_to_string(d.d_ino_softlimit, s, sizeof(s)),
num_to_string(d.d_ino_hardlimit, h, sizeof(h)),
d.d_iwarns,
- time_to_string(d.d_itimer, qflags));
+ time_to_string(timer, qflags));
else
fprintf(fp, " %10llu %10llu %10llu %02d %9s",
(unsigned long long)d.d_icount,
(unsigned long long)d.d_ino_softlimit,
(unsigned long long)d.d_ino_hardlimit,
d.d_iwarns,
- time_to_string(d.d_itimer, qflags));
+ time_to_string(timer, qflags));
}
if (form & XFS_RTBLOCK_QUOTA) {
+ timer = d.d_rtbtimer;
qflags = (flags & HUMAN_FLAG);
if (d.d_rtb_hardlimit && d.d_rtbcount > d.d_rtb_hardlimit)
qflags |= LIMIT_FLAG;
@@ -450,14 +454,14 @@ report_mount(
bbs_to_string(d.d_rtb_softlimit, s, sizeof(s)),
bbs_to_string(d.d_rtb_hardlimit, h, sizeof(h)),
d.d_rtbwarns,
- time_to_string(d.d_rtbtimer, qflags));
+ time_to_string(timer, qflags));
else
fprintf(fp, " %10llu %10llu %10llu %02d %9s",
(unsigned long long)d.d_rtbcount >> 1,
(unsigned long long)d.d_rtb_softlimit >> 1,
(unsigned long long)d.d_rtb_hardlimit >> 1,
d.d_rtbwarns,
- time_to_string(d.d_rtbtimer, qflags));
+ time_to_string(timer, qflags));
}
fputc('\n', fp);
return 1;
diff --git a/quota/util.c b/quota/util.c
index 50470ab..361d2a8 100644
--- a/quota/util.c
+++ b/quota/util.c
@@ -18,11 +18,12 @@
char *
time_to_string(
- time_t origin,
+ time64_t origin,
uint flags)
{
static char timestamp[32];
- time_t now, timer;
+ time64_t timer;
+ time_t now;
uint days, hours, minutes, seconds;
if (flags & ABSOLUTE_FLAG) {

View File

@ -0,0 +1,35 @@
From 0d7b09ac95e4cde766a534fdb7ea8dd46451ad53 Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sandeen@redhat.com>
Date: Fri, 4 Dec 2020 12:17:12 -0500
Subject: [PATCH] xfs_quota: document how the default quota is stored
Nowhere in the man page is the default quota described; what it
does or where it is stored. Add some brief information about this.
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>
---
man/man8/xfs_quota.8 | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/man/man8/xfs_quota.8 b/man/man8/xfs_quota.8
index dd0479cd..6ead7ee9 100644
--- a/man/man8/xfs_quota.8
+++ b/man/man8/xfs_quota.8
@@ -178,6 +178,12 @@ to a file on
where the user's quota has not been exceeded.
Then after rectifying the quota situation, the file can be moved back to the
filesystem it belongs on.
+.SS Default Quotas
+The XFS quota subsystem allows a default quota to be enforced
+for any user, group or project which does not have a quota limit
+explicitly set.
+These limits are stored in and displayed as ID 0's limits, although they
+do not actually limit ID 0.
.SH USER COMMANDS
.TP
.B print
--
2.29.2

View File

@ -0,0 +1,236 @@
From f3eb31d9c005558ce975e2806f8dc73b0ecbd7f7 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 20 Nov 2020 17:03:28 -0500
Subject: [PATCH] xfs_quota: support editing and reporting quotas with bigtime
Enhance xfs_quota to detect and report grace period expirations past
2038.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/include/xqm.h b/include/xqm.h
index 8ab1907..573441d 100644
--- a/include/xqm.h
+++ b/include/xqm.h
@@ -47,7 +47,10 @@ typedef struct fs_disk_quota {
__s32 d_btimer; /* similar to above; for disk blocks */
__u16 d_iwarns; /* # warnings issued wrt num inodes */
__u16 d_bwarns; /* # warnings issued wrt disk blocks */
- __s32 d_padding2; /* padding2 - for future use */
+ __s8 d_itimer_hi; /* upper 8 bits of timer values */
+ __s8 d_btimer_hi;
+ __s8 d_rtbtimer_hi;
+ __s8 d_padding2; /* padding2 - for future use */
__u64 d_rtb_hardlimit;/* absolute limit on realtime blks */
__u64 d_rtb_softlimit;/* preferred limit on RT disk blks */
__u64 d_rtbcount; /* # realtime blocks owned */
@@ -93,6 +96,21 @@ typedef struct fs_disk_quota {
#define FS_DQ_RTBWARNS (1<<11)
#define FS_DQ_WARNS_MASK (FS_DQ_BWARNS | FS_DQ_IWARNS | FS_DQ_RTBWARNS)
+/*
+ * Accounting values. These can only be set for filesystem with
+ * non-transactional quotas that require quotacheck(8) in userspace.
+ */
+#define FS_DQ_BCOUNT (1<<12)
+#define FS_DQ_ICOUNT (1<<13)
+#define FS_DQ_RTBCOUNT (1<<14)
+#define FS_DQ_ACCT_MASK (FS_DQ_BCOUNT | FS_DQ_ICOUNT | FS_DQ_RTBCOUNT)
+
+/*
+ * Quota expiration timestamps are 40-bit signed integers, with the upper 8
+ * bits encoded in the _hi fields.
+ */
+#define FS_DQ_BIGTIME (1<<15)
+
/*
* Various flags related to quotactl(2). Only relevant to XFS filesystems.
*/
diff --git a/quota/edit.c b/quota/edit.c
index b3cad02..1a3b2d9 100644
--- a/quota/edit.c
+++ b/quota/edit.c
@@ -417,6 +417,53 @@ restore_f(
return 0;
}
+time64_t
+decode_timer(
+ const struct fs_disk_quota *d,
+ __s32 timer_lo,
+ __s8 timer_hi)
+{
+ if (d->d_fieldmask & FS_DQ_BIGTIME)
+ return (uint32_t)timer_lo | (int64_t)timer_hi << 32;
+ return timer_lo;
+}
+
+static inline void
+encode_timer(
+ const struct fs_disk_quota *d,
+ __s32 *timer_lo,
+ __s8 *timer_hi,
+ time64_t timer)
+{
+ *timer_lo = timer;
+ if (d->d_fieldmask & FS_DQ_BIGTIME)
+ *timer_hi = timer >> 32;
+ else
+ *timer_hi = 0;
+}
+
+static inline bool want_bigtime(time64_t timer)
+{
+ return timer > INT32_MAX || timer < INT32_MIN;
+}
+
+static void
+encode_timers(
+ struct fs_disk_quota *d,
+ time64_t btimer,
+ time64_t itimer,
+ time64_t rtbtimer)
+{
+ d->d_fieldmask &= ~FS_DQ_BIGTIME;
+ if (want_bigtime(btimer) || want_bigtime(itimer) ||
+ want_bigtime(rtbtimer))
+ d->d_fieldmask |= FS_DQ_BIGTIME;
+
+ encode_timer(d, &d->d_btimer, &d->d_btimer_hi, btimer);
+ encode_timer(d, &d->d_itimer, &d->d_itimer_hi, itimer);
+ encode_timer(d, &d->d_rtbtimer, &d->d_rtbtimer_hi, rtbtimer);
+}
+
static void
set_timer(
uint32_t id,
@@ -426,6 +473,7 @@ set_timer(
time64_t value)
{
struct fs_disk_quota d;
+ time64_t btimer, itimer, rtbtimer;
memset(&d, 0, sizeof(d));
@@ -446,23 +494,28 @@ set_timer(
time(&now);
+ btimer = decode_timer(&d, d.d_btimer, d.d_btimer_hi);
+ itimer = decode_timer(&d, d.d_itimer, d.d_itimer_hi);
+ rtbtimer = decode_timer(&d, d.d_rtbtimer, d.d_rtbtimer_hi);
+
/* Only set grace time if user is already past soft limit */
if (d.d_blk_softlimit && d.d_bcount > d.d_blk_softlimit)
- d.d_btimer = now + value;
+ btimer = now + value;
if (d.d_ino_softlimit && d.d_icount > d.d_ino_softlimit)
- d.d_itimer = now + value;
+ itimer = now + value;
if (d.d_rtb_softlimit && d.d_rtbcount > d.d_rtb_softlimit)
- d.d_rtbtimer = now + value;
+ rtbtimer = now + value;
} else {
- d.d_btimer = value;
- d.d_itimer = value;
- d.d_rtbtimer = value;
+ btimer = value;
+ itimer = value;
+ rtbtimer = value;
}
d.d_version = FS_DQUOT_VERSION;
d.d_flags = type;
d.d_fieldmask = mask;
d.d_id = id;
+ encode_timers(&d, btimer, itimer, rtbtimer);
if (xfsquotactl(XFS_SETQLIM, dev, type, id, (void *)&d) < 0) {
exitcode = 1;
diff --git a/quota/quota.c b/quota/quota.c
index 8ba0995..0747ced 100644
--- a/quota/quota.c
+++ b/quota/quota.c
@@ -101,7 +101,7 @@ quota_mount(
}
if (form & XFS_BLOCK_QUOTA) {
- timer = d.d_btimer;
+ timer = decode_timer(&d, d.d_btimer, d.d_btimer_hi);
qflags = (flags & HUMAN_FLAG);
if (d.d_blk_hardlimit && d.d_bcount > d.d_blk_hardlimit)
qflags |= LIMIT_FLAG;
@@ -123,7 +123,7 @@ quota_mount(
time_to_string(timer, qflags));
}
if (form & XFS_INODE_QUOTA) {
- timer = d.d_itimer;
+ timer = decode_timer(&d, d.d_itimer, d.d_itimer_hi);
qflags = (flags & HUMAN_FLAG);
if (d.d_ino_hardlimit && d.d_icount > d.d_ino_hardlimit)
qflags |= LIMIT_FLAG;
@@ -145,7 +145,7 @@ quota_mount(
time_to_string(timer, qflags));
}
if (form & XFS_RTBLOCK_QUOTA) {
- timer = d.d_rtbtimer;
+ timer = decode_timer(&d, d.d_rtbtimer, d.d_rtbtimer_hi);
qflags = (flags & HUMAN_FLAG);
if (d.d_rtb_hardlimit && d.d_rtbcount > d.d_rtb_hardlimit)
qflags |= LIMIT_FLAG;
diff --git a/quota/quota.h b/quota/quota.h
index 13ae450..74eb146 100644
--- a/quota/quota.h
+++ b/quota/quota.h
@@ -3,6 +3,8 @@
* Copyright (c) 2005 Silicon Graphics, Inc.
* All Rights Reserved.
*/
+#ifndef XFS_QUOTA_QUOTA_H_
+#define XFS_QUOTA_QUOTA_H_
#include "xqm.h"
#include "path.h"
@@ -73,3 +75,8 @@ extern char *uid_to_name(uint32_t __uid);
extern char *gid_to_name(uint32_t __gid);
extern char *prid_to_name(uint32_t __prid);
extern bool isdigits_only(const char *);
+
+time64_t decode_timer(const struct fs_disk_quota *d, __s32 timer_lo,
+ __s8 timer_hi);
+
+#endif /* XFS_QUOTA_QUOTA_H_ */
diff --git a/quota/report.c b/quota/report.c
index 2d5024e..6ac5549 100644
--- a/quota/report.c
+++ b/quota/report.c
@@ -398,7 +398,7 @@ report_mount(
}
if (form & XFS_BLOCK_QUOTA) {
- timer = d.d_btimer;
+ timer = decode_timer(&d, d.d_btimer, d.d_btimer_hi);
qflags = (flags & HUMAN_FLAG);
if (d.d_blk_hardlimit && d.d_bcount > d.d_blk_hardlimit)
qflags |= LIMIT_FLAG;
@@ -420,7 +420,7 @@ report_mount(
time_to_string(timer, qflags));
}
if (form & XFS_INODE_QUOTA) {
- timer = d.d_itimer;
+ timer = decode_timer(&d, d.d_itimer, d.d_itimer_hi);
qflags = (flags & HUMAN_FLAG);
if (d.d_ino_hardlimit && d.d_icount > d.d_ino_hardlimit)
qflags |= LIMIT_FLAG;
@@ -442,7 +442,7 @@ report_mount(
time_to_string(timer, qflags));
}
if (form & XFS_RTBLOCK_QUOTA) {
- timer = d.d_rtbtimer;
+ timer = decode_timer(&d, d.d_rtbtimer, d.d_rtbtimer_hi);
qflags = (flags & HUMAN_FLAG);
if (d.d_rtb_hardlimit && d.d_rtbcount > d.d_rtb_hardlimit)
qflags |= LIMIT_FLAG;

View File

@ -0,0 +1,92 @@
xfs_repair: Use proper min/max values in compute_level_geometry
When compute_level_geometry was added it exclusively uses
m_alloc_mnr/m_alloc_mxr but the rmap btree should be using
m_rmap_mnr/m_rmap_mxr. Pass those in directly to fix the
problem.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---
diff --git a/repair/phase5.c b/repair/phase5.c
index 0b8a55ff..dff342c8 100644
--- a/repair/phase5.c
+++ b/repair/phase5.c
@@ -355,12 +355,12 @@ compute_level_geometry(
struct bt_stat_level *lptr,
uint64_t nr_this_level,
int slack,
- bool leaf)
+ uint maxrecs,
+ uint minrecs)
{
- unsigned int maxrecs = mp->m_alloc_mxr[!leaf];
unsigned int desired_npb;
- desired_npb = max(mp->m_alloc_mnr[!leaf], maxrecs - slack);
+ desired_npb = max(minrecs, maxrecs - slack);
lptr->num_recs_tot = nr_this_level;
lptr->num_blocks = max(1ULL, nr_this_level / desired_npb);
@@ -410,7 +410,8 @@ calculate_freespace_cursor(xfs_mount_t *mp, xfs_agnumber_t agno,
* of the tree and set up the cursor for the leaf level
* (note that the same code is duplicated further down)
*/
- compute_level_geometry(mp, lptr, num_extents, 2, true);
+ compute_level_geometry(mp, lptr, num_extents, 2,
+ mp->m_alloc_mxr[0], mp->m_alloc_mnr[0]);
level = 1;
#ifdef XR_BLD_FREE_TRACE
@@ -429,7 +430,8 @@ calculate_freespace_cursor(xfs_mount_t *mp, xfs_agnumber_t agno,
lptr = &btree_curs->level[level];
compute_level_geometry(mp, lptr,
- p_lptr->num_blocks, 0, false);
+ p_lptr->num_blocks, 0,
+ mp->m_alloc_mxr[1], mp->m_alloc_mnr[1]);
#ifdef XR_BLD_FREE_TRACE
fprintf(stderr, "%s %d %d %d %d %d\n", __func__,
level,
@@ -509,7 +511,8 @@ calculate_freespace_cursor(xfs_mount_t *mp, xfs_agnumber_t agno,
* of the number of extents changing
*/
old_blocks = btree_curs->level[0].num_blocks;
- compute_level_geometry(mp, &btree_curs->level[0], num_extents, 2, true);
+ compute_level_geometry(mp, &btree_curs->level[0], num_extents, 2,
+ mp->m_alloc_mxr[0], mp->m_alloc_mnr[0]);
extra_blocks = 0;
if (old_blocks != btree_curs->level[0].num_blocks) {
@@ -578,7 +581,8 @@ calculate_freespace_cursor(xfs_mount_t *mp, xfs_agnumber_t agno,
lptr = &btree_curs->level[level++];
compute_level_geometry(mp, lptr,
- p_lptr->num_blocks, 0, false);
+ p_lptr->num_blocks, 0,
+ mp->m_alloc_mxr[1], mp->m_alloc_mnr[1]);
}
ASSERT(level < XFS_BTREE_MAXLEVELS);
ASSERT(lptr->num_blocks == 1);
@@ -1399,7 +1403,8 @@ init_rmapbt_cursor(
* metadata AG entries without too many splits.
*/
compute_level_geometry(mp, lptr, num_recs,
- num_recs > mp->m_rmap_mxr[0] ? 10 : 0, true);
+ num_recs > mp->m_rmap_mxr[0] ? 10 : 0,
+ mp->m_rmap_mxr[0], mp->m_rmap_mnr[0]);
blocks_allocated = lptr->num_blocks;
level = 1;
@@ -1408,7 +1413,8 @@ init_rmapbt_cursor(
lptr = &btree_curs->level[level++];
compute_level_geometry(mp, lptr,
- p_lptr->num_blocks, 0, false);
+ p_lptr->num_blocks, 0,
+ mp->m_rmap_mxr[1], mp->m_rmap_mnr[1]);
blocks_allocated += lptr->num_blocks;
}
ASSERT(level < XFS_BTREE_MAXLEVELS);

View File

@ -0,0 +1,98 @@
From 62c713cb0c7791717c0b2a663ff0cc72842fe6c7 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 20 Nov 2020 17:03:27 -0500
Subject: [PATCH] xfs_repair: check inode btree block counters in AGI
Make sure that both inode btree block counters in the AGI are correct.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/repair/scan.c b/repair/scan.c
index 5b76212..086a3cd 100644
--- a/repair/scan.c
+++ b/repair/scan.c
@@ -1933,6 +1933,12 @@ _("invalid inode count, inode chunk %d/%u, count %d ninodes %d\n"),
return suspect;
}
+struct ino_priv {
+ struct aghdr_cnts *agcnts;
+ uint32_t ino_blocks;
+ uint32_t fino_blocks;
+};
+
/*
* this one walks the inode btrees sucking the info there into
* the incore avl tree. We try and rescue corrupted btree records
@@ -1961,7 +1967,8 @@ scan_inobt(
void *priv,
const struct xfs_buf_ops *ops)
{
- struct aghdr_cnts *agcnts = priv;
+ struct ino_priv *ipriv = priv;
+ struct aghdr_cnts *agcnts = ipriv->agcnts;
char *name;
int i;
int numrecs;
@@ -1977,10 +1984,12 @@ scan_inobt(
case XFS_FIBT_MAGIC:
case XFS_FIBT_CRC_MAGIC:
name = "fino";
+ ipriv->fino_blocks++;
break;
case XFS_IBT_MAGIC:
case XFS_IBT_CRC_MAGIC:
name = "ino";
+ ipriv->ino_blocks++;
break;
default:
name = "(unknown)";
@@ -2320,6 +2329,9 @@ validate_agi(
xfs_agnumber_t agno,
struct aghdr_cnts *agcnts)
{
+ struct ino_priv priv = {
+ .agcnts = agcnts,
+ };
xfs_agblock_t bno;
int i;
uint32_t magic;
@@ -2329,7 +2341,7 @@ validate_agi(
magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_IBT_CRC_MAGIC
: XFS_IBT_MAGIC;
scan_sbtree(bno, be32_to_cpu(agi->agi_level),
- agno, 0, scan_inobt, 1, magic, agcnts,
+ agno, 0, scan_inobt, 1, magic, &priv,
&xfs_inobt_buf_ops);
} else {
do_warn(_("bad agbno %u for inobt root, agno %d\n"),
@@ -2342,7 +2354,7 @@ validate_agi(
magic = xfs_sb_version_hascrc(&mp->m_sb) ?
XFS_FIBT_CRC_MAGIC : XFS_FIBT_MAGIC;
scan_sbtree(bno, be32_to_cpu(agi->agi_free_level),
- agno, 0, scan_inobt, 1, magic, agcnts,
+ agno, 0, scan_inobt, 1, magic, &priv,
&xfs_inobt_buf_ops);
} else {
do_warn(_("bad agbno %u for finobt root, agno %d\n"),
@@ -2350,6 +2362,17 @@ validate_agi(
}
}
+ if (xfs_sb_version_hasinobtcounts(&mp->m_sb)) {
+ if (be32_to_cpu(agi->agi_iblocks) != priv.ino_blocks)
+ do_warn(_("bad inobt block count %u, saw %u\n"),
+ be32_to_cpu(agi->agi_iblocks),
+ priv.ino_blocks);
+ if (be32_to_cpu(agi->agi_fblocks) != priv.fino_blocks)
+ do_warn(_("bad finobt block count %u, saw %u\n"),
+ be32_to_cpu(agi->agi_fblocks),
+ priv.fino_blocks);
+ }
+
if (be32_to_cpu(agi->agi_count) != agcnts->agicount) {
do_warn(_("agi_count %u, counted %u in ag %u\n"),
be32_to_cpu(agi->agi_count), agcnts->agicount, agno);

View File

@ -0,0 +1,177 @@
From a4d94d6c30acac66ff82e740e2dcb95736d7d195 Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sandeen@redhat.com>
Date: Tue, 26 May 2020 14:36:04 -0400
Subject: [PATCH] xfs_repair: fix progress reporting
The Fixes: commit tried to avoid a segfault in case the progress timer
went off before the first message type had been set up, but this
had the net effect of short-circuiting the pthread start routine,
and so the timer didn't get set up at all and we lost all fine-grained
progress reporting.
The initial problem occurred when log zeroing took more time than the
timer interval.
So, make a new log zeroing progress item and initialize it when we first
set up the timer thread, to be sure that if the timer goes off while we
are still zeroing the log, it will be initialized and correct.
(We can't offer fine-grained status on log zeroing, so it'll go from
zero to $LOGBLOCKS with nothing in between, but it's unlikely that log
zeroing will take so long that this really matters.)
Reported-by: Leonardo Vaz <lvaz@redhat.com>
Fixes: 7f2d6b811755 ("xfs_repair: avoid segfault if reporting progre...")
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Donald Douwsma <ddouwsma@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
Signed-off-by: Pavel Reichl <preichl@redhat.com>
---
repair/phase2.c | 6 ++++++
repair/progress.c | 35 +++++++++++++++++++----------------
repair/progress.h | 31 ++++++++++++++++---------------
3 files changed, 41 insertions(+), 31 deletions(-)
diff --git a/repair/phase2.c b/repair/phase2.c
index 40ea2f84..952ac4a5 100644
--- a/repair/phase2.c
+++ b/repair/phase2.c
@@ -120,6 +120,9 @@ zero_log(
do_error(_("failed to clear log"));
}
+ /* And we are now magically complete! */
+ PROG_RPT_INC(prog_rpt_done[0], mp->m_sb.sb_logblocks);
+
/*
* Finally, seed the max LSN from the current state of the log if this
* is a v5 filesystem.
@@ -160,7 +163,10 @@ phase2(
/* Zero log if applicable */
do_log(_(" - zero log...\n"));
+
+ set_progress_msg(PROG_FMT_ZERO_LOG, (uint64_t)mp->m_sb.sb_logblocks);
zero_log(mp);
+ print_final_rpt();
do_log(_(" - scan filesystem freespace and inode maps...\n"));
diff --git a/repair/progress.c b/repair/progress.c
index 5ee08229..e5a9c1ef 100644
--- a/repair/progress.c
+++ b/repair/progress.c
@@ -49,35 +49,37 @@ typedef struct progress_rpt_s {
static
progress_rpt_t progress_rpt_reports[] = {
-{FMT1, N_("scanning filesystem freespace"), /* 0 */
+{FMT1, N_("zeroing log"), /* 0 */
+ &rpt_fmts[FMT1], &rpt_types[TYPE_BLOCK]},
+{FMT1, N_("scanning filesystem freespace"), /* 1 */
&rpt_fmts[FMT1], &rpt_types[TYPE_AG]},
-{FMT1, N_("scanning agi unlinked lists"), /* 1 */
+{FMT1, N_("scanning agi unlinked lists"), /* 2 */
&rpt_fmts[FMT1], &rpt_types[TYPE_AG]},
-{FMT2, N_("check uncertain AG inodes"), /* 2 */
+{FMT2, N_("check uncertain AG inodes"), /* 3 */
&rpt_fmts[FMT2], &rpt_types[TYPE_AGI_BUCKET]},
-{FMT1, N_("process known inodes and inode discovery"), /* 3 */
+{FMT1, N_("process known inodes and inode discovery"), /* 4 */
&rpt_fmts[FMT1], &rpt_types[TYPE_INODE]},
-{FMT1, N_("process newly discovered inodes"), /* 4 */
+{FMT1, N_("process newly discovered inodes"), /* 5 */
&rpt_fmts[FMT1], &rpt_types[TYPE_AG]},
-{FMT1, N_("setting up duplicate extent list"), /* 5 */
+{FMT1, N_("setting up duplicate extent list"), /* 6 */
&rpt_fmts[FMT1], &rpt_types[TYPE_AG]},
-{FMT1, N_("initialize realtime bitmap"), /* 6 */
+{FMT1, N_("initialize realtime bitmap"), /* 7 */
&rpt_fmts[FMT1], &rpt_types[TYPE_BLOCK]},
-{FMT1, N_("reset realtime bitmaps"), /* 7 */
+{FMT1, N_("reset realtime bitmaps"), /* 8 */
&rpt_fmts[FMT1], &rpt_types[TYPE_AG]},
-{FMT1, N_("check for inodes claiming duplicate blocks"), /* 8 */
+{FMT1, N_("check for inodes claiming duplicate blocks"), /* 9 */
&rpt_fmts[FMT1], &rpt_types[TYPE_INODE]},
-{FMT1, N_("rebuild AG headers and trees"), /* 9 */
+{FMT1, N_("rebuild AG headers and trees"), /* 10 */
&rpt_fmts[FMT1], &rpt_types[TYPE_AG]},
-{FMT1, N_("traversing filesystem"), /* 10 */
+{FMT1, N_("traversing filesystem"), /* 12 */
&rpt_fmts[FMT1], &rpt_types[TYPE_AG]},
-{FMT2, N_("traversing all unattached subtrees"), /* 11 */
+{FMT2, N_("traversing all unattached subtrees"), /* 12 */
&rpt_fmts[FMT2], &rpt_types[TYPE_DIR]},
-{FMT2, N_("moving disconnected inodes to lost+found"), /* 12 */
+{FMT2, N_("moving disconnected inodes to lost+found"), /* 13 */
&rpt_fmts[FMT2], &rpt_types[TYPE_INODE]},
-{FMT1, N_("verify and correct link counts"), /* 13 */
+{FMT1, N_("verify and correct link counts"), /* 14 */
&rpt_fmts[FMT1], &rpt_types[TYPE_AG]},
-{FMT1, N_("verify link counts"), /* 14 */
+{FMT1, N_("verify link counts"), /* 15 */
&rpt_fmts[FMT1], &rpt_types[TYPE_AG]}
};
@@ -125,7 +127,8 @@ init_progress_rpt (void)
*/
pthread_mutex_init(&global_msgs.mutex, NULL);
- global_msgs.format = NULL;
+ /* Make sure the format is set to the first phase and not NULL */
+ global_msgs.format = &progress_rpt_reports[PROG_FMT_ZERO_LOG];
global_msgs.count = glob_agcount;
global_msgs.interval = report_interval;
global_msgs.done = prog_rpt_done;
diff --git a/repair/progress.h b/repair/progress.h
index 9de9eb72..2c1690db 100644
--- a/repair/progress.h
+++ b/repair/progress.h
@@ -8,26 +8,27 @@
#define PHASE_END 1
-#define PROG_FMT_SCAN_AG 0 /* Phase 2 */
+#define PROG_FMT_ZERO_LOG 0 /* Phase 2 */
+#define PROG_FMT_SCAN_AG 1
-#define PROG_FMT_AGI_UNLINKED 1 /* Phase 3 */
-#define PROG_FMT_UNCERTAIN 2
-#define PROG_FMT_PROCESS_INO 3
-#define PROG_FMT_NEW_INODES 4
+#define PROG_FMT_AGI_UNLINKED 2 /* Phase 3 */
+#define PROG_FMT_UNCERTAIN 3
+#define PROG_FMT_PROCESS_INO 4
+#define PROG_FMT_NEW_INODES 5
-#define PROG_FMT_DUP_EXTENT 5 /* Phase 4 */
-#define PROG_FMT_INIT_RTEXT 6
-#define PROG_FMT_RESET_RTBM 7
-#define PROG_FMT_DUP_BLOCKS 8
+#define PROG_FMT_DUP_EXTENT 6 /* Phase 4 */
+#define PROG_FMT_INIT_RTEXT 7
+#define PROG_FMT_RESET_RTBM 8
+#define PROG_FMT_DUP_BLOCKS 9
-#define PROG_FMT_REBUILD_AG 9 /* Phase 5 */
+#define PROG_FMT_REBUILD_AG 10 /* Phase 5 */
-#define PROG_FMT_TRAVERSAL 10 /* Phase 6 */
-#define PROG_FMT_TRAVERSSUB 11
-#define PROG_FMT_DISCONINODE 12
+#define PROG_FMT_TRAVERSAL 11 /* Phase 6 */
+#define PROG_FMT_TRAVERSSUB 12
+#define PROG_FMT_DISCONINODE 13
-#define PROGRESS_FMT_CORR_LINK 13 /* Phase 7 */
-#define PROGRESS_FMT_VRFY_LINK 14
+#define PROGRESS_FMT_CORR_LINK 14 /* Phase 7 */
+#define PROGRESS_FMT_VRFY_LINK 15
#define DURATION_BUF_SIZE 512
--
2.40.1

View File

@ -0,0 +1,29 @@
From 086250dc5707ee6fcfb1ee8499e7af092904a7a6 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 20 Nov 2020 17:03:27 -0500
Subject: [PATCH] xfs_repair: regenerate inode btree block counters in AGI
Reset both inode btree block counters in the AGI when rebuilding the
metadata indexes.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/repair/phase5.c b/repair/phase5.c
index ad9394d..a37d672 100644
--- a/repair/phase5.c
+++ b/repair/phase5.c
@@ -1126,6 +1126,11 @@ build_agi(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs,
agi->agi_free_level = cpu_to_be32(finobt_curs->num_levels);
}
+ if (xfs_sb_version_hasinobtcounts(&mp->m_sb)) {
+ agi->agi_iblocks = cpu_to_be32(btree_curs->num_tot_blocks);
+ agi->agi_fblocks = cpu_to_be32(finobt_curs->num_tot_blocks);
+ }
+
libxfs_writebuf(agi_buf, 0);
}

View File

@ -0,0 +1,81 @@
From 37c7dda1c20bfd2cc73679275bab2dd43e0ad9b8 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 20 Nov 2020 17:03:28 -0500
Subject: [PATCH] xfs_repair: support bigtime timestamp checking
Make sure that inodes don't have the bigtime flag set when the feature
is disabled, and don't check for overflows in the nanoseconds when
bigtime is enabled because that is no longer possible. Also make sure
that quotas don't have bigtime set erroneously.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
NOTE: we do not have quota repair in this version of xfsprogs
diff --git a/repair/dinode.c b/repair/dinode.c
index 0c40f2a..561603b 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -2213,11 +2213,15 @@ static void
check_nsec(
const char *name,
xfs_ino_t lino,
+ struct xfs_dinode *dip,
xfs_timestamp_t *ts,
int *dirty)
{
struct xfs_legacy_timestamp *t;
+ if (xfs_dinode_has_bigtime(dip))
+ return;
+
t = (struct xfs_legacy_timestamp *)ts;
if (be32_to_cpu(t->t_nsec) < NSEC_PER_SEC)
return;
@@ -2625,6 +2629,27 @@ _("bad (negative) size %" PRId64 " on inode %" PRIu64 "\n"),
flags2 &= ~XFS_DIFLAG2_COWEXTSIZE;
}
+ if (xfs_dinode_has_bigtime(dino) &&
+ !xfs_sb_version_hasbigtime(&mp->m_sb)) {
+ if (!uncertain) {
+ do_warn(
+ _("inode %" PRIu64 " is marked bigtime but file system does not support large timestamps\n"),
+ lino);
+ }
+ flags2 &= ~XFS_DIFLAG2_BIGTIME;
+
+ if (no_modify) {
+ do_warn(_("would zero timestamps.\n"));
+ } else {
+ do_warn(_("zeroing timestamps.\n"));
+ dino->di_atime = 0;
+ dino->di_mtime = 0;
+ dino->di_ctime = 0;
+ dino->di_crtime = 0;
+ *dirty = 1;
+ }
+ }
+
if (!verify_mode && flags2 != be64_to_cpu(dino->di_flags2)) {
if (!no_modify) {
do_warn(_("fixing bad flags2.\n"));
@@ -2752,11 +2777,11 @@ _("Bad CoW extent size %u on inode %" PRIu64 ", "),
}
/* nsec fields cannot be larger than 1 billion */
- check_nsec("atime", lino, &dino->di_atime, dirty);
- check_nsec("mtime", lino, &dino->di_mtime, dirty);
- check_nsec("ctime", lino, &dino->di_ctime, dirty);
+ check_nsec("atime", lino, dino, &dino->di_atime, dirty);
+ check_nsec("mtime", lino, dino, &dino->di_mtime, dirty);
+ check_nsec("ctime", lino, dino, &dino->di_ctime, dirty);
if (dino->di_version >= 3)
- check_nsec("crtime", lino, &dino->di_crtime, dirty);
+ check_nsec("crtime", lino, dino, &dino->di_crtime, dirty);
/*
* general size/consistency checks:

View File

@ -0,0 +1,38 @@
From 2c40c5a72b3cd0c4599bc84a7a8b09a496d46db3 Mon Sep 17 00:00:00 2001
From: Zorro Lang <zlang@redhat.com>
Date: Fri, 12 Feb 2021 17:23:05 -0500
Subject: [PATCH] mkfs: fix wrong inobtcount usage error output
When mkfs fails, it shows:
...
/* metadata */ [-m crc=0|1,finobt=0|1,uuid=xxx,rmapbt=0|1,reflink=0|1,\n\
inobtcnt=0|1,bigtime=0|1]\n\
...
The "inobtcnt=0|1" is wrong usage, it must be inobtcount, there's not
an alias. To avoid misadvice, fix it.
Signed-off-by: Zorro Lang <zlang@redhat.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
mkfs/xfs_mkfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 0c66255a..964299d3 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -928,7 +928,7 @@ usage( void )
fprintf(stderr, _("Usage: %s\n\
/* blocksize */ [-b size=num]\n\
/* metadata */ [-m crc=0|1,finobt=0|1,uuid=xxx,rmapbt=0|1,reflink=0|1,\n\
- inobtcnt=0|1,bigtime=0|1]\n\
+ inobtcount=0|1,bigtime=0|1]\n\
/* data subvol */ [-d agcount=n,agsize=n,file,name=xxx,size=num,\n\
(sunit=value,swidth=value|su=num,sw=num|noalign),\n\
sectsize=num\n\
--
2.27.0

View File

@ -0,0 +1,53 @@
From dcad5c60c59bfcdf4e27dc552b94591eced0a452 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <djwong@kernel.org>
Date: Thu, 15 Apr 2021 15:44:10 -0400
Subject: [PATCH] libfrog: report inobtcount in geometry
Report the inode btree counter feature in fs feature reports.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
libfrog/fsgeom.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/libfrog/fsgeom.c b/libfrog/fsgeom.c
index 14507668..4f1a1842 100644
--- a/libfrog/fsgeom.c
+++ b/libfrog/fsgeom.c
@@ -29,6 +29,7 @@ xfs_report_geom(
int rmapbt_enabled;
int reflink_enabled;
int bigtime_enabled;
+ int inobtcount;
isint = geo->logstart > 0;
lazycount = geo->flags & XFS_FSOP_GEOM_FLAGS_LAZYSB ? 1 : 0;
@@ -45,12 +46,13 @@ xfs_report_geom(
rmapbt_enabled = geo->flags & XFS_FSOP_GEOM_FLAGS_RMAPBT ? 1 : 0;
reflink_enabled = geo->flags & XFS_FSOP_GEOM_FLAGS_REFLINK ? 1 : 0;
bigtime_enabled = geo->flags & XFS_FSOP_GEOM_FLAGS_BIGTIME ? 1 : 0;
+ inobtcount = geo->flags & XFS_FSOP_GEOM_FLAGS_INOBTCNT ? 1 : 0;
printf(_(
"meta-data=%-22s isize=%-6d agcount=%u, agsize=%u blks\n"
" =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n"
" =%-22s crc=%-8u finobt=%u, sparse=%u, rmapbt=%u\n"
-" =%-22s reflink=%-4u bigtime=%u\n"
+" =%-22s reflink=%-4u bigtime=%u inobtcount=%u\n"
"data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n"
" =%-22s sunit=%-6u swidth=%u blks\n"
"naming =version %-14u bsize=%-6u ascii-ci=%d, ftype=%d\n"
@@ -60,7 +62,7 @@ xfs_report_geom(
mntpoint, geo->inodesize, geo->agcount, geo->agblocks,
"", geo->sectsize, attrversion, projid32bit,
"", crcs_enabled, finobt_enabled, spinodes, rmapbt_enabled,
- "", reflink_enabled, bigtime_enabled,
+ "", reflink_enabled, bigtime_enabled, inobtcount,
"", geo->blocksize, (unsigned long long)geo->datablocks,
geo->imaxpct,
"", geo->sunit, geo->swidth,
--
2.27.0

View File

@ -0,0 +1,29 @@
From d625f74125863304d111f5c6a0817a115f8e502d Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <djwong@kernel.org>
Date: Fri, 7 May 2021 10:42:17 -0400
Subject: [PATCH] libxfs: copy crtime correctly now that it's timespec64
The incore i_mtime and di_crtime are both timespec64 now, which means
that tv_sec is a 64-bit value. Don't cast that to int32_t when we're
creating an inode, because we'll end up truncating the creation time
incorrectly, should an xfsprogs of this vintage make it to 2039. :P
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/libxfs/util.c b/libxfs/util.c
index 7a8729f..fd4906f 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -326,8 +326,7 @@ libxfs_ialloc(
ip->i_d.di_flags2 = xfs_flags2diflags2(ip, fsx->fsx_xflags);
}
- ip->i_d.di_crtime.tv_sec = (int32_t)VFS_I(ip)->i_mtime.tv_sec;
- ip->i_d.di_crtime.tv_nsec = (int32_t)VFS_I(ip)->i_mtime.tv_nsec;
+ ip->i_d.di_crtime = VFS_I(ip)->i_mtime; /* struct copy */
ip->i_d.di_cowextsize = pip ? 0 : fsx->fsx_cowextsize;
}

View File

@ -0,0 +1,42 @@
From bdeb014153934e1d98787a9609a7532baf6a5c37 Mon Sep 17 00:00:00 2001
From: Zorro Lang <zlang@redhat.com>
Date: Tue, 6 Apr 2021 16:56:32 -0400
Subject: [PATCH] libxfs: expose inobtcount in xfs geometry
Source kernel commit: bc41fa5321f93ecbabec177f888451cfc17ad66d
As xfs supports the feature of inode btree block counters now, expose
this feature flag in xfs geometry, for userspace can check if the
inobtcnt is enabled or not.
Signed-off-by: Zorro Lang <zlang@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index 714dba1..4e4a22e 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -232,6 +232,7 @@ typedef struct xfs_fsop_resblks {
#define XFS_FSOP_GEOM_FLAGS_RMAPBT 0x80000 /* reverse mapping btree */
#define XFS_FSOP_GEOM_FLAGS_REFLINK 0x100000 /* files can share blocks */
#define XFS_FSOP_GEOM_FLAGS_BIGTIME 0x200000 /* 64-bit nsec timestamps */
+#define XFS_FSOP_GEOM_FLAGS_INOBTCNT 0x400000 /* inobt btree counter */
/*
* Minimum and maximum sizes need for growth checks.
diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c
index d11545b..6249e9a 100644
--- a/libxfs/xfs_sb.c
+++ b/libxfs/xfs_sb.c
@@ -1126,6 +1126,8 @@ xfs_fs_geometry(
geo->flags |= XFS_FSOP_GEOM_FLAGS_REFLINK;
if (xfs_sb_version_hasbigtime(sbp))
geo->flags |= XFS_FSOP_GEOM_FLAGS_BIGTIME;
+ if (xfs_sb_version_hasinobtcounts(sbp))
+ geo->flags |= XFS_FSOP_GEOM_FLAGS_INOBTCNT;
if (xfs_sb_version_hassector(sbp))
geo->logsectsize = sbp->sb_logsectsize;
else

View File

@ -0,0 +1,29 @@
From 5b9782c9317b7ac0ff942dffb667bad8502f0932 Mon Sep 17 00:00:00 2001
From: Christoph Hellwig <hch@lst.de>
Date: Wed, 30 Jun 2021 18:29:41 -0400
Subject: [PATCH] xfs: remove the unused xfs_icdinode_has_bigtime helper
Source kernel commit: 55f773380e922d3b975a7acb24331c76611cce30
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/libxfs/xfs_inode_buf.h b/libxfs/xfs_inode_buf.h
index 2b91e60..8d6737b 100644
--- a/libxfs/xfs_inode_buf.h
+++ b/libxfs/xfs_inode_buf.h
@@ -40,11 +40,6 @@ struct xfs_icdinode {
struct timespec64 di_crtime; /* time created */
};
-static inline bool xfs_icdinode_has_bigtime(const struct xfs_icdinode *icd)
-{
- return icd->di_flags2 & XFS_DIFLAG2_BIGTIME;
-}
-
/*
* Inode location information. Stored in the inode and passed to
* xfs_imap_to_bp() to get a buffer and dinode for a given inode.

View File

@ -0,0 +1,46 @@
From 59301887102cc0415c8350a5e9562fe4beb083b6 Mon Sep 17 00:00:00 2001
From: Christoph Hellwig <hch@lst.de>
Date: Wed, 30 Jun 2021 18:38:58 -0400
Subject: [PATCH] xfs: rename struct xfs_legacy_ictimestamp
Source kernel commit: 732de7dbdbd30df40a6d260a8da6fc5262039439
Rename struct xfs_legacy_ictimestamp to struct xfs_log_legacy_timestamp
as it is a type used for logging timestamps with no relationship to the
in-core inode.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h
index 85ac52c..bc26894 100644
--- a/libxfs/xfs_log_format.h
+++ b/libxfs/xfs_log_format.h
@@ -371,7 +371,7 @@ static inline int xfs_ilog_fdata(int w)
typedef uint64_t xfs_log_timestamp_t;
/* Legacy timestamp encoding format. */
-struct xfs_legacy_ictimestamp {
+struct xfs_log_legacy_timestamp {
int32_t t_sec; /* timestamp seconds */
int32_t t_nsec; /* timestamp nanoseconds */
};
diff --git a/logprint/log_misc.c b/logprint/log_misc.c
index f4fd7a8..4889e65 100644
--- a/logprint/log_misc.c
+++ b/logprint/log_misc.c
@@ -745,9 +745,9 @@ time64_t
xlog_extract_dinode_ts(
const xfs_log_timestamp_t its)
{
- struct xfs_legacy_ictimestamp *lits;
+ struct xfs_log_legacy_timestamp *lits;
- lits = (struct xfs_legacy_ictimestamp *)&its;
+ lits = (struct xfs_log_legacy_timestamp *)&its;
return (time64_t)lits->t_sec;
}

View File

@ -0,0 +1,77 @@
From 27bb0efa5e615a9162f5bc3e228bdb7c337faa4c Mon Sep 17 00:00:00 2001
From: Christoph Hellwig <hch@lst.de>
Date: Wed, 30 Jun 2021 18:38:58 -0400
Subject: [PATCH] xfs: rename xfs_ictimestamp_t
Source kernel commit: 6fc277c7c935c7e1fdee23e82da988d9d3cb6bef
Rename xfs_ictimestamp_t to xfs_log_timestamp_t as it is a type used
for logging timestamps with no relationship to the in-core inode.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h
index 8dc0df0..85ac52c 100644
--- a/libxfs/xfs_log_format.h
+++ b/libxfs/xfs_log_format.h
@@ -368,7 +368,7 @@ static inline int xfs_ilog_fdata(int w)
* directly mirrors the xfs_dinode structure as it must contain all the same
* information.
*/
-typedef uint64_t xfs_ictimestamp_t;
+typedef uint64_t xfs_log_timestamp_t;
/* Legacy timestamp encoding format. */
struct xfs_legacy_ictimestamp {
@@ -393,9 +393,9 @@ struct xfs_log_dinode {
uint16_t di_projid_hi; /* higher part of owner's project id */
uint8_t di_pad[6]; /* unused, zeroed space */
uint16_t di_flushiter; /* incremented on flush */
- xfs_ictimestamp_t di_atime; /* time last accessed */
- xfs_ictimestamp_t di_mtime; /* time last modified */
- xfs_ictimestamp_t di_ctime; /* time created/inode modified */
+ xfs_log_timestamp_t di_atime; /* time last accessed */
+ xfs_log_timestamp_t di_mtime; /* time last modified */
+ xfs_log_timestamp_t di_ctime; /* time created/inode modified */
xfs_fsize_t di_size; /* number of bytes in file */
xfs_rfsblock_t di_nblocks; /* # of direct & btree blocks used */
xfs_extlen_t di_extsize; /* basic/minimum extent size for file */
@@ -420,7 +420,7 @@ struct xfs_log_dinode {
uint8_t di_pad2[12]; /* more padding for future expansion */
/* fields only written to during inode creation */
- xfs_ictimestamp_t di_crtime; /* time created */
+ xfs_log_timestamp_t di_crtime; /* time created */
xfs_ino_t di_ino; /* inode number */
uuid_t di_uuid; /* UUID of the filesystem */
diff --git a/logprint/log_misc.c b/logprint/log_misc.c
index 4fad82b..f4fd7a8 100644
--- a/logprint/log_misc.c
+++ b/logprint/log_misc.c
@@ -743,7 +743,7 @@ xlog_print_trans_icreate(
time64_t
xlog_extract_dinode_ts(
- const xfs_ictimestamp_t its)
+ const xfs_log_timestamp_t its)
{
struct xfs_legacy_ictimestamp *lits;
diff --git a/logprint/logprint.h b/logprint/logprint.h
index 0061d5a..fe3831d 100644
--- a/logprint/logprint.h
+++ b/logprint/logprint.h
@@ -18,7 +18,7 @@ extern int print_no_data;
extern int print_no_print;
/* exports */
-extern time64_t xlog_extract_dinode_ts(const xfs_ictimestamp_t);
+extern time64_t xlog_extract_dinode_ts(const xfs_log_timestamp_t);
extern void xlog_print_lseek(struct xlog *, int, xfs_daddr_t, int);
extern void xfs_log_copy(struct xlog *, int, char *);

View File

@ -0,0 +1,112 @@
From 50dba8189b1f628073eb61d824ae8a8a1b43cefb Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <djwong@kernel.org>
Date: Wed, 13 Jul 2022 20:58:28 -0500
Subject: [PATCH] mkfs: terminate getsubopt arrays properly
Having not drank any (or maybe too much) coffee this morning, I typed:
$ mkfs.xfs -d agcount=3 -d nrext64=0
Segmentation fault
I traced this down to getsubopt walking off the end of the dopts.subopts
array. The manpage says you're supposed to terminate the suboptions
string array with a NULL entry, but the structure definition uses
MAX_SUBOPTS/D_MAX_OPTS directly, which means there is no terminator.
Explicitly terminate each suboption array with a NULL entry after
making room for it.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
[sandeen: explicitly add NULL terminators & clarify comment]
Reviewed-by: Eric Sandeen <sandeen@sandeen.net>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
Signed-off-by: Pavel Reichl <preichl@redhat.com>
---
mkfs/xfs_mkfs.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index db322b3a..b140b815 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -140,8 +140,11 @@ enum {
M_MAX_OPTS,
};
-/* Just define the max options array size manually right now */
-#define MAX_SUBOPTS D_MAX_OPTS
+/*
+ * Just define the max options array size manually to the largest
+ * enum right now, leaving room for a NULL terminator at the end
+ */
+#define MAX_SUBOPTS (D_MAX_OPTS + 1)
#define SUBOPT_NEEDS_VAL (-1LL)
#define MAX_CONFLICTS 8
@@ -251,6 +254,7 @@ static struct opt_params bopts = {
.name = 'b',
.subopts = {
[B_SIZE] = "size",
+ [B_MAX_OPTS] = NULL,
},
.subopt_params = {
{ .index = B_SIZE,
@@ -306,6 +311,7 @@ static struct opt_params dopts = {
[D_PROJINHERIT] = "projinherit",
[D_EXTSZINHERIT] = "extszinherit",
[D_COWEXTSIZE] = "cowextsize",
+ [D_MAX_OPTS] = NULL,
},
.subopt_params = {
{ .index = D_AGCOUNT,
@@ -443,6 +449,7 @@ static struct opt_params iopts = {
[I_ATTR] = "attr",
[I_PROJID32BIT] = "projid32bit",
[I_SPINODES] = "sparse",
+ [I_MAX_OPTS] = NULL,
},
.subopt_params = {
{ .index = I_ALIGN,
@@ -515,6 +522,7 @@ static struct opt_params lopts = {
[L_FILE] = "file",
[L_NAME] = "name",
[L_LAZYSBCNTR] = "lazy-count",
+ [L_MAX_OPTS] = NULL,
},
.subopt_params = {
{ .index = L_AGNUM,
@@ -607,6 +615,7 @@ static struct opt_params nopts = {
[N_SIZE] = "size",
[N_VERSION] = "version",
[N_FTYPE] = "ftype",
+ [N_MAX_OPTS] = NULL,
},
.subopt_params = {
{ .index = N_SIZE,
@@ -642,6 +651,7 @@ static struct opt_params ropts = {
[R_FILE] = "file",
[R_NAME] = "name",
[R_NOALIGN] = "noalign",
+ [R_MAX_OPTS] = NULL,
},
.subopt_params = {
{ .index = R_EXTSIZE,
@@ -689,6 +699,7 @@ static struct opt_params sopts = {
.subopts = {
[S_SIZE] = "size",
[S_SECTSIZE] = "sectsize",
+ [S_MAX_OPTS] = NULL,
},
.subopt_params = {
{ .index = S_SIZE,
@@ -725,6 +736,7 @@ static struct opt_params mopts = {
[M_REFLINK] = "reflink",
[M_INOBTCNT] = "inobtcount",
[M_BIGTIME] = "bigtime",
+ [M_MAX_OPTS] = NULL,
},
.subopt_params = {
{ .index = M_CRC,
--
2.40.1

View File

@ -0,0 +1,56 @@
From f50d3462c654acc484ab3ea68e75e8252b77e262 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <djwong@kernel.org>
Date: Wed, 13 Jul 2022 20:58:25 -0500
Subject: [PATCH] xfs_repair: ignore empty xattr leaf blocks
As detailed in the commit:
5e572d1a xfs: empty xattr leaf header blocks are not corruption
empty xattr leaf blocks can be the benign byproduct of the system
going down during the multi-step process of adding a large xattr
to a file that has no xattrs. If we find one at attr fork offset 0,
we should clear it, but this isn't a corruption.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
Signed-off-by: Pavel Reichl <preichl@redhat.com>
---
repair/attr_repair.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/repair/attr_repair.c b/repair/attr_repair.c
index 2055d96e..c3a6d502 100644
--- a/repair/attr_repair.c
+++ b/repair/attr_repair.c
@@ -579,6 +579,26 @@ process_leaf_attr_block(
firstb = mp->m_sb.sb_blocksize;
stop = xfs_attr3_leaf_hdr_size(leaf);
+ /*
+ * Empty leaf blocks at offset zero can occur as a race between
+ * setxattr and the system going down, so we only take action if we're
+ * running in modify mode. See xfs_attr3_leaf_verify for details of
+ * how we've screwed this up many times.
+ */
+ if (!leafhdr.count && da_bno == 0) {
+ if (no_modify) {
+ do_log(
+ _("would clear empty leaf attr block 0, inode %" PRIu64 "\n"),
+ ino);
+ return 0;
+ }
+
+ do_warn(
+ _("will clear empty leaf attr block 0, inode %" PRIu64 "\n"),
+ ino);
+ return 1;
+ }
+
/* does the count look sorta valid? */
if (!leafhdr.count ||
leafhdr.count * sizeof(xfs_attr_leaf_entry_t) + stop >
--
2.40.1

View File

@ -0,0 +1,70 @@
From 7e8275f8939988f18f9a4a596381ca215fde2270 Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sandeen@redhat.com>
Date: Mon, 4 Nov 2019 15:35:49 -0500
Subject: [PATCH] xfs_growfs: allow mounted device node as argument
Up until:
b97815a0 xfs_growfs: ensure target path is an active xfs mountpoint
xfs_growfs actually accepted a mounted block device name as the
primary argument, because it could be found in the mount table.
It turns out that Ansible was making use of this undocumented behavior,
and it's trivial to allow it, so put it back in place and document
it this time.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
growfs/xfs_growfs.c | 3 +++
man/man8/xfs_growfs.8 | 10 +++++++++-
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/growfs/xfs_growfs.c b/growfs/xfs_growfs.c
index eab15984..6c62833b 100644
--- a/growfs/xfs_growfs.c
+++ b/growfs/xfs_growfs.c
@@ -141,6 +141,9 @@ main(int argc, char **argv)
}
fs = fs_table_lookup_mount(rpath);
+ if (!fs)
+ fs = fs_table_lookup_blkdev(rpath);
+
if (!fs) {
fprintf(stderr, _("%s: %s is not a mounted XFS filesystem\n"),
progname, argv[optind]);
diff --git a/man/man8/xfs_growfs.8 b/man/man8/xfs_growfs.8
index 7e6a387c..60a88189 100644
--- a/man/man8/xfs_growfs.8
+++ b/man/man8/xfs_growfs.8
@@ -35,7 +35,12 @@ xfs_growfs \- expand an XFS filesystem
.B \-R
.I size
]
+[
.I mount-point
+|
+.I block-device
+]
+
.br
.B xfs_growfs \-V
.SH DESCRIPTION
@@ -45,7 +50,10 @@ expands an existing XFS filesystem (see
The
.I mount-point
argument is the pathname of the directory where the filesystem
-is mounted. The filesystem must be mounted to be grown (see
+is mounted. The
+.I block-device
+argument is the device name of a mounted XFS filesystem.
+The filesystem must be mounted to be grown (see
.BR mount (8)).
The existing contents of the filesystem are undisturbed, and the added space
becomes available for additional file storage.
--
2.17.0

View File

@ -0,0 +1,109 @@
From 7e8a6edb4d1ba0079152eb477abbbc1dfb1ebb7e Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Fri, 13 Dec 2019 16:21:26 -0500
Subject: [PATCH] mkfs: Break block discard into chunks of 2 GB
Some users are not happy about the BLKDISCARD taking too long and at the
same time not being informed about that - so they think that the command
actually hung.
This commit changes code so that progress reporting is possible and also
typing the ^C will cancel the ongoing BLKDISCARD.
Signed-off-by: Pavel Reichl <preichl@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
mkfs/xfs_mkfs.c | 50 ++++++++++++++++++++++++++++++++++++-------------
1 file changed, 37 insertions(+), 13 deletions(-)
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 18338a61..4bfdebf6 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -1240,17 +1240,40 @@ done:
}
static void
-discard_blocks(dev_t dev, uint64_t nsectors)
+discard_blocks(dev_t dev, uint64_t nsectors, int quiet)
{
- int fd;
+ int fd;
+ uint64_t offset = 0;
+ /* Discard the device 2G at a time */
+ const uint64_t step = 2ULL << 30;
+ const uint64_t count = BBTOB(nsectors);
- /*
- * We intentionally ignore errors from the discard ioctl. It is
- * not necessary for the mkfs functionality but just an optimization.
- */
fd = libxfs_device_to_fd(dev);
- if (fd > 0)
- platform_discard_blocks(fd, 0, nsectors << 9);
+ if (fd <= 0)
+ return;
+ if (!quiet) {
+ printf("Discarding blocks...");
+ fflush(stdout);
+ }
+
+ /* The block discarding happens in smaller batches so it can be
+ * interrupted prematurely
+ */
+ while (offset < count) {
+ uint64_t tmp_step = min(step, count - offset);
+
+ /*
+ * We intentionally ignore errors from the discard ioctl. It is
+ * not necessary for the mkfs functionality but just an
+ * optimization. However we should stop on error.
+ */
+ if (platform_discard_blocks(fd, offset, tmp_step))
+ return;
+
+ offset += tmp_step;
+ }
+ if (!quiet)
+ printf("Done.\n");
}
static __attribute__((noreturn)) void
@@ -2507,18 +2530,19 @@ open_devices(
static void
discard_devices(
- struct libxfs_xinit *xi)
+ struct libxfs_xinit *xi,
+ int quiet)
{
/*
* This function has to be called after libxfs has been initialized.
*/
if (!xi->disfile)
- discard_blocks(xi->ddev, xi->dsize);
+ discard_blocks(xi->ddev, xi->dsize, quiet);
if (xi->rtdev && !xi->risfile)
- discard_blocks(xi->rtdev, xi->rtsize);
+ discard_blocks(xi->rtdev, xi->rtsize, quiet);
if (xi->logdev && xi->logdev != xi->ddev && !xi->lisfile)
- discard_blocks(xi->logdev, xi->logBBsize);
+ discard_blocks(xi->logdev, xi->logBBsize, quiet);
}
static void
@@ -3749,7 +3773,7 @@ main(
* All values have been validated, discard the old device layout.
*/
if (discard && !dry_run)
- discard_devices(&xi);
+ discard_devices(&xi, quiet);
/*
* we need the libxfs buffer cache from here on in.
--
2.17.0

View File

@ -0,0 +1,56 @@
From 2383d7c5cf20efcff75cb29ca3e02cfbe1bf2209 Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sandeen@redhat.com>
Date: Tue, 17 Dec 2019 16:52:39 -0500
Subject: [PATCH] mkfs: tidy up discard notifications
Only notify user of discard operations if the first one succeeds,
and be sure to print a trailing newline if we stop early.
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>
---
mkfs/xfs_mkfs.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 4bfdebf6..606f79da 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -1251,10 +1251,6 @@ discard_blocks(dev_t dev, uint64_t nsectors, int quiet)
fd = libxfs_device_to_fd(dev);
if (fd <= 0)
return;
- if (!quiet) {
- printf("Discarding blocks...");
- fflush(stdout);
- }
/* The block discarding happens in smaller batches so it can be
* interrupted prematurely
@@ -1267,12 +1263,20 @@ discard_blocks(dev_t dev, uint64_t nsectors, int quiet)
* not necessary for the mkfs functionality but just an
* optimization. However we should stop on error.
*/
- if (platform_discard_blocks(fd, offset, tmp_step))
+ if (platform_discard_blocks(fd, offset, tmp_step) == 0) {
+ if (offset == 0 && !quiet) {
+ printf("Discarding blocks...");
+ fflush(stdout);
+ }
+ } else {
+ if (offset > 0 && !quiet)
+ printf("\n");
return;
+ }
offset += tmp_step;
}
- if (!quiet)
+ if (offset > 0 && !quiet)
printf("Done.\n");
}
--
2.17.0

View File

@ -0,0 +1,112 @@
From 9d6023a856a1c4f84415dff59b0d5459cc8768db Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sandeen@redhat.com>
Date: Thu, 27 Feb 2020 15:05:48 -0500
Subject: [PATCH] libxfs: use FALLOC_FL_ZERO_RANGE in libxfs_device_zero
I had a request from someone who cared about mkfs speed over
a slower network block device to look into using faster zeroing
methods, particularly for the log, during mkfs.
Using FALLOC_FL_ZERO_RANGE is faster in this case than writing
a bunch of zeros across a wire.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
include/builddefs.in | 3 +++
include/linux.h | 22 ++++++++++++++++++++++
libxfs/rdwr.c | 15 +++++++++++----
3 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/include/builddefs.in b/include/builddefs.in
index 4700b52..1dd27f7 100644
--- a/include/builddefs.in
+++ b/include/builddefs.in
@@ -144,6 +144,9 @@ endif
ifeq ($(HAVE_GETFSMAP),yes)
PCFLAGS+= -DHAVE_GETFSMAP
endif
+ifeq ($(HAVE_FALLOCATE),yes)
+PCFLAGS += -DHAVE_FALLOCATE
+endif
LIBICU_LIBS = @libicu_LIBS@
LIBICU_CFLAGS = @libicu_CFLAGS@
diff --git a/include/linux.h b/include/linux.h
index 8f3c32b..57726bb 100644
--- a/include/linux.h
+++ b/include/linux.h
@@ -20,6 +20,10 @@
#include <stdio.h>
#include <asm/types.h>
#include <mntent.h>
+#include <fcntl.h>
+#if defined(HAVE_FALLOCATE)
+#include <linux/falloc.h>
+#endif
#ifdef OVERRIDE_SYSTEM_FSXATTR
# define fsxattr sys_fsxattr
#endif
@@ -164,6 +168,24 @@ static inline void platform_mntent_close(struct mntent_cursor * cursor)
endmntent(cursor->mtabp);
}
+#if defined(FALLOC_FL_ZERO_RANGE)
+static inline int
+platform_zero_range(
+ int fd,
+ xfs_off_t start,
+ size_t len)
+{
+ int ret;
+
+ ret = fallocate(fd, FALLOC_FL_ZERO_RANGE, start, len);
+ if (!ret)
+ return 0;
+ return -errno;
+}
+#else
+#define platform_zero_range(fd, s, l) (-EOPNOTSUPP)
+#endif
+
/*
* Check whether we have to define FS_IOC_FS[GS]ETXATTR ourselves. These
* are a copy of the definitions moved to linux/uapi/fs.h in the 4.5 kernel,
diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
index 0d9d720..e2d9d79 100644
--- a/libxfs/rdwr.c
+++ b/libxfs/rdwr.c
@@ -61,8 +61,18 @@ libxfs_device_zero(struct xfs_buftarg *btp, xfs_daddr_t start, uint len)
{
xfs_off_t start_offset, end_offset, offset;
ssize_t zsize, bytes;
+ size_t len_bytes;
char *z;
- int fd;
+ int error, fd;
+
+ fd = libxfs_device_to_fd(btp->dev);
+ start_offset = LIBXFS_BBTOOFF64(start);
+
+ /* try to use special zeroing methods, fall back to writes if needed */
+ len_bytes = LIBXFS_BBTOOFF64(len);
+ error = platform_zero_range(fd, start_offset, len_bytes);
+ if (!error)
+ return 0;
zsize = min(BDSTRAT_SIZE, BBTOB(len));
if ((z = memalign(libxfs_device_alignment(), zsize)) == NULL) {
@@ -73,9 +83,6 @@ libxfs_device_zero(struct xfs_buftarg *btp, xfs_daddr_t start, uint len)
}
memset(z, 0, zsize);
- fd = libxfs_device_to_fd(btp->dev);
- start_offset = LIBXFS_BBTOOFF64(start);
-
if ((lseek(fd, start_offset, SEEK_SET)) < 0) {
fprintf(stderr, _("%s: %s seek to offset %llu failed: %s\n"),
progname, __FUNCTION__,
--
2.9.5

View File

@ -0,0 +1,123 @@
From cb49e9a41477791af390a397c97da28da31fb81d Mon Sep 17 00:00:00 2001
From: Christoph Hellwig <hch@lst.de>
Date: Wed, 22 Jan 2020 11:29:44 -0500
Subject: [PATCH] xfs: use a struct timespec64 for the in-core crtime
Source kernel commit: 8d2d878db897d7501aaa2f72e10bb28295bb5498
struct xfs_icdinode is purely an in-memory data structure, so don't use
a log on-disk structure for it. This simplifies the code a bit, and
also reduces our include hell slightly.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
[darrick: fix a minor indenting problem in xfs_trans_ichgtime]
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/include/libxfs.h b/include/libxfs.h
index 2bdef70..731561c 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -36,6 +36,8 @@ extern uint32_t crc32c_le(uint32_t crc, unsigned char const *p, size_t len);
#include "xfs_cksum.h"
+#define timespec64 timespec
+
/*
* This mirrors the kernel include for xfs_buf.h - it's implicitly included in
* every files via a similar include in the kernel xfs_linux.h.
diff --git a/include/xfs_inode.h b/include/xfs_inode.h
index 76f9ac7..e03d1cb 100644
--- a/include/xfs_inode.h
+++ b/include/xfs_inode.h
@@ -161,7 +161,6 @@ extern void libxfs_trans_ichgtime(struct xfs_trans *,
struct xfs_inode *, int);
extern int libxfs_iflush_int (struct xfs_inode *, struct xfs_buf *);
-#define timespec64 timespec
extern struct timespec64 current_time(struct inode *inode);
/* Inode Cache Interfaces */
diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h
index b45d07e..8232f89 100644
--- a/libxfs/libxfs_priv.h
+++ b/libxfs/libxfs_priv.h
@@ -62,6 +62,8 @@ extern kmem_zone_t *xfs_buf_zone;
extern kmem_zone_t *xfs_inode_zone;
extern kmem_zone_t *xfs_trans_zone;
+#define timespec64 timespec
+
/* CRC stuff, buffer API dependent on it */
#define crc32c(c,p,l) crc32c_le((c),(unsigned char const *)(p),(l))
diff --git a/libxfs/util.c b/libxfs/util.c
index 951f7cf..9383bb8 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -170,10 +170,8 @@ libxfs_trans_ichgtime(
VFS_I(ip)->i_mtime = tv;
if (flags & XFS_ICHGTIME_CHG)
VFS_I(ip)->i_ctime = tv;
- if (flags & XFS_ICHGTIME_CREATE) {
- ip->i_d.di_crtime.t_sec = (int32_t)tv.tv_sec;
- ip->i_d.di_crtime.t_nsec = (int32_t)tv.tv_nsec;
- }
+ if (flags & XFS_ICHGTIME_CREATE)
+ ip->i_d.di_crtime = tv;
}
STATIC uint16_t
@@ -321,8 +319,8 @@ libxfs_ialloc(
VFS_I(ip)->i_version = 1;
ip->i_d.di_flags2 = pip ? 0 : xfs_flags2diflags2(ip,
fsx->fsx_xflags);
- ip->i_d.di_crtime.t_sec = (int32_t)VFS_I(ip)->i_mtime.tv_sec;
- ip->i_d.di_crtime.t_nsec = (int32_t)VFS_I(ip)->i_mtime.tv_nsec;
+ ip->i_d.di_crtime.tv_sec = (int32_t)VFS_I(ip)->i_mtime.tv_sec;
+ ip->i_d.di_crtime.tv_nsec = (int32_t)VFS_I(ip)->i_mtime.tv_nsec;
ip->i_d.di_cowextsize = pip ? 0 : fsx->fsx_cowextsize;
}
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index 503990f..975f097 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -254,8 +254,8 @@ xfs_inode_from_disk(
if (to->di_version == 3) {
inode_set_iversion_queried(inode,
be64_to_cpu(from->di_changecount));
- to->di_crtime.t_sec = be32_to_cpu(from->di_crtime.t_sec);
- to->di_crtime.t_nsec = be32_to_cpu(from->di_crtime.t_nsec);
+ to->di_crtime.tv_sec = be32_to_cpu(from->di_crtime.t_sec);
+ to->di_crtime.tv_nsec = be32_to_cpu(from->di_crtime.t_nsec);
to->di_flags2 = be64_to_cpu(from->di_flags2);
to->di_cowextsize = be32_to_cpu(from->di_cowextsize);
}
@@ -304,8 +304,8 @@ xfs_inode_to_disk(
if (from->di_version == 3) {
to->di_changecount = cpu_to_be64(inode_peek_iversion(inode));
- to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.t_sec);
- to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.t_nsec);
+ to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.tv_sec);
+ to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.tv_nsec);
to->di_flags2 = cpu_to_be64(from->di_flags2);
to->di_cowextsize = cpu_to_be32(from->di_cowextsize);
to->di_ino = cpu_to_be64(ip->i_ino);
diff --git a/libxfs/xfs_inode_buf.h b/libxfs/xfs_inode_buf.h
index ab0f841..c9ac69c 100644
--- a/libxfs/xfs_inode_buf.h
+++ b/libxfs/xfs_inode_buf.h
@@ -37,7 +37,7 @@ struct xfs_icdinode {
uint64_t di_flags2; /* more random flags */
uint32_t di_cowextsize; /* basic cow extent size for file */
- xfs_ictimestamp_t di_crtime; /* time created */
+ struct timespec64 di_crtime; /* time created */
};
/*

View File

@ -0,0 +1,227 @@
From 36dc471cc9bb17868b79cf8dea8151b207387539 Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sandeen@redhat.com>
Date: Tue, 26 May 2020 14:36:26 -0400
Subject: [PATCH] xfs_quota: allow individual timer extension
The only grace period which can be set via xfs_quota today is for id 0,
i.e. the default grace period for all users. However, setting an
individual grace period is useful; for example:
Alice has a soft quota of 100 inodes, and a hard quota of 200 inodes
Alice uses 150 inodes, and enters a short grace period
Alice really needs to use those 150 inodes past the grace period
The administrator extends Alice's grace period until next Monday
vfs quota users such as ext4 can do this today, with setquota -T
xfs_quota can now accept an optional user id or name (symmetric with
how warn limits are specified), in which case that user's grace period
is extended to expire the given amount of time from now().
To maintain compatibility with old command lines, if none of
[-d|id|name] are specified, default limits are set as before.
(kernelspace requires updates to enable all this as well.)
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>
---
man/man8/xfs_quota.8 | 36 +++++++++++++++++--
quota/edit.c | 83 +++++++++++++++++++++++++++++++++++++-------
2 files changed, 104 insertions(+), 15 deletions(-)
Index: xfsprogs-5.0.0/man/man8/xfs_quota.8
===================================================================
--- xfsprogs-5.0.0.orig/man/man8/xfs_quota.8
+++ xfsprogs-5.0.0/man/man8/xfs_quota.8
@@ -460,14 +460,46 @@ must be specified.
.B \-bir
]
.I value
+[
+.B -d
+|
+.I id
+|
+.I name
+]
.br
Allows the quota enforcement timeout (i.e. the amount of time allowed
to pass before the soft limits are enforced as the hard limits) to
be modified. The current timeout setting can be displayed using the
.B state
-command. The value argument is a number of seconds, but units of
-\&'minutes', 'hours', 'days', and 'weeks' are also understood
+command.
+.br
+When setting the default timer via the
+.B \-d
+option, or for
+.B id
+0, or if no argument is given after
+.I value
+the
+.I value
+argument is a number of seconds indicating the relative amount of time after
+soft limits are exceeded, before hard limits are enforced.
+.br
+When setting any other individual timer by
+.I id
+or
+.I name,
+the
+.I value
+is the number of seconds from now, at which time the hard limits will be enforced.
+This allows extending the grace time of an individual user who has exceeded soft
+limits.
+.br
+For
+.I value,
+units of \&'minutes', 'hours', 'days', and 'weeks' are also understood
(as are their abbreviations 'm', 'h', 'd', and 'w').
+.br
.HP
.B warn
[
Index: xfsprogs-5.0.0/quota/edit.c
===================================================================
--- xfsprogs-5.0.0.orig/quota/edit.c
+++ xfsprogs-5.0.0/quota/edit.c
@@ -419,6 +419,7 @@ restore_f(
static void
set_timer(
+ uint32_t id,
uint type,
uint mask,
char *dev,
@@ -427,14 +428,43 @@ set_timer(
fs_disk_quota_t d;
memset(&d, 0, sizeof(d));
+
+ /*
+ * If id is specified we are extending grace time by value
+ * Otherwise we are setting the default grace time
+ */
+ if (id) {
+ time_t now;
+
+ /* Get quota to find out whether user is past soft limits */
+ if (xfsquotactl(XFS_GETQUOTA, dev, type, id, (void *)&d) < 0) {
+ exitcode = 1;
+ fprintf(stderr, _("%s: cannot get quota: %s\n"),
+ progname, strerror(errno));
+ return;
+ }
+
+ time(&now);
+
+ /* Only set grace time if user is already past soft limit */
+ if (d.d_blk_softlimit && d.d_bcount > d.d_blk_softlimit)
+ d.d_btimer = now + value;
+ if (d.d_ino_softlimit && d.d_icount > d.d_ino_softlimit)
+ d.d_itimer = now + value;
+ if (d.d_rtb_softlimit && d.d_rtbcount > d.d_rtb_softlimit)
+ d.d_rtbtimer = now + value;
+ } else {
+ d.d_btimer = value;
+ d.d_itimer = value;
+ d.d_rtbtimer = value;
+ }
+
d.d_version = FS_DQUOT_VERSION;
d.d_flags = type;
d.d_fieldmask = mask;
- d.d_itimer = value;
- d.d_btimer = value;
- d.d_rtbtimer = value;
+ d.d_id = id;
- if (xfsquotactl(XFS_SETQLIM, dev, type, 0, (void *)&d) < 0) {
+ if (xfsquotactl(XFS_SETQLIM, dev, type, id, (void *)&d) < 0) {
exitcode = 1;
fprintf(stderr, _("%s: cannot set timer: %s\n"),
progname, strerror(errno));
@@ -447,10 +477,15 @@ timer_f(
char **argv)
{
uint value;
- int c, type = 0, mask = 0;
+ char *name = NULL;
+ uint32_t id = 0;
+ int c, flags = 0, type = 0, mask = 0;
- while ((c = getopt(argc, argv, "bgipru")) != EOF) {
+ while ((c = getopt(argc, argv, "bdgipru")) != EOF) {
switch (c) {
+ case 'd':
+ flags |= DEFAULTS_FLAG;
+ break;
case 'b':
mask |= FS_DQ_BTIMER;
break;
@@ -474,23 +509,45 @@ timer_f(
}
}
- if (argc != optind + 1)
+ /*
+ * Older versions of the command did not accept -d|id|name,
+ * so in that case we assume we're setting default timer,
+ * and the last arg is the timer value.
+ *
+ * Otherwise, if the defaults flag is set, we expect 1 more arg for
+ * timer value ; if not, 2 more args: 1 for value, one for id/name.
+ */
+ if (!(flags & DEFAULTS_FLAG) && (argc == optind + 1)) {
+ value = cvttime(argv[optind++]);
+ } else if (flags & DEFAULTS_FLAG) {
+ if (argc != optind + 1)
+ return command_usage(&timer_cmd);
+ value = cvttime(argv[optind++]);
+ } else if (argc == optind + 2) {
+ value = cvttime(argv[optind++]);
+ name = (flags & DEFAULTS_FLAG) ? "0" : argv[optind++];
+ } else
return command_usage(&timer_cmd);
- value = cvttime(argv[optind++]);
+ /* if none of -bir specified, set them all */
if (!mask)
mask = FS_DQ_TIMER_MASK;
if (!type) {
type = XFS_USER_QUOTA;
} else if (type != XFS_GROUP_QUOTA &&
- type != XFS_PROJ_QUOTA &&
- type != XFS_USER_QUOTA) {
+ type != XFS_PROJ_QUOTA &&
+ type != XFS_USER_QUOTA) {
return command_usage(&timer_cmd);
}
- set_timer(type, mask, fs_path->fs_name, value);
+ if (name)
+ id = id_from_string(name, type);
+
+ if (id >= 0)
+ set_timer(id, type, mask, fs_path->fs_name, value);
+
return 0;
}
@@ -616,9 +673,9 @@ edit_init(void)
timer_cmd.name = "timer";
timer_cmd.cfunc = timer_f;
- timer_cmd.argmin = 2;
+ timer_cmd.argmin = 1;
timer_cmd.argmax = -1;
- timer_cmd.args = _("[-bir] [-g|-p|-u] value");
+ timer_cmd.args = _("[-bir] [-g|-p|-u] value [-d|id|name]");
timer_cmd.oneline = _("set quota enforcement timeouts");
timer_cmd.help = timer_help;
timer_cmd.flags = CMD_FLAG_FOREIGN_OK;

View File

@ -0,0 +1,69 @@
From eaa5b0b79bcf2eb36f7a5e1a5b7171ad5ced7bac Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 10 Jul 2020 15:33:36 -0400
Subject: [PATCH] xfs_quota: fix unsigned int id comparisons
Fix compiler warnings about unsigned int comparisons by replacing them
with an explicit check for the one possible invalid value (-1U).
id_from_string sets exitcode to nonzero when it sees this value, so the
call sites don't have to do that.
Coverity-id: 1463855, 1463856, 1463857
Fixes: 67a73d6139d0 ("xfs_quota: refactor code to generate id from name")
Fixes: 36dc471cc9bb ("xfs_quota: allow individual timer extension")
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
quota/edit.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
Index: xfsprogs-5.0.0/quota/edit.c
===================================================================
--- xfsprogs-5.0.0.orig/quota/edit.c
+++ xfsprogs-5.0.0/quota/edit.c
@@ -307,11 +307,11 @@ limit_f(
id = id_from_string(name, type);
- if (id >= 0)
- set_limits(id, type, mask, fs_path->fs_name,
- &bsoft, &bhard, &isoft, &ihard, &rtbsoft, &rtbhard);
- else
- exitcode = -1;
+ if (id == -1)
+ return 0;
+
+ set_limits(id, type, mask, fs_path->fs_name,
+ &bsoft, &bhard, &isoft, &ihard, &rtbsoft, &rtbhard);
return 0;
}
@@ -545,9 +545,10 @@ timer_f(
if (name)
id = id_from_string(name, type);
- if (id >= 0)
- set_timer(id, type, mask, fs_path->fs_name, value);
+ if (id == -1)
+ return 0;
+ set_timer(id, type, mask, fs_path->fs_name, value);
return 0;
}
@@ -642,11 +643,10 @@ warn_f(
}
id = id_from_string(name, type);
- if (id >= 0)
- set_warnings(id, type, mask, fs_path->fs_name, value);
- else
- exitcode = -1;
+ if (id == -1)
+ return 0;
+ set_warnings(id, type, mask, fs_path->fs_name, value);
return 0;
}

View File

@ -0,0 +1,271 @@
From 67a73d6139d0336eb7ced05bd78a26b57f408187 Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sandeen@redhat.com>
Date: Tue, 26 May 2020 14:36:04 -0400
Subject: [PATCH] xfs_quota: refactor code to generate id from name
There's boilerplate for setting limits and warnings, where we have
a case statement for each of the 3 quota types, and from there call
3 different functions to configure each of the 3 types, each of which
calls its own version of id to string function...
Refactor this so that the main function can call a generic id to string
conversion routine, and then call a common action. This save a lot of
LOC.
I was looking at allowing xfs to bump out individual grace periods like
setquota can do, and this refactoring allows us to add new actions like
that without copying all the boilerplate again.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
quota/edit.c | 194 +++++++++++++--------------------------------------
1 file changed, 49 insertions(+), 145 deletions(-)
Index: xfsprogs-5.0.0/quota/edit.c
===================================================================
--- xfsprogs-5.0.0.orig/quota/edit.c
+++ xfsprogs-5.0.0/quota/edit.c
@@ -101,6 +101,40 @@ warn_help(void)
"\n"));
}
+static uint32_t
+id_from_string(
+ char *name,
+ int type)
+{
+ uint32_t id = -1;
+ const char *type_name = "unknown type";
+
+ switch (type) {
+ case XFS_USER_QUOTA:
+ type_name = "user";
+ id = uid_from_string(name);
+ break;
+ case XFS_GROUP_QUOTA:
+ type_name = "group";
+ id = gid_from_string(name);
+ break;
+ case XFS_PROJ_QUOTA:
+ type_name = "project";
+ id = prid_from_string(name);
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ if (id == -1) {
+ fprintf(stderr, _("%s: invalid %s name: %s\n"),
+ type_name, progname, name);
+ exitcode = 1;
+ }
+ return id;
+}
+
static void
set_limits(
uint32_t id,
@@ -135,75 +169,6 @@ set_limits(
}
}
-static void
-set_user_limits(
- char *name,
- uint type,
- uint mask,
- uint64_t *bsoft,
- uint64_t *bhard,
- uint64_t *isoft,
- uint64_t *ihard,
- uint64_t *rtbsoft,
- uint64_t *rtbhard)
-{
- uid_t uid = uid_from_string(name);
-
- if (uid == -1) {
- exitcode = 1;
- fprintf(stderr, _("%s: invalid user name: %s\n"),
- progname, name);
- } else
- set_limits(uid, type, mask, fs_path->fs_name,
- bsoft, bhard, isoft, ihard, rtbsoft, rtbhard);
-}
-
-static void
-set_group_limits(
- char *name,
- uint type,
- uint mask,
- uint64_t *bsoft,
- uint64_t *bhard,
- uint64_t *isoft,
- uint64_t *ihard,
- uint64_t *rtbsoft,
- uint64_t *rtbhard)
-{
- gid_t gid = gid_from_string(name);
-
- if (gid == -1) {
- exitcode = 1;
- fprintf(stderr, _("%s: invalid group name: %s\n"),
- progname, name);
- } else
- set_limits(gid, type, mask, fs_path->fs_name,
- bsoft, bhard, isoft, ihard, rtbsoft, rtbhard);
-}
-
-static void
-set_project_limits(
- char *name,
- uint type,
- uint mask,
- uint64_t *bsoft,
- uint64_t *bhard,
- uint64_t *isoft,
- uint64_t *ihard,
- uint64_t *rtbsoft,
- uint64_t *rtbhard)
-{
- prid_t prid = prid_from_string(name);
-
- if (prid == -1) {
- exitcode = 1;
- fprintf(stderr, _("%s: invalid project name: %s\n"),
- progname, name);
- } else
- set_limits(prid, type, mask, fs_path->fs_name,
- bsoft, bhard, isoft, ihard, rtbsoft, rtbhard);
-}
-
/* extract number of blocks from an ascii string */
static int
extractb(
@@ -258,6 +223,7 @@ limit_f(
char **argv)
{
char *name;
+ uint32_t id;
uint64_t bsoft, bhard, isoft, ihard, rtbsoft, rtbhard;
int c, type = 0, mask = 0, flags = 0;
uint bsize, ssize, endoptions;
@@ -339,20 +305,13 @@ limit_f(
return command_usage(&limit_cmd);
}
- switch (type) {
- case XFS_USER_QUOTA:
- set_user_limits(name, type, mask,
- &bsoft, &bhard, &isoft, &ihard, &rtbsoft, &rtbhard);
- break;
- case XFS_GROUP_QUOTA:
- set_group_limits(name, type, mask,
- &bsoft, &bhard, &isoft, &ihard, &rtbsoft, &rtbhard);
- break;
- case XFS_PROJ_QUOTA:
- set_project_limits(name, type, mask,
- &bsoft, &bhard, &isoft, &ihard, &rtbsoft, &rtbhard);
- break;
- }
+
+ id = id_from_string(name, type);
+ if (id >= 0)
+ set_limits(id, type, mask, fs_path->fs_name,
+ &bsoft, &bhard, &isoft, &ihard, &rtbsoft, &rtbhard);
+ else
+ exitcode = -1;
return 0;
}
@@ -561,63 +520,13 @@ set_warnings(
}
}
-static void
-set_user_warnings(
- char *name,
- uint type,
- uint mask,
- uint value)
-{
- uid_t uid = uid_from_string(name);
-
- if (uid == -1) {
- exitcode = 1;
- fprintf(stderr, _("%s: invalid user name: %s\n"),
- progname, name);
- } else
- set_warnings(uid, type, mask, fs_path->fs_name, value);
-}
-
-static void
-set_group_warnings(
- char *name,
- uint type,
- uint mask,
- uint value)
-{
- gid_t gid = gid_from_string(name);
-
- if (gid == -1) {
- exitcode = 1;
- fprintf(stderr, _("%s: invalid group name: %s\n"),
- progname, name);
- } else
- set_warnings(gid, type, mask, fs_path->fs_name, value);
-}
-
-static void
-set_project_warnings(
- char *name,
- uint type,
- uint mask,
- uint value)
-{
- prid_t prid = prid_from_string(name);
-
- if (prid == -1) {
- exitcode = 1;
- fprintf(stderr, _("%s: invalid project name: %s\n"),
- progname, name);
- } else
- set_warnings(prid, type, mask, fs_path->fs_name, value);
-}
-
static int
warn_f(
int argc,
char **argv)
{
char *name;
+ uint32_t id;
uint value;
int c, flags = 0, type = 0, mask = 0;
@@ -675,17 +584,12 @@ warn_f(
return command_usage(&warn_cmd);
}
- switch (type) {
- case XFS_USER_QUOTA:
- set_user_warnings(name, type, mask, value);
- break;
- case XFS_GROUP_QUOTA:
- set_group_warnings(name, type, mask, value);
- break;
- case XFS_PROJ_QUOTA:
- set_project_warnings(name, type, mask, value);
- break;
- }
+ id = id_from_string(name, type);
+ if (id >= 0)
+ set_warnings(id, type, mask, fs_path->fs_name, value);
+ else
+ exitcode = -1;
+
return 0;
}

View File

@ -0,0 +1,54 @@
From cae4fd291266c32441c6a7fcca49929fe11c391c Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 10 Jul 2020 15:35:44 -0400
Subject: [PATCH] xfs_repair: check for AG btree records that would wrap around
For AG btree types, make sure that each record's length is not so huge
that integer wraparound would happen.
Found via xfs/358 fuzzing recs[1].blockcount = ones.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
repair/scan.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/repair/scan.c b/repair/scan.c
index 5c8d8b23..1ddb5763 100644
--- a/repair/scan.c
+++ b/repair/scan.c
@@ -684,7 +684,8 @@ _("%s freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
b, i, name, agno, bno);
continue;
}
- if (len == 0 || !verify_agbno(mp, agno, end - 1)) {
+ if (len == 0 || end <= b ||
+ !verify_agbno(mp, agno, end - 1)) {
do_warn(
_("invalid length %u in record %u of %s btree block %u/%u\n"),
len, i, name, agno, bno);
@@ -1066,7 +1067,8 @@ _("%s rmap btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
b, i, name, agno, bno);
continue;
}
- if (len == 0 || !verify_agbno(mp, agno, end - 1)) {
+ if (len == 0 || end <= b ||
+ !verify_agbno(mp, agno, end - 1)) {
do_warn(
_("invalid length %u in record %u of %s btree block %u/%u\n"),
len, i, name, agno, bno);
@@ -1353,7 +1355,8 @@ _("leftover CoW extent has invalid startblock in record %u of %s btree block %u/
b, i, name, agno, bno);
continue;
}
- if (len == 0 || !verify_agbno(mp, agno, end - 1)) {
+ if (len == 0 || end <= agb ||
+ !verify_agbno(mp, agno, end - 1)) {
do_warn(
_("invalid length %u in record %u of %s btree block %u/%u\n"),
len, i, name, agno, bno);
--
2.29.2

View File

@ -0,0 +1,124 @@
From 320cc3b263542e692c4978fb327efa591892ab37 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 10 Jul 2020 15:35:45 -0400
Subject: [PATCH] xfs_repair: complain about bad interior btree pointers
Actually complain about garbage btree node pointers, don't just silently
ignore them.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
libxfs/libxfs_api_defs.h | 1 +
repair/scan.c | 55 +++++++++++++++++++++++++++++-----------
2 files changed, 41 insertions(+), 15 deletions(-)
Index: xfsprogs-5.0.0/libxfs/libxfs_api_defs.h
===================================================================
--- xfsprogs-5.0.0.orig/libxfs/libxfs_api_defs.h
+++ xfsprogs-5.0.0/libxfs/libxfs_api_defs.h
@@ -118,6 +118,7 @@
#define xfs_symlink_blocks libxfs_symlink_blocks
#define xfs_symlink_hdr_ok libxfs_symlink_hdr_ok
+#define xfs_verify_agbno libxfs_verify_agbno
#define xfs_verify_cksum libxfs_verify_cksum
#define xfs_dinode_verify libxfs_dinode_verify
Index: xfsprogs-5.0.0/repair/scan.c
===================================================================
--- xfsprogs-5.0.0.orig/repair/scan.c
+++ xfsprogs-5.0.0/repair/scan.c
@@ -743,6 +743,14 @@ _("%s freespace btree block claimed (sta
for (i = 0; i < numrecs; i++) {
xfs_agblock_t agbno = be32_to_cpu(pp[i]);
+ if (!libxfs_verify_agbno(mp, agno, agbno)) {
+ do_warn(
+ _("bad btree pointer (%u) in %sbt block %u/%u\n"),
+ agbno, name, agno, bno);
+ suspect++;
+ return;
+ }
+
/*
* XXX - put sibling detection right here.
* we know our sibling chain is good. So as we go,
@@ -752,10 +760,8 @@ _("%s freespace btree block claimed (sta
* pointer mismatch, try and extract as much data
* as possible.
*/
- if (agbno != 0 && verify_agbno(mp, agno, agbno)) {
- scan_sbtree(agbno, level, agno, suspect, scan_allocbt,
- 0, magic, priv, ops);
- }
+ scan_sbtree(agbno, level, agno, suspect, scan_allocbt, 0,
+ magic, priv, ops);
}
}
@@ -1196,10 +1202,16 @@ advance:
continue;
}
- if (agbno != 0 && verify_agbno(mp, agno, agbno)) {
- scan_sbtree(agbno, level, agno, suspect, scan_rmapbt, 0,
- magic, priv, ops);
+ if (!libxfs_verify_agbno(mp, agno, agbno)) {
+ do_warn(
+ _("bad btree pointer (%u) in %sbt block %u/%u\n"),
+ agbno, name, agno, bno);
+ suspect++;
+ return;
}
+
+ scan_sbtree(agbno, level, agno, suspect, scan_rmapbt, 0, magic,
+ priv, ops);
}
out:
@@ -1416,10 +1428,16 @@ _("extent (%u/%u) len %u claimed, state
for (i = 0; i < numrecs; i++) {
xfs_agblock_t agbno = be32_to_cpu(pp[i]);
- if (agbno != 0 && verify_agbno(mp, agno, agbno)) {
- scan_sbtree(agbno, level, agno, suspect, scan_refcbt, 0,
- magic, priv, ops);
+ if (!libxfs_verify_agbno(mp, agno, agbno)) {
+ do_warn(
+ _("bad btree pointer (%u) in %sbt block %u/%u\n"),
+ agbno, name, agno, bno);
+ suspect++;
+ return;
}
+
+ scan_sbtree(agbno, level, agno, suspect, scan_refcbt, 0, magic,
+ priv, ops);
}
out:
if (suspect)
@@ -2083,11 +2101,18 @@ _("inode btree block claimed (state %d),
}
for (i = 0; i < numrecs; i++) {
- if (be32_to_cpu(pp[i]) != 0 && verify_agbno(mp, agno,
- be32_to_cpu(pp[i])))
- scan_sbtree(be32_to_cpu(pp[i]), level, agno,
- suspect, scan_inobt, 0, magic, priv,
- ops);
+ xfs_agblock_t agbno = be32_to_cpu(pp[i]);
+
+ if (!libxfs_verify_agbno(mp, agno, agbno)) {
+ do_warn(
+ _("bad btree pointer (%u) in %sbt block %u/%u\n"),
+ agbno, name, agno, bno);
+ suspect++;
+ return;
+ }
+
+ scan_sbtree(be32_to_cpu(pp[i]), level, agno, suspect,
+ scan_inobt, 0, magic, priv, ops);
}
}

View File

@ -0,0 +1,209 @@
From dcd6c2e1490ba5c59c14ca8ea843ca36048888b8 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 10 Jul 2020 15:35:45 -0400
Subject: [PATCH] xfs_repair: convert to libxfs_verify_agbno
Convert the homegrown verify_agbno callers to use the libxfs function,
as needed. In some places we drop the "bno != 0" checks because those
conditionals are checking btree roots; btree roots should never be
zero if the corresponding feature bit is set; and repair skips the if
clause entirely if the feature bit is disabled.
In effect, this strengthens repair to validate that AG btree pointers
neither point to the AG headers nor past the end of the AG.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
libxfs/libxfs_api_defs.h | 1 +
repair/dinode.c | 11 -----------
repair/dinode.h | 5 -----
repair/scan.c | 36 +++++++++++++++++++++++-------------
4 files changed, 24 insertions(+), 29 deletions(-)
Index: xfsprogs-5.0.0/libxfs/libxfs_api_defs.h
===================================================================
--- xfsprogs-5.0.0.orig/libxfs/libxfs_api_defs.h
+++ xfsprogs-5.0.0/libxfs/libxfs_api_defs.h
@@ -121,6 +121,7 @@
#define xfs_verify_agbno libxfs_verify_agbno
#define xfs_verify_cksum libxfs_verify_cksum
#define xfs_dinode_verify libxfs_dinode_verify
+#define xfs_ag_block_count libxfs_ag_block_count
#define xfs_alloc_ag_max_usable libxfs_alloc_ag_max_usable
#define xfs_allocbt_maxrecs libxfs_allocbt_maxrecs
Index: xfsprogs-5.0.0/repair/dinode.c
===================================================================
--- xfsprogs-5.0.0.orig/repair/dinode.c
+++ xfsprogs-5.0.0/repair/dinode.c
@@ -284,17 +284,6 @@ verify_dfsbno_range(xfs_mount_t *mp,
return (XR_DFSBNORANGE_VALID);
}
-int
-verify_agbno(xfs_mount_t *mp,
- xfs_agnumber_t agno,
- xfs_agblock_t agbno)
-{
- xfs_sb_t *sbp = &mp->m_sb;;
-
- /* range check ag #, ag block. range-checking offset is pointless */
- return verify_ag_bno(sbp, agno, agbno) == 0;
-}
-
static int
process_rt_rec(
xfs_mount_t *mp,
Index: xfsprogs-5.0.0/repair/dinode.h
===================================================================
--- xfsprogs-5.0.0.orig/repair/dinode.h
+++ xfsprogs-5.0.0/repair/dinode.h
@@ -10,11 +10,6 @@ struct blkmap;
struct prefetch_args;
int
-verify_agbno(xfs_mount_t *mp,
- xfs_agnumber_t agno,
- xfs_agblock_t agbno);
-
-int
verify_dfsbno(xfs_mount_t *mp,
xfs_fsblock_t fsbno);
Index: xfsprogs-5.0.0/repair/scan.c
===================================================================
--- xfsprogs-5.0.0.orig/repair/scan.c
+++ xfsprogs-5.0.0/repair/scan.c
@@ -642,14 +642,14 @@ _("%s freespace btree block claimed (sta
len = be32_to_cpu(rp[i].ar_blockcount);
end = b + len;
- if (b == 0 || !verify_agbno(mp, agno, b)) {
+ if (!libxfs_verify_agbno(mp, agno, b)) {
do_warn(
_("invalid start block %u in record %u of %s btree block %u/%u\n"),
b, i, name, agno, bno);
continue;
}
if (len == 0 || end <= b ||
- !verify_agbno(mp, agno, end - 1)) {
+ !libxfs_verify_agbno(mp, agno, end - 1)) {
do_warn(
_("invalid length %u in record %u of %s btree block %u/%u\n"),
len, i, name, agno, bno);
@@ -914,6 +914,16 @@ rmap_in_order(
return offset > lastoffset;
}
+static inline bool
+verify_rmap_agbno(
+ struct xfs_mount *mp,
+ xfs_agnumber_t agno,
+ xfs_agblock_t agbno)
+{
+ return agbno < libxfs_ag_block_count(mp, agno);
+}
+
+
static void
scan_rmapbt(
struct xfs_btree_block *block,
@@ -1031,14 +1041,14 @@ _("%s rmap btree block claimed (state %d
end = key.rm_startblock + key.rm_blockcount;
/* Make sure agbno & len make sense. */
- if (!verify_agbno(mp, agno, b)) {
+ if (!verify_rmap_agbno(mp, agno, b)) {
do_warn(
_("invalid start block %u in record %u of %s btree block %u/%u\n"),
b, i, name, agno, bno);
continue;
}
if (len == 0 || end <= b ||
- !verify_agbno(mp, agno, end - 1)) {
+ !verify_rmap_agbno(mp, agno, end - 1)) {
do_warn(
_("invalid length %u in record %u of %s btree block %u/%u\n"),
len, i, name, agno, bno);
@@ -1325,14 +1335,14 @@ _("leftover CoW extent has invalid start
}
end = agb + len;
- if (!verify_agbno(mp, agno, agb)) {
+ if (!libxfs_verify_agbno(mp, agno, agb)) {
do_warn(
_("invalid start block %u in record %u of %s btree block %u/%u\n"),
b, i, name, agno, bno);
continue;
}
if (len == 0 || end <= agb ||
- !verify_agbno(mp, agno, end - 1)) {
+ !libxfs_verify_agbno(mp, agno, end - 1)) {
do_warn(
_("invalid length %u in record %u of %s btree block %u/%u\n"),
len, i, name, agno, bno);
@@ -2145,7 +2155,7 @@ scan_agfl(
{
struct agfl_state *as = priv;
- if (verify_agbno(mp, as->agno, bno))
+ if (libxfs_verify_agbno(mp, as->agno, bno))
set_bmap(as->agno, bno, XR_E_FREE);
else
do_warn(_("bad agbno %u in agfl, agno %d\n"),
@@ -2217,7 +2227,7 @@ validate_agf(
uint32_t magic;
bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]);
- if (bno != 0 && verify_agbno(mp, agno, bno)) {
+ if (libxfs_verify_agbno(mp, agno, bno)) {
magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_ABTB_CRC_MAGIC
: XFS_ABTB_MAGIC;
scan_sbtree(bno, be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]),
@@ -2229,7 +2239,7 @@ validate_agf(
}
bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]);
- if (bno != 0 && verify_agbno(mp, agno, bno)) {
+ if (libxfs_verify_agbno(mp, agno, bno)) {
magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_ABTC_CRC_MAGIC
: XFS_ABTC_MAGIC;
scan_sbtree(bno, be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]),
@@ -2249,7 +2259,7 @@ validate_agf(
priv.last_rec.rm_owner = XFS_RMAP_OWN_UNKNOWN;
priv.nr_blocks = 0;
bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_RMAP]);
- if (bno != 0 && verify_agbno(mp, agno, bno)) {
+ if (libxfs_verify_agbno(mp, agno, bno)) {
scan_sbtree(bno,
be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]),
agno, 0, scan_rmapbt, 1, XFS_RMAP_CRC_MAGIC,
@@ -2267,7 +2277,7 @@ validate_agf(
if (xfs_sb_version_hasreflink(&mp->m_sb)) {
bno = be32_to_cpu(agf->agf_refcount_root);
- if (bno != 0 && verify_agbno(mp, agno, bno)) {
+ if (libxfs_verify_agbno(mp, agno, bno)) {
struct refc_priv priv;
memset(&priv, 0, sizeof(priv));
@@ -2315,7 +2325,7 @@ validate_agi(
uint32_t magic;
bno = be32_to_cpu(agi->agi_root);
- if (bno != 0 && verify_agbno(mp, agno, bno)) {
+ if (libxfs_verify_agbno(mp, agno, bno)) {
magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_IBT_CRC_MAGIC
: XFS_IBT_MAGIC;
scan_sbtree(bno, be32_to_cpu(agi->agi_level),
@@ -2328,7 +2338,7 @@ validate_agi(
if (xfs_sb_version_hasfinobt(&mp->m_sb)) {
bno = be32_to_cpu(agi->agi_free_root);
- if (bno != 0 && verify_agbno(mp, agno, bno)) {
+ if (libxfs_verify_agbno(mp, agno, bno)) {
magic = xfs_sb_version_hascrc(&mp->m_sb) ?
XFS_FIBT_CRC_MAGIC : XFS_FIBT_MAGIC;
scan_sbtree(bno, be32_to_cpu(agi->agi_free_level),

View File

@ -0,0 +1,290 @@
From 6df28d12d7760701c9d11e659e374665c5ffd0b9 Mon Sep 17 00:00:00 2001
From: Gao Xiang <hsiangkao@redhat.com>
Date: Fri, 10 Jul 2020 15:32:36 -0400
Subject: [PATCH] xfs_repair: fix rebuilding btree block less than minrecs
In production, we found that sometimes xfs_repair phase 5
rebuilds freespace node block with pointers less than minrecs
and if we trigger xfs_repair again it would report such
the following message:
bad btree nrecs (39, min=40, max=80) in btbno block 0/7882
The background is that xfs_repair starts to rebuild AGFL
after the freespace btree is settled in phase 5 so we may
need to leave necessary room in advance for each btree
leaves in order to avoid freespace btree split and then
result in AGFL rebuild fails. The old mathematics uses
ceil(num_extents / maxrecs) to decide the number of node
blocks. That would be fine without leaving extra space
since minrecs = maxrecs / 2 but if some slack was decreased
from maxrecs, the result would be larger than what is
expected and cause num_recs_pb less than minrecs, i.e:
num_extents = 79, adj_maxrecs = 80 - 2 (slack) = 78
so we'd get
num_blocks = ceil(79 / 78) = 2,
num_recs_pb = 79 / 2 = 39, which is less than
minrecs = 80 / 2 = 40
OTOH, btree bulk loading code behaves in a different way.
As in xfs_btree_bload_level_geometry it wrote
num_blocks = floor(num_extents / maxrecs)
which will never go below minrecs. And when it goes above
maxrecs, just increment num_blocks and recalculate so we
can get the reasonable results.
Later, btree bulk loader will replace the current repair code.
But we may still want to look for a backportable solution
for stable versions. Hence, keep the same logic to avoid
the freespace as well as rmap btree minrecs underflow for now.
Cc: "Darrick J. Wong" <darrick.wong@oracle.com>
Cc: Dave Chinner <dchinner@redhat.com>
Cc: Eric Sandeen <sandeen@sandeen.net>
Fixes: 9851fd79bfb1 ("repair: AGFL rebuild fails if btree split required")
Signed-off-by: Gao Xiang <hsiangkao@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
repair/phase5.c | 152 ++++++++++++++++++++----------------------------
1 file changed, 63 insertions(+), 89 deletions(-)
Index: xfsprogs-5.0.0/repair/phase5.c
===================================================================
--- xfsprogs-5.0.0.orig/repair/phase5.c
+++ xfsprogs-5.0.0/repair/phase5.c
@@ -346,11 +346,32 @@ finish_cursor(bt_status_t *curs)
* failure at runtime. Hence leave a couple of records slack space in
* each block to allow immediate modification of the tree without
* requiring splits to be done.
- *
- * XXX(hch): any reason we don't just look at mp->m_alloc_mxr?
*/
-#define XR_ALLOC_BLOCK_MAXRECS(mp, level) \
- (libxfs_allocbt_maxrecs((mp), (mp)->m_sb.sb_blocksize, (level) == 0) - 2)
+static void
+compute_level_geometry(
+ struct xfs_mount *mp,
+ struct bt_stat_level *lptr,
+ uint64_t nr_this_level,
+ int slack,
+ bool leaf)
+{
+ unsigned int maxrecs = mp->m_alloc_mxr[!leaf];
+ unsigned int desired_npb;
+
+ desired_npb = max(mp->m_alloc_mnr[!leaf], maxrecs - slack);
+ lptr->num_recs_tot = nr_this_level;
+ lptr->num_blocks = max(1ULL, nr_this_level / desired_npb);
+
+ lptr->num_recs_pb = nr_this_level / lptr->num_blocks;
+ lptr->modulo = nr_this_level % lptr->num_blocks;
+ if (lptr->num_recs_pb > maxrecs ||
+ (lptr->num_recs_pb == maxrecs && lptr->modulo)) {
+ lptr->num_blocks++;
+
+ lptr->num_recs_pb = nr_this_level / lptr->num_blocks;
+ lptr->modulo = nr_this_level % lptr->num_blocks;
+ }
+}
/*
* this calculates a freespace cursor for an ag.
@@ -368,6 +389,7 @@ calculate_freespace_cursor(xfs_mount_t *
int i;
int extents_used;
int extra_blocks;
+ uint64_t old_blocks;
bt_stat_level_t *lptr;
bt_stat_level_t *p_lptr;
extent_tree_node_t *ext_ptr;
@@ -386,10 +408,7 @@ calculate_freespace_cursor(xfs_mount_t *
* of the tree and set up the cursor for the leaf level
* (note that the same code is duplicated further down)
*/
- lptr->num_blocks = howmany(num_extents, XR_ALLOC_BLOCK_MAXRECS(mp, 0));
- lptr->num_recs_pb = num_extents / lptr->num_blocks;
- lptr->modulo = num_extents % lptr->num_blocks;
- lptr->num_recs_tot = num_extents;
+ compute_level_geometry(mp, lptr, num_extents, 2, true);
level = 1;
#ifdef XR_BLD_FREE_TRACE
@@ -403,30 +422,23 @@ calculate_freespace_cursor(xfs_mount_t *
* if we need more levels, set them up. # of records
* per level is the # of blocks in the level below it
*/
- if (lptr->num_blocks > 1) {
- for (; btree_curs->level[level - 1].num_blocks > 1
- && level < XFS_BTREE_MAXLEVELS;
- level++) {
- lptr = &btree_curs->level[level];
- p_lptr = &btree_curs->level[level - 1];
- lptr->num_blocks = howmany(p_lptr->num_blocks,
- XR_ALLOC_BLOCK_MAXRECS(mp, level));
- lptr->modulo = p_lptr->num_blocks
- % lptr->num_blocks;
- lptr->num_recs_pb = p_lptr->num_blocks
- / lptr->num_blocks;
- lptr->num_recs_tot = p_lptr->num_blocks;
+ while (lptr->num_blocks > 1) {
+ p_lptr = lptr;
+ lptr = &btree_curs->level[level];
+
+ compute_level_geometry(mp, lptr,
+ p_lptr->num_blocks, 0, false);
#ifdef XR_BLD_FREE_TRACE
- fprintf(stderr, "%s %d %d %d %d %d\n", __func__,
- level,
- lptr->num_blocks,
- lptr->num_recs_pb,
- lptr->modulo,
- lptr->num_recs_tot);
+ fprintf(stderr, "%s %d %d %d %d %d\n", __func__,
+ level,
+ lptr->num_blocks,
+ lptr->num_recs_pb,
+ lptr->modulo,
+ lptr->num_recs_tot);
#endif
- }
+ level++;
}
-
+ ASSERT(level < XFS_BTREE_MAXLEVELS);
ASSERT(lptr->num_blocks == 1);
btree_curs->num_levels = level;
@@ -494,8 +506,11 @@ calculate_freespace_cursor(xfs_mount_t *
* see if the number of leaf blocks will change as a result
* of the number of extents changing
*/
- if (howmany(num_extents, XR_ALLOC_BLOCK_MAXRECS(mp, 0))
- != btree_curs->level[0].num_blocks) {
+ old_blocks = btree_curs->level[0].num_blocks;
+ compute_level_geometry(mp, &btree_curs->level[0], num_extents, 2, true);
+ extra_blocks = 0;
+
+ if (old_blocks != btree_curs->level[0].num_blocks) {
/*
* yes -- recalculate the cursor. If the number of
* excess (overallocated) blocks is < xfs_agfl_size/2, we're ok.
@@ -551,31 +566,19 @@ calculate_freespace_cursor(xfs_mount_t *
}
lptr = &btree_curs->level[0];
- lptr->num_blocks = howmany(num_extents,
- XR_ALLOC_BLOCK_MAXRECS(mp, 0));
- lptr->num_recs_pb = num_extents / lptr->num_blocks;
- lptr->modulo = num_extents % lptr->num_blocks;
- lptr->num_recs_tot = num_extents;
level = 1;
/*
* if we need more levels, set them up
*/
- if (lptr->num_blocks > 1) {
- for (level = 1; btree_curs->level[level-1].num_blocks
- > 1 && level < XFS_BTREE_MAXLEVELS;
- level++) {
- lptr = &btree_curs->level[level];
- p_lptr = &btree_curs->level[level-1];
- lptr->num_blocks = howmany(p_lptr->num_blocks,
- XR_ALLOC_BLOCK_MAXRECS(mp, level));
- lptr->modulo = p_lptr->num_blocks
- % lptr->num_blocks;
- lptr->num_recs_pb = p_lptr->num_blocks
- / lptr->num_blocks;
- lptr->num_recs_tot = p_lptr->num_blocks;
- }
+ while (lptr->num_blocks > 1) {
+ p_lptr = lptr;
+ lptr = &btree_curs->level[level++];
+
+ compute_level_geometry(mp, lptr,
+ p_lptr->num_blocks, 0, false);
}
+ ASSERT(level < XFS_BTREE_MAXLEVELS);
ASSERT(lptr->num_blocks == 1);
btree_curs->num_levels = level;
@@ -589,22 +592,6 @@ calculate_freespace_cursor(xfs_mount_t *
ASSERT(blocks_allocated_total >= blocks_needed);
extra_blocks = blocks_allocated_total - blocks_needed;
- } else {
- if (extents_used > 0) {
- /*
- * reset the leaf level geometry to account
- * for consumed extents. we can leave the
- * rest of the cursor alone since the number
- * of leaf blocks hasn't changed.
- */
- lptr = &btree_curs->level[0];
-
- lptr->num_recs_pb = num_extents / lptr->num_blocks;
- lptr->modulo = num_extents % lptr->num_blocks;
- lptr->num_recs_tot = num_extents;
- }
-
- extra_blocks = 0;
}
btree_curs->num_tot_blocks = blocks_allocated_pt;
@@ -1335,7 +1322,6 @@ init_rmapbt_cursor(
struct bt_stat_level *lptr;
struct bt_stat_level *p_lptr;
xfs_extlen_t blocks_allocated;
- int maxrecs;
if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) {
memset(btree_curs, 0, sizeof(struct bt_status));
@@ -1371,32 +1357,20 @@ init_rmapbt_cursor(
* Leave enough slack in the rmapbt that we can insert the
* metadata AG entries without too many splits.
*/
- maxrecs = mp->m_rmap_mxr[0];
- if (num_recs > maxrecs)
- maxrecs -= 10;
- blocks_allocated = lptr->num_blocks = howmany(num_recs, maxrecs);
-
- lptr->modulo = num_recs % lptr->num_blocks;
- lptr->num_recs_pb = num_recs / lptr->num_blocks;
- lptr->num_recs_tot = num_recs;
+ compute_level_geometry(mp, lptr, num_recs,
+ num_recs > mp->m_rmap_mxr[0] ? 10 : 0, true);
+ blocks_allocated = lptr->num_blocks;
level = 1;
- if (lptr->num_blocks > 1) {
- for (; btree_curs->level[level-1].num_blocks > 1
- && level < XFS_BTREE_MAXLEVELS;
- level++) {
- lptr = &btree_curs->level[level];
- p_lptr = &btree_curs->level[level - 1];
- lptr->num_blocks = howmany(p_lptr->num_blocks,
- mp->m_rmap_mxr[1]);
- lptr->modulo = p_lptr->num_blocks % lptr->num_blocks;
- lptr->num_recs_pb = p_lptr->num_blocks
- / lptr->num_blocks;
- lptr->num_recs_tot = p_lptr->num_blocks;
-
- blocks_allocated += lptr->num_blocks;
- }
+ while (lptr->num_blocks > 1) {
+ p_lptr = lptr;
+ lptr = &btree_curs->level[level++];
+
+ compute_level_geometry(mp, lptr,
+ p_lptr->num_blocks, 0, false);
+ blocks_allocated += lptr->num_blocks;
}
+ ASSERT(level < XFS_BTREE_MAXLEVELS);
ASSERT(lptr->num_blocks == 1);
btree_curs->num_levels = level;

View File

@ -0,0 +1,88 @@
From 08280b4b6efd317c673c6718a27d77e702d0480d Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 10 Jul 2020 15:35:45 -0400
Subject: [PATCH] xfs_repair: tag inobt vs finobt errors properly
Amend the generic inode btree block scanner function to tag correctly
which tree it's complaining about. Previously, dubious finobt headers
would be attributed to the "inode btree", which is at best ambiguous
and misleading at worst.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
repair/scan.c | 36 ++++++++++++++++++++++++++----------
1 file changed, 26 insertions(+), 10 deletions(-)
Index: xfsprogs-5.0.0/repair/scan.c
===================================================================
--- xfsprogs-5.0.0.orig/repair/scan.c
+++ xfsprogs-5.0.0/repair/scan.c
@@ -1934,6 +1934,7 @@ scan_inobt(
const struct xfs_buf_ops *ops)
{
struct aghdr_cnts *agcnts = priv;
+ char *name;
int i;
int numrecs;
int state;
@@ -1944,17 +1945,32 @@ scan_inobt(
hdr_errors = 0;
+ switch (magic) {
+ case XFS_FIBT_MAGIC:
+ case XFS_FIBT_CRC_MAGIC:
+ name = "fino";
+ break;
+ case XFS_IBT_MAGIC:
+ case XFS_IBT_CRC_MAGIC:
+ name = "ino";
+ break;
+ default:
+ name = "(unknown)";
+ assert(0);
+ break;
+ }
+
if (be32_to_cpu(block->bb_magic) != magic) {
- do_warn(_("bad magic # %#x in inobt block %d/%d\n"),
- be32_to_cpu(block->bb_magic), agno, bno);
+ do_warn(_("bad magic # %#x in %sbt block %d/%d\n"),
+ be32_to_cpu(block->bb_magic), name, agno, bno);
hdr_errors++;
bad_ino_btree = 1;
if (suspect)
return;
}
if (be16_to_cpu(block->bb_level) != level) {
- do_warn(_("expected level %d got %d in inobt block %d/%d\n"),
- level, be16_to_cpu(block->bb_level), agno, bno);
+ do_warn(_("expected level %d got %d in %sbt block %d/%d\n"),
+ level, be16_to_cpu(block->bb_level), name, agno, bno);
hdr_errors++;
bad_ino_btree = 1;
if (suspect)
@@ -1976,8 +1992,8 @@ scan_inobt(
default:
set_bmap(agno, bno, XR_E_MULT);
do_warn(
-_("inode btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
- state, agno, bno, suspect);
+_("%sbt btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
+ name, state, agno, bno, suspect);
}
numrecs = be16_to_cpu(block->bb_numrecs);
@@ -1999,8 +2015,8 @@ _("inode btree block claimed (state %d),
if (hdr_errors) {
bad_ino_btree = 1;
- do_warn(_("dubious inode btree block header %d/%d\n"),
- agno, bno);
+ do_warn(_("dubious %sbt btree block header %d/%d\n"),
+ name, agno, bno);
suspect++;
}

View File

@ -0,0 +1,31 @@
From 7b4a7b3f6bce91be45b54fc68e169cb756dc8c74 Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sandeen@redhat.com>
Date: Mon, 24 Aug 2020 12:47:47 -0400
Subject: [PATCH] xfs_db: short circuit type_f if type is unchanged
There's no reason to go through the type change code if the
type has not been changed.
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>
---
db/type.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/db/type.c b/db/type.c
index 3cb1e868..572ac6d6 100644
--- a/db/type.c
+++ b/db/type.c
@@ -216,6 +216,8 @@ type_f(
tt = findtyp(argv[1]);
if (tt == NULL) {
dbprintf(_("no such type %s\n"), argv[1]);
+ } else if (iocur_top->typ == tt) {
+ return 0;
} else {
if (iocur_top->typ == NULL)
dbprintf(_("no current object\n"));
--
2.29.2

View File

@ -0,0 +1,76 @@
From ca42fa70929e88781e7daeee4cf4588adb834661 Mon Sep 17 00:00:00 2001
From: Bill O'Donnell <billodo@redhat.com>
Date: Mon, 24 Aug 2020 13:23:23 -0400
Subject: [PATCH] xfs_quota: command error message improvement
Make the error messages for rudimentary xfs_quota commands
(off, enable, disable) more user friendly, instead of the
terse sys error outputs.
Signed-off-by: Bill O'Donnell <billodo@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
quota/state.c | 32 ++++++++++++++++++++++++++------
1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/quota/state.c b/quota/state.c
index 8f9718f1..7a595fc6 100644
--- a/quota/state.c
+++ b/quota/state.c
@@ -306,8 +306,16 @@ enable_enforcement(
return;
}
dir = mount->fs_name;
- if (xfsquotactl(XFS_QUOTAON, dir, type, 0, (void *)&qflags) < 0)
- perror("XFS_QUOTAON");
+ if (xfsquotactl(XFS_QUOTAON, dir, type, 0, (void *)&qflags) < 0) {
+ if (errno == EEXIST)
+ fprintf(stderr,
+ _("Quota enforcement already enabled.\n"));
+ else if (errno == EINVAL || errno == ENOSYS)
+ fprintf(stderr,
+ _("Can't enable enforcement when quota off.\n"));
+ else
+ perror("XFS_QUOTAON");
+ }
else if (flags & VERBOSE_FLAG)
state_quotafile_mount(stdout, type, mount, flags);
}
@@ -328,8 +336,16 @@ disable_enforcement(
return;
}
dir = mount->fs_name;
- if (xfsquotactl(XFS_QUOTAOFF, dir, type, 0, (void *)&qflags) < 0)
- perror("XFS_QUOTAOFF");
+ if (xfsquotactl(XFS_QUOTAOFF, dir, type, 0, (void *)&qflags) < 0) {
+ if (errno == EEXIST)
+ fprintf(stderr,
+ _("Quota enforcement already disabled.\n"));
+ else if (errno == EINVAL || errno == ENOSYS)
+ fprintf(stderr,
+ _("Can't disable enforcement when quota off.\n"));
+ else
+ perror("XFS_QUOTAOFF");
+ }
else if (flags & VERBOSE_FLAG)
state_quotafile_mount(stdout, type, mount, flags);
}
@@ -350,8 +366,12 @@ quotaoff(
return;
}
dir = mount->fs_name;
- if (xfsquotactl(XFS_QUOTAOFF, dir, type, 0, (void *)&qflags) < 0)
- perror("XFS_QUOTAOFF");
+ if (xfsquotactl(XFS_QUOTAOFF, dir, type, 0, (void *)&qflags) < 0) {
+ if (errno == EEXIST || errno == ENOSYS)
+ fprintf(stderr, _("Quota already off.\n"));
+ else
+ perror("XFS_QUOTAOFF");
+ }
else if (flags & VERBOSE_FLAG)
state_quotafile_mount(stdout, type, mount, flags);
}
--
2.31.1

View File

@ -0,0 +1,52 @@
From 387a96e12a937c1b2ee29a0f2c52245d6a283078 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Mon, 24 Aug 2020 13:23:32 -0400
Subject: [PATCH] xfs_quota: display warning limits when printing quota type
information
We should dump the default warning limits when we're printing quota
information.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
quota/state.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/quota/state.c b/quota/state.c
index 7a595fc6..1627181d 100644
--- a/quota/state.c
+++ b/quota/state.c
@@ -130,6 +130,16 @@ state_timelimit(
time_to_string(timelimit, VERBOSE_FLAG | ABSOLUTE_FLAG));
}
+static void
+state_warnlimit(
+ FILE *fp,
+ uint form,
+ uint16_t warnlimit)
+{
+ fprintf(fp, _("%s max warnings: %u\n"),
+ form_to_string(form), warnlimit);
+}
+
/*
* fs_quota_stat holds a subset of fs_quota_statv; this copies
* the smaller into the larger, leaving any not-present fields
@@ -218,7 +228,11 @@ state_quotafile_mount(
sv.qs_flags & XFS_QUOTA_PDQ_ENFD);
state_timelimit(fp, XFS_BLOCK_QUOTA, sv.qs_btimelimit);
+ state_warnlimit(fp, XFS_BLOCK_QUOTA, sv.qs_bwarnlimit);
+
state_timelimit(fp, XFS_INODE_QUOTA, sv.qs_itimelimit);
+ state_warnlimit(fp, XFS_INODE_QUOTA, sv.qs_iwarnlimit);
+
state_timelimit(fp, XFS_RTBLOCK_QUOTA, sv.qs_rtbtimelimit);
}
--
2.31.1

View File

@ -0,0 +1,141 @@
From d8a9454608ff97e98fb7de0da28f8d40804d2296 Mon Sep 17 00:00:00 2001
From: Bill O'Donnell <billodo@redhat.com>
Date: Mon, 24 Aug 2020 13:23:43 -0400
Subject: [PATCH] xfs_quota: state command should report ugp grace times
Since grace periods are now supported for three quota types (ugp),
modify xfs_quota state command to report times for all three.
Add a helper function for stat reporting.
Signed-off-by: Bill O'Donnell <billodo@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
quota/state.c | 96 +++++++++++++++++++++++++++++++++++----------------
1 file changed, 67 insertions(+), 29 deletions(-)
diff --git a/quota/state.c b/quota/state.c
index 1627181d..19d34ed0 100644
--- a/quota/state.c
+++ b/quota/state.c
@@ -191,49 +191,87 @@ state_stat_to_statv(
}
static void
-state_quotafile_mount(
+state_quotafile_stat(
FILE *fp,
uint type,
- struct fs_path *mount,
+ struct fs_path *mount,
+ struct fs_quota_statv *sv,
+ struct fs_quota_stat *s,
uint flags)
{
- struct fs_quota_stat s;
- struct fs_quota_statv sv;
+ bool accounting, enforcing;
+ struct fs_qfilestatv *qsv;
char *dev = mount->fs_name;
- sv.qs_version = FS_QSTATV_VERSION1;
-
- if (xfsquotactl(XFS_GETQSTATV, dev, type, 0, (void *)&sv) < 0) {
- if (xfsquotactl(XFS_GETQSTAT, dev, type, 0, (void *)&s) < 0) {
+ if (xfsquotactl(XFS_GETQSTATV, dev, type, 0, (void *)sv) < 0) {
+ if (xfsquotactl(XFS_GETQSTAT, dev, type, 0, (void *)s) < 0) {
if (flags & VERBOSE_FLAG)
fprintf(fp,
_("%s quota are not enabled on %s\n"),
type_to_string(type), dev);
return;
}
- state_stat_to_statv(&s, &sv);
+ state_stat_to_statv(s, sv);
+ }
+
+ switch(type) {
+ case XFS_USER_QUOTA:
+ qsv = &sv->qs_uquota;
+ accounting = sv->qs_flags & XFS_QUOTA_UDQ_ACCT;
+ enforcing = sv->qs_flags & XFS_QUOTA_UDQ_ENFD;
+ break;
+ case XFS_GROUP_QUOTA:
+ qsv = &sv->qs_gquota;
+ accounting = sv->qs_flags & XFS_QUOTA_GDQ_ACCT;
+ enforcing = sv->qs_flags & XFS_QUOTA_GDQ_ENFD;
+ break;
+ case XFS_PROJ_QUOTA:
+ qsv = &sv->qs_pquota;
+ accounting = sv->qs_flags & XFS_QUOTA_PDQ_ACCT;
+ enforcing = sv->qs_flags & XFS_QUOTA_PDQ_ENFD;
+ break;
+ default:
+ return;
}
- if (type & XFS_USER_QUOTA)
- state_qfilestat(fp, mount, XFS_USER_QUOTA, &sv.qs_uquota,
- sv.qs_flags & XFS_QUOTA_UDQ_ACCT,
- sv.qs_flags & XFS_QUOTA_UDQ_ENFD);
- if (type & XFS_GROUP_QUOTA)
- state_qfilestat(fp, mount, XFS_GROUP_QUOTA, &sv.qs_gquota,
- sv.qs_flags & XFS_QUOTA_GDQ_ACCT,
- sv.qs_flags & XFS_QUOTA_GDQ_ENFD);
- if (type & XFS_PROJ_QUOTA)
- state_qfilestat(fp, mount, XFS_PROJ_QUOTA, &sv.qs_pquota,
- sv.qs_flags & XFS_QUOTA_PDQ_ACCT,
- sv.qs_flags & XFS_QUOTA_PDQ_ENFD);
-
- state_timelimit(fp, XFS_BLOCK_QUOTA, sv.qs_btimelimit);
- state_warnlimit(fp, XFS_BLOCK_QUOTA, sv.qs_bwarnlimit);
-
- state_timelimit(fp, XFS_INODE_QUOTA, sv.qs_itimelimit);
- state_warnlimit(fp, XFS_INODE_QUOTA, sv.qs_iwarnlimit);
-
- state_timelimit(fp, XFS_RTBLOCK_QUOTA, sv.qs_rtbtimelimit);
+
+ state_qfilestat(fp, mount, type, qsv, accounting, enforcing);
+
+ state_timelimit(fp, XFS_BLOCK_QUOTA, sv->qs_btimelimit);
+ state_warnlimit(fp, XFS_BLOCK_QUOTA, sv->qs_bwarnlimit);
+
+ state_timelimit(fp, XFS_INODE_QUOTA, sv->qs_itimelimit);
+ state_warnlimit(fp, XFS_INODE_QUOTA, sv->qs_iwarnlimit);
+
+ state_timelimit(fp, XFS_RTBLOCK_QUOTA, sv->qs_rtbtimelimit);
+}
+
+static void
+state_quotafile_mount(
+ FILE *fp,
+ uint type,
+ struct fs_path *mount,
+ uint flags)
+{
+ struct fs_quota_stat s;
+ struct fs_quota_statv sv;
+
+ sv.qs_version = FS_QSTATV_VERSION1;
+
+ if (type & XFS_USER_QUOTA) {
+ state_quotafile_stat(fp, XFS_USER_QUOTA, mount,
+ &sv, &s, flags);
+ }
+
+ if (type & XFS_GROUP_QUOTA) {
+ state_quotafile_stat(fp, XFS_GROUP_QUOTA, mount,
+ &sv, &s, flags);
+ }
+
+ if (type & XFS_PROJ_QUOTA) {
+ state_quotafile_stat(fp, XFS_PROJ_QUOTA, mount,
+ &sv, &s, flags);
+ }
}
static void
--
2.31.1

View File

@ -0,0 +1,76 @@
From 97a4059660b27a9b0e3d8cdde5dbef8712685865 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Mon, 28 Sep 2020 17:31:18 -0400
Subject: [PATCH] mkfs.xfs: fix ASSERT on too-small device with stripe geometry
When a too-small device is created with stripe geometry, we hit an
assert in align_ag_geometry():
mkfs.xfs: xfs_mkfs.c:2834: align_ag_geometry: Assertion `cfg->agcount != 0' failed.
This is because align_ag_geometry() finds that the size of the last
(only) AG is too small, and attempts to trim it off. Obviously 0
AGs is invalid, and we hit the ASSERT.
Reported-by: Zdenek Kabelac <zkabelac@redhat.com>
Suggested-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Pavel Reichl <preichl@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
include/xfs_multidisk.h | 14 +++++++-------
mkfs/xfs_mkfs.c | 6 +++---
2 files changed, 10 insertions(+), 10 deletions(-)
Index: xfsprogs-5.0.0/include/xfs_multidisk.h
===================================================================
--- xfsprogs-5.0.0.orig/include/xfs_multidisk.h
+++ xfsprogs-5.0.0/include/xfs_multidisk.h
@@ -14,7 +14,6 @@
#define XFS_DFL_BLOCKSIZE_LOG 12 /* 4096 byte blocks */
#define XFS_DINODE_DFL_LOG 8 /* 256 byte inodes */
#define XFS_DINODE_DFL_CRC_LOG 9 /* 512 byte inodes for CRCs */
-#define XFS_MIN_DATA_BLOCKS 100
#define XFS_MIN_INODE_PERBLOCK 2 /* min inodes per block */
#define XFS_DFL_IMAXIMUM_PCT 25 /* max % of space for inodes */
#define XFS_MIN_REC_DIRSIZE 12 /* 4096 byte dirblocks (V2) */
@@ -25,13 +24,14 @@
* accept w/o warnings
*/
-#define XFS_AG_BYTES(bblog) ((long long)BBSIZE << (bblog))
-#define XFS_AG_MIN_BYTES ((XFS_AG_BYTES(15))) /* 16 MB */
-#define XFS_AG_MAX_BYTES ((XFS_AG_BYTES(31))) /* 1 TB */
-#define XFS_AG_MIN_BLOCKS(blog) (XFS_AG_MIN_BYTES >> (blog))
-#define XFS_AG_MAX_BLOCKS(blog) ((XFS_AG_MAX_BYTES - 1) >> (blog))
+#define XFS_AG_BYTES(bblog) ((long long)BBSIZE << (bblog))
+#define XFS_MIN_DATA_BLOCKS(cfg) (XFS_AG_MIN_BLOCKS((cfg)->blocklog))
+#define XFS_AG_MIN_BYTES ((XFS_AG_BYTES(15))) /* 16 MB */
+#define XFS_AG_MAX_BYTES ((XFS_AG_BYTES(31))) /* 1 TB */
+#define XFS_AG_MIN_BLOCKS(blog) (XFS_AG_MIN_BYTES >> (blog))
+#define XFS_AG_MAX_BLOCKS(blog) ((XFS_AG_MAX_BYTES - 1) >> (blog))
-#define XFS_MAX_AGNUMBER ((xfs_agnumber_t)(NULLAGNUMBER - 1))
+#define XFS_MAX_AGNUMBER ((xfs_agnumber_t)(NULLAGNUMBER - 1))
/*
* These values define what we consider a "multi-disk" filesystem. That is, a
Index: xfsprogs-5.0.0/mkfs/xfs_mkfs.c
===================================================================
--- xfsprogs-5.0.0.orig/mkfs/xfs_mkfs.c
+++ xfsprogs-5.0.0/mkfs/xfs_mkfs.c
@@ -2581,10 +2581,10 @@ _("size %s specified for data subvolume
cfg->dblocks = DTOBT(xi->dsize, cfg->blocklog);
}
- if (cfg->dblocks < XFS_MIN_DATA_BLOCKS) {
+ if (cfg->dblocks < XFS_MIN_DATA_BLOCKS(cfg)) {
fprintf(stderr,
-_("size %lld of data subvolume is too small, minimum %d blocks\n"),
- (long long)cfg->dblocks, XFS_MIN_DATA_BLOCKS);
+_("size %lld of data subvolume is too small, minimum %lld blocks\n"),
+ (long long)cfg->dblocks, XFS_MIN_DATA_BLOCKS(cfg));
usage();
}

View File

@ -0,0 +1,101 @@
From bce109af5ea0b0d6547d8cd0500560f32532e6bd Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 4 Sep 2020 16:05:20 -0400
Subject: [PATCH] xfs: drop the type parameter from xfs_dquot_verify
Source kernel commit: f9751c4ad3d17fa93773c187732f10c8a49940e3
xfs_qm_reset_dqcounts (aka quotacheck) is the only xfs_dqblk_verify
caller that actually knows the specific quota type that it's looking
for. Since everything else just pass in type==0 (including the buffer
verifier), drop the parameter and open-code the check like
xfs_dquot_from_disk already does.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
diff --git a/libxfs/xfs_dquot_buf.c b/libxfs/xfs_dquot_buf.c
index 5e31938..a3e8ba1 100644
--- a/libxfs/xfs_dquot_buf.c
+++ b/libxfs/xfs_dquot_buf.c
@@ -37,8 +37,7 @@ xfs_failaddr_t
xfs_dquot_verify(
struct xfs_mount *mp,
xfs_disk_dquot_t *ddq,
- xfs_dqid_t id,
- uint type) /* used only during quotacheck */
+ xfs_dqid_t id) /* used only during quotacheck */
{
/*
* We can encounter an uninitialized dquot buffer for 2 reasons:
@@ -60,8 +59,6 @@ xfs_dquot_verify(
if (ddq->d_version != XFS_DQUOT_VERSION)
return __this_address;
- if (type && ddq->d_flags != type)
- return __this_address;
if (ddq->d_flags != XFS_DQ_USER &&
ddq->d_flags != XFS_DQ_PROJ &&
ddq->d_flags != XFS_DQ_GROUP)
@@ -95,14 +92,13 @@ xfs_failaddr_t
xfs_dqblk_verify(
struct xfs_mount *mp,
struct xfs_dqblk *dqb,
- xfs_dqid_t id,
- uint type) /* used only during quotacheck */
+ xfs_dqid_t id) /* used only during quotacheck */
{
if (xfs_sb_version_hascrc(&mp->m_sb) &&
!uuid_equal(&dqb->dd_uuid, &mp->m_sb.sb_meta_uuid))
return __this_address;
- return xfs_dquot_verify(mp, &dqb->dd_diskdq, id, type);
+ return xfs_dquot_verify(mp, &dqb->dd_diskdq, id);
}
/*
@@ -207,7 +203,7 @@ xfs_dquot_buf_verify(
if (i == 0)
id = be32_to_cpu(ddq->d_id);
- fa = xfs_dqblk_verify(mp, &dqb[i], id + i, 0);
+ fa = xfs_dqblk_verify(mp, &dqb[i], id + i);
if (fa) {
if (!readahead)
xfs_buf_verifier_error(bp, -EFSCORRUPTED,
diff --git a/libxfs/xfs_quota_defs.h b/libxfs/xfs_quota_defs.h
index d3f2977..afe1ea0 100644
--- a/libxfs/xfs_quota_defs.h
+++ b/libxfs/xfs_quota_defs.h
@@ -140,9 +140,9 @@ typedef uint16_t xfs_qwarncnt_t;
#define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS)
extern xfs_failaddr_t xfs_dquot_verify(struct xfs_mount *mp,
- struct xfs_disk_dquot *ddq, xfs_dqid_t id, uint type);
+ struct xfs_disk_dquot *ddq, xfs_dqid_t id);
extern xfs_failaddr_t xfs_dqblk_verify(struct xfs_mount *mp,
- struct xfs_dqblk *dqb, xfs_dqid_t id, uint type);
+ struct xfs_dqblk *dqb, xfs_dqid_t id);
extern int xfs_calc_dquots_per_chunk(unsigned int nbblks);
extern int xfs_dqblk_repair(struct xfs_mount *mp, struct xfs_dqblk *dqb,
xfs_dqid_t id, uint type);
diff --git a/repair/dinode.c b/repair/dinode.c
index 04c2dd5..77f78f1 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -1233,8 +1233,10 @@ _("cannot read inode %" PRIu64 ", file block %" PRIu64 ", disk block %" PRIu64 "
goto bad;
}
}
- if (libxfs_dquot_verify(mp, &dqb->dd_diskdq, dqid,
- quota_type) != NULL) {
+ if (libxfs_dquot_verify(mp, &dqb->dd_diskdq, dqid)
+ != NULL ||
+ (dqb->dd_diskdq.d_flags & XFS_DQ_ALLTYPES)
+ != quota_type) {
do_warn(_("%s: Corrupt quota for id %u. "),
quota_string, dqid);
bad_dqb = 1;

View File

@ -0,0 +1,78 @@
From 5ca4d781d36946de197ed2d4196c84c8f6b4522f Mon Sep 17 00:00:00 2001
From: Ian Kent <raven@themaw.net>
Date: Mon, 12 Oct 2020 15:40:01 -0400
Subject: [PATCH] xfsprogs: ignore autofs mount table entries
Some of the xfsprogs utilities read the mount table via. getmntent(3).
The mount table may contain (almost always these days since /etc/mtab is
symlinked to /proc/self/mounts) autofs mount entries. During processing
of the mount table entries statfs(2) can be called on mount point paths
which will trigger an automount if those entries are direct or offset
autofs mount triggers (indirect autofs mounts aren't affected).
This can be a problem when there are a lot of autofs direct or offset
mounts because real mounts will be triggered when statfs(2) is called.
This can be particularly bad if the triggered mounts are NFS mounts and
the server is unavailable leading to lengthy boot times or worse.
Simply ignoring autofs mount entries during getmentent(3) traversals
avoids the statfs() call that triggers these mounts. If there are
automounted mounts (real mounts) at the time of reading the mount table
these will still be seen in the list so they will be included if that
actually matters to the reader.
Recent glibc getmntent(3) can ignore autofs mounts but that requires the
autofs user to configure autofs to use the "ignore" pseudo mount option
for autofs mounts. But this isn't yet the autofs default (to prevent
unexpected side effects) so that can't be used.
The autofs direct and offset automount triggers are pseudo file system
mounts and are more or less useless in terms on file system information
so excluding them doesn't sacrifice useful file system information
either.
Consequently excluding autofs mounts shouldn't have any adverse side
effects.
Changes since v1:
- drop hunk from fsr/xfs_fsr.c.
Signed-off-by: Ian Kent <raven@themaw.net>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
Signed-off-by: Pavel Reichl <preichl@redhat.com>
---
libfrog/linux.c | 2 ++
libfrog/paths.c | 2 ++
2 files changed, 4 insertions(+)
diff --git a/libfrog/linux.c b/libfrog/linux.c
index 40a839d1..a45d99ab 100644
--- a/libfrog/linux.c
+++ b/libfrog/linux.c
@@ -73,6 +73,8 @@ platform_check_mount(char *name, char *block, struct stat *s, int flags)
* servers. So first, a simple check: does the "dev" start with "/" ?
*/
while ((mnt = getmntent(f)) != NULL) {
+ if (!strcmp(mnt->mnt_type, "autofs"))
+ continue;
if (mnt->mnt_fsname[0] != '/')
continue;
if (stat(mnt->mnt_dir, &mst) < 0)
diff --git a/libfrog/paths.c b/libfrog/paths.c
index 32737223..d6793764 100644
--- a/libfrog/paths.c
+++ b/libfrog/paths.c
@@ -389,6 +389,8 @@ fs_table_initialise_mounts(
return errno;
while ((mnt = getmntent(mtp)) != NULL) {
+ if (!strcmp(mnt->mnt_type, "autofs"))
+ continue;
if (!realpath(mnt->mnt_dir, rmnt_dir))
continue;
if (!realpath(mnt->mnt_fsname, rmnt_fsname))
--
2.40.1

View File

@ -0,0 +1,98 @@
From 28518f7782310951019d6d28f2a6e9f9fc6e4a1c Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Tue, 15 Sep 2020 15:50:35 -0400
Subject: [PATCH] xfs: improve ondisk dquot flags checking
Source kernel commit: a990f7a84edc9941956ea3c1dfb89733c80f9ad0
Create an XFS_DQTYPE_ANY mask for ondisk dquots flags, and use that to
ensure that we never accept any garbage flags when we're loading dquots.
While we're at it, restructure the quota type flag checking to use the
proper masking.
Note that I plan to add y2038 support soon, which will require a new
xfs_dqtype_t flag for extended timestamp support, hence all the work to
make the type masking work correctly.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
NOTES: I did not backport the type-vs-flags split, so some of the
naming convenstions are different here.
diff --git a/db/check.c b/db/check.c
index c3dae20..27f6639 100644
--- a/db/check.c
+++ b/db/check.c
@@ -3452,7 +3452,7 @@ process_quota(
error++;
continue;
}
- if (dqb->dd_diskdq.d_flags != exp_flags) {
+ if (dqb->dd_diskdq.d_flags & ~XFS_DQTYPE_ANY) {
if (scicb)
dbprintf(_("bad flags %#x for %s dqblk "
"%lld entry %d id %u\n"),
@@ -3461,6 +3461,17 @@ process_quota(
error++;
continue;
}
+ if ((dqb->dd_diskdq.d_flags & XFS_DQ_ALLTYPES)
+ != exp_flags) {
+ if (scicb)
+ dbprintf(_("wrong type %#x for %s dqblk "
+ "%lld entry %d id %u\n"),
+ dqb->dd_diskdq.d_flags &
+ XFS_DQ_ALLTYPES, s,
+ (xfs_fileoff_t)qbno, i, dqid);
+ error++;
+ continue;
+ }
if (be32_to_cpu(dqb->dd_diskdq.d_id) != dqid) {
if (scicb)
dbprintf(_("bad id %u for %s dqblk %lld "
diff --git a/libxfs/xfs_dquot_buf.c b/libxfs/xfs_dquot_buf.c
index a3e8ba1..324f528 100644
--- a/libxfs/xfs_dquot_buf.c
+++ b/libxfs/xfs_dquot_buf.c
@@ -39,6 +39,8 @@ xfs_dquot_verify(
xfs_disk_dquot_t *ddq,
xfs_dqid_t id) /* used only during quotacheck */
{
+ __u8 ddq_type;
+
/*
* We can encounter an uninitialized dquot buffer for 2 reasons:
* 1. If we crash while deleting the quotainode(s), and those blks got
@@ -59,9 +61,12 @@ xfs_dquot_verify(
if (ddq->d_version != XFS_DQUOT_VERSION)
return __this_address;
- if (ddq->d_flags != XFS_DQ_USER &&
- ddq->d_flags != XFS_DQ_PROJ &&
- ddq->d_flags != XFS_DQ_GROUP)
+ if (ddq->d_flags & ~XFS_DQTYPE_ANY)
+ return __this_address;
+ ddq_type = ddq->d_flags & XFS_DQ_ALLTYPES;
+ if (ddq_type != XFS_DQ_USER &&
+ ddq_type != XFS_DQ_PROJ &&
+ ddq_type != XFS_DQ_GROUP)
return __this_address;
if (id != -1 && id != be32_to_cpu(ddq->d_id))
diff --git a/libxfs/xfs_quota_defs.h b/libxfs/xfs_quota_defs.h
index afe1ea0..c69dba4 100644
--- a/libxfs/xfs_quota_defs.h
+++ b/libxfs/xfs_quota_defs.h
@@ -31,6 +31,8 @@ typedef uint16_t xfs_qwarncnt_t;
#define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
+#define XFS_DQTYPE_ANY (XFS_DQ_ALLTYPES)
+
#define XFS_DQ_FLAGS \
{ XFS_DQ_USER, "USER" }, \
{ XFS_DQ_PROJ, "PROJ" }, \

View File

@ -1,7 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iIUEABYIAC0WIQT6QG4gav94c4l8aGS0VhjDaiT9IwUCZLfVMw8cY2VtQGtlcm5l
bC5vcmcACgkQtFYYw2ok/SNKPwEA6fsxp1TRbPXQn6a605fU3cE6WjcqDLej3zYa
lx91BnABAKIWP14Rd7KPbCH4ezAPydFZxSn26trKqPxzAFOZ/skP
=mkU4
-----END PGP SIGNATURE-----

View File

@ -1,39 +0,0 @@
From 780e93c5103d3c19d53c36ab7f4794d14912f3a5 Mon Sep 17 00:00:00 2001
From: Bill O'Donnell <bodonnel@redhat.com>
Date: Fri, 28 Jul 2023 17:20:17 -0500
Subject: [PATCH] mkfs.xfs.8: correction on mkfs.xfs manpage since reflink and
dax are compatible
Merged early in 2023: Commit 480017957d638 xfs: remove restrictions for fsdax
and reflink. There needs to be a corresponding change to the mkfs.xfs manpage
to remove the incompatiblity statement.
Signed-off-by: Bill O'Donnell <bodonnel@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Pavel Reichl <preichl@redhat.com>
---
man/man8/mkfs.xfs.8.in | 7 -------
1 file changed, 7 deletions(-)
diff --git a/man/man8/mkfs.xfs.8.in b/man/man8/mkfs.xfs.8.in
index ce6f1e2d..08bb92f6 100644
--- a/man/man8/mkfs.xfs.8.in
+++ b/man/man8/mkfs.xfs.8.in
@@ -323,13 +323,6 @@ option set. When the option
.B \-m crc=0
is used, the reference count btree feature is not supported and reflink is
disabled.
-.IP
-Note: the filesystem DAX mount option (
-.B \-o dax
-) is incompatible with
-reflink-enabled XFS filesystems. To use filesystem DAX with XFS, specify the
-.B \-m reflink=0
-option to mkfs.xfs to disable the reflink feature.
.RE
.PP
.PD 0
--
2.41.0

View File

@ -1,57 +0,0 @@
From d096b26c33a858ad88db98306057da67e6d18611 Mon Sep 17 00:00:00 2001
From: Dave Chinner <dchinner@redhat.com>
Date: Wed, 6 Sep 2023 13:52:48 +0200
Subject: [PATCH] xfs: fix bounds check in xfs_defer_agfl_block()
Source kernel commit: 2bed0d82c2f78b91a0a9a5a73da57ee883a0c070
Need to happen before we allocate and then leak the xefi. Found by
coverity via an xfsprogs libxfs scan.
[djwong: This also fixes the type of the @agbno argument.]
Fixes: 7dfee17b13e5 ("xfs: validate block number being freed before adding to xefi")
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
libxfs/xfs_alloc.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
Index: xfsprogs-6.4.0/libxfs/xfs_alloc.c
===================================================================
--- xfsprogs-6.4.0.orig/libxfs/xfs_alloc.c
+++ xfsprogs-6.4.0/libxfs/xfs_alloc.c
@@ -2431,24 +2431,25 @@ static int
xfs_defer_agfl_block(
struct xfs_trans *tp,
xfs_agnumber_t agno,
- xfs_fsblock_t agbno,
+ xfs_agblock_t agbno,
struct xfs_owner_info *oinfo)
{
struct xfs_mount *mp = tp->t_mountp;
struct xfs_extent_free_item *xefi;
+ xfs_fsblock_t fsbno = XFS_AGB_TO_FSB(mp, agno, agbno);
ASSERT(xfs_extfree_item_cache != NULL);
ASSERT(oinfo != NULL);
+ if (XFS_IS_CORRUPT(mp, !xfs_verify_fsbno(mp, fsbno)))
+ return -EFSCORRUPTED;
+
xefi = kmem_cache_zalloc(xfs_extfree_item_cache,
GFP_KERNEL | __GFP_NOFAIL);
- xefi->xefi_startblock = XFS_AGB_TO_FSB(mp, agno, agbno);
+ xefi->xefi_startblock = fsbno;
xefi->xefi_blockcount = 1;
xefi->xefi_owner = oinfo->oi_owner;
- if (XFS_IS_CORRUPT(mp, !xfs_verify_fsbno(mp, xefi->xefi_startblock)))
- return -EFSCORRUPTED;
-
trace_xfs_agfl_free_defer(mp, agno, 0, agbno, 1);
xfs_extent_free_get_group(mp, xefi);

View File

@ -1,102 +0,0 @@
From a21daa3a739194b929de644779c359949390d467 Mon Sep 17 00:00:00 2001
From: Andrey Albershteyn <aalbersh@redhat.com>
Date: Wed, 17 Apr 2024 18:19:30 +0200
Subject: [PATCH] xfs_db: add helper for flist_find_type for clearer field
matching
Make flist_find_type() more readable by unloading field type
matching to the helper.
Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
db/flist.c | 60 ++++++++++++++++++++++++++++++++++--------------------
1 file changed, 38 insertions(+), 22 deletions(-)
diff --git a/db/flist.c b/db/flist.c
index 0a6cc5fc..ab0a0f13 100644
--- a/db/flist.c
+++ b/db/flist.c
@@ -400,6 +400,40 @@ flist_split(
return v;
}
+static flist_t *
+flist_field_match(
+ const field_t *field,
+ fldt_t type,
+ void *obj,
+ int startoff)
+{
+ flist_t *fl;
+ int count;
+ const ftattr_t *fa;
+ flist_t *nfl;
+
+ fl = flist_make(field->name);
+ fl->fld = field;
+ if (field->ftyp == type)
+ return fl;
+ count = fcount(field, obj, startoff);
+ if (!count)
+ goto out;
+ fa = &ftattrtab[field->ftyp];
+ if (!fa->subfld)
+ goto out;
+
+ nfl = flist_find_ftyp(fa->subfld, type, obj, startoff);
+ if (nfl) {
+ fl->child = nfl;
+ return fl;
+ }
+
+out:
+ flist_free(fl);
+ return NULL;
+}
+
/*
* Given a set of fields, scan for a field of the given type.
* Return an flist leading to the first found field
@@ -413,33 +447,15 @@ flist_find_ftyp(
void *obj,
int startoff)
{
- flist_t *fl;
const field_t *f;
- int count;
- const ftattr_t *fa;
+ flist_t *fl;
for (f = fields; f->name; f++) {
- fl = flist_make(f->name);
- fl->fld = f;
- if (f->ftyp == type)
+ fl = flist_field_match(f, type, obj, startoff);
+ if (fl)
return fl;
- count = fcount(f, obj, startoff);
- if (!count) {
- flist_free(fl);
- continue;
- }
- fa = &ftattrtab[f->ftyp];
- if (fa->subfld) {
- flist_t *nfl;
-
- nfl = flist_find_ftyp(fa->subfld, type, obj, startoff);
- if (nfl) {
- fl->child = nfl;
- return fl;
- }
- }
- flist_free(fl);
}
+
return NULL;
}
--
2.45.2

View File

@ -1,35 +0,0 @@
From 21dc682a3842eb7e4c79f7e511d840e708d7e757 Mon Sep 17 00:00:00 2001
From: Andrey Albershteyn <aalbersh@redhat.com>
Date: Tue, 23 Apr 2024 14:36:14 +0200
Subject: [PATCH] xfs_db: fix leak in flist_find_ftyp()
When count is zero fl reference is lost. Fix it by freeing the list.
Fixes: a0d79cb37a36 ("xfs_db: make flist_find_ftyp() to check for field existance on disk")
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Bill O'Donnell <bodonnel@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
---
db/flist.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/db/flist.c b/db/flist.c
index c81d229a..0a6cc5fc 100644
--- a/db/flist.c
+++ b/db/flist.c
@@ -424,8 +424,10 @@ flist_find_ftyp(
if (f->ftyp == type)
return fl;
count = fcount(f, obj, startoff);
- if (!count)
+ if (!count) {
+ flist_free(fl);
continue;
+ }
fa = &ftattrtab[f->ftyp];
if (fa->subfld) {
flist_t *nfl;
--
2.45.2

View File

@ -1,56 +0,0 @@
From 9c6e9d8de2d236f630efdd6fddb6277e8664989b Mon Sep 17 00:00:00 2001
From: Andrey Albershteyn <aalbersh@redhat.com>
Date: Tue, 23 Apr 2024 14:36:17 +0200
Subject: [PATCH] xfs_fsr: convert fsrallfs to use time_t instead of int
Convert howlong argument to a time_t as it's truncated to int, but in
practice this is not an issue as duration will never be this big.
Add check for howlong to fit into int (printf can use int format
specifier). Even longer interval doesn't make much sense.
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
---
fsr/xfs_fsr.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c
index 3077d8f4..02d61ef9 100644
--- a/fsr/xfs_fsr.c
+++ b/fsr/xfs_fsr.c
@@ -72,7 +72,7 @@ static int packfile(char *fname, char *tname, int fd,
static void fsrdir(char *dirname);
static int fsrfs(char *mntdir, xfs_ino_t ino, int targetrange);
static void initallfs(char *mtab);
-static void fsrallfs(char *mtab, int howlong, char *leftofffile);
+static void fsrallfs(char *mtab, time_t howlong, char *leftofffile);
static void fsrall_cleanup(int timeout);
static int getnextents(int);
int xfsrtextsize(int fd);
@@ -165,6 +165,12 @@ main(int argc, char **argv)
break;
case 't':
howlong = atoi(optarg);
+ if (howlong > INT_MAX) {
+ fprintf(stderr,
+ _("%s: the maximum runtime is %d seconds.\n"),
+ optarg, INT_MAX);
+ exit(1);
+ }
break;
case 'f':
leftofffile = optarg;
@@ -387,7 +393,7 @@ initallfs(char *mtab)
}
static void
-fsrallfs(char *mtab, int howlong, char *leftofffile)
+fsrallfs(char *mtab, time_t howlong, char *leftofffile)
{
int fd;
int error;
--
2.45.2

View File

@ -1,64 +0,0 @@
From 652f8066b7ca7dc1e08c2c40cdd9ba593a9de568 Mon Sep 17 00:00:00 2001
From: Andrey Albershteyn <aalbersh@redhat.com>
Date: Wed, 17 Apr 2024 18:19:29 +0200
Subject: [PATCH] xfs_fsr: replace atoi() with strtol()
Replace atoi() which silently fails with strtol() and report the
error.
Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
fsr/xfs_fsr.c | 26 +++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c
index 02d61ef9..fdd37756 100644
--- a/fsr/xfs_fsr.c
+++ b/fsr/xfs_fsr.c
@@ -164,7 +164,13 @@ main(int argc, char **argv)
usage(1);
break;
case 't':
- howlong = atoi(optarg);
+ errno = 0;
+ howlong = strtol(optarg, NULL, 10);
+ if (errno) {
+ fprintf(stderr, _("%s: invalid runtime: %s\n"),
+ optarg, strerror(errno));
+ exit(1);
+ }
if (howlong > INT_MAX) {
fprintf(stderr,
_("%s: the maximum runtime is %d seconds.\n"),
@@ -179,10 +185,24 @@ main(int argc, char **argv)
mtab = optarg;
break;
case 'b':
- argv_blksz_dio = atoi(optarg);
+ errno = 0;
+ argv_blksz_dio = strtol(optarg, NULL, 10);
+ if (errno) {
+ fprintf(stderr,
+ _("%s: invalid block size: %s\n"),
+ optarg, strerror(errno));
+ exit(1);
+ }
break;
case 'p':
- npasses = atoi(optarg);
+ errno = 0;
+ npasses = strtol(optarg, NULL, 10);
+ if (errno) {
+ fprintf(stderr,
+ _("%s: invalid number of passes: %s\n"),
+ optarg, strerror(errno));
+ exit(1);
+ }
break;
case 'C':
/* Testing opt: coerses frag count in result */
--
2.45.2

View File

@ -1,129 +0,0 @@
From d03b73d240dc7f5b4c02700c79c2c4eeeb94b08b Mon Sep 17 00:00:00 2001
From: Andrey Albershteyn <aalbersh@redhat.com>
Date: Wed, 17 Apr 2024 18:19:31 +0200
Subject: [PATCH] xfs_repair: catch strtol() errors
strtol() sets errno if string parsing. Abort and tell user which
parameter is wrong.
Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
repair/xfs_repair.c | 40 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 39 insertions(+), 1 deletion(-)
diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c
index 2ceea87d..2fc89dac 100644
--- a/repair/xfs_repair.c
+++ b/repair/xfs_repair.c
@@ -252,14 +252,22 @@ process_args(int argc, char **argv)
if (!val)
do_abort(
_("-o bhash requires a parameter\n"));
+ errno = 0;
libxfs_bhash_size = (int)strtol(val, NULL, 0);
+ if (errno)
+ do_abort(
+ _("-o bhash invalid parameter: %s\n"), strerror(errno));
bhash_option_used = 1;
break;
case AG_STRIDE:
if (!val)
do_abort(
_("-o ag_stride requires a parameter\n"));
+ errno = 0;
ag_stride = (int)strtol(val, NULL, 0);
+ if (errno)
+ do_abort(
+ _("-o ag_stride invalid parameter: %s\n"), strerror(errno));
break;
case FORCE_GEO:
if (val)
@@ -272,19 +280,31 @@ process_args(int argc, char **argv)
if (!val)
do_abort(
_("-o phase2_threads requires a parameter\n"));
+ errno = 0;
phase2_threads = (int)strtol(val, NULL, 0);
+ if (errno)
+ do_abort(
+ _("-o phase2_threads invalid parameter: %s\n"), strerror(errno));
break;
case BLOAD_LEAF_SLACK:
if (!val)
do_abort(
_("-o debug_bload_leaf_slack requires a parameter\n"));
+ errno = 0;
bload_leaf_slack = (int)strtol(val, NULL, 0);
+ if (errno)
+ do_abort(
+ _("-o debug_bload_leaf_slack invalid parameter: %s\n"), strerror(errno));
break;
case BLOAD_NODE_SLACK:
if (!val)
do_abort(
_("-o debug_bload_node_slack requires a parameter\n"));
+ errno = 0;
bload_node_slack = (int)strtol(val, NULL, 0);
+ if (errno)
+ do_abort(
+ _("-o debug_bload_node_slack invalid parameter: %s\n"), strerror(errno));
break;
case NOQUOTA:
quotacheck_skip();
@@ -305,7 +325,11 @@ process_args(int argc, char **argv)
if (!val)
do_abort(
_("-c lazycount requires a parameter\n"));
+ errno = 0;
lazy_count = (int)strtol(val, NULL, 0);
+ if (errno)
+ do_abort(
+ _("-o lazycount invalid parameter: %s\n"), strerror(errno));
convert_lazy_count = 1;
break;
case CONVERT_INOBTCOUNT:
@@ -356,7 +380,11 @@ process_args(int argc, char **argv)
if (bhash_option_used)
do_abort(_("-m option cannot be used with "
"-o bhash option\n"));
+ errno = 0;
max_mem_specified = strtol(optarg, NULL, 0);
+ if (errno)
+ do_abort(
+ _("%s: invalid memory amount: %s\n"), optarg, strerror(errno));
break;
case 'L':
zap_log = 1;
@@ -377,7 +405,11 @@ process_args(int argc, char **argv)
do_prefetch = 0;
break;
case 't':
+ errno = 0;
report_interval = strtol(optarg, NULL, 0);
+ if (errno)
+ do_abort(
+ _("%s: invalid interval: %s\n"), optarg, strerror(errno));
break;
case 'e':
report_corrected = true;
@@ -397,8 +429,14 @@ process_args(int argc, char **argv)
usage();
p = getenv("XFS_REPAIR_FAIL_AFTER_PHASE");
- if (p)
+ if (p) {
+ errno = 0;
fail_after_phase = (int)strtol(p, NULL, 0);
+ if (errno)
+ do_abort(
+ _("%s: invalid phase in XFS_REPAIR_FAIL_AFTER_PHASE: %s\n"),
+ p, strerror(errno));
+ }
}
void __attribute__((noreturn))
--
2.45.2

View File

@ -1,110 +0,0 @@
From fcac184ccf342a345ea8fe4d842415841af89e64 Mon Sep 17 00:00:00 2001
From: Andrey Albershteyn <aalbersh@redhat.com>
Date: Tue, 23 Apr 2024 14:36:15 +0200
Subject: [PATCH] xfs_repair: make duration take time_t
In most of the uses of duration() takes time_t instead of int.
Convert the rest to use time_t and make duration() take time_t to
not truncate it to int.
While at it remove unnecessary parentheses around 'elapsed'.
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
---
repair/globals.c | 2 +-
repair/globals.h | 2 +-
repair/progress.c | 9 +++++----
repair/progress.h | 2 +-
repair/xfs_repair.c | 2 +-
5 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/repair/globals.c b/repair/globals.c
index a68929bd..24f720c4 100644
--- a/repair/globals.c
+++ b/repair/globals.c
@@ -116,7 +116,7 @@ uint32_t sb_width;
struct aglock *ag_locks;
struct aglock rt_lock;
-int report_interval;
+time_t report_interval;
uint64_t *prog_rpt_done;
int ag_stride;
diff --git a/repair/globals.h b/repair/globals.h
index a67e384a..b83a8ae6 100644
--- a/repair/globals.h
+++ b/repair/globals.h
@@ -160,7 +160,7 @@ struct aglock {
extern struct aglock *ag_locks;
extern struct aglock rt_lock;
-extern int report_interval;
+extern time_t report_interval;
extern uint64_t *prog_rpt_done;
extern int ag_stride;
diff --git a/repair/progress.c b/repair/progress.c
index f6c4d988..2ce36cef 100644
--- a/repair/progress.c
+++ b/repair/progress.c
@@ -265,15 +265,16 @@ progress_rpt_thread (void *p)
(current_phase == 7))) {
/* for inode phase report % complete */
do_log(
- _("\t- %02d:%02d:%02d: Phase %d: elapsed time %s - processed %d %s per minute\n"),
+ _("\t- %02d:%02d:%02d: Phase %d: elapsed time %s - processed %ld %s per minute\n"),
tmp->tm_hour, tmp->tm_min, tmp->tm_sec,
current_phase, duration(elapsed, msgbuf),
- (int) (60*sum/(elapsed)), *msgp->format->type);
+ 60 * sum / elapsed, *msgp->format->type);
do_log(
_("\t- %02d:%02d:%02d: Phase %d: %" PRIu64 "%% done - estimated remaining time %s\n"),
tmp->tm_hour, tmp->tm_min, tmp->tm_sec,
current_phase, percent,
- duration((int) ((*msgp->total - sum) * (elapsed)/sum), msgbuf));
+ duration((*msgp->total - sum) * elapsed / sum,
+ msgbuf));
}
if (pthread_mutex_unlock(&msgp->mutex) != 0) {
@@ -420,7 +421,7 @@ timestamp(int end, int phase, char *buf)
}
char *
-duration(int length, char *buf)
+duration(time_t length, char *buf)
{
int sum;
int weeks;
diff --git a/repair/progress.h b/repair/progress.h
index 2c1690db..9575df16 100644
--- a/repair/progress.h
+++ b/repair/progress.h
@@ -38,7 +38,7 @@ extern void summary_report(void);
extern int set_progress_msg(int report, uint64_t total);
extern uint64_t print_final_rpt(void);
extern char *timestamp(int end, int phase, char *buf);
-extern char *duration(int val, char *buf);
+extern char *duration(time_t val, char *buf);
extern int do_parallel;
#define PROG_RPT_INC(a,b) if (ag_stride && prog_rpt_done) (a) += (b)
diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c
index ba9d2833..2ceea87d 100644
--- a/repair/xfs_repair.c
+++ b/repair/xfs_repair.c
@@ -377,7 +377,7 @@ process_args(int argc, char **argv)
do_prefetch = 0;
break;
case 't':
- report_interval = (int)strtol(optarg, NULL, 0);
+ report_interval = strtol(optarg, NULL, 0);
break;
case 'e':
report_corrected = true;
--
2.45.2

View File

@ -1,43 +0,0 @@
From c4dd920b8a8900046e0785e55a43c7190b82c59a Mon Sep 17 00:00:00 2001
From: Andrey Albershteyn <aalbersh@redhat.com>
Date: Tue, 23 Apr 2024 14:36:16 +0200
Subject: [PATCH] xfs_scrub: don't call phase_end if phase_rusage was not
initialized
If unicrash_load() fails, all_pi can be used uninitialized in
phase_end(). Fix it by going to the unload: section if unicrash_load
fails and just go with unicrash_unload() (the is_service won't be
initialized here).
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Bill O'Donnell <bodonnel@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
---
scrub/xfs_scrub.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/scrub/xfs_scrub.c b/scrub/xfs_scrub.c
index 752180d6..50565857 100644
--- a/scrub/xfs_scrub.c
+++ b/scrub/xfs_scrub.c
@@ -631,7 +631,7 @@ main(
fprintf(stderr,
_("%s: couldn't initialize Unicode library.\n"),
progname);
- goto out;
+ goto out_unicrash;
}
pthread_mutex_init(&ctx.lock, NULL);
@@ -828,6 +828,7 @@ out:
phase_end(&all_pi, 0);
if (progress_fp)
fclose(progress_fp);
+out_unicrash:
unicrash_unload();
/*
--
2.45.2

View File

@ -1,80 +0,0 @@
From 5a43a00432ebe9ab8b54155703a9eb9e1a1dd4ec Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <djwong@kernel.org>
Date: Mon, 29 Jul 2024 16:23:31 -0700
Subject: [PATCH] xfs_repair: allow symlinks with short remote targets
Symbolic links can have extended attributes. If the attr fork consumes
enough space in the inode record, a shortform symlink can become a
remote symlink. However, if we delete those extended attributes, the
target is not moved back into the inode core.
IOWs, we can end up with a symlink inode that looks like this:
core.magic = 0x494e
core.mode = 0120777
core.version = 3
core.format = 2 (extents)
core.nlinkv2 = 1
core.nextents = 1
core.size = 297
core.nblocks = 1
core.naextents = 0
core.forkoff = 0
core.aformat = 2 (extents)
u3.bmx[0] = [startoff,startblock,blockcount,extentflag]
0:[0,12,1,0]
This is a symbolic link with a 297-byte target stored in a disk block,
which is to say this is a symlink with a remote target. The forkoff is
0, which is to say that there's 512 - 176 == 336 bytes in the inode core
to store the data fork.
Prior to kernel commit 1eb70f54c445f, the kernel was ok with this
arrangement, but the change to symlink validation in that patch now
produces corruption errors on filesystems written by older kernels that
are not otherwise inconsistent. Those changes were inspired by reports
of illegal memory accesses, which I think were a result of making data
fork access decisions based on symlink di_size and not on di_format.
Unfortunately, for a very long time xfs_repair has flagged these inodes
as being corrupt, even though the kernel has historically been willing
to read and write symlinks with these properties. Resolve the conflict
by adjusting the xfs_repair corruption tests to allow extents format.
This change matches the kernel patch "xfs: allow symlinks with short
remote targets".
While we're at it, fix a lurking bad symlink fork access.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Pavel Reichl <preichl@redhat.com>
---
repair/dinode.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/repair/dinode.c b/repair/dinode.c
index 168cbf48..e36de9bf 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -1036,7 +1036,8 @@ process_symlink_extlist(
int max_blocks;
if (be64_to_cpu(dino->di_size) <= XFS_DFORK_DSIZE(dino, mp)) {
- if (dino->di_format == XFS_DINODE_FMT_LOCAL)
+ if (dino->di_format == XFS_DINODE_FMT_LOCAL ||
+ dino->di_format == XFS_DINODE_FMT_EXTENTS)
return 0;
do_warn(
_("mismatch between format (%d) and size (%" PRId64 ") in symlink ino %" PRIu64 "\n"),
@@ -1368,7 +1369,7 @@ process_symlink(
* get symlink contents into data area
*/
symlink = &data[0];
- if (be64_to_cpu(dino->di_size) <= XFS_DFORK_DSIZE(dino, mp)) {
+ if (dino->di_format == XFS_DINODE_FMT_LOCAL) {
/*
* local symlink, just copy the symlink out of the
* inode into the data area
--
2.46.0

View File

@ -1,52 +0,0 @@
--- a/mkfs/xfs_mkfs.c.orig 2022-08-12 20:38:21.000000000 +0200
+++ b/mkfs/xfs_mkfs.c 2023-01-25 11:06:01.863076713 +0100
@@ -13,6 +13,8 @@
#include "libfrog/dahashselftest.h"
#include "proto.h"
#include <ini.h>
+#include <linux/version.h>
+#include <sys/utsname.h>
#define TERABYTES(count, blog) ((uint64_t)(count) << (40 - (blog)))
#define GIGABYTES(count, blog) ((uint64_t)(count) << (30 - (blog)))
@@ -3998,6 +4000,23 @@
cli->cfgfile);
}
+static unsigned int get_system_kver(void)
+{
+ const char *kver = getenv("KVER");
+ struct utsname utsname;
+ int a, b, c;
+
+ if (!kver) {
+ uname(&utsname);
+ kver = utsname.release;
+ }
+
+ if (sscanf(kver, "%d.%d.%d", &a, &b, &c) != 3)
+ return LINUX_VERSION_CODE;
+
+ return KERNEL_VERSION(a,b,c);
+}
+
int
main(
int argc,
@@ -4077,8 +4096,16 @@
};
struct list_head buffer_list;
+ unsigned int kver;
int error;
+ /* turn bigtime & inobtcnt back off if running under older kernels */
+ kver = get_system_kver();
+ if (kver < KERNEL_VERSION(5,10,0)) {
+ dft.sb_feat.inobtcnt = false;
+ dft.sb_feat.bigtime = false;
+ }
+
platform_uuid_generate(&cli.uuid);
progname = basename(argv[0]);
setlocale(LC_ALL, "");

View File

@ -1,15 +0,0 @@
--- a/man/man8/mkfs.xfs.8.in 2021-12-01 20:48:09.241170607 +0100
+++ b/man/man8/mkfs.xfs.8.in 2021-12-03 15:34:32.382616819 +0100
@@ -1091,6 +1091,12 @@
.HP
.PD
.PP
+.SH Example Of Backward Compatible Configuration Files
+An example of a configuration file that facilitates creation of Red Hat
+Enterprise Linux 8 compatible XFS filesystems while running on Red Hat
+Enterprise Linux 9 can be found at:
+/usr/share/xfsprogs/mkfs/rhel8.0.conf
+.PP
.SH SEE ALSO
.BR xfs (5),
.BR mkfs (8),

View File

@ -0,0 +1,28 @@
From 31980fef484df925b23824244de8ef353e436cef Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Thu, 8 Jun 2023 10:57:52 +0200
Subject: [PATCH] mkfs: fix man's default value for sparse option
Fixes: 9cf846b51 ("mkfs: enable sparse inodes by default")
Suggested-by: Lukas Herbolt <lukas@herbolt.com>
Signed-off-by: Pavel Reichl <preichl@redhat.com>
---
man/man8/mkfs.xfs.8 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/man/man8/mkfs.xfs.8 b/man/man8/mkfs.xfs.8
index 49e64d47a..48e26ece7 100644
--- a/man/man8/mkfs.xfs.8
+++ b/man/man8/mkfs.xfs.8
@@ -631,7 +631,7 @@ 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
+enabled by default. This feature is only available for filesystems
formatted with
.B \-m crc=1.
.IP
--
2.40.1

View File

@ -1,91 +0,0 @@
From 17b691400e8ce0755bb1d7a33490fbc014067e5e Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Fri, 27 Jan 2023 06:30:20 +0100
Subject: [PATCH] mkfs: tolerate tiny filesystems
Signed-off-by: Pavel Reichl <preichl@redhat.com>
---
man/man8/mkfs.xfs.8.in | 4 ++--
mkfs/xfs_mkfs.c | 23 ++++++++++++++---------
2 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/man/man8/mkfs.xfs.8.in b/man/man8/mkfs.xfs.8.in
index 211e7b0c..03f0fda8 100644
--- a/man/man8/mkfs.xfs.8.in
+++ b/man/man8/mkfs.xfs.8.in
@@ -405,7 +405,7 @@ is required if
is given. Otherwise, it is only needed if the filesystem should occupy
less space than the size of the special file.
-The data section must be at least 300MB in size.
+The data section should be at least 300MB in size.
.TP
.BI sunit= value
This is used to specify the stripe unit for a RAID device or a
@@ -705,7 +705,7 @@ described above. The overriding minimum value for size is 512 blocks.
With some combinations of filesystem block size, inode size,
and directory block size, the minimum log size is larger than 512 blocks.
-The log must be at least 64MB in size.
+The log should be at least 64MB in size.
The log cannot be more than 2GB in size.
.TP
.BI version= value
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 9dd0e79c..72c906d6 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -2503,6 +2503,8 @@ validate_supported(
struct xfs_mount *mp,
struct cli_params *cli)
{
+ bool deprecated = false;
+
/* Undocumented option to enable unsupported tiny filesystems. */
if (!cli->is_supported) {
printf(
@@ -2532,9 +2534,8 @@ validate_supported(
* 64MB * (8 / 7) * 4 = 293MB
*/
if (mp->m_sb.sb_dblocks < MEGABYTES(300, mp->m_sb.sb_blocklog)) {
- fprintf(stderr,
- _("Filesystem must be larger than 300MB.\n"));
- usage();
+ printf(_("Filesystem should be larger than 300MB.\n"));
+ deprecated = true;
}
/*
@@ -2543,9 +2544,8 @@ validate_supported(
*/
if (mp->m_sb.sb_logblocks <
XFS_MIN_REALISTIC_LOG_BLOCKS(mp->m_sb.sb_blocklog)) {
- fprintf(stderr,
- _("Log size must be at least 64MB.\n"));
- usage();
+ printf( _("Log size should be at least 64MB.\n"));
+ deprecated = true;
}
/*
@@ -2553,9 +2553,14 @@ validate_supported(
* have redundant superblocks.
*/
if (mp->m_sb.sb_agcount < 2) {
- fprintf(stderr,
- _("Filesystem must have at least 2 superblocks for redundancy!\n"));
- usage();
+ printf(
+ _("Filesystem should have at least 2 superblocks for redundancy!\n"));
+ deprecated = true;
+ }
+
+ if (deprecated) {
+ printf(
+_("Support for filesystems like this one is deprecated and they will not be supported in future releases.\n"));
}
}
--
2.39.1

View File

@ -1,91 +0,0 @@
From ea73527ddb9c9525e696efe0b0dc5f5c8326ec4a Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Wed, 11 Oct 2023 22:27:55 +0200
Subject: [PATCH] xfs_quota: fix missing mount point warning
When user have mounted an XFS volume, and defined project in
/etc/projects file that points to a directory on a different volume,
then:
`xfs_quota -xc "report -a" $path_to_mounted_volume'
complains with:
"xfs_quota: cannot find mount point for path \
`directory_from_projects': Invalid argument"
unlike `xfs_quota -xc "report -a"' which works as expected and no
warning is printed.
This is happening because in the 1st call we pass to xfs_quota command
the $path_to_mounted_volume argument which says to xfs_quota not to
look for all mounted volumes on the system, but use only those passed
to the command and ignore all others (This behavior is intended as an
optimization for systems with huge number of mounted volumes). After
that, while projects are initialized, the project's directories on
other volumes are obviously not in searched subset of volumes and
warning is printed.
I propose to fix this behavior by conditioning the printing of warning
only if all mounted volumes are searched.
Signed-off-by: Pavel Reichl <preichl@redhat.com>
---
libfrog/paths.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/libfrog/paths.c b/libfrog/paths.c
index abb29a237..d8c42163a 100644
--- a/libfrog/paths.c
+++ b/libfrog/paths.c
@@ -457,7 +457,8 @@ fs_table_insert_mount(
static int
fs_table_initialise_projects(
- char *project)
+ char *project,
+ bool all_mps_initialised)
{
fs_project_path_t *path;
fs_path_t *fs;
@@ -473,8 +474,10 @@ fs_table_initialise_projects(
continue;
fs = fs_mount_point_from_path(path->pp_pathname);
if (!fs) {
- fprintf(stderr, _("%s: cannot find mount point for path `%s': %s\n"),
- progname, path->pp_pathname, strerror(errno));
+ if (all_mps_initialised)
+ fprintf(stderr,
+ _("%s: cannot find mount point for path `%s': %s\n"), progname,
+ path->pp_pathname, strerror(errno));
continue;
}
(void) fs_table_insert(path->pp_pathname, path->pp_prid,
@@ -495,11 +498,12 @@ fs_table_initialise_projects(
static void
fs_table_insert_project(
- char *project)
+ char *project,
+ bool all_mps_initialised)
{
int error;
- error = fs_table_initialise_projects(project);
+ error = fs_table_initialise_projects(project, all_mps_initialised);
if (error)
fprintf(stderr, _("%s: cannot setup path for project %s: %s\n"),
progname, project, strerror(error));
@@ -532,9 +536,9 @@ fs_table_initialise(
}
if (project_count) {
for (i = 0; i < project_count; i++)
- fs_table_insert_project(projects[i]);
+ fs_table_insert_project(projects[i], mount_count == 0);
} else {
- error = fs_table_initialise_projects(NULL);
+ error = fs_table_initialise_projects(NULL, mount_count == 0);
if (error)
goto out_error;
}
--
2.41.0

View File

@ -1,25 +0,0 @@
jdm_parentpaths() doesn't initialize count. If count happens to be
non-zero, following loop can result in access overflow.
Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
---
io/parent.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/io/parent.c b/io/parent.c
index 8f63607ffec2..5750d98a3b75 100644
--- a/io/parent.c
+++ b/io/parent.c
@@ -112,7 +112,7 @@ check_parents(parent_t *parentbuf, size_t *parentbuf_size,
jdm_fshandle_t *fshandlep, struct xfs_bstat *statp)
{
int error, i;
- __u32 count;
+ __u32 count = 0;
parent_t *entryp;
do {
--
2.42.0

View File

@ -1,44 +1,90 @@
Summary: Utilities for managing the XFS filesystem Summary: Utilities for managing the XFS filesystem
Name: xfsprogs Name: xfsprogs
Version: 6.4.0 Version: 5.0.0
Release: 4%{?dist} Release: 12%{?dist}
License: GPL+ and LGPLv2+ License: GPL+ and LGPLv2+
Group: System Environment/Base
URL: https://xfs.wiki.kernel.org URL: https://xfs.wiki.kernel.org
Source0: http://kernel.org/pub/linux/utils/fs/xfs/xfsprogs/%{name}-%{version}.tar.xz Source0: http://kernel.org/pub/linux/utils/fs/xfs/xfsprogs/%{name}-%{version}.tar.xz
Source1: http://kernel.org/pub/linux/utils/fs/xfs/xfsprogs/%{name}-%{version}.tar.sign
Source2: https://git.kernel.org/pub/scm/docs/kernel/pgpkeys.git/plain/keys/13F703E6C11CF6F0.asc
Source3: rhel8.0.conf
Requires: util-linux
BuildRequires: make
BuildRequires: gcc BuildRequires: gcc
BuildRequires: libtool, gettext, libattr-devel, libuuid-devel BuildRequires: libtool, gettext, libattr-devel, libuuid-devel
BuildRequires: libedit-devel, libblkid-devel >= 2.17-0.1.git5e51568 BuildRequires: readline-devel, libblkid-devel >= 2.17-0.1.git5e51568
Buildrequires: lvm2-devel, libicu-devel >= 4.6 BuildRequires: lvm2-devel, libicu-devel >= 4.6
BuildRequires: gnupg2, xz, inih-devel
BuildRequires: userspace-rcu-devel
Provides: xfs-cmds Provides: xfs-cmds
Obsoletes: xfs-cmds <= %{version} Obsoletes: xfs-cmds <= %{version}
Provides: xfsprogs-qa-devel Provides: xfsprogs-qa-devel
Obsoletes: xfsprogs-qa-devel <= %{version} Obsoletes: xfsprogs-qa-devel <= %{version}
Conflicts: xfsdump < 3.0.1 Conflicts: xfsdump < 3.0.1
Suggests: xfsprogs-xfs_scrub
Patch0: xfsprogs-rhelonly-disable-old-kernel-bigtime-inobtcnt-on.patch # reflink is not yet default upstream, but we enabled it as such
Patch1: xfsprogs-rhelonly-example-conf.patch Patch0: xfsprogs-4.17.0-reflink-default.patch
Patch2: xfsprogs-rhelonly-mkfs-tolerate-tiny-filesystems.patch Patch1: xfsprogs-5.1.0-mkfs-validate-start-and-end-of-aligned-logs.patch
Patch3: xfsprogs-rhelonly-upstream-v6.6.0-xfs_quota-fix-missing-mount-point-warning.patch Patch2: xfsprogs-5.1.0-mkfs-don-t-use-xfs_verify_fsbno-before-m_sb-is-fully.patch
Patch4: xfsprogs-6.5.0-mkfs.xfs.8-correction-on-mkfs.xfs-manpage-since-refl.patch Patch3: xfsprogs-5.1.0-xfsprogs-Fix-uninitialized-cfg-lsunit.patch
Patch5: xfsprogs-6.5.0-xfs_db.xfs.8-xfs_db-fix-leak-in-flist_find_ftyp.patch Patch4: xfsprogs-5.3.0-xfs_growfs-allow-mounted-device-node-as-argument.patch
Patch6: xfsprogs-6.5.0-xfs_repair.xfs.8-xfs_repair-make-duration-take-time_t.patch Patch5: xfsprogs-5.5.0-libxfs-use-FALLOC_FL_ZERO_RANGE-in-libxfs_device_zer.patch
Patch7: xfsprogs-6.5.0-xfs_repair.xfs.8-xfs_scrub-don-t-call-phase_end-if-phase_rusage-was-n.patch Patch6: xfsprogs-5.4.0-mkfs-Break-block-discard-into-chunks-of-2-GB.patch
Patch8: xfsprogs-6.5.0-xfs_fsr.xfs.8-xfs_fsr-convert-fsrallfs-to-use-time_t-instead-of-in.patch Patch7: xfsprogs-5.4.0-mkfs-tidy-up-discard-notifications.patch
Patch9: xfsprogs-6.5.0-xfs_fsr.xfs.8-xfs_fsr-replace-atoi-with-strtol.patch Patch8: xfsprogs-5.7.0-xfs_quota-refactor-code-to-generate-id-from-name.patch
Patch10: xfsprogs-6.5.0-xfs_db.xfs.8-xfs_db-add-helper-for-flist_find_type-for-clearer-fi.patch Patch9: xfsprogs-5.7.0-xfs_quota-allow-individual-timer-extension.patch
Patch11: xfsprogs-6.5.0-xfs_repair.xfs.8-xfs_repair-catch-strtol-errors.patch Patch10: xfsprogs-5.7.0-xfs_quota-fix-unsigned-int-id-comparisons.patch
Patch12: xfsprogs-rhelonly-xfs_db-fix-unitialized-variable-in-check_parents-function.patch Patch11: xfsprogs-5.7.0-xfs_repair-check-for-AG-btree-records-that-would-wra.patch
Patch13: xfsprogs-6.5.0-xfs.8-xfs-fix-bounds-check-in-xfs_defer_agfl_block.patch Patch12: xfsprogs-5.7.0-xfs_repair-tag-inobt-vs-finobt-errors-properly.patch
# v6.9.0-270-g5a43a004: This patch is taken from the `for-next` branch. Patch13: xfsprogs-5.7.0-xfs_repair-complain-about-bad-interior-btree-pointer.patch
Patch14: xfsprogs-for-next-xfs_repair-allow-symlinks-with-short-remote-targets.patch Patch14: xfsprogs-5.7.0-xfs_repair-convert-to-libxfs_verify_agbno.patch
Patch15: xfsprogs-5.9.0-mkfs.xfs-fix-ASSERT-on-too-small-device-with-stripe.patch
Patch16: xfsprogs-5.7.0-xfs_repair-fix-rebuilding-btree-block-less-than-minr.patch
Patch17: xfsprogs-5.10.0-xfs_quota-document-how-the-default-quota-is-stored.patch
Patch18: xfsprogs-5.8.0-xfs_db-short-circuit-type_f-if-type-is-unchanged.patch
Patch19: xfsprogs-5.10.0-xfs_repair-Use-proper-min-max-values-in-compute_level_geometry.patch
Patch20: xfsprogs-5.8.0-xfs_quota-command-error-message-improvement.patch
Patch21: xfsprogs-5.8.0-xfs_quota-display-warning-limits-when-printing-quota.patch
Patch22: xfsprogs-5.8.0-xfs_quota-state-command-should-report-ugp-grace-time.patch
Patch23: xfsprogs-5.1.0-libxfs-create-current_time-helper-and-sync-xfs_trans.patch
Patch24: xfsprogs-5.5.0-xfs-use-a-struct-timespec64-for-the-in-core-crtime.patch
Patch25: xfsprogs-5.9.0-xfs-drop-the-type-parameter-from-xfs_dquot_verify.patch
Patch26: xfsprogs-5.9.0-xfs-improve-ondisk-dquot-flags-checking.patch
Patch27: xfsprogs-5.10.0-libxfs-create-a-real-struct-timespec64.patch
Patch28: xfsprogs-5.10.0-libxfs-refactor-NSEC_PER_SEC.patch
Patch29: xfsprogs-5.10.0-xfs-store-inode-btree-block-counts-in-AGI-header.patch
Patch30: xfsprogs-5.10.0-xfs-use-the-finobt-block-counts-to-speed-up-mount-ti.patch
Patch31: xfsprogs-5.10.0-xfs-explicitly-define-inode-timestamp-range.patch
Patch32: xfsprogs-5.10.0-xfs-refactor-quota-expiration-timer-modification.patch
Patch33: xfsprogs-5.10.0-xfs-refactor-default-quota-grace-period-setting-code.patch
Patch34: xfsprogs-5.10.0-xfs-refactor-quota-timestamp-coding.patch
Patch35: xfsprogs-5.10.0-xfs-move-xfs_log_dinode_to_disk-to-the-log-recovery-.patch
Patch36: xfsprogs-5.10.0-xfs-redefine-xfs_timestamp_t.patch
Patch37: xfsprogs-5.10.0-xfs-redefine-xfs_ictimestamp_t.patch
Patch38: xfsprogs-5.10.0-xfs-widen-ondisk-inode-timestamps-to-deal-with-y2038.patch
Patch39: xfsprogs-5.10.0-xfs-widen-ondisk-quota-expiration-timestamps-to-hand.patch
Patch40: xfsprogs-5.10.0-xfs_db-support-displaying-inode-btree-block-counts-i.patch
Patch41: xfsprogs-5.10.0-xfs_repair-check-inode-btree-block-counters-in-AGI.patch
Patch42: xfsprogs-5.10.0-xfs_repair-regenerate-inode-btree-block-counters-in-.patch
Patch43: xfsprogs-5.10.0-xfs-enable-new-inode-btree-counters-feature.patch
Patch44: xfsprogs-5.10.0-mkfs-enable-the-inode-btree-counter-feature.patch
Patch45: xfsprogs-5.10.0-libfrog-convert-cvttime-to-return-time64_t.patch
Patch46: xfsprogs-5.10.0-xfs_quota-convert-time_to_string-to-use-time64_t.patch
Patch47: xfsprogs-5.10.0-xfs_db-refactor-timestamp-printing.patch
Patch48: xfsprogs-5.10.0-xfs_db-refactor-quota-timer-printing.patch
Patch49: xfsprogs-5.10.0-libfrog-list-the-bigtime-feature-when-reporting-geom.patch
Patch50: xfsprogs-5.10.0-xfs_db-report-bigtime-format-timestamps.patch
Patch51: xfsprogs-5.10.0-xfs_db-support-printing-time-limits.patch
Patch52: xfsprogs-5.10.0-xfs_quota-support-editing-and-reporting-quotas-with-.patch
Patch53: xfsprogs-5.10.0-xfs_repair-support-bigtime-timestamp-checking.patch
Patch54: xfsprogs-5.10.0-xfs-enable-big-timestamps.patch
Patch55: xfsprogs-5.10.0-mkfs-format-bigtime-filesystems.patch
Patch56: xfsprogs-5.12.0-libxfs-copy-crtime-correctly-now-that-it-s-timespec6.patch
Patch57: xfsprogs-5.13.0-xfs-remove-the-unused-xfs_icdinode_has_bigtime-helpe.patch
Patch58: xfsprogs-5.13.0-xfs-rename-xfs_ictimestamp_t.patch
Patch59: xfsprogs-5.13.0-xfs-rename-struct-xfs_legacy_ictimestamp.patch
Patch60: xfsprogs-5.11.0-mkfs-fix-wrong-inobtcount-usage-error-output.patch
Patch61: xfsprogs-5.12.0-libxfs-expose-inobtcount-in-xfs-geometry.patch
Patch62: xfsprogs-5.12.0-libfrog-report-inobtcount-in-geometry.patch
Patch63: xfsprogs-5.19.0-xfs_repair-ignore-empty-xattr-leaf-blocks.patch
Patch64: xfsprogs-5.19.0-mkfs-terminate-getsubopt-arrays-properly.patch
Patch65: xfsprogs-5.9.0-xfs-ignore-autofs-mount-table-entries.patch
Patch66: xfsprogs-5.10.0-xfs_repair-fix-progress-reporting.patch
Patch67: xfsprogs-rhelonly-mkfs-fix-man-s-default-value-for-sparse-option.patch
%description %description
A set of commands to use the XFS filesystem, including mkfs.xfs. A set of commands to use the XFS filesystem, including mkfs.xfs.
@ -55,6 +101,7 @@ of XFS.
%package devel %package devel
Summary: XFS filesystem-specific headers Summary: XFS filesystem-specific headers
Group: Development/Libraries
Requires: xfsprogs = %{version}-%{release}, libuuid-devel Requires: xfsprogs = %{version}-%{release}, libuuid-devel
%description devel %description devel
@ -65,28 +112,90 @@ You should install xfsprogs-devel if you want to develop XFS
filesystem-specific programs, If you install xfsprogs-devel, you'll filesystem-specific programs, If you install xfsprogs-devel, you'll
also want to install xfsprogs. also want to install xfsprogs.
%package xfs_scrub
Summary: XFS filesystem online scrubbing utilities
Requires: xfsprogs = %{version}-%{release}, python3
%description xfs_scrub
xfs_scrub attempts to check and repair all metadata in a mounted XFS filesystem.
WARNING! This program is EXPERIMENTAL, which means that its behavior and
interface could change at any time!
%prep %prep
xzcat '%{SOURCE0}' | %{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data=- %setup -q
%autosetup -p1
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1
%patch26 -p1
%patch27 -p1
%patch28 -p1
%patch29 -p1
%patch30 -p1
%patch31 -p1
%patch32 -p1
%patch33 -p1
%patch34 -p1
%patch35 -p1
%patch36 -p1
%patch37 -p1
%patch38 -p1
%patch39 -p1
%patch40 -p1
%patch41 -p1
%patch42 -p1
%patch43 -p1
%patch44 -p1
%patch45 -p1
%patch46 -p1
%patch47 -p1
%patch48 -p1
%patch49 -p1
%patch50 -p1
%patch51 -p1
%patch52 -p1
%patch53 -p1
%patch54 -p1
%patch55 -p1
%patch56 -p1
%patch57 -p1
%patch58 -p1
%patch59 -p1
%patch60 -p1
%patch61 -p1
%patch62 -p1
%patch63 -p1
%patch64 -p1
%patch65 -p1
%patch66 -p1
%patch67 -p1
%build %build
export tagname=CC export tagname=CC
%configure \ %configure \
--enable-editline=yes \ --enable-readline=yes \
--enable-blkid=yes \ --enable-blkid=yes \
--enable-lto=no --enable-lto=no \
--enable-scrub=no
%make_build # NOTE scrub manpages manually removed below as well
make V=1 %{?_smp_mflags}
%install %install
make DIST_ROOT=$RPM_BUILD_ROOT install install-dev \ make DIST_ROOT=$RPM_BUILD_ROOT install install-dev \
@ -98,37 +207,21 @@ rm -f $RPM_BUILD_ROOT/{%{_lib}/*.{la,a,so},%{_libdir}/*.{la,a}}
# remove non-versioned docs location # remove non-versioned docs location
rm -rf $RPM_BUILD_ROOT/%{_datadir}/doc/xfsprogs/ rm -rf $RPM_BUILD_ROOT/%{_datadir}/doc/xfsprogs/
# add backward compatible configure file for mkfs # Remove scrub manpages
%global mkfsdir %{_datadir}/xfsprogs/mkfs rm -rf $RPM_BUILD_ROOT/%{_mandir}/man8/xfs_scrub*
install -m 0755 -d %{buildroot}%{mkfsdir}
install -m 0644 %{SOURCE3} %{buildroot}%{mkfsdir}
%find_lang %{name} %find_lang %{name}
%ldconfig_scriptlets %post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%files -f %{name}.lang %files -f %{name}.lang
%doc doc/CHANGES README %doc doc/CHANGES README
%{_libdir}/*.so.* %{_libdir}/*.so.*
%dir %{_usr}/%{_lib}/xfsprogs
%{_usr}/%{_lib}/xfsprogs/*
%{_mandir}/man5/* %{_mandir}/man5/*
%{_mandir}/man8/* %{_mandir}/man8/*
%{_sbindir}/* %{_sbindir}/*
%{_unitdir}/*
%{mkfsdir}
%exclude %{_sbindir}/xfs_scrub*
%exclude %{_mandir}/man8/xfs_scrub*
%exclude %{_usr}/%{_lib}/xfsprogs/xfs_scrub*
%exclude %{_mandir}/man8/xfs_scrub_all*
%exclude %{_unitdir}/xfs_scrub*
%files xfs_scrub
%{_sbindir}/xfs_scrub*
%{_mandir}/man8/xfs_scrub*
%{_usr}/%{_lib}/xfsprogs/xfs_scrub*
%{_mandir}/man8/xfs_scrub_all*
%{_unitdir}/xfs_scrub*
%files devel %files devel
%{_mandir}/man2/* %{_mandir}/man2/*
@ -140,7 +233,6 @@ install -m 0644 %{SOURCE3} %{buildroot}%{mkfsdir}
%{_includedir}/xfs/xfs.h %{_includedir}/xfs/xfs.h
%{_includedir}/xfs/xfs_arch.h %{_includedir}/xfs/xfs_arch.h
%{_includedir}/xfs/xfs_fs.h %{_includedir}/xfs/xfs_fs.h
%{_includedir}/xfs/xfs_fs_compat.h
%{_includedir}/xfs/xfs_types.h %{_includedir}/xfs/xfs_types.h
%{_includedir}/xfs/xfs_format.h %{_includedir}/xfs/xfs_format.h
%{_includedir}/xfs/xfs_da_format.h %{_includedir}/xfs/xfs_da_format.h
@ -150,229 +242,85 @@ install -m 0644 %{SOURCE3} %{buildroot}%{mkfsdir}
%{_libdir}/*.so %{_libdir}/*.so
%changelog %changelog
* Thu Aug 15 2024 Pavel Reichl <preichl@redhat.com> - 6.4.0-4 * Thu Jun 08 2023 Pavel Reichl <preichl@redhat.com> - 5.0.0-12
- xfs_repair: allow symlinks with short remote targets - Fix xfs_repair progress reporting is not working (#2183398)
- Related: RHEL-54306 and RHEL-53164 - Fix man page default for sparse mkfs option (#2118564)
* Thu Jul 11 2024 Bill O'Donnell <bodonnel@redhat.com> - 6.4.0-3 * Tue May 02 2023 Pavel Reichl <preichl@redhat.com> - 5.0.0-11
- Fix coverity issue - Fix xfstest fails with error "missing xfsprogs fix patch"(#2161936,#2160746)
- Related: RHEL-39449 - Fix ignore autofs mount table entries (#2182361)
- Following is the patch list:
- xfsprogs-6.5.0-xfs.8-xfs-fix-bounds-check-in-xfs_defer_agfl_block.patch
* Wed Jun 26 2024 Bill O'Donnell <bodonnel@redhat.com> - 6.4.0-2 * Thu Dec 09 2021 Bill O'Donnell <bodonnel@redhat.com> 5.0.0-10
- Fix various CVE issues. - xfsprogs: enable bigtime and inode btree counter features in RHEL8 (#2024201))
- Related: RHEL-32996
- Following is the patch list:
- xfsprogs-6.5.0-xfs_db.xfs.8-xfs_db-fix-leak-in-flist_find_ftyp.patch
- xfsprogs-6.5.0-xfs_repair.xfs.8-xfs_repair-make-duration-take-time_t.patch
- xfsprogs-6.5.0-xfs_repair.xfs.8-xfs_scrub-don-t-call-phase_end-if-phase_rusage-was-n.patch
- xfsprogs-6.5.0-xfs_fsr.xfs.8-xfs_fsr-convert-fsrallfs-to-use-time_t-instead-of-in.patch
- xfsprogs-6.5.0-xfs_fsr.xfs.8-xfs_fsr-replace-atoi-with-strtol.patch
- xfsprogs-6.5.0-xfs_db.xfs.8-xfs_db-add-helper-for-flist_find_type-for-clearer-fi.patch
- xfsprogs-6.5.0-xfs_repair.xfs.8-xfs_repair-catch-strtol-errors.patch
- xfsprogs-rhelonly-xfs_db-fix-unitialized-variable-in-check_parents-function.patch
* Mon May 20 2024 Pavel Reichl <preichl@redhat.com> - 6.4.0-1 * Thu Jul 08 2021 Bill O'Donnell <bodonnel@redhat.com> 5.0.0-9
- Rebase to a more recent upstream release - xfs_quota: state command should report ugp grace time (#1949743)
- Related: RHEL-28339
- Following is a list of dropped backported patches which
- are contained in the current rebase:
- xfsprogs-6.4.0-set-bnobt-cntbt-numrecs-correctly-when-formattin.patch
- xfsprogs-6.4.0-mkfs-fix-man-s-default-value-for-sparse-option.patch
- xfsprogs-6.4.0-xfs_repair-don-t-add-junked-entries-to-the-rebuilt-d.patch
- xfsprogs-6.4.0-xfs_repair-fix-messaging-when-fixing-imap-due-to-spa.patch
- xfsprogs-6.4.0-xfs_repair-don-t-spray-correcting-imap-all-by-itself.patch
- xfsprogs-6.4.0-xfs_repair-fix-messaging-when-shortform_dir2_junk-is.patch
- xfsprogs-6.4.0-xfs_db-move-obfuscate_name-assertion-to-callers.patch
- xfsprogs-6.4.0-xfs_db-fix-metadump-name-obfuscation-for-ascii-ci-fi.patch
- xfsprogs-6.4.0-xfs-stabilize-the-dirent-name-transformation-functio.patch
-
- Rename xfs_quota-fix-missing-mount-point-warning.patch to reflect upstream
- version it was merged in.
* Mon Nov 13 2023 Pavel Reichl <preichl@redhat.com> - 6.3.0-1 * Thu Jan 07 2021 Bill O'Donnell <billodo@redhat.com> 5.0.0-8
- Rebase to upstream version 6.3.0 - xfs_repair: Use proper min/max values in compute_level_geometry (#1910384)
-
- Following is a list of dropped backported patches which
- are contained in the current rebase:
- xfsprogs-5.19.0-xfs-hoist-refcount-record-merge-predicates.patch (v6.2.0)
- xfsprogs-5.19.0-xfs_db-fix-dir3-block-magic-check.patch (v6.1.0)
- xfsprogs-5.19.0-xfs-estimate-post-merge-refcounts-correctly.patch (v6.2.0)
- xfsprogs-5.19.0-xfs-get-rid-of-assert-from-xfs_btree_islastblock.patch (v6.2.0)
- xfsprogs-5.19.0-xfs-fix-off-by-one-error-in-xfs_btree_space_to_heigh.patch (v6.2.0)
- xfsprogs-5.19.0-xfs-fix-sb-write-verify-for-lazysbcount.patch (v6.1.0)
- xfsprogs-5.19.0-xfs-removed-useless-condition-in-function-xfs_attr_n.patch (v6.0.0)
- xfsprogs-5.19.0-xfs_repair-retain-superblock-buffer-to-avoid-write-h.patch (v6.1.0)
-
- Rename the remaining patches so the name contains upstream version in which
- they are implemented, or "rhelonly".
-
- Drop Eric Sandeen's public key used to check tarball signature and replace it by
- Carlos Maiolino's (current upstream xfsprogs maintainer).
-
- Following is a list of newly backported patches from versions released after 6.3
- which are fixing patches present in version 6.3:
- xfsprogs-6.4.0-xfs_repair-don-t-add-junked-entries-to-the-rebuilt-d.patch
- xfsprogs-6.4.0-xfs_repair-don-t-spray-correcting-imap-all-by-itself.patch
- xfsprogs-6.4.0-xfs_repair-fix-messaging-when-fixing-imap-due-to-spa.patch
- xfsprogs-6.4.0-xfs_repair-fix-messaging-when-shortform_dir2_junk-is.patch
-
- Backport:
- xfsprogs-6.4.0-xfs_db-move-obfuscate_name-assertion-to-callers.patch
- xfsprogs-6.4.0-xfs_db-fix-metadump-name-obfuscation-for-ascii-ci-fi.patch
- xfsprogs-6.4.0-xfs-stabilize-the-dirent-name-transformation-functio.patch
- to implement RHEL-RHEL-8284
-
- Backport xfsprogs-rhelonly-xfs_quota-fix-missing-mount-point-warning.patch
- to implement RHEL-7900
-
- Related: RHEL-15399
- Related: RHEL-8284
- Related: RHEL-7900
* Wed Aug 02 2023 Pavel Reichl <preichl@redhat.com> - 5.19.0-4 * Mon Dec 14 2020 Bill O'Donnell <billodo@redhat.com> 5.0.0-7
- Fix man page, mkfs.xfs(8): Update section on dax+reflink - xfs_quota: document how the default quota is stored (#1850188)
- compatibility (#2226900) - xfs_db: skip type change if type_f unchanged (#1867474)
* Tue Jun 20 2023 Pavel Reichl <preichl@redhat.com> - 5.19.0-3 * Wed Dec 09 2020 Bill O'Donnell <billodo@redhat.com> 5.0.0-6
- Fix man page default for sparse mkfs option (#2216118) - xfs_repair: improve AG btree ptr validation (libxfs_verify_agbno) (#1887288)
- mkfs.xfs: fix ASSERT on too-small device with stripe geometry (#1887401)
- xfs_repair: fix rebuilding btree block less than minrecs (#1759452)
* Fri May 26 2023 Pavel Reichl <preichl@redhat.com> - 5.19.0-2 * Wed Dec 02 2020 Bill O'Donnell <billodo@redhat.com> 5.0.0-5
- Fix xfs corrupted when AG size is a multiple of stripe width - xfs_quota: allow individual timer extension (#1899204)
- Related: rhbz#2192982
* Tue Jan 10 2023 Pavel Reichl <preichl@redhat.com> - 5.19.0-1 * Wed Jun 03 2020 Eric Sandeen <sandeen@redhat.com> 5.0.0-4
- New upstream release - mkfs.xfs: inform user about discard, and make interruptable (#1836414)
- Tolerate tiny (<300MB) filesystems
- Rename xfsprogs-5.12.0-default-bigtime-inobtcnt-on.patch to
xfsprogs-5.19.0-disable-old-kernel-bigtime-inobtcnt-on.patch
and amend it to reflect upstream changes
- Backport all "Fixing" patches relevant to 5.19
Related: rhbz#2142910
* Fri Jan 21 2022 Pavel Reichl <preichl@redhat.com> - 5.14.2-1 * Mon Apr 20 2020 Eric Sandeen <sandeen@redhat.com> 5.0.0-3
- New upstream release - mkfs.xfs: use faster log zeroing on supported devices (#1755046)
Related: rhbz#2041525
* Wed Dec 01 2021 Pavel Reichl <preichl@redhat.com> - 5.12.0-5 * Sat Dec 14 2019 Eric Sandeen <sandeen@redhat.com> 5.0.0-2
- Add an example of backward compatible conf. file for mkfs - mkfs.xfs: validate log stripe unit alignment (#1632596)
Related: rhbz#2026002 - xfs_growfs: allow mounted device node as argument (#1765217)
* Tue Aug 10 2021 Mohan Boddu <mboddu@redhat.com> - 5.12.0-4 * Tue May 21 2019 Eric Sandeen <sandeen@redhat.com> 5.0.0-1
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags - New upstream version (#1712147)
Related: rhbz#1991688 - mkfs.xfs: validate extent size hint parameters (#1683007)
- mkfs.xfs: null-terminate symlinks created via protofile (#1640503)
- xfs_repair: allow '/' in attribute names (#1667354)
- xfs_info: allow device name as parameter (#1679840)
- xfs_quota: fix project inheritance flag handling (#1664105)
- xfs_metadump: handle symlinks correctly (#1693074)
- xfs_db: fix finobt record decoding with sparse inodes (#1690245)
* Wed Jun 16 2021 Eric Sandeen <sandeen@redhat.com> 5.12.0-3 * Mon Feb 04 2019 Eric Sandeen <sandeen@redhat.com> 4.19.0-2
- Local change to default bigtime & inobtcnt to off under older kernels - xfs_repair: initialize non-leaf finobt blocks with correct magic (#1670153)
* Thu Jun 03 2021 Eric Sandeen <sandeen@redhat.com> 5.12.0-2 * Tue Nov 27 2018 Eric Sandeen <sandeen@redhat.com> 4.19.0-1
- Turn on bigtime (y2038) and inobtcnt features by default - New upstream release (#1652248)
- Note reflink default in mkfs.xfs manpage (#1641698)
- Fix xfs_db sign extension in agi freecount (#1640090)
- Fix xfs_repair hang on large filesystem (#1630674)
* Thu Jun 03 2021 Eric Sandeen <sandeen@redhat.com> 5.12.0-1 * Tue Sep 25 2018 Eric Sandeen <sandeen@redhat.com> 4.18.0-3
- New upstream release - Remove experimental xfs_scrub utility (#1623301)
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 5.10.0-3 * Wed Sep 19 2018 Eric Sandeen <sandeen@redhat.com> 4.18.0-2
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 - Fix annobin checks (#1630641)
* Thu Jan 28 2021 Fedora Release Engineering <releng@fedoraproject.org> - 5.10.0-2 * Tue Aug 28 2018 Eric Sandeen <sandeen@redhat.com> 4.18.0-1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild - New upstream release (#1623695)
* Fri Dec 11 2020 Eric Sandeen <sandeen@redhat.com> 5.10.0-1 * Mon Aug 13 2018 Eric Sandeen <sandeen@redhat.com> 4.17.0-4
- New upstream release - Disable reflink automatically if crcs are disabled (#1600610)
- New mkfs config file feature
- Y2038+ format support
* Tue Oct 20 2020 Eric Sandeen <sandeen@redhat.com> 5.9.0-1 * Wed Aug 01 2018 Charalampos Stratakis <cstratak@redhat.com> - 4.17.0-3
- New upstream release - Rebuild for platform-python
* Fri Sep 04 2020 Eric Sandeen <sandeen@redhat.com> 5.8.0-1 * Thu Jun 28 2018 Eric Sandeen <sandeen@redhat.com> 4.17.0-2
- New upstream release - Default mkfs to reflink enabled (#1494028)
* Fri Jul 24 2020 Eric Sandeen <sandeen@redhat.com> 5.7.0-1
- New upstream release
- Replace libreadline with libedit
- Add tarball signature checking
* Tue Jul 14 2020 Tom Stellard <tstellar@redhat.com> - 5.6.0-3
- Use make macros
- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro
* Sat May 16 2020 Pete Walter <pwalter@fedoraproject.org> - 5.6.0-2
- Rebuild for ICU 67
* Tue Apr 14 2020 Eric Sandeen <sandeen@redhat.com> 5.6.0-1
- New upstream release
* Fri Mar 13 2020 Eric Sandeen <sandeen@redhat.com> 5.5.0-1
- New upstream release
* Fri Jan 31 2020 Eric Sandeen <sandeen@redhat.com> 5.4.0-3
- Fix global redefinitions for gcc10 build
* Fri Jan 31 2020 Fedora Release Engineering <releng@fedoraproject.org> - 5.4.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Fri Jan 17 2020 Eric Sandeen <sandeen@redhat.com> 5.4.0-1
- New upstream release
* Fri Nov 15 2019 Eric Sandeen <sandeen@redhat.com> 5.3.0-1
- New upstream release
* Fri Nov 01 2019 Pete Walter <pwalter@fedoraproject.org> - 5.2.1-2
- Rebuild for ICU 65
* Wed Aug 21 2019 Eric Sandeen <sandeen@redhat.com> 5.2.1-1
- New upstream release
* Fri Aug 16 2019 Eric Sandeen <sandeen@redhat.com> 5.2.0-1
- New upstream release
* Sat Jul 27 2019 Fedora Release Engineering <releng@fedoraproject.org> - 5.1.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Fri Jul 19 2019 Eric Sandeen <sandeen@redhat.com> 5.1.0-1
- New upstream release
* Wed May 08 2019 Eric Sandeen <sandeen@redhat.com> 5.0.0-2
- Create new xfs_scrub subpackage (#1666839)
* Fri May 03 2019 Eric Sandeen <sandeen@redhat.com> 5.0.0-1
- New upstream release
* Fri Feb 22 2019 Eric Sandeen <sandeen@redhat.com> 4.20.0-1
- New upstream release
* Sun Feb 17 2019 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 4.19.0-4
- Rebuild for readline 8.0
* Sun Feb 03 2019 Fedora Release Engineering <releng@fedoraproject.org> - 4.19.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Wed Jan 23 2019 Pete Walter <pwalter@fedoraproject.org> - 4.19.0-2
- Rebuild for ICU 63
* Tue Nov 13 2018 Eric Sandeen <sandeen@redhat.com> 4.19.0-1
- New upstream release
* Fri Aug 24 2018 Eric Sandeen <sandeen@redhat.com> 4.18.0-1
- New upstream release
* Sat Jul 14 2018 Fedora Release Engineering <releng@fedoraproject.org> - 4.17.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Tue Jul 10 2018 Pete Walter <pwalter@fedoraproject.org> - 4.17.0-2
- Rebuild for ICU 62
* Thu Jun 28 2018 Eric Sandeen <sandeen@redhat.com> 4.17.0-1 * Thu Jun 28 2018 Eric Sandeen <sandeen@redhat.com> 4.17.0-1
- New upstream release - New upstream release
- Clean up spec file
* Mon Apr 30 2018 Pete Walter <pwalter@fedoraproject.org> - 4.16.0-2
- Rebuild for ICU 61.1
* Thu Apr 26 2018 Eric Sandeen <sandeen@redhat.com> 4.16.0-1
- New upstream release
- Clean up specfile
* Mon Feb 26 2018 Eric Sandeen <sandeen@redhat.com> 4.15.1-1 * Mon Feb 26 2018 Eric Sandeen <sandeen@redhat.com> 4.15.1-1
- New upstream release - New upstream release