3
0

e2fsck.c 355 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * e2fsck
  4. *
  5. * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
  6. * Copyright (C) 2006 Garrett Kajmowicz
  7. *
  8. * Dictionary Abstract Data Type
  9. * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
  10. * Free Software License:
  11. * All rights are reserved by the author, with the following exceptions:
  12. * Permission is granted to freely reproduce and distribute this software,
  13. * possibly in exchange for a fee, provided that this copyright notice appears
  14. * intact. Permission is also granted to adapt this software to produce
  15. * derivative works, as long as the modified versions carry this copyright
  16. * notice and additional notices stating that the work has been modified.
  17. * This source code may be translated into executable form and incorporated
  18. * into proprietary software; there is no requirement for such software to
  19. * contain a copyright notice related to this source.
  20. *
  21. * linux/fs/recovery and linux/fs/revoke
  22. * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
  23. *
  24. * Copyright 1999-2000 Red Hat Software --- All Rights Reserved
  25. *
  26. * Journal recovery routines for the generic filesystem journaling code;
  27. * part of the ext2fs journaling system.
  28. *
  29. * Licensed under GPLv2 or later, see file License in this tarball for details.
  30. */
  31. #ifndef _GNU_SOURCE
  32. #define _GNU_SOURCE 1 /* get strnlen() */
  33. #endif
  34. #include "e2fsck.h" /*Put all of our defines here to clean things up*/
  35. #define _(x) x
  36. #define N_(x) x
  37. /*
  38. * Procedure declarations
  39. */
  40. static void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf);
  41. /* pass1.c */
  42. static void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool);
  43. /* pass2.c */
  44. static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
  45. ext2_ino_t ino, char *buf);
  46. /* pass3.c */
  47. static int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t inode);
  48. static errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
  49. int num, int gauranteed_size);
  50. static ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix);
  51. static errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino,
  52. int adj);
  53. /* rehash.c */
  54. static void e2fsck_rehash_directories(e2fsck_t ctx);
  55. /* util.c */
  56. static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
  57. const char *description);
  58. static int ask(e2fsck_t ctx, const char * string, int def);
  59. static void e2fsck_read_bitmaps(e2fsck_t ctx);
  60. static void preenhalt(e2fsck_t ctx);
  61. static void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
  62. struct ext2_inode * inode, const char * proc);
  63. static void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
  64. struct ext2_inode * inode, const char * proc);
  65. static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
  66. const char *name, io_manager manager);
  67. /* unix.c */
  68. static void e2fsck_clear_progbar(e2fsck_t ctx);
  69. static int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
  70. float percent, unsigned int dpynum);
  71. /*
  72. * problem.h --- e2fsck problem error codes
  73. */
  74. typedef __u32 problem_t;
  75. struct problem_context {
  76. errcode_t errcode;
  77. ext2_ino_t ino, ino2, dir;
  78. struct ext2_inode *inode;
  79. struct ext2_dir_entry *dirent;
  80. blk_t blk, blk2;
  81. e2_blkcnt_t blkcount;
  82. int group;
  83. __u64 num;
  84. const char *str;
  85. };
  86. /*
  87. * Function declarations
  88. */
  89. static int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx);
  90. static int end_problem_latch(e2fsck_t ctx, int mask);
  91. static int set_latch_flags(int mask, int setflags, int clearflags);
  92. static void clear_problem_context(struct problem_context *ctx);
  93. /*
  94. * Dictionary Abstract Data Type
  95. * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
  96. *
  97. * dict.h v 1.22.2.6 2000/11/13 01:36:44 kaz
  98. * kazlib_1_20
  99. */
  100. #ifndef DICT_H
  101. #define DICT_H
  102. /*
  103. * Blurb for inclusion into C++ translation units
  104. */
  105. typedef unsigned long dictcount_t;
  106. #define DICTCOUNT_T_MAX ULONG_MAX
  107. /*
  108. * The dictionary is implemented as a red-black tree
  109. */
  110. typedef enum { dnode_red, dnode_black } dnode_color_t;
  111. typedef struct dnode_t {
  112. struct dnode_t *dict_left;
  113. struct dnode_t *dict_right;
  114. struct dnode_t *dict_parent;
  115. dnode_color_t dict_color;
  116. const void *dict_key;
  117. void *dict_data;
  118. } dnode_t;
  119. typedef int (*dict_comp_t)(const void *, const void *);
  120. typedef void (*dnode_free_t)(dnode_t *);
  121. typedef struct dict_t {
  122. dnode_t dict_nilnode;
  123. dictcount_t dict_nodecount;
  124. dictcount_t dict_maxcount;
  125. dict_comp_t dict_compare;
  126. dnode_free_t dict_freenode;
  127. int dict_dupes;
  128. } dict_t;
  129. typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
  130. typedef struct dict_load_t {
  131. dict_t *dict_dictptr;
  132. dnode_t dict_nilnode;
  133. } dict_load_t;
  134. #define dict_count(D) ((D)->dict_nodecount)
  135. #define dnode_get(N) ((N)->dict_data)
  136. #define dnode_getkey(N) ((N)->dict_key)
  137. #endif
  138. /*
  139. * Compatibility header file for e2fsck which should be included
  140. * instead of linux/jfs.h
  141. *
  142. * Copyright (C) 2000 Stephen C. Tweedie
  143. */
  144. /*
  145. * Pull in the definition of the e2fsck context structure
  146. */
  147. struct buffer_head {
  148. char b_data[8192];
  149. e2fsck_t b_ctx;
  150. io_channel b_io;
  151. int b_size;
  152. blk_t b_blocknr;
  153. int b_dirty;
  154. int b_uptodate;
  155. int b_err;
  156. };
  157. #define K_DEV_FS 1
  158. #define K_DEV_JOURNAL 2
  159. #define lock_buffer(bh) do {} while(0)
  160. #define unlock_buffer(bh) do {} while(0)
  161. #define buffer_req(bh) 1
  162. #define do_readahead(journal, start) do {} while(0)
  163. static e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
  164. typedef struct {
  165. int object_length;
  166. } kmem_cache_t;
  167. #define kmem_cache_alloc(cache,flags) malloc((cache)->object_length)
  168. /*
  169. * We use the standard libext2fs portability tricks for inline
  170. * functions.
  171. */
  172. static kmem_cache_t * do_cache_create(int len)
  173. {
  174. kmem_cache_t *new_cache;
  175. new_cache = malloc(sizeof(*new_cache));
  176. if (new_cache)
  177. new_cache->object_length = len;
  178. return new_cache;
  179. }
  180. static void do_cache_destroy(kmem_cache_t *cache)
  181. {
  182. free(cache);
  183. }
  184. /*
  185. * Dictionary Abstract Data Type
  186. */
  187. /*
  188. * These macros provide short convenient names for structure members,
  189. * which are embellished with dict_ prefixes so that they are
  190. * properly confined to the documented namespace. It's legal for a
  191. * program which uses dict to define, for instance, a macro called ``parent''.
  192. * Such a macro would interfere with the dnode_t struct definition.
  193. * In general, highly portable and reusable C modules which expose their
  194. * structures need to confine structure member names to well-defined spaces.
  195. * The resulting identifiers aren't necessarily convenient to use, nor
  196. * readable, in the implementation, however!
  197. */
  198. #define left dict_left
  199. #define right dict_right
  200. #define parent dict_parent
  201. #define color dict_color
  202. #define key dict_key
  203. #define data dict_data
  204. #define nilnode dict_nilnode
  205. #define maxcount dict_maxcount
  206. #define compare dict_compare
  207. #define dupes dict_dupes
  208. #define dict_root(D) ((D)->nilnode.left)
  209. #define dict_nil(D) (&(D)->nilnode)
  210. static void dnode_free(dnode_t *node);
  211. /*
  212. * Perform a ``left rotation'' adjustment on the tree. The given node P and
  213. * its right child C are rearranged so that the P instead becomes the left
  214. * child of C. The left subtree of C is inherited as the new right subtree
  215. * for P. The ordering of the keys within the tree is thus preserved.
  216. */
  217. static void rotate_left(dnode_t *upper)
  218. {
  219. dnode_t *lower, *lowleft, *upparent;
  220. lower = upper->right;
  221. upper->right = lowleft = lower->left;
  222. lowleft->parent = upper;
  223. lower->parent = upparent = upper->parent;
  224. /* don't need to check for root node here because root->parent is
  225. the sentinel nil node, and root->parent->left points back to root */
  226. if (upper == upparent->left) {
  227. upparent->left = lower;
  228. } else {
  229. assert (upper == upparent->right);
  230. upparent->right = lower;
  231. }
  232. lower->left = upper;
  233. upper->parent = lower;
  234. }
  235. /*
  236. * This operation is the ``mirror'' image of rotate_left. It is
  237. * the same procedure, but with left and right interchanged.
  238. */
  239. static void rotate_right(dnode_t *upper)
  240. {
  241. dnode_t *lower, *lowright, *upparent;
  242. lower = upper->left;
  243. upper->left = lowright = lower->right;
  244. lowright->parent = upper;
  245. lower->parent = upparent = upper->parent;
  246. if (upper == upparent->right) {
  247. upparent->right = lower;
  248. } else {
  249. assert (upper == upparent->left);
  250. upparent->left = lower;
  251. }
  252. lower->right = upper;
  253. upper->parent = lower;
  254. }
  255. /*
  256. * Do a postorder traversal of the tree rooted at the specified
  257. * node and free everything under it. Used by dict_free().
  258. */
  259. static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil)
  260. {
  261. if (node == nil)
  262. return;
  263. free_nodes(dict, node->left, nil);
  264. free_nodes(dict, node->right, nil);
  265. dict->dict_freenode(node);
  266. }
  267. /*
  268. * Verify that the tree contains the given node. This is done by
  269. * traversing all of the nodes and comparing their pointers to the
  270. * given pointer. Returns 1 if the node is found, otherwise
  271. * returns zero. It is intended for debugging purposes.
  272. */
  273. static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node)
  274. {
  275. if (root != nil) {
  276. return root == node
  277. || verify_dict_has_node(nil, root->left, node)
  278. || verify_dict_has_node(nil, root->right, node);
  279. }
  280. return 0;
  281. }
  282. /*
  283. * Select a different set of node allocator routines.
  284. */
  285. static void dict_set_allocator(dict_t *dict, dnode_free_t fr)
  286. {
  287. assert (dict_count(dict) == 0);
  288. dict->dict_freenode = fr;
  289. }
  290. /*
  291. * Free all the nodes in the dictionary by using the dictionary's
  292. * installed free routine. The dictionary is emptied.
  293. */
  294. static void dict_free_nodes(dict_t *dict)
  295. {
  296. dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
  297. free_nodes(dict, root, nil);
  298. dict->dict_nodecount = 0;
  299. dict->nilnode.left = &dict->nilnode;
  300. dict->nilnode.right = &dict->nilnode;
  301. }
  302. /*
  303. * Initialize a user-supplied dictionary object.
  304. */
  305. static dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp)
  306. {
  307. dict->compare = comp;
  308. dict->dict_freenode = dnode_free;
  309. dict->dict_nodecount = 0;
  310. dict->maxcount = maxcount;
  311. dict->nilnode.left = &dict->nilnode;
  312. dict->nilnode.right = &dict->nilnode;
  313. dict->nilnode.parent = &dict->nilnode;
  314. dict->nilnode.color = dnode_black;
  315. dict->dupes = 0;
  316. return dict;
  317. }
  318. /*
  319. * Locate a node in the dictionary having the given key.
  320. * If the node is not found, a null a pointer is returned (rather than
  321. * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
  322. * located node is returned.
  323. */
  324. static dnode_t *dict_lookup(dict_t *dict, const void *key)
  325. {
  326. dnode_t *root = dict_root(dict);
  327. dnode_t *nil = dict_nil(dict);
  328. dnode_t *saved;
  329. int result;
  330. /* simple binary search adapted for trees that contain duplicate keys */
  331. while (root != nil) {
  332. result = dict->compare(key, root->key);
  333. if (result < 0)
  334. root = root->left;
  335. else if (result > 0)
  336. root = root->right;
  337. else {
  338. if (!dict->dupes) { /* no duplicates, return match */
  339. return root;
  340. } else { /* could be dupes, find leftmost one */
  341. do {
  342. saved = root;
  343. root = root->left;
  344. while (root != nil && dict->compare(key, root->key))
  345. root = root->right;
  346. } while (root != nil);
  347. return saved;
  348. }
  349. }
  350. }
  351. return NULL;
  352. }
  353. /*
  354. * Insert a node into the dictionary. The node should have been
  355. * initialized with a data field. All other fields are ignored.
  356. * The behavior is undefined if the user attempts to insert into
  357. * a dictionary that is already full (for which the dict_isfull()
  358. * function returns true).
  359. */
  360. static void dict_insert(dict_t *dict, dnode_t *node, const void *key)
  361. {
  362. dnode_t *where = dict_root(dict), *nil = dict_nil(dict);
  363. dnode_t *parent = nil, *uncle, *grandpa;
  364. int result = -1;
  365. node->key = key;
  366. /* basic binary tree insert */
  367. while (where != nil) {
  368. parent = where;
  369. result = dict->compare(key, where->key);
  370. /* trap attempts at duplicate key insertion unless it's explicitly allowed */
  371. assert (dict->dupes || result != 0);
  372. if (result < 0)
  373. where = where->left;
  374. else
  375. where = where->right;
  376. }
  377. assert (where == nil);
  378. if (result < 0)
  379. parent->left = node;
  380. else
  381. parent->right = node;
  382. node->parent = parent;
  383. node->left = nil;
  384. node->right = nil;
  385. dict->dict_nodecount++;
  386. /* red black adjustments */
  387. node->color = dnode_red;
  388. while (parent->color == dnode_red) {
  389. grandpa = parent->parent;
  390. if (parent == grandpa->left) {
  391. uncle = grandpa->right;
  392. if (uncle->color == dnode_red) { /* red parent, red uncle */
  393. parent->color = dnode_black;
  394. uncle->color = dnode_black;
  395. grandpa->color = dnode_red;
  396. node = grandpa;
  397. parent = grandpa->parent;
  398. } else { /* red parent, black uncle */
  399. if (node == parent->right) {
  400. rotate_left(parent);
  401. parent = node;
  402. assert (grandpa == parent->parent);
  403. /* rotation between parent and child preserves grandpa */
  404. }
  405. parent->color = dnode_black;
  406. grandpa->color = dnode_red;
  407. rotate_right(grandpa);
  408. break;
  409. }
  410. } else { /* symmetric cases: parent == parent->parent->right */
  411. uncle = grandpa->left;
  412. if (uncle->color == dnode_red) {
  413. parent->color = dnode_black;
  414. uncle->color = dnode_black;
  415. grandpa->color = dnode_red;
  416. node = grandpa;
  417. parent = grandpa->parent;
  418. } else {
  419. if (node == parent->left) {
  420. rotate_right(parent);
  421. parent = node;
  422. assert (grandpa == parent->parent);
  423. }
  424. parent->color = dnode_black;
  425. grandpa->color = dnode_red;
  426. rotate_left(grandpa);
  427. break;
  428. }
  429. }
  430. }
  431. dict_root(dict)->color = dnode_black;
  432. }
  433. /*
  434. * Allocate a node using the dictionary's allocator routine, give it
  435. * the data item.
  436. */
  437. static dnode_t *dnode_init(dnode_t *dnode, void *data)
  438. {
  439. dnode->data = data;
  440. dnode->parent = NULL;
  441. dnode->left = NULL;
  442. dnode->right = NULL;
  443. return dnode;
  444. }
  445. static int dict_alloc_insert(dict_t *dict, const void *key, void *data)
  446. {
  447. dnode_t *node = malloc(sizeof(dnode_t));
  448. if (node) {
  449. dnode_init(node, data);
  450. dict_insert(dict, node, key);
  451. return 1;
  452. }
  453. return 0;
  454. }
  455. /*
  456. * Return the node with the lowest (leftmost) key. If the dictionary is empty
  457. * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
  458. */
  459. static dnode_t *dict_first(dict_t *dict)
  460. {
  461. dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
  462. if (root != nil)
  463. while ((left = root->left) != nil)
  464. root = left;
  465. return (root == nil) ? NULL : root;
  466. }
  467. /*
  468. * Return the given node's successor node---the node which has the
  469. * next key in the the left to right ordering. If the node has
  470. * no successor, a null pointer is returned rather than a pointer to
  471. * the nil node.
  472. */
  473. static dnode_t *dict_next(dict_t *dict, dnode_t *curr)
  474. {
  475. dnode_t *nil = dict_nil(dict), *parent, *left;
  476. if (curr->right != nil) {
  477. curr = curr->right;
  478. while ((left = curr->left) != nil)
  479. curr = left;
  480. return curr;
  481. }
  482. parent = curr->parent;
  483. while (parent != nil && curr == parent->right) {
  484. curr = parent;
  485. parent = curr->parent;
  486. }
  487. return (parent == nil) ? NULL : parent;
  488. }
  489. static void dnode_free(dnode_t *node)
  490. {
  491. free(node);
  492. }
  493. #undef left
  494. #undef right
  495. #undef parent
  496. #undef color
  497. #undef key
  498. #undef data
  499. #undef nilnode
  500. #undef maxcount
  501. #undef compare
  502. #undef dupes
  503. /*
  504. * dirinfo.c --- maintains the directory information table for e2fsck.
  505. */
  506. /*
  507. * This subroutine is called during pass1 to create a directory info
  508. * entry. During pass1, the passed-in parent is 0; it will get filled
  509. * in during pass2.
  510. */
  511. static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
  512. {
  513. struct dir_info *dir;
  514. int i, j;
  515. ext2_ino_t num_dirs;
  516. errcode_t retval;
  517. unsigned long old_size;
  518. if (!ctx->dir_info) {
  519. ctx->dir_info_count = 0;
  520. retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
  521. if (retval)
  522. num_dirs = 1024; /* Guess */
  523. ctx->dir_info_size = num_dirs + 10;
  524. ctx->dir_info = (struct dir_info *)
  525. e2fsck_allocate_memory(ctx, ctx->dir_info_size
  526. * sizeof (struct dir_info),
  527. "directory map");
  528. }
  529. if (ctx->dir_info_count >= ctx->dir_info_size) {
  530. old_size = ctx->dir_info_size * sizeof(struct dir_info);
  531. ctx->dir_info_size += 10;
  532. retval = ext2fs_resize_mem(old_size, ctx->dir_info_size *
  533. sizeof(struct dir_info),
  534. &ctx->dir_info);
  535. if (retval) {
  536. ctx->dir_info_size -= 10;
  537. return;
  538. }
  539. }
  540. /*
  541. * Normally, add_dir_info is called with each inode in
  542. * sequential order; but once in a while (like when pass 3
  543. * needs to recreate the root directory or lost+found
  544. * directory) it is called out of order. In those cases, we
  545. * need to move the dir_info entries down to make room, since
  546. * the dir_info array needs to be sorted by inode number for
  547. * get_dir_info()'s sake.
  548. */
  549. if (ctx->dir_info_count &&
  550. ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
  551. for (i = ctx->dir_info_count-1; i > 0; i--)
  552. if (ctx->dir_info[i-1].ino < ino)
  553. break;
  554. dir = &ctx->dir_info[i];
  555. if (dir->ino != ino)
  556. for (j = ctx->dir_info_count++; j > i; j--)
  557. ctx->dir_info[j] = ctx->dir_info[j-1];
  558. } else
  559. dir = &ctx->dir_info[ctx->dir_info_count++];
  560. dir->ino = ino;
  561. dir->dotdot = parent;
  562. dir->parent = parent;
  563. }
  564. /*
  565. * get_dir_info() --- given an inode number, try to find the directory
  566. * information entry for it.
  567. */
  568. static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
  569. {
  570. int low, high, mid;
  571. low = 0;
  572. high = ctx->dir_info_count-1;
  573. if (!ctx->dir_info)
  574. return 0;
  575. if (ino == ctx->dir_info[low].ino)
  576. return &ctx->dir_info[low];
  577. if (ino == ctx->dir_info[high].ino)
  578. return &ctx->dir_info[high];
  579. while (low < high) {
  580. mid = (low+high)/2;
  581. if (mid == low || mid == high)
  582. break;
  583. if (ino == ctx->dir_info[mid].ino)
  584. return &ctx->dir_info[mid];
  585. if (ino < ctx->dir_info[mid].ino)
  586. high = mid;
  587. else
  588. low = mid;
  589. }
  590. return 0;
  591. }
  592. /*
  593. * Free the dir_info structure when it isn't needed any more.
  594. */
  595. static void e2fsck_free_dir_info(e2fsck_t ctx)
  596. {
  597. ext2fs_free_mem(&ctx->dir_info);
  598. ctx->dir_info_size = 0;
  599. ctx->dir_info_count = 0;
  600. }
  601. /*
  602. * Return the count of number of directories in the dir_info structure
  603. */
  604. static int e2fsck_get_num_dirinfo(e2fsck_t ctx)
  605. {
  606. return ctx->dir_info_count;
  607. }
  608. /*
  609. * A simple interator function
  610. */
  611. static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
  612. {
  613. if (*control >= ctx->dir_info_count)
  614. return 0;
  615. return ctx->dir_info + (*control)++;
  616. }
  617. /*
  618. * dirinfo.c --- maintains the directory information table for e2fsck.
  619. *
  620. */
  621. #ifdef ENABLE_HTREE
  622. /*
  623. * This subroutine is called during pass1 to create a directory info
  624. * entry. During pass1, the passed-in parent is 0; it will get filled
  625. * in during pass2.
  626. */
  627. static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
  628. {
  629. struct dx_dir_info *dir;
  630. int i, j;
  631. errcode_t retval;
  632. unsigned long old_size;
  633. if (!ctx->dx_dir_info) {
  634. ctx->dx_dir_info_count = 0;
  635. ctx->dx_dir_info_size = 100; /* Guess */
  636. ctx->dx_dir_info = (struct dx_dir_info *)
  637. e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size
  638. * sizeof (struct dx_dir_info),
  639. "directory map");
  640. }
  641. if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
  642. old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
  643. ctx->dx_dir_info_size += 10;
  644. retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
  645. sizeof(struct dx_dir_info),
  646. &ctx->dx_dir_info);
  647. if (retval) {
  648. ctx->dx_dir_info_size -= 10;
  649. return;
  650. }
  651. }
  652. /*
  653. * Normally, add_dx_dir_info is called with each inode in
  654. * sequential order; but once in a while (like when pass 3
  655. * needs to recreate the root directory or lost+found
  656. * directory) it is called out of order. In those cases, we
  657. * need to move the dx_dir_info entries down to make room, since
  658. * the dx_dir_info array needs to be sorted by inode number for
  659. * get_dx_dir_info()'s sake.
  660. */
  661. if (ctx->dx_dir_info_count &&
  662. ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) {
  663. for (i = ctx->dx_dir_info_count-1; i > 0; i--)
  664. if (ctx->dx_dir_info[i-1].ino < ino)
  665. break;
  666. dir = &ctx->dx_dir_info[i];
  667. if (dir->ino != ino)
  668. for (j = ctx->dx_dir_info_count++; j > i; j--)
  669. ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
  670. } else
  671. dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
  672. dir->ino = ino;
  673. dir->numblocks = num_blocks;
  674. dir->hashversion = 0;
  675. dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
  676. * sizeof (struct dx_dirblock_info),
  677. "dx_block info array");
  678. }
  679. /*
  680. * get_dx_dir_info() --- given an inode number, try to find the directory
  681. * information entry for it.
  682. */
  683. static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
  684. {
  685. int low, high, mid;
  686. low = 0;
  687. high = ctx->dx_dir_info_count-1;
  688. if (!ctx->dx_dir_info)
  689. return 0;
  690. if (ino == ctx->dx_dir_info[low].ino)
  691. return &ctx->dx_dir_info[low];
  692. if (ino == ctx->dx_dir_info[high].ino)
  693. return &ctx->dx_dir_info[high];
  694. while (low < high) {
  695. mid = (low+high)/2;
  696. if (mid == low || mid == high)
  697. break;
  698. if (ino == ctx->dx_dir_info[mid].ino)
  699. return &ctx->dx_dir_info[mid];
  700. if (ino < ctx->dx_dir_info[mid].ino)
  701. high = mid;
  702. else
  703. low = mid;
  704. }
  705. return 0;
  706. }
  707. /*
  708. * Free the dx_dir_info structure when it isn't needed any more.
  709. */
  710. static void e2fsck_free_dx_dir_info(e2fsck_t ctx)
  711. {
  712. int i;
  713. struct dx_dir_info *dir;
  714. if (ctx->dx_dir_info) {
  715. dir = ctx->dx_dir_info;
  716. for (i=0; i < ctx->dx_dir_info_count; i++) {
  717. ext2fs_free_mem(&dir->dx_block);
  718. }
  719. ext2fs_free_mem(&ctx->dx_dir_info);
  720. }
  721. ctx->dx_dir_info_size = 0;
  722. ctx->dx_dir_info_count = 0;
  723. }
  724. /*
  725. * A simple interator function
  726. */
  727. static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
  728. {
  729. if (*control >= ctx->dx_dir_info_count)
  730. return 0;
  731. return ctx->dx_dir_info + (*control)++;
  732. }
  733. #endif /* ENABLE_HTREE */
  734. /*
  735. * e2fsck.c - a consistency checker for the new extended file system.
  736. *
  737. */
  738. /*
  739. * This function allocates an e2fsck context
  740. */
  741. static errcode_t e2fsck_allocate_context(e2fsck_t *ret)
  742. {
  743. e2fsck_t context;
  744. errcode_t retval;
  745. retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
  746. if (retval)
  747. return retval;
  748. memset(context, 0, sizeof(struct e2fsck_struct));
  749. context->process_inode_size = 256;
  750. context->ext_attr_ver = 2;
  751. *ret = context;
  752. return 0;
  753. }
  754. struct ea_refcount_el {
  755. blk_t ea_blk;
  756. int ea_count;
  757. };
  758. struct ea_refcount {
  759. blk_t count;
  760. blk_t size;
  761. blk_t cursor;
  762. struct ea_refcount_el *list;
  763. };
  764. static void ea_refcount_free(ext2_refcount_t refcount)
  765. {
  766. if (!refcount)
  767. return;
  768. ext2fs_free_mem(&refcount->list);
  769. ext2fs_free_mem(&refcount);
  770. }
  771. /*
  772. * This function resets an e2fsck context; it is called when e2fsck
  773. * needs to be restarted.
  774. */
  775. static errcode_t e2fsck_reset_context(e2fsck_t ctx)
  776. {
  777. ctx->flags = 0;
  778. ctx->lost_and_found = 0;
  779. ctx->bad_lost_and_found = 0;
  780. ext2fs_free_inode_bitmap(ctx->inode_used_map);
  781. ctx->inode_used_map = 0;
  782. ext2fs_free_inode_bitmap(ctx->inode_dir_map);
  783. ctx->inode_dir_map = 0;
  784. ext2fs_free_inode_bitmap(ctx->inode_reg_map);
  785. ctx->inode_reg_map = 0;
  786. ext2fs_free_block_bitmap(ctx->block_found_map);
  787. ctx->block_found_map = 0;
  788. ext2fs_free_icount(ctx->inode_link_info);
  789. ctx->inode_link_info = 0;
  790. if (ctx->journal_io) {
  791. if (ctx->fs && ctx->fs->io != ctx->journal_io)
  792. io_channel_close(ctx->journal_io);
  793. ctx->journal_io = 0;
  794. }
  795. if (ctx->fs) {
  796. ext2fs_free_dblist(ctx->fs->dblist);
  797. ctx->fs->dblist = 0;
  798. }
  799. e2fsck_free_dir_info(ctx);
  800. #ifdef ENABLE_HTREE
  801. e2fsck_free_dx_dir_info(ctx);
  802. #endif
  803. ea_refcount_free(ctx->refcount);
  804. ctx->refcount = 0;
  805. ea_refcount_free(ctx->refcount_extra);
  806. ctx->refcount_extra = 0;
  807. ext2fs_free_block_bitmap(ctx->block_dup_map);
  808. ctx->block_dup_map = 0;
  809. ext2fs_free_block_bitmap(ctx->block_ea_map);
  810. ctx->block_ea_map = 0;
  811. ext2fs_free_inode_bitmap(ctx->inode_bad_map);
  812. ctx->inode_bad_map = 0;
  813. ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
  814. ctx->inode_imagic_map = 0;
  815. ext2fs_u32_list_free(ctx->dirs_to_hash);
  816. ctx->dirs_to_hash = 0;
  817. /*
  818. * Clear the array of invalid meta-data flags
  819. */
  820. ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
  821. ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
  822. ext2fs_free_mem(&ctx->invalid_inode_table_flag);
  823. /* Clear statistic counters */
  824. ctx->fs_directory_count = 0;
  825. ctx->fs_regular_count = 0;
  826. ctx->fs_blockdev_count = 0;
  827. ctx->fs_chardev_count = 0;
  828. ctx->fs_links_count = 0;
  829. ctx->fs_symlinks_count = 0;
  830. ctx->fs_fast_symlinks_count = 0;
  831. ctx->fs_fifo_count = 0;
  832. ctx->fs_total_count = 0;
  833. ctx->fs_sockets_count = 0;
  834. ctx->fs_ind_count = 0;
  835. ctx->fs_dind_count = 0;
  836. ctx->fs_tind_count = 0;
  837. ctx->fs_fragmented = 0;
  838. ctx->large_files = 0;
  839. /* Reset the superblock to the user's requested value */
  840. ctx->superblock = ctx->use_superblock;
  841. return 0;
  842. }
  843. static void e2fsck_free_context(e2fsck_t ctx)
  844. {
  845. if (!ctx)
  846. return;
  847. e2fsck_reset_context(ctx);
  848. if (ctx->blkid)
  849. blkid_put_cache(ctx->blkid);
  850. ext2fs_free_mem(&ctx);
  851. }
  852. /*
  853. * ea_refcount.c
  854. */
  855. /*
  856. * The strategy we use for keeping track of EA refcounts is as
  857. * follows. We keep a sorted array of first EA blocks and its
  858. * reference counts. Once the refcount has dropped to zero, it is
  859. * removed from the array to save memory space. Once the EA block is
  860. * checked, its bit is set in the block_ea_map bitmap.
  861. */
  862. static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
  863. {
  864. ext2_refcount_t refcount;
  865. errcode_t retval;
  866. size_t bytes;
  867. retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount);
  868. if (retval)
  869. return retval;
  870. memset(refcount, 0, sizeof(struct ea_refcount));
  871. if (!size)
  872. size = 500;
  873. refcount->size = size;
  874. bytes = (size_t) (size * sizeof(struct ea_refcount_el));
  875. #ifdef DEBUG
  876. printf("Refcount allocated %d entries, %d bytes.\n",
  877. refcount->size, bytes);
  878. #endif
  879. retval = ext2fs_get_mem(bytes, &refcount->list);
  880. if (retval)
  881. goto errout;
  882. memset(refcount->list, 0, bytes);
  883. refcount->count = 0;
  884. refcount->cursor = 0;
  885. *ret = refcount;
  886. return 0;
  887. errout:
  888. ea_refcount_free(refcount);
  889. return retval;
  890. }
  891. /*
  892. * collapse_refcount() --- go through the refcount array, and get rid
  893. * of any count == zero entries
  894. */
  895. static void refcount_collapse(ext2_refcount_t refcount)
  896. {
  897. unsigned int i, j;
  898. struct ea_refcount_el *list;
  899. list = refcount->list;
  900. for (i = 0, j = 0; i < refcount->count; i++) {
  901. if (list[i].ea_count) {
  902. if (i != j)
  903. list[j] = list[i];
  904. j++;
  905. }
  906. }
  907. #if defined(DEBUG) || defined(TEST_PROGRAM)
  908. printf("Refcount_collapse: size was %d, now %d\n",
  909. refcount->count, j);
  910. #endif
  911. refcount->count = j;
  912. }
  913. /*
  914. * insert_refcount_el() --- Insert a new entry into the sorted list at a
  915. * specified position.
  916. */
  917. static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
  918. blk_t blk, int pos)
  919. {
  920. struct ea_refcount_el *el;
  921. errcode_t retval;
  922. blk_t new_size = 0;
  923. int num;
  924. if (refcount->count >= refcount->size) {
  925. new_size = refcount->size + 100;
  926. #ifdef DEBUG
  927. printf("Reallocating refcount %d entries...\n", new_size);
  928. #endif
  929. retval = ext2fs_resize_mem((size_t) refcount->size *
  930. sizeof(struct ea_refcount_el),
  931. (size_t) new_size *
  932. sizeof(struct ea_refcount_el),
  933. &refcount->list);
  934. if (retval)
  935. return 0;
  936. refcount->size = new_size;
  937. }
  938. num = (int) refcount->count - pos;
  939. if (num < 0)
  940. return 0; /* should never happen */
  941. if (num) {
  942. memmove(&refcount->list[pos+1], &refcount->list[pos],
  943. sizeof(struct ea_refcount_el) * num);
  944. }
  945. refcount->count++;
  946. el = &refcount->list[pos];
  947. el->ea_count = 0;
  948. el->ea_blk = blk;
  949. return el;
  950. }
  951. /*
  952. * get_refcount_el() --- given an block number, try to find refcount
  953. * information in the sorted list. If the create flag is set,
  954. * and we can't find an entry, create one in the sorted list.
  955. */
  956. static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
  957. blk_t blk, int create)
  958. {
  959. float range;
  960. int low, high, mid;
  961. blk_t lowval, highval;
  962. if (!refcount || !refcount->list)
  963. return 0;
  964. retry:
  965. low = 0;
  966. high = (int) refcount->count-1;
  967. if (create && ((refcount->count == 0) ||
  968. (blk > refcount->list[high].ea_blk))) {
  969. if (refcount->count >= refcount->size)
  970. refcount_collapse(refcount);
  971. return insert_refcount_el(refcount, blk,
  972. (unsigned) refcount->count);
  973. }
  974. if (refcount->count == 0)
  975. return 0;
  976. if (refcount->cursor >= refcount->count)
  977. refcount->cursor = 0;
  978. if (blk == refcount->list[refcount->cursor].ea_blk)
  979. return &refcount->list[refcount->cursor++];
  980. #ifdef DEBUG
  981. printf("Non-cursor get_refcount_el: %u\n", blk);
  982. #endif
  983. while (low <= high) {
  984. if (low == high)
  985. mid = low;
  986. else {
  987. /* Interpolate for efficiency */
  988. lowval = refcount->list[low].ea_blk;
  989. highval = refcount->list[high].ea_blk;
  990. if (blk < lowval)
  991. range = 0;
  992. else if (blk > highval)
  993. range = 1;
  994. else
  995. range = ((float) (blk - lowval)) /
  996. (highval - lowval);
  997. mid = low + ((int) (range * (high-low)));
  998. }
  999. if (blk == refcount->list[mid].ea_blk) {
  1000. refcount->cursor = mid+1;
  1001. return &refcount->list[mid];
  1002. }
  1003. if (blk < refcount->list[mid].ea_blk)
  1004. high = mid-1;
  1005. else
  1006. low = mid+1;
  1007. }
  1008. /*
  1009. * If we need to create a new entry, it should be right at
  1010. * low (where high will be left at low-1).
  1011. */
  1012. if (create) {
  1013. if (refcount->count >= refcount->size) {
  1014. refcount_collapse(refcount);
  1015. if (refcount->count < refcount->size)
  1016. goto retry;
  1017. }
  1018. return insert_refcount_el(refcount, blk, low);
  1019. }
  1020. return 0;
  1021. }
  1022. static errcode_t
  1023. ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
  1024. {
  1025. struct ea_refcount_el *el;
  1026. el = get_refcount_el(refcount, blk, 1);
  1027. if (!el)
  1028. return EXT2_ET_NO_MEMORY;
  1029. el->ea_count++;
  1030. if (ret)
  1031. *ret = el->ea_count;
  1032. return 0;
  1033. }
  1034. static errcode_t
  1035. ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
  1036. {
  1037. struct ea_refcount_el *el;
  1038. el = get_refcount_el(refcount, blk, 0);
  1039. if (!el || el->ea_count == 0)
  1040. return EXT2_ET_INVALID_ARGUMENT;
  1041. el->ea_count--;
  1042. if (ret)
  1043. *ret = el->ea_count;
  1044. return 0;
  1045. }
  1046. static errcode_t
  1047. ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
  1048. {
  1049. struct ea_refcount_el *el;
  1050. /*
  1051. * Get the refcount element
  1052. */
  1053. el = get_refcount_el(refcount, blk, count ? 1 : 0);
  1054. if (!el)
  1055. return count ? EXT2_ET_NO_MEMORY : 0;
  1056. el->ea_count = count;
  1057. return 0;
  1058. }
  1059. static inline void ea_refcount_intr_begin(ext2_refcount_t refcount)
  1060. {
  1061. refcount->cursor = 0;
  1062. }
  1063. static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret)
  1064. {
  1065. struct ea_refcount_el *list;
  1066. while (1) {
  1067. if (refcount->cursor >= refcount->count)
  1068. return 0;
  1069. list = refcount->list;
  1070. if (list[refcount->cursor].ea_count) {
  1071. if (ret)
  1072. *ret = list[refcount->cursor].ea_count;
  1073. return list[refcount->cursor++].ea_blk;
  1074. }
  1075. refcount->cursor++;
  1076. }
  1077. }
  1078. /*
  1079. * ehandler.c --- handle bad block errors which come up during the
  1080. * course of an e2fsck session.
  1081. */
  1082. static const char *operation;
  1083. static errcode_t
  1084. e2fsck_handle_read_error(io_channel channel, unsigned long block, int count,
  1085. void *data, size_t size FSCK_ATTR((unused)),
  1086. int actual FSCK_ATTR((unused)), errcode_t error)
  1087. {
  1088. int i;
  1089. char *p;
  1090. ext2_filsys fs = (ext2_filsys) channel->app_data;
  1091. e2fsck_t ctx;
  1092. ctx = (e2fsck_t) fs->priv_data;
  1093. /*
  1094. * If more than one block was read, try reading each block
  1095. * separately. We could use the actual bytes read to figure
  1096. * out where to start, but we don't bother.
  1097. */
  1098. if (count > 1) {
  1099. p = (char *) data;
  1100. for (i=0; i < count; i++, p += channel->block_size, block++) {
  1101. error = io_channel_read_blk(channel, block,
  1102. 1, p);
  1103. if (error)
  1104. return error;
  1105. }
  1106. return 0;
  1107. }
  1108. if (operation)
  1109. printf(_("Error reading block %lu (%s) while %s. "), block,
  1110. error_message(error), operation);
  1111. else
  1112. printf(_("Error reading block %lu (%s). "), block,
  1113. error_message(error));
  1114. preenhalt(ctx);
  1115. if (ask(ctx, _("Ignore error"), 1)) {
  1116. if (ask(ctx, _("Force rewrite"), 1))
  1117. io_channel_write_blk(channel, block, 1, data);
  1118. return 0;
  1119. }
  1120. return error;
  1121. }
  1122. static errcode_t
  1123. e2fsck_handle_write_error(io_channel channel, unsigned long block, int count,
  1124. const void *data, size_t size FSCK_ATTR((unused)),
  1125. int actual FSCK_ATTR((unused)), errcode_t error)
  1126. {
  1127. int i;
  1128. const char *p;
  1129. ext2_filsys fs = (ext2_filsys) channel->app_data;
  1130. e2fsck_t ctx;
  1131. ctx = (e2fsck_t) fs->priv_data;
  1132. /*
  1133. * If more than one block was written, try writing each block
  1134. * separately. We could use the actual bytes read to figure
  1135. * out where to start, but we don't bother.
  1136. */
  1137. if (count > 1) {
  1138. p = (const char *) data;
  1139. for (i=0; i < count; i++, p += channel->block_size, block++) {
  1140. error = io_channel_write_blk(channel, block,
  1141. 1, p);
  1142. if (error)
  1143. return error;
  1144. }
  1145. return 0;
  1146. }
  1147. if (operation)
  1148. printf(_("Error writing block %lu (%s) while %s. "), block,
  1149. error_message(error), operation);
  1150. else
  1151. printf(_("Error writing block %lu (%s). "), block,
  1152. error_message(error));
  1153. preenhalt(ctx);
  1154. if (ask(ctx, _("Ignore error"), 1))
  1155. return 0;
  1156. return error;
  1157. }
  1158. static const char *ehandler_operation(const char *op)
  1159. {
  1160. const char *ret = operation;
  1161. operation = op;
  1162. return ret;
  1163. }
  1164. static void ehandler_init(io_channel channel)
  1165. {
  1166. channel->read_error = e2fsck_handle_read_error;
  1167. channel->write_error = e2fsck_handle_write_error;
  1168. }
  1169. /*
  1170. * journal.c --- code for handling the "ext3" journal
  1171. *
  1172. * Copyright (C) 2000 Andreas Dilger
  1173. * Copyright (C) 2000 Theodore Ts'o
  1174. *
  1175. * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
  1176. * Copyright (C) 1999 Red Hat Software
  1177. *
  1178. * This file may be redistributed under the terms of the
  1179. * GNU General Public License version 2 or at your discretion
  1180. * any later version.
  1181. */
  1182. /*
  1183. * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
  1184. * This creates a larger static binary, and a smaller binary using
  1185. * shared libraries. It's also probably slightly less CPU-efficient,
  1186. * which is why it's not on by default. But, it's a good way of
  1187. * testing the functions in inode_io.c and fileio.c.
  1188. */
  1189. #undef USE_INODE_IO
  1190. /* Kernel compatibility functions for handling the journal. These allow us
  1191. * to use the recovery.c file virtually unchanged from the kernel, so we
  1192. * don't have to do much to keep kernel and user recovery in sync.
  1193. */
  1194. static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys)
  1195. {
  1196. #ifdef USE_INODE_IO
  1197. *phys = block;
  1198. return 0;
  1199. #else
  1200. struct inode *inode = journal->j_inode;
  1201. errcode_t retval;
  1202. blk_t pblk;
  1203. if (!inode) {
  1204. *phys = block;
  1205. return 0;
  1206. }
  1207. retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino,
  1208. &inode->i_ext2, NULL, 0, block, &pblk);
  1209. *phys = pblk;
  1210. return retval;
  1211. #endif
  1212. }
  1213. static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize)
  1214. {
  1215. struct buffer_head *bh;
  1216. bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer");
  1217. if (!bh)
  1218. return NULL;
  1219. bh->b_ctx = kdev->k_ctx;
  1220. if (kdev->k_dev == K_DEV_FS)
  1221. bh->b_io = kdev->k_ctx->fs->io;
  1222. else
  1223. bh->b_io = kdev->k_ctx->journal_io;
  1224. bh->b_size = blocksize;
  1225. bh->b_blocknr = blocknr;
  1226. return bh;
  1227. }
  1228. static void sync_blockdev(kdev_t kdev)
  1229. {
  1230. io_channel io;
  1231. if (kdev->k_dev == K_DEV_FS)
  1232. io = kdev->k_ctx->fs->io;
  1233. else
  1234. io = kdev->k_ctx->journal_io;
  1235. io_channel_flush(io);
  1236. }
  1237. static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
  1238. {
  1239. int retval;
  1240. struct buffer_head *bh;
  1241. for (; nr > 0; --nr) {
  1242. bh = *bhp++;
  1243. if (rw == READ && !bh->b_uptodate) {
  1244. retval = io_channel_read_blk(bh->b_io,
  1245. bh->b_blocknr,
  1246. 1, bh->b_data);
  1247. if (retval) {
  1248. bb_error_msg("while reading block %lu",
  1249. (unsigned long) bh->b_blocknr);
  1250. bh->b_err = retval;
  1251. continue;
  1252. }
  1253. bh->b_uptodate = 1;
  1254. } else if (rw == WRITE && bh->b_dirty) {
  1255. retval = io_channel_write_blk(bh->b_io,
  1256. bh->b_blocknr,
  1257. 1, bh->b_data);
  1258. if (retval) {
  1259. bb_error_msg("while writing block %lu",
  1260. (unsigned long) bh->b_blocknr);
  1261. bh->b_err = retval;
  1262. continue;
  1263. }
  1264. bh->b_dirty = 0;
  1265. bh->b_uptodate = 1;
  1266. }
  1267. }
  1268. }
  1269. static void mark_buffer_dirty(struct buffer_head *bh)
  1270. {
  1271. bh->b_dirty = 1;
  1272. }
  1273. static inline void mark_buffer_clean(struct buffer_head * bh)
  1274. {
  1275. bh->b_dirty = 0;
  1276. }
  1277. static void brelse(struct buffer_head *bh)
  1278. {
  1279. if (bh->b_dirty)
  1280. ll_rw_block(WRITE, 1, &bh);
  1281. ext2fs_free_mem(&bh);
  1282. }
  1283. static int buffer_uptodate(struct buffer_head *bh)
  1284. {
  1285. return bh->b_uptodate;
  1286. }
  1287. static inline void mark_buffer_uptodate(struct buffer_head *bh, int val)
  1288. {
  1289. bh->b_uptodate = val;
  1290. }
  1291. static void wait_on_buffer(struct buffer_head *bh)
  1292. {
  1293. if (!bh->b_uptodate)
  1294. ll_rw_block(READ, 1, &bh);
  1295. }
  1296. static void e2fsck_clear_recover(e2fsck_t ctx, int error)
  1297. {
  1298. ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
  1299. /* if we had an error doing journal recovery, we need a full fsck */
  1300. if (error)
  1301. ctx->fs->super->s_state &= ~EXT2_VALID_FS;
  1302. ext2fs_mark_super_dirty(ctx->fs);
  1303. }
  1304. static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
  1305. {
  1306. struct ext2_super_block *sb = ctx->fs->super;
  1307. struct ext2_super_block jsuper;
  1308. struct problem_context pctx;
  1309. struct buffer_head *bh;
  1310. struct inode *j_inode = NULL;
  1311. struct kdev_s *dev_fs = NULL, *dev_journal;
  1312. const char *journal_name = 0;
  1313. journal_t *journal = NULL;
  1314. errcode_t retval = 0;
  1315. io_manager io_ptr = 0;
  1316. unsigned long start = 0;
  1317. blk_t blk;
  1318. int ext_journal = 0;
  1319. int tried_backup_jnl = 0;
  1320. int i;
  1321. clear_problem_context(&pctx);
  1322. journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
  1323. if (!journal) {
  1324. return EXT2_ET_NO_MEMORY;
  1325. }
  1326. dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
  1327. if (!dev_fs) {
  1328. retval = EXT2_ET_NO_MEMORY;
  1329. goto errout;
  1330. }
  1331. dev_journal = dev_fs+1;
  1332. dev_fs->k_ctx = dev_journal->k_ctx = ctx;
  1333. dev_fs->k_dev = K_DEV_FS;
  1334. dev_journal->k_dev = K_DEV_JOURNAL;
  1335. journal->j_dev = dev_journal;
  1336. journal->j_fs_dev = dev_fs;
  1337. journal->j_inode = NULL;
  1338. journal->j_blocksize = ctx->fs->blocksize;
  1339. if (uuid_is_null(sb->s_journal_uuid)) {
  1340. if (!sb->s_journal_inum)
  1341. return EXT2_ET_BAD_INODE_NUM;
  1342. j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
  1343. "journal inode");
  1344. if (!j_inode) {
  1345. retval = EXT2_ET_NO_MEMORY;
  1346. goto errout;
  1347. }
  1348. j_inode->i_ctx = ctx;
  1349. j_inode->i_ino = sb->s_journal_inum;
  1350. if ((retval = ext2fs_read_inode(ctx->fs,
  1351. sb->s_journal_inum,
  1352. &j_inode->i_ext2))) {
  1353. try_backup_journal:
  1354. if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
  1355. tried_backup_jnl)
  1356. goto errout;
  1357. memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
  1358. memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
  1359. EXT2_N_BLOCKS*4);
  1360. j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
  1361. j_inode->i_ext2.i_links_count = 1;
  1362. j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
  1363. tried_backup_jnl++;
  1364. }
  1365. if (!j_inode->i_ext2.i_links_count ||
  1366. !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
  1367. retval = EXT2_ET_NO_JOURNAL;
  1368. goto try_backup_journal;
  1369. }
  1370. if (j_inode->i_ext2.i_size / journal->j_blocksize <
  1371. JFS_MIN_JOURNAL_BLOCKS) {
  1372. retval = EXT2_ET_JOURNAL_TOO_SMALL;
  1373. goto try_backup_journal;
  1374. }
  1375. for (i=0; i < EXT2_N_BLOCKS; i++) {
  1376. blk = j_inode->i_ext2.i_block[i];
  1377. if (!blk) {
  1378. if (i < EXT2_NDIR_BLOCKS) {
  1379. retval = EXT2_ET_JOURNAL_TOO_SMALL;
  1380. goto try_backup_journal;
  1381. }
  1382. continue;
  1383. }
  1384. if (blk < sb->s_first_data_block ||
  1385. blk >= sb->s_blocks_count) {
  1386. retval = EXT2_ET_BAD_BLOCK_NUM;
  1387. goto try_backup_journal;
  1388. }
  1389. }
  1390. journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
  1391. #ifdef USE_INODE_IO
  1392. retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
  1393. &j_inode->i_ext2,
  1394. &journal_name);
  1395. if (retval)
  1396. goto errout;
  1397. io_ptr = inode_io_manager;
  1398. #else
  1399. journal->j_inode = j_inode;
  1400. ctx->journal_io = ctx->fs->io;
  1401. if ((retval = journal_bmap(journal, 0, &start)) != 0)
  1402. goto errout;
  1403. #endif
  1404. } else {
  1405. ext_journal = 1;
  1406. if (!ctx->journal_name) {
  1407. char uuid[37];
  1408. uuid_unparse(sb->s_journal_uuid, uuid);
  1409. ctx->journal_name = blkid_get_devname(ctx->blkid,
  1410. "UUID", uuid);
  1411. if (!ctx->journal_name)
  1412. ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
  1413. }
  1414. journal_name = ctx->journal_name;
  1415. if (!journal_name) {
  1416. fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
  1417. return EXT2_ET_LOAD_EXT_JOURNAL;
  1418. }
  1419. io_ptr = unix_io_manager;
  1420. }
  1421. #ifndef USE_INODE_IO
  1422. if (ext_journal)
  1423. #endif
  1424. retval = io_ptr->open(journal_name, IO_FLAG_RW,
  1425. &ctx->journal_io);
  1426. if (retval)
  1427. goto errout;
  1428. io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
  1429. if (ext_journal) {
  1430. if (ctx->fs->blocksize == 1024)
  1431. start = 1;
  1432. bh = getblk(dev_journal, start, ctx->fs->blocksize);
  1433. if (!bh) {
  1434. retval = EXT2_ET_NO_MEMORY;
  1435. goto errout;
  1436. }
  1437. ll_rw_block(READ, 1, &bh);
  1438. if ((retval = bh->b_err) != 0)
  1439. goto errout;
  1440. memcpy(&jsuper, start ? bh->b_data : bh->b_data + 1024,
  1441. sizeof(jsuper));
  1442. brelse(bh);
  1443. #if BB_BIG_ENDIAN
  1444. if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
  1445. ext2fs_swap_super(&jsuper);
  1446. #endif
  1447. if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
  1448. !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
  1449. fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
  1450. retval = EXT2_ET_LOAD_EXT_JOURNAL;
  1451. goto errout;
  1452. }
  1453. /* Make sure the journal UUID is correct */
  1454. if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
  1455. sizeof(jsuper.s_uuid))) {
  1456. fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
  1457. retval = EXT2_ET_LOAD_EXT_JOURNAL;
  1458. goto errout;
  1459. }
  1460. journal->j_maxlen = jsuper.s_blocks_count;
  1461. start++;
  1462. }
  1463. if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
  1464. retval = EXT2_ET_NO_MEMORY;
  1465. goto errout;
  1466. }
  1467. journal->j_sb_buffer = bh;
  1468. journal->j_superblock = (journal_superblock_t *)bh->b_data;
  1469. #ifdef USE_INODE_IO
  1470. ext2fs_free_mem(&j_inode);
  1471. #endif
  1472. *ret_journal = journal;
  1473. return 0;
  1474. errout:
  1475. ext2fs_free_mem(&dev_fs);
  1476. ext2fs_free_mem(&j_inode);
  1477. ext2fs_free_mem(&journal);
  1478. return retval;
  1479. }
  1480. static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
  1481. struct problem_context *pctx)
  1482. {
  1483. struct ext2_super_block *sb = ctx->fs->super;
  1484. int recover = ctx->fs->super->s_feature_incompat &
  1485. EXT3_FEATURE_INCOMPAT_RECOVER;
  1486. int has_journal = ctx->fs->super->s_feature_compat &
  1487. EXT3_FEATURE_COMPAT_HAS_JOURNAL;
  1488. if (has_journal || sb->s_journal_inum) {
  1489. /* The journal inode is bogus, remove and force full fsck */
  1490. pctx->ino = sb->s_journal_inum;
  1491. if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
  1492. if (has_journal && sb->s_journal_inum)
  1493. printf("*** ext3 journal has been deleted - "
  1494. "filesystem is now ext2 only ***\n\n");
  1495. sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
  1496. sb->s_journal_inum = 0;
  1497. ctx->flags |= E2F_FLAG_JOURNAL_INODE; /* FIXME: todo */
  1498. e2fsck_clear_recover(ctx, 1);
  1499. return 0;
  1500. }
  1501. return EXT2_ET_BAD_INODE_NUM;
  1502. } else if (recover) {
  1503. if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
  1504. e2fsck_clear_recover(ctx, 1);
  1505. return 0;
  1506. }
  1507. return EXT2_ET_UNSUPP_FEATURE;
  1508. }
  1509. return 0;
  1510. }
  1511. #define V1_SB_SIZE 0x0024
  1512. static void clear_v2_journal_fields(journal_t *journal)
  1513. {
  1514. e2fsck_t ctx = journal->j_dev->k_ctx;
  1515. struct problem_context pctx;
  1516. clear_problem_context(&pctx);
  1517. if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
  1518. return;
  1519. memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
  1520. ctx->fs->blocksize-V1_SB_SIZE);
  1521. mark_buffer_dirty(journal->j_sb_buffer);
  1522. }
  1523. static errcode_t e2fsck_journal_load(journal_t *journal)
  1524. {
  1525. e2fsck_t ctx = journal->j_dev->k_ctx;
  1526. journal_superblock_t *jsb;
  1527. struct buffer_head *jbh = journal->j_sb_buffer;
  1528. struct problem_context pctx;
  1529. clear_problem_context(&pctx);
  1530. ll_rw_block(READ, 1, &jbh);
  1531. if (jbh->b_err) {
  1532. bb_error_msg(_("reading journal superblock"));
  1533. return jbh->b_err;
  1534. }
  1535. jsb = journal->j_superblock;
  1536. /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
  1537. if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
  1538. return e2fsck_journal_fix_bad_inode(ctx, &pctx);
  1539. switch (ntohl(jsb->s_header.h_blocktype)) {
  1540. case JFS_SUPERBLOCK_V1:
  1541. journal->j_format_version = 1;
  1542. if (jsb->s_feature_compat ||
  1543. jsb->s_feature_incompat ||
  1544. jsb->s_feature_ro_compat ||
  1545. jsb->s_nr_users)
  1546. clear_v2_journal_fields(journal);
  1547. break;
  1548. case JFS_SUPERBLOCK_V2:
  1549. journal->j_format_version = 2;
  1550. if (ntohl(jsb->s_nr_users) > 1 &&
  1551. uuid_is_null(ctx->fs->super->s_journal_uuid))
  1552. clear_v2_journal_fields(journal);
  1553. if (ntohl(jsb->s_nr_users) > 1) {
  1554. fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
  1555. return EXT2_ET_JOURNAL_UNSUPP_VERSION;
  1556. }
  1557. break;
  1558. /*
  1559. * These should never appear in a journal super block, so if
  1560. * they do, the journal is badly corrupted.
  1561. */
  1562. case JFS_DESCRIPTOR_BLOCK:
  1563. case JFS_COMMIT_BLOCK:
  1564. case JFS_REVOKE_BLOCK:
  1565. return EXT2_ET_CORRUPT_SUPERBLOCK;
  1566. /* If we don't understand the superblock major type, but there
  1567. * is a magic number, then it is likely to be a new format we
  1568. * just don't understand, so leave it alone. */
  1569. default:
  1570. return EXT2_ET_JOURNAL_UNSUPP_VERSION;
  1571. }
  1572. if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
  1573. return EXT2_ET_UNSUPP_FEATURE;
  1574. if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
  1575. return EXT2_ET_RO_UNSUPP_FEATURE;
  1576. /* We have now checked whether we know enough about the journal
  1577. * format to be able to proceed safely, so any other checks that
  1578. * fail we should attempt to recover from. */
  1579. if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
  1580. bb_error_msg(_("%s: no valid journal superblock found"),
  1581. ctx->device_name);
  1582. return EXT2_ET_CORRUPT_SUPERBLOCK;
  1583. }
  1584. if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
  1585. journal->j_maxlen = ntohl(jsb->s_maxlen);
  1586. else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) {
  1587. bb_error_msg(_("%s: journal too short"),
  1588. ctx->device_name);
  1589. return EXT2_ET_CORRUPT_SUPERBLOCK;
  1590. }
  1591. journal->j_tail_sequence = ntohl(jsb->s_sequence);
  1592. journal->j_transaction_sequence = journal->j_tail_sequence;
  1593. journal->j_tail = ntohl(jsb->s_start);
  1594. journal->j_first = ntohl(jsb->s_first);
  1595. journal->j_last = ntohl(jsb->s_maxlen);
  1596. return 0;
  1597. }
  1598. static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
  1599. journal_t *journal)
  1600. {
  1601. char *p;
  1602. union {
  1603. uuid_t uuid;
  1604. __u32 val[4];
  1605. } u;
  1606. __u32 new_seq = 0;
  1607. int i;
  1608. /* Leave a valid existing V1 superblock signature alone.
  1609. * Anything unrecognisable we overwrite with a new V2
  1610. * signature. */
  1611. if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
  1612. jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) {
  1613. jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
  1614. jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
  1615. }
  1616. /* Zero out everything else beyond the superblock header */
  1617. p = ((char *) jsb) + sizeof(journal_header_t);
  1618. memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
  1619. jsb->s_blocksize = htonl(ctx->fs->blocksize);
  1620. jsb->s_maxlen = htonl(journal->j_maxlen);
  1621. jsb->s_first = htonl(1);
  1622. /* Initialize the journal sequence number so that there is "no"
  1623. * chance we will find old "valid" transactions in the journal.
  1624. * This avoids the need to zero the whole journal (slow to do,
  1625. * and risky when we are just recovering the filesystem).
  1626. */
  1627. uuid_generate(u.uuid);
  1628. for (i = 0; i < 4; i ++)
  1629. new_seq ^= u.val[i];
  1630. jsb->s_sequence = htonl(new_seq);
  1631. mark_buffer_dirty(journal->j_sb_buffer);
  1632. ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
  1633. }
  1634. static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
  1635. journal_t *journal,
  1636. struct problem_context *pctx)
  1637. {
  1638. struct ext2_super_block *sb = ctx->fs->super;
  1639. int recover = ctx->fs->super->s_feature_incompat &
  1640. EXT3_FEATURE_INCOMPAT_RECOVER;
  1641. if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
  1642. if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
  1643. e2fsck_journal_reset_super(ctx, journal->j_superblock,
  1644. journal);
  1645. journal->j_transaction_sequence = 1;
  1646. e2fsck_clear_recover(ctx, recover);
  1647. return 0;
  1648. }
  1649. return EXT2_ET_CORRUPT_SUPERBLOCK;
  1650. } else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
  1651. return EXT2_ET_CORRUPT_SUPERBLOCK;
  1652. return 0;
  1653. }
  1654. static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
  1655. int reset, int drop)
  1656. {
  1657. journal_superblock_t *jsb;
  1658. if (drop)
  1659. mark_buffer_clean(journal->j_sb_buffer);
  1660. else if (!(ctx->options & E2F_OPT_READONLY)) {
  1661. jsb = journal->j_superblock;
  1662. jsb->s_sequence = htonl(journal->j_transaction_sequence);
  1663. if (reset)
  1664. jsb->s_start = 0; /* this marks the journal as empty */
  1665. mark_buffer_dirty(journal->j_sb_buffer);
  1666. }
  1667. brelse(journal->j_sb_buffer);
  1668. if (ctx->journal_io) {
  1669. if (ctx->fs && ctx->fs->io != ctx->journal_io)
  1670. io_channel_close(ctx->journal_io);
  1671. ctx->journal_io = 0;
  1672. }
  1673. #ifndef USE_INODE_IO
  1674. ext2fs_free_mem(&journal->j_inode);
  1675. #endif
  1676. ext2fs_free_mem(&journal->j_fs_dev);
  1677. ext2fs_free_mem(&journal);
  1678. }
  1679. /*
  1680. * This function makes sure that the superblock fields regarding the
  1681. * journal are consistent.
  1682. */
  1683. static int e2fsck_check_ext3_journal(e2fsck_t ctx)
  1684. {
  1685. struct ext2_super_block *sb = ctx->fs->super;
  1686. journal_t *journal;
  1687. int recover = ctx->fs->super->s_feature_incompat &
  1688. EXT3_FEATURE_INCOMPAT_RECOVER;
  1689. struct problem_context pctx;
  1690. problem_t problem;
  1691. int reset = 0, force_fsck = 0;
  1692. int retval;
  1693. /* If we don't have any journal features, don't do anything more */
  1694. if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
  1695. !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
  1696. uuid_is_null(sb->s_journal_uuid))
  1697. return 0;
  1698. clear_problem_context(&pctx);
  1699. pctx.num = sb->s_journal_inum;
  1700. retval = e2fsck_get_journal(ctx, &journal);
  1701. if (retval) {
  1702. if ((retval == EXT2_ET_BAD_INODE_NUM) ||
  1703. (retval == EXT2_ET_BAD_BLOCK_NUM) ||
  1704. (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
  1705. (retval == EXT2_ET_NO_JOURNAL))
  1706. return e2fsck_journal_fix_bad_inode(ctx, &pctx);
  1707. return retval;
  1708. }
  1709. retval = e2fsck_journal_load(journal);
  1710. if (retval) {
  1711. if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
  1712. ((retval == EXT2_ET_UNSUPP_FEATURE) &&
  1713. (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
  1714. &pctx))) ||
  1715. ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
  1716. (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
  1717. &pctx))) ||
  1718. ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
  1719. (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
  1720. retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
  1721. &pctx);
  1722. e2fsck_journal_release(ctx, journal, 0, 1);
  1723. return retval;
  1724. }
  1725. /*
  1726. * We want to make the flags consistent here. We will not leave with
  1727. * needs_recovery set but has_journal clear. We can't get in a loop
  1728. * with -y, -n, or -p, only if a user isn't making up their mind.
  1729. */
  1730. no_has_journal:
  1731. if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
  1732. recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER;
  1733. pctx.str = "inode";
  1734. if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
  1735. if (recover &&
  1736. !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
  1737. goto no_has_journal;
  1738. /*
  1739. * Need a full fsck if we are releasing a
  1740. * journal stored on a reserved inode.
  1741. */
  1742. force_fsck = recover ||
  1743. (sb->s_journal_inum < EXT2_FIRST_INODE(sb));
  1744. /* Clear all of the journal fields */
  1745. sb->s_journal_inum = 0;
  1746. sb->s_journal_dev = 0;
  1747. memset(sb->s_journal_uuid, 0,
  1748. sizeof(sb->s_journal_uuid));
  1749. e2fsck_clear_recover(ctx, force_fsck);
  1750. } else if (!(ctx->options & E2F_OPT_READONLY)) {
  1751. sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
  1752. ext2fs_mark_super_dirty(ctx->fs);
  1753. }
  1754. }
  1755. if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
  1756. !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
  1757. journal->j_superblock->s_start != 0) {
  1758. /* Print status information */
  1759. fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
  1760. if (ctx->superblock)
  1761. problem = PR_0_JOURNAL_RUN_DEFAULT;
  1762. else
  1763. problem = PR_0_JOURNAL_RUN;
  1764. if (fix_problem(ctx, problem, &pctx)) {
  1765. ctx->options |= E2F_OPT_FORCE;
  1766. sb->s_feature_incompat |=
  1767. EXT3_FEATURE_INCOMPAT_RECOVER;
  1768. ext2fs_mark_super_dirty(ctx->fs);
  1769. } else if (fix_problem(ctx,
  1770. PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
  1771. reset = 1;
  1772. sb->s_state &= ~EXT2_VALID_FS;
  1773. ext2fs_mark_super_dirty(ctx->fs);
  1774. }
  1775. /*
  1776. * If the user answers no to the above question, we
  1777. * ignore the fact that journal apparently has data;
  1778. * accidentally replaying over valid data would be far
  1779. * worse than skipping a questionable recovery.
  1780. *
  1781. * XXX should we abort with a fatal error here? What
  1782. * will the ext3 kernel code do if a filesystem with
  1783. * !NEEDS_RECOVERY but with a non-zero
  1784. * journal->j_superblock->s_start is mounted?
  1785. */
  1786. }
  1787. e2fsck_journal_release(ctx, journal, reset, 0);
  1788. return retval;
  1789. }
  1790. static errcode_t recover_ext3_journal(e2fsck_t ctx)
  1791. {
  1792. journal_t *journal;
  1793. int retval;
  1794. journal_init_revoke_caches();
  1795. retval = e2fsck_get_journal(ctx, &journal);
  1796. if (retval)
  1797. return retval;
  1798. retval = e2fsck_journal_load(journal);
  1799. if (retval)
  1800. goto errout;
  1801. retval = journal_init_revoke(journal, 1024);
  1802. if (retval)
  1803. goto errout;
  1804. retval = -journal_recover(journal);
  1805. if (retval)
  1806. goto errout;
  1807. if (journal->j_superblock->s_errno) {
  1808. ctx->fs->super->s_state |= EXT2_ERROR_FS;
  1809. ext2fs_mark_super_dirty(ctx->fs);
  1810. journal->j_superblock->s_errno = 0;
  1811. mark_buffer_dirty(journal->j_sb_buffer);
  1812. }
  1813. errout:
  1814. journal_destroy_revoke(journal);
  1815. journal_destroy_revoke_caches();
  1816. e2fsck_journal_release(ctx, journal, 1, 0);
  1817. return retval;
  1818. }
  1819. static int e2fsck_run_ext3_journal(e2fsck_t ctx)
  1820. {
  1821. io_manager io_ptr = ctx->fs->io->manager;
  1822. int blocksize = ctx->fs->blocksize;
  1823. errcode_t retval, recover_retval;
  1824. printf(_("%s: recovering journal\n"), ctx->device_name);
  1825. if (ctx->options & E2F_OPT_READONLY) {
  1826. printf(_("%s: won't do journal recovery while read-only\n"),
  1827. ctx->device_name);
  1828. return EXT2_ET_FILE_RO;
  1829. }
  1830. if (ctx->fs->flags & EXT2_FLAG_DIRTY)
  1831. ext2fs_flush(ctx->fs); /* Force out any modifications */
  1832. recover_retval = recover_ext3_journal(ctx);
  1833. /*
  1834. * Reload the filesystem context to get up-to-date data from disk
  1835. * because journal recovery will change the filesystem under us.
  1836. */
  1837. ext2fs_close(ctx->fs);
  1838. retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
  1839. ctx->superblock, blocksize, io_ptr,
  1840. &ctx->fs);
  1841. if (retval) {
  1842. bb_error_msg(_("while trying to re-open %s"),
  1843. ctx->device_name);
  1844. bb_error_msg_and_die(0);
  1845. }
  1846. ctx->fs->priv_data = ctx;
  1847. /* Set the superblock flags */
  1848. e2fsck_clear_recover(ctx, recover_retval);
  1849. return recover_retval;
  1850. }
  1851. /*
  1852. * This function will move the journal inode from a visible file in
  1853. * the filesystem directory hierarchy to the reserved inode if necessary.
  1854. */
  1855. static const char * const journal_names[] = {
  1856. ".journal", "journal", ".journal.dat", "journal.dat", 0 };
  1857. static void e2fsck_move_ext3_journal(e2fsck_t ctx)
  1858. {
  1859. struct ext2_super_block *sb = ctx->fs->super;
  1860. struct problem_context pctx;
  1861. struct ext2_inode inode;
  1862. ext2_filsys fs = ctx->fs;
  1863. ext2_ino_t ino;
  1864. errcode_t retval;
  1865. const char * const * cpp;
  1866. int group, mount_flags;
  1867. clear_problem_context(&pctx);
  1868. /*
  1869. * If the filesystem is opened read-only, or there is no
  1870. * journal, then do nothing.
  1871. */
  1872. if ((ctx->options & E2F_OPT_READONLY) ||
  1873. (sb->s_journal_inum == 0) ||
  1874. !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
  1875. return;
  1876. /*
  1877. * Read in the journal inode
  1878. */
  1879. if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
  1880. return;
  1881. /*
  1882. * If it's necessary to backup the journal inode, do so.
  1883. */
  1884. if ((sb->s_jnl_backup_type == 0) ||
  1885. ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
  1886. memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
  1887. if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
  1888. memcpy(sb->s_jnl_blocks, inode.i_block,
  1889. EXT2_N_BLOCKS*4);
  1890. sb->s_jnl_blocks[16] = inode.i_size;
  1891. sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
  1892. ext2fs_mark_super_dirty(fs);
  1893. fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
  1894. }
  1895. }
  1896. /*
  1897. * If the journal is already the hidden inode, then do nothing
  1898. */
  1899. if (sb->s_journal_inum == EXT2_JOURNAL_INO)
  1900. return;
  1901. /*
  1902. * The journal inode had better have only one link and not be readable.
  1903. */
  1904. if (inode.i_links_count != 1)
  1905. return;
  1906. /*
  1907. * If the filesystem is mounted, or we can't tell whether
  1908. * or not it's mounted, do nothing.
  1909. */
  1910. retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
  1911. if (retval || (mount_flags & EXT2_MF_MOUNTED))
  1912. return;
  1913. /*
  1914. * If we can't find the name of the journal inode, then do
  1915. * nothing.
  1916. */
  1917. for (cpp = journal_names; *cpp; cpp++) {
  1918. retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
  1919. strlen(*cpp), 0, &ino);
  1920. if ((retval == 0) && (ino == sb->s_journal_inum))
  1921. break;
  1922. }
  1923. if (*cpp == 0)
  1924. return;
  1925. /* We need the inode bitmap to be loaded */
  1926. retval = ext2fs_read_bitmaps(fs);
  1927. if (retval)
  1928. return;
  1929. pctx.str = *cpp;
  1930. if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
  1931. return;
  1932. /*
  1933. * OK, we've done all the checks, let's actually move the
  1934. * journal inode. Errors at this point mean we need to force
  1935. * an ext2 filesystem check.
  1936. */
  1937. if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
  1938. goto err_out;
  1939. if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
  1940. goto err_out;
  1941. sb->s_journal_inum = EXT2_JOURNAL_INO;
  1942. ext2fs_mark_super_dirty(fs);
  1943. fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
  1944. inode.i_links_count = 0;
  1945. inode.i_dtime = time(0);
  1946. if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
  1947. goto err_out;
  1948. group = ext2fs_group_of_ino(fs, ino);
  1949. ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
  1950. ext2fs_mark_ib_dirty(fs);
  1951. fs->group_desc[group].bg_free_inodes_count++;
  1952. fs->super->s_free_inodes_count++;
  1953. return;
  1954. err_out:
  1955. pctx.errcode = retval;
  1956. fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
  1957. fs->super->s_state &= ~EXT2_VALID_FS;
  1958. ext2fs_mark_super_dirty(fs);
  1959. return;
  1960. }
  1961. /*
  1962. * message.c --- print e2fsck messages (with compression)
  1963. *
  1964. * print_e2fsck_message() prints a message to the user, using
  1965. * compression techniques and expansions of abbreviations.
  1966. *
  1967. * The following % expansions are supported:
  1968. *
  1969. * %b <blk> block number
  1970. * %B <blkcount> integer
  1971. * %c <blk2> block number
  1972. * %Di <dirent>->ino inode number
  1973. * %Dn <dirent>->name string
  1974. * %Dr <dirent>->rec_len
  1975. * %Dl <dirent>->name_len
  1976. * %Dt <dirent>->filetype
  1977. * %d <dir> inode number
  1978. * %g <group> integer
  1979. * %i <ino> inode number
  1980. * %Is <inode> -> i_size
  1981. * %IS <inode> -> i_extra_isize
  1982. * %Ib <inode> -> i_blocks
  1983. * %Il <inode> -> i_links_count
  1984. * %Im <inode> -> i_mode
  1985. * %IM <inode> -> i_mtime
  1986. * %IF <inode> -> i_faddr
  1987. * %If <inode> -> i_file_acl
  1988. * %Id <inode> -> i_dir_acl
  1989. * %Iu <inode> -> i_uid
  1990. * %Ig <inode> -> i_gid
  1991. * %j <ino2> inode number
  1992. * %m <com_err error message>
  1993. * %N <num>
  1994. * %p ext2fs_get_pathname of directory <ino>
  1995. * %P ext2fs_get_pathname of <dirent>->ino with <ino2> as
  1996. * the containing directory. (If dirent is NULL
  1997. * then return the pathname of directory <ino2>)
  1998. * %q ext2fs_get_pathname of directory <dir>
  1999. * %Q ext2fs_get_pathname of directory <ino> with <dir> as
  2000. * the containing directory.
  2001. * %s <str> miscellaneous string
  2002. * %S backup superblock
  2003. * %X <num> hexadecimal format
  2004. *
  2005. * The following '@' expansions are supported:
  2006. *
  2007. * @a extended attribute
  2008. * @A error allocating
  2009. * @b block
  2010. * @B bitmap
  2011. * @c compress
  2012. * @C conflicts with some other fs block
  2013. * @D deleted
  2014. * @d directory
  2015. * @e entry
  2016. * @E Entry '%Dn' in %p (%i)
  2017. * @f filesystem
  2018. * @F for @i %i (%Q) is
  2019. * @g group
  2020. * @h HTREE directory inode
  2021. * @i inode
  2022. * @I illegal
  2023. * @j journal
  2024. * @l lost+found
  2025. * @L is a link
  2026. * @m multiply-claimed
  2027. * @n invalid
  2028. * @o orphaned
  2029. * @p problem in
  2030. * @r root inode
  2031. * @s should be
  2032. * @S superblock
  2033. * @u unattached
  2034. * @v device
  2035. * @z zero-length
  2036. */
  2037. /*
  2038. * This structure defines the abbreviations used by the text strings
  2039. * below. The first character in the string is the index letter. An
  2040. * abbreviation of the form '@<i>' is expanded by looking up the index
  2041. * letter <i> in the table below.
  2042. */
  2043. static const char * const abbrevs[] = {
  2044. N_("aextended attribute"),
  2045. N_("Aerror allocating"),
  2046. N_("bblock"),
  2047. N_("Bbitmap"),
  2048. N_("ccompress"),
  2049. N_("Cconflicts with some other fs @b"),
  2050. N_("iinode"),
  2051. N_("Iillegal"),
  2052. N_("jjournal"),
  2053. N_("Ddeleted"),
  2054. N_("ddirectory"),
  2055. N_("eentry"),
  2056. N_("E@e '%Dn' in %p (%i)"),
  2057. N_("ffilesystem"),
  2058. N_("Ffor @i %i (%Q) is"),
  2059. N_("ggroup"),
  2060. N_("hHTREE @d @i"),
  2061. N_("llost+found"),
  2062. N_("Lis a link"),
  2063. N_("mmultiply-claimed"),
  2064. N_("ninvalid"),
  2065. N_("oorphaned"),
  2066. N_("pproblem in"),
  2067. N_("rroot @i"),
  2068. N_("sshould be"),
  2069. N_("Ssuper@b"),
  2070. N_("uunattached"),
  2071. N_("vdevice"),
  2072. N_("zzero-length"),
  2073. "@@",
  2074. 0
  2075. };
  2076. /*
  2077. * Give more user friendly names to the "special" inodes.
  2078. */
  2079. #define num_special_inodes 11
  2080. static const char * const special_inode_name[] =
  2081. {
  2082. N_("<The NULL inode>"), /* 0 */
  2083. N_("<The bad blocks inode>"), /* 1 */
  2084. "/", /* 2 */
  2085. N_("<The ACL index inode>"), /* 3 */
  2086. N_("<The ACL data inode>"), /* 4 */
  2087. N_("<The boot loader inode>"), /* 5 */
  2088. N_("<The undelete directory inode>"), /* 6 */
  2089. N_("<The group descriptor inode>"), /* 7 */
  2090. N_("<The journal inode>"), /* 8 */
  2091. N_("<Reserved inode 9>"), /* 9 */
  2092. N_("<Reserved inode 10>"), /* 10 */
  2093. };
  2094. /*
  2095. * This function does "safe" printing. It will convert non-printable
  2096. * ASCII characters using '^' and M- notation.
  2097. */
  2098. static void safe_print(const char *cp, int len)
  2099. {
  2100. unsigned char ch;
  2101. if (len < 0)
  2102. len = strlen(cp);
  2103. while (len--) {
  2104. ch = *cp++;
  2105. if (ch > 128) {
  2106. fputs("M-", stdout);
  2107. ch -= 128;
  2108. }
  2109. if ((ch < 32) || (ch == 0x7f)) {
  2110. fputc('^', stdout);
  2111. ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
  2112. }
  2113. fputc(ch, stdout);
  2114. }
  2115. }
  2116. /*
  2117. * This function prints a pathname, using the ext2fs_get_pathname
  2118. * function
  2119. */
  2120. static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
  2121. {
  2122. errcode_t retval;
  2123. char *path;
  2124. if (!dir && (ino < num_special_inodes)) {
  2125. fputs(_(special_inode_name[ino]), stdout);
  2126. return;
  2127. }
  2128. retval = ext2fs_get_pathname(fs, dir, ino, &path);
  2129. if (retval)
  2130. fputs("???", stdout);
  2131. else {
  2132. safe_print(path, -1);
  2133. ext2fs_free_mem(&path);
  2134. }
  2135. }
  2136. static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
  2137. struct problem_context *pctx, int first);
  2138. /*
  2139. * This function handles the '@' expansion. We allow recursive
  2140. * expansion; an @ expression can contain further '@' and '%'
  2141. * expressions.
  2142. */
  2143. static void expand_at_expression(e2fsck_t ctx, char ch,
  2144. struct problem_context *pctx,
  2145. int *first)
  2146. {
  2147. const char * const *cpp;
  2148. const char *str;
  2149. /* Search for the abbreviation */
  2150. for (cpp = abbrevs; *cpp; cpp++) {
  2151. if (ch == *cpp[0])
  2152. break;
  2153. }
  2154. if (*cpp) {
  2155. str = _(*cpp) + 1;
  2156. if (*first && islower(*str)) {
  2157. *first = 0;
  2158. fputc(toupper(*str++), stdout);
  2159. }
  2160. print_e2fsck_message(ctx, str, pctx, *first);
  2161. } else
  2162. printf("@%c", ch);
  2163. }
  2164. /*
  2165. * This function expands '%IX' expressions
  2166. */
  2167. static void expand_inode_expression(char ch,
  2168. struct problem_context *ctx)
  2169. {
  2170. struct ext2_inode *inode;
  2171. struct ext2_inode_large *large_inode;
  2172. char * time_str;
  2173. time_t t;
  2174. int do_gmt = -1;
  2175. if (!ctx || !ctx->inode)
  2176. goto no_inode;
  2177. inode = ctx->inode;
  2178. large_inode = (struct ext2_inode_large *) inode;
  2179. switch (ch) {
  2180. case 's':
  2181. if (LINUX_S_ISDIR(inode->i_mode))
  2182. printf("%u", inode->i_size);
  2183. else {
  2184. printf("%"PRIu64, (inode->i_size |
  2185. ((uint64_t) inode->i_size_high << 32)));
  2186. }
  2187. break;
  2188. case 'S':
  2189. printf("%u", large_inode->i_extra_isize);
  2190. break;
  2191. case 'b':
  2192. printf("%u", inode->i_blocks);
  2193. break;
  2194. case 'l':
  2195. printf("%d", inode->i_links_count);
  2196. break;
  2197. case 'm':
  2198. printf("0%o", inode->i_mode);
  2199. break;
  2200. case 'M':
  2201. /* The diet libc doesn't respect the TZ environemnt variable */
  2202. if (do_gmt == -1) {
  2203. time_str = getenv("TZ");
  2204. if (!time_str)
  2205. time_str = "";
  2206. do_gmt = !strcmp(time_str, "GMT");
  2207. }
  2208. t = inode->i_mtime;
  2209. time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
  2210. printf("%.24s", time_str);
  2211. break;
  2212. case 'F':
  2213. printf("%u", inode->i_faddr);
  2214. break;
  2215. case 'f':
  2216. printf("%u", inode->i_file_acl);
  2217. break;
  2218. case 'd':
  2219. printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
  2220. inode->i_dir_acl : 0));
  2221. break;
  2222. case 'u':
  2223. printf("%d", (inode->i_uid |
  2224. (inode->osd2.linux2.l_i_uid_high << 16)));
  2225. break;
  2226. case 'g':
  2227. printf("%d", (inode->i_gid |
  2228. (inode->osd2.linux2.l_i_gid_high << 16)));
  2229. break;
  2230. default:
  2231. no_inode:
  2232. printf("%%I%c", ch);
  2233. break;
  2234. }
  2235. }
  2236. /*
  2237. * This function expands '%dX' expressions
  2238. */
  2239. static void expand_dirent_expression(char ch,
  2240. struct problem_context *ctx)
  2241. {
  2242. struct ext2_dir_entry *dirent;
  2243. int len;
  2244. if (!ctx || !ctx->dirent)
  2245. goto no_dirent;
  2246. dirent = ctx->dirent;
  2247. switch (ch) {
  2248. case 'i':
  2249. printf("%u", dirent->inode);
  2250. break;
  2251. case 'n':
  2252. len = dirent->name_len & 0xFF;
  2253. if (len > EXT2_NAME_LEN)
  2254. len = EXT2_NAME_LEN;
  2255. if (len > dirent->rec_len)
  2256. len = dirent->rec_len;
  2257. safe_print(dirent->name, len);
  2258. break;
  2259. case 'r':
  2260. printf("%u", dirent->rec_len);
  2261. break;
  2262. case 'l':
  2263. printf("%u", dirent->name_len & 0xFF);
  2264. break;
  2265. case 't':
  2266. printf("%u", dirent->name_len >> 8);
  2267. break;
  2268. default:
  2269. no_dirent:
  2270. printf("%%D%c", ch);
  2271. break;
  2272. }
  2273. }
  2274. static void expand_percent_expression(ext2_filsys fs, char ch,
  2275. struct problem_context *ctx)
  2276. {
  2277. if (!ctx)
  2278. goto no_context;
  2279. switch (ch) {
  2280. case '%':
  2281. fputc('%', stdout);
  2282. break;
  2283. case 'b':
  2284. printf("%u", ctx->blk);
  2285. break;
  2286. case 'B':
  2287. printf("%"PRIi64, ctx->blkcount);
  2288. break;
  2289. case 'c':
  2290. printf("%u", ctx->blk2);
  2291. break;
  2292. case 'd':
  2293. printf("%u", ctx->dir);
  2294. break;
  2295. case 'g':
  2296. printf("%d", ctx->group);
  2297. break;
  2298. case 'i':
  2299. printf("%u", ctx->ino);
  2300. break;
  2301. case 'j':
  2302. printf("%u", ctx->ino2);
  2303. break;
  2304. case 'm':
  2305. printf("%s", error_message(ctx->errcode));
  2306. break;
  2307. case 'N':
  2308. printf("%"PRIi64, ctx->num);
  2309. break;
  2310. case 'p':
  2311. print_pathname(fs, ctx->ino, 0);
  2312. break;
  2313. case 'P':
  2314. print_pathname(fs, ctx->ino2,
  2315. ctx->dirent ? ctx->dirent->inode : 0);
  2316. break;
  2317. case 'q':
  2318. print_pathname(fs, ctx->dir, 0);
  2319. break;
  2320. case 'Q':
  2321. print_pathname(fs, ctx->dir, ctx->ino);
  2322. break;
  2323. case 'S':
  2324. printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
  2325. break;
  2326. case 's':
  2327. printf("%s", ctx->str ? ctx->str : "NULL");
  2328. break;
  2329. case 'X':
  2330. printf("0x%"PRIi64, ctx->num);
  2331. break;
  2332. default:
  2333. no_context:
  2334. printf("%%%c", ch);
  2335. break;
  2336. }
  2337. }
  2338. static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
  2339. struct problem_context *pctx, int first)
  2340. {
  2341. ext2_filsys fs = ctx->fs;
  2342. const char * cp;
  2343. int i;
  2344. e2fsck_clear_progbar(ctx);
  2345. for (cp = msg; *cp; cp++) {
  2346. if (cp[0] == '@') {
  2347. cp++;
  2348. expand_at_expression(ctx, *cp, pctx, &first);
  2349. } else if (cp[0] == '%' && cp[1] == 'I') {
  2350. cp += 2;
  2351. expand_inode_expression(*cp, pctx);
  2352. } else if (cp[0] == '%' && cp[1] == 'D') {
  2353. cp += 2;
  2354. expand_dirent_expression(*cp, pctx);
  2355. } else if ((cp[0] == '%')) {
  2356. cp++;
  2357. expand_percent_expression(fs, *cp, pctx);
  2358. } else {
  2359. for (i=0; cp[i]; i++)
  2360. if ((cp[i] == '@') || cp[i] == '%')
  2361. break;
  2362. printf("%.*s", i, cp);
  2363. cp += i-1;
  2364. }
  2365. first = 0;
  2366. }
  2367. }
  2368. /*
  2369. * region.c --- code which manages allocations within a region.
  2370. */
  2371. struct region_el {
  2372. region_addr_t start;
  2373. region_addr_t end;
  2374. struct region_el *next;
  2375. };
  2376. struct region_struct {
  2377. region_addr_t min;
  2378. region_addr_t max;
  2379. struct region_el *allocated;
  2380. };
  2381. static region_t region_create(region_addr_t min, region_addr_t max)
  2382. {
  2383. region_t region;
  2384. region = malloc(sizeof(struct region_struct));
  2385. if (!region)
  2386. return NULL;
  2387. memset(region, 0, sizeof(struct region_struct));
  2388. region->min = min;
  2389. region->max = max;
  2390. return region;
  2391. }
  2392. static void region_free(region_t region)
  2393. {
  2394. struct region_el *r, *next;
  2395. for (r = region->allocated; r; r = next) {
  2396. next = r->next;
  2397. free(r);
  2398. }
  2399. memset(region, 0, sizeof(struct region_struct));
  2400. free(region);
  2401. }
  2402. static int region_allocate(region_t region, region_addr_t start, int n)
  2403. {
  2404. struct region_el *r, *new_region, *prev, *next;
  2405. region_addr_t end;
  2406. end = start+n;
  2407. if ((start < region->min) || (end > region->max))
  2408. return -1;
  2409. if (n == 0)
  2410. return 1;
  2411. /*
  2412. * Search through the linked list. If we find that it
  2413. * conflicts witih something that's already allocated, return
  2414. * 1; if we can find an existing region which we can grow, do
  2415. * so. Otherwise, stop when we find the appropriate place
  2416. * insert a new region element into the linked list.
  2417. */
  2418. for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
  2419. if (((start >= r->start) && (start < r->end)) ||
  2420. ((end > r->start) && (end <= r->end)) ||
  2421. ((start <= r->start) && (end >= r->end)))
  2422. return 1;
  2423. if (end == r->start) {
  2424. r->start = start;
  2425. return 0;
  2426. }
  2427. if (start == r->end) {
  2428. if ((next = r->next)) {
  2429. if (end > next->start)
  2430. return 1;
  2431. if (end == next->start) {
  2432. r->end = next->end;
  2433. r->next = next->next;
  2434. free(next);
  2435. return 0;
  2436. }
  2437. }
  2438. r->end = end;
  2439. return 0;
  2440. }
  2441. if (start < r->start)
  2442. break;
  2443. }
  2444. /*
  2445. * Insert a new region element structure into the linked list
  2446. */
  2447. new_region = malloc(sizeof(struct region_el));
  2448. if (!new_region)
  2449. return -1;
  2450. new_region->start = start;
  2451. new_region->end = start + n;
  2452. new_region->next = r;
  2453. if (prev)
  2454. prev->next = new_region;
  2455. else
  2456. region->allocated = new_region;
  2457. return 0;
  2458. }
  2459. /*
  2460. * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
  2461. *
  2462. * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
  2463. * and applies the following tests to each inode:
  2464. *
  2465. * - The mode field of the inode must be legal.
  2466. * - The size and block count fields of the inode are correct.
  2467. * - A data block must not be used by another inode
  2468. *
  2469. * Pass 1 also gathers the collects the following information:
  2470. *
  2471. * - A bitmap of which inodes are in use. (inode_used_map)
  2472. * - A bitmap of which inodes are directories. (inode_dir_map)
  2473. * - A bitmap of which inodes are regular files. (inode_reg_map)
  2474. * - A bitmap of which inodes have bad fields. (inode_bad_map)
  2475. * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
  2476. * - A bitmap of which blocks are in use. (block_found_map)
  2477. * - A bitmap of which blocks are in use by two inodes (block_dup_map)
  2478. * - The data blocks of the directory inodes. (dir_map)
  2479. *
  2480. * Pass 1 is designed to stash away enough information so that the
  2481. * other passes should not need to read in the inode information
  2482. * during the normal course of a filesystem check. (Althogh if an
  2483. * inconsistency is detected, other passes may need to read in an
  2484. * inode to fix it.)
  2485. *
  2486. * Note that pass 1B will be invoked if there are any duplicate blocks
  2487. * found.
  2488. */
  2489. static int process_block(ext2_filsys fs, blk_t *blocknr,
  2490. e2_blkcnt_t blockcnt, blk_t ref_blk,
  2491. int ref_offset, void *priv_data);
  2492. static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
  2493. e2_blkcnt_t blockcnt, blk_t ref_blk,
  2494. int ref_offset, void *priv_data);
  2495. static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
  2496. char *block_buf);
  2497. static void mark_table_blocks(e2fsck_t ctx);
  2498. static void alloc_imagic_map(e2fsck_t ctx);
  2499. static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
  2500. static void handle_fs_bad_blocks(e2fsck_t ctx);
  2501. static void process_inodes(e2fsck_t ctx, char *block_buf);
  2502. static int process_inode_cmp(const void *a, const void *b);
  2503. static errcode_t scan_callback(ext2_filsys fs,
  2504. dgrp_t group, void * priv_data);
  2505. static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
  2506. char *block_buf, int adjust_sign);
  2507. /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
  2508. static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
  2509. struct ext2_inode * inode, int bufsize,
  2510. const char *proc);
  2511. struct process_block_struct_1 {
  2512. ext2_ino_t ino;
  2513. unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
  2514. fragmented:1, compressed:1, bbcheck:1;
  2515. blk_t num_blocks;
  2516. blk_t max_blocks;
  2517. e2_blkcnt_t last_block;
  2518. int num_illegal_blocks;
  2519. blk_t previous_block;
  2520. struct ext2_inode *inode;
  2521. struct problem_context *pctx;
  2522. ext2fs_block_bitmap fs_meta_blocks;
  2523. e2fsck_t ctx;
  2524. };
  2525. struct process_inode_block {
  2526. ext2_ino_t ino;
  2527. struct ext2_inode inode;
  2528. };
  2529. struct scan_callback_struct {
  2530. e2fsck_t ctx;
  2531. char *block_buf;
  2532. };
  2533. /*
  2534. * For the inodes to process list.
  2535. */
  2536. static struct process_inode_block *inodes_to_process;
  2537. static int process_inode_count;
  2538. static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
  2539. EXT2_MIN_BLOCK_LOG_SIZE + 1];
  2540. /*
  2541. * Free all memory allocated by pass1 in preparation for restarting
  2542. * things.
  2543. */
  2544. static void unwind_pass1(void)
  2545. {
  2546. ext2fs_free_mem(&inodes_to_process);
  2547. }
  2548. /*
  2549. * Check to make sure a device inode is real. Returns 1 if the device
  2550. * checks out, 0 if not.
  2551. *
  2552. * Note: this routine is now also used to check FIFO's and Sockets,
  2553. * since they have the same requirement; the i_block fields should be
  2554. * zero.
  2555. */
  2556. static int
  2557. e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
  2558. {
  2559. int i;
  2560. /*
  2561. * If i_blocks is non-zero, or the index flag is set, then
  2562. * this is a bogus device/fifo/socket
  2563. */
  2564. if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
  2565. (inode->i_flags & EXT2_INDEX_FL))
  2566. return 0;
  2567. /*
  2568. * We should be able to do the test below all the time, but
  2569. * because the kernel doesn't forcibly clear the device
  2570. * inode's additional i_block fields, there are some rare
  2571. * occasions when a legitimate device inode will have non-zero
  2572. * additional i_block fields. So for now, we only complain
  2573. * when the immutable flag is set, which should never happen
  2574. * for devices. (And that's when the problem is caused, since
  2575. * you can't set or clear immutable flags for devices.) Once
  2576. * the kernel has been fixed we can change this...
  2577. */
  2578. if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
  2579. for (i=4; i < EXT2_N_BLOCKS; i++)
  2580. if (inode->i_block[i])
  2581. return 0;
  2582. }
  2583. return 1;
  2584. }
  2585. /*
  2586. * Check to make sure a symlink inode is real. Returns 1 if the symlink
  2587. * checks out, 0 if not.
  2588. */
  2589. static int
  2590. e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf)
  2591. {
  2592. unsigned int len;
  2593. int i;
  2594. blk_t blocks;
  2595. if ((inode->i_size_high || inode->i_size == 0) ||
  2596. (inode->i_flags & EXT2_INDEX_FL))
  2597. return 0;
  2598. blocks = ext2fs_inode_data_blocks(fs, inode);
  2599. if (blocks) {
  2600. if ((inode->i_size >= fs->blocksize) ||
  2601. (blocks != fs->blocksize >> 9) ||
  2602. (inode->i_block[0] < fs->super->s_first_data_block) ||
  2603. (inode->i_block[0] >= fs->super->s_blocks_count))
  2604. return 0;
  2605. for (i = 1; i < EXT2_N_BLOCKS; i++)
  2606. if (inode->i_block[i])
  2607. return 0;
  2608. if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
  2609. return 0;
  2610. len = strnlen(buf, fs->blocksize);
  2611. if (len == fs->blocksize)
  2612. return 0;
  2613. } else {
  2614. if (inode->i_size >= sizeof(inode->i_block))
  2615. return 0;
  2616. len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
  2617. if (len == sizeof(inode->i_block))
  2618. return 0;
  2619. }
  2620. if (len != inode->i_size)
  2621. return 0;
  2622. return 1;
  2623. }
  2624. /*
  2625. * If the immutable (or append-only) flag is set on the inode, offer
  2626. * to clear it.
  2627. */
  2628. #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
  2629. static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
  2630. {
  2631. if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
  2632. return;
  2633. if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
  2634. return;
  2635. pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
  2636. e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
  2637. }
  2638. /*
  2639. * If device, fifo or socket, check size is zero -- if not offer to
  2640. * clear it
  2641. */
  2642. static void check_size(e2fsck_t ctx, struct problem_context *pctx)
  2643. {
  2644. struct ext2_inode *inode = pctx->inode;
  2645. if ((inode->i_size == 0) && (inode->i_size_high == 0))
  2646. return;
  2647. if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
  2648. return;
  2649. inode->i_size = 0;
  2650. inode->i_size_high = 0;
  2651. e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
  2652. }
  2653. static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
  2654. {
  2655. struct ext2_super_block *sb = ctx->fs->super;
  2656. struct ext2_inode_large *inode;
  2657. struct ext2_ext_attr_entry *entry;
  2658. char *start, *end;
  2659. int storage_size, remain, offs;
  2660. int problem = 0;
  2661. inode = (struct ext2_inode_large *) pctx->inode;
  2662. storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
  2663. inode->i_extra_isize;
  2664. start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
  2665. inode->i_extra_isize + sizeof(__u32);
  2666. end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
  2667. entry = (struct ext2_ext_attr_entry *) start;
  2668. /* scan all entry's headers first */
  2669. /* take finish entry 0UL into account */
  2670. remain = storage_size - sizeof(__u32);
  2671. offs = end - start;
  2672. while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
  2673. /* header eats this space */
  2674. remain -= sizeof(struct ext2_ext_attr_entry);
  2675. /* is attribute name valid? */
  2676. if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
  2677. pctx->num = entry->e_name_len;
  2678. problem = PR_1_ATTR_NAME_LEN;
  2679. goto fix;
  2680. }
  2681. /* attribute len eats this space */
  2682. remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
  2683. /* check value size */
  2684. if (entry->e_value_size == 0 || entry->e_value_size > remain) {
  2685. pctx->num = entry->e_value_size;
  2686. problem = PR_1_ATTR_VALUE_SIZE;
  2687. goto fix;
  2688. }
  2689. /* check value placement */
  2690. if (entry->e_value_offs +
  2691. EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
  2692. printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
  2693. pctx->num = entry->e_value_offs;
  2694. problem = PR_1_ATTR_VALUE_OFFSET;
  2695. goto fix;
  2696. }
  2697. /* e_value_block must be 0 in inode's ea */
  2698. if (entry->e_value_block != 0) {
  2699. pctx->num = entry->e_value_block;
  2700. problem = PR_1_ATTR_VALUE_BLOCK;
  2701. goto fix;
  2702. }
  2703. /* e_hash must be 0 in inode's ea */
  2704. if (entry->e_hash != 0) {
  2705. pctx->num = entry->e_hash;
  2706. problem = PR_1_ATTR_HASH;
  2707. goto fix;
  2708. }
  2709. remain -= entry->e_value_size;
  2710. offs -= EXT2_XATTR_SIZE(entry->e_value_size);
  2711. entry = EXT2_EXT_ATTR_NEXT(entry);
  2712. }
  2713. fix:
  2714. /*
  2715. * it seems like a corruption. it's very unlikely we could repair
  2716. * EA(s) in automatic fashion -bzzz
  2717. */
  2718. if (problem == 0 || !fix_problem(ctx, problem, pctx))
  2719. return;
  2720. /* simple remove all possible EA(s) */
  2721. *((__u32 *)start) = 0UL;
  2722. e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
  2723. EXT2_INODE_SIZE(sb), "pass1");
  2724. }
  2725. static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
  2726. {
  2727. struct ext2_super_block *sb = ctx->fs->super;
  2728. struct ext2_inode_large *inode;
  2729. __u32 *eamagic;
  2730. int min, max;
  2731. inode = (struct ext2_inode_large *) pctx->inode;
  2732. if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
  2733. /* this isn't large inode. so, nothing to check */
  2734. return;
  2735. }
  2736. /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
  2737. min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
  2738. max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
  2739. /*
  2740. * For now we will allow i_extra_isize to be 0, but really
  2741. * implementations should never allow i_extra_isize to be 0
  2742. */
  2743. if (inode->i_extra_isize &&
  2744. (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
  2745. if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
  2746. return;
  2747. inode->i_extra_isize = min;
  2748. e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
  2749. EXT2_INODE_SIZE(sb), "pass1");
  2750. return;
  2751. }
  2752. eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
  2753. inode->i_extra_isize);
  2754. if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
  2755. /* it seems inode has an extended attribute(s) in body */
  2756. check_ea_in_inode(ctx, pctx);
  2757. }
  2758. }
  2759. static void e2fsck_pass1(e2fsck_t ctx)
  2760. {
  2761. int i;
  2762. __u64 max_sizes;
  2763. ext2_filsys fs = ctx->fs;
  2764. ext2_ino_t ino;
  2765. struct ext2_inode *inode;
  2766. ext2_inode_scan scan;
  2767. char *block_buf;
  2768. unsigned char frag, fsize;
  2769. struct problem_context pctx;
  2770. struct scan_callback_struct scan_struct;
  2771. struct ext2_super_block *sb = ctx->fs->super;
  2772. int imagic_fs;
  2773. int busted_fs_time = 0;
  2774. int inode_size;
  2775. clear_problem_context(&pctx);
  2776. if (!(ctx->options & E2F_OPT_PREEN))
  2777. fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
  2778. if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
  2779. !(ctx->options & E2F_OPT_NO)) {
  2780. if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
  2781. ctx->dirs_to_hash = 0;
  2782. }
  2783. /* Pass 1 */
  2784. #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
  2785. for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
  2786. max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
  2787. max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
  2788. max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
  2789. max_sizes = (max_sizes * (1UL << i)) - 1;
  2790. ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
  2791. }
  2792. #undef EXT2_BPP
  2793. imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
  2794. /*
  2795. * Allocate bitmaps structures
  2796. */
  2797. pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
  2798. &ctx->inode_used_map);
  2799. if (pctx.errcode) {
  2800. pctx.num = 1;
  2801. fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
  2802. ctx->flags |= E2F_FLAG_ABORT;
  2803. return;
  2804. }
  2805. pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
  2806. _("directory inode map"), &ctx->inode_dir_map);
  2807. if (pctx.errcode) {
  2808. pctx.num = 2;
  2809. fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
  2810. ctx->flags |= E2F_FLAG_ABORT;
  2811. return;
  2812. }
  2813. pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
  2814. _("regular file inode map"), &ctx->inode_reg_map);
  2815. if (pctx.errcode) {
  2816. pctx.num = 6;
  2817. fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
  2818. ctx->flags |= E2F_FLAG_ABORT;
  2819. return;
  2820. }
  2821. pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
  2822. &ctx->block_found_map);
  2823. if (pctx.errcode) {
  2824. pctx.num = 1;
  2825. fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
  2826. ctx->flags |= E2F_FLAG_ABORT;
  2827. return;
  2828. }
  2829. pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
  2830. &ctx->inode_link_info);
  2831. if (pctx.errcode) {
  2832. fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
  2833. ctx->flags |= E2F_FLAG_ABORT;
  2834. return;
  2835. }
  2836. inode_size = EXT2_INODE_SIZE(fs->super);
  2837. inode = (struct ext2_inode *)
  2838. e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
  2839. inodes_to_process = (struct process_inode_block *)
  2840. e2fsck_allocate_memory(ctx,
  2841. (ctx->process_inode_size *
  2842. sizeof(struct process_inode_block)),
  2843. "array of inodes to process");
  2844. process_inode_count = 0;
  2845. pctx.errcode = ext2fs_init_dblist(fs, 0);
  2846. if (pctx.errcode) {
  2847. fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
  2848. ctx->flags |= E2F_FLAG_ABORT;
  2849. return;
  2850. }
  2851. /*
  2852. * If the last orphan field is set, clear it, since the pass1
  2853. * processing will automatically find and clear the orphans.
  2854. * In the future, we may want to try using the last_orphan
  2855. * linked list ourselves, but for now, we clear it so that the
  2856. * ext3 mount code won't get confused.
  2857. */
  2858. if (!(ctx->options & E2F_OPT_READONLY)) {
  2859. if (fs->super->s_last_orphan) {
  2860. fs->super->s_last_orphan = 0;
  2861. ext2fs_mark_super_dirty(fs);
  2862. }
  2863. }
  2864. mark_table_blocks(ctx);
  2865. block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
  2866. "block interate buffer");
  2867. e2fsck_use_inode_shortcuts(ctx, 1);
  2868. ehandler_operation(_("doing inode scan"));
  2869. pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
  2870. &scan);
  2871. if (pctx.errcode) {
  2872. fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
  2873. ctx->flags |= E2F_FLAG_ABORT;
  2874. return;
  2875. }
  2876. ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
  2877. ctx->stashed_inode = inode;
  2878. scan_struct.ctx = ctx;
  2879. scan_struct.block_buf = block_buf;
  2880. ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
  2881. if (ctx->progress)
  2882. if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
  2883. return;
  2884. if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
  2885. (fs->super->s_mtime < fs->super->s_inodes_count))
  2886. busted_fs_time = 1;
  2887. while (1) {
  2888. pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
  2889. inode, inode_size);
  2890. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  2891. return;
  2892. if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
  2893. continue;
  2894. }
  2895. if (pctx.errcode) {
  2896. fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
  2897. ctx->flags |= E2F_FLAG_ABORT;
  2898. return;
  2899. }
  2900. if (!ino)
  2901. break;
  2902. pctx.ino = ino;
  2903. pctx.inode = inode;
  2904. ctx->stashed_ino = ino;
  2905. if (inode->i_links_count) {
  2906. pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
  2907. ino, inode->i_links_count);
  2908. if (pctx.errcode) {
  2909. pctx.num = inode->i_links_count;
  2910. fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
  2911. ctx->flags |= E2F_FLAG_ABORT;
  2912. return;
  2913. }
  2914. }
  2915. if (ino == EXT2_BAD_INO) {
  2916. struct process_block_struct_1 pb;
  2917. pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
  2918. &pb.fs_meta_blocks);
  2919. if (pctx.errcode) {
  2920. pctx.num = 4;
  2921. fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
  2922. ctx->flags |= E2F_FLAG_ABORT;
  2923. return;
  2924. }
  2925. pb.ino = EXT2_BAD_INO;
  2926. pb.num_blocks = pb.last_block = 0;
  2927. pb.num_illegal_blocks = 0;
  2928. pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
  2929. pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
  2930. pb.inode = inode;
  2931. pb.pctx = &pctx;
  2932. pb.ctx = ctx;
  2933. pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
  2934. block_buf, process_bad_block, &pb);
  2935. ext2fs_free_block_bitmap(pb.fs_meta_blocks);
  2936. if (pctx.errcode) {
  2937. fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
  2938. ctx->flags |= E2F_FLAG_ABORT;
  2939. return;
  2940. }
  2941. if (pb.bbcheck)
  2942. if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
  2943. ctx->flags |= E2F_FLAG_ABORT;
  2944. return;
  2945. }
  2946. ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
  2947. clear_problem_context(&pctx);
  2948. continue;
  2949. } else if (ino == EXT2_ROOT_INO) {
  2950. /*
  2951. * Make sure the root inode is a directory; if
  2952. * not, offer to clear it. It will be
  2953. * regnerated in pass #3.
  2954. */
  2955. if (!LINUX_S_ISDIR(inode->i_mode)) {
  2956. if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
  2957. inode->i_dtime = time(0);
  2958. inode->i_links_count = 0;
  2959. ext2fs_icount_store(ctx->inode_link_info,
  2960. ino, 0);
  2961. e2fsck_write_inode(ctx, ino, inode,
  2962. "pass1");
  2963. }
  2964. }
  2965. /*
  2966. * If dtime is set, offer to clear it. mke2fs
  2967. * version 0.2b created filesystems with the
  2968. * dtime field set for the root and lost+found
  2969. * directories. We won't worry about
  2970. * /lost+found, since that can be regenerated
  2971. * easily. But we will fix the root directory
  2972. * as a special case.
  2973. */
  2974. if (inode->i_dtime && inode->i_links_count) {
  2975. if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
  2976. inode->i_dtime = 0;
  2977. e2fsck_write_inode(ctx, ino, inode,
  2978. "pass1");
  2979. }
  2980. }
  2981. } else if (ino == EXT2_JOURNAL_INO) {
  2982. ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
  2983. if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
  2984. if (!LINUX_S_ISREG(inode->i_mode) &&
  2985. fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
  2986. &pctx)) {
  2987. inode->i_mode = LINUX_S_IFREG;
  2988. e2fsck_write_inode(ctx, ino, inode,
  2989. "pass1");
  2990. }
  2991. check_blocks(ctx, &pctx, block_buf);
  2992. continue;
  2993. }
  2994. if ((inode->i_links_count || inode->i_blocks ||
  2995. inode->i_blocks || inode->i_block[0]) &&
  2996. fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
  2997. &pctx)) {
  2998. memset(inode, 0, inode_size);
  2999. ext2fs_icount_store(ctx->inode_link_info,
  3000. ino, 0);
  3001. e2fsck_write_inode_full(ctx, ino, inode,
  3002. inode_size, "pass1");
  3003. }
  3004. } else if (ino < EXT2_FIRST_INODE(fs->super)) {
  3005. int problem = 0;
  3006. ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
  3007. if (ino == EXT2_BOOT_LOADER_INO) {
  3008. if (LINUX_S_ISDIR(inode->i_mode))
  3009. problem = PR_1_RESERVED_BAD_MODE;
  3010. } else if (ino == EXT2_RESIZE_INO) {
  3011. if (inode->i_mode &&
  3012. !LINUX_S_ISREG(inode->i_mode))
  3013. problem = PR_1_RESERVED_BAD_MODE;
  3014. } else {
  3015. if (inode->i_mode != 0)
  3016. problem = PR_1_RESERVED_BAD_MODE;
  3017. }
  3018. if (problem) {
  3019. if (fix_problem(ctx, problem, &pctx)) {
  3020. inode->i_mode = 0;
  3021. e2fsck_write_inode(ctx, ino, inode,
  3022. "pass1");
  3023. }
  3024. }
  3025. check_blocks(ctx, &pctx, block_buf);
  3026. continue;
  3027. }
  3028. /*
  3029. * Check for inodes who might have been part of the
  3030. * orphaned list linked list. They should have gotten
  3031. * dealt with by now, unless the list had somehow been
  3032. * corrupted.
  3033. *
  3034. * FIXME: In the future, inodes which are still in use
  3035. * (and which are therefore) pending truncation should
  3036. * be handled specially. Right now we just clear the
  3037. * dtime field, and the normal e2fsck handling of
  3038. * inodes where i_size and the inode blocks are
  3039. * inconsistent is to fix i_size, instead of releasing
  3040. * the extra blocks. This won't catch the inodes that
  3041. * was at the end of the orphan list, but it's better
  3042. * than nothing. The right answer is that there
  3043. * shouldn't be any bugs in the orphan list handling. :-)
  3044. */
  3045. if (inode->i_dtime && !busted_fs_time &&
  3046. inode->i_dtime < ctx->fs->super->s_inodes_count) {
  3047. if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
  3048. inode->i_dtime = inode->i_links_count ?
  3049. 0 : time(0);
  3050. e2fsck_write_inode(ctx, ino, inode,
  3051. "pass1");
  3052. }
  3053. }
  3054. /*
  3055. * This code assumes that deleted inodes have
  3056. * i_links_count set to 0.
  3057. */
  3058. if (!inode->i_links_count) {
  3059. if (!inode->i_dtime && inode->i_mode) {
  3060. if (fix_problem(ctx,
  3061. PR_1_ZERO_DTIME, &pctx)) {
  3062. inode->i_dtime = time(0);
  3063. e2fsck_write_inode(ctx, ino, inode,
  3064. "pass1");
  3065. }
  3066. }
  3067. continue;
  3068. }
  3069. /*
  3070. * n.b. 0.3c ext2fs code didn't clear i_links_count for
  3071. * deleted files. Oops.
  3072. *
  3073. * Since all new ext2 implementations get this right,
  3074. * we now assume that the case of non-zero
  3075. * i_links_count and non-zero dtime means that we
  3076. * should keep the file, not delete it.
  3077. *
  3078. */
  3079. if (inode->i_dtime) {
  3080. if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
  3081. inode->i_dtime = 0;
  3082. e2fsck_write_inode(ctx, ino, inode, "pass1");
  3083. }
  3084. }
  3085. ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
  3086. switch (fs->super->s_creator_os) {
  3087. case EXT2_OS_LINUX:
  3088. frag = inode->osd2.linux2.l_i_frag;
  3089. fsize = inode->osd2.linux2.l_i_fsize;
  3090. break;
  3091. case EXT2_OS_HURD:
  3092. frag = inode->osd2.hurd2.h_i_frag;
  3093. fsize = inode->osd2.hurd2.h_i_fsize;
  3094. break;
  3095. case EXT2_OS_MASIX:
  3096. frag = inode->osd2.masix2.m_i_frag;
  3097. fsize = inode->osd2.masix2.m_i_fsize;
  3098. break;
  3099. default:
  3100. frag = fsize = 0;
  3101. }
  3102. if (inode->i_faddr || frag || fsize ||
  3103. (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
  3104. mark_inode_bad(ctx, ino);
  3105. if (inode->i_flags & EXT2_IMAGIC_FL) {
  3106. if (imagic_fs) {
  3107. if (!ctx->inode_imagic_map)
  3108. alloc_imagic_map(ctx);
  3109. ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
  3110. ino);
  3111. } else {
  3112. if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
  3113. inode->i_flags &= ~EXT2_IMAGIC_FL;
  3114. e2fsck_write_inode(ctx, ino,
  3115. inode, "pass1");
  3116. }
  3117. }
  3118. }
  3119. check_inode_extra_space(ctx, &pctx);
  3120. if (LINUX_S_ISDIR(inode->i_mode)) {
  3121. ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
  3122. e2fsck_add_dir_info(ctx, ino, 0);
  3123. ctx->fs_directory_count++;
  3124. } else if (LINUX_S_ISREG (inode->i_mode)) {
  3125. ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
  3126. ctx->fs_regular_count++;
  3127. } else if (LINUX_S_ISCHR (inode->i_mode) &&
  3128. e2fsck_pass1_check_device_inode(fs, inode)) {
  3129. check_immutable(ctx, &pctx);
  3130. check_size(ctx, &pctx);
  3131. ctx->fs_chardev_count++;
  3132. } else if (LINUX_S_ISBLK (inode->i_mode) &&
  3133. e2fsck_pass1_check_device_inode(fs, inode)) {
  3134. check_immutable(ctx, &pctx);
  3135. check_size(ctx, &pctx);
  3136. ctx->fs_blockdev_count++;
  3137. } else if (LINUX_S_ISLNK (inode->i_mode) &&
  3138. e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
  3139. check_immutable(ctx, &pctx);
  3140. ctx->fs_symlinks_count++;
  3141. if (ext2fs_inode_data_blocks(fs, inode) == 0) {
  3142. ctx->fs_fast_symlinks_count++;
  3143. check_blocks(ctx, &pctx, block_buf);
  3144. continue;
  3145. }
  3146. }
  3147. else if (LINUX_S_ISFIFO (inode->i_mode) &&
  3148. e2fsck_pass1_check_device_inode(fs, inode)) {
  3149. check_immutable(ctx, &pctx);
  3150. check_size(ctx, &pctx);
  3151. ctx->fs_fifo_count++;
  3152. } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
  3153. e2fsck_pass1_check_device_inode(fs, inode)) {
  3154. check_immutable(ctx, &pctx);
  3155. check_size(ctx, &pctx);
  3156. ctx->fs_sockets_count++;
  3157. } else
  3158. mark_inode_bad(ctx, ino);
  3159. if (inode->i_block[EXT2_IND_BLOCK])
  3160. ctx->fs_ind_count++;
  3161. if (inode->i_block[EXT2_DIND_BLOCK])
  3162. ctx->fs_dind_count++;
  3163. if (inode->i_block[EXT2_TIND_BLOCK])
  3164. ctx->fs_tind_count++;
  3165. if (inode->i_block[EXT2_IND_BLOCK] ||
  3166. inode->i_block[EXT2_DIND_BLOCK] ||
  3167. inode->i_block[EXT2_TIND_BLOCK] ||
  3168. inode->i_file_acl) {
  3169. inodes_to_process[process_inode_count].ino = ino;
  3170. inodes_to_process[process_inode_count].inode = *inode;
  3171. process_inode_count++;
  3172. } else
  3173. check_blocks(ctx, &pctx, block_buf);
  3174. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  3175. return;
  3176. if (process_inode_count >= ctx->process_inode_size) {
  3177. process_inodes(ctx, block_buf);
  3178. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  3179. return;
  3180. }
  3181. }
  3182. process_inodes(ctx, block_buf);
  3183. ext2fs_close_inode_scan(scan);
  3184. ehandler_operation(0);
  3185. /*
  3186. * If any extended attribute blocks' reference counts need to
  3187. * be adjusted, either up (ctx->refcount_extra), or down
  3188. * (ctx->refcount), then fix them.
  3189. */
  3190. if (ctx->refcount) {
  3191. adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
  3192. ea_refcount_free(ctx->refcount);
  3193. ctx->refcount = 0;
  3194. }
  3195. if (ctx->refcount_extra) {
  3196. adjust_extattr_refcount(ctx, ctx->refcount_extra,
  3197. block_buf, +1);
  3198. ea_refcount_free(ctx->refcount_extra);
  3199. ctx->refcount_extra = 0;
  3200. }
  3201. if (ctx->invalid_bitmaps)
  3202. handle_fs_bad_blocks(ctx);
  3203. /* We don't need the block_ea_map any more */
  3204. ext2fs_free_block_bitmap(ctx->block_ea_map);
  3205. ctx->block_ea_map = 0;
  3206. if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
  3207. ext2fs_block_bitmap save_bmap;
  3208. save_bmap = fs->block_map;
  3209. fs->block_map = ctx->block_found_map;
  3210. clear_problem_context(&pctx);
  3211. pctx.errcode = ext2fs_create_resize_inode(fs);
  3212. if (pctx.errcode) {
  3213. fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
  3214. /* Should never get here */
  3215. ctx->flags |= E2F_FLAG_ABORT;
  3216. return;
  3217. }
  3218. e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
  3219. "recreate inode");
  3220. inode->i_mtime = time(0);
  3221. e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
  3222. "recreate inode");
  3223. fs->block_map = save_bmap;
  3224. ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
  3225. }
  3226. if (ctx->flags & E2F_FLAG_RESTART) {
  3227. /*
  3228. * Only the master copy of the superblock and block
  3229. * group descriptors are going to be written during a
  3230. * restart, so set the superblock to be used to be the
  3231. * master superblock.
  3232. */
  3233. ctx->use_superblock = 0;
  3234. unwind_pass1();
  3235. goto endit;
  3236. }
  3237. if (ctx->block_dup_map) {
  3238. if (ctx->options & E2F_OPT_PREEN) {
  3239. clear_problem_context(&pctx);
  3240. fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
  3241. }
  3242. e2fsck_pass1_dupblocks(ctx, block_buf);
  3243. }
  3244. ext2fs_free_mem(&inodes_to_process);
  3245. endit:
  3246. e2fsck_use_inode_shortcuts(ctx, 0);
  3247. ext2fs_free_mem(&block_buf);
  3248. ext2fs_free_mem(&inode);
  3249. }
  3250. /*
  3251. * When the inode_scan routines call this callback at the end of the
  3252. * glock group, call process_inodes.
  3253. */
  3254. static errcode_t scan_callback(ext2_filsys fs,
  3255. dgrp_t group, void * priv_data)
  3256. {
  3257. struct scan_callback_struct *scan_struct;
  3258. e2fsck_t ctx;
  3259. scan_struct = (struct scan_callback_struct *) priv_data;
  3260. ctx = scan_struct->ctx;
  3261. process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
  3262. if (ctx->progress)
  3263. if ((ctx->progress)(ctx, 1, group+1,
  3264. ctx->fs->group_desc_count))
  3265. return EXT2_ET_CANCEL_REQUESTED;
  3266. return 0;
  3267. }
  3268. /*
  3269. * Process the inodes in the "inodes to process" list.
  3270. */
  3271. static void process_inodes(e2fsck_t ctx, char *block_buf)
  3272. {
  3273. int i;
  3274. struct ext2_inode *old_stashed_inode;
  3275. ext2_ino_t old_stashed_ino;
  3276. const char *old_operation;
  3277. char buf[80];
  3278. struct problem_context pctx;
  3279. /* begin process_inodes */
  3280. if (process_inode_count == 0)
  3281. return;
  3282. old_operation = ehandler_operation(0);
  3283. old_stashed_inode = ctx->stashed_inode;
  3284. old_stashed_ino = ctx->stashed_ino;
  3285. qsort(inodes_to_process, process_inode_count,
  3286. sizeof(struct process_inode_block), process_inode_cmp);
  3287. clear_problem_context(&pctx);
  3288. for (i=0; i < process_inode_count; i++) {
  3289. pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
  3290. pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
  3291. sprintf(buf, _("reading indirect blocks of inode %u"),
  3292. pctx.ino);
  3293. ehandler_operation(buf);
  3294. check_blocks(ctx, &pctx, block_buf);
  3295. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  3296. break;
  3297. }
  3298. ctx->stashed_inode = old_stashed_inode;
  3299. ctx->stashed_ino = old_stashed_ino;
  3300. process_inode_count = 0;
  3301. /* end process inodes */
  3302. ehandler_operation(old_operation);
  3303. }
  3304. static int process_inode_cmp(const void *a, const void *b)
  3305. {
  3306. const struct process_inode_block *ib_a =
  3307. (const struct process_inode_block *) a;
  3308. const struct process_inode_block *ib_b =
  3309. (const struct process_inode_block *) b;
  3310. int ret;
  3311. ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
  3312. ib_b->inode.i_block[EXT2_IND_BLOCK]);
  3313. if (ret == 0)
  3314. ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
  3315. return ret;
  3316. }
  3317. /*
  3318. * Mark an inode as being bad in some what
  3319. */
  3320. static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
  3321. {
  3322. struct problem_context pctx;
  3323. if (!ctx->inode_bad_map) {
  3324. clear_problem_context(&pctx);
  3325. pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
  3326. _("bad inode map"), &ctx->inode_bad_map);
  3327. if (pctx.errcode) {
  3328. pctx.num = 3;
  3329. fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
  3330. /* Should never get here */
  3331. ctx->flags |= E2F_FLAG_ABORT;
  3332. return;
  3333. }
  3334. }
  3335. ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
  3336. }
  3337. /*
  3338. * This procedure will allocate the inode imagic table
  3339. */
  3340. static void alloc_imagic_map(e2fsck_t ctx)
  3341. {
  3342. struct problem_context pctx;
  3343. clear_problem_context(&pctx);
  3344. pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
  3345. _("imagic inode map"),
  3346. &ctx->inode_imagic_map);
  3347. if (pctx.errcode) {
  3348. pctx.num = 5;
  3349. fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
  3350. /* Should never get here */
  3351. ctx->flags |= E2F_FLAG_ABORT;
  3352. return;
  3353. }
  3354. }
  3355. /*
  3356. * Marks a block as in use, setting the dup_map if it's been set
  3357. * already. Called by process_block and process_bad_block.
  3358. *
  3359. * WARNING: Assumes checks have already been done to make sure block
  3360. * is valid. This is true in both process_block and process_bad_block.
  3361. */
  3362. static void mark_block_used(e2fsck_t ctx, blk_t block)
  3363. {
  3364. struct problem_context pctx;
  3365. clear_problem_context(&pctx);
  3366. if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
  3367. if (!ctx->block_dup_map) {
  3368. pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
  3369. _("multiply claimed block map"),
  3370. &ctx->block_dup_map);
  3371. if (pctx.errcode) {
  3372. pctx.num = 3;
  3373. fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
  3374. &pctx);
  3375. /* Should never get here */
  3376. ctx->flags |= E2F_FLAG_ABORT;
  3377. return;
  3378. }
  3379. }
  3380. ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
  3381. } else {
  3382. ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
  3383. }
  3384. }
  3385. /*
  3386. * Adjust the extended attribute block's reference counts at the end
  3387. * of pass 1, either by subtracting out references for EA blocks that
  3388. * are still referenced in ctx->refcount, or by adding references for
  3389. * EA blocks that had extra references as accounted for in
  3390. * ctx->refcount_extra.
  3391. */
  3392. static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
  3393. char *block_buf, int adjust_sign)
  3394. {
  3395. struct ext2_ext_attr_header *header;
  3396. struct problem_context pctx;
  3397. ext2_filsys fs = ctx->fs;
  3398. blk_t blk;
  3399. __u32 should_be;
  3400. int count;
  3401. clear_problem_context(&pctx);
  3402. ea_refcount_intr_begin(refcount);
  3403. while (1) {
  3404. if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
  3405. break;
  3406. pctx.blk = blk;
  3407. pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
  3408. if (pctx.errcode) {
  3409. fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
  3410. return;
  3411. }
  3412. header = (struct ext2_ext_attr_header *) block_buf;
  3413. pctx.blkcount = header->h_refcount;
  3414. should_be = header->h_refcount + adjust_sign * count;
  3415. pctx.num = should_be;
  3416. if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
  3417. header->h_refcount = should_be;
  3418. pctx.errcode = ext2fs_write_ext_attr(fs, blk,
  3419. block_buf);
  3420. if (pctx.errcode) {
  3421. fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
  3422. continue;
  3423. }
  3424. }
  3425. }
  3426. }
  3427. /*
  3428. * Handle processing the extended attribute blocks
  3429. */
  3430. static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
  3431. char *block_buf)
  3432. {
  3433. ext2_filsys fs = ctx->fs;
  3434. ext2_ino_t ino = pctx->ino;
  3435. struct ext2_inode *inode = pctx->inode;
  3436. blk_t blk;
  3437. char * end;
  3438. struct ext2_ext_attr_header *header;
  3439. struct ext2_ext_attr_entry *entry;
  3440. int count;
  3441. region_t region;
  3442. blk = inode->i_file_acl;
  3443. if (blk == 0)
  3444. return 0;
  3445. /*
  3446. * If the Extended attribute flag isn't set, then a non-zero
  3447. * file acl means that the inode is corrupted.
  3448. *
  3449. * Or if the extended attribute block is an invalid block,
  3450. * then the inode is also corrupted.
  3451. */
  3452. if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
  3453. (blk < fs->super->s_first_data_block) ||
  3454. (blk >= fs->super->s_blocks_count)) {
  3455. mark_inode_bad(ctx, ino);
  3456. return 0;
  3457. }
  3458. /* If ea bitmap hasn't been allocated, create it */
  3459. if (!ctx->block_ea_map) {
  3460. pctx->errcode = ext2fs_allocate_block_bitmap(fs,
  3461. _("ext attr block map"),
  3462. &ctx->block_ea_map);
  3463. if (pctx->errcode) {
  3464. pctx->num = 2;
  3465. fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
  3466. ctx->flags |= E2F_FLAG_ABORT;
  3467. return 0;
  3468. }
  3469. }
  3470. /* Create the EA refcount structure if necessary */
  3471. if (!ctx->refcount) {
  3472. pctx->errcode = ea_refcount_create(0, &ctx->refcount);
  3473. if (pctx->errcode) {
  3474. pctx->num = 1;
  3475. fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
  3476. ctx->flags |= E2F_FLAG_ABORT;
  3477. return 0;
  3478. }
  3479. }
  3480. /* Have we seen this EA block before? */
  3481. if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
  3482. if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
  3483. return 1;
  3484. /* Ooops, this EA was referenced more than it stated */
  3485. if (!ctx->refcount_extra) {
  3486. pctx->errcode = ea_refcount_create(0,
  3487. &ctx->refcount_extra);
  3488. if (pctx->errcode) {
  3489. pctx->num = 2;
  3490. fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
  3491. ctx->flags |= E2F_FLAG_ABORT;
  3492. return 0;
  3493. }
  3494. }
  3495. ea_refcount_increment(ctx->refcount_extra, blk, 0);
  3496. return 1;
  3497. }
  3498. /*
  3499. * OK, we haven't seen this EA block yet. So we need to
  3500. * validate it
  3501. */
  3502. pctx->blk = blk;
  3503. pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
  3504. if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
  3505. goto clear_extattr;
  3506. header = (struct ext2_ext_attr_header *) block_buf;
  3507. pctx->blk = inode->i_file_acl;
  3508. if (((ctx->ext_attr_ver == 1) &&
  3509. (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
  3510. ((ctx->ext_attr_ver == 2) &&
  3511. (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
  3512. if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
  3513. goto clear_extattr;
  3514. }
  3515. if (header->h_blocks != 1) {
  3516. if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
  3517. goto clear_extattr;
  3518. }
  3519. region = region_create(0, fs->blocksize);
  3520. if (!region) {
  3521. fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
  3522. ctx->flags |= E2F_FLAG_ABORT;
  3523. return 0;
  3524. }
  3525. if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
  3526. if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
  3527. goto clear_extattr;
  3528. }
  3529. entry = (struct ext2_ext_attr_entry *)(header+1);
  3530. end = block_buf + fs->blocksize;
  3531. while ((char *)entry < end && *(__u32 *)entry) {
  3532. if (region_allocate(region, (char *)entry - (char *)header,
  3533. EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
  3534. if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
  3535. goto clear_extattr;
  3536. }
  3537. if ((ctx->ext_attr_ver == 1 &&
  3538. (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
  3539. (ctx->ext_attr_ver == 2 &&
  3540. entry->e_name_index == 0)) {
  3541. if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
  3542. goto clear_extattr;
  3543. }
  3544. if (entry->e_value_block != 0) {
  3545. if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
  3546. goto clear_extattr;
  3547. }
  3548. if (entry->e_value_size &&
  3549. region_allocate(region, entry->e_value_offs,
  3550. EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
  3551. if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
  3552. goto clear_extattr;
  3553. }
  3554. entry = EXT2_EXT_ATTR_NEXT(entry);
  3555. }
  3556. if (region_allocate(region, (char *)entry - (char *)header, 4)) {
  3557. if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
  3558. goto clear_extattr;
  3559. }
  3560. region_free(region);
  3561. count = header->h_refcount - 1;
  3562. if (count)
  3563. ea_refcount_store(ctx->refcount, blk, count);
  3564. mark_block_used(ctx, blk);
  3565. ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
  3566. return 1;
  3567. clear_extattr:
  3568. inode->i_file_acl = 0;
  3569. e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
  3570. return 0;
  3571. }
  3572. /* Returns 1 if bad htree, 0 if OK */
  3573. static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
  3574. ext2_ino_t ino FSCK_ATTR((unused)),
  3575. struct ext2_inode *inode,
  3576. char *block_buf)
  3577. {
  3578. struct ext2_dx_root_info *root;
  3579. ext2_filsys fs = ctx->fs;
  3580. errcode_t retval;
  3581. blk_t blk;
  3582. if ((!LINUX_S_ISDIR(inode->i_mode) &&
  3583. fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
  3584. (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
  3585. fix_problem(ctx, PR_1_HTREE_SET, pctx)))
  3586. return 1;
  3587. blk = inode->i_block[0];
  3588. if (((blk == 0) ||
  3589. (blk < fs->super->s_first_data_block) ||
  3590. (blk >= fs->super->s_blocks_count)) &&
  3591. fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
  3592. return 1;
  3593. retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
  3594. if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
  3595. return 1;
  3596. /* XXX should check that beginning matches a directory */
  3597. root = (struct ext2_dx_root_info *) (block_buf + 24);
  3598. if ((root->reserved_zero || root->info_length < 8) &&
  3599. fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
  3600. return 1;
  3601. pctx->num = root->hash_version;
  3602. if ((root->hash_version != EXT2_HASH_LEGACY) &&
  3603. (root->hash_version != EXT2_HASH_HALF_MD4) &&
  3604. (root->hash_version != EXT2_HASH_TEA) &&
  3605. fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
  3606. return 1;
  3607. if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
  3608. fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
  3609. return 1;
  3610. pctx->num = root->indirect_levels;
  3611. if ((root->indirect_levels > 1) &&
  3612. fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
  3613. return 1;
  3614. return 0;
  3615. }
  3616. /*
  3617. * This subroutine is called on each inode to account for all of the
  3618. * blocks used by that inode.
  3619. */
  3620. static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
  3621. char *block_buf)
  3622. {
  3623. ext2_filsys fs = ctx->fs;
  3624. struct process_block_struct_1 pb;
  3625. ext2_ino_t ino = pctx->ino;
  3626. struct ext2_inode *inode = pctx->inode;
  3627. int bad_size = 0;
  3628. int dirty_inode = 0;
  3629. __u64 size;
  3630. pb.ino = ino;
  3631. pb.num_blocks = 0;
  3632. pb.last_block = -1;
  3633. pb.num_illegal_blocks = 0;
  3634. pb.suppress = 0; pb.clear = 0;
  3635. pb.fragmented = 0;
  3636. pb.compressed = 0;
  3637. pb.previous_block = 0;
  3638. pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
  3639. pb.is_reg = LINUX_S_ISREG(inode->i_mode);
  3640. pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
  3641. pb.inode = inode;
  3642. pb.pctx = pctx;
  3643. pb.ctx = ctx;
  3644. pctx->ino = ino;
  3645. pctx->errcode = 0;
  3646. if (inode->i_flags & EXT2_COMPRBLK_FL) {
  3647. if (fs->super->s_feature_incompat &
  3648. EXT2_FEATURE_INCOMPAT_COMPRESSION)
  3649. pb.compressed = 1;
  3650. else {
  3651. if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
  3652. inode->i_flags &= ~EXT2_COMPRBLK_FL;
  3653. dirty_inode++;
  3654. }
  3655. }
  3656. }
  3657. if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
  3658. pb.num_blocks++;
  3659. if (ext2fs_inode_has_valid_blocks(inode))
  3660. pctx->errcode = ext2fs_block_iterate2(fs, ino,
  3661. pb.is_dir ? BLOCK_FLAG_HOLE : 0,
  3662. block_buf, process_block, &pb);
  3663. end_problem_latch(ctx, PR_LATCH_BLOCK);
  3664. end_problem_latch(ctx, PR_LATCH_TOOBIG);
  3665. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  3666. goto out;
  3667. if (pctx->errcode)
  3668. fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
  3669. if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
  3670. ctx->fs_fragmented++;
  3671. if (pb.clear) {
  3672. inode->i_links_count = 0;
  3673. ext2fs_icount_store(ctx->inode_link_info, ino, 0);
  3674. inode->i_dtime = time(0);
  3675. dirty_inode++;
  3676. ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
  3677. ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
  3678. ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
  3679. /*
  3680. * The inode was probably partially accounted for
  3681. * before processing was aborted, so we need to
  3682. * restart the pass 1 scan.
  3683. */
  3684. ctx->flags |= E2F_FLAG_RESTART;
  3685. goto out;
  3686. }
  3687. if (inode->i_flags & EXT2_INDEX_FL) {
  3688. if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
  3689. inode->i_flags &= ~EXT2_INDEX_FL;
  3690. dirty_inode++;
  3691. } else {
  3692. #ifdef ENABLE_HTREE
  3693. e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
  3694. #endif
  3695. }
  3696. }
  3697. if (ctx->dirs_to_hash && pb.is_dir &&
  3698. !(inode->i_flags & EXT2_INDEX_FL) &&
  3699. ((inode->i_size / fs->blocksize) >= 3))
  3700. ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
  3701. if (!pb.num_blocks && pb.is_dir) {
  3702. if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
  3703. inode->i_links_count = 0;
  3704. ext2fs_icount_store(ctx->inode_link_info, ino, 0);
  3705. inode->i_dtime = time(0);
  3706. dirty_inode++;
  3707. ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
  3708. ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
  3709. ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
  3710. ctx->fs_directory_count--;
  3711. goto out;
  3712. }
  3713. }
  3714. pb.num_blocks *= (fs->blocksize / 512);
  3715. if (pb.is_dir) {
  3716. int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
  3717. if (nblock > (pb.last_block + 1))
  3718. bad_size = 1;
  3719. else if (nblock < (pb.last_block + 1)) {
  3720. if (((pb.last_block + 1) - nblock) >
  3721. fs->super->s_prealloc_dir_blocks)
  3722. bad_size = 2;
  3723. }
  3724. } else {
  3725. size = EXT2_I_SIZE(inode);
  3726. if ((pb.last_block >= 0) &&
  3727. (size < (__u64) pb.last_block * fs->blocksize))
  3728. bad_size = 3;
  3729. else if (size > ext2_max_sizes[fs->super->s_log_block_size])
  3730. bad_size = 4;
  3731. }
  3732. /* i_size for symlinks is checked elsewhere */
  3733. if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
  3734. pctx->num = (pb.last_block+1) * fs->blocksize;
  3735. if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
  3736. inode->i_size = pctx->num;
  3737. if (!LINUX_S_ISDIR(inode->i_mode))
  3738. inode->i_size_high = pctx->num >> 32;
  3739. dirty_inode++;
  3740. }
  3741. pctx->num = 0;
  3742. }
  3743. if (LINUX_S_ISREG(inode->i_mode) &&
  3744. (inode->i_size_high || inode->i_size & 0x80000000UL))
  3745. ctx->large_files++;
  3746. if (pb.num_blocks != inode->i_blocks) {
  3747. pctx->num = pb.num_blocks;
  3748. if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
  3749. inode->i_blocks = pb.num_blocks;
  3750. dirty_inode++;
  3751. }
  3752. pctx->num = 0;
  3753. }
  3754. out:
  3755. if (dirty_inode)
  3756. e2fsck_write_inode(ctx, ino, inode, "check_blocks");
  3757. }
  3758. /*
  3759. * This is a helper function for check_blocks().
  3760. */
  3761. static int process_block(ext2_filsys fs,
  3762. blk_t *block_nr,
  3763. e2_blkcnt_t blockcnt,
  3764. blk_t ref_block FSCK_ATTR((unused)),
  3765. int ref_offset FSCK_ATTR((unused)),
  3766. void *priv_data)
  3767. {
  3768. struct process_block_struct_1 *p;
  3769. struct problem_context *pctx;
  3770. blk_t blk = *block_nr;
  3771. int ret_code = 0;
  3772. int problem = 0;
  3773. e2fsck_t ctx;
  3774. p = (struct process_block_struct_1 *) priv_data;
  3775. pctx = p->pctx;
  3776. ctx = p->ctx;
  3777. if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
  3778. /* todo: Check that the comprblk_fl is high, that the
  3779. blkaddr pattern looks right (all non-holes up to
  3780. first EXT2FS_COMPRESSED_BLKADDR, then all
  3781. EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
  3782. that the feature_incompat bit is high, and that the
  3783. inode is a regular file. If we're doing a "full
  3784. check" (a concept introduced to e2fsck by e2compr,
  3785. meaning that we look at data blocks as well as
  3786. metadata) then call some library routine that
  3787. checks the compressed data. I'll have to think
  3788. about this, because one particularly important
  3789. problem to be able to fix is to recalculate the
  3790. cluster size if necessary. I think that perhaps
  3791. we'd better do most/all e2compr-specific checks
  3792. separately, after the non-e2compr checks. If not
  3793. doing a full check, it may be useful to test that
  3794. the personality is linux; e.g. if it isn't then
  3795. perhaps this really is just an illegal block. */
  3796. return 0;
  3797. }
  3798. if (blk == 0) {
  3799. if (p->is_dir == 0) {
  3800. /*
  3801. * Should never happen, since only directories
  3802. * get called with BLOCK_FLAG_HOLE
  3803. */
  3804. #ifdef DEBUG_E2FSCK
  3805. printf("process_block() called with blk == 0, "
  3806. "blockcnt=%d, inode %lu???\n",
  3807. blockcnt, p->ino);
  3808. #endif
  3809. return 0;
  3810. }
  3811. if (blockcnt < 0)
  3812. return 0;
  3813. if (blockcnt * fs->blocksize < p->inode->i_size) {
  3814. goto mark_dir;
  3815. }
  3816. return 0;
  3817. }
  3818. /*
  3819. * Simplistic fragmentation check. We merely require that the
  3820. * file be contiguous. (Which can never be true for really
  3821. * big files that are greater than a block group.)
  3822. */
  3823. if (!HOLE_BLKADDR(p->previous_block)) {
  3824. if (p->previous_block+1 != blk)
  3825. p->fragmented = 1;
  3826. }
  3827. p->previous_block = blk;
  3828. if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
  3829. problem = PR_1_TOOBIG_DIR;
  3830. if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
  3831. problem = PR_1_TOOBIG_REG;
  3832. if (!p->is_dir && !p->is_reg && blockcnt > 0)
  3833. problem = PR_1_TOOBIG_SYMLINK;
  3834. if (blk < fs->super->s_first_data_block ||
  3835. blk >= fs->super->s_blocks_count)
  3836. problem = PR_1_ILLEGAL_BLOCK_NUM;
  3837. if (problem) {
  3838. p->num_illegal_blocks++;
  3839. if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
  3840. if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
  3841. p->clear = 1;
  3842. return BLOCK_ABORT;
  3843. }
  3844. if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
  3845. p->suppress = 1;
  3846. set_latch_flags(PR_LATCH_BLOCK,
  3847. PRL_SUPPRESS, 0);
  3848. }
  3849. }
  3850. pctx->blk = blk;
  3851. pctx->blkcount = blockcnt;
  3852. if (fix_problem(ctx, problem, pctx)) {
  3853. blk = *block_nr = 0;
  3854. ret_code = BLOCK_CHANGED;
  3855. goto mark_dir;
  3856. } else
  3857. return 0;
  3858. }
  3859. if (p->ino == EXT2_RESIZE_INO) {
  3860. /*
  3861. * The resize inode has already be sanity checked
  3862. * during pass #0 (the superblock checks). All we
  3863. * have to do is mark the double indirect block as
  3864. * being in use; all of the other blocks are handled
  3865. * by mark_table_blocks()).
  3866. */
  3867. if (blockcnt == BLOCK_COUNT_DIND)
  3868. mark_block_used(ctx, blk);
  3869. } else
  3870. mark_block_used(ctx, blk);
  3871. p->num_blocks++;
  3872. if (blockcnt >= 0)
  3873. p->last_block = blockcnt;
  3874. mark_dir:
  3875. if (p->is_dir && (blockcnt >= 0)) {
  3876. pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
  3877. blk, blockcnt);
  3878. if (pctx->errcode) {
  3879. pctx->blk = blk;
  3880. pctx->num = blockcnt;
  3881. fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
  3882. /* Should never get here */
  3883. ctx->flags |= E2F_FLAG_ABORT;
  3884. return BLOCK_ABORT;
  3885. }
  3886. }
  3887. return ret_code;
  3888. }
  3889. static int process_bad_block(ext2_filsys fs FSCK_ATTR((unused)),
  3890. blk_t *block_nr,
  3891. e2_blkcnt_t blockcnt,
  3892. blk_t ref_block FSCK_ATTR((unused)),
  3893. int ref_offset FSCK_ATTR((unused)),
  3894. void *priv_data EXT2FS_ATTR((unused)))
  3895. {
  3896. /*
  3897. * Note: This function processes blocks for the bad blocks
  3898. * inode, which is never compressed. So we don't use HOLE_BLKADDR().
  3899. */
  3900. printf("Unrecoverable Error: Found %"PRIi64" bad blocks starting at block number: %u\n", blockcnt, *block_nr);
  3901. return BLOCK_ERROR;
  3902. }
  3903. /*
  3904. * This routine gets called at the end of pass 1 if bad blocks are
  3905. * detected in the superblock, group descriptors, inode_bitmaps, or
  3906. * block bitmaps. At this point, all of the blocks have been mapped
  3907. * out, so we can try to allocate new block(s) to replace the bad
  3908. * blocks.
  3909. */
  3910. static void handle_fs_bad_blocks(e2fsck_t ctx)
  3911. {
  3912. printf("Bad blocks detected on your filesystem\n"
  3913. "You should get your data off as the device will soon die\n");
  3914. }
  3915. /*
  3916. * This routine marks all blocks which are used by the superblock,
  3917. * group descriptors, inode bitmaps, and block bitmaps.
  3918. */
  3919. static void mark_table_blocks(e2fsck_t ctx)
  3920. {
  3921. ext2_filsys fs = ctx->fs;
  3922. blk_t block, b;
  3923. dgrp_t i;
  3924. int j;
  3925. struct problem_context pctx;
  3926. clear_problem_context(&pctx);
  3927. block = fs->super->s_first_data_block;
  3928. for (i = 0; i < fs->group_desc_count; i++) {
  3929. pctx.group = i;
  3930. ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
  3931. /*
  3932. * Mark the blocks used for the inode table
  3933. */
  3934. if (fs->group_desc[i].bg_inode_table) {
  3935. for (j = 0, b = fs->group_desc[i].bg_inode_table;
  3936. j < fs->inode_blocks_per_group;
  3937. j++, b++) {
  3938. if (ext2fs_test_block_bitmap(ctx->block_found_map,
  3939. b)) {
  3940. pctx.blk = b;
  3941. if (fix_problem(ctx,
  3942. PR_1_ITABLE_CONFLICT, &pctx)) {
  3943. ctx->invalid_inode_table_flag[i]++;
  3944. ctx->invalid_bitmaps++;
  3945. }
  3946. } else {
  3947. ext2fs_mark_block_bitmap(ctx->block_found_map,
  3948. b);
  3949. }
  3950. }
  3951. }
  3952. /*
  3953. * Mark block used for the block bitmap
  3954. */
  3955. if (fs->group_desc[i].bg_block_bitmap) {
  3956. if (ext2fs_test_block_bitmap(ctx->block_found_map,
  3957. fs->group_desc[i].bg_block_bitmap)) {
  3958. pctx.blk = fs->group_desc[i].bg_block_bitmap;
  3959. if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
  3960. ctx->invalid_block_bitmap_flag[i]++;
  3961. ctx->invalid_bitmaps++;
  3962. }
  3963. } else {
  3964. ext2fs_mark_block_bitmap(ctx->block_found_map,
  3965. fs->group_desc[i].bg_block_bitmap);
  3966. }
  3967. }
  3968. /*
  3969. * Mark block used for the inode bitmap
  3970. */
  3971. if (fs->group_desc[i].bg_inode_bitmap) {
  3972. if (ext2fs_test_block_bitmap(ctx->block_found_map,
  3973. fs->group_desc[i].bg_inode_bitmap)) {
  3974. pctx.blk = fs->group_desc[i].bg_inode_bitmap;
  3975. if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
  3976. ctx->invalid_inode_bitmap_flag[i]++;
  3977. ctx->invalid_bitmaps++;
  3978. }
  3979. } else {
  3980. ext2fs_mark_block_bitmap(ctx->block_found_map,
  3981. fs->group_desc[i].bg_inode_bitmap);
  3982. }
  3983. }
  3984. block += fs->super->s_blocks_per_group;
  3985. }
  3986. }
  3987. /*
  3988. * Thes subroutines short circuits ext2fs_get_blocks and
  3989. * ext2fs_check_directory; we use them since we already have the inode
  3990. * structure, so there's no point in letting the ext2fs library read
  3991. * the inode again.
  3992. */
  3993. static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
  3994. blk_t *blocks)
  3995. {
  3996. e2fsck_t ctx = (e2fsck_t) fs->priv_data;
  3997. int i;
  3998. if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
  3999. return EXT2_ET_CALLBACK_NOTHANDLED;
  4000. for (i=0; i < EXT2_N_BLOCKS; i++)
  4001. blocks[i] = ctx->stashed_inode->i_block[i];
  4002. return 0;
  4003. }
  4004. static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
  4005. struct ext2_inode *inode)
  4006. {
  4007. e2fsck_t ctx = (e2fsck_t) fs->priv_data;
  4008. if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
  4009. return EXT2_ET_CALLBACK_NOTHANDLED;
  4010. *inode = *ctx->stashed_inode;
  4011. return 0;
  4012. }
  4013. static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
  4014. struct ext2_inode *inode)
  4015. {
  4016. e2fsck_t ctx = (e2fsck_t) fs->priv_data;
  4017. if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
  4018. *ctx->stashed_inode = *inode;
  4019. return EXT2_ET_CALLBACK_NOTHANDLED;
  4020. }
  4021. static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
  4022. {
  4023. e2fsck_t ctx = (e2fsck_t) fs->priv_data;
  4024. if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
  4025. return EXT2_ET_CALLBACK_NOTHANDLED;
  4026. if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
  4027. return EXT2_ET_NO_DIRECTORY;
  4028. return 0;
  4029. }
  4030. void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
  4031. {
  4032. ext2_filsys fs = ctx->fs;
  4033. if (bool) {
  4034. fs->get_blocks = pass1_get_blocks;
  4035. fs->check_directory = pass1_check_directory;
  4036. fs->read_inode = pass1_read_inode;
  4037. fs->write_inode = pass1_write_inode;
  4038. ctx->stashed_ino = 0;
  4039. } else {
  4040. fs->get_blocks = 0;
  4041. fs->check_directory = 0;
  4042. fs->read_inode = 0;
  4043. fs->write_inode = 0;
  4044. }
  4045. }
  4046. /*
  4047. * pass1b.c --- Pass #1b of e2fsck
  4048. *
  4049. * This file contains pass1B, pass1C, and pass1D of e2fsck. They are
  4050. * only invoked if pass 1 discovered blocks which are in use by more
  4051. * than one inode.
  4052. *
  4053. * Pass1B scans the data blocks of all the inodes again, generating a
  4054. * complete list of duplicate blocks and which inodes have claimed
  4055. * them.
  4056. *
  4057. * Pass1C does a tree-traversal of the filesystem, to determine the
  4058. * parent directories of these inodes. This step is necessary so that
  4059. * e2fsck can print out the pathnames of affected inodes.
  4060. *
  4061. * Pass1D is a reconciliation pass. For each inode with duplicate
  4062. * blocks, the user is prompted if s/he would like to clone the file
  4063. * (so that the file gets a fresh copy of the duplicated blocks) or
  4064. * simply to delete the file.
  4065. *
  4066. */
  4067. /* Needed for architectures where sizeof(int) != sizeof(void *) */
  4068. #define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val))
  4069. #define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr))
  4070. /* Define an extension to the ext2 library's block count information */
  4071. #define BLOCK_COUNT_EXTATTR (-5)
  4072. struct block_el {
  4073. blk_t block;
  4074. struct block_el *next;
  4075. };
  4076. struct inode_el {
  4077. ext2_ino_t inode;
  4078. struct inode_el *next;
  4079. };
  4080. struct dup_block {
  4081. int num_bad;
  4082. struct inode_el *inode_list;
  4083. };
  4084. /*
  4085. * This structure stores information about a particular inode which
  4086. * is sharing blocks with other inodes. This information is collected
  4087. * to display to the user, so that the user knows what files he or she
  4088. * is dealing with, when trying to decide how to resolve the conflict
  4089. * of multiply-claimed blocks.
  4090. */
  4091. struct dup_inode {
  4092. ext2_ino_t dir;
  4093. int num_dupblocks;
  4094. struct ext2_inode inode;
  4095. struct block_el *block_list;
  4096. };
  4097. static int process_pass1b_block(ext2_filsys fs, blk_t *blocknr,
  4098. e2_blkcnt_t blockcnt, blk_t ref_blk,
  4099. int ref_offset, void *priv_data);
  4100. static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
  4101. struct dup_inode *dp, char *block_buf);
  4102. static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
  4103. struct dup_inode *dp, char* block_buf);
  4104. static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
  4105. static void pass1b(e2fsck_t ctx, char *block_buf);
  4106. static void pass1c(e2fsck_t ctx, char *block_buf);
  4107. static void pass1d(e2fsck_t ctx, char *block_buf);
  4108. static int dup_inode_count = 0;
  4109. static dict_t blk_dict, ino_dict;
  4110. static ext2fs_inode_bitmap inode_dup_map;
  4111. static int dict_int_cmp(const void *a, const void *b)
  4112. {
  4113. intptr_t ia, ib;
  4114. ia = (intptr_t)a;
  4115. ib = (intptr_t)b;
  4116. return (ia-ib);
  4117. }
  4118. /*
  4119. * Add a duplicate block record
  4120. */
  4121. static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
  4122. struct ext2_inode *inode)
  4123. {
  4124. dnode_t *n;
  4125. struct dup_block *db;
  4126. struct dup_inode *di;
  4127. struct block_el *blk_el;
  4128. struct inode_el *ino_el;
  4129. n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
  4130. if (n)
  4131. db = (struct dup_block *) dnode_get(n);
  4132. else {
  4133. db = (struct dup_block *) e2fsck_allocate_memory(ctx,
  4134. sizeof(struct dup_block), "duplicate block header");
  4135. db->num_bad = 0;
  4136. db->inode_list = 0;
  4137. dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
  4138. }
  4139. ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
  4140. sizeof(struct inode_el), "inode element");
  4141. ino_el->inode = ino;
  4142. ino_el->next = db->inode_list;
  4143. db->inode_list = ino_el;
  4144. db->num_bad++;
  4145. n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
  4146. if (n)
  4147. di = (struct dup_inode *) dnode_get(n);
  4148. else {
  4149. di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
  4150. sizeof(struct dup_inode), "duplicate inode header");
  4151. di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0 ;
  4152. di->num_dupblocks = 0;
  4153. di->block_list = 0;
  4154. di->inode = *inode;
  4155. dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
  4156. }
  4157. blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
  4158. sizeof(struct block_el), "block element");
  4159. blk_el->block = blk;
  4160. blk_el->next = di->block_list;
  4161. di->block_list = blk_el;
  4162. di->num_dupblocks++;
  4163. }
  4164. /*
  4165. * Free a duplicate inode record
  4166. */
  4167. static void inode_dnode_free(dnode_t *node)
  4168. {
  4169. struct dup_inode *di;
  4170. struct block_el *p, *next;
  4171. di = (struct dup_inode *) dnode_get(node);
  4172. for (p = di->block_list; p; p = next) {
  4173. next = p->next;
  4174. free(p);
  4175. }
  4176. free(node);
  4177. }
  4178. /*
  4179. * Free a duplicate block record
  4180. */
  4181. static void block_dnode_free(dnode_t *node)
  4182. {
  4183. struct dup_block *db;
  4184. struct inode_el *p, *next;
  4185. db = (struct dup_block *) dnode_get(node);
  4186. for (p = db->inode_list; p; p = next) {
  4187. next = p->next;
  4188. free(p);
  4189. }
  4190. free(node);
  4191. }
  4192. /*
  4193. * Main procedure for handling duplicate blocks
  4194. */
  4195. void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
  4196. {
  4197. ext2_filsys fs = ctx->fs;
  4198. struct problem_context pctx;
  4199. clear_problem_context(&pctx);
  4200. pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
  4201. _("multiply claimed inode map"), &inode_dup_map);
  4202. if (pctx.errcode) {
  4203. fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
  4204. ctx->flags |= E2F_FLAG_ABORT;
  4205. return;
  4206. }
  4207. dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
  4208. dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
  4209. dict_set_allocator(&ino_dict, inode_dnode_free);
  4210. dict_set_allocator(&blk_dict, block_dnode_free);
  4211. pass1b(ctx, block_buf);
  4212. pass1c(ctx, block_buf);
  4213. pass1d(ctx, block_buf);
  4214. /*
  4215. * Time to free all of the accumulated data structures that we
  4216. * don't need anymore.
  4217. */
  4218. dict_free_nodes(&ino_dict);
  4219. dict_free_nodes(&blk_dict);
  4220. }
  4221. /*
  4222. * Scan the inodes looking for inodes that contain duplicate blocks.
  4223. */
  4224. struct process_block_struct_1b {
  4225. e2fsck_t ctx;
  4226. ext2_ino_t ino;
  4227. int dup_blocks;
  4228. struct ext2_inode *inode;
  4229. struct problem_context *pctx;
  4230. };
  4231. static void pass1b(e2fsck_t ctx, char *block_buf)
  4232. {
  4233. ext2_filsys fs = ctx->fs;
  4234. ext2_ino_t ino;
  4235. struct ext2_inode inode;
  4236. ext2_inode_scan scan;
  4237. struct process_block_struct_1b pb;
  4238. struct problem_context pctx;
  4239. clear_problem_context(&pctx);
  4240. if (!(ctx->options & E2F_OPT_PREEN))
  4241. fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
  4242. pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
  4243. &scan);
  4244. if (pctx.errcode) {
  4245. fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
  4246. ctx->flags |= E2F_FLAG_ABORT;
  4247. return;
  4248. }
  4249. ctx->stashed_inode = &inode;
  4250. pb.ctx = ctx;
  4251. pb.pctx = &pctx;
  4252. pctx.str = "pass1b";
  4253. while (1) {
  4254. pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
  4255. if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
  4256. continue;
  4257. if (pctx.errcode) {
  4258. fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
  4259. ctx->flags |= E2F_FLAG_ABORT;
  4260. return;
  4261. }
  4262. if (!ino)
  4263. break;
  4264. pctx.ino = ctx->stashed_ino = ino;
  4265. if ((ino != EXT2_BAD_INO) &&
  4266. !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
  4267. continue;
  4268. pb.ino = ino;
  4269. pb.dup_blocks = 0;
  4270. pb.inode = &inode;
  4271. if (ext2fs_inode_has_valid_blocks(&inode) ||
  4272. (ino == EXT2_BAD_INO))
  4273. pctx.errcode = ext2fs_block_iterate2(fs, ino,
  4274. 0, block_buf, process_pass1b_block, &pb);
  4275. if (inode.i_file_acl)
  4276. process_pass1b_block(fs, &inode.i_file_acl,
  4277. BLOCK_COUNT_EXTATTR, 0, 0, &pb);
  4278. if (pb.dup_blocks) {
  4279. end_problem_latch(ctx, PR_LATCH_DBLOCK);
  4280. if (ino >= EXT2_FIRST_INODE(fs->super) ||
  4281. ino == EXT2_ROOT_INO)
  4282. dup_inode_count++;
  4283. }
  4284. if (pctx.errcode)
  4285. fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
  4286. }
  4287. ext2fs_close_inode_scan(scan);
  4288. e2fsck_use_inode_shortcuts(ctx, 0);
  4289. }
  4290. static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)),
  4291. blk_t *block_nr,
  4292. e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
  4293. blk_t ref_blk FSCK_ATTR((unused)),
  4294. int ref_offset FSCK_ATTR((unused)),
  4295. void *priv_data)
  4296. {
  4297. struct process_block_struct_1b *p;
  4298. e2fsck_t ctx;
  4299. if (HOLE_BLKADDR(*block_nr))
  4300. return 0;
  4301. p = (struct process_block_struct_1b *) priv_data;
  4302. ctx = p->ctx;
  4303. if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
  4304. return 0;
  4305. /* OK, this is a duplicate block */
  4306. if (p->ino != EXT2_BAD_INO) {
  4307. p->pctx->blk = *block_nr;
  4308. fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
  4309. }
  4310. p->dup_blocks++;
  4311. ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
  4312. add_dupe(ctx, p->ino, *block_nr, p->inode);
  4313. return 0;
  4314. }
  4315. /*
  4316. * Pass 1c: Scan directories for inodes with duplicate blocks. This
  4317. * is used so that we can print pathnames when prompting the user for
  4318. * what to do.
  4319. */
  4320. struct search_dir_struct {
  4321. int count;
  4322. ext2_ino_t first_inode;
  4323. ext2_ino_t max_inode;
  4324. };
  4325. static int search_dirent_proc(ext2_ino_t dir, int entry,
  4326. struct ext2_dir_entry *dirent,
  4327. int offset FSCK_ATTR((unused)),
  4328. int blocksize FSCK_ATTR((unused)),
  4329. char *buf FSCK_ATTR((unused)),
  4330. void *priv_data)
  4331. {
  4332. struct search_dir_struct *sd;
  4333. struct dup_inode *p;
  4334. dnode_t *n;
  4335. sd = (struct search_dir_struct *) priv_data;
  4336. if (dirent->inode > sd->max_inode)
  4337. /* Should abort this inode, but not everything */
  4338. return 0;
  4339. if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
  4340. !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
  4341. return 0;
  4342. n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
  4343. if (!n)
  4344. return 0;
  4345. p = (struct dup_inode *) dnode_get(n);
  4346. p->dir = dir;
  4347. sd->count--;
  4348. return sd->count ? 0 : DIRENT_ABORT;
  4349. }
  4350. static void pass1c(e2fsck_t ctx, char *block_buf)
  4351. {
  4352. ext2_filsys fs = ctx->fs;
  4353. struct search_dir_struct sd;
  4354. struct problem_context pctx;
  4355. clear_problem_context(&pctx);
  4356. if (!(ctx->options & E2F_OPT_PREEN))
  4357. fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
  4358. /*
  4359. * Search through all directories to translate inodes to names
  4360. * (by searching for the containing directory for that inode.)
  4361. */
  4362. sd.count = dup_inode_count;
  4363. sd.first_inode = EXT2_FIRST_INODE(fs->super);
  4364. sd.max_inode = fs->super->s_inodes_count;
  4365. ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
  4366. search_dirent_proc, &sd);
  4367. }
  4368. static void pass1d(e2fsck_t ctx, char *block_buf)
  4369. {
  4370. ext2_filsys fs = ctx->fs;
  4371. struct dup_inode *p, *t;
  4372. struct dup_block *q;
  4373. ext2_ino_t *shared, ino;
  4374. int shared_len;
  4375. int i;
  4376. int file_ok;
  4377. int meta_data = 0;
  4378. struct problem_context pctx;
  4379. dnode_t *n, *m;
  4380. struct block_el *s;
  4381. struct inode_el *r;
  4382. clear_problem_context(&pctx);
  4383. if (!(ctx->options & E2F_OPT_PREEN))
  4384. fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
  4385. e2fsck_read_bitmaps(ctx);
  4386. pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
  4387. fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
  4388. shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
  4389. sizeof(ext2_ino_t) * dict_count(&ino_dict),
  4390. "Shared inode list");
  4391. for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
  4392. p = (struct dup_inode *) dnode_get(n);
  4393. shared_len = 0;
  4394. file_ok = 1;
  4395. ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
  4396. if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO)
  4397. continue;
  4398. /*
  4399. * Find all of the inodes which share blocks with this
  4400. * one. First we find all of the duplicate blocks
  4401. * belonging to this inode, and then search each block
  4402. * get the list of inodes, and merge them together.
  4403. */
  4404. for (s = p->block_list; s; s = s->next) {
  4405. m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
  4406. if (!m)
  4407. continue; /* Should never happen... */
  4408. q = (struct dup_block *) dnode_get(m);
  4409. if (q->num_bad > 1)
  4410. file_ok = 0;
  4411. if (check_if_fs_block(ctx, s->block)) {
  4412. file_ok = 0;
  4413. meta_data = 1;
  4414. }
  4415. /*
  4416. * Add all inodes used by this block to the
  4417. * shared[] --- which is a unique list, so
  4418. * if an inode is already in shared[], don't
  4419. * add it again.
  4420. */
  4421. for (r = q->inode_list; r; r = r->next) {
  4422. if (r->inode == ino)
  4423. continue;
  4424. for (i = 0; i < shared_len; i++)
  4425. if (shared[i] == r->inode)
  4426. break;
  4427. if (i == shared_len) {
  4428. shared[shared_len++] = r->inode;
  4429. }
  4430. }
  4431. }
  4432. /*
  4433. * Report the inode that we are working on
  4434. */
  4435. pctx.inode = &p->inode;
  4436. pctx.ino = ino;
  4437. pctx.dir = p->dir;
  4438. pctx.blkcount = p->num_dupblocks;
  4439. pctx.num = meta_data ? shared_len+1 : shared_len;
  4440. fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
  4441. pctx.blkcount = 0;
  4442. pctx.num = 0;
  4443. if (meta_data)
  4444. fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
  4445. for (i = 0; i < shared_len; i++) {
  4446. m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
  4447. if (!m)
  4448. continue; /* should never happen */
  4449. t = (struct dup_inode *) dnode_get(m);
  4450. /*
  4451. * Report the inode that we are sharing with
  4452. */
  4453. pctx.inode = &t->inode;
  4454. pctx.ino = shared[i];
  4455. pctx.dir = t->dir;
  4456. fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
  4457. }
  4458. if (file_ok) {
  4459. fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
  4460. continue;
  4461. }
  4462. if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
  4463. pctx.errcode = clone_file(ctx, ino, p, block_buf);
  4464. if (pctx.errcode)
  4465. fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
  4466. else
  4467. continue;
  4468. }
  4469. if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
  4470. delete_file(ctx, ino, p, block_buf);
  4471. else
  4472. ext2fs_unmark_valid(fs);
  4473. }
  4474. ext2fs_free_mem(&shared);
  4475. }
  4476. /*
  4477. * Drop the refcount on the dup_block structure, and clear the entry
  4478. * in the block_dup_map if appropriate.
  4479. */
  4480. static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
  4481. {
  4482. p->num_bad--;
  4483. if (p->num_bad <= 0 ||
  4484. (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
  4485. ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
  4486. }
  4487. static int delete_file_block(ext2_filsys fs,
  4488. blk_t *block_nr,
  4489. e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
  4490. blk_t ref_block FSCK_ATTR((unused)),
  4491. int ref_offset FSCK_ATTR((unused)),
  4492. void *priv_data)
  4493. {
  4494. struct process_block_struct_1b *pb;
  4495. struct dup_block *p;
  4496. dnode_t *n;
  4497. e2fsck_t ctx;
  4498. pb = (struct process_block_struct_1b *) priv_data;
  4499. ctx = pb->ctx;
  4500. if (HOLE_BLKADDR(*block_nr))
  4501. return 0;
  4502. if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
  4503. n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
  4504. if (n) {
  4505. p = (struct dup_block *) dnode_get(n);
  4506. decrement_badcount(ctx, *block_nr, p);
  4507. } else
  4508. bb_error_msg(_("internal error; can't find dup_blk for %d"),
  4509. *block_nr);
  4510. } else {
  4511. ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
  4512. ext2fs_block_alloc_stats(fs, *block_nr, -1);
  4513. }
  4514. return 0;
  4515. }
  4516. static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
  4517. struct dup_inode *dp, char* block_buf)
  4518. {
  4519. ext2_filsys fs = ctx->fs;
  4520. struct process_block_struct_1b pb;
  4521. struct ext2_inode inode;
  4522. struct problem_context pctx;
  4523. unsigned int count;
  4524. clear_problem_context(&pctx);
  4525. pctx.ino = pb.ino = ino;
  4526. pb.dup_blocks = dp->num_dupblocks;
  4527. pb.ctx = ctx;
  4528. pctx.str = "delete_file";
  4529. e2fsck_read_inode(ctx, ino, &inode, "delete_file");
  4530. if (ext2fs_inode_has_valid_blocks(&inode))
  4531. pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
  4532. delete_file_block, &pb);
  4533. if (pctx.errcode)
  4534. fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
  4535. ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
  4536. ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
  4537. if (ctx->inode_bad_map)
  4538. ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
  4539. ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
  4540. /* Inode may have changed by block_iterate, so reread it */
  4541. e2fsck_read_inode(ctx, ino, &inode, "delete_file");
  4542. inode.i_links_count = 0;
  4543. inode.i_dtime = time(0);
  4544. if (inode.i_file_acl &&
  4545. (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
  4546. count = 1;
  4547. pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
  4548. block_buf, -1, &count);
  4549. if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
  4550. pctx.errcode = 0;
  4551. count = 1;
  4552. }
  4553. if (pctx.errcode) {
  4554. pctx.blk = inode.i_file_acl;
  4555. fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
  4556. }
  4557. /*
  4558. * If the count is zero, then arrange to have the
  4559. * block deleted. If the block is in the block_dup_map,
  4560. * also call delete_file_block since it will take care
  4561. * of keeping the accounting straight.
  4562. */
  4563. if ((count == 0) ||
  4564. ext2fs_test_block_bitmap(ctx->block_dup_map,
  4565. inode.i_file_acl))
  4566. delete_file_block(fs, &inode.i_file_acl,
  4567. BLOCK_COUNT_EXTATTR, 0, 0, &pb);
  4568. }
  4569. e2fsck_write_inode(ctx, ino, &inode, "delete_file");
  4570. }
  4571. struct clone_struct {
  4572. errcode_t errcode;
  4573. ext2_ino_t dir;
  4574. char *buf;
  4575. e2fsck_t ctx;
  4576. };
  4577. static int clone_file_block(ext2_filsys fs,
  4578. blk_t *block_nr,
  4579. e2_blkcnt_t blockcnt,
  4580. blk_t ref_block FSCK_ATTR((unused)),
  4581. int ref_offset FSCK_ATTR((unused)),
  4582. void *priv_data)
  4583. {
  4584. struct dup_block *p;
  4585. blk_t new_block;
  4586. errcode_t retval;
  4587. struct clone_struct *cs = (struct clone_struct *) priv_data;
  4588. dnode_t *n;
  4589. e2fsck_t ctx;
  4590. ctx = cs->ctx;
  4591. if (HOLE_BLKADDR(*block_nr))
  4592. return 0;
  4593. if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
  4594. n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
  4595. if (n) {
  4596. p = (struct dup_block *) dnode_get(n);
  4597. retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
  4598. &new_block);
  4599. if (retval) {
  4600. cs->errcode = retval;
  4601. return BLOCK_ABORT;
  4602. }
  4603. if (cs->dir && (blockcnt >= 0)) {
  4604. retval = ext2fs_set_dir_block(fs->dblist,
  4605. cs->dir, new_block, blockcnt);
  4606. if (retval) {
  4607. cs->errcode = retval;
  4608. return BLOCK_ABORT;
  4609. }
  4610. }
  4611. retval = io_channel_read_blk(fs->io, *block_nr, 1,
  4612. cs->buf);
  4613. if (retval) {
  4614. cs->errcode = retval;
  4615. return BLOCK_ABORT;
  4616. }
  4617. retval = io_channel_write_blk(fs->io, new_block, 1,
  4618. cs->buf);
  4619. if (retval) {
  4620. cs->errcode = retval;
  4621. return BLOCK_ABORT;
  4622. }
  4623. decrement_badcount(ctx, *block_nr, p);
  4624. *block_nr = new_block;
  4625. ext2fs_mark_block_bitmap(ctx->block_found_map,
  4626. new_block);
  4627. ext2fs_mark_block_bitmap(fs->block_map, new_block);
  4628. return BLOCK_CHANGED;
  4629. } else
  4630. bb_error_msg(_("internal error; can't find dup_blk for %d"),
  4631. *block_nr);
  4632. }
  4633. return 0;
  4634. }
  4635. static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
  4636. struct dup_inode *dp, char* block_buf)
  4637. {
  4638. ext2_filsys fs = ctx->fs;
  4639. errcode_t retval;
  4640. struct clone_struct cs;
  4641. struct problem_context pctx;
  4642. blk_t blk;
  4643. dnode_t *n;
  4644. struct inode_el *ino_el;
  4645. struct dup_block *db;
  4646. struct dup_inode *di;
  4647. clear_problem_context(&pctx);
  4648. cs.errcode = 0;
  4649. cs.dir = 0;
  4650. cs.ctx = ctx;
  4651. retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
  4652. if (retval)
  4653. return retval;
  4654. if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
  4655. cs.dir = ino;
  4656. pctx.ino = ino;
  4657. pctx.str = "clone_file";
  4658. if (ext2fs_inode_has_valid_blocks(&dp->inode))
  4659. pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
  4660. clone_file_block, &cs);
  4661. ext2fs_mark_bb_dirty(fs);
  4662. if (pctx.errcode) {
  4663. fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
  4664. retval = pctx.errcode;
  4665. goto errout;
  4666. }
  4667. if (cs.errcode) {
  4668. bb_error_msg(_("returned from clone_file_block"));
  4669. retval = cs.errcode;
  4670. goto errout;
  4671. }
  4672. /* The inode may have changed on disk, so we have to re-read it */
  4673. e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
  4674. blk = dp->inode.i_file_acl;
  4675. if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
  4676. BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
  4677. BLOCK_CHANGED)) {
  4678. e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
  4679. /*
  4680. * If we cloned the EA block, find all other inodes
  4681. * which refered to that EA block, and modify
  4682. * them to point to the new EA block.
  4683. */
  4684. n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
  4685. db = (struct dup_block *) dnode_get(n);
  4686. for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
  4687. if (ino_el->inode == ino)
  4688. continue;
  4689. n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
  4690. di = (struct dup_inode *) dnode_get(n);
  4691. if (di->inode.i_file_acl == blk) {
  4692. di->inode.i_file_acl = dp->inode.i_file_acl;
  4693. e2fsck_write_inode(ctx, ino_el->inode,
  4694. &di->inode, "clone file EA");
  4695. decrement_badcount(ctx, blk, db);
  4696. }
  4697. }
  4698. }
  4699. retval = 0;
  4700. errout:
  4701. ext2fs_free_mem(&cs.buf);
  4702. return retval;
  4703. }
  4704. /*
  4705. * This routine returns 1 if a block overlaps with one of the superblocks,
  4706. * group descriptors, inode bitmaps, or block bitmaps.
  4707. */
  4708. static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
  4709. {
  4710. ext2_filsys fs = ctx->fs;
  4711. blk_t block;
  4712. dgrp_t i;
  4713. block = fs->super->s_first_data_block;
  4714. for (i = 0; i < fs->group_desc_count; i++) {
  4715. /* Check superblocks/block group descriptros */
  4716. if (ext2fs_bg_has_super(fs, i)) {
  4717. if (test_block >= block &&
  4718. (test_block <= block + fs->desc_blocks))
  4719. return 1;
  4720. }
  4721. /* Check the inode table */
  4722. if ((fs->group_desc[i].bg_inode_table) &&
  4723. (test_block >= fs->group_desc[i].bg_inode_table) &&
  4724. (test_block < (fs->group_desc[i].bg_inode_table +
  4725. fs->inode_blocks_per_group)))
  4726. return 1;
  4727. /* Check the bitmap blocks */
  4728. if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
  4729. (test_block == fs->group_desc[i].bg_inode_bitmap))
  4730. return 1;
  4731. block += fs->super->s_blocks_per_group;
  4732. }
  4733. return 0;
  4734. }
  4735. /*
  4736. * pass2.c --- check directory structure
  4737. *
  4738. * Pass 2 of e2fsck iterates through all active directory inodes, and
  4739. * applies to following tests to each directory entry in the directory
  4740. * blocks in the inodes:
  4741. *
  4742. * - The length of the directory entry (rec_len) should be at
  4743. * least 8 bytes, and no more than the remaining space
  4744. * left in the directory block.
  4745. * - The length of the name in the directory entry (name_len)
  4746. * should be less than (rec_len - 8).
  4747. * - The inode number in the directory entry should be within
  4748. * legal bounds.
  4749. * - The inode number should refer to a in-use inode.
  4750. * - The first entry should be '.', and its inode should be
  4751. * the inode of the directory.
  4752. * - The second entry should be '..'.
  4753. *
  4754. * To minimize disk seek time, the directory blocks are processed in
  4755. * sorted order of block numbers.
  4756. *
  4757. * Pass 2 also collects the following information:
  4758. * - The inode numbers of the subdirectories for each directory.
  4759. *
  4760. * Pass 2 relies on the following information from previous passes:
  4761. * - The directory information collected in pass 1.
  4762. * - The inode_used_map bitmap
  4763. * - The inode_bad_map bitmap
  4764. * - The inode_dir_map bitmap
  4765. *
  4766. * Pass 2 frees the following data structures
  4767. * - The inode_bad_map bitmap
  4768. * - The inode_reg_map bitmap
  4769. */
  4770. /*
  4771. * Keeps track of how many times an inode is referenced.
  4772. */
  4773. static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
  4774. static int check_dir_block(ext2_filsys fs,
  4775. struct ext2_db_entry *dir_blocks_info,
  4776. void *priv_data);
  4777. static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info,
  4778. struct problem_context *pctx);
  4779. static int update_dir_block(ext2_filsys fs,
  4780. blk_t *block_nr,
  4781. e2_blkcnt_t blockcnt,
  4782. blk_t ref_block,
  4783. int ref_offset,
  4784. void *priv_data);
  4785. static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
  4786. static int htree_depth(struct dx_dir_info *dx_dir,
  4787. struct dx_dirblock_info *dx_db);
  4788. static int special_dir_block_cmp(const void *a, const void *b);
  4789. struct check_dir_struct {
  4790. char *buf;
  4791. struct problem_context pctx;
  4792. int count, max;
  4793. e2fsck_t ctx;
  4794. };
  4795. static void e2fsck_pass2(e2fsck_t ctx)
  4796. {
  4797. struct ext2_super_block *sb = ctx->fs->super;
  4798. struct problem_context pctx;
  4799. ext2_filsys fs = ctx->fs;
  4800. char *buf;
  4801. struct dir_info *dir;
  4802. struct check_dir_struct cd;
  4803. struct dx_dir_info *dx_dir;
  4804. struct dx_dirblock_info *dx_db, *dx_parent;
  4805. int b;
  4806. int i, depth;
  4807. problem_t code;
  4808. int bad_dir;
  4809. clear_problem_context(&cd.pctx);
  4810. /* Pass 2 */
  4811. if (!(ctx->options & E2F_OPT_PREEN))
  4812. fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
  4813. cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
  4814. 0, ctx->inode_link_info,
  4815. &ctx->inode_count);
  4816. if (cd.pctx.errcode) {
  4817. fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
  4818. ctx->flags |= E2F_FLAG_ABORT;
  4819. return;
  4820. }
  4821. buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
  4822. "directory scan buffer");
  4823. /*
  4824. * Set up the parent pointer for the root directory, if
  4825. * present. (If the root directory is not present, we will
  4826. * create it in pass 3.)
  4827. */
  4828. dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
  4829. if (dir)
  4830. dir->parent = EXT2_ROOT_INO;
  4831. cd.buf = buf;
  4832. cd.ctx = ctx;
  4833. cd.count = 1;
  4834. cd.max = ext2fs_dblist_count(fs->dblist);
  4835. if (ctx->progress)
  4836. (void) (ctx->progress)(ctx, 2, 0, cd.max);
  4837. if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
  4838. ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
  4839. cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
  4840. &cd);
  4841. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  4842. return;
  4843. if (cd.pctx.errcode) {
  4844. fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
  4845. ctx->flags |= E2F_FLAG_ABORT;
  4846. return;
  4847. }
  4848. #ifdef ENABLE_HTREE
  4849. for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
  4850. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  4851. return;
  4852. if (dx_dir->numblocks == 0)
  4853. continue;
  4854. clear_problem_context(&pctx);
  4855. bad_dir = 0;
  4856. pctx.dir = dx_dir->ino;
  4857. dx_db = dx_dir->dx_block;
  4858. if (dx_db->flags & DX_FLAG_REFERENCED)
  4859. dx_db->flags |= DX_FLAG_DUP_REF;
  4860. else
  4861. dx_db->flags |= DX_FLAG_REFERENCED;
  4862. /*
  4863. * Find all of the first and last leaf blocks, and
  4864. * update their parent's min and max hash values
  4865. */
  4866. for (b=0, dx_db = dx_dir->dx_block;
  4867. b < dx_dir->numblocks;
  4868. b++, dx_db++) {
  4869. if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
  4870. !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
  4871. continue;
  4872. dx_parent = &dx_dir->dx_block[dx_db->parent];
  4873. /*
  4874. * XXX Make sure dx_parent->min_hash > dx_db->min_hash
  4875. */
  4876. if (dx_db->flags & DX_FLAG_FIRST)
  4877. dx_parent->min_hash = dx_db->min_hash;
  4878. /*
  4879. * XXX Make sure dx_parent->max_hash < dx_db->max_hash
  4880. */
  4881. if (dx_db->flags & DX_FLAG_LAST)
  4882. dx_parent->max_hash = dx_db->max_hash;
  4883. }
  4884. for (b=0, dx_db = dx_dir->dx_block;
  4885. b < dx_dir->numblocks;
  4886. b++, dx_db++) {
  4887. pctx.blkcount = b;
  4888. pctx.group = dx_db->parent;
  4889. code = 0;
  4890. if (!(dx_db->flags & DX_FLAG_FIRST) &&
  4891. (dx_db->min_hash < dx_db->node_min_hash)) {
  4892. pctx.blk = dx_db->min_hash;
  4893. pctx.blk2 = dx_db->node_min_hash;
  4894. code = PR_2_HTREE_MIN_HASH;
  4895. fix_problem(ctx, code, &pctx);
  4896. bad_dir++;
  4897. }
  4898. if (dx_db->type == DX_DIRBLOCK_LEAF) {
  4899. depth = htree_depth(dx_dir, dx_db);
  4900. if (depth != dx_dir->depth) {
  4901. code = PR_2_HTREE_BAD_DEPTH;
  4902. fix_problem(ctx, code, &pctx);
  4903. bad_dir++;
  4904. }
  4905. }
  4906. /*
  4907. * This test doesn't apply for the root block
  4908. * at block #0
  4909. */
  4910. if (b &&
  4911. (dx_db->max_hash > dx_db->node_max_hash)) {
  4912. pctx.blk = dx_db->max_hash;
  4913. pctx.blk2 = dx_db->node_max_hash;
  4914. code = PR_2_HTREE_MAX_HASH;
  4915. fix_problem(ctx, code, &pctx);
  4916. bad_dir++;
  4917. }
  4918. if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
  4919. code = PR_2_HTREE_NOTREF;
  4920. fix_problem(ctx, code, &pctx);
  4921. bad_dir++;
  4922. } else if (dx_db->flags & DX_FLAG_DUP_REF) {
  4923. code = PR_2_HTREE_DUPREF;
  4924. fix_problem(ctx, code, &pctx);
  4925. bad_dir++;
  4926. }
  4927. if (code == 0)
  4928. continue;
  4929. }
  4930. if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
  4931. clear_htree(ctx, dx_dir->ino);
  4932. dx_dir->numblocks = 0;
  4933. }
  4934. }
  4935. #endif
  4936. ext2fs_free_mem(&buf);
  4937. ext2fs_free_dblist(fs->dblist);
  4938. ext2fs_free_inode_bitmap(ctx->inode_bad_map);
  4939. ctx->inode_bad_map = 0;
  4940. ext2fs_free_inode_bitmap(ctx->inode_reg_map);
  4941. ctx->inode_reg_map = 0;
  4942. clear_problem_context(&pctx);
  4943. if (ctx->large_files) {
  4944. if (!(sb->s_feature_ro_compat &
  4945. EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
  4946. fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
  4947. sb->s_feature_ro_compat |=
  4948. EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
  4949. ext2fs_mark_super_dirty(fs);
  4950. }
  4951. if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
  4952. fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
  4953. ext2fs_update_dynamic_rev(fs);
  4954. ext2fs_mark_super_dirty(fs);
  4955. }
  4956. } else if (!ctx->large_files &&
  4957. (sb->s_feature_ro_compat &
  4958. EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
  4959. if (fs->flags & EXT2_FLAG_RW) {
  4960. sb->s_feature_ro_compat &=
  4961. ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
  4962. ext2fs_mark_super_dirty(fs);
  4963. }
  4964. }
  4965. }
  4966. #define MAX_DEPTH 32000
  4967. static int htree_depth(struct dx_dir_info *dx_dir,
  4968. struct dx_dirblock_info *dx_db)
  4969. {
  4970. int depth = 0;
  4971. while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
  4972. dx_db = &dx_dir->dx_block[dx_db->parent];
  4973. depth++;
  4974. }
  4975. return depth;
  4976. }
  4977. static int dict_de_cmp(const void *a, const void *b)
  4978. {
  4979. const struct ext2_dir_entry *de_a, *de_b;
  4980. int a_len, b_len;
  4981. de_a = (const struct ext2_dir_entry *) a;
  4982. a_len = de_a->name_len & 0xFF;
  4983. de_b = (const struct ext2_dir_entry *) b;
  4984. b_len = de_b->name_len & 0xFF;
  4985. if (a_len != b_len)
  4986. return (a_len - b_len);
  4987. return strncmp(de_a->name, de_b->name, a_len);
  4988. }
  4989. /*
  4990. * This is special sort function that makes sure that directory blocks
  4991. * with a dirblock of zero are sorted to the beginning of the list.
  4992. * This guarantees that the root node of the htree directories are
  4993. * processed first, so we know what hash version to use.
  4994. */
  4995. static int special_dir_block_cmp(const void *a, const void *b)
  4996. {
  4997. const struct ext2_db_entry *db_a =
  4998. (const struct ext2_db_entry *) a;
  4999. const struct ext2_db_entry *db_b =
  5000. (const struct ext2_db_entry *) b;
  5001. if (db_a->blockcnt && !db_b->blockcnt)
  5002. return 1;
  5003. if (!db_a->blockcnt && db_b->blockcnt)
  5004. return -1;
  5005. if (db_a->blk != db_b->blk)
  5006. return (int) (db_a->blk - db_b->blk);
  5007. if (db_a->ino != db_b->ino)
  5008. return (int) (db_a->ino - db_b->ino);
  5009. return (int) (db_a->blockcnt - db_b->blockcnt);
  5010. }
  5011. /*
  5012. * Make sure the first entry in the directory is '.', and that the
  5013. * directory entry is sane.
  5014. */
  5015. static int check_dot(e2fsck_t ctx,
  5016. struct ext2_dir_entry *dirent,
  5017. ext2_ino_t ino, struct problem_context *pctx)
  5018. {
  5019. struct ext2_dir_entry *nextdir;
  5020. int status = 0;
  5021. int created = 0;
  5022. int new_len;
  5023. int problem = 0;
  5024. if (!dirent->inode)
  5025. problem = PR_2_MISSING_DOT;
  5026. else if (((dirent->name_len & 0xFF) != 1) ||
  5027. (dirent->name[0] != '.'))
  5028. problem = PR_2_1ST_NOT_DOT;
  5029. else if (dirent->name[1] != '\0')
  5030. problem = PR_2_DOT_NULL_TERM;
  5031. if (problem) {
  5032. if (fix_problem(ctx, problem, pctx)) {
  5033. if (dirent->rec_len < 12)
  5034. dirent->rec_len = 12;
  5035. dirent->inode = ino;
  5036. dirent->name_len = 1;
  5037. dirent->name[0] = '.';
  5038. dirent->name[1] = '\0';
  5039. status = 1;
  5040. created = 1;
  5041. }
  5042. }
  5043. if (dirent->inode != ino) {
  5044. if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
  5045. dirent->inode = ino;
  5046. status = 1;
  5047. }
  5048. }
  5049. if (dirent->rec_len > 12) {
  5050. new_len = dirent->rec_len - 12;
  5051. if (new_len > 12) {
  5052. if (created ||
  5053. fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
  5054. nextdir = (struct ext2_dir_entry *)
  5055. ((char *) dirent + 12);
  5056. dirent->rec_len = 12;
  5057. nextdir->rec_len = new_len;
  5058. nextdir->inode = 0;
  5059. nextdir->name_len = 0;
  5060. status = 1;
  5061. }
  5062. }
  5063. }
  5064. return status;
  5065. }
  5066. /*
  5067. * Make sure the second entry in the directory is '..', and that the
  5068. * directory entry is sane. We do not check the inode number of '..'
  5069. * here; this gets done in pass 3.
  5070. */
  5071. static int check_dotdot(e2fsck_t ctx,
  5072. struct ext2_dir_entry *dirent,
  5073. struct dir_info *dir, struct problem_context *pctx)
  5074. {
  5075. int problem = 0;
  5076. if (!dirent->inode)
  5077. problem = PR_2_MISSING_DOT_DOT;
  5078. else if (((dirent->name_len & 0xFF) != 2) ||
  5079. (dirent->name[0] != '.') ||
  5080. (dirent->name[1] != '.'))
  5081. problem = PR_2_2ND_NOT_DOT_DOT;
  5082. else if (dirent->name[2] != '\0')
  5083. problem = PR_2_DOT_DOT_NULL_TERM;
  5084. if (problem) {
  5085. if (fix_problem(ctx, problem, pctx)) {
  5086. if (dirent->rec_len < 12)
  5087. dirent->rec_len = 12;
  5088. /*
  5089. * Note: we don't have the parent inode just
  5090. * yet, so we will fill it in with the root
  5091. * inode. This will get fixed in pass 3.
  5092. */
  5093. dirent->inode = EXT2_ROOT_INO;
  5094. dirent->name_len = 2;
  5095. dirent->name[0] = '.';
  5096. dirent->name[1] = '.';
  5097. dirent->name[2] = '\0';
  5098. return 1;
  5099. }
  5100. return 0;
  5101. }
  5102. dir->dotdot = dirent->inode;
  5103. return 0;
  5104. }
  5105. /*
  5106. * Check to make sure a directory entry doesn't contain any illegal
  5107. * characters.
  5108. */
  5109. static int check_name(e2fsck_t ctx,
  5110. struct ext2_dir_entry *dirent,
  5111. struct problem_context *pctx)
  5112. {
  5113. int i;
  5114. int fixup = -1;
  5115. int ret = 0;
  5116. for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
  5117. if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
  5118. if (fixup < 0) {
  5119. fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
  5120. }
  5121. if (fixup) {
  5122. dirent->name[i] = '.';
  5123. ret = 1;
  5124. }
  5125. }
  5126. }
  5127. return ret;
  5128. }
  5129. /*
  5130. * Check the directory filetype (if present)
  5131. */
  5132. /*
  5133. * Given a mode, return the ext2 file type
  5134. */
  5135. static int ext2_file_type(unsigned int mode)
  5136. {
  5137. if (LINUX_S_ISREG(mode))
  5138. return EXT2_FT_REG_FILE;
  5139. if (LINUX_S_ISDIR(mode))
  5140. return EXT2_FT_DIR;
  5141. if (LINUX_S_ISCHR(mode))
  5142. return EXT2_FT_CHRDEV;
  5143. if (LINUX_S_ISBLK(mode))
  5144. return EXT2_FT_BLKDEV;
  5145. if (LINUX_S_ISLNK(mode))
  5146. return EXT2_FT_SYMLINK;
  5147. if (LINUX_S_ISFIFO(mode))
  5148. return EXT2_FT_FIFO;
  5149. if (LINUX_S_ISSOCK(mode))
  5150. return EXT2_FT_SOCK;
  5151. return 0;
  5152. }
  5153. static int check_filetype(e2fsck_t ctx,
  5154. struct ext2_dir_entry *dirent,
  5155. struct problem_context *pctx)
  5156. {
  5157. int filetype = dirent->name_len >> 8;
  5158. int should_be = EXT2_FT_UNKNOWN;
  5159. struct ext2_inode inode;
  5160. if (!(ctx->fs->super->s_feature_incompat &
  5161. EXT2_FEATURE_INCOMPAT_FILETYPE)) {
  5162. if (filetype == 0 ||
  5163. !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
  5164. return 0;
  5165. dirent->name_len = dirent->name_len & 0xFF;
  5166. return 1;
  5167. }
  5168. if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
  5169. should_be = EXT2_FT_DIR;
  5170. } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
  5171. dirent->inode)) {
  5172. should_be = EXT2_FT_REG_FILE;
  5173. } else if (ctx->inode_bad_map &&
  5174. ext2fs_test_inode_bitmap(ctx->inode_bad_map,
  5175. dirent->inode))
  5176. should_be = 0;
  5177. else {
  5178. e2fsck_read_inode(ctx, dirent->inode, &inode,
  5179. "check_filetype");
  5180. should_be = ext2_file_type(inode.i_mode);
  5181. }
  5182. if (filetype == should_be)
  5183. return 0;
  5184. pctx->num = should_be;
  5185. if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
  5186. pctx) == 0)
  5187. return 0;
  5188. dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
  5189. return 1;
  5190. }
  5191. #ifdef ENABLE_HTREE
  5192. static void parse_int_node(ext2_filsys fs,
  5193. struct ext2_db_entry *db,
  5194. struct check_dir_struct *cd,
  5195. struct dx_dir_info *dx_dir,
  5196. char *block_buf)
  5197. {
  5198. struct ext2_dx_root_info *root;
  5199. struct ext2_dx_entry *ent;
  5200. struct ext2_dx_countlimit *limit;
  5201. struct dx_dirblock_info *dx_db;
  5202. int i, expect_limit, count;
  5203. blk_t blk;
  5204. ext2_dirhash_t min_hash = 0xffffffff;
  5205. ext2_dirhash_t max_hash = 0;
  5206. ext2_dirhash_t hash = 0, prev_hash;
  5207. if (db->blockcnt == 0) {
  5208. root = (struct ext2_dx_root_info *) (block_buf + 24);
  5209. ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
  5210. } else {
  5211. ent = (struct ext2_dx_entry *) (block_buf+8);
  5212. }
  5213. limit = (struct ext2_dx_countlimit *) ent;
  5214. count = ext2fs_le16_to_cpu(limit->count);
  5215. expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
  5216. sizeof(struct ext2_dx_entry);
  5217. if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
  5218. cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
  5219. if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
  5220. goto clear_and_exit;
  5221. }
  5222. if (count > expect_limit) {
  5223. cd->pctx.num = count;
  5224. if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
  5225. goto clear_and_exit;
  5226. count = expect_limit;
  5227. }
  5228. for (i=0; i < count; i++) {
  5229. prev_hash = hash;
  5230. hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
  5231. blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
  5232. /* Check to make sure the block is valid */
  5233. if (blk > (blk_t) dx_dir->numblocks) {
  5234. cd->pctx.blk = blk;
  5235. if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
  5236. &cd->pctx))
  5237. goto clear_and_exit;
  5238. }
  5239. if (hash < prev_hash &&
  5240. fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
  5241. goto clear_and_exit;
  5242. dx_db = &dx_dir->dx_block[blk];
  5243. if (dx_db->flags & DX_FLAG_REFERENCED) {
  5244. dx_db->flags |= DX_FLAG_DUP_REF;
  5245. } else {
  5246. dx_db->flags |= DX_FLAG_REFERENCED;
  5247. dx_db->parent = db->blockcnt;
  5248. }
  5249. if (hash < min_hash)
  5250. min_hash = hash;
  5251. if (hash > max_hash)
  5252. max_hash = hash;
  5253. dx_db->node_min_hash = hash;
  5254. if ((i+1) < count)
  5255. dx_db->node_max_hash =
  5256. ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
  5257. else {
  5258. dx_db->node_max_hash = 0xfffffffe;
  5259. dx_db->flags |= DX_FLAG_LAST;
  5260. }
  5261. if (i == 0)
  5262. dx_db->flags |= DX_FLAG_FIRST;
  5263. }
  5264. dx_db = &dx_dir->dx_block[db->blockcnt];
  5265. dx_db->min_hash = min_hash;
  5266. dx_db->max_hash = max_hash;
  5267. return;
  5268. clear_and_exit:
  5269. clear_htree(cd->ctx, cd->pctx.ino);
  5270. dx_dir->numblocks = 0;
  5271. }
  5272. #endif /* ENABLE_HTREE */
  5273. /*
  5274. * Given a busted directory, try to salvage it somehow.
  5275. *
  5276. */
  5277. static void salvage_directory(ext2_filsys fs,
  5278. struct ext2_dir_entry *dirent,
  5279. struct ext2_dir_entry *prev,
  5280. unsigned int *offset)
  5281. {
  5282. char *cp = (char *) dirent;
  5283. int left = fs->blocksize - *offset - dirent->rec_len;
  5284. int name_len = dirent->name_len & 0xFF;
  5285. /*
  5286. * Special case of directory entry of size 8: copy what's left
  5287. * of the directory block up to cover up the invalid hole.
  5288. */
  5289. if ((left >= 12) && (dirent->rec_len == 8)) {
  5290. memmove(cp, cp+8, left);
  5291. memset(cp + left, 0, 8);
  5292. return;
  5293. }
  5294. /*
  5295. * If the directory entry overruns the end of the directory
  5296. * block, and the name is small enough to fit, then adjust the
  5297. * record length.
  5298. */
  5299. if ((left < 0) &&
  5300. (name_len + 8 <= dirent->rec_len + left) &&
  5301. dirent->inode <= fs->super->s_inodes_count &&
  5302. strnlen(dirent->name, name_len) == name_len) {
  5303. dirent->rec_len += left;
  5304. return;
  5305. }
  5306. /*
  5307. * If the directory entry is a multiple of four, so it is
  5308. * valid, let the previous directory entry absorb the invalid
  5309. * one.
  5310. */
  5311. if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
  5312. prev->rec_len += dirent->rec_len;
  5313. *offset += dirent->rec_len;
  5314. return;
  5315. }
  5316. /*
  5317. * Default salvage method --- kill all of the directory
  5318. * entries for the rest of the block. We will either try to
  5319. * absorb it into the previous directory entry, or create a
  5320. * new empty directory entry the rest of the directory block.
  5321. */
  5322. if (prev) {
  5323. prev->rec_len += fs->blocksize - *offset;
  5324. *offset = fs->blocksize;
  5325. } else {
  5326. dirent->rec_len = fs->blocksize - *offset;
  5327. dirent->name_len = 0;
  5328. dirent->inode = 0;
  5329. }
  5330. }
  5331. static int check_dir_block(ext2_filsys fs,
  5332. struct ext2_db_entry *db,
  5333. void *priv_data)
  5334. {
  5335. struct dir_info *subdir, *dir;
  5336. struct dx_dir_info *dx_dir;
  5337. #ifdef ENABLE_HTREE
  5338. struct dx_dirblock_info *dx_db = 0;
  5339. #endif /* ENABLE_HTREE */
  5340. struct ext2_dir_entry *dirent, *prev;
  5341. ext2_dirhash_t hash;
  5342. unsigned int offset = 0;
  5343. int dir_modified = 0;
  5344. int dot_state;
  5345. blk_t block_nr = db->blk;
  5346. ext2_ino_t ino = db->ino;
  5347. __u16 links;
  5348. struct check_dir_struct *cd;
  5349. char *buf;
  5350. e2fsck_t ctx;
  5351. int problem;
  5352. struct ext2_dx_root_info *root;
  5353. struct ext2_dx_countlimit *limit;
  5354. static dict_t de_dict;
  5355. struct problem_context pctx;
  5356. int dups_found = 0;
  5357. cd = (struct check_dir_struct *) priv_data;
  5358. buf = cd->buf;
  5359. ctx = cd->ctx;
  5360. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  5361. return DIRENT_ABORT;
  5362. if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
  5363. return DIRENT_ABORT;
  5364. /*
  5365. * Make sure the inode is still in use (could have been
  5366. * deleted in the duplicate/bad blocks pass.
  5367. */
  5368. if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
  5369. return 0;
  5370. cd->pctx.ino = ino;
  5371. cd->pctx.blk = block_nr;
  5372. cd->pctx.blkcount = db->blockcnt;
  5373. cd->pctx.ino2 = 0;
  5374. cd->pctx.dirent = 0;
  5375. cd->pctx.num = 0;
  5376. if (db->blk == 0) {
  5377. if (allocate_dir_block(ctx, db, &cd->pctx))
  5378. return 0;
  5379. block_nr = db->blk;
  5380. }
  5381. if (db->blockcnt)
  5382. dot_state = 2;
  5383. else
  5384. dot_state = 0;
  5385. if (ctx->dirs_to_hash &&
  5386. ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
  5387. dups_found++;
  5388. cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
  5389. if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
  5390. cd->pctx.errcode = 0; /* We'll handle this ourselves */
  5391. if (cd->pctx.errcode) {
  5392. if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
  5393. ctx->flags |= E2F_FLAG_ABORT;
  5394. return DIRENT_ABORT;
  5395. }
  5396. memset(buf, 0, fs->blocksize);
  5397. }
  5398. #ifdef ENABLE_HTREE
  5399. dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
  5400. if (dx_dir && dx_dir->numblocks) {
  5401. if (db->blockcnt >= dx_dir->numblocks) {
  5402. printf("XXX should never happen!!!\n");
  5403. abort();
  5404. }
  5405. dx_db = &dx_dir->dx_block[db->blockcnt];
  5406. dx_db->type = DX_DIRBLOCK_LEAF;
  5407. dx_db->phys = block_nr;
  5408. dx_db->min_hash = ~0;
  5409. dx_db->max_hash = 0;
  5410. dirent = (struct ext2_dir_entry *) buf;
  5411. limit = (struct ext2_dx_countlimit *) (buf+8);
  5412. if (db->blockcnt == 0) {
  5413. root = (struct ext2_dx_root_info *) (buf + 24);
  5414. dx_db->type = DX_DIRBLOCK_ROOT;
  5415. dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
  5416. if ((root->reserved_zero ||
  5417. root->info_length < 8 ||
  5418. root->indirect_levels > 1) &&
  5419. fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
  5420. clear_htree(ctx, ino);
  5421. dx_dir->numblocks = 0;
  5422. dx_db = 0;
  5423. }
  5424. dx_dir->hashversion = root->hash_version;
  5425. dx_dir->depth = root->indirect_levels + 1;
  5426. } else if ((dirent->inode == 0) &&
  5427. (dirent->rec_len == fs->blocksize) &&
  5428. (dirent->name_len == 0) &&
  5429. (ext2fs_le16_to_cpu(limit->limit) ==
  5430. ((fs->blocksize-8) /
  5431. sizeof(struct ext2_dx_entry))))
  5432. dx_db->type = DX_DIRBLOCK_NODE;
  5433. }
  5434. #endif /* ENABLE_HTREE */
  5435. dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
  5436. prev = 0;
  5437. do {
  5438. problem = 0;
  5439. dirent = (struct ext2_dir_entry *) (buf + offset);
  5440. cd->pctx.dirent = dirent;
  5441. cd->pctx.num = offset;
  5442. if (((offset + dirent->rec_len) > fs->blocksize) ||
  5443. (dirent->rec_len < 12) ||
  5444. ((dirent->rec_len % 4) != 0) ||
  5445. (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
  5446. if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
  5447. salvage_directory(fs, dirent, prev, &offset);
  5448. dir_modified++;
  5449. continue;
  5450. } else
  5451. goto abort_free_dict;
  5452. }
  5453. if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
  5454. if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
  5455. dirent->name_len = EXT2_NAME_LEN;
  5456. dir_modified++;
  5457. }
  5458. }
  5459. if (dot_state == 0) {
  5460. if (check_dot(ctx, dirent, ino, &cd->pctx))
  5461. dir_modified++;
  5462. } else if (dot_state == 1) {
  5463. dir = e2fsck_get_dir_info(ctx, ino);
  5464. if (!dir) {
  5465. fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
  5466. goto abort_free_dict;
  5467. }
  5468. if (check_dotdot(ctx, dirent, dir, &cd->pctx))
  5469. dir_modified++;
  5470. } else if (dirent->inode == ino) {
  5471. problem = PR_2_LINK_DOT;
  5472. if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
  5473. dirent->inode = 0;
  5474. dir_modified++;
  5475. goto next;
  5476. }
  5477. }
  5478. if (!dirent->inode)
  5479. goto next;
  5480. /*
  5481. * Make sure the inode listed is a legal one.
  5482. */
  5483. if (((dirent->inode != EXT2_ROOT_INO) &&
  5484. (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
  5485. (dirent->inode > fs->super->s_inodes_count)) {
  5486. problem = PR_2_BAD_INO;
  5487. } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
  5488. dirent->inode))) {
  5489. /*
  5490. * If the inode is unused, offer to clear it.
  5491. */
  5492. problem = PR_2_UNUSED_INODE;
  5493. } else if ((dot_state > 1) &&
  5494. ((dirent->name_len & 0xFF) == 1) &&
  5495. (dirent->name[0] == '.')) {
  5496. /*
  5497. * If there's a '.' entry in anything other
  5498. * than the first directory entry, it's a
  5499. * duplicate entry that should be removed.
  5500. */
  5501. problem = PR_2_DUP_DOT;
  5502. } else if ((dot_state > 1) &&
  5503. ((dirent->name_len & 0xFF) == 2) &&
  5504. (dirent->name[0] == '.') &&
  5505. (dirent->name[1] == '.')) {
  5506. /*
  5507. * If there's a '..' entry in anything other
  5508. * than the second directory entry, it's a
  5509. * duplicate entry that should be removed.
  5510. */
  5511. problem = PR_2_DUP_DOT_DOT;
  5512. } else if ((dot_state > 1) &&
  5513. (dirent->inode == EXT2_ROOT_INO)) {
  5514. /*
  5515. * Don't allow links to the root directory.
  5516. * We check this specially to make sure we
  5517. * catch this error case even if the root
  5518. * directory hasn't been created yet.
  5519. */
  5520. problem = PR_2_LINK_ROOT;
  5521. } else if ((dot_state > 1) &&
  5522. (dirent->name_len & 0xFF) == 0) {
  5523. /*
  5524. * Don't allow zero-length directory names.
  5525. */
  5526. problem = PR_2_NULL_NAME;
  5527. }
  5528. if (problem) {
  5529. if (fix_problem(ctx, problem, &cd->pctx)) {
  5530. dirent->inode = 0;
  5531. dir_modified++;
  5532. goto next;
  5533. } else {
  5534. ext2fs_unmark_valid(fs);
  5535. if (problem == PR_2_BAD_INO)
  5536. goto next;
  5537. }
  5538. }
  5539. /*
  5540. * If the inode was marked as having bad fields in
  5541. * pass1, process it and offer to fix/clear it.
  5542. * (We wait until now so that we can display the
  5543. * pathname to the user.)
  5544. */
  5545. if (ctx->inode_bad_map &&
  5546. ext2fs_test_inode_bitmap(ctx->inode_bad_map,
  5547. dirent->inode)) {
  5548. if (e2fsck_process_bad_inode(ctx, ino,
  5549. dirent->inode,
  5550. buf + fs->blocksize)) {
  5551. dirent->inode = 0;
  5552. dir_modified++;
  5553. goto next;
  5554. }
  5555. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  5556. return DIRENT_ABORT;
  5557. }
  5558. if (check_name(ctx, dirent, &cd->pctx))
  5559. dir_modified++;
  5560. if (check_filetype(ctx, dirent, &cd->pctx))
  5561. dir_modified++;
  5562. #ifdef ENABLE_HTREE
  5563. if (dx_db) {
  5564. ext2fs_dirhash(dx_dir->hashversion, dirent->name,
  5565. (dirent->name_len & 0xFF),
  5566. fs->super->s_hash_seed, &hash, 0);
  5567. if (hash < dx_db->min_hash)
  5568. dx_db->min_hash = hash;
  5569. if (hash > dx_db->max_hash)
  5570. dx_db->max_hash = hash;
  5571. }
  5572. #endif
  5573. /*
  5574. * If this is a directory, then mark its parent in its
  5575. * dir_info structure. If the parent field is already
  5576. * filled in, then this directory has more than one
  5577. * hard link. We assume the first link is correct,
  5578. * and ask the user if he/she wants to clear this one.
  5579. */
  5580. if ((dot_state > 1) &&
  5581. (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
  5582. dirent->inode))) {
  5583. subdir = e2fsck_get_dir_info(ctx, dirent->inode);
  5584. if (!subdir) {
  5585. cd->pctx.ino = dirent->inode;
  5586. fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
  5587. goto abort_free_dict;
  5588. }
  5589. if (subdir->parent) {
  5590. cd->pctx.ino2 = subdir->parent;
  5591. if (fix_problem(ctx, PR_2_LINK_DIR,
  5592. &cd->pctx)) {
  5593. dirent->inode = 0;
  5594. dir_modified++;
  5595. goto next;
  5596. }
  5597. cd->pctx.ino2 = 0;
  5598. } else
  5599. subdir->parent = ino;
  5600. }
  5601. if (dups_found) {
  5602. ;
  5603. } else if (dict_lookup(&de_dict, dirent)) {
  5604. clear_problem_context(&pctx);
  5605. pctx.ino = ino;
  5606. pctx.dirent = dirent;
  5607. fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
  5608. if (!ctx->dirs_to_hash)
  5609. ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
  5610. if (ctx->dirs_to_hash)
  5611. ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
  5612. dups_found++;
  5613. } else
  5614. dict_alloc_insert(&de_dict, dirent, dirent);
  5615. ext2fs_icount_increment(ctx->inode_count, dirent->inode,
  5616. &links);
  5617. if (links > 1)
  5618. ctx->fs_links_count++;
  5619. ctx->fs_total_count++;
  5620. next:
  5621. prev = dirent;
  5622. offset += dirent->rec_len;
  5623. dot_state++;
  5624. } while (offset < fs->blocksize);
  5625. #ifdef ENABLE_HTREE
  5626. if (dx_db) {
  5627. cd->pctx.dir = cd->pctx.ino;
  5628. if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
  5629. (dx_db->type == DX_DIRBLOCK_NODE))
  5630. parse_int_node(fs, db, cd, dx_dir, buf);
  5631. }
  5632. #endif /* ENABLE_HTREE */
  5633. if (offset != fs->blocksize) {
  5634. cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
  5635. if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
  5636. dirent->rec_len = cd->pctx.num;
  5637. dir_modified++;
  5638. }
  5639. }
  5640. if (dir_modified) {
  5641. cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
  5642. if (cd->pctx.errcode) {
  5643. if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
  5644. &cd->pctx))
  5645. goto abort_free_dict;
  5646. }
  5647. ext2fs_mark_changed(fs);
  5648. }
  5649. dict_free_nodes(&de_dict);
  5650. return 0;
  5651. abort_free_dict:
  5652. dict_free_nodes(&de_dict);
  5653. ctx->flags |= E2F_FLAG_ABORT;
  5654. return DIRENT_ABORT;
  5655. }
  5656. /*
  5657. * This function is called to deallocate a block, and is an interator
  5658. * functioned called by deallocate inode via ext2fs_iterate_block().
  5659. */
  5660. static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr,
  5661. e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
  5662. blk_t ref_block FSCK_ATTR((unused)),
  5663. int ref_offset FSCK_ATTR((unused)),
  5664. void *priv_data)
  5665. {
  5666. e2fsck_t ctx = (e2fsck_t) priv_data;
  5667. if (HOLE_BLKADDR(*block_nr))
  5668. return 0;
  5669. if ((*block_nr < fs->super->s_first_data_block) ||
  5670. (*block_nr >= fs->super->s_blocks_count))
  5671. return 0;
  5672. ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
  5673. ext2fs_block_alloc_stats(fs, *block_nr, -1);
  5674. return 0;
  5675. }
  5676. /*
  5677. * This fuction deallocates an inode
  5678. */
  5679. static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
  5680. {
  5681. ext2_filsys fs = ctx->fs;
  5682. struct ext2_inode inode;
  5683. struct problem_context pctx;
  5684. __u32 count;
  5685. ext2fs_icount_store(ctx->inode_link_info, ino, 0);
  5686. e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
  5687. inode.i_links_count = 0;
  5688. inode.i_dtime = time(0);
  5689. e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
  5690. clear_problem_context(&pctx);
  5691. pctx.ino = ino;
  5692. /*
  5693. * Fix up the bitmaps...
  5694. */
  5695. e2fsck_read_bitmaps(ctx);
  5696. ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
  5697. ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
  5698. if (ctx->inode_bad_map)
  5699. ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
  5700. ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
  5701. if (inode.i_file_acl &&
  5702. (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
  5703. pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
  5704. block_buf, -1, &count);
  5705. if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
  5706. pctx.errcode = 0;
  5707. count = 1;
  5708. }
  5709. if (pctx.errcode) {
  5710. pctx.blk = inode.i_file_acl;
  5711. fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
  5712. ctx->flags |= E2F_FLAG_ABORT;
  5713. return;
  5714. }
  5715. if (count == 0) {
  5716. ext2fs_unmark_block_bitmap(ctx->block_found_map,
  5717. inode.i_file_acl);
  5718. ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
  5719. }
  5720. inode.i_file_acl = 0;
  5721. }
  5722. if (!ext2fs_inode_has_valid_blocks(&inode))
  5723. return;
  5724. if (LINUX_S_ISREG(inode.i_mode) &&
  5725. (inode.i_size_high || inode.i_size & 0x80000000UL))
  5726. ctx->large_files--;
  5727. pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
  5728. deallocate_inode_block, ctx);
  5729. if (pctx.errcode) {
  5730. fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
  5731. ctx->flags |= E2F_FLAG_ABORT;
  5732. return;
  5733. }
  5734. }
  5735. /*
  5736. * This fuction clears the htree flag on an inode
  5737. */
  5738. static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
  5739. {
  5740. struct ext2_inode inode;
  5741. e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
  5742. inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
  5743. e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
  5744. if (ctx->dirs_to_hash)
  5745. ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
  5746. }
  5747. static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
  5748. ext2_ino_t ino, char *buf)
  5749. {
  5750. ext2_filsys fs = ctx->fs;
  5751. struct ext2_inode inode;
  5752. int inode_modified = 0;
  5753. int not_fixed = 0;
  5754. unsigned char *frag, *fsize;
  5755. struct problem_context pctx;
  5756. int problem = 0;
  5757. e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
  5758. clear_problem_context(&pctx);
  5759. pctx.ino = ino;
  5760. pctx.dir = dir;
  5761. pctx.inode = &inode;
  5762. if (inode.i_file_acl &&
  5763. !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
  5764. fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
  5765. inode.i_file_acl = 0;
  5766. #if BB_BIG_ENDIAN
  5767. /*
  5768. * This is a special kludge to deal with long symlinks
  5769. * on big endian systems. i_blocks had already been
  5770. * decremented earlier in pass 1, but since i_file_acl
  5771. * hadn't yet been cleared, ext2fs_read_inode()
  5772. * assumed that the file was short symlink and would
  5773. * not have byte swapped i_block[0]. Hence, we have
  5774. * to byte-swap it here.
  5775. */
  5776. if (LINUX_S_ISLNK(inode.i_mode) &&
  5777. (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
  5778. (inode.i_blocks == fs->blocksize >> 9))
  5779. inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
  5780. #endif
  5781. inode_modified++;
  5782. } else
  5783. not_fixed++;
  5784. if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
  5785. !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
  5786. !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
  5787. !(LINUX_S_ISSOCK(inode.i_mode)))
  5788. problem = PR_2_BAD_MODE;
  5789. else if (LINUX_S_ISCHR(inode.i_mode)
  5790. && !e2fsck_pass1_check_device_inode(fs, &inode))
  5791. problem = PR_2_BAD_CHAR_DEV;
  5792. else if (LINUX_S_ISBLK(inode.i_mode)
  5793. && !e2fsck_pass1_check_device_inode(fs, &inode))
  5794. problem = PR_2_BAD_BLOCK_DEV;
  5795. else if (LINUX_S_ISFIFO(inode.i_mode)
  5796. && !e2fsck_pass1_check_device_inode(fs, &inode))
  5797. problem = PR_2_BAD_FIFO;
  5798. else if (LINUX_S_ISSOCK(inode.i_mode)
  5799. && !e2fsck_pass1_check_device_inode(fs, &inode))
  5800. problem = PR_2_BAD_SOCKET;
  5801. else if (LINUX_S_ISLNK(inode.i_mode)
  5802. && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
  5803. problem = PR_2_INVALID_SYMLINK;
  5804. }
  5805. if (problem) {
  5806. if (fix_problem(ctx, problem, &pctx)) {
  5807. deallocate_inode(ctx, ino, 0);
  5808. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  5809. return 0;
  5810. return 1;
  5811. } else
  5812. not_fixed++;
  5813. problem = 0;
  5814. }
  5815. if (inode.i_faddr) {
  5816. if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
  5817. inode.i_faddr = 0;
  5818. inode_modified++;
  5819. } else
  5820. not_fixed++;
  5821. }
  5822. switch (fs->super->s_creator_os) {
  5823. case EXT2_OS_LINUX:
  5824. frag = &inode.osd2.linux2.l_i_frag;
  5825. fsize = &inode.osd2.linux2.l_i_fsize;
  5826. break;
  5827. case EXT2_OS_HURD:
  5828. frag = &inode.osd2.hurd2.h_i_frag;
  5829. fsize = &inode.osd2.hurd2.h_i_fsize;
  5830. break;
  5831. case EXT2_OS_MASIX:
  5832. frag = &inode.osd2.masix2.m_i_frag;
  5833. fsize = &inode.osd2.masix2.m_i_fsize;
  5834. break;
  5835. default:
  5836. frag = fsize = 0;
  5837. }
  5838. if (frag && *frag) {
  5839. pctx.num = *frag;
  5840. if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
  5841. *frag = 0;
  5842. inode_modified++;
  5843. } else
  5844. not_fixed++;
  5845. pctx.num = 0;
  5846. }
  5847. if (fsize && *fsize) {
  5848. pctx.num = *fsize;
  5849. if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
  5850. *fsize = 0;
  5851. inode_modified++;
  5852. } else
  5853. not_fixed++;
  5854. pctx.num = 0;
  5855. }
  5856. if (inode.i_file_acl &&
  5857. ((inode.i_file_acl < fs->super->s_first_data_block) ||
  5858. (inode.i_file_acl >= fs->super->s_blocks_count))) {
  5859. if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
  5860. inode.i_file_acl = 0;
  5861. inode_modified++;
  5862. } else
  5863. not_fixed++;
  5864. }
  5865. if (inode.i_dir_acl &&
  5866. LINUX_S_ISDIR(inode.i_mode)) {
  5867. if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
  5868. inode.i_dir_acl = 0;
  5869. inode_modified++;
  5870. } else
  5871. not_fixed++;
  5872. }
  5873. if (inode_modified)
  5874. e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
  5875. if (!not_fixed)
  5876. ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
  5877. return 0;
  5878. }
  5879. /*
  5880. * allocate_dir_block --- this function allocates a new directory
  5881. * block for a particular inode; this is done if a directory has
  5882. * a "hole" in it, or if a directory has a illegal block number
  5883. * that was zeroed out and now needs to be replaced.
  5884. */
  5885. static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db,
  5886. struct problem_context *pctx)
  5887. {
  5888. ext2_filsys fs = ctx->fs;
  5889. blk_t blk;
  5890. char *block;
  5891. struct ext2_inode inode;
  5892. if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
  5893. return 1;
  5894. /*
  5895. * Read the inode and block bitmaps in; we'll be messing with
  5896. * them.
  5897. */
  5898. e2fsck_read_bitmaps(ctx);
  5899. /*
  5900. * First, find a free block
  5901. */
  5902. pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
  5903. if (pctx->errcode) {
  5904. pctx->str = "ext2fs_new_block";
  5905. fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
  5906. return 1;
  5907. }
  5908. ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
  5909. ext2fs_mark_block_bitmap(fs->block_map, blk);
  5910. ext2fs_mark_bb_dirty(fs);
  5911. /*
  5912. * Now let's create the actual data block for the inode
  5913. */
  5914. if (db->blockcnt)
  5915. pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
  5916. else
  5917. pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
  5918. EXT2_ROOT_INO, &block);
  5919. if (pctx->errcode) {
  5920. pctx->str = "ext2fs_new_dir_block";
  5921. fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
  5922. return 1;
  5923. }
  5924. pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
  5925. ext2fs_free_mem(&block);
  5926. if (pctx->errcode) {
  5927. pctx->str = "ext2fs_write_dir_block";
  5928. fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
  5929. return 1;
  5930. }
  5931. /*
  5932. * Update the inode block count
  5933. */
  5934. e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
  5935. inode.i_blocks += fs->blocksize / 512;
  5936. if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
  5937. inode.i_size = (db->blockcnt+1) * fs->blocksize;
  5938. e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
  5939. /*
  5940. * Finally, update the block pointers for the inode
  5941. */
  5942. db->blk = blk;
  5943. pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
  5944. 0, update_dir_block, db);
  5945. if (pctx->errcode) {
  5946. pctx->str = "ext2fs_block_iterate";
  5947. fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
  5948. return 1;
  5949. }
  5950. return 0;
  5951. }
  5952. /*
  5953. * This is a helper function for allocate_dir_block().
  5954. */
  5955. static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)),
  5956. blk_t *block_nr,
  5957. e2_blkcnt_t blockcnt,
  5958. blk_t ref_block FSCK_ATTR((unused)),
  5959. int ref_offset FSCK_ATTR((unused)),
  5960. void *priv_data)
  5961. {
  5962. struct ext2_db_entry *db;
  5963. db = (struct ext2_db_entry *) priv_data;
  5964. if (db->blockcnt == (int) blockcnt) {
  5965. *block_nr = db->blk;
  5966. return BLOCK_CHANGED;
  5967. }
  5968. return 0;
  5969. }
  5970. /*
  5971. * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
  5972. *
  5973. * Pass #3 assures that all directories are connected to the
  5974. * filesystem tree, using the following algorithm:
  5975. *
  5976. * First, the root directory is checked to make sure it exists; if
  5977. * not, e2fsck will offer to create a new one. It is then marked as
  5978. * "done".
  5979. *
  5980. * Then, pass3 interates over all directory inodes; for each directory
  5981. * it attempts to trace up the filesystem tree, using dirinfo.parent
  5982. * until it reaches a directory which has been marked "done". If it
  5983. * cannot do so, then the directory must be disconnected, and e2fsck
  5984. * will offer to reconnect it to /lost+found. While it is chasing
  5985. * parent pointers up the filesystem tree, if pass3 sees a directory
  5986. * twice, then it has detected a filesystem loop, and it will again
  5987. * offer to reconnect the directory to /lost+found in to break the
  5988. * filesystem loop.
  5989. *
  5990. * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
  5991. * reconnect inodes to /lost+found; this subroutine is also used by
  5992. * pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which
  5993. * is responsible for creating /lost+found if it does not exist.
  5994. *
  5995. * Pass 3 frees the following data structures:
  5996. * - The dirinfo directory information cache.
  5997. */
  5998. static void check_root(e2fsck_t ctx);
  5999. static int check_directory(e2fsck_t ctx, struct dir_info *dir,
  6000. struct problem_context *pctx);
  6001. static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
  6002. static ext2fs_inode_bitmap inode_loop_detect;
  6003. static ext2fs_inode_bitmap inode_done_map;
  6004. static void e2fsck_pass3(e2fsck_t ctx)
  6005. {
  6006. ext2_filsys fs = ctx->fs;
  6007. int i;
  6008. struct problem_context pctx;
  6009. struct dir_info *dir;
  6010. unsigned long maxdirs, count;
  6011. clear_problem_context(&pctx);
  6012. /* Pass 3 */
  6013. if (!(ctx->options & E2F_OPT_PREEN))
  6014. fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
  6015. /*
  6016. * Allocate some bitmaps to do loop detection.
  6017. */
  6018. pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
  6019. &inode_done_map);
  6020. if (pctx.errcode) {
  6021. pctx.num = 2;
  6022. fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
  6023. ctx->flags |= E2F_FLAG_ABORT;
  6024. goto abort_exit;
  6025. }
  6026. check_root(ctx);
  6027. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  6028. goto abort_exit;
  6029. ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
  6030. maxdirs = e2fsck_get_num_dirinfo(ctx);
  6031. count = 1;
  6032. if (ctx->progress)
  6033. if ((ctx->progress)(ctx, 3, 0, maxdirs))
  6034. goto abort_exit;
  6035. for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
  6036. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  6037. goto abort_exit;
  6038. if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
  6039. goto abort_exit;
  6040. if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
  6041. if (check_directory(ctx, dir, &pctx))
  6042. goto abort_exit;
  6043. }
  6044. /*
  6045. * Force the creation of /lost+found if not present
  6046. */
  6047. if ((ctx->flags & E2F_OPT_READONLY) == 0)
  6048. e2fsck_get_lost_and_found(ctx, 1);
  6049. /*
  6050. * If there are any directories that need to be indexed or
  6051. * optimized, do it here.
  6052. */
  6053. e2fsck_rehash_directories(ctx);
  6054. abort_exit:
  6055. e2fsck_free_dir_info(ctx);
  6056. ext2fs_free_inode_bitmap(inode_loop_detect);
  6057. inode_loop_detect = 0;
  6058. ext2fs_free_inode_bitmap(inode_done_map);
  6059. inode_done_map = 0;
  6060. }
  6061. /*
  6062. * This makes sure the root inode is present; if not, we ask if the
  6063. * user wants us to create it. Not creating it is a fatal error.
  6064. */
  6065. static void check_root(e2fsck_t ctx)
  6066. {
  6067. ext2_filsys fs = ctx->fs;
  6068. blk_t blk;
  6069. struct ext2_inode inode;
  6070. char * block;
  6071. struct problem_context pctx;
  6072. clear_problem_context(&pctx);
  6073. if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
  6074. /*
  6075. * If the root inode is not a directory, die here. The
  6076. * user must have answered 'no' in pass1 when we
  6077. * offered to clear it.
  6078. */
  6079. if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
  6080. EXT2_ROOT_INO))) {
  6081. fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
  6082. ctx->flags |= E2F_FLAG_ABORT;
  6083. }
  6084. return;
  6085. }
  6086. if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
  6087. fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
  6088. ctx->flags |= E2F_FLAG_ABORT;
  6089. return;
  6090. }
  6091. e2fsck_read_bitmaps(ctx);
  6092. /*
  6093. * First, find a free block
  6094. */
  6095. pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
  6096. if (pctx.errcode) {
  6097. pctx.str = "ext2fs_new_block";
  6098. fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
  6099. ctx->flags |= E2F_FLAG_ABORT;
  6100. return;
  6101. }
  6102. ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
  6103. ext2fs_mark_block_bitmap(fs->block_map, blk);
  6104. ext2fs_mark_bb_dirty(fs);
  6105. /*
  6106. * Now let's create the actual data block for the inode
  6107. */
  6108. pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
  6109. &block);
  6110. if (pctx.errcode) {
  6111. pctx.str = "ext2fs_new_dir_block";
  6112. fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
  6113. ctx->flags |= E2F_FLAG_ABORT;
  6114. return;
  6115. }
  6116. pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
  6117. if (pctx.errcode) {
  6118. pctx.str = "ext2fs_write_dir_block";
  6119. fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
  6120. ctx->flags |= E2F_FLAG_ABORT;
  6121. return;
  6122. }
  6123. ext2fs_free_mem(&block);
  6124. /*
  6125. * Set up the inode structure
  6126. */
  6127. memset(&inode, 0, sizeof(inode));
  6128. inode.i_mode = 040755;
  6129. inode.i_size = fs->blocksize;
  6130. inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
  6131. inode.i_links_count = 2;
  6132. inode.i_blocks = fs->blocksize / 512;
  6133. inode.i_block[0] = blk;
  6134. /*
  6135. * Write out the inode.
  6136. */
  6137. pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
  6138. if (pctx.errcode) {
  6139. pctx.str = "ext2fs_write_inode";
  6140. fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
  6141. ctx->flags |= E2F_FLAG_ABORT;
  6142. return;
  6143. }
  6144. /*
  6145. * Miscellaneous bookkeeping...
  6146. */
  6147. e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
  6148. ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
  6149. ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
  6150. ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
  6151. ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
  6152. ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
  6153. ext2fs_mark_ib_dirty(fs);
  6154. }
  6155. /*
  6156. * This subroutine is responsible for making sure that a particular
  6157. * directory is connected to the root; if it isn't we trace it up as
  6158. * far as we can go, and then offer to connect the resulting parent to
  6159. * the lost+found. We have to do loop detection; if we ever discover
  6160. * a loop, we treat that as a disconnected directory and offer to
  6161. * reparent it to lost+found.
  6162. *
  6163. * However, loop detection is expensive, because for very large
  6164. * filesystems, the inode_loop_detect bitmap is huge, and clearing it
  6165. * is non-trivial. Loops in filesystems are also a rare error case,
  6166. * and we shouldn't optimize for error cases. So we try two passes of
  6167. * the algorithm. The first time, we ignore loop detection and merely
  6168. * increment a counter; if the counter exceeds some extreme threshold,
  6169. * then we try again with the loop detection bitmap enabled.
  6170. */
  6171. static int check_directory(e2fsck_t ctx, struct dir_info *dir,
  6172. struct problem_context *pctx)
  6173. {
  6174. ext2_filsys fs = ctx->fs;
  6175. struct dir_info *p = dir;
  6176. int loop_pass = 0, parent_count = 0;
  6177. if (!p)
  6178. return 0;
  6179. while (1) {
  6180. /*
  6181. * Mark this inode as being "done"; by the time we
  6182. * return from this function, the inode we either be
  6183. * verified as being connected to the directory tree,
  6184. * or we will have offered to reconnect this to
  6185. * lost+found.
  6186. *
  6187. * If it was marked done already, then we've reached a
  6188. * parent we've already checked.
  6189. */
  6190. if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
  6191. break;
  6192. /*
  6193. * If this directory doesn't have a parent, or we've
  6194. * seen the parent once already, then offer to
  6195. * reparent it to lost+found
  6196. */
  6197. if (!p->parent ||
  6198. (loop_pass &&
  6199. (ext2fs_test_inode_bitmap(inode_loop_detect,
  6200. p->parent)))) {
  6201. pctx->ino = p->ino;
  6202. if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
  6203. if (e2fsck_reconnect_file(ctx, pctx->ino))
  6204. ext2fs_unmark_valid(fs);
  6205. else {
  6206. p = e2fsck_get_dir_info(ctx, pctx->ino);
  6207. p->parent = ctx->lost_and_found;
  6208. fix_dotdot(ctx, p, ctx->lost_and_found);
  6209. }
  6210. }
  6211. break;
  6212. }
  6213. p = e2fsck_get_dir_info(ctx, p->parent);
  6214. if (!p) {
  6215. fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
  6216. return 0;
  6217. }
  6218. if (loop_pass) {
  6219. ext2fs_mark_inode_bitmap(inode_loop_detect,
  6220. p->ino);
  6221. } else if (parent_count++ > 2048) {
  6222. /*
  6223. * If we've run into a path depth that's
  6224. * greater than 2048, try again with the inode
  6225. * loop bitmap turned on and start from the
  6226. * top.
  6227. */
  6228. loop_pass = 1;
  6229. if (inode_loop_detect)
  6230. ext2fs_clear_inode_bitmap(inode_loop_detect);
  6231. else {
  6232. pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
  6233. if (pctx->errcode) {
  6234. pctx->num = 1;
  6235. fix_problem(ctx,
  6236. PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
  6237. ctx->flags |= E2F_FLAG_ABORT;
  6238. return -1;
  6239. }
  6240. }
  6241. p = dir;
  6242. }
  6243. }
  6244. /*
  6245. * Make sure that .. and the parent directory are the same;
  6246. * offer to fix it if not.
  6247. */
  6248. if (dir->parent != dir->dotdot) {
  6249. pctx->ino = dir->ino;
  6250. pctx->ino2 = dir->dotdot;
  6251. pctx->dir = dir->parent;
  6252. if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
  6253. fix_dotdot(ctx, dir, dir->parent);
  6254. }
  6255. return 0;
  6256. }
  6257. /*
  6258. * This routine gets the lost_and_found inode, making it a directory
  6259. * if necessary
  6260. */
  6261. ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
  6262. {
  6263. ext2_filsys fs = ctx->fs;
  6264. ext2_ino_t ino;
  6265. blk_t blk;
  6266. errcode_t retval;
  6267. struct ext2_inode inode;
  6268. char * block;
  6269. static const char name[] = "lost+found";
  6270. struct problem_context pctx;
  6271. struct dir_info *dirinfo;
  6272. if (ctx->lost_and_found)
  6273. return ctx->lost_and_found;
  6274. clear_problem_context(&pctx);
  6275. retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
  6276. sizeof(name)-1, 0, &ino);
  6277. if (retval && !fix)
  6278. return 0;
  6279. if (!retval) {
  6280. if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
  6281. ctx->lost_and_found = ino;
  6282. return ino;
  6283. }
  6284. /* Lost+found isn't a directory! */
  6285. if (!fix)
  6286. return 0;
  6287. pctx.ino = ino;
  6288. if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
  6289. return 0;
  6290. /* OK, unlink the old /lost+found file. */
  6291. pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
  6292. if (pctx.errcode) {
  6293. pctx.str = "ext2fs_unlink";
  6294. fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
  6295. return 0;
  6296. }
  6297. dirinfo = e2fsck_get_dir_info(ctx, ino);
  6298. if (dirinfo)
  6299. dirinfo->parent = 0;
  6300. e2fsck_adjust_inode_count(ctx, ino, -1);
  6301. } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
  6302. pctx.errcode = retval;
  6303. fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
  6304. }
  6305. if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
  6306. return 0;
  6307. /*
  6308. * Read the inode and block bitmaps in; we'll be messing with
  6309. * them.
  6310. */
  6311. e2fsck_read_bitmaps(ctx);
  6312. /*
  6313. * First, find a free block
  6314. */
  6315. retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
  6316. if (retval) {
  6317. pctx.errcode = retval;
  6318. fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
  6319. return 0;
  6320. }
  6321. ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
  6322. ext2fs_block_alloc_stats(fs, blk, +1);
  6323. /*
  6324. * Next find a free inode.
  6325. */
  6326. retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
  6327. ctx->inode_used_map, &ino);
  6328. if (retval) {
  6329. pctx.errcode = retval;
  6330. fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
  6331. return 0;
  6332. }
  6333. ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
  6334. ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
  6335. ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
  6336. /*
  6337. * Now let's create the actual data block for the inode
  6338. */
  6339. retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
  6340. if (retval) {
  6341. pctx.errcode = retval;
  6342. fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
  6343. return 0;
  6344. }
  6345. retval = ext2fs_write_dir_block(fs, blk, block);
  6346. ext2fs_free_mem(&block);
  6347. if (retval) {
  6348. pctx.errcode = retval;
  6349. fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
  6350. return 0;
  6351. }
  6352. /*
  6353. * Set up the inode structure
  6354. */
  6355. memset(&inode, 0, sizeof(inode));
  6356. inode.i_mode = 040700;
  6357. inode.i_size = fs->blocksize;
  6358. inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
  6359. inode.i_links_count = 2;
  6360. inode.i_blocks = fs->blocksize / 512;
  6361. inode.i_block[0] = blk;
  6362. /*
  6363. * Next, write out the inode.
  6364. */
  6365. pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
  6366. if (pctx.errcode) {
  6367. pctx.str = "ext2fs_write_inode";
  6368. fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
  6369. return 0;
  6370. }
  6371. /*
  6372. * Finally, create the directory link
  6373. */
  6374. pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
  6375. if (pctx.errcode) {
  6376. pctx.str = "ext2fs_link";
  6377. fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
  6378. return 0;
  6379. }
  6380. /*
  6381. * Miscellaneous bookkeeping that needs to be kept straight.
  6382. */
  6383. e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
  6384. e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
  6385. ext2fs_icount_store(ctx->inode_count, ino, 2);
  6386. ext2fs_icount_store(ctx->inode_link_info, ino, 2);
  6387. ctx->lost_and_found = ino;
  6388. return ino;
  6389. }
  6390. /*
  6391. * This routine will connect a file to lost+found
  6392. */
  6393. int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
  6394. {
  6395. ext2_filsys fs = ctx->fs;
  6396. errcode_t retval;
  6397. char name[80];
  6398. struct problem_context pctx;
  6399. struct ext2_inode inode;
  6400. int file_type = 0;
  6401. clear_problem_context(&pctx);
  6402. pctx.ino = ino;
  6403. if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
  6404. if (e2fsck_get_lost_and_found(ctx, 1) == 0)
  6405. ctx->bad_lost_and_found++;
  6406. }
  6407. if (ctx->bad_lost_and_found) {
  6408. fix_problem(ctx, PR_3_NO_LPF, &pctx);
  6409. return 1;
  6410. }
  6411. sprintf(name, "#%u", ino);
  6412. if (ext2fs_read_inode(fs, ino, &inode) == 0)
  6413. file_type = ext2_file_type(inode.i_mode);
  6414. retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
  6415. if (retval == EXT2_ET_DIR_NO_SPACE) {
  6416. if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
  6417. return 1;
  6418. retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
  6419. 1, 0);
  6420. if (retval) {
  6421. pctx.errcode = retval;
  6422. fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
  6423. return 1;
  6424. }
  6425. retval = ext2fs_link(fs, ctx->lost_and_found, name,
  6426. ino, file_type);
  6427. }
  6428. if (retval) {
  6429. pctx.errcode = retval;
  6430. fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
  6431. return 1;
  6432. }
  6433. e2fsck_adjust_inode_count(ctx, ino, 1);
  6434. return 0;
  6435. }
  6436. /*
  6437. * Utility routine to adjust the inode counts on an inode.
  6438. */
  6439. errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
  6440. {
  6441. ext2_filsys fs = ctx->fs;
  6442. errcode_t retval;
  6443. struct ext2_inode inode;
  6444. if (!ino)
  6445. return 0;
  6446. retval = ext2fs_read_inode(fs, ino, &inode);
  6447. if (retval)
  6448. return retval;
  6449. if (adj == 1) {
  6450. ext2fs_icount_increment(ctx->inode_count, ino, 0);
  6451. if (inode.i_links_count == (__u16) ~0)
  6452. return 0;
  6453. ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
  6454. inode.i_links_count++;
  6455. } else if (adj == -1) {
  6456. ext2fs_icount_decrement(ctx->inode_count, ino, 0);
  6457. if (inode.i_links_count == 0)
  6458. return 0;
  6459. ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
  6460. inode.i_links_count--;
  6461. }
  6462. retval = ext2fs_write_inode(fs, ino, &inode);
  6463. if (retval)
  6464. return retval;
  6465. return 0;
  6466. }
  6467. /*
  6468. * Fix parent --- this routine fixes up the parent of a directory.
  6469. */
  6470. struct fix_dotdot_struct {
  6471. ext2_filsys fs;
  6472. ext2_ino_t parent;
  6473. int done;
  6474. e2fsck_t ctx;
  6475. };
  6476. static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
  6477. int offset FSCK_ATTR((unused)),
  6478. int blocksize FSCK_ATTR((unused)),
  6479. char *buf FSCK_ATTR((unused)),
  6480. void *priv_data)
  6481. {
  6482. struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
  6483. errcode_t retval;
  6484. struct problem_context pctx;
  6485. if ((dirent->name_len & 0xFF) != 2)
  6486. return 0;
  6487. if (strncmp(dirent->name, "..", 2))
  6488. return 0;
  6489. clear_problem_context(&pctx);
  6490. retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
  6491. if (retval) {
  6492. pctx.errcode = retval;
  6493. fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
  6494. }
  6495. retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
  6496. if (retval) {
  6497. pctx.errcode = retval;
  6498. fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
  6499. }
  6500. dirent->inode = fp->parent;
  6501. fp->done++;
  6502. return DIRENT_ABORT | DIRENT_CHANGED;
  6503. }
  6504. static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
  6505. {
  6506. ext2_filsys fs = ctx->fs;
  6507. errcode_t retval;
  6508. struct fix_dotdot_struct fp;
  6509. struct problem_context pctx;
  6510. fp.fs = fs;
  6511. fp.parent = parent;
  6512. fp.done = 0;
  6513. fp.ctx = ctx;
  6514. retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
  6515. 0, fix_dotdot_proc, &fp);
  6516. if (retval || !fp.done) {
  6517. clear_problem_context(&pctx);
  6518. pctx.ino = dir->ino;
  6519. pctx.errcode = retval;
  6520. fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
  6521. PR_3_FIX_PARENT_NOFIND, &pctx);
  6522. ext2fs_unmark_valid(fs);
  6523. }
  6524. dir->dotdot = parent;
  6525. return;
  6526. }
  6527. /*
  6528. * These routines are responsible for expanding a /lost+found if it is
  6529. * too small.
  6530. */
  6531. struct expand_dir_struct {
  6532. int num;
  6533. int guaranteed_size;
  6534. int newblocks;
  6535. int last_block;
  6536. errcode_t err;
  6537. e2fsck_t ctx;
  6538. };
  6539. static int expand_dir_proc(ext2_filsys fs,
  6540. blk_t *blocknr,
  6541. e2_blkcnt_t blockcnt,
  6542. blk_t ref_block FSCK_ATTR((unused)),
  6543. int ref_offset FSCK_ATTR((unused)),
  6544. void *priv_data)
  6545. {
  6546. struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
  6547. blk_t new_blk;
  6548. static blk_t last_blk = 0;
  6549. char *block;
  6550. errcode_t retval;
  6551. e2fsck_t ctx;
  6552. ctx = es->ctx;
  6553. if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
  6554. return BLOCK_ABORT;
  6555. if (blockcnt > 0)
  6556. es->last_block = blockcnt;
  6557. if (*blocknr) {
  6558. last_blk = *blocknr;
  6559. return 0;
  6560. }
  6561. retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
  6562. &new_blk);
  6563. if (retval) {
  6564. es->err = retval;
  6565. return BLOCK_ABORT;
  6566. }
  6567. if (blockcnt > 0) {
  6568. retval = ext2fs_new_dir_block(fs, 0, 0, &block);
  6569. if (retval) {
  6570. es->err = retval;
  6571. return BLOCK_ABORT;
  6572. }
  6573. es->num--;
  6574. retval = ext2fs_write_dir_block(fs, new_blk, block);
  6575. } else {
  6576. retval = ext2fs_get_mem(fs->blocksize, &block);
  6577. if (retval) {
  6578. es->err = retval;
  6579. return BLOCK_ABORT;
  6580. }
  6581. memset(block, 0, fs->blocksize);
  6582. retval = io_channel_write_blk(fs->io, new_blk, 1, block);
  6583. }
  6584. if (retval) {
  6585. es->err = retval;
  6586. return BLOCK_ABORT;
  6587. }
  6588. ext2fs_free_mem(&block);
  6589. *blocknr = new_blk;
  6590. ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
  6591. ext2fs_block_alloc_stats(fs, new_blk, +1);
  6592. es->newblocks++;
  6593. if (es->num == 0)
  6594. return (BLOCK_CHANGED | BLOCK_ABORT);
  6595. else
  6596. return BLOCK_CHANGED;
  6597. }
  6598. errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
  6599. int num, int guaranteed_size)
  6600. {
  6601. ext2_filsys fs = ctx->fs;
  6602. errcode_t retval;
  6603. struct expand_dir_struct es;
  6604. struct ext2_inode inode;
  6605. if (!(fs->flags & EXT2_FLAG_RW))
  6606. return EXT2_ET_RO_FILSYS;
  6607. /*
  6608. * Read the inode and block bitmaps in; we'll be messing with
  6609. * them.
  6610. */
  6611. e2fsck_read_bitmaps(ctx);
  6612. retval = ext2fs_check_directory(fs, dir);
  6613. if (retval)
  6614. return retval;
  6615. es.num = num;
  6616. es.guaranteed_size = guaranteed_size;
  6617. es.last_block = 0;
  6618. es.err = 0;
  6619. es.newblocks = 0;
  6620. es.ctx = ctx;
  6621. retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
  6622. 0, expand_dir_proc, &es);
  6623. if (es.err)
  6624. return es.err;
  6625. /*
  6626. * Update the size and block count fields in the inode.
  6627. */
  6628. retval = ext2fs_read_inode(fs, dir, &inode);
  6629. if (retval)
  6630. return retval;
  6631. inode.i_size = (es.last_block + 1) * fs->blocksize;
  6632. inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
  6633. e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
  6634. return 0;
  6635. }
  6636. /*
  6637. * pass4.c -- pass #4 of e2fsck: Check reference counts
  6638. *
  6639. * Pass 4 frees the following data structures:
  6640. * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
  6641. */
  6642. /*
  6643. * This routine is called when an inode is not connected to the
  6644. * directory tree.
  6645. *
  6646. * This subroutine returns 1 then the caller shouldn't bother with the
  6647. * rest of the pass 4 tests.
  6648. */
  6649. static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
  6650. {
  6651. ext2_filsys fs = ctx->fs;
  6652. struct ext2_inode inode;
  6653. struct problem_context pctx;
  6654. e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
  6655. clear_problem_context(&pctx);
  6656. pctx.ino = i;
  6657. pctx.inode = &inode;
  6658. /*
  6659. * Offer to delete any zero-length files that does not have
  6660. * blocks. If there is an EA block, it might have useful
  6661. * information, so we won't prompt to delete it, but let it be
  6662. * reconnected to lost+found.
  6663. */
  6664. if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
  6665. LINUX_S_ISDIR(inode.i_mode))) {
  6666. if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
  6667. ext2fs_icount_store(ctx->inode_link_info, i, 0);
  6668. inode.i_links_count = 0;
  6669. inode.i_dtime = time(0);
  6670. e2fsck_write_inode(ctx, i, &inode,
  6671. "disconnect_inode");
  6672. /*
  6673. * Fix up the bitmaps...
  6674. */
  6675. e2fsck_read_bitmaps(ctx);
  6676. ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
  6677. ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
  6678. ext2fs_inode_alloc_stats2(fs, i, -1,
  6679. LINUX_S_ISDIR(inode.i_mode));
  6680. return 0;
  6681. }
  6682. }
  6683. /*
  6684. * Prompt to reconnect.
  6685. */
  6686. if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
  6687. if (e2fsck_reconnect_file(ctx, i))
  6688. ext2fs_unmark_valid(fs);
  6689. } else {
  6690. /*
  6691. * If we don't attach the inode, then skip the
  6692. * i_links_test since there's no point in trying to
  6693. * force i_links_count to zero.
  6694. */
  6695. ext2fs_unmark_valid(fs);
  6696. return 1;
  6697. }
  6698. return 0;
  6699. }
  6700. static void e2fsck_pass4(e2fsck_t ctx)
  6701. {
  6702. ext2_filsys fs = ctx->fs;
  6703. ext2_ino_t i;
  6704. struct ext2_inode inode;
  6705. struct problem_context pctx;
  6706. __u16 link_count, link_counted;
  6707. char *buf = 0;
  6708. int group, maxgroup;
  6709. /* Pass 4 */
  6710. clear_problem_context(&pctx);
  6711. if (!(ctx->options & E2F_OPT_PREEN))
  6712. fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
  6713. group = 0;
  6714. maxgroup = fs->group_desc_count;
  6715. if (ctx->progress)
  6716. if ((ctx->progress)(ctx, 4, 0, maxgroup))
  6717. return;
  6718. for (i=1; i <= fs->super->s_inodes_count; i++) {
  6719. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  6720. return;
  6721. if ((i % fs->super->s_inodes_per_group) == 0) {
  6722. group++;
  6723. if (ctx->progress)
  6724. if ((ctx->progress)(ctx, 4, group, maxgroup))
  6725. return;
  6726. }
  6727. if (i == EXT2_BAD_INO ||
  6728. (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
  6729. continue;
  6730. if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
  6731. (ctx->inode_imagic_map &&
  6732. ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)))
  6733. continue;
  6734. ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
  6735. ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
  6736. if (link_counted == 0) {
  6737. if (!buf)
  6738. buf = e2fsck_allocate_memory(ctx,
  6739. fs->blocksize, "bad_inode buffer");
  6740. if (e2fsck_process_bad_inode(ctx, 0, i, buf))
  6741. continue;
  6742. if (disconnect_inode(ctx, i))
  6743. continue;
  6744. ext2fs_icount_fetch(ctx->inode_link_info, i,
  6745. &link_count);
  6746. ext2fs_icount_fetch(ctx->inode_count, i,
  6747. &link_counted);
  6748. }
  6749. if (link_counted != link_count) {
  6750. e2fsck_read_inode(ctx, i, &inode, "pass4");
  6751. pctx.ino = i;
  6752. pctx.inode = &inode;
  6753. if (link_count != inode.i_links_count) {
  6754. pctx.num = link_count;
  6755. fix_problem(ctx,
  6756. PR_4_INCONSISTENT_COUNT, &pctx);
  6757. }
  6758. pctx.num = link_counted;
  6759. if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
  6760. inode.i_links_count = link_counted;
  6761. e2fsck_write_inode(ctx, i, &inode, "pass4");
  6762. }
  6763. }
  6764. }
  6765. ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
  6766. ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
  6767. ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
  6768. ctx->inode_imagic_map = 0;
  6769. ext2fs_free_mem(&buf);
  6770. }
  6771. /*
  6772. * pass5.c --- check block and inode bitmaps against on-disk bitmaps
  6773. */
  6774. #define NO_BLK ((blk_t) -1)
  6775. static void print_bitmap_problem(e2fsck_t ctx, int problem,
  6776. struct problem_context *pctx)
  6777. {
  6778. switch (problem) {
  6779. case PR_5_BLOCK_UNUSED:
  6780. if (pctx->blk == pctx->blk2)
  6781. pctx->blk2 = 0;
  6782. else
  6783. problem = PR_5_BLOCK_RANGE_UNUSED;
  6784. break;
  6785. case PR_5_BLOCK_USED:
  6786. if (pctx->blk == pctx->blk2)
  6787. pctx->blk2 = 0;
  6788. else
  6789. problem = PR_5_BLOCK_RANGE_USED;
  6790. break;
  6791. case PR_5_INODE_UNUSED:
  6792. if (pctx->ino == pctx->ino2)
  6793. pctx->ino2 = 0;
  6794. else
  6795. problem = PR_5_INODE_RANGE_UNUSED;
  6796. break;
  6797. case PR_5_INODE_USED:
  6798. if (pctx->ino == pctx->ino2)
  6799. pctx->ino2 = 0;
  6800. else
  6801. problem = PR_5_INODE_RANGE_USED;
  6802. break;
  6803. }
  6804. fix_problem(ctx, problem, pctx);
  6805. pctx->blk = pctx->blk2 = NO_BLK;
  6806. pctx->ino = pctx->ino2 = 0;
  6807. }
  6808. static void check_block_bitmaps(e2fsck_t ctx)
  6809. {
  6810. ext2_filsys fs = ctx->fs;
  6811. blk_t i;
  6812. int *free_array;
  6813. int group = 0;
  6814. unsigned int blocks = 0;
  6815. unsigned int free_blocks = 0;
  6816. int group_free = 0;
  6817. int actual, bitmap;
  6818. struct problem_context pctx;
  6819. int problem, save_problem, fixit, had_problem;
  6820. errcode_t retval;
  6821. clear_problem_context(&pctx);
  6822. free_array = (int *) e2fsck_allocate_memory(ctx,
  6823. fs->group_desc_count * sizeof(int), "free block count array");
  6824. if ((fs->super->s_first_data_block <
  6825. ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
  6826. (fs->super->s_blocks_count-1 >
  6827. ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
  6828. pctx.num = 1;
  6829. pctx.blk = fs->super->s_first_data_block;
  6830. pctx.blk2 = fs->super->s_blocks_count -1;
  6831. pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
  6832. pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
  6833. fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
  6834. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  6835. return;
  6836. }
  6837. if ((fs->super->s_first_data_block <
  6838. ext2fs_get_block_bitmap_start(fs->block_map)) ||
  6839. (fs->super->s_blocks_count-1 >
  6840. ext2fs_get_block_bitmap_end(fs->block_map))) {
  6841. pctx.num = 2;
  6842. pctx.blk = fs->super->s_first_data_block;
  6843. pctx.blk2 = fs->super->s_blocks_count -1;
  6844. pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
  6845. pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
  6846. fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
  6847. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  6848. return;
  6849. }
  6850. redo_counts:
  6851. had_problem = 0;
  6852. save_problem = 0;
  6853. pctx.blk = pctx.blk2 = NO_BLK;
  6854. for (i = fs->super->s_first_data_block;
  6855. i < fs->super->s_blocks_count;
  6856. i++) {
  6857. actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
  6858. bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
  6859. if (actual == bitmap)
  6860. goto do_counts;
  6861. if (!actual && bitmap) {
  6862. /*
  6863. * Block not used, but marked in use in the bitmap.
  6864. */
  6865. problem = PR_5_BLOCK_UNUSED;
  6866. } else {
  6867. /*
  6868. * Block used, but not marked in use in the bitmap.
  6869. */
  6870. problem = PR_5_BLOCK_USED;
  6871. }
  6872. if (pctx.blk == NO_BLK) {
  6873. pctx.blk = pctx.blk2 = i;
  6874. save_problem = problem;
  6875. } else {
  6876. if ((problem == save_problem) &&
  6877. (pctx.blk2 == i-1))
  6878. pctx.blk2++;
  6879. else {
  6880. print_bitmap_problem(ctx, save_problem, &pctx);
  6881. pctx.blk = pctx.blk2 = i;
  6882. save_problem = problem;
  6883. }
  6884. }
  6885. ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
  6886. had_problem++;
  6887. do_counts:
  6888. if (!bitmap) {
  6889. group_free++;
  6890. free_blocks++;
  6891. }
  6892. blocks ++;
  6893. if ((blocks == fs->super->s_blocks_per_group) ||
  6894. (i == fs->super->s_blocks_count-1)) {
  6895. free_array[group] = group_free;
  6896. group ++;
  6897. blocks = 0;
  6898. group_free = 0;
  6899. if (ctx->progress)
  6900. if ((ctx->progress)(ctx, 5, group,
  6901. fs->group_desc_count*2))
  6902. return;
  6903. }
  6904. }
  6905. if (pctx.blk != NO_BLK)
  6906. print_bitmap_problem(ctx, save_problem, &pctx);
  6907. if (had_problem)
  6908. fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
  6909. else
  6910. fixit = -1;
  6911. ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
  6912. if (fixit == 1) {
  6913. ext2fs_free_block_bitmap(fs->block_map);
  6914. retval = ext2fs_copy_bitmap(ctx->block_found_map,
  6915. &fs->block_map);
  6916. if (retval) {
  6917. clear_problem_context(&pctx);
  6918. fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
  6919. ctx->flags |= E2F_FLAG_ABORT;
  6920. return;
  6921. }
  6922. ext2fs_set_bitmap_padding(fs->block_map);
  6923. ext2fs_mark_bb_dirty(fs);
  6924. /* Redo the counts */
  6925. blocks = 0; free_blocks = 0; group_free = 0; group = 0;
  6926. memset(free_array, 0, fs->group_desc_count * sizeof(int));
  6927. goto redo_counts;
  6928. } else if (fixit == 0)
  6929. ext2fs_unmark_valid(fs);
  6930. for (i = 0; i < fs->group_desc_count; i++) {
  6931. if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
  6932. pctx.group = i;
  6933. pctx.blk = fs->group_desc[i].bg_free_blocks_count;
  6934. pctx.blk2 = free_array[i];
  6935. if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
  6936. &pctx)) {
  6937. fs->group_desc[i].bg_free_blocks_count =
  6938. free_array[i];
  6939. ext2fs_mark_super_dirty(fs);
  6940. } else
  6941. ext2fs_unmark_valid(fs);
  6942. }
  6943. }
  6944. if (free_blocks != fs->super->s_free_blocks_count) {
  6945. pctx.group = 0;
  6946. pctx.blk = fs->super->s_free_blocks_count;
  6947. pctx.blk2 = free_blocks;
  6948. if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
  6949. fs->super->s_free_blocks_count = free_blocks;
  6950. ext2fs_mark_super_dirty(fs);
  6951. } else
  6952. ext2fs_unmark_valid(fs);
  6953. }
  6954. ext2fs_free_mem(&free_array);
  6955. }
  6956. static void check_inode_bitmaps(e2fsck_t ctx)
  6957. {
  6958. ext2_filsys fs = ctx->fs;
  6959. ext2_ino_t i;
  6960. unsigned int free_inodes = 0;
  6961. int group_free = 0;
  6962. int dirs_count = 0;
  6963. int group = 0;
  6964. unsigned int inodes = 0;
  6965. int *free_array;
  6966. int *dir_array;
  6967. int actual, bitmap;
  6968. errcode_t retval;
  6969. struct problem_context pctx;
  6970. int problem, save_problem, fixit, had_problem;
  6971. clear_problem_context(&pctx);
  6972. free_array = (int *) e2fsck_allocate_memory(ctx,
  6973. fs->group_desc_count * sizeof(int), "free inode count array");
  6974. dir_array = (int *) e2fsck_allocate_memory(ctx,
  6975. fs->group_desc_count * sizeof(int), "directory count array");
  6976. if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
  6977. (fs->super->s_inodes_count >
  6978. ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
  6979. pctx.num = 3;
  6980. pctx.blk = 1;
  6981. pctx.blk2 = fs->super->s_inodes_count;
  6982. pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
  6983. pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
  6984. fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
  6985. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  6986. return;
  6987. }
  6988. if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
  6989. (fs->super->s_inodes_count >
  6990. ext2fs_get_inode_bitmap_end(fs->inode_map))) {
  6991. pctx.num = 4;
  6992. pctx.blk = 1;
  6993. pctx.blk2 = fs->super->s_inodes_count;
  6994. pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
  6995. pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
  6996. fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
  6997. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  6998. return;
  6999. }
  7000. redo_counts:
  7001. had_problem = 0;
  7002. save_problem = 0;
  7003. pctx.ino = pctx.ino2 = 0;
  7004. for (i = 1; i <= fs->super->s_inodes_count; i++) {
  7005. actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
  7006. bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
  7007. if (actual == bitmap)
  7008. goto do_counts;
  7009. if (!actual && bitmap) {
  7010. /*
  7011. * Inode wasn't used, but marked in bitmap
  7012. */
  7013. problem = PR_5_INODE_UNUSED;
  7014. } else /* if (actual && !bitmap) */ {
  7015. /*
  7016. * Inode used, but not in bitmap
  7017. */
  7018. problem = PR_5_INODE_USED;
  7019. }
  7020. if (pctx.ino == 0) {
  7021. pctx.ino = pctx.ino2 = i;
  7022. save_problem = problem;
  7023. } else {
  7024. if ((problem == save_problem) &&
  7025. (pctx.ino2 == i-1))
  7026. pctx.ino2++;
  7027. else {
  7028. print_bitmap_problem(ctx, save_problem, &pctx);
  7029. pctx.ino = pctx.ino2 = i;
  7030. save_problem = problem;
  7031. }
  7032. }
  7033. ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
  7034. had_problem++;
  7035. do_counts:
  7036. if (!bitmap) {
  7037. group_free++;
  7038. free_inodes++;
  7039. } else {
  7040. if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
  7041. dirs_count++;
  7042. }
  7043. inodes++;
  7044. if ((inodes == fs->super->s_inodes_per_group) ||
  7045. (i == fs->super->s_inodes_count)) {
  7046. free_array[group] = group_free;
  7047. dir_array[group] = dirs_count;
  7048. group ++;
  7049. inodes = 0;
  7050. group_free = 0;
  7051. dirs_count = 0;
  7052. if (ctx->progress)
  7053. if ((ctx->progress)(ctx, 5,
  7054. group + fs->group_desc_count,
  7055. fs->group_desc_count*2))
  7056. return;
  7057. }
  7058. }
  7059. if (pctx.ino)
  7060. print_bitmap_problem(ctx, save_problem, &pctx);
  7061. if (had_problem)
  7062. fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
  7063. else
  7064. fixit = -1;
  7065. ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
  7066. if (fixit == 1) {
  7067. ext2fs_free_inode_bitmap(fs->inode_map);
  7068. retval = ext2fs_copy_bitmap(ctx->inode_used_map,
  7069. &fs->inode_map);
  7070. if (retval) {
  7071. clear_problem_context(&pctx);
  7072. fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
  7073. ctx->flags |= E2F_FLAG_ABORT;
  7074. return;
  7075. }
  7076. ext2fs_set_bitmap_padding(fs->inode_map);
  7077. ext2fs_mark_ib_dirty(fs);
  7078. /* redo counts */
  7079. inodes = 0; free_inodes = 0; group_free = 0;
  7080. dirs_count = 0; group = 0;
  7081. memset(free_array, 0, fs->group_desc_count * sizeof(int));
  7082. memset(dir_array, 0, fs->group_desc_count * sizeof(int));
  7083. goto redo_counts;
  7084. } else if (fixit == 0)
  7085. ext2fs_unmark_valid(fs);
  7086. for (i = 0; i < fs->group_desc_count; i++) {
  7087. if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
  7088. pctx.group = i;
  7089. pctx.ino = fs->group_desc[i].bg_free_inodes_count;
  7090. pctx.ino2 = free_array[i];
  7091. if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
  7092. &pctx)) {
  7093. fs->group_desc[i].bg_free_inodes_count =
  7094. free_array[i];
  7095. ext2fs_mark_super_dirty(fs);
  7096. } else
  7097. ext2fs_unmark_valid(fs);
  7098. }
  7099. if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
  7100. pctx.group = i;
  7101. pctx.ino = fs->group_desc[i].bg_used_dirs_count;
  7102. pctx.ino2 = dir_array[i];
  7103. if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
  7104. &pctx)) {
  7105. fs->group_desc[i].bg_used_dirs_count =
  7106. dir_array[i];
  7107. ext2fs_mark_super_dirty(fs);
  7108. } else
  7109. ext2fs_unmark_valid(fs);
  7110. }
  7111. }
  7112. if (free_inodes != fs->super->s_free_inodes_count) {
  7113. pctx.group = -1;
  7114. pctx.ino = fs->super->s_free_inodes_count;
  7115. pctx.ino2 = free_inodes;
  7116. if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
  7117. fs->super->s_free_inodes_count = free_inodes;
  7118. ext2fs_mark_super_dirty(fs);
  7119. } else
  7120. ext2fs_unmark_valid(fs);
  7121. }
  7122. ext2fs_free_mem(&free_array);
  7123. ext2fs_free_mem(&dir_array);
  7124. }
  7125. static void check_inode_end(e2fsck_t ctx)
  7126. {
  7127. ext2_filsys fs = ctx->fs;
  7128. ext2_ino_t end, save_inodes_count, i;
  7129. struct problem_context pctx;
  7130. clear_problem_context(&pctx);
  7131. end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
  7132. pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
  7133. &save_inodes_count);
  7134. if (pctx.errcode) {
  7135. pctx.num = 1;
  7136. fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
  7137. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  7138. return;
  7139. }
  7140. if (save_inodes_count == end)
  7141. return;
  7142. for (i = save_inodes_count + 1; i <= end; i++) {
  7143. if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
  7144. if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
  7145. for (i = save_inodes_count + 1; i <= end; i++)
  7146. ext2fs_mark_inode_bitmap(fs->inode_map,
  7147. i);
  7148. ext2fs_mark_ib_dirty(fs);
  7149. } else
  7150. ext2fs_unmark_valid(fs);
  7151. break;
  7152. }
  7153. }
  7154. pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
  7155. save_inodes_count, 0);
  7156. if (pctx.errcode) {
  7157. pctx.num = 2;
  7158. fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
  7159. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  7160. return;
  7161. }
  7162. }
  7163. static void check_block_end(e2fsck_t ctx)
  7164. {
  7165. ext2_filsys fs = ctx->fs;
  7166. blk_t end, save_blocks_count, i;
  7167. struct problem_context pctx;
  7168. clear_problem_context(&pctx);
  7169. end = fs->block_map->start +
  7170. (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
  7171. pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
  7172. &save_blocks_count);
  7173. if (pctx.errcode) {
  7174. pctx.num = 3;
  7175. fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
  7176. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  7177. return;
  7178. }
  7179. if (save_blocks_count == end)
  7180. return;
  7181. for (i = save_blocks_count + 1; i <= end; i++) {
  7182. if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
  7183. if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
  7184. for (i = save_blocks_count + 1; i <= end; i++)
  7185. ext2fs_mark_block_bitmap(fs->block_map,
  7186. i);
  7187. ext2fs_mark_bb_dirty(fs);
  7188. } else
  7189. ext2fs_unmark_valid(fs);
  7190. break;
  7191. }
  7192. }
  7193. pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
  7194. save_blocks_count, 0);
  7195. if (pctx.errcode) {
  7196. pctx.num = 4;
  7197. fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
  7198. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  7199. return;
  7200. }
  7201. }
  7202. static void e2fsck_pass5(e2fsck_t ctx)
  7203. {
  7204. struct problem_context pctx;
  7205. /* Pass 5 */
  7206. clear_problem_context(&pctx);
  7207. if (!(ctx->options & E2F_OPT_PREEN))
  7208. fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
  7209. if (ctx->progress)
  7210. if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
  7211. return;
  7212. e2fsck_read_bitmaps(ctx);
  7213. check_block_bitmaps(ctx);
  7214. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  7215. return;
  7216. check_inode_bitmaps(ctx);
  7217. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  7218. return;
  7219. check_inode_end(ctx);
  7220. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  7221. return;
  7222. check_block_end(ctx);
  7223. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  7224. return;
  7225. ext2fs_free_inode_bitmap(ctx->inode_used_map);
  7226. ctx->inode_used_map = 0;
  7227. ext2fs_free_inode_bitmap(ctx->inode_dir_map);
  7228. ctx->inode_dir_map = 0;
  7229. ext2fs_free_block_bitmap(ctx->block_found_map);
  7230. ctx->block_found_map = 0;
  7231. }
  7232. /*
  7233. * problem.c --- report filesystem problems to the user
  7234. */
  7235. #define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */
  7236. #define PR_NO_OK 0x000002 /* If user answers no, don't make fs invalid */
  7237. #define PR_NO_DEFAULT 0x000004 /* Default to no */
  7238. #define PR_MSG_ONLY 0x000008 /* Print message only */
  7239. /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
  7240. #define PR_FATAL 0x001000 /* Fatal error */
  7241. #define PR_AFTER_CODE 0x002000 /* After asking the first question, */
  7242. /* ask another */
  7243. #define PR_PREEN_NOMSG 0x004000 /* Don't print a message if we're preening */
  7244. #define PR_NOCOLLATE 0x008000 /* Don't collate answers for this latch */
  7245. #define PR_NO_NOMSG 0x010000 /* Don't print a message if e2fsck -n */
  7246. #define PR_PREEN_NO 0x020000 /* Use No as an answer if preening */
  7247. #define PR_PREEN_NOHDR 0x040000 /* Don't print the preen header */
  7248. #define PROMPT_NONE 0
  7249. #define PROMPT_FIX 1
  7250. #define PROMPT_CLEAR 2
  7251. #define PROMPT_RELOCATE 3
  7252. #define PROMPT_ALLOCATE 4
  7253. #define PROMPT_EXPAND 5
  7254. #define PROMPT_CONNECT 6
  7255. #define PROMPT_CREATE 7
  7256. #define PROMPT_SALVAGE 8
  7257. #define PROMPT_TRUNCATE 9
  7258. #define PROMPT_CLEAR_INODE 10
  7259. #define PROMPT_ABORT 11
  7260. #define PROMPT_SPLIT 12
  7261. #define PROMPT_CONTINUE 13
  7262. #define PROMPT_CLONE 14
  7263. #define PROMPT_DELETE 15
  7264. #define PROMPT_SUPPRESS 16
  7265. #define PROMPT_UNLINK 17
  7266. #define PROMPT_CLEAR_HTREE 18
  7267. #define PROMPT_RECREATE 19
  7268. #define PROMPT_NULL 20
  7269. struct e2fsck_problem {
  7270. problem_t e2p_code;
  7271. const char * e2p_description;
  7272. char prompt;
  7273. int flags;
  7274. problem_t second_code;
  7275. };
  7276. struct latch_descr {
  7277. int latch_code;
  7278. problem_t question;
  7279. problem_t end_message;
  7280. int flags;
  7281. };
  7282. /*
  7283. * These are the prompts which are used to ask the user if they want
  7284. * to fix a problem.
  7285. */
  7286. static const char * const prompt[] = {
  7287. N_("(no prompt)"), /* 0 */
  7288. N_("Fix"), /* 1 */
  7289. N_("Clear"), /* 2 */
  7290. N_("Relocate"), /* 3 */
  7291. N_("Allocate"), /* 4 */
  7292. N_("Expand"), /* 5 */
  7293. N_("Connect to /lost+found"), /* 6 */
  7294. N_("Create"), /* 7 */
  7295. N_("Salvage"), /* 8 */
  7296. N_("Truncate"), /* 9 */
  7297. N_("Clear inode"), /* 10 */
  7298. N_("Abort"), /* 11 */
  7299. N_("Split"), /* 12 */
  7300. N_("Continue"), /* 13 */
  7301. N_("Clone multiply-claimed blocks"), /* 14 */
  7302. N_("Delete file"), /* 15 */
  7303. N_("Suppress messages"),/* 16 */
  7304. N_("Unlink"), /* 17 */
  7305. N_("Clear HTree index"),/* 18 */
  7306. N_("Recreate"), /* 19 */
  7307. "", /* 20 */
  7308. };
  7309. /*
  7310. * These messages are printed when we are preen mode and we will be
  7311. * automatically fixing the problem.
  7312. */
  7313. static const char * const preen_msg[] = {
  7314. N_("(NONE)"), /* 0 */
  7315. N_("FIXED"), /* 1 */
  7316. N_("CLEARED"), /* 2 */
  7317. N_("RELOCATED"), /* 3 */
  7318. N_("ALLOCATED"), /* 4 */
  7319. N_("EXPANDED"), /* 5 */
  7320. N_("RECONNECTED"), /* 6 */
  7321. N_("CREATED"), /* 7 */
  7322. N_("SALVAGED"), /* 8 */
  7323. N_("TRUNCATED"), /* 9 */
  7324. N_("INODE CLEARED"), /* 10 */
  7325. N_("ABORTED"), /* 11 */
  7326. N_("SPLIT"), /* 12 */
  7327. N_("CONTINUING"), /* 13 */
  7328. N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
  7329. N_("FILE DELETED"), /* 15 */
  7330. N_("SUPPRESSED"), /* 16 */
  7331. N_("UNLINKED"), /* 17 */
  7332. N_("HTREE INDEX CLEARED"),/* 18 */
  7333. N_("WILL RECREATE"), /* 19 */
  7334. "", /* 20 */
  7335. };
  7336. static const struct e2fsck_problem problem_table[] = {
  7337. /* Pre-Pass 1 errors */
  7338. /* Block bitmap not in group */
  7339. { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
  7340. PROMPT_RELOCATE, PR_LATCH_RELOC },
  7341. /* Inode bitmap not in group */
  7342. { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
  7343. PROMPT_RELOCATE, PR_LATCH_RELOC },
  7344. /* Inode table not in group */
  7345. { PR_0_ITABLE_NOT_GROUP,
  7346. N_("@i table for @g %g is not in @g. (@b %b)\n"
  7347. "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
  7348. PROMPT_RELOCATE, PR_LATCH_RELOC },
  7349. /* Superblock corrupt */
  7350. { PR_0_SB_CORRUPT,
  7351. N_("\nThe @S could not be read or does not describe a correct ext2\n"
  7352. "@f. If the @v is valid and it really contains an ext2\n"
  7353. "@f (and not swap or ufs or something else), then the @S\n"
  7354. "is corrupt, and you might try running e2fsck with an alternate @S:\n"
  7355. " e2fsck -b %S <@v>\n\n"),
  7356. PROMPT_NONE, PR_FATAL },
  7357. /* Filesystem size is wrong */
  7358. { PR_0_FS_SIZE_WRONG,
  7359. N_("The @f size (according to the @S) is %b @bs\n"
  7360. "The physical size of the @v is %c @bs\n"
  7361. "Either the @S or the partition table is likely to be corrupt!\n"),
  7362. PROMPT_ABORT, 0 },
  7363. /* Fragments not supported */
  7364. { PR_0_NO_FRAGMENTS,
  7365. N_("@S @b_size = %b, fragsize = %c.\n"
  7366. "This version of e2fsck does not support fragment sizes different\n"
  7367. "from the @b size.\n"),
  7368. PROMPT_NONE, PR_FATAL },
  7369. /* Bad blocks_per_group */
  7370. { PR_0_BLOCKS_PER_GROUP,
  7371. N_("@S @bs_per_group = %b, should have been %c\n"),
  7372. PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
  7373. /* Bad first_data_block */
  7374. { PR_0_FIRST_DATA_BLOCK,
  7375. N_("@S first_data_@b = %b, should have been %c\n"),
  7376. PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
  7377. /* Adding UUID to filesystem */
  7378. { PR_0_ADD_UUID,
  7379. N_("@f did not have a UUID; generating one.\n\n"),
  7380. PROMPT_NONE, 0 },
  7381. /* Relocate hint */
  7382. { PR_0_RELOCATE_HINT,
  7383. N_("Note: if several inode or block bitmap blocks or part\n"
  7384. "of the inode table require relocation, you may wish to try\n"
  7385. "running e2fsck with the '-b %S' option first. The problem\n"
  7386. "may lie only with the primary block group descriptors, and\n"
  7387. "the backup block group descriptors may be OK.\n\n"),
  7388. PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
  7389. /* Miscellaneous superblock corruption */
  7390. { PR_0_MISC_CORRUPT_SUPER,
  7391. N_("Corruption found in @S. (%s = %N).\n"),
  7392. PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
  7393. /* Error determing physical device size of filesystem */
  7394. { PR_0_GETSIZE_ERROR,
  7395. N_("Error determining size of the physical @v: %m\n"),
  7396. PROMPT_NONE, PR_FATAL },
  7397. /* Inode count in superblock is incorrect */
  7398. { PR_0_INODE_COUNT_WRONG,
  7399. N_("@i count in @S is %i, @s %j.\n"),
  7400. PROMPT_FIX, 0 },
  7401. { PR_0_HURD_CLEAR_FILETYPE,
  7402. N_("The Hurd does not support the filetype feature.\n"),
  7403. PROMPT_CLEAR, 0 },
  7404. /* Journal inode is invalid */
  7405. { PR_0_JOURNAL_BAD_INODE,
  7406. N_("@S has an @n ext3 @j (@i %i).\n"),
  7407. PROMPT_CLEAR, PR_PREEN_OK },
  7408. /* The external journal has (unsupported) multiple filesystems */
  7409. { PR_0_JOURNAL_UNSUPP_MULTIFS,
  7410. N_("External @j has multiple @f users (unsupported).\n"),
  7411. PROMPT_NONE, PR_FATAL },
  7412. /* Can't find external journal */
  7413. { PR_0_CANT_FIND_JOURNAL,
  7414. N_("Can't find external @j\n"),
  7415. PROMPT_NONE, PR_FATAL },
  7416. /* External journal has bad superblock */
  7417. { PR_0_EXT_JOURNAL_BAD_SUPER,
  7418. N_("External @j has bad @S\n"),
  7419. PROMPT_NONE, PR_FATAL },
  7420. /* Superblock has a bad journal UUID */
  7421. { PR_0_JOURNAL_BAD_UUID,
  7422. N_("External @j does not support this @f\n"),
  7423. PROMPT_NONE, PR_FATAL },
  7424. /* Journal has an unknown superblock type */
  7425. { PR_0_JOURNAL_UNSUPP_SUPER,
  7426. N_("Ext3 @j @S is unknown type %N (unsupported).\n"
  7427. "It is likely that your copy of e2fsck is old and/or doesn't "
  7428. "support this @j format.\n"
  7429. "It is also possible the @j @S is corrupt.\n"),
  7430. PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
  7431. /* Journal superblock is corrupt */
  7432. { PR_0_JOURNAL_BAD_SUPER,
  7433. N_("Ext3 @j @S is corrupt.\n"),
  7434. PROMPT_FIX, PR_PREEN_OK },
  7435. /* Superblock flag should be cleared */
  7436. { PR_0_JOURNAL_HAS_JOURNAL,
  7437. N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
  7438. PROMPT_CLEAR, PR_PREEN_OK },
  7439. /* Superblock flag is incorrect */
  7440. { PR_0_JOURNAL_RECOVER_SET,
  7441. N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
  7442. PROMPT_CLEAR, PR_PREEN_OK },
  7443. /* Journal has data, but recovery flag is clear */
  7444. { PR_0_JOURNAL_RECOVERY_CLEAR,
  7445. N_("ext3 recovery flag is clear, but @j has data.\n"),
  7446. PROMPT_NONE, 0 },
  7447. /* Ask if we should clear the journal */
  7448. { PR_0_JOURNAL_RESET_JOURNAL,
  7449. N_("Clear @j"),
  7450. PROMPT_NULL, PR_PREEN_NOMSG },
  7451. /* Ask if we should run the journal anyway */
  7452. { PR_0_JOURNAL_RUN,
  7453. N_("Run @j anyway"),
  7454. PROMPT_NULL, 0 },
  7455. /* Run the journal by default */
  7456. { PR_0_JOURNAL_RUN_DEFAULT,
  7457. N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
  7458. PROMPT_NONE, 0 },
  7459. /* Clearing orphan inode */
  7460. { PR_0_ORPHAN_CLEAR_INODE,
  7461. N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
  7462. PROMPT_NONE, 0 },
  7463. /* Illegal block found in orphaned inode */
  7464. { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
  7465. N_("@I @b #%B (%b) found in @o @i %i.\n"),
  7466. PROMPT_NONE, 0 },
  7467. /* Already cleared block found in orphaned inode */
  7468. { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
  7469. N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
  7470. PROMPT_NONE, 0 },
  7471. /* Illegal orphan inode in superblock */
  7472. { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
  7473. N_("@I @o @i %i in @S.\n"),
  7474. PROMPT_NONE, 0 },
  7475. /* Illegal inode in orphaned inode list */
  7476. { PR_0_ORPHAN_ILLEGAL_INODE,
  7477. N_("@I @i %i in @o @i list.\n"),
  7478. PROMPT_NONE, 0 },
  7479. /* Filesystem revision is 0, but feature flags are set */
  7480. { PR_0_FS_REV_LEVEL,
  7481. N_("@f has feature flag(s) set, but is a revision 0 @f. "),
  7482. PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
  7483. /* Journal superblock has an unknown read-only feature flag set */
  7484. { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
  7485. N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
  7486. PROMPT_ABORT, 0 },
  7487. /* Journal superblock has an unknown incompatible feature flag set */
  7488. { PR_0_JOURNAL_UNSUPP_INCOMPAT,
  7489. N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
  7490. PROMPT_ABORT, 0 },
  7491. /* Journal has unsupported version number */
  7492. { PR_0_JOURNAL_UNSUPP_VERSION,
  7493. N_("@j version not supported by this e2fsck.\n"),
  7494. PROMPT_ABORT, 0 },
  7495. /* Moving journal to hidden file */
  7496. { PR_0_MOVE_JOURNAL,
  7497. N_("Moving @j from /%s to hidden @i.\n\n"),
  7498. PROMPT_NONE, 0 },
  7499. /* Error moving journal to hidden file */
  7500. { PR_0_ERR_MOVE_JOURNAL,
  7501. N_("Error moving @j: %m\n\n"),
  7502. PROMPT_NONE, 0 },
  7503. /* Clearing V2 journal superblock */
  7504. { PR_0_CLEAR_V2_JOURNAL,
  7505. N_("Found @n V2 @j @S fields (from V1 @j).\n"
  7506. "Clearing fields beyond the V1 @j @S...\n\n"),
  7507. PROMPT_NONE, 0 },
  7508. /* Backup journal inode blocks */
  7509. { PR_0_BACKUP_JNL,
  7510. N_("Backing up @j @i @b information.\n\n"),
  7511. PROMPT_NONE, 0 },
  7512. /* Reserved blocks w/o resize_inode */
  7513. { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
  7514. N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
  7515. "is %N; @s zero. "),
  7516. PROMPT_FIX, 0 },
  7517. /* Resize_inode not enabled, but resize inode is non-zero */
  7518. { PR_0_CLEAR_RESIZE_INODE,
  7519. N_("Resize_@i not enabled, but the resize @i is non-zero. "),
  7520. PROMPT_CLEAR, 0 },
  7521. /* Resize inode invalid */
  7522. { PR_0_RESIZE_INODE_INVALID,
  7523. N_("Resize @i not valid. "),
  7524. PROMPT_RECREATE, 0 },
  7525. /* Pass 1 errors */
  7526. /* Pass 1: Checking inodes, blocks, and sizes */
  7527. { PR_1_PASS_HEADER,
  7528. N_("Pass 1: Checking @is, @bs, and sizes\n"),
  7529. PROMPT_NONE, 0 },
  7530. /* Root directory is not an inode */
  7531. { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
  7532. PROMPT_CLEAR, 0 },
  7533. /* Root directory has dtime set */
  7534. { PR_1_ROOT_DTIME,
  7535. N_("@r has dtime set (probably due to old mke2fs). "),
  7536. PROMPT_FIX, PR_PREEN_OK },
  7537. /* Reserved inode has bad mode */
  7538. { PR_1_RESERVED_BAD_MODE,
  7539. N_("Reserved @i %i (%Q) has @n mode. "),
  7540. PROMPT_CLEAR, PR_PREEN_OK },
  7541. /* Deleted inode has zero dtime */
  7542. { PR_1_ZERO_DTIME,
  7543. N_("@D @i %i has zero dtime. "),
  7544. PROMPT_FIX, PR_PREEN_OK },
  7545. /* Inode in use, but dtime set */
  7546. { PR_1_SET_DTIME,
  7547. N_("@i %i is in use, but has dtime set. "),
  7548. PROMPT_FIX, PR_PREEN_OK },
  7549. /* Zero-length directory */
  7550. { PR_1_ZERO_LENGTH_DIR,
  7551. N_("@i %i is a @z @d. "),
  7552. PROMPT_CLEAR, PR_PREEN_OK },
  7553. /* Block bitmap conflicts with some other fs block */
  7554. { PR_1_BB_CONFLICT,
  7555. N_("@g %g's @b @B at %b @C.\n"),
  7556. PROMPT_RELOCATE, 0 },
  7557. /* Inode bitmap conflicts with some other fs block */
  7558. { PR_1_IB_CONFLICT,
  7559. N_("@g %g's @i @B at %b @C.\n"),
  7560. PROMPT_RELOCATE, 0 },
  7561. /* Inode table conflicts with some other fs block */
  7562. { PR_1_ITABLE_CONFLICT,
  7563. N_("@g %g's @i table at %b @C.\n"),
  7564. PROMPT_RELOCATE, 0 },
  7565. /* Block bitmap is on a bad block */
  7566. { PR_1_BB_BAD_BLOCK,
  7567. N_("@g %g's @b @B (%b) is bad. "),
  7568. PROMPT_RELOCATE, 0 },
  7569. /* Inode bitmap is on a bad block */
  7570. { PR_1_IB_BAD_BLOCK,
  7571. N_("@g %g's @i @B (%b) is bad. "),
  7572. PROMPT_RELOCATE, 0 },
  7573. /* Inode has incorrect i_size */
  7574. { PR_1_BAD_I_SIZE,
  7575. N_("@i %i, i_size is %Is, @s %N. "),
  7576. PROMPT_FIX, PR_PREEN_OK },
  7577. /* Inode has incorrect i_blocks */
  7578. { PR_1_BAD_I_BLOCKS,
  7579. N_("@i %i, i_@bs is %Ib, @s %N. "),
  7580. PROMPT_FIX, PR_PREEN_OK },
  7581. /* Illegal blocknumber in inode */
  7582. { PR_1_ILLEGAL_BLOCK_NUM,
  7583. N_("@I @b #%B (%b) in @i %i. "),
  7584. PROMPT_CLEAR, PR_LATCH_BLOCK },
  7585. /* Block number overlaps fs metadata */
  7586. { PR_1_BLOCK_OVERLAPS_METADATA,
  7587. N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
  7588. PROMPT_CLEAR, PR_LATCH_BLOCK },
  7589. /* Inode has illegal blocks (latch question) */
  7590. { PR_1_INODE_BLOCK_LATCH,
  7591. N_("@i %i has illegal @b(s). "),
  7592. PROMPT_CLEAR, 0 },
  7593. /* Too many bad blocks in inode */
  7594. { PR_1_TOO_MANY_BAD_BLOCKS,
  7595. N_("Too many illegal @bs in @i %i.\n"),
  7596. PROMPT_CLEAR_INODE, PR_NO_OK },
  7597. /* Illegal block number in bad block inode */
  7598. { PR_1_BB_ILLEGAL_BLOCK_NUM,
  7599. N_("@I @b #%B (%b) in bad @b @i. "),
  7600. PROMPT_CLEAR, PR_LATCH_BBLOCK },
  7601. /* Bad block inode has illegal blocks (latch question) */
  7602. { PR_1_INODE_BBLOCK_LATCH,
  7603. N_("Bad @b @i has illegal @b(s). "),
  7604. PROMPT_CLEAR, 0 },
  7605. /* Duplicate or bad blocks in use! */
  7606. { PR_1_DUP_BLOCKS_PREENSTOP,
  7607. N_("Duplicate or bad @b in use!\n"),
  7608. PROMPT_NONE, 0 },
  7609. /* Bad block used as bad block indirect block */
  7610. { PR_1_BBINODE_BAD_METABLOCK,
  7611. N_("Bad @b %b used as bad @b @i indirect @b. "),
  7612. PROMPT_CLEAR, PR_LATCH_BBLOCK },
  7613. /* Inconsistency can't be fixed prompt */
  7614. { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
  7615. N_("\nThe bad @b @i has probably been corrupted. You probably\n"
  7616. "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
  7617. "in the @f.\n"),
  7618. PROMPT_CONTINUE, PR_PREEN_NOMSG },
  7619. /* Bad primary block */
  7620. { PR_1_BAD_PRIMARY_BLOCK,
  7621. N_("\nIf the @b is really bad, the @f cannot be fixed.\n"),
  7622. PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
  7623. /* Bad primary block prompt */
  7624. { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
  7625. N_("You can remove this @b from the bad @b list and hope\n"
  7626. "that the @b is really OK. But there are no guarantees.\n\n"),
  7627. PROMPT_CLEAR, PR_PREEN_NOMSG },
  7628. /* Bad primary superblock */
  7629. { PR_1_BAD_PRIMARY_SUPERBLOCK,
  7630. N_("The primary @S (%b) is on the bad @b list.\n"),
  7631. PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
  7632. /* Bad primary block group descriptors */
  7633. { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
  7634. N_("Block %b in the primary @g descriptors "
  7635. "is on the bad @b list\n"),
  7636. PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
  7637. /* Bad superblock in group */
  7638. { PR_1_BAD_SUPERBLOCK,
  7639. N_("Warning: Group %g's @S (%b) is bad.\n"),
  7640. PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
  7641. /* Bad block group descriptors in group */
  7642. { PR_1_BAD_GROUP_DESCRIPTORS,
  7643. N_("Warning: Group %g's copy of the @g descriptors has a bad "
  7644. "@b (%b).\n"),
  7645. PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
  7646. /* Block claimed for no reason */
  7647. { PR_1_PROGERR_CLAIMED_BLOCK,
  7648. N_("Programming error? @b #%b claimed for no reason in "
  7649. "process_bad_@b.\n"),
  7650. PROMPT_NONE, PR_PREEN_OK },
  7651. /* Error allocating blocks for relocating metadata */
  7652. { PR_1_RELOC_BLOCK_ALLOCATE,
  7653. N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
  7654. PROMPT_NONE, PR_PREEN_OK },
  7655. /* Error allocating block buffer during relocation process */
  7656. { PR_1_RELOC_MEMORY_ALLOCATE,
  7657. N_("@A @b buffer for relocating %s\n"),
  7658. PROMPT_NONE, PR_PREEN_OK },
  7659. /* Relocating metadata group information from X to Y */
  7660. { PR_1_RELOC_FROM_TO,
  7661. N_("Relocating @g %g's %s from %b to %c...\n"),
  7662. PROMPT_NONE, PR_PREEN_OK },
  7663. /* Relocating metatdata group information to X */
  7664. { PR_1_RELOC_TO,
  7665. N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
  7666. PROMPT_NONE, PR_PREEN_OK },
  7667. /* Block read error during relocation process */
  7668. { PR_1_RELOC_READ_ERR,
  7669. N_("Warning: could not read @b %b of %s: %m\n"),
  7670. PROMPT_NONE, PR_PREEN_OK },
  7671. /* Block write error during relocation process */
  7672. { PR_1_RELOC_WRITE_ERR,
  7673. N_("Warning: could not write @b %b for %s: %m\n"),
  7674. PROMPT_NONE, PR_PREEN_OK },
  7675. /* Error allocating inode bitmap */
  7676. { PR_1_ALLOCATE_IBITMAP_ERROR,
  7677. N_("@A @i @B (%N): %m\n"),
  7678. PROMPT_NONE, PR_FATAL },
  7679. /* Error allocating block bitmap */
  7680. { PR_1_ALLOCATE_BBITMAP_ERROR,
  7681. N_("@A @b @B (%N): %m\n"),
  7682. PROMPT_NONE, PR_FATAL },
  7683. /* Error allocating icount structure */
  7684. { PR_1_ALLOCATE_ICOUNT,
  7685. N_("@A icount link information: %m\n"),
  7686. PROMPT_NONE, PR_FATAL },
  7687. /* Error allocating dbcount */
  7688. { PR_1_ALLOCATE_DBCOUNT,
  7689. N_("@A @d @b array: %m\n"),
  7690. PROMPT_NONE, PR_FATAL },
  7691. /* Error while scanning inodes */
  7692. { PR_1_ISCAN_ERROR,
  7693. N_("Error while scanning @is (%i): %m\n"),
  7694. PROMPT_NONE, PR_FATAL },
  7695. /* Error while iterating over blocks */
  7696. { PR_1_BLOCK_ITERATE,
  7697. N_("Error while iterating over @bs in @i %i: %m\n"),
  7698. PROMPT_NONE, PR_FATAL },
  7699. /* Error while storing inode count information */
  7700. { PR_1_ICOUNT_STORE,
  7701. N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
  7702. PROMPT_NONE, PR_FATAL },
  7703. /* Error while storing directory block information */
  7704. { PR_1_ADD_DBLOCK,
  7705. N_("Error storing @d @b information "
  7706. "(@i=%i, @b=%b, num=%N): %m\n"),
  7707. PROMPT_NONE, PR_FATAL },
  7708. /* Error while reading inode (for clearing) */
  7709. { PR_1_READ_INODE,
  7710. N_("Error reading @i %i: %m\n"),
  7711. PROMPT_NONE, PR_FATAL },
  7712. /* Suppress messages prompt */
  7713. { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
  7714. /* Imagic flag set on an inode when filesystem doesn't support it */
  7715. { PR_1_SET_IMAGIC,
  7716. N_("@i %i has imagic flag set. "),
  7717. PROMPT_CLEAR, 0 },
  7718. /* Immutable flag set on a device or socket inode */
  7719. { PR_1_SET_IMMUTABLE,
  7720. N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
  7721. "or append-only flag set. "),
  7722. PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
  7723. /* Compression flag set on an inode when filesystem doesn't support it */
  7724. { PR_1_COMPR_SET,
  7725. N_("@i %i has @cion flag set on @f without @cion support. "),
  7726. PROMPT_CLEAR, 0 },
  7727. /* Non-zero size for device, fifo or socket inode */
  7728. { PR_1_SET_NONZSIZE,
  7729. N_("Special (@v/socket/fifo) @i %i has non-zero size. "),
  7730. PROMPT_FIX, PR_PREEN_OK },
  7731. /* Filesystem revision is 0, but feature flags are set */
  7732. { PR_1_FS_REV_LEVEL,
  7733. N_("@f has feature flag(s) set, but is a revision 0 @f. "),
  7734. PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
  7735. /* Journal inode is not in use, but contains data */
  7736. { PR_1_JOURNAL_INODE_NOT_CLEAR,
  7737. N_("@j @i is not in use, but contains data. "),
  7738. PROMPT_CLEAR, PR_PREEN_OK },
  7739. /* Journal has bad mode */
  7740. { PR_1_JOURNAL_BAD_MODE,
  7741. N_("@j is not regular file. "),
  7742. PROMPT_FIX, PR_PREEN_OK },
  7743. /* Deal with inodes that were part of orphan linked list */
  7744. { PR_1_LOW_DTIME,
  7745. N_("@i %i was part of the @o @i list. "),
  7746. PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
  7747. /* Deal with inodes that were part of corrupted orphan linked
  7748. list (latch question) */
  7749. { PR_1_ORPHAN_LIST_REFUGEES,
  7750. N_("@is that were part of a corrupted orphan linked list found. "),
  7751. PROMPT_FIX, 0 },
  7752. /* Error allocating refcount structure */
  7753. { PR_1_ALLOCATE_REFCOUNT,
  7754. N_("@A refcount structure (%N): %m\n"),
  7755. PROMPT_NONE, PR_FATAL },
  7756. /* Error reading extended attribute block */
  7757. { PR_1_READ_EA_BLOCK,
  7758. N_("Error reading @a @b %b for @i %i. "),
  7759. PROMPT_CLEAR, 0 },
  7760. /* Invalid extended attribute block */
  7761. { PR_1_BAD_EA_BLOCK,
  7762. N_("@i %i has a bad @a @b %b. "),
  7763. PROMPT_CLEAR, 0 },
  7764. /* Error reading Extended Attribute block while fixing refcount */
  7765. { PR_1_EXTATTR_READ_ABORT,
  7766. N_("Error reading @a @b %b (%m). "),
  7767. PROMPT_ABORT, 0 },
  7768. /* Extended attribute reference count incorrect */
  7769. { PR_1_EXTATTR_REFCOUNT,
  7770. N_("@a @b %b has reference count %B, @s %N. "),
  7771. PROMPT_FIX, 0 },
  7772. /* Error writing Extended Attribute block while fixing refcount */
  7773. { PR_1_EXTATTR_WRITE,
  7774. N_("Error writing @a @b %b (%m). "),
  7775. PROMPT_ABORT, 0 },
  7776. /* Multiple EA blocks not supported */
  7777. { PR_1_EA_MULTI_BLOCK,
  7778. N_("@a @b %b has h_@bs > 1. "),
  7779. PROMPT_CLEAR, 0},
  7780. /* Error allocating EA region allocation structure */
  7781. { PR_1_EA_ALLOC_REGION,
  7782. N_("@A @a @b %b. "),
  7783. PROMPT_ABORT, 0},
  7784. /* Error EA allocation collision */
  7785. { PR_1_EA_ALLOC_COLLISION,
  7786. N_("@a @b %b is corrupt (allocation collision). "),
  7787. PROMPT_CLEAR, 0},
  7788. /* Bad extended attribute name */
  7789. { PR_1_EA_BAD_NAME,
  7790. N_("@a @b %b is corrupt (@n name). "),
  7791. PROMPT_CLEAR, 0},
  7792. /* Bad extended attribute value */
  7793. { PR_1_EA_BAD_VALUE,
  7794. N_("@a @b %b is corrupt (@n value). "),
  7795. PROMPT_CLEAR, 0},
  7796. /* Inode too big (latch question) */
  7797. { PR_1_INODE_TOOBIG,
  7798. N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 },
  7799. /* Directory too big */
  7800. { PR_1_TOOBIG_DIR,
  7801. N_("@b #%B (%b) causes @d to be too big. "),
  7802. PROMPT_CLEAR, PR_LATCH_TOOBIG },
  7803. /* Regular file too big */
  7804. { PR_1_TOOBIG_REG,
  7805. N_("@b #%B (%b) causes file to be too big. "),
  7806. PROMPT_CLEAR, PR_LATCH_TOOBIG },
  7807. /* Symlink too big */
  7808. { PR_1_TOOBIG_SYMLINK,
  7809. N_("@b #%B (%b) causes symlink to be too big. "),
  7810. PROMPT_CLEAR, PR_LATCH_TOOBIG },
  7811. /* INDEX_FL flag set on a non-HTREE filesystem */
  7812. { PR_1_HTREE_SET,
  7813. N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
  7814. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  7815. /* INDEX_FL flag set on a non-directory */
  7816. { PR_1_HTREE_NODIR,
  7817. N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
  7818. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  7819. /* Invalid root node in HTREE directory */
  7820. { PR_1_HTREE_BADROOT,
  7821. N_("@h %i has an @n root node.\n"),
  7822. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  7823. /* Unsupported hash version in HTREE directory */
  7824. { PR_1_HTREE_HASHV,
  7825. N_("@h %i has an unsupported hash version (%N)\n"),
  7826. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  7827. /* Incompatible flag in HTREE root node */
  7828. { PR_1_HTREE_INCOMPAT,
  7829. N_("@h %i uses an incompatible htree root node flag.\n"),
  7830. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  7831. /* HTREE too deep */
  7832. { PR_1_HTREE_DEPTH,
  7833. N_("@h %i has a tree depth (%N) which is too big\n"),
  7834. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  7835. /* Bad block has indirect block that conflicts with filesystem block */
  7836. { PR_1_BB_FS_BLOCK,
  7837. N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
  7838. "@f metadata. "),
  7839. PROMPT_CLEAR, PR_LATCH_BBLOCK },
  7840. /* Resize inode failed */
  7841. { PR_1_RESIZE_INODE_CREATE,
  7842. N_("Resize @i (re)creation failed: %m."),
  7843. PROMPT_ABORT, 0 },
  7844. /* invalid inode->i_extra_isize */
  7845. { PR_1_EXTRA_ISIZE,
  7846. N_("@i %i has a extra size (%IS) which is @n\n"),
  7847. PROMPT_FIX, PR_PREEN_OK },
  7848. /* invalid ea entry->e_name_len */
  7849. { PR_1_ATTR_NAME_LEN,
  7850. N_("@a in @i %i has a namelen (%N) which is @n\n"),
  7851. PROMPT_CLEAR, PR_PREEN_OK },
  7852. /* invalid ea entry->e_value_size */
  7853. { PR_1_ATTR_VALUE_SIZE,
  7854. N_("@a in @i %i has a value size (%N) which is @n\n"),
  7855. PROMPT_CLEAR, PR_PREEN_OK },
  7856. /* invalid ea entry->e_value_offs */
  7857. { PR_1_ATTR_VALUE_OFFSET,
  7858. N_("@a in @i %i has a value offset (%N) which is @n\n"),
  7859. PROMPT_CLEAR, PR_PREEN_OK },
  7860. /* invalid ea entry->e_value_block */
  7861. { PR_1_ATTR_VALUE_BLOCK,
  7862. N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
  7863. PROMPT_CLEAR, PR_PREEN_OK },
  7864. /* invalid ea entry->e_hash */
  7865. { PR_1_ATTR_HASH,
  7866. N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
  7867. PROMPT_CLEAR, PR_PREEN_OK },
  7868. /* Pass 1b errors */
  7869. /* Pass 1B: Rescan for duplicate/bad blocks */
  7870. { PR_1B_PASS_HEADER,
  7871. N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
  7872. "Pass 1B: Rescanning for @m @bs\n"),
  7873. PROMPT_NONE, 0 },
  7874. /* Duplicate/bad block(s) header */
  7875. { PR_1B_DUP_BLOCK_HEADER,
  7876. N_("@m @b(s) in @i %i:"),
  7877. PROMPT_NONE, 0 },
  7878. /* Duplicate/bad block(s) in inode */
  7879. { PR_1B_DUP_BLOCK,
  7880. " %b",
  7881. PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
  7882. /* Duplicate/bad block(s) end */
  7883. { PR_1B_DUP_BLOCK_END,
  7884. "\n",
  7885. PROMPT_NONE, PR_PREEN_NOHDR },
  7886. /* Error while scanning inodes */
  7887. { PR_1B_ISCAN_ERROR,
  7888. N_("Error while scanning inodes (%i): %m\n"),
  7889. PROMPT_NONE, PR_FATAL },
  7890. /* Error allocating inode bitmap */
  7891. { PR_1B_ALLOCATE_IBITMAP_ERROR,
  7892. N_("@A @i @B (@i_dup_map): %m\n"),
  7893. PROMPT_NONE, PR_FATAL },
  7894. /* Error while iterating over blocks */
  7895. { PR_1B_BLOCK_ITERATE,
  7896. N_("Error while iterating over @bs in @i %i (%s): %m\n"),
  7897. PROMPT_NONE, 0 },
  7898. /* Error adjusting EA refcount */
  7899. { PR_1B_ADJ_EA_REFCOUNT,
  7900. N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
  7901. PROMPT_NONE, 0 },
  7902. /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
  7903. { PR_1C_PASS_HEADER,
  7904. N_("Pass 1C: Scanning directories for @is with @m @bs.\n"),
  7905. PROMPT_NONE, 0 },
  7906. /* Pass 1D: Reconciling multiply-claimed blocks */
  7907. { PR_1D_PASS_HEADER,
  7908. N_("Pass 1D: Reconciling @m @bs\n"),
  7909. PROMPT_NONE, 0 },
  7910. /* File has duplicate blocks */
  7911. { PR_1D_DUP_FILE,
  7912. N_("File %Q (@i #%i, mod time %IM)\n"
  7913. " has %B @m @b(s), shared with %N file(s):\n"),
  7914. PROMPT_NONE, 0 },
  7915. /* List of files sharing duplicate blocks */
  7916. { PR_1D_DUP_FILE_LIST,
  7917. N_("\t%Q (@i #%i, mod time %IM)\n"),
  7918. PROMPT_NONE, 0 },
  7919. /* File sharing blocks with filesystem metadata */
  7920. { PR_1D_SHARE_METADATA,
  7921. N_("\t<@f metadata>\n"),
  7922. PROMPT_NONE, 0 },
  7923. /* Report of how many duplicate/bad inodes */
  7924. { PR_1D_NUM_DUP_INODES,
  7925. N_("(There are %N @is containing @m @bs.)\n\n"),
  7926. PROMPT_NONE, 0 },
  7927. /* Duplicated blocks already reassigned or cloned. */
  7928. { PR_1D_DUP_BLOCKS_DEALT,
  7929. N_("@m @bs already reassigned or cloned.\n\n"),
  7930. PROMPT_NONE, 0 },
  7931. /* Clone duplicate/bad blocks? */
  7932. { PR_1D_CLONE_QUESTION,
  7933. "", PROMPT_CLONE, PR_NO_OK },
  7934. /* Delete file? */
  7935. { PR_1D_DELETE_QUESTION,
  7936. "", PROMPT_DELETE, 0 },
  7937. /* Couldn't clone file (error) */
  7938. { PR_1D_CLONE_ERROR,
  7939. N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
  7940. /* Pass 2 errors */
  7941. /* Pass 2: Checking directory structure */
  7942. { PR_2_PASS_HEADER,
  7943. N_("Pass 2: Checking @d structure\n"),
  7944. PROMPT_NONE, 0 },
  7945. /* Bad inode number for '.' */
  7946. { PR_2_BAD_INODE_DOT,
  7947. N_("@n @i number for '.' in @d @i %i.\n"),
  7948. PROMPT_FIX, 0 },
  7949. /* Directory entry has bad inode number */
  7950. { PR_2_BAD_INO,
  7951. N_("@E has @n @i #: %Di.\n"),
  7952. PROMPT_CLEAR, 0 },
  7953. /* Directory entry has deleted or unused inode */
  7954. { PR_2_UNUSED_INODE,
  7955. N_("@E has @D/unused @i %Di. "),
  7956. PROMPT_CLEAR, PR_PREEN_OK },
  7957. /* Directry entry is link to '.' */
  7958. { PR_2_LINK_DOT,
  7959. N_("@E @L to '.' "),
  7960. PROMPT_CLEAR, 0 },
  7961. /* Directory entry points to inode now located in a bad block */
  7962. { PR_2_BB_INODE,
  7963. N_("@E points to @i (%Di) located in a bad @b.\n"),
  7964. PROMPT_CLEAR, 0 },
  7965. /* Directory entry contains a link to a directory */
  7966. { PR_2_LINK_DIR,
  7967. N_("@E @L to @d %P (%Di).\n"),
  7968. PROMPT_CLEAR, 0 },
  7969. /* Directory entry contains a link to the root directry */
  7970. { PR_2_LINK_ROOT,
  7971. N_("@E @L to the @r.\n"),
  7972. PROMPT_CLEAR, 0 },
  7973. /* Directory entry has illegal characters in its name */
  7974. { PR_2_BAD_NAME,
  7975. N_("@E has illegal characters in its name.\n"),
  7976. PROMPT_FIX, 0 },
  7977. /* Missing '.' in directory inode */
  7978. { PR_2_MISSING_DOT,
  7979. N_("Missing '.' in @d @i %i.\n"),
  7980. PROMPT_FIX, 0 },
  7981. /* Missing '..' in directory inode */
  7982. { PR_2_MISSING_DOT_DOT,
  7983. N_("Missing '..' in @d @i %i.\n"),
  7984. PROMPT_FIX, 0 },
  7985. /* First entry in directory inode doesn't contain '.' */
  7986. { PR_2_1ST_NOT_DOT,
  7987. N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
  7988. PROMPT_FIX, 0 },
  7989. /* Second entry in directory inode doesn't contain '..' */
  7990. { PR_2_2ND_NOT_DOT_DOT,
  7991. N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
  7992. PROMPT_FIX, 0 },
  7993. /* i_faddr should be zero */
  7994. { PR_2_FADDR_ZERO,
  7995. N_("i_faddr @F %IF, @s zero.\n"),
  7996. PROMPT_CLEAR, 0 },
  7997. /* i_file_acl should be zero */
  7998. { PR_2_FILE_ACL_ZERO,
  7999. N_("i_file_acl @F %If, @s zero.\n"),
  8000. PROMPT_CLEAR, 0 },
  8001. /* i_dir_acl should be zero */
  8002. { PR_2_DIR_ACL_ZERO,
  8003. N_("i_dir_acl @F %Id, @s zero.\n"),
  8004. PROMPT_CLEAR, 0 },
  8005. /* i_frag should be zero */
  8006. { PR_2_FRAG_ZERO,
  8007. N_("i_frag @F %N, @s zero.\n"),
  8008. PROMPT_CLEAR, 0 },
  8009. /* i_fsize should be zero */
  8010. { PR_2_FSIZE_ZERO,
  8011. N_("i_fsize @F %N, @s zero.\n"),
  8012. PROMPT_CLEAR, 0 },
  8013. /* inode has bad mode */
  8014. { PR_2_BAD_MODE,
  8015. N_("@i %i (%Q) has @n mode (%Im).\n"),
  8016. PROMPT_CLEAR, 0 },
  8017. /* directory corrupted */
  8018. { PR_2_DIR_CORRUPTED,
  8019. N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
  8020. PROMPT_SALVAGE, 0 },
  8021. /* filename too long */
  8022. { PR_2_FILENAME_LONG,
  8023. N_("@d @i %i, @b %B, offset %N: filename too long\n"),
  8024. PROMPT_TRUNCATE, 0 },
  8025. /* Directory inode has a missing block (hole) */
  8026. { PR_2_DIRECTORY_HOLE,
  8027. N_("@d @i %i has an unallocated @b #%B. "),
  8028. PROMPT_ALLOCATE, 0 },
  8029. /* '.' is not NULL terminated */
  8030. { PR_2_DOT_NULL_TERM,
  8031. N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
  8032. PROMPT_FIX, 0 },
  8033. /* '..' is not NULL terminated */
  8034. { PR_2_DOT_DOT_NULL_TERM,
  8035. N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
  8036. PROMPT_FIX, 0 },
  8037. /* Illegal character device inode */
  8038. { PR_2_BAD_CHAR_DEV,
  8039. N_("@i %i (%Q) is an @I character @v.\n"),
  8040. PROMPT_CLEAR, 0 },
  8041. /* Illegal block device inode */
  8042. { PR_2_BAD_BLOCK_DEV,
  8043. N_("@i %i (%Q) is an @I @b @v.\n"),
  8044. PROMPT_CLEAR, 0 },
  8045. /* Duplicate '.' entry */
  8046. { PR_2_DUP_DOT,
  8047. N_("@E is duplicate '.' @e.\n"),
  8048. PROMPT_FIX, 0 },
  8049. /* Duplicate '..' entry */
  8050. { PR_2_DUP_DOT_DOT,
  8051. N_("@E is duplicate '..' @e.\n"),
  8052. PROMPT_FIX, 0 },
  8053. /* Internal error: couldn't find dir_info */
  8054. { PR_2_NO_DIRINFO,
  8055. N_("Internal error: cannot find dir_info for %i.\n"),
  8056. PROMPT_NONE, PR_FATAL },
  8057. /* Final rec_len is wrong */
  8058. { PR_2_FINAL_RECLEN,
  8059. N_("@E has rec_len of %Dr, @s %N.\n"),
  8060. PROMPT_FIX, 0 },
  8061. /* Error allocating icount structure */
  8062. { PR_2_ALLOCATE_ICOUNT,
  8063. N_("@A icount structure: %m\n"),
  8064. PROMPT_NONE, PR_FATAL },
  8065. /* Error iterating over directory blocks */
  8066. { PR_2_DBLIST_ITERATE,
  8067. N_("Error iterating over @d @bs: %m\n"),
  8068. PROMPT_NONE, PR_FATAL },
  8069. /* Error reading directory block */
  8070. { PR_2_READ_DIRBLOCK,
  8071. N_("Error reading @d @b %b (@i %i): %m\n"),
  8072. PROMPT_CONTINUE, 0 },
  8073. /* Error writing directory block */
  8074. { PR_2_WRITE_DIRBLOCK,
  8075. N_("Error writing @d @b %b (@i %i): %m\n"),
  8076. PROMPT_CONTINUE, 0 },
  8077. /* Error allocating new directory block */
  8078. { PR_2_ALLOC_DIRBOCK,
  8079. N_("@A new @d @b for @i %i (%s): %m\n"),
  8080. PROMPT_NONE, 0 },
  8081. /* Error deallocating inode */
  8082. { PR_2_DEALLOC_INODE,
  8083. N_("Error deallocating @i %i: %m\n"),
  8084. PROMPT_NONE, PR_FATAL },
  8085. /* Directory entry for '.' is big. Split? */
  8086. { PR_2_SPLIT_DOT,
  8087. N_("@d @e for '.' is big. "),
  8088. PROMPT_SPLIT, PR_NO_OK },
  8089. /* Illegal FIFO inode */
  8090. { PR_2_BAD_FIFO,
  8091. N_("@i %i (%Q) is an @I FIFO.\n"),
  8092. PROMPT_CLEAR, 0 },
  8093. /* Illegal socket inode */
  8094. { PR_2_BAD_SOCKET,
  8095. N_("@i %i (%Q) is an @I socket.\n"),
  8096. PROMPT_CLEAR, 0 },
  8097. /* Directory filetype not set */
  8098. { PR_2_SET_FILETYPE,
  8099. N_("Setting filetype for @E to %N.\n"),
  8100. PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
  8101. /* Directory filetype incorrect */
  8102. { PR_2_BAD_FILETYPE,
  8103. N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
  8104. PROMPT_FIX, 0 },
  8105. /* Directory filetype set on filesystem */
  8106. { PR_2_CLEAR_FILETYPE,
  8107. N_("@E has filetype set.\n"),
  8108. PROMPT_CLEAR, PR_PREEN_OK },
  8109. /* Directory filename is null */
  8110. { PR_2_NULL_NAME,
  8111. N_("@E has a @z name.\n"),
  8112. PROMPT_CLEAR, 0 },
  8113. /* Invalid symlink */
  8114. { PR_2_INVALID_SYMLINK,
  8115. N_("Symlink %Q (@i #%i) is @n.\n"),
  8116. PROMPT_CLEAR, 0 },
  8117. /* i_file_acl (extended attribute block) is bad */
  8118. { PR_2_FILE_ACL_BAD,
  8119. N_("@a @b @F @n (%If).\n"),
  8120. PROMPT_CLEAR, 0 },
  8121. /* Filesystem contains large files, but has no such flag in sb */
  8122. { PR_2_FEATURE_LARGE_FILES,
  8123. N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
  8124. PROMPT_FIX, 0 },
  8125. /* Node in HTREE directory not referenced */
  8126. { PR_2_HTREE_NOTREF,
  8127. N_("@p @h %d: node (%B) not referenced\n"),
  8128. PROMPT_NONE, 0 },
  8129. /* Node in HTREE directory referenced twice */
  8130. { PR_2_HTREE_DUPREF,
  8131. N_("@p @h %d: node (%B) referenced twice\n"),
  8132. PROMPT_NONE, 0 },
  8133. /* Node in HTREE directory has bad min hash */
  8134. { PR_2_HTREE_MIN_HASH,
  8135. N_("@p @h %d: node (%B) has bad min hash\n"),
  8136. PROMPT_NONE, 0 },
  8137. /* Node in HTREE directory has bad max hash */
  8138. { PR_2_HTREE_MAX_HASH,
  8139. N_("@p @h %d: node (%B) has bad max hash\n"),
  8140. PROMPT_NONE, 0 },
  8141. /* Clear invalid HTREE directory */
  8142. { PR_2_HTREE_CLEAR,
  8143. N_("@n @h %d (%q). "), PROMPT_CLEAR, 0 },
  8144. /* Bad block in htree interior node */
  8145. { PR_2_HTREE_BADBLK,
  8146. N_("@p @h %d (%q): bad @b number %b.\n"),
  8147. PROMPT_CLEAR_HTREE, 0 },
  8148. /* Error adjusting EA refcount */
  8149. { PR_2_ADJ_EA_REFCOUNT,
  8150. N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
  8151. PROMPT_NONE, PR_FATAL },
  8152. /* Invalid HTREE root node */
  8153. { PR_2_HTREE_BAD_ROOT,
  8154. N_("@p @h %d: root node is @n\n"),
  8155. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  8156. /* Invalid HTREE limit */
  8157. { PR_2_HTREE_BAD_LIMIT,
  8158. N_("@p @h %d: node (%B) has @n limit (%N)\n"),
  8159. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  8160. /* Invalid HTREE count */
  8161. { PR_2_HTREE_BAD_COUNT,
  8162. N_("@p @h %d: node (%B) has @n count (%N)\n"),
  8163. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  8164. /* HTREE interior node has out-of-order hashes in table */
  8165. { PR_2_HTREE_HASH_ORDER,
  8166. N_("@p @h %d: node (%B) has an unordered hash table\n"),
  8167. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  8168. /* Node in HTREE directory has invalid depth */
  8169. { PR_2_HTREE_BAD_DEPTH,
  8170. N_("@p @h %d: node (%B) has @n depth\n"),
  8171. PROMPT_NONE, 0 },
  8172. /* Duplicate directory entry found */
  8173. { PR_2_DUPLICATE_DIRENT,
  8174. N_("Duplicate @E found. "),
  8175. PROMPT_CLEAR, 0 },
  8176. /* Non-unique filename found */
  8177. { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
  8178. N_("@E has a non-unique filename.\nRename to %s"),
  8179. PROMPT_NULL, 0 },
  8180. /* Duplicate directory entry found */
  8181. { PR_2_REPORT_DUP_DIRENT,
  8182. N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
  8183. PROMPT_NONE, 0 },
  8184. /* Pass 3 errors */
  8185. /* Pass 3: Checking directory connectivity */
  8186. { PR_3_PASS_HEADER,
  8187. N_("Pass 3: Checking @d connectivity\n"),
  8188. PROMPT_NONE, 0 },
  8189. /* Root inode not allocated */
  8190. { PR_3_NO_ROOT_INODE,
  8191. N_("@r not allocated. "),
  8192. PROMPT_ALLOCATE, 0 },
  8193. /* No room in lost+found */
  8194. { PR_3_EXPAND_LF_DIR,
  8195. N_("No room in @l @d. "),
  8196. PROMPT_EXPAND, 0 },
  8197. /* Unconnected directory inode */
  8198. { PR_3_UNCONNECTED_DIR,
  8199. N_("Unconnected @d @i %i (%p)\n"),
  8200. PROMPT_CONNECT, 0 },
  8201. /* /lost+found not found */
  8202. { PR_3_NO_LF_DIR,
  8203. N_("/@l not found. "),
  8204. PROMPT_CREATE, PR_PREEN_OK },
  8205. /* .. entry is incorrect */
  8206. { PR_3_BAD_DOT_DOT,
  8207. N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
  8208. PROMPT_FIX, 0 },
  8209. /* Bad or non-existent /lost+found. Cannot reconnect */
  8210. { PR_3_NO_LPF,
  8211. N_("Bad or non-existent /@l. Cannot reconnect.\n"),
  8212. PROMPT_NONE, 0 },
  8213. /* Could not expand /lost+found */
  8214. { PR_3_CANT_EXPAND_LPF,
  8215. N_("Could not expand /@l: %m\n"),
  8216. PROMPT_NONE, 0 },
  8217. /* Could not reconnect inode */
  8218. { PR_3_CANT_RECONNECT,
  8219. N_("Could not reconnect %i: %m\n"),
  8220. PROMPT_NONE, 0 },
  8221. /* Error while trying to find /lost+found */
  8222. { PR_3_ERR_FIND_LPF,
  8223. N_("Error while trying to find /@l: %m\n"),
  8224. PROMPT_NONE, 0 },
  8225. /* Error in ext2fs_new_block while creating /lost+found */
  8226. { PR_3_ERR_LPF_NEW_BLOCK,
  8227. N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
  8228. PROMPT_NONE, 0 },
  8229. /* Error in ext2fs_new_inode while creating /lost+found */
  8230. { PR_3_ERR_LPF_NEW_INODE,
  8231. N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
  8232. PROMPT_NONE, 0 },
  8233. /* Error in ext2fs_new_dir_block while creating /lost+found */
  8234. { PR_3_ERR_LPF_NEW_DIR_BLOCK,
  8235. N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
  8236. PROMPT_NONE, 0 },
  8237. /* Error while writing directory block for /lost+found */
  8238. { PR_3_ERR_LPF_WRITE_BLOCK,
  8239. N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
  8240. PROMPT_NONE, 0 },
  8241. /* Error while adjusting inode count */
  8242. { PR_3_ADJUST_INODE,
  8243. N_("Error while adjusting @i count on @i %i\n"),
  8244. PROMPT_NONE, 0 },
  8245. /* Couldn't fix parent directory -- error */
  8246. { PR_3_FIX_PARENT_ERR,
  8247. N_("Couldn't fix parent of @i %i: %m\n\n"),
  8248. PROMPT_NONE, 0 },
  8249. /* Couldn't fix parent directory -- couldn't find it */
  8250. { PR_3_FIX_PARENT_NOFIND,
  8251. N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
  8252. PROMPT_NONE, 0 },
  8253. /* Error allocating inode bitmap */
  8254. { PR_3_ALLOCATE_IBITMAP_ERROR,
  8255. N_("@A @i @B (%N): %m\n"),
  8256. PROMPT_NONE, PR_FATAL },
  8257. /* Error creating root directory */
  8258. { PR_3_CREATE_ROOT_ERROR,
  8259. N_("Error creating root @d (%s): %m\n"),
  8260. PROMPT_NONE, PR_FATAL },
  8261. /* Error creating lost and found directory */
  8262. { PR_3_CREATE_LPF_ERROR,
  8263. N_("Error creating /@l @d (%s): %m\n"),
  8264. PROMPT_NONE, PR_FATAL },
  8265. /* Root inode is not directory; aborting */
  8266. { PR_3_ROOT_NOT_DIR_ABORT,
  8267. N_("@r is not a @d; aborting.\n"),
  8268. PROMPT_NONE, PR_FATAL },
  8269. /* Cannot proceed without a root inode. */
  8270. { PR_3_NO_ROOT_INODE_ABORT,
  8271. N_("Cannot proceed without a @r.\n"),
  8272. PROMPT_NONE, PR_FATAL },
  8273. /* Internal error: couldn't find dir_info */
  8274. { PR_3_NO_DIRINFO,
  8275. N_("Internal error: cannot find dir_info for %i.\n"),
  8276. PROMPT_NONE, PR_FATAL },
  8277. /* Lost+found not a directory */
  8278. { PR_3_LPF_NOTDIR,
  8279. N_("/@l is not a @d (ino=%i)\n"),
  8280. PROMPT_UNLINK, 0 },
  8281. /* Pass 3A Directory Optimization */
  8282. /* Pass 3A: Optimizing directories */
  8283. { PR_3A_PASS_HEADER,
  8284. N_("Pass 3A: Optimizing directories\n"),
  8285. PROMPT_NONE, PR_PREEN_NOMSG },
  8286. /* Error iterating over directories */
  8287. { PR_3A_OPTIMIZE_ITER,
  8288. N_("Failed to create dirs_to_hash iterator: %m"),
  8289. PROMPT_NONE, 0 },
  8290. /* Error rehash directory */
  8291. { PR_3A_OPTIMIZE_DIR_ERR,
  8292. N_("Failed to optimize directory %q (%d): %m"),
  8293. PROMPT_NONE, 0 },
  8294. /* Rehashing dir header */
  8295. { PR_3A_OPTIMIZE_DIR_HEADER,
  8296. N_("Optimizing directories: "),
  8297. PROMPT_NONE, PR_MSG_ONLY },
  8298. /* Rehashing directory %d */
  8299. { PR_3A_OPTIMIZE_DIR,
  8300. " %d",
  8301. PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
  8302. /* Rehashing dir end */
  8303. { PR_3A_OPTIMIZE_DIR_END,
  8304. "\n",
  8305. PROMPT_NONE, PR_PREEN_NOHDR },
  8306. /* Pass 4 errors */
  8307. /* Pass 4: Checking reference counts */
  8308. { PR_4_PASS_HEADER,
  8309. N_("Pass 4: Checking reference counts\n"),
  8310. PROMPT_NONE, 0 },
  8311. /* Unattached zero-length inode */
  8312. { PR_4_ZERO_LEN_INODE,
  8313. N_("@u @z @i %i. "),
  8314. PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
  8315. /* Unattached inode */
  8316. { PR_4_UNATTACHED_INODE,
  8317. N_("@u @i %i\n"),
  8318. PROMPT_CONNECT, 0 },
  8319. /* Inode ref count wrong */
  8320. { PR_4_BAD_REF_COUNT,
  8321. N_("@i %i ref count is %Il, @s %N. "),
  8322. PROMPT_FIX, PR_PREEN_OK },
  8323. { PR_4_INCONSISTENT_COUNT,
  8324. N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
  8325. "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
  8326. "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
  8327. "They @s the same!\n"),
  8328. PROMPT_NONE, 0 },
  8329. /* Pass 5 errors */
  8330. /* Pass 5: Checking group summary information */
  8331. { PR_5_PASS_HEADER,
  8332. N_("Pass 5: Checking @g summary information\n"),
  8333. PROMPT_NONE, 0 },
  8334. /* Padding at end of inode bitmap is not set. */
  8335. { PR_5_INODE_BMAP_PADDING,
  8336. N_("Padding at end of @i @B is not set. "),
  8337. PROMPT_FIX, PR_PREEN_OK },
  8338. /* Padding at end of block bitmap is not set. */
  8339. { PR_5_BLOCK_BMAP_PADDING,
  8340. N_("Padding at end of @b @B is not set. "),
  8341. PROMPT_FIX, PR_PREEN_OK },
  8342. /* Block bitmap differences header */
  8343. { PR_5_BLOCK_BITMAP_HEADER,
  8344. N_("@b @B differences: "),
  8345. PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
  8346. /* Block not used, but marked in bitmap */
  8347. { PR_5_BLOCK_UNUSED,
  8348. " -%b",
  8349. PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8350. /* Block used, but not marked used in bitmap */
  8351. { PR_5_BLOCK_USED,
  8352. " +%b",
  8353. PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8354. /* Block bitmap differences end */
  8355. { PR_5_BLOCK_BITMAP_END,
  8356. "\n",
  8357. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8358. /* Inode bitmap differences header */
  8359. { PR_5_INODE_BITMAP_HEADER,
  8360. N_("@i @B differences: "),
  8361. PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
  8362. /* Inode not used, but marked in bitmap */
  8363. { PR_5_INODE_UNUSED,
  8364. " -%i",
  8365. PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8366. /* Inode used, but not marked used in bitmap */
  8367. { PR_5_INODE_USED,
  8368. " +%i",
  8369. PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8370. /* Inode bitmap differences end */
  8371. { PR_5_INODE_BITMAP_END,
  8372. "\n",
  8373. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8374. /* Free inodes count for group wrong */
  8375. { PR_5_FREE_INODE_COUNT_GROUP,
  8376. N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
  8377. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8378. /* Directories count for group wrong */
  8379. { PR_5_FREE_DIR_COUNT_GROUP,
  8380. N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
  8381. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8382. /* Free inodes count wrong */
  8383. { PR_5_FREE_INODE_COUNT,
  8384. N_("Free @is count wrong (%i, counted=%j).\n"),
  8385. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8386. /* Free blocks count for group wrong */
  8387. { PR_5_FREE_BLOCK_COUNT_GROUP,
  8388. N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
  8389. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8390. /* Free blocks count wrong */
  8391. { PR_5_FREE_BLOCK_COUNT,
  8392. N_("Free @bs count wrong (%b, counted=%c).\n"),
  8393. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8394. /* Programming error: bitmap endpoints don't match */
  8395. { PR_5_BMAP_ENDPOINTS,
  8396. N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
  8397. "match calculated @B endpoints (%i, %j)\n"),
  8398. PROMPT_NONE, PR_FATAL },
  8399. /* Internal error: fudging end of bitmap */
  8400. { PR_5_FUDGE_BITMAP_ERROR,
  8401. N_("Internal error: fudging end of bitmap (%N)\n"),
  8402. PROMPT_NONE, PR_FATAL },
  8403. /* Error copying in replacement inode bitmap */
  8404. { PR_5_COPY_IBITMAP_ERROR,
  8405. N_("Error copying in replacement @i @B: %m\n"),
  8406. PROMPT_NONE, PR_FATAL },
  8407. /* Error copying in replacement block bitmap */
  8408. { PR_5_COPY_BBITMAP_ERROR,
  8409. N_("Error copying in replacement @b @B: %m\n"),
  8410. PROMPT_NONE, PR_FATAL },
  8411. /* Block range not used, but marked in bitmap */
  8412. { PR_5_BLOCK_RANGE_UNUSED,
  8413. " -(%b--%c)",
  8414. PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8415. /* Block range used, but not marked used in bitmap */
  8416. { PR_5_BLOCK_RANGE_USED,
  8417. " +(%b--%c)",
  8418. PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8419. /* Inode range not used, but marked in bitmap */
  8420. { PR_5_INODE_RANGE_UNUSED,
  8421. " -(%i--%j)",
  8422. PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8423. /* Inode range used, but not marked used in bitmap */
  8424. { PR_5_INODE_RANGE_USED,
  8425. " +(%i--%j)",
  8426. PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8427. { 0 }
  8428. };
  8429. /*
  8430. * This is the latch flags register. It allows several problems to be
  8431. * "latched" together. This means that the user has to answer but one
  8432. * question for the set of problems, and all of the associated
  8433. * problems will be either fixed or not fixed.
  8434. */
  8435. static struct latch_descr pr_latch_info[] = {
  8436. { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
  8437. { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
  8438. { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
  8439. { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
  8440. { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
  8441. { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
  8442. { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
  8443. { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
  8444. { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
  8445. { -1, 0, 0 },
  8446. };
  8447. static const struct e2fsck_problem *find_problem(problem_t code)
  8448. {
  8449. int i;
  8450. for (i=0; problem_table[i].e2p_code; i++) {
  8451. if (problem_table[i].e2p_code == code)
  8452. return &problem_table[i];
  8453. }
  8454. return 0;
  8455. }
  8456. static struct latch_descr *find_latch(int code)
  8457. {
  8458. int i;
  8459. for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
  8460. if (pr_latch_info[i].latch_code == code)
  8461. return &pr_latch_info[i];
  8462. }
  8463. return 0;
  8464. }
  8465. int end_problem_latch(e2fsck_t ctx, int mask)
  8466. {
  8467. struct latch_descr *ldesc;
  8468. struct problem_context pctx;
  8469. int answer = -1;
  8470. ldesc = find_latch(mask);
  8471. if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
  8472. clear_problem_context(&pctx);
  8473. answer = fix_problem(ctx, ldesc->end_message, &pctx);
  8474. }
  8475. ldesc->flags &= ~(PRL_VARIABLE);
  8476. return answer;
  8477. }
  8478. int set_latch_flags(int mask, int setflags, int clearflags)
  8479. {
  8480. struct latch_descr *ldesc;
  8481. ldesc = find_latch(mask);
  8482. if (!ldesc)
  8483. return -1;
  8484. ldesc->flags |= setflags;
  8485. ldesc->flags &= ~clearflags;
  8486. return 0;
  8487. }
  8488. void clear_problem_context(struct problem_context *ctx)
  8489. {
  8490. memset(ctx, 0, sizeof(struct problem_context));
  8491. ctx->blkcount = -1;
  8492. ctx->group = -1;
  8493. }
  8494. int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
  8495. {
  8496. ext2_filsys fs = ctx->fs;
  8497. const struct e2fsck_problem *ptr;
  8498. struct latch_descr *ldesc = 0;
  8499. const char *message;
  8500. int def_yn, answer, ans;
  8501. int print_answer = 0;
  8502. int suppress = 0;
  8503. ptr = find_problem(code);
  8504. if (!ptr) {
  8505. printf(_("Unhandled error code (0x%x)!\n"), code);
  8506. return 0;
  8507. }
  8508. def_yn = 1;
  8509. if ((ptr->flags & PR_NO_DEFAULT) ||
  8510. ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
  8511. (ctx->options & E2F_OPT_NO))
  8512. def_yn= 0;
  8513. /*
  8514. * Do special latch processing. This is where we ask the
  8515. * latch question, if it exists
  8516. */
  8517. if (ptr->flags & PR_LATCH_MASK) {
  8518. ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
  8519. if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
  8520. ans = fix_problem(ctx, ldesc->question, pctx);
  8521. if (ans == 1)
  8522. ldesc->flags |= PRL_YES;
  8523. if (ans == 0)
  8524. ldesc->flags |= PRL_NO;
  8525. ldesc->flags |= PRL_LATCHED;
  8526. }
  8527. if (ldesc->flags & PRL_SUPPRESS)
  8528. suppress++;
  8529. }
  8530. if ((ptr->flags & PR_PREEN_NOMSG) &&
  8531. (ctx->options & E2F_OPT_PREEN))
  8532. suppress++;
  8533. if ((ptr->flags & PR_NO_NOMSG) &&
  8534. (ctx->options & E2F_OPT_NO))
  8535. suppress++;
  8536. if (!suppress) {
  8537. message = ptr->e2p_description;
  8538. if ((ctx->options & E2F_OPT_PREEN) &&
  8539. !(ptr->flags & PR_PREEN_NOHDR)) {
  8540. printf("%s: ", ctx->device_name ?
  8541. ctx->device_name : ctx->filesystem_name);
  8542. }
  8543. if (*message)
  8544. print_e2fsck_message(ctx, _(message), pctx, 1);
  8545. }
  8546. if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
  8547. preenhalt(ctx);
  8548. if (ptr->flags & PR_FATAL)
  8549. bb_error_msg_and_die(0);
  8550. if (ptr->prompt == PROMPT_NONE) {
  8551. if (ptr->flags & PR_NOCOLLATE)
  8552. answer = -1;
  8553. else
  8554. answer = def_yn;
  8555. } else {
  8556. if (ctx->options & E2F_OPT_PREEN) {
  8557. answer = def_yn;
  8558. if (!(ptr->flags & PR_PREEN_NOMSG))
  8559. print_answer = 1;
  8560. } else if ((ptr->flags & PR_LATCH_MASK) &&
  8561. (ldesc->flags & (PRL_YES | PRL_NO))) {
  8562. if (!suppress)
  8563. print_answer = 1;
  8564. if (ldesc->flags & PRL_YES)
  8565. answer = 1;
  8566. else
  8567. answer = 0;
  8568. } else
  8569. answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
  8570. if (!answer && !(ptr->flags & PR_NO_OK))
  8571. ext2fs_unmark_valid(fs);
  8572. if (print_answer)
  8573. printf("%s.\n", answer ?
  8574. _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
  8575. }
  8576. if ((ptr->prompt == PROMPT_ABORT) && answer)
  8577. bb_error_msg_and_die(0);
  8578. if (ptr->flags & PR_AFTER_CODE)
  8579. answer = fix_problem(ctx, ptr->second_code, pctx);
  8580. return answer;
  8581. }
  8582. /*
  8583. * linux/fs/recovery.c
  8584. *
  8585. * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
  8586. */
  8587. /*
  8588. * Maintain information about the progress of the recovery job, so that
  8589. * the different passes can carry information between them.
  8590. */
  8591. struct recovery_info
  8592. {
  8593. tid_t start_transaction;
  8594. tid_t end_transaction;
  8595. int nr_replays;
  8596. int nr_revokes;
  8597. int nr_revoke_hits;
  8598. };
  8599. enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
  8600. static int do_one_pass(journal_t *journal,
  8601. struct recovery_info *info, enum passtype pass);
  8602. static int scan_revoke_records(journal_t *, struct buffer_head *,
  8603. tid_t, struct recovery_info *);
  8604. /*
  8605. * Read a block from the journal
  8606. */
  8607. static int jread(struct buffer_head **bhp, journal_t *journal,
  8608. unsigned int offset)
  8609. {
  8610. int err;
  8611. unsigned long blocknr;
  8612. struct buffer_head *bh;
  8613. *bhp = NULL;
  8614. err = journal_bmap(journal, offset, &blocknr);
  8615. if (err) {
  8616. printf("JBD: bad block at offset %u\n", offset);
  8617. return err;
  8618. }
  8619. bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
  8620. if (!bh)
  8621. return -ENOMEM;
  8622. if (!buffer_uptodate(bh)) {
  8623. /* If this is a brand new buffer, start readahead.
  8624. Otherwise, we assume we are already reading it. */
  8625. if (!buffer_req(bh))
  8626. do_readahead(journal, offset);
  8627. wait_on_buffer(bh);
  8628. }
  8629. if (!buffer_uptodate(bh)) {
  8630. printf("JBD: Failed to read block at offset %u\n", offset);
  8631. brelse(bh);
  8632. return -EIO;
  8633. }
  8634. *bhp = bh;
  8635. return 0;
  8636. }
  8637. /*
  8638. * Count the number of in-use tags in a journal descriptor block.
  8639. */
  8640. static int count_tags(struct buffer_head *bh, int size)
  8641. {
  8642. char * tagp;
  8643. journal_block_tag_t * tag;
  8644. int nr = 0;
  8645. tagp = &bh->b_data[sizeof(journal_header_t)];
  8646. while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
  8647. tag = (journal_block_tag_t *) tagp;
  8648. nr++;
  8649. tagp += sizeof(journal_block_tag_t);
  8650. if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
  8651. tagp += 16;
  8652. if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
  8653. break;
  8654. }
  8655. return nr;
  8656. }
  8657. /* Make sure we wrap around the log correctly! */
  8658. #define wrap(journal, var) \
  8659. do { \
  8660. if (var >= (journal)->j_last) \
  8661. var -= ((journal)->j_last - (journal)->j_first); \
  8662. } while (0)
  8663. /**
  8664. * int journal_recover(journal_t *journal) - recovers a on-disk journal
  8665. * @journal: the journal to recover
  8666. *
  8667. * The primary function for recovering the log contents when mounting a
  8668. * journaled device.
  8669. *
  8670. * Recovery is done in three passes. In the first pass, we look for the
  8671. * end of the log. In the second, we assemble the list of revoke
  8672. * blocks. In the third and final pass, we replay any un-revoked blocks
  8673. * in the log.
  8674. */
  8675. int journal_recover(journal_t *journal)
  8676. {
  8677. int err;
  8678. journal_superblock_t * sb;
  8679. struct recovery_info info;
  8680. memset(&info, 0, sizeof(info));
  8681. sb = journal->j_superblock;
  8682. /*
  8683. * The journal superblock's s_start field (the current log head)
  8684. * is always zero if, and only if, the journal was cleanly
  8685. * unmounted.
  8686. */
  8687. if (!sb->s_start) {
  8688. journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
  8689. return 0;
  8690. }
  8691. err = do_one_pass(journal, &info, PASS_SCAN);
  8692. if (!err)
  8693. err = do_one_pass(journal, &info, PASS_REVOKE);
  8694. if (!err)
  8695. err = do_one_pass(journal, &info, PASS_REPLAY);
  8696. /* Restart the log at the next transaction ID, thus invalidating
  8697. * any existing commit records in the log. */
  8698. journal->j_transaction_sequence = ++info.end_transaction;
  8699. journal_clear_revoke(journal);
  8700. sync_blockdev(journal->j_fs_dev);
  8701. return err;
  8702. }
  8703. static int do_one_pass(journal_t *journal,
  8704. struct recovery_info *info, enum passtype pass)
  8705. {
  8706. unsigned int first_commit_ID, next_commit_ID;
  8707. unsigned long next_log_block;
  8708. int err, success = 0;
  8709. journal_superblock_t * sb;
  8710. journal_header_t * tmp;
  8711. struct buffer_head * bh;
  8712. unsigned int sequence;
  8713. int blocktype;
  8714. /* Precompute the maximum metadata descriptors in a descriptor block */
  8715. int MAX_BLOCKS_PER_DESC;
  8716. MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
  8717. / sizeof(journal_block_tag_t));
  8718. /*
  8719. * First thing is to establish what we expect to find in the log
  8720. * (in terms of transaction IDs), and where (in terms of log
  8721. * block offsets): query the superblock.
  8722. */
  8723. sb = journal->j_superblock;
  8724. next_commit_ID = ntohl(sb->s_sequence);
  8725. next_log_block = ntohl(sb->s_start);
  8726. first_commit_ID = next_commit_ID;
  8727. if (pass == PASS_SCAN)
  8728. info->start_transaction = first_commit_ID;
  8729. /*
  8730. * Now we walk through the log, transaction by transaction,
  8731. * making sure that each transaction has a commit block in the
  8732. * expected place. Each complete transaction gets replayed back
  8733. * into the main filesystem.
  8734. */
  8735. while (1) {
  8736. int flags;
  8737. char * tagp;
  8738. journal_block_tag_t * tag;
  8739. struct buffer_head * obh;
  8740. struct buffer_head * nbh;
  8741. /* If we already know where to stop the log traversal,
  8742. * check right now that we haven't gone past the end of
  8743. * the log. */
  8744. if (pass != PASS_SCAN)
  8745. if (tid_geq(next_commit_ID, info->end_transaction))
  8746. break;
  8747. /* Skip over each chunk of the transaction looking
  8748. * either the next descriptor block or the final commit
  8749. * record. */
  8750. err = jread(&bh, journal, next_log_block);
  8751. if (err)
  8752. goto failed;
  8753. next_log_block++;
  8754. wrap(journal, next_log_block);
  8755. /* What kind of buffer is it?
  8756. *
  8757. * If it is a descriptor block, check that it has the
  8758. * expected sequence number. Otherwise, we're all done
  8759. * here. */
  8760. tmp = (journal_header_t *)bh->b_data;
  8761. if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
  8762. brelse(bh);
  8763. break;
  8764. }
  8765. blocktype = ntohl(tmp->h_blocktype);
  8766. sequence = ntohl(tmp->h_sequence);
  8767. if (sequence != next_commit_ID) {
  8768. brelse(bh);
  8769. break;
  8770. }
  8771. /* OK, we have a valid descriptor block which matches
  8772. * all of the sequence number checks. What are we going
  8773. * to do with it? That depends on the pass... */
  8774. switch(blocktype) {
  8775. case JFS_DESCRIPTOR_BLOCK:
  8776. /* If it is a valid descriptor block, replay it
  8777. * in pass REPLAY; otherwise, just skip over the
  8778. * blocks it describes. */
  8779. if (pass != PASS_REPLAY) {
  8780. next_log_block +=
  8781. count_tags(bh, journal->j_blocksize);
  8782. wrap(journal, next_log_block);
  8783. brelse(bh);
  8784. continue;
  8785. }
  8786. /* A descriptor block: we can now write all of
  8787. * the data blocks. Yay, useful work is finally
  8788. * getting done here! */
  8789. tagp = &bh->b_data[sizeof(journal_header_t)];
  8790. while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
  8791. <= journal->j_blocksize) {
  8792. unsigned long io_block;
  8793. tag = (journal_block_tag_t *) tagp;
  8794. flags = ntohl(tag->t_flags);
  8795. io_block = next_log_block++;
  8796. wrap(journal, next_log_block);
  8797. err = jread(&obh, journal, io_block);
  8798. if (err) {
  8799. /* Recover what we can, but
  8800. * report failure at the end. */
  8801. success = err;
  8802. printf("JBD: IO error %d recovering "
  8803. "block %ld in log\n",
  8804. err, io_block);
  8805. } else {
  8806. unsigned long blocknr;
  8807. blocknr = ntohl(tag->t_blocknr);
  8808. /* If the block has been
  8809. * revoked, then we're all done
  8810. * here. */
  8811. if (journal_test_revoke
  8812. (journal, blocknr,
  8813. next_commit_ID)) {
  8814. brelse(obh);
  8815. ++info->nr_revoke_hits;
  8816. goto skip_write;
  8817. }
  8818. /* Find a buffer for the new
  8819. * data being restored */
  8820. nbh = getblk(journal->j_fs_dev,
  8821. blocknr,
  8822. journal->j_blocksize);
  8823. if (nbh == NULL) {
  8824. printf("JBD: Out of memory "
  8825. "during recovery.\n");
  8826. err = -ENOMEM;
  8827. brelse(bh);
  8828. brelse(obh);
  8829. goto failed;
  8830. }
  8831. lock_buffer(nbh);
  8832. memcpy(nbh->b_data, obh->b_data,
  8833. journal->j_blocksize);
  8834. if (flags & JFS_FLAG_ESCAPE) {
  8835. *((unsigned int *)bh->b_data) =
  8836. htonl(JFS_MAGIC_NUMBER);
  8837. }
  8838. mark_buffer_uptodate(nbh, 1);
  8839. mark_buffer_dirty(nbh);
  8840. ++info->nr_replays;
  8841. /* ll_rw_block(WRITE, 1, &nbh); */
  8842. unlock_buffer(nbh);
  8843. brelse(obh);
  8844. brelse(nbh);
  8845. }
  8846. skip_write:
  8847. tagp += sizeof(journal_block_tag_t);
  8848. if (!(flags & JFS_FLAG_SAME_UUID))
  8849. tagp += 16;
  8850. if (flags & JFS_FLAG_LAST_TAG)
  8851. break;
  8852. }
  8853. brelse(bh);
  8854. continue;
  8855. case JFS_COMMIT_BLOCK:
  8856. /* Found an expected commit block: not much to
  8857. * do other than move on to the next sequence
  8858. * number. */
  8859. brelse(bh);
  8860. next_commit_ID++;
  8861. continue;
  8862. case JFS_REVOKE_BLOCK:
  8863. /* If we aren't in the REVOKE pass, then we can
  8864. * just skip over this block. */
  8865. if (pass != PASS_REVOKE) {
  8866. brelse(bh);
  8867. continue;
  8868. }
  8869. err = scan_revoke_records(journal, bh,
  8870. next_commit_ID, info);
  8871. brelse(bh);
  8872. if (err)
  8873. goto failed;
  8874. continue;
  8875. default:
  8876. goto done;
  8877. }
  8878. }
  8879. done:
  8880. /*
  8881. * We broke out of the log scan loop: either we came to the
  8882. * known end of the log or we found an unexpected block in the
  8883. * log. If the latter happened, then we know that the "current"
  8884. * transaction marks the end of the valid log.
  8885. */
  8886. if (pass == PASS_SCAN)
  8887. info->end_transaction = next_commit_ID;
  8888. else {
  8889. /* It's really bad news if different passes end up at
  8890. * different places (but possible due to IO errors). */
  8891. if (info->end_transaction != next_commit_ID) {
  8892. printf("JBD: recovery pass %d ended at "
  8893. "transaction %u, expected %u\n",
  8894. pass, next_commit_ID, info->end_transaction);
  8895. if (!success)
  8896. success = -EIO;
  8897. }
  8898. }
  8899. return success;
  8900. failed:
  8901. return err;
  8902. }
  8903. /* Scan a revoke record, marking all blocks mentioned as revoked. */
  8904. static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
  8905. tid_t sequence, struct recovery_info *info)
  8906. {
  8907. journal_revoke_header_t *header;
  8908. int offset, max;
  8909. header = (journal_revoke_header_t *) bh->b_data;
  8910. offset = sizeof(journal_revoke_header_t);
  8911. max = ntohl(header->r_count);
  8912. while (offset < max) {
  8913. unsigned long blocknr;
  8914. int err;
  8915. blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
  8916. offset += 4;
  8917. err = journal_set_revoke(journal, blocknr, sequence);
  8918. if (err)
  8919. return err;
  8920. ++info->nr_revokes;
  8921. }
  8922. return 0;
  8923. }
  8924. /*
  8925. * rehash.c --- rebuild hash tree directories
  8926. *
  8927. * This algorithm is designed for simplicity of implementation and to
  8928. * pack the directory as much as possible. It however requires twice
  8929. * as much memory as the size of the directory. The maximum size
  8930. * directory supported using a 4k blocksize is roughly a gigabyte, and
  8931. * so there may very well be problems with machines that don't have
  8932. * virtual memory, and obscenely large directories.
  8933. *
  8934. * An alternate algorithm which is much more disk intensive could be
  8935. * written, and probably will need to be written in the future. The
  8936. * design goals of such an algorithm are: (a) use (roughly) constant
  8937. * amounts of memory, no matter how large the directory, (b) the
  8938. * directory must be safe at all times, even if e2fsck is interrupted
  8939. * in the middle, (c) we must use minimal amounts of extra disk
  8940. * blocks. This pretty much requires an incremental approach, where
  8941. * we are reading from one part of the directory, and inserting into
  8942. * the front half. So the algorithm will have to keep track of a
  8943. * moving block boundary between the new tree and the old tree, and
  8944. * files will need to be moved from the old directory and inserted
  8945. * into the new tree. If the new directory requires space which isn't
  8946. * yet available, blocks from the beginning part of the old directory
  8947. * may need to be moved to the end of the directory to make room for
  8948. * the new tree:
  8949. *
  8950. * --------------------------------------------------------
  8951. * | new tree | | old tree |
  8952. * --------------------------------------------------------
  8953. * ^ ptr ^ptr
  8954. * tail new head old
  8955. *
  8956. * This is going to be a pain in the tuckus to implement, and will
  8957. * require a lot more disk accesses. So I'm going to skip it for now;
  8958. * it's only really going to be an issue for really, really big
  8959. * filesystems (when we reach the level of tens of millions of files
  8960. * in a single directory). It will probably be easier to simply
  8961. * require that e2fsck use VM first.
  8962. */
  8963. struct fill_dir_struct {
  8964. char *buf;
  8965. struct ext2_inode *inode;
  8966. int err;
  8967. e2fsck_t ctx;
  8968. struct hash_entry *harray;
  8969. int max_array, num_array;
  8970. int dir_size;
  8971. int compress;
  8972. ino_t parent;
  8973. };
  8974. struct hash_entry {
  8975. ext2_dirhash_t hash;
  8976. ext2_dirhash_t minor_hash;
  8977. struct ext2_dir_entry *dir;
  8978. };
  8979. struct out_dir {
  8980. int num;
  8981. int max;
  8982. char *buf;
  8983. ext2_dirhash_t *hashes;
  8984. };
  8985. static int fill_dir_block(ext2_filsys fs,
  8986. blk_t *block_nr,
  8987. e2_blkcnt_t blockcnt,
  8988. blk_t ref_block FSCK_ATTR((unused)),
  8989. int ref_offset FSCK_ATTR((unused)),
  8990. void *priv_data)
  8991. {
  8992. struct fill_dir_struct *fd = (struct fill_dir_struct *) priv_data;
  8993. struct hash_entry *new_array, *ent;
  8994. struct ext2_dir_entry *dirent;
  8995. char *dir;
  8996. unsigned int offset, dir_offset;
  8997. if (blockcnt < 0)
  8998. return 0;
  8999. offset = blockcnt * fs->blocksize;
  9000. if (offset + fs->blocksize > fd->inode->i_size) {
  9001. fd->err = EXT2_ET_DIR_CORRUPTED;
  9002. return BLOCK_ABORT;
  9003. }
  9004. dir = (fd->buf+offset);
  9005. if (HOLE_BLKADDR(*block_nr)) {
  9006. memset(dir, 0, fs->blocksize);
  9007. dirent = (struct ext2_dir_entry *) dir;
  9008. dirent->rec_len = fs->blocksize;
  9009. } else {
  9010. fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
  9011. if (fd->err)
  9012. return BLOCK_ABORT;
  9013. }
  9014. /* While the directory block is "hot", index it. */
  9015. dir_offset = 0;
  9016. while (dir_offset < fs->blocksize) {
  9017. dirent = (struct ext2_dir_entry *) (dir + dir_offset);
  9018. if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
  9019. (dirent->rec_len < 8) ||
  9020. ((dirent->rec_len % 4) != 0) ||
  9021. (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
  9022. fd->err = EXT2_ET_DIR_CORRUPTED;
  9023. return BLOCK_ABORT;
  9024. }
  9025. dir_offset += dirent->rec_len;
  9026. if (dirent->inode == 0)
  9027. continue;
  9028. if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
  9029. (dirent->name[0] == '.'))
  9030. continue;
  9031. if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
  9032. (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
  9033. fd->parent = dirent->inode;
  9034. continue;
  9035. }
  9036. if (fd->num_array >= fd->max_array) {
  9037. new_array = realloc(fd->harray,
  9038. sizeof(struct hash_entry) * (fd->max_array+500));
  9039. if (!new_array) {
  9040. fd->err = ENOMEM;
  9041. return BLOCK_ABORT;
  9042. }
  9043. fd->harray = new_array;
  9044. fd->max_array += 500;
  9045. }
  9046. ent = fd->harray + fd->num_array++;
  9047. ent->dir = dirent;
  9048. fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
  9049. if (fd->compress)
  9050. ent->hash = ent->minor_hash = 0;
  9051. else {
  9052. fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
  9053. dirent->name,
  9054. dirent->name_len & 0xFF,
  9055. fs->super->s_hash_seed,
  9056. &ent->hash, &ent->minor_hash);
  9057. if (fd->err)
  9058. return BLOCK_ABORT;
  9059. }
  9060. }
  9061. return 0;
  9062. }
  9063. /* Used for sorting the hash entry */
  9064. static int name_cmp(const void *a, const void *b)
  9065. {
  9066. const struct hash_entry *he_a = (const struct hash_entry *) a;
  9067. const struct hash_entry *he_b = (const struct hash_entry *) b;
  9068. int ret;
  9069. int min_len;
  9070. min_len = he_a->dir->name_len;
  9071. if (min_len > he_b->dir->name_len)
  9072. min_len = he_b->dir->name_len;
  9073. ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
  9074. if (ret == 0) {
  9075. if (he_a->dir->name_len > he_b->dir->name_len)
  9076. ret = 1;
  9077. else if (he_a->dir->name_len < he_b->dir->name_len)
  9078. ret = -1;
  9079. else
  9080. ret = he_b->dir->inode - he_a->dir->inode;
  9081. }
  9082. return ret;
  9083. }
  9084. /* Used for sorting the hash entry */
  9085. static int hash_cmp(const void *a, const void *b)
  9086. {
  9087. const struct hash_entry *he_a = (const struct hash_entry *) a;
  9088. const struct hash_entry *he_b = (const struct hash_entry *) b;
  9089. int ret;
  9090. if (he_a->hash > he_b->hash)
  9091. ret = 1;
  9092. else if (he_a->hash < he_b->hash)
  9093. ret = -1;
  9094. else {
  9095. if (he_a->minor_hash > he_b->minor_hash)
  9096. ret = 1;
  9097. else if (he_a->minor_hash < he_b->minor_hash)
  9098. ret = -1;
  9099. else
  9100. ret = name_cmp(a, b);
  9101. }
  9102. return ret;
  9103. }
  9104. static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
  9105. int blocks)
  9106. {
  9107. void *new_mem;
  9108. if (outdir->max) {
  9109. new_mem = realloc(outdir->buf, blocks * fs->blocksize);
  9110. if (!new_mem)
  9111. return ENOMEM;
  9112. outdir->buf = new_mem;
  9113. new_mem = realloc(outdir->hashes,
  9114. blocks * sizeof(ext2_dirhash_t));
  9115. if (!new_mem)
  9116. return ENOMEM;
  9117. outdir->hashes = new_mem;
  9118. } else {
  9119. outdir->buf = malloc(blocks * fs->blocksize);
  9120. outdir->hashes = malloc(blocks * sizeof(ext2_dirhash_t));
  9121. outdir->num = 0;
  9122. }
  9123. outdir->max = blocks;
  9124. return 0;
  9125. }
  9126. static void free_out_dir(struct out_dir *outdir)
  9127. {
  9128. free(outdir->buf);
  9129. free(outdir->hashes);
  9130. outdir->max = 0;
  9131. outdir->num =0;
  9132. }
  9133. static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
  9134. char ** ret)
  9135. {
  9136. errcode_t retval;
  9137. if (outdir->num >= outdir->max) {
  9138. retval = alloc_size_dir(fs, outdir, outdir->max + 50);
  9139. if (retval)
  9140. return retval;
  9141. }
  9142. *ret = outdir->buf + (outdir->num++ * fs->blocksize);
  9143. memset(*ret, 0, fs->blocksize);
  9144. return 0;
  9145. }
  9146. /*
  9147. * This function is used to make a unique filename. We do this by
  9148. * appending ~0, and then incrementing the number. However, we cannot
  9149. * expand the length of the filename beyond the padding available in
  9150. * the directory entry.
  9151. */
  9152. static void mutate_name(char *str, __u16 *len)
  9153. {
  9154. int i;
  9155. __u16 l = *len & 0xFF, h = *len & 0xff00;
  9156. /*
  9157. * First check to see if it looks the name has been mutated
  9158. * already
  9159. */
  9160. for (i = l-1; i > 0; i--) {
  9161. if (!isdigit(str[i]))
  9162. break;
  9163. }
  9164. if ((i == l-1) || (str[i] != '~')) {
  9165. if (((l-1) & 3) < 2)
  9166. l += 2;
  9167. else
  9168. l = (l+3) & ~3;
  9169. str[l-2] = '~';
  9170. str[l-1] = '0';
  9171. *len = l | h;
  9172. return;
  9173. }
  9174. for (i = l-1; i >= 0; i--) {
  9175. if (isdigit(str[i])) {
  9176. if (str[i] == '9')
  9177. str[i] = '0';
  9178. else {
  9179. str[i]++;
  9180. return;
  9181. }
  9182. continue;
  9183. }
  9184. if (i == 1) {
  9185. if (str[0] == 'z')
  9186. str[0] = 'A';
  9187. else if (str[0] == 'Z') {
  9188. str[0] = '~';
  9189. str[1] = '0';
  9190. } else
  9191. str[0]++;
  9192. } else if (i > 0) {
  9193. str[i] = '1';
  9194. str[i-1] = '~';
  9195. } else {
  9196. if (str[0] == '~')
  9197. str[0] = 'a';
  9198. else
  9199. str[0]++;
  9200. }
  9201. break;
  9202. }
  9203. }
  9204. static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
  9205. ext2_ino_t ino,
  9206. struct fill_dir_struct *fd)
  9207. {
  9208. struct problem_context pctx;
  9209. struct hash_entry *ent, *prev;
  9210. int i, j;
  9211. int fixed = 0;
  9212. char new_name[256];
  9213. __u16 new_len;
  9214. clear_problem_context(&pctx);
  9215. pctx.ino = ino;
  9216. for (i=1; i < fd->num_array; i++) {
  9217. ent = fd->harray + i;
  9218. prev = ent - 1;
  9219. if (!ent->dir->inode ||
  9220. ((ent->dir->name_len & 0xFF) !=
  9221. (prev->dir->name_len & 0xFF)) ||
  9222. (strncmp(ent->dir->name, prev->dir->name,
  9223. ent->dir->name_len & 0xFF)))
  9224. continue;
  9225. pctx.dirent = ent->dir;
  9226. if ((ent->dir->inode == prev->dir->inode) &&
  9227. fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
  9228. e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
  9229. ent->dir->inode = 0;
  9230. fixed++;
  9231. continue;
  9232. }
  9233. memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
  9234. new_len = ent->dir->name_len;
  9235. mutate_name(new_name, &new_len);
  9236. for (j=0; j < fd->num_array; j++) {
  9237. if ((i==j) ||
  9238. ((ent->dir->name_len & 0xFF) !=
  9239. (fd->harray[j].dir->name_len & 0xFF)) ||
  9240. (strncmp(new_name, fd->harray[j].dir->name,
  9241. new_len & 0xFF)))
  9242. continue;
  9243. mutate_name(new_name, &new_len);
  9244. j = -1;
  9245. }
  9246. new_name[new_len & 0xFF] = 0;
  9247. pctx.str = new_name;
  9248. if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
  9249. memcpy(ent->dir->name, new_name, new_len & 0xFF);
  9250. ent->dir->name_len = new_len;
  9251. ext2fs_dirhash(fs->super->s_def_hash_version,
  9252. ent->dir->name,
  9253. ent->dir->name_len & 0xFF,
  9254. fs->super->s_hash_seed,
  9255. &ent->hash, &ent->minor_hash);
  9256. fixed++;
  9257. }
  9258. }
  9259. return fixed;
  9260. }
  9261. static errcode_t copy_dir_entries(ext2_filsys fs,
  9262. struct fill_dir_struct *fd,
  9263. struct out_dir *outdir)
  9264. {
  9265. errcode_t retval;
  9266. char *block_start;
  9267. struct hash_entry *ent;
  9268. struct ext2_dir_entry *dirent;
  9269. int i, rec_len, left;
  9270. ext2_dirhash_t prev_hash;
  9271. int offset;
  9272. outdir->max = 0;
  9273. retval = alloc_size_dir(fs, outdir,
  9274. (fd->dir_size / fs->blocksize) + 2);
  9275. if (retval)
  9276. return retval;
  9277. outdir->num = fd->compress ? 0 : 1;
  9278. offset = 0;
  9279. outdir->hashes[0] = 0;
  9280. prev_hash = 1;
  9281. if ((retval = get_next_block(fs, outdir, &block_start)))
  9282. return retval;
  9283. dirent = (struct ext2_dir_entry *) block_start;
  9284. left = fs->blocksize;
  9285. for (i=0; i < fd->num_array; i++) {
  9286. ent = fd->harray + i;
  9287. if (ent->dir->inode == 0)
  9288. continue;
  9289. rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
  9290. if (rec_len > left) {
  9291. if (left)
  9292. dirent->rec_len += left;
  9293. if ((retval = get_next_block(fs, outdir,
  9294. &block_start)))
  9295. return retval;
  9296. offset = 0;
  9297. }
  9298. left = fs->blocksize - offset;
  9299. dirent = (struct ext2_dir_entry *) (block_start + offset);
  9300. if (offset == 0) {
  9301. if (ent->hash == prev_hash)
  9302. outdir->hashes[outdir->num-1] = ent->hash | 1;
  9303. else
  9304. outdir->hashes[outdir->num-1] = ent->hash;
  9305. }
  9306. dirent->inode = ent->dir->inode;
  9307. dirent->name_len = ent->dir->name_len;
  9308. dirent->rec_len = rec_len;
  9309. memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
  9310. offset += rec_len;
  9311. left -= rec_len;
  9312. if (left < 12) {
  9313. dirent->rec_len += left;
  9314. offset += left;
  9315. left = 0;
  9316. }
  9317. prev_hash = ent->hash;
  9318. }
  9319. if (left)
  9320. dirent->rec_len += left;
  9321. return 0;
  9322. }
  9323. static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
  9324. ext2_ino_t ino, ext2_ino_t parent)
  9325. {
  9326. struct ext2_dir_entry *dir;
  9327. struct ext2_dx_root_info *root;
  9328. struct ext2_dx_countlimit *limits;
  9329. int filetype = 0;
  9330. if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
  9331. filetype = EXT2_FT_DIR << 8;
  9332. memset(buf, 0, fs->blocksize);
  9333. dir = (struct ext2_dir_entry *) buf;
  9334. dir->inode = ino;
  9335. dir->name[0] = '.';
  9336. dir->name_len = 1 | filetype;
  9337. dir->rec_len = 12;
  9338. dir = (struct ext2_dir_entry *) (buf + 12);
  9339. dir->inode = parent;
  9340. dir->name[0] = '.';
  9341. dir->name[1] = '.';
  9342. dir->name_len = 2 | filetype;
  9343. dir->rec_len = fs->blocksize - 12;
  9344. root = (struct ext2_dx_root_info *) (buf+24);
  9345. root->reserved_zero = 0;
  9346. root->hash_version = fs->super->s_def_hash_version;
  9347. root->info_length = 8;
  9348. root->indirect_levels = 0;
  9349. root->unused_flags = 0;
  9350. limits = (struct ext2_dx_countlimit *) (buf+32);
  9351. limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
  9352. limits->count = 0;
  9353. return root;
  9354. }
  9355. static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
  9356. {
  9357. struct ext2_dir_entry *dir;
  9358. struct ext2_dx_countlimit *limits;
  9359. memset(buf, 0, fs->blocksize);
  9360. dir = (struct ext2_dir_entry *) buf;
  9361. dir->inode = 0;
  9362. dir->rec_len = fs->blocksize;
  9363. limits = (struct ext2_dx_countlimit *) (buf+8);
  9364. limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
  9365. limits->count = 0;
  9366. return (struct ext2_dx_entry *) limits;
  9367. }
  9368. /*
  9369. * This function takes the leaf nodes which have been written in
  9370. * outdir, and populates the root node and any necessary interior nodes.
  9371. */
  9372. static errcode_t calculate_tree(ext2_filsys fs,
  9373. struct out_dir *outdir,
  9374. ext2_ino_t ino,
  9375. ext2_ino_t parent)
  9376. {
  9377. struct ext2_dx_root_info *root_info;
  9378. struct ext2_dx_entry *root, *dx_ent = 0;
  9379. struct ext2_dx_countlimit *root_limit, *limit;
  9380. errcode_t retval;
  9381. char * block_start;
  9382. int i, c1, c2, nblks;
  9383. int limit_offset, root_offset;
  9384. root_info = set_root_node(fs, outdir->buf, ino, parent);
  9385. root_offset = limit_offset = ((char *) root_info - outdir->buf) +
  9386. root_info->info_length;
  9387. root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
  9388. c1 = root_limit->limit;
  9389. nblks = outdir->num;
  9390. /* Write out the pointer blocks */
  9391. if (nblks-1 <= c1) {
  9392. /* Just write out the root block, and we're done */
  9393. root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
  9394. for (i=1; i < nblks; i++) {
  9395. root->block = ext2fs_cpu_to_le32(i);
  9396. if (i != 1)
  9397. root->hash =
  9398. ext2fs_cpu_to_le32(outdir->hashes[i]);
  9399. root++;
  9400. c1--;
  9401. }
  9402. } else {
  9403. c2 = 0;
  9404. limit = 0;
  9405. root_info->indirect_levels = 1;
  9406. for (i=1; i < nblks; i++) {
  9407. if (c1 == 0)
  9408. return ENOSPC;
  9409. if (c2 == 0) {
  9410. if (limit)
  9411. limit->limit = limit->count =
  9412. ext2fs_cpu_to_le16(limit->limit);
  9413. root = (struct ext2_dx_entry *)
  9414. (outdir->buf + root_offset);
  9415. root->block = ext2fs_cpu_to_le32(outdir->num);
  9416. if (i != 1)
  9417. root->hash =
  9418. ext2fs_cpu_to_le32(outdir->hashes[i]);
  9419. if ((retval = get_next_block(fs, outdir,
  9420. &block_start)))
  9421. return retval;
  9422. dx_ent = set_int_node(fs, block_start);
  9423. limit = (struct ext2_dx_countlimit *) dx_ent;
  9424. c2 = limit->limit;
  9425. root_offset += sizeof(struct ext2_dx_entry);
  9426. c1--;
  9427. }
  9428. dx_ent->block = ext2fs_cpu_to_le32(i);
  9429. if (c2 != limit->limit)
  9430. dx_ent->hash =
  9431. ext2fs_cpu_to_le32(outdir->hashes[i]);
  9432. dx_ent++;
  9433. c2--;
  9434. }
  9435. limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
  9436. limit->limit = ext2fs_cpu_to_le16(limit->limit);
  9437. }
  9438. root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
  9439. root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
  9440. root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
  9441. return 0;
  9442. }
  9443. struct write_dir_struct {
  9444. struct out_dir *outdir;
  9445. errcode_t err;
  9446. e2fsck_t ctx;
  9447. int cleared;
  9448. };
  9449. /*
  9450. * Helper function which writes out a directory block.
  9451. */
  9452. static int write_dir_block(ext2_filsys fs,
  9453. blk_t *block_nr,
  9454. e2_blkcnt_t blockcnt,
  9455. blk_t ref_block FSCK_ATTR((unused)),
  9456. int ref_offset FSCK_ATTR((unused)),
  9457. void *priv_data)
  9458. {
  9459. struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
  9460. blk_t blk;
  9461. char *dir;
  9462. if (*block_nr == 0)
  9463. return 0;
  9464. if (blockcnt >= wd->outdir->num) {
  9465. e2fsck_read_bitmaps(wd->ctx);
  9466. blk = *block_nr;
  9467. ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
  9468. ext2fs_block_alloc_stats(fs, blk, -1);
  9469. *block_nr = 0;
  9470. wd->cleared++;
  9471. return BLOCK_CHANGED;
  9472. }
  9473. if (blockcnt < 0)
  9474. return 0;
  9475. dir = wd->outdir->buf + (blockcnt * fs->blocksize);
  9476. wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
  9477. if (wd->err)
  9478. return BLOCK_ABORT;
  9479. return 0;
  9480. }
  9481. static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
  9482. struct out_dir *outdir,
  9483. ext2_ino_t ino, int compress)
  9484. {
  9485. struct write_dir_struct wd;
  9486. errcode_t retval;
  9487. struct ext2_inode inode;
  9488. retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
  9489. if (retval)
  9490. return retval;
  9491. wd.outdir = outdir;
  9492. wd.err = 0;
  9493. wd.ctx = ctx;
  9494. wd.cleared = 0;
  9495. retval = ext2fs_block_iterate2(fs, ino, 0, 0,
  9496. write_dir_block, &wd);
  9497. if (retval)
  9498. return retval;
  9499. if (wd.err)
  9500. return wd.err;
  9501. e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
  9502. if (compress)
  9503. inode.i_flags &= ~EXT2_INDEX_FL;
  9504. else
  9505. inode.i_flags |= EXT2_INDEX_FL;
  9506. inode.i_size = outdir->num * fs->blocksize;
  9507. inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
  9508. e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
  9509. return 0;
  9510. }
  9511. static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
  9512. {
  9513. ext2_filsys fs = ctx->fs;
  9514. errcode_t retval;
  9515. struct ext2_inode inode;
  9516. char *dir_buf = 0;
  9517. struct fill_dir_struct fd;
  9518. struct out_dir outdir;
  9519. outdir.max = outdir.num = 0;
  9520. outdir.buf = 0;
  9521. outdir.hashes = 0;
  9522. e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
  9523. retval = ENOMEM;
  9524. fd.harray = 0;
  9525. dir_buf = malloc(inode.i_size);
  9526. if (!dir_buf)
  9527. goto errout;
  9528. fd.max_array = inode.i_size / 32;
  9529. fd.num_array = 0;
  9530. fd.harray = malloc(fd.max_array * sizeof(struct hash_entry));
  9531. if (!fd.harray)
  9532. goto errout;
  9533. fd.ctx = ctx;
  9534. fd.buf = dir_buf;
  9535. fd.inode = &inode;
  9536. fd.err = 0;
  9537. fd.dir_size = 0;
  9538. fd.compress = 0;
  9539. if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
  9540. (inode.i_size / fs->blocksize) < 2)
  9541. fd.compress = 1;
  9542. fd.parent = 0;
  9543. /* Read in the entire directory into memory */
  9544. retval = ext2fs_block_iterate2(fs, ino, 0, 0,
  9545. fill_dir_block, &fd);
  9546. if (fd.err) {
  9547. retval = fd.err;
  9548. goto errout;
  9549. }
  9550. /* Sort the list */
  9551. resort:
  9552. if (fd.compress)
  9553. qsort(fd.harray+2, fd.num_array-2,
  9554. sizeof(struct hash_entry), name_cmp);
  9555. else
  9556. qsort(fd.harray, fd.num_array,
  9557. sizeof(struct hash_entry), hash_cmp);
  9558. /*
  9559. * Look for duplicates
  9560. */
  9561. if (duplicate_search_and_fix(ctx, fs, ino, &fd))
  9562. goto resort;
  9563. if (ctx->options & E2F_OPT_NO) {
  9564. retval = 0;
  9565. goto errout;
  9566. }
  9567. /*
  9568. * Copy the directory entries. In a htree directory these
  9569. * will become the leaf nodes.
  9570. */
  9571. retval = copy_dir_entries(fs, &fd, &outdir);
  9572. if (retval)
  9573. goto errout;
  9574. free(dir_buf); dir_buf = 0;
  9575. if (!fd.compress) {
  9576. /* Calculate the interior nodes */
  9577. retval = calculate_tree(fs, &outdir, ino, fd.parent);
  9578. if (retval)
  9579. goto errout;
  9580. }
  9581. retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
  9582. errout:
  9583. free(dir_buf);
  9584. free(fd.harray);
  9585. free_out_dir(&outdir);
  9586. return retval;
  9587. }
  9588. void e2fsck_rehash_directories(e2fsck_t ctx)
  9589. {
  9590. struct problem_context pctx;
  9591. struct dir_info *dir;
  9592. ext2_u32_iterate iter;
  9593. ext2_ino_t ino;
  9594. errcode_t retval;
  9595. int i, cur, max, all_dirs, dir_index, first = 1;
  9596. all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
  9597. if (!ctx->dirs_to_hash && !all_dirs)
  9598. return;
  9599. e2fsck_get_lost_and_found(ctx, 0);
  9600. clear_problem_context(&pctx);
  9601. dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
  9602. cur = 0;
  9603. if (all_dirs) {
  9604. i = 0;
  9605. max = e2fsck_get_num_dirinfo(ctx);
  9606. } else {
  9607. retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
  9608. &iter);
  9609. if (retval) {
  9610. pctx.errcode = retval;
  9611. fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
  9612. return;
  9613. }
  9614. max = ext2fs_u32_list_count(ctx->dirs_to_hash);
  9615. }
  9616. while (1) {
  9617. if (all_dirs) {
  9618. if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
  9619. break;
  9620. ino = dir->ino;
  9621. } else {
  9622. if (!ext2fs_u32_list_iterate(iter, &ino))
  9623. break;
  9624. }
  9625. if (ino == ctx->lost_and_found)
  9626. continue;
  9627. pctx.dir = ino;
  9628. if (first) {
  9629. fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
  9630. first = 0;
  9631. }
  9632. pctx.errcode = e2fsck_rehash_dir(ctx, ino);
  9633. if (pctx.errcode) {
  9634. end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
  9635. fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
  9636. }
  9637. if (ctx->progress && !ctx->progress_fd)
  9638. e2fsck_simple_progress(ctx, "Rebuilding directory",
  9639. 100.0 * (float) (++cur) / (float) max, ino);
  9640. }
  9641. end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
  9642. if (!all_dirs)
  9643. ext2fs_u32_list_iterate_end(iter);
  9644. ext2fs_u32_list_free(ctx->dirs_to_hash);
  9645. ctx->dirs_to_hash = 0;
  9646. }
  9647. /*
  9648. * linux/fs/revoke.c
  9649. *
  9650. * Journal revoke routines for the generic filesystem journaling code;
  9651. * part of the ext2fs journaling system.
  9652. *
  9653. * Revoke is the mechanism used to prevent old log records for deleted
  9654. * metadata from being replayed on top of newer data using the same
  9655. * blocks. The revoke mechanism is used in two separate places:
  9656. *
  9657. * + Commit: during commit we write the entire list of the current
  9658. * transaction's revoked blocks to the journal
  9659. *
  9660. * + Recovery: during recovery we record the transaction ID of all
  9661. * revoked blocks. If there are multiple revoke records in the log
  9662. * for a single block, only the last one counts, and if there is a log
  9663. * entry for a block beyond the last revoke, then that log entry still
  9664. * gets replayed.
  9665. *
  9666. * We can get interactions between revokes and new log data within a
  9667. * single transaction:
  9668. *
  9669. * Block is revoked and then journaled:
  9670. * The desired end result is the journaling of the new block, so we
  9671. * cancel the revoke before the transaction commits.
  9672. *
  9673. * Block is journaled and then revoked:
  9674. * The revoke must take precedence over the write of the block, so we
  9675. * need either to cancel the journal entry or to write the revoke
  9676. * later in the log than the log block. In this case, we choose the
  9677. * latter: journaling a block cancels any revoke record for that block
  9678. * in the current transaction, so any revoke for that block in the
  9679. * transaction must have happened after the block was journaled and so
  9680. * the revoke must take precedence.
  9681. *
  9682. * Block is revoked and then written as data:
  9683. * The data write is allowed to succeed, but the revoke is _not_
  9684. * cancelled. We still need to prevent old log records from
  9685. * overwriting the new data. We don't even need to clear the revoke
  9686. * bit here.
  9687. *
  9688. * Revoke information on buffers is a tri-state value:
  9689. *
  9690. * RevokeValid clear: no cached revoke status, need to look it up
  9691. * RevokeValid set, Revoked clear:
  9692. * buffer has not been revoked, and cancel_revoke
  9693. * need do nothing.
  9694. * RevokeValid set, Revoked set:
  9695. * buffer has been revoked.
  9696. */
  9697. static kmem_cache_t *revoke_record_cache;
  9698. static kmem_cache_t *revoke_table_cache;
  9699. /* Each revoke record represents one single revoked block. During
  9700. journal replay, this involves recording the transaction ID of the
  9701. last transaction to revoke this block. */
  9702. struct jbd_revoke_record_s
  9703. {
  9704. struct list_head hash;
  9705. tid_t sequence; /* Used for recovery only */
  9706. unsigned long blocknr;
  9707. };
  9708. /* The revoke table is just a simple hash table of revoke records. */
  9709. struct jbd_revoke_table_s
  9710. {
  9711. /* It is conceivable that we might want a larger hash table
  9712. * for recovery. Must be a power of two. */
  9713. int hash_size;
  9714. int hash_shift;
  9715. struct list_head *hash_table;
  9716. };
  9717. /* Utility functions to maintain the revoke table */
  9718. /* Borrowed from buffer.c: this is a tried and tested block hash function */
  9719. static int hash(journal_t *journal, unsigned long block)
  9720. {
  9721. struct jbd_revoke_table_s *table = journal->j_revoke;
  9722. int hash_shift = table->hash_shift;
  9723. return ((block << (hash_shift - 6)) ^
  9724. (block >> 13) ^
  9725. (block << (hash_shift - 12))) & (table->hash_size - 1);
  9726. }
  9727. static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
  9728. tid_t seq)
  9729. {
  9730. struct list_head *hash_list;
  9731. struct jbd_revoke_record_s *record;
  9732. record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
  9733. if (!record)
  9734. goto oom;
  9735. record->sequence = seq;
  9736. record->blocknr = blocknr;
  9737. hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
  9738. list_add(&record->hash, hash_list);
  9739. return 0;
  9740. oom:
  9741. return -ENOMEM;
  9742. }
  9743. /* Find a revoke record in the journal's hash table. */
  9744. static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
  9745. unsigned long blocknr)
  9746. {
  9747. struct list_head *hash_list;
  9748. struct jbd_revoke_record_s *record;
  9749. hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
  9750. record = (struct jbd_revoke_record_s *) hash_list->next;
  9751. while (&(record->hash) != hash_list) {
  9752. if (record->blocknr == blocknr)
  9753. return record;
  9754. record = (struct jbd_revoke_record_s *) record->hash.next;
  9755. }
  9756. return NULL;
  9757. }
  9758. int journal_init_revoke_caches(void)
  9759. {
  9760. revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s));
  9761. if (revoke_record_cache == 0)
  9762. return -ENOMEM;
  9763. revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s));
  9764. if (revoke_table_cache == 0) {
  9765. do_cache_destroy(revoke_record_cache);
  9766. revoke_record_cache = NULL;
  9767. return -ENOMEM;
  9768. }
  9769. return 0;
  9770. }
  9771. void journal_destroy_revoke_caches(void)
  9772. {
  9773. do_cache_destroy(revoke_record_cache);
  9774. revoke_record_cache = 0;
  9775. do_cache_destroy(revoke_table_cache);
  9776. revoke_table_cache = 0;
  9777. }
  9778. /* Initialise the revoke table for a given journal to a given size. */
  9779. int journal_init_revoke(journal_t *journal, int hash_size)
  9780. {
  9781. int shift, tmp;
  9782. journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
  9783. if (!journal->j_revoke)
  9784. return -ENOMEM;
  9785. /* Check that the hash_size is a power of two */
  9786. journal->j_revoke->hash_size = hash_size;
  9787. shift = 0;
  9788. tmp = hash_size;
  9789. while((tmp >>= 1UL) != 0UL)
  9790. shift++;
  9791. journal->j_revoke->hash_shift = shift;
  9792. journal->j_revoke->hash_table = malloc(hash_size * sizeof(struct list_head));
  9793. if (!journal->j_revoke->hash_table) {
  9794. free(journal->j_revoke);
  9795. journal->j_revoke = NULL;
  9796. return -ENOMEM;
  9797. }
  9798. for (tmp = 0; tmp < hash_size; tmp++)
  9799. INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
  9800. return 0;
  9801. }
  9802. /* Destoy a journal's revoke table. The table must already be empty! */
  9803. void journal_destroy_revoke(journal_t *journal)
  9804. {
  9805. struct jbd_revoke_table_s *table;
  9806. struct list_head *hash_list;
  9807. int i;
  9808. table = journal->j_revoke;
  9809. if (!table)
  9810. return;
  9811. for (i=0; i<table->hash_size; i++) {
  9812. hash_list = &table->hash_table[i];
  9813. }
  9814. free(table->hash_table);
  9815. free(table);
  9816. journal->j_revoke = NULL;
  9817. }
  9818. /*
  9819. * Revoke support for recovery.
  9820. *
  9821. * Recovery needs to be able to:
  9822. *
  9823. * record all revoke records, including the tid of the latest instance
  9824. * of each revoke in the journal
  9825. *
  9826. * check whether a given block in a given transaction should be replayed
  9827. * (ie. has not been revoked by a revoke record in that or a subsequent
  9828. * transaction)
  9829. *
  9830. * empty the revoke table after recovery.
  9831. */
  9832. /*
  9833. * First, setting revoke records. We create a new revoke record for
  9834. * every block ever revoked in the log as we scan it for recovery, and
  9835. * we update the existing records if we find multiple revokes for a
  9836. * single block.
  9837. */
  9838. int journal_set_revoke(journal_t *journal, unsigned long blocknr,
  9839. tid_t sequence)
  9840. {
  9841. struct jbd_revoke_record_s *record;
  9842. record = find_revoke_record(journal, blocknr);
  9843. if (record) {
  9844. /* If we have multiple occurences, only record the
  9845. * latest sequence number in the hashed record */
  9846. if (tid_gt(sequence, record->sequence))
  9847. record->sequence = sequence;
  9848. return 0;
  9849. }
  9850. return insert_revoke_hash(journal, blocknr, sequence);
  9851. }
  9852. /*
  9853. * Test revoke records. For a given block referenced in the log, has
  9854. * that block been revoked? A revoke record with a given transaction
  9855. * sequence number revokes all blocks in that transaction and earlier
  9856. * ones, but later transactions still need replayed.
  9857. */
  9858. int journal_test_revoke(journal_t *journal, unsigned long blocknr,
  9859. tid_t sequence)
  9860. {
  9861. struct jbd_revoke_record_s *record;
  9862. record = find_revoke_record(journal, blocknr);
  9863. if (!record)
  9864. return 0;
  9865. if (tid_gt(sequence, record->sequence))
  9866. return 0;
  9867. return 1;
  9868. }
  9869. /*
  9870. * Finally, once recovery is over, we need to clear the revoke table so
  9871. * that it can be reused by the running filesystem.
  9872. */
  9873. void journal_clear_revoke(journal_t *journal)
  9874. {
  9875. int i;
  9876. struct list_head *hash_list;
  9877. struct jbd_revoke_record_s *record;
  9878. struct jbd_revoke_table_s *revoke_var;
  9879. revoke_var = journal->j_revoke;
  9880. for (i = 0; i < revoke_var->hash_size; i++) {
  9881. hash_list = &revoke_var->hash_table[i];
  9882. while (!list_empty(hash_list)) {
  9883. record = (struct jbd_revoke_record_s*) hash_list->next;
  9884. list_del(&record->hash);
  9885. free(record);
  9886. }
  9887. }
  9888. }
  9889. /*
  9890. * e2fsck.c - superblock checks
  9891. */
  9892. #define MIN_CHECK 1
  9893. #define MAX_CHECK 2
  9894. static void check_super_value(e2fsck_t ctx, const char *descr,
  9895. unsigned long value, int flags,
  9896. unsigned long min_val, unsigned long max_val)
  9897. {
  9898. struct problem_context pctx;
  9899. if (((flags & MIN_CHECK) && (value < min_val)) ||
  9900. ((flags & MAX_CHECK) && (value > max_val))) {
  9901. clear_problem_context(&pctx);
  9902. pctx.num = value;
  9903. pctx.str = descr;
  9904. fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
  9905. ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
  9906. }
  9907. }
  9908. /*
  9909. * This routine may get stubbed out in special compilations of the
  9910. * e2fsck code..
  9911. */
  9912. #ifndef EXT2_SPECIAL_DEVICE_SIZE
  9913. static errcode_t e2fsck_get_device_size(e2fsck_t ctx)
  9914. {
  9915. return (ext2fs_get_device_size(ctx->filesystem_name,
  9916. EXT2_BLOCK_SIZE(ctx->fs->super),
  9917. &ctx->num_blocks));
  9918. }
  9919. #endif
  9920. /*
  9921. * helper function to release an inode
  9922. */
  9923. struct process_block_struct {
  9924. e2fsck_t ctx;
  9925. char *buf;
  9926. struct problem_context *pctx;
  9927. int truncating;
  9928. int truncate_offset;
  9929. e2_blkcnt_t truncate_block;
  9930. int truncated_blocks;
  9931. int abort;
  9932. errcode_t errcode;
  9933. };
  9934. static int release_inode_block(ext2_filsys fs, blk_t *block_nr,
  9935. e2_blkcnt_t blockcnt,
  9936. blk_t ref_blk FSCK_ATTR((unused)),
  9937. int ref_offset FSCK_ATTR((unused)),
  9938. void *priv_data)
  9939. {
  9940. struct process_block_struct *pb;
  9941. e2fsck_t ctx;
  9942. struct problem_context *pctx;
  9943. blk_t blk = *block_nr;
  9944. int retval = 0;
  9945. pb = (struct process_block_struct *) priv_data;
  9946. ctx = pb->ctx;
  9947. pctx = pb->pctx;
  9948. pctx->blk = blk;
  9949. pctx->blkcount = blockcnt;
  9950. if (HOLE_BLKADDR(blk))
  9951. return 0;
  9952. if ((blk < fs->super->s_first_data_block) ||
  9953. (blk >= fs->super->s_blocks_count)) {
  9954. fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
  9955. return_abort:
  9956. pb->abort = 1;
  9957. return BLOCK_ABORT;
  9958. }
  9959. if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
  9960. fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
  9961. goto return_abort;
  9962. }
  9963. /*
  9964. * If we are deleting an orphan, then we leave the fields alone.
  9965. * If we are truncating an orphan, then update the inode fields
  9966. * and clean up any partial block data.
  9967. */
  9968. if (pb->truncating) {
  9969. /*
  9970. * We only remove indirect blocks if they are
  9971. * completely empty.
  9972. */
  9973. if (blockcnt < 0) {
  9974. int i, limit;
  9975. blk_t *bp;
  9976. pb->errcode = io_channel_read_blk(fs->io, blk, 1,
  9977. pb->buf);
  9978. if (pb->errcode)
  9979. goto return_abort;
  9980. limit = fs->blocksize >> 2;
  9981. for (i = 0, bp = (blk_t *) pb->buf;
  9982. i < limit; i++, bp++)
  9983. if (*bp)
  9984. return 0;
  9985. }
  9986. /*
  9987. * We don't remove direct blocks until we've reached
  9988. * the truncation block.
  9989. */
  9990. if (blockcnt >= 0 && blockcnt < pb->truncate_block)
  9991. return 0;
  9992. /*
  9993. * If part of the last block needs truncating, we do
  9994. * it here.
  9995. */
  9996. if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
  9997. pb->errcode = io_channel_read_blk(fs->io, blk, 1,
  9998. pb->buf);
  9999. if (pb->errcode)
  10000. goto return_abort;
  10001. memset(pb->buf + pb->truncate_offset, 0,
  10002. fs->blocksize - pb->truncate_offset);
  10003. pb->errcode = io_channel_write_blk(fs->io, blk, 1,
  10004. pb->buf);
  10005. if (pb->errcode)
  10006. goto return_abort;
  10007. }
  10008. pb->truncated_blocks++;
  10009. *block_nr = 0;
  10010. retval |= BLOCK_CHANGED;
  10011. }
  10012. ext2fs_block_alloc_stats(fs, blk, -1);
  10013. return retval;
  10014. }
  10015. /*
  10016. * This function releases an inode. Returns 1 if an inconsistency was
  10017. * found. If the inode has a link count, then it is being truncated and
  10018. * not deleted.
  10019. */
  10020. static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
  10021. struct ext2_inode *inode, char *block_buf,
  10022. struct problem_context *pctx)
  10023. {
  10024. struct process_block_struct pb;
  10025. ext2_filsys fs = ctx->fs;
  10026. errcode_t retval;
  10027. __u32 count;
  10028. if (!ext2fs_inode_has_valid_blocks(inode))
  10029. return 0;
  10030. pb.buf = block_buf + 3 * ctx->fs->blocksize;
  10031. pb.ctx = ctx;
  10032. pb.abort = 0;
  10033. pb.errcode = 0;
  10034. pb.pctx = pctx;
  10035. if (inode->i_links_count) {
  10036. pb.truncating = 1;
  10037. pb.truncate_block = (e2_blkcnt_t)
  10038. ((((long long)inode->i_size_high << 32) +
  10039. inode->i_size + fs->blocksize - 1) /
  10040. fs->blocksize);
  10041. pb.truncate_offset = inode->i_size % fs->blocksize;
  10042. } else {
  10043. pb.truncating = 0;
  10044. pb.truncate_block = 0;
  10045. pb.truncate_offset = 0;
  10046. }
  10047. pb.truncated_blocks = 0;
  10048. retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
  10049. block_buf, release_inode_block, &pb);
  10050. if (retval) {
  10051. bb_error_msg(_("while calling ext2fs_block_iterate for inode %d"),
  10052. ino);
  10053. return 1;
  10054. }
  10055. if (pb.abort)
  10056. return 1;
  10057. /* Refresh the inode since ext2fs_block_iterate may have changed it */
  10058. e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
  10059. if (pb.truncated_blocks)
  10060. inode->i_blocks -= pb.truncated_blocks *
  10061. (fs->blocksize / 512);
  10062. if (inode->i_file_acl) {
  10063. retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
  10064. block_buf, -1, &count);
  10065. if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
  10066. retval = 0;
  10067. count = 1;
  10068. }
  10069. if (retval) {
  10070. bb_error_msg(_("while calling ext2fs_adjust_ea_refocunt for inode %d"),
  10071. ino);
  10072. return 1;
  10073. }
  10074. if (count == 0)
  10075. ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
  10076. inode->i_file_acl = 0;
  10077. }
  10078. return 0;
  10079. }
  10080. /*
  10081. * This function releases all of the orphan inodes. It returns 1 if
  10082. * it hit some error, and 0 on success.
  10083. */
  10084. static int release_orphan_inodes(e2fsck_t ctx)
  10085. {
  10086. ext2_filsys fs = ctx->fs;
  10087. ext2_ino_t ino, next_ino;
  10088. struct ext2_inode inode;
  10089. struct problem_context pctx;
  10090. char *block_buf;
  10091. if ((ino = fs->super->s_last_orphan) == 0)
  10092. return 0;
  10093. /*
  10094. * Win or lose, we won't be using the head of the orphan inode
  10095. * list again.
  10096. */
  10097. fs->super->s_last_orphan = 0;
  10098. ext2fs_mark_super_dirty(fs);
  10099. /*
  10100. * If the filesystem contains errors, don't run the orphan
  10101. * list, since the orphan list can't be trusted; and we're
  10102. * going to be running a full e2fsck run anyway...
  10103. */
  10104. if (fs->super->s_state & EXT2_ERROR_FS)
  10105. return 0;
  10106. if ((ino < EXT2_FIRST_INODE(fs->super)) ||
  10107. (ino > fs->super->s_inodes_count)) {
  10108. clear_problem_context(&pctx);
  10109. pctx.ino = ino;
  10110. fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
  10111. return 1;
  10112. }
  10113. block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
  10114. "block iterate buffer");
  10115. e2fsck_read_bitmaps(ctx);
  10116. while (ino) {
  10117. e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
  10118. clear_problem_context(&pctx);
  10119. pctx.ino = ino;
  10120. pctx.inode = &inode;
  10121. pctx.str = inode.i_links_count ? _("Truncating") :
  10122. _("Clearing");
  10123. fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
  10124. next_ino = inode.i_dtime;
  10125. if (next_ino &&
  10126. ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
  10127. (next_ino > fs->super->s_inodes_count))) {
  10128. pctx.ino = next_ino;
  10129. fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
  10130. goto return_abort;
  10131. }
  10132. if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
  10133. goto return_abort;
  10134. if (!inode.i_links_count) {
  10135. ext2fs_inode_alloc_stats2(fs, ino, -1,
  10136. LINUX_S_ISDIR(inode.i_mode));
  10137. inode.i_dtime = time(0);
  10138. } else {
  10139. inode.i_dtime = 0;
  10140. }
  10141. e2fsck_write_inode(ctx, ino, &inode, "delete_file");
  10142. ino = next_ino;
  10143. }
  10144. ext2fs_free_mem(&block_buf);
  10145. return 0;
  10146. return_abort:
  10147. ext2fs_free_mem(&block_buf);
  10148. return 1;
  10149. }
  10150. /*
  10151. * Check the resize inode to make sure it is sane. We check both for
  10152. * the case where on-line resizing is not enabled (in which case the
  10153. * resize inode should be cleared) as well as the case where on-line
  10154. * resizing is enabled.
  10155. */
  10156. static void check_resize_inode(e2fsck_t ctx)
  10157. {
  10158. ext2_filsys fs = ctx->fs;
  10159. struct ext2_inode inode;
  10160. struct problem_context pctx;
  10161. int i, j, gdt_off, ind_off;
  10162. blk_t blk, pblk, expect;
  10163. __u32 *dind_buf = 0, *ind_buf;
  10164. errcode_t retval;
  10165. clear_problem_context(&pctx);
  10166. /*
  10167. * If the resize inode feature isn't set, then
  10168. * s_reserved_gdt_blocks must be zero.
  10169. */
  10170. if (!(fs->super->s_feature_compat &
  10171. EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
  10172. if (fs->super->s_reserved_gdt_blocks) {
  10173. pctx.num = fs->super->s_reserved_gdt_blocks;
  10174. if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
  10175. &pctx)) {
  10176. fs->super->s_reserved_gdt_blocks = 0;
  10177. ext2fs_mark_super_dirty(fs);
  10178. }
  10179. }
  10180. }
  10181. /* Read the resize inode */
  10182. pctx.ino = EXT2_RESIZE_INO;
  10183. retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
  10184. if (retval) {
  10185. if (fs->super->s_feature_compat &
  10186. EXT2_FEATURE_COMPAT_RESIZE_INODE)
  10187. ctx->flags |= E2F_FLAG_RESIZE_INODE;
  10188. return;
  10189. }
  10190. /*
  10191. * If the resize inode feature isn't set, check to make sure
  10192. * the resize inode is cleared; then we're done.
  10193. */
  10194. if (!(fs->super->s_feature_compat &
  10195. EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
  10196. for (i=0; i < EXT2_N_BLOCKS; i++) {
  10197. if (inode.i_block[i])
  10198. break;
  10199. }
  10200. if ((i < EXT2_N_BLOCKS) &&
  10201. fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
  10202. memset(&inode, 0, sizeof(inode));
  10203. e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
  10204. "clear_resize");
  10205. }
  10206. return;
  10207. }
  10208. /*
  10209. * The resize inode feature is enabled; check to make sure the
  10210. * only block in use is the double indirect block
  10211. */
  10212. blk = inode.i_block[EXT2_DIND_BLOCK];
  10213. for (i=0; i < EXT2_N_BLOCKS; i++) {
  10214. if (i != EXT2_DIND_BLOCK && inode.i_block[i])
  10215. break;
  10216. }
  10217. if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
  10218. !(inode.i_mode & LINUX_S_IFREG) ||
  10219. (blk < fs->super->s_first_data_block ||
  10220. blk >= fs->super->s_blocks_count)) {
  10221. resize_inode_invalid:
  10222. if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
  10223. memset(&inode, 0, sizeof(inode));
  10224. e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
  10225. "clear_resize");
  10226. ctx->flags |= E2F_FLAG_RESIZE_INODE;
  10227. }
  10228. if (!(ctx->options & E2F_OPT_READONLY)) {
  10229. fs->super->s_state &= ~EXT2_VALID_FS;
  10230. ext2fs_mark_super_dirty(fs);
  10231. }
  10232. goto cleanup;
  10233. }
  10234. dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
  10235. "resize dind buffer");
  10236. ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
  10237. retval = ext2fs_read_ind_block(fs, blk, dind_buf);
  10238. if (retval)
  10239. goto resize_inode_invalid;
  10240. gdt_off = fs->desc_blocks;
  10241. pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
  10242. for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
  10243. i++, gdt_off++, pblk++) {
  10244. gdt_off %= fs->blocksize/4;
  10245. if (dind_buf[gdt_off] != pblk)
  10246. goto resize_inode_invalid;
  10247. retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
  10248. if (retval)
  10249. goto resize_inode_invalid;
  10250. ind_off = 0;
  10251. for (j = 1; j < fs->group_desc_count; j++) {
  10252. if (!ext2fs_bg_has_super(fs, j))
  10253. continue;
  10254. expect = pblk + (j * fs->super->s_blocks_per_group);
  10255. if (ind_buf[ind_off] != expect)
  10256. goto resize_inode_invalid;
  10257. ind_off++;
  10258. }
  10259. }
  10260. cleanup:
  10261. ext2fs_free_mem(&dind_buf);
  10262. }
  10263. static void check_super_block(e2fsck_t ctx)
  10264. {
  10265. ext2_filsys fs = ctx->fs;
  10266. blk_t first_block, last_block;
  10267. struct ext2_super_block *sb = fs->super;
  10268. struct ext2_group_desc *gd;
  10269. blk_t blocks_per_group = fs->super->s_blocks_per_group;
  10270. blk_t bpg_max;
  10271. int inodes_per_block;
  10272. int ipg_max;
  10273. int inode_size;
  10274. dgrp_t i;
  10275. blk_t should_be;
  10276. struct problem_context pctx;
  10277. __u32 free_blocks = 0, free_inodes = 0;
  10278. inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
  10279. ipg_max = inodes_per_block * (blocks_per_group - 4);
  10280. if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
  10281. ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
  10282. bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
  10283. if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
  10284. bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
  10285. ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
  10286. sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
  10287. ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
  10288. sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
  10289. ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
  10290. sizeof(int) * fs->group_desc_count, "invalid_inode_table");
  10291. clear_problem_context(&pctx);
  10292. /*
  10293. * Verify the super block constants...
  10294. */
  10295. check_super_value(ctx, "inodes_count", sb->s_inodes_count,
  10296. MIN_CHECK, 1, 0);
  10297. check_super_value(ctx, "blocks_count", sb->s_blocks_count,
  10298. MIN_CHECK, 1, 0);
  10299. check_super_value(ctx, "first_data_block", sb->s_first_data_block,
  10300. MAX_CHECK, 0, sb->s_blocks_count);
  10301. check_super_value(ctx, "log_block_size", sb->s_log_block_size,
  10302. MIN_CHECK | MAX_CHECK, 0,
  10303. EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
  10304. check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
  10305. MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
  10306. check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
  10307. MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
  10308. bpg_max);
  10309. check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
  10310. MIN_CHECK | MAX_CHECK, 8, bpg_max);
  10311. check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
  10312. MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
  10313. check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
  10314. MAX_CHECK, 0, sb->s_blocks_count / 2);
  10315. check_super_value(ctx, "reserved_gdt_blocks",
  10316. sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
  10317. fs->blocksize/4);
  10318. inode_size = EXT2_INODE_SIZE(sb);
  10319. check_super_value(ctx, "inode_size",
  10320. inode_size, MIN_CHECK | MAX_CHECK,
  10321. EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
  10322. if (inode_size & (inode_size - 1)) {
  10323. pctx.num = inode_size;
  10324. pctx.str = "inode_size";
  10325. fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
  10326. ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
  10327. return;
  10328. }
  10329. if (!ctx->num_blocks) {
  10330. pctx.errcode = e2fsck_get_device_size(ctx);
  10331. if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
  10332. fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
  10333. ctx->flags |= E2F_FLAG_ABORT;
  10334. return;
  10335. }
  10336. if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
  10337. (ctx->num_blocks < sb->s_blocks_count)) {
  10338. pctx.blk = sb->s_blocks_count;
  10339. pctx.blk2 = ctx->num_blocks;
  10340. if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
  10341. ctx->flags |= E2F_FLAG_ABORT;
  10342. return;
  10343. }
  10344. }
  10345. }
  10346. if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
  10347. pctx.blk = EXT2_BLOCK_SIZE(sb);
  10348. pctx.blk2 = EXT2_FRAG_SIZE(sb);
  10349. fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
  10350. ctx->flags |= E2F_FLAG_ABORT;
  10351. return;
  10352. }
  10353. should_be = sb->s_frags_per_group >>
  10354. (sb->s_log_block_size - sb->s_log_frag_size);
  10355. if (sb->s_blocks_per_group != should_be) {
  10356. pctx.blk = sb->s_blocks_per_group;
  10357. pctx.blk2 = should_be;
  10358. fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
  10359. ctx->flags |= E2F_FLAG_ABORT;
  10360. return;
  10361. }
  10362. should_be = (sb->s_log_block_size == 0) ? 1 : 0;
  10363. if (sb->s_first_data_block != should_be) {
  10364. pctx.blk = sb->s_first_data_block;
  10365. pctx.blk2 = should_be;
  10366. fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
  10367. ctx->flags |= E2F_FLAG_ABORT;
  10368. return;
  10369. }
  10370. should_be = sb->s_inodes_per_group * fs->group_desc_count;
  10371. if (sb->s_inodes_count != should_be) {
  10372. pctx.ino = sb->s_inodes_count;
  10373. pctx.ino2 = should_be;
  10374. if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
  10375. sb->s_inodes_count = should_be;
  10376. ext2fs_mark_super_dirty(fs);
  10377. }
  10378. }
  10379. /*
  10380. * Verify the group descriptors....
  10381. */
  10382. first_block = sb->s_first_data_block;
  10383. last_block = first_block + blocks_per_group;
  10384. for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
  10385. pctx.group = i;
  10386. if (i == fs->group_desc_count - 1)
  10387. last_block = sb->s_blocks_count;
  10388. if ((gd->bg_block_bitmap < first_block) ||
  10389. (gd->bg_block_bitmap >= last_block)) {
  10390. pctx.blk = gd->bg_block_bitmap;
  10391. if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
  10392. gd->bg_block_bitmap = 0;
  10393. }
  10394. if (gd->bg_block_bitmap == 0) {
  10395. ctx->invalid_block_bitmap_flag[i]++;
  10396. ctx->invalid_bitmaps++;
  10397. }
  10398. if ((gd->bg_inode_bitmap < first_block) ||
  10399. (gd->bg_inode_bitmap >= last_block)) {
  10400. pctx.blk = gd->bg_inode_bitmap;
  10401. if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
  10402. gd->bg_inode_bitmap = 0;
  10403. }
  10404. if (gd->bg_inode_bitmap == 0) {
  10405. ctx->invalid_inode_bitmap_flag[i]++;
  10406. ctx->invalid_bitmaps++;
  10407. }
  10408. if ((gd->bg_inode_table < first_block) ||
  10409. ((gd->bg_inode_table +
  10410. fs->inode_blocks_per_group - 1) >= last_block)) {
  10411. pctx.blk = gd->bg_inode_table;
  10412. if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
  10413. gd->bg_inode_table = 0;
  10414. }
  10415. if (gd->bg_inode_table == 0) {
  10416. ctx->invalid_inode_table_flag[i]++;
  10417. ctx->invalid_bitmaps++;
  10418. }
  10419. free_blocks += gd->bg_free_blocks_count;
  10420. free_inodes += gd->bg_free_inodes_count;
  10421. first_block += sb->s_blocks_per_group;
  10422. last_block += sb->s_blocks_per_group;
  10423. if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
  10424. (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
  10425. (gd->bg_used_dirs_count > sb->s_inodes_per_group))
  10426. ext2fs_unmark_valid(fs);
  10427. }
  10428. /*
  10429. * Update the global counts from the block group counts. This
  10430. * is needed for an experimental patch which eliminates
  10431. * locking the entire filesystem when allocating blocks or
  10432. * inodes; if the filesystem is not unmounted cleanly, the
  10433. * global counts may not be accurate.
  10434. */
  10435. if ((free_blocks != sb->s_free_blocks_count) ||
  10436. (free_inodes != sb->s_free_inodes_count)) {
  10437. if (ctx->options & E2F_OPT_READONLY)
  10438. ext2fs_unmark_valid(fs);
  10439. else {
  10440. sb->s_free_blocks_count = free_blocks;
  10441. sb->s_free_inodes_count = free_inodes;
  10442. ext2fs_mark_super_dirty(fs);
  10443. }
  10444. }
  10445. if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
  10446. (sb->s_free_inodes_count > sb->s_inodes_count))
  10447. ext2fs_unmark_valid(fs);
  10448. /*
  10449. * If we have invalid bitmaps, set the error state of the
  10450. * filesystem.
  10451. */
  10452. if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
  10453. sb->s_state &= ~EXT2_VALID_FS;
  10454. ext2fs_mark_super_dirty(fs);
  10455. }
  10456. clear_problem_context(&pctx);
  10457. /*
  10458. * If the UUID field isn't assigned, assign it.
  10459. */
  10460. if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
  10461. if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
  10462. uuid_generate(sb->s_uuid);
  10463. ext2fs_mark_super_dirty(fs);
  10464. fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
  10465. }
  10466. }
  10467. /* FIXME - HURD support?
  10468. * For the Hurd, check to see if the filetype option is set,
  10469. * since it doesn't support it.
  10470. */
  10471. if (!(ctx->options & E2F_OPT_READONLY) &&
  10472. fs->super->s_creator_os == EXT2_OS_HURD &&
  10473. (fs->super->s_feature_incompat &
  10474. EXT2_FEATURE_INCOMPAT_FILETYPE)) {
  10475. if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
  10476. fs->super->s_feature_incompat &=
  10477. ~EXT2_FEATURE_INCOMPAT_FILETYPE;
  10478. ext2fs_mark_super_dirty(fs);
  10479. }
  10480. }
  10481. /*
  10482. * If we have any of the compatibility flags set, we need to have a
  10483. * revision 1 filesystem. Most kernels will not check the flags on
  10484. * a rev 0 filesystem and we may have corruption issues because of
  10485. * the incompatible changes to the filesystem.
  10486. */
  10487. if (!(ctx->options & E2F_OPT_READONLY) &&
  10488. fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
  10489. (fs->super->s_feature_compat ||
  10490. fs->super->s_feature_ro_compat ||
  10491. fs->super->s_feature_incompat) &&
  10492. fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
  10493. ext2fs_update_dynamic_rev(fs);
  10494. ext2fs_mark_super_dirty(fs);
  10495. }
  10496. check_resize_inode(ctx);
  10497. /*
  10498. * Clean up any orphan inodes, if present.
  10499. */
  10500. if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
  10501. fs->super->s_state &= ~EXT2_VALID_FS;
  10502. ext2fs_mark_super_dirty(fs);
  10503. }
  10504. /*
  10505. * Move the ext3 journal file, if necessary.
  10506. */
  10507. e2fsck_move_ext3_journal(ctx);
  10508. return;
  10509. }
  10510. /*
  10511. * swapfs.c --- byte-swap an ext2 filesystem
  10512. */
  10513. #ifdef ENABLE_SWAPFS
  10514. struct swap_block_struct {
  10515. ext2_ino_t ino;
  10516. int isdir;
  10517. errcode_t errcode;
  10518. char *dir_buf;
  10519. struct ext2_inode *inode;
  10520. };
  10521. /*
  10522. * This is a helper function for block_iterate. We mark all of the
  10523. * indirect and direct blocks as changed, so that block_iterate will
  10524. * write them out.
  10525. */
  10526. static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
  10527. void *priv_data)
  10528. {
  10529. errcode_t retval;
  10530. struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
  10531. if (sb->isdir && (blockcnt >= 0) && *block_nr) {
  10532. retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
  10533. if (retval) {
  10534. sb->errcode = retval;
  10535. return BLOCK_ABORT;
  10536. }
  10537. retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
  10538. if (retval) {
  10539. sb->errcode = retval;
  10540. return BLOCK_ABORT;
  10541. }
  10542. }
  10543. if (blockcnt >= 0) {
  10544. if (blockcnt < EXT2_NDIR_BLOCKS)
  10545. return 0;
  10546. return BLOCK_CHANGED;
  10547. }
  10548. if (blockcnt == BLOCK_COUNT_IND) {
  10549. if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
  10550. return 0;
  10551. return BLOCK_CHANGED;
  10552. }
  10553. if (blockcnt == BLOCK_COUNT_DIND) {
  10554. if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
  10555. return 0;
  10556. return BLOCK_CHANGED;
  10557. }
  10558. if (blockcnt == BLOCK_COUNT_TIND) {
  10559. if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
  10560. return 0;
  10561. return BLOCK_CHANGED;
  10562. }
  10563. return BLOCK_CHANGED;
  10564. }
  10565. /*
  10566. * This function is responsible for byte-swapping all of the indirect,
  10567. * block pointers. It is also responsible for byte-swapping directories.
  10568. */
  10569. static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
  10570. struct ext2_inode *inode)
  10571. {
  10572. errcode_t retval;
  10573. struct swap_block_struct sb;
  10574. sb.ino = ino;
  10575. sb.inode = inode;
  10576. sb.dir_buf = block_buf + ctx->fs->blocksize*3;
  10577. sb.errcode = 0;
  10578. sb.isdir = 0;
  10579. if (LINUX_S_ISDIR(inode->i_mode))
  10580. sb.isdir = 1;
  10581. retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
  10582. swap_block, &sb);
  10583. if (retval) {
  10584. bb_error_msg(_("while calling ext2fs_block_iterate"));
  10585. ctx->flags |= E2F_FLAG_ABORT;
  10586. return;
  10587. }
  10588. if (sb.errcode) {
  10589. bb_error_msg(_("while calling iterator function"));
  10590. ctx->flags |= E2F_FLAG_ABORT;
  10591. return;
  10592. }
  10593. }
  10594. static void swap_inodes(e2fsck_t ctx)
  10595. {
  10596. ext2_filsys fs = ctx->fs;
  10597. dgrp_t group;
  10598. unsigned int i;
  10599. ext2_ino_t ino = 1;
  10600. char *buf, *block_buf;
  10601. errcode_t retval;
  10602. struct ext2_inode * inode;
  10603. e2fsck_use_inode_shortcuts(ctx, 1);
  10604. retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
  10605. &buf);
  10606. if (retval) {
  10607. bb_error_msg(_("while allocating inode buffer"));
  10608. ctx->flags |= E2F_FLAG_ABORT;
  10609. return;
  10610. }
  10611. block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
  10612. "block interate buffer");
  10613. for (group = 0; group < fs->group_desc_count; group++) {
  10614. retval = io_channel_read_blk(fs->io,
  10615. fs->group_desc[group].bg_inode_table,
  10616. fs->inode_blocks_per_group, buf);
  10617. if (retval) {
  10618. bb_error_msg(_("while reading inode table (group %d)"),
  10619. group);
  10620. ctx->flags |= E2F_FLAG_ABORT;
  10621. return;
  10622. }
  10623. inode = (struct ext2_inode *) buf;
  10624. for (i=0; i < fs->super->s_inodes_per_group;
  10625. i++, ino++, inode++) {
  10626. ctx->stashed_ino = ino;
  10627. ctx->stashed_inode = inode;
  10628. if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
  10629. ext2fs_swap_inode(fs, inode, inode, 0);
  10630. /*
  10631. * Skip deleted files.
  10632. */
  10633. if (inode->i_links_count == 0)
  10634. continue;
  10635. if (LINUX_S_ISDIR(inode->i_mode) ||
  10636. ((inode->i_block[EXT2_IND_BLOCK] ||
  10637. inode->i_block[EXT2_DIND_BLOCK] ||
  10638. inode->i_block[EXT2_TIND_BLOCK]) &&
  10639. ext2fs_inode_has_valid_blocks(inode)))
  10640. swap_inode_blocks(ctx, ino, block_buf, inode);
  10641. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  10642. return;
  10643. if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
  10644. ext2fs_swap_inode(fs, inode, inode, 1);
  10645. }
  10646. retval = io_channel_write_blk(fs->io,
  10647. fs->group_desc[group].bg_inode_table,
  10648. fs->inode_blocks_per_group, buf);
  10649. if (retval) {
  10650. bb_error_msg(_("while writing inode table (group %d)"),
  10651. group);
  10652. ctx->flags |= E2F_FLAG_ABORT;
  10653. return;
  10654. }
  10655. }
  10656. ext2fs_free_mem(&buf);
  10657. ext2fs_free_mem(&block_buf);
  10658. e2fsck_use_inode_shortcuts(ctx, 0);
  10659. ext2fs_flush_icache(fs);
  10660. }
  10661. #if defined(__powerpc__) && BB_BIG_ENDIAN
  10662. /*
  10663. * On the PowerPC, the big-endian variant of the ext2 filesystem
  10664. * has its bitmaps stored as 32-bit words with bit 0 as the LSB
  10665. * of each word. Thus a bitmap with only bit 0 set would be, as
  10666. * a string of bytes, 00 00 00 01 00 ...
  10667. * To cope with this, we byte-reverse each word of a bitmap if
  10668. * we have a big-endian filesystem, that is, if we are *not*
  10669. * byte-swapping other word-sized numbers.
  10670. */
  10671. #define EXT2_BIG_ENDIAN_BITMAPS
  10672. #endif
  10673. #ifdef EXT2_BIG_ENDIAN_BITMAPS
  10674. static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
  10675. {
  10676. __u32 *p = (__u32 *) bmap->bitmap;
  10677. int n, nbytes = (bmap->end - bmap->start + 7) / 8;
  10678. for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
  10679. *p = ext2fs_swab32(*p);
  10680. }
  10681. #endif
  10682. #ifdef ENABLE_SWAPFS
  10683. static void swap_filesys(e2fsck_t ctx)
  10684. {
  10685. ext2_filsys fs = ctx->fs;
  10686. if (!(ctx->options & E2F_OPT_PREEN))
  10687. printf(_("Pass 0: Doing byte-swap of filesystem\n"));
  10688. /* Byte swap */
  10689. if (fs->super->s_mnt_count) {
  10690. fprintf(stderr, _("%s: the filesystem must be freshly "
  10691. "checked using fsck\n"
  10692. "and not mounted before trying to "
  10693. "byte-swap it.\n"), ctx->device_name);
  10694. ctx->flags |= E2F_FLAG_ABORT;
  10695. return;
  10696. }
  10697. if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
  10698. fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
  10699. EXT2_FLAG_SWAP_BYTES_WRITE);
  10700. fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
  10701. } else {
  10702. fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
  10703. fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
  10704. }
  10705. swap_inodes(ctx);
  10706. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  10707. return;
  10708. if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
  10709. fs->flags |= EXT2_FLAG_SWAP_BYTES;
  10710. fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
  10711. EXT2_FLAG_SWAP_BYTES_WRITE);
  10712. #ifdef EXT2_BIG_ENDIAN_BITMAPS
  10713. e2fsck_read_bitmaps(ctx);
  10714. ext2fs_swap_bitmap(fs->inode_map);
  10715. ext2fs_swap_bitmap(fs->block_map);
  10716. fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
  10717. #endif
  10718. fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
  10719. ext2fs_flush(fs);
  10720. fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
  10721. }
  10722. #endif /* ENABLE_SWAPFS */
  10723. #endif
  10724. /*
  10725. * util.c --- miscellaneous utilities
  10726. */
  10727. void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
  10728. const char *description)
  10729. {
  10730. void *ret;
  10731. char buf[256];
  10732. ret = malloc(size);
  10733. if (!ret) {
  10734. sprintf(buf, "Can't allocate %s\n", description);
  10735. bb_error_msg_and_die(buf);
  10736. }
  10737. memset(ret, 0, size);
  10738. return ret;
  10739. }
  10740. static char *string_copy(const char *str, int len)
  10741. {
  10742. char *ret;
  10743. if (!str)
  10744. return NULL;
  10745. if (!len)
  10746. len = strlen(str);
  10747. ret = malloc(len+1);
  10748. if (ret) {
  10749. strncpy(ret, str, len);
  10750. ret[len] = 0;
  10751. }
  10752. return ret;
  10753. }
  10754. #ifndef HAVE_CONIO_H
  10755. static int read_a_char(void)
  10756. {
  10757. char c;
  10758. int r;
  10759. int fail = 0;
  10760. while(1) {
  10761. if (e2fsck_global_ctx &&
  10762. (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
  10763. return 3;
  10764. }
  10765. r = read(0, &c, 1);
  10766. if (r == 1)
  10767. return c;
  10768. if (fail++ > 100)
  10769. break;
  10770. }
  10771. return EOF;
  10772. }
  10773. #endif
  10774. static int ask_yn(const char * string, int def)
  10775. {
  10776. int c;
  10777. const char *defstr;
  10778. static const char short_yes[] = "yY";
  10779. static const char short_no[] = "nN";
  10780. #ifdef HAVE_TERMIOS_H
  10781. struct termios termios, tmp;
  10782. tcgetattr (0, &termios);
  10783. tmp = termios;
  10784. tmp.c_lflag &= ~(ICANON | ECHO);
  10785. tmp.c_cc[VMIN] = 1;
  10786. tmp.c_cc[VTIME] = 0;
  10787. tcsetattr (0, TCSANOW, &tmp);
  10788. #endif
  10789. if (def == 1)
  10790. defstr = "<y>";
  10791. else if (def == 0)
  10792. defstr = "<n>";
  10793. else
  10794. defstr = " (y/n)";
  10795. printf("%s%s? ", string, defstr);
  10796. while (1) {
  10797. fflush (stdout);
  10798. if ((c = read_a_char()) == EOF)
  10799. break;
  10800. if (c == 3) {
  10801. #ifdef HAVE_TERMIOS_H
  10802. tcsetattr (0, TCSANOW, &termios);
  10803. #endif
  10804. if (e2fsck_global_ctx &&
  10805. e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
  10806. puts("\n");
  10807. longjmp(e2fsck_global_ctx->abort_loc, 1);
  10808. }
  10809. puts(_("cancelled!\n"));
  10810. return 0;
  10811. }
  10812. if (strchr(short_yes, (char) c)) {
  10813. def = 1;
  10814. break;
  10815. }
  10816. else if (strchr(short_no, (char) c)) {
  10817. def = 0;
  10818. break;
  10819. }
  10820. else if ((c == ' ' || c == '\n') && (def != -1))
  10821. break;
  10822. }
  10823. if (def)
  10824. puts("yes\n");
  10825. else
  10826. puts ("no\n");
  10827. #ifdef HAVE_TERMIOS_H
  10828. tcsetattr (0, TCSANOW, &termios);
  10829. #endif
  10830. return def;
  10831. }
  10832. int ask (e2fsck_t ctx, const char * string, int def)
  10833. {
  10834. if (ctx->options & E2F_OPT_NO) {
  10835. printf(_("%s? no\n\n"), string);
  10836. return 0;
  10837. }
  10838. if (ctx->options & E2F_OPT_YES) {
  10839. printf(_("%s? yes\n\n"), string);
  10840. return 1;
  10841. }
  10842. if (ctx->options & E2F_OPT_PREEN) {
  10843. printf("%s? %s\n\n", string, def ? _("yes") : _("no"));
  10844. return def;
  10845. }
  10846. return ask_yn(string, def);
  10847. }
  10848. void e2fsck_read_bitmaps(e2fsck_t ctx)
  10849. {
  10850. ext2_filsys fs = ctx->fs;
  10851. errcode_t retval;
  10852. if (ctx->invalid_bitmaps) {
  10853. bb_error_msg(_("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
  10854. ctx->device_name);
  10855. bb_error_msg_and_die(0);
  10856. }
  10857. ehandler_operation(_("reading inode and block bitmaps"));
  10858. retval = ext2fs_read_bitmaps(fs);
  10859. ehandler_operation(0);
  10860. if (retval) {
  10861. bb_error_msg(_("while retrying to read bitmaps for %s"),
  10862. ctx->device_name);
  10863. bb_error_msg_and_die(0);
  10864. }
  10865. }
  10866. static void e2fsck_write_bitmaps(e2fsck_t ctx)
  10867. {
  10868. ext2_filsys fs = ctx->fs;
  10869. errcode_t retval;
  10870. if (ext2fs_test_bb_dirty(fs)) {
  10871. ehandler_operation(_("writing block bitmaps"));
  10872. retval = ext2fs_write_block_bitmap(fs);
  10873. ehandler_operation(0);
  10874. if (retval) {
  10875. bb_error_msg(_("while retrying to write block bitmaps for %s"),
  10876. ctx->device_name);
  10877. bb_error_msg_and_die(0);
  10878. }
  10879. }
  10880. if (ext2fs_test_ib_dirty(fs)) {
  10881. ehandler_operation(_("writing inode bitmaps"));
  10882. retval = ext2fs_write_inode_bitmap(fs);
  10883. ehandler_operation(0);
  10884. if (retval) {
  10885. bb_error_msg(_("while retrying to write inode bitmaps for %s"),
  10886. ctx->device_name);
  10887. bb_error_msg_and_die(0);
  10888. }
  10889. }
  10890. }
  10891. void preenhalt(e2fsck_t ctx)
  10892. {
  10893. ext2_filsys fs = ctx->fs;
  10894. if (!(ctx->options & E2F_OPT_PREEN))
  10895. return;
  10896. fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
  10897. "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
  10898. ctx->device_name);
  10899. if (fs != NULL) {
  10900. fs->super->s_state |= EXT2_ERROR_FS;
  10901. ext2fs_mark_super_dirty(fs);
  10902. ext2fs_close(fs);
  10903. }
  10904. exit(EXIT_UNCORRECTED);
  10905. }
  10906. void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
  10907. struct ext2_inode * inode, const char *proc)
  10908. {
  10909. int retval;
  10910. retval = ext2fs_read_inode(ctx->fs, ino, inode);
  10911. if (retval) {
  10912. bb_error_msg(_("while reading inode %ld in %s"), ino, proc);
  10913. bb_error_msg_and_die(0);
  10914. }
  10915. }
  10916. extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
  10917. struct ext2_inode * inode, int bufsize,
  10918. const char *proc)
  10919. {
  10920. int retval;
  10921. retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
  10922. if (retval) {
  10923. bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
  10924. bb_error_msg_and_die(0);
  10925. }
  10926. }
  10927. extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
  10928. struct ext2_inode * inode, const char *proc)
  10929. {
  10930. int retval;
  10931. retval = ext2fs_write_inode(ctx->fs, ino, inode);
  10932. if (retval) {
  10933. bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
  10934. bb_error_msg_and_die(0);
  10935. }
  10936. }
  10937. blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
  10938. io_manager manager)
  10939. {
  10940. struct ext2_super_block *sb;
  10941. io_channel io = NULL;
  10942. void *buf = NULL;
  10943. int blocksize;
  10944. blk_t superblock, ret_sb = 8193;
  10945. if (fs && fs->super) {
  10946. ret_sb = (fs->super->s_blocks_per_group +
  10947. fs->super->s_first_data_block);
  10948. if (ctx) {
  10949. ctx->superblock = ret_sb;
  10950. ctx->blocksize = fs->blocksize;
  10951. }
  10952. return ret_sb;
  10953. }
  10954. if (ctx) {
  10955. if (ctx->blocksize) {
  10956. ret_sb = ctx->blocksize * 8;
  10957. if (ctx->blocksize == 1024)
  10958. ret_sb++;
  10959. ctx->superblock = ret_sb;
  10960. return ret_sb;
  10961. }
  10962. ctx->superblock = ret_sb;
  10963. ctx->blocksize = 1024;
  10964. }
  10965. if (!name || !manager)
  10966. goto cleanup;
  10967. if (manager->open(name, 0, &io) != 0)
  10968. goto cleanup;
  10969. if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
  10970. goto cleanup;
  10971. sb = (struct ext2_super_block *) buf;
  10972. for (blocksize = EXT2_MIN_BLOCK_SIZE;
  10973. blocksize <= EXT2_MAX_BLOCK_SIZE ; blocksize *= 2) {
  10974. superblock = blocksize*8;
  10975. if (blocksize == 1024)
  10976. superblock++;
  10977. io_channel_set_blksize(io, blocksize);
  10978. if (io_channel_read_blk(io, superblock,
  10979. -SUPERBLOCK_SIZE, buf))
  10980. continue;
  10981. #if BB_BIG_ENDIAN
  10982. if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
  10983. ext2fs_swap_super(sb);
  10984. #endif
  10985. if (sb->s_magic == EXT2_SUPER_MAGIC) {
  10986. ret_sb = superblock;
  10987. if (ctx) {
  10988. ctx->superblock = superblock;
  10989. ctx->blocksize = blocksize;
  10990. }
  10991. break;
  10992. }
  10993. }
  10994. cleanup:
  10995. if (io)
  10996. io_channel_close(io);
  10997. ext2fs_free_mem(&buf);
  10998. return ret_sb;
  10999. }
  11000. /*
  11001. * This function runs through the e2fsck passes and calls them all,
  11002. * returning restart, abort, or cancel as necessary...
  11003. */
  11004. typedef void (*pass_t)(e2fsck_t ctx);
  11005. static const pass_t e2fsck_passes[] = {
  11006. e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
  11007. e2fsck_pass5, 0 };
  11008. #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
  11009. static int e2fsck_run(e2fsck_t ctx)
  11010. {
  11011. int i;
  11012. pass_t e2fsck_pass;
  11013. if (setjmp(ctx->abort_loc)) {
  11014. ctx->flags &= ~E2F_FLAG_SETJMP_OK;
  11015. return (ctx->flags & E2F_FLAG_RUN_RETURN);
  11016. }
  11017. ctx->flags |= E2F_FLAG_SETJMP_OK;
  11018. for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
  11019. if (ctx->flags & E2F_FLAG_RUN_RETURN)
  11020. break;
  11021. e2fsck_pass(ctx);
  11022. if (ctx->progress)
  11023. (void) (ctx->progress)(ctx, 0, 0, 0);
  11024. }
  11025. ctx->flags &= ~E2F_FLAG_SETJMP_OK;
  11026. if (ctx->flags & E2F_FLAG_RUN_RETURN)
  11027. return (ctx->flags & E2F_FLAG_RUN_RETURN);
  11028. return 0;
  11029. }
  11030. /*
  11031. * unix.c - The unix-specific code for e2fsck
  11032. */
  11033. /* Command line options */
  11034. static int swapfs;
  11035. #ifdef ENABLE_SWAPFS
  11036. static int normalize_swapfs;
  11037. #endif
  11038. static int cflag; /* check disk */
  11039. static int show_version_only;
  11040. static int verbose;
  11041. #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural)
  11042. static void show_stats(e2fsck_t ctx)
  11043. {
  11044. ext2_filsys fs = ctx->fs;
  11045. int inodes, inodes_used, blocks, blocks_used;
  11046. int dir_links;
  11047. int num_files, num_links;
  11048. int frag_percent;
  11049. dir_links = 2 * ctx->fs_directory_count - 1;
  11050. num_files = ctx->fs_total_count - dir_links;
  11051. num_links = ctx->fs_links_count - dir_links;
  11052. inodes = fs->super->s_inodes_count;
  11053. inodes_used = (fs->super->s_inodes_count -
  11054. fs->super->s_free_inodes_count);
  11055. blocks = fs->super->s_blocks_count;
  11056. blocks_used = (fs->super->s_blocks_count -
  11057. fs->super->s_free_blocks_count);
  11058. frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
  11059. frag_percent = (frag_percent + 5) / 10;
  11060. if (!verbose) {
  11061. printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
  11062. ctx->device_name, inodes_used, inodes,
  11063. frag_percent / 10, frag_percent % 10,
  11064. blocks_used, blocks);
  11065. return;
  11066. }
  11067. printf("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used),
  11068. 100 * inodes_used / inodes);
  11069. printf("%8d non-contiguous inode%s (%0d.%d%%)\n",
  11070. P_E2("", "s", ctx->fs_fragmented),
  11071. frag_percent / 10, frag_percent % 10);
  11072. printf(_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
  11073. ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
  11074. printf("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used),
  11075. (int) ((long long) 100 * blocks_used / blocks));
  11076. printf("%8d large file%s\n", P_E2("", "s", ctx->large_files));
  11077. printf("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count));
  11078. printf("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count));
  11079. printf("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count));
  11080. printf("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count));
  11081. printf("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count));
  11082. printf("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links));
  11083. printf("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count));
  11084. printf(" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count));
  11085. printf("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count));
  11086. printf("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links));
  11087. }
  11088. static void check_mount(e2fsck_t ctx)
  11089. {
  11090. errcode_t retval;
  11091. int cont;
  11092. retval = ext2fs_check_if_mounted(ctx->filesystem_name,
  11093. &ctx->mount_flags);
  11094. if (retval) {
  11095. bb_error_msg(_("while determining whether %s is mounted."),
  11096. ctx->filesystem_name);
  11097. return;
  11098. }
  11099. /*
  11100. * If the filesystem isn't mounted, or it's the root filesystem
  11101. * and it's mounted read-only, then everything's fine.
  11102. */
  11103. if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
  11104. ((ctx->mount_flags & EXT2_MF_ISROOT) &&
  11105. (ctx->mount_flags & EXT2_MF_READONLY)))
  11106. return;
  11107. if (ctx->options & E2F_OPT_READONLY) {
  11108. printf(_("Warning! %s is mounted.\n"), ctx->filesystem_name);
  11109. return;
  11110. }
  11111. printf(_("%s is mounted. "), ctx->filesystem_name);
  11112. if (!ctx->interactive)
  11113. bb_error_msg_and_die(_("Cannot continue, aborting."));
  11114. printf(_("\n\n\007\007\007\007WARNING!!! "
  11115. "Running e2fsck on a mounted filesystem may cause\n"
  11116. "SEVERE filesystem damage.\007\007\007\n\n"));
  11117. cont = ask_yn(_("Do you really want to continue"), -1);
  11118. if (!cont) {
  11119. printf(_("check aborted.\n"));
  11120. exit (0);
  11121. }
  11122. return;
  11123. }
  11124. static int is_on_batt(void)
  11125. {
  11126. FILE *f;
  11127. DIR *d;
  11128. char tmp[80], tmp2[80], fname[80];
  11129. unsigned int acflag;
  11130. struct dirent* de;
  11131. f = fopen("/proc/apm", "r");
  11132. if (f) {
  11133. if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
  11134. acflag = 1;
  11135. fclose(f);
  11136. return (acflag != 1);
  11137. }
  11138. d = opendir("/proc/acpi/ac_adapter");
  11139. if (d) {
  11140. while ((de=readdir(d)) != NULL) {
  11141. if (!strncmp(".", de->d_name, 1))
  11142. continue;
  11143. snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
  11144. de->d_name);
  11145. f = fopen(fname, "r");
  11146. if (!f)
  11147. continue;
  11148. if (fscanf(f, "%s %s", tmp2, tmp) != 2)
  11149. tmp[0] = 0;
  11150. fclose(f);
  11151. if (strncmp(tmp, "off-line", 8) == 0) {
  11152. closedir(d);
  11153. return 1;
  11154. }
  11155. }
  11156. closedir(d);
  11157. }
  11158. return 0;
  11159. }
  11160. /*
  11161. * This routine checks to see if a filesystem can be skipped; if so,
  11162. * it will exit with EXIT_OK. Under some conditions it will print a
  11163. * message explaining why a check is being forced.
  11164. */
  11165. static void check_if_skip(e2fsck_t ctx)
  11166. {
  11167. ext2_filsys fs = ctx->fs;
  11168. const char *reason = NULL;
  11169. unsigned int reason_arg = 0;
  11170. long next_check;
  11171. int batt = is_on_batt();
  11172. time_t now = time(0);
  11173. if ((ctx->options & E2F_OPT_FORCE) || cflag || swapfs)
  11174. return;
  11175. if ((fs->super->s_state & EXT2_ERROR_FS) ||
  11176. !ext2fs_test_valid(fs))
  11177. reason = _(" contains a file system with errors");
  11178. else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
  11179. reason = _(" was not cleanly unmounted");
  11180. else if ((fs->super->s_max_mnt_count > 0) &&
  11181. (fs->super->s_mnt_count >=
  11182. (unsigned) fs->super->s_max_mnt_count)) {
  11183. reason = _(" has been mounted %u times without being checked");
  11184. reason_arg = fs->super->s_mnt_count;
  11185. if (batt && (fs->super->s_mnt_count <
  11186. (unsigned) fs->super->s_max_mnt_count*2))
  11187. reason = 0;
  11188. } else if (fs->super->s_checkinterval &&
  11189. ((now - fs->super->s_lastcheck) >=
  11190. fs->super->s_checkinterval)) {
  11191. reason = _(" has gone %u days without being checked");
  11192. reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
  11193. if (batt && ((now - fs->super->s_lastcheck) <
  11194. fs->super->s_checkinterval*2))
  11195. reason = 0;
  11196. }
  11197. if (reason) {
  11198. fputs(ctx->device_name, stdout);
  11199. printf(reason, reason_arg);
  11200. fputs(_(", check forced.\n"), stdout);
  11201. return;
  11202. }
  11203. printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
  11204. fs->super->s_inodes_count - fs->super->s_free_inodes_count,
  11205. fs->super->s_inodes_count,
  11206. fs->super->s_blocks_count - fs->super->s_free_blocks_count,
  11207. fs->super->s_blocks_count);
  11208. next_check = 100000;
  11209. if (fs->super->s_max_mnt_count > 0) {
  11210. next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
  11211. if (next_check <= 0)
  11212. next_check = 1;
  11213. }
  11214. if (fs->super->s_checkinterval &&
  11215. ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
  11216. next_check = 1;
  11217. if (next_check <= 5) {
  11218. if (next_check == 1)
  11219. fputs(_(" (check after next mount)"), stdout);
  11220. else
  11221. printf(_(" (check in %ld mounts)"), next_check);
  11222. }
  11223. fputc('\n', stdout);
  11224. ext2fs_close(fs);
  11225. ctx->fs = NULL;
  11226. e2fsck_free_context(ctx);
  11227. exit(EXIT_OK);
  11228. }
  11229. /*
  11230. * For completion notice
  11231. */
  11232. struct percent_tbl {
  11233. int max_pass;
  11234. int table[32];
  11235. };
  11236. static const struct percent_tbl e2fsck_tbl = {
  11237. 5, { 0, 70, 90, 92, 95, 100 }
  11238. };
  11239. static char bar[128], spaces[128];
  11240. static float calc_percent(const struct percent_tbl *tbl, int pass, int curr,
  11241. int max)
  11242. {
  11243. float percent;
  11244. if (pass <= 0)
  11245. return 0.0;
  11246. if (pass > tbl->max_pass || max == 0)
  11247. return 100.0;
  11248. percent = ((float) curr) / ((float) max);
  11249. return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
  11250. + tbl->table[pass-1]);
  11251. }
  11252. void e2fsck_clear_progbar(e2fsck_t ctx)
  11253. {
  11254. if (!(ctx->flags & E2F_FLAG_PROG_BAR))
  11255. return;
  11256. printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
  11257. ctx->stop_meta);
  11258. fflush(stdout);
  11259. ctx->flags &= ~E2F_FLAG_PROG_BAR;
  11260. }
  11261. int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
  11262. unsigned int dpynum)
  11263. {
  11264. static const char spinner[] = "\\|/-";
  11265. int i;
  11266. unsigned int tick;
  11267. struct timeval tv;
  11268. int dpywidth;
  11269. int fixed_percent;
  11270. if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
  11271. return 0;
  11272. /*
  11273. * Calculate the new progress position. If the
  11274. * percentage hasn't changed, then we skip out right
  11275. * away.
  11276. */
  11277. fixed_percent = (int) ((10 * percent) + 0.5);
  11278. if (ctx->progress_last_percent == fixed_percent)
  11279. return 0;
  11280. ctx->progress_last_percent = fixed_percent;
  11281. /*
  11282. * If we've already updated the spinner once within
  11283. * the last 1/8th of a second, no point doing it
  11284. * again.
  11285. */
  11286. gettimeofday(&tv, NULL);
  11287. tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
  11288. if ((tick == ctx->progress_last_time) &&
  11289. (fixed_percent != 0) && (fixed_percent != 1000))
  11290. return 0;
  11291. ctx->progress_last_time = tick;
  11292. /*
  11293. * Advance the spinner, and note that the progress bar
  11294. * will be on the screen
  11295. */
  11296. ctx->progress_pos = (ctx->progress_pos+1) & 3;
  11297. ctx->flags |= E2F_FLAG_PROG_BAR;
  11298. dpywidth = 66 - strlen(label);
  11299. dpywidth = 8 * (dpywidth / 8);
  11300. if (dpynum)
  11301. dpywidth -= 8;
  11302. i = ((percent * dpywidth) + 50) / 100;
  11303. printf("%s%s: |%s%s", ctx->start_meta, label,
  11304. bar + (sizeof(bar) - (i+1)),
  11305. spaces + (sizeof(spaces) - (dpywidth - i + 1)));
  11306. if (fixed_percent == 1000)
  11307. fputc('|', stdout);
  11308. else
  11309. fputc(spinner[ctx->progress_pos & 3], stdout);
  11310. printf(" %4.1f%% ", percent);
  11311. if (dpynum)
  11312. printf("%u\r", dpynum);
  11313. else
  11314. fputs(" \r", stdout);
  11315. fputs(ctx->stop_meta, stdout);
  11316. if (fixed_percent == 1000)
  11317. e2fsck_clear_progbar(ctx);
  11318. fflush(stdout);
  11319. return 0;
  11320. }
  11321. static int e2fsck_update_progress(e2fsck_t ctx, int pass,
  11322. unsigned long cur, unsigned long max)
  11323. {
  11324. char buf[80];
  11325. float percent;
  11326. if (pass == 0)
  11327. return 0;
  11328. if (ctx->progress_fd) {
  11329. sprintf(buf, "%d %lu %lu\n", pass, cur, max);
  11330. write(ctx->progress_fd, buf, strlen(buf));
  11331. } else {
  11332. percent = calc_percent(&e2fsck_tbl, pass, cur, max);
  11333. e2fsck_simple_progress(ctx, ctx->device_name,
  11334. percent, 0);
  11335. }
  11336. return 0;
  11337. }
  11338. static void reserve_stdio_fds(void)
  11339. {
  11340. int fd;
  11341. while (1) {
  11342. fd = open(bb_dev_null, O_RDWR);
  11343. if (fd > 2)
  11344. break;
  11345. if (fd < 0) {
  11346. fprintf(stderr, _("ERROR: Cannot open "
  11347. "/dev/null (%s)\n"),
  11348. strerror(errno));
  11349. break;
  11350. }
  11351. }
  11352. close(fd);
  11353. }
  11354. static void signal_progress_on(int sig FSCK_ATTR((unused)))
  11355. {
  11356. e2fsck_t ctx = e2fsck_global_ctx;
  11357. if (!ctx)
  11358. return;
  11359. ctx->progress = e2fsck_update_progress;
  11360. ctx->progress_fd = 0;
  11361. }
  11362. static void signal_progress_off(int sig FSCK_ATTR((unused)))
  11363. {
  11364. e2fsck_t ctx = e2fsck_global_ctx;
  11365. if (!ctx)
  11366. return;
  11367. e2fsck_clear_progbar(ctx);
  11368. ctx->progress = 0;
  11369. }
  11370. static void signal_cancel(int sig FSCK_ATTR((unused)))
  11371. {
  11372. e2fsck_t ctx = e2fsck_global_ctx;
  11373. if (!ctx)
  11374. exit(FSCK_CANCELED);
  11375. ctx->flags |= E2F_FLAG_CANCEL;
  11376. }
  11377. static void parse_extended_opts(e2fsck_t ctx, const char *opts)
  11378. {
  11379. char *buf, *token, *next, *p, *arg;
  11380. int ea_ver;
  11381. int extended_usage = 0;
  11382. buf = string_copy(opts, 0);
  11383. for (token = buf; token && *token; token = next) {
  11384. p = strchr(token, ',');
  11385. next = 0;
  11386. if (p) {
  11387. *p = 0;
  11388. next = p+1;
  11389. }
  11390. arg = strchr(token, '=');
  11391. if (arg) {
  11392. *arg = 0;
  11393. arg++;
  11394. }
  11395. if (strcmp(token, "ea_ver") == 0) {
  11396. if (!arg) {
  11397. extended_usage++;
  11398. continue;
  11399. }
  11400. ea_ver = strtoul(arg, &p, 0);
  11401. if (*p ||
  11402. ((ea_ver != 1) && (ea_ver != 2))) {
  11403. fprintf(stderr,
  11404. _("Invalid EA version.\n"));
  11405. extended_usage++;
  11406. continue;
  11407. }
  11408. ctx->ext_attr_ver = ea_ver;
  11409. } else {
  11410. fprintf(stderr, _("Unknown extended option: %s\n"),
  11411. token);
  11412. extended_usage++;
  11413. }
  11414. }
  11415. if (extended_usage) {
  11416. bb_error_msg_and_die(
  11417. "Extended options are separated by commas, "
  11418. "and may take an argument which\n"
  11419. "is set off by an equals ('=') sign. "
  11420. "Valid extended options are:\n"
  11421. "\tea_ver=<ea_version (1 or 2)>\n\n");
  11422. }
  11423. }
  11424. static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
  11425. {
  11426. int flush = 0;
  11427. int c, fd;
  11428. e2fsck_t ctx;
  11429. errcode_t retval;
  11430. struct sigaction sa;
  11431. char *extended_opts = 0;
  11432. retval = e2fsck_allocate_context(&ctx);
  11433. if (retval)
  11434. return retval;
  11435. *ret_ctx = ctx;
  11436. setvbuf(stdout, NULL, _IONBF, BUFSIZ);
  11437. setvbuf(stderr, NULL, _IONBF, BUFSIZ);
  11438. if (isatty(0) && isatty(1)) {
  11439. ctx->interactive = 1;
  11440. } else {
  11441. ctx->start_meta[0] = '\001';
  11442. ctx->stop_meta[0] = '\002';
  11443. }
  11444. memset(bar, '=', sizeof(bar)-1);
  11445. memset(spaces, ' ', sizeof(spaces)-1);
  11446. blkid_get_cache(&ctx->blkid, NULL);
  11447. if (argc && *argv)
  11448. ctx->program_name = *argv;
  11449. else
  11450. ctx->program_name = "e2fsck";
  11451. while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
  11452. switch (c) {
  11453. case 'C':
  11454. ctx->progress = e2fsck_update_progress;
  11455. ctx->progress_fd = atoi(optarg);
  11456. if (!ctx->progress_fd)
  11457. break;
  11458. /* Validate the file descriptor to avoid disasters */
  11459. fd = dup(ctx->progress_fd);
  11460. if (fd < 0) {
  11461. fprintf(stderr,
  11462. _("Error validating file descriptor %d: %s\n"),
  11463. ctx->progress_fd,
  11464. error_message(errno));
  11465. bb_error_msg_and_die(_("Invalid completion information file descriptor"));
  11466. } else
  11467. close(fd);
  11468. break;
  11469. case 'D':
  11470. ctx->options |= E2F_OPT_COMPRESS_DIRS;
  11471. break;
  11472. case 'E':
  11473. extended_opts = optarg;
  11474. break;
  11475. case 'p':
  11476. case 'a':
  11477. if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
  11478. conflict_opt:
  11479. bb_error_msg_and_die(_("Only one the options -p/-a, -n or -y may be specified."));
  11480. }
  11481. ctx->options |= E2F_OPT_PREEN;
  11482. break;
  11483. case 'n':
  11484. if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
  11485. goto conflict_opt;
  11486. ctx->options |= E2F_OPT_NO;
  11487. break;
  11488. case 'y':
  11489. if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
  11490. goto conflict_opt;
  11491. ctx->options |= E2F_OPT_YES;
  11492. break;
  11493. case 't':
  11494. /* FIXME - This needs to go away in a future path - will change binary */
  11495. fprintf(stderr, _("The -t option is not "
  11496. "supported on this version of e2fsck.\n"));
  11497. break;
  11498. case 'c':
  11499. if (cflag++)
  11500. ctx->options |= E2F_OPT_WRITECHECK;
  11501. ctx->options |= E2F_OPT_CHECKBLOCKS;
  11502. break;
  11503. case 'r':
  11504. /* What we do by default, anyway! */
  11505. break;
  11506. case 'b':
  11507. ctx->use_superblock = atoi(optarg);
  11508. ctx->flags |= E2F_FLAG_SB_SPECIFIED;
  11509. break;
  11510. case 'B':
  11511. ctx->blocksize = atoi(optarg);
  11512. break;
  11513. case 'I':
  11514. ctx->inode_buffer_blocks = atoi(optarg);
  11515. break;
  11516. case 'j':
  11517. ctx->journal_name = string_copy(optarg, 0);
  11518. break;
  11519. case 'P':
  11520. ctx->process_inode_size = atoi(optarg);
  11521. break;
  11522. case 'd':
  11523. ctx->options |= E2F_OPT_DEBUG;
  11524. break;
  11525. case 'f':
  11526. ctx->options |= E2F_OPT_FORCE;
  11527. break;
  11528. case 'F':
  11529. flush = 1;
  11530. break;
  11531. case 'v':
  11532. verbose = 1;
  11533. break;
  11534. case 'V':
  11535. show_version_only = 1;
  11536. break;
  11537. case 'N':
  11538. ctx->device_name = optarg;
  11539. break;
  11540. #ifdef ENABLE_SWAPFS
  11541. case 's':
  11542. normalize_swapfs = 1;
  11543. case 'S':
  11544. swapfs = 1;
  11545. break;
  11546. #else
  11547. case 's':
  11548. case 'S':
  11549. fprintf(stderr, _("Byte-swapping filesystems "
  11550. "not compiled in this version "
  11551. "of e2fsck\n"));
  11552. exit(1);
  11553. #endif
  11554. default:
  11555. bb_show_usage();
  11556. }
  11557. if (show_version_only)
  11558. return 0;
  11559. if (optind != argc - 1)
  11560. bb_show_usage();
  11561. if ((ctx->options & E2F_OPT_NO) &&
  11562. !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
  11563. ctx->options |= E2F_OPT_READONLY;
  11564. ctx->io_options = strchr(argv[optind], '?');
  11565. if (ctx->io_options)
  11566. *ctx->io_options++ = 0;
  11567. ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
  11568. if (!ctx->filesystem_name) {
  11569. bb_error_msg(_("Unable to resolve '%s'"), argv[optind]);
  11570. bb_error_msg_and_die(0);
  11571. }
  11572. if (extended_opts)
  11573. parse_extended_opts(ctx, extended_opts);
  11574. if (flush) {
  11575. fd = open(ctx->filesystem_name, O_RDONLY, 0);
  11576. if (fd < 0) {
  11577. bb_error_msg(_("while opening %s for flushing"),
  11578. ctx->filesystem_name);
  11579. bb_error_msg_and_die(0);
  11580. }
  11581. if ((retval = ext2fs_sync_device(fd, 1))) {
  11582. bb_error_msg(_("while trying to flush %s"),
  11583. ctx->filesystem_name);
  11584. bb_error_msg_and_die(0);
  11585. }
  11586. close(fd);
  11587. }
  11588. #ifdef ENABLE_SWAPFS
  11589. if (swapfs && cflag) {
  11590. fprintf(stderr, _("Incompatible options not "
  11591. "allowed when byte-swapping.\n"));
  11592. exit(EXIT_USAGE);
  11593. }
  11594. #endif
  11595. /*
  11596. * Set up signal action
  11597. */
  11598. memset(&sa, 0, sizeof(struct sigaction));
  11599. sa.sa_handler = signal_cancel;
  11600. sigaction(SIGINT, &sa, 0);
  11601. sigaction(SIGTERM, &sa, 0);
  11602. #ifdef SA_RESTART
  11603. sa.sa_flags = SA_RESTART;
  11604. #endif
  11605. e2fsck_global_ctx = ctx;
  11606. sa.sa_handler = signal_progress_on;
  11607. sigaction(SIGUSR1, &sa, 0);
  11608. sa.sa_handler = signal_progress_off;
  11609. sigaction(SIGUSR2, &sa, 0);
  11610. /* Update our PATH to include /sbin if we need to run badblocks */
  11611. if (cflag)
  11612. e2fs_set_sbin_path();
  11613. return 0;
  11614. }
  11615. static const char my_ver_string[] = E2FSPROGS_VERSION;
  11616. static const char my_ver_date[] = E2FSPROGS_DATE;
  11617. int e2fsck_main (int argc, char *argv[])
  11618. {
  11619. errcode_t retval;
  11620. int exit_value = EXIT_OK;
  11621. ext2_filsys fs = 0;
  11622. io_manager io_ptr;
  11623. struct ext2_super_block *sb;
  11624. const char *lib_ver_date;
  11625. int my_ver, lib_ver;
  11626. e2fsck_t ctx;
  11627. struct problem_context pctx;
  11628. int flags, run_result;
  11629. clear_problem_context(&pctx);
  11630. my_ver = ext2fs_parse_version_string(my_ver_string);
  11631. lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
  11632. if (my_ver > lib_ver) {
  11633. fprintf( stderr, _("Error: ext2fs library version "
  11634. "out of date!\n"));
  11635. show_version_only++;
  11636. }
  11637. retval = PRS(argc, argv, &ctx);
  11638. if (retval) {
  11639. bb_error_msg(_("while trying to initialize program"));
  11640. exit(EXIT_ERROR);
  11641. }
  11642. reserve_stdio_fds();
  11643. if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
  11644. fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
  11645. my_ver_date);
  11646. if (show_version_only) {
  11647. fprintf(stderr, _("\tUsing %s, %s\n"),
  11648. error_message(EXT2_ET_BASE), lib_ver_date);
  11649. exit(EXIT_OK);
  11650. }
  11651. check_mount(ctx);
  11652. if (!(ctx->options & E2F_OPT_PREEN) &&
  11653. !(ctx->options & E2F_OPT_NO) &&
  11654. !(ctx->options & E2F_OPT_YES)) {
  11655. if (!ctx->interactive)
  11656. bb_error_msg_and_die(_("need terminal for interactive repairs"));
  11657. }
  11658. ctx->superblock = ctx->use_superblock;
  11659. restart:
  11660. #ifdef CONFIG_TESTIO_DEBUG
  11661. io_ptr = test_io_manager;
  11662. test_io_backing_manager = unix_io_manager;
  11663. #else
  11664. io_ptr = unix_io_manager;
  11665. #endif
  11666. flags = 0;
  11667. if ((ctx->options & E2F_OPT_READONLY) == 0)
  11668. flags |= EXT2_FLAG_RW;
  11669. if (ctx->superblock && ctx->blocksize) {
  11670. retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
  11671. flags, ctx->superblock, ctx->blocksize,
  11672. io_ptr, &fs);
  11673. } else if (ctx->superblock) {
  11674. int blocksize;
  11675. for (blocksize = EXT2_MIN_BLOCK_SIZE;
  11676. blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
  11677. retval = ext2fs_open2(ctx->filesystem_name,
  11678. ctx->io_options, flags,
  11679. ctx->superblock, blocksize,
  11680. io_ptr, &fs);
  11681. if (!retval)
  11682. break;
  11683. }
  11684. } else
  11685. retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
  11686. flags, 0, 0, io_ptr, &fs);
  11687. if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
  11688. !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
  11689. ((retval == EXT2_ET_BAD_MAGIC) ||
  11690. ((retval == 0) && ext2fs_check_desc(fs)))) {
  11691. if (!fs || (fs->group_desc_count > 1)) {
  11692. printf(_("%s trying backup blocks...\n"),
  11693. retval ? _("Couldn't find ext2 superblock,") :
  11694. _("Group descriptors look bad..."));
  11695. get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
  11696. if (fs)
  11697. ext2fs_close(fs);
  11698. goto restart;
  11699. }
  11700. }
  11701. if (retval) {
  11702. bb_error_msg(_("while trying to open %s"),
  11703. ctx->filesystem_name);
  11704. if (retval == EXT2_ET_REV_TOO_HIGH) {
  11705. printf(_("The filesystem revision is apparently "
  11706. "too high for this version of e2fsck.\n"
  11707. "(Or the filesystem superblock "
  11708. "is corrupt)\n\n"));
  11709. fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
  11710. } else if (retval == EXT2_ET_SHORT_READ)
  11711. printf(_("Could this be a zero-length partition?\n"));
  11712. else if ((retval == EPERM) || (retval == EACCES))
  11713. printf(_("You must have %s access to the "
  11714. "filesystem or be root\n"),
  11715. (ctx->options & E2F_OPT_READONLY) ?
  11716. "r/o" : "r/w");
  11717. else if (retval == ENXIO)
  11718. printf(_("Possibly non-existent or swap device?\n"));
  11719. #ifdef EROFS
  11720. else if (retval == EROFS)
  11721. printf(_("Disk write-protected; use the -n option "
  11722. "to do a read-only\n"
  11723. "check of the device.\n"));
  11724. #endif
  11725. else
  11726. fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
  11727. bb_error_msg_and_die(0);
  11728. }
  11729. ctx->fs = fs;
  11730. fs->priv_data = ctx;
  11731. sb = fs->super;
  11732. if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
  11733. bb_error_msg(_("while trying to open %s"),
  11734. ctx->filesystem_name);
  11735. get_newer:
  11736. bb_error_msg_and_die(_("Get a newer version of e2fsck!"));
  11737. }
  11738. /*
  11739. * Set the device name, which is used whenever we print error
  11740. * or informational messages to the user.
  11741. */
  11742. if (ctx->device_name == 0 &&
  11743. (sb->s_volume_name[0] != 0)) {
  11744. ctx->device_name = string_copy(sb->s_volume_name,
  11745. sizeof(sb->s_volume_name));
  11746. }
  11747. if (ctx->device_name == 0)
  11748. ctx->device_name = ctx->filesystem_name;
  11749. /*
  11750. * Make sure the ext3 superblock fields are consistent.
  11751. */
  11752. retval = e2fsck_check_ext3_journal(ctx);
  11753. if (retval) {
  11754. bb_error_msg(_("while checking ext3 journal for %s"),
  11755. ctx->device_name);
  11756. bb_error_msg_and_die(0);
  11757. }
  11758. /*
  11759. * Check to see if we need to do ext3-style recovery. If so,
  11760. * do it, and then restart the fsck.
  11761. */
  11762. if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
  11763. if (ctx->options & E2F_OPT_READONLY) {
  11764. printf(_("Warning: skipping journal recovery "
  11765. "because doing a read-only filesystem "
  11766. "check.\n"));
  11767. io_channel_flush(ctx->fs->io);
  11768. } else {
  11769. if (ctx->flags & E2F_FLAG_RESTARTED) {
  11770. /*
  11771. * Whoops, we attempted to run the
  11772. * journal twice. This should never
  11773. * happen, unless the hardware or
  11774. * device driver is being bogus.
  11775. */
  11776. bb_error_msg(_("cannot set superblock flags on %s"), ctx->device_name);
  11777. bb_error_msg_and_die(0);
  11778. }
  11779. retval = e2fsck_run_ext3_journal(ctx);
  11780. if (retval) {
  11781. bb_error_msg(_("while recovering ext3 journal of %s"),
  11782. ctx->device_name);
  11783. bb_error_msg_and_die(0);
  11784. }
  11785. ext2fs_close(ctx->fs);
  11786. ctx->fs = 0;
  11787. ctx->flags |= E2F_FLAG_RESTARTED;
  11788. goto restart;
  11789. }
  11790. }
  11791. /*
  11792. * Check for compatibility with the feature sets. We need to
  11793. * be more stringent than ext2fs_open().
  11794. */
  11795. if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
  11796. (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
  11797. bb_error_msg("(%s)", ctx->device_name);
  11798. goto get_newer;
  11799. }
  11800. if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
  11801. bb_error_msg("(%s)", ctx->device_name);
  11802. goto get_newer;
  11803. }
  11804. #ifdef ENABLE_COMPRESSION
  11805. /* FIXME - do we support this at all? */
  11806. if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
  11807. bb_error_msg(_("Warning: compression support is experimental."));
  11808. #endif
  11809. #ifndef ENABLE_HTREE
  11810. if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
  11811. bb_error_msg(_("E2fsck not compiled with HTREE support,\n\t"
  11812. "but filesystem %s has HTREE directories."),
  11813. ctx->device_name);
  11814. goto get_newer;
  11815. }
  11816. #endif
  11817. /*
  11818. * If the user specified a specific superblock, presumably the
  11819. * master superblock has been trashed. So we mark the
  11820. * superblock as dirty, so it can be written out.
  11821. */
  11822. if (ctx->superblock &&
  11823. !(ctx->options & E2F_OPT_READONLY))
  11824. ext2fs_mark_super_dirty(fs);
  11825. /*
  11826. * We only update the master superblock because (a) paranoia;
  11827. * we don't want to corrupt the backup superblocks, and (b) we
  11828. * don't need to update the mount count and last checked
  11829. * fields in the backup superblock (the kernel doesn't
  11830. * update the backup superblocks anyway).
  11831. */
  11832. fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
  11833. ehandler_init(fs->io);
  11834. if (ctx->superblock)
  11835. set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
  11836. ext2fs_mark_valid(fs);
  11837. check_super_block(ctx);
  11838. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  11839. bb_error_msg_and_die(0);
  11840. check_if_skip(ctx);
  11841. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  11842. bb_error_msg_and_die(0);
  11843. #ifdef ENABLE_SWAPFS
  11844. #ifdef WORDS_BIGENDIAN
  11845. #define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES
  11846. #else
  11847. #define NATIVE_FLAG 0
  11848. #endif
  11849. if (normalize_swapfs) {
  11850. if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == NATIVE_FLAG) {
  11851. fprintf(stderr, _("%s: Filesystem byte order "
  11852. "already normalized.\n"), ctx->device_name);
  11853. bb_error_msg_and_die(0);
  11854. }
  11855. }
  11856. if (swapfs) {
  11857. swap_filesys(ctx);
  11858. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  11859. bb_error_msg_and_die(0);
  11860. }
  11861. #endif
  11862. /*
  11863. * Mark the system as valid, 'til proven otherwise
  11864. */
  11865. ext2fs_mark_valid(fs);
  11866. retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
  11867. if (retval) {
  11868. bb_error_msg(_("while reading bad blocks inode"));
  11869. preenhalt(ctx);
  11870. printf(_("This doesn't bode well,"
  11871. " but we'll try to go on...\n"));
  11872. }
  11873. run_result = e2fsck_run(ctx);
  11874. e2fsck_clear_progbar(ctx);
  11875. if (run_result == E2F_FLAG_RESTART) {
  11876. printf(_("Restarting e2fsck from the beginning...\n"));
  11877. retval = e2fsck_reset_context(ctx);
  11878. if (retval) {
  11879. bb_error_msg(_("while resetting context"));
  11880. bb_error_msg_and_die(0);
  11881. }
  11882. ext2fs_close(fs);
  11883. goto restart;
  11884. }
  11885. if (run_result & E2F_FLAG_CANCEL) {
  11886. printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
  11887. ctx->device_name : ctx->filesystem_name);
  11888. exit_value |= FSCK_CANCELED;
  11889. }
  11890. if (run_result & E2F_FLAG_ABORT)
  11891. bb_error_msg_and_die(_("aborted"));
  11892. /* Cleanup */
  11893. if (ext2fs_test_changed(fs)) {
  11894. exit_value |= EXIT_NONDESTRUCT;
  11895. if (!(ctx->options & E2F_OPT_PREEN))
  11896. printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
  11897. ctx->device_name);
  11898. if (ctx->mount_flags & EXT2_MF_ISROOT) {
  11899. printf(_("%s: ***** REBOOT LINUX *****\n"),
  11900. ctx->device_name);
  11901. exit_value |= EXIT_DESTRUCT;
  11902. }
  11903. }
  11904. if (!ext2fs_test_valid(fs)) {
  11905. printf(_("\n%s: ********** WARNING: Filesystem still has "
  11906. "errors **********\n\n"), ctx->device_name);
  11907. exit_value |= EXIT_UNCORRECTED;
  11908. exit_value &= ~EXIT_NONDESTRUCT;
  11909. }
  11910. if (exit_value & FSCK_CANCELED)
  11911. exit_value &= ~EXIT_NONDESTRUCT;
  11912. else {
  11913. show_stats(ctx);
  11914. if (!(ctx->options & E2F_OPT_READONLY)) {
  11915. if (ext2fs_test_valid(fs)) {
  11916. if (!(sb->s_state & EXT2_VALID_FS))
  11917. exit_value |= EXIT_NONDESTRUCT;
  11918. sb->s_state = EXT2_VALID_FS;
  11919. } else
  11920. sb->s_state &= ~EXT2_VALID_FS;
  11921. sb->s_mnt_count = 0;
  11922. sb->s_lastcheck = time(NULL);
  11923. ext2fs_mark_super_dirty(fs);
  11924. }
  11925. }
  11926. e2fsck_write_bitmaps(ctx);
  11927. ext2fs_close(fs);
  11928. ctx->fs = NULL;
  11929. free(ctx->filesystem_name);
  11930. free(ctx->journal_name);
  11931. e2fsck_free_context(ctx);
  11932. return exit_value;
  11933. }