3
0

e2fsck.c 355 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520
  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 source tree.
  30. */
  31. /*
  32. //usage:#define e2fsck_trivial_usage
  33. //usage: "[-panyrcdfvstDFSV] [-b superblock] [-B blocksize] "
  34. //usage: "[-I inode_buffer_blocks] [-P process_inode_size] "
  35. //usage: "[-l|-L bad_blocks_file] [-C fd] [-j external_journal] "
  36. //usage: "[-E extended-options] device"
  37. //usage:#define e2fsck_full_usage "\n\n"
  38. //usage: "Check ext2/ext3 file system\n"
  39. //usage: "\n -p Automatic repair (no questions)"
  40. //usage: "\n -n Make no changes to the filesystem"
  41. //usage: "\n -y Assume 'yes' to all questions"
  42. //usage: "\n -c Check for bad blocks and add them to the badblock list"
  43. //usage: "\n -f Force checking even if filesystem is marked clean"
  44. //usage: "\n -v Verbose"
  45. //usage: "\n -b superblock Use alternative superblock"
  46. //usage: "\n -B blocksize Force blocksize when looking for superblock"
  47. //usage: "\n -j journal Set location of the external journal"
  48. //usage: "\n -l file Add to badblocks list"
  49. //usage: "\n -L file Set badblocks list"
  50. */
  51. #include "e2fsck.h" /*Put all of our defines here to clean things up*/
  52. #define _(x) x
  53. #define N_(x) x
  54. /*
  55. * Procedure declarations
  56. */
  57. static void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf);
  58. /* pass1.c */
  59. static void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool);
  60. /* pass2.c */
  61. static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
  62. ext2_ino_t ino, char *buf);
  63. /* pass3.c */
  64. static int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t inode);
  65. static errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
  66. int num, int gauranteed_size);
  67. static ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix);
  68. static errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino,
  69. int adj);
  70. /* rehash.c */
  71. static void e2fsck_rehash_directories(e2fsck_t ctx);
  72. /* util.c */
  73. static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
  74. const char *description);
  75. static int ask(e2fsck_t ctx, const char * string, int def);
  76. static void e2fsck_read_bitmaps(e2fsck_t ctx);
  77. static void preenhalt(e2fsck_t ctx);
  78. static void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
  79. struct ext2_inode * inode, const char * proc);
  80. static void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
  81. struct ext2_inode * inode, const char * proc);
  82. static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
  83. const char *name, io_manager manager);
  84. /* unix.c */
  85. static void e2fsck_clear_progbar(e2fsck_t ctx);
  86. static int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
  87. float percent, unsigned int dpynum);
  88. /*
  89. * problem.h --- e2fsck problem error codes
  90. */
  91. typedef __u32 problem_t;
  92. struct problem_context {
  93. errcode_t errcode;
  94. ext2_ino_t ino, ino2, dir;
  95. struct ext2_inode *inode;
  96. struct ext2_dir_entry *dirent;
  97. blk_t blk, blk2;
  98. e2_blkcnt_t blkcount;
  99. int group;
  100. __u64 num;
  101. const char *str;
  102. };
  103. /*
  104. * Function declarations
  105. */
  106. static int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx);
  107. static int end_problem_latch(e2fsck_t ctx, int mask);
  108. static int set_latch_flags(int mask, int setflags, int clearflags);
  109. static void clear_problem_context(struct problem_context *ctx);
  110. /*
  111. * Dictionary Abstract Data Type
  112. * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
  113. *
  114. * dict.h v 1.22.2.6 2000/11/13 01:36:44 kaz
  115. * kazlib_1_20
  116. */
  117. #ifndef DICT_H
  118. #define DICT_H
  119. /*
  120. * Blurb for inclusion into C++ translation units
  121. */
  122. typedef unsigned long dictcount_t;
  123. #define DICTCOUNT_T_MAX ULONG_MAX
  124. /*
  125. * The dictionary is implemented as a red-black tree
  126. */
  127. typedef enum { dnode_red, dnode_black } dnode_color_t;
  128. typedef struct dnode_t {
  129. struct dnode_t *dict_left;
  130. struct dnode_t *dict_right;
  131. struct dnode_t *dict_parent;
  132. dnode_color_t dict_color;
  133. const void *dict_key;
  134. void *dict_data;
  135. } dnode_t;
  136. typedef int (*dict_comp_t)(const void *, const void *);
  137. typedef void (*dnode_free_t)(dnode_t *);
  138. typedef struct dict_t {
  139. dnode_t dict_nilnode;
  140. dictcount_t dict_nodecount;
  141. dictcount_t dict_maxcount;
  142. dict_comp_t dict_compare;
  143. dnode_free_t dict_freenode;
  144. int dict_dupes;
  145. } dict_t;
  146. typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
  147. typedef struct dict_load_t {
  148. dict_t *dict_dictptr;
  149. dnode_t dict_nilnode;
  150. } dict_load_t;
  151. #define dict_count(D) ((D)->dict_nodecount)
  152. #define dnode_get(N) ((N)->dict_data)
  153. #define dnode_getkey(N) ((N)->dict_key)
  154. #endif
  155. /*
  156. * Compatibility header file for e2fsck which should be included
  157. * instead of linux/jfs.h
  158. *
  159. * Copyright (C) 2000 Stephen C. Tweedie
  160. */
  161. /*
  162. * Pull in the definition of the e2fsck context structure
  163. */
  164. struct buffer_head {
  165. char b_data[8192];
  166. e2fsck_t b_ctx;
  167. io_channel b_io;
  168. int b_size;
  169. blk_t b_blocknr;
  170. int b_dirty;
  171. int b_uptodate;
  172. int b_err;
  173. };
  174. #define K_DEV_FS 1
  175. #define K_DEV_JOURNAL 2
  176. #define lock_buffer(bh) do {} while (0)
  177. #define unlock_buffer(bh) do {} while (0)
  178. #define buffer_req(bh) 1
  179. #define do_readahead(journal, start) do {} while (0)
  180. static e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
  181. typedef struct {
  182. int object_length;
  183. } kmem_cache_t;
  184. #define kmem_cache_alloc(cache,flags) malloc((cache)->object_length)
  185. /*
  186. * We use the standard libext2fs portability tricks for inline
  187. * functions.
  188. */
  189. static kmem_cache_t * do_cache_create(int len)
  190. {
  191. kmem_cache_t *new_cache;
  192. new_cache = xmalloc(sizeof(*new_cache));
  193. new_cache->object_length = len;
  194. return new_cache;
  195. }
  196. static void do_cache_destroy(kmem_cache_t *cache)
  197. {
  198. free(cache);
  199. }
  200. /*
  201. * Dictionary Abstract Data Type
  202. */
  203. /*
  204. * These macros provide short convenient names for structure members,
  205. * which are embellished with dict_ prefixes so that they are
  206. * properly confined to the documented namespace. It's legal for a
  207. * program which uses dict to define, for instance, a macro called ``parent''.
  208. * Such a macro would interfere with the dnode_t struct definition.
  209. * In general, highly portable and reusable C modules which expose their
  210. * structures need to confine structure member names to well-defined spaces.
  211. * The resulting identifiers aren't necessarily convenient to use, nor
  212. * readable, in the implementation, however!
  213. */
  214. #define left dict_left
  215. #define right dict_right
  216. #define parent dict_parent
  217. #define color dict_color
  218. #define key dict_key
  219. #define data dict_data
  220. #define nilnode dict_nilnode
  221. #define maxcount dict_maxcount
  222. #define compare dict_compare
  223. #define dupes dict_dupes
  224. #define dict_root(D) ((D)->nilnode.left)
  225. #define dict_nil(D) (&(D)->nilnode)
  226. static void dnode_free(dnode_t *node);
  227. /*
  228. * Perform a ``left rotation'' adjustment on the tree. The given node P and
  229. * its right child C are rearranged so that the P instead becomes the left
  230. * child of C. The left subtree of C is inherited as the new right subtree
  231. * for P. The ordering of the keys within the tree is thus preserved.
  232. */
  233. static void rotate_left(dnode_t *upper)
  234. {
  235. dnode_t *lower, *lowleft, *upparent;
  236. lower = upper->right;
  237. upper->right = lowleft = lower->left;
  238. lowleft->parent = upper;
  239. lower->parent = upparent = upper->parent;
  240. /* don't need to check for root node here because root->parent is
  241. the sentinel nil node, and root->parent->left points back to root */
  242. if (upper == upparent->left) {
  243. upparent->left = lower;
  244. } else {
  245. assert (upper == upparent->right);
  246. upparent->right = lower;
  247. }
  248. lower->left = upper;
  249. upper->parent = lower;
  250. }
  251. /*
  252. * This operation is the ``mirror'' image of rotate_left. It is
  253. * the same procedure, but with left and right interchanged.
  254. */
  255. static void rotate_right(dnode_t *upper)
  256. {
  257. dnode_t *lower, *lowright, *upparent;
  258. lower = upper->left;
  259. upper->left = lowright = lower->right;
  260. lowright->parent = upper;
  261. lower->parent = upparent = upper->parent;
  262. if (upper == upparent->right) {
  263. upparent->right = lower;
  264. } else {
  265. assert (upper == upparent->left);
  266. upparent->left = lower;
  267. }
  268. lower->right = upper;
  269. upper->parent = lower;
  270. }
  271. /*
  272. * Do a postorder traversal of the tree rooted at the specified
  273. * node and free everything under it. Used by dict_free().
  274. */
  275. static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil)
  276. {
  277. if (node == nil)
  278. return;
  279. free_nodes(dict, node->left, nil);
  280. free_nodes(dict, node->right, nil);
  281. dict->dict_freenode(node);
  282. }
  283. /*
  284. * Verify that the tree contains the given node. This is done by
  285. * traversing all of the nodes and comparing their pointers to the
  286. * given pointer. Returns 1 if the node is found, otherwise
  287. * returns zero. It is intended for debugging purposes.
  288. */
  289. static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node)
  290. {
  291. if (root != nil) {
  292. return root == node
  293. || verify_dict_has_node(nil, root->left, node)
  294. || verify_dict_has_node(nil, root->right, node);
  295. }
  296. return 0;
  297. }
  298. /*
  299. * Select a different set of node allocator routines.
  300. */
  301. static void dict_set_allocator(dict_t *dict, dnode_free_t fr)
  302. {
  303. assert(dict_count(dict) == 0);
  304. dict->dict_freenode = fr;
  305. }
  306. /*
  307. * Free all the nodes in the dictionary by using the dictionary's
  308. * installed free routine. The dictionary is emptied.
  309. */
  310. static void dict_free_nodes(dict_t *dict)
  311. {
  312. dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
  313. free_nodes(dict, root, nil);
  314. dict->dict_nodecount = 0;
  315. dict->nilnode.left = &dict->nilnode;
  316. dict->nilnode.right = &dict->nilnode;
  317. }
  318. /*
  319. * Initialize a user-supplied dictionary object.
  320. */
  321. static dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp)
  322. {
  323. dict->compare = comp;
  324. dict->dict_freenode = dnode_free;
  325. dict->dict_nodecount = 0;
  326. dict->maxcount = maxcount;
  327. dict->nilnode.left = &dict->nilnode;
  328. dict->nilnode.right = &dict->nilnode;
  329. dict->nilnode.parent = &dict->nilnode;
  330. dict->nilnode.color = dnode_black;
  331. dict->dupes = 0;
  332. return dict;
  333. }
  334. /*
  335. * Locate a node in the dictionary having the given key.
  336. * If the node is not found, a null a pointer is returned (rather than
  337. * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
  338. * located node is returned.
  339. */
  340. static dnode_t *dict_lookup(dict_t *dict, const void *key)
  341. {
  342. dnode_t *root = dict_root(dict);
  343. dnode_t *nil = dict_nil(dict);
  344. dnode_t *saved;
  345. int result;
  346. /* simple binary search adapted for trees that contain duplicate keys */
  347. while (root != nil) {
  348. result = dict->compare(key, root->key);
  349. if (result < 0)
  350. root = root->left;
  351. else if (result > 0)
  352. root = root->right;
  353. else {
  354. if (!dict->dupes) { /* no duplicates, return match */
  355. return root;
  356. } else { /* could be dupes, find leftmost one */
  357. do {
  358. saved = root;
  359. root = root->left;
  360. while (root != nil && dict->compare(key, root->key))
  361. root = root->right;
  362. } while (root != nil);
  363. return saved;
  364. }
  365. }
  366. }
  367. return NULL;
  368. }
  369. /*
  370. * Insert a node into the dictionary. The node should have been
  371. * initialized with a data field. All other fields are ignored.
  372. * The behavior is undefined if the user attempts to insert into
  373. * a dictionary that is already full (for which the dict_isfull()
  374. * function returns true).
  375. */
  376. static void dict_insert(dict_t *dict, dnode_t *node, const void *key)
  377. {
  378. dnode_t *where = dict_root(dict), *nil = dict_nil(dict);
  379. dnode_t *parent = nil, *uncle, *grandpa;
  380. int result = -1;
  381. node->key = key;
  382. /* basic binary tree insert */
  383. while (where != nil) {
  384. parent = where;
  385. result = dict->compare(key, where->key);
  386. /* trap attempts at duplicate key insertion unless it's explicitly allowed */
  387. assert(dict->dupes || result != 0);
  388. if (result < 0)
  389. where = where->left;
  390. else
  391. where = where->right;
  392. }
  393. assert(where == nil);
  394. if (result < 0)
  395. parent->left = node;
  396. else
  397. parent->right = node;
  398. node->parent = parent;
  399. node->left = nil;
  400. node->right = nil;
  401. dict->dict_nodecount++;
  402. /* red black adjustments */
  403. node->color = dnode_red;
  404. while (parent->color == dnode_red) {
  405. grandpa = parent->parent;
  406. if (parent == grandpa->left) {
  407. uncle = grandpa->right;
  408. if (uncle->color == dnode_red) { /* red parent, red uncle */
  409. parent->color = dnode_black;
  410. uncle->color = dnode_black;
  411. grandpa->color = dnode_red;
  412. node = grandpa;
  413. parent = grandpa->parent;
  414. } else { /* red parent, black uncle */
  415. if (node == parent->right) {
  416. rotate_left(parent);
  417. parent = node;
  418. assert (grandpa == parent->parent);
  419. /* rotation between parent and child preserves grandpa */
  420. }
  421. parent->color = dnode_black;
  422. grandpa->color = dnode_red;
  423. rotate_right(grandpa);
  424. break;
  425. }
  426. } else { /* symmetric cases: parent == parent->parent->right */
  427. uncle = grandpa->left;
  428. if (uncle->color == dnode_red) {
  429. parent->color = dnode_black;
  430. uncle->color = dnode_black;
  431. grandpa->color = dnode_red;
  432. node = grandpa;
  433. parent = grandpa->parent;
  434. } else {
  435. if (node == parent->left) {
  436. rotate_right(parent);
  437. parent = node;
  438. assert (grandpa == parent->parent);
  439. }
  440. parent->color = dnode_black;
  441. grandpa->color = dnode_red;
  442. rotate_left(grandpa);
  443. break;
  444. }
  445. }
  446. }
  447. dict_root(dict)->color = dnode_black;
  448. }
  449. /*
  450. * Allocate a node using the dictionary's allocator routine, give it
  451. * the data item.
  452. */
  453. static dnode_t *dnode_init(dnode_t *dnode, void *data)
  454. {
  455. dnode->data = data;
  456. dnode->parent = NULL;
  457. dnode->left = NULL;
  458. dnode->right = NULL;
  459. return dnode;
  460. }
  461. static int dict_alloc_insert(dict_t *dict, const void *key, void *data)
  462. {
  463. dnode_t *node = xmalloc(sizeof(dnode_t));
  464. dnode_init(node, data);
  465. dict_insert(dict, node, key);
  466. return 1;
  467. }
  468. /*
  469. * Return the node with the lowest (leftmost) key. If the dictionary is empty
  470. * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
  471. */
  472. static dnode_t *dict_first(dict_t *dict)
  473. {
  474. dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
  475. if (root != nil)
  476. while ((left = root->left) != nil)
  477. root = left;
  478. return (root == nil) ? NULL : root;
  479. }
  480. /*
  481. * Return the given node's successor node---the node which has the
  482. * next key in the left to right ordering. If the node has
  483. * no successor, a null pointer is returned rather than a pointer to
  484. * the nil node.
  485. */
  486. static dnode_t *dict_next(dict_t *dict, dnode_t *curr)
  487. {
  488. dnode_t *nil = dict_nil(dict), *parent, *left;
  489. if (curr->right != nil) {
  490. curr = curr->right;
  491. while ((left = curr->left) != nil)
  492. curr = left;
  493. return curr;
  494. }
  495. parent = curr->parent;
  496. while (parent != nil && curr == parent->right) {
  497. curr = parent;
  498. parent = curr->parent;
  499. }
  500. return (parent == nil) ? NULL : parent;
  501. }
  502. static void dnode_free(dnode_t *node)
  503. {
  504. free(node);
  505. }
  506. #undef left
  507. #undef right
  508. #undef parent
  509. #undef color
  510. #undef key
  511. #undef data
  512. #undef nilnode
  513. #undef maxcount
  514. #undef compare
  515. #undef dupes
  516. /*
  517. * dirinfo.c --- maintains the directory information table for e2fsck.
  518. */
  519. /*
  520. * This subroutine is called during pass1 to create a directory info
  521. * entry. During pass1, the passed-in parent is 0; it will get filled
  522. * in during pass2.
  523. */
  524. static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
  525. {
  526. struct dir_info *dir;
  527. int i, j;
  528. ext2_ino_t num_dirs;
  529. errcode_t retval;
  530. unsigned long old_size;
  531. if (!ctx->dir_info) {
  532. ctx->dir_info_count = 0;
  533. retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
  534. if (retval)
  535. num_dirs = 1024; /* Guess */
  536. ctx->dir_info_size = num_dirs + 10;
  537. ctx->dir_info = (struct dir_info *)
  538. e2fsck_allocate_memory(ctx, ctx->dir_info_size
  539. * sizeof (struct dir_info),
  540. "directory map");
  541. }
  542. if (ctx->dir_info_count >= ctx->dir_info_size) {
  543. old_size = ctx->dir_info_size * sizeof(struct dir_info);
  544. ctx->dir_info_size += 10;
  545. retval = ext2fs_resize_mem(old_size, ctx->dir_info_size *
  546. sizeof(struct dir_info),
  547. &ctx->dir_info);
  548. if (retval) {
  549. ctx->dir_info_size -= 10;
  550. return;
  551. }
  552. }
  553. /*
  554. * Normally, add_dir_info is called with each inode in
  555. * sequential order; but once in a while (like when pass 3
  556. * needs to recreate the root directory or lost+found
  557. * directory) it is called out of order. In those cases, we
  558. * need to move the dir_info entries down to make room, since
  559. * the dir_info array needs to be sorted by inode number for
  560. * get_dir_info()'s sake.
  561. */
  562. if (ctx->dir_info_count &&
  563. ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
  564. for (i = ctx->dir_info_count-1; i > 0; i--)
  565. if (ctx->dir_info[i-1].ino < ino)
  566. break;
  567. dir = &ctx->dir_info[i];
  568. if (dir->ino != ino)
  569. for (j = ctx->dir_info_count++; j > i; j--)
  570. ctx->dir_info[j] = ctx->dir_info[j-1];
  571. } else
  572. dir = &ctx->dir_info[ctx->dir_info_count++];
  573. dir->ino = ino;
  574. dir->dotdot = parent;
  575. dir->parent = parent;
  576. }
  577. /*
  578. * get_dir_info() --- given an inode number, try to find the directory
  579. * information entry for it.
  580. */
  581. static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
  582. {
  583. int low, high, mid;
  584. low = 0;
  585. high = ctx->dir_info_count-1;
  586. if (!ctx->dir_info)
  587. return 0;
  588. if (ino == ctx->dir_info[low].ino)
  589. return &ctx->dir_info[low];
  590. if (ino == ctx->dir_info[high].ino)
  591. return &ctx->dir_info[high];
  592. while (low < high) {
  593. mid = (low+high)/2;
  594. if (mid == low || mid == high)
  595. break;
  596. if (ino == ctx->dir_info[mid].ino)
  597. return &ctx->dir_info[mid];
  598. if (ino < ctx->dir_info[mid].ino)
  599. high = mid;
  600. else
  601. low = mid;
  602. }
  603. return 0;
  604. }
  605. /*
  606. * Free the dir_info structure when it isn't needed any more.
  607. */
  608. static void e2fsck_free_dir_info(e2fsck_t ctx)
  609. {
  610. ext2fs_free_mem(&ctx->dir_info);
  611. ctx->dir_info_size = 0;
  612. ctx->dir_info_count = 0;
  613. }
  614. /*
  615. * Return the count of number of directories in the dir_info structure
  616. */
  617. static int e2fsck_get_num_dirinfo(e2fsck_t ctx)
  618. {
  619. return ctx->dir_info_count;
  620. }
  621. /*
  622. * A simple interator function
  623. */
  624. static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
  625. {
  626. if (*control >= ctx->dir_info_count)
  627. return 0;
  628. return ctx->dir_info + (*control)++;
  629. }
  630. /*
  631. * dirinfo.c --- maintains the directory information table for e2fsck.
  632. *
  633. */
  634. #ifdef ENABLE_HTREE
  635. /*
  636. * This subroutine is called during pass1 to create a directory info
  637. * entry. During pass1, the passed-in parent is 0; it will get filled
  638. * in during pass2.
  639. */
  640. static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
  641. {
  642. struct dx_dir_info *dir;
  643. int i, j;
  644. errcode_t retval;
  645. unsigned long old_size;
  646. if (!ctx->dx_dir_info) {
  647. ctx->dx_dir_info_count = 0;
  648. ctx->dx_dir_info_size = 100; /* Guess */
  649. ctx->dx_dir_info = (struct dx_dir_info *)
  650. e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size
  651. * sizeof (struct dx_dir_info),
  652. "directory map");
  653. }
  654. if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
  655. old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
  656. ctx->dx_dir_info_size += 10;
  657. retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
  658. sizeof(struct dx_dir_info),
  659. &ctx->dx_dir_info);
  660. if (retval) {
  661. ctx->dx_dir_info_size -= 10;
  662. return;
  663. }
  664. }
  665. /*
  666. * Normally, add_dx_dir_info is called with each inode in
  667. * sequential order; but once in a while (like when pass 3
  668. * needs to recreate the root directory or lost+found
  669. * directory) it is called out of order. In those cases, we
  670. * need to move the dx_dir_info entries down to make room, since
  671. * the dx_dir_info array needs to be sorted by inode number for
  672. * get_dx_dir_info()'s sake.
  673. */
  674. if (ctx->dx_dir_info_count &&
  675. ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) {
  676. for (i = ctx->dx_dir_info_count-1; i > 0; i--)
  677. if (ctx->dx_dir_info[i-1].ino < ino)
  678. break;
  679. dir = &ctx->dx_dir_info[i];
  680. if (dir->ino != ino)
  681. for (j = ctx->dx_dir_info_count++; j > i; j--)
  682. ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
  683. } else
  684. dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
  685. dir->ino = ino;
  686. dir->numblocks = num_blocks;
  687. dir->hashversion = 0;
  688. dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
  689. * sizeof (struct dx_dirblock_info),
  690. "dx_block info array");
  691. }
  692. /*
  693. * get_dx_dir_info() --- given an inode number, try to find the directory
  694. * information entry for it.
  695. */
  696. static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
  697. {
  698. int low, high, mid;
  699. low = 0;
  700. high = ctx->dx_dir_info_count-1;
  701. if (!ctx->dx_dir_info)
  702. return 0;
  703. if (ino == ctx->dx_dir_info[low].ino)
  704. return &ctx->dx_dir_info[low];
  705. if (ino == ctx->dx_dir_info[high].ino)
  706. return &ctx->dx_dir_info[high];
  707. while (low < high) {
  708. mid = (low+high)/2;
  709. if (mid == low || mid == high)
  710. break;
  711. if (ino == ctx->dx_dir_info[mid].ino)
  712. return &ctx->dx_dir_info[mid];
  713. if (ino < ctx->dx_dir_info[mid].ino)
  714. high = mid;
  715. else
  716. low = mid;
  717. }
  718. return 0;
  719. }
  720. /*
  721. * Free the dx_dir_info structure when it isn't needed any more.
  722. */
  723. static void e2fsck_free_dx_dir_info(e2fsck_t ctx)
  724. {
  725. int i;
  726. struct dx_dir_info *dir;
  727. if (ctx->dx_dir_info) {
  728. dir = ctx->dx_dir_info;
  729. for (i=0; i < ctx->dx_dir_info_count; i++) {
  730. ext2fs_free_mem(&dir->dx_block);
  731. }
  732. ext2fs_free_mem(&ctx->dx_dir_info);
  733. }
  734. ctx->dx_dir_info_size = 0;
  735. ctx->dx_dir_info_count = 0;
  736. }
  737. /*
  738. * A simple interator function
  739. */
  740. static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
  741. {
  742. if (*control >= ctx->dx_dir_info_count)
  743. return 0;
  744. return ctx->dx_dir_info + (*control)++;
  745. }
  746. #endif /* ENABLE_HTREE */
  747. /*
  748. * e2fsck.c - a consistency checker for the new extended file system.
  749. *
  750. */
  751. /*
  752. * This function allocates an e2fsck context
  753. */
  754. static errcode_t e2fsck_allocate_context(e2fsck_t *ret)
  755. {
  756. e2fsck_t context;
  757. errcode_t retval;
  758. retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
  759. if (retval)
  760. return retval;
  761. memset(context, 0, sizeof(struct e2fsck_struct));
  762. context->process_inode_size = 256;
  763. context->ext_attr_ver = 2;
  764. *ret = context;
  765. return 0;
  766. }
  767. struct ea_refcount_el {
  768. blk_t ea_blk;
  769. int ea_count;
  770. };
  771. struct ea_refcount {
  772. blk_t count;
  773. blk_t size;
  774. blk_t cursor;
  775. struct ea_refcount_el *list;
  776. };
  777. static void ea_refcount_free(ext2_refcount_t refcount)
  778. {
  779. if (!refcount)
  780. return;
  781. ext2fs_free_mem(&refcount->list);
  782. ext2fs_free_mem(&refcount);
  783. }
  784. /*
  785. * This function resets an e2fsck context; it is called when e2fsck
  786. * needs to be restarted.
  787. */
  788. static errcode_t e2fsck_reset_context(e2fsck_t ctx)
  789. {
  790. ctx->flags = 0;
  791. ctx->lost_and_found = 0;
  792. ctx->bad_lost_and_found = 0;
  793. ext2fs_free_inode_bitmap(ctx->inode_used_map);
  794. ctx->inode_used_map = 0;
  795. ext2fs_free_inode_bitmap(ctx->inode_dir_map);
  796. ctx->inode_dir_map = 0;
  797. ext2fs_free_inode_bitmap(ctx->inode_reg_map);
  798. ctx->inode_reg_map = 0;
  799. ext2fs_free_block_bitmap(ctx->block_found_map);
  800. ctx->block_found_map = 0;
  801. ext2fs_free_icount(ctx->inode_link_info);
  802. ctx->inode_link_info = 0;
  803. if (ctx->journal_io) {
  804. if (ctx->fs && ctx->fs->io != ctx->journal_io)
  805. io_channel_close(ctx->journal_io);
  806. ctx->journal_io = 0;
  807. }
  808. if (ctx->fs) {
  809. ext2fs_free_dblist(ctx->fs->dblist);
  810. ctx->fs->dblist = 0;
  811. }
  812. e2fsck_free_dir_info(ctx);
  813. #ifdef ENABLE_HTREE
  814. e2fsck_free_dx_dir_info(ctx);
  815. #endif
  816. ea_refcount_free(ctx->refcount);
  817. ctx->refcount = 0;
  818. ea_refcount_free(ctx->refcount_extra);
  819. ctx->refcount_extra = 0;
  820. ext2fs_free_block_bitmap(ctx->block_dup_map);
  821. ctx->block_dup_map = 0;
  822. ext2fs_free_block_bitmap(ctx->block_ea_map);
  823. ctx->block_ea_map = 0;
  824. ext2fs_free_inode_bitmap(ctx->inode_bad_map);
  825. ctx->inode_bad_map = 0;
  826. ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
  827. ctx->inode_imagic_map = 0;
  828. ext2fs_u32_list_free(ctx->dirs_to_hash);
  829. ctx->dirs_to_hash = 0;
  830. /*
  831. * Clear the array of invalid meta-data flags
  832. */
  833. ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
  834. ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
  835. ext2fs_free_mem(&ctx->invalid_inode_table_flag);
  836. /* Clear statistic counters */
  837. ctx->fs_directory_count = 0;
  838. ctx->fs_regular_count = 0;
  839. ctx->fs_blockdev_count = 0;
  840. ctx->fs_chardev_count = 0;
  841. ctx->fs_links_count = 0;
  842. ctx->fs_symlinks_count = 0;
  843. ctx->fs_fast_symlinks_count = 0;
  844. ctx->fs_fifo_count = 0;
  845. ctx->fs_total_count = 0;
  846. ctx->fs_sockets_count = 0;
  847. ctx->fs_ind_count = 0;
  848. ctx->fs_dind_count = 0;
  849. ctx->fs_tind_count = 0;
  850. ctx->fs_fragmented = 0;
  851. ctx->large_files = 0;
  852. /* Reset the superblock to the user's requested value */
  853. ctx->superblock = ctx->use_superblock;
  854. return 0;
  855. }
  856. static void e2fsck_free_context(e2fsck_t ctx)
  857. {
  858. if (!ctx)
  859. return;
  860. e2fsck_reset_context(ctx);
  861. if (ctx->blkid)
  862. blkid_put_cache(ctx->blkid);
  863. ext2fs_free_mem(&ctx);
  864. }
  865. /*
  866. * ea_refcount.c
  867. */
  868. /*
  869. * The strategy we use for keeping track of EA refcounts is as
  870. * follows. We keep a sorted array of first EA blocks and its
  871. * reference counts. Once the refcount has dropped to zero, it is
  872. * removed from the array to save memory space. Once the EA block is
  873. * checked, its bit is set in the block_ea_map bitmap.
  874. */
  875. static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
  876. {
  877. ext2_refcount_t refcount;
  878. errcode_t retval;
  879. size_t bytes;
  880. retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount);
  881. if (retval)
  882. return retval;
  883. memset(refcount, 0, sizeof(struct ea_refcount));
  884. if (!size)
  885. size = 500;
  886. refcount->size = size;
  887. bytes = (size_t) (size * sizeof(struct ea_refcount_el));
  888. #ifdef DEBUG
  889. printf("Refcount allocated %d entries, %d bytes.\n",
  890. refcount->size, bytes);
  891. #endif
  892. retval = ext2fs_get_mem(bytes, &refcount->list);
  893. if (retval)
  894. goto errout;
  895. memset(refcount->list, 0, bytes);
  896. refcount->count = 0;
  897. refcount->cursor = 0;
  898. *ret = refcount;
  899. return 0;
  900. errout:
  901. ea_refcount_free(refcount);
  902. return retval;
  903. }
  904. /*
  905. * collapse_refcount() --- go through the refcount array, and get rid
  906. * of any count == zero entries
  907. */
  908. static void refcount_collapse(ext2_refcount_t refcount)
  909. {
  910. unsigned int i, j;
  911. struct ea_refcount_el *list;
  912. list = refcount->list;
  913. for (i = 0, j = 0; i < refcount->count; i++) {
  914. if (list[i].ea_count) {
  915. if (i != j)
  916. list[j] = list[i];
  917. j++;
  918. }
  919. }
  920. #if defined(DEBUG) || defined(TEST_PROGRAM)
  921. printf("Refcount_collapse: size was %d, now %d\n",
  922. refcount->count, j);
  923. #endif
  924. refcount->count = j;
  925. }
  926. /*
  927. * insert_refcount_el() --- Insert a new entry into the sorted list at a
  928. * specified position.
  929. */
  930. static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
  931. blk_t blk, int pos)
  932. {
  933. struct ea_refcount_el *el;
  934. errcode_t retval;
  935. blk_t new_size = 0;
  936. int num;
  937. if (refcount->count >= refcount->size) {
  938. new_size = refcount->size + 100;
  939. #ifdef DEBUG
  940. printf("Reallocating refcount %d entries...\n", new_size);
  941. #endif
  942. retval = ext2fs_resize_mem((size_t) refcount->size *
  943. sizeof(struct ea_refcount_el),
  944. (size_t) new_size *
  945. sizeof(struct ea_refcount_el),
  946. &refcount->list);
  947. if (retval)
  948. return 0;
  949. refcount->size = new_size;
  950. }
  951. num = (int) refcount->count - pos;
  952. if (num < 0)
  953. return 0; /* should never happen */
  954. if (num) {
  955. memmove(&refcount->list[pos+1], &refcount->list[pos],
  956. sizeof(struct ea_refcount_el) * num);
  957. }
  958. refcount->count++;
  959. el = &refcount->list[pos];
  960. el->ea_count = 0;
  961. el->ea_blk = blk;
  962. return el;
  963. }
  964. /*
  965. * get_refcount_el() --- given an block number, try to find refcount
  966. * information in the sorted list. If the create flag is set,
  967. * and we can't find an entry, create one in the sorted list.
  968. */
  969. static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
  970. blk_t blk, int create)
  971. {
  972. float range;
  973. int low, high, mid;
  974. blk_t lowval, highval;
  975. if (!refcount || !refcount->list)
  976. return 0;
  977. retry:
  978. low = 0;
  979. high = (int) refcount->count-1;
  980. if (create && ((refcount->count == 0) ||
  981. (blk > refcount->list[high].ea_blk))) {
  982. if (refcount->count >= refcount->size)
  983. refcount_collapse(refcount);
  984. return insert_refcount_el(refcount, blk,
  985. (unsigned) refcount->count);
  986. }
  987. if (refcount->count == 0)
  988. return 0;
  989. if (refcount->cursor >= refcount->count)
  990. refcount->cursor = 0;
  991. if (blk == refcount->list[refcount->cursor].ea_blk)
  992. return &refcount->list[refcount->cursor++];
  993. #ifdef DEBUG
  994. printf("Non-cursor get_refcount_el: %u\n", blk);
  995. #endif
  996. while (low <= high) {
  997. if (low == high)
  998. mid = low;
  999. else {
  1000. /* Interpolate for efficiency */
  1001. lowval = refcount->list[low].ea_blk;
  1002. highval = refcount->list[high].ea_blk;
  1003. if (blk < lowval)
  1004. range = 0;
  1005. else if (blk > highval)
  1006. range = 1;
  1007. else
  1008. range = ((float) (blk - lowval)) /
  1009. (highval - lowval);
  1010. mid = low + ((int) (range * (high-low)));
  1011. }
  1012. if (blk == refcount->list[mid].ea_blk) {
  1013. refcount->cursor = mid+1;
  1014. return &refcount->list[mid];
  1015. }
  1016. if (blk < refcount->list[mid].ea_blk)
  1017. high = mid-1;
  1018. else
  1019. low = mid+1;
  1020. }
  1021. /*
  1022. * If we need to create a new entry, it should be right at
  1023. * low (where high will be left at low-1).
  1024. */
  1025. if (create) {
  1026. if (refcount->count >= refcount->size) {
  1027. refcount_collapse(refcount);
  1028. if (refcount->count < refcount->size)
  1029. goto retry;
  1030. }
  1031. return insert_refcount_el(refcount, blk, low);
  1032. }
  1033. return 0;
  1034. }
  1035. static errcode_t
  1036. ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
  1037. {
  1038. struct ea_refcount_el *el;
  1039. el = get_refcount_el(refcount, blk, 1);
  1040. if (!el)
  1041. return EXT2_ET_NO_MEMORY;
  1042. el->ea_count++;
  1043. if (ret)
  1044. *ret = el->ea_count;
  1045. return 0;
  1046. }
  1047. static errcode_t
  1048. ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
  1049. {
  1050. struct ea_refcount_el *el;
  1051. el = get_refcount_el(refcount, blk, 0);
  1052. if (!el || el->ea_count == 0)
  1053. return EXT2_ET_INVALID_ARGUMENT;
  1054. el->ea_count--;
  1055. if (ret)
  1056. *ret = el->ea_count;
  1057. return 0;
  1058. }
  1059. static errcode_t
  1060. ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
  1061. {
  1062. struct ea_refcount_el *el;
  1063. /*
  1064. * Get the refcount element
  1065. */
  1066. el = get_refcount_el(refcount, blk, count ? 1 : 0);
  1067. if (!el)
  1068. return count ? EXT2_ET_NO_MEMORY : 0;
  1069. el->ea_count = count;
  1070. return 0;
  1071. }
  1072. static inline void ea_refcount_intr_begin(ext2_refcount_t refcount)
  1073. {
  1074. refcount->cursor = 0;
  1075. }
  1076. static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret)
  1077. {
  1078. struct ea_refcount_el *list;
  1079. while (1) {
  1080. if (refcount->cursor >= refcount->count)
  1081. return 0;
  1082. list = refcount->list;
  1083. if (list[refcount->cursor].ea_count) {
  1084. if (ret)
  1085. *ret = list[refcount->cursor].ea_count;
  1086. return list[refcount->cursor++].ea_blk;
  1087. }
  1088. refcount->cursor++;
  1089. }
  1090. }
  1091. /*
  1092. * ehandler.c --- handle bad block errors which come up during the
  1093. * course of an e2fsck session.
  1094. */
  1095. static const char *operation;
  1096. static errcode_t
  1097. e2fsck_handle_read_error(io_channel channel, unsigned long block, int count,
  1098. void *data, size_t size FSCK_ATTR((unused)),
  1099. int actual FSCK_ATTR((unused)), errcode_t error)
  1100. {
  1101. int i;
  1102. char *p;
  1103. ext2_filsys fs = (ext2_filsys) channel->app_data;
  1104. e2fsck_t ctx;
  1105. ctx = (e2fsck_t) fs->priv_data;
  1106. /*
  1107. * If more than one block was read, try reading each block
  1108. * separately. We could use the actual bytes read to figure
  1109. * out where to start, but we don't bother.
  1110. */
  1111. if (count > 1) {
  1112. p = (char *) data;
  1113. for (i=0; i < count; i++, p += channel->block_size, block++) {
  1114. error = io_channel_read_blk(channel, block,
  1115. 1, p);
  1116. if (error)
  1117. return error;
  1118. }
  1119. return 0;
  1120. }
  1121. if (operation)
  1122. printf(_("Error reading block %lu (%s) while %s. "), block,
  1123. error_message(error), operation);
  1124. else
  1125. printf(_("Error reading block %lu (%s). "), block,
  1126. error_message(error));
  1127. preenhalt(ctx);
  1128. if (ask(ctx, _("Ignore error"), 1)) {
  1129. if (ask(ctx, _("Force rewrite"), 1))
  1130. io_channel_write_blk(channel, block, 1, data);
  1131. return 0;
  1132. }
  1133. return error;
  1134. }
  1135. static errcode_t
  1136. e2fsck_handle_write_error(io_channel channel, unsigned long block, int count,
  1137. const void *data, size_t size FSCK_ATTR((unused)),
  1138. int actual FSCK_ATTR((unused)), errcode_t error)
  1139. {
  1140. int i;
  1141. const char *p;
  1142. ext2_filsys fs = (ext2_filsys) channel->app_data;
  1143. e2fsck_t ctx;
  1144. ctx = (e2fsck_t) fs->priv_data;
  1145. /*
  1146. * If more than one block was written, try writing each block
  1147. * separately. We could use the actual bytes read to figure
  1148. * out where to start, but we don't bother.
  1149. */
  1150. if (count > 1) {
  1151. p = (const char *) data;
  1152. for (i=0; i < count; i++, p += channel->block_size, block++) {
  1153. error = io_channel_write_blk(channel, block,
  1154. 1, p);
  1155. if (error)
  1156. return error;
  1157. }
  1158. return 0;
  1159. }
  1160. if (operation)
  1161. printf(_("Error writing block %lu (%s) while %s. "), block,
  1162. error_message(error), operation);
  1163. else
  1164. printf(_("Error writing block %lu (%s). "), block,
  1165. error_message(error));
  1166. preenhalt(ctx);
  1167. if (ask(ctx, _("Ignore error"), 1))
  1168. return 0;
  1169. return error;
  1170. }
  1171. static const char *ehandler_operation(const char *op)
  1172. {
  1173. const char *ret = operation;
  1174. operation = op;
  1175. return ret;
  1176. }
  1177. static void ehandler_init(io_channel channel)
  1178. {
  1179. channel->read_error = e2fsck_handle_read_error;
  1180. channel->write_error = e2fsck_handle_write_error;
  1181. }
  1182. /*
  1183. * journal.c --- code for handling the "ext3" journal
  1184. *
  1185. * Copyright (C) 2000 Andreas Dilger
  1186. * Copyright (C) 2000 Theodore Ts'o
  1187. *
  1188. * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
  1189. * Copyright (C) 1999 Red Hat Software
  1190. *
  1191. * This file may be redistributed under the terms of the
  1192. * GNU General Public License version 2 or at your discretion
  1193. * any later version.
  1194. */
  1195. /*
  1196. * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
  1197. * This creates a larger static binary, and a smaller binary using
  1198. * shared libraries. It's also probably slightly less CPU-efficient,
  1199. * which is why it's not on by default. But, it's a good way of
  1200. * testing the functions in inode_io.c and fileio.c.
  1201. */
  1202. #undef USE_INODE_IO
  1203. /* Kernel compatibility functions for handling the journal. These allow us
  1204. * to use the recovery.c file virtually unchanged from the kernel, so we
  1205. * don't have to do much to keep kernel and user recovery in sync.
  1206. */
  1207. static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys)
  1208. {
  1209. #ifdef USE_INODE_IO
  1210. *phys = block;
  1211. return 0;
  1212. #else
  1213. struct inode *inode = journal->j_inode;
  1214. errcode_t retval;
  1215. blk_t pblk;
  1216. if (!inode) {
  1217. *phys = block;
  1218. return 0;
  1219. }
  1220. retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino,
  1221. &inode->i_ext2, NULL, 0, block, &pblk);
  1222. *phys = pblk;
  1223. return retval;
  1224. #endif
  1225. }
  1226. static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize)
  1227. {
  1228. struct buffer_head *bh;
  1229. bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer");
  1230. if (!bh)
  1231. return NULL;
  1232. bh->b_ctx = kdev->k_ctx;
  1233. if (kdev->k_dev == K_DEV_FS)
  1234. bh->b_io = kdev->k_ctx->fs->io;
  1235. else
  1236. bh->b_io = kdev->k_ctx->journal_io;
  1237. bh->b_size = blocksize;
  1238. bh->b_blocknr = blocknr;
  1239. return bh;
  1240. }
  1241. static void sync_blockdev(kdev_t kdev)
  1242. {
  1243. io_channel io;
  1244. if (kdev->k_dev == K_DEV_FS)
  1245. io = kdev->k_ctx->fs->io;
  1246. else
  1247. io = kdev->k_ctx->journal_io;
  1248. io_channel_flush(io);
  1249. }
  1250. static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
  1251. {
  1252. int retval;
  1253. struct buffer_head *bh;
  1254. for (; nr > 0; --nr) {
  1255. bh = *bhp++;
  1256. if (rw == READ && !bh->b_uptodate) {
  1257. retval = io_channel_read_blk(bh->b_io,
  1258. bh->b_blocknr,
  1259. 1, bh->b_data);
  1260. if (retval) {
  1261. bb_error_msg("while reading block %lu",
  1262. (unsigned long) bh->b_blocknr);
  1263. bh->b_err = retval;
  1264. continue;
  1265. }
  1266. bh->b_uptodate = 1;
  1267. } else if (rw == WRITE && bh->b_dirty) {
  1268. retval = io_channel_write_blk(bh->b_io,
  1269. bh->b_blocknr,
  1270. 1, bh->b_data);
  1271. if (retval) {
  1272. bb_error_msg("while writing block %lu",
  1273. (unsigned long) bh->b_blocknr);
  1274. bh->b_err = retval;
  1275. continue;
  1276. }
  1277. bh->b_dirty = 0;
  1278. bh->b_uptodate = 1;
  1279. }
  1280. }
  1281. }
  1282. static void mark_buffer_dirty(struct buffer_head *bh)
  1283. {
  1284. bh->b_dirty = 1;
  1285. }
  1286. static inline void mark_buffer_clean(struct buffer_head * bh)
  1287. {
  1288. bh->b_dirty = 0;
  1289. }
  1290. static void brelse(struct buffer_head *bh)
  1291. {
  1292. if (bh->b_dirty)
  1293. ll_rw_block(WRITE, 1, &bh);
  1294. ext2fs_free_mem(&bh);
  1295. }
  1296. static int buffer_uptodate(struct buffer_head *bh)
  1297. {
  1298. return bh->b_uptodate;
  1299. }
  1300. static inline void mark_buffer_uptodate(struct buffer_head *bh, int val)
  1301. {
  1302. bh->b_uptodate = val;
  1303. }
  1304. static void wait_on_buffer(struct buffer_head *bh)
  1305. {
  1306. if (!bh->b_uptodate)
  1307. ll_rw_block(READ, 1, &bh);
  1308. }
  1309. static void e2fsck_clear_recover(e2fsck_t ctx, int error)
  1310. {
  1311. ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
  1312. /* if we had an error doing journal recovery, we need a full fsck */
  1313. if (error)
  1314. ctx->fs->super->s_state &= ~EXT2_VALID_FS;
  1315. ext2fs_mark_super_dirty(ctx->fs);
  1316. }
  1317. static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
  1318. {
  1319. struct ext2_super_block *sb = ctx->fs->super;
  1320. struct ext2_super_block jsuper;
  1321. struct problem_context pctx;
  1322. struct buffer_head *bh;
  1323. struct inode *j_inode = NULL;
  1324. struct kdev_s *dev_fs = NULL, *dev_journal;
  1325. const char *journal_name = NULL;
  1326. journal_t *journal = NULL;
  1327. errcode_t retval = 0;
  1328. io_manager io_ptr = 0;
  1329. unsigned long start = 0;
  1330. blk_t blk;
  1331. int ext_journal = 0;
  1332. int tried_backup_jnl = 0;
  1333. int i;
  1334. clear_problem_context(&pctx);
  1335. journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
  1336. if (!journal) {
  1337. return EXT2_ET_NO_MEMORY;
  1338. }
  1339. dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
  1340. if (!dev_fs) {
  1341. retval = EXT2_ET_NO_MEMORY;
  1342. goto errout;
  1343. }
  1344. dev_journal = dev_fs+1;
  1345. dev_fs->k_ctx = dev_journal->k_ctx = ctx;
  1346. dev_fs->k_dev = K_DEV_FS;
  1347. dev_journal->k_dev = K_DEV_JOURNAL;
  1348. journal->j_dev = dev_journal;
  1349. journal->j_fs_dev = dev_fs;
  1350. journal->j_inode = NULL;
  1351. journal->j_blocksize = ctx->fs->blocksize;
  1352. if (uuid_is_null(sb->s_journal_uuid)) {
  1353. if (!sb->s_journal_inum)
  1354. return EXT2_ET_BAD_INODE_NUM;
  1355. j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
  1356. "journal inode");
  1357. if (!j_inode) {
  1358. retval = EXT2_ET_NO_MEMORY;
  1359. goto errout;
  1360. }
  1361. j_inode->i_ctx = ctx;
  1362. j_inode->i_ino = sb->s_journal_inum;
  1363. if ((retval = ext2fs_read_inode(ctx->fs,
  1364. sb->s_journal_inum,
  1365. &j_inode->i_ext2))) {
  1366. try_backup_journal:
  1367. if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
  1368. tried_backup_jnl)
  1369. goto errout;
  1370. memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
  1371. memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
  1372. EXT2_N_BLOCKS*4);
  1373. j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
  1374. j_inode->i_ext2.i_links_count = 1;
  1375. j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
  1376. tried_backup_jnl++;
  1377. }
  1378. if (!j_inode->i_ext2.i_links_count ||
  1379. !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
  1380. retval = EXT2_ET_NO_JOURNAL;
  1381. goto try_backup_journal;
  1382. }
  1383. if (j_inode->i_ext2.i_size / journal->j_blocksize <
  1384. JFS_MIN_JOURNAL_BLOCKS) {
  1385. retval = EXT2_ET_JOURNAL_TOO_SMALL;
  1386. goto try_backup_journal;
  1387. }
  1388. for (i=0; i < EXT2_N_BLOCKS; i++) {
  1389. blk = j_inode->i_ext2.i_block[i];
  1390. if (!blk) {
  1391. if (i < EXT2_NDIR_BLOCKS) {
  1392. retval = EXT2_ET_JOURNAL_TOO_SMALL;
  1393. goto try_backup_journal;
  1394. }
  1395. continue;
  1396. }
  1397. if (blk < sb->s_first_data_block ||
  1398. blk >= sb->s_blocks_count) {
  1399. retval = EXT2_ET_BAD_BLOCK_NUM;
  1400. goto try_backup_journal;
  1401. }
  1402. }
  1403. journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
  1404. #ifdef USE_INODE_IO
  1405. retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
  1406. &j_inode->i_ext2,
  1407. &journal_name);
  1408. if (retval)
  1409. goto errout;
  1410. io_ptr = inode_io_manager;
  1411. #else
  1412. journal->j_inode = j_inode;
  1413. ctx->journal_io = ctx->fs->io;
  1414. if ((retval = journal_bmap(journal, 0, &start)) != 0)
  1415. goto errout;
  1416. #endif
  1417. } else {
  1418. ext_journal = 1;
  1419. if (!ctx->journal_name) {
  1420. char uuid[37];
  1421. uuid_unparse(sb->s_journal_uuid, uuid);
  1422. ctx->journal_name = blkid_get_devname(ctx->blkid,
  1423. "UUID", uuid);
  1424. if (!ctx->journal_name)
  1425. ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
  1426. }
  1427. journal_name = ctx->journal_name;
  1428. if (!journal_name) {
  1429. fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
  1430. return EXT2_ET_LOAD_EXT_JOURNAL;
  1431. }
  1432. io_ptr = unix_io_manager;
  1433. }
  1434. #ifndef USE_INODE_IO
  1435. if (ext_journal)
  1436. #endif
  1437. retval = io_ptr->open(journal_name, IO_FLAG_RW,
  1438. &ctx->journal_io);
  1439. if (retval)
  1440. goto errout;
  1441. io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
  1442. if (ext_journal) {
  1443. if (ctx->fs->blocksize == 1024)
  1444. start = 1;
  1445. bh = getblk(dev_journal, start, ctx->fs->blocksize);
  1446. if (!bh) {
  1447. retval = EXT2_ET_NO_MEMORY;
  1448. goto errout;
  1449. }
  1450. ll_rw_block(READ, 1, &bh);
  1451. if ((retval = bh->b_err) != 0)
  1452. goto errout;
  1453. memcpy(&jsuper, start ? bh->b_data : bh->b_data + 1024,
  1454. sizeof(jsuper));
  1455. brelse(bh);
  1456. #if BB_BIG_ENDIAN
  1457. if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
  1458. ext2fs_swap_super(&jsuper);
  1459. #endif
  1460. if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
  1461. !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
  1462. fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
  1463. retval = EXT2_ET_LOAD_EXT_JOURNAL;
  1464. goto errout;
  1465. }
  1466. /* Make sure the journal UUID is correct */
  1467. if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
  1468. sizeof(jsuper.s_uuid))) {
  1469. fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
  1470. retval = EXT2_ET_LOAD_EXT_JOURNAL;
  1471. goto errout;
  1472. }
  1473. journal->j_maxlen = jsuper.s_blocks_count;
  1474. start++;
  1475. }
  1476. if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
  1477. retval = EXT2_ET_NO_MEMORY;
  1478. goto errout;
  1479. }
  1480. journal->j_sb_buffer = bh;
  1481. journal->j_superblock = (journal_superblock_t *)bh->b_data;
  1482. #ifdef USE_INODE_IO
  1483. ext2fs_free_mem(&j_inode);
  1484. #endif
  1485. *ret_journal = journal;
  1486. return 0;
  1487. errout:
  1488. ext2fs_free_mem(&dev_fs);
  1489. ext2fs_free_mem(&j_inode);
  1490. ext2fs_free_mem(&journal);
  1491. return retval;
  1492. }
  1493. static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
  1494. struct problem_context *pctx)
  1495. {
  1496. struct ext2_super_block *sb = ctx->fs->super;
  1497. int recover = ctx->fs->super->s_feature_incompat &
  1498. EXT3_FEATURE_INCOMPAT_RECOVER;
  1499. int has_journal = ctx->fs->super->s_feature_compat &
  1500. EXT3_FEATURE_COMPAT_HAS_JOURNAL;
  1501. if (has_journal || sb->s_journal_inum) {
  1502. /* The journal inode is bogus, remove and force full fsck */
  1503. pctx->ino = sb->s_journal_inum;
  1504. if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
  1505. if (has_journal && sb->s_journal_inum)
  1506. printf("*** ext3 journal has been deleted - "
  1507. "filesystem is now ext2 only ***\n\n");
  1508. sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
  1509. sb->s_journal_inum = 0;
  1510. ctx->flags |= E2F_FLAG_JOURNAL_INODE; /* FIXME: todo */
  1511. e2fsck_clear_recover(ctx, 1);
  1512. return 0;
  1513. }
  1514. return EXT2_ET_BAD_INODE_NUM;
  1515. } else if (recover) {
  1516. if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
  1517. e2fsck_clear_recover(ctx, 1);
  1518. return 0;
  1519. }
  1520. return EXT2_ET_UNSUPP_FEATURE;
  1521. }
  1522. return 0;
  1523. }
  1524. #define V1_SB_SIZE 0x0024
  1525. static void clear_v2_journal_fields(journal_t *journal)
  1526. {
  1527. e2fsck_t ctx = journal->j_dev->k_ctx;
  1528. struct problem_context pctx;
  1529. clear_problem_context(&pctx);
  1530. if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
  1531. return;
  1532. memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
  1533. ctx->fs->blocksize-V1_SB_SIZE);
  1534. mark_buffer_dirty(journal->j_sb_buffer);
  1535. }
  1536. static errcode_t e2fsck_journal_load(journal_t *journal)
  1537. {
  1538. e2fsck_t ctx = journal->j_dev->k_ctx;
  1539. journal_superblock_t *jsb;
  1540. struct buffer_head *jbh = journal->j_sb_buffer;
  1541. struct problem_context pctx;
  1542. clear_problem_context(&pctx);
  1543. ll_rw_block(READ, 1, &jbh);
  1544. if (jbh->b_err) {
  1545. bb_error_msg(_("reading journal superblock"));
  1546. return jbh->b_err;
  1547. }
  1548. jsb = journal->j_superblock;
  1549. /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
  1550. if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
  1551. return e2fsck_journal_fix_bad_inode(ctx, &pctx);
  1552. switch (ntohl(jsb->s_header.h_blocktype)) {
  1553. case JFS_SUPERBLOCK_V1:
  1554. journal->j_format_version = 1;
  1555. if (jsb->s_feature_compat ||
  1556. jsb->s_feature_incompat ||
  1557. jsb->s_feature_ro_compat ||
  1558. jsb->s_nr_users)
  1559. clear_v2_journal_fields(journal);
  1560. break;
  1561. case JFS_SUPERBLOCK_V2:
  1562. journal->j_format_version = 2;
  1563. if (ntohl(jsb->s_nr_users) > 1 &&
  1564. uuid_is_null(ctx->fs->super->s_journal_uuid))
  1565. clear_v2_journal_fields(journal);
  1566. if (ntohl(jsb->s_nr_users) > 1) {
  1567. fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
  1568. return EXT2_ET_JOURNAL_UNSUPP_VERSION;
  1569. }
  1570. break;
  1571. /*
  1572. * These should never appear in a journal super block, so if
  1573. * they do, the journal is badly corrupted.
  1574. */
  1575. case JFS_DESCRIPTOR_BLOCK:
  1576. case JFS_COMMIT_BLOCK:
  1577. case JFS_REVOKE_BLOCK:
  1578. return EXT2_ET_CORRUPT_SUPERBLOCK;
  1579. /* If we don't understand the superblock major type, but there
  1580. * is a magic number, then it is likely to be a new format we
  1581. * just don't understand, so leave it alone. */
  1582. default:
  1583. return EXT2_ET_JOURNAL_UNSUPP_VERSION;
  1584. }
  1585. if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
  1586. return EXT2_ET_UNSUPP_FEATURE;
  1587. if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
  1588. return EXT2_ET_RO_UNSUPP_FEATURE;
  1589. /* We have now checked whether we know enough about the journal
  1590. * format to be able to proceed safely, so any other checks that
  1591. * fail we should attempt to recover from. */
  1592. if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
  1593. bb_error_msg(_("%s: no valid journal superblock found"),
  1594. ctx->device_name);
  1595. return EXT2_ET_CORRUPT_SUPERBLOCK;
  1596. }
  1597. if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
  1598. journal->j_maxlen = ntohl(jsb->s_maxlen);
  1599. else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) {
  1600. bb_error_msg(_("%s: journal too short"),
  1601. ctx->device_name);
  1602. return EXT2_ET_CORRUPT_SUPERBLOCK;
  1603. }
  1604. journal->j_tail_sequence = ntohl(jsb->s_sequence);
  1605. journal->j_transaction_sequence = journal->j_tail_sequence;
  1606. journal->j_tail = ntohl(jsb->s_start);
  1607. journal->j_first = ntohl(jsb->s_first);
  1608. journal->j_last = ntohl(jsb->s_maxlen);
  1609. return 0;
  1610. }
  1611. static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
  1612. journal_t *journal)
  1613. {
  1614. char *p;
  1615. union {
  1616. uuid_t uuid;
  1617. __u32 val[4];
  1618. } u;
  1619. __u32 new_seq = 0;
  1620. int i;
  1621. /* Leave a valid existing V1 superblock signature alone.
  1622. * Anything unrecognizable we overwrite with a new V2
  1623. * signature. */
  1624. if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
  1625. jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) {
  1626. jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
  1627. jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
  1628. }
  1629. /* Zero out everything else beyond the superblock header */
  1630. p = ((char *) jsb) + sizeof(journal_header_t);
  1631. memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
  1632. jsb->s_blocksize = htonl(ctx->fs->blocksize);
  1633. jsb->s_maxlen = htonl(journal->j_maxlen);
  1634. jsb->s_first = htonl(1);
  1635. /* Initialize the journal sequence number so that there is "no"
  1636. * chance we will find old "valid" transactions in the journal.
  1637. * This avoids the need to zero the whole journal (slow to do,
  1638. * and risky when we are just recovering the filesystem).
  1639. */
  1640. uuid_generate(u.uuid);
  1641. for (i = 0; i < 4; i ++)
  1642. new_seq ^= u.val[i];
  1643. jsb->s_sequence = htonl(new_seq);
  1644. mark_buffer_dirty(journal->j_sb_buffer);
  1645. ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
  1646. }
  1647. static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
  1648. journal_t *journal,
  1649. struct problem_context *pctx)
  1650. {
  1651. struct ext2_super_block *sb = ctx->fs->super;
  1652. int recover = ctx->fs->super->s_feature_incompat &
  1653. EXT3_FEATURE_INCOMPAT_RECOVER;
  1654. if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
  1655. if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
  1656. e2fsck_journal_reset_super(ctx, journal->j_superblock,
  1657. journal);
  1658. journal->j_transaction_sequence = 1;
  1659. e2fsck_clear_recover(ctx, recover);
  1660. return 0;
  1661. }
  1662. return EXT2_ET_CORRUPT_SUPERBLOCK;
  1663. } else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
  1664. return EXT2_ET_CORRUPT_SUPERBLOCK;
  1665. return 0;
  1666. }
  1667. static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
  1668. int reset, int drop)
  1669. {
  1670. journal_superblock_t *jsb;
  1671. if (drop)
  1672. mark_buffer_clean(journal->j_sb_buffer);
  1673. else if (!(ctx->options & E2F_OPT_READONLY)) {
  1674. jsb = journal->j_superblock;
  1675. jsb->s_sequence = htonl(journal->j_transaction_sequence);
  1676. if (reset)
  1677. jsb->s_start = 0; /* this marks the journal as empty */
  1678. mark_buffer_dirty(journal->j_sb_buffer);
  1679. }
  1680. brelse(journal->j_sb_buffer);
  1681. if (ctx->journal_io) {
  1682. if (ctx->fs && ctx->fs->io != ctx->journal_io)
  1683. io_channel_close(ctx->journal_io);
  1684. ctx->journal_io = 0;
  1685. }
  1686. #ifndef USE_INODE_IO
  1687. ext2fs_free_mem(&journal->j_inode);
  1688. #endif
  1689. ext2fs_free_mem(&journal->j_fs_dev);
  1690. ext2fs_free_mem(&journal);
  1691. }
  1692. /*
  1693. * This function makes sure that the superblock fields regarding the
  1694. * journal are consistent.
  1695. */
  1696. static int e2fsck_check_ext3_journal(e2fsck_t ctx)
  1697. {
  1698. struct ext2_super_block *sb = ctx->fs->super;
  1699. journal_t *journal;
  1700. int recover = ctx->fs->super->s_feature_incompat &
  1701. EXT3_FEATURE_INCOMPAT_RECOVER;
  1702. struct problem_context pctx;
  1703. problem_t problem;
  1704. int reset = 0, force_fsck = 0;
  1705. int retval;
  1706. /* If we don't have any journal features, don't do anything more */
  1707. if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
  1708. !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
  1709. uuid_is_null(sb->s_journal_uuid))
  1710. return 0;
  1711. clear_problem_context(&pctx);
  1712. pctx.num = sb->s_journal_inum;
  1713. retval = e2fsck_get_journal(ctx, &journal);
  1714. if (retval) {
  1715. if ((retval == EXT2_ET_BAD_INODE_NUM) ||
  1716. (retval == EXT2_ET_BAD_BLOCK_NUM) ||
  1717. (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
  1718. (retval == EXT2_ET_NO_JOURNAL))
  1719. return e2fsck_journal_fix_bad_inode(ctx, &pctx);
  1720. return retval;
  1721. }
  1722. retval = e2fsck_journal_load(journal);
  1723. if (retval) {
  1724. if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
  1725. ((retval == EXT2_ET_UNSUPP_FEATURE) &&
  1726. (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
  1727. &pctx))) ||
  1728. ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
  1729. (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
  1730. &pctx))) ||
  1731. ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
  1732. (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
  1733. retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
  1734. &pctx);
  1735. e2fsck_journal_release(ctx, journal, 0, 1);
  1736. return retval;
  1737. }
  1738. /*
  1739. * We want to make the flags consistent here. We will not leave with
  1740. * needs_recovery set but has_journal clear. We can't get in a loop
  1741. * with -y, -n, or -p, only if a user isn't making up their mind.
  1742. */
  1743. no_has_journal:
  1744. if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
  1745. recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER;
  1746. pctx.str = "inode";
  1747. if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
  1748. if (recover &&
  1749. !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
  1750. goto no_has_journal;
  1751. /*
  1752. * Need a full fsck if we are releasing a
  1753. * journal stored on a reserved inode.
  1754. */
  1755. force_fsck = recover ||
  1756. (sb->s_journal_inum < EXT2_FIRST_INODE(sb));
  1757. /* Clear all of the journal fields */
  1758. sb->s_journal_inum = 0;
  1759. sb->s_journal_dev = 0;
  1760. memset(sb->s_journal_uuid, 0,
  1761. sizeof(sb->s_journal_uuid));
  1762. e2fsck_clear_recover(ctx, force_fsck);
  1763. } else if (!(ctx->options & E2F_OPT_READONLY)) {
  1764. sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
  1765. ext2fs_mark_super_dirty(ctx->fs);
  1766. }
  1767. }
  1768. if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
  1769. !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
  1770. journal->j_superblock->s_start != 0) {
  1771. /* Print status information */
  1772. fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
  1773. if (ctx->superblock)
  1774. problem = PR_0_JOURNAL_RUN_DEFAULT;
  1775. else
  1776. problem = PR_0_JOURNAL_RUN;
  1777. if (fix_problem(ctx, problem, &pctx)) {
  1778. ctx->options |= E2F_OPT_FORCE;
  1779. sb->s_feature_incompat |=
  1780. EXT3_FEATURE_INCOMPAT_RECOVER;
  1781. ext2fs_mark_super_dirty(ctx->fs);
  1782. } else if (fix_problem(ctx,
  1783. PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
  1784. reset = 1;
  1785. sb->s_state &= ~EXT2_VALID_FS;
  1786. ext2fs_mark_super_dirty(ctx->fs);
  1787. }
  1788. /*
  1789. * If the user answers no to the above question, we
  1790. * ignore the fact that journal apparently has data;
  1791. * accidentally replaying over valid data would be far
  1792. * worse than skipping a questionable recovery.
  1793. *
  1794. * XXX should we abort with a fatal error here? What
  1795. * will the ext3 kernel code do if a filesystem with
  1796. * !NEEDS_RECOVERY but with a non-zero
  1797. * journal->j_superblock->s_start is mounted?
  1798. */
  1799. }
  1800. e2fsck_journal_release(ctx, journal, reset, 0);
  1801. return retval;
  1802. }
  1803. static errcode_t recover_ext3_journal(e2fsck_t ctx)
  1804. {
  1805. journal_t *journal;
  1806. int retval;
  1807. journal_init_revoke_caches();
  1808. retval = e2fsck_get_journal(ctx, &journal);
  1809. if (retval)
  1810. return retval;
  1811. retval = e2fsck_journal_load(journal);
  1812. if (retval)
  1813. goto errout;
  1814. retval = journal_init_revoke(journal, 1024);
  1815. if (retval)
  1816. goto errout;
  1817. retval = -journal_recover(journal);
  1818. if (retval)
  1819. goto errout;
  1820. if (journal->j_superblock->s_errno) {
  1821. ctx->fs->super->s_state |= EXT2_ERROR_FS;
  1822. ext2fs_mark_super_dirty(ctx->fs);
  1823. journal->j_superblock->s_errno = 0;
  1824. mark_buffer_dirty(journal->j_sb_buffer);
  1825. }
  1826. errout:
  1827. journal_destroy_revoke(journal);
  1828. journal_destroy_revoke_caches();
  1829. e2fsck_journal_release(ctx, journal, 1, 0);
  1830. return retval;
  1831. }
  1832. static int e2fsck_run_ext3_journal(e2fsck_t ctx)
  1833. {
  1834. io_manager io_ptr = ctx->fs->io->manager;
  1835. int blocksize = ctx->fs->blocksize;
  1836. errcode_t retval, recover_retval;
  1837. printf(_("%s: recovering journal\n"), ctx->device_name);
  1838. if (ctx->options & E2F_OPT_READONLY) {
  1839. printf(_("%s: won't do journal recovery while read-only\n"),
  1840. ctx->device_name);
  1841. return EXT2_ET_FILE_RO;
  1842. }
  1843. if (ctx->fs->flags & EXT2_FLAG_DIRTY)
  1844. ext2fs_flush(ctx->fs); /* Force out any modifications */
  1845. recover_retval = recover_ext3_journal(ctx);
  1846. /*
  1847. * Reload the filesystem context to get up-to-date data from disk
  1848. * because journal recovery will change the filesystem under us.
  1849. */
  1850. ext2fs_close(ctx->fs);
  1851. retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
  1852. ctx->superblock, blocksize, io_ptr,
  1853. &ctx->fs);
  1854. if (retval) {
  1855. bb_error_msg(_("while trying to re-open %s"),
  1856. ctx->device_name);
  1857. bb_error_msg_and_die(0);
  1858. }
  1859. ctx->fs->priv_data = ctx;
  1860. /* Set the superblock flags */
  1861. e2fsck_clear_recover(ctx, recover_retval);
  1862. return recover_retval;
  1863. }
  1864. /*
  1865. * This function will move the journal inode from a visible file in
  1866. * the filesystem directory hierarchy to the reserved inode if necessary.
  1867. */
  1868. static const char *const journal_names[] = {
  1869. ".journal", "journal", ".journal.dat", "journal.dat", 0 };
  1870. static void e2fsck_move_ext3_journal(e2fsck_t ctx)
  1871. {
  1872. struct ext2_super_block *sb = ctx->fs->super;
  1873. struct problem_context pctx;
  1874. struct ext2_inode inode;
  1875. ext2_filsys fs = ctx->fs;
  1876. ext2_ino_t ino;
  1877. errcode_t retval;
  1878. const char *const * cpp;
  1879. int group, mount_flags;
  1880. clear_problem_context(&pctx);
  1881. /*
  1882. * If the filesystem is opened read-only, or there is no
  1883. * journal, then do nothing.
  1884. */
  1885. if ((ctx->options & E2F_OPT_READONLY) ||
  1886. (sb->s_journal_inum == 0) ||
  1887. !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
  1888. return;
  1889. /*
  1890. * Read in the journal inode
  1891. */
  1892. if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
  1893. return;
  1894. /*
  1895. * If it's necessary to backup the journal inode, do so.
  1896. */
  1897. if ((sb->s_jnl_backup_type == 0) ||
  1898. ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
  1899. memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
  1900. if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
  1901. memcpy(sb->s_jnl_blocks, inode.i_block,
  1902. EXT2_N_BLOCKS*4);
  1903. sb->s_jnl_blocks[16] = inode.i_size;
  1904. sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
  1905. ext2fs_mark_super_dirty(fs);
  1906. fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
  1907. }
  1908. }
  1909. /*
  1910. * If the journal is already the hidden inode, then do nothing
  1911. */
  1912. if (sb->s_journal_inum == EXT2_JOURNAL_INO)
  1913. return;
  1914. /*
  1915. * The journal inode had better have only one link and not be readable.
  1916. */
  1917. if (inode.i_links_count != 1)
  1918. return;
  1919. /*
  1920. * If the filesystem is mounted, or we can't tell whether
  1921. * or not it's mounted, do nothing.
  1922. */
  1923. retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
  1924. if (retval || (mount_flags & EXT2_MF_MOUNTED))
  1925. return;
  1926. /*
  1927. * If we can't find the name of the journal inode, then do
  1928. * nothing.
  1929. */
  1930. for (cpp = journal_names; *cpp; cpp++) {
  1931. retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
  1932. strlen(*cpp), 0, &ino);
  1933. if ((retval == 0) && (ino == sb->s_journal_inum))
  1934. break;
  1935. }
  1936. if (*cpp == 0)
  1937. return;
  1938. /* We need the inode bitmap to be loaded */
  1939. retval = ext2fs_read_bitmaps(fs);
  1940. if (retval)
  1941. return;
  1942. pctx.str = *cpp;
  1943. if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
  1944. return;
  1945. /*
  1946. * OK, we've done all the checks, let's actually move the
  1947. * journal inode. Errors at this point mean we need to force
  1948. * an ext2 filesystem check.
  1949. */
  1950. if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
  1951. goto err_out;
  1952. if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
  1953. goto err_out;
  1954. sb->s_journal_inum = EXT2_JOURNAL_INO;
  1955. ext2fs_mark_super_dirty(fs);
  1956. fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
  1957. inode.i_links_count = 0;
  1958. inode.i_dtime = time(NULL);
  1959. if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
  1960. goto err_out;
  1961. group = ext2fs_group_of_ino(fs, ino);
  1962. ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
  1963. ext2fs_mark_ib_dirty(fs);
  1964. fs->group_desc[group].bg_free_inodes_count++;
  1965. fs->super->s_free_inodes_count++;
  1966. return;
  1967. err_out:
  1968. pctx.errcode = retval;
  1969. fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
  1970. fs->super->s_state &= ~EXT2_VALID_FS;
  1971. ext2fs_mark_super_dirty(fs);
  1972. }
  1973. /*
  1974. * message.c --- print e2fsck messages (with compression)
  1975. *
  1976. * print_e2fsck_message() prints a message to the user, using
  1977. * compression techniques and expansions of abbreviations.
  1978. *
  1979. * The following % expansions are supported:
  1980. *
  1981. * %b <blk> block number
  1982. * %B <blkcount> integer
  1983. * %c <blk2> block number
  1984. * %Di <dirent>->ino inode number
  1985. * %Dn <dirent>->name string
  1986. * %Dr <dirent>->rec_len
  1987. * %Dl <dirent>->name_len
  1988. * %Dt <dirent>->filetype
  1989. * %d <dir> inode number
  1990. * %g <group> integer
  1991. * %i <ino> inode number
  1992. * %Is <inode> -> i_size
  1993. * %IS <inode> -> i_extra_isize
  1994. * %Ib <inode> -> i_blocks
  1995. * %Il <inode> -> i_links_count
  1996. * %Im <inode> -> i_mode
  1997. * %IM <inode> -> i_mtime
  1998. * %IF <inode> -> i_faddr
  1999. * %If <inode> -> i_file_acl
  2000. * %Id <inode> -> i_dir_acl
  2001. * %Iu <inode> -> i_uid
  2002. * %Ig <inode> -> i_gid
  2003. * %j <ino2> inode number
  2004. * %m <com_err error message>
  2005. * %N <num>
  2006. * %p ext2fs_get_pathname of directory <ino>
  2007. * %P ext2fs_get_pathname of <dirent>->ino with <ino2> as
  2008. * the containing directory. (If dirent is NULL
  2009. * then return the pathname of directory <ino2>)
  2010. * %q ext2fs_get_pathname of directory <dir>
  2011. * %Q ext2fs_get_pathname of directory <ino> with <dir> as
  2012. * the containing directory.
  2013. * %s <str> miscellaneous string
  2014. * %S backup superblock
  2015. * %X <num> hexadecimal format
  2016. *
  2017. * The following '@' expansions are supported:
  2018. *
  2019. * @a extended attribute
  2020. * @A error allocating
  2021. * @b block
  2022. * @B bitmap
  2023. * @c compress
  2024. * @C conflicts with some other fs block
  2025. * @D deleted
  2026. * @d directory
  2027. * @e entry
  2028. * @E Entry '%Dn' in %p (%i)
  2029. * @f filesystem
  2030. * @F for @i %i (%Q) is
  2031. * @g group
  2032. * @h HTREE directory inode
  2033. * @i inode
  2034. * @I illegal
  2035. * @j journal
  2036. * @l lost+found
  2037. * @L is a link
  2038. * @m multiply-claimed
  2039. * @n invalid
  2040. * @o orphaned
  2041. * @p problem in
  2042. * @r root inode
  2043. * @s should be
  2044. * @S superblock
  2045. * @u unattached
  2046. * @v device
  2047. * @z zero-length
  2048. */
  2049. /*
  2050. * This structure defines the abbreviations used by the text strings
  2051. * below. The first character in the string is the index letter. An
  2052. * abbreviation of the form '@<i>' is expanded by looking up the index
  2053. * letter <i> in the table below.
  2054. */
  2055. static const char *const abbrevs[] = {
  2056. N_("aextended attribute"),
  2057. N_("Aerror allocating"),
  2058. N_("bblock"),
  2059. N_("Bbitmap"),
  2060. N_("ccompress"),
  2061. N_("Cconflicts with some other fs @b"),
  2062. N_("iinode"),
  2063. N_("Iillegal"),
  2064. N_("jjournal"),
  2065. N_("Ddeleted"),
  2066. N_("ddirectory"),
  2067. N_("eentry"),
  2068. N_("E@e '%Dn' in %p (%i)"),
  2069. N_("ffilesystem"),
  2070. N_("Ffor @i %i (%Q) is"),
  2071. N_("ggroup"),
  2072. N_("hHTREE @d @i"),
  2073. N_("llost+found"),
  2074. N_("Lis a link"),
  2075. N_("mmultiply-claimed"),
  2076. N_("ninvalid"),
  2077. N_("oorphaned"),
  2078. N_("pproblem in"),
  2079. N_("rroot @i"),
  2080. N_("sshould be"),
  2081. N_("Ssuper@b"),
  2082. N_("uunattached"),
  2083. N_("vdevice"),
  2084. N_("zzero-length"),
  2085. "@@",
  2086. 0
  2087. };
  2088. /*
  2089. * Give more user friendly names to the "special" inodes.
  2090. */
  2091. #define num_special_inodes 11
  2092. static const char *const special_inode_name[] =
  2093. {
  2094. N_("<The NULL inode>"), /* 0 */
  2095. N_("<The bad blocks inode>"), /* 1 */
  2096. "/", /* 2 */
  2097. N_("<The ACL index inode>"), /* 3 */
  2098. N_("<The ACL data inode>"), /* 4 */
  2099. N_("<The boot loader inode>"), /* 5 */
  2100. N_("<The undelete directory inode>"), /* 6 */
  2101. N_("<The group descriptor inode>"), /* 7 */
  2102. N_("<The journal inode>"), /* 8 */
  2103. N_("<Reserved inode 9>"), /* 9 */
  2104. N_("<Reserved inode 10>"), /* 10 */
  2105. };
  2106. /*
  2107. * This function does "safe" printing. It will convert non-printable
  2108. * ASCII characters using '^' and M- notation.
  2109. */
  2110. static void safe_print(const char *cp, int len)
  2111. {
  2112. unsigned char ch;
  2113. if (len < 0)
  2114. len = strlen(cp);
  2115. while (len--) {
  2116. ch = *cp++;
  2117. if (ch > 128) {
  2118. fputs("M-", stdout);
  2119. ch -= 128;
  2120. }
  2121. if ((ch < 32) || (ch == 0x7f)) {
  2122. bb_putchar('^');
  2123. ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
  2124. }
  2125. bb_putchar(ch);
  2126. }
  2127. }
  2128. /*
  2129. * This function prints a pathname, using the ext2fs_get_pathname
  2130. * function
  2131. */
  2132. static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
  2133. {
  2134. errcode_t retval;
  2135. char *path;
  2136. if (!dir && (ino < num_special_inodes)) {
  2137. fputs(_(special_inode_name[ino]), stdout);
  2138. return;
  2139. }
  2140. retval = ext2fs_get_pathname(fs, dir, ino, &path);
  2141. if (retval)
  2142. fputs("???", stdout);
  2143. else {
  2144. safe_print(path, -1);
  2145. ext2fs_free_mem(&path);
  2146. }
  2147. }
  2148. static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
  2149. struct problem_context *pctx, int first);
  2150. /*
  2151. * This function handles the '@' expansion. We allow recursive
  2152. * expansion; an @ expression can contain further '@' and '%'
  2153. * expressions.
  2154. */
  2155. static void expand_at_expression(e2fsck_t ctx, char ch,
  2156. struct problem_context *pctx,
  2157. int *first)
  2158. {
  2159. const char *const *cpp;
  2160. const char *str;
  2161. /* Search for the abbreviation */
  2162. for (cpp = abbrevs; *cpp; cpp++) {
  2163. if (ch == *cpp[0])
  2164. break;
  2165. }
  2166. if (*cpp) {
  2167. str = _(*cpp) + 1;
  2168. if (*first && islower(*str)) {
  2169. *first = 0;
  2170. bb_putchar(toupper(*str++));
  2171. }
  2172. print_e2fsck_message(ctx, str, pctx, *first);
  2173. } else
  2174. printf("@%c", ch);
  2175. }
  2176. /*
  2177. * This function expands '%IX' expressions
  2178. */
  2179. static void expand_inode_expression(char ch,
  2180. struct problem_context *ctx)
  2181. {
  2182. struct ext2_inode *inode;
  2183. struct ext2_inode_large *large_inode;
  2184. char * time_str;
  2185. time_t t;
  2186. int do_gmt = -1;
  2187. if (!ctx || !ctx->inode)
  2188. goto no_inode;
  2189. inode = ctx->inode;
  2190. large_inode = (struct ext2_inode_large *) inode;
  2191. switch (ch) {
  2192. case 's':
  2193. if (LINUX_S_ISDIR(inode->i_mode))
  2194. printf("%u", inode->i_size);
  2195. else {
  2196. printf("%"PRIu64, (inode->i_size |
  2197. ((uint64_t) inode->i_size_high << 32)));
  2198. }
  2199. break;
  2200. case 'S':
  2201. printf("%u", large_inode->i_extra_isize);
  2202. break;
  2203. case 'b':
  2204. printf("%u", inode->i_blocks);
  2205. break;
  2206. case 'l':
  2207. printf("%d", inode->i_links_count);
  2208. break;
  2209. case 'm':
  2210. printf("0%o", inode->i_mode);
  2211. break;
  2212. case 'M':
  2213. /* The diet libc doesn't respect the TZ environemnt variable */
  2214. if (do_gmt == -1) {
  2215. time_str = getenv("TZ");
  2216. if (!time_str)
  2217. time_str = "";
  2218. do_gmt = !strcmp(time_str, "GMT");
  2219. }
  2220. t = inode->i_mtime;
  2221. time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
  2222. printf("%.24s", time_str);
  2223. break;
  2224. case 'F':
  2225. printf("%u", inode->i_faddr);
  2226. break;
  2227. case 'f':
  2228. printf("%u", inode->i_file_acl);
  2229. break;
  2230. case 'd':
  2231. printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
  2232. inode->i_dir_acl : 0));
  2233. break;
  2234. case 'u':
  2235. printf("%d", (inode->i_uid |
  2236. (inode->osd2.linux2.l_i_uid_high << 16)));
  2237. break;
  2238. case 'g':
  2239. printf("%d", (inode->i_gid |
  2240. (inode->osd2.linux2.l_i_gid_high << 16)));
  2241. break;
  2242. default:
  2243. no_inode:
  2244. printf("%%I%c", ch);
  2245. break;
  2246. }
  2247. }
  2248. /*
  2249. * This function expands '%dX' expressions
  2250. */
  2251. static void expand_dirent_expression(char ch,
  2252. struct problem_context *ctx)
  2253. {
  2254. struct ext2_dir_entry *dirent;
  2255. int len;
  2256. if (!ctx || !ctx->dirent)
  2257. goto no_dirent;
  2258. dirent = ctx->dirent;
  2259. switch (ch) {
  2260. case 'i':
  2261. printf("%u", dirent->inode);
  2262. break;
  2263. case 'n':
  2264. len = dirent->name_len & 0xFF;
  2265. if (len > EXT2_NAME_LEN)
  2266. len = EXT2_NAME_LEN;
  2267. if (len > dirent->rec_len)
  2268. len = dirent->rec_len;
  2269. safe_print(dirent->name, len);
  2270. break;
  2271. case 'r':
  2272. printf("%u", dirent->rec_len);
  2273. break;
  2274. case 'l':
  2275. printf("%u", dirent->name_len & 0xFF);
  2276. break;
  2277. case 't':
  2278. printf("%u", dirent->name_len >> 8);
  2279. break;
  2280. default:
  2281. no_dirent:
  2282. printf("%%D%c", ch);
  2283. break;
  2284. }
  2285. }
  2286. static void expand_percent_expression(ext2_filsys fs, char ch,
  2287. struct problem_context *ctx)
  2288. {
  2289. if (!ctx)
  2290. goto no_context;
  2291. switch (ch) {
  2292. case '%':
  2293. bb_putchar('%');
  2294. break;
  2295. case 'b':
  2296. printf("%u", ctx->blk);
  2297. break;
  2298. case 'B':
  2299. printf("%"PRIi64, ctx->blkcount);
  2300. break;
  2301. case 'c':
  2302. printf("%u", ctx->blk2);
  2303. break;
  2304. case 'd':
  2305. printf("%u", ctx->dir);
  2306. break;
  2307. case 'g':
  2308. printf("%d", ctx->group);
  2309. break;
  2310. case 'i':
  2311. printf("%u", ctx->ino);
  2312. break;
  2313. case 'j':
  2314. printf("%u", ctx->ino2);
  2315. break;
  2316. case 'm':
  2317. fputs(error_message(ctx->errcode), stdout);
  2318. break;
  2319. case 'N':
  2320. printf("%"PRIi64, ctx->num);
  2321. break;
  2322. case 'p':
  2323. print_pathname(fs, ctx->ino, 0);
  2324. break;
  2325. case 'P':
  2326. print_pathname(fs, ctx->ino2,
  2327. ctx->dirent ? ctx->dirent->inode : 0);
  2328. break;
  2329. case 'q':
  2330. print_pathname(fs, ctx->dir, 0);
  2331. break;
  2332. case 'Q':
  2333. print_pathname(fs, ctx->dir, ctx->ino);
  2334. break;
  2335. case 'S':
  2336. printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
  2337. break;
  2338. case 's':
  2339. fputs((ctx->str ? ctx->str : "NULL"), stdout);
  2340. break;
  2341. case 'X':
  2342. printf("0x%"PRIi64, ctx->num);
  2343. break;
  2344. default:
  2345. no_context:
  2346. printf("%%%c", ch);
  2347. break;
  2348. }
  2349. }
  2350. static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
  2351. struct problem_context *pctx, int first)
  2352. {
  2353. ext2_filsys fs = ctx->fs;
  2354. const char * cp;
  2355. int i;
  2356. e2fsck_clear_progbar(ctx);
  2357. for (cp = msg; *cp; cp++) {
  2358. if (cp[0] == '@') {
  2359. cp++;
  2360. expand_at_expression(ctx, *cp, pctx, &first);
  2361. } else if (cp[0] == '%' && cp[1] == 'I') {
  2362. cp += 2;
  2363. expand_inode_expression(*cp, pctx);
  2364. } else if (cp[0] == '%' && cp[1] == 'D') {
  2365. cp += 2;
  2366. expand_dirent_expression(*cp, pctx);
  2367. } else if ((cp[0] == '%')) {
  2368. cp++;
  2369. expand_percent_expression(fs, *cp, pctx);
  2370. } else {
  2371. for (i=0; cp[i]; i++)
  2372. if ((cp[i] == '@') || cp[i] == '%')
  2373. break;
  2374. printf("%.*s", i, cp);
  2375. cp += i-1;
  2376. }
  2377. first = 0;
  2378. }
  2379. }
  2380. /*
  2381. * region.c --- code which manages allocations within a region.
  2382. */
  2383. struct region_el {
  2384. region_addr_t start;
  2385. region_addr_t end;
  2386. struct region_el *next;
  2387. };
  2388. struct region_struct {
  2389. region_addr_t min;
  2390. region_addr_t max;
  2391. struct region_el *allocated;
  2392. };
  2393. static region_t region_create(region_addr_t min, region_addr_t max)
  2394. {
  2395. region_t region;
  2396. region = xzalloc(sizeof(struct region_struct));
  2397. region->min = min;
  2398. region->max = max;
  2399. return region;
  2400. }
  2401. static void region_free(region_t region)
  2402. {
  2403. struct region_el *r, *next;
  2404. for (r = region->allocated; r; r = next) {
  2405. next = r->next;
  2406. free(r);
  2407. }
  2408. memset(region, 0, sizeof(struct region_struct));
  2409. free(region);
  2410. }
  2411. static int region_allocate(region_t region, region_addr_t start, int n)
  2412. {
  2413. struct region_el *r, *new_region, *prev, *next;
  2414. region_addr_t end;
  2415. end = start+n;
  2416. if ((start < region->min) || (end > region->max))
  2417. return -1;
  2418. if (n == 0)
  2419. return 1;
  2420. /*
  2421. * Search through the linked list. If we find that it
  2422. * conflicts witih something that's already allocated, return
  2423. * 1; if we can find an existing region which we can grow, do
  2424. * so. Otherwise, stop when we find the appropriate place
  2425. * insert a new region element into the linked list.
  2426. */
  2427. for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
  2428. if (((start >= r->start) && (start < r->end)) ||
  2429. ((end > r->start) && (end <= r->end)) ||
  2430. ((start <= r->start) && (end >= r->end)))
  2431. return 1;
  2432. if (end == r->start) {
  2433. r->start = start;
  2434. return 0;
  2435. }
  2436. if (start == r->end) {
  2437. if ((next = r->next)) {
  2438. if (end > next->start)
  2439. return 1;
  2440. if (end == next->start) {
  2441. r->end = next->end;
  2442. r->next = next->next;
  2443. free(next);
  2444. return 0;
  2445. }
  2446. }
  2447. r->end = end;
  2448. return 0;
  2449. }
  2450. if (start < r->start)
  2451. break;
  2452. }
  2453. /*
  2454. * Insert a new region element structure into the linked list
  2455. */
  2456. new_region = xmalloc(sizeof(struct region_el));
  2457. new_region->start = start;
  2458. new_region->end = start + n;
  2459. new_region->next = r;
  2460. if (prev)
  2461. prev->next = new_region;
  2462. else
  2463. region->allocated = new_region;
  2464. return 0;
  2465. }
  2466. /*
  2467. * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
  2468. *
  2469. * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
  2470. * and applies the following tests to each inode:
  2471. *
  2472. * - The mode field of the inode must be legal.
  2473. * - The size and block count fields of the inode are correct.
  2474. * - A data block must not be used by another inode
  2475. *
  2476. * Pass 1 also gathers the collects the following information:
  2477. *
  2478. * - A bitmap of which inodes are in use. (inode_used_map)
  2479. * - A bitmap of which inodes are directories. (inode_dir_map)
  2480. * - A bitmap of which inodes are regular files. (inode_reg_map)
  2481. * - A bitmap of which inodes have bad fields. (inode_bad_map)
  2482. * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
  2483. * - A bitmap of which blocks are in use. (block_found_map)
  2484. * - A bitmap of which blocks are in use by two inodes (block_dup_map)
  2485. * - The data blocks of the directory inodes. (dir_map)
  2486. *
  2487. * Pass 1 is designed to stash away enough information so that the
  2488. * other passes should not need to read in the inode information
  2489. * during the normal course of a filesystem check. (Althogh if an
  2490. * inconsistency is detected, other passes may need to read in an
  2491. * inode to fix it.)
  2492. *
  2493. * Note that pass 1B will be invoked if there are any duplicate blocks
  2494. * found.
  2495. */
  2496. static int process_block(ext2_filsys fs, blk_t *blocknr,
  2497. e2_blkcnt_t blockcnt, blk_t ref_blk,
  2498. int ref_offset, void *priv_data);
  2499. static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
  2500. e2_blkcnt_t blockcnt, blk_t ref_blk,
  2501. int ref_offset, void *priv_data);
  2502. static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
  2503. char *block_buf);
  2504. static void mark_table_blocks(e2fsck_t ctx);
  2505. static void alloc_imagic_map(e2fsck_t ctx);
  2506. static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
  2507. static void handle_fs_bad_blocks(e2fsck_t ctx);
  2508. static void process_inodes(e2fsck_t ctx, char *block_buf);
  2509. static int process_inode_cmp(const void *a, const void *b);
  2510. static errcode_t scan_callback(ext2_filsys fs,
  2511. dgrp_t group, void * priv_data);
  2512. static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
  2513. char *block_buf, int adjust_sign);
  2514. /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
  2515. static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
  2516. struct ext2_inode * inode, int bufsize,
  2517. const char *proc);
  2518. struct process_block_struct_1 {
  2519. ext2_ino_t ino;
  2520. unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
  2521. fragmented:1, compressed:1, bbcheck:1;
  2522. blk_t num_blocks;
  2523. blk_t max_blocks;
  2524. e2_blkcnt_t last_block;
  2525. int num_illegal_blocks;
  2526. blk_t previous_block;
  2527. struct ext2_inode *inode;
  2528. struct problem_context *pctx;
  2529. ext2fs_block_bitmap fs_meta_blocks;
  2530. e2fsck_t ctx;
  2531. };
  2532. struct process_inode_block {
  2533. ext2_ino_t ino;
  2534. struct ext2_inode inode;
  2535. };
  2536. struct scan_callback_struct {
  2537. e2fsck_t ctx;
  2538. char *block_buf;
  2539. };
  2540. /*
  2541. * For the inodes to process list.
  2542. */
  2543. static struct process_inode_block *inodes_to_process;
  2544. static int process_inode_count;
  2545. static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
  2546. EXT2_MIN_BLOCK_LOG_SIZE + 1];
  2547. /*
  2548. * Free all memory allocated by pass1 in preparation for restarting
  2549. * things.
  2550. */
  2551. static void unwind_pass1(void)
  2552. {
  2553. ext2fs_free_mem(&inodes_to_process);
  2554. }
  2555. /*
  2556. * Check to make sure a device inode is real. Returns 1 if the device
  2557. * checks out, 0 if not.
  2558. *
  2559. * Note: this routine is now also used to check FIFO's and Sockets,
  2560. * since they have the same requirement; the i_block fields should be
  2561. * zero.
  2562. */
  2563. static int
  2564. e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
  2565. {
  2566. int i;
  2567. /*
  2568. * If i_blocks is non-zero, or the index flag is set, then
  2569. * this is a bogus device/fifo/socket
  2570. */
  2571. if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
  2572. (inode->i_flags & EXT2_INDEX_FL))
  2573. return 0;
  2574. /*
  2575. * We should be able to do the test below all the time, but
  2576. * because the kernel doesn't forcibly clear the device
  2577. * inode's additional i_block fields, there are some rare
  2578. * occasions when a legitimate device inode will have non-zero
  2579. * additional i_block fields. So for now, we only complain
  2580. * when the immutable flag is set, which should never happen
  2581. * for devices. (And that's when the problem is caused, since
  2582. * you can't set or clear immutable flags for devices.) Once
  2583. * the kernel has been fixed we can change this...
  2584. */
  2585. if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
  2586. for (i=4; i < EXT2_N_BLOCKS; i++)
  2587. if (inode->i_block[i])
  2588. return 0;
  2589. }
  2590. return 1;
  2591. }
  2592. /*
  2593. * Check to make sure a symlink inode is real. Returns 1 if the symlink
  2594. * checks out, 0 if not.
  2595. */
  2596. static int
  2597. e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf)
  2598. {
  2599. unsigned int len;
  2600. int i;
  2601. blk_t blocks;
  2602. if ((inode->i_size_high || inode->i_size == 0) ||
  2603. (inode->i_flags & EXT2_INDEX_FL))
  2604. return 0;
  2605. blocks = ext2fs_inode_data_blocks(fs, inode);
  2606. if (blocks) {
  2607. if ((inode->i_size >= fs->blocksize) ||
  2608. (blocks != fs->blocksize >> 9) ||
  2609. (inode->i_block[0] < fs->super->s_first_data_block) ||
  2610. (inode->i_block[0] >= fs->super->s_blocks_count))
  2611. return 0;
  2612. for (i = 1; i < EXT2_N_BLOCKS; i++)
  2613. if (inode->i_block[i])
  2614. return 0;
  2615. if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
  2616. return 0;
  2617. len = strnlen(buf, fs->blocksize);
  2618. if (len == fs->blocksize)
  2619. return 0;
  2620. } else {
  2621. if (inode->i_size >= sizeof(inode->i_block))
  2622. return 0;
  2623. len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
  2624. if (len == sizeof(inode->i_block))
  2625. return 0;
  2626. }
  2627. if (len != inode->i_size)
  2628. return 0;
  2629. return 1;
  2630. }
  2631. /*
  2632. * If the immutable (or append-only) flag is set on the inode, offer
  2633. * to clear it.
  2634. */
  2635. #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
  2636. static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
  2637. {
  2638. if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
  2639. return;
  2640. if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
  2641. return;
  2642. pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
  2643. e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
  2644. }
  2645. /*
  2646. * If device, fifo or socket, check size is zero -- if not offer to
  2647. * clear it
  2648. */
  2649. static void check_size(e2fsck_t ctx, struct problem_context *pctx)
  2650. {
  2651. struct ext2_inode *inode = pctx->inode;
  2652. if ((inode->i_size == 0) && (inode->i_size_high == 0))
  2653. return;
  2654. if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
  2655. return;
  2656. inode->i_size = 0;
  2657. inode->i_size_high = 0;
  2658. e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
  2659. }
  2660. static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
  2661. {
  2662. struct ext2_super_block *sb = ctx->fs->super;
  2663. struct ext2_inode_large *inode;
  2664. struct ext2_ext_attr_entry *entry;
  2665. char *start, *end;
  2666. int storage_size, remain, offs;
  2667. int problem = 0;
  2668. inode = (struct ext2_inode_large *) pctx->inode;
  2669. storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
  2670. inode->i_extra_isize;
  2671. start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
  2672. inode->i_extra_isize + sizeof(__u32);
  2673. end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
  2674. entry = (struct ext2_ext_attr_entry *) start;
  2675. /* scan all entry's headers first */
  2676. /* take finish entry 0UL into account */
  2677. remain = storage_size - sizeof(__u32);
  2678. offs = end - start;
  2679. while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
  2680. /* header eats this space */
  2681. remain -= sizeof(struct ext2_ext_attr_entry);
  2682. /* is attribute name valid? */
  2683. if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
  2684. pctx->num = entry->e_name_len;
  2685. problem = PR_1_ATTR_NAME_LEN;
  2686. goto fix;
  2687. }
  2688. /* attribute len eats this space */
  2689. remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
  2690. /* check value size */
  2691. if (entry->e_value_size == 0 || entry->e_value_size > remain) {
  2692. pctx->num = entry->e_value_size;
  2693. problem = PR_1_ATTR_VALUE_SIZE;
  2694. goto fix;
  2695. }
  2696. /* check value placement */
  2697. if (entry->e_value_offs +
  2698. EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
  2699. printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
  2700. pctx->num = entry->e_value_offs;
  2701. problem = PR_1_ATTR_VALUE_OFFSET;
  2702. goto fix;
  2703. }
  2704. /* e_value_block must be 0 in inode's ea */
  2705. if (entry->e_value_block != 0) {
  2706. pctx->num = entry->e_value_block;
  2707. problem = PR_1_ATTR_VALUE_BLOCK;
  2708. goto fix;
  2709. }
  2710. /* e_hash must be 0 in inode's ea */
  2711. if (entry->e_hash != 0) {
  2712. pctx->num = entry->e_hash;
  2713. problem = PR_1_ATTR_HASH;
  2714. goto fix;
  2715. }
  2716. remain -= entry->e_value_size;
  2717. offs -= EXT2_XATTR_SIZE(entry->e_value_size);
  2718. entry = EXT2_EXT_ATTR_NEXT(entry);
  2719. }
  2720. fix:
  2721. /*
  2722. * it seems like a corruption. it's very unlikely we could repair
  2723. * EA(s) in automatic fashion -bzzz
  2724. */
  2725. if (problem == 0 || !fix_problem(ctx, problem, pctx))
  2726. return;
  2727. /* simple remove all possible EA(s) */
  2728. *((__u32 *)start) = 0UL;
  2729. e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
  2730. EXT2_INODE_SIZE(sb), "pass1");
  2731. }
  2732. static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
  2733. {
  2734. struct ext2_super_block *sb = ctx->fs->super;
  2735. struct ext2_inode_large *inode;
  2736. __u32 *eamagic;
  2737. int min, max;
  2738. inode = (struct ext2_inode_large *) pctx->inode;
  2739. if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
  2740. /* this isn't large inode. so, nothing to check */
  2741. return;
  2742. }
  2743. /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
  2744. min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
  2745. max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
  2746. /*
  2747. * For now we will allow i_extra_isize to be 0, but really
  2748. * implementations should never allow i_extra_isize to be 0
  2749. */
  2750. if (inode->i_extra_isize &&
  2751. (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
  2752. if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
  2753. return;
  2754. inode->i_extra_isize = min;
  2755. e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
  2756. EXT2_INODE_SIZE(sb), "pass1");
  2757. return;
  2758. }
  2759. eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
  2760. inode->i_extra_isize);
  2761. if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
  2762. /* it seems inode has an extended attribute(s) in body */
  2763. check_ea_in_inode(ctx, pctx);
  2764. }
  2765. }
  2766. static void e2fsck_pass1(e2fsck_t ctx)
  2767. {
  2768. int i;
  2769. __u64 max_sizes;
  2770. ext2_filsys fs = ctx->fs;
  2771. ext2_ino_t ino;
  2772. struct ext2_inode *inode;
  2773. ext2_inode_scan scan;
  2774. char *block_buf;
  2775. unsigned char frag, fsize;
  2776. struct problem_context pctx;
  2777. struct scan_callback_struct scan_struct;
  2778. struct ext2_super_block *sb = ctx->fs->super;
  2779. int imagic_fs;
  2780. int busted_fs_time = 0;
  2781. int inode_size;
  2782. clear_problem_context(&pctx);
  2783. if (!(ctx->options & E2F_OPT_PREEN))
  2784. fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
  2785. if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
  2786. !(ctx->options & E2F_OPT_NO)) {
  2787. if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
  2788. ctx->dirs_to_hash = 0;
  2789. }
  2790. /* Pass 1 */
  2791. #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
  2792. for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
  2793. max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
  2794. max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
  2795. max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
  2796. max_sizes = (max_sizes * (1UL << i)) - 1;
  2797. ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
  2798. }
  2799. #undef EXT2_BPP
  2800. imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
  2801. /*
  2802. * Allocate bitmaps structures
  2803. */
  2804. pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
  2805. &ctx->inode_used_map);
  2806. if (pctx.errcode) {
  2807. pctx.num = 1;
  2808. fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
  2809. ctx->flags |= E2F_FLAG_ABORT;
  2810. return;
  2811. }
  2812. pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
  2813. _("directory inode map"), &ctx->inode_dir_map);
  2814. if (pctx.errcode) {
  2815. pctx.num = 2;
  2816. fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
  2817. ctx->flags |= E2F_FLAG_ABORT;
  2818. return;
  2819. }
  2820. pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
  2821. _("regular file inode map"), &ctx->inode_reg_map);
  2822. if (pctx.errcode) {
  2823. pctx.num = 6;
  2824. fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
  2825. ctx->flags |= E2F_FLAG_ABORT;
  2826. return;
  2827. }
  2828. pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
  2829. &ctx->block_found_map);
  2830. if (pctx.errcode) {
  2831. pctx.num = 1;
  2832. fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
  2833. ctx->flags |= E2F_FLAG_ABORT;
  2834. return;
  2835. }
  2836. pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
  2837. &ctx->inode_link_info);
  2838. if (pctx.errcode) {
  2839. fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
  2840. ctx->flags |= E2F_FLAG_ABORT;
  2841. return;
  2842. }
  2843. inode_size = EXT2_INODE_SIZE(fs->super);
  2844. inode = (struct ext2_inode *)
  2845. e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
  2846. inodes_to_process = (struct process_inode_block *)
  2847. e2fsck_allocate_memory(ctx,
  2848. (ctx->process_inode_size *
  2849. sizeof(struct process_inode_block)),
  2850. "array of inodes to process");
  2851. process_inode_count = 0;
  2852. pctx.errcode = ext2fs_init_dblist(fs, 0);
  2853. if (pctx.errcode) {
  2854. fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
  2855. ctx->flags |= E2F_FLAG_ABORT;
  2856. return;
  2857. }
  2858. /*
  2859. * If the last orphan field is set, clear it, since the pass1
  2860. * processing will automatically find and clear the orphans.
  2861. * In the future, we may want to try using the last_orphan
  2862. * linked list ourselves, but for now, we clear it so that the
  2863. * ext3 mount code won't get confused.
  2864. */
  2865. if (!(ctx->options & E2F_OPT_READONLY)) {
  2866. if (fs->super->s_last_orphan) {
  2867. fs->super->s_last_orphan = 0;
  2868. ext2fs_mark_super_dirty(fs);
  2869. }
  2870. }
  2871. mark_table_blocks(ctx);
  2872. block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
  2873. "block interate buffer");
  2874. e2fsck_use_inode_shortcuts(ctx, 1);
  2875. ehandler_operation(_("doing inode scan"));
  2876. pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
  2877. &scan);
  2878. if (pctx.errcode) {
  2879. fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
  2880. ctx->flags |= E2F_FLAG_ABORT;
  2881. return;
  2882. }
  2883. ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
  2884. ctx->stashed_inode = inode;
  2885. scan_struct.ctx = ctx;
  2886. scan_struct.block_buf = block_buf;
  2887. ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
  2888. if (ctx->progress)
  2889. if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
  2890. return;
  2891. if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
  2892. (fs->super->s_mtime < fs->super->s_inodes_count))
  2893. busted_fs_time = 1;
  2894. while (1) {
  2895. pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
  2896. inode, inode_size);
  2897. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  2898. return;
  2899. if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
  2900. continue;
  2901. }
  2902. if (pctx.errcode) {
  2903. fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
  2904. ctx->flags |= E2F_FLAG_ABORT;
  2905. return;
  2906. }
  2907. if (!ino)
  2908. break;
  2909. pctx.ino = ino;
  2910. pctx.inode = inode;
  2911. ctx->stashed_ino = ino;
  2912. if (inode->i_links_count) {
  2913. pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
  2914. ino, inode->i_links_count);
  2915. if (pctx.errcode) {
  2916. pctx.num = inode->i_links_count;
  2917. fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
  2918. ctx->flags |= E2F_FLAG_ABORT;
  2919. return;
  2920. }
  2921. }
  2922. if (ino == EXT2_BAD_INO) {
  2923. struct process_block_struct_1 pb;
  2924. pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
  2925. &pb.fs_meta_blocks);
  2926. if (pctx.errcode) {
  2927. pctx.num = 4;
  2928. fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
  2929. ctx->flags |= E2F_FLAG_ABORT;
  2930. return;
  2931. }
  2932. pb.ino = EXT2_BAD_INO;
  2933. pb.num_blocks = pb.last_block = 0;
  2934. pb.num_illegal_blocks = 0;
  2935. pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
  2936. pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
  2937. pb.inode = inode;
  2938. pb.pctx = &pctx;
  2939. pb.ctx = ctx;
  2940. pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
  2941. block_buf, process_bad_block, &pb);
  2942. ext2fs_free_block_bitmap(pb.fs_meta_blocks);
  2943. if (pctx.errcode) {
  2944. fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
  2945. ctx->flags |= E2F_FLAG_ABORT;
  2946. return;
  2947. }
  2948. if (pb.bbcheck)
  2949. if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
  2950. ctx->flags |= E2F_FLAG_ABORT;
  2951. return;
  2952. }
  2953. ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
  2954. clear_problem_context(&pctx);
  2955. continue;
  2956. } else if (ino == EXT2_ROOT_INO) {
  2957. /*
  2958. * Make sure the root inode is a directory; if
  2959. * not, offer to clear it. It will be
  2960. * regnerated in pass #3.
  2961. */
  2962. if (!LINUX_S_ISDIR(inode->i_mode)) {
  2963. if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
  2964. inode->i_dtime = time(NULL);
  2965. inode->i_links_count = 0;
  2966. ext2fs_icount_store(ctx->inode_link_info,
  2967. ino, 0);
  2968. e2fsck_write_inode(ctx, ino, inode,
  2969. "pass1");
  2970. }
  2971. }
  2972. /*
  2973. * If dtime is set, offer to clear it. mke2fs
  2974. * version 0.2b created filesystems with the
  2975. * dtime field set for the root and lost+found
  2976. * directories. We won't worry about
  2977. * /lost+found, since that can be regenerated
  2978. * easily. But we will fix the root directory
  2979. * as a special case.
  2980. */
  2981. if (inode->i_dtime && inode->i_links_count) {
  2982. if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
  2983. inode->i_dtime = 0;
  2984. e2fsck_write_inode(ctx, ino, inode,
  2985. "pass1");
  2986. }
  2987. }
  2988. } else if (ino == EXT2_JOURNAL_INO) {
  2989. ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
  2990. if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
  2991. if (!LINUX_S_ISREG(inode->i_mode) &&
  2992. fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
  2993. &pctx)) {
  2994. inode->i_mode = LINUX_S_IFREG;
  2995. e2fsck_write_inode(ctx, ino, inode,
  2996. "pass1");
  2997. }
  2998. check_blocks(ctx, &pctx, block_buf);
  2999. continue;
  3000. }
  3001. if ((inode->i_links_count || inode->i_blocks ||
  3002. inode->i_blocks || inode->i_block[0]) &&
  3003. fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
  3004. &pctx)) {
  3005. memset(inode, 0, inode_size);
  3006. ext2fs_icount_store(ctx->inode_link_info,
  3007. ino, 0);
  3008. e2fsck_write_inode_full(ctx, ino, inode,
  3009. inode_size, "pass1");
  3010. }
  3011. } else if (ino < EXT2_FIRST_INODE(fs->super)) {
  3012. int problem = 0;
  3013. ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
  3014. if (ino == EXT2_BOOT_LOADER_INO) {
  3015. if (LINUX_S_ISDIR(inode->i_mode))
  3016. problem = PR_1_RESERVED_BAD_MODE;
  3017. } else if (ino == EXT2_RESIZE_INO) {
  3018. if (inode->i_mode &&
  3019. !LINUX_S_ISREG(inode->i_mode))
  3020. problem = PR_1_RESERVED_BAD_MODE;
  3021. } else {
  3022. if (inode->i_mode != 0)
  3023. problem = PR_1_RESERVED_BAD_MODE;
  3024. }
  3025. if (problem) {
  3026. if (fix_problem(ctx, problem, &pctx)) {
  3027. inode->i_mode = 0;
  3028. e2fsck_write_inode(ctx, ino, inode,
  3029. "pass1");
  3030. }
  3031. }
  3032. check_blocks(ctx, &pctx, block_buf);
  3033. continue;
  3034. }
  3035. /*
  3036. * Check for inodes who might have been part of the
  3037. * orphaned list linked list. They should have gotten
  3038. * dealt with by now, unless the list had somehow been
  3039. * corrupted.
  3040. *
  3041. * FIXME: In the future, inodes which are still in use
  3042. * (and which are therefore) pending truncation should
  3043. * be handled specially. Right now we just clear the
  3044. * dtime field, and the normal e2fsck handling of
  3045. * inodes where i_size and the inode blocks are
  3046. * inconsistent is to fix i_size, instead of releasing
  3047. * the extra blocks. This won't catch the inodes that
  3048. * was at the end of the orphan list, but it's better
  3049. * than nothing. The right answer is that there
  3050. * shouldn't be any bugs in the orphan list handling. :-)
  3051. */
  3052. if (inode->i_dtime && !busted_fs_time &&
  3053. inode->i_dtime < ctx->fs->super->s_inodes_count) {
  3054. if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
  3055. inode->i_dtime = inode->i_links_count ?
  3056. 0 : time(NULL);
  3057. e2fsck_write_inode(ctx, ino, inode,
  3058. "pass1");
  3059. }
  3060. }
  3061. /*
  3062. * This code assumes that deleted inodes have
  3063. * i_links_count set to 0.
  3064. */
  3065. if (!inode->i_links_count) {
  3066. if (!inode->i_dtime && inode->i_mode) {
  3067. if (fix_problem(ctx,
  3068. PR_1_ZERO_DTIME, &pctx)) {
  3069. inode->i_dtime = time(NULL);
  3070. e2fsck_write_inode(ctx, ino, inode,
  3071. "pass1");
  3072. }
  3073. }
  3074. continue;
  3075. }
  3076. /*
  3077. * n.b. 0.3c ext2fs code didn't clear i_links_count for
  3078. * deleted files. Oops.
  3079. *
  3080. * Since all new ext2 implementations get this right,
  3081. * we now assume that the case of non-zero
  3082. * i_links_count and non-zero dtime means that we
  3083. * should keep the file, not delete it.
  3084. *
  3085. */
  3086. if (inode->i_dtime) {
  3087. if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
  3088. inode->i_dtime = 0;
  3089. e2fsck_write_inode(ctx, ino, inode, "pass1");
  3090. }
  3091. }
  3092. ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
  3093. switch (fs->super->s_creator_os) {
  3094. case EXT2_OS_LINUX:
  3095. frag = inode->osd2.linux2.l_i_frag;
  3096. fsize = inode->osd2.linux2.l_i_fsize;
  3097. break;
  3098. case EXT2_OS_HURD:
  3099. frag = inode->osd2.hurd2.h_i_frag;
  3100. fsize = inode->osd2.hurd2.h_i_fsize;
  3101. break;
  3102. case EXT2_OS_MASIX:
  3103. frag = inode->osd2.masix2.m_i_frag;
  3104. fsize = inode->osd2.masix2.m_i_fsize;
  3105. break;
  3106. default:
  3107. frag = fsize = 0;
  3108. }
  3109. if (inode->i_faddr || frag || fsize ||
  3110. (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
  3111. mark_inode_bad(ctx, ino);
  3112. if (inode->i_flags & EXT2_IMAGIC_FL) {
  3113. if (imagic_fs) {
  3114. if (!ctx->inode_imagic_map)
  3115. alloc_imagic_map(ctx);
  3116. ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
  3117. ino);
  3118. } else {
  3119. if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
  3120. inode->i_flags &= ~EXT2_IMAGIC_FL;
  3121. e2fsck_write_inode(ctx, ino,
  3122. inode, "pass1");
  3123. }
  3124. }
  3125. }
  3126. check_inode_extra_space(ctx, &pctx);
  3127. if (LINUX_S_ISDIR(inode->i_mode)) {
  3128. ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
  3129. e2fsck_add_dir_info(ctx, ino, 0);
  3130. ctx->fs_directory_count++;
  3131. } else if (LINUX_S_ISREG (inode->i_mode)) {
  3132. ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
  3133. ctx->fs_regular_count++;
  3134. } else if (LINUX_S_ISCHR (inode->i_mode) &&
  3135. e2fsck_pass1_check_device_inode(fs, inode)) {
  3136. check_immutable(ctx, &pctx);
  3137. check_size(ctx, &pctx);
  3138. ctx->fs_chardev_count++;
  3139. } else if (LINUX_S_ISBLK (inode->i_mode) &&
  3140. e2fsck_pass1_check_device_inode(fs, inode)) {
  3141. check_immutable(ctx, &pctx);
  3142. check_size(ctx, &pctx);
  3143. ctx->fs_blockdev_count++;
  3144. } else if (LINUX_S_ISLNK (inode->i_mode) &&
  3145. e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
  3146. check_immutable(ctx, &pctx);
  3147. ctx->fs_symlinks_count++;
  3148. if (ext2fs_inode_data_blocks(fs, inode) == 0) {
  3149. ctx->fs_fast_symlinks_count++;
  3150. check_blocks(ctx, &pctx, block_buf);
  3151. continue;
  3152. }
  3153. }
  3154. else if (LINUX_S_ISFIFO (inode->i_mode) &&
  3155. e2fsck_pass1_check_device_inode(fs, inode)) {
  3156. check_immutable(ctx, &pctx);
  3157. check_size(ctx, &pctx);
  3158. ctx->fs_fifo_count++;
  3159. } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
  3160. e2fsck_pass1_check_device_inode(fs, inode)) {
  3161. check_immutable(ctx, &pctx);
  3162. check_size(ctx, &pctx);
  3163. ctx->fs_sockets_count++;
  3164. } else
  3165. mark_inode_bad(ctx, ino);
  3166. if (inode->i_block[EXT2_IND_BLOCK])
  3167. ctx->fs_ind_count++;
  3168. if (inode->i_block[EXT2_DIND_BLOCK])
  3169. ctx->fs_dind_count++;
  3170. if (inode->i_block[EXT2_TIND_BLOCK])
  3171. ctx->fs_tind_count++;
  3172. if (inode->i_block[EXT2_IND_BLOCK] ||
  3173. inode->i_block[EXT2_DIND_BLOCK] ||
  3174. inode->i_block[EXT2_TIND_BLOCK] ||
  3175. inode->i_file_acl) {
  3176. inodes_to_process[process_inode_count].ino = ino;
  3177. inodes_to_process[process_inode_count].inode = *inode;
  3178. process_inode_count++;
  3179. } else
  3180. check_blocks(ctx, &pctx, block_buf);
  3181. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  3182. return;
  3183. if (process_inode_count >= ctx->process_inode_size) {
  3184. process_inodes(ctx, block_buf);
  3185. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  3186. return;
  3187. }
  3188. }
  3189. process_inodes(ctx, block_buf);
  3190. ext2fs_close_inode_scan(scan);
  3191. ehandler_operation(0);
  3192. /*
  3193. * If any extended attribute blocks' reference counts need to
  3194. * be adjusted, either up (ctx->refcount_extra), or down
  3195. * (ctx->refcount), then fix them.
  3196. */
  3197. if (ctx->refcount) {
  3198. adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
  3199. ea_refcount_free(ctx->refcount);
  3200. ctx->refcount = 0;
  3201. }
  3202. if (ctx->refcount_extra) {
  3203. adjust_extattr_refcount(ctx, ctx->refcount_extra,
  3204. block_buf, +1);
  3205. ea_refcount_free(ctx->refcount_extra);
  3206. ctx->refcount_extra = 0;
  3207. }
  3208. if (ctx->invalid_bitmaps)
  3209. handle_fs_bad_blocks(ctx);
  3210. /* We don't need the block_ea_map any more */
  3211. ext2fs_free_block_bitmap(ctx->block_ea_map);
  3212. ctx->block_ea_map = 0;
  3213. if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
  3214. ext2fs_block_bitmap save_bmap;
  3215. save_bmap = fs->block_map;
  3216. fs->block_map = ctx->block_found_map;
  3217. clear_problem_context(&pctx);
  3218. pctx.errcode = ext2fs_create_resize_inode(fs);
  3219. if (pctx.errcode) {
  3220. fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
  3221. /* Should never get here */
  3222. ctx->flags |= E2F_FLAG_ABORT;
  3223. return;
  3224. }
  3225. e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
  3226. "recreate inode");
  3227. inode->i_mtime = time(NULL);
  3228. e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
  3229. "recreate inode");
  3230. fs->block_map = save_bmap;
  3231. ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
  3232. }
  3233. if (ctx->flags & E2F_FLAG_RESTART) {
  3234. /*
  3235. * Only the master copy of the superblock and block
  3236. * group descriptors are going to be written during a
  3237. * restart, so set the superblock to be used to be the
  3238. * master superblock.
  3239. */
  3240. ctx->use_superblock = 0;
  3241. unwind_pass1();
  3242. goto endit;
  3243. }
  3244. if (ctx->block_dup_map) {
  3245. if (ctx->options & E2F_OPT_PREEN) {
  3246. clear_problem_context(&pctx);
  3247. fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
  3248. }
  3249. e2fsck_pass1_dupblocks(ctx, block_buf);
  3250. }
  3251. ext2fs_free_mem(&inodes_to_process);
  3252. endit:
  3253. e2fsck_use_inode_shortcuts(ctx, 0);
  3254. ext2fs_free_mem(&block_buf);
  3255. ext2fs_free_mem(&inode);
  3256. }
  3257. /*
  3258. * When the inode_scan routines call this callback at the end of the
  3259. * glock group, call process_inodes.
  3260. */
  3261. static errcode_t scan_callback(ext2_filsys fs,
  3262. dgrp_t group, void * priv_data)
  3263. {
  3264. struct scan_callback_struct *scan_struct;
  3265. e2fsck_t ctx;
  3266. scan_struct = (struct scan_callback_struct *) priv_data;
  3267. ctx = scan_struct->ctx;
  3268. process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
  3269. if (ctx->progress)
  3270. if ((ctx->progress)(ctx, 1, group+1,
  3271. ctx->fs->group_desc_count))
  3272. return EXT2_ET_CANCEL_REQUESTED;
  3273. return 0;
  3274. }
  3275. /*
  3276. * Process the inodes in the "inodes to process" list.
  3277. */
  3278. static void process_inodes(e2fsck_t ctx, char *block_buf)
  3279. {
  3280. int i;
  3281. struct ext2_inode *old_stashed_inode;
  3282. ext2_ino_t old_stashed_ino;
  3283. const char *old_operation;
  3284. char buf[80];
  3285. struct problem_context pctx;
  3286. /* begin process_inodes */
  3287. if (process_inode_count == 0)
  3288. return;
  3289. old_operation = ehandler_operation(0);
  3290. old_stashed_inode = ctx->stashed_inode;
  3291. old_stashed_ino = ctx->stashed_ino;
  3292. qsort(inodes_to_process, process_inode_count,
  3293. sizeof(struct process_inode_block), process_inode_cmp);
  3294. clear_problem_context(&pctx);
  3295. for (i=0; i < process_inode_count; i++) {
  3296. pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
  3297. pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
  3298. sprintf(buf, _("reading indirect blocks of inode %u"),
  3299. pctx.ino);
  3300. ehandler_operation(buf);
  3301. check_blocks(ctx, &pctx, block_buf);
  3302. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  3303. break;
  3304. }
  3305. ctx->stashed_inode = old_stashed_inode;
  3306. ctx->stashed_ino = old_stashed_ino;
  3307. process_inode_count = 0;
  3308. /* end process inodes */
  3309. ehandler_operation(old_operation);
  3310. }
  3311. static int process_inode_cmp(const void *a, const void *b)
  3312. {
  3313. const struct process_inode_block *ib_a =
  3314. (const struct process_inode_block *) a;
  3315. const struct process_inode_block *ib_b =
  3316. (const struct process_inode_block *) b;
  3317. int ret;
  3318. ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
  3319. ib_b->inode.i_block[EXT2_IND_BLOCK]);
  3320. if (ret == 0)
  3321. ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
  3322. return ret;
  3323. }
  3324. /*
  3325. * Mark an inode as being bad in some what
  3326. */
  3327. static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
  3328. {
  3329. struct problem_context pctx;
  3330. if (!ctx->inode_bad_map) {
  3331. clear_problem_context(&pctx);
  3332. pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
  3333. _("bad inode map"), &ctx->inode_bad_map);
  3334. if (pctx.errcode) {
  3335. pctx.num = 3;
  3336. fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
  3337. /* Should never get here */
  3338. ctx->flags |= E2F_FLAG_ABORT;
  3339. return;
  3340. }
  3341. }
  3342. ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
  3343. }
  3344. /*
  3345. * This procedure will allocate the inode imagic table
  3346. */
  3347. static void alloc_imagic_map(e2fsck_t ctx)
  3348. {
  3349. struct problem_context pctx;
  3350. clear_problem_context(&pctx);
  3351. pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
  3352. _("imagic inode map"),
  3353. &ctx->inode_imagic_map);
  3354. if (pctx.errcode) {
  3355. pctx.num = 5;
  3356. fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
  3357. /* Should never get here */
  3358. ctx->flags |= E2F_FLAG_ABORT;
  3359. return;
  3360. }
  3361. }
  3362. /*
  3363. * Marks a block as in use, setting the dup_map if it's been set
  3364. * already. Called by process_block and process_bad_block.
  3365. *
  3366. * WARNING: Assumes checks have already been done to make sure block
  3367. * is valid. This is true in both process_block and process_bad_block.
  3368. */
  3369. static void mark_block_used(e2fsck_t ctx, blk_t block)
  3370. {
  3371. struct problem_context pctx;
  3372. clear_problem_context(&pctx);
  3373. if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
  3374. if (!ctx->block_dup_map) {
  3375. pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
  3376. _("multiply claimed block map"),
  3377. &ctx->block_dup_map);
  3378. if (pctx.errcode) {
  3379. pctx.num = 3;
  3380. fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
  3381. &pctx);
  3382. /* Should never get here */
  3383. ctx->flags |= E2F_FLAG_ABORT;
  3384. return;
  3385. }
  3386. }
  3387. ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
  3388. } else {
  3389. ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
  3390. }
  3391. }
  3392. /*
  3393. * Adjust the extended attribute block's reference counts at the end
  3394. * of pass 1, either by subtracting out references for EA blocks that
  3395. * are still referenced in ctx->refcount, or by adding references for
  3396. * EA blocks that had extra references as accounted for in
  3397. * ctx->refcount_extra.
  3398. */
  3399. static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
  3400. char *block_buf, int adjust_sign)
  3401. {
  3402. struct ext2_ext_attr_header *header;
  3403. struct problem_context pctx;
  3404. ext2_filsys fs = ctx->fs;
  3405. blk_t blk;
  3406. __u32 should_be;
  3407. int count;
  3408. clear_problem_context(&pctx);
  3409. ea_refcount_intr_begin(refcount);
  3410. while (1) {
  3411. if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
  3412. break;
  3413. pctx.blk = blk;
  3414. pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
  3415. if (pctx.errcode) {
  3416. fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
  3417. return;
  3418. }
  3419. header = (struct ext2_ext_attr_header *) block_buf;
  3420. pctx.blkcount = header->h_refcount;
  3421. should_be = header->h_refcount + adjust_sign * count;
  3422. pctx.num = should_be;
  3423. if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
  3424. header->h_refcount = should_be;
  3425. pctx.errcode = ext2fs_write_ext_attr(fs, blk,
  3426. block_buf);
  3427. if (pctx.errcode) {
  3428. fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
  3429. continue;
  3430. }
  3431. }
  3432. }
  3433. }
  3434. /*
  3435. * Handle processing the extended attribute blocks
  3436. */
  3437. static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
  3438. char *block_buf)
  3439. {
  3440. ext2_filsys fs = ctx->fs;
  3441. ext2_ino_t ino = pctx->ino;
  3442. struct ext2_inode *inode = pctx->inode;
  3443. blk_t blk;
  3444. char * end;
  3445. struct ext2_ext_attr_header *header;
  3446. struct ext2_ext_attr_entry *entry;
  3447. int count;
  3448. region_t region;
  3449. blk = inode->i_file_acl;
  3450. if (blk == 0)
  3451. return 0;
  3452. /*
  3453. * If the Extended attribute flag isn't set, then a non-zero
  3454. * file acl means that the inode is corrupted.
  3455. *
  3456. * Or if the extended attribute block is an invalid block,
  3457. * then the inode is also corrupted.
  3458. */
  3459. if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
  3460. (blk < fs->super->s_first_data_block) ||
  3461. (blk >= fs->super->s_blocks_count)) {
  3462. mark_inode_bad(ctx, ino);
  3463. return 0;
  3464. }
  3465. /* If ea bitmap hasn't been allocated, create it */
  3466. if (!ctx->block_ea_map) {
  3467. pctx->errcode = ext2fs_allocate_block_bitmap(fs,
  3468. _("ext attr block map"),
  3469. &ctx->block_ea_map);
  3470. if (pctx->errcode) {
  3471. pctx->num = 2;
  3472. fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
  3473. ctx->flags |= E2F_FLAG_ABORT;
  3474. return 0;
  3475. }
  3476. }
  3477. /* Create the EA refcount structure if necessary */
  3478. if (!ctx->refcount) {
  3479. pctx->errcode = ea_refcount_create(0, &ctx->refcount);
  3480. if (pctx->errcode) {
  3481. pctx->num = 1;
  3482. fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
  3483. ctx->flags |= E2F_FLAG_ABORT;
  3484. return 0;
  3485. }
  3486. }
  3487. /* Have we seen this EA block before? */
  3488. if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
  3489. if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
  3490. return 1;
  3491. /* Ooops, this EA was referenced more than it stated */
  3492. if (!ctx->refcount_extra) {
  3493. pctx->errcode = ea_refcount_create(0,
  3494. &ctx->refcount_extra);
  3495. if (pctx->errcode) {
  3496. pctx->num = 2;
  3497. fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
  3498. ctx->flags |= E2F_FLAG_ABORT;
  3499. return 0;
  3500. }
  3501. }
  3502. ea_refcount_increment(ctx->refcount_extra, blk, 0);
  3503. return 1;
  3504. }
  3505. /*
  3506. * OK, we haven't seen this EA block yet. So we need to
  3507. * validate it
  3508. */
  3509. pctx->blk = blk;
  3510. pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
  3511. if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
  3512. goto clear_extattr;
  3513. header = (struct ext2_ext_attr_header *) block_buf;
  3514. pctx->blk = inode->i_file_acl;
  3515. if (((ctx->ext_attr_ver == 1) &&
  3516. (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
  3517. ((ctx->ext_attr_ver == 2) &&
  3518. (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
  3519. if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
  3520. goto clear_extattr;
  3521. }
  3522. if (header->h_blocks != 1) {
  3523. if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
  3524. goto clear_extattr;
  3525. }
  3526. region = region_create(0, fs->blocksize);
  3527. if (!region) {
  3528. fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
  3529. ctx->flags |= E2F_FLAG_ABORT;
  3530. return 0;
  3531. }
  3532. if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
  3533. if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
  3534. goto clear_extattr;
  3535. }
  3536. entry = (struct ext2_ext_attr_entry *)(header+1);
  3537. end = block_buf + fs->blocksize;
  3538. while ((char *)entry < end && *(__u32 *)entry) {
  3539. if (region_allocate(region, (char *)entry - (char *)header,
  3540. EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
  3541. if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
  3542. goto clear_extattr;
  3543. }
  3544. if ((ctx->ext_attr_ver == 1 &&
  3545. (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
  3546. (ctx->ext_attr_ver == 2 &&
  3547. entry->e_name_index == 0)) {
  3548. if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
  3549. goto clear_extattr;
  3550. }
  3551. if (entry->e_value_block != 0) {
  3552. if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
  3553. goto clear_extattr;
  3554. }
  3555. if (entry->e_value_size &&
  3556. region_allocate(region, entry->e_value_offs,
  3557. EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
  3558. if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
  3559. goto clear_extattr;
  3560. }
  3561. entry = EXT2_EXT_ATTR_NEXT(entry);
  3562. }
  3563. if (region_allocate(region, (char *)entry - (char *)header, 4)) {
  3564. if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
  3565. goto clear_extattr;
  3566. }
  3567. region_free(region);
  3568. count = header->h_refcount - 1;
  3569. if (count)
  3570. ea_refcount_store(ctx->refcount, blk, count);
  3571. mark_block_used(ctx, blk);
  3572. ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
  3573. return 1;
  3574. clear_extattr:
  3575. inode->i_file_acl = 0;
  3576. e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
  3577. return 0;
  3578. }
  3579. /* Returns 1 if bad htree, 0 if OK */
  3580. static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
  3581. ext2_ino_t ino FSCK_ATTR((unused)),
  3582. struct ext2_inode *inode,
  3583. char *block_buf)
  3584. {
  3585. struct ext2_dx_root_info *root;
  3586. ext2_filsys fs = ctx->fs;
  3587. errcode_t retval;
  3588. blk_t blk;
  3589. if ((!LINUX_S_ISDIR(inode->i_mode) &&
  3590. fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
  3591. (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
  3592. fix_problem(ctx, PR_1_HTREE_SET, pctx)))
  3593. return 1;
  3594. blk = inode->i_block[0];
  3595. if (((blk == 0) ||
  3596. (blk < fs->super->s_first_data_block) ||
  3597. (blk >= fs->super->s_blocks_count)) &&
  3598. fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
  3599. return 1;
  3600. retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
  3601. if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
  3602. return 1;
  3603. /* XXX should check that beginning matches a directory */
  3604. root = (struct ext2_dx_root_info *) (block_buf + 24);
  3605. if ((root->reserved_zero || root->info_length < 8) &&
  3606. fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
  3607. return 1;
  3608. pctx->num = root->hash_version;
  3609. if ((root->hash_version != EXT2_HASH_LEGACY) &&
  3610. (root->hash_version != EXT2_HASH_HALF_MD4) &&
  3611. (root->hash_version != EXT2_HASH_TEA) &&
  3612. fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
  3613. return 1;
  3614. if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
  3615. fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
  3616. return 1;
  3617. pctx->num = root->indirect_levels;
  3618. if ((root->indirect_levels > 1) &&
  3619. fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
  3620. return 1;
  3621. return 0;
  3622. }
  3623. /*
  3624. * This subroutine is called on each inode to account for all of the
  3625. * blocks used by that inode.
  3626. */
  3627. static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
  3628. char *block_buf)
  3629. {
  3630. ext2_filsys fs = ctx->fs;
  3631. struct process_block_struct_1 pb;
  3632. ext2_ino_t ino = pctx->ino;
  3633. struct ext2_inode *inode = pctx->inode;
  3634. int bad_size = 0;
  3635. int dirty_inode = 0;
  3636. __u64 size;
  3637. pb.ino = ino;
  3638. pb.num_blocks = 0;
  3639. pb.last_block = -1;
  3640. pb.num_illegal_blocks = 0;
  3641. pb.suppress = 0; pb.clear = 0;
  3642. pb.fragmented = 0;
  3643. pb.compressed = 0;
  3644. pb.previous_block = 0;
  3645. pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
  3646. pb.is_reg = LINUX_S_ISREG(inode->i_mode);
  3647. pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
  3648. pb.inode = inode;
  3649. pb.pctx = pctx;
  3650. pb.ctx = ctx;
  3651. pctx->ino = ino;
  3652. pctx->errcode = 0;
  3653. if (inode->i_flags & EXT2_COMPRBLK_FL) {
  3654. if (fs->super->s_feature_incompat &
  3655. EXT2_FEATURE_INCOMPAT_COMPRESSION)
  3656. pb.compressed = 1;
  3657. else {
  3658. if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
  3659. inode->i_flags &= ~EXT2_COMPRBLK_FL;
  3660. dirty_inode++;
  3661. }
  3662. }
  3663. }
  3664. if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
  3665. pb.num_blocks++;
  3666. if (ext2fs_inode_has_valid_blocks(inode))
  3667. pctx->errcode = ext2fs_block_iterate2(fs, ino,
  3668. pb.is_dir ? BLOCK_FLAG_HOLE : 0,
  3669. block_buf, process_block, &pb);
  3670. end_problem_latch(ctx, PR_LATCH_BLOCK);
  3671. end_problem_latch(ctx, PR_LATCH_TOOBIG);
  3672. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  3673. goto out;
  3674. if (pctx->errcode)
  3675. fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
  3676. if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
  3677. ctx->fs_fragmented++;
  3678. if (pb.clear) {
  3679. inode->i_links_count = 0;
  3680. ext2fs_icount_store(ctx->inode_link_info, ino, 0);
  3681. inode->i_dtime = time(NULL);
  3682. dirty_inode++;
  3683. ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
  3684. ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
  3685. ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
  3686. /*
  3687. * The inode was probably partially accounted for
  3688. * before processing was aborted, so we need to
  3689. * restart the pass 1 scan.
  3690. */
  3691. ctx->flags |= E2F_FLAG_RESTART;
  3692. goto out;
  3693. }
  3694. if (inode->i_flags & EXT2_INDEX_FL) {
  3695. if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
  3696. inode->i_flags &= ~EXT2_INDEX_FL;
  3697. dirty_inode++;
  3698. } else {
  3699. #ifdef ENABLE_HTREE
  3700. e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
  3701. #endif
  3702. }
  3703. }
  3704. if (ctx->dirs_to_hash && pb.is_dir &&
  3705. !(inode->i_flags & EXT2_INDEX_FL) &&
  3706. ((inode->i_size / fs->blocksize) >= 3))
  3707. ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
  3708. if (!pb.num_blocks && pb.is_dir) {
  3709. if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
  3710. inode->i_links_count = 0;
  3711. ext2fs_icount_store(ctx->inode_link_info, ino, 0);
  3712. inode->i_dtime = time(NULL);
  3713. dirty_inode++;
  3714. ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
  3715. ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
  3716. ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
  3717. ctx->fs_directory_count--;
  3718. goto out;
  3719. }
  3720. }
  3721. pb.num_blocks *= (fs->blocksize / 512);
  3722. if (pb.is_dir) {
  3723. int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
  3724. if (nblock > (pb.last_block + 1))
  3725. bad_size = 1;
  3726. else if (nblock < (pb.last_block + 1)) {
  3727. if (((pb.last_block + 1) - nblock) >
  3728. fs->super->s_prealloc_dir_blocks)
  3729. bad_size = 2;
  3730. }
  3731. } else {
  3732. size = EXT2_I_SIZE(inode);
  3733. if ((pb.last_block >= 0) &&
  3734. (size < (__u64) pb.last_block * fs->blocksize))
  3735. bad_size = 3;
  3736. else if (size > ext2_max_sizes[fs->super->s_log_block_size])
  3737. bad_size = 4;
  3738. }
  3739. /* i_size for symlinks is checked elsewhere */
  3740. if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
  3741. pctx->num = (pb.last_block+1) * fs->blocksize;
  3742. if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
  3743. inode->i_size = pctx->num;
  3744. if (!LINUX_S_ISDIR(inode->i_mode))
  3745. inode->i_size_high = pctx->num >> 32;
  3746. dirty_inode++;
  3747. }
  3748. pctx->num = 0;
  3749. }
  3750. if (LINUX_S_ISREG(inode->i_mode) &&
  3751. (inode->i_size_high || inode->i_size & 0x80000000UL))
  3752. ctx->large_files++;
  3753. if (pb.num_blocks != inode->i_blocks) {
  3754. pctx->num = pb.num_blocks;
  3755. if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
  3756. inode->i_blocks = pb.num_blocks;
  3757. dirty_inode++;
  3758. }
  3759. pctx->num = 0;
  3760. }
  3761. out:
  3762. if (dirty_inode)
  3763. e2fsck_write_inode(ctx, ino, inode, "check_blocks");
  3764. }
  3765. /*
  3766. * This is a helper function for check_blocks().
  3767. */
  3768. static int process_block(ext2_filsys fs,
  3769. blk_t *block_nr,
  3770. e2_blkcnt_t blockcnt,
  3771. blk_t ref_block FSCK_ATTR((unused)),
  3772. int ref_offset FSCK_ATTR((unused)),
  3773. void *priv_data)
  3774. {
  3775. struct process_block_struct_1 *p;
  3776. struct problem_context *pctx;
  3777. blk_t blk = *block_nr;
  3778. int ret_code = 0;
  3779. int problem = 0;
  3780. e2fsck_t ctx;
  3781. p = (struct process_block_struct_1 *) priv_data;
  3782. pctx = p->pctx;
  3783. ctx = p->ctx;
  3784. if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
  3785. /* todo: Check that the comprblk_fl is high, that the
  3786. blkaddr pattern looks right (all non-holes up to
  3787. first EXT2FS_COMPRESSED_BLKADDR, then all
  3788. EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
  3789. that the feature_incompat bit is high, and that the
  3790. inode is a regular file. If we're doing a "full
  3791. check" (a concept introduced to e2fsck by e2compr,
  3792. meaning that we look at data blocks as well as
  3793. metadata) then call some library routine that
  3794. checks the compressed data. I'll have to think
  3795. about this, because one particularly important
  3796. problem to be able to fix is to recalculate the
  3797. cluster size if necessary. I think that perhaps
  3798. we'd better do most/all e2compr-specific checks
  3799. separately, after the non-e2compr checks. If not
  3800. doing a full check, it may be useful to test that
  3801. the personality is linux; e.g. if it isn't then
  3802. perhaps this really is just an illegal block. */
  3803. return 0;
  3804. }
  3805. if (blk == 0) {
  3806. if (p->is_dir == 0) {
  3807. /*
  3808. * Should never happen, since only directories
  3809. * get called with BLOCK_FLAG_HOLE
  3810. */
  3811. #ifdef DEBUG_E2FSCK
  3812. printf("process_block() called with blk == 0, "
  3813. "blockcnt=%d, inode %lu???\n",
  3814. blockcnt, p->ino);
  3815. #endif
  3816. return 0;
  3817. }
  3818. if (blockcnt < 0)
  3819. return 0;
  3820. if (blockcnt * fs->blocksize < p->inode->i_size) {
  3821. goto mark_dir;
  3822. }
  3823. return 0;
  3824. }
  3825. /*
  3826. * Simplistic fragmentation check. We merely require that the
  3827. * file be contiguous. (Which can never be true for really
  3828. * big files that are greater than a block group.)
  3829. */
  3830. if (!HOLE_BLKADDR(p->previous_block)) {
  3831. if (p->previous_block+1 != blk)
  3832. p->fragmented = 1;
  3833. }
  3834. p->previous_block = blk;
  3835. if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
  3836. problem = PR_1_TOOBIG_DIR;
  3837. if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
  3838. problem = PR_1_TOOBIG_REG;
  3839. if (!p->is_dir && !p->is_reg && blockcnt > 0)
  3840. problem = PR_1_TOOBIG_SYMLINK;
  3841. if (blk < fs->super->s_first_data_block ||
  3842. blk >= fs->super->s_blocks_count)
  3843. problem = PR_1_ILLEGAL_BLOCK_NUM;
  3844. if (problem) {
  3845. p->num_illegal_blocks++;
  3846. if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
  3847. if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
  3848. p->clear = 1;
  3849. return BLOCK_ABORT;
  3850. }
  3851. if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
  3852. p->suppress = 1;
  3853. set_latch_flags(PR_LATCH_BLOCK,
  3854. PRL_SUPPRESS, 0);
  3855. }
  3856. }
  3857. pctx->blk = blk;
  3858. pctx->blkcount = blockcnt;
  3859. if (fix_problem(ctx, problem, pctx)) {
  3860. blk = *block_nr = 0;
  3861. ret_code = BLOCK_CHANGED;
  3862. goto mark_dir;
  3863. } else
  3864. return 0;
  3865. }
  3866. if (p->ino == EXT2_RESIZE_INO) {
  3867. /*
  3868. * The resize inode has already be sanity checked
  3869. * during pass #0 (the superblock checks). All we
  3870. * have to do is mark the double indirect block as
  3871. * being in use; all of the other blocks are handled
  3872. * by mark_table_blocks()).
  3873. */
  3874. if (blockcnt == BLOCK_COUNT_DIND)
  3875. mark_block_used(ctx, blk);
  3876. } else
  3877. mark_block_used(ctx, blk);
  3878. p->num_blocks++;
  3879. if (blockcnt >= 0)
  3880. p->last_block = blockcnt;
  3881. mark_dir:
  3882. if (p->is_dir && (blockcnt >= 0)) {
  3883. pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
  3884. blk, blockcnt);
  3885. if (pctx->errcode) {
  3886. pctx->blk = blk;
  3887. pctx->num = blockcnt;
  3888. fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
  3889. /* Should never get here */
  3890. ctx->flags |= E2F_FLAG_ABORT;
  3891. return BLOCK_ABORT;
  3892. }
  3893. }
  3894. return ret_code;
  3895. }
  3896. static int process_bad_block(ext2_filsys fs FSCK_ATTR((unused)),
  3897. blk_t *block_nr,
  3898. e2_blkcnt_t blockcnt,
  3899. blk_t ref_block FSCK_ATTR((unused)),
  3900. int ref_offset FSCK_ATTR((unused)),
  3901. void *priv_data EXT2FS_ATTR((unused)))
  3902. {
  3903. /*
  3904. * Note: This function processes blocks for the bad blocks
  3905. * inode, which is never compressed. So we don't use HOLE_BLKADDR().
  3906. */
  3907. printf("Unrecoverable Error: Found %"PRIi64" bad blocks starting at block number: %u\n", blockcnt, *block_nr);
  3908. return BLOCK_ERROR;
  3909. }
  3910. /*
  3911. * This routine gets called at the end of pass 1 if bad blocks are
  3912. * detected in the superblock, group descriptors, inode_bitmaps, or
  3913. * block bitmaps. At this point, all of the blocks have been mapped
  3914. * out, so we can try to allocate new block(s) to replace the bad
  3915. * blocks.
  3916. */
  3917. static void handle_fs_bad_blocks(e2fsck_t ctx)
  3918. {
  3919. printf("Bad blocks detected on your filesystem\n"
  3920. "You should get your data off as the device will soon die\n");
  3921. }
  3922. /*
  3923. * This routine marks all blocks which are used by the superblock,
  3924. * group descriptors, inode bitmaps, and block bitmaps.
  3925. */
  3926. static void mark_table_blocks(e2fsck_t ctx)
  3927. {
  3928. ext2_filsys fs = ctx->fs;
  3929. blk_t block, b;
  3930. dgrp_t i;
  3931. int j;
  3932. struct problem_context pctx;
  3933. clear_problem_context(&pctx);
  3934. block = fs->super->s_first_data_block;
  3935. for (i = 0; i < fs->group_desc_count; i++) {
  3936. pctx.group = i;
  3937. ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
  3938. /*
  3939. * Mark the blocks used for the inode table
  3940. */
  3941. if (fs->group_desc[i].bg_inode_table) {
  3942. for (j = 0, b = fs->group_desc[i].bg_inode_table;
  3943. j < fs->inode_blocks_per_group;
  3944. j++, b++) {
  3945. if (ext2fs_test_block_bitmap(ctx->block_found_map,
  3946. b)) {
  3947. pctx.blk = b;
  3948. if (fix_problem(ctx,
  3949. PR_1_ITABLE_CONFLICT, &pctx)) {
  3950. ctx->invalid_inode_table_flag[i]++;
  3951. ctx->invalid_bitmaps++;
  3952. }
  3953. } else {
  3954. ext2fs_mark_block_bitmap(ctx->block_found_map, b);
  3955. }
  3956. }
  3957. }
  3958. /*
  3959. * Mark block used for the block bitmap
  3960. */
  3961. if (fs->group_desc[i].bg_block_bitmap) {
  3962. if (ext2fs_test_block_bitmap(ctx->block_found_map,
  3963. fs->group_desc[i].bg_block_bitmap)) {
  3964. pctx.blk = fs->group_desc[i].bg_block_bitmap;
  3965. if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
  3966. ctx->invalid_block_bitmap_flag[i]++;
  3967. ctx->invalid_bitmaps++;
  3968. }
  3969. } else {
  3970. ext2fs_mark_block_bitmap(ctx->block_found_map,
  3971. fs->group_desc[i].bg_block_bitmap);
  3972. }
  3973. }
  3974. /*
  3975. * Mark block used for the inode bitmap
  3976. */
  3977. if (fs->group_desc[i].bg_inode_bitmap) {
  3978. if (ext2fs_test_block_bitmap(ctx->block_found_map,
  3979. fs->group_desc[i].bg_inode_bitmap)) {
  3980. pctx.blk = fs->group_desc[i].bg_inode_bitmap;
  3981. if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
  3982. ctx->invalid_inode_bitmap_flag[i]++;
  3983. ctx->invalid_bitmaps++;
  3984. }
  3985. } else {
  3986. ext2fs_mark_block_bitmap(ctx->block_found_map,
  3987. fs->group_desc[i].bg_inode_bitmap);
  3988. }
  3989. }
  3990. block += fs->super->s_blocks_per_group;
  3991. }
  3992. }
  3993. /*
  3994. * Thes subroutines short circuits ext2fs_get_blocks and
  3995. * ext2fs_check_directory; we use them since we already have the inode
  3996. * structure, so there's no point in letting the ext2fs library read
  3997. * the inode again.
  3998. */
  3999. static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
  4000. blk_t *blocks)
  4001. {
  4002. e2fsck_t ctx = (e2fsck_t) fs->priv_data;
  4003. int i;
  4004. if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
  4005. return EXT2_ET_CALLBACK_NOTHANDLED;
  4006. for (i=0; i < EXT2_N_BLOCKS; i++)
  4007. blocks[i] = ctx->stashed_inode->i_block[i];
  4008. return 0;
  4009. }
  4010. static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
  4011. struct ext2_inode *inode)
  4012. {
  4013. e2fsck_t ctx = (e2fsck_t) fs->priv_data;
  4014. if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
  4015. return EXT2_ET_CALLBACK_NOTHANDLED;
  4016. *inode = *ctx->stashed_inode;
  4017. return 0;
  4018. }
  4019. static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
  4020. struct ext2_inode *inode)
  4021. {
  4022. e2fsck_t ctx = (e2fsck_t) fs->priv_data;
  4023. if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
  4024. *ctx->stashed_inode = *inode;
  4025. return EXT2_ET_CALLBACK_NOTHANDLED;
  4026. }
  4027. static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
  4028. {
  4029. e2fsck_t ctx = (e2fsck_t) fs->priv_data;
  4030. if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
  4031. return EXT2_ET_CALLBACK_NOTHANDLED;
  4032. if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
  4033. return EXT2_ET_NO_DIRECTORY;
  4034. return 0;
  4035. }
  4036. void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
  4037. {
  4038. ext2_filsys fs = ctx->fs;
  4039. if (bool) {
  4040. fs->get_blocks = pass1_get_blocks;
  4041. fs->check_directory = pass1_check_directory;
  4042. fs->read_inode = pass1_read_inode;
  4043. fs->write_inode = pass1_write_inode;
  4044. ctx->stashed_ino = 0;
  4045. } else {
  4046. fs->get_blocks = 0;
  4047. fs->check_directory = 0;
  4048. fs->read_inode = 0;
  4049. fs->write_inode = 0;
  4050. }
  4051. }
  4052. /*
  4053. * pass1b.c --- Pass #1b of e2fsck
  4054. *
  4055. * This file contains pass1B, pass1C, and pass1D of e2fsck. They are
  4056. * only invoked if pass 1 discovered blocks which are in use by more
  4057. * than one inode.
  4058. *
  4059. * Pass1B scans the data blocks of all the inodes again, generating a
  4060. * complete list of duplicate blocks and which inodes have claimed
  4061. * them.
  4062. *
  4063. * Pass1C does a tree-traversal of the filesystem, to determine the
  4064. * parent directories of these inodes. This step is necessary so that
  4065. * e2fsck can print out the pathnames of affected inodes.
  4066. *
  4067. * Pass1D is a reconciliation pass. For each inode with duplicate
  4068. * blocks, the user is prompted if s/he would like to clone the file
  4069. * (so that the file gets a fresh copy of the duplicated blocks) or
  4070. * simply to delete the file.
  4071. *
  4072. */
  4073. /* Needed for architectures where sizeof(int) != sizeof(void *) */
  4074. #define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val))
  4075. #define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr))
  4076. /* Define an extension to the ext2 library's block count information */
  4077. #define BLOCK_COUNT_EXTATTR (-5)
  4078. struct block_el {
  4079. blk_t block;
  4080. struct block_el *next;
  4081. };
  4082. struct inode_el {
  4083. ext2_ino_t inode;
  4084. struct inode_el *next;
  4085. };
  4086. struct dup_block {
  4087. int num_bad;
  4088. struct inode_el *inode_list;
  4089. };
  4090. /*
  4091. * This structure stores information about a particular inode which
  4092. * is sharing blocks with other inodes. This information is collected
  4093. * to display to the user, so that the user knows what files he or she
  4094. * is dealing with, when trying to decide how to resolve the conflict
  4095. * of multiply-claimed blocks.
  4096. */
  4097. struct dup_inode {
  4098. ext2_ino_t dir;
  4099. int num_dupblocks;
  4100. struct ext2_inode inode;
  4101. struct block_el *block_list;
  4102. };
  4103. static int process_pass1b_block(ext2_filsys fs, blk_t *blocknr,
  4104. e2_blkcnt_t blockcnt, blk_t ref_blk,
  4105. int ref_offset, void *priv_data);
  4106. static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
  4107. struct dup_inode *dp, char *block_buf);
  4108. static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
  4109. struct dup_inode *dp, char* block_buf);
  4110. static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
  4111. static void pass1b(e2fsck_t ctx, char *block_buf);
  4112. static void pass1c(e2fsck_t ctx, char *block_buf);
  4113. static void pass1d(e2fsck_t ctx, char *block_buf);
  4114. static int dup_inode_count = 0;
  4115. static dict_t blk_dict, ino_dict;
  4116. static ext2fs_inode_bitmap inode_dup_map;
  4117. static int dict_int_cmp(const void *a, const void *b)
  4118. {
  4119. intptr_t ia, ib;
  4120. ia = (intptr_t)a;
  4121. ib = (intptr_t)b;
  4122. return (ia-ib);
  4123. }
  4124. /*
  4125. * Add a duplicate block record
  4126. */
  4127. static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
  4128. struct ext2_inode *inode)
  4129. {
  4130. dnode_t *n;
  4131. struct dup_block *db;
  4132. struct dup_inode *di;
  4133. struct block_el *blk_el;
  4134. struct inode_el *ino_el;
  4135. n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
  4136. if (n)
  4137. db = (struct dup_block *) dnode_get(n);
  4138. else {
  4139. db = (struct dup_block *) e2fsck_allocate_memory(ctx,
  4140. sizeof(struct dup_block), "duplicate block header");
  4141. db->num_bad = 0;
  4142. db->inode_list = 0;
  4143. dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
  4144. }
  4145. ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
  4146. sizeof(struct inode_el), "inode element");
  4147. ino_el->inode = ino;
  4148. ino_el->next = db->inode_list;
  4149. db->inode_list = ino_el;
  4150. db->num_bad++;
  4151. n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
  4152. if (n)
  4153. di = (struct dup_inode *) dnode_get(n);
  4154. else {
  4155. di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
  4156. sizeof(struct dup_inode), "duplicate inode header");
  4157. di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0;
  4158. di->num_dupblocks = 0;
  4159. di->block_list = 0;
  4160. di->inode = *inode;
  4161. dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
  4162. }
  4163. blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
  4164. sizeof(struct block_el), "block element");
  4165. blk_el->block = blk;
  4166. blk_el->next = di->block_list;
  4167. di->block_list = blk_el;
  4168. di->num_dupblocks++;
  4169. }
  4170. /*
  4171. * Free a duplicate inode record
  4172. */
  4173. static void inode_dnode_free(dnode_t *node)
  4174. {
  4175. struct dup_inode *di;
  4176. struct block_el *p, *next;
  4177. di = (struct dup_inode *) dnode_get(node);
  4178. for (p = di->block_list; p; p = next) {
  4179. next = p->next;
  4180. free(p);
  4181. }
  4182. free(node);
  4183. }
  4184. /*
  4185. * Free a duplicate block record
  4186. */
  4187. static void block_dnode_free(dnode_t *node)
  4188. {
  4189. struct dup_block *db;
  4190. struct inode_el *p, *next;
  4191. db = (struct dup_block *) dnode_get(node);
  4192. for (p = db->inode_list; p; p = next) {
  4193. next = p->next;
  4194. free(p);
  4195. }
  4196. free(node);
  4197. }
  4198. /*
  4199. * Main procedure for handling duplicate blocks
  4200. */
  4201. void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
  4202. {
  4203. ext2_filsys fs = ctx->fs;
  4204. struct problem_context pctx;
  4205. clear_problem_context(&pctx);
  4206. pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
  4207. _("multiply claimed inode map"), &inode_dup_map);
  4208. if (pctx.errcode) {
  4209. fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
  4210. ctx->flags |= E2F_FLAG_ABORT;
  4211. return;
  4212. }
  4213. dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
  4214. dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
  4215. dict_set_allocator(&ino_dict, inode_dnode_free);
  4216. dict_set_allocator(&blk_dict, block_dnode_free);
  4217. pass1b(ctx, block_buf);
  4218. pass1c(ctx, block_buf);
  4219. pass1d(ctx, block_buf);
  4220. /*
  4221. * Time to free all of the accumulated data structures that we
  4222. * don't need anymore.
  4223. */
  4224. dict_free_nodes(&ino_dict);
  4225. dict_free_nodes(&blk_dict);
  4226. }
  4227. /*
  4228. * Scan the inodes looking for inodes that contain duplicate blocks.
  4229. */
  4230. struct process_block_struct_1b {
  4231. e2fsck_t ctx;
  4232. ext2_ino_t ino;
  4233. int dup_blocks;
  4234. struct ext2_inode *inode;
  4235. struct problem_context *pctx;
  4236. };
  4237. static void pass1b(e2fsck_t ctx, char *block_buf)
  4238. {
  4239. ext2_filsys fs = ctx->fs;
  4240. ext2_ino_t ino;
  4241. struct ext2_inode inode;
  4242. ext2_inode_scan scan;
  4243. struct process_block_struct_1b pb;
  4244. struct problem_context pctx;
  4245. clear_problem_context(&pctx);
  4246. if (!(ctx->options & E2F_OPT_PREEN))
  4247. fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
  4248. pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
  4249. &scan);
  4250. if (pctx.errcode) {
  4251. fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
  4252. ctx->flags |= E2F_FLAG_ABORT;
  4253. return;
  4254. }
  4255. ctx->stashed_inode = &inode;
  4256. pb.ctx = ctx;
  4257. pb.pctx = &pctx;
  4258. pctx.str = "pass1b";
  4259. while (1) {
  4260. pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
  4261. if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
  4262. continue;
  4263. if (pctx.errcode) {
  4264. fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
  4265. ctx->flags |= E2F_FLAG_ABORT;
  4266. return;
  4267. }
  4268. if (!ino)
  4269. break;
  4270. pctx.ino = ctx->stashed_ino = ino;
  4271. if ((ino != EXT2_BAD_INO) &&
  4272. !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
  4273. continue;
  4274. pb.ino = ino;
  4275. pb.dup_blocks = 0;
  4276. pb.inode = &inode;
  4277. if (ext2fs_inode_has_valid_blocks(&inode) ||
  4278. (ino == EXT2_BAD_INO))
  4279. pctx.errcode = ext2fs_block_iterate2(fs, ino,
  4280. 0, block_buf, process_pass1b_block, &pb);
  4281. if (inode.i_file_acl)
  4282. process_pass1b_block(fs, &inode.i_file_acl,
  4283. BLOCK_COUNT_EXTATTR, 0, 0, &pb);
  4284. if (pb.dup_blocks) {
  4285. end_problem_latch(ctx, PR_LATCH_DBLOCK);
  4286. if (ino >= EXT2_FIRST_INODE(fs->super) ||
  4287. ino == EXT2_ROOT_INO)
  4288. dup_inode_count++;
  4289. }
  4290. if (pctx.errcode)
  4291. fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
  4292. }
  4293. ext2fs_close_inode_scan(scan);
  4294. e2fsck_use_inode_shortcuts(ctx, 0);
  4295. }
  4296. static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)),
  4297. blk_t *block_nr,
  4298. e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
  4299. blk_t ref_blk FSCK_ATTR((unused)),
  4300. int ref_offset FSCK_ATTR((unused)),
  4301. void *priv_data)
  4302. {
  4303. struct process_block_struct_1b *p;
  4304. e2fsck_t ctx;
  4305. if (HOLE_BLKADDR(*block_nr))
  4306. return 0;
  4307. p = (struct process_block_struct_1b *) priv_data;
  4308. ctx = p->ctx;
  4309. if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
  4310. return 0;
  4311. /* OK, this is a duplicate block */
  4312. if (p->ino != EXT2_BAD_INO) {
  4313. p->pctx->blk = *block_nr;
  4314. fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
  4315. }
  4316. p->dup_blocks++;
  4317. ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
  4318. add_dupe(ctx, p->ino, *block_nr, p->inode);
  4319. return 0;
  4320. }
  4321. /*
  4322. * Pass 1c: Scan directories for inodes with duplicate blocks. This
  4323. * is used so that we can print pathnames when prompting the user for
  4324. * what to do.
  4325. */
  4326. struct search_dir_struct {
  4327. int count;
  4328. ext2_ino_t first_inode;
  4329. ext2_ino_t max_inode;
  4330. };
  4331. static int search_dirent_proc(ext2_ino_t dir, int entry,
  4332. struct ext2_dir_entry *dirent,
  4333. int offset FSCK_ATTR((unused)),
  4334. int blocksize FSCK_ATTR((unused)),
  4335. char *buf FSCK_ATTR((unused)),
  4336. void *priv_data)
  4337. {
  4338. struct search_dir_struct *sd;
  4339. struct dup_inode *p;
  4340. dnode_t *n;
  4341. sd = (struct search_dir_struct *) priv_data;
  4342. if (dirent->inode > sd->max_inode)
  4343. /* Should abort this inode, but not everything */
  4344. return 0;
  4345. if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
  4346. !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
  4347. return 0;
  4348. n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
  4349. if (!n)
  4350. return 0;
  4351. p = (struct dup_inode *) dnode_get(n);
  4352. p->dir = dir;
  4353. sd->count--;
  4354. return sd->count ? 0 : DIRENT_ABORT;
  4355. }
  4356. static void pass1c(e2fsck_t ctx, char *block_buf)
  4357. {
  4358. ext2_filsys fs = ctx->fs;
  4359. struct search_dir_struct sd;
  4360. struct problem_context pctx;
  4361. clear_problem_context(&pctx);
  4362. if (!(ctx->options & E2F_OPT_PREEN))
  4363. fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
  4364. /*
  4365. * Search through all directories to translate inodes to names
  4366. * (by searching for the containing directory for that inode.)
  4367. */
  4368. sd.count = dup_inode_count;
  4369. sd.first_inode = EXT2_FIRST_INODE(fs->super);
  4370. sd.max_inode = fs->super->s_inodes_count;
  4371. ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
  4372. search_dirent_proc, &sd);
  4373. }
  4374. static void pass1d(e2fsck_t ctx, char *block_buf)
  4375. {
  4376. ext2_filsys fs = ctx->fs;
  4377. struct dup_inode *p, *t;
  4378. struct dup_block *q;
  4379. ext2_ino_t *shared, ino;
  4380. int shared_len;
  4381. int i;
  4382. int file_ok;
  4383. int meta_data = 0;
  4384. struct problem_context pctx;
  4385. dnode_t *n, *m;
  4386. struct block_el *s;
  4387. struct inode_el *r;
  4388. clear_problem_context(&pctx);
  4389. if (!(ctx->options & E2F_OPT_PREEN))
  4390. fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
  4391. e2fsck_read_bitmaps(ctx);
  4392. pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
  4393. fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
  4394. shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
  4395. sizeof(ext2_ino_t) * dict_count(&ino_dict),
  4396. "Shared inode list");
  4397. for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
  4398. p = (struct dup_inode *) dnode_get(n);
  4399. shared_len = 0;
  4400. file_ok = 1;
  4401. ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
  4402. if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO)
  4403. continue;
  4404. /*
  4405. * Find all of the inodes which share blocks with this
  4406. * one. First we find all of the duplicate blocks
  4407. * belonging to this inode, and then search each block
  4408. * get the list of inodes, and merge them together.
  4409. */
  4410. for (s = p->block_list; s; s = s->next) {
  4411. m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
  4412. if (!m)
  4413. continue; /* Should never happen... */
  4414. q = (struct dup_block *) dnode_get(m);
  4415. if (q->num_bad > 1)
  4416. file_ok = 0;
  4417. if (check_if_fs_block(ctx, s->block)) {
  4418. file_ok = 0;
  4419. meta_data = 1;
  4420. }
  4421. /*
  4422. * Add all inodes used by this block to the
  4423. * shared[] --- which is a unique list, so
  4424. * if an inode is already in shared[], don't
  4425. * add it again.
  4426. */
  4427. for (r = q->inode_list; r; r = r->next) {
  4428. if (r->inode == ino)
  4429. continue;
  4430. for (i = 0; i < shared_len; i++)
  4431. if (shared[i] == r->inode)
  4432. break;
  4433. if (i == shared_len) {
  4434. shared[shared_len++] = r->inode;
  4435. }
  4436. }
  4437. }
  4438. /*
  4439. * Report the inode that we are working on
  4440. */
  4441. pctx.inode = &p->inode;
  4442. pctx.ino = ino;
  4443. pctx.dir = p->dir;
  4444. pctx.blkcount = p->num_dupblocks;
  4445. pctx.num = meta_data ? shared_len+1 : shared_len;
  4446. fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
  4447. pctx.blkcount = 0;
  4448. pctx.num = 0;
  4449. if (meta_data)
  4450. fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
  4451. for (i = 0; i < shared_len; i++) {
  4452. m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
  4453. if (!m)
  4454. continue; /* should never happen */
  4455. t = (struct dup_inode *) dnode_get(m);
  4456. /*
  4457. * Report the inode that we are sharing with
  4458. */
  4459. pctx.inode = &t->inode;
  4460. pctx.ino = shared[i];
  4461. pctx.dir = t->dir;
  4462. fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
  4463. }
  4464. if (file_ok) {
  4465. fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
  4466. continue;
  4467. }
  4468. if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
  4469. pctx.errcode = clone_file(ctx, ino, p, block_buf);
  4470. if (pctx.errcode)
  4471. fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
  4472. else
  4473. continue;
  4474. }
  4475. if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
  4476. delete_file(ctx, ino, p, block_buf);
  4477. else
  4478. ext2fs_unmark_valid(fs);
  4479. }
  4480. ext2fs_free_mem(&shared);
  4481. }
  4482. /*
  4483. * Drop the refcount on the dup_block structure, and clear the entry
  4484. * in the block_dup_map if appropriate.
  4485. */
  4486. static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
  4487. {
  4488. p->num_bad--;
  4489. if (p->num_bad <= 0 ||
  4490. (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
  4491. ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
  4492. }
  4493. static int delete_file_block(ext2_filsys fs,
  4494. blk_t *block_nr,
  4495. e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
  4496. blk_t ref_block FSCK_ATTR((unused)),
  4497. int ref_offset FSCK_ATTR((unused)),
  4498. void *priv_data)
  4499. {
  4500. struct process_block_struct_1b *pb;
  4501. struct dup_block *p;
  4502. dnode_t *n;
  4503. e2fsck_t ctx;
  4504. pb = (struct process_block_struct_1b *) priv_data;
  4505. ctx = pb->ctx;
  4506. if (HOLE_BLKADDR(*block_nr))
  4507. return 0;
  4508. if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
  4509. n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
  4510. if (n) {
  4511. p = (struct dup_block *) dnode_get(n);
  4512. decrement_badcount(ctx, *block_nr, p);
  4513. } else
  4514. bb_error_msg(_("internal error; can't find dup_blk for %d"),
  4515. *block_nr);
  4516. } else {
  4517. ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
  4518. ext2fs_block_alloc_stats(fs, *block_nr, -1);
  4519. }
  4520. return 0;
  4521. }
  4522. static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
  4523. struct dup_inode *dp, char* block_buf)
  4524. {
  4525. ext2_filsys fs = ctx->fs;
  4526. struct process_block_struct_1b pb;
  4527. struct ext2_inode inode;
  4528. struct problem_context pctx;
  4529. unsigned int count;
  4530. clear_problem_context(&pctx);
  4531. pctx.ino = pb.ino = ino;
  4532. pb.dup_blocks = dp->num_dupblocks;
  4533. pb.ctx = ctx;
  4534. pctx.str = "delete_file";
  4535. e2fsck_read_inode(ctx, ino, &inode, "delete_file");
  4536. if (ext2fs_inode_has_valid_blocks(&inode))
  4537. pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
  4538. delete_file_block, &pb);
  4539. if (pctx.errcode)
  4540. fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
  4541. ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
  4542. ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
  4543. if (ctx->inode_bad_map)
  4544. ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
  4545. ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
  4546. /* Inode may have changed by block_iterate, so reread it */
  4547. e2fsck_read_inode(ctx, ino, &inode, "delete_file");
  4548. inode.i_links_count = 0;
  4549. inode.i_dtime = time(NULL);
  4550. if (inode.i_file_acl &&
  4551. (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
  4552. count = 1;
  4553. pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
  4554. block_buf, -1, &count);
  4555. if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
  4556. pctx.errcode = 0;
  4557. count = 1;
  4558. }
  4559. if (pctx.errcode) {
  4560. pctx.blk = inode.i_file_acl;
  4561. fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
  4562. }
  4563. /*
  4564. * If the count is zero, then arrange to have the
  4565. * block deleted. If the block is in the block_dup_map,
  4566. * also call delete_file_block since it will take care
  4567. * of keeping the accounting straight.
  4568. */
  4569. if ((count == 0) ||
  4570. ext2fs_test_block_bitmap(ctx->block_dup_map,
  4571. inode.i_file_acl))
  4572. delete_file_block(fs, &inode.i_file_acl,
  4573. BLOCK_COUNT_EXTATTR, 0, 0, &pb);
  4574. }
  4575. e2fsck_write_inode(ctx, ino, &inode, "delete_file");
  4576. }
  4577. struct clone_struct {
  4578. errcode_t errcode;
  4579. ext2_ino_t dir;
  4580. char *buf;
  4581. e2fsck_t ctx;
  4582. };
  4583. static int clone_file_block(ext2_filsys fs,
  4584. blk_t *block_nr,
  4585. e2_blkcnt_t blockcnt,
  4586. blk_t ref_block FSCK_ATTR((unused)),
  4587. int ref_offset FSCK_ATTR((unused)),
  4588. void *priv_data)
  4589. {
  4590. struct dup_block *p;
  4591. blk_t new_block;
  4592. errcode_t retval;
  4593. struct clone_struct *cs = (struct clone_struct *) priv_data;
  4594. dnode_t *n;
  4595. e2fsck_t ctx;
  4596. ctx = cs->ctx;
  4597. if (HOLE_BLKADDR(*block_nr))
  4598. return 0;
  4599. if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
  4600. n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
  4601. if (n) {
  4602. p = (struct dup_block *) dnode_get(n);
  4603. retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
  4604. &new_block);
  4605. if (retval) {
  4606. cs->errcode = retval;
  4607. return BLOCK_ABORT;
  4608. }
  4609. if (cs->dir && (blockcnt >= 0)) {
  4610. retval = ext2fs_set_dir_block(fs->dblist,
  4611. cs->dir, new_block, blockcnt);
  4612. if (retval) {
  4613. cs->errcode = retval;
  4614. return BLOCK_ABORT;
  4615. }
  4616. }
  4617. retval = io_channel_read_blk(fs->io, *block_nr, 1,
  4618. cs->buf);
  4619. if (retval) {
  4620. cs->errcode = retval;
  4621. return BLOCK_ABORT;
  4622. }
  4623. retval = io_channel_write_blk(fs->io, new_block, 1,
  4624. cs->buf);
  4625. if (retval) {
  4626. cs->errcode = retval;
  4627. return BLOCK_ABORT;
  4628. }
  4629. decrement_badcount(ctx, *block_nr, p);
  4630. *block_nr = new_block;
  4631. ext2fs_mark_block_bitmap(ctx->block_found_map,
  4632. new_block);
  4633. ext2fs_mark_block_bitmap(fs->block_map, new_block);
  4634. return BLOCK_CHANGED;
  4635. } else
  4636. bb_error_msg(_("internal error; can't find dup_blk for %d"),
  4637. *block_nr);
  4638. }
  4639. return 0;
  4640. }
  4641. static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
  4642. struct dup_inode *dp, char* block_buf)
  4643. {
  4644. ext2_filsys fs = ctx->fs;
  4645. errcode_t retval;
  4646. struct clone_struct cs;
  4647. struct problem_context pctx;
  4648. blk_t blk;
  4649. dnode_t *n;
  4650. struct inode_el *ino_el;
  4651. struct dup_block *db;
  4652. struct dup_inode *di;
  4653. clear_problem_context(&pctx);
  4654. cs.errcode = 0;
  4655. cs.dir = 0;
  4656. cs.ctx = ctx;
  4657. retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
  4658. if (retval)
  4659. return retval;
  4660. if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
  4661. cs.dir = ino;
  4662. pctx.ino = ino;
  4663. pctx.str = "clone_file";
  4664. if (ext2fs_inode_has_valid_blocks(&dp->inode))
  4665. pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
  4666. clone_file_block, &cs);
  4667. ext2fs_mark_bb_dirty(fs);
  4668. if (pctx.errcode) {
  4669. fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
  4670. retval = pctx.errcode;
  4671. goto errout;
  4672. }
  4673. if (cs.errcode) {
  4674. bb_error_msg(_("returned from clone_file_block"));
  4675. retval = cs.errcode;
  4676. goto errout;
  4677. }
  4678. /* The inode may have changed on disk, so we have to re-read it */
  4679. e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
  4680. blk = dp->inode.i_file_acl;
  4681. if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
  4682. BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
  4683. BLOCK_CHANGED)) {
  4684. e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
  4685. /*
  4686. * If we cloned the EA block, find all other inodes
  4687. * which refered to that EA block, and modify
  4688. * them to point to the new EA block.
  4689. */
  4690. n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
  4691. db = (struct dup_block *) dnode_get(n);
  4692. for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
  4693. if (ino_el->inode == ino)
  4694. continue;
  4695. n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
  4696. di = (struct dup_inode *) dnode_get(n);
  4697. if (di->inode.i_file_acl == blk) {
  4698. di->inode.i_file_acl = dp->inode.i_file_acl;
  4699. e2fsck_write_inode(ctx, ino_el->inode,
  4700. &di->inode, "clone file EA");
  4701. decrement_badcount(ctx, blk, db);
  4702. }
  4703. }
  4704. }
  4705. retval = 0;
  4706. errout:
  4707. ext2fs_free_mem(&cs.buf);
  4708. return retval;
  4709. }
  4710. /*
  4711. * This routine returns 1 if a block overlaps with one of the superblocks,
  4712. * group descriptors, inode bitmaps, or block bitmaps.
  4713. */
  4714. static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
  4715. {
  4716. ext2_filsys fs = ctx->fs;
  4717. blk_t block;
  4718. dgrp_t i;
  4719. block = fs->super->s_first_data_block;
  4720. for (i = 0; i < fs->group_desc_count; i++) {
  4721. /* Check superblocks/block group descriptros */
  4722. if (ext2fs_bg_has_super(fs, i)) {
  4723. if (test_block >= block &&
  4724. (test_block <= block + fs->desc_blocks))
  4725. return 1;
  4726. }
  4727. /* Check the inode table */
  4728. if ((fs->group_desc[i].bg_inode_table) &&
  4729. (test_block >= fs->group_desc[i].bg_inode_table) &&
  4730. (test_block < (fs->group_desc[i].bg_inode_table +
  4731. fs->inode_blocks_per_group)))
  4732. return 1;
  4733. /* Check the bitmap blocks */
  4734. if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
  4735. (test_block == fs->group_desc[i].bg_inode_bitmap))
  4736. return 1;
  4737. block += fs->super->s_blocks_per_group;
  4738. }
  4739. return 0;
  4740. }
  4741. /*
  4742. * pass2.c --- check directory structure
  4743. *
  4744. * Pass 2 of e2fsck iterates through all active directory inodes, and
  4745. * applies to following tests to each directory entry in the directory
  4746. * blocks in the inodes:
  4747. *
  4748. * - The length of the directory entry (rec_len) should be at
  4749. * least 8 bytes, and no more than the remaining space
  4750. * left in the directory block.
  4751. * - The length of the name in the directory entry (name_len)
  4752. * should be less than (rec_len - 8).
  4753. * - The inode number in the directory entry should be within
  4754. * legal bounds.
  4755. * - The inode number should refer to a in-use inode.
  4756. * - The first entry should be '.', and its inode should be
  4757. * the inode of the directory.
  4758. * - The second entry should be '..'.
  4759. *
  4760. * To minimize disk seek time, the directory blocks are processed in
  4761. * sorted order of block numbers.
  4762. *
  4763. * Pass 2 also collects the following information:
  4764. * - The inode numbers of the subdirectories for each directory.
  4765. *
  4766. * Pass 2 relies on the following information from previous passes:
  4767. * - The directory information collected in pass 1.
  4768. * - The inode_used_map bitmap
  4769. * - The inode_bad_map bitmap
  4770. * - The inode_dir_map bitmap
  4771. *
  4772. * Pass 2 frees the following data structures
  4773. * - The inode_bad_map bitmap
  4774. * - The inode_reg_map bitmap
  4775. */
  4776. /*
  4777. * Keeps track of how many times an inode is referenced.
  4778. */
  4779. static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
  4780. static int check_dir_block(ext2_filsys fs,
  4781. struct ext2_db_entry *dir_blocks_info,
  4782. void *priv_data);
  4783. static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info,
  4784. struct problem_context *pctx);
  4785. static int update_dir_block(ext2_filsys fs,
  4786. blk_t *block_nr,
  4787. e2_blkcnt_t blockcnt,
  4788. blk_t ref_block,
  4789. int ref_offset,
  4790. void *priv_data);
  4791. static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
  4792. static int htree_depth(struct dx_dir_info *dx_dir,
  4793. struct dx_dirblock_info *dx_db);
  4794. static int special_dir_block_cmp(const void *a, const void *b);
  4795. struct check_dir_struct {
  4796. char *buf;
  4797. struct problem_context pctx;
  4798. int count, max;
  4799. e2fsck_t ctx;
  4800. };
  4801. static void e2fsck_pass2(e2fsck_t ctx)
  4802. {
  4803. struct ext2_super_block *sb = ctx->fs->super;
  4804. struct problem_context pctx;
  4805. ext2_filsys fs = ctx->fs;
  4806. char *buf;
  4807. struct dir_info *dir;
  4808. struct check_dir_struct cd;
  4809. struct dx_dir_info *dx_dir;
  4810. struct dx_dirblock_info *dx_db, *dx_parent;
  4811. int b;
  4812. int i, depth;
  4813. problem_t code;
  4814. int bad_dir;
  4815. clear_problem_context(&cd.pctx);
  4816. /* Pass 2 */
  4817. if (!(ctx->options & E2F_OPT_PREEN))
  4818. fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
  4819. cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
  4820. 0, ctx->inode_link_info,
  4821. &ctx->inode_count);
  4822. if (cd.pctx.errcode) {
  4823. fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
  4824. ctx->flags |= E2F_FLAG_ABORT;
  4825. return;
  4826. }
  4827. buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
  4828. "directory scan buffer");
  4829. /*
  4830. * Set up the parent pointer for the root directory, if
  4831. * present. (If the root directory is not present, we will
  4832. * create it in pass 3.)
  4833. */
  4834. dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
  4835. if (dir)
  4836. dir->parent = EXT2_ROOT_INO;
  4837. cd.buf = buf;
  4838. cd.ctx = ctx;
  4839. cd.count = 1;
  4840. cd.max = ext2fs_dblist_count(fs->dblist);
  4841. if (ctx->progress)
  4842. (void) (ctx->progress)(ctx, 2, 0, cd.max);
  4843. if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
  4844. ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
  4845. cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
  4846. &cd);
  4847. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  4848. return;
  4849. if (cd.pctx.errcode) {
  4850. fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
  4851. ctx->flags |= E2F_FLAG_ABORT;
  4852. return;
  4853. }
  4854. #ifdef ENABLE_HTREE
  4855. for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
  4856. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  4857. return;
  4858. if (dx_dir->numblocks == 0)
  4859. continue;
  4860. clear_problem_context(&pctx);
  4861. bad_dir = 0;
  4862. pctx.dir = dx_dir->ino;
  4863. dx_db = dx_dir->dx_block;
  4864. if (dx_db->flags & DX_FLAG_REFERENCED)
  4865. dx_db->flags |= DX_FLAG_DUP_REF;
  4866. else
  4867. dx_db->flags |= DX_FLAG_REFERENCED;
  4868. /*
  4869. * Find all of the first and last leaf blocks, and
  4870. * update their parent's min and max hash values
  4871. */
  4872. for (b=0, dx_db = dx_dir->dx_block;
  4873. b < dx_dir->numblocks;
  4874. b++, dx_db++) {
  4875. if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
  4876. !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
  4877. continue;
  4878. dx_parent = &dx_dir->dx_block[dx_db->parent];
  4879. /*
  4880. * XXX Make sure dx_parent->min_hash > dx_db->min_hash
  4881. */
  4882. if (dx_db->flags & DX_FLAG_FIRST)
  4883. dx_parent->min_hash = dx_db->min_hash;
  4884. /*
  4885. * XXX Make sure dx_parent->max_hash < dx_db->max_hash
  4886. */
  4887. if (dx_db->flags & DX_FLAG_LAST)
  4888. dx_parent->max_hash = dx_db->max_hash;
  4889. }
  4890. for (b=0, dx_db = dx_dir->dx_block;
  4891. b < dx_dir->numblocks;
  4892. b++, dx_db++) {
  4893. pctx.blkcount = b;
  4894. pctx.group = dx_db->parent;
  4895. code = 0;
  4896. if (!(dx_db->flags & DX_FLAG_FIRST) &&
  4897. (dx_db->min_hash < dx_db->node_min_hash)) {
  4898. pctx.blk = dx_db->min_hash;
  4899. pctx.blk2 = dx_db->node_min_hash;
  4900. code = PR_2_HTREE_MIN_HASH;
  4901. fix_problem(ctx, code, &pctx);
  4902. bad_dir++;
  4903. }
  4904. if (dx_db->type == DX_DIRBLOCK_LEAF) {
  4905. depth = htree_depth(dx_dir, dx_db);
  4906. if (depth != dx_dir->depth) {
  4907. code = PR_2_HTREE_BAD_DEPTH;
  4908. fix_problem(ctx, code, &pctx);
  4909. bad_dir++;
  4910. }
  4911. }
  4912. /*
  4913. * This test doesn't apply for the root block
  4914. * at block #0
  4915. */
  4916. if (b &&
  4917. (dx_db->max_hash > dx_db->node_max_hash)) {
  4918. pctx.blk = dx_db->max_hash;
  4919. pctx.blk2 = dx_db->node_max_hash;
  4920. code = PR_2_HTREE_MAX_HASH;
  4921. fix_problem(ctx, code, &pctx);
  4922. bad_dir++;
  4923. }
  4924. if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
  4925. code = PR_2_HTREE_NOTREF;
  4926. fix_problem(ctx, code, &pctx);
  4927. bad_dir++;
  4928. } else if (dx_db->flags & DX_FLAG_DUP_REF) {
  4929. code = PR_2_HTREE_DUPREF;
  4930. fix_problem(ctx, code, &pctx);
  4931. bad_dir++;
  4932. }
  4933. if (code == 0)
  4934. continue;
  4935. }
  4936. if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
  4937. clear_htree(ctx, dx_dir->ino);
  4938. dx_dir->numblocks = 0;
  4939. }
  4940. }
  4941. #endif
  4942. ext2fs_free_mem(&buf);
  4943. ext2fs_free_dblist(fs->dblist);
  4944. ext2fs_free_inode_bitmap(ctx->inode_bad_map);
  4945. ctx->inode_bad_map = 0;
  4946. ext2fs_free_inode_bitmap(ctx->inode_reg_map);
  4947. ctx->inode_reg_map = 0;
  4948. clear_problem_context(&pctx);
  4949. if (ctx->large_files) {
  4950. if (!(sb->s_feature_ro_compat &
  4951. EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
  4952. fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
  4953. sb->s_feature_ro_compat |=
  4954. EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
  4955. ext2fs_mark_super_dirty(fs);
  4956. }
  4957. if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
  4958. fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
  4959. ext2fs_update_dynamic_rev(fs);
  4960. ext2fs_mark_super_dirty(fs);
  4961. }
  4962. } else if (!ctx->large_files &&
  4963. (sb->s_feature_ro_compat &
  4964. EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
  4965. if (fs->flags & EXT2_FLAG_RW) {
  4966. sb->s_feature_ro_compat &=
  4967. ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
  4968. ext2fs_mark_super_dirty(fs);
  4969. }
  4970. }
  4971. }
  4972. #define MAX_DEPTH 32000
  4973. static int htree_depth(struct dx_dir_info *dx_dir,
  4974. struct dx_dirblock_info *dx_db)
  4975. {
  4976. int depth = 0;
  4977. while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
  4978. dx_db = &dx_dir->dx_block[dx_db->parent];
  4979. depth++;
  4980. }
  4981. return depth;
  4982. }
  4983. static int dict_de_cmp(const void *a, const void *b)
  4984. {
  4985. const struct ext2_dir_entry *de_a, *de_b;
  4986. int a_len, b_len;
  4987. de_a = (const struct ext2_dir_entry *) a;
  4988. a_len = de_a->name_len & 0xFF;
  4989. de_b = (const struct ext2_dir_entry *) b;
  4990. b_len = de_b->name_len & 0xFF;
  4991. if (a_len != b_len)
  4992. return (a_len - b_len);
  4993. return strncmp(de_a->name, de_b->name, a_len);
  4994. }
  4995. /*
  4996. * This is special sort function that makes sure that directory blocks
  4997. * with a dirblock of zero are sorted to the beginning of the list.
  4998. * This guarantees that the root node of the htree directories are
  4999. * processed first, so we know what hash version to use.
  5000. */
  5001. static int special_dir_block_cmp(const void *a, const void *b)
  5002. {
  5003. const struct ext2_db_entry *db_a =
  5004. (const struct ext2_db_entry *) a;
  5005. const struct ext2_db_entry *db_b =
  5006. (const struct ext2_db_entry *) b;
  5007. if (db_a->blockcnt && !db_b->blockcnt)
  5008. return 1;
  5009. if (!db_a->blockcnt && db_b->blockcnt)
  5010. return -1;
  5011. if (db_a->blk != db_b->blk)
  5012. return (int) (db_a->blk - db_b->blk);
  5013. if (db_a->ino != db_b->ino)
  5014. return (int) (db_a->ino - db_b->ino);
  5015. return (int) (db_a->blockcnt - db_b->blockcnt);
  5016. }
  5017. /*
  5018. * Make sure the first entry in the directory is '.', and that the
  5019. * directory entry is sane.
  5020. */
  5021. static int check_dot(e2fsck_t ctx,
  5022. struct ext2_dir_entry *dirent,
  5023. ext2_ino_t ino, struct problem_context *pctx)
  5024. {
  5025. struct ext2_dir_entry *nextdir;
  5026. int status = 0;
  5027. int created = 0;
  5028. int new_len;
  5029. int problem = 0;
  5030. if (!dirent->inode)
  5031. problem = PR_2_MISSING_DOT;
  5032. else if (((dirent->name_len & 0xFF) != 1) ||
  5033. (dirent->name[0] != '.'))
  5034. problem = PR_2_1ST_NOT_DOT;
  5035. else if (dirent->name[1] != '\0')
  5036. problem = PR_2_DOT_NULL_TERM;
  5037. if (problem) {
  5038. if (fix_problem(ctx, problem, pctx)) {
  5039. if (dirent->rec_len < 12)
  5040. dirent->rec_len = 12;
  5041. dirent->inode = ino;
  5042. dirent->name_len = 1;
  5043. dirent->name[0] = '.';
  5044. dirent->name[1] = '\0';
  5045. status = 1;
  5046. created = 1;
  5047. }
  5048. }
  5049. if (dirent->inode != ino) {
  5050. if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
  5051. dirent->inode = ino;
  5052. status = 1;
  5053. }
  5054. }
  5055. if (dirent->rec_len > 12) {
  5056. new_len = dirent->rec_len - 12;
  5057. if (new_len > 12) {
  5058. if (created ||
  5059. fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
  5060. nextdir = (struct ext2_dir_entry *)
  5061. ((char *) dirent + 12);
  5062. dirent->rec_len = 12;
  5063. nextdir->rec_len = new_len;
  5064. nextdir->inode = 0;
  5065. nextdir->name_len = 0;
  5066. status = 1;
  5067. }
  5068. }
  5069. }
  5070. return status;
  5071. }
  5072. /*
  5073. * Make sure the second entry in the directory is '..', and that the
  5074. * directory entry is sane. We do not check the inode number of '..'
  5075. * here; this gets done in pass 3.
  5076. */
  5077. static int check_dotdot(e2fsck_t ctx,
  5078. struct ext2_dir_entry *dirent,
  5079. struct dir_info *dir, struct problem_context *pctx)
  5080. {
  5081. int problem = 0;
  5082. if (!dirent->inode)
  5083. problem = PR_2_MISSING_DOT_DOT;
  5084. else if (((dirent->name_len & 0xFF) != 2) ||
  5085. (dirent->name[0] != '.') ||
  5086. (dirent->name[1] != '.'))
  5087. problem = PR_2_2ND_NOT_DOT_DOT;
  5088. else if (dirent->name[2] != '\0')
  5089. problem = PR_2_DOT_DOT_NULL_TERM;
  5090. if (problem) {
  5091. if (fix_problem(ctx, problem, pctx)) {
  5092. if (dirent->rec_len < 12)
  5093. dirent->rec_len = 12;
  5094. /*
  5095. * Note: we don't have the parent inode just
  5096. * yet, so we will fill it in with the root
  5097. * inode. This will get fixed in pass 3.
  5098. */
  5099. dirent->inode = EXT2_ROOT_INO;
  5100. dirent->name_len = 2;
  5101. dirent->name[0] = '.';
  5102. dirent->name[1] = '.';
  5103. dirent->name[2] = '\0';
  5104. return 1;
  5105. }
  5106. return 0;
  5107. }
  5108. dir->dotdot = dirent->inode;
  5109. return 0;
  5110. }
  5111. /*
  5112. * Check to make sure a directory entry doesn't contain any illegal
  5113. * characters.
  5114. */
  5115. static int check_name(e2fsck_t ctx,
  5116. struct ext2_dir_entry *dirent,
  5117. struct problem_context *pctx)
  5118. {
  5119. int i;
  5120. int fixup = -1;
  5121. int ret = 0;
  5122. for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
  5123. if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
  5124. if (fixup < 0) {
  5125. fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
  5126. }
  5127. if (fixup) {
  5128. dirent->name[i] = '.';
  5129. ret = 1;
  5130. }
  5131. }
  5132. }
  5133. return ret;
  5134. }
  5135. /*
  5136. * Check the directory filetype (if present)
  5137. */
  5138. /*
  5139. * Given a mode, return the ext2 file type
  5140. */
  5141. static int ext2_file_type(unsigned int mode)
  5142. {
  5143. if (LINUX_S_ISREG(mode))
  5144. return EXT2_FT_REG_FILE;
  5145. if (LINUX_S_ISDIR(mode))
  5146. return EXT2_FT_DIR;
  5147. if (LINUX_S_ISCHR(mode))
  5148. return EXT2_FT_CHRDEV;
  5149. if (LINUX_S_ISBLK(mode))
  5150. return EXT2_FT_BLKDEV;
  5151. if (LINUX_S_ISLNK(mode))
  5152. return EXT2_FT_SYMLINK;
  5153. if (LINUX_S_ISFIFO(mode))
  5154. return EXT2_FT_FIFO;
  5155. if (LINUX_S_ISSOCK(mode))
  5156. return EXT2_FT_SOCK;
  5157. return 0;
  5158. }
  5159. static int check_filetype(e2fsck_t ctx,
  5160. struct ext2_dir_entry *dirent,
  5161. struct problem_context *pctx)
  5162. {
  5163. int filetype = dirent->name_len >> 8;
  5164. int should_be = EXT2_FT_UNKNOWN;
  5165. struct ext2_inode inode;
  5166. if (!(ctx->fs->super->s_feature_incompat &
  5167. EXT2_FEATURE_INCOMPAT_FILETYPE)) {
  5168. if (filetype == 0 ||
  5169. !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
  5170. return 0;
  5171. dirent->name_len = dirent->name_len & 0xFF;
  5172. return 1;
  5173. }
  5174. if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
  5175. should_be = EXT2_FT_DIR;
  5176. } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
  5177. dirent->inode)) {
  5178. should_be = EXT2_FT_REG_FILE;
  5179. } else if (ctx->inode_bad_map &&
  5180. ext2fs_test_inode_bitmap(ctx->inode_bad_map,
  5181. dirent->inode))
  5182. should_be = 0;
  5183. else {
  5184. e2fsck_read_inode(ctx, dirent->inode, &inode,
  5185. "check_filetype");
  5186. should_be = ext2_file_type(inode.i_mode);
  5187. }
  5188. if (filetype == should_be)
  5189. return 0;
  5190. pctx->num = should_be;
  5191. if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
  5192. pctx) == 0)
  5193. return 0;
  5194. dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
  5195. return 1;
  5196. }
  5197. #ifdef ENABLE_HTREE
  5198. static void parse_int_node(ext2_filsys fs,
  5199. struct ext2_db_entry *db,
  5200. struct check_dir_struct *cd,
  5201. struct dx_dir_info *dx_dir,
  5202. char *block_buf)
  5203. {
  5204. struct ext2_dx_root_info *root;
  5205. struct ext2_dx_entry *ent;
  5206. struct ext2_dx_countlimit *limit;
  5207. struct dx_dirblock_info *dx_db;
  5208. int i, expect_limit, count;
  5209. blk_t blk;
  5210. ext2_dirhash_t min_hash = 0xffffffff;
  5211. ext2_dirhash_t max_hash = 0;
  5212. ext2_dirhash_t hash = 0, prev_hash;
  5213. if (db->blockcnt == 0) {
  5214. root = (struct ext2_dx_root_info *) (block_buf + 24);
  5215. ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
  5216. } else {
  5217. ent = (struct ext2_dx_entry *) (block_buf+8);
  5218. }
  5219. limit = (struct ext2_dx_countlimit *) ent;
  5220. count = ext2fs_le16_to_cpu(limit->count);
  5221. expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
  5222. sizeof(struct ext2_dx_entry);
  5223. if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
  5224. cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
  5225. if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
  5226. goto clear_and_exit;
  5227. }
  5228. if (count > expect_limit) {
  5229. cd->pctx.num = count;
  5230. if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
  5231. goto clear_and_exit;
  5232. count = expect_limit;
  5233. }
  5234. for (i=0; i < count; i++) {
  5235. prev_hash = hash;
  5236. hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
  5237. blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
  5238. /* Check to make sure the block is valid */
  5239. if (blk > (blk_t) dx_dir->numblocks) {
  5240. cd->pctx.blk = blk;
  5241. if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
  5242. &cd->pctx))
  5243. goto clear_and_exit;
  5244. }
  5245. if (hash < prev_hash &&
  5246. fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
  5247. goto clear_and_exit;
  5248. dx_db = &dx_dir->dx_block[blk];
  5249. if (dx_db->flags & DX_FLAG_REFERENCED) {
  5250. dx_db->flags |= DX_FLAG_DUP_REF;
  5251. } else {
  5252. dx_db->flags |= DX_FLAG_REFERENCED;
  5253. dx_db->parent = db->blockcnt;
  5254. }
  5255. if (hash < min_hash)
  5256. min_hash = hash;
  5257. if (hash > max_hash)
  5258. max_hash = hash;
  5259. dx_db->node_min_hash = hash;
  5260. if ((i+1) < count)
  5261. dx_db->node_max_hash =
  5262. ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
  5263. else {
  5264. dx_db->node_max_hash = 0xfffffffe;
  5265. dx_db->flags |= DX_FLAG_LAST;
  5266. }
  5267. if (i == 0)
  5268. dx_db->flags |= DX_FLAG_FIRST;
  5269. }
  5270. dx_db = &dx_dir->dx_block[db->blockcnt];
  5271. dx_db->min_hash = min_hash;
  5272. dx_db->max_hash = max_hash;
  5273. return;
  5274. clear_and_exit:
  5275. clear_htree(cd->ctx, cd->pctx.ino);
  5276. dx_dir->numblocks = 0;
  5277. }
  5278. #endif /* ENABLE_HTREE */
  5279. /*
  5280. * Given a busted directory, try to salvage it somehow.
  5281. *
  5282. */
  5283. static void salvage_directory(ext2_filsys fs,
  5284. struct ext2_dir_entry *dirent,
  5285. struct ext2_dir_entry *prev,
  5286. unsigned int *offset)
  5287. {
  5288. char *cp = (char *) dirent;
  5289. int left = fs->blocksize - *offset - dirent->rec_len;
  5290. int name_len = dirent->name_len & 0xFF;
  5291. /*
  5292. * Special case of directory entry of size 8: copy what's left
  5293. * of the directory block up to cover up the invalid hole.
  5294. */
  5295. if ((left >= 12) && (dirent->rec_len == 8)) {
  5296. memmove(cp, cp+8, left);
  5297. memset(cp + left, 0, 8);
  5298. return;
  5299. }
  5300. /*
  5301. * If the directory entry overruns the end of the directory
  5302. * block, and the name is small enough to fit, then adjust the
  5303. * record length.
  5304. */
  5305. if ((left < 0) &&
  5306. (name_len + 8 <= dirent->rec_len + left) &&
  5307. dirent->inode <= fs->super->s_inodes_count &&
  5308. strnlen(dirent->name, name_len) == name_len) {
  5309. dirent->rec_len += left;
  5310. return;
  5311. }
  5312. /*
  5313. * If the directory entry is a multiple of four, so it is
  5314. * valid, let the previous directory entry absorb the invalid
  5315. * one.
  5316. */
  5317. if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
  5318. prev->rec_len += dirent->rec_len;
  5319. *offset += dirent->rec_len;
  5320. return;
  5321. }
  5322. /*
  5323. * Default salvage method --- kill all of the directory
  5324. * entries for the rest of the block. We will either try to
  5325. * absorb it into the previous directory entry, or create a
  5326. * new empty directory entry the rest of the directory block.
  5327. */
  5328. if (prev) {
  5329. prev->rec_len += fs->blocksize - *offset;
  5330. *offset = fs->blocksize;
  5331. } else {
  5332. dirent->rec_len = fs->blocksize - *offset;
  5333. dirent->name_len = 0;
  5334. dirent->inode = 0;
  5335. }
  5336. }
  5337. static int check_dir_block(ext2_filsys fs,
  5338. struct ext2_db_entry *db,
  5339. void *priv_data)
  5340. {
  5341. struct dir_info *subdir, *dir;
  5342. struct dx_dir_info *dx_dir;
  5343. #ifdef ENABLE_HTREE
  5344. struct dx_dirblock_info *dx_db = NULL;
  5345. #endif /* ENABLE_HTREE */
  5346. struct ext2_dir_entry *dirent, *prev;
  5347. ext2_dirhash_t hash;
  5348. unsigned int offset = 0;
  5349. int dir_modified = 0;
  5350. int dot_state;
  5351. blk_t block_nr = db->blk;
  5352. ext2_ino_t ino = db->ino;
  5353. __u16 links;
  5354. struct check_dir_struct *cd;
  5355. char *buf;
  5356. e2fsck_t ctx;
  5357. int problem;
  5358. struct ext2_dx_root_info *root;
  5359. struct ext2_dx_countlimit *limit;
  5360. static dict_t de_dict;
  5361. struct problem_context pctx;
  5362. int dups_found = 0;
  5363. cd = (struct check_dir_struct *) priv_data;
  5364. buf = cd->buf;
  5365. ctx = cd->ctx;
  5366. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  5367. return DIRENT_ABORT;
  5368. if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
  5369. return DIRENT_ABORT;
  5370. /*
  5371. * Make sure the inode is still in use (could have been
  5372. * deleted in the duplicate/bad blocks pass.
  5373. */
  5374. if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
  5375. return 0;
  5376. cd->pctx.ino = ino;
  5377. cd->pctx.blk = block_nr;
  5378. cd->pctx.blkcount = db->blockcnt;
  5379. cd->pctx.ino2 = 0;
  5380. cd->pctx.dirent = 0;
  5381. cd->pctx.num = 0;
  5382. if (db->blk == 0) {
  5383. if (allocate_dir_block(ctx, db, &cd->pctx))
  5384. return 0;
  5385. block_nr = db->blk;
  5386. }
  5387. if (db->blockcnt)
  5388. dot_state = 2;
  5389. else
  5390. dot_state = 0;
  5391. if (ctx->dirs_to_hash &&
  5392. ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
  5393. dups_found++;
  5394. cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
  5395. if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
  5396. cd->pctx.errcode = 0; /* We'll handle this ourselves */
  5397. if (cd->pctx.errcode) {
  5398. if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
  5399. ctx->flags |= E2F_FLAG_ABORT;
  5400. return DIRENT_ABORT;
  5401. }
  5402. memset(buf, 0, fs->blocksize);
  5403. }
  5404. #ifdef ENABLE_HTREE
  5405. dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
  5406. if (dx_dir && dx_dir->numblocks) {
  5407. if (db->blockcnt >= dx_dir->numblocks) {
  5408. printf("XXX should never happen!!!\n");
  5409. abort();
  5410. }
  5411. dx_db = &dx_dir->dx_block[db->blockcnt];
  5412. dx_db->type = DX_DIRBLOCK_LEAF;
  5413. dx_db->phys = block_nr;
  5414. dx_db->min_hash = ~0;
  5415. dx_db->max_hash = 0;
  5416. dirent = (struct ext2_dir_entry *) buf;
  5417. limit = (struct ext2_dx_countlimit *) (buf+8);
  5418. if (db->blockcnt == 0) {
  5419. root = (struct ext2_dx_root_info *) (buf + 24);
  5420. dx_db->type = DX_DIRBLOCK_ROOT;
  5421. dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
  5422. if ((root->reserved_zero ||
  5423. root->info_length < 8 ||
  5424. root->indirect_levels > 1) &&
  5425. fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
  5426. clear_htree(ctx, ino);
  5427. dx_dir->numblocks = 0;
  5428. dx_db = 0;
  5429. }
  5430. dx_dir->hashversion = root->hash_version;
  5431. dx_dir->depth = root->indirect_levels + 1;
  5432. } else if ((dirent->inode == 0) &&
  5433. (dirent->rec_len == fs->blocksize) &&
  5434. (dirent->name_len == 0) &&
  5435. (ext2fs_le16_to_cpu(limit->limit) ==
  5436. ((fs->blocksize-8) /
  5437. sizeof(struct ext2_dx_entry))))
  5438. dx_db->type = DX_DIRBLOCK_NODE;
  5439. }
  5440. #endif /* ENABLE_HTREE */
  5441. dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
  5442. prev = 0;
  5443. do {
  5444. problem = 0;
  5445. dirent = (struct ext2_dir_entry *) (buf + offset);
  5446. cd->pctx.dirent = dirent;
  5447. cd->pctx.num = offset;
  5448. if (((offset + dirent->rec_len) > fs->blocksize) ||
  5449. (dirent->rec_len < 12) ||
  5450. ((dirent->rec_len % 4) != 0) ||
  5451. (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
  5452. if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
  5453. salvage_directory(fs, dirent, prev, &offset);
  5454. dir_modified++;
  5455. continue;
  5456. } else
  5457. goto abort_free_dict;
  5458. }
  5459. if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
  5460. if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
  5461. dirent->name_len = EXT2_NAME_LEN;
  5462. dir_modified++;
  5463. }
  5464. }
  5465. if (dot_state == 0) {
  5466. if (check_dot(ctx, dirent, ino, &cd->pctx))
  5467. dir_modified++;
  5468. } else if (dot_state == 1) {
  5469. dir = e2fsck_get_dir_info(ctx, ino);
  5470. if (!dir) {
  5471. fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
  5472. goto abort_free_dict;
  5473. }
  5474. if (check_dotdot(ctx, dirent, dir, &cd->pctx))
  5475. dir_modified++;
  5476. } else if (dirent->inode == ino) {
  5477. problem = PR_2_LINK_DOT;
  5478. if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
  5479. dirent->inode = 0;
  5480. dir_modified++;
  5481. goto next;
  5482. }
  5483. }
  5484. if (!dirent->inode)
  5485. goto next;
  5486. /*
  5487. * Make sure the inode listed is a legal one.
  5488. */
  5489. if (((dirent->inode != EXT2_ROOT_INO) &&
  5490. (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
  5491. (dirent->inode > fs->super->s_inodes_count)) {
  5492. problem = PR_2_BAD_INO;
  5493. } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
  5494. dirent->inode))) {
  5495. /*
  5496. * If the inode is unused, offer to clear it.
  5497. */
  5498. problem = PR_2_UNUSED_INODE;
  5499. } else if ((dot_state > 1) &&
  5500. ((dirent->name_len & 0xFF) == 1) &&
  5501. (dirent->name[0] == '.')) {
  5502. /*
  5503. * If there's a '.' entry in anything other
  5504. * than the first directory entry, it's a
  5505. * duplicate entry that should be removed.
  5506. */
  5507. problem = PR_2_DUP_DOT;
  5508. } else if ((dot_state > 1) &&
  5509. ((dirent->name_len & 0xFF) == 2) &&
  5510. (dirent->name[0] == '.') &&
  5511. (dirent->name[1] == '.')) {
  5512. /*
  5513. * If there's a '..' entry in anything other
  5514. * than the second directory entry, it's a
  5515. * duplicate entry that should be removed.
  5516. */
  5517. problem = PR_2_DUP_DOT_DOT;
  5518. } else if ((dot_state > 1) &&
  5519. (dirent->inode == EXT2_ROOT_INO)) {
  5520. /*
  5521. * Don't allow links to the root directory.
  5522. * We check this specially to make sure we
  5523. * catch this error case even if the root
  5524. * directory hasn't been created yet.
  5525. */
  5526. problem = PR_2_LINK_ROOT;
  5527. } else if ((dot_state > 1) &&
  5528. (dirent->name_len & 0xFF) == 0) {
  5529. /*
  5530. * Don't allow zero-length directory names.
  5531. */
  5532. problem = PR_2_NULL_NAME;
  5533. }
  5534. if (problem) {
  5535. if (fix_problem(ctx, problem, &cd->pctx)) {
  5536. dirent->inode = 0;
  5537. dir_modified++;
  5538. goto next;
  5539. } else {
  5540. ext2fs_unmark_valid(fs);
  5541. if (problem == PR_2_BAD_INO)
  5542. goto next;
  5543. }
  5544. }
  5545. /*
  5546. * If the inode was marked as having bad fields in
  5547. * pass1, process it and offer to fix/clear it.
  5548. * (We wait until now so that we can display the
  5549. * pathname to the user.)
  5550. */
  5551. if (ctx->inode_bad_map &&
  5552. ext2fs_test_inode_bitmap(ctx->inode_bad_map,
  5553. dirent->inode)) {
  5554. if (e2fsck_process_bad_inode(ctx, ino,
  5555. dirent->inode,
  5556. buf + fs->blocksize)) {
  5557. dirent->inode = 0;
  5558. dir_modified++;
  5559. goto next;
  5560. }
  5561. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  5562. return DIRENT_ABORT;
  5563. }
  5564. if (check_name(ctx, dirent, &cd->pctx))
  5565. dir_modified++;
  5566. if (check_filetype(ctx, dirent, &cd->pctx))
  5567. dir_modified++;
  5568. #ifdef ENABLE_HTREE
  5569. if (dx_db) {
  5570. ext2fs_dirhash(dx_dir->hashversion, dirent->name,
  5571. (dirent->name_len & 0xFF),
  5572. fs->super->s_hash_seed, &hash, 0);
  5573. if (hash < dx_db->min_hash)
  5574. dx_db->min_hash = hash;
  5575. if (hash > dx_db->max_hash)
  5576. dx_db->max_hash = hash;
  5577. }
  5578. #endif
  5579. /*
  5580. * If this is a directory, then mark its parent in its
  5581. * dir_info structure. If the parent field is already
  5582. * filled in, then this directory has more than one
  5583. * hard link. We assume the first link is correct,
  5584. * and ask the user if he/she wants to clear this one.
  5585. */
  5586. if ((dot_state > 1) &&
  5587. (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
  5588. dirent->inode))) {
  5589. subdir = e2fsck_get_dir_info(ctx, dirent->inode);
  5590. if (!subdir) {
  5591. cd->pctx.ino = dirent->inode;
  5592. fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
  5593. goto abort_free_dict;
  5594. }
  5595. if (subdir->parent) {
  5596. cd->pctx.ino2 = subdir->parent;
  5597. if (fix_problem(ctx, PR_2_LINK_DIR,
  5598. &cd->pctx)) {
  5599. dirent->inode = 0;
  5600. dir_modified++;
  5601. goto next;
  5602. }
  5603. cd->pctx.ino2 = 0;
  5604. } else
  5605. subdir->parent = ino;
  5606. }
  5607. if (dups_found) {
  5608. ;
  5609. } else if (dict_lookup(&de_dict, dirent)) {
  5610. clear_problem_context(&pctx);
  5611. pctx.ino = ino;
  5612. pctx.dirent = dirent;
  5613. fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
  5614. if (!ctx->dirs_to_hash)
  5615. ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
  5616. if (ctx->dirs_to_hash)
  5617. ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
  5618. dups_found++;
  5619. } else
  5620. dict_alloc_insert(&de_dict, dirent, dirent);
  5621. ext2fs_icount_increment(ctx->inode_count, dirent->inode,
  5622. &links);
  5623. if (links > 1)
  5624. ctx->fs_links_count++;
  5625. ctx->fs_total_count++;
  5626. next:
  5627. prev = dirent;
  5628. offset += dirent->rec_len;
  5629. dot_state++;
  5630. } while (offset < fs->blocksize);
  5631. #ifdef ENABLE_HTREE
  5632. if (dx_db) {
  5633. cd->pctx.dir = cd->pctx.ino;
  5634. if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
  5635. (dx_db->type == DX_DIRBLOCK_NODE))
  5636. parse_int_node(fs, db, cd, dx_dir, buf);
  5637. }
  5638. #endif /* ENABLE_HTREE */
  5639. if (offset != fs->blocksize) {
  5640. cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
  5641. if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
  5642. dirent->rec_len = cd->pctx.num;
  5643. dir_modified++;
  5644. }
  5645. }
  5646. if (dir_modified) {
  5647. cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
  5648. if (cd->pctx.errcode) {
  5649. if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
  5650. &cd->pctx))
  5651. goto abort_free_dict;
  5652. }
  5653. ext2fs_mark_changed(fs);
  5654. }
  5655. dict_free_nodes(&de_dict);
  5656. return 0;
  5657. abort_free_dict:
  5658. dict_free_nodes(&de_dict);
  5659. ctx->flags |= E2F_FLAG_ABORT;
  5660. return DIRENT_ABORT;
  5661. }
  5662. /*
  5663. * This function is called to deallocate a block, and is an interator
  5664. * functioned called by deallocate inode via ext2fs_iterate_block().
  5665. */
  5666. static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr,
  5667. e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
  5668. blk_t ref_block FSCK_ATTR((unused)),
  5669. int ref_offset FSCK_ATTR((unused)),
  5670. void *priv_data)
  5671. {
  5672. e2fsck_t ctx = (e2fsck_t) priv_data;
  5673. if (HOLE_BLKADDR(*block_nr))
  5674. return 0;
  5675. if ((*block_nr < fs->super->s_first_data_block) ||
  5676. (*block_nr >= fs->super->s_blocks_count))
  5677. return 0;
  5678. ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
  5679. ext2fs_block_alloc_stats(fs, *block_nr, -1);
  5680. return 0;
  5681. }
  5682. /*
  5683. * This fuction deallocates an inode
  5684. */
  5685. static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
  5686. {
  5687. ext2_filsys fs = ctx->fs;
  5688. struct ext2_inode inode;
  5689. struct problem_context pctx;
  5690. __u32 count;
  5691. ext2fs_icount_store(ctx->inode_link_info, ino, 0);
  5692. e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
  5693. inode.i_links_count = 0;
  5694. inode.i_dtime = time(NULL);
  5695. e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
  5696. clear_problem_context(&pctx);
  5697. pctx.ino = ino;
  5698. /*
  5699. * Fix up the bitmaps...
  5700. */
  5701. e2fsck_read_bitmaps(ctx);
  5702. ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
  5703. ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
  5704. if (ctx->inode_bad_map)
  5705. ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
  5706. ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
  5707. if (inode.i_file_acl &&
  5708. (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
  5709. pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
  5710. block_buf, -1, &count);
  5711. if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
  5712. pctx.errcode = 0;
  5713. count = 1;
  5714. }
  5715. if (pctx.errcode) {
  5716. pctx.blk = inode.i_file_acl;
  5717. fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
  5718. ctx->flags |= E2F_FLAG_ABORT;
  5719. return;
  5720. }
  5721. if (count == 0) {
  5722. ext2fs_unmark_block_bitmap(ctx->block_found_map,
  5723. inode.i_file_acl);
  5724. ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
  5725. }
  5726. inode.i_file_acl = 0;
  5727. }
  5728. if (!ext2fs_inode_has_valid_blocks(&inode))
  5729. return;
  5730. if (LINUX_S_ISREG(inode.i_mode) &&
  5731. (inode.i_size_high || inode.i_size & 0x80000000UL))
  5732. ctx->large_files--;
  5733. pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
  5734. deallocate_inode_block, ctx);
  5735. if (pctx.errcode) {
  5736. fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
  5737. ctx->flags |= E2F_FLAG_ABORT;
  5738. return;
  5739. }
  5740. }
  5741. /*
  5742. * This fuction clears the htree flag on an inode
  5743. */
  5744. static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
  5745. {
  5746. struct ext2_inode inode;
  5747. e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
  5748. inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
  5749. e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
  5750. if (ctx->dirs_to_hash)
  5751. ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
  5752. }
  5753. static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
  5754. ext2_ino_t ino, char *buf)
  5755. {
  5756. ext2_filsys fs = ctx->fs;
  5757. struct ext2_inode inode;
  5758. int inode_modified = 0;
  5759. int not_fixed = 0;
  5760. unsigned char *frag, *fsize;
  5761. struct problem_context pctx;
  5762. int problem = 0;
  5763. e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
  5764. clear_problem_context(&pctx);
  5765. pctx.ino = ino;
  5766. pctx.dir = dir;
  5767. pctx.inode = &inode;
  5768. if (inode.i_file_acl &&
  5769. !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
  5770. fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
  5771. inode.i_file_acl = 0;
  5772. #if BB_BIG_ENDIAN
  5773. /*
  5774. * This is a special kludge to deal with long symlinks
  5775. * on big endian systems. i_blocks had already been
  5776. * decremented earlier in pass 1, but since i_file_acl
  5777. * hadn't yet been cleared, ext2fs_read_inode()
  5778. * assumed that the file was short symlink and would
  5779. * not have byte swapped i_block[0]. Hence, we have
  5780. * to byte-swap it here.
  5781. */
  5782. if (LINUX_S_ISLNK(inode.i_mode) &&
  5783. (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
  5784. (inode.i_blocks == fs->blocksize >> 9))
  5785. inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
  5786. #endif
  5787. inode_modified++;
  5788. } else
  5789. not_fixed++;
  5790. if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
  5791. !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
  5792. !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
  5793. !(LINUX_S_ISSOCK(inode.i_mode)))
  5794. problem = PR_2_BAD_MODE;
  5795. else if (LINUX_S_ISCHR(inode.i_mode)
  5796. && !e2fsck_pass1_check_device_inode(fs, &inode))
  5797. problem = PR_2_BAD_CHAR_DEV;
  5798. else if (LINUX_S_ISBLK(inode.i_mode)
  5799. && !e2fsck_pass1_check_device_inode(fs, &inode))
  5800. problem = PR_2_BAD_BLOCK_DEV;
  5801. else if (LINUX_S_ISFIFO(inode.i_mode)
  5802. && !e2fsck_pass1_check_device_inode(fs, &inode))
  5803. problem = PR_2_BAD_FIFO;
  5804. else if (LINUX_S_ISSOCK(inode.i_mode)
  5805. && !e2fsck_pass1_check_device_inode(fs, &inode))
  5806. problem = PR_2_BAD_SOCKET;
  5807. else if (LINUX_S_ISLNK(inode.i_mode)
  5808. && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
  5809. problem = PR_2_INVALID_SYMLINK;
  5810. }
  5811. if (problem) {
  5812. if (fix_problem(ctx, problem, &pctx)) {
  5813. deallocate_inode(ctx, ino, 0);
  5814. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  5815. return 0;
  5816. return 1;
  5817. } else
  5818. not_fixed++;
  5819. problem = 0;
  5820. }
  5821. if (inode.i_faddr) {
  5822. if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
  5823. inode.i_faddr = 0;
  5824. inode_modified++;
  5825. } else
  5826. not_fixed++;
  5827. }
  5828. switch (fs->super->s_creator_os) {
  5829. case EXT2_OS_LINUX:
  5830. frag = &inode.osd2.linux2.l_i_frag;
  5831. fsize = &inode.osd2.linux2.l_i_fsize;
  5832. break;
  5833. case EXT2_OS_HURD:
  5834. frag = &inode.osd2.hurd2.h_i_frag;
  5835. fsize = &inode.osd2.hurd2.h_i_fsize;
  5836. break;
  5837. case EXT2_OS_MASIX:
  5838. frag = &inode.osd2.masix2.m_i_frag;
  5839. fsize = &inode.osd2.masix2.m_i_fsize;
  5840. break;
  5841. default:
  5842. frag = fsize = 0;
  5843. }
  5844. if (frag && *frag) {
  5845. pctx.num = *frag;
  5846. if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
  5847. *frag = 0;
  5848. inode_modified++;
  5849. } else
  5850. not_fixed++;
  5851. pctx.num = 0;
  5852. }
  5853. if (fsize && *fsize) {
  5854. pctx.num = *fsize;
  5855. if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
  5856. *fsize = 0;
  5857. inode_modified++;
  5858. } else
  5859. not_fixed++;
  5860. pctx.num = 0;
  5861. }
  5862. if (inode.i_file_acl &&
  5863. ((inode.i_file_acl < fs->super->s_first_data_block) ||
  5864. (inode.i_file_acl >= fs->super->s_blocks_count))) {
  5865. if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
  5866. inode.i_file_acl = 0;
  5867. inode_modified++;
  5868. } else
  5869. not_fixed++;
  5870. }
  5871. if (inode.i_dir_acl &&
  5872. LINUX_S_ISDIR(inode.i_mode)) {
  5873. if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
  5874. inode.i_dir_acl = 0;
  5875. inode_modified++;
  5876. } else
  5877. not_fixed++;
  5878. }
  5879. if (inode_modified)
  5880. e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
  5881. if (!not_fixed)
  5882. ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
  5883. return 0;
  5884. }
  5885. /*
  5886. * allocate_dir_block --- this function allocates a new directory
  5887. * block for a particular inode; this is done if a directory has
  5888. * a "hole" in it, or if a directory has a illegal block number
  5889. * that was zeroed out and now needs to be replaced.
  5890. */
  5891. static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db,
  5892. struct problem_context *pctx)
  5893. {
  5894. ext2_filsys fs = ctx->fs;
  5895. blk_t blk;
  5896. char *block;
  5897. struct ext2_inode inode;
  5898. if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
  5899. return 1;
  5900. /*
  5901. * Read the inode and block bitmaps in; we'll be messing with
  5902. * them.
  5903. */
  5904. e2fsck_read_bitmaps(ctx);
  5905. /*
  5906. * First, find a free block
  5907. */
  5908. pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
  5909. if (pctx->errcode) {
  5910. pctx->str = "ext2fs_new_block";
  5911. fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
  5912. return 1;
  5913. }
  5914. ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
  5915. ext2fs_mark_block_bitmap(fs->block_map, blk);
  5916. ext2fs_mark_bb_dirty(fs);
  5917. /*
  5918. * Now let's create the actual data block for the inode
  5919. */
  5920. if (db->blockcnt)
  5921. pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
  5922. else
  5923. pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
  5924. EXT2_ROOT_INO, &block);
  5925. if (pctx->errcode) {
  5926. pctx->str = "ext2fs_new_dir_block";
  5927. fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
  5928. return 1;
  5929. }
  5930. pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
  5931. ext2fs_free_mem(&block);
  5932. if (pctx->errcode) {
  5933. pctx->str = "ext2fs_write_dir_block";
  5934. fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
  5935. return 1;
  5936. }
  5937. /*
  5938. * Update the inode block count
  5939. */
  5940. e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
  5941. inode.i_blocks += fs->blocksize / 512;
  5942. if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
  5943. inode.i_size = (db->blockcnt+1) * fs->blocksize;
  5944. e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
  5945. /*
  5946. * Finally, update the block pointers for the inode
  5947. */
  5948. db->blk = blk;
  5949. pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
  5950. 0, update_dir_block, db);
  5951. if (pctx->errcode) {
  5952. pctx->str = "ext2fs_block_iterate";
  5953. fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
  5954. return 1;
  5955. }
  5956. return 0;
  5957. }
  5958. /*
  5959. * This is a helper function for allocate_dir_block().
  5960. */
  5961. static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)),
  5962. blk_t *block_nr,
  5963. e2_blkcnt_t blockcnt,
  5964. blk_t ref_block FSCK_ATTR((unused)),
  5965. int ref_offset FSCK_ATTR((unused)),
  5966. void *priv_data)
  5967. {
  5968. struct ext2_db_entry *db;
  5969. db = (struct ext2_db_entry *) priv_data;
  5970. if (db->blockcnt == (int) blockcnt) {
  5971. *block_nr = db->blk;
  5972. return BLOCK_CHANGED;
  5973. }
  5974. return 0;
  5975. }
  5976. /*
  5977. * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
  5978. *
  5979. * Pass #3 assures that all directories are connected to the
  5980. * filesystem tree, using the following algorithm:
  5981. *
  5982. * First, the root directory is checked to make sure it exists; if
  5983. * not, e2fsck will offer to create a new one. It is then marked as
  5984. * "done".
  5985. *
  5986. * Then, pass3 interates over all directory inodes; for each directory
  5987. * it attempts to trace up the filesystem tree, using dirinfo.parent
  5988. * until it reaches a directory which has been marked "done". If it
  5989. * cannot do so, then the directory must be disconnected, and e2fsck
  5990. * will offer to reconnect it to /lost+found. While it is chasing
  5991. * parent pointers up the filesystem tree, if pass3 sees a directory
  5992. * twice, then it has detected a filesystem loop, and it will again
  5993. * offer to reconnect the directory to /lost+found in to break the
  5994. * filesystem loop.
  5995. *
  5996. * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
  5997. * reconnect inodes to /lost+found; this subroutine is also used by
  5998. * pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which
  5999. * is responsible for creating /lost+found if it does not exist.
  6000. *
  6001. * Pass 3 frees the following data structures:
  6002. * - The dirinfo directory information cache.
  6003. */
  6004. static void check_root(e2fsck_t ctx);
  6005. static int check_directory(e2fsck_t ctx, struct dir_info *dir,
  6006. struct problem_context *pctx);
  6007. static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
  6008. static ext2fs_inode_bitmap inode_loop_detect;
  6009. static ext2fs_inode_bitmap inode_done_map;
  6010. static void e2fsck_pass3(e2fsck_t ctx)
  6011. {
  6012. ext2_filsys fs = ctx->fs;
  6013. int i;
  6014. struct problem_context pctx;
  6015. struct dir_info *dir;
  6016. unsigned long maxdirs, count;
  6017. clear_problem_context(&pctx);
  6018. /* Pass 3 */
  6019. if (!(ctx->options & E2F_OPT_PREEN))
  6020. fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
  6021. /*
  6022. * Allocate some bitmaps to do loop detection.
  6023. */
  6024. pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
  6025. &inode_done_map);
  6026. if (pctx.errcode) {
  6027. pctx.num = 2;
  6028. fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
  6029. ctx->flags |= E2F_FLAG_ABORT;
  6030. goto abort_exit;
  6031. }
  6032. check_root(ctx);
  6033. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  6034. goto abort_exit;
  6035. ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
  6036. maxdirs = e2fsck_get_num_dirinfo(ctx);
  6037. count = 1;
  6038. if (ctx->progress)
  6039. if ((ctx->progress)(ctx, 3, 0, maxdirs))
  6040. goto abort_exit;
  6041. for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
  6042. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  6043. goto abort_exit;
  6044. if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
  6045. goto abort_exit;
  6046. if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
  6047. if (check_directory(ctx, dir, &pctx))
  6048. goto abort_exit;
  6049. }
  6050. /*
  6051. * Force the creation of /lost+found if not present
  6052. */
  6053. if ((ctx->flags & E2F_OPT_READONLY) == 0)
  6054. e2fsck_get_lost_and_found(ctx, 1);
  6055. /*
  6056. * If there are any directories that need to be indexed or
  6057. * optimized, do it here.
  6058. */
  6059. e2fsck_rehash_directories(ctx);
  6060. abort_exit:
  6061. e2fsck_free_dir_info(ctx);
  6062. ext2fs_free_inode_bitmap(inode_loop_detect);
  6063. inode_loop_detect = 0;
  6064. ext2fs_free_inode_bitmap(inode_done_map);
  6065. inode_done_map = 0;
  6066. }
  6067. /*
  6068. * This makes sure the root inode is present; if not, we ask if the
  6069. * user wants us to create it. Not creating it is a fatal error.
  6070. */
  6071. static void check_root(e2fsck_t ctx)
  6072. {
  6073. ext2_filsys fs = ctx->fs;
  6074. blk_t blk;
  6075. struct ext2_inode inode;
  6076. char * block;
  6077. struct problem_context pctx;
  6078. clear_problem_context(&pctx);
  6079. if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
  6080. /*
  6081. * If the root inode is not a directory, die here. The
  6082. * user must have answered 'no' in pass1 when we
  6083. * offered to clear it.
  6084. */
  6085. if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
  6086. EXT2_ROOT_INO))) {
  6087. fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
  6088. ctx->flags |= E2F_FLAG_ABORT;
  6089. }
  6090. return;
  6091. }
  6092. if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
  6093. fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
  6094. ctx->flags |= E2F_FLAG_ABORT;
  6095. return;
  6096. }
  6097. e2fsck_read_bitmaps(ctx);
  6098. /*
  6099. * First, find a free block
  6100. */
  6101. pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
  6102. if (pctx.errcode) {
  6103. pctx.str = "ext2fs_new_block";
  6104. fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
  6105. ctx->flags |= E2F_FLAG_ABORT;
  6106. return;
  6107. }
  6108. ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
  6109. ext2fs_mark_block_bitmap(fs->block_map, blk);
  6110. ext2fs_mark_bb_dirty(fs);
  6111. /*
  6112. * Now let's create the actual data block for the inode
  6113. */
  6114. pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
  6115. &block);
  6116. if (pctx.errcode) {
  6117. pctx.str = "ext2fs_new_dir_block";
  6118. fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
  6119. ctx->flags |= E2F_FLAG_ABORT;
  6120. return;
  6121. }
  6122. pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
  6123. if (pctx.errcode) {
  6124. pctx.str = "ext2fs_write_dir_block";
  6125. fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
  6126. ctx->flags |= E2F_FLAG_ABORT;
  6127. return;
  6128. }
  6129. ext2fs_free_mem(&block);
  6130. /*
  6131. * Set up the inode structure
  6132. */
  6133. memset(&inode, 0, sizeof(inode));
  6134. inode.i_mode = 040755;
  6135. inode.i_size = fs->blocksize;
  6136. inode.i_atime = inode.i_ctime = inode.i_mtime = time(NULL);
  6137. inode.i_links_count = 2;
  6138. inode.i_blocks = fs->blocksize / 512;
  6139. inode.i_block[0] = blk;
  6140. /*
  6141. * Write out the inode.
  6142. */
  6143. pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
  6144. if (pctx.errcode) {
  6145. pctx.str = "ext2fs_write_inode";
  6146. fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
  6147. ctx->flags |= E2F_FLAG_ABORT;
  6148. return;
  6149. }
  6150. /*
  6151. * Miscellaneous bookkeeping...
  6152. */
  6153. e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
  6154. ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
  6155. ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
  6156. ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
  6157. ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
  6158. ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
  6159. ext2fs_mark_ib_dirty(fs);
  6160. }
  6161. /*
  6162. * This subroutine is responsible for making sure that a particular
  6163. * directory is connected to the root; if it isn't we trace it up as
  6164. * far as we can go, and then offer to connect the resulting parent to
  6165. * the lost+found. We have to do loop detection; if we ever discover
  6166. * a loop, we treat that as a disconnected directory and offer to
  6167. * reparent it to lost+found.
  6168. *
  6169. * However, loop detection is expensive, because for very large
  6170. * filesystems, the inode_loop_detect bitmap is huge, and clearing it
  6171. * is non-trivial. Loops in filesystems are also a rare error case,
  6172. * and we shouldn't optimize for error cases. So we try two passes of
  6173. * the algorithm. The first time, we ignore loop detection and merely
  6174. * increment a counter; if the counter exceeds some extreme threshold,
  6175. * then we try again with the loop detection bitmap enabled.
  6176. */
  6177. static int check_directory(e2fsck_t ctx, struct dir_info *dir,
  6178. struct problem_context *pctx)
  6179. {
  6180. ext2_filsys fs = ctx->fs;
  6181. struct dir_info *p = dir;
  6182. int loop_pass = 0, parent_count = 0;
  6183. if (!p)
  6184. return 0;
  6185. while (1) {
  6186. /*
  6187. * Mark this inode as being "done"; by the time we
  6188. * return from this function, the inode we either be
  6189. * verified as being connected to the directory tree,
  6190. * or we will have offered to reconnect this to
  6191. * lost+found.
  6192. *
  6193. * If it was marked done already, then we've reached a
  6194. * parent we've already checked.
  6195. */
  6196. if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
  6197. break;
  6198. /*
  6199. * If this directory doesn't have a parent, or we've
  6200. * seen the parent once already, then offer to
  6201. * reparent it to lost+found
  6202. */
  6203. if (!p->parent ||
  6204. (loop_pass &&
  6205. (ext2fs_test_inode_bitmap(inode_loop_detect,
  6206. p->parent)))) {
  6207. pctx->ino = p->ino;
  6208. if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
  6209. if (e2fsck_reconnect_file(ctx, pctx->ino))
  6210. ext2fs_unmark_valid(fs);
  6211. else {
  6212. p = e2fsck_get_dir_info(ctx, pctx->ino);
  6213. p->parent = ctx->lost_and_found;
  6214. fix_dotdot(ctx, p, ctx->lost_and_found);
  6215. }
  6216. }
  6217. break;
  6218. }
  6219. p = e2fsck_get_dir_info(ctx, p->parent);
  6220. if (!p) {
  6221. fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
  6222. return 0;
  6223. }
  6224. if (loop_pass) {
  6225. ext2fs_mark_inode_bitmap(inode_loop_detect,
  6226. p->ino);
  6227. } else if (parent_count++ > 2048) {
  6228. /*
  6229. * If we've run into a path depth that's
  6230. * greater than 2048, try again with the inode
  6231. * loop bitmap turned on and start from the
  6232. * top.
  6233. */
  6234. loop_pass = 1;
  6235. if (inode_loop_detect)
  6236. ext2fs_clear_inode_bitmap(inode_loop_detect);
  6237. else {
  6238. pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
  6239. if (pctx->errcode) {
  6240. pctx->num = 1;
  6241. fix_problem(ctx,
  6242. PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
  6243. ctx->flags |= E2F_FLAG_ABORT;
  6244. return -1;
  6245. }
  6246. }
  6247. p = dir;
  6248. }
  6249. }
  6250. /*
  6251. * Make sure that .. and the parent directory are the same;
  6252. * offer to fix it if not.
  6253. */
  6254. if (dir->parent != dir->dotdot) {
  6255. pctx->ino = dir->ino;
  6256. pctx->ino2 = dir->dotdot;
  6257. pctx->dir = dir->parent;
  6258. if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
  6259. fix_dotdot(ctx, dir, dir->parent);
  6260. }
  6261. return 0;
  6262. }
  6263. /*
  6264. * This routine gets the lost_and_found inode, making it a directory
  6265. * if necessary
  6266. */
  6267. ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
  6268. {
  6269. ext2_filsys fs = ctx->fs;
  6270. ext2_ino_t ino;
  6271. blk_t blk;
  6272. errcode_t retval;
  6273. struct ext2_inode inode;
  6274. char * block;
  6275. static const char name[] = "lost+found";
  6276. struct problem_context pctx;
  6277. struct dir_info *dirinfo;
  6278. if (ctx->lost_and_found)
  6279. return ctx->lost_and_found;
  6280. clear_problem_context(&pctx);
  6281. retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
  6282. sizeof(name)-1, 0, &ino);
  6283. if (retval && !fix)
  6284. return 0;
  6285. if (!retval) {
  6286. if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
  6287. ctx->lost_and_found = ino;
  6288. return ino;
  6289. }
  6290. /* Lost+found isn't a directory! */
  6291. if (!fix)
  6292. return 0;
  6293. pctx.ino = ino;
  6294. if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
  6295. return 0;
  6296. /* OK, unlink the old /lost+found file. */
  6297. pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
  6298. if (pctx.errcode) {
  6299. pctx.str = "ext2fs_unlink";
  6300. fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
  6301. return 0;
  6302. }
  6303. dirinfo = e2fsck_get_dir_info(ctx, ino);
  6304. if (dirinfo)
  6305. dirinfo->parent = 0;
  6306. e2fsck_adjust_inode_count(ctx, ino, -1);
  6307. } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
  6308. pctx.errcode = retval;
  6309. fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
  6310. }
  6311. if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
  6312. return 0;
  6313. /*
  6314. * Read the inode and block bitmaps in; we'll be messing with
  6315. * them.
  6316. */
  6317. e2fsck_read_bitmaps(ctx);
  6318. /*
  6319. * First, find a free block
  6320. */
  6321. retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
  6322. if (retval) {
  6323. pctx.errcode = retval;
  6324. fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
  6325. return 0;
  6326. }
  6327. ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
  6328. ext2fs_block_alloc_stats(fs, blk, +1);
  6329. /*
  6330. * Next find a free inode.
  6331. */
  6332. retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
  6333. ctx->inode_used_map, &ino);
  6334. if (retval) {
  6335. pctx.errcode = retval;
  6336. fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
  6337. return 0;
  6338. }
  6339. ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
  6340. ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
  6341. ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
  6342. /*
  6343. * Now let's create the actual data block for the inode
  6344. */
  6345. retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
  6346. if (retval) {
  6347. pctx.errcode = retval;
  6348. fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
  6349. return 0;
  6350. }
  6351. retval = ext2fs_write_dir_block(fs, blk, block);
  6352. ext2fs_free_mem(&block);
  6353. if (retval) {
  6354. pctx.errcode = retval;
  6355. fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
  6356. return 0;
  6357. }
  6358. /*
  6359. * Set up the inode structure
  6360. */
  6361. memset(&inode, 0, sizeof(inode));
  6362. inode.i_mode = 040700;
  6363. inode.i_size = fs->blocksize;
  6364. inode.i_atime = inode.i_ctime = inode.i_mtime = time(NULL);
  6365. inode.i_links_count = 2;
  6366. inode.i_blocks = fs->blocksize / 512;
  6367. inode.i_block[0] = blk;
  6368. /*
  6369. * Next, write out the inode.
  6370. */
  6371. pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
  6372. if (pctx.errcode) {
  6373. pctx.str = "ext2fs_write_inode";
  6374. fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
  6375. return 0;
  6376. }
  6377. /*
  6378. * Finally, create the directory link
  6379. */
  6380. pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
  6381. if (pctx.errcode) {
  6382. pctx.str = "ext2fs_link";
  6383. fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
  6384. return 0;
  6385. }
  6386. /*
  6387. * Miscellaneous bookkeeping that needs to be kept straight.
  6388. */
  6389. e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
  6390. e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
  6391. ext2fs_icount_store(ctx->inode_count, ino, 2);
  6392. ext2fs_icount_store(ctx->inode_link_info, ino, 2);
  6393. ctx->lost_and_found = ino;
  6394. return ino;
  6395. }
  6396. /*
  6397. * This routine will connect a file to lost+found
  6398. */
  6399. int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
  6400. {
  6401. ext2_filsys fs = ctx->fs;
  6402. errcode_t retval;
  6403. char name[80];
  6404. struct problem_context pctx;
  6405. struct ext2_inode inode;
  6406. int file_type = 0;
  6407. clear_problem_context(&pctx);
  6408. pctx.ino = ino;
  6409. if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
  6410. if (e2fsck_get_lost_and_found(ctx, 1) == 0)
  6411. ctx->bad_lost_and_found++;
  6412. }
  6413. if (ctx->bad_lost_and_found) {
  6414. fix_problem(ctx, PR_3_NO_LPF, &pctx);
  6415. return 1;
  6416. }
  6417. sprintf(name, "#%u", ino);
  6418. if (ext2fs_read_inode(fs, ino, &inode) == 0)
  6419. file_type = ext2_file_type(inode.i_mode);
  6420. retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
  6421. if (retval == EXT2_ET_DIR_NO_SPACE) {
  6422. if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
  6423. return 1;
  6424. retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
  6425. 1, 0);
  6426. if (retval) {
  6427. pctx.errcode = retval;
  6428. fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
  6429. return 1;
  6430. }
  6431. retval = ext2fs_link(fs, ctx->lost_and_found, name,
  6432. ino, file_type);
  6433. }
  6434. if (retval) {
  6435. pctx.errcode = retval;
  6436. fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
  6437. return 1;
  6438. }
  6439. e2fsck_adjust_inode_count(ctx, ino, 1);
  6440. return 0;
  6441. }
  6442. /*
  6443. * Utility routine to adjust the inode counts on an inode.
  6444. */
  6445. errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
  6446. {
  6447. ext2_filsys fs = ctx->fs;
  6448. errcode_t retval;
  6449. struct ext2_inode inode;
  6450. if (!ino)
  6451. return 0;
  6452. retval = ext2fs_read_inode(fs, ino, &inode);
  6453. if (retval)
  6454. return retval;
  6455. if (adj == 1) {
  6456. ext2fs_icount_increment(ctx->inode_count, ino, 0);
  6457. if (inode.i_links_count == (__u16) ~0)
  6458. return 0;
  6459. ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
  6460. inode.i_links_count++;
  6461. } else if (adj == -1) {
  6462. ext2fs_icount_decrement(ctx->inode_count, ino, 0);
  6463. if (inode.i_links_count == 0)
  6464. return 0;
  6465. ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
  6466. inode.i_links_count--;
  6467. }
  6468. retval = ext2fs_write_inode(fs, ino, &inode);
  6469. if (retval)
  6470. return retval;
  6471. return 0;
  6472. }
  6473. /*
  6474. * Fix parent --- this routine fixes up the parent of a directory.
  6475. */
  6476. struct fix_dotdot_struct {
  6477. ext2_filsys fs;
  6478. ext2_ino_t parent;
  6479. int done;
  6480. e2fsck_t ctx;
  6481. };
  6482. static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
  6483. int offset FSCK_ATTR((unused)),
  6484. int blocksize FSCK_ATTR((unused)),
  6485. char *buf FSCK_ATTR((unused)),
  6486. void *priv_data)
  6487. {
  6488. struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
  6489. errcode_t retval;
  6490. struct problem_context pctx;
  6491. if ((dirent->name_len & 0xFF) != 2)
  6492. return 0;
  6493. if (strncmp(dirent->name, "..", 2))
  6494. return 0;
  6495. clear_problem_context(&pctx);
  6496. retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
  6497. if (retval) {
  6498. pctx.errcode = retval;
  6499. fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
  6500. }
  6501. retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
  6502. if (retval) {
  6503. pctx.errcode = retval;
  6504. fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
  6505. }
  6506. dirent->inode = fp->parent;
  6507. fp->done++;
  6508. return DIRENT_ABORT | DIRENT_CHANGED;
  6509. }
  6510. static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
  6511. {
  6512. ext2_filsys fs = ctx->fs;
  6513. errcode_t retval;
  6514. struct fix_dotdot_struct fp;
  6515. struct problem_context pctx;
  6516. fp.fs = fs;
  6517. fp.parent = parent;
  6518. fp.done = 0;
  6519. fp.ctx = ctx;
  6520. retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
  6521. 0, fix_dotdot_proc, &fp);
  6522. if (retval || !fp.done) {
  6523. clear_problem_context(&pctx);
  6524. pctx.ino = dir->ino;
  6525. pctx.errcode = retval;
  6526. fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
  6527. PR_3_FIX_PARENT_NOFIND, &pctx);
  6528. ext2fs_unmark_valid(fs);
  6529. }
  6530. dir->dotdot = parent;
  6531. }
  6532. /*
  6533. * These routines are responsible for expanding a /lost+found if it is
  6534. * too small.
  6535. */
  6536. struct expand_dir_struct {
  6537. int num;
  6538. int guaranteed_size;
  6539. int newblocks;
  6540. int last_block;
  6541. errcode_t err;
  6542. e2fsck_t ctx;
  6543. };
  6544. static int expand_dir_proc(ext2_filsys fs,
  6545. blk_t *blocknr,
  6546. e2_blkcnt_t blockcnt,
  6547. blk_t ref_block FSCK_ATTR((unused)),
  6548. int ref_offset FSCK_ATTR((unused)),
  6549. void *priv_data)
  6550. {
  6551. struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
  6552. blk_t new_blk;
  6553. static blk_t last_blk = 0;
  6554. char *block;
  6555. errcode_t retval;
  6556. e2fsck_t ctx;
  6557. ctx = es->ctx;
  6558. if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
  6559. return BLOCK_ABORT;
  6560. if (blockcnt > 0)
  6561. es->last_block = blockcnt;
  6562. if (*blocknr) {
  6563. last_blk = *blocknr;
  6564. return 0;
  6565. }
  6566. retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
  6567. &new_blk);
  6568. if (retval) {
  6569. es->err = retval;
  6570. return BLOCK_ABORT;
  6571. }
  6572. if (blockcnt > 0) {
  6573. retval = ext2fs_new_dir_block(fs, 0, 0, &block);
  6574. if (retval) {
  6575. es->err = retval;
  6576. return BLOCK_ABORT;
  6577. }
  6578. es->num--;
  6579. retval = ext2fs_write_dir_block(fs, new_blk, block);
  6580. } else {
  6581. retval = ext2fs_get_mem(fs->blocksize, &block);
  6582. if (retval) {
  6583. es->err = retval;
  6584. return BLOCK_ABORT;
  6585. }
  6586. memset(block, 0, fs->blocksize);
  6587. retval = io_channel_write_blk(fs->io, new_blk, 1, block);
  6588. }
  6589. if (retval) {
  6590. es->err = retval;
  6591. return BLOCK_ABORT;
  6592. }
  6593. ext2fs_free_mem(&block);
  6594. *blocknr = new_blk;
  6595. ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
  6596. ext2fs_block_alloc_stats(fs, new_blk, +1);
  6597. es->newblocks++;
  6598. if (es->num == 0)
  6599. return (BLOCK_CHANGED | BLOCK_ABORT);
  6600. else
  6601. return BLOCK_CHANGED;
  6602. }
  6603. errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
  6604. int num, int guaranteed_size)
  6605. {
  6606. ext2_filsys fs = ctx->fs;
  6607. errcode_t retval;
  6608. struct expand_dir_struct es;
  6609. struct ext2_inode inode;
  6610. if (!(fs->flags & EXT2_FLAG_RW))
  6611. return EXT2_ET_RO_FILSYS;
  6612. /*
  6613. * Read the inode and block bitmaps in; we'll be messing with
  6614. * them.
  6615. */
  6616. e2fsck_read_bitmaps(ctx);
  6617. retval = ext2fs_check_directory(fs, dir);
  6618. if (retval)
  6619. return retval;
  6620. es.num = num;
  6621. es.guaranteed_size = guaranteed_size;
  6622. es.last_block = 0;
  6623. es.err = 0;
  6624. es.newblocks = 0;
  6625. es.ctx = ctx;
  6626. retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
  6627. 0, expand_dir_proc, &es);
  6628. if (es.err)
  6629. return es.err;
  6630. /*
  6631. * Update the size and block count fields in the inode.
  6632. */
  6633. retval = ext2fs_read_inode(fs, dir, &inode);
  6634. if (retval)
  6635. return retval;
  6636. inode.i_size = (es.last_block + 1) * fs->blocksize;
  6637. inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
  6638. e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
  6639. return 0;
  6640. }
  6641. /*
  6642. * pass4.c -- pass #4 of e2fsck: Check reference counts
  6643. *
  6644. * Pass 4 frees the following data structures:
  6645. * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
  6646. */
  6647. /*
  6648. * This routine is called when an inode is not connected to the
  6649. * directory tree.
  6650. *
  6651. * This subroutine returns 1 then the caller shouldn't bother with the
  6652. * rest of the pass 4 tests.
  6653. */
  6654. static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
  6655. {
  6656. ext2_filsys fs = ctx->fs;
  6657. struct ext2_inode inode;
  6658. struct problem_context pctx;
  6659. e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
  6660. clear_problem_context(&pctx);
  6661. pctx.ino = i;
  6662. pctx.inode = &inode;
  6663. /*
  6664. * Offer to delete any zero-length files that does not have
  6665. * blocks. If there is an EA block, it might have useful
  6666. * information, so we won't prompt to delete it, but let it be
  6667. * reconnected to lost+found.
  6668. */
  6669. if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
  6670. LINUX_S_ISDIR(inode.i_mode))) {
  6671. if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
  6672. ext2fs_icount_store(ctx->inode_link_info, i, 0);
  6673. inode.i_links_count = 0;
  6674. inode.i_dtime = time(NULL);
  6675. e2fsck_write_inode(ctx, i, &inode,
  6676. "disconnect_inode");
  6677. /*
  6678. * Fix up the bitmaps...
  6679. */
  6680. e2fsck_read_bitmaps(ctx);
  6681. ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
  6682. ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
  6683. ext2fs_inode_alloc_stats2(fs, i, -1,
  6684. LINUX_S_ISDIR(inode.i_mode));
  6685. return 0;
  6686. }
  6687. }
  6688. /*
  6689. * Prompt to reconnect.
  6690. */
  6691. if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
  6692. if (e2fsck_reconnect_file(ctx, i))
  6693. ext2fs_unmark_valid(fs);
  6694. } else {
  6695. /*
  6696. * If we don't attach the inode, then skip the
  6697. * i_links_test since there's no point in trying to
  6698. * force i_links_count to zero.
  6699. */
  6700. ext2fs_unmark_valid(fs);
  6701. return 1;
  6702. }
  6703. return 0;
  6704. }
  6705. static void e2fsck_pass4(e2fsck_t ctx)
  6706. {
  6707. ext2_filsys fs = ctx->fs;
  6708. ext2_ino_t i;
  6709. struct ext2_inode inode;
  6710. struct problem_context pctx;
  6711. __u16 link_count, link_counted;
  6712. char *buf = NULL;
  6713. int group, maxgroup;
  6714. /* Pass 4 */
  6715. clear_problem_context(&pctx);
  6716. if (!(ctx->options & E2F_OPT_PREEN))
  6717. fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
  6718. group = 0;
  6719. maxgroup = fs->group_desc_count;
  6720. if (ctx->progress)
  6721. if ((ctx->progress)(ctx, 4, 0, maxgroup))
  6722. return;
  6723. for (i=1; i <= fs->super->s_inodes_count; i++) {
  6724. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  6725. return;
  6726. if ((i % fs->super->s_inodes_per_group) == 0) {
  6727. group++;
  6728. if (ctx->progress)
  6729. if ((ctx->progress)(ctx, 4, group, maxgroup))
  6730. return;
  6731. }
  6732. if (i == EXT2_BAD_INO ||
  6733. (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
  6734. continue;
  6735. if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
  6736. (ctx->inode_imagic_map &&
  6737. ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)))
  6738. continue;
  6739. ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
  6740. ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
  6741. if (link_counted == 0) {
  6742. if (!buf)
  6743. buf = e2fsck_allocate_memory(ctx,
  6744. fs->blocksize, "bad_inode buffer");
  6745. if (e2fsck_process_bad_inode(ctx, 0, i, buf))
  6746. continue;
  6747. if (disconnect_inode(ctx, i))
  6748. continue;
  6749. ext2fs_icount_fetch(ctx->inode_link_info, i,
  6750. &link_count);
  6751. ext2fs_icount_fetch(ctx->inode_count, i,
  6752. &link_counted);
  6753. }
  6754. if (link_counted != link_count) {
  6755. e2fsck_read_inode(ctx, i, &inode, "pass4");
  6756. pctx.ino = i;
  6757. pctx.inode = &inode;
  6758. if (link_count != inode.i_links_count) {
  6759. pctx.num = link_count;
  6760. fix_problem(ctx,
  6761. PR_4_INCONSISTENT_COUNT, &pctx);
  6762. }
  6763. pctx.num = link_counted;
  6764. if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
  6765. inode.i_links_count = link_counted;
  6766. e2fsck_write_inode(ctx, i, &inode, "pass4");
  6767. }
  6768. }
  6769. }
  6770. ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
  6771. ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
  6772. ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
  6773. ctx->inode_imagic_map = 0;
  6774. ext2fs_free_mem(&buf);
  6775. }
  6776. /*
  6777. * pass5.c --- check block and inode bitmaps against on-disk bitmaps
  6778. */
  6779. #define NO_BLK ((blk_t) -1)
  6780. static void print_bitmap_problem(e2fsck_t ctx, int problem,
  6781. struct problem_context *pctx)
  6782. {
  6783. switch (problem) {
  6784. case PR_5_BLOCK_UNUSED:
  6785. if (pctx->blk == pctx->blk2)
  6786. pctx->blk2 = 0;
  6787. else
  6788. problem = PR_5_BLOCK_RANGE_UNUSED;
  6789. break;
  6790. case PR_5_BLOCK_USED:
  6791. if (pctx->blk == pctx->blk2)
  6792. pctx->blk2 = 0;
  6793. else
  6794. problem = PR_5_BLOCK_RANGE_USED;
  6795. break;
  6796. case PR_5_INODE_UNUSED:
  6797. if (pctx->ino == pctx->ino2)
  6798. pctx->ino2 = 0;
  6799. else
  6800. problem = PR_5_INODE_RANGE_UNUSED;
  6801. break;
  6802. case PR_5_INODE_USED:
  6803. if (pctx->ino == pctx->ino2)
  6804. pctx->ino2 = 0;
  6805. else
  6806. problem = PR_5_INODE_RANGE_USED;
  6807. break;
  6808. }
  6809. fix_problem(ctx, problem, pctx);
  6810. pctx->blk = pctx->blk2 = NO_BLK;
  6811. pctx->ino = pctx->ino2 = 0;
  6812. }
  6813. static void check_block_bitmaps(e2fsck_t ctx)
  6814. {
  6815. ext2_filsys fs = ctx->fs;
  6816. blk_t i;
  6817. int *free_array;
  6818. int group = 0;
  6819. unsigned int blocks = 0;
  6820. unsigned int free_blocks = 0;
  6821. int group_free = 0;
  6822. int actual, bitmap;
  6823. struct problem_context pctx;
  6824. int problem, save_problem, fixit, had_problem;
  6825. errcode_t retval;
  6826. clear_problem_context(&pctx);
  6827. free_array = (int *) e2fsck_allocate_memory(ctx,
  6828. fs->group_desc_count * sizeof(int), "free block count array");
  6829. if ((fs->super->s_first_data_block <
  6830. ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
  6831. (fs->super->s_blocks_count-1 >
  6832. ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
  6833. pctx.num = 1;
  6834. pctx.blk = fs->super->s_first_data_block;
  6835. pctx.blk2 = fs->super->s_blocks_count -1;
  6836. pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
  6837. pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
  6838. fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
  6839. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  6840. return;
  6841. }
  6842. if ((fs->super->s_first_data_block <
  6843. ext2fs_get_block_bitmap_start(fs->block_map)) ||
  6844. (fs->super->s_blocks_count-1 >
  6845. ext2fs_get_block_bitmap_end(fs->block_map))) {
  6846. pctx.num = 2;
  6847. pctx.blk = fs->super->s_first_data_block;
  6848. pctx.blk2 = fs->super->s_blocks_count -1;
  6849. pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
  6850. pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
  6851. fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
  6852. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  6853. return;
  6854. }
  6855. redo_counts:
  6856. had_problem = 0;
  6857. save_problem = 0;
  6858. pctx.blk = pctx.blk2 = NO_BLK;
  6859. for (i = fs->super->s_first_data_block;
  6860. i < fs->super->s_blocks_count;
  6861. i++) {
  6862. actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
  6863. bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
  6864. if (actual == bitmap)
  6865. goto do_counts;
  6866. if (!actual && bitmap) {
  6867. /*
  6868. * Block not used, but marked in use in the bitmap.
  6869. */
  6870. problem = PR_5_BLOCK_UNUSED;
  6871. } else {
  6872. /*
  6873. * Block used, but not marked in use in the bitmap.
  6874. */
  6875. problem = PR_5_BLOCK_USED;
  6876. }
  6877. if (pctx.blk == NO_BLK) {
  6878. pctx.blk = pctx.blk2 = i;
  6879. save_problem = problem;
  6880. } else {
  6881. if ((problem == save_problem) &&
  6882. (pctx.blk2 == i-1))
  6883. pctx.blk2++;
  6884. else {
  6885. print_bitmap_problem(ctx, save_problem, &pctx);
  6886. pctx.blk = pctx.blk2 = i;
  6887. save_problem = problem;
  6888. }
  6889. }
  6890. ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
  6891. had_problem++;
  6892. do_counts:
  6893. if (!bitmap) {
  6894. group_free++;
  6895. free_blocks++;
  6896. }
  6897. blocks ++;
  6898. if ((blocks == fs->super->s_blocks_per_group) ||
  6899. (i == fs->super->s_blocks_count-1)) {
  6900. free_array[group] = group_free;
  6901. group ++;
  6902. blocks = 0;
  6903. group_free = 0;
  6904. if (ctx->progress)
  6905. if ((ctx->progress)(ctx, 5, group,
  6906. fs->group_desc_count*2))
  6907. return;
  6908. }
  6909. }
  6910. if (pctx.blk != NO_BLK)
  6911. print_bitmap_problem(ctx, save_problem, &pctx);
  6912. if (had_problem)
  6913. fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
  6914. else
  6915. fixit = -1;
  6916. ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
  6917. if (fixit == 1) {
  6918. ext2fs_free_block_bitmap(fs->block_map);
  6919. retval = ext2fs_copy_bitmap(ctx->block_found_map,
  6920. &fs->block_map);
  6921. if (retval) {
  6922. clear_problem_context(&pctx);
  6923. fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
  6924. ctx->flags |= E2F_FLAG_ABORT;
  6925. return;
  6926. }
  6927. ext2fs_set_bitmap_padding(fs->block_map);
  6928. ext2fs_mark_bb_dirty(fs);
  6929. /* Redo the counts */
  6930. blocks = 0; free_blocks = 0; group_free = 0; group = 0;
  6931. memset(free_array, 0, fs->group_desc_count * sizeof(int));
  6932. goto redo_counts;
  6933. } else if (fixit == 0)
  6934. ext2fs_unmark_valid(fs);
  6935. for (i = 0; i < fs->group_desc_count; i++) {
  6936. if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
  6937. pctx.group = i;
  6938. pctx.blk = fs->group_desc[i].bg_free_blocks_count;
  6939. pctx.blk2 = free_array[i];
  6940. if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
  6941. &pctx)) {
  6942. fs->group_desc[i].bg_free_blocks_count =
  6943. free_array[i];
  6944. ext2fs_mark_super_dirty(fs);
  6945. } else
  6946. ext2fs_unmark_valid(fs);
  6947. }
  6948. }
  6949. if (free_blocks != fs->super->s_free_blocks_count) {
  6950. pctx.group = 0;
  6951. pctx.blk = fs->super->s_free_blocks_count;
  6952. pctx.blk2 = free_blocks;
  6953. if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
  6954. fs->super->s_free_blocks_count = free_blocks;
  6955. ext2fs_mark_super_dirty(fs);
  6956. } else
  6957. ext2fs_unmark_valid(fs);
  6958. }
  6959. ext2fs_free_mem(&free_array);
  6960. }
  6961. static void check_inode_bitmaps(e2fsck_t ctx)
  6962. {
  6963. ext2_filsys fs = ctx->fs;
  6964. ext2_ino_t i;
  6965. unsigned int free_inodes = 0;
  6966. int group_free = 0;
  6967. int dirs_count = 0;
  6968. int group = 0;
  6969. unsigned int inodes = 0;
  6970. int *free_array;
  6971. int *dir_array;
  6972. int actual, bitmap;
  6973. errcode_t retval;
  6974. struct problem_context pctx;
  6975. int problem, save_problem, fixit, had_problem;
  6976. clear_problem_context(&pctx);
  6977. free_array = (int *) e2fsck_allocate_memory(ctx,
  6978. fs->group_desc_count * sizeof(int), "free inode count array");
  6979. dir_array = (int *) e2fsck_allocate_memory(ctx,
  6980. fs->group_desc_count * sizeof(int), "directory count array");
  6981. if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
  6982. (fs->super->s_inodes_count >
  6983. ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
  6984. pctx.num = 3;
  6985. pctx.blk = 1;
  6986. pctx.blk2 = fs->super->s_inodes_count;
  6987. pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
  6988. pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
  6989. fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
  6990. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  6991. return;
  6992. }
  6993. if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
  6994. (fs->super->s_inodes_count >
  6995. ext2fs_get_inode_bitmap_end(fs->inode_map))) {
  6996. pctx.num = 4;
  6997. pctx.blk = 1;
  6998. pctx.blk2 = fs->super->s_inodes_count;
  6999. pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
  7000. pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
  7001. fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
  7002. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  7003. return;
  7004. }
  7005. redo_counts:
  7006. had_problem = 0;
  7007. save_problem = 0;
  7008. pctx.ino = pctx.ino2 = 0;
  7009. for (i = 1; i <= fs->super->s_inodes_count; i++) {
  7010. actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
  7011. bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
  7012. if (actual == bitmap)
  7013. goto do_counts;
  7014. if (!actual && bitmap) {
  7015. /*
  7016. * Inode wasn't used, but marked in bitmap
  7017. */
  7018. problem = PR_5_INODE_UNUSED;
  7019. } else /* if (actual && !bitmap) */ {
  7020. /*
  7021. * Inode used, but not in bitmap
  7022. */
  7023. problem = PR_5_INODE_USED;
  7024. }
  7025. if (pctx.ino == 0) {
  7026. pctx.ino = pctx.ino2 = i;
  7027. save_problem = problem;
  7028. } else {
  7029. if ((problem == save_problem) &&
  7030. (pctx.ino2 == i-1))
  7031. pctx.ino2++;
  7032. else {
  7033. print_bitmap_problem(ctx, save_problem, &pctx);
  7034. pctx.ino = pctx.ino2 = i;
  7035. save_problem = problem;
  7036. }
  7037. }
  7038. ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
  7039. had_problem++;
  7040. do_counts:
  7041. if (!bitmap) {
  7042. group_free++;
  7043. free_inodes++;
  7044. } else {
  7045. if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
  7046. dirs_count++;
  7047. }
  7048. inodes++;
  7049. if ((inodes == fs->super->s_inodes_per_group) ||
  7050. (i == fs->super->s_inodes_count)) {
  7051. free_array[group] = group_free;
  7052. dir_array[group] = dirs_count;
  7053. group ++;
  7054. inodes = 0;
  7055. group_free = 0;
  7056. dirs_count = 0;
  7057. if (ctx->progress)
  7058. if ((ctx->progress)(ctx, 5,
  7059. group + fs->group_desc_count,
  7060. fs->group_desc_count*2))
  7061. return;
  7062. }
  7063. }
  7064. if (pctx.ino)
  7065. print_bitmap_problem(ctx, save_problem, &pctx);
  7066. if (had_problem)
  7067. fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
  7068. else
  7069. fixit = -1;
  7070. ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
  7071. if (fixit == 1) {
  7072. ext2fs_free_inode_bitmap(fs->inode_map);
  7073. retval = ext2fs_copy_bitmap(ctx->inode_used_map,
  7074. &fs->inode_map);
  7075. if (retval) {
  7076. clear_problem_context(&pctx);
  7077. fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
  7078. ctx->flags |= E2F_FLAG_ABORT;
  7079. return;
  7080. }
  7081. ext2fs_set_bitmap_padding(fs->inode_map);
  7082. ext2fs_mark_ib_dirty(fs);
  7083. /* redo counts */
  7084. inodes = 0; free_inodes = 0; group_free = 0;
  7085. dirs_count = 0; group = 0;
  7086. memset(free_array, 0, fs->group_desc_count * sizeof(int));
  7087. memset(dir_array, 0, fs->group_desc_count * sizeof(int));
  7088. goto redo_counts;
  7089. } else if (fixit == 0)
  7090. ext2fs_unmark_valid(fs);
  7091. for (i = 0; i < fs->group_desc_count; i++) {
  7092. if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
  7093. pctx.group = i;
  7094. pctx.ino = fs->group_desc[i].bg_free_inodes_count;
  7095. pctx.ino2 = free_array[i];
  7096. if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
  7097. &pctx)) {
  7098. fs->group_desc[i].bg_free_inodes_count =
  7099. free_array[i];
  7100. ext2fs_mark_super_dirty(fs);
  7101. } else
  7102. ext2fs_unmark_valid(fs);
  7103. }
  7104. if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
  7105. pctx.group = i;
  7106. pctx.ino = fs->group_desc[i].bg_used_dirs_count;
  7107. pctx.ino2 = dir_array[i];
  7108. if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
  7109. &pctx)) {
  7110. fs->group_desc[i].bg_used_dirs_count =
  7111. dir_array[i];
  7112. ext2fs_mark_super_dirty(fs);
  7113. } else
  7114. ext2fs_unmark_valid(fs);
  7115. }
  7116. }
  7117. if (free_inodes != fs->super->s_free_inodes_count) {
  7118. pctx.group = -1;
  7119. pctx.ino = fs->super->s_free_inodes_count;
  7120. pctx.ino2 = free_inodes;
  7121. if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
  7122. fs->super->s_free_inodes_count = free_inodes;
  7123. ext2fs_mark_super_dirty(fs);
  7124. } else
  7125. ext2fs_unmark_valid(fs);
  7126. }
  7127. ext2fs_free_mem(&free_array);
  7128. ext2fs_free_mem(&dir_array);
  7129. }
  7130. static void check_inode_end(e2fsck_t ctx)
  7131. {
  7132. ext2_filsys fs = ctx->fs;
  7133. ext2_ino_t end, save_inodes_count, i;
  7134. struct problem_context pctx;
  7135. clear_problem_context(&pctx);
  7136. end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
  7137. pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
  7138. &save_inodes_count);
  7139. if (pctx.errcode) {
  7140. pctx.num = 1;
  7141. fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
  7142. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  7143. return;
  7144. }
  7145. if (save_inodes_count == end)
  7146. return;
  7147. for (i = save_inodes_count + 1; i <= end; i++) {
  7148. if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
  7149. if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
  7150. for (i = save_inodes_count + 1; i <= end; i++)
  7151. ext2fs_mark_inode_bitmap(fs->inode_map,
  7152. i);
  7153. ext2fs_mark_ib_dirty(fs);
  7154. } else
  7155. ext2fs_unmark_valid(fs);
  7156. break;
  7157. }
  7158. }
  7159. pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
  7160. save_inodes_count, 0);
  7161. if (pctx.errcode) {
  7162. pctx.num = 2;
  7163. fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
  7164. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  7165. return;
  7166. }
  7167. }
  7168. static void check_block_end(e2fsck_t ctx)
  7169. {
  7170. ext2_filsys fs = ctx->fs;
  7171. blk_t end, save_blocks_count, i;
  7172. struct problem_context pctx;
  7173. clear_problem_context(&pctx);
  7174. end = fs->block_map->start +
  7175. (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
  7176. pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
  7177. &save_blocks_count);
  7178. if (pctx.errcode) {
  7179. pctx.num = 3;
  7180. fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
  7181. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  7182. return;
  7183. }
  7184. if (save_blocks_count == end)
  7185. return;
  7186. for (i = save_blocks_count + 1; i <= end; i++) {
  7187. if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
  7188. if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
  7189. for (i = save_blocks_count + 1; i <= end; i++)
  7190. ext2fs_mark_block_bitmap(fs->block_map,
  7191. i);
  7192. ext2fs_mark_bb_dirty(fs);
  7193. } else
  7194. ext2fs_unmark_valid(fs);
  7195. break;
  7196. }
  7197. }
  7198. pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
  7199. save_blocks_count, 0);
  7200. if (pctx.errcode) {
  7201. pctx.num = 4;
  7202. fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
  7203. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  7204. return;
  7205. }
  7206. }
  7207. static void e2fsck_pass5(e2fsck_t ctx)
  7208. {
  7209. struct problem_context pctx;
  7210. /* Pass 5 */
  7211. clear_problem_context(&pctx);
  7212. if (!(ctx->options & E2F_OPT_PREEN))
  7213. fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
  7214. if (ctx->progress)
  7215. if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
  7216. return;
  7217. e2fsck_read_bitmaps(ctx);
  7218. check_block_bitmaps(ctx);
  7219. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  7220. return;
  7221. check_inode_bitmaps(ctx);
  7222. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  7223. return;
  7224. check_inode_end(ctx);
  7225. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  7226. return;
  7227. check_block_end(ctx);
  7228. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  7229. return;
  7230. ext2fs_free_inode_bitmap(ctx->inode_used_map);
  7231. ctx->inode_used_map = 0;
  7232. ext2fs_free_inode_bitmap(ctx->inode_dir_map);
  7233. ctx->inode_dir_map = 0;
  7234. ext2fs_free_block_bitmap(ctx->block_found_map);
  7235. ctx->block_found_map = 0;
  7236. }
  7237. /*
  7238. * problem.c --- report filesystem problems to the user
  7239. */
  7240. #define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */
  7241. #define PR_NO_OK 0x000002 /* If user answers no, don't make fs invalid */
  7242. #define PR_NO_DEFAULT 0x000004 /* Default to no */
  7243. #define PR_MSG_ONLY 0x000008 /* Print message only */
  7244. /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
  7245. #define PR_FATAL 0x001000 /* Fatal error */
  7246. #define PR_AFTER_CODE 0x002000 /* After asking the first question, */
  7247. /* ask another */
  7248. #define PR_PREEN_NOMSG 0x004000 /* Don't print a message if we're preening */
  7249. #define PR_NOCOLLATE 0x008000 /* Don't collate answers for this latch */
  7250. #define PR_NO_NOMSG 0x010000 /* Don't print a message if e2fsck -n */
  7251. #define PR_PREEN_NO 0x020000 /* Use No as an answer if preening */
  7252. #define PR_PREEN_NOHDR 0x040000 /* Don't print the preen header */
  7253. #define PROMPT_NONE 0
  7254. #define PROMPT_FIX 1
  7255. #define PROMPT_CLEAR 2
  7256. #define PROMPT_RELOCATE 3
  7257. #define PROMPT_ALLOCATE 4
  7258. #define PROMPT_EXPAND 5
  7259. #define PROMPT_CONNECT 6
  7260. #define PROMPT_CREATE 7
  7261. #define PROMPT_SALVAGE 8
  7262. #define PROMPT_TRUNCATE 9
  7263. #define PROMPT_CLEAR_INODE 10
  7264. #define PROMPT_ABORT 11
  7265. #define PROMPT_SPLIT 12
  7266. #define PROMPT_CONTINUE 13
  7267. #define PROMPT_CLONE 14
  7268. #define PROMPT_DELETE 15
  7269. #define PROMPT_SUPPRESS 16
  7270. #define PROMPT_UNLINK 17
  7271. #define PROMPT_CLEAR_HTREE 18
  7272. #define PROMPT_RECREATE 19
  7273. #define PROMPT_NULL 20
  7274. struct e2fsck_problem {
  7275. problem_t e2p_code;
  7276. const char * e2p_description;
  7277. char prompt;
  7278. int flags;
  7279. problem_t second_code;
  7280. };
  7281. struct latch_descr {
  7282. int latch_code;
  7283. problem_t question;
  7284. problem_t end_message;
  7285. int flags;
  7286. };
  7287. /*
  7288. * These are the prompts which are used to ask the user if they want
  7289. * to fix a problem.
  7290. */
  7291. static const char *const prompt[] = {
  7292. N_("(no prompt)"), /* 0 */
  7293. N_("Fix"), /* 1 */
  7294. N_("Clear"), /* 2 */
  7295. N_("Relocate"), /* 3 */
  7296. N_("Allocate"), /* 4 */
  7297. N_("Expand"), /* 5 */
  7298. N_("Connect to /lost+found"), /* 6 */
  7299. N_("Create"), /* 7 */
  7300. N_("Salvage"), /* 8 */
  7301. N_("Truncate"), /* 9 */
  7302. N_("Clear inode"), /* 10 */
  7303. N_("Abort"), /* 11 */
  7304. N_("Split"), /* 12 */
  7305. N_("Continue"), /* 13 */
  7306. N_("Clone multiply-claimed blocks"), /* 14 */
  7307. N_("Delete file"), /* 15 */
  7308. N_("Suppress messages"),/* 16 */
  7309. N_("Unlink"), /* 17 */
  7310. N_("Clear HTree index"),/* 18 */
  7311. N_("Recreate"), /* 19 */
  7312. "", /* 20 */
  7313. };
  7314. /*
  7315. * These messages are printed when we are preen mode and we will be
  7316. * automatically fixing the problem.
  7317. */
  7318. static const char *const preen_msg[] = {
  7319. N_("(NONE)"), /* 0 */
  7320. N_("FIXED"), /* 1 */
  7321. N_("CLEARED"), /* 2 */
  7322. N_("RELOCATED"), /* 3 */
  7323. N_("ALLOCATED"), /* 4 */
  7324. N_("EXPANDED"), /* 5 */
  7325. N_("RECONNECTED"), /* 6 */
  7326. N_("CREATED"), /* 7 */
  7327. N_("SALVAGED"), /* 8 */
  7328. N_("TRUNCATED"), /* 9 */
  7329. N_("INODE CLEARED"), /* 10 */
  7330. N_("ABORTED"), /* 11 */
  7331. N_("SPLIT"), /* 12 */
  7332. N_("CONTINUING"), /* 13 */
  7333. N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
  7334. N_("FILE DELETED"), /* 15 */
  7335. N_("SUPPRESSED"), /* 16 */
  7336. N_("UNLINKED"), /* 17 */
  7337. N_("HTREE INDEX CLEARED"),/* 18 */
  7338. N_("WILL RECREATE"), /* 19 */
  7339. "", /* 20 */
  7340. };
  7341. static const struct e2fsck_problem problem_table[] = {
  7342. /* Pre-Pass 1 errors */
  7343. /* Block bitmap not in group */
  7344. { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
  7345. PROMPT_RELOCATE, PR_LATCH_RELOC },
  7346. /* Inode bitmap not in group */
  7347. { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
  7348. PROMPT_RELOCATE, PR_LATCH_RELOC },
  7349. /* Inode table not in group */
  7350. { PR_0_ITABLE_NOT_GROUP,
  7351. N_("@i table for @g %g is not in @g. (@b %b)\n"
  7352. "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
  7353. PROMPT_RELOCATE, PR_LATCH_RELOC },
  7354. /* Superblock corrupt */
  7355. { PR_0_SB_CORRUPT,
  7356. N_("\nThe @S could not be read or does not describe a correct ext2\n"
  7357. "@f. If the @v is valid and it really contains an ext2\n"
  7358. "@f (and not swap or ufs or something else), then the @S\n"
  7359. "is corrupt, and you might try running e2fsck with an alternate @S:\n"
  7360. " e2fsck -b %S <@v>\n\n"),
  7361. PROMPT_NONE, PR_FATAL },
  7362. /* Filesystem size is wrong */
  7363. { PR_0_FS_SIZE_WRONG,
  7364. N_("The @f size (according to the @S) is %b @bs\n"
  7365. "The physical size of the @v is %c @bs\n"
  7366. "Either the @S or the partition table is likely to be corrupt!\n"),
  7367. PROMPT_ABORT, 0 },
  7368. /* Fragments not supported */
  7369. { PR_0_NO_FRAGMENTS,
  7370. N_("@S @b_size = %b, fragsize = %c.\n"
  7371. "This version of e2fsck does not support fragment sizes different\n"
  7372. "from the @b size.\n"),
  7373. PROMPT_NONE, PR_FATAL },
  7374. /* Bad blocks_per_group */
  7375. { PR_0_BLOCKS_PER_GROUP,
  7376. N_("@S @bs_per_group = %b, should have been %c\n"),
  7377. PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
  7378. /* Bad first_data_block */
  7379. { PR_0_FIRST_DATA_BLOCK,
  7380. N_("@S first_data_@b = %b, should have been %c\n"),
  7381. PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
  7382. /* Adding UUID to filesystem */
  7383. { PR_0_ADD_UUID,
  7384. N_("@f did not have a UUID; generating one.\n\n"),
  7385. PROMPT_NONE, 0 },
  7386. /* Relocate hint */
  7387. { PR_0_RELOCATE_HINT,
  7388. N_("Note: if several inode or block bitmap blocks or part\n"
  7389. "of the inode table require relocation, you may wish to try\n"
  7390. "running e2fsck with the '-b %S' option first. The problem\n"
  7391. "may lie only with the primary block group descriptors, and\n"
  7392. "the backup block group descriptors may be OK.\n\n"),
  7393. PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
  7394. /* Miscellaneous superblock corruption */
  7395. { PR_0_MISC_CORRUPT_SUPER,
  7396. N_("Corruption found in @S. (%s = %N).\n"),
  7397. PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
  7398. /* Error determing physical device size of filesystem */
  7399. { PR_0_GETSIZE_ERROR,
  7400. N_("Error determining size of the physical @v: %m\n"),
  7401. PROMPT_NONE, PR_FATAL },
  7402. /* Inode count in superblock is incorrect */
  7403. { PR_0_INODE_COUNT_WRONG,
  7404. N_("@i count in @S is %i, @s %j.\n"),
  7405. PROMPT_FIX, 0 },
  7406. { PR_0_HURD_CLEAR_FILETYPE,
  7407. N_("The Hurd does not support the filetype feature.\n"),
  7408. PROMPT_CLEAR, 0 },
  7409. /* Journal inode is invalid */
  7410. { PR_0_JOURNAL_BAD_INODE,
  7411. N_("@S has an @n ext3 @j (@i %i).\n"),
  7412. PROMPT_CLEAR, PR_PREEN_OK },
  7413. /* The external journal has (unsupported) multiple filesystems */
  7414. { PR_0_JOURNAL_UNSUPP_MULTIFS,
  7415. N_("External @j has multiple @f users (unsupported).\n"),
  7416. PROMPT_NONE, PR_FATAL },
  7417. /* Can't find external journal */
  7418. { PR_0_CANT_FIND_JOURNAL,
  7419. N_("Can't find external @j\n"),
  7420. PROMPT_NONE, PR_FATAL },
  7421. /* External journal has bad superblock */
  7422. { PR_0_EXT_JOURNAL_BAD_SUPER,
  7423. N_("External @j has bad @S\n"),
  7424. PROMPT_NONE, PR_FATAL },
  7425. /* Superblock has a bad journal UUID */
  7426. { PR_0_JOURNAL_BAD_UUID,
  7427. N_("External @j does not support this @f\n"),
  7428. PROMPT_NONE, PR_FATAL },
  7429. /* Journal has an unknown superblock type */
  7430. { PR_0_JOURNAL_UNSUPP_SUPER,
  7431. N_("Ext3 @j @S is unknown type %N (unsupported).\n"
  7432. "It is likely that your copy of e2fsck is old and/or doesn't "
  7433. "support this @j format.\n"
  7434. "It is also possible the @j @S is corrupt.\n"),
  7435. PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
  7436. /* Journal superblock is corrupt */
  7437. { PR_0_JOURNAL_BAD_SUPER,
  7438. N_("Ext3 @j @S is corrupt.\n"),
  7439. PROMPT_FIX, PR_PREEN_OK },
  7440. /* Superblock flag should be cleared */
  7441. { PR_0_JOURNAL_HAS_JOURNAL,
  7442. N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
  7443. PROMPT_CLEAR, PR_PREEN_OK },
  7444. /* Superblock flag is incorrect */
  7445. { PR_0_JOURNAL_RECOVER_SET,
  7446. N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
  7447. PROMPT_CLEAR, PR_PREEN_OK },
  7448. /* Journal has data, but recovery flag is clear */
  7449. { PR_0_JOURNAL_RECOVERY_CLEAR,
  7450. N_("ext3 recovery flag is clear, but @j has data.\n"),
  7451. PROMPT_NONE, 0 },
  7452. /* Ask if we should clear the journal */
  7453. { PR_0_JOURNAL_RESET_JOURNAL,
  7454. N_("Clear @j"),
  7455. PROMPT_NULL, PR_PREEN_NOMSG },
  7456. /* Ask if we should run the journal anyway */
  7457. { PR_0_JOURNAL_RUN,
  7458. N_("Run @j anyway"),
  7459. PROMPT_NULL, 0 },
  7460. /* Run the journal by default */
  7461. { PR_0_JOURNAL_RUN_DEFAULT,
  7462. N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
  7463. PROMPT_NONE, 0 },
  7464. /* Clearing orphan inode */
  7465. { PR_0_ORPHAN_CLEAR_INODE,
  7466. N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
  7467. PROMPT_NONE, 0 },
  7468. /* Illegal block found in orphaned inode */
  7469. { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
  7470. N_("@I @b #%B (%b) found in @o @i %i.\n"),
  7471. PROMPT_NONE, 0 },
  7472. /* Already cleared block found in orphaned inode */
  7473. { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
  7474. N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
  7475. PROMPT_NONE, 0 },
  7476. /* Illegal orphan inode in superblock */
  7477. { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
  7478. N_("@I @o @i %i in @S.\n"),
  7479. PROMPT_NONE, 0 },
  7480. /* Illegal inode in orphaned inode list */
  7481. { PR_0_ORPHAN_ILLEGAL_INODE,
  7482. N_("@I @i %i in @o @i list.\n"),
  7483. PROMPT_NONE, 0 },
  7484. /* Filesystem revision is 0, but feature flags are set */
  7485. { PR_0_FS_REV_LEVEL,
  7486. N_("@f has feature flag(s) set, but is a revision 0 @f. "),
  7487. PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
  7488. /* Journal superblock has an unknown read-only feature flag set */
  7489. { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
  7490. N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
  7491. PROMPT_ABORT, 0 },
  7492. /* Journal superblock has an unknown incompatible feature flag set */
  7493. { PR_0_JOURNAL_UNSUPP_INCOMPAT,
  7494. N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
  7495. PROMPT_ABORT, 0 },
  7496. /* Journal has unsupported version number */
  7497. { PR_0_JOURNAL_UNSUPP_VERSION,
  7498. N_("@j version not supported by this e2fsck.\n"),
  7499. PROMPT_ABORT, 0 },
  7500. /* Moving journal to hidden file */
  7501. { PR_0_MOVE_JOURNAL,
  7502. N_("Moving @j from /%s to hidden @i.\n\n"),
  7503. PROMPT_NONE, 0 },
  7504. /* Error moving journal to hidden file */
  7505. { PR_0_ERR_MOVE_JOURNAL,
  7506. N_("Error moving @j: %m\n\n"),
  7507. PROMPT_NONE, 0 },
  7508. /* Clearing V2 journal superblock */
  7509. { PR_0_CLEAR_V2_JOURNAL,
  7510. N_("Found @n V2 @j @S fields (from V1 @j).\n"
  7511. "Clearing fields beyond the V1 @j @S...\n\n"),
  7512. PROMPT_NONE, 0 },
  7513. /* Backup journal inode blocks */
  7514. { PR_0_BACKUP_JNL,
  7515. N_("Backing up @j @i @b information.\n\n"),
  7516. PROMPT_NONE, 0 },
  7517. /* Reserved blocks w/o resize_inode */
  7518. { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
  7519. N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
  7520. "is %N; @s zero. "),
  7521. PROMPT_FIX, 0 },
  7522. /* Resize_inode not enabled, but resize inode is non-zero */
  7523. { PR_0_CLEAR_RESIZE_INODE,
  7524. N_("Resize_@i not enabled, but the resize @i is non-zero. "),
  7525. PROMPT_CLEAR, 0 },
  7526. /* Resize inode invalid */
  7527. { PR_0_RESIZE_INODE_INVALID,
  7528. N_("Resize @i not valid. "),
  7529. PROMPT_RECREATE, 0 },
  7530. /* Pass 1 errors */
  7531. /* Pass 1: Checking inodes, blocks, and sizes */
  7532. { PR_1_PASS_HEADER,
  7533. N_("Pass 1: Checking @is, @bs, and sizes\n"),
  7534. PROMPT_NONE, 0 },
  7535. /* Root directory is not an inode */
  7536. { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
  7537. PROMPT_CLEAR, 0 },
  7538. /* Root directory has dtime set */
  7539. { PR_1_ROOT_DTIME,
  7540. N_("@r has dtime set (probably due to old mke2fs). "),
  7541. PROMPT_FIX, PR_PREEN_OK },
  7542. /* Reserved inode has bad mode */
  7543. { PR_1_RESERVED_BAD_MODE,
  7544. N_("Reserved @i %i (%Q) has @n mode. "),
  7545. PROMPT_CLEAR, PR_PREEN_OK },
  7546. /* Deleted inode has zero dtime */
  7547. { PR_1_ZERO_DTIME,
  7548. N_("@D @i %i has zero dtime. "),
  7549. PROMPT_FIX, PR_PREEN_OK },
  7550. /* Inode in use, but dtime set */
  7551. { PR_1_SET_DTIME,
  7552. N_("@i %i is in use, but has dtime set. "),
  7553. PROMPT_FIX, PR_PREEN_OK },
  7554. /* Zero-length directory */
  7555. { PR_1_ZERO_LENGTH_DIR,
  7556. N_("@i %i is a @z @d. "),
  7557. PROMPT_CLEAR, PR_PREEN_OK },
  7558. /* Block bitmap conflicts with some other fs block */
  7559. { PR_1_BB_CONFLICT,
  7560. N_("@g %g's @b @B at %b @C.\n"),
  7561. PROMPT_RELOCATE, 0 },
  7562. /* Inode bitmap conflicts with some other fs block */
  7563. { PR_1_IB_CONFLICT,
  7564. N_("@g %g's @i @B at %b @C.\n"),
  7565. PROMPT_RELOCATE, 0 },
  7566. /* Inode table conflicts with some other fs block */
  7567. { PR_1_ITABLE_CONFLICT,
  7568. N_("@g %g's @i table at %b @C.\n"),
  7569. PROMPT_RELOCATE, 0 },
  7570. /* Block bitmap is on a bad block */
  7571. { PR_1_BB_BAD_BLOCK,
  7572. N_("@g %g's @b @B (%b) is bad. "),
  7573. PROMPT_RELOCATE, 0 },
  7574. /* Inode bitmap is on a bad block */
  7575. { PR_1_IB_BAD_BLOCK,
  7576. N_("@g %g's @i @B (%b) is bad. "),
  7577. PROMPT_RELOCATE, 0 },
  7578. /* Inode has incorrect i_size */
  7579. { PR_1_BAD_I_SIZE,
  7580. N_("@i %i, i_size is %Is, @s %N. "),
  7581. PROMPT_FIX, PR_PREEN_OK },
  7582. /* Inode has incorrect i_blocks */
  7583. { PR_1_BAD_I_BLOCKS,
  7584. N_("@i %i, i_@bs is %Ib, @s %N. "),
  7585. PROMPT_FIX, PR_PREEN_OK },
  7586. /* Illegal blocknumber in inode */
  7587. { PR_1_ILLEGAL_BLOCK_NUM,
  7588. N_("@I @b #%B (%b) in @i %i. "),
  7589. PROMPT_CLEAR, PR_LATCH_BLOCK },
  7590. /* Block number overlaps fs metadata */
  7591. { PR_1_BLOCK_OVERLAPS_METADATA,
  7592. N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
  7593. PROMPT_CLEAR, PR_LATCH_BLOCK },
  7594. /* Inode has illegal blocks (latch question) */
  7595. { PR_1_INODE_BLOCK_LATCH,
  7596. N_("@i %i has illegal @b(s). "),
  7597. PROMPT_CLEAR, 0 },
  7598. /* Too many bad blocks in inode */
  7599. { PR_1_TOO_MANY_BAD_BLOCKS,
  7600. N_("Too many illegal @bs in @i %i.\n"),
  7601. PROMPT_CLEAR_INODE, PR_NO_OK },
  7602. /* Illegal block number in bad block inode */
  7603. { PR_1_BB_ILLEGAL_BLOCK_NUM,
  7604. N_("@I @b #%B (%b) in bad @b @i. "),
  7605. PROMPT_CLEAR, PR_LATCH_BBLOCK },
  7606. /* Bad block inode has illegal blocks (latch question) */
  7607. { PR_1_INODE_BBLOCK_LATCH,
  7608. N_("Bad @b @i has illegal @b(s). "),
  7609. PROMPT_CLEAR, 0 },
  7610. /* Duplicate or bad blocks in use! */
  7611. { PR_1_DUP_BLOCKS_PREENSTOP,
  7612. N_("Duplicate or bad @b in use!\n"),
  7613. PROMPT_NONE, 0 },
  7614. /* Bad block used as bad block indirect block */
  7615. { PR_1_BBINODE_BAD_METABLOCK,
  7616. N_("Bad @b %b used as bad @b @i indirect @b. "),
  7617. PROMPT_CLEAR, PR_LATCH_BBLOCK },
  7618. /* Inconsistency can't be fixed prompt */
  7619. { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
  7620. N_("\nThe bad @b @i has probably been corrupted. You probably\n"
  7621. "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
  7622. "in the @f.\n"),
  7623. PROMPT_CONTINUE, PR_PREEN_NOMSG },
  7624. /* Bad primary block */
  7625. { PR_1_BAD_PRIMARY_BLOCK,
  7626. N_("\nIf the @b is really bad, the @f cannot be fixed.\n"),
  7627. PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
  7628. /* Bad primary block prompt */
  7629. { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
  7630. N_("You can remove this @b from the bad @b list and hope\n"
  7631. "that the @b is really OK. But there are no guarantees.\n\n"),
  7632. PROMPT_CLEAR, PR_PREEN_NOMSG },
  7633. /* Bad primary superblock */
  7634. { PR_1_BAD_PRIMARY_SUPERBLOCK,
  7635. N_("The primary @S (%b) is on the bad @b list.\n"),
  7636. PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
  7637. /* Bad primary block group descriptors */
  7638. { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
  7639. N_("Block %b in the primary @g descriptors "
  7640. "is on the bad @b list\n"),
  7641. PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
  7642. /* Bad superblock in group */
  7643. { PR_1_BAD_SUPERBLOCK,
  7644. N_("Warning: Group %g's @S (%b) is bad.\n"),
  7645. PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
  7646. /* Bad block group descriptors in group */
  7647. { PR_1_BAD_GROUP_DESCRIPTORS,
  7648. N_("Warning: Group %g's copy of the @g descriptors has a bad "
  7649. "@b (%b).\n"),
  7650. PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
  7651. /* Block claimed for no reason */
  7652. { PR_1_PROGERR_CLAIMED_BLOCK,
  7653. N_("Programming error? @b #%b claimed for no reason in "
  7654. "process_bad_@b.\n"),
  7655. PROMPT_NONE, PR_PREEN_OK },
  7656. /* Error allocating blocks for relocating metadata */
  7657. { PR_1_RELOC_BLOCK_ALLOCATE,
  7658. N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
  7659. PROMPT_NONE, PR_PREEN_OK },
  7660. /* Error allocating block buffer during relocation process */
  7661. { PR_1_RELOC_MEMORY_ALLOCATE,
  7662. N_("@A @b buffer for relocating %s\n"),
  7663. PROMPT_NONE, PR_PREEN_OK },
  7664. /* Relocating metadata group information from X to Y */
  7665. { PR_1_RELOC_FROM_TO,
  7666. N_("Relocating @g %g's %s from %b to %c...\n"),
  7667. PROMPT_NONE, PR_PREEN_OK },
  7668. /* Relocating metatdata group information to X */
  7669. { PR_1_RELOC_TO,
  7670. N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
  7671. PROMPT_NONE, PR_PREEN_OK },
  7672. /* Block read error during relocation process */
  7673. { PR_1_RELOC_READ_ERR,
  7674. N_("Warning: could not read @b %b of %s: %m\n"),
  7675. PROMPT_NONE, PR_PREEN_OK },
  7676. /* Block write error during relocation process */
  7677. { PR_1_RELOC_WRITE_ERR,
  7678. N_("Warning: could not write @b %b for %s: %m\n"),
  7679. PROMPT_NONE, PR_PREEN_OK },
  7680. /* Error allocating inode bitmap */
  7681. { PR_1_ALLOCATE_IBITMAP_ERROR,
  7682. N_("@A @i @B (%N): %m\n"),
  7683. PROMPT_NONE, PR_FATAL },
  7684. /* Error allocating block bitmap */
  7685. { PR_1_ALLOCATE_BBITMAP_ERROR,
  7686. N_("@A @b @B (%N): %m\n"),
  7687. PROMPT_NONE, PR_FATAL },
  7688. /* Error allocating icount structure */
  7689. { PR_1_ALLOCATE_ICOUNT,
  7690. N_("@A icount link information: %m\n"),
  7691. PROMPT_NONE, PR_FATAL },
  7692. /* Error allocating dbcount */
  7693. { PR_1_ALLOCATE_DBCOUNT,
  7694. N_("@A @d @b array: %m\n"),
  7695. PROMPT_NONE, PR_FATAL },
  7696. /* Error while scanning inodes */
  7697. { PR_1_ISCAN_ERROR,
  7698. N_("Error while scanning @is (%i): %m\n"),
  7699. PROMPT_NONE, PR_FATAL },
  7700. /* Error while iterating over blocks */
  7701. { PR_1_BLOCK_ITERATE,
  7702. N_("Error while iterating over @bs in @i %i: %m\n"),
  7703. PROMPT_NONE, PR_FATAL },
  7704. /* Error while storing inode count information */
  7705. { PR_1_ICOUNT_STORE,
  7706. N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
  7707. PROMPT_NONE, PR_FATAL },
  7708. /* Error while storing directory block information */
  7709. { PR_1_ADD_DBLOCK,
  7710. N_("Error storing @d @b information "
  7711. "(@i=%i, @b=%b, num=%N): %m\n"),
  7712. PROMPT_NONE, PR_FATAL },
  7713. /* Error while reading inode (for clearing) */
  7714. { PR_1_READ_INODE,
  7715. N_("Error reading @i %i: %m\n"),
  7716. PROMPT_NONE, PR_FATAL },
  7717. /* Suppress messages prompt */
  7718. { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
  7719. /* Imagic flag set on an inode when filesystem doesn't support it */
  7720. { PR_1_SET_IMAGIC,
  7721. N_("@i %i has imagic flag set. "),
  7722. PROMPT_CLEAR, 0 },
  7723. /* Immutable flag set on a device or socket inode */
  7724. { PR_1_SET_IMMUTABLE,
  7725. N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
  7726. "or append-only flag set. "),
  7727. PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
  7728. /* Compression flag set on an inode when filesystem doesn't support it */
  7729. { PR_1_COMPR_SET,
  7730. N_("@i %i has @cion flag set on @f without @cion support. "),
  7731. PROMPT_CLEAR, 0 },
  7732. /* Non-zero size for device, fifo or socket inode */
  7733. { PR_1_SET_NONZSIZE,
  7734. N_("Special (@v/socket/fifo) @i %i has non-zero size. "),
  7735. PROMPT_FIX, PR_PREEN_OK },
  7736. /* Filesystem revision is 0, but feature flags are set */
  7737. { PR_1_FS_REV_LEVEL,
  7738. N_("@f has feature flag(s) set, but is a revision 0 @f. "),
  7739. PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
  7740. /* Journal inode is not in use, but contains data */
  7741. { PR_1_JOURNAL_INODE_NOT_CLEAR,
  7742. N_("@j @i is not in use, but contains data. "),
  7743. PROMPT_CLEAR, PR_PREEN_OK },
  7744. /* Journal has bad mode */
  7745. { PR_1_JOURNAL_BAD_MODE,
  7746. N_("@j is not regular file. "),
  7747. PROMPT_FIX, PR_PREEN_OK },
  7748. /* Deal with inodes that were part of orphan linked list */
  7749. { PR_1_LOW_DTIME,
  7750. N_("@i %i was part of the @o @i list. "),
  7751. PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
  7752. /* Deal with inodes that were part of corrupted orphan linked
  7753. list (latch question) */
  7754. { PR_1_ORPHAN_LIST_REFUGEES,
  7755. N_("@is that were part of a corrupted orphan linked list found. "),
  7756. PROMPT_FIX, 0 },
  7757. /* Error allocating refcount structure */
  7758. { PR_1_ALLOCATE_REFCOUNT,
  7759. N_("@A refcount structure (%N): %m\n"),
  7760. PROMPT_NONE, PR_FATAL },
  7761. /* Error reading extended attribute block */
  7762. { PR_1_READ_EA_BLOCK,
  7763. N_("Error reading @a @b %b for @i %i. "),
  7764. PROMPT_CLEAR, 0 },
  7765. /* Invalid extended attribute block */
  7766. { PR_1_BAD_EA_BLOCK,
  7767. N_("@i %i has a bad @a @b %b. "),
  7768. PROMPT_CLEAR, 0 },
  7769. /* Error reading Extended Attribute block while fixing refcount */
  7770. { PR_1_EXTATTR_READ_ABORT,
  7771. N_("Error reading @a @b %b (%m). "),
  7772. PROMPT_ABORT, 0 },
  7773. /* Extended attribute reference count incorrect */
  7774. { PR_1_EXTATTR_REFCOUNT,
  7775. N_("@a @b %b has reference count %B, @s %N. "),
  7776. PROMPT_FIX, 0 },
  7777. /* Error writing Extended Attribute block while fixing refcount */
  7778. { PR_1_EXTATTR_WRITE,
  7779. N_("Error writing @a @b %b (%m). "),
  7780. PROMPT_ABORT, 0 },
  7781. /* Multiple EA blocks not supported */
  7782. { PR_1_EA_MULTI_BLOCK,
  7783. N_("@a @b %b has h_@bs > 1. "),
  7784. PROMPT_CLEAR, 0},
  7785. /* Error allocating EA region allocation structure */
  7786. { PR_1_EA_ALLOC_REGION,
  7787. N_("@A @a @b %b. "),
  7788. PROMPT_ABORT, 0},
  7789. /* Error EA allocation collision */
  7790. { PR_1_EA_ALLOC_COLLISION,
  7791. N_("@a @b %b is corrupt (allocation collision). "),
  7792. PROMPT_CLEAR, 0},
  7793. /* Bad extended attribute name */
  7794. { PR_1_EA_BAD_NAME,
  7795. N_("@a @b %b is corrupt (@n name). "),
  7796. PROMPT_CLEAR, 0},
  7797. /* Bad extended attribute value */
  7798. { PR_1_EA_BAD_VALUE,
  7799. N_("@a @b %b is corrupt (@n value). "),
  7800. PROMPT_CLEAR, 0},
  7801. /* Inode too big (latch question) */
  7802. { PR_1_INODE_TOOBIG,
  7803. N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 },
  7804. /* Directory too big */
  7805. { PR_1_TOOBIG_DIR,
  7806. N_("@b #%B (%b) causes @d to be too big. "),
  7807. PROMPT_CLEAR, PR_LATCH_TOOBIG },
  7808. /* Regular file too big */
  7809. { PR_1_TOOBIG_REG,
  7810. N_("@b #%B (%b) causes file to be too big. "),
  7811. PROMPT_CLEAR, PR_LATCH_TOOBIG },
  7812. /* Symlink too big */
  7813. { PR_1_TOOBIG_SYMLINK,
  7814. N_("@b #%B (%b) causes symlink to be too big. "),
  7815. PROMPT_CLEAR, PR_LATCH_TOOBIG },
  7816. /* INDEX_FL flag set on a non-HTREE filesystem */
  7817. { PR_1_HTREE_SET,
  7818. N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
  7819. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  7820. /* INDEX_FL flag set on a non-directory */
  7821. { PR_1_HTREE_NODIR,
  7822. N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
  7823. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  7824. /* Invalid root node in HTREE directory */
  7825. { PR_1_HTREE_BADROOT,
  7826. N_("@h %i has an @n root node.\n"),
  7827. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  7828. /* Unsupported hash version in HTREE directory */
  7829. { PR_1_HTREE_HASHV,
  7830. N_("@h %i has an unsupported hash version (%N)\n"),
  7831. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  7832. /* Incompatible flag in HTREE root node */
  7833. { PR_1_HTREE_INCOMPAT,
  7834. N_("@h %i uses an incompatible htree root node flag.\n"),
  7835. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  7836. /* HTREE too deep */
  7837. { PR_1_HTREE_DEPTH,
  7838. N_("@h %i has a tree depth (%N) which is too big\n"),
  7839. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  7840. /* Bad block has indirect block that conflicts with filesystem block */
  7841. { PR_1_BB_FS_BLOCK,
  7842. N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
  7843. "@f metadata. "),
  7844. PROMPT_CLEAR, PR_LATCH_BBLOCK },
  7845. /* Resize inode failed */
  7846. { PR_1_RESIZE_INODE_CREATE,
  7847. N_("Resize @i (re)creation failed: %m."),
  7848. PROMPT_ABORT, 0 },
  7849. /* invalid inode->i_extra_isize */
  7850. { PR_1_EXTRA_ISIZE,
  7851. N_("@i %i has a extra size (%IS) which is @n\n"),
  7852. PROMPT_FIX, PR_PREEN_OK },
  7853. /* invalid ea entry->e_name_len */
  7854. { PR_1_ATTR_NAME_LEN,
  7855. N_("@a in @i %i has a namelen (%N) which is @n\n"),
  7856. PROMPT_CLEAR, PR_PREEN_OK },
  7857. /* invalid ea entry->e_value_size */
  7858. { PR_1_ATTR_VALUE_SIZE,
  7859. N_("@a in @i %i has a value size (%N) which is @n\n"),
  7860. PROMPT_CLEAR, PR_PREEN_OK },
  7861. /* invalid ea entry->e_value_offs */
  7862. { PR_1_ATTR_VALUE_OFFSET,
  7863. N_("@a in @i %i has a value offset (%N) which is @n\n"),
  7864. PROMPT_CLEAR, PR_PREEN_OK },
  7865. /* invalid ea entry->e_value_block */
  7866. { PR_1_ATTR_VALUE_BLOCK,
  7867. N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
  7868. PROMPT_CLEAR, PR_PREEN_OK },
  7869. /* invalid ea entry->e_hash */
  7870. { PR_1_ATTR_HASH,
  7871. N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
  7872. PROMPT_CLEAR, PR_PREEN_OK },
  7873. /* Pass 1b errors */
  7874. /* Pass 1B: Rescan for duplicate/bad blocks */
  7875. { PR_1B_PASS_HEADER,
  7876. N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
  7877. "Pass 1B: Rescanning for @m @bs\n"),
  7878. PROMPT_NONE, 0 },
  7879. /* Duplicate/bad block(s) header */
  7880. { PR_1B_DUP_BLOCK_HEADER,
  7881. N_("@m @b(s) in @i %i:"),
  7882. PROMPT_NONE, 0 },
  7883. /* Duplicate/bad block(s) in inode */
  7884. { PR_1B_DUP_BLOCK,
  7885. " %b",
  7886. PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
  7887. /* Duplicate/bad block(s) end */
  7888. { PR_1B_DUP_BLOCK_END,
  7889. "\n",
  7890. PROMPT_NONE, PR_PREEN_NOHDR },
  7891. /* Error while scanning inodes */
  7892. { PR_1B_ISCAN_ERROR,
  7893. N_("Error while scanning inodes (%i): %m\n"),
  7894. PROMPT_NONE, PR_FATAL },
  7895. /* Error allocating inode bitmap */
  7896. { PR_1B_ALLOCATE_IBITMAP_ERROR,
  7897. N_("@A @i @B (@i_dup_map): %m\n"),
  7898. PROMPT_NONE, PR_FATAL },
  7899. /* Error while iterating over blocks */
  7900. { PR_1B_BLOCK_ITERATE,
  7901. N_("Error while iterating over @bs in @i %i (%s): %m\n"),
  7902. PROMPT_NONE, 0 },
  7903. /* Error adjusting EA refcount */
  7904. { PR_1B_ADJ_EA_REFCOUNT,
  7905. N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
  7906. PROMPT_NONE, 0 },
  7907. /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
  7908. { PR_1C_PASS_HEADER,
  7909. N_("Pass 1C: Scanning directories for @is with @m @bs.\n"),
  7910. PROMPT_NONE, 0 },
  7911. /* Pass 1D: Reconciling multiply-claimed blocks */
  7912. { PR_1D_PASS_HEADER,
  7913. N_("Pass 1D: Reconciling @m @bs\n"),
  7914. PROMPT_NONE, 0 },
  7915. /* File has duplicate blocks */
  7916. { PR_1D_DUP_FILE,
  7917. N_("File %Q (@i #%i, mod time %IM)\n"
  7918. " has %B @m @b(s), shared with %N file(s):\n"),
  7919. PROMPT_NONE, 0 },
  7920. /* List of files sharing duplicate blocks */
  7921. { PR_1D_DUP_FILE_LIST,
  7922. N_("\t%Q (@i #%i, mod time %IM)\n"),
  7923. PROMPT_NONE, 0 },
  7924. /* File sharing blocks with filesystem metadata */
  7925. { PR_1D_SHARE_METADATA,
  7926. N_("\t<@f metadata>\n"),
  7927. PROMPT_NONE, 0 },
  7928. /* Report of how many duplicate/bad inodes */
  7929. { PR_1D_NUM_DUP_INODES,
  7930. N_("(There are %N @is containing @m @bs.)\n\n"),
  7931. PROMPT_NONE, 0 },
  7932. /* Duplicated blocks already reassigned or cloned. */
  7933. { PR_1D_DUP_BLOCKS_DEALT,
  7934. N_("@m @bs already reassigned or cloned.\n\n"),
  7935. PROMPT_NONE, 0 },
  7936. /* Clone duplicate/bad blocks? */
  7937. { PR_1D_CLONE_QUESTION,
  7938. "", PROMPT_CLONE, PR_NO_OK },
  7939. /* Delete file? */
  7940. { PR_1D_DELETE_QUESTION,
  7941. "", PROMPT_DELETE, 0 },
  7942. /* Couldn't clone file (error) */
  7943. { PR_1D_CLONE_ERROR,
  7944. N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
  7945. /* Pass 2 errors */
  7946. /* Pass 2: Checking directory structure */
  7947. { PR_2_PASS_HEADER,
  7948. N_("Pass 2: Checking @d structure\n"),
  7949. PROMPT_NONE, 0 },
  7950. /* Bad inode number for '.' */
  7951. { PR_2_BAD_INODE_DOT,
  7952. N_("@n @i number for '.' in @d @i %i.\n"),
  7953. PROMPT_FIX, 0 },
  7954. /* Directory entry has bad inode number */
  7955. { PR_2_BAD_INO,
  7956. N_("@E has @n @i #: %Di.\n"),
  7957. PROMPT_CLEAR, 0 },
  7958. /* Directory entry has deleted or unused inode */
  7959. { PR_2_UNUSED_INODE,
  7960. N_("@E has @D/unused @i %Di. "),
  7961. PROMPT_CLEAR, PR_PREEN_OK },
  7962. /* Directry entry is link to '.' */
  7963. { PR_2_LINK_DOT,
  7964. N_("@E @L to '.' "),
  7965. PROMPT_CLEAR, 0 },
  7966. /* Directory entry points to inode now located in a bad block */
  7967. { PR_2_BB_INODE,
  7968. N_("@E points to @i (%Di) located in a bad @b.\n"),
  7969. PROMPT_CLEAR, 0 },
  7970. /* Directory entry contains a link to a directory */
  7971. { PR_2_LINK_DIR,
  7972. N_("@E @L to @d %P (%Di).\n"),
  7973. PROMPT_CLEAR, 0 },
  7974. /* Directory entry contains a link to the root directry */
  7975. { PR_2_LINK_ROOT,
  7976. N_("@E @L to the @r.\n"),
  7977. PROMPT_CLEAR, 0 },
  7978. /* Directory entry has illegal characters in its name */
  7979. { PR_2_BAD_NAME,
  7980. N_("@E has illegal characters in its name.\n"),
  7981. PROMPT_FIX, 0 },
  7982. /* Missing '.' in directory inode */
  7983. { PR_2_MISSING_DOT,
  7984. N_("Missing '.' in @d @i %i.\n"),
  7985. PROMPT_FIX, 0 },
  7986. /* Missing '..' in directory inode */
  7987. { PR_2_MISSING_DOT_DOT,
  7988. N_("Missing '..' in @d @i %i.\n"),
  7989. PROMPT_FIX, 0 },
  7990. /* First entry in directory inode doesn't contain '.' */
  7991. { PR_2_1ST_NOT_DOT,
  7992. N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
  7993. PROMPT_FIX, 0 },
  7994. /* Second entry in directory inode doesn't contain '..' */
  7995. { PR_2_2ND_NOT_DOT_DOT,
  7996. N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
  7997. PROMPT_FIX, 0 },
  7998. /* i_faddr should be zero */
  7999. { PR_2_FADDR_ZERO,
  8000. N_("i_faddr @F %IF, @s zero.\n"),
  8001. PROMPT_CLEAR, 0 },
  8002. /* i_file_acl should be zero */
  8003. { PR_2_FILE_ACL_ZERO,
  8004. N_("i_file_acl @F %If, @s zero.\n"),
  8005. PROMPT_CLEAR, 0 },
  8006. /* i_dir_acl should be zero */
  8007. { PR_2_DIR_ACL_ZERO,
  8008. N_("i_dir_acl @F %Id, @s zero.\n"),
  8009. PROMPT_CLEAR, 0 },
  8010. /* i_frag should be zero */
  8011. { PR_2_FRAG_ZERO,
  8012. N_("i_frag @F %N, @s zero.\n"),
  8013. PROMPT_CLEAR, 0 },
  8014. /* i_fsize should be zero */
  8015. { PR_2_FSIZE_ZERO,
  8016. N_("i_fsize @F %N, @s zero.\n"),
  8017. PROMPT_CLEAR, 0 },
  8018. /* inode has bad mode */
  8019. { PR_2_BAD_MODE,
  8020. N_("@i %i (%Q) has @n mode (%Im).\n"),
  8021. PROMPT_CLEAR, 0 },
  8022. /* directory corrupted */
  8023. { PR_2_DIR_CORRUPTED,
  8024. N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
  8025. PROMPT_SALVAGE, 0 },
  8026. /* filename too long */
  8027. { PR_2_FILENAME_LONG,
  8028. N_("@d @i %i, @b %B, offset %N: filename too long\n"),
  8029. PROMPT_TRUNCATE, 0 },
  8030. /* Directory inode has a missing block (hole) */
  8031. { PR_2_DIRECTORY_HOLE,
  8032. N_("@d @i %i has an unallocated @b #%B. "),
  8033. PROMPT_ALLOCATE, 0 },
  8034. /* '.' is not NULL terminated */
  8035. { PR_2_DOT_NULL_TERM,
  8036. N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
  8037. PROMPT_FIX, 0 },
  8038. /* '..' is not NULL terminated */
  8039. { PR_2_DOT_DOT_NULL_TERM,
  8040. N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
  8041. PROMPT_FIX, 0 },
  8042. /* Illegal character device inode */
  8043. { PR_2_BAD_CHAR_DEV,
  8044. N_("@i %i (%Q) is an @I character @v.\n"),
  8045. PROMPT_CLEAR, 0 },
  8046. /* Illegal block device inode */
  8047. { PR_2_BAD_BLOCK_DEV,
  8048. N_("@i %i (%Q) is an @I @b @v.\n"),
  8049. PROMPT_CLEAR, 0 },
  8050. /* Duplicate '.' entry */
  8051. { PR_2_DUP_DOT,
  8052. N_("@E is duplicate '.' @e.\n"),
  8053. PROMPT_FIX, 0 },
  8054. /* Duplicate '..' entry */
  8055. { PR_2_DUP_DOT_DOT,
  8056. N_("@E is duplicate '..' @e.\n"),
  8057. PROMPT_FIX, 0 },
  8058. /* Internal error: couldn't find dir_info */
  8059. { PR_2_NO_DIRINFO,
  8060. N_("Internal error: cannot find dir_info for %i.\n"),
  8061. PROMPT_NONE, PR_FATAL },
  8062. /* Final rec_len is wrong */
  8063. { PR_2_FINAL_RECLEN,
  8064. N_("@E has rec_len of %Dr, @s %N.\n"),
  8065. PROMPT_FIX, 0 },
  8066. /* Error allocating icount structure */
  8067. { PR_2_ALLOCATE_ICOUNT,
  8068. N_("@A icount structure: %m\n"),
  8069. PROMPT_NONE, PR_FATAL },
  8070. /* Error iterating over directory blocks */
  8071. { PR_2_DBLIST_ITERATE,
  8072. N_("Error iterating over @d @bs: %m\n"),
  8073. PROMPT_NONE, PR_FATAL },
  8074. /* Error reading directory block */
  8075. { PR_2_READ_DIRBLOCK,
  8076. N_("Error reading @d @b %b (@i %i): %m\n"),
  8077. PROMPT_CONTINUE, 0 },
  8078. /* Error writing directory block */
  8079. { PR_2_WRITE_DIRBLOCK,
  8080. N_("Error writing @d @b %b (@i %i): %m\n"),
  8081. PROMPT_CONTINUE, 0 },
  8082. /* Error allocating new directory block */
  8083. { PR_2_ALLOC_DIRBOCK,
  8084. N_("@A new @d @b for @i %i (%s): %m\n"),
  8085. PROMPT_NONE, 0 },
  8086. /* Error deallocating inode */
  8087. { PR_2_DEALLOC_INODE,
  8088. N_("Error deallocating @i %i: %m\n"),
  8089. PROMPT_NONE, PR_FATAL },
  8090. /* Directory entry for '.' is big. Split? */
  8091. { PR_2_SPLIT_DOT,
  8092. N_("@d @e for '.' is big. "),
  8093. PROMPT_SPLIT, PR_NO_OK },
  8094. /* Illegal FIFO inode */
  8095. { PR_2_BAD_FIFO,
  8096. N_("@i %i (%Q) is an @I FIFO.\n"),
  8097. PROMPT_CLEAR, 0 },
  8098. /* Illegal socket inode */
  8099. { PR_2_BAD_SOCKET,
  8100. N_("@i %i (%Q) is an @I socket.\n"),
  8101. PROMPT_CLEAR, 0 },
  8102. /* Directory filetype not set */
  8103. { PR_2_SET_FILETYPE,
  8104. N_("Setting filetype for @E to %N.\n"),
  8105. PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
  8106. /* Directory filetype incorrect */
  8107. { PR_2_BAD_FILETYPE,
  8108. N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
  8109. PROMPT_FIX, 0 },
  8110. /* Directory filetype set on filesystem */
  8111. { PR_2_CLEAR_FILETYPE,
  8112. N_("@E has filetype set.\n"),
  8113. PROMPT_CLEAR, PR_PREEN_OK },
  8114. /* Directory filename is null */
  8115. { PR_2_NULL_NAME,
  8116. N_("@E has a @z name.\n"),
  8117. PROMPT_CLEAR, 0 },
  8118. /* Invalid symlink */
  8119. { PR_2_INVALID_SYMLINK,
  8120. N_("Symlink %Q (@i #%i) is @n.\n"),
  8121. PROMPT_CLEAR, 0 },
  8122. /* i_file_acl (extended attribute block) is bad */
  8123. { PR_2_FILE_ACL_BAD,
  8124. N_("@a @b @F @n (%If).\n"),
  8125. PROMPT_CLEAR, 0 },
  8126. /* Filesystem contains large files, but has no such flag in sb */
  8127. { PR_2_FEATURE_LARGE_FILES,
  8128. N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
  8129. PROMPT_FIX, 0 },
  8130. /* Node in HTREE directory not referenced */
  8131. { PR_2_HTREE_NOTREF,
  8132. N_("@p @h %d: node (%B) not referenced\n"),
  8133. PROMPT_NONE, 0 },
  8134. /* Node in HTREE directory referenced twice */
  8135. { PR_2_HTREE_DUPREF,
  8136. N_("@p @h %d: node (%B) referenced twice\n"),
  8137. PROMPT_NONE, 0 },
  8138. /* Node in HTREE directory has bad min hash */
  8139. { PR_2_HTREE_MIN_HASH,
  8140. N_("@p @h %d: node (%B) has bad min hash\n"),
  8141. PROMPT_NONE, 0 },
  8142. /* Node in HTREE directory has bad max hash */
  8143. { PR_2_HTREE_MAX_HASH,
  8144. N_("@p @h %d: node (%B) has bad max hash\n"),
  8145. PROMPT_NONE, 0 },
  8146. /* Clear invalid HTREE directory */
  8147. { PR_2_HTREE_CLEAR,
  8148. N_("@n @h %d (%q). "), PROMPT_CLEAR, 0 },
  8149. /* Bad block in htree interior node */
  8150. { PR_2_HTREE_BADBLK,
  8151. N_("@p @h %d (%q): bad @b number %b.\n"),
  8152. PROMPT_CLEAR_HTREE, 0 },
  8153. /* Error adjusting EA refcount */
  8154. { PR_2_ADJ_EA_REFCOUNT,
  8155. N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
  8156. PROMPT_NONE, PR_FATAL },
  8157. /* Invalid HTREE root node */
  8158. { PR_2_HTREE_BAD_ROOT,
  8159. N_("@p @h %d: root node is @n\n"),
  8160. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  8161. /* Invalid HTREE limit */
  8162. { PR_2_HTREE_BAD_LIMIT,
  8163. N_("@p @h %d: node (%B) has @n limit (%N)\n"),
  8164. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  8165. /* Invalid HTREE count */
  8166. { PR_2_HTREE_BAD_COUNT,
  8167. N_("@p @h %d: node (%B) has @n count (%N)\n"),
  8168. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  8169. /* HTREE interior node has out-of-order hashes in table */
  8170. { PR_2_HTREE_HASH_ORDER,
  8171. N_("@p @h %d: node (%B) has an unordered hash table\n"),
  8172. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  8173. /* Node in HTREE directory has invalid depth */
  8174. { PR_2_HTREE_BAD_DEPTH,
  8175. N_("@p @h %d: node (%B) has @n depth\n"),
  8176. PROMPT_NONE, 0 },
  8177. /* Duplicate directory entry found */
  8178. { PR_2_DUPLICATE_DIRENT,
  8179. N_("Duplicate @E found. "),
  8180. PROMPT_CLEAR, 0 },
  8181. /* Non-unique filename found */
  8182. { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
  8183. N_("@E has a non-unique filename.\nRename to %s"),
  8184. PROMPT_NULL, 0 },
  8185. /* Duplicate directory entry found */
  8186. { PR_2_REPORT_DUP_DIRENT,
  8187. N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
  8188. PROMPT_NONE, 0 },
  8189. /* Pass 3 errors */
  8190. /* Pass 3: Checking directory connectivity */
  8191. { PR_3_PASS_HEADER,
  8192. N_("Pass 3: Checking @d connectivity\n"),
  8193. PROMPT_NONE, 0 },
  8194. /* Root inode not allocated */
  8195. { PR_3_NO_ROOT_INODE,
  8196. N_("@r not allocated. "),
  8197. PROMPT_ALLOCATE, 0 },
  8198. /* No room in lost+found */
  8199. { PR_3_EXPAND_LF_DIR,
  8200. N_("No room in @l @d. "),
  8201. PROMPT_EXPAND, 0 },
  8202. /* Unconnected directory inode */
  8203. { PR_3_UNCONNECTED_DIR,
  8204. N_("Unconnected @d @i %i (%p)\n"),
  8205. PROMPT_CONNECT, 0 },
  8206. /* /lost+found not found */
  8207. { PR_3_NO_LF_DIR,
  8208. N_("/@l not found. "),
  8209. PROMPT_CREATE, PR_PREEN_OK },
  8210. /* .. entry is incorrect */
  8211. { PR_3_BAD_DOT_DOT,
  8212. N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
  8213. PROMPT_FIX, 0 },
  8214. /* Bad or non-existent /lost+found. Cannot reconnect */
  8215. { PR_3_NO_LPF,
  8216. N_("Bad or non-existent /@l. Cannot reconnect.\n"),
  8217. PROMPT_NONE, 0 },
  8218. /* Could not expand /lost+found */
  8219. { PR_3_CANT_EXPAND_LPF,
  8220. N_("Could not expand /@l: %m\n"),
  8221. PROMPT_NONE, 0 },
  8222. /* Could not reconnect inode */
  8223. { PR_3_CANT_RECONNECT,
  8224. N_("Could not reconnect %i: %m\n"),
  8225. PROMPT_NONE, 0 },
  8226. /* Error while trying to find /lost+found */
  8227. { PR_3_ERR_FIND_LPF,
  8228. N_("Error while trying to find /@l: %m\n"),
  8229. PROMPT_NONE, 0 },
  8230. /* Error in ext2fs_new_block while creating /lost+found */
  8231. { PR_3_ERR_LPF_NEW_BLOCK,
  8232. N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
  8233. PROMPT_NONE, 0 },
  8234. /* Error in ext2fs_new_inode while creating /lost+found */
  8235. { PR_3_ERR_LPF_NEW_INODE,
  8236. N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
  8237. PROMPT_NONE, 0 },
  8238. /* Error in ext2fs_new_dir_block while creating /lost+found */
  8239. { PR_3_ERR_LPF_NEW_DIR_BLOCK,
  8240. N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
  8241. PROMPT_NONE, 0 },
  8242. /* Error while writing directory block for /lost+found */
  8243. { PR_3_ERR_LPF_WRITE_BLOCK,
  8244. N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
  8245. PROMPT_NONE, 0 },
  8246. /* Error while adjusting inode count */
  8247. { PR_3_ADJUST_INODE,
  8248. N_("Error while adjusting @i count on @i %i\n"),
  8249. PROMPT_NONE, 0 },
  8250. /* Couldn't fix parent directory -- error */
  8251. { PR_3_FIX_PARENT_ERR,
  8252. N_("Couldn't fix parent of @i %i: %m\n\n"),
  8253. PROMPT_NONE, 0 },
  8254. /* Couldn't fix parent directory -- couldn't find it */
  8255. { PR_3_FIX_PARENT_NOFIND,
  8256. N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
  8257. PROMPT_NONE, 0 },
  8258. /* Error allocating inode bitmap */
  8259. { PR_3_ALLOCATE_IBITMAP_ERROR,
  8260. N_("@A @i @B (%N): %m\n"),
  8261. PROMPT_NONE, PR_FATAL },
  8262. /* Error creating root directory */
  8263. { PR_3_CREATE_ROOT_ERROR,
  8264. N_("Error creating root @d (%s): %m\n"),
  8265. PROMPT_NONE, PR_FATAL },
  8266. /* Error creating lost and found directory */
  8267. { PR_3_CREATE_LPF_ERROR,
  8268. N_("Error creating /@l @d (%s): %m\n"),
  8269. PROMPT_NONE, PR_FATAL },
  8270. /* Root inode is not directory; aborting */
  8271. { PR_3_ROOT_NOT_DIR_ABORT,
  8272. N_("@r is not a @d; aborting.\n"),
  8273. PROMPT_NONE, PR_FATAL },
  8274. /* Cannot proceed without a root inode. */
  8275. { PR_3_NO_ROOT_INODE_ABORT,
  8276. N_("can't proceed without a @r.\n"),
  8277. PROMPT_NONE, PR_FATAL },
  8278. /* Internal error: couldn't find dir_info */
  8279. { PR_3_NO_DIRINFO,
  8280. N_("Internal error: cannot find dir_info for %i.\n"),
  8281. PROMPT_NONE, PR_FATAL },
  8282. /* Lost+found not a directory */
  8283. { PR_3_LPF_NOTDIR,
  8284. N_("/@l is not a @d (ino=%i)\n"),
  8285. PROMPT_UNLINK, 0 },
  8286. /* Pass 3A Directory Optimization */
  8287. /* Pass 3A: Optimizing directories */
  8288. { PR_3A_PASS_HEADER,
  8289. N_("Pass 3A: Optimizing directories\n"),
  8290. PROMPT_NONE, PR_PREEN_NOMSG },
  8291. /* Error iterating over directories */
  8292. { PR_3A_OPTIMIZE_ITER,
  8293. N_("Failed to create dirs_to_hash iterator: %m"),
  8294. PROMPT_NONE, 0 },
  8295. /* Error rehash directory */
  8296. { PR_3A_OPTIMIZE_DIR_ERR,
  8297. N_("Failed to optimize directory %q (%d): %m"),
  8298. PROMPT_NONE, 0 },
  8299. /* Rehashing dir header */
  8300. { PR_3A_OPTIMIZE_DIR_HEADER,
  8301. N_("Optimizing directories: "),
  8302. PROMPT_NONE, PR_MSG_ONLY },
  8303. /* Rehashing directory %d */
  8304. { PR_3A_OPTIMIZE_DIR,
  8305. " %d",
  8306. PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
  8307. /* Rehashing dir end */
  8308. { PR_3A_OPTIMIZE_DIR_END,
  8309. "\n",
  8310. PROMPT_NONE, PR_PREEN_NOHDR },
  8311. /* Pass 4 errors */
  8312. /* Pass 4: Checking reference counts */
  8313. { PR_4_PASS_HEADER,
  8314. N_("Pass 4: Checking reference counts\n"),
  8315. PROMPT_NONE, 0 },
  8316. /* Unattached zero-length inode */
  8317. { PR_4_ZERO_LEN_INODE,
  8318. N_("@u @z @i %i. "),
  8319. PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
  8320. /* Unattached inode */
  8321. { PR_4_UNATTACHED_INODE,
  8322. N_("@u @i %i\n"),
  8323. PROMPT_CONNECT, 0 },
  8324. /* Inode ref count wrong */
  8325. { PR_4_BAD_REF_COUNT,
  8326. N_("@i %i ref count is %Il, @s %N. "),
  8327. PROMPT_FIX, PR_PREEN_OK },
  8328. { PR_4_INCONSISTENT_COUNT,
  8329. N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
  8330. "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
  8331. "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
  8332. "They @s the same!\n"),
  8333. PROMPT_NONE, 0 },
  8334. /* Pass 5 errors */
  8335. /* Pass 5: Checking group summary information */
  8336. { PR_5_PASS_HEADER,
  8337. N_("Pass 5: Checking @g summary information\n"),
  8338. PROMPT_NONE, 0 },
  8339. /* Padding at end of inode bitmap is not set. */
  8340. { PR_5_INODE_BMAP_PADDING,
  8341. N_("Padding at end of @i @B is not set. "),
  8342. PROMPT_FIX, PR_PREEN_OK },
  8343. /* Padding at end of block bitmap is not set. */
  8344. { PR_5_BLOCK_BMAP_PADDING,
  8345. N_("Padding at end of @b @B is not set. "),
  8346. PROMPT_FIX, PR_PREEN_OK },
  8347. /* Block bitmap differences header */
  8348. { PR_5_BLOCK_BITMAP_HEADER,
  8349. N_("@b @B differences: "),
  8350. PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
  8351. /* Block not used, but marked in bitmap */
  8352. { PR_5_BLOCK_UNUSED,
  8353. " -%b",
  8354. PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8355. /* Block used, but not marked used in bitmap */
  8356. { PR_5_BLOCK_USED,
  8357. " +%b",
  8358. PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8359. /* Block bitmap differences end */
  8360. { PR_5_BLOCK_BITMAP_END,
  8361. "\n",
  8362. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8363. /* Inode bitmap differences header */
  8364. { PR_5_INODE_BITMAP_HEADER,
  8365. N_("@i @B differences: "),
  8366. PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
  8367. /* Inode not used, but marked in bitmap */
  8368. { PR_5_INODE_UNUSED,
  8369. " -%i",
  8370. PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8371. /* Inode used, but not marked used in bitmap */
  8372. { PR_5_INODE_USED,
  8373. " +%i",
  8374. PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8375. /* Inode bitmap differences end */
  8376. { PR_5_INODE_BITMAP_END,
  8377. "\n",
  8378. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8379. /* Free inodes count for group wrong */
  8380. { PR_5_FREE_INODE_COUNT_GROUP,
  8381. N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
  8382. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8383. /* Directories count for group wrong */
  8384. { PR_5_FREE_DIR_COUNT_GROUP,
  8385. N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
  8386. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8387. /* Free inodes count wrong */
  8388. { PR_5_FREE_INODE_COUNT,
  8389. N_("Free @is count wrong (%i, counted=%j).\n"),
  8390. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8391. /* Free blocks count for group wrong */
  8392. { PR_5_FREE_BLOCK_COUNT_GROUP,
  8393. N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
  8394. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8395. /* Free blocks count wrong */
  8396. { PR_5_FREE_BLOCK_COUNT,
  8397. N_("Free @bs count wrong (%b, counted=%c).\n"),
  8398. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8399. /* Programming error: bitmap endpoints don't match */
  8400. { PR_5_BMAP_ENDPOINTS,
  8401. N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
  8402. "match calculated @B endpoints (%i, %j)\n"),
  8403. PROMPT_NONE, PR_FATAL },
  8404. /* Internal error: fudging end of bitmap */
  8405. { PR_5_FUDGE_BITMAP_ERROR,
  8406. N_("Internal error: fudging end of bitmap (%N)\n"),
  8407. PROMPT_NONE, PR_FATAL },
  8408. /* Error copying in replacement inode bitmap */
  8409. { PR_5_COPY_IBITMAP_ERROR,
  8410. N_("Error copying in replacement @i @B: %m\n"),
  8411. PROMPT_NONE, PR_FATAL },
  8412. /* Error copying in replacement block bitmap */
  8413. { PR_5_COPY_BBITMAP_ERROR,
  8414. N_("Error copying in replacement @b @B: %m\n"),
  8415. PROMPT_NONE, PR_FATAL },
  8416. /* Block range not used, but marked in bitmap */
  8417. { PR_5_BLOCK_RANGE_UNUSED,
  8418. " -(%b--%c)",
  8419. PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8420. /* Block range used, but not marked used in bitmap */
  8421. { PR_5_BLOCK_RANGE_USED,
  8422. " +(%b--%c)",
  8423. PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8424. /* Inode range not used, but marked in bitmap */
  8425. { PR_5_INODE_RANGE_UNUSED,
  8426. " -(%i--%j)",
  8427. PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8428. /* Inode range used, but not marked used in bitmap */
  8429. { PR_5_INODE_RANGE_USED,
  8430. " +(%i--%j)",
  8431. PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8432. { 0 }
  8433. };
  8434. /*
  8435. * This is the latch flags register. It allows several problems to be
  8436. * "latched" together. This means that the user has to answer but one
  8437. * question for the set of problems, and all of the associated
  8438. * problems will be either fixed or not fixed.
  8439. */
  8440. static struct latch_descr pr_latch_info[] = {
  8441. { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
  8442. { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
  8443. { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
  8444. { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
  8445. { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
  8446. { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
  8447. { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
  8448. { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
  8449. { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
  8450. { -1, 0, 0 },
  8451. };
  8452. static const struct e2fsck_problem *find_problem(problem_t code)
  8453. {
  8454. int i;
  8455. for (i=0; problem_table[i].e2p_code; i++) {
  8456. if (problem_table[i].e2p_code == code)
  8457. return &problem_table[i];
  8458. }
  8459. return 0;
  8460. }
  8461. static struct latch_descr *find_latch(int code)
  8462. {
  8463. int i;
  8464. for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
  8465. if (pr_latch_info[i].latch_code == code)
  8466. return &pr_latch_info[i];
  8467. }
  8468. return 0;
  8469. }
  8470. int end_problem_latch(e2fsck_t ctx, int mask)
  8471. {
  8472. struct latch_descr *ldesc;
  8473. struct problem_context pctx;
  8474. int answer = -1;
  8475. ldesc = find_latch(mask);
  8476. if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
  8477. clear_problem_context(&pctx);
  8478. answer = fix_problem(ctx, ldesc->end_message, &pctx);
  8479. }
  8480. ldesc->flags &= ~(PRL_VARIABLE);
  8481. return answer;
  8482. }
  8483. int set_latch_flags(int mask, int setflags, int clearflags)
  8484. {
  8485. struct latch_descr *ldesc;
  8486. ldesc = find_latch(mask);
  8487. if (!ldesc)
  8488. return -1;
  8489. ldesc->flags |= setflags;
  8490. ldesc->flags &= ~clearflags;
  8491. return 0;
  8492. }
  8493. void clear_problem_context(struct problem_context *ctx)
  8494. {
  8495. memset(ctx, 0, sizeof(struct problem_context));
  8496. ctx->blkcount = -1;
  8497. ctx->group = -1;
  8498. }
  8499. int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
  8500. {
  8501. ext2_filsys fs = ctx->fs;
  8502. const struct e2fsck_problem *ptr;
  8503. struct latch_descr *ldesc = NULL;
  8504. const char *message;
  8505. int def_yn, answer, ans;
  8506. int print_answer = 0;
  8507. int suppress = 0;
  8508. ptr = find_problem(code);
  8509. if (!ptr) {
  8510. printf(_("Unhandled error code (0x%x)!\n"), code);
  8511. return 0;
  8512. }
  8513. def_yn = 1;
  8514. if ((ptr->flags & PR_NO_DEFAULT) ||
  8515. ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
  8516. (ctx->options & E2F_OPT_NO))
  8517. def_yn= 0;
  8518. /*
  8519. * Do special latch processing. This is where we ask the
  8520. * latch question, if it exists
  8521. */
  8522. if (ptr->flags & PR_LATCH_MASK) {
  8523. ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
  8524. if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
  8525. ans = fix_problem(ctx, ldesc->question, pctx);
  8526. if (ans == 1)
  8527. ldesc->flags |= PRL_YES;
  8528. if (ans == 0)
  8529. ldesc->flags |= PRL_NO;
  8530. ldesc->flags |= PRL_LATCHED;
  8531. }
  8532. if (ldesc->flags & PRL_SUPPRESS)
  8533. suppress++;
  8534. }
  8535. if ((ptr->flags & PR_PREEN_NOMSG) &&
  8536. (ctx->options & E2F_OPT_PREEN))
  8537. suppress++;
  8538. if ((ptr->flags & PR_NO_NOMSG) &&
  8539. (ctx->options & E2F_OPT_NO))
  8540. suppress++;
  8541. if (!suppress) {
  8542. message = ptr->e2p_description;
  8543. if ((ctx->options & E2F_OPT_PREEN) &&
  8544. !(ptr->flags & PR_PREEN_NOHDR)) {
  8545. printf("%s: ", ctx->device_name ?
  8546. ctx->device_name : ctx->filesystem_name);
  8547. }
  8548. if (*message)
  8549. print_e2fsck_message(ctx, _(message), pctx, 1);
  8550. }
  8551. if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
  8552. preenhalt(ctx);
  8553. if (ptr->flags & PR_FATAL)
  8554. bb_error_msg_and_die(0);
  8555. if (ptr->prompt == PROMPT_NONE) {
  8556. if (ptr->flags & PR_NOCOLLATE)
  8557. answer = -1;
  8558. else
  8559. answer = def_yn;
  8560. } else {
  8561. if (ctx->options & E2F_OPT_PREEN) {
  8562. answer = def_yn;
  8563. if (!(ptr->flags & PR_PREEN_NOMSG))
  8564. print_answer = 1;
  8565. } else if ((ptr->flags & PR_LATCH_MASK) &&
  8566. (ldesc->flags & (PRL_YES | PRL_NO))) {
  8567. if (!suppress)
  8568. print_answer = 1;
  8569. if (ldesc->flags & PRL_YES)
  8570. answer = 1;
  8571. else
  8572. answer = 0;
  8573. } else
  8574. answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
  8575. if (!answer && !(ptr->flags & PR_NO_OK))
  8576. ext2fs_unmark_valid(fs);
  8577. if (print_answer)
  8578. printf("%s.\n", answer ?
  8579. _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
  8580. }
  8581. if ((ptr->prompt == PROMPT_ABORT) && answer)
  8582. bb_error_msg_and_die(0);
  8583. if (ptr->flags & PR_AFTER_CODE)
  8584. answer = fix_problem(ctx, ptr->second_code, pctx);
  8585. return answer;
  8586. }
  8587. /*
  8588. * linux/fs/recovery.c
  8589. *
  8590. * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
  8591. */
  8592. /*
  8593. * Maintain information about the progress of the recovery job, so that
  8594. * the different passes can carry information between them.
  8595. */
  8596. struct recovery_info
  8597. {
  8598. tid_t start_transaction;
  8599. tid_t end_transaction;
  8600. int nr_replays;
  8601. int nr_revokes;
  8602. int nr_revoke_hits;
  8603. };
  8604. enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
  8605. static int do_one_pass(journal_t *journal,
  8606. struct recovery_info *info, enum passtype pass);
  8607. static int scan_revoke_records(journal_t *, struct buffer_head *,
  8608. tid_t, struct recovery_info *);
  8609. /*
  8610. * Read a block from the journal
  8611. */
  8612. static int jread(struct buffer_head **bhp, journal_t *journal,
  8613. unsigned int offset)
  8614. {
  8615. int err;
  8616. unsigned long blocknr;
  8617. struct buffer_head *bh;
  8618. *bhp = NULL;
  8619. err = journal_bmap(journal, offset, &blocknr);
  8620. if (err) {
  8621. printf("JBD: bad block at offset %u\n", offset);
  8622. return err;
  8623. }
  8624. bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
  8625. if (!bh)
  8626. return -ENOMEM;
  8627. if (!buffer_uptodate(bh)) {
  8628. /* If this is a brand new buffer, start readahead.
  8629. Otherwise, we assume we are already reading it. */
  8630. if (!buffer_req(bh))
  8631. do_readahead(journal, offset);
  8632. wait_on_buffer(bh);
  8633. }
  8634. if (!buffer_uptodate(bh)) {
  8635. printf("JBD: Failed to read block at offset %u\n", offset);
  8636. brelse(bh);
  8637. return -EIO;
  8638. }
  8639. *bhp = bh;
  8640. return 0;
  8641. }
  8642. /*
  8643. * Count the number of in-use tags in a journal descriptor block.
  8644. */
  8645. static int count_tags(struct buffer_head *bh, int size)
  8646. {
  8647. char * tagp;
  8648. journal_block_tag_t * tag;
  8649. int nr = 0;
  8650. tagp = &bh->b_data[sizeof(journal_header_t)];
  8651. while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
  8652. tag = (journal_block_tag_t *) tagp;
  8653. nr++;
  8654. tagp += sizeof(journal_block_tag_t);
  8655. if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
  8656. tagp += 16;
  8657. if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
  8658. break;
  8659. }
  8660. return nr;
  8661. }
  8662. /* Make sure we wrap around the log correctly! */
  8663. #define wrap(journal, var) \
  8664. do { \
  8665. if (var >= (journal)->j_last) \
  8666. var -= ((journal)->j_last - (journal)->j_first); \
  8667. } while (0)
  8668. /**
  8669. * int journal_recover(journal_t *journal) - recovers a on-disk journal
  8670. * @journal: the journal to recover
  8671. *
  8672. * The primary function for recovering the log contents when mounting a
  8673. * journaled device.
  8674. *
  8675. * Recovery is done in three passes. In the first pass, we look for the
  8676. * end of the log. In the second, we assemble the list of revoke
  8677. * blocks. In the third and final pass, we replay any un-revoked blocks
  8678. * in the log.
  8679. */
  8680. int journal_recover(journal_t *journal)
  8681. {
  8682. int err;
  8683. journal_superblock_t * sb;
  8684. struct recovery_info info;
  8685. memset(&info, 0, sizeof(info));
  8686. sb = journal->j_superblock;
  8687. /*
  8688. * The journal superblock's s_start field (the current log head)
  8689. * is always zero if, and only if, the journal was cleanly
  8690. * unmounted.
  8691. */
  8692. if (!sb->s_start) {
  8693. journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
  8694. return 0;
  8695. }
  8696. err = do_one_pass(journal, &info, PASS_SCAN);
  8697. if (!err)
  8698. err = do_one_pass(journal, &info, PASS_REVOKE);
  8699. if (!err)
  8700. err = do_one_pass(journal, &info, PASS_REPLAY);
  8701. /* Restart the log at the next transaction ID, thus invalidating
  8702. * any existing commit records in the log. */
  8703. journal->j_transaction_sequence = ++info.end_transaction;
  8704. journal_clear_revoke(journal);
  8705. sync_blockdev(journal->j_fs_dev);
  8706. return err;
  8707. }
  8708. static int do_one_pass(journal_t *journal,
  8709. struct recovery_info *info, enum passtype pass)
  8710. {
  8711. unsigned int first_commit_ID, next_commit_ID;
  8712. unsigned long next_log_block;
  8713. int err, success = 0;
  8714. journal_superblock_t * sb;
  8715. journal_header_t * tmp;
  8716. struct buffer_head * bh;
  8717. unsigned int sequence;
  8718. int blocktype;
  8719. /* Precompute the maximum metadata descriptors in a descriptor block */
  8720. int MAX_BLOCKS_PER_DESC;
  8721. MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
  8722. / sizeof(journal_block_tag_t));
  8723. /*
  8724. * First thing is to establish what we expect to find in the log
  8725. * (in terms of transaction IDs), and where (in terms of log
  8726. * block offsets): query the superblock.
  8727. */
  8728. sb = journal->j_superblock;
  8729. next_commit_ID = ntohl(sb->s_sequence);
  8730. next_log_block = ntohl(sb->s_start);
  8731. first_commit_ID = next_commit_ID;
  8732. if (pass == PASS_SCAN)
  8733. info->start_transaction = first_commit_ID;
  8734. /*
  8735. * Now we walk through the log, transaction by transaction,
  8736. * making sure that each transaction has a commit block in the
  8737. * expected place. Each complete transaction gets replayed back
  8738. * into the main filesystem.
  8739. */
  8740. while (1) {
  8741. int flags;
  8742. char * tagp;
  8743. journal_block_tag_t * tag;
  8744. struct buffer_head * obh;
  8745. struct buffer_head * nbh;
  8746. /* If we already know where to stop the log traversal,
  8747. * check right now that we haven't gone past the end of
  8748. * the log. */
  8749. if (pass != PASS_SCAN)
  8750. if (tid_geq(next_commit_ID, info->end_transaction))
  8751. break;
  8752. /* Skip over each chunk of the transaction looking
  8753. * either the next descriptor block or the final commit
  8754. * record. */
  8755. err = jread(&bh, journal, next_log_block);
  8756. if (err)
  8757. goto failed;
  8758. next_log_block++;
  8759. wrap(journal, next_log_block);
  8760. /* What kind of buffer is it?
  8761. *
  8762. * If it is a descriptor block, check that it has the
  8763. * expected sequence number. Otherwise, we're all done
  8764. * here. */
  8765. tmp = (journal_header_t *)bh->b_data;
  8766. if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
  8767. brelse(bh);
  8768. break;
  8769. }
  8770. blocktype = ntohl(tmp->h_blocktype);
  8771. sequence = ntohl(tmp->h_sequence);
  8772. if (sequence != next_commit_ID) {
  8773. brelse(bh);
  8774. break;
  8775. }
  8776. /* OK, we have a valid descriptor block which matches
  8777. * all of the sequence number checks. What are we going
  8778. * to do with it? That depends on the pass... */
  8779. switch (blocktype) {
  8780. case JFS_DESCRIPTOR_BLOCK:
  8781. /* If it is a valid descriptor block, replay it
  8782. * in pass REPLAY; otherwise, just skip over the
  8783. * blocks it describes. */
  8784. if (pass != PASS_REPLAY) {
  8785. next_log_block +=
  8786. count_tags(bh, journal->j_blocksize);
  8787. wrap(journal, next_log_block);
  8788. brelse(bh);
  8789. continue;
  8790. }
  8791. /* A descriptor block: we can now write all of
  8792. * the data blocks. Yay, useful work is finally
  8793. * getting done here! */
  8794. tagp = &bh->b_data[sizeof(journal_header_t)];
  8795. while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
  8796. <= journal->j_blocksize) {
  8797. unsigned long io_block;
  8798. tag = (journal_block_tag_t *) tagp;
  8799. flags = ntohl(tag->t_flags);
  8800. io_block = next_log_block++;
  8801. wrap(journal, next_log_block);
  8802. err = jread(&obh, journal, io_block);
  8803. if (err) {
  8804. /* Recover what we can, but
  8805. * report failure at the end. */
  8806. success = err;
  8807. printf("JBD: IO error %d recovering "
  8808. "block %ld in log\n",
  8809. err, io_block);
  8810. } else {
  8811. unsigned long blocknr;
  8812. blocknr = ntohl(tag->t_blocknr);
  8813. /* If the block has been
  8814. * revoked, then we're all done
  8815. * here. */
  8816. if (journal_test_revoke
  8817. (journal, blocknr,
  8818. next_commit_ID)) {
  8819. brelse(obh);
  8820. ++info->nr_revoke_hits;
  8821. goto skip_write;
  8822. }
  8823. /* Find a buffer for the new
  8824. * data being restored */
  8825. nbh = getblk(journal->j_fs_dev,
  8826. blocknr,
  8827. journal->j_blocksize);
  8828. if (nbh == NULL) {
  8829. printf("JBD: Out of memory "
  8830. "during recovery.\n");
  8831. err = -ENOMEM;
  8832. brelse(bh);
  8833. brelse(obh);
  8834. goto failed;
  8835. }
  8836. lock_buffer(nbh);
  8837. memcpy(nbh->b_data, obh->b_data,
  8838. journal->j_blocksize);
  8839. if (flags & JFS_FLAG_ESCAPE) {
  8840. *((unsigned int *)bh->b_data) =
  8841. htonl(JFS_MAGIC_NUMBER);
  8842. }
  8843. mark_buffer_uptodate(nbh, 1);
  8844. mark_buffer_dirty(nbh);
  8845. ++info->nr_replays;
  8846. /* ll_rw_block(WRITE, 1, &nbh); */
  8847. unlock_buffer(nbh);
  8848. brelse(obh);
  8849. brelse(nbh);
  8850. }
  8851. skip_write:
  8852. tagp += sizeof(journal_block_tag_t);
  8853. if (!(flags & JFS_FLAG_SAME_UUID))
  8854. tagp += 16;
  8855. if (flags & JFS_FLAG_LAST_TAG)
  8856. break;
  8857. }
  8858. brelse(bh);
  8859. continue;
  8860. case JFS_COMMIT_BLOCK:
  8861. /* Found an expected commit block: not much to
  8862. * do other than move on to the next sequence
  8863. * number. */
  8864. brelse(bh);
  8865. next_commit_ID++;
  8866. continue;
  8867. case JFS_REVOKE_BLOCK:
  8868. /* If we aren't in the REVOKE pass, then we can
  8869. * just skip over this block. */
  8870. if (pass != PASS_REVOKE) {
  8871. brelse(bh);
  8872. continue;
  8873. }
  8874. err = scan_revoke_records(journal, bh,
  8875. next_commit_ID, info);
  8876. brelse(bh);
  8877. if (err)
  8878. goto failed;
  8879. continue;
  8880. default:
  8881. goto done;
  8882. }
  8883. }
  8884. done:
  8885. /*
  8886. * We broke out of the log scan loop: either we came to the
  8887. * known end of the log or we found an unexpected block in the
  8888. * log. If the latter happened, then we know that the "current"
  8889. * transaction marks the end of the valid log.
  8890. */
  8891. if (pass == PASS_SCAN)
  8892. info->end_transaction = next_commit_ID;
  8893. else {
  8894. /* It's really bad news if different passes end up at
  8895. * different places (but possible due to IO errors). */
  8896. if (info->end_transaction != next_commit_ID) {
  8897. printf("JBD: recovery pass %d ended at "
  8898. "transaction %u, expected %u\n",
  8899. pass, next_commit_ID, info->end_transaction);
  8900. if (!success)
  8901. success = -EIO;
  8902. }
  8903. }
  8904. return success;
  8905. failed:
  8906. return err;
  8907. }
  8908. /* Scan a revoke record, marking all blocks mentioned as revoked. */
  8909. static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
  8910. tid_t sequence, struct recovery_info *info)
  8911. {
  8912. journal_revoke_header_t *header;
  8913. int offset, max;
  8914. header = (journal_revoke_header_t *) bh->b_data;
  8915. offset = sizeof(journal_revoke_header_t);
  8916. max = ntohl(header->r_count);
  8917. while (offset < max) {
  8918. unsigned long blocknr;
  8919. int err;
  8920. blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
  8921. offset += 4;
  8922. err = journal_set_revoke(journal, blocknr, sequence);
  8923. if (err)
  8924. return err;
  8925. ++info->nr_revokes;
  8926. }
  8927. return 0;
  8928. }
  8929. /*
  8930. * rehash.c --- rebuild hash tree directories
  8931. *
  8932. * This algorithm is designed for simplicity of implementation and to
  8933. * pack the directory as much as possible. It however requires twice
  8934. * as much memory as the size of the directory. The maximum size
  8935. * directory supported using a 4k blocksize is roughly a gigabyte, and
  8936. * so there may very well be problems with machines that don't have
  8937. * virtual memory, and obscenely large directories.
  8938. *
  8939. * An alternate algorithm which is much more disk intensive could be
  8940. * written, and probably will need to be written in the future. The
  8941. * design goals of such an algorithm are: (a) use (roughly) constant
  8942. * amounts of memory, no matter how large the directory, (b) the
  8943. * directory must be safe at all times, even if e2fsck is interrupted
  8944. * in the middle, (c) we must use minimal amounts of extra disk
  8945. * blocks. This pretty much requires an incremental approach, where
  8946. * we are reading from one part of the directory, and inserting into
  8947. * the front half. So the algorithm will have to keep track of a
  8948. * moving block boundary between the new tree and the old tree, and
  8949. * files will need to be moved from the old directory and inserted
  8950. * into the new tree. If the new directory requires space which isn't
  8951. * yet available, blocks from the beginning part of the old directory
  8952. * may need to be moved to the end of the directory to make room for
  8953. * the new tree:
  8954. *
  8955. * --------------------------------------------------------
  8956. * | new tree | | old tree |
  8957. * --------------------------------------------------------
  8958. * ^ ptr ^ptr
  8959. * tail new head old
  8960. *
  8961. * This is going to be a pain in the tuckus to implement, and will
  8962. * require a lot more disk accesses. So I'm going to skip it for now;
  8963. * it's only really going to be an issue for really, really big
  8964. * filesystems (when we reach the level of tens of millions of files
  8965. * in a single directory). It will probably be easier to simply
  8966. * require that e2fsck use VM first.
  8967. */
  8968. struct fill_dir_struct {
  8969. char *buf;
  8970. struct ext2_inode *inode;
  8971. int err;
  8972. e2fsck_t ctx;
  8973. struct hash_entry *harray;
  8974. int max_array, num_array;
  8975. int dir_size;
  8976. int compress;
  8977. ino_t parent;
  8978. };
  8979. struct hash_entry {
  8980. ext2_dirhash_t hash;
  8981. ext2_dirhash_t minor_hash;
  8982. struct ext2_dir_entry *dir;
  8983. };
  8984. struct out_dir {
  8985. int num;
  8986. int max;
  8987. char *buf;
  8988. ext2_dirhash_t *hashes;
  8989. };
  8990. static int fill_dir_block(ext2_filsys fs,
  8991. blk_t *block_nr,
  8992. e2_blkcnt_t blockcnt,
  8993. blk_t ref_block FSCK_ATTR((unused)),
  8994. int ref_offset FSCK_ATTR((unused)),
  8995. void *priv_data)
  8996. {
  8997. struct fill_dir_struct *fd = (struct fill_dir_struct *) priv_data;
  8998. struct hash_entry *new_array, *ent;
  8999. struct ext2_dir_entry *dirent;
  9000. char *dir;
  9001. unsigned int offset, dir_offset;
  9002. if (blockcnt < 0)
  9003. return 0;
  9004. offset = blockcnt * fs->blocksize;
  9005. if (offset + fs->blocksize > fd->inode->i_size) {
  9006. fd->err = EXT2_ET_DIR_CORRUPTED;
  9007. return BLOCK_ABORT;
  9008. }
  9009. dir = (fd->buf+offset);
  9010. if (HOLE_BLKADDR(*block_nr)) {
  9011. memset(dir, 0, fs->blocksize);
  9012. dirent = (struct ext2_dir_entry *) dir;
  9013. dirent->rec_len = fs->blocksize;
  9014. } else {
  9015. fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
  9016. if (fd->err)
  9017. return BLOCK_ABORT;
  9018. }
  9019. /* While the directory block is "hot", index it. */
  9020. dir_offset = 0;
  9021. while (dir_offset < fs->blocksize) {
  9022. dirent = (struct ext2_dir_entry *) (dir + dir_offset);
  9023. if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
  9024. (dirent->rec_len < 8) ||
  9025. ((dirent->rec_len % 4) != 0) ||
  9026. (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
  9027. fd->err = EXT2_ET_DIR_CORRUPTED;
  9028. return BLOCK_ABORT;
  9029. }
  9030. dir_offset += dirent->rec_len;
  9031. if (dirent->inode == 0)
  9032. continue;
  9033. if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
  9034. (dirent->name[0] == '.'))
  9035. continue;
  9036. if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
  9037. (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
  9038. fd->parent = dirent->inode;
  9039. continue;
  9040. }
  9041. if (fd->num_array >= fd->max_array) {
  9042. new_array = xrealloc(fd->harray,
  9043. sizeof(struct hash_entry) * (fd->max_array+500));
  9044. fd->harray = new_array;
  9045. fd->max_array += 500;
  9046. }
  9047. ent = fd->harray + fd->num_array++;
  9048. ent->dir = dirent;
  9049. fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
  9050. if (fd->compress)
  9051. ent->hash = ent->minor_hash = 0;
  9052. else {
  9053. fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
  9054. dirent->name,
  9055. dirent->name_len & 0xFF,
  9056. fs->super->s_hash_seed,
  9057. &ent->hash, &ent->minor_hash);
  9058. if (fd->err)
  9059. return BLOCK_ABORT;
  9060. }
  9061. }
  9062. return 0;
  9063. }
  9064. /* Used for sorting the hash entry */
  9065. static int name_cmp(const void *a, const void *b)
  9066. {
  9067. const struct hash_entry *he_a = (const struct hash_entry *) a;
  9068. const struct hash_entry *he_b = (const struct hash_entry *) b;
  9069. int ret;
  9070. int min_len;
  9071. min_len = he_a->dir->name_len;
  9072. if (min_len > he_b->dir->name_len)
  9073. min_len = he_b->dir->name_len;
  9074. ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
  9075. if (ret == 0) {
  9076. if (he_a->dir->name_len > he_b->dir->name_len)
  9077. ret = 1;
  9078. else if (he_a->dir->name_len < he_b->dir->name_len)
  9079. ret = -1;
  9080. else
  9081. ret = he_b->dir->inode - he_a->dir->inode;
  9082. }
  9083. return ret;
  9084. }
  9085. /* Used for sorting the hash entry */
  9086. static int hash_cmp(const void *a, const void *b)
  9087. {
  9088. const struct hash_entry *he_a = (const struct hash_entry *) a;
  9089. const struct hash_entry *he_b = (const struct hash_entry *) b;
  9090. int ret;
  9091. if (he_a->hash > he_b->hash)
  9092. ret = 1;
  9093. else if (he_a->hash < he_b->hash)
  9094. ret = -1;
  9095. else {
  9096. if (he_a->minor_hash > he_b->minor_hash)
  9097. ret = 1;
  9098. else if (he_a->minor_hash < he_b->minor_hash)
  9099. ret = -1;
  9100. else
  9101. ret = name_cmp(a, b);
  9102. }
  9103. return ret;
  9104. }
  9105. static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
  9106. int blocks)
  9107. {
  9108. void *new_mem;
  9109. if (outdir->max) {
  9110. new_mem = xrealloc(outdir->buf, blocks * fs->blocksize);
  9111. outdir->buf = new_mem;
  9112. new_mem = xrealloc(outdir->hashes,
  9113. blocks * sizeof(ext2_dirhash_t));
  9114. outdir->hashes = new_mem;
  9115. } else {
  9116. outdir->buf = xmalloc(blocks * fs->blocksize);
  9117. outdir->hashes = xmalloc(blocks * sizeof(ext2_dirhash_t));
  9118. outdir->num = 0;
  9119. }
  9120. outdir->max = blocks;
  9121. return 0;
  9122. }
  9123. static void free_out_dir(struct out_dir *outdir)
  9124. {
  9125. free(outdir->buf);
  9126. free(outdir->hashes);
  9127. outdir->max = 0;
  9128. outdir->num =0;
  9129. }
  9130. static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
  9131. char ** ret)
  9132. {
  9133. errcode_t retval;
  9134. if (outdir->num >= outdir->max) {
  9135. retval = alloc_size_dir(fs, outdir, outdir->max + 50);
  9136. if (retval)
  9137. return retval;
  9138. }
  9139. *ret = outdir->buf + (outdir->num++ * fs->blocksize);
  9140. memset(*ret, 0, fs->blocksize);
  9141. return 0;
  9142. }
  9143. /*
  9144. * This function is used to make a unique filename. We do this by
  9145. * appending ~0, and then incrementing the number. However, we cannot
  9146. * expand the length of the filename beyond the padding available in
  9147. * the directory entry.
  9148. */
  9149. static void mutate_name(char *str, __u16 *len)
  9150. {
  9151. int i;
  9152. __u16 l = *len & 0xFF, h = *len & 0xff00;
  9153. /*
  9154. * First check to see if it looks the name has been mutated
  9155. * already
  9156. */
  9157. for (i = l-1; i > 0; i--) {
  9158. if (!isdigit(str[i]))
  9159. break;
  9160. }
  9161. if ((i == l-1) || (str[i] != '~')) {
  9162. if (((l-1) & 3) < 2)
  9163. l += 2;
  9164. else
  9165. l = (l+3) & ~3;
  9166. str[l-2] = '~';
  9167. str[l-1] = '0';
  9168. *len = l | h;
  9169. return;
  9170. }
  9171. for (i = l-1; i >= 0; i--) {
  9172. if (isdigit(str[i])) {
  9173. if (str[i] == '9')
  9174. str[i] = '0';
  9175. else {
  9176. str[i]++;
  9177. return;
  9178. }
  9179. continue;
  9180. }
  9181. if (i == 1) {
  9182. if (str[0] == 'z')
  9183. str[0] = 'A';
  9184. else if (str[0] == 'Z') {
  9185. str[0] = '~';
  9186. str[1] = '0';
  9187. } else
  9188. str[0]++;
  9189. } else if (i > 0) {
  9190. str[i] = '1';
  9191. str[i-1] = '~';
  9192. } else {
  9193. if (str[0] == '~')
  9194. str[0] = 'a';
  9195. else
  9196. str[0]++;
  9197. }
  9198. break;
  9199. }
  9200. }
  9201. static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
  9202. ext2_ino_t ino,
  9203. struct fill_dir_struct *fd)
  9204. {
  9205. struct problem_context pctx;
  9206. struct hash_entry *ent, *prev;
  9207. int i, j;
  9208. int fixed = 0;
  9209. char new_name[256];
  9210. __u16 new_len;
  9211. clear_problem_context(&pctx);
  9212. pctx.ino = ino;
  9213. for (i=1; i < fd->num_array; i++) {
  9214. ent = fd->harray + i;
  9215. prev = ent - 1;
  9216. if (!ent->dir->inode ||
  9217. ((ent->dir->name_len & 0xFF) !=
  9218. (prev->dir->name_len & 0xFF)) ||
  9219. (strncmp(ent->dir->name, prev->dir->name,
  9220. ent->dir->name_len & 0xFF)))
  9221. continue;
  9222. pctx.dirent = ent->dir;
  9223. if ((ent->dir->inode == prev->dir->inode) &&
  9224. fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
  9225. e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
  9226. ent->dir->inode = 0;
  9227. fixed++;
  9228. continue;
  9229. }
  9230. memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
  9231. new_len = ent->dir->name_len;
  9232. mutate_name(new_name, &new_len);
  9233. for (j=0; j < fd->num_array; j++) {
  9234. if ((i==j) ||
  9235. ((ent->dir->name_len & 0xFF) !=
  9236. (fd->harray[j].dir->name_len & 0xFF)) ||
  9237. (strncmp(new_name, fd->harray[j].dir->name,
  9238. new_len & 0xFF)))
  9239. continue;
  9240. mutate_name(new_name, &new_len);
  9241. j = -1;
  9242. }
  9243. new_name[new_len & 0xFF] = 0;
  9244. pctx.str = new_name;
  9245. if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
  9246. memcpy(ent->dir->name, new_name, new_len & 0xFF);
  9247. ent->dir->name_len = new_len;
  9248. ext2fs_dirhash(fs->super->s_def_hash_version,
  9249. ent->dir->name,
  9250. ent->dir->name_len & 0xFF,
  9251. fs->super->s_hash_seed,
  9252. &ent->hash, &ent->minor_hash);
  9253. fixed++;
  9254. }
  9255. }
  9256. return fixed;
  9257. }
  9258. static errcode_t copy_dir_entries(ext2_filsys fs,
  9259. struct fill_dir_struct *fd,
  9260. struct out_dir *outdir)
  9261. {
  9262. errcode_t retval;
  9263. char *block_start;
  9264. struct hash_entry *ent;
  9265. struct ext2_dir_entry *dirent;
  9266. int i, rec_len, left;
  9267. ext2_dirhash_t prev_hash;
  9268. int offset;
  9269. outdir->max = 0;
  9270. retval = alloc_size_dir(fs, outdir,
  9271. (fd->dir_size / fs->blocksize) + 2);
  9272. if (retval)
  9273. return retval;
  9274. outdir->num = fd->compress ? 0 : 1;
  9275. offset = 0;
  9276. outdir->hashes[0] = 0;
  9277. prev_hash = 1;
  9278. if ((retval = get_next_block(fs, outdir, &block_start)))
  9279. return retval;
  9280. dirent = (struct ext2_dir_entry *) block_start;
  9281. left = fs->blocksize;
  9282. for (i=0; i < fd->num_array; i++) {
  9283. ent = fd->harray + i;
  9284. if (ent->dir->inode == 0)
  9285. continue;
  9286. rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
  9287. if (rec_len > left) {
  9288. if (left)
  9289. dirent->rec_len += left;
  9290. if ((retval = get_next_block(fs, outdir,
  9291. &block_start)))
  9292. return retval;
  9293. offset = 0;
  9294. }
  9295. left = fs->blocksize - offset;
  9296. dirent = (struct ext2_dir_entry *) (block_start + offset);
  9297. if (offset == 0) {
  9298. if (ent->hash == prev_hash)
  9299. outdir->hashes[outdir->num-1] = ent->hash | 1;
  9300. else
  9301. outdir->hashes[outdir->num-1] = ent->hash;
  9302. }
  9303. dirent->inode = ent->dir->inode;
  9304. dirent->name_len = ent->dir->name_len;
  9305. dirent->rec_len = rec_len;
  9306. memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
  9307. offset += rec_len;
  9308. left -= rec_len;
  9309. if (left < 12) {
  9310. dirent->rec_len += left;
  9311. offset += left;
  9312. left = 0;
  9313. }
  9314. prev_hash = ent->hash;
  9315. }
  9316. if (left)
  9317. dirent->rec_len += left;
  9318. return 0;
  9319. }
  9320. static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
  9321. ext2_ino_t ino, ext2_ino_t parent)
  9322. {
  9323. struct ext2_dir_entry *dir;
  9324. struct ext2_dx_root_info *root;
  9325. struct ext2_dx_countlimit *limits;
  9326. int filetype = 0;
  9327. if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
  9328. filetype = EXT2_FT_DIR << 8;
  9329. memset(buf, 0, fs->blocksize);
  9330. dir = (struct ext2_dir_entry *) buf;
  9331. dir->inode = ino;
  9332. dir->name[0] = '.';
  9333. dir->name_len = 1 | filetype;
  9334. dir->rec_len = 12;
  9335. dir = (struct ext2_dir_entry *) (buf + 12);
  9336. dir->inode = parent;
  9337. dir->name[0] = '.';
  9338. dir->name[1] = '.';
  9339. dir->name_len = 2 | filetype;
  9340. dir->rec_len = fs->blocksize - 12;
  9341. root = (struct ext2_dx_root_info *) (buf+24);
  9342. root->reserved_zero = 0;
  9343. root->hash_version = fs->super->s_def_hash_version;
  9344. root->info_length = 8;
  9345. root->indirect_levels = 0;
  9346. root->unused_flags = 0;
  9347. limits = (struct ext2_dx_countlimit *) (buf+32);
  9348. limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
  9349. limits->count = 0;
  9350. return root;
  9351. }
  9352. static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
  9353. {
  9354. struct ext2_dir_entry *dir;
  9355. struct ext2_dx_countlimit *limits;
  9356. memset(buf, 0, fs->blocksize);
  9357. dir = (struct ext2_dir_entry *) buf;
  9358. dir->inode = 0;
  9359. dir->rec_len = fs->blocksize;
  9360. limits = (struct ext2_dx_countlimit *) (buf+8);
  9361. limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
  9362. limits->count = 0;
  9363. return (struct ext2_dx_entry *) limits;
  9364. }
  9365. /*
  9366. * This function takes the leaf nodes which have been written in
  9367. * outdir, and populates the root node and any necessary interior nodes.
  9368. */
  9369. static errcode_t calculate_tree(ext2_filsys fs,
  9370. struct out_dir *outdir,
  9371. ext2_ino_t ino,
  9372. ext2_ino_t parent)
  9373. {
  9374. struct ext2_dx_root_info *root_info;
  9375. struct ext2_dx_entry *root, *dx_ent = NULL;
  9376. struct ext2_dx_countlimit *root_limit, *limit;
  9377. errcode_t retval;
  9378. char * block_start;
  9379. int i, c1, c2, nblks;
  9380. int limit_offset, root_offset;
  9381. root_info = set_root_node(fs, outdir->buf, ino, parent);
  9382. root_offset = limit_offset = ((char *) root_info - outdir->buf) +
  9383. root_info->info_length;
  9384. root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
  9385. c1 = root_limit->limit;
  9386. nblks = outdir->num;
  9387. /* Write out the pointer blocks */
  9388. if (nblks-1 <= c1) {
  9389. /* Just write out the root block, and we're done */
  9390. root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
  9391. for (i=1; i < nblks; i++) {
  9392. root->block = ext2fs_cpu_to_le32(i);
  9393. if (i != 1)
  9394. root->hash =
  9395. ext2fs_cpu_to_le32(outdir->hashes[i]);
  9396. root++;
  9397. c1--;
  9398. }
  9399. } else {
  9400. c2 = 0;
  9401. limit = 0;
  9402. root_info->indirect_levels = 1;
  9403. for (i=1; i < nblks; i++) {
  9404. if (c1 == 0)
  9405. return ENOSPC;
  9406. if (c2 == 0) {
  9407. if (limit)
  9408. limit->limit = limit->count =
  9409. ext2fs_cpu_to_le16(limit->limit);
  9410. root = (struct ext2_dx_entry *)
  9411. (outdir->buf + root_offset);
  9412. root->block = ext2fs_cpu_to_le32(outdir->num);
  9413. if (i != 1)
  9414. root->hash =
  9415. ext2fs_cpu_to_le32(outdir->hashes[i]);
  9416. if ((retval = get_next_block(fs, outdir,
  9417. &block_start)))
  9418. return retval;
  9419. dx_ent = set_int_node(fs, block_start);
  9420. limit = (struct ext2_dx_countlimit *) dx_ent;
  9421. c2 = limit->limit;
  9422. root_offset += sizeof(struct ext2_dx_entry);
  9423. c1--;
  9424. }
  9425. dx_ent->block = ext2fs_cpu_to_le32(i);
  9426. if (c2 != limit->limit)
  9427. dx_ent->hash =
  9428. ext2fs_cpu_to_le32(outdir->hashes[i]);
  9429. dx_ent++;
  9430. c2--;
  9431. }
  9432. limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
  9433. limit->limit = ext2fs_cpu_to_le16(limit->limit);
  9434. }
  9435. root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
  9436. root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
  9437. root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
  9438. return 0;
  9439. }
  9440. struct write_dir_struct {
  9441. struct out_dir *outdir;
  9442. errcode_t err;
  9443. e2fsck_t ctx;
  9444. int cleared;
  9445. };
  9446. /*
  9447. * Helper function which writes out a directory block.
  9448. */
  9449. static int write_dir_block(ext2_filsys fs,
  9450. blk_t *block_nr,
  9451. e2_blkcnt_t blockcnt,
  9452. blk_t ref_block FSCK_ATTR((unused)),
  9453. int ref_offset FSCK_ATTR((unused)),
  9454. void *priv_data)
  9455. {
  9456. struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
  9457. blk_t blk;
  9458. char *dir;
  9459. if (*block_nr == 0)
  9460. return 0;
  9461. if (blockcnt >= wd->outdir->num) {
  9462. e2fsck_read_bitmaps(wd->ctx);
  9463. blk = *block_nr;
  9464. ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
  9465. ext2fs_block_alloc_stats(fs, blk, -1);
  9466. *block_nr = 0;
  9467. wd->cleared++;
  9468. return BLOCK_CHANGED;
  9469. }
  9470. if (blockcnt < 0)
  9471. return 0;
  9472. dir = wd->outdir->buf + (blockcnt * fs->blocksize);
  9473. wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
  9474. if (wd->err)
  9475. return BLOCK_ABORT;
  9476. return 0;
  9477. }
  9478. static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
  9479. struct out_dir *outdir,
  9480. ext2_ino_t ino, int compress)
  9481. {
  9482. struct write_dir_struct wd;
  9483. errcode_t retval;
  9484. struct ext2_inode inode;
  9485. retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
  9486. if (retval)
  9487. return retval;
  9488. wd.outdir = outdir;
  9489. wd.err = 0;
  9490. wd.ctx = ctx;
  9491. wd.cleared = 0;
  9492. retval = ext2fs_block_iterate2(fs, ino, 0, 0,
  9493. write_dir_block, &wd);
  9494. if (retval)
  9495. return retval;
  9496. if (wd.err)
  9497. return wd.err;
  9498. e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
  9499. if (compress)
  9500. inode.i_flags &= ~EXT2_INDEX_FL;
  9501. else
  9502. inode.i_flags |= EXT2_INDEX_FL;
  9503. inode.i_size = outdir->num * fs->blocksize;
  9504. inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
  9505. e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
  9506. return 0;
  9507. }
  9508. static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
  9509. {
  9510. ext2_filsys fs = ctx->fs;
  9511. errcode_t retval;
  9512. struct ext2_inode inode;
  9513. char *dir_buf = NULL;
  9514. struct fill_dir_struct fd;
  9515. struct out_dir outdir;
  9516. outdir.max = outdir.num = 0;
  9517. outdir.buf = 0;
  9518. outdir.hashes = 0;
  9519. e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
  9520. retval = ENOMEM;
  9521. fd.harray = 0;
  9522. dir_buf = xmalloc(inode.i_size);
  9523. fd.max_array = inode.i_size / 32;
  9524. fd.num_array = 0;
  9525. fd.harray = xmalloc(fd.max_array * sizeof(struct hash_entry));
  9526. fd.ctx = ctx;
  9527. fd.buf = dir_buf;
  9528. fd.inode = &inode;
  9529. fd.err = 0;
  9530. fd.dir_size = 0;
  9531. fd.compress = 0;
  9532. if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
  9533. (inode.i_size / fs->blocksize) < 2)
  9534. fd.compress = 1;
  9535. fd.parent = 0;
  9536. /* Read in the entire directory into memory */
  9537. retval = ext2fs_block_iterate2(fs, ino, 0, 0,
  9538. fill_dir_block, &fd);
  9539. if (fd.err) {
  9540. retval = fd.err;
  9541. goto errout;
  9542. }
  9543. /* Sort the list */
  9544. resort:
  9545. if (fd.compress)
  9546. qsort(fd.harray+2, fd.num_array-2,
  9547. sizeof(struct hash_entry), name_cmp);
  9548. else
  9549. qsort(fd.harray, fd.num_array,
  9550. sizeof(struct hash_entry), hash_cmp);
  9551. /*
  9552. * Look for duplicates
  9553. */
  9554. if (duplicate_search_and_fix(ctx, fs, ino, &fd))
  9555. goto resort;
  9556. if (ctx->options & E2F_OPT_NO) {
  9557. retval = 0;
  9558. goto errout;
  9559. }
  9560. /*
  9561. * Copy the directory entries. In a htree directory these
  9562. * will become the leaf nodes.
  9563. */
  9564. retval = copy_dir_entries(fs, &fd, &outdir);
  9565. if (retval)
  9566. goto errout;
  9567. free(dir_buf); dir_buf = 0;
  9568. if (!fd.compress) {
  9569. /* Calculate the interior nodes */
  9570. retval = calculate_tree(fs, &outdir, ino, fd.parent);
  9571. if (retval)
  9572. goto errout;
  9573. }
  9574. retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
  9575. errout:
  9576. free(dir_buf);
  9577. free(fd.harray);
  9578. free_out_dir(&outdir);
  9579. return retval;
  9580. }
  9581. void e2fsck_rehash_directories(e2fsck_t ctx)
  9582. {
  9583. struct problem_context pctx;
  9584. struct dir_info *dir;
  9585. ext2_u32_iterate iter;
  9586. ext2_ino_t ino;
  9587. errcode_t retval;
  9588. int i, cur, max, all_dirs, dir_index, first = 1;
  9589. all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
  9590. if (!ctx->dirs_to_hash && !all_dirs)
  9591. return;
  9592. e2fsck_get_lost_and_found(ctx, 0);
  9593. clear_problem_context(&pctx);
  9594. dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
  9595. cur = 0;
  9596. if (all_dirs) {
  9597. i = 0;
  9598. max = e2fsck_get_num_dirinfo(ctx);
  9599. } else {
  9600. retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
  9601. &iter);
  9602. if (retval) {
  9603. pctx.errcode = retval;
  9604. fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
  9605. return;
  9606. }
  9607. max = ext2fs_u32_list_count(ctx->dirs_to_hash);
  9608. }
  9609. while (1) {
  9610. if (all_dirs) {
  9611. if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
  9612. break;
  9613. ino = dir->ino;
  9614. } else {
  9615. if (!ext2fs_u32_list_iterate(iter, &ino))
  9616. break;
  9617. }
  9618. if (ino == ctx->lost_and_found)
  9619. continue;
  9620. pctx.dir = ino;
  9621. if (first) {
  9622. fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
  9623. first = 0;
  9624. }
  9625. pctx.errcode = e2fsck_rehash_dir(ctx, ino);
  9626. if (pctx.errcode) {
  9627. end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
  9628. fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
  9629. }
  9630. if (ctx->progress && !ctx->progress_fd)
  9631. e2fsck_simple_progress(ctx, "Rebuilding directory",
  9632. 100.0 * (float) (++cur) / (float) max, ino);
  9633. }
  9634. end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
  9635. if (!all_dirs)
  9636. ext2fs_u32_list_iterate_end(iter);
  9637. ext2fs_u32_list_free(ctx->dirs_to_hash);
  9638. ctx->dirs_to_hash = 0;
  9639. }
  9640. /*
  9641. * linux/fs/revoke.c
  9642. *
  9643. * Journal revoke routines for the generic filesystem journaling code;
  9644. * part of the ext2fs journaling system.
  9645. *
  9646. * Revoke is the mechanism used to prevent old log records for deleted
  9647. * metadata from being replayed on top of newer data using the same
  9648. * blocks. The revoke mechanism is used in two separate places:
  9649. *
  9650. * + Commit: during commit we write the entire list of the current
  9651. * transaction's revoked blocks to the journal
  9652. *
  9653. * + Recovery: during recovery we record the transaction ID of all
  9654. * revoked blocks. If there are multiple revoke records in the log
  9655. * for a single block, only the last one counts, and if there is a log
  9656. * entry for a block beyond the last revoke, then that log entry still
  9657. * gets replayed.
  9658. *
  9659. * We can get interactions between revokes and new log data within a
  9660. * single transaction:
  9661. *
  9662. * Block is revoked and then journaled:
  9663. * The desired end result is the journaling of the new block, so we
  9664. * cancel the revoke before the transaction commits.
  9665. *
  9666. * Block is journaled and then revoked:
  9667. * The revoke must take precedence over the write of the block, so we
  9668. * need either to cancel the journal entry or to write the revoke
  9669. * later in the log than the log block. In this case, we choose the
  9670. * latter: journaling a block cancels any revoke record for that block
  9671. * in the current transaction, so any revoke for that block in the
  9672. * transaction must have happened after the block was journaled and so
  9673. * the revoke must take precedence.
  9674. *
  9675. * Block is revoked and then written as data:
  9676. * The data write is allowed to succeed, but the revoke is _not_
  9677. * cancelled. We still need to prevent old log records from
  9678. * overwriting the new data. We don't even need to clear the revoke
  9679. * bit here.
  9680. *
  9681. * Revoke information on buffers is a tri-state value:
  9682. *
  9683. * RevokeValid clear: no cached revoke status, need to look it up
  9684. * RevokeValid set, Revoked clear:
  9685. * buffer has not been revoked, and cancel_revoke
  9686. * need do nothing.
  9687. * RevokeValid set, Revoked set:
  9688. * buffer has been revoked.
  9689. */
  9690. static kmem_cache_t *revoke_record_cache;
  9691. static kmem_cache_t *revoke_table_cache;
  9692. /* Each revoke record represents one single revoked block. During
  9693. journal replay, this involves recording the transaction ID of the
  9694. last transaction to revoke this block. */
  9695. struct jbd_revoke_record_s
  9696. {
  9697. struct list_head hash;
  9698. tid_t sequence; /* Used for recovery only */
  9699. unsigned long blocknr;
  9700. };
  9701. /* The revoke table is just a simple hash table of revoke records. */
  9702. struct jbd_revoke_table_s
  9703. {
  9704. /* It is conceivable that we might want a larger hash table
  9705. * for recovery. Must be a power of two. */
  9706. int hash_size;
  9707. int hash_shift;
  9708. struct list_head *hash_table;
  9709. };
  9710. /* Utility functions to maintain the revoke table */
  9711. /* Borrowed from buffer.c: this is a tried and tested block hash function */
  9712. static int hash(journal_t *journal, unsigned long block)
  9713. {
  9714. struct jbd_revoke_table_s *table = journal->j_revoke;
  9715. int hash_shift = table->hash_shift;
  9716. return ((block << (hash_shift - 6)) ^
  9717. (block >> 13) ^
  9718. (block << (hash_shift - 12))) & (table->hash_size - 1);
  9719. }
  9720. static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
  9721. tid_t seq)
  9722. {
  9723. struct list_head *hash_list;
  9724. struct jbd_revoke_record_s *record;
  9725. record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
  9726. if (!record)
  9727. goto oom;
  9728. record->sequence = seq;
  9729. record->blocknr = blocknr;
  9730. hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
  9731. list_add(&record->hash, hash_list);
  9732. return 0;
  9733. oom:
  9734. return -ENOMEM;
  9735. }
  9736. /* Find a revoke record in the journal's hash table. */
  9737. static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
  9738. unsigned long blocknr)
  9739. {
  9740. struct list_head *hash_list;
  9741. struct jbd_revoke_record_s *record;
  9742. hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
  9743. record = (struct jbd_revoke_record_s *) hash_list->next;
  9744. while (&(record->hash) != hash_list) {
  9745. if (record->blocknr == blocknr)
  9746. return record;
  9747. record = (struct jbd_revoke_record_s *) record->hash.next;
  9748. }
  9749. return NULL;
  9750. }
  9751. int journal_init_revoke_caches(void)
  9752. {
  9753. revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s));
  9754. if (revoke_record_cache == 0)
  9755. return -ENOMEM;
  9756. revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s));
  9757. if (revoke_table_cache == 0) {
  9758. do_cache_destroy(revoke_record_cache);
  9759. revoke_record_cache = NULL;
  9760. return -ENOMEM;
  9761. }
  9762. return 0;
  9763. }
  9764. void journal_destroy_revoke_caches(void)
  9765. {
  9766. do_cache_destroy(revoke_record_cache);
  9767. revoke_record_cache = 0;
  9768. do_cache_destroy(revoke_table_cache);
  9769. revoke_table_cache = 0;
  9770. }
  9771. /* Initialise the revoke table for a given journal to a given size. */
  9772. int journal_init_revoke(journal_t *journal, int hash_size)
  9773. {
  9774. int shift, tmp;
  9775. journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
  9776. if (!journal->j_revoke)
  9777. return -ENOMEM;
  9778. /* Check that the hash_size is a power of two */
  9779. journal->j_revoke->hash_size = hash_size;
  9780. shift = 0;
  9781. tmp = hash_size;
  9782. while ((tmp >>= 1UL) != 0UL)
  9783. shift++;
  9784. journal->j_revoke->hash_shift = shift;
  9785. journal->j_revoke->hash_table = xmalloc(hash_size * sizeof(struct list_head));
  9786. for (tmp = 0; tmp < hash_size; tmp++)
  9787. INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
  9788. return 0;
  9789. }
  9790. /* Destoy a journal's revoke table. The table must already be empty! */
  9791. void journal_destroy_revoke(journal_t *journal)
  9792. {
  9793. struct jbd_revoke_table_s *table;
  9794. struct list_head *hash_list;
  9795. int i;
  9796. table = journal->j_revoke;
  9797. if (!table)
  9798. return;
  9799. for (i=0; i<table->hash_size; i++) {
  9800. hash_list = &table->hash_table[i];
  9801. }
  9802. free(table->hash_table);
  9803. free(table);
  9804. journal->j_revoke = NULL;
  9805. }
  9806. /*
  9807. * Revoke support for recovery.
  9808. *
  9809. * Recovery needs to be able to:
  9810. *
  9811. * record all revoke records, including the tid of the latest instance
  9812. * of each revoke in the journal
  9813. *
  9814. * check whether a given block in a given transaction should be replayed
  9815. * (ie. has not been revoked by a revoke record in that or a subsequent
  9816. * transaction)
  9817. *
  9818. * empty the revoke table after recovery.
  9819. */
  9820. /*
  9821. * First, setting revoke records. We create a new revoke record for
  9822. * every block ever revoked in the log as we scan it for recovery, and
  9823. * we update the existing records if we find multiple revokes for a
  9824. * single block.
  9825. */
  9826. int journal_set_revoke(journal_t *journal, unsigned long blocknr,
  9827. tid_t sequence)
  9828. {
  9829. struct jbd_revoke_record_s *record;
  9830. record = find_revoke_record(journal, blocknr);
  9831. if (record) {
  9832. /* If we have multiple occurences, only record the
  9833. * latest sequence number in the hashed record */
  9834. if (tid_gt(sequence, record->sequence))
  9835. record->sequence = sequence;
  9836. return 0;
  9837. }
  9838. return insert_revoke_hash(journal, blocknr, sequence);
  9839. }
  9840. /*
  9841. * Test revoke records. For a given block referenced in the log, has
  9842. * that block been revoked? A revoke record with a given transaction
  9843. * sequence number revokes all blocks in that transaction and earlier
  9844. * ones, but later transactions still need replayed.
  9845. */
  9846. int journal_test_revoke(journal_t *journal, unsigned long blocknr,
  9847. tid_t sequence)
  9848. {
  9849. struct jbd_revoke_record_s *record;
  9850. record = find_revoke_record(journal, blocknr);
  9851. if (!record)
  9852. return 0;
  9853. if (tid_gt(sequence, record->sequence))
  9854. return 0;
  9855. return 1;
  9856. }
  9857. /*
  9858. * Finally, once recovery is over, we need to clear the revoke table so
  9859. * that it can be reused by the running filesystem.
  9860. */
  9861. void journal_clear_revoke(journal_t *journal)
  9862. {
  9863. int i;
  9864. struct list_head *hash_list;
  9865. struct jbd_revoke_record_s *record;
  9866. struct jbd_revoke_table_s *revoke_var;
  9867. revoke_var = journal->j_revoke;
  9868. for (i = 0; i < revoke_var->hash_size; i++) {
  9869. hash_list = &revoke_var->hash_table[i];
  9870. while (!list_empty(hash_list)) {
  9871. record = (struct jbd_revoke_record_s*) hash_list->next;
  9872. list_del(&record->hash);
  9873. free(record);
  9874. }
  9875. }
  9876. }
  9877. /*
  9878. * e2fsck.c - superblock checks
  9879. */
  9880. #define MIN_CHECK 1
  9881. #define MAX_CHECK 2
  9882. static void check_super_value(e2fsck_t ctx, const char *descr,
  9883. unsigned long value, int flags,
  9884. unsigned long min_val, unsigned long max_val)
  9885. {
  9886. struct problem_context pctx;
  9887. if (((flags & MIN_CHECK) && (value < min_val)) ||
  9888. ((flags & MAX_CHECK) && (value > max_val))) {
  9889. clear_problem_context(&pctx);
  9890. pctx.num = value;
  9891. pctx.str = descr;
  9892. fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
  9893. ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
  9894. }
  9895. }
  9896. /*
  9897. * This routine may get stubbed out in special compilations of the
  9898. * e2fsck code..
  9899. */
  9900. #ifndef EXT2_SPECIAL_DEVICE_SIZE
  9901. static errcode_t e2fsck_get_device_size(e2fsck_t ctx)
  9902. {
  9903. return (ext2fs_get_device_size(ctx->filesystem_name,
  9904. EXT2_BLOCK_SIZE(ctx->fs->super),
  9905. &ctx->num_blocks));
  9906. }
  9907. #endif
  9908. /*
  9909. * helper function to release an inode
  9910. */
  9911. struct process_block_struct {
  9912. e2fsck_t ctx;
  9913. char *buf;
  9914. struct problem_context *pctx;
  9915. int truncating;
  9916. int truncate_offset;
  9917. e2_blkcnt_t truncate_block;
  9918. int truncated_blocks;
  9919. int abort;
  9920. errcode_t errcode;
  9921. };
  9922. static int release_inode_block(ext2_filsys fs, blk_t *block_nr,
  9923. e2_blkcnt_t blockcnt,
  9924. blk_t ref_blk FSCK_ATTR((unused)),
  9925. int ref_offset FSCK_ATTR((unused)),
  9926. void *priv_data)
  9927. {
  9928. struct process_block_struct *pb;
  9929. e2fsck_t ctx;
  9930. struct problem_context *pctx;
  9931. blk_t blk = *block_nr;
  9932. int retval = 0;
  9933. pb = (struct process_block_struct *) priv_data;
  9934. ctx = pb->ctx;
  9935. pctx = pb->pctx;
  9936. pctx->blk = blk;
  9937. pctx->blkcount = blockcnt;
  9938. if (HOLE_BLKADDR(blk))
  9939. return 0;
  9940. if ((blk < fs->super->s_first_data_block) ||
  9941. (blk >= fs->super->s_blocks_count)) {
  9942. fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
  9943. return_abort:
  9944. pb->abort = 1;
  9945. return BLOCK_ABORT;
  9946. }
  9947. if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
  9948. fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
  9949. goto return_abort;
  9950. }
  9951. /*
  9952. * If we are deleting an orphan, then we leave the fields alone.
  9953. * If we are truncating an orphan, then update the inode fields
  9954. * and clean up any partial block data.
  9955. */
  9956. if (pb->truncating) {
  9957. /*
  9958. * We only remove indirect blocks if they are
  9959. * completely empty.
  9960. */
  9961. if (blockcnt < 0) {
  9962. int i, limit;
  9963. blk_t *bp;
  9964. pb->errcode = io_channel_read_blk(fs->io, blk, 1,
  9965. pb->buf);
  9966. if (pb->errcode)
  9967. goto return_abort;
  9968. limit = fs->blocksize >> 2;
  9969. for (i = 0, bp = (blk_t *) pb->buf;
  9970. i < limit; i++, bp++)
  9971. if (*bp)
  9972. return 0;
  9973. }
  9974. /*
  9975. * We don't remove direct blocks until we've reached
  9976. * the truncation block.
  9977. */
  9978. if (blockcnt >= 0 && blockcnt < pb->truncate_block)
  9979. return 0;
  9980. /*
  9981. * If part of the last block needs truncating, we do
  9982. * it here.
  9983. */
  9984. if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
  9985. pb->errcode = io_channel_read_blk(fs->io, blk, 1,
  9986. pb->buf);
  9987. if (pb->errcode)
  9988. goto return_abort;
  9989. memset(pb->buf + pb->truncate_offset, 0,
  9990. fs->blocksize - pb->truncate_offset);
  9991. pb->errcode = io_channel_write_blk(fs->io, blk, 1,
  9992. pb->buf);
  9993. if (pb->errcode)
  9994. goto return_abort;
  9995. }
  9996. pb->truncated_blocks++;
  9997. *block_nr = 0;
  9998. retval |= BLOCK_CHANGED;
  9999. }
  10000. ext2fs_block_alloc_stats(fs, blk, -1);
  10001. return retval;
  10002. }
  10003. /*
  10004. * This function releases an inode. Returns 1 if an inconsistency was
  10005. * found. If the inode has a link count, then it is being truncated and
  10006. * not deleted.
  10007. */
  10008. static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
  10009. struct ext2_inode *inode, char *block_buf,
  10010. struct problem_context *pctx)
  10011. {
  10012. struct process_block_struct pb;
  10013. ext2_filsys fs = ctx->fs;
  10014. errcode_t retval;
  10015. __u32 count;
  10016. if (!ext2fs_inode_has_valid_blocks(inode))
  10017. return 0;
  10018. pb.buf = block_buf + 3 * ctx->fs->blocksize;
  10019. pb.ctx = ctx;
  10020. pb.abort = 0;
  10021. pb.errcode = 0;
  10022. pb.pctx = pctx;
  10023. if (inode->i_links_count) {
  10024. pb.truncating = 1;
  10025. pb.truncate_block = (e2_blkcnt_t)
  10026. ((((long long)inode->i_size_high << 32) +
  10027. inode->i_size + fs->blocksize - 1) /
  10028. fs->blocksize);
  10029. pb.truncate_offset = inode->i_size % fs->blocksize;
  10030. } else {
  10031. pb.truncating = 0;
  10032. pb.truncate_block = 0;
  10033. pb.truncate_offset = 0;
  10034. }
  10035. pb.truncated_blocks = 0;
  10036. retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
  10037. block_buf, release_inode_block, &pb);
  10038. if (retval) {
  10039. bb_error_msg(_("while calling ext2fs_block_iterate for inode %d"),
  10040. ino);
  10041. return 1;
  10042. }
  10043. if (pb.abort)
  10044. return 1;
  10045. /* Refresh the inode since ext2fs_block_iterate may have changed it */
  10046. e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
  10047. if (pb.truncated_blocks)
  10048. inode->i_blocks -= pb.truncated_blocks *
  10049. (fs->blocksize / 512);
  10050. if (inode->i_file_acl) {
  10051. retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
  10052. block_buf, -1, &count);
  10053. if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
  10054. retval = 0;
  10055. count = 1;
  10056. }
  10057. if (retval) {
  10058. bb_error_msg(_("while calling ext2fs_adjust_ea_refocunt for inode %d"),
  10059. ino);
  10060. return 1;
  10061. }
  10062. if (count == 0)
  10063. ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
  10064. inode->i_file_acl = 0;
  10065. }
  10066. return 0;
  10067. }
  10068. /*
  10069. * This function releases all of the orphan inodes. It returns 1 if
  10070. * it hit some error, and 0 on success.
  10071. */
  10072. static int release_orphan_inodes(e2fsck_t ctx)
  10073. {
  10074. ext2_filsys fs = ctx->fs;
  10075. ext2_ino_t ino, next_ino;
  10076. struct ext2_inode inode;
  10077. struct problem_context pctx;
  10078. char *block_buf;
  10079. if ((ino = fs->super->s_last_orphan) == 0)
  10080. return 0;
  10081. /*
  10082. * Win or lose, we won't be using the head of the orphan inode
  10083. * list again.
  10084. */
  10085. fs->super->s_last_orphan = 0;
  10086. ext2fs_mark_super_dirty(fs);
  10087. /*
  10088. * If the filesystem contains errors, don't run the orphan
  10089. * list, since the orphan list can't be trusted; and we're
  10090. * going to be running a full e2fsck run anyway...
  10091. */
  10092. if (fs->super->s_state & EXT2_ERROR_FS)
  10093. return 0;
  10094. if ((ino < EXT2_FIRST_INODE(fs->super)) ||
  10095. (ino > fs->super->s_inodes_count)) {
  10096. clear_problem_context(&pctx);
  10097. pctx.ino = ino;
  10098. fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
  10099. return 1;
  10100. }
  10101. block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
  10102. "block iterate buffer");
  10103. e2fsck_read_bitmaps(ctx);
  10104. while (ino) {
  10105. e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
  10106. clear_problem_context(&pctx);
  10107. pctx.ino = ino;
  10108. pctx.inode = &inode;
  10109. pctx.str = inode.i_links_count ? _("Truncating") :
  10110. _("Clearing");
  10111. fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
  10112. next_ino = inode.i_dtime;
  10113. if (next_ino &&
  10114. ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
  10115. (next_ino > fs->super->s_inodes_count))) {
  10116. pctx.ino = next_ino;
  10117. fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
  10118. goto return_abort;
  10119. }
  10120. if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
  10121. goto return_abort;
  10122. if (!inode.i_links_count) {
  10123. ext2fs_inode_alloc_stats2(fs, ino, -1,
  10124. LINUX_S_ISDIR(inode.i_mode));
  10125. inode.i_dtime = time(NULL);
  10126. } else {
  10127. inode.i_dtime = 0;
  10128. }
  10129. e2fsck_write_inode(ctx, ino, &inode, "delete_file");
  10130. ino = next_ino;
  10131. }
  10132. ext2fs_free_mem(&block_buf);
  10133. return 0;
  10134. return_abort:
  10135. ext2fs_free_mem(&block_buf);
  10136. return 1;
  10137. }
  10138. /*
  10139. * Check the resize inode to make sure it is sane. We check both for
  10140. * the case where on-line resizing is not enabled (in which case the
  10141. * resize inode should be cleared) as well as the case where on-line
  10142. * resizing is enabled.
  10143. */
  10144. static void check_resize_inode(e2fsck_t ctx)
  10145. {
  10146. ext2_filsys fs = ctx->fs;
  10147. struct ext2_inode inode;
  10148. struct problem_context pctx;
  10149. int i, j, gdt_off, ind_off;
  10150. blk_t blk, pblk, expect;
  10151. __u32 *dind_buf = NULL, *ind_buf;
  10152. errcode_t retval;
  10153. clear_problem_context(&pctx);
  10154. /*
  10155. * If the resize inode feature isn't set, then
  10156. * s_reserved_gdt_blocks must be zero.
  10157. */
  10158. if (!(fs->super->s_feature_compat &
  10159. EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
  10160. if (fs->super->s_reserved_gdt_blocks) {
  10161. pctx.num = fs->super->s_reserved_gdt_blocks;
  10162. if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
  10163. &pctx)) {
  10164. fs->super->s_reserved_gdt_blocks = 0;
  10165. ext2fs_mark_super_dirty(fs);
  10166. }
  10167. }
  10168. }
  10169. /* Read the resize inode */
  10170. pctx.ino = EXT2_RESIZE_INO;
  10171. retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
  10172. if (retval) {
  10173. if (fs->super->s_feature_compat &
  10174. EXT2_FEATURE_COMPAT_RESIZE_INODE)
  10175. ctx->flags |= E2F_FLAG_RESIZE_INODE;
  10176. return;
  10177. }
  10178. /*
  10179. * If the resize inode feature isn't set, check to make sure
  10180. * the resize inode is cleared; then we're done.
  10181. */
  10182. if (!(fs->super->s_feature_compat &
  10183. EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
  10184. for (i=0; i < EXT2_N_BLOCKS; i++) {
  10185. if (inode.i_block[i])
  10186. break;
  10187. }
  10188. if ((i < EXT2_N_BLOCKS) &&
  10189. fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
  10190. memset(&inode, 0, sizeof(inode));
  10191. e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
  10192. "clear_resize");
  10193. }
  10194. return;
  10195. }
  10196. /*
  10197. * The resize inode feature is enabled; check to make sure the
  10198. * only block in use is the double indirect block
  10199. */
  10200. blk = inode.i_block[EXT2_DIND_BLOCK];
  10201. for (i=0; i < EXT2_N_BLOCKS; i++) {
  10202. if (i != EXT2_DIND_BLOCK && inode.i_block[i])
  10203. break;
  10204. }
  10205. if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
  10206. !(inode.i_mode & LINUX_S_IFREG) ||
  10207. (blk < fs->super->s_first_data_block ||
  10208. blk >= fs->super->s_blocks_count)) {
  10209. resize_inode_invalid:
  10210. if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
  10211. memset(&inode, 0, sizeof(inode));
  10212. e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
  10213. "clear_resize");
  10214. ctx->flags |= E2F_FLAG_RESIZE_INODE;
  10215. }
  10216. if (!(ctx->options & E2F_OPT_READONLY)) {
  10217. fs->super->s_state &= ~EXT2_VALID_FS;
  10218. ext2fs_mark_super_dirty(fs);
  10219. }
  10220. goto cleanup;
  10221. }
  10222. dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
  10223. "resize dind buffer");
  10224. ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
  10225. retval = ext2fs_read_ind_block(fs, blk, dind_buf);
  10226. if (retval)
  10227. goto resize_inode_invalid;
  10228. gdt_off = fs->desc_blocks;
  10229. pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
  10230. for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
  10231. i++, gdt_off++, pblk++) {
  10232. gdt_off %= fs->blocksize/4;
  10233. if (dind_buf[gdt_off] != pblk)
  10234. goto resize_inode_invalid;
  10235. retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
  10236. if (retval)
  10237. goto resize_inode_invalid;
  10238. ind_off = 0;
  10239. for (j = 1; j < fs->group_desc_count; j++) {
  10240. if (!ext2fs_bg_has_super(fs, j))
  10241. continue;
  10242. expect = pblk + (j * fs->super->s_blocks_per_group);
  10243. if (ind_buf[ind_off] != expect)
  10244. goto resize_inode_invalid;
  10245. ind_off++;
  10246. }
  10247. }
  10248. cleanup:
  10249. ext2fs_free_mem(&dind_buf);
  10250. }
  10251. static void check_super_block(e2fsck_t ctx)
  10252. {
  10253. ext2_filsys fs = ctx->fs;
  10254. blk_t first_block, last_block;
  10255. struct ext2_super_block *sb = fs->super;
  10256. struct ext2_group_desc *gd;
  10257. blk_t blocks_per_group = fs->super->s_blocks_per_group;
  10258. blk_t bpg_max;
  10259. int inodes_per_block;
  10260. int ipg_max;
  10261. int inode_size;
  10262. dgrp_t i;
  10263. blk_t should_be;
  10264. struct problem_context pctx;
  10265. __u32 free_blocks = 0, free_inodes = 0;
  10266. inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
  10267. ipg_max = inodes_per_block * (blocks_per_group - 4);
  10268. if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
  10269. ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
  10270. bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
  10271. if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
  10272. bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
  10273. ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
  10274. sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
  10275. ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
  10276. sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
  10277. ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
  10278. sizeof(int) * fs->group_desc_count, "invalid_inode_table");
  10279. clear_problem_context(&pctx);
  10280. /*
  10281. * Verify the super block constants...
  10282. */
  10283. check_super_value(ctx, "inodes_count", sb->s_inodes_count,
  10284. MIN_CHECK, 1, 0);
  10285. check_super_value(ctx, "blocks_count", sb->s_blocks_count,
  10286. MIN_CHECK, 1, 0);
  10287. check_super_value(ctx, "first_data_block", sb->s_first_data_block,
  10288. MAX_CHECK, 0, sb->s_blocks_count);
  10289. check_super_value(ctx, "log_block_size", sb->s_log_block_size,
  10290. MIN_CHECK | MAX_CHECK, 0,
  10291. EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
  10292. check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
  10293. MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
  10294. check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
  10295. MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
  10296. bpg_max);
  10297. check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
  10298. MIN_CHECK | MAX_CHECK, 8, bpg_max);
  10299. check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
  10300. MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
  10301. check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
  10302. MAX_CHECK, 0, sb->s_blocks_count / 2);
  10303. check_super_value(ctx, "reserved_gdt_blocks",
  10304. sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
  10305. fs->blocksize/4);
  10306. inode_size = EXT2_INODE_SIZE(sb);
  10307. check_super_value(ctx, "inode_size",
  10308. inode_size, MIN_CHECK | MAX_CHECK,
  10309. EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
  10310. if (inode_size & (inode_size - 1)) {
  10311. pctx.num = inode_size;
  10312. pctx.str = "inode_size";
  10313. fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
  10314. ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
  10315. return;
  10316. }
  10317. if (!ctx->num_blocks) {
  10318. pctx.errcode = e2fsck_get_device_size(ctx);
  10319. if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
  10320. fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
  10321. ctx->flags |= E2F_FLAG_ABORT;
  10322. return;
  10323. }
  10324. if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
  10325. (ctx->num_blocks < sb->s_blocks_count)) {
  10326. pctx.blk = sb->s_blocks_count;
  10327. pctx.blk2 = ctx->num_blocks;
  10328. if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
  10329. ctx->flags |= E2F_FLAG_ABORT;
  10330. return;
  10331. }
  10332. }
  10333. }
  10334. if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
  10335. pctx.blk = EXT2_BLOCK_SIZE(sb);
  10336. pctx.blk2 = EXT2_FRAG_SIZE(sb);
  10337. fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
  10338. ctx->flags |= E2F_FLAG_ABORT;
  10339. return;
  10340. }
  10341. should_be = sb->s_frags_per_group >>
  10342. (sb->s_log_block_size - sb->s_log_frag_size);
  10343. if (sb->s_blocks_per_group != should_be) {
  10344. pctx.blk = sb->s_blocks_per_group;
  10345. pctx.blk2 = should_be;
  10346. fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
  10347. ctx->flags |= E2F_FLAG_ABORT;
  10348. return;
  10349. }
  10350. should_be = (sb->s_log_block_size == 0) ? 1 : 0;
  10351. if (sb->s_first_data_block != should_be) {
  10352. pctx.blk = sb->s_first_data_block;
  10353. pctx.blk2 = should_be;
  10354. fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
  10355. ctx->flags |= E2F_FLAG_ABORT;
  10356. return;
  10357. }
  10358. should_be = sb->s_inodes_per_group * fs->group_desc_count;
  10359. if (sb->s_inodes_count != should_be) {
  10360. pctx.ino = sb->s_inodes_count;
  10361. pctx.ino2 = should_be;
  10362. if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
  10363. sb->s_inodes_count = should_be;
  10364. ext2fs_mark_super_dirty(fs);
  10365. }
  10366. }
  10367. /*
  10368. * Verify the group descriptors....
  10369. */
  10370. first_block = sb->s_first_data_block;
  10371. last_block = first_block + blocks_per_group;
  10372. for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
  10373. pctx.group = i;
  10374. if (i == fs->group_desc_count - 1)
  10375. last_block = sb->s_blocks_count;
  10376. if ((gd->bg_block_bitmap < first_block) ||
  10377. (gd->bg_block_bitmap >= last_block)) {
  10378. pctx.blk = gd->bg_block_bitmap;
  10379. if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
  10380. gd->bg_block_bitmap = 0;
  10381. }
  10382. if (gd->bg_block_bitmap == 0) {
  10383. ctx->invalid_block_bitmap_flag[i]++;
  10384. ctx->invalid_bitmaps++;
  10385. }
  10386. if ((gd->bg_inode_bitmap < first_block) ||
  10387. (gd->bg_inode_bitmap >= last_block)) {
  10388. pctx.blk = gd->bg_inode_bitmap;
  10389. if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
  10390. gd->bg_inode_bitmap = 0;
  10391. }
  10392. if (gd->bg_inode_bitmap == 0) {
  10393. ctx->invalid_inode_bitmap_flag[i]++;
  10394. ctx->invalid_bitmaps++;
  10395. }
  10396. if ((gd->bg_inode_table < first_block) ||
  10397. ((gd->bg_inode_table +
  10398. fs->inode_blocks_per_group - 1) >= last_block)) {
  10399. pctx.blk = gd->bg_inode_table;
  10400. if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
  10401. gd->bg_inode_table = 0;
  10402. }
  10403. if (gd->bg_inode_table == 0) {
  10404. ctx->invalid_inode_table_flag[i]++;
  10405. ctx->invalid_bitmaps++;
  10406. }
  10407. free_blocks += gd->bg_free_blocks_count;
  10408. free_inodes += gd->bg_free_inodes_count;
  10409. first_block += sb->s_blocks_per_group;
  10410. last_block += sb->s_blocks_per_group;
  10411. if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
  10412. (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
  10413. (gd->bg_used_dirs_count > sb->s_inodes_per_group))
  10414. ext2fs_unmark_valid(fs);
  10415. }
  10416. /*
  10417. * Update the global counts from the block group counts. This
  10418. * is needed for an experimental patch which eliminates
  10419. * locking the entire filesystem when allocating blocks or
  10420. * inodes; if the filesystem is not unmounted cleanly, the
  10421. * global counts may not be accurate.
  10422. */
  10423. if ((free_blocks != sb->s_free_blocks_count) ||
  10424. (free_inodes != sb->s_free_inodes_count)) {
  10425. if (ctx->options & E2F_OPT_READONLY)
  10426. ext2fs_unmark_valid(fs);
  10427. else {
  10428. sb->s_free_blocks_count = free_blocks;
  10429. sb->s_free_inodes_count = free_inodes;
  10430. ext2fs_mark_super_dirty(fs);
  10431. }
  10432. }
  10433. if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
  10434. (sb->s_free_inodes_count > sb->s_inodes_count))
  10435. ext2fs_unmark_valid(fs);
  10436. /*
  10437. * If we have invalid bitmaps, set the error state of the
  10438. * filesystem.
  10439. */
  10440. if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
  10441. sb->s_state &= ~EXT2_VALID_FS;
  10442. ext2fs_mark_super_dirty(fs);
  10443. }
  10444. clear_problem_context(&pctx);
  10445. /*
  10446. * If the UUID field isn't assigned, assign it.
  10447. */
  10448. if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
  10449. if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
  10450. uuid_generate(sb->s_uuid);
  10451. ext2fs_mark_super_dirty(fs);
  10452. fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
  10453. }
  10454. }
  10455. /* FIXME - HURD support?
  10456. * For the Hurd, check to see if the filetype option is set,
  10457. * since it doesn't support it.
  10458. */
  10459. if (!(ctx->options & E2F_OPT_READONLY) &&
  10460. fs->super->s_creator_os == EXT2_OS_HURD &&
  10461. (fs->super->s_feature_incompat &
  10462. EXT2_FEATURE_INCOMPAT_FILETYPE)) {
  10463. if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
  10464. fs->super->s_feature_incompat &=
  10465. ~EXT2_FEATURE_INCOMPAT_FILETYPE;
  10466. ext2fs_mark_super_dirty(fs);
  10467. }
  10468. }
  10469. /*
  10470. * If we have any of the compatibility flags set, we need to have a
  10471. * revision 1 filesystem. Most kernels will not check the flags on
  10472. * a rev 0 filesystem and we may have corruption issues because of
  10473. * the incompatible changes to the filesystem.
  10474. */
  10475. if (!(ctx->options & E2F_OPT_READONLY) &&
  10476. fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
  10477. (fs->super->s_feature_compat ||
  10478. fs->super->s_feature_ro_compat ||
  10479. fs->super->s_feature_incompat) &&
  10480. fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
  10481. ext2fs_update_dynamic_rev(fs);
  10482. ext2fs_mark_super_dirty(fs);
  10483. }
  10484. check_resize_inode(ctx);
  10485. /*
  10486. * Clean up any orphan inodes, if present.
  10487. */
  10488. if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
  10489. fs->super->s_state &= ~EXT2_VALID_FS;
  10490. ext2fs_mark_super_dirty(fs);
  10491. }
  10492. /*
  10493. * Move the ext3 journal file, if necessary.
  10494. */
  10495. e2fsck_move_ext3_journal(ctx);
  10496. }
  10497. /*
  10498. * swapfs.c --- byte-swap an ext2 filesystem
  10499. */
  10500. #ifdef ENABLE_SWAPFS
  10501. struct swap_block_struct {
  10502. ext2_ino_t ino;
  10503. int isdir;
  10504. errcode_t errcode;
  10505. char *dir_buf;
  10506. struct ext2_inode *inode;
  10507. };
  10508. /*
  10509. * This is a helper function for block_iterate. We mark all of the
  10510. * indirect and direct blocks as changed, so that block_iterate will
  10511. * write them out.
  10512. */
  10513. static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
  10514. void *priv_data)
  10515. {
  10516. errcode_t retval;
  10517. struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
  10518. if (sb->isdir && (blockcnt >= 0) && *block_nr) {
  10519. retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
  10520. if (retval) {
  10521. sb->errcode = retval;
  10522. return BLOCK_ABORT;
  10523. }
  10524. retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
  10525. if (retval) {
  10526. sb->errcode = retval;
  10527. return BLOCK_ABORT;
  10528. }
  10529. }
  10530. if (blockcnt >= 0) {
  10531. if (blockcnt < EXT2_NDIR_BLOCKS)
  10532. return 0;
  10533. return BLOCK_CHANGED;
  10534. }
  10535. if (blockcnt == BLOCK_COUNT_IND) {
  10536. if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
  10537. return 0;
  10538. return BLOCK_CHANGED;
  10539. }
  10540. if (blockcnt == BLOCK_COUNT_DIND) {
  10541. if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
  10542. return 0;
  10543. return BLOCK_CHANGED;
  10544. }
  10545. if (blockcnt == BLOCK_COUNT_TIND) {
  10546. if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
  10547. return 0;
  10548. return BLOCK_CHANGED;
  10549. }
  10550. return BLOCK_CHANGED;
  10551. }
  10552. /*
  10553. * This function is responsible for byte-swapping all of the indirect,
  10554. * block pointers. It is also responsible for byte-swapping directories.
  10555. */
  10556. static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
  10557. struct ext2_inode *inode)
  10558. {
  10559. errcode_t retval;
  10560. struct swap_block_struct sb;
  10561. sb.ino = ino;
  10562. sb.inode = inode;
  10563. sb.dir_buf = block_buf + ctx->fs->blocksize*3;
  10564. sb.errcode = 0;
  10565. sb.isdir = 0;
  10566. if (LINUX_S_ISDIR(inode->i_mode))
  10567. sb.isdir = 1;
  10568. retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
  10569. swap_block, &sb);
  10570. if (retval) {
  10571. bb_error_msg(_("while calling ext2fs_block_iterate"));
  10572. ctx->flags |= E2F_FLAG_ABORT;
  10573. return;
  10574. }
  10575. if (sb.errcode) {
  10576. bb_error_msg(_("while calling iterator function"));
  10577. ctx->flags |= E2F_FLAG_ABORT;
  10578. return;
  10579. }
  10580. }
  10581. static void swap_inodes(e2fsck_t ctx)
  10582. {
  10583. ext2_filsys fs = ctx->fs;
  10584. dgrp_t group;
  10585. unsigned int i;
  10586. ext2_ino_t ino = 1;
  10587. char *buf, *block_buf;
  10588. errcode_t retval;
  10589. struct ext2_inode * inode;
  10590. e2fsck_use_inode_shortcuts(ctx, 1);
  10591. retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
  10592. &buf);
  10593. if (retval) {
  10594. bb_error_msg(_("while allocating inode buffer"));
  10595. ctx->flags |= E2F_FLAG_ABORT;
  10596. return;
  10597. }
  10598. block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
  10599. "block interate buffer");
  10600. for (group = 0; group < fs->group_desc_count; group++) {
  10601. retval = io_channel_read_blk(fs->io,
  10602. fs->group_desc[group].bg_inode_table,
  10603. fs->inode_blocks_per_group, buf);
  10604. if (retval) {
  10605. bb_error_msg(_("while reading inode table (group %d)"),
  10606. group);
  10607. ctx->flags |= E2F_FLAG_ABORT;
  10608. return;
  10609. }
  10610. inode = (struct ext2_inode *) buf;
  10611. for (i=0; i < fs->super->s_inodes_per_group;
  10612. i++, ino++, inode++) {
  10613. ctx->stashed_ino = ino;
  10614. ctx->stashed_inode = inode;
  10615. if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
  10616. ext2fs_swap_inode(fs, inode, inode, 0);
  10617. /*
  10618. * Skip deleted files.
  10619. */
  10620. if (inode->i_links_count == 0)
  10621. continue;
  10622. if (LINUX_S_ISDIR(inode->i_mode) ||
  10623. ((inode->i_block[EXT2_IND_BLOCK] ||
  10624. inode->i_block[EXT2_DIND_BLOCK] ||
  10625. inode->i_block[EXT2_TIND_BLOCK]) &&
  10626. ext2fs_inode_has_valid_blocks(inode)))
  10627. swap_inode_blocks(ctx, ino, block_buf, inode);
  10628. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  10629. return;
  10630. if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
  10631. ext2fs_swap_inode(fs, inode, inode, 1);
  10632. }
  10633. retval = io_channel_write_blk(fs->io,
  10634. fs->group_desc[group].bg_inode_table,
  10635. fs->inode_blocks_per_group, buf);
  10636. if (retval) {
  10637. bb_error_msg(_("while writing inode table (group %d)"),
  10638. group);
  10639. ctx->flags |= E2F_FLAG_ABORT;
  10640. return;
  10641. }
  10642. }
  10643. ext2fs_free_mem(&buf);
  10644. ext2fs_free_mem(&block_buf);
  10645. e2fsck_use_inode_shortcuts(ctx, 0);
  10646. ext2fs_flush_icache(fs);
  10647. }
  10648. #if defined(__powerpc__) && BB_BIG_ENDIAN
  10649. /*
  10650. * On the PowerPC, the big-endian variant of the ext2 filesystem
  10651. * has its bitmaps stored as 32-bit words with bit 0 as the LSB
  10652. * of each word. Thus a bitmap with only bit 0 set would be, as
  10653. * a string of bytes, 00 00 00 01 00 ...
  10654. * To cope with this, we byte-reverse each word of a bitmap if
  10655. * we have a big-endian filesystem, that is, if we are *not*
  10656. * byte-swapping other word-sized numbers.
  10657. */
  10658. #define EXT2_BIG_ENDIAN_BITMAPS
  10659. #endif
  10660. #ifdef EXT2_BIG_ENDIAN_BITMAPS
  10661. static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
  10662. {
  10663. __u32 *p = (__u32 *) bmap->bitmap;
  10664. int n, nbytes = (bmap->end - bmap->start + 7) / 8;
  10665. for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
  10666. *p = ext2fs_swab32(*p);
  10667. }
  10668. #endif
  10669. #ifdef ENABLE_SWAPFS
  10670. static void swap_filesys(e2fsck_t ctx)
  10671. {
  10672. ext2_filsys fs = ctx->fs;
  10673. if (!(ctx->options & E2F_OPT_PREEN))
  10674. printf(_("Pass 0: Doing byte-swap of filesystem\n"));
  10675. /* Byte swap */
  10676. if (fs->super->s_mnt_count) {
  10677. fprintf(stderr, _("%s: the filesystem must be freshly "
  10678. "checked using fsck\n"
  10679. "and not mounted before trying to "
  10680. "byte-swap it.\n"), ctx->device_name);
  10681. ctx->flags |= E2F_FLAG_ABORT;
  10682. return;
  10683. }
  10684. if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
  10685. fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
  10686. EXT2_FLAG_SWAP_BYTES_WRITE);
  10687. fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
  10688. } else {
  10689. fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
  10690. fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
  10691. }
  10692. swap_inodes(ctx);
  10693. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  10694. return;
  10695. if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
  10696. fs->flags |= EXT2_FLAG_SWAP_BYTES;
  10697. fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
  10698. EXT2_FLAG_SWAP_BYTES_WRITE);
  10699. #ifdef EXT2_BIG_ENDIAN_BITMAPS
  10700. e2fsck_read_bitmaps(ctx);
  10701. ext2fs_swap_bitmap(fs->inode_map);
  10702. ext2fs_swap_bitmap(fs->block_map);
  10703. fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
  10704. #endif
  10705. fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
  10706. ext2fs_flush(fs);
  10707. fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
  10708. }
  10709. #endif /* ENABLE_SWAPFS */
  10710. #endif
  10711. /*
  10712. * util.c --- miscellaneous utilities
  10713. */
  10714. void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
  10715. const char *description)
  10716. {
  10717. void *ret;
  10718. char buf[256];
  10719. ret = xzalloc(size);
  10720. return ret;
  10721. }
  10722. static char *string_copy(const char *str, int len)
  10723. {
  10724. char *ret;
  10725. if (!str)
  10726. return NULL;
  10727. if (!len)
  10728. len = strlen(str);
  10729. ret = xmalloc(len+1);
  10730. strncpy(ret, str, len);
  10731. ret[len] = 0;
  10732. return ret;
  10733. }
  10734. #ifndef HAVE_CONIO_H
  10735. static int read_a_char(void)
  10736. {
  10737. char c;
  10738. int r;
  10739. int fail = 0;
  10740. while (1) {
  10741. if (e2fsck_global_ctx &&
  10742. (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
  10743. return 3;
  10744. }
  10745. r = read(0, &c, 1);
  10746. if (r == 1)
  10747. return c;
  10748. if (fail++ > 100)
  10749. break;
  10750. }
  10751. return EOF;
  10752. }
  10753. #endif
  10754. static int ask_yn(const char * string, int def)
  10755. {
  10756. int c;
  10757. const char *defstr;
  10758. static const char short_yes[] = "yY";
  10759. static const char short_no[] = "nN";
  10760. #ifdef HAVE_TERMIOS_H
  10761. struct termios termios, tmp;
  10762. tcgetattr (0, &termios);
  10763. tmp = termios;
  10764. tmp.c_lflag &= ~(ICANON | ECHO);
  10765. tmp.c_cc[VMIN] = 1;
  10766. tmp.c_cc[VTIME] = 0;
  10767. tcsetattr_stdin_TCSANOW(&tmp);
  10768. #endif
  10769. if (def == 1)
  10770. defstr = "<y>";
  10771. else if (def == 0)
  10772. defstr = "<n>";
  10773. else
  10774. defstr = " (y/n)";
  10775. printf("%s%s? ", string, defstr);
  10776. while (1) {
  10777. fflush (stdout);
  10778. if ((c = read_a_char()) == EOF)
  10779. break;
  10780. if (c == 3) {
  10781. #ifdef HAVE_TERMIOS_H
  10782. tcsetattr_stdin_TCSANOW(&termios);
  10783. #endif
  10784. if (e2fsck_global_ctx &&
  10785. e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
  10786. puts("\n");
  10787. longjmp(e2fsck_global_ctx->abort_loc, 1);
  10788. }
  10789. puts(_("cancelled!\n"));
  10790. return 0;
  10791. }
  10792. if (strchr(short_yes, (char) c)) {
  10793. def = 1;
  10794. break;
  10795. }
  10796. else if (strchr(short_no, (char) c)) {
  10797. def = 0;
  10798. break;
  10799. }
  10800. else if ((c == ' ' || c == '\n') && (def != -1))
  10801. break;
  10802. }
  10803. if (def)
  10804. puts("yes\n");
  10805. else
  10806. puts ("no\n");
  10807. #ifdef HAVE_TERMIOS_H
  10808. tcsetattr_stdin_TCSANOW(&termios);
  10809. #endif
  10810. return def;
  10811. }
  10812. int ask (e2fsck_t ctx, const char * string, int def)
  10813. {
  10814. if (ctx->options & E2F_OPT_NO) {
  10815. printf(_("%s? no\n\n"), string);
  10816. return 0;
  10817. }
  10818. if (ctx->options & E2F_OPT_YES) {
  10819. printf(_("%s? yes\n\n"), string);
  10820. return 1;
  10821. }
  10822. if (ctx->options & E2F_OPT_PREEN) {
  10823. printf("%s? %s\n\n", string, def ? _("yes") : _("no"));
  10824. return def;
  10825. }
  10826. return ask_yn(string, def);
  10827. }
  10828. void e2fsck_read_bitmaps(e2fsck_t ctx)
  10829. {
  10830. ext2_filsys fs = ctx->fs;
  10831. errcode_t retval;
  10832. if (ctx->invalid_bitmaps) {
  10833. bb_error_msg(_("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
  10834. ctx->device_name);
  10835. bb_error_msg_and_die(0);
  10836. }
  10837. ehandler_operation(_("reading inode and block bitmaps"));
  10838. retval = ext2fs_read_bitmaps(fs);
  10839. ehandler_operation(0);
  10840. if (retval) {
  10841. bb_error_msg(_("while retrying to read bitmaps for %s"),
  10842. ctx->device_name);
  10843. bb_error_msg_and_die(0);
  10844. }
  10845. }
  10846. static void e2fsck_write_bitmaps(e2fsck_t ctx)
  10847. {
  10848. ext2_filsys fs = ctx->fs;
  10849. errcode_t retval;
  10850. if (ext2fs_test_bb_dirty(fs)) {
  10851. ehandler_operation(_("writing block bitmaps"));
  10852. retval = ext2fs_write_block_bitmap(fs);
  10853. ehandler_operation(0);
  10854. if (retval) {
  10855. bb_error_msg(_("while retrying to write block bitmaps for %s"),
  10856. ctx->device_name);
  10857. bb_error_msg_and_die(0);
  10858. }
  10859. }
  10860. if (ext2fs_test_ib_dirty(fs)) {
  10861. ehandler_operation(_("writing inode bitmaps"));
  10862. retval = ext2fs_write_inode_bitmap(fs);
  10863. ehandler_operation(0);
  10864. if (retval) {
  10865. bb_error_msg(_("while retrying to write inode bitmaps for %s"),
  10866. ctx->device_name);
  10867. bb_error_msg_and_die(0);
  10868. }
  10869. }
  10870. }
  10871. void preenhalt(e2fsck_t ctx)
  10872. {
  10873. ext2_filsys fs = ctx->fs;
  10874. if (!(ctx->options & E2F_OPT_PREEN))
  10875. return;
  10876. fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
  10877. "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
  10878. ctx->device_name);
  10879. if (fs != NULL) {
  10880. fs->super->s_state |= EXT2_ERROR_FS;
  10881. ext2fs_mark_super_dirty(fs);
  10882. ext2fs_close(fs);
  10883. }
  10884. exit(EXIT_UNCORRECTED);
  10885. }
  10886. void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
  10887. struct ext2_inode * inode, const char *proc)
  10888. {
  10889. int retval;
  10890. retval = ext2fs_read_inode(ctx->fs, ino, inode);
  10891. if (retval) {
  10892. bb_error_msg(_("while reading inode %ld in %s"), ino, proc);
  10893. bb_error_msg_and_die(0);
  10894. }
  10895. }
  10896. extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
  10897. struct ext2_inode * inode, int bufsize,
  10898. const char *proc)
  10899. {
  10900. int retval;
  10901. retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
  10902. if (retval) {
  10903. bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
  10904. bb_error_msg_and_die(0);
  10905. }
  10906. }
  10907. extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
  10908. struct ext2_inode * inode, const char *proc)
  10909. {
  10910. int retval;
  10911. retval = ext2fs_write_inode(ctx->fs, ino, inode);
  10912. if (retval) {
  10913. bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
  10914. bb_error_msg_and_die(0);
  10915. }
  10916. }
  10917. blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
  10918. io_manager manager)
  10919. {
  10920. struct ext2_super_block *sb;
  10921. io_channel io = NULL;
  10922. void *buf = NULL;
  10923. int blocksize;
  10924. blk_t superblock, ret_sb = 8193;
  10925. if (fs && fs->super) {
  10926. ret_sb = (fs->super->s_blocks_per_group +
  10927. fs->super->s_first_data_block);
  10928. if (ctx) {
  10929. ctx->superblock = ret_sb;
  10930. ctx->blocksize = fs->blocksize;
  10931. }
  10932. return ret_sb;
  10933. }
  10934. if (ctx) {
  10935. if (ctx->blocksize) {
  10936. ret_sb = ctx->blocksize * 8;
  10937. if (ctx->blocksize == 1024)
  10938. ret_sb++;
  10939. ctx->superblock = ret_sb;
  10940. return ret_sb;
  10941. }
  10942. ctx->superblock = ret_sb;
  10943. ctx->blocksize = 1024;
  10944. }
  10945. if (!name || !manager)
  10946. goto cleanup;
  10947. if (manager->open(name, 0, &io) != 0)
  10948. goto cleanup;
  10949. if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
  10950. goto cleanup;
  10951. sb = (struct ext2_super_block *) buf;
  10952. for (blocksize = EXT2_MIN_BLOCK_SIZE;
  10953. blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
  10954. superblock = blocksize*8;
  10955. if (blocksize == 1024)
  10956. superblock++;
  10957. io_channel_set_blksize(io, blocksize);
  10958. if (io_channel_read_blk(io, superblock,
  10959. -SUPERBLOCK_SIZE, buf))
  10960. continue;
  10961. #if BB_BIG_ENDIAN
  10962. if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
  10963. ext2fs_swap_super(sb);
  10964. #endif
  10965. if (sb->s_magic == EXT2_SUPER_MAGIC) {
  10966. ret_sb = superblock;
  10967. if (ctx) {
  10968. ctx->superblock = superblock;
  10969. ctx->blocksize = blocksize;
  10970. }
  10971. break;
  10972. }
  10973. }
  10974. cleanup:
  10975. if (io)
  10976. io_channel_close(io);
  10977. ext2fs_free_mem(&buf);
  10978. return ret_sb;
  10979. }
  10980. /*
  10981. * This function runs through the e2fsck passes and calls them all,
  10982. * returning restart, abort, or cancel as necessary...
  10983. */
  10984. typedef void (*pass_t)(e2fsck_t ctx);
  10985. static const pass_t e2fsck_passes[] = {
  10986. e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
  10987. e2fsck_pass5, 0 };
  10988. #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
  10989. static int e2fsck_run(e2fsck_t ctx)
  10990. {
  10991. int i;
  10992. pass_t e2fsck_pass;
  10993. if (setjmp(ctx->abort_loc)) {
  10994. ctx->flags &= ~E2F_FLAG_SETJMP_OK;
  10995. return (ctx->flags & E2F_FLAG_RUN_RETURN);
  10996. }
  10997. ctx->flags |= E2F_FLAG_SETJMP_OK;
  10998. for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
  10999. if (ctx->flags & E2F_FLAG_RUN_RETURN)
  11000. break;
  11001. e2fsck_pass(ctx);
  11002. if (ctx->progress)
  11003. (void) (ctx->progress)(ctx, 0, 0, 0);
  11004. }
  11005. ctx->flags &= ~E2F_FLAG_SETJMP_OK;
  11006. if (ctx->flags & E2F_FLAG_RUN_RETURN)
  11007. return (ctx->flags & E2F_FLAG_RUN_RETURN);
  11008. return 0;
  11009. }
  11010. /*
  11011. * unix.c - The unix-specific code for e2fsck
  11012. */
  11013. /* Command line options */
  11014. static int swapfs;
  11015. #ifdef ENABLE_SWAPFS
  11016. static int normalize_swapfs;
  11017. #endif
  11018. static int cflag; /* check disk */
  11019. static int show_version_only;
  11020. static int verbose;
  11021. #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural)
  11022. static void show_stats(e2fsck_t ctx)
  11023. {
  11024. ext2_filsys fs = ctx->fs;
  11025. int inodes, inodes_used, blocks, blocks_used;
  11026. int dir_links;
  11027. int num_files, num_links;
  11028. int frag_percent;
  11029. dir_links = 2 * ctx->fs_directory_count - 1;
  11030. num_files = ctx->fs_total_count - dir_links;
  11031. num_links = ctx->fs_links_count - dir_links;
  11032. inodes = fs->super->s_inodes_count;
  11033. inodes_used = (fs->super->s_inodes_count -
  11034. fs->super->s_free_inodes_count);
  11035. blocks = fs->super->s_blocks_count;
  11036. blocks_used = (fs->super->s_blocks_count -
  11037. fs->super->s_free_blocks_count);
  11038. frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
  11039. frag_percent = (frag_percent + 5) / 10;
  11040. if (!verbose) {
  11041. printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
  11042. ctx->device_name, inodes_used, inodes,
  11043. frag_percent / 10, frag_percent % 10,
  11044. blocks_used, blocks);
  11045. return;
  11046. }
  11047. printf("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used),
  11048. 100 * inodes_used / inodes);
  11049. printf("%8d non-contiguous inode%s (%0d.%d%%)\n",
  11050. P_E2("", "s", ctx->fs_fragmented),
  11051. frag_percent / 10, frag_percent % 10);
  11052. printf(_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
  11053. ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
  11054. printf("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used),
  11055. (int) ((long long) 100 * blocks_used / blocks));
  11056. printf("%8d large file%s\n", P_E2("", "s", ctx->large_files));
  11057. printf("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count));
  11058. printf("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count));
  11059. printf("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count));
  11060. printf("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count));
  11061. printf("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count));
  11062. printf("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links));
  11063. printf("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count));
  11064. printf(" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count));
  11065. printf("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count));
  11066. printf("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links));
  11067. }
  11068. static void check_mount(e2fsck_t ctx)
  11069. {
  11070. errcode_t retval;
  11071. int cont;
  11072. retval = ext2fs_check_if_mounted(ctx->filesystem_name,
  11073. &ctx->mount_flags);
  11074. if (retval) {
  11075. bb_error_msg(_("while determining whether %s is mounted"),
  11076. ctx->filesystem_name);
  11077. return;
  11078. }
  11079. /*
  11080. * If the filesystem isn't mounted, or it's the root filesystem
  11081. * and it's mounted read-only, then everything's fine.
  11082. */
  11083. if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
  11084. ((ctx->mount_flags & EXT2_MF_ISROOT) &&
  11085. (ctx->mount_flags & EXT2_MF_READONLY)))
  11086. return;
  11087. if (ctx->options & E2F_OPT_READONLY) {
  11088. printf(_("Warning! %s is mounted.\n"), ctx->filesystem_name);
  11089. return;
  11090. }
  11091. printf(_("%s is mounted. "), ctx->filesystem_name);
  11092. if (!ctx->interactive)
  11093. bb_error_msg_and_die(_("can't continue, aborting"));
  11094. printf(_("\n\n\007\007\007\007WARNING!!! "
  11095. "Running e2fsck on a mounted filesystem may cause\n"
  11096. "SEVERE filesystem damage.\007\007\007\n\n"));
  11097. cont = ask_yn(_("Do you really want to continue"), -1);
  11098. if (!cont) {
  11099. printf(_("check aborted.\n"));
  11100. exit(0);
  11101. }
  11102. }
  11103. static int is_on_batt(void)
  11104. {
  11105. FILE *f;
  11106. DIR *d;
  11107. char tmp[80], tmp2[80], fname[80];
  11108. unsigned int acflag;
  11109. struct dirent* de;
  11110. f = fopen_for_read("/proc/apm");
  11111. if (f) {
  11112. if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
  11113. acflag = 1;
  11114. fclose(f);
  11115. return (acflag != 1);
  11116. }
  11117. d = opendir("/proc/acpi/ac_adapter");
  11118. if (d) {
  11119. while ((de=readdir(d)) != NULL) {
  11120. if (!strncmp(".", de->d_name, 1))
  11121. continue;
  11122. snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
  11123. de->d_name);
  11124. f = fopen_for_read(fname);
  11125. if (!f)
  11126. continue;
  11127. if (fscanf(f, "%s %s", tmp2, tmp) != 2)
  11128. tmp[0] = 0;
  11129. fclose(f);
  11130. if (strncmp(tmp, "off-line", 8) == 0) {
  11131. closedir(d);
  11132. return 1;
  11133. }
  11134. }
  11135. closedir(d);
  11136. }
  11137. return 0;
  11138. }
  11139. /*
  11140. * This routine checks to see if a filesystem can be skipped; if so,
  11141. * it will exit with EXIT_OK. Under some conditions it will print a
  11142. * message explaining why a check is being forced.
  11143. */
  11144. static void check_if_skip(e2fsck_t ctx)
  11145. {
  11146. ext2_filsys fs = ctx->fs;
  11147. const char *reason = NULL;
  11148. unsigned int reason_arg = 0;
  11149. long next_check;
  11150. int batt = is_on_batt();
  11151. time_t now = time(NULL);
  11152. if ((ctx->options & E2F_OPT_FORCE) || cflag || swapfs)
  11153. return;
  11154. if ((fs->super->s_state & EXT2_ERROR_FS) ||
  11155. !ext2fs_test_valid(fs))
  11156. reason = _(" contains a file system with errors");
  11157. else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
  11158. reason = _(" was not cleanly unmounted");
  11159. else if ((fs->super->s_max_mnt_count > 0) &&
  11160. (fs->super->s_mnt_count >=
  11161. (unsigned) fs->super->s_max_mnt_count)) {
  11162. reason = _(" has been mounted %u times without being checked");
  11163. reason_arg = fs->super->s_mnt_count;
  11164. if (batt && (fs->super->s_mnt_count <
  11165. (unsigned) fs->super->s_max_mnt_count*2))
  11166. reason = 0;
  11167. } else if (fs->super->s_checkinterval &&
  11168. ((now - fs->super->s_lastcheck) >=
  11169. fs->super->s_checkinterval)) {
  11170. reason = _(" has gone %u days without being checked");
  11171. reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
  11172. if (batt && ((now - fs->super->s_lastcheck) <
  11173. fs->super->s_checkinterval*2))
  11174. reason = 0;
  11175. }
  11176. if (reason) {
  11177. fputs(ctx->device_name, stdout);
  11178. printf(reason, reason_arg);
  11179. fputs(_(", check forced.\n"), stdout);
  11180. return;
  11181. }
  11182. printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
  11183. fs->super->s_inodes_count - fs->super->s_free_inodes_count,
  11184. fs->super->s_inodes_count,
  11185. fs->super->s_blocks_count - fs->super->s_free_blocks_count,
  11186. fs->super->s_blocks_count);
  11187. next_check = 100000;
  11188. if (fs->super->s_max_mnt_count > 0) {
  11189. next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
  11190. if (next_check <= 0)
  11191. next_check = 1;
  11192. }
  11193. if (fs->super->s_checkinterval &&
  11194. ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
  11195. next_check = 1;
  11196. if (next_check <= 5) {
  11197. if (next_check == 1)
  11198. fputs(_(" (check after next mount)"), stdout);
  11199. else
  11200. printf(_(" (check in %ld mounts)"), next_check);
  11201. }
  11202. bb_putchar('\n');
  11203. ext2fs_close(fs);
  11204. ctx->fs = NULL;
  11205. e2fsck_free_context(ctx);
  11206. exit(EXIT_OK);
  11207. }
  11208. /*
  11209. * For completion notice
  11210. */
  11211. struct percent_tbl {
  11212. int max_pass;
  11213. int table[32];
  11214. };
  11215. static const struct percent_tbl e2fsck_tbl = {
  11216. 5, { 0, 70, 90, 92, 95, 100 }
  11217. };
  11218. static char bar[128], spaces[128];
  11219. static float calc_percent(const struct percent_tbl *tbl, int pass, int curr,
  11220. int max)
  11221. {
  11222. float percent;
  11223. if (pass <= 0)
  11224. return 0.0;
  11225. if (pass > tbl->max_pass || max == 0)
  11226. return 100.0;
  11227. percent = ((float) curr) / ((float) max);
  11228. return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
  11229. + tbl->table[pass-1]);
  11230. }
  11231. void e2fsck_clear_progbar(e2fsck_t ctx)
  11232. {
  11233. if (!(ctx->flags & E2F_FLAG_PROG_BAR))
  11234. return;
  11235. printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
  11236. ctx->stop_meta);
  11237. fflush(stdout);
  11238. ctx->flags &= ~E2F_FLAG_PROG_BAR;
  11239. }
  11240. int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
  11241. unsigned int dpynum)
  11242. {
  11243. static const char spinner[] = "\\|/-";
  11244. int i;
  11245. unsigned int tick;
  11246. struct timeval tv;
  11247. int dpywidth;
  11248. int fixed_percent;
  11249. if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
  11250. return 0;
  11251. /*
  11252. * Calculate the new progress position. If the
  11253. * percentage hasn't changed, then we skip out right
  11254. * away.
  11255. */
  11256. fixed_percent = (int) ((10 * percent) + 0.5);
  11257. if (ctx->progress_last_percent == fixed_percent)
  11258. return 0;
  11259. ctx->progress_last_percent = fixed_percent;
  11260. /*
  11261. * If we've already updated the spinner once within
  11262. * the last 1/8th of a second, no point doing it
  11263. * again.
  11264. */
  11265. gettimeofday(&tv, NULL);
  11266. tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
  11267. if ((tick == ctx->progress_last_time) &&
  11268. (fixed_percent != 0) && (fixed_percent != 1000))
  11269. return 0;
  11270. ctx->progress_last_time = tick;
  11271. /*
  11272. * Advance the spinner, and note that the progress bar
  11273. * will be on the screen
  11274. */
  11275. ctx->progress_pos = (ctx->progress_pos+1) & 3;
  11276. ctx->flags |= E2F_FLAG_PROG_BAR;
  11277. dpywidth = 66 - strlen(label);
  11278. dpywidth = 8 * (dpywidth / 8);
  11279. if (dpynum)
  11280. dpywidth -= 8;
  11281. i = ((percent * dpywidth) + 50) / 100;
  11282. printf("%s%s: |%s%s", ctx->start_meta, label,
  11283. bar + (sizeof(bar) - (i+1)),
  11284. spaces + (sizeof(spaces) - (dpywidth - i + 1)));
  11285. if (fixed_percent == 1000)
  11286. bb_putchar('|');
  11287. else
  11288. bb_putchar(spinner[ctx->progress_pos & 3]);
  11289. printf(" %4.1f%% ", percent);
  11290. if (dpynum)
  11291. printf("%u\r", dpynum);
  11292. else
  11293. fputs(" \r", stdout);
  11294. fputs(ctx->stop_meta, stdout);
  11295. if (fixed_percent == 1000)
  11296. e2fsck_clear_progbar(ctx);
  11297. fflush(stdout);
  11298. return 0;
  11299. }
  11300. static int e2fsck_update_progress(e2fsck_t ctx, int pass,
  11301. unsigned long cur, unsigned long max)
  11302. {
  11303. char buf[80];
  11304. float percent;
  11305. if (pass == 0)
  11306. return 0;
  11307. if (ctx->progress_fd) {
  11308. sprintf(buf, "%d %lu %lu\n", pass, cur, max);
  11309. xwrite_str(ctx->progress_fd, buf);
  11310. } else {
  11311. percent = calc_percent(&e2fsck_tbl, pass, cur, max);
  11312. e2fsck_simple_progress(ctx, ctx->device_name,
  11313. percent, 0);
  11314. }
  11315. return 0;
  11316. }
  11317. static void reserve_stdio_fds(void)
  11318. {
  11319. int fd;
  11320. while (1) {
  11321. fd = open(bb_dev_null, O_RDWR);
  11322. if (fd > 2)
  11323. break;
  11324. if (fd < 0) {
  11325. fprintf(stderr, _("ERROR: Cannot open "
  11326. "/dev/null (%s)\n"),
  11327. strerror(errno));
  11328. break;
  11329. }
  11330. }
  11331. close(fd);
  11332. }
  11333. static void signal_progress_on(int sig FSCK_ATTR((unused)))
  11334. {
  11335. e2fsck_t ctx = e2fsck_global_ctx;
  11336. if (!ctx)
  11337. return;
  11338. ctx->progress = e2fsck_update_progress;
  11339. ctx->progress_fd = 0;
  11340. }
  11341. static void signal_progress_off(int sig FSCK_ATTR((unused)))
  11342. {
  11343. e2fsck_t ctx = e2fsck_global_ctx;
  11344. if (!ctx)
  11345. return;
  11346. e2fsck_clear_progbar(ctx);
  11347. ctx->progress = 0;
  11348. }
  11349. static void signal_cancel(int sig FSCK_ATTR((unused)))
  11350. {
  11351. e2fsck_t ctx = e2fsck_global_ctx;
  11352. if (!ctx)
  11353. exit(FSCK_CANCELED);
  11354. ctx->flags |= E2F_FLAG_CANCEL;
  11355. }
  11356. static void parse_extended_opts(e2fsck_t ctx, const char *opts)
  11357. {
  11358. char *buf, *token, *next, *p, *arg;
  11359. int ea_ver;
  11360. int extended_usage = 0;
  11361. buf = string_copy(opts, 0);
  11362. for (token = buf; token && *token; token = next) {
  11363. p = strchr(token, ',');
  11364. next = 0;
  11365. if (p) {
  11366. *p = 0;
  11367. next = p+1;
  11368. }
  11369. arg = strchr(token, '=');
  11370. if (arg) {
  11371. *arg = 0;
  11372. arg++;
  11373. }
  11374. if (strcmp(token, "ea_ver") == 0) {
  11375. if (!arg) {
  11376. extended_usage++;
  11377. continue;
  11378. }
  11379. ea_ver = strtoul(arg, &p, 0);
  11380. if (*p ||
  11381. ((ea_ver != 1) && (ea_ver != 2))) {
  11382. fprintf(stderr,
  11383. _("Invalid EA version.\n"));
  11384. extended_usage++;
  11385. continue;
  11386. }
  11387. ctx->ext_attr_ver = ea_ver;
  11388. } else {
  11389. fprintf(stderr, _("Unknown extended option: %s\n"),
  11390. token);
  11391. extended_usage++;
  11392. }
  11393. }
  11394. if (extended_usage) {
  11395. bb_error_msg_and_die(
  11396. "Extended options are separated by commas, "
  11397. "and may take an argument which\n"
  11398. "is set off by an equals ('=') sign. "
  11399. "Valid extended options are:\n"
  11400. "\tea_ver=<ea_version (1 or 2)>\n\n");
  11401. }
  11402. }
  11403. static errcode_t PRS(int argc, char **argv, e2fsck_t *ret_ctx)
  11404. {
  11405. int flush = 0;
  11406. int c, fd;
  11407. e2fsck_t ctx;
  11408. errcode_t retval;
  11409. struct sigaction sa;
  11410. char *extended_opts = NULL;
  11411. retval = e2fsck_allocate_context(&ctx);
  11412. if (retval)
  11413. return retval;
  11414. *ret_ctx = ctx;
  11415. setvbuf(stdout, NULL, _IONBF, BUFSIZ);
  11416. setvbuf(stderr, NULL, _IONBF, BUFSIZ);
  11417. if (isatty(0) && isatty(1)) {
  11418. ctx->interactive = 1;
  11419. } else {
  11420. ctx->start_meta[0] = '\001';
  11421. ctx->stop_meta[0] = '\002';
  11422. }
  11423. memset(bar, '=', sizeof(bar)-1);
  11424. memset(spaces, ' ', sizeof(spaces)-1);
  11425. blkid_get_cache(&ctx->blkid, NULL);
  11426. if (argc && *argv)
  11427. ctx->program_name = *argv;
  11428. else
  11429. ctx->program_name = "e2fsck";
  11430. while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
  11431. switch (c) {
  11432. case 'C':
  11433. ctx->progress = e2fsck_update_progress;
  11434. ctx->progress_fd = atoi(optarg);
  11435. if (!ctx->progress_fd)
  11436. break;
  11437. /* Validate the file descriptor to avoid disasters */
  11438. fd = dup(ctx->progress_fd);
  11439. if (fd < 0) {
  11440. fprintf(stderr,
  11441. _("Error validating file descriptor %d: %s\n"),
  11442. ctx->progress_fd,
  11443. error_message(errno));
  11444. bb_error_msg_and_die(_("Invalid completion information file descriptor"));
  11445. } else
  11446. close(fd);
  11447. break;
  11448. case 'D':
  11449. ctx->options |= E2F_OPT_COMPRESS_DIRS;
  11450. break;
  11451. case 'E':
  11452. extended_opts = optarg;
  11453. break;
  11454. case 'p':
  11455. case 'a':
  11456. if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
  11457. conflict_opt:
  11458. bb_error_msg_and_die(_("only one the options -p/-a, -n or -y may be specified"));
  11459. }
  11460. ctx->options |= E2F_OPT_PREEN;
  11461. break;
  11462. case 'n':
  11463. if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
  11464. goto conflict_opt;
  11465. ctx->options |= E2F_OPT_NO;
  11466. break;
  11467. case 'y':
  11468. if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
  11469. goto conflict_opt;
  11470. ctx->options |= E2F_OPT_YES;
  11471. break;
  11472. case 't':
  11473. /* FIXME - This needs to go away in a future path - will change binary */
  11474. fprintf(stderr, _("The -t option is not "
  11475. "supported on this version of e2fsck.\n"));
  11476. break;
  11477. case 'c':
  11478. if (cflag++)
  11479. ctx->options |= E2F_OPT_WRITECHECK;
  11480. ctx->options |= E2F_OPT_CHECKBLOCKS;
  11481. break;
  11482. case 'r':
  11483. /* What we do by default, anyway! */
  11484. break;
  11485. case 'b':
  11486. ctx->use_superblock = atoi(optarg);
  11487. ctx->flags |= E2F_FLAG_SB_SPECIFIED;
  11488. break;
  11489. case 'B':
  11490. ctx->blocksize = atoi(optarg);
  11491. break;
  11492. case 'I':
  11493. ctx->inode_buffer_blocks = atoi(optarg);
  11494. break;
  11495. case 'j':
  11496. ctx->journal_name = string_copy(optarg, 0);
  11497. break;
  11498. case 'P':
  11499. ctx->process_inode_size = atoi(optarg);
  11500. break;
  11501. case 'd':
  11502. ctx->options |= E2F_OPT_DEBUG;
  11503. break;
  11504. case 'f':
  11505. ctx->options |= E2F_OPT_FORCE;
  11506. break;
  11507. case 'F':
  11508. flush = 1;
  11509. break;
  11510. case 'v':
  11511. verbose = 1;
  11512. break;
  11513. case 'V':
  11514. show_version_only = 1;
  11515. break;
  11516. case 'N':
  11517. ctx->device_name = optarg;
  11518. break;
  11519. #ifdef ENABLE_SWAPFS
  11520. case 's':
  11521. normalize_swapfs = 1;
  11522. case 'S':
  11523. swapfs = 1;
  11524. break;
  11525. #else
  11526. case 's':
  11527. case 'S':
  11528. fprintf(stderr, _("Byte-swapping filesystems "
  11529. "not compiled in this version "
  11530. "of e2fsck\n"));
  11531. exit(1);
  11532. #endif
  11533. default:
  11534. bb_show_usage();
  11535. }
  11536. if (show_version_only)
  11537. return 0;
  11538. if (optind != argc - 1)
  11539. bb_show_usage();
  11540. if ((ctx->options & E2F_OPT_NO) &&
  11541. !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
  11542. ctx->options |= E2F_OPT_READONLY;
  11543. ctx->io_options = strchr(argv[optind], '?');
  11544. if (ctx->io_options)
  11545. *ctx->io_options++ = 0;
  11546. ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
  11547. if (!ctx->filesystem_name) {
  11548. bb_error_msg(_("Unable to resolve '%s'"), argv[optind]);
  11549. bb_error_msg_and_die(0);
  11550. }
  11551. if (extended_opts)
  11552. parse_extended_opts(ctx, extended_opts);
  11553. if (flush) {
  11554. fd = open(ctx->filesystem_name, O_RDONLY, 0);
  11555. if (fd < 0) {
  11556. bb_error_msg(_("while opening %s for flushing"),
  11557. ctx->filesystem_name);
  11558. bb_error_msg_and_die(0);
  11559. }
  11560. if ((retval = ext2fs_sync_device(fd, 1))) {
  11561. bb_error_msg(_("while trying to flush %s"),
  11562. ctx->filesystem_name);
  11563. bb_error_msg_and_die(0);
  11564. }
  11565. close(fd);
  11566. }
  11567. #ifdef ENABLE_SWAPFS
  11568. if (swapfs && cflag) {
  11569. fprintf(stderr, _("Incompatible options not "
  11570. "allowed when byte-swapping.\n"));
  11571. exit(EXIT_USAGE);
  11572. }
  11573. #endif
  11574. /*
  11575. * Set up signal action
  11576. */
  11577. memset(&sa, 0, sizeof(struct sigaction));
  11578. sa.sa_handler = signal_cancel;
  11579. sigaction(SIGINT, &sa, 0);
  11580. sigaction(SIGTERM, &sa, 0);
  11581. #ifdef SA_RESTART
  11582. sa.sa_flags = SA_RESTART;
  11583. #endif
  11584. e2fsck_global_ctx = ctx;
  11585. sa.sa_handler = signal_progress_on;
  11586. sigaction(SIGUSR1, &sa, 0);
  11587. sa.sa_handler = signal_progress_off;
  11588. sigaction(SIGUSR2, &sa, 0);
  11589. /* Update our PATH to include /sbin if we need to run badblocks */
  11590. if (cflag)
  11591. e2fs_set_sbin_path();
  11592. return 0;
  11593. }
  11594. static const char my_ver_string[] = E2FSPROGS_VERSION;
  11595. static const char my_ver_date[] = E2FSPROGS_DATE;
  11596. int e2fsck_main (int argc, char **argv);
  11597. int e2fsck_main (int argc, char **argv)
  11598. {
  11599. errcode_t retval;
  11600. int exit_value = EXIT_OK;
  11601. ext2_filsys fs = 0;
  11602. io_manager io_ptr;
  11603. struct ext2_super_block *sb;
  11604. const char *lib_ver_date;
  11605. int my_ver, lib_ver;
  11606. e2fsck_t ctx;
  11607. struct problem_context pctx;
  11608. int flags, run_result;
  11609. clear_problem_context(&pctx);
  11610. my_ver = ext2fs_parse_version_string(my_ver_string);
  11611. lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
  11612. if (my_ver > lib_ver) {
  11613. fprintf( stderr, _("Error: ext2fs library version "
  11614. "out of date!\n"));
  11615. show_version_only++;
  11616. }
  11617. retval = PRS(argc, argv, &ctx);
  11618. if (retval) {
  11619. bb_error_msg(_("while trying to initialize program"));
  11620. exit(EXIT_ERROR);
  11621. }
  11622. reserve_stdio_fds();
  11623. if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
  11624. fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
  11625. my_ver_date);
  11626. if (show_version_only) {
  11627. fprintf(stderr, _("\tUsing %s, %s\n"),
  11628. error_message(EXT2_ET_BASE), lib_ver_date);
  11629. exit(EXIT_OK);
  11630. }
  11631. check_mount(ctx);
  11632. if (!(ctx->options & E2F_OPT_PREEN) &&
  11633. !(ctx->options & E2F_OPT_NO) &&
  11634. !(ctx->options & E2F_OPT_YES)) {
  11635. if (!ctx->interactive)
  11636. bb_error_msg_and_die(_("need terminal for interactive repairs"));
  11637. }
  11638. ctx->superblock = ctx->use_superblock;
  11639. restart:
  11640. #ifdef CONFIG_TESTIO_DEBUG
  11641. io_ptr = test_io_manager;
  11642. test_io_backing_manager = unix_io_manager;
  11643. #else
  11644. io_ptr = unix_io_manager;
  11645. #endif
  11646. flags = 0;
  11647. if ((ctx->options & E2F_OPT_READONLY) == 0)
  11648. flags |= EXT2_FLAG_RW;
  11649. if (ctx->superblock && ctx->blocksize) {
  11650. retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
  11651. flags, ctx->superblock, ctx->blocksize,
  11652. io_ptr, &fs);
  11653. } else if (ctx->superblock) {
  11654. int blocksize;
  11655. for (blocksize = EXT2_MIN_BLOCK_SIZE;
  11656. blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
  11657. retval = ext2fs_open2(ctx->filesystem_name,
  11658. ctx->io_options, flags,
  11659. ctx->superblock, blocksize,
  11660. io_ptr, &fs);
  11661. if (!retval)
  11662. break;
  11663. }
  11664. } else
  11665. retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
  11666. flags, 0, 0, io_ptr, &fs);
  11667. if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
  11668. !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
  11669. ((retval == EXT2_ET_BAD_MAGIC) ||
  11670. ((retval == 0) && ext2fs_check_desc(fs)))) {
  11671. if (!fs || (fs->group_desc_count > 1)) {
  11672. printf(_("%s trying backup blocks...\n"),
  11673. retval ? _("Couldn't find ext2 superblock,") :
  11674. _("Group descriptors look bad..."));
  11675. get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
  11676. if (fs)
  11677. ext2fs_close(fs);
  11678. goto restart;
  11679. }
  11680. }
  11681. if (retval) {
  11682. bb_error_msg(_("while trying to open %s"),
  11683. ctx->filesystem_name);
  11684. if (retval == EXT2_ET_REV_TOO_HIGH) {
  11685. printf(_("The filesystem revision is apparently "
  11686. "too high for this version of e2fsck.\n"
  11687. "(Or the filesystem superblock "
  11688. "is corrupt)\n\n"));
  11689. fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
  11690. } else if (retval == EXT2_ET_SHORT_READ)
  11691. printf(_("Could this be a zero-length partition?\n"));
  11692. else if ((retval == EPERM) || (retval == EACCES))
  11693. printf(_("You must have %s access to the "
  11694. "filesystem or be root\n"),
  11695. (ctx->options & E2F_OPT_READONLY) ?
  11696. "r/o" : "r/w");
  11697. else if (retval == ENXIO)
  11698. printf(_("Possibly non-existent or swap device?\n"));
  11699. #ifdef EROFS
  11700. else if (retval == EROFS)
  11701. printf(_("Disk write-protected; use the -n option "
  11702. "to do a read-only\n"
  11703. "check of the device.\n"));
  11704. #endif
  11705. else
  11706. fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
  11707. bb_error_msg_and_die(0);
  11708. }
  11709. ctx->fs = fs;
  11710. fs->priv_data = ctx;
  11711. sb = fs->super;
  11712. if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
  11713. bb_error_msg(_("while trying to open %s"),
  11714. ctx->filesystem_name);
  11715. get_newer:
  11716. bb_error_msg_and_die(_("Get a newer version of e2fsck!"));
  11717. }
  11718. /*
  11719. * Set the device name, which is used whenever we print error
  11720. * or informational messages to the user.
  11721. */
  11722. if (ctx->device_name == 0 &&
  11723. (sb->s_volume_name[0] != 0)) {
  11724. ctx->device_name = string_copy(sb->s_volume_name,
  11725. sizeof(sb->s_volume_name));
  11726. }
  11727. if (ctx->device_name == 0)
  11728. ctx->device_name = ctx->filesystem_name;
  11729. /*
  11730. * Make sure the ext3 superblock fields are consistent.
  11731. */
  11732. retval = e2fsck_check_ext3_journal(ctx);
  11733. if (retval) {
  11734. bb_error_msg(_("while checking ext3 journal for %s"),
  11735. ctx->device_name);
  11736. bb_error_msg_and_die(0);
  11737. }
  11738. /*
  11739. * Check to see if we need to do ext3-style recovery. If so,
  11740. * do it, and then restart the fsck.
  11741. */
  11742. if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
  11743. if (ctx->options & E2F_OPT_READONLY) {
  11744. printf(_("Warning: skipping journal recovery "
  11745. "because doing a read-only filesystem "
  11746. "check.\n"));
  11747. io_channel_flush(ctx->fs->io);
  11748. } else {
  11749. if (ctx->flags & E2F_FLAG_RESTARTED) {
  11750. /*
  11751. * Whoops, we attempted to run the
  11752. * journal twice. This should never
  11753. * happen, unless the hardware or
  11754. * device driver is being bogus.
  11755. */
  11756. bb_error_msg(_("can't set superblock flags on %s"), ctx->device_name);
  11757. bb_error_msg_and_die(0);
  11758. }
  11759. retval = e2fsck_run_ext3_journal(ctx);
  11760. if (retval) {
  11761. bb_error_msg(_("while recovering ext3 journal of %s"),
  11762. ctx->device_name);
  11763. bb_error_msg_and_die(0);
  11764. }
  11765. ext2fs_close(ctx->fs);
  11766. ctx->fs = 0;
  11767. ctx->flags |= E2F_FLAG_RESTARTED;
  11768. goto restart;
  11769. }
  11770. }
  11771. /*
  11772. * Check for compatibility with the feature sets. We need to
  11773. * be more stringent than ext2fs_open().
  11774. */
  11775. if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
  11776. (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
  11777. bb_error_msg("(%s)", ctx->device_name);
  11778. goto get_newer;
  11779. }
  11780. if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
  11781. bb_error_msg("(%s)", ctx->device_name);
  11782. goto get_newer;
  11783. }
  11784. #ifdef ENABLE_COMPRESSION
  11785. /* FIXME - do we support this at all? */
  11786. if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
  11787. bb_error_msg(_("warning: compression support is experimental"));
  11788. #endif
  11789. #ifndef ENABLE_HTREE
  11790. if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
  11791. bb_error_msg(_("E2fsck not compiled with HTREE support,\n\t"
  11792. "but filesystem %s has HTREE directories."),
  11793. ctx->device_name);
  11794. goto get_newer;
  11795. }
  11796. #endif
  11797. /*
  11798. * If the user specified a specific superblock, presumably the
  11799. * master superblock has been trashed. So we mark the
  11800. * superblock as dirty, so it can be written out.
  11801. */
  11802. if (ctx->superblock &&
  11803. !(ctx->options & E2F_OPT_READONLY))
  11804. ext2fs_mark_super_dirty(fs);
  11805. /*
  11806. * We only update the master superblock because (a) paranoia;
  11807. * we don't want to corrupt the backup superblocks, and (b) we
  11808. * don't need to update the mount count and last checked
  11809. * fields in the backup superblock (the kernel doesn't
  11810. * update the backup superblocks anyway).
  11811. */
  11812. fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
  11813. ehandler_init(fs->io);
  11814. if (ctx->superblock)
  11815. set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
  11816. ext2fs_mark_valid(fs);
  11817. check_super_block(ctx);
  11818. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  11819. bb_error_msg_and_die(0);
  11820. check_if_skip(ctx);
  11821. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  11822. bb_error_msg_and_die(0);
  11823. #ifdef ENABLE_SWAPFS
  11824. #ifdef WORDS_BIGENDIAN
  11825. #define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES
  11826. #else
  11827. #define NATIVE_FLAG 0
  11828. #endif
  11829. if (normalize_swapfs) {
  11830. if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == NATIVE_FLAG) {
  11831. fprintf(stderr, _("%s: Filesystem byte order "
  11832. "already normalized.\n"), ctx->device_name);
  11833. bb_error_msg_and_die(0);
  11834. }
  11835. }
  11836. if (swapfs) {
  11837. swap_filesys(ctx);
  11838. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  11839. bb_error_msg_and_die(0);
  11840. }
  11841. #endif
  11842. /*
  11843. * Mark the system as valid, 'til proven otherwise
  11844. */
  11845. ext2fs_mark_valid(fs);
  11846. retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
  11847. if (retval) {
  11848. bb_error_msg(_("while reading bad blocks inode"));
  11849. preenhalt(ctx);
  11850. printf(_("This doesn't bode well,"
  11851. " but we'll try to go on...\n"));
  11852. }
  11853. run_result = e2fsck_run(ctx);
  11854. e2fsck_clear_progbar(ctx);
  11855. if (run_result == E2F_FLAG_RESTART) {
  11856. printf(_("Restarting e2fsck from the beginning...\n"));
  11857. retval = e2fsck_reset_context(ctx);
  11858. if (retval) {
  11859. bb_error_msg(_("while resetting context"));
  11860. bb_error_msg_and_die(0);
  11861. }
  11862. ext2fs_close(fs);
  11863. goto restart;
  11864. }
  11865. if (run_result & E2F_FLAG_CANCEL) {
  11866. printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
  11867. ctx->device_name : ctx->filesystem_name);
  11868. exit_value |= FSCK_CANCELED;
  11869. }
  11870. if (run_result & E2F_FLAG_ABORT)
  11871. bb_error_msg_and_die(_("aborted"));
  11872. /* Cleanup */
  11873. if (ext2fs_test_changed(fs)) {
  11874. exit_value |= EXIT_NONDESTRUCT;
  11875. if (!(ctx->options & E2F_OPT_PREEN))
  11876. printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
  11877. ctx->device_name);
  11878. if (ctx->mount_flags & EXT2_MF_ISROOT) {
  11879. printf(_("%s: ***** REBOOT LINUX *****\n"),
  11880. ctx->device_name);
  11881. exit_value |= EXIT_DESTRUCT;
  11882. }
  11883. }
  11884. if (!ext2fs_test_valid(fs)) {
  11885. printf(_("\n%s: ********** WARNING: Filesystem still has "
  11886. "errors **********\n\n"), ctx->device_name);
  11887. exit_value |= EXIT_UNCORRECTED;
  11888. exit_value &= ~EXIT_NONDESTRUCT;
  11889. }
  11890. if (exit_value & FSCK_CANCELED)
  11891. exit_value &= ~EXIT_NONDESTRUCT;
  11892. else {
  11893. show_stats(ctx);
  11894. if (!(ctx->options & E2F_OPT_READONLY)) {
  11895. if (ext2fs_test_valid(fs)) {
  11896. if (!(sb->s_state & EXT2_VALID_FS))
  11897. exit_value |= EXIT_NONDESTRUCT;
  11898. sb->s_state = EXT2_VALID_FS;
  11899. } else
  11900. sb->s_state &= ~EXT2_VALID_FS;
  11901. sb->s_mnt_count = 0;
  11902. sb->s_lastcheck = time(NULL);
  11903. ext2fs_mark_super_dirty(fs);
  11904. }
  11905. }
  11906. e2fsck_write_bitmaps(ctx);
  11907. ext2fs_close(fs);
  11908. ctx->fs = NULL;
  11909. free(ctx->filesystem_name);
  11910. free(ctx->journal_name);
  11911. e2fsck_free_context(ctx);
  11912. return exit_value;
  11913. }