3
0

e2fsck.c 354 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499
  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. #include "e2fsck.h" /*Put all of our defines here to clean things up*/
  32. #define _(x) x
  33. #define N_(x) x
  34. /*
  35. * Procedure declarations
  36. */
  37. static void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf);
  38. /* pass1.c */
  39. static void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool);
  40. /* pass2.c */
  41. static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
  42. ext2_ino_t ino, char *buf);
  43. /* pass3.c */
  44. static int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t inode);
  45. static errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
  46. int num, int gauranteed_size);
  47. static ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix);
  48. static errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino,
  49. int adj);
  50. /* rehash.c */
  51. static void e2fsck_rehash_directories(e2fsck_t ctx);
  52. /* util.c */
  53. static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
  54. const char *description);
  55. static int ask(e2fsck_t ctx, const char * string, int def);
  56. static void e2fsck_read_bitmaps(e2fsck_t ctx);
  57. static void preenhalt(e2fsck_t ctx);
  58. static void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
  59. struct ext2_inode * inode, const char * proc);
  60. static void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
  61. struct ext2_inode * inode, const char * proc);
  62. static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
  63. const char *name, io_manager manager);
  64. /* unix.c */
  65. static void e2fsck_clear_progbar(e2fsck_t ctx);
  66. static int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
  67. float percent, unsigned int dpynum);
  68. /*
  69. * problem.h --- e2fsck problem error codes
  70. */
  71. typedef __u32 problem_t;
  72. struct problem_context {
  73. errcode_t errcode;
  74. ext2_ino_t ino, ino2, dir;
  75. struct ext2_inode *inode;
  76. struct ext2_dir_entry *dirent;
  77. blk_t blk, blk2;
  78. e2_blkcnt_t blkcount;
  79. int group;
  80. __u64 num;
  81. const char *str;
  82. };
  83. /*
  84. * Function declarations
  85. */
  86. static int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx);
  87. static int end_problem_latch(e2fsck_t ctx, int mask);
  88. static int set_latch_flags(int mask, int setflags, int clearflags);
  89. static void clear_problem_context(struct problem_context *ctx);
  90. /*
  91. * Dictionary Abstract Data Type
  92. * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
  93. *
  94. * dict.h v 1.22.2.6 2000/11/13 01:36:44 kaz
  95. * kazlib_1_20
  96. */
  97. #ifndef DICT_H
  98. #define DICT_H
  99. /*
  100. * Blurb for inclusion into C++ translation units
  101. */
  102. typedef unsigned long dictcount_t;
  103. #define DICTCOUNT_T_MAX ULONG_MAX
  104. /*
  105. * The dictionary is implemented as a red-black tree
  106. */
  107. typedef enum { dnode_red, dnode_black } dnode_color_t;
  108. typedef struct dnode_t {
  109. struct dnode_t *dict_left;
  110. struct dnode_t *dict_right;
  111. struct dnode_t *dict_parent;
  112. dnode_color_t dict_color;
  113. const void *dict_key;
  114. void *dict_data;
  115. } dnode_t;
  116. typedef int (*dict_comp_t)(const void *, const void *);
  117. typedef void (*dnode_free_t)(dnode_t *);
  118. typedef struct dict_t {
  119. dnode_t dict_nilnode;
  120. dictcount_t dict_nodecount;
  121. dictcount_t dict_maxcount;
  122. dict_comp_t dict_compare;
  123. dnode_free_t dict_freenode;
  124. int dict_dupes;
  125. } dict_t;
  126. typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
  127. typedef struct dict_load_t {
  128. dict_t *dict_dictptr;
  129. dnode_t dict_nilnode;
  130. } dict_load_t;
  131. #define dict_count(D) ((D)->dict_nodecount)
  132. #define dnode_get(N) ((N)->dict_data)
  133. #define dnode_getkey(N) ((N)->dict_key)
  134. #endif
  135. /*
  136. * Compatibility header file for e2fsck which should be included
  137. * instead of linux/jfs.h
  138. *
  139. * Copyright (C) 2000 Stephen C. Tweedie
  140. */
  141. /*
  142. * Pull in the definition of the e2fsck context structure
  143. */
  144. struct buffer_head {
  145. char b_data[8192];
  146. e2fsck_t b_ctx;
  147. io_channel b_io;
  148. int b_size;
  149. blk_t b_blocknr;
  150. int b_dirty;
  151. int b_uptodate;
  152. int b_err;
  153. };
  154. #define K_DEV_FS 1
  155. #define K_DEV_JOURNAL 2
  156. #define lock_buffer(bh) do {} while (0)
  157. #define unlock_buffer(bh) do {} while (0)
  158. #define buffer_req(bh) 1
  159. #define do_readahead(journal, start) do {} while (0)
  160. static e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
  161. typedef struct {
  162. int object_length;
  163. } kmem_cache_t;
  164. #define kmem_cache_alloc(cache,flags) malloc((cache)->object_length)
  165. /*
  166. * We use the standard libext2fs portability tricks for inline
  167. * functions.
  168. */
  169. static kmem_cache_t * do_cache_create(int len)
  170. {
  171. kmem_cache_t *new_cache;
  172. new_cache = xmalloc(sizeof(*new_cache));
  173. new_cache->object_length = len;
  174. return new_cache;
  175. }
  176. static void do_cache_destroy(kmem_cache_t *cache)
  177. {
  178. free(cache);
  179. }
  180. /*
  181. * Dictionary Abstract Data Type
  182. */
  183. /*
  184. * These macros provide short convenient names for structure members,
  185. * which are embellished with dict_ prefixes so that they are
  186. * properly confined to the documented namespace. It's legal for a
  187. * program which uses dict to define, for instance, a macro called ``parent''.
  188. * Such a macro would interfere with the dnode_t struct definition.
  189. * In general, highly portable and reusable C modules which expose their
  190. * structures need to confine structure member names to well-defined spaces.
  191. * The resulting identifiers aren't necessarily convenient to use, nor
  192. * readable, in the implementation, however!
  193. */
  194. #define left dict_left
  195. #define right dict_right
  196. #define parent dict_parent
  197. #define color dict_color
  198. #define key dict_key
  199. #define data dict_data
  200. #define nilnode dict_nilnode
  201. #define maxcount dict_maxcount
  202. #define compare dict_compare
  203. #define dupes dict_dupes
  204. #define dict_root(D) ((D)->nilnode.left)
  205. #define dict_nil(D) (&(D)->nilnode)
  206. static void dnode_free(dnode_t *node);
  207. /*
  208. * Perform a ``left rotation'' adjustment on the tree. The given node P and
  209. * its right child C are rearranged so that the P instead becomes the left
  210. * child of C. The left subtree of C is inherited as the new right subtree
  211. * for P. The ordering of the keys within the tree is thus preserved.
  212. */
  213. static void rotate_left(dnode_t *upper)
  214. {
  215. dnode_t *lower, *lowleft, *upparent;
  216. lower = upper->right;
  217. upper->right = lowleft = lower->left;
  218. lowleft->parent = upper;
  219. lower->parent = upparent = upper->parent;
  220. /* don't need to check for root node here because root->parent is
  221. the sentinel nil node, and root->parent->left points back to root */
  222. if (upper == upparent->left) {
  223. upparent->left = lower;
  224. } else {
  225. assert (upper == upparent->right);
  226. upparent->right = lower;
  227. }
  228. lower->left = upper;
  229. upper->parent = lower;
  230. }
  231. /*
  232. * This operation is the ``mirror'' image of rotate_left. It is
  233. * the same procedure, but with left and right interchanged.
  234. */
  235. static void rotate_right(dnode_t *upper)
  236. {
  237. dnode_t *lower, *lowright, *upparent;
  238. lower = upper->left;
  239. upper->left = lowright = lower->right;
  240. lowright->parent = upper;
  241. lower->parent = upparent = upper->parent;
  242. if (upper == upparent->right) {
  243. upparent->right = lower;
  244. } else {
  245. assert (upper == upparent->left);
  246. upparent->left = lower;
  247. }
  248. lower->right = upper;
  249. upper->parent = lower;
  250. }
  251. /*
  252. * Do a postorder traversal of the tree rooted at the specified
  253. * node and free everything under it. Used by dict_free().
  254. */
  255. static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil)
  256. {
  257. if (node == nil)
  258. return;
  259. free_nodes(dict, node->left, nil);
  260. free_nodes(dict, node->right, nil);
  261. dict->dict_freenode(node);
  262. }
  263. /*
  264. * Verify that the tree contains the given node. This is done by
  265. * traversing all of the nodes and comparing their pointers to the
  266. * given pointer. Returns 1 if the node is found, otherwise
  267. * returns zero. It is intended for debugging purposes.
  268. */
  269. static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node)
  270. {
  271. if (root != nil) {
  272. return root == node
  273. || verify_dict_has_node(nil, root->left, node)
  274. || verify_dict_has_node(nil, root->right, node);
  275. }
  276. return 0;
  277. }
  278. /*
  279. * Select a different set of node allocator routines.
  280. */
  281. static void dict_set_allocator(dict_t *dict, dnode_free_t fr)
  282. {
  283. assert(dict_count(dict) == 0);
  284. dict->dict_freenode = fr;
  285. }
  286. /*
  287. * Free all the nodes in the dictionary by using the dictionary's
  288. * installed free routine. The dictionary is emptied.
  289. */
  290. static void dict_free_nodes(dict_t *dict)
  291. {
  292. dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
  293. free_nodes(dict, root, nil);
  294. dict->dict_nodecount = 0;
  295. dict->nilnode.left = &dict->nilnode;
  296. dict->nilnode.right = &dict->nilnode;
  297. }
  298. /*
  299. * Initialize a user-supplied dictionary object.
  300. */
  301. static dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp)
  302. {
  303. dict->compare = comp;
  304. dict->dict_freenode = dnode_free;
  305. dict->dict_nodecount = 0;
  306. dict->maxcount = maxcount;
  307. dict->nilnode.left = &dict->nilnode;
  308. dict->nilnode.right = &dict->nilnode;
  309. dict->nilnode.parent = &dict->nilnode;
  310. dict->nilnode.color = dnode_black;
  311. dict->dupes = 0;
  312. return dict;
  313. }
  314. /*
  315. * Locate a node in the dictionary having the given key.
  316. * If the node is not found, a null a pointer is returned (rather than
  317. * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
  318. * located node is returned.
  319. */
  320. static dnode_t *dict_lookup(dict_t *dict, const void *key)
  321. {
  322. dnode_t *root = dict_root(dict);
  323. dnode_t *nil = dict_nil(dict);
  324. dnode_t *saved;
  325. int result;
  326. /* simple binary search adapted for trees that contain duplicate keys */
  327. while (root != nil) {
  328. result = dict->compare(key, root->key);
  329. if (result < 0)
  330. root = root->left;
  331. else if (result > 0)
  332. root = root->right;
  333. else {
  334. if (!dict->dupes) { /* no duplicates, return match */
  335. return root;
  336. } else { /* could be dupes, find leftmost one */
  337. do {
  338. saved = root;
  339. root = root->left;
  340. while (root != nil && dict->compare(key, root->key))
  341. root = root->right;
  342. } while (root != nil);
  343. return saved;
  344. }
  345. }
  346. }
  347. return NULL;
  348. }
  349. /*
  350. * Insert a node into the dictionary. The node should have been
  351. * initialized with a data field. All other fields are ignored.
  352. * The behavior is undefined if the user attempts to insert into
  353. * a dictionary that is already full (for which the dict_isfull()
  354. * function returns true).
  355. */
  356. static void dict_insert(dict_t *dict, dnode_t *node, const void *key)
  357. {
  358. dnode_t *where = dict_root(dict), *nil = dict_nil(dict);
  359. dnode_t *parent = nil, *uncle, *grandpa;
  360. int result = -1;
  361. node->key = key;
  362. /* basic binary tree insert */
  363. while (where != nil) {
  364. parent = where;
  365. result = dict->compare(key, where->key);
  366. /* trap attempts at duplicate key insertion unless it's explicitly allowed */
  367. assert(dict->dupes || result != 0);
  368. if (result < 0)
  369. where = where->left;
  370. else
  371. where = where->right;
  372. }
  373. assert(where == nil);
  374. if (result < 0)
  375. parent->left = node;
  376. else
  377. parent->right = node;
  378. node->parent = parent;
  379. node->left = nil;
  380. node->right = nil;
  381. dict->dict_nodecount++;
  382. /* red black adjustments */
  383. node->color = dnode_red;
  384. while (parent->color == dnode_red) {
  385. grandpa = parent->parent;
  386. if (parent == grandpa->left) {
  387. uncle = grandpa->right;
  388. if (uncle->color == dnode_red) { /* red parent, red uncle */
  389. parent->color = dnode_black;
  390. uncle->color = dnode_black;
  391. grandpa->color = dnode_red;
  392. node = grandpa;
  393. parent = grandpa->parent;
  394. } else { /* red parent, black uncle */
  395. if (node == parent->right) {
  396. rotate_left(parent);
  397. parent = node;
  398. assert (grandpa == parent->parent);
  399. /* rotation between parent and child preserves grandpa */
  400. }
  401. parent->color = dnode_black;
  402. grandpa->color = dnode_red;
  403. rotate_right(grandpa);
  404. break;
  405. }
  406. } else { /* symmetric cases: parent == parent->parent->right */
  407. uncle = grandpa->left;
  408. if (uncle->color == dnode_red) {
  409. parent->color = dnode_black;
  410. uncle->color = dnode_black;
  411. grandpa->color = dnode_red;
  412. node = grandpa;
  413. parent = grandpa->parent;
  414. } else {
  415. if (node == parent->left) {
  416. rotate_right(parent);
  417. parent = node;
  418. assert (grandpa == parent->parent);
  419. }
  420. parent->color = dnode_black;
  421. grandpa->color = dnode_red;
  422. rotate_left(grandpa);
  423. break;
  424. }
  425. }
  426. }
  427. dict_root(dict)->color = dnode_black;
  428. }
  429. /*
  430. * Allocate a node using the dictionary's allocator routine, give it
  431. * the data item.
  432. */
  433. static dnode_t *dnode_init(dnode_t *dnode, void *data)
  434. {
  435. dnode->data = data;
  436. dnode->parent = NULL;
  437. dnode->left = NULL;
  438. dnode->right = NULL;
  439. return dnode;
  440. }
  441. static int dict_alloc_insert(dict_t *dict, const void *key, void *data)
  442. {
  443. dnode_t *node = xmalloc(sizeof(dnode_t));
  444. dnode_init(node, data);
  445. dict_insert(dict, node, key);
  446. return 1;
  447. }
  448. /*
  449. * Return the node with the lowest (leftmost) key. If the dictionary is empty
  450. * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
  451. */
  452. static dnode_t *dict_first(dict_t *dict)
  453. {
  454. dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
  455. if (root != nil)
  456. while ((left = root->left) != nil)
  457. root = left;
  458. return (root == nil) ? NULL : root;
  459. }
  460. /*
  461. * Return the given node's successor node---the node which has the
  462. * next key in the the left to right ordering. If the node has
  463. * no successor, a null pointer is returned rather than a pointer to
  464. * the nil node.
  465. */
  466. static dnode_t *dict_next(dict_t *dict, dnode_t *curr)
  467. {
  468. dnode_t *nil = dict_nil(dict), *parent, *left;
  469. if (curr->right != nil) {
  470. curr = curr->right;
  471. while ((left = curr->left) != nil)
  472. curr = left;
  473. return curr;
  474. }
  475. parent = curr->parent;
  476. while (parent != nil && curr == parent->right) {
  477. curr = parent;
  478. parent = curr->parent;
  479. }
  480. return (parent == nil) ? NULL : parent;
  481. }
  482. static void dnode_free(dnode_t *node)
  483. {
  484. free(node);
  485. }
  486. #undef left
  487. #undef right
  488. #undef parent
  489. #undef color
  490. #undef key
  491. #undef data
  492. #undef nilnode
  493. #undef maxcount
  494. #undef compare
  495. #undef dupes
  496. /*
  497. * dirinfo.c --- maintains the directory information table for e2fsck.
  498. */
  499. /*
  500. * This subroutine is called during pass1 to create a directory info
  501. * entry. During pass1, the passed-in parent is 0; it will get filled
  502. * in during pass2.
  503. */
  504. static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
  505. {
  506. struct dir_info *dir;
  507. int i, j;
  508. ext2_ino_t num_dirs;
  509. errcode_t retval;
  510. unsigned long old_size;
  511. if (!ctx->dir_info) {
  512. ctx->dir_info_count = 0;
  513. retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
  514. if (retval)
  515. num_dirs = 1024; /* Guess */
  516. ctx->dir_info_size = num_dirs + 10;
  517. ctx->dir_info = (struct dir_info *)
  518. e2fsck_allocate_memory(ctx, ctx->dir_info_size
  519. * sizeof (struct dir_info),
  520. "directory map");
  521. }
  522. if (ctx->dir_info_count >= ctx->dir_info_size) {
  523. old_size = ctx->dir_info_size * sizeof(struct dir_info);
  524. ctx->dir_info_size += 10;
  525. retval = ext2fs_resize_mem(old_size, ctx->dir_info_size *
  526. sizeof(struct dir_info),
  527. &ctx->dir_info);
  528. if (retval) {
  529. ctx->dir_info_size -= 10;
  530. return;
  531. }
  532. }
  533. /*
  534. * Normally, add_dir_info is called with each inode in
  535. * sequential order; but once in a while (like when pass 3
  536. * needs to recreate the root directory or lost+found
  537. * directory) it is called out of order. In those cases, we
  538. * need to move the dir_info entries down to make room, since
  539. * the dir_info array needs to be sorted by inode number for
  540. * get_dir_info()'s sake.
  541. */
  542. if (ctx->dir_info_count &&
  543. ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
  544. for (i = ctx->dir_info_count-1; i > 0; i--)
  545. if (ctx->dir_info[i-1].ino < ino)
  546. break;
  547. dir = &ctx->dir_info[i];
  548. if (dir->ino != ino)
  549. for (j = ctx->dir_info_count++; j > i; j--)
  550. ctx->dir_info[j] = ctx->dir_info[j-1];
  551. } else
  552. dir = &ctx->dir_info[ctx->dir_info_count++];
  553. dir->ino = ino;
  554. dir->dotdot = parent;
  555. dir->parent = parent;
  556. }
  557. /*
  558. * get_dir_info() --- given an inode number, try to find the directory
  559. * information entry for it.
  560. */
  561. static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
  562. {
  563. int low, high, mid;
  564. low = 0;
  565. high = ctx->dir_info_count-1;
  566. if (!ctx->dir_info)
  567. return 0;
  568. if (ino == ctx->dir_info[low].ino)
  569. return &ctx->dir_info[low];
  570. if (ino == ctx->dir_info[high].ino)
  571. return &ctx->dir_info[high];
  572. while (low < high) {
  573. mid = (low+high)/2;
  574. if (mid == low || mid == high)
  575. break;
  576. if (ino == ctx->dir_info[mid].ino)
  577. return &ctx->dir_info[mid];
  578. if (ino < ctx->dir_info[mid].ino)
  579. high = mid;
  580. else
  581. low = mid;
  582. }
  583. return 0;
  584. }
  585. /*
  586. * Free the dir_info structure when it isn't needed any more.
  587. */
  588. static void e2fsck_free_dir_info(e2fsck_t ctx)
  589. {
  590. ext2fs_free_mem(&ctx->dir_info);
  591. ctx->dir_info_size = 0;
  592. ctx->dir_info_count = 0;
  593. }
  594. /*
  595. * Return the count of number of directories in the dir_info structure
  596. */
  597. static int e2fsck_get_num_dirinfo(e2fsck_t ctx)
  598. {
  599. return ctx->dir_info_count;
  600. }
  601. /*
  602. * A simple interator function
  603. */
  604. static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
  605. {
  606. if (*control >= ctx->dir_info_count)
  607. return 0;
  608. return ctx->dir_info + (*control)++;
  609. }
  610. /*
  611. * dirinfo.c --- maintains the directory information table for e2fsck.
  612. *
  613. */
  614. #ifdef ENABLE_HTREE
  615. /*
  616. * This subroutine is called during pass1 to create a directory info
  617. * entry. During pass1, the passed-in parent is 0; it will get filled
  618. * in during pass2.
  619. */
  620. static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
  621. {
  622. struct dx_dir_info *dir;
  623. int i, j;
  624. errcode_t retval;
  625. unsigned long old_size;
  626. if (!ctx->dx_dir_info) {
  627. ctx->dx_dir_info_count = 0;
  628. ctx->dx_dir_info_size = 100; /* Guess */
  629. ctx->dx_dir_info = (struct dx_dir_info *)
  630. e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size
  631. * sizeof (struct dx_dir_info),
  632. "directory map");
  633. }
  634. if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
  635. old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
  636. ctx->dx_dir_info_size += 10;
  637. retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
  638. sizeof(struct dx_dir_info),
  639. &ctx->dx_dir_info);
  640. if (retval) {
  641. ctx->dx_dir_info_size -= 10;
  642. return;
  643. }
  644. }
  645. /*
  646. * Normally, add_dx_dir_info is called with each inode in
  647. * sequential order; but once in a while (like when pass 3
  648. * needs to recreate the root directory or lost+found
  649. * directory) it is called out of order. In those cases, we
  650. * need to move the dx_dir_info entries down to make room, since
  651. * the dx_dir_info array needs to be sorted by inode number for
  652. * get_dx_dir_info()'s sake.
  653. */
  654. if (ctx->dx_dir_info_count &&
  655. ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) {
  656. for (i = ctx->dx_dir_info_count-1; i > 0; i--)
  657. if (ctx->dx_dir_info[i-1].ino < ino)
  658. break;
  659. dir = &ctx->dx_dir_info[i];
  660. if (dir->ino != ino)
  661. for (j = ctx->dx_dir_info_count++; j > i; j--)
  662. ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
  663. } else
  664. dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
  665. dir->ino = ino;
  666. dir->numblocks = num_blocks;
  667. dir->hashversion = 0;
  668. dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
  669. * sizeof (struct dx_dirblock_info),
  670. "dx_block info array");
  671. }
  672. /*
  673. * get_dx_dir_info() --- given an inode number, try to find the directory
  674. * information entry for it.
  675. */
  676. static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
  677. {
  678. int low, high, mid;
  679. low = 0;
  680. high = ctx->dx_dir_info_count-1;
  681. if (!ctx->dx_dir_info)
  682. return 0;
  683. if (ino == ctx->dx_dir_info[low].ino)
  684. return &ctx->dx_dir_info[low];
  685. if (ino == ctx->dx_dir_info[high].ino)
  686. return &ctx->dx_dir_info[high];
  687. while (low < high) {
  688. mid = (low+high)/2;
  689. if (mid == low || mid == high)
  690. break;
  691. if (ino == ctx->dx_dir_info[mid].ino)
  692. return &ctx->dx_dir_info[mid];
  693. if (ino < ctx->dx_dir_info[mid].ino)
  694. high = mid;
  695. else
  696. low = mid;
  697. }
  698. return 0;
  699. }
  700. /*
  701. * Free the dx_dir_info structure when it isn't needed any more.
  702. */
  703. static void e2fsck_free_dx_dir_info(e2fsck_t ctx)
  704. {
  705. int i;
  706. struct dx_dir_info *dir;
  707. if (ctx->dx_dir_info) {
  708. dir = ctx->dx_dir_info;
  709. for (i=0; i < ctx->dx_dir_info_count; i++) {
  710. ext2fs_free_mem(&dir->dx_block);
  711. }
  712. ext2fs_free_mem(&ctx->dx_dir_info);
  713. }
  714. ctx->dx_dir_info_size = 0;
  715. ctx->dx_dir_info_count = 0;
  716. }
  717. /*
  718. * A simple interator function
  719. */
  720. static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
  721. {
  722. if (*control >= ctx->dx_dir_info_count)
  723. return 0;
  724. return ctx->dx_dir_info + (*control)++;
  725. }
  726. #endif /* ENABLE_HTREE */
  727. /*
  728. * e2fsck.c - a consistency checker for the new extended file system.
  729. *
  730. */
  731. /*
  732. * This function allocates an e2fsck context
  733. */
  734. static errcode_t e2fsck_allocate_context(e2fsck_t *ret)
  735. {
  736. e2fsck_t context;
  737. errcode_t retval;
  738. retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
  739. if (retval)
  740. return retval;
  741. memset(context, 0, sizeof(struct e2fsck_struct));
  742. context->process_inode_size = 256;
  743. context->ext_attr_ver = 2;
  744. *ret = context;
  745. return 0;
  746. }
  747. struct ea_refcount_el {
  748. blk_t ea_blk;
  749. int ea_count;
  750. };
  751. struct ea_refcount {
  752. blk_t count;
  753. blk_t size;
  754. blk_t cursor;
  755. struct ea_refcount_el *list;
  756. };
  757. static void ea_refcount_free(ext2_refcount_t refcount)
  758. {
  759. if (!refcount)
  760. return;
  761. ext2fs_free_mem(&refcount->list);
  762. ext2fs_free_mem(&refcount);
  763. }
  764. /*
  765. * This function resets an e2fsck context; it is called when e2fsck
  766. * needs to be restarted.
  767. */
  768. static errcode_t e2fsck_reset_context(e2fsck_t ctx)
  769. {
  770. ctx->flags = 0;
  771. ctx->lost_and_found = 0;
  772. ctx->bad_lost_and_found = 0;
  773. ext2fs_free_inode_bitmap(ctx->inode_used_map);
  774. ctx->inode_used_map = 0;
  775. ext2fs_free_inode_bitmap(ctx->inode_dir_map);
  776. ctx->inode_dir_map = 0;
  777. ext2fs_free_inode_bitmap(ctx->inode_reg_map);
  778. ctx->inode_reg_map = 0;
  779. ext2fs_free_block_bitmap(ctx->block_found_map);
  780. ctx->block_found_map = 0;
  781. ext2fs_free_icount(ctx->inode_link_info);
  782. ctx->inode_link_info = 0;
  783. if (ctx->journal_io) {
  784. if (ctx->fs && ctx->fs->io != ctx->journal_io)
  785. io_channel_close(ctx->journal_io);
  786. ctx->journal_io = 0;
  787. }
  788. if (ctx->fs) {
  789. ext2fs_free_dblist(ctx->fs->dblist);
  790. ctx->fs->dblist = 0;
  791. }
  792. e2fsck_free_dir_info(ctx);
  793. #ifdef ENABLE_HTREE
  794. e2fsck_free_dx_dir_info(ctx);
  795. #endif
  796. ea_refcount_free(ctx->refcount);
  797. ctx->refcount = 0;
  798. ea_refcount_free(ctx->refcount_extra);
  799. ctx->refcount_extra = 0;
  800. ext2fs_free_block_bitmap(ctx->block_dup_map);
  801. ctx->block_dup_map = 0;
  802. ext2fs_free_block_bitmap(ctx->block_ea_map);
  803. ctx->block_ea_map = 0;
  804. ext2fs_free_inode_bitmap(ctx->inode_bad_map);
  805. ctx->inode_bad_map = 0;
  806. ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
  807. ctx->inode_imagic_map = 0;
  808. ext2fs_u32_list_free(ctx->dirs_to_hash);
  809. ctx->dirs_to_hash = 0;
  810. /*
  811. * Clear the array of invalid meta-data flags
  812. */
  813. ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
  814. ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
  815. ext2fs_free_mem(&ctx->invalid_inode_table_flag);
  816. /* Clear statistic counters */
  817. ctx->fs_directory_count = 0;
  818. ctx->fs_regular_count = 0;
  819. ctx->fs_blockdev_count = 0;
  820. ctx->fs_chardev_count = 0;
  821. ctx->fs_links_count = 0;
  822. ctx->fs_symlinks_count = 0;
  823. ctx->fs_fast_symlinks_count = 0;
  824. ctx->fs_fifo_count = 0;
  825. ctx->fs_total_count = 0;
  826. ctx->fs_sockets_count = 0;
  827. ctx->fs_ind_count = 0;
  828. ctx->fs_dind_count = 0;
  829. ctx->fs_tind_count = 0;
  830. ctx->fs_fragmented = 0;
  831. ctx->large_files = 0;
  832. /* Reset the superblock to the user's requested value */
  833. ctx->superblock = ctx->use_superblock;
  834. return 0;
  835. }
  836. static void e2fsck_free_context(e2fsck_t ctx)
  837. {
  838. if (!ctx)
  839. return;
  840. e2fsck_reset_context(ctx);
  841. if (ctx->blkid)
  842. blkid_put_cache(ctx->blkid);
  843. ext2fs_free_mem(&ctx);
  844. }
  845. /*
  846. * ea_refcount.c
  847. */
  848. /*
  849. * The strategy we use for keeping track of EA refcounts is as
  850. * follows. We keep a sorted array of first EA blocks and its
  851. * reference counts. Once the refcount has dropped to zero, it is
  852. * removed from the array to save memory space. Once the EA block is
  853. * checked, its bit is set in the block_ea_map bitmap.
  854. */
  855. static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
  856. {
  857. ext2_refcount_t refcount;
  858. errcode_t retval;
  859. size_t bytes;
  860. retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount);
  861. if (retval)
  862. return retval;
  863. memset(refcount, 0, sizeof(struct ea_refcount));
  864. if (!size)
  865. size = 500;
  866. refcount->size = size;
  867. bytes = (size_t) (size * sizeof(struct ea_refcount_el));
  868. #ifdef DEBUG
  869. printf("Refcount allocated %d entries, %d bytes.\n",
  870. refcount->size, bytes);
  871. #endif
  872. retval = ext2fs_get_mem(bytes, &refcount->list);
  873. if (retval)
  874. goto errout;
  875. memset(refcount->list, 0, bytes);
  876. refcount->count = 0;
  877. refcount->cursor = 0;
  878. *ret = refcount;
  879. return 0;
  880. errout:
  881. ea_refcount_free(refcount);
  882. return retval;
  883. }
  884. /*
  885. * collapse_refcount() --- go through the refcount array, and get rid
  886. * of any count == zero entries
  887. */
  888. static void refcount_collapse(ext2_refcount_t refcount)
  889. {
  890. unsigned int i, j;
  891. struct ea_refcount_el *list;
  892. list = refcount->list;
  893. for (i = 0, j = 0; i < refcount->count; i++) {
  894. if (list[i].ea_count) {
  895. if (i != j)
  896. list[j] = list[i];
  897. j++;
  898. }
  899. }
  900. #if defined(DEBUG) || defined(TEST_PROGRAM)
  901. printf("Refcount_collapse: size was %d, now %d\n",
  902. refcount->count, j);
  903. #endif
  904. refcount->count = j;
  905. }
  906. /*
  907. * insert_refcount_el() --- Insert a new entry into the sorted list at a
  908. * specified position.
  909. */
  910. static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
  911. blk_t blk, int pos)
  912. {
  913. struct ea_refcount_el *el;
  914. errcode_t retval;
  915. blk_t new_size = 0;
  916. int num;
  917. if (refcount->count >= refcount->size) {
  918. new_size = refcount->size + 100;
  919. #ifdef DEBUG
  920. printf("Reallocating refcount %d entries...\n", new_size);
  921. #endif
  922. retval = ext2fs_resize_mem((size_t) refcount->size *
  923. sizeof(struct ea_refcount_el),
  924. (size_t) new_size *
  925. sizeof(struct ea_refcount_el),
  926. &refcount->list);
  927. if (retval)
  928. return 0;
  929. refcount->size = new_size;
  930. }
  931. num = (int) refcount->count - pos;
  932. if (num < 0)
  933. return 0; /* should never happen */
  934. if (num) {
  935. memmove(&refcount->list[pos+1], &refcount->list[pos],
  936. sizeof(struct ea_refcount_el) * num);
  937. }
  938. refcount->count++;
  939. el = &refcount->list[pos];
  940. el->ea_count = 0;
  941. el->ea_blk = blk;
  942. return el;
  943. }
  944. /*
  945. * get_refcount_el() --- given an block number, try to find refcount
  946. * information in the sorted list. If the create flag is set,
  947. * and we can't find an entry, create one in the sorted list.
  948. */
  949. static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
  950. blk_t blk, int create)
  951. {
  952. float range;
  953. int low, high, mid;
  954. blk_t lowval, highval;
  955. if (!refcount || !refcount->list)
  956. return 0;
  957. retry:
  958. low = 0;
  959. high = (int) refcount->count-1;
  960. if (create && ((refcount->count == 0) ||
  961. (blk > refcount->list[high].ea_blk))) {
  962. if (refcount->count >= refcount->size)
  963. refcount_collapse(refcount);
  964. return insert_refcount_el(refcount, blk,
  965. (unsigned) refcount->count);
  966. }
  967. if (refcount->count == 0)
  968. return 0;
  969. if (refcount->cursor >= refcount->count)
  970. refcount->cursor = 0;
  971. if (blk == refcount->list[refcount->cursor].ea_blk)
  972. return &refcount->list[refcount->cursor++];
  973. #ifdef DEBUG
  974. printf("Non-cursor get_refcount_el: %u\n", blk);
  975. #endif
  976. while (low <= high) {
  977. if (low == high)
  978. mid = low;
  979. else {
  980. /* Interpolate for efficiency */
  981. lowval = refcount->list[low].ea_blk;
  982. highval = refcount->list[high].ea_blk;
  983. if (blk < lowval)
  984. range = 0;
  985. else if (blk > highval)
  986. range = 1;
  987. else
  988. range = ((float) (blk - lowval)) /
  989. (highval - lowval);
  990. mid = low + ((int) (range * (high-low)));
  991. }
  992. if (blk == refcount->list[mid].ea_blk) {
  993. refcount->cursor = mid+1;
  994. return &refcount->list[mid];
  995. }
  996. if (blk < refcount->list[mid].ea_blk)
  997. high = mid-1;
  998. else
  999. low = mid+1;
  1000. }
  1001. /*
  1002. * If we need to create a new entry, it should be right at
  1003. * low (where high will be left at low-1).
  1004. */
  1005. if (create) {
  1006. if (refcount->count >= refcount->size) {
  1007. refcount_collapse(refcount);
  1008. if (refcount->count < refcount->size)
  1009. goto retry;
  1010. }
  1011. return insert_refcount_el(refcount, blk, low);
  1012. }
  1013. return 0;
  1014. }
  1015. static errcode_t
  1016. ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
  1017. {
  1018. struct ea_refcount_el *el;
  1019. el = get_refcount_el(refcount, blk, 1);
  1020. if (!el)
  1021. return EXT2_ET_NO_MEMORY;
  1022. el->ea_count++;
  1023. if (ret)
  1024. *ret = el->ea_count;
  1025. return 0;
  1026. }
  1027. static errcode_t
  1028. ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
  1029. {
  1030. struct ea_refcount_el *el;
  1031. el = get_refcount_el(refcount, blk, 0);
  1032. if (!el || el->ea_count == 0)
  1033. return EXT2_ET_INVALID_ARGUMENT;
  1034. el->ea_count--;
  1035. if (ret)
  1036. *ret = el->ea_count;
  1037. return 0;
  1038. }
  1039. static errcode_t
  1040. ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
  1041. {
  1042. struct ea_refcount_el *el;
  1043. /*
  1044. * Get the refcount element
  1045. */
  1046. el = get_refcount_el(refcount, blk, count ? 1 : 0);
  1047. if (!el)
  1048. return count ? EXT2_ET_NO_MEMORY : 0;
  1049. el->ea_count = count;
  1050. return 0;
  1051. }
  1052. static inline void ea_refcount_intr_begin(ext2_refcount_t refcount)
  1053. {
  1054. refcount->cursor = 0;
  1055. }
  1056. static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret)
  1057. {
  1058. struct ea_refcount_el *list;
  1059. while (1) {
  1060. if (refcount->cursor >= refcount->count)
  1061. return 0;
  1062. list = refcount->list;
  1063. if (list[refcount->cursor].ea_count) {
  1064. if (ret)
  1065. *ret = list[refcount->cursor].ea_count;
  1066. return list[refcount->cursor++].ea_blk;
  1067. }
  1068. refcount->cursor++;
  1069. }
  1070. }
  1071. /*
  1072. * ehandler.c --- handle bad block errors which come up during the
  1073. * course of an e2fsck session.
  1074. */
  1075. static const char *operation;
  1076. static errcode_t
  1077. e2fsck_handle_read_error(io_channel channel, unsigned long block, int count,
  1078. void *data, size_t size FSCK_ATTR((unused)),
  1079. int actual FSCK_ATTR((unused)), errcode_t error)
  1080. {
  1081. int i;
  1082. char *p;
  1083. ext2_filsys fs = (ext2_filsys) channel->app_data;
  1084. e2fsck_t ctx;
  1085. ctx = (e2fsck_t) fs->priv_data;
  1086. /*
  1087. * If more than one block was read, try reading each block
  1088. * separately. We could use the actual bytes read to figure
  1089. * out where to start, but we don't bother.
  1090. */
  1091. if (count > 1) {
  1092. p = (char *) data;
  1093. for (i=0; i < count; i++, p += channel->block_size, block++) {
  1094. error = io_channel_read_blk(channel, block,
  1095. 1, p);
  1096. if (error)
  1097. return error;
  1098. }
  1099. return 0;
  1100. }
  1101. if (operation)
  1102. printf(_("Error reading block %lu (%s) while %s. "), block,
  1103. error_message(error), operation);
  1104. else
  1105. printf(_("Error reading block %lu (%s). "), block,
  1106. error_message(error));
  1107. preenhalt(ctx);
  1108. if (ask(ctx, _("Ignore error"), 1)) {
  1109. if (ask(ctx, _("Force rewrite"), 1))
  1110. io_channel_write_blk(channel, block, 1, data);
  1111. return 0;
  1112. }
  1113. return error;
  1114. }
  1115. static errcode_t
  1116. e2fsck_handle_write_error(io_channel channel, unsigned long block, int count,
  1117. const void *data, size_t size FSCK_ATTR((unused)),
  1118. int actual FSCK_ATTR((unused)), errcode_t error)
  1119. {
  1120. int i;
  1121. const char *p;
  1122. ext2_filsys fs = (ext2_filsys) channel->app_data;
  1123. e2fsck_t ctx;
  1124. ctx = (e2fsck_t) fs->priv_data;
  1125. /*
  1126. * If more than one block was written, try writing each block
  1127. * separately. We could use the actual bytes read to figure
  1128. * out where to start, but we don't bother.
  1129. */
  1130. if (count > 1) {
  1131. p = (const char *) data;
  1132. for (i=0; i < count; i++, p += channel->block_size, block++) {
  1133. error = io_channel_write_blk(channel, block,
  1134. 1, p);
  1135. if (error)
  1136. return error;
  1137. }
  1138. return 0;
  1139. }
  1140. if (operation)
  1141. printf(_("Error writing block %lu (%s) while %s. "), block,
  1142. error_message(error), operation);
  1143. else
  1144. printf(_("Error writing block %lu (%s). "), block,
  1145. error_message(error));
  1146. preenhalt(ctx);
  1147. if (ask(ctx, _("Ignore error"), 1))
  1148. return 0;
  1149. return error;
  1150. }
  1151. static const char *ehandler_operation(const char *op)
  1152. {
  1153. const char *ret = operation;
  1154. operation = op;
  1155. return ret;
  1156. }
  1157. static void ehandler_init(io_channel channel)
  1158. {
  1159. channel->read_error = e2fsck_handle_read_error;
  1160. channel->write_error = e2fsck_handle_write_error;
  1161. }
  1162. /*
  1163. * journal.c --- code for handling the "ext3" journal
  1164. *
  1165. * Copyright (C) 2000 Andreas Dilger
  1166. * Copyright (C) 2000 Theodore Ts'o
  1167. *
  1168. * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
  1169. * Copyright (C) 1999 Red Hat Software
  1170. *
  1171. * This file may be redistributed under the terms of the
  1172. * GNU General Public License version 2 or at your discretion
  1173. * any later version.
  1174. */
  1175. /*
  1176. * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
  1177. * This creates a larger static binary, and a smaller binary using
  1178. * shared libraries. It's also probably slightly less CPU-efficient,
  1179. * which is why it's not on by default. But, it's a good way of
  1180. * testing the functions in inode_io.c and fileio.c.
  1181. */
  1182. #undef USE_INODE_IO
  1183. /* Kernel compatibility functions for handling the journal. These allow us
  1184. * to use the recovery.c file virtually unchanged from the kernel, so we
  1185. * don't have to do much to keep kernel and user recovery in sync.
  1186. */
  1187. static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys)
  1188. {
  1189. #ifdef USE_INODE_IO
  1190. *phys = block;
  1191. return 0;
  1192. #else
  1193. struct inode *inode = journal->j_inode;
  1194. errcode_t retval;
  1195. blk_t pblk;
  1196. if (!inode) {
  1197. *phys = block;
  1198. return 0;
  1199. }
  1200. retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino,
  1201. &inode->i_ext2, NULL, 0, block, &pblk);
  1202. *phys = pblk;
  1203. return retval;
  1204. #endif
  1205. }
  1206. static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize)
  1207. {
  1208. struct buffer_head *bh;
  1209. bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer");
  1210. if (!bh)
  1211. return NULL;
  1212. bh->b_ctx = kdev->k_ctx;
  1213. if (kdev->k_dev == K_DEV_FS)
  1214. bh->b_io = kdev->k_ctx->fs->io;
  1215. else
  1216. bh->b_io = kdev->k_ctx->journal_io;
  1217. bh->b_size = blocksize;
  1218. bh->b_blocknr = blocknr;
  1219. return bh;
  1220. }
  1221. static void sync_blockdev(kdev_t kdev)
  1222. {
  1223. io_channel io;
  1224. if (kdev->k_dev == K_DEV_FS)
  1225. io = kdev->k_ctx->fs->io;
  1226. else
  1227. io = kdev->k_ctx->journal_io;
  1228. io_channel_flush(io);
  1229. }
  1230. static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
  1231. {
  1232. int retval;
  1233. struct buffer_head *bh;
  1234. for (; nr > 0; --nr) {
  1235. bh = *bhp++;
  1236. if (rw == READ && !bh->b_uptodate) {
  1237. retval = io_channel_read_blk(bh->b_io,
  1238. bh->b_blocknr,
  1239. 1, bh->b_data);
  1240. if (retval) {
  1241. bb_error_msg("while reading block %lu",
  1242. (unsigned long) bh->b_blocknr);
  1243. bh->b_err = retval;
  1244. continue;
  1245. }
  1246. bh->b_uptodate = 1;
  1247. } else if (rw == WRITE && bh->b_dirty) {
  1248. retval = io_channel_write_blk(bh->b_io,
  1249. bh->b_blocknr,
  1250. 1, bh->b_data);
  1251. if (retval) {
  1252. bb_error_msg("while writing block %lu",
  1253. (unsigned long) bh->b_blocknr);
  1254. bh->b_err = retval;
  1255. continue;
  1256. }
  1257. bh->b_dirty = 0;
  1258. bh->b_uptodate = 1;
  1259. }
  1260. }
  1261. }
  1262. static void mark_buffer_dirty(struct buffer_head *bh)
  1263. {
  1264. bh->b_dirty = 1;
  1265. }
  1266. static inline void mark_buffer_clean(struct buffer_head * bh)
  1267. {
  1268. bh->b_dirty = 0;
  1269. }
  1270. static void brelse(struct buffer_head *bh)
  1271. {
  1272. if (bh->b_dirty)
  1273. ll_rw_block(WRITE, 1, &bh);
  1274. ext2fs_free_mem(&bh);
  1275. }
  1276. static int buffer_uptodate(struct buffer_head *bh)
  1277. {
  1278. return bh->b_uptodate;
  1279. }
  1280. static inline void mark_buffer_uptodate(struct buffer_head *bh, int val)
  1281. {
  1282. bh->b_uptodate = val;
  1283. }
  1284. static void wait_on_buffer(struct buffer_head *bh)
  1285. {
  1286. if (!bh->b_uptodate)
  1287. ll_rw_block(READ, 1, &bh);
  1288. }
  1289. static void e2fsck_clear_recover(e2fsck_t ctx, int error)
  1290. {
  1291. ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
  1292. /* if we had an error doing journal recovery, we need a full fsck */
  1293. if (error)
  1294. ctx->fs->super->s_state &= ~EXT2_VALID_FS;
  1295. ext2fs_mark_super_dirty(ctx->fs);
  1296. }
  1297. static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
  1298. {
  1299. struct ext2_super_block *sb = ctx->fs->super;
  1300. struct ext2_super_block jsuper;
  1301. struct problem_context pctx;
  1302. struct buffer_head *bh;
  1303. struct inode *j_inode = NULL;
  1304. struct kdev_s *dev_fs = NULL, *dev_journal;
  1305. const char *journal_name = NULL;
  1306. journal_t *journal = NULL;
  1307. errcode_t retval = 0;
  1308. io_manager io_ptr = 0;
  1309. unsigned long start = 0;
  1310. blk_t blk;
  1311. int ext_journal = 0;
  1312. int tried_backup_jnl = 0;
  1313. int i;
  1314. clear_problem_context(&pctx);
  1315. journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
  1316. if (!journal) {
  1317. return EXT2_ET_NO_MEMORY;
  1318. }
  1319. dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
  1320. if (!dev_fs) {
  1321. retval = EXT2_ET_NO_MEMORY;
  1322. goto errout;
  1323. }
  1324. dev_journal = dev_fs+1;
  1325. dev_fs->k_ctx = dev_journal->k_ctx = ctx;
  1326. dev_fs->k_dev = K_DEV_FS;
  1327. dev_journal->k_dev = K_DEV_JOURNAL;
  1328. journal->j_dev = dev_journal;
  1329. journal->j_fs_dev = dev_fs;
  1330. journal->j_inode = NULL;
  1331. journal->j_blocksize = ctx->fs->blocksize;
  1332. if (uuid_is_null(sb->s_journal_uuid)) {
  1333. if (!sb->s_journal_inum)
  1334. return EXT2_ET_BAD_INODE_NUM;
  1335. j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
  1336. "journal inode");
  1337. if (!j_inode) {
  1338. retval = EXT2_ET_NO_MEMORY;
  1339. goto errout;
  1340. }
  1341. j_inode->i_ctx = ctx;
  1342. j_inode->i_ino = sb->s_journal_inum;
  1343. if ((retval = ext2fs_read_inode(ctx->fs,
  1344. sb->s_journal_inum,
  1345. &j_inode->i_ext2))) {
  1346. try_backup_journal:
  1347. if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
  1348. tried_backup_jnl)
  1349. goto errout;
  1350. memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
  1351. memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
  1352. EXT2_N_BLOCKS*4);
  1353. j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
  1354. j_inode->i_ext2.i_links_count = 1;
  1355. j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
  1356. tried_backup_jnl++;
  1357. }
  1358. if (!j_inode->i_ext2.i_links_count ||
  1359. !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
  1360. retval = EXT2_ET_NO_JOURNAL;
  1361. goto try_backup_journal;
  1362. }
  1363. if (j_inode->i_ext2.i_size / journal->j_blocksize <
  1364. JFS_MIN_JOURNAL_BLOCKS) {
  1365. retval = EXT2_ET_JOURNAL_TOO_SMALL;
  1366. goto try_backup_journal;
  1367. }
  1368. for (i=0; i < EXT2_N_BLOCKS; i++) {
  1369. blk = j_inode->i_ext2.i_block[i];
  1370. if (!blk) {
  1371. if (i < EXT2_NDIR_BLOCKS) {
  1372. retval = EXT2_ET_JOURNAL_TOO_SMALL;
  1373. goto try_backup_journal;
  1374. }
  1375. continue;
  1376. }
  1377. if (blk < sb->s_first_data_block ||
  1378. blk >= sb->s_blocks_count) {
  1379. retval = EXT2_ET_BAD_BLOCK_NUM;
  1380. goto try_backup_journal;
  1381. }
  1382. }
  1383. journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
  1384. #ifdef USE_INODE_IO
  1385. retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
  1386. &j_inode->i_ext2,
  1387. &journal_name);
  1388. if (retval)
  1389. goto errout;
  1390. io_ptr = inode_io_manager;
  1391. #else
  1392. journal->j_inode = j_inode;
  1393. ctx->journal_io = ctx->fs->io;
  1394. if ((retval = journal_bmap(journal, 0, &start)) != 0)
  1395. goto errout;
  1396. #endif
  1397. } else {
  1398. ext_journal = 1;
  1399. if (!ctx->journal_name) {
  1400. char uuid[37];
  1401. uuid_unparse(sb->s_journal_uuid, uuid);
  1402. ctx->journal_name = blkid_get_devname(ctx->blkid,
  1403. "UUID", uuid);
  1404. if (!ctx->journal_name)
  1405. ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
  1406. }
  1407. journal_name = ctx->journal_name;
  1408. if (!journal_name) {
  1409. fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
  1410. return EXT2_ET_LOAD_EXT_JOURNAL;
  1411. }
  1412. io_ptr = unix_io_manager;
  1413. }
  1414. #ifndef USE_INODE_IO
  1415. if (ext_journal)
  1416. #endif
  1417. retval = io_ptr->open(journal_name, IO_FLAG_RW,
  1418. &ctx->journal_io);
  1419. if (retval)
  1420. goto errout;
  1421. io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
  1422. if (ext_journal) {
  1423. if (ctx->fs->blocksize == 1024)
  1424. start = 1;
  1425. bh = getblk(dev_journal, start, ctx->fs->blocksize);
  1426. if (!bh) {
  1427. retval = EXT2_ET_NO_MEMORY;
  1428. goto errout;
  1429. }
  1430. ll_rw_block(READ, 1, &bh);
  1431. if ((retval = bh->b_err) != 0)
  1432. goto errout;
  1433. memcpy(&jsuper, start ? bh->b_data : bh->b_data + 1024,
  1434. sizeof(jsuper));
  1435. brelse(bh);
  1436. #if BB_BIG_ENDIAN
  1437. if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
  1438. ext2fs_swap_super(&jsuper);
  1439. #endif
  1440. if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
  1441. !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
  1442. fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
  1443. retval = EXT2_ET_LOAD_EXT_JOURNAL;
  1444. goto errout;
  1445. }
  1446. /* Make sure the journal UUID is correct */
  1447. if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
  1448. sizeof(jsuper.s_uuid))) {
  1449. fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
  1450. retval = EXT2_ET_LOAD_EXT_JOURNAL;
  1451. goto errout;
  1452. }
  1453. journal->j_maxlen = jsuper.s_blocks_count;
  1454. start++;
  1455. }
  1456. if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
  1457. retval = EXT2_ET_NO_MEMORY;
  1458. goto errout;
  1459. }
  1460. journal->j_sb_buffer = bh;
  1461. journal->j_superblock = (journal_superblock_t *)bh->b_data;
  1462. #ifdef USE_INODE_IO
  1463. ext2fs_free_mem(&j_inode);
  1464. #endif
  1465. *ret_journal = journal;
  1466. return 0;
  1467. errout:
  1468. ext2fs_free_mem(&dev_fs);
  1469. ext2fs_free_mem(&j_inode);
  1470. ext2fs_free_mem(&journal);
  1471. return retval;
  1472. }
  1473. static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
  1474. struct problem_context *pctx)
  1475. {
  1476. struct ext2_super_block *sb = ctx->fs->super;
  1477. int recover = ctx->fs->super->s_feature_incompat &
  1478. EXT3_FEATURE_INCOMPAT_RECOVER;
  1479. int has_journal = ctx->fs->super->s_feature_compat &
  1480. EXT3_FEATURE_COMPAT_HAS_JOURNAL;
  1481. if (has_journal || sb->s_journal_inum) {
  1482. /* The journal inode is bogus, remove and force full fsck */
  1483. pctx->ino = sb->s_journal_inum;
  1484. if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
  1485. if (has_journal && sb->s_journal_inum)
  1486. printf("*** ext3 journal has been deleted - "
  1487. "filesystem is now ext2 only ***\n\n");
  1488. sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
  1489. sb->s_journal_inum = 0;
  1490. ctx->flags |= E2F_FLAG_JOURNAL_INODE; /* FIXME: todo */
  1491. e2fsck_clear_recover(ctx, 1);
  1492. return 0;
  1493. }
  1494. return EXT2_ET_BAD_INODE_NUM;
  1495. } else if (recover) {
  1496. if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
  1497. e2fsck_clear_recover(ctx, 1);
  1498. return 0;
  1499. }
  1500. return EXT2_ET_UNSUPP_FEATURE;
  1501. }
  1502. return 0;
  1503. }
  1504. #define V1_SB_SIZE 0x0024
  1505. static void clear_v2_journal_fields(journal_t *journal)
  1506. {
  1507. e2fsck_t ctx = journal->j_dev->k_ctx;
  1508. struct problem_context pctx;
  1509. clear_problem_context(&pctx);
  1510. if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
  1511. return;
  1512. memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
  1513. ctx->fs->blocksize-V1_SB_SIZE);
  1514. mark_buffer_dirty(journal->j_sb_buffer);
  1515. }
  1516. static errcode_t e2fsck_journal_load(journal_t *journal)
  1517. {
  1518. e2fsck_t ctx = journal->j_dev->k_ctx;
  1519. journal_superblock_t *jsb;
  1520. struct buffer_head *jbh = journal->j_sb_buffer;
  1521. struct problem_context pctx;
  1522. clear_problem_context(&pctx);
  1523. ll_rw_block(READ, 1, &jbh);
  1524. if (jbh->b_err) {
  1525. bb_error_msg(_("reading journal superblock"));
  1526. return jbh->b_err;
  1527. }
  1528. jsb = journal->j_superblock;
  1529. /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
  1530. if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
  1531. return e2fsck_journal_fix_bad_inode(ctx, &pctx);
  1532. switch (ntohl(jsb->s_header.h_blocktype)) {
  1533. case JFS_SUPERBLOCK_V1:
  1534. journal->j_format_version = 1;
  1535. if (jsb->s_feature_compat ||
  1536. jsb->s_feature_incompat ||
  1537. jsb->s_feature_ro_compat ||
  1538. jsb->s_nr_users)
  1539. clear_v2_journal_fields(journal);
  1540. break;
  1541. case JFS_SUPERBLOCK_V2:
  1542. journal->j_format_version = 2;
  1543. if (ntohl(jsb->s_nr_users) > 1 &&
  1544. uuid_is_null(ctx->fs->super->s_journal_uuid))
  1545. clear_v2_journal_fields(journal);
  1546. if (ntohl(jsb->s_nr_users) > 1) {
  1547. fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
  1548. return EXT2_ET_JOURNAL_UNSUPP_VERSION;
  1549. }
  1550. break;
  1551. /*
  1552. * These should never appear in a journal super block, so if
  1553. * they do, the journal is badly corrupted.
  1554. */
  1555. case JFS_DESCRIPTOR_BLOCK:
  1556. case JFS_COMMIT_BLOCK:
  1557. case JFS_REVOKE_BLOCK:
  1558. return EXT2_ET_CORRUPT_SUPERBLOCK;
  1559. /* If we don't understand the superblock major type, but there
  1560. * is a magic number, then it is likely to be a new format we
  1561. * just don't understand, so leave it alone. */
  1562. default:
  1563. return EXT2_ET_JOURNAL_UNSUPP_VERSION;
  1564. }
  1565. if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
  1566. return EXT2_ET_UNSUPP_FEATURE;
  1567. if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
  1568. return EXT2_ET_RO_UNSUPP_FEATURE;
  1569. /* We have now checked whether we know enough about the journal
  1570. * format to be able to proceed safely, so any other checks that
  1571. * fail we should attempt to recover from. */
  1572. if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
  1573. bb_error_msg(_("%s: no valid journal superblock found"),
  1574. ctx->device_name);
  1575. return EXT2_ET_CORRUPT_SUPERBLOCK;
  1576. }
  1577. if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
  1578. journal->j_maxlen = ntohl(jsb->s_maxlen);
  1579. else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) {
  1580. bb_error_msg(_("%s: journal too short"),
  1581. ctx->device_name);
  1582. return EXT2_ET_CORRUPT_SUPERBLOCK;
  1583. }
  1584. journal->j_tail_sequence = ntohl(jsb->s_sequence);
  1585. journal->j_transaction_sequence = journal->j_tail_sequence;
  1586. journal->j_tail = ntohl(jsb->s_start);
  1587. journal->j_first = ntohl(jsb->s_first);
  1588. journal->j_last = ntohl(jsb->s_maxlen);
  1589. return 0;
  1590. }
  1591. static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
  1592. journal_t *journal)
  1593. {
  1594. char *p;
  1595. union {
  1596. uuid_t uuid;
  1597. __u32 val[4];
  1598. } u;
  1599. __u32 new_seq = 0;
  1600. int i;
  1601. /* Leave a valid existing V1 superblock signature alone.
  1602. * Anything unrecognizable we overwrite with a new V2
  1603. * signature. */
  1604. if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
  1605. jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) {
  1606. jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
  1607. jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
  1608. }
  1609. /* Zero out everything else beyond the superblock header */
  1610. p = ((char *) jsb) + sizeof(journal_header_t);
  1611. memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
  1612. jsb->s_blocksize = htonl(ctx->fs->blocksize);
  1613. jsb->s_maxlen = htonl(journal->j_maxlen);
  1614. jsb->s_first = htonl(1);
  1615. /* Initialize the journal sequence number so that there is "no"
  1616. * chance we will find old "valid" transactions in the journal.
  1617. * This avoids the need to zero the whole journal (slow to do,
  1618. * and risky when we are just recovering the filesystem).
  1619. */
  1620. uuid_generate(u.uuid);
  1621. for (i = 0; i < 4; i ++)
  1622. new_seq ^= u.val[i];
  1623. jsb->s_sequence = htonl(new_seq);
  1624. mark_buffer_dirty(journal->j_sb_buffer);
  1625. ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
  1626. }
  1627. static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
  1628. journal_t *journal,
  1629. struct problem_context *pctx)
  1630. {
  1631. struct ext2_super_block *sb = ctx->fs->super;
  1632. int recover = ctx->fs->super->s_feature_incompat &
  1633. EXT3_FEATURE_INCOMPAT_RECOVER;
  1634. if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
  1635. if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
  1636. e2fsck_journal_reset_super(ctx, journal->j_superblock,
  1637. journal);
  1638. journal->j_transaction_sequence = 1;
  1639. e2fsck_clear_recover(ctx, recover);
  1640. return 0;
  1641. }
  1642. return EXT2_ET_CORRUPT_SUPERBLOCK;
  1643. } else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
  1644. return EXT2_ET_CORRUPT_SUPERBLOCK;
  1645. return 0;
  1646. }
  1647. static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
  1648. int reset, int drop)
  1649. {
  1650. journal_superblock_t *jsb;
  1651. if (drop)
  1652. mark_buffer_clean(journal->j_sb_buffer);
  1653. else if (!(ctx->options & E2F_OPT_READONLY)) {
  1654. jsb = journal->j_superblock;
  1655. jsb->s_sequence = htonl(journal->j_transaction_sequence);
  1656. if (reset)
  1657. jsb->s_start = 0; /* this marks the journal as empty */
  1658. mark_buffer_dirty(journal->j_sb_buffer);
  1659. }
  1660. brelse(journal->j_sb_buffer);
  1661. if (ctx->journal_io) {
  1662. if (ctx->fs && ctx->fs->io != ctx->journal_io)
  1663. io_channel_close(ctx->journal_io);
  1664. ctx->journal_io = 0;
  1665. }
  1666. #ifndef USE_INODE_IO
  1667. ext2fs_free_mem(&journal->j_inode);
  1668. #endif
  1669. ext2fs_free_mem(&journal->j_fs_dev);
  1670. ext2fs_free_mem(&journal);
  1671. }
  1672. /*
  1673. * This function makes sure that the superblock fields regarding the
  1674. * journal are consistent.
  1675. */
  1676. static int e2fsck_check_ext3_journal(e2fsck_t ctx)
  1677. {
  1678. struct ext2_super_block *sb = ctx->fs->super;
  1679. journal_t *journal;
  1680. int recover = ctx->fs->super->s_feature_incompat &
  1681. EXT3_FEATURE_INCOMPAT_RECOVER;
  1682. struct problem_context pctx;
  1683. problem_t problem;
  1684. int reset = 0, force_fsck = 0;
  1685. int retval;
  1686. /* If we don't have any journal features, don't do anything more */
  1687. if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
  1688. !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
  1689. uuid_is_null(sb->s_journal_uuid))
  1690. return 0;
  1691. clear_problem_context(&pctx);
  1692. pctx.num = sb->s_journal_inum;
  1693. retval = e2fsck_get_journal(ctx, &journal);
  1694. if (retval) {
  1695. if ((retval == EXT2_ET_BAD_INODE_NUM) ||
  1696. (retval == EXT2_ET_BAD_BLOCK_NUM) ||
  1697. (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
  1698. (retval == EXT2_ET_NO_JOURNAL))
  1699. return e2fsck_journal_fix_bad_inode(ctx, &pctx);
  1700. return retval;
  1701. }
  1702. retval = e2fsck_journal_load(journal);
  1703. if (retval) {
  1704. if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
  1705. ((retval == EXT2_ET_UNSUPP_FEATURE) &&
  1706. (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
  1707. &pctx))) ||
  1708. ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
  1709. (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
  1710. &pctx))) ||
  1711. ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
  1712. (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
  1713. retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
  1714. &pctx);
  1715. e2fsck_journal_release(ctx, journal, 0, 1);
  1716. return retval;
  1717. }
  1718. /*
  1719. * We want to make the flags consistent here. We will not leave with
  1720. * needs_recovery set but has_journal clear. We can't get in a loop
  1721. * with -y, -n, or -p, only if a user isn't making up their mind.
  1722. */
  1723. no_has_journal:
  1724. if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
  1725. recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER;
  1726. pctx.str = "inode";
  1727. if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
  1728. if (recover &&
  1729. !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
  1730. goto no_has_journal;
  1731. /*
  1732. * Need a full fsck if we are releasing a
  1733. * journal stored on a reserved inode.
  1734. */
  1735. force_fsck = recover ||
  1736. (sb->s_journal_inum < EXT2_FIRST_INODE(sb));
  1737. /* Clear all of the journal fields */
  1738. sb->s_journal_inum = 0;
  1739. sb->s_journal_dev = 0;
  1740. memset(sb->s_journal_uuid, 0,
  1741. sizeof(sb->s_journal_uuid));
  1742. e2fsck_clear_recover(ctx, force_fsck);
  1743. } else if (!(ctx->options & E2F_OPT_READONLY)) {
  1744. sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
  1745. ext2fs_mark_super_dirty(ctx->fs);
  1746. }
  1747. }
  1748. if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
  1749. !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
  1750. journal->j_superblock->s_start != 0) {
  1751. /* Print status information */
  1752. fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
  1753. if (ctx->superblock)
  1754. problem = PR_0_JOURNAL_RUN_DEFAULT;
  1755. else
  1756. problem = PR_0_JOURNAL_RUN;
  1757. if (fix_problem(ctx, problem, &pctx)) {
  1758. ctx->options |= E2F_OPT_FORCE;
  1759. sb->s_feature_incompat |=
  1760. EXT3_FEATURE_INCOMPAT_RECOVER;
  1761. ext2fs_mark_super_dirty(ctx->fs);
  1762. } else if (fix_problem(ctx,
  1763. PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
  1764. reset = 1;
  1765. sb->s_state &= ~EXT2_VALID_FS;
  1766. ext2fs_mark_super_dirty(ctx->fs);
  1767. }
  1768. /*
  1769. * If the user answers no to the above question, we
  1770. * ignore the fact that journal apparently has data;
  1771. * accidentally replaying over valid data would be far
  1772. * worse than skipping a questionable recovery.
  1773. *
  1774. * XXX should we abort with a fatal error here? What
  1775. * will the ext3 kernel code do if a filesystem with
  1776. * !NEEDS_RECOVERY but with a non-zero
  1777. * journal->j_superblock->s_start is mounted?
  1778. */
  1779. }
  1780. e2fsck_journal_release(ctx, journal, reset, 0);
  1781. return retval;
  1782. }
  1783. static errcode_t recover_ext3_journal(e2fsck_t ctx)
  1784. {
  1785. journal_t *journal;
  1786. int retval;
  1787. journal_init_revoke_caches();
  1788. retval = e2fsck_get_journal(ctx, &journal);
  1789. if (retval)
  1790. return retval;
  1791. retval = e2fsck_journal_load(journal);
  1792. if (retval)
  1793. goto errout;
  1794. retval = journal_init_revoke(journal, 1024);
  1795. if (retval)
  1796. goto errout;
  1797. retval = -journal_recover(journal);
  1798. if (retval)
  1799. goto errout;
  1800. if (journal->j_superblock->s_errno) {
  1801. ctx->fs->super->s_state |= EXT2_ERROR_FS;
  1802. ext2fs_mark_super_dirty(ctx->fs);
  1803. journal->j_superblock->s_errno = 0;
  1804. mark_buffer_dirty(journal->j_sb_buffer);
  1805. }
  1806. errout:
  1807. journal_destroy_revoke(journal);
  1808. journal_destroy_revoke_caches();
  1809. e2fsck_journal_release(ctx, journal, 1, 0);
  1810. return retval;
  1811. }
  1812. static int e2fsck_run_ext3_journal(e2fsck_t ctx)
  1813. {
  1814. io_manager io_ptr = ctx->fs->io->manager;
  1815. int blocksize = ctx->fs->blocksize;
  1816. errcode_t retval, recover_retval;
  1817. printf(_("%s: recovering journal\n"), ctx->device_name);
  1818. if (ctx->options & E2F_OPT_READONLY) {
  1819. printf(_("%s: won't do journal recovery while read-only\n"),
  1820. ctx->device_name);
  1821. return EXT2_ET_FILE_RO;
  1822. }
  1823. if (ctx->fs->flags & EXT2_FLAG_DIRTY)
  1824. ext2fs_flush(ctx->fs); /* Force out any modifications */
  1825. recover_retval = recover_ext3_journal(ctx);
  1826. /*
  1827. * Reload the filesystem context to get up-to-date data from disk
  1828. * because journal recovery will change the filesystem under us.
  1829. */
  1830. ext2fs_close(ctx->fs);
  1831. retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
  1832. ctx->superblock, blocksize, io_ptr,
  1833. &ctx->fs);
  1834. if (retval) {
  1835. bb_error_msg(_("while trying to re-open %s"),
  1836. ctx->device_name);
  1837. bb_error_msg_and_die(0);
  1838. }
  1839. ctx->fs->priv_data = ctx;
  1840. /* Set the superblock flags */
  1841. e2fsck_clear_recover(ctx, recover_retval);
  1842. return recover_retval;
  1843. }
  1844. /*
  1845. * This function will move the journal inode from a visible file in
  1846. * the filesystem directory hierarchy to the reserved inode if necessary.
  1847. */
  1848. static const char *const journal_names[] = {
  1849. ".journal", "journal", ".journal.dat", "journal.dat", 0 };
  1850. static void e2fsck_move_ext3_journal(e2fsck_t ctx)
  1851. {
  1852. struct ext2_super_block *sb = ctx->fs->super;
  1853. struct problem_context pctx;
  1854. struct ext2_inode inode;
  1855. ext2_filsys fs = ctx->fs;
  1856. ext2_ino_t ino;
  1857. errcode_t retval;
  1858. const char *const * cpp;
  1859. int group, mount_flags;
  1860. clear_problem_context(&pctx);
  1861. /*
  1862. * If the filesystem is opened read-only, or there is no
  1863. * journal, then do nothing.
  1864. */
  1865. if ((ctx->options & E2F_OPT_READONLY) ||
  1866. (sb->s_journal_inum == 0) ||
  1867. !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
  1868. return;
  1869. /*
  1870. * Read in the journal inode
  1871. */
  1872. if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
  1873. return;
  1874. /*
  1875. * If it's necessary to backup the journal inode, do so.
  1876. */
  1877. if ((sb->s_jnl_backup_type == 0) ||
  1878. ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
  1879. memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
  1880. if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
  1881. memcpy(sb->s_jnl_blocks, inode.i_block,
  1882. EXT2_N_BLOCKS*4);
  1883. sb->s_jnl_blocks[16] = inode.i_size;
  1884. sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
  1885. ext2fs_mark_super_dirty(fs);
  1886. fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
  1887. }
  1888. }
  1889. /*
  1890. * If the journal is already the hidden inode, then do nothing
  1891. */
  1892. if (sb->s_journal_inum == EXT2_JOURNAL_INO)
  1893. return;
  1894. /*
  1895. * The journal inode had better have only one link and not be readable.
  1896. */
  1897. if (inode.i_links_count != 1)
  1898. return;
  1899. /*
  1900. * If the filesystem is mounted, or we can't tell whether
  1901. * or not it's mounted, do nothing.
  1902. */
  1903. retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
  1904. if (retval || (mount_flags & EXT2_MF_MOUNTED))
  1905. return;
  1906. /*
  1907. * If we can't find the name of the journal inode, then do
  1908. * nothing.
  1909. */
  1910. for (cpp = journal_names; *cpp; cpp++) {
  1911. retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
  1912. strlen(*cpp), 0, &ino);
  1913. if ((retval == 0) && (ino == sb->s_journal_inum))
  1914. break;
  1915. }
  1916. if (*cpp == 0)
  1917. return;
  1918. /* We need the inode bitmap to be loaded */
  1919. retval = ext2fs_read_bitmaps(fs);
  1920. if (retval)
  1921. return;
  1922. pctx.str = *cpp;
  1923. if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
  1924. return;
  1925. /*
  1926. * OK, we've done all the checks, let's actually move the
  1927. * journal inode. Errors at this point mean we need to force
  1928. * an ext2 filesystem check.
  1929. */
  1930. if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
  1931. goto err_out;
  1932. if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
  1933. goto err_out;
  1934. sb->s_journal_inum = EXT2_JOURNAL_INO;
  1935. ext2fs_mark_super_dirty(fs);
  1936. fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
  1937. inode.i_links_count = 0;
  1938. inode.i_dtime = time(NULL);
  1939. if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
  1940. goto err_out;
  1941. group = ext2fs_group_of_ino(fs, ino);
  1942. ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
  1943. ext2fs_mark_ib_dirty(fs);
  1944. fs->group_desc[group].bg_free_inodes_count++;
  1945. fs->super->s_free_inodes_count++;
  1946. return;
  1947. err_out:
  1948. pctx.errcode = retval;
  1949. fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
  1950. fs->super->s_state &= ~EXT2_VALID_FS;
  1951. ext2fs_mark_super_dirty(fs);
  1952. }
  1953. /*
  1954. * message.c --- print e2fsck messages (with compression)
  1955. *
  1956. * print_e2fsck_message() prints a message to the user, using
  1957. * compression techniques and expansions of abbreviations.
  1958. *
  1959. * The following % expansions are supported:
  1960. *
  1961. * %b <blk> block number
  1962. * %B <blkcount> integer
  1963. * %c <blk2> block number
  1964. * %Di <dirent>->ino inode number
  1965. * %Dn <dirent>->name string
  1966. * %Dr <dirent>->rec_len
  1967. * %Dl <dirent>->name_len
  1968. * %Dt <dirent>->filetype
  1969. * %d <dir> inode number
  1970. * %g <group> integer
  1971. * %i <ino> inode number
  1972. * %Is <inode> -> i_size
  1973. * %IS <inode> -> i_extra_isize
  1974. * %Ib <inode> -> i_blocks
  1975. * %Il <inode> -> i_links_count
  1976. * %Im <inode> -> i_mode
  1977. * %IM <inode> -> i_mtime
  1978. * %IF <inode> -> i_faddr
  1979. * %If <inode> -> i_file_acl
  1980. * %Id <inode> -> i_dir_acl
  1981. * %Iu <inode> -> i_uid
  1982. * %Ig <inode> -> i_gid
  1983. * %j <ino2> inode number
  1984. * %m <com_err error message>
  1985. * %N <num>
  1986. * %p ext2fs_get_pathname of directory <ino>
  1987. * %P ext2fs_get_pathname of <dirent>->ino with <ino2> as
  1988. * the containing directory. (If dirent is NULL
  1989. * then return the pathname of directory <ino2>)
  1990. * %q ext2fs_get_pathname of directory <dir>
  1991. * %Q ext2fs_get_pathname of directory <ino> with <dir> as
  1992. * the containing directory.
  1993. * %s <str> miscellaneous string
  1994. * %S backup superblock
  1995. * %X <num> hexadecimal format
  1996. *
  1997. * The following '@' expansions are supported:
  1998. *
  1999. * @a extended attribute
  2000. * @A error allocating
  2001. * @b block
  2002. * @B bitmap
  2003. * @c compress
  2004. * @C conflicts with some other fs block
  2005. * @D deleted
  2006. * @d directory
  2007. * @e entry
  2008. * @E Entry '%Dn' in %p (%i)
  2009. * @f filesystem
  2010. * @F for @i %i (%Q) is
  2011. * @g group
  2012. * @h HTREE directory inode
  2013. * @i inode
  2014. * @I illegal
  2015. * @j journal
  2016. * @l lost+found
  2017. * @L is a link
  2018. * @m multiply-claimed
  2019. * @n invalid
  2020. * @o orphaned
  2021. * @p problem in
  2022. * @r root inode
  2023. * @s should be
  2024. * @S superblock
  2025. * @u unattached
  2026. * @v device
  2027. * @z zero-length
  2028. */
  2029. /*
  2030. * This structure defines the abbreviations used by the text strings
  2031. * below. The first character in the string is the index letter. An
  2032. * abbreviation of the form '@<i>' is expanded by looking up the index
  2033. * letter <i> in the table below.
  2034. */
  2035. static const char *const abbrevs[] = {
  2036. N_("aextended attribute"),
  2037. N_("Aerror allocating"),
  2038. N_("bblock"),
  2039. N_("Bbitmap"),
  2040. N_("ccompress"),
  2041. N_("Cconflicts with some other fs @b"),
  2042. N_("iinode"),
  2043. N_("Iillegal"),
  2044. N_("jjournal"),
  2045. N_("Ddeleted"),
  2046. N_("ddirectory"),
  2047. N_("eentry"),
  2048. N_("E@e '%Dn' in %p (%i)"),
  2049. N_("ffilesystem"),
  2050. N_("Ffor @i %i (%Q) is"),
  2051. N_("ggroup"),
  2052. N_("hHTREE @d @i"),
  2053. N_("llost+found"),
  2054. N_("Lis a link"),
  2055. N_("mmultiply-claimed"),
  2056. N_("ninvalid"),
  2057. N_("oorphaned"),
  2058. N_("pproblem in"),
  2059. N_("rroot @i"),
  2060. N_("sshould be"),
  2061. N_("Ssuper@b"),
  2062. N_("uunattached"),
  2063. N_("vdevice"),
  2064. N_("zzero-length"),
  2065. "@@",
  2066. 0
  2067. };
  2068. /*
  2069. * Give more user friendly names to the "special" inodes.
  2070. */
  2071. #define num_special_inodes 11
  2072. static const char *const special_inode_name[] =
  2073. {
  2074. N_("<The NULL inode>"), /* 0 */
  2075. N_("<The bad blocks inode>"), /* 1 */
  2076. "/", /* 2 */
  2077. N_("<The ACL index inode>"), /* 3 */
  2078. N_("<The ACL data inode>"), /* 4 */
  2079. N_("<The boot loader inode>"), /* 5 */
  2080. N_("<The undelete directory inode>"), /* 6 */
  2081. N_("<The group descriptor inode>"), /* 7 */
  2082. N_("<The journal inode>"), /* 8 */
  2083. N_("<Reserved inode 9>"), /* 9 */
  2084. N_("<Reserved inode 10>"), /* 10 */
  2085. };
  2086. /*
  2087. * This function does "safe" printing. It will convert non-printable
  2088. * ASCII characters using '^' and M- notation.
  2089. */
  2090. static void safe_print(const char *cp, int len)
  2091. {
  2092. unsigned char ch;
  2093. if (len < 0)
  2094. len = strlen(cp);
  2095. while (len--) {
  2096. ch = *cp++;
  2097. if (ch > 128) {
  2098. fputs("M-", stdout);
  2099. ch -= 128;
  2100. }
  2101. if ((ch < 32) || (ch == 0x7f)) {
  2102. bb_putchar('^');
  2103. ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
  2104. }
  2105. bb_putchar(ch);
  2106. }
  2107. }
  2108. /*
  2109. * This function prints a pathname, using the ext2fs_get_pathname
  2110. * function
  2111. */
  2112. static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
  2113. {
  2114. errcode_t retval;
  2115. char *path;
  2116. if (!dir && (ino < num_special_inodes)) {
  2117. fputs(_(special_inode_name[ino]), stdout);
  2118. return;
  2119. }
  2120. retval = ext2fs_get_pathname(fs, dir, ino, &path);
  2121. if (retval)
  2122. fputs("???", stdout);
  2123. else {
  2124. safe_print(path, -1);
  2125. ext2fs_free_mem(&path);
  2126. }
  2127. }
  2128. static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
  2129. struct problem_context *pctx, int first);
  2130. /*
  2131. * This function handles the '@' expansion. We allow recursive
  2132. * expansion; an @ expression can contain further '@' and '%'
  2133. * expressions.
  2134. */
  2135. static void expand_at_expression(e2fsck_t ctx, char ch,
  2136. struct problem_context *pctx,
  2137. int *first)
  2138. {
  2139. const char *const *cpp;
  2140. const char *str;
  2141. /* Search for the abbreviation */
  2142. for (cpp = abbrevs; *cpp; cpp++) {
  2143. if (ch == *cpp[0])
  2144. break;
  2145. }
  2146. if (*cpp) {
  2147. str = _(*cpp) + 1;
  2148. if (*first && islower(*str)) {
  2149. *first = 0;
  2150. bb_putchar(toupper(*str++));
  2151. }
  2152. print_e2fsck_message(ctx, str, pctx, *first);
  2153. } else
  2154. printf("@%c", ch);
  2155. }
  2156. /*
  2157. * This function expands '%IX' expressions
  2158. */
  2159. static void expand_inode_expression(char ch,
  2160. struct problem_context *ctx)
  2161. {
  2162. struct ext2_inode *inode;
  2163. struct ext2_inode_large *large_inode;
  2164. char * time_str;
  2165. time_t t;
  2166. int do_gmt = -1;
  2167. if (!ctx || !ctx->inode)
  2168. goto no_inode;
  2169. inode = ctx->inode;
  2170. large_inode = (struct ext2_inode_large *) inode;
  2171. switch (ch) {
  2172. case 's':
  2173. if (LINUX_S_ISDIR(inode->i_mode))
  2174. printf("%u", inode->i_size);
  2175. else {
  2176. printf("%"PRIu64, (inode->i_size |
  2177. ((uint64_t) inode->i_size_high << 32)));
  2178. }
  2179. break;
  2180. case 'S':
  2181. printf("%u", large_inode->i_extra_isize);
  2182. break;
  2183. case 'b':
  2184. printf("%u", inode->i_blocks);
  2185. break;
  2186. case 'l':
  2187. printf("%d", inode->i_links_count);
  2188. break;
  2189. case 'm':
  2190. printf("0%o", inode->i_mode);
  2191. break;
  2192. case 'M':
  2193. /* The diet libc doesn't respect the TZ environemnt variable */
  2194. if (do_gmt == -1) {
  2195. time_str = getenv("TZ");
  2196. if (!time_str)
  2197. time_str = "";
  2198. do_gmt = !strcmp(time_str, "GMT");
  2199. }
  2200. t = inode->i_mtime;
  2201. time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
  2202. printf("%.24s", time_str);
  2203. break;
  2204. case 'F':
  2205. printf("%u", inode->i_faddr);
  2206. break;
  2207. case 'f':
  2208. printf("%u", inode->i_file_acl);
  2209. break;
  2210. case 'd':
  2211. printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
  2212. inode->i_dir_acl : 0));
  2213. break;
  2214. case 'u':
  2215. printf("%d", (inode->i_uid |
  2216. (inode->osd2.linux2.l_i_uid_high << 16)));
  2217. break;
  2218. case 'g':
  2219. printf("%d", (inode->i_gid |
  2220. (inode->osd2.linux2.l_i_gid_high << 16)));
  2221. break;
  2222. default:
  2223. no_inode:
  2224. printf("%%I%c", ch);
  2225. break;
  2226. }
  2227. }
  2228. /*
  2229. * This function expands '%dX' expressions
  2230. */
  2231. static void expand_dirent_expression(char ch,
  2232. struct problem_context *ctx)
  2233. {
  2234. struct ext2_dir_entry *dirent;
  2235. int len;
  2236. if (!ctx || !ctx->dirent)
  2237. goto no_dirent;
  2238. dirent = ctx->dirent;
  2239. switch (ch) {
  2240. case 'i':
  2241. printf("%u", dirent->inode);
  2242. break;
  2243. case 'n':
  2244. len = dirent->name_len & 0xFF;
  2245. if (len > EXT2_NAME_LEN)
  2246. len = EXT2_NAME_LEN;
  2247. if (len > dirent->rec_len)
  2248. len = dirent->rec_len;
  2249. safe_print(dirent->name, len);
  2250. break;
  2251. case 'r':
  2252. printf("%u", dirent->rec_len);
  2253. break;
  2254. case 'l':
  2255. printf("%u", dirent->name_len & 0xFF);
  2256. break;
  2257. case 't':
  2258. printf("%u", dirent->name_len >> 8);
  2259. break;
  2260. default:
  2261. no_dirent:
  2262. printf("%%D%c", ch);
  2263. break;
  2264. }
  2265. }
  2266. static void expand_percent_expression(ext2_filsys fs, char ch,
  2267. struct problem_context *ctx)
  2268. {
  2269. if (!ctx)
  2270. goto no_context;
  2271. switch (ch) {
  2272. case '%':
  2273. bb_putchar('%');
  2274. break;
  2275. case 'b':
  2276. printf("%u", ctx->blk);
  2277. break;
  2278. case 'B':
  2279. printf("%"PRIi64, ctx->blkcount);
  2280. break;
  2281. case 'c':
  2282. printf("%u", ctx->blk2);
  2283. break;
  2284. case 'd':
  2285. printf("%u", ctx->dir);
  2286. break;
  2287. case 'g':
  2288. printf("%d", ctx->group);
  2289. break;
  2290. case 'i':
  2291. printf("%u", ctx->ino);
  2292. break;
  2293. case 'j':
  2294. printf("%u", ctx->ino2);
  2295. break;
  2296. case 'm':
  2297. fputs(error_message(ctx->errcode), stdout);
  2298. break;
  2299. case 'N':
  2300. printf("%"PRIi64, ctx->num);
  2301. break;
  2302. case 'p':
  2303. print_pathname(fs, ctx->ino, 0);
  2304. break;
  2305. case 'P':
  2306. print_pathname(fs, ctx->ino2,
  2307. ctx->dirent ? ctx->dirent->inode : 0);
  2308. break;
  2309. case 'q':
  2310. print_pathname(fs, ctx->dir, 0);
  2311. break;
  2312. case 'Q':
  2313. print_pathname(fs, ctx->dir, ctx->ino);
  2314. break;
  2315. case 'S':
  2316. printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
  2317. break;
  2318. case 's':
  2319. fputs((ctx->str ? ctx->str : "NULL"), stdout);
  2320. break;
  2321. case 'X':
  2322. printf("0x%"PRIi64, ctx->num);
  2323. break;
  2324. default:
  2325. no_context:
  2326. printf("%%%c", ch);
  2327. break;
  2328. }
  2329. }
  2330. static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
  2331. struct problem_context *pctx, int first)
  2332. {
  2333. ext2_filsys fs = ctx->fs;
  2334. const char * cp;
  2335. int i;
  2336. e2fsck_clear_progbar(ctx);
  2337. for (cp = msg; *cp; cp++) {
  2338. if (cp[0] == '@') {
  2339. cp++;
  2340. expand_at_expression(ctx, *cp, pctx, &first);
  2341. } else if (cp[0] == '%' && cp[1] == 'I') {
  2342. cp += 2;
  2343. expand_inode_expression(*cp, pctx);
  2344. } else if (cp[0] == '%' && cp[1] == 'D') {
  2345. cp += 2;
  2346. expand_dirent_expression(*cp, pctx);
  2347. } else if ((cp[0] == '%')) {
  2348. cp++;
  2349. expand_percent_expression(fs, *cp, pctx);
  2350. } else {
  2351. for (i=0; cp[i]; i++)
  2352. if ((cp[i] == '@') || cp[i] == '%')
  2353. break;
  2354. printf("%.*s", i, cp);
  2355. cp += i-1;
  2356. }
  2357. first = 0;
  2358. }
  2359. }
  2360. /*
  2361. * region.c --- code which manages allocations within a region.
  2362. */
  2363. struct region_el {
  2364. region_addr_t start;
  2365. region_addr_t end;
  2366. struct region_el *next;
  2367. };
  2368. struct region_struct {
  2369. region_addr_t min;
  2370. region_addr_t max;
  2371. struct region_el *allocated;
  2372. };
  2373. static region_t region_create(region_addr_t min, region_addr_t max)
  2374. {
  2375. region_t region;
  2376. region = xzalloc(sizeof(struct region_struct));
  2377. region->min = min;
  2378. region->max = max;
  2379. return region;
  2380. }
  2381. static void region_free(region_t region)
  2382. {
  2383. struct region_el *r, *next;
  2384. for (r = region->allocated; r; r = next) {
  2385. next = r->next;
  2386. free(r);
  2387. }
  2388. memset(region, 0, sizeof(struct region_struct));
  2389. free(region);
  2390. }
  2391. static int region_allocate(region_t region, region_addr_t start, int n)
  2392. {
  2393. struct region_el *r, *new_region, *prev, *next;
  2394. region_addr_t end;
  2395. end = start+n;
  2396. if ((start < region->min) || (end > region->max))
  2397. return -1;
  2398. if (n == 0)
  2399. return 1;
  2400. /*
  2401. * Search through the linked list. If we find that it
  2402. * conflicts witih something that's already allocated, return
  2403. * 1; if we can find an existing region which we can grow, do
  2404. * so. Otherwise, stop when we find the appropriate place
  2405. * insert a new region element into the linked list.
  2406. */
  2407. for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
  2408. if (((start >= r->start) && (start < r->end)) ||
  2409. ((end > r->start) && (end <= r->end)) ||
  2410. ((start <= r->start) && (end >= r->end)))
  2411. return 1;
  2412. if (end == r->start) {
  2413. r->start = start;
  2414. return 0;
  2415. }
  2416. if (start == r->end) {
  2417. if ((next = r->next)) {
  2418. if (end > next->start)
  2419. return 1;
  2420. if (end == next->start) {
  2421. r->end = next->end;
  2422. r->next = next->next;
  2423. free(next);
  2424. return 0;
  2425. }
  2426. }
  2427. r->end = end;
  2428. return 0;
  2429. }
  2430. if (start < r->start)
  2431. break;
  2432. }
  2433. /*
  2434. * Insert a new region element structure into the linked list
  2435. */
  2436. new_region = xmalloc(sizeof(struct region_el));
  2437. new_region->start = start;
  2438. new_region->end = start + n;
  2439. new_region->next = r;
  2440. if (prev)
  2441. prev->next = new_region;
  2442. else
  2443. region->allocated = new_region;
  2444. return 0;
  2445. }
  2446. /*
  2447. * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
  2448. *
  2449. * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
  2450. * and applies the following tests to each inode:
  2451. *
  2452. * - The mode field of the inode must be legal.
  2453. * - The size and block count fields of the inode are correct.
  2454. * - A data block must not be used by another inode
  2455. *
  2456. * Pass 1 also gathers the collects the following information:
  2457. *
  2458. * - A bitmap of which inodes are in use. (inode_used_map)
  2459. * - A bitmap of which inodes are directories. (inode_dir_map)
  2460. * - A bitmap of which inodes are regular files. (inode_reg_map)
  2461. * - A bitmap of which inodes have bad fields. (inode_bad_map)
  2462. * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
  2463. * - A bitmap of which blocks are in use. (block_found_map)
  2464. * - A bitmap of which blocks are in use by two inodes (block_dup_map)
  2465. * - The data blocks of the directory inodes. (dir_map)
  2466. *
  2467. * Pass 1 is designed to stash away enough information so that the
  2468. * other passes should not need to read in the inode information
  2469. * during the normal course of a filesystem check. (Althogh if an
  2470. * inconsistency is detected, other passes may need to read in an
  2471. * inode to fix it.)
  2472. *
  2473. * Note that pass 1B will be invoked if there are any duplicate blocks
  2474. * found.
  2475. */
  2476. static int process_block(ext2_filsys fs, blk_t *blocknr,
  2477. e2_blkcnt_t blockcnt, blk_t ref_blk,
  2478. int ref_offset, void *priv_data);
  2479. static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
  2480. e2_blkcnt_t blockcnt, blk_t ref_blk,
  2481. int ref_offset, void *priv_data);
  2482. static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
  2483. char *block_buf);
  2484. static void mark_table_blocks(e2fsck_t ctx);
  2485. static void alloc_imagic_map(e2fsck_t ctx);
  2486. static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
  2487. static void handle_fs_bad_blocks(e2fsck_t ctx);
  2488. static void process_inodes(e2fsck_t ctx, char *block_buf);
  2489. static int process_inode_cmp(const void *a, const void *b);
  2490. static errcode_t scan_callback(ext2_filsys fs,
  2491. dgrp_t group, void * priv_data);
  2492. static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
  2493. char *block_buf, int adjust_sign);
  2494. /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
  2495. static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
  2496. struct ext2_inode * inode, int bufsize,
  2497. const char *proc);
  2498. struct process_block_struct_1 {
  2499. ext2_ino_t ino;
  2500. unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
  2501. fragmented:1, compressed:1, bbcheck:1;
  2502. blk_t num_blocks;
  2503. blk_t max_blocks;
  2504. e2_blkcnt_t last_block;
  2505. int num_illegal_blocks;
  2506. blk_t previous_block;
  2507. struct ext2_inode *inode;
  2508. struct problem_context *pctx;
  2509. ext2fs_block_bitmap fs_meta_blocks;
  2510. e2fsck_t ctx;
  2511. };
  2512. struct process_inode_block {
  2513. ext2_ino_t ino;
  2514. struct ext2_inode inode;
  2515. };
  2516. struct scan_callback_struct {
  2517. e2fsck_t ctx;
  2518. char *block_buf;
  2519. };
  2520. /*
  2521. * For the inodes to process list.
  2522. */
  2523. static struct process_inode_block *inodes_to_process;
  2524. static int process_inode_count;
  2525. static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
  2526. EXT2_MIN_BLOCK_LOG_SIZE + 1];
  2527. /*
  2528. * Free all memory allocated by pass1 in preparation for restarting
  2529. * things.
  2530. */
  2531. static void unwind_pass1(void)
  2532. {
  2533. ext2fs_free_mem(&inodes_to_process);
  2534. }
  2535. /*
  2536. * Check to make sure a device inode is real. Returns 1 if the device
  2537. * checks out, 0 if not.
  2538. *
  2539. * Note: this routine is now also used to check FIFO's and Sockets,
  2540. * since they have the same requirement; the i_block fields should be
  2541. * zero.
  2542. */
  2543. static int
  2544. e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
  2545. {
  2546. int i;
  2547. /*
  2548. * If i_blocks is non-zero, or the index flag is set, then
  2549. * this is a bogus device/fifo/socket
  2550. */
  2551. if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
  2552. (inode->i_flags & EXT2_INDEX_FL))
  2553. return 0;
  2554. /*
  2555. * We should be able to do the test below all the time, but
  2556. * because the kernel doesn't forcibly clear the device
  2557. * inode's additional i_block fields, there are some rare
  2558. * occasions when a legitimate device inode will have non-zero
  2559. * additional i_block fields. So for now, we only complain
  2560. * when the immutable flag is set, which should never happen
  2561. * for devices. (And that's when the problem is caused, since
  2562. * you can't set or clear immutable flags for devices.) Once
  2563. * the kernel has been fixed we can change this...
  2564. */
  2565. if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
  2566. for (i=4; i < EXT2_N_BLOCKS; i++)
  2567. if (inode->i_block[i])
  2568. return 0;
  2569. }
  2570. return 1;
  2571. }
  2572. /*
  2573. * Check to make sure a symlink inode is real. Returns 1 if the symlink
  2574. * checks out, 0 if not.
  2575. */
  2576. static int
  2577. e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf)
  2578. {
  2579. unsigned int len;
  2580. int i;
  2581. blk_t blocks;
  2582. if ((inode->i_size_high || inode->i_size == 0) ||
  2583. (inode->i_flags & EXT2_INDEX_FL))
  2584. return 0;
  2585. blocks = ext2fs_inode_data_blocks(fs, inode);
  2586. if (blocks) {
  2587. if ((inode->i_size >= fs->blocksize) ||
  2588. (blocks != fs->blocksize >> 9) ||
  2589. (inode->i_block[0] < fs->super->s_first_data_block) ||
  2590. (inode->i_block[0] >= fs->super->s_blocks_count))
  2591. return 0;
  2592. for (i = 1; i < EXT2_N_BLOCKS; i++)
  2593. if (inode->i_block[i])
  2594. return 0;
  2595. if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
  2596. return 0;
  2597. len = strnlen(buf, fs->blocksize);
  2598. if (len == fs->blocksize)
  2599. return 0;
  2600. } else {
  2601. if (inode->i_size >= sizeof(inode->i_block))
  2602. return 0;
  2603. len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
  2604. if (len == sizeof(inode->i_block))
  2605. return 0;
  2606. }
  2607. if (len != inode->i_size)
  2608. return 0;
  2609. return 1;
  2610. }
  2611. /*
  2612. * If the immutable (or append-only) flag is set on the inode, offer
  2613. * to clear it.
  2614. */
  2615. #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
  2616. static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
  2617. {
  2618. if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
  2619. return;
  2620. if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
  2621. return;
  2622. pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
  2623. e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
  2624. }
  2625. /*
  2626. * If device, fifo or socket, check size is zero -- if not offer to
  2627. * clear it
  2628. */
  2629. static void check_size(e2fsck_t ctx, struct problem_context *pctx)
  2630. {
  2631. struct ext2_inode *inode = pctx->inode;
  2632. if ((inode->i_size == 0) && (inode->i_size_high == 0))
  2633. return;
  2634. if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
  2635. return;
  2636. inode->i_size = 0;
  2637. inode->i_size_high = 0;
  2638. e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
  2639. }
  2640. static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
  2641. {
  2642. struct ext2_super_block *sb = ctx->fs->super;
  2643. struct ext2_inode_large *inode;
  2644. struct ext2_ext_attr_entry *entry;
  2645. char *start, *end;
  2646. int storage_size, remain, offs;
  2647. int problem = 0;
  2648. inode = (struct ext2_inode_large *) pctx->inode;
  2649. storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
  2650. inode->i_extra_isize;
  2651. start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
  2652. inode->i_extra_isize + sizeof(__u32);
  2653. end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
  2654. entry = (struct ext2_ext_attr_entry *) start;
  2655. /* scan all entry's headers first */
  2656. /* take finish entry 0UL into account */
  2657. remain = storage_size - sizeof(__u32);
  2658. offs = end - start;
  2659. while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
  2660. /* header eats this space */
  2661. remain -= sizeof(struct ext2_ext_attr_entry);
  2662. /* is attribute name valid? */
  2663. if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
  2664. pctx->num = entry->e_name_len;
  2665. problem = PR_1_ATTR_NAME_LEN;
  2666. goto fix;
  2667. }
  2668. /* attribute len eats this space */
  2669. remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
  2670. /* check value size */
  2671. if (entry->e_value_size == 0 || entry->e_value_size > remain) {
  2672. pctx->num = entry->e_value_size;
  2673. problem = PR_1_ATTR_VALUE_SIZE;
  2674. goto fix;
  2675. }
  2676. /* check value placement */
  2677. if (entry->e_value_offs +
  2678. EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
  2679. printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
  2680. pctx->num = entry->e_value_offs;
  2681. problem = PR_1_ATTR_VALUE_OFFSET;
  2682. goto fix;
  2683. }
  2684. /* e_value_block must be 0 in inode's ea */
  2685. if (entry->e_value_block != 0) {
  2686. pctx->num = entry->e_value_block;
  2687. problem = PR_1_ATTR_VALUE_BLOCK;
  2688. goto fix;
  2689. }
  2690. /* e_hash must be 0 in inode's ea */
  2691. if (entry->e_hash != 0) {
  2692. pctx->num = entry->e_hash;
  2693. problem = PR_1_ATTR_HASH;
  2694. goto fix;
  2695. }
  2696. remain -= entry->e_value_size;
  2697. offs -= EXT2_XATTR_SIZE(entry->e_value_size);
  2698. entry = EXT2_EXT_ATTR_NEXT(entry);
  2699. }
  2700. fix:
  2701. /*
  2702. * it seems like a corruption. it's very unlikely we could repair
  2703. * EA(s) in automatic fashion -bzzz
  2704. */
  2705. if (problem == 0 || !fix_problem(ctx, problem, pctx))
  2706. return;
  2707. /* simple remove all possible EA(s) */
  2708. *((__u32 *)start) = 0UL;
  2709. e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
  2710. EXT2_INODE_SIZE(sb), "pass1");
  2711. }
  2712. static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
  2713. {
  2714. struct ext2_super_block *sb = ctx->fs->super;
  2715. struct ext2_inode_large *inode;
  2716. __u32 *eamagic;
  2717. int min, max;
  2718. inode = (struct ext2_inode_large *) pctx->inode;
  2719. if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
  2720. /* this isn't large inode. so, nothing to check */
  2721. return;
  2722. }
  2723. /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
  2724. min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
  2725. max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
  2726. /*
  2727. * For now we will allow i_extra_isize to be 0, but really
  2728. * implementations should never allow i_extra_isize to be 0
  2729. */
  2730. if (inode->i_extra_isize &&
  2731. (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
  2732. if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
  2733. return;
  2734. inode->i_extra_isize = min;
  2735. e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
  2736. EXT2_INODE_SIZE(sb), "pass1");
  2737. return;
  2738. }
  2739. eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
  2740. inode->i_extra_isize);
  2741. if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
  2742. /* it seems inode has an extended attribute(s) in body */
  2743. check_ea_in_inode(ctx, pctx);
  2744. }
  2745. }
  2746. static void e2fsck_pass1(e2fsck_t ctx)
  2747. {
  2748. int i;
  2749. __u64 max_sizes;
  2750. ext2_filsys fs = ctx->fs;
  2751. ext2_ino_t ino;
  2752. struct ext2_inode *inode;
  2753. ext2_inode_scan scan;
  2754. char *block_buf;
  2755. unsigned char frag, fsize;
  2756. struct problem_context pctx;
  2757. struct scan_callback_struct scan_struct;
  2758. struct ext2_super_block *sb = ctx->fs->super;
  2759. int imagic_fs;
  2760. int busted_fs_time = 0;
  2761. int inode_size;
  2762. clear_problem_context(&pctx);
  2763. if (!(ctx->options & E2F_OPT_PREEN))
  2764. fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
  2765. if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
  2766. !(ctx->options & E2F_OPT_NO)) {
  2767. if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
  2768. ctx->dirs_to_hash = 0;
  2769. }
  2770. /* Pass 1 */
  2771. #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
  2772. for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
  2773. max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
  2774. max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
  2775. max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
  2776. max_sizes = (max_sizes * (1UL << i)) - 1;
  2777. ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
  2778. }
  2779. #undef EXT2_BPP
  2780. imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
  2781. /*
  2782. * Allocate bitmaps structures
  2783. */
  2784. pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
  2785. &ctx->inode_used_map);
  2786. if (pctx.errcode) {
  2787. pctx.num = 1;
  2788. fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
  2789. ctx->flags |= E2F_FLAG_ABORT;
  2790. return;
  2791. }
  2792. pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
  2793. _("directory inode map"), &ctx->inode_dir_map);
  2794. if (pctx.errcode) {
  2795. pctx.num = 2;
  2796. fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
  2797. ctx->flags |= E2F_FLAG_ABORT;
  2798. return;
  2799. }
  2800. pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
  2801. _("regular file inode map"), &ctx->inode_reg_map);
  2802. if (pctx.errcode) {
  2803. pctx.num = 6;
  2804. fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
  2805. ctx->flags |= E2F_FLAG_ABORT;
  2806. return;
  2807. }
  2808. pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
  2809. &ctx->block_found_map);
  2810. if (pctx.errcode) {
  2811. pctx.num = 1;
  2812. fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
  2813. ctx->flags |= E2F_FLAG_ABORT;
  2814. return;
  2815. }
  2816. pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
  2817. &ctx->inode_link_info);
  2818. if (pctx.errcode) {
  2819. fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
  2820. ctx->flags |= E2F_FLAG_ABORT;
  2821. return;
  2822. }
  2823. inode_size = EXT2_INODE_SIZE(fs->super);
  2824. inode = (struct ext2_inode *)
  2825. e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
  2826. inodes_to_process = (struct process_inode_block *)
  2827. e2fsck_allocate_memory(ctx,
  2828. (ctx->process_inode_size *
  2829. sizeof(struct process_inode_block)),
  2830. "array of inodes to process");
  2831. process_inode_count = 0;
  2832. pctx.errcode = ext2fs_init_dblist(fs, 0);
  2833. if (pctx.errcode) {
  2834. fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
  2835. ctx->flags |= E2F_FLAG_ABORT;
  2836. return;
  2837. }
  2838. /*
  2839. * If the last orphan field is set, clear it, since the pass1
  2840. * processing will automatically find and clear the orphans.
  2841. * In the future, we may want to try using the last_orphan
  2842. * linked list ourselves, but for now, we clear it so that the
  2843. * ext3 mount code won't get confused.
  2844. */
  2845. if (!(ctx->options & E2F_OPT_READONLY)) {
  2846. if (fs->super->s_last_orphan) {
  2847. fs->super->s_last_orphan = 0;
  2848. ext2fs_mark_super_dirty(fs);
  2849. }
  2850. }
  2851. mark_table_blocks(ctx);
  2852. block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
  2853. "block interate buffer");
  2854. e2fsck_use_inode_shortcuts(ctx, 1);
  2855. ehandler_operation(_("doing inode scan"));
  2856. pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
  2857. &scan);
  2858. if (pctx.errcode) {
  2859. fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
  2860. ctx->flags |= E2F_FLAG_ABORT;
  2861. return;
  2862. }
  2863. ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
  2864. ctx->stashed_inode = inode;
  2865. scan_struct.ctx = ctx;
  2866. scan_struct.block_buf = block_buf;
  2867. ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
  2868. if (ctx->progress)
  2869. if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
  2870. return;
  2871. if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
  2872. (fs->super->s_mtime < fs->super->s_inodes_count))
  2873. busted_fs_time = 1;
  2874. while (1) {
  2875. pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
  2876. inode, inode_size);
  2877. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  2878. return;
  2879. if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
  2880. continue;
  2881. }
  2882. if (pctx.errcode) {
  2883. fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
  2884. ctx->flags |= E2F_FLAG_ABORT;
  2885. return;
  2886. }
  2887. if (!ino)
  2888. break;
  2889. pctx.ino = ino;
  2890. pctx.inode = inode;
  2891. ctx->stashed_ino = ino;
  2892. if (inode->i_links_count) {
  2893. pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
  2894. ino, inode->i_links_count);
  2895. if (pctx.errcode) {
  2896. pctx.num = inode->i_links_count;
  2897. fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
  2898. ctx->flags |= E2F_FLAG_ABORT;
  2899. return;
  2900. }
  2901. }
  2902. if (ino == EXT2_BAD_INO) {
  2903. struct process_block_struct_1 pb;
  2904. pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
  2905. &pb.fs_meta_blocks);
  2906. if (pctx.errcode) {
  2907. pctx.num = 4;
  2908. fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
  2909. ctx->flags |= E2F_FLAG_ABORT;
  2910. return;
  2911. }
  2912. pb.ino = EXT2_BAD_INO;
  2913. pb.num_blocks = pb.last_block = 0;
  2914. pb.num_illegal_blocks = 0;
  2915. pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
  2916. pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
  2917. pb.inode = inode;
  2918. pb.pctx = &pctx;
  2919. pb.ctx = ctx;
  2920. pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
  2921. block_buf, process_bad_block, &pb);
  2922. ext2fs_free_block_bitmap(pb.fs_meta_blocks);
  2923. if (pctx.errcode) {
  2924. fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
  2925. ctx->flags |= E2F_FLAG_ABORT;
  2926. return;
  2927. }
  2928. if (pb.bbcheck)
  2929. if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
  2930. ctx->flags |= E2F_FLAG_ABORT;
  2931. return;
  2932. }
  2933. ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
  2934. clear_problem_context(&pctx);
  2935. continue;
  2936. } else if (ino == EXT2_ROOT_INO) {
  2937. /*
  2938. * Make sure the root inode is a directory; if
  2939. * not, offer to clear it. It will be
  2940. * regnerated in pass #3.
  2941. */
  2942. if (!LINUX_S_ISDIR(inode->i_mode)) {
  2943. if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
  2944. inode->i_dtime = time(NULL);
  2945. inode->i_links_count = 0;
  2946. ext2fs_icount_store(ctx->inode_link_info,
  2947. ino, 0);
  2948. e2fsck_write_inode(ctx, ino, inode,
  2949. "pass1");
  2950. }
  2951. }
  2952. /*
  2953. * If dtime is set, offer to clear it. mke2fs
  2954. * version 0.2b created filesystems with the
  2955. * dtime field set for the root and lost+found
  2956. * directories. We won't worry about
  2957. * /lost+found, since that can be regenerated
  2958. * easily. But we will fix the root directory
  2959. * as a special case.
  2960. */
  2961. if (inode->i_dtime && inode->i_links_count) {
  2962. if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
  2963. inode->i_dtime = 0;
  2964. e2fsck_write_inode(ctx, ino, inode,
  2965. "pass1");
  2966. }
  2967. }
  2968. } else if (ino == EXT2_JOURNAL_INO) {
  2969. ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
  2970. if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
  2971. if (!LINUX_S_ISREG(inode->i_mode) &&
  2972. fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
  2973. &pctx)) {
  2974. inode->i_mode = LINUX_S_IFREG;
  2975. e2fsck_write_inode(ctx, ino, inode,
  2976. "pass1");
  2977. }
  2978. check_blocks(ctx, &pctx, block_buf);
  2979. continue;
  2980. }
  2981. if ((inode->i_links_count || inode->i_blocks ||
  2982. inode->i_blocks || inode->i_block[0]) &&
  2983. fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
  2984. &pctx)) {
  2985. memset(inode, 0, inode_size);
  2986. ext2fs_icount_store(ctx->inode_link_info,
  2987. ino, 0);
  2988. e2fsck_write_inode_full(ctx, ino, inode,
  2989. inode_size, "pass1");
  2990. }
  2991. } else if (ino < EXT2_FIRST_INODE(fs->super)) {
  2992. int problem = 0;
  2993. ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
  2994. if (ino == EXT2_BOOT_LOADER_INO) {
  2995. if (LINUX_S_ISDIR(inode->i_mode))
  2996. problem = PR_1_RESERVED_BAD_MODE;
  2997. } else if (ino == EXT2_RESIZE_INO) {
  2998. if (inode->i_mode &&
  2999. !LINUX_S_ISREG(inode->i_mode))
  3000. problem = PR_1_RESERVED_BAD_MODE;
  3001. } else {
  3002. if (inode->i_mode != 0)
  3003. problem = PR_1_RESERVED_BAD_MODE;
  3004. }
  3005. if (problem) {
  3006. if (fix_problem(ctx, problem, &pctx)) {
  3007. inode->i_mode = 0;
  3008. e2fsck_write_inode(ctx, ino, inode,
  3009. "pass1");
  3010. }
  3011. }
  3012. check_blocks(ctx, &pctx, block_buf);
  3013. continue;
  3014. }
  3015. /*
  3016. * Check for inodes who might have been part of the
  3017. * orphaned list linked list. They should have gotten
  3018. * dealt with by now, unless the list had somehow been
  3019. * corrupted.
  3020. *
  3021. * FIXME: In the future, inodes which are still in use
  3022. * (and which are therefore) pending truncation should
  3023. * be handled specially. Right now we just clear the
  3024. * dtime field, and the normal e2fsck handling of
  3025. * inodes where i_size and the inode blocks are
  3026. * inconsistent is to fix i_size, instead of releasing
  3027. * the extra blocks. This won't catch the inodes that
  3028. * was at the end of the orphan list, but it's better
  3029. * than nothing. The right answer is that there
  3030. * shouldn't be any bugs in the orphan list handling. :-)
  3031. */
  3032. if (inode->i_dtime && !busted_fs_time &&
  3033. inode->i_dtime < ctx->fs->super->s_inodes_count) {
  3034. if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
  3035. inode->i_dtime = inode->i_links_count ?
  3036. 0 : time(NULL);
  3037. e2fsck_write_inode(ctx, ino, inode,
  3038. "pass1");
  3039. }
  3040. }
  3041. /*
  3042. * This code assumes that deleted inodes have
  3043. * i_links_count set to 0.
  3044. */
  3045. if (!inode->i_links_count) {
  3046. if (!inode->i_dtime && inode->i_mode) {
  3047. if (fix_problem(ctx,
  3048. PR_1_ZERO_DTIME, &pctx)) {
  3049. inode->i_dtime = time(NULL);
  3050. e2fsck_write_inode(ctx, ino, inode,
  3051. "pass1");
  3052. }
  3053. }
  3054. continue;
  3055. }
  3056. /*
  3057. * n.b. 0.3c ext2fs code didn't clear i_links_count for
  3058. * deleted files. Oops.
  3059. *
  3060. * Since all new ext2 implementations get this right,
  3061. * we now assume that the case of non-zero
  3062. * i_links_count and non-zero dtime means that we
  3063. * should keep the file, not delete it.
  3064. *
  3065. */
  3066. if (inode->i_dtime) {
  3067. if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
  3068. inode->i_dtime = 0;
  3069. e2fsck_write_inode(ctx, ino, inode, "pass1");
  3070. }
  3071. }
  3072. ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
  3073. switch (fs->super->s_creator_os) {
  3074. case EXT2_OS_LINUX:
  3075. frag = inode->osd2.linux2.l_i_frag;
  3076. fsize = inode->osd2.linux2.l_i_fsize;
  3077. break;
  3078. case EXT2_OS_HURD:
  3079. frag = inode->osd2.hurd2.h_i_frag;
  3080. fsize = inode->osd2.hurd2.h_i_fsize;
  3081. break;
  3082. case EXT2_OS_MASIX:
  3083. frag = inode->osd2.masix2.m_i_frag;
  3084. fsize = inode->osd2.masix2.m_i_fsize;
  3085. break;
  3086. default:
  3087. frag = fsize = 0;
  3088. }
  3089. if (inode->i_faddr || frag || fsize ||
  3090. (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
  3091. mark_inode_bad(ctx, ino);
  3092. if (inode->i_flags & EXT2_IMAGIC_FL) {
  3093. if (imagic_fs) {
  3094. if (!ctx->inode_imagic_map)
  3095. alloc_imagic_map(ctx);
  3096. ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
  3097. ino);
  3098. } else {
  3099. if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
  3100. inode->i_flags &= ~EXT2_IMAGIC_FL;
  3101. e2fsck_write_inode(ctx, ino,
  3102. inode, "pass1");
  3103. }
  3104. }
  3105. }
  3106. check_inode_extra_space(ctx, &pctx);
  3107. if (LINUX_S_ISDIR(inode->i_mode)) {
  3108. ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
  3109. e2fsck_add_dir_info(ctx, ino, 0);
  3110. ctx->fs_directory_count++;
  3111. } else if (LINUX_S_ISREG (inode->i_mode)) {
  3112. ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
  3113. ctx->fs_regular_count++;
  3114. } else if (LINUX_S_ISCHR (inode->i_mode) &&
  3115. e2fsck_pass1_check_device_inode(fs, inode)) {
  3116. check_immutable(ctx, &pctx);
  3117. check_size(ctx, &pctx);
  3118. ctx->fs_chardev_count++;
  3119. } else if (LINUX_S_ISBLK (inode->i_mode) &&
  3120. e2fsck_pass1_check_device_inode(fs, inode)) {
  3121. check_immutable(ctx, &pctx);
  3122. check_size(ctx, &pctx);
  3123. ctx->fs_blockdev_count++;
  3124. } else if (LINUX_S_ISLNK (inode->i_mode) &&
  3125. e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
  3126. check_immutable(ctx, &pctx);
  3127. ctx->fs_symlinks_count++;
  3128. if (ext2fs_inode_data_blocks(fs, inode) == 0) {
  3129. ctx->fs_fast_symlinks_count++;
  3130. check_blocks(ctx, &pctx, block_buf);
  3131. continue;
  3132. }
  3133. }
  3134. else if (LINUX_S_ISFIFO (inode->i_mode) &&
  3135. e2fsck_pass1_check_device_inode(fs, inode)) {
  3136. check_immutable(ctx, &pctx);
  3137. check_size(ctx, &pctx);
  3138. ctx->fs_fifo_count++;
  3139. } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
  3140. e2fsck_pass1_check_device_inode(fs, inode)) {
  3141. check_immutable(ctx, &pctx);
  3142. check_size(ctx, &pctx);
  3143. ctx->fs_sockets_count++;
  3144. } else
  3145. mark_inode_bad(ctx, ino);
  3146. if (inode->i_block[EXT2_IND_BLOCK])
  3147. ctx->fs_ind_count++;
  3148. if (inode->i_block[EXT2_DIND_BLOCK])
  3149. ctx->fs_dind_count++;
  3150. if (inode->i_block[EXT2_TIND_BLOCK])
  3151. ctx->fs_tind_count++;
  3152. if (inode->i_block[EXT2_IND_BLOCK] ||
  3153. inode->i_block[EXT2_DIND_BLOCK] ||
  3154. inode->i_block[EXT2_TIND_BLOCK] ||
  3155. inode->i_file_acl) {
  3156. inodes_to_process[process_inode_count].ino = ino;
  3157. inodes_to_process[process_inode_count].inode = *inode;
  3158. process_inode_count++;
  3159. } else
  3160. check_blocks(ctx, &pctx, block_buf);
  3161. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  3162. return;
  3163. if (process_inode_count >= ctx->process_inode_size) {
  3164. process_inodes(ctx, block_buf);
  3165. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  3166. return;
  3167. }
  3168. }
  3169. process_inodes(ctx, block_buf);
  3170. ext2fs_close_inode_scan(scan);
  3171. ehandler_operation(0);
  3172. /*
  3173. * If any extended attribute blocks' reference counts need to
  3174. * be adjusted, either up (ctx->refcount_extra), or down
  3175. * (ctx->refcount), then fix them.
  3176. */
  3177. if (ctx->refcount) {
  3178. adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
  3179. ea_refcount_free(ctx->refcount);
  3180. ctx->refcount = 0;
  3181. }
  3182. if (ctx->refcount_extra) {
  3183. adjust_extattr_refcount(ctx, ctx->refcount_extra,
  3184. block_buf, +1);
  3185. ea_refcount_free(ctx->refcount_extra);
  3186. ctx->refcount_extra = 0;
  3187. }
  3188. if (ctx->invalid_bitmaps)
  3189. handle_fs_bad_blocks(ctx);
  3190. /* We don't need the block_ea_map any more */
  3191. ext2fs_free_block_bitmap(ctx->block_ea_map);
  3192. ctx->block_ea_map = 0;
  3193. if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
  3194. ext2fs_block_bitmap save_bmap;
  3195. save_bmap = fs->block_map;
  3196. fs->block_map = ctx->block_found_map;
  3197. clear_problem_context(&pctx);
  3198. pctx.errcode = ext2fs_create_resize_inode(fs);
  3199. if (pctx.errcode) {
  3200. fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
  3201. /* Should never get here */
  3202. ctx->flags |= E2F_FLAG_ABORT;
  3203. return;
  3204. }
  3205. e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
  3206. "recreate inode");
  3207. inode->i_mtime = time(NULL);
  3208. e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
  3209. "recreate inode");
  3210. fs->block_map = save_bmap;
  3211. ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
  3212. }
  3213. if (ctx->flags & E2F_FLAG_RESTART) {
  3214. /*
  3215. * Only the master copy of the superblock and block
  3216. * group descriptors are going to be written during a
  3217. * restart, so set the superblock to be used to be the
  3218. * master superblock.
  3219. */
  3220. ctx->use_superblock = 0;
  3221. unwind_pass1();
  3222. goto endit;
  3223. }
  3224. if (ctx->block_dup_map) {
  3225. if (ctx->options & E2F_OPT_PREEN) {
  3226. clear_problem_context(&pctx);
  3227. fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
  3228. }
  3229. e2fsck_pass1_dupblocks(ctx, block_buf);
  3230. }
  3231. ext2fs_free_mem(&inodes_to_process);
  3232. endit:
  3233. e2fsck_use_inode_shortcuts(ctx, 0);
  3234. ext2fs_free_mem(&block_buf);
  3235. ext2fs_free_mem(&inode);
  3236. }
  3237. /*
  3238. * When the inode_scan routines call this callback at the end of the
  3239. * glock group, call process_inodes.
  3240. */
  3241. static errcode_t scan_callback(ext2_filsys fs,
  3242. dgrp_t group, void * priv_data)
  3243. {
  3244. struct scan_callback_struct *scan_struct;
  3245. e2fsck_t ctx;
  3246. scan_struct = (struct scan_callback_struct *) priv_data;
  3247. ctx = scan_struct->ctx;
  3248. process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
  3249. if (ctx->progress)
  3250. if ((ctx->progress)(ctx, 1, group+1,
  3251. ctx->fs->group_desc_count))
  3252. return EXT2_ET_CANCEL_REQUESTED;
  3253. return 0;
  3254. }
  3255. /*
  3256. * Process the inodes in the "inodes to process" list.
  3257. */
  3258. static void process_inodes(e2fsck_t ctx, char *block_buf)
  3259. {
  3260. int i;
  3261. struct ext2_inode *old_stashed_inode;
  3262. ext2_ino_t old_stashed_ino;
  3263. const char *old_operation;
  3264. char buf[80];
  3265. struct problem_context pctx;
  3266. /* begin process_inodes */
  3267. if (process_inode_count == 0)
  3268. return;
  3269. old_operation = ehandler_operation(0);
  3270. old_stashed_inode = ctx->stashed_inode;
  3271. old_stashed_ino = ctx->stashed_ino;
  3272. qsort(inodes_to_process, process_inode_count,
  3273. sizeof(struct process_inode_block), process_inode_cmp);
  3274. clear_problem_context(&pctx);
  3275. for (i=0; i < process_inode_count; i++) {
  3276. pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
  3277. pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
  3278. sprintf(buf, _("reading indirect blocks of inode %u"),
  3279. pctx.ino);
  3280. ehandler_operation(buf);
  3281. check_blocks(ctx, &pctx, block_buf);
  3282. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  3283. break;
  3284. }
  3285. ctx->stashed_inode = old_stashed_inode;
  3286. ctx->stashed_ino = old_stashed_ino;
  3287. process_inode_count = 0;
  3288. /* end process inodes */
  3289. ehandler_operation(old_operation);
  3290. }
  3291. static int process_inode_cmp(const void *a, const void *b)
  3292. {
  3293. const struct process_inode_block *ib_a =
  3294. (const struct process_inode_block *) a;
  3295. const struct process_inode_block *ib_b =
  3296. (const struct process_inode_block *) b;
  3297. int ret;
  3298. ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
  3299. ib_b->inode.i_block[EXT2_IND_BLOCK]);
  3300. if (ret == 0)
  3301. ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
  3302. return ret;
  3303. }
  3304. /*
  3305. * Mark an inode as being bad in some what
  3306. */
  3307. static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
  3308. {
  3309. struct problem_context pctx;
  3310. if (!ctx->inode_bad_map) {
  3311. clear_problem_context(&pctx);
  3312. pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
  3313. _("bad inode map"), &ctx->inode_bad_map);
  3314. if (pctx.errcode) {
  3315. pctx.num = 3;
  3316. fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
  3317. /* Should never get here */
  3318. ctx->flags |= E2F_FLAG_ABORT;
  3319. return;
  3320. }
  3321. }
  3322. ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
  3323. }
  3324. /*
  3325. * This procedure will allocate the inode imagic table
  3326. */
  3327. static void alloc_imagic_map(e2fsck_t ctx)
  3328. {
  3329. struct problem_context pctx;
  3330. clear_problem_context(&pctx);
  3331. pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
  3332. _("imagic inode map"),
  3333. &ctx->inode_imagic_map);
  3334. if (pctx.errcode) {
  3335. pctx.num = 5;
  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. /*
  3343. * Marks a block as in use, setting the dup_map if it's been set
  3344. * already. Called by process_block and process_bad_block.
  3345. *
  3346. * WARNING: Assumes checks have already been done to make sure block
  3347. * is valid. This is true in both process_block and process_bad_block.
  3348. */
  3349. static void mark_block_used(e2fsck_t ctx, blk_t block)
  3350. {
  3351. struct problem_context pctx;
  3352. clear_problem_context(&pctx);
  3353. if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
  3354. if (!ctx->block_dup_map) {
  3355. pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
  3356. _("multiply claimed block map"),
  3357. &ctx->block_dup_map);
  3358. if (pctx.errcode) {
  3359. pctx.num = 3;
  3360. fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
  3361. &pctx);
  3362. /* Should never get here */
  3363. ctx->flags |= E2F_FLAG_ABORT;
  3364. return;
  3365. }
  3366. }
  3367. ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
  3368. } else {
  3369. ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
  3370. }
  3371. }
  3372. /*
  3373. * Adjust the extended attribute block's reference counts at the end
  3374. * of pass 1, either by subtracting out references for EA blocks that
  3375. * are still referenced in ctx->refcount, or by adding references for
  3376. * EA blocks that had extra references as accounted for in
  3377. * ctx->refcount_extra.
  3378. */
  3379. static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
  3380. char *block_buf, int adjust_sign)
  3381. {
  3382. struct ext2_ext_attr_header *header;
  3383. struct problem_context pctx;
  3384. ext2_filsys fs = ctx->fs;
  3385. blk_t blk;
  3386. __u32 should_be;
  3387. int count;
  3388. clear_problem_context(&pctx);
  3389. ea_refcount_intr_begin(refcount);
  3390. while (1) {
  3391. if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
  3392. break;
  3393. pctx.blk = blk;
  3394. pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
  3395. if (pctx.errcode) {
  3396. fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
  3397. return;
  3398. }
  3399. header = (struct ext2_ext_attr_header *) block_buf;
  3400. pctx.blkcount = header->h_refcount;
  3401. should_be = header->h_refcount + adjust_sign * count;
  3402. pctx.num = should_be;
  3403. if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
  3404. header->h_refcount = should_be;
  3405. pctx.errcode = ext2fs_write_ext_attr(fs, blk,
  3406. block_buf);
  3407. if (pctx.errcode) {
  3408. fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
  3409. continue;
  3410. }
  3411. }
  3412. }
  3413. }
  3414. /*
  3415. * Handle processing the extended attribute blocks
  3416. */
  3417. static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
  3418. char *block_buf)
  3419. {
  3420. ext2_filsys fs = ctx->fs;
  3421. ext2_ino_t ino = pctx->ino;
  3422. struct ext2_inode *inode = pctx->inode;
  3423. blk_t blk;
  3424. char * end;
  3425. struct ext2_ext_attr_header *header;
  3426. struct ext2_ext_attr_entry *entry;
  3427. int count;
  3428. region_t region;
  3429. blk = inode->i_file_acl;
  3430. if (blk == 0)
  3431. return 0;
  3432. /*
  3433. * If the Extended attribute flag isn't set, then a non-zero
  3434. * file acl means that the inode is corrupted.
  3435. *
  3436. * Or if the extended attribute block is an invalid block,
  3437. * then the inode is also corrupted.
  3438. */
  3439. if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
  3440. (blk < fs->super->s_first_data_block) ||
  3441. (blk >= fs->super->s_blocks_count)) {
  3442. mark_inode_bad(ctx, ino);
  3443. return 0;
  3444. }
  3445. /* If ea bitmap hasn't been allocated, create it */
  3446. if (!ctx->block_ea_map) {
  3447. pctx->errcode = ext2fs_allocate_block_bitmap(fs,
  3448. _("ext attr block map"),
  3449. &ctx->block_ea_map);
  3450. if (pctx->errcode) {
  3451. pctx->num = 2;
  3452. fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
  3453. ctx->flags |= E2F_FLAG_ABORT;
  3454. return 0;
  3455. }
  3456. }
  3457. /* Create the EA refcount structure if necessary */
  3458. if (!ctx->refcount) {
  3459. pctx->errcode = ea_refcount_create(0, &ctx->refcount);
  3460. if (pctx->errcode) {
  3461. pctx->num = 1;
  3462. fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
  3463. ctx->flags |= E2F_FLAG_ABORT;
  3464. return 0;
  3465. }
  3466. }
  3467. /* Have we seen this EA block before? */
  3468. if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
  3469. if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
  3470. return 1;
  3471. /* Ooops, this EA was referenced more than it stated */
  3472. if (!ctx->refcount_extra) {
  3473. pctx->errcode = ea_refcount_create(0,
  3474. &ctx->refcount_extra);
  3475. if (pctx->errcode) {
  3476. pctx->num = 2;
  3477. fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
  3478. ctx->flags |= E2F_FLAG_ABORT;
  3479. return 0;
  3480. }
  3481. }
  3482. ea_refcount_increment(ctx->refcount_extra, blk, 0);
  3483. return 1;
  3484. }
  3485. /*
  3486. * OK, we haven't seen this EA block yet. So we need to
  3487. * validate it
  3488. */
  3489. pctx->blk = blk;
  3490. pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
  3491. if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
  3492. goto clear_extattr;
  3493. header = (struct ext2_ext_attr_header *) block_buf;
  3494. pctx->blk = inode->i_file_acl;
  3495. if (((ctx->ext_attr_ver == 1) &&
  3496. (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
  3497. ((ctx->ext_attr_ver == 2) &&
  3498. (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
  3499. if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
  3500. goto clear_extattr;
  3501. }
  3502. if (header->h_blocks != 1) {
  3503. if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
  3504. goto clear_extattr;
  3505. }
  3506. region = region_create(0, fs->blocksize);
  3507. if (!region) {
  3508. fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
  3509. ctx->flags |= E2F_FLAG_ABORT;
  3510. return 0;
  3511. }
  3512. if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
  3513. if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
  3514. goto clear_extattr;
  3515. }
  3516. entry = (struct ext2_ext_attr_entry *)(header+1);
  3517. end = block_buf + fs->blocksize;
  3518. while ((char *)entry < end && *(__u32 *)entry) {
  3519. if (region_allocate(region, (char *)entry - (char *)header,
  3520. EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
  3521. if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
  3522. goto clear_extattr;
  3523. }
  3524. if ((ctx->ext_attr_ver == 1 &&
  3525. (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
  3526. (ctx->ext_attr_ver == 2 &&
  3527. entry->e_name_index == 0)) {
  3528. if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
  3529. goto clear_extattr;
  3530. }
  3531. if (entry->e_value_block != 0) {
  3532. if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
  3533. goto clear_extattr;
  3534. }
  3535. if (entry->e_value_size &&
  3536. region_allocate(region, entry->e_value_offs,
  3537. EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
  3538. if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
  3539. goto clear_extattr;
  3540. }
  3541. entry = EXT2_EXT_ATTR_NEXT(entry);
  3542. }
  3543. if (region_allocate(region, (char *)entry - (char *)header, 4)) {
  3544. if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
  3545. goto clear_extattr;
  3546. }
  3547. region_free(region);
  3548. count = header->h_refcount - 1;
  3549. if (count)
  3550. ea_refcount_store(ctx->refcount, blk, count);
  3551. mark_block_used(ctx, blk);
  3552. ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
  3553. return 1;
  3554. clear_extattr:
  3555. inode->i_file_acl = 0;
  3556. e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
  3557. return 0;
  3558. }
  3559. /* Returns 1 if bad htree, 0 if OK */
  3560. static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
  3561. ext2_ino_t ino FSCK_ATTR((unused)),
  3562. struct ext2_inode *inode,
  3563. char *block_buf)
  3564. {
  3565. struct ext2_dx_root_info *root;
  3566. ext2_filsys fs = ctx->fs;
  3567. errcode_t retval;
  3568. blk_t blk;
  3569. if ((!LINUX_S_ISDIR(inode->i_mode) &&
  3570. fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
  3571. (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
  3572. fix_problem(ctx, PR_1_HTREE_SET, pctx)))
  3573. return 1;
  3574. blk = inode->i_block[0];
  3575. if (((blk == 0) ||
  3576. (blk < fs->super->s_first_data_block) ||
  3577. (blk >= fs->super->s_blocks_count)) &&
  3578. fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
  3579. return 1;
  3580. retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
  3581. if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
  3582. return 1;
  3583. /* XXX should check that beginning matches a directory */
  3584. root = (struct ext2_dx_root_info *) (block_buf + 24);
  3585. if ((root->reserved_zero || root->info_length < 8) &&
  3586. fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
  3587. return 1;
  3588. pctx->num = root->hash_version;
  3589. if ((root->hash_version != EXT2_HASH_LEGACY) &&
  3590. (root->hash_version != EXT2_HASH_HALF_MD4) &&
  3591. (root->hash_version != EXT2_HASH_TEA) &&
  3592. fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
  3593. return 1;
  3594. if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
  3595. fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
  3596. return 1;
  3597. pctx->num = root->indirect_levels;
  3598. if ((root->indirect_levels > 1) &&
  3599. fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
  3600. return 1;
  3601. return 0;
  3602. }
  3603. /*
  3604. * This subroutine is called on each inode to account for all of the
  3605. * blocks used by that inode.
  3606. */
  3607. static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
  3608. char *block_buf)
  3609. {
  3610. ext2_filsys fs = ctx->fs;
  3611. struct process_block_struct_1 pb;
  3612. ext2_ino_t ino = pctx->ino;
  3613. struct ext2_inode *inode = pctx->inode;
  3614. int bad_size = 0;
  3615. int dirty_inode = 0;
  3616. __u64 size;
  3617. pb.ino = ino;
  3618. pb.num_blocks = 0;
  3619. pb.last_block = -1;
  3620. pb.num_illegal_blocks = 0;
  3621. pb.suppress = 0; pb.clear = 0;
  3622. pb.fragmented = 0;
  3623. pb.compressed = 0;
  3624. pb.previous_block = 0;
  3625. pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
  3626. pb.is_reg = LINUX_S_ISREG(inode->i_mode);
  3627. pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
  3628. pb.inode = inode;
  3629. pb.pctx = pctx;
  3630. pb.ctx = ctx;
  3631. pctx->ino = ino;
  3632. pctx->errcode = 0;
  3633. if (inode->i_flags & EXT2_COMPRBLK_FL) {
  3634. if (fs->super->s_feature_incompat &
  3635. EXT2_FEATURE_INCOMPAT_COMPRESSION)
  3636. pb.compressed = 1;
  3637. else {
  3638. if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
  3639. inode->i_flags &= ~EXT2_COMPRBLK_FL;
  3640. dirty_inode++;
  3641. }
  3642. }
  3643. }
  3644. if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
  3645. pb.num_blocks++;
  3646. if (ext2fs_inode_has_valid_blocks(inode))
  3647. pctx->errcode = ext2fs_block_iterate2(fs, ino,
  3648. pb.is_dir ? BLOCK_FLAG_HOLE : 0,
  3649. block_buf, process_block, &pb);
  3650. end_problem_latch(ctx, PR_LATCH_BLOCK);
  3651. end_problem_latch(ctx, PR_LATCH_TOOBIG);
  3652. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  3653. goto out;
  3654. if (pctx->errcode)
  3655. fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
  3656. if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
  3657. ctx->fs_fragmented++;
  3658. if (pb.clear) {
  3659. inode->i_links_count = 0;
  3660. ext2fs_icount_store(ctx->inode_link_info, ino, 0);
  3661. inode->i_dtime = time(NULL);
  3662. dirty_inode++;
  3663. ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
  3664. ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
  3665. ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
  3666. /*
  3667. * The inode was probably partially accounted for
  3668. * before processing was aborted, so we need to
  3669. * restart the pass 1 scan.
  3670. */
  3671. ctx->flags |= E2F_FLAG_RESTART;
  3672. goto out;
  3673. }
  3674. if (inode->i_flags & EXT2_INDEX_FL) {
  3675. if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
  3676. inode->i_flags &= ~EXT2_INDEX_FL;
  3677. dirty_inode++;
  3678. } else {
  3679. #ifdef ENABLE_HTREE
  3680. e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
  3681. #endif
  3682. }
  3683. }
  3684. if (ctx->dirs_to_hash && pb.is_dir &&
  3685. !(inode->i_flags & EXT2_INDEX_FL) &&
  3686. ((inode->i_size / fs->blocksize) >= 3))
  3687. ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
  3688. if (!pb.num_blocks && pb.is_dir) {
  3689. if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
  3690. inode->i_links_count = 0;
  3691. ext2fs_icount_store(ctx->inode_link_info, ino, 0);
  3692. inode->i_dtime = time(NULL);
  3693. dirty_inode++;
  3694. ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
  3695. ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
  3696. ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
  3697. ctx->fs_directory_count--;
  3698. goto out;
  3699. }
  3700. }
  3701. pb.num_blocks *= (fs->blocksize / 512);
  3702. if (pb.is_dir) {
  3703. int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
  3704. if (nblock > (pb.last_block + 1))
  3705. bad_size = 1;
  3706. else if (nblock < (pb.last_block + 1)) {
  3707. if (((pb.last_block + 1) - nblock) >
  3708. fs->super->s_prealloc_dir_blocks)
  3709. bad_size = 2;
  3710. }
  3711. } else {
  3712. size = EXT2_I_SIZE(inode);
  3713. if ((pb.last_block >= 0) &&
  3714. (size < (__u64) pb.last_block * fs->blocksize))
  3715. bad_size = 3;
  3716. else if (size > ext2_max_sizes[fs->super->s_log_block_size])
  3717. bad_size = 4;
  3718. }
  3719. /* i_size for symlinks is checked elsewhere */
  3720. if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
  3721. pctx->num = (pb.last_block+1) * fs->blocksize;
  3722. if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
  3723. inode->i_size = pctx->num;
  3724. if (!LINUX_S_ISDIR(inode->i_mode))
  3725. inode->i_size_high = pctx->num >> 32;
  3726. dirty_inode++;
  3727. }
  3728. pctx->num = 0;
  3729. }
  3730. if (LINUX_S_ISREG(inode->i_mode) &&
  3731. (inode->i_size_high || inode->i_size & 0x80000000UL))
  3732. ctx->large_files++;
  3733. if (pb.num_blocks != inode->i_blocks) {
  3734. pctx->num = pb.num_blocks;
  3735. if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
  3736. inode->i_blocks = pb.num_blocks;
  3737. dirty_inode++;
  3738. }
  3739. pctx->num = 0;
  3740. }
  3741. out:
  3742. if (dirty_inode)
  3743. e2fsck_write_inode(ctx, ino, inode, "check_blocks");
  3744. }
  3745. /*
  3746. * This is a helper function for check_blocks().
  3747. */
  3748. static int process_block(ext2_filsys fs,
  3749. blk_t *block_nr,
  3750. e2_blkcnt_t blockcnt,
  3751. blk_t ref_block FSCK_ATTR((unused)),
  3752. int ref_offset FSCK_ATTR((unused)),
  3753. void *priv_data)
  3754. {
  3755. struct process_block_struct_1 *p;
  3756. struct problem_context *pctx;
  3757. blk_t blk = *block_nr;
  3758. int ret_code = 0;
  3759. int problem = 0;
  3760. e2fsck_t ctx;
  3761. p = (struct process_block_struct_1 *) priv_data;
  3762. pctx = p->pctx;
  3763. ctx = p->ctx;
  3764. if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
  3765. /* todo: Check that the comprblk_fl is high, that the
  3766. blkaddr pattern looks right (all non-holes up to
  3767. first EXT2FS_COMPRESSED_BLKADDR, then all
  3768. EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
  3769. that the feature_incompat bit is high, and that the
  3770. inode is a regular file. If we're doing a "full
  3771. check" (a concept introduced to e2fsck by e2compr,
  3772. meaning that we look at data blocks as well as
  3773. metadata) then call some library routine that
  3774. checks the compressed data. I'll have to think
  3775. about this, because one particularly important
  3776. problem to be able to fix is to recalculate the
  3777. cluster size if necessary. I think that perhaps
  3778. we'd better do most/all e2compr-specific checks
  3779. separately, after the non-e2compr checks. If not
  3780. doing a full check, it may be useful to test that
  3781. the personality is linux; e.g. if it isn't then
  3782. perhaps this really is just an illegal block. */
  3783. return 0;
  3784. }
  3785. if (blk == 0) {
  3786. if (p->is_dir == 0) {
  3787. /*
  3788. * Should never happen, since only directories
  3789. * get called with BLOCK_FLAG_HOLE
  3790. */
  3791. #ifdef DEBUG_E2FSCK
  3792. printf("process_block() called with blk == 0, "
  3793. "blockcnt=%d, inode %lu???\n",
  3794. blockcnt, p->ino);
  3795. #endif
  3796. return 0;
  3797. }
  3798. if (blockcnt < 0)
  3799. return 0;
  3800. if (blockcnt * fs->blocksize < p->inode->i_size) {
  3801. goto mark_dir;
  3802. }
  3803. return 0;
  3804. }
  3805. /*
  3806. * Simplistic fragmentation check. We merely require that the
  3807. * file be contiguous. (Which can never be true for really
  3808. * big files that are greater than a block group.)
  3809. */
  3810. if (!HOLE_BLKADDR(p->previous_block)) {
  3811. if (p->previous_block+1 != blk)
  3812. p->fragmented = 1;
  3813. }
  3814. p->previous_block = blk;
  3815. if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
  3816. problem = PR_1_TOOBIG_DIR;
  3817. if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
  3818. problem = PR_1_TOOBIG_REG;
  3819. if (!p->is_dir && !p->is_reg && blockcnt > 0)
  3820. problem = PR_1_TOOBIG_SYMLINK;
  3821. if (blk < fs->super->s_first_data_block ||
  3822. blk >= fs->super->s_blocks_count)
  3823. problem = PR_1_ILLEGAL_BLOCK_NUM;
  3824. if (problem) {
  3825. p->num_illegal_blocks++;
  3826. if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
  3827. if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
  3828. p->clear = 1;
  3829. return BLOCK_ABORT;
  3830. }
  3831. if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
  3832. p->suppress = 1;
  3833. set_latch_flags(PR_LATCH_BLOCK,
  3834. PRL_SUPPRESS, 0);
  3835. }
  3836. }
  3837. pctx->blk = blk;
  3838. pctx->blkcount = blockcnt;
  3839. if (fix_problem(ctx, problem, pctx)) {
  3840. blk = *block_nr = 0;
  3841. ret_code = BLOCK_CHANGED;
  3842. goto mark_dir;
  3843. } else
  3844. return 0;
  3845. }
  3846. if (p->ino == EXT2_RESIZE_INO) {
  3847. /*
  3848. * The resize inode has already be sanity checked
  3849. * during pass #0 (the superblock checks). All we
  3850. * have to do is mark the double indirect block as
  3851. * being in use; all of the other blocks are handled
  3852. * by mark_table_blocks()).
  3853. */
  3854. if (blockcnt == BLOCK_COUNT_DIND)
  3855. mark_block_used(ctx, blk);
  3856. } else
  3857. mark_block_used(ctx, blk);
  3858. p->num_blocks++;
  3859. if (blockcnt >= 0)
  3860. p->last_block = blockcnt;
  3861. mark_dir:
  3862. if (p->is_dir && (blockcnt >= 0)) {
  3863. pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
  3864. blk, blockcnt);
  3865. if (pctx->errcode) {
  3866. pctx->blk = blk;
  3867. pctx->num = blockcnt;
  3868. fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
  3869. /* Should never get here */
  3870. ctx->flags |= E2F_FLAG_ABORT;
  3871. return BLOCK_ABORT;
  3872. }
  3873. }
  3874. return ret_code;
  3875. }
  3876. static int process_bad_block(ext2_filsys fs FSCK_ATTR((unused)),
  3877. blk_t *block_nr,
  3878. e2_blkcnt_t blockcnt,
  3879. blk_t ref_block FSCK_ATTR((unused)),
  3880. int ref_offset FSCK_ATTR((unused)),
  3881. void *priv_data EXT2FS_ATTR((unused)))
  3882. {
  3883. /*
  3884. * Note: This function processes blocks for the bad blocks
  3885. * inode, which is never compressed. So we don't use HOLE_BLKADDR().
  3886. */
  3887. printf("Unrecoverable Error: Found %"PRIi64" bad blocks starting at block number: %u\n", blockcnt, *block_nr);
  3888. return BLOCK_ERROR;
  3889. }
  3890. /*
  3891. * This routine gets called at the end of pass 1 if bad blocks are
  3892. * detected in the superblock, group descriptors, inode_bitmaps, or
  3893. * block bitmaps. At this point, all of the blocks have been mapped
  3894. * out, so we can try to allocate new block(s) to replace the bad
  3895. * blocks.
  3896. */
  3897. static void handle_fs_bad_blocks(e2fsck_t ctx)
  3898. {
  3899. printf("Bad blocks detected on your filesystem\n"
  3900. "You should get your data off as the device will soon die\n");
  3901. }
  3902. /*
  3903. * This routine marks all blocks which are used by the superblock,
  3904. * group descriptors, inode bitmaps, and block bitmaps.
  3905. */
  3906. static void mark_table_blocks(e2fsck_t ctx)
  3907. {
  3908. ext2_filsys fs = ctx->fs;
  3909. blk_t block, b;
  3910. dgrp_t i;
  3911. int j;
  3912. struct problem_context pctx;
  3913. clear_problem_context(&pctx);
  3914. block = fs->super->s_first_data_block;
  3915. for (i = 0; i < fs->group_desc_count; i++) {
  3916. pctx.group = i;
  3917. ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
  3918. /*
  3919. * Mark the blocks used for the inode table
  3920. */
  3921. if (fs->group_desc[i].bg_inode_table) {
  3922. for (j = 0, b = fs->group_desc[i].bg_inode_table;
  3923. j < fs->inode_blocks_per_group;
  3924. j++, b++) {
  3925. if (ext2fs_test_block_bitmap(ctx->block_found_map,
  3926. b)) {
  3927. pctx.blk = b;
  3928. if (fix_problem(ctx,
  3929. PR_1_ITABLE_CONFLICT, &pctx)) {
  3930. ctx->invalid_inode_table_flag[i]++;
  3931. ctx->invalid_bitmaps++;
  3932. }
  3933. } else {
  3934. ext2fs_mark_block_bitmap(ctx->block_found_map, b);
  3935. }
  3936. }
  3937. }
  3938. /*
  3939. * Mark block used for the block bitmap
  3940. */
  3941. if (fs->group_desc[i].bg_block_bitmap) {
  3942. if (ext2fs_test_block_bitmap(ctx->block_found_map,
  3943. fs->group_desc[i].bg_block_bitmap)) {
  3944. pctx.blk = fs->group_desc[i].bg_block_bitmap;
  3945. if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
  3946. ctx->invalid_block_bitmap_flag[i]++;
  3947. ctx->invalid_bitmaps++;
  3948. }
  3949. } else {
  3950. ext2fs_mark_block_bitmap(ctx->block_found_map,
  3951. fs->group_desc[i].bg_block_bitmap);
  3952. }
  3953. }
  3954. /*
  3955. * Mark block used for the inode bitmap
  3956. */
  3957. if (fs->group_desc[i].bg_inode_bitmap) {
  3958. if (ext2fs_test_block_bitmap(ctx->block_found_map,
  3959. fs->group_desc[i].bg_inode_bitmap)) {
  3960. pctx.blk = fs->group_desc[i].bg_inode_bitmap;
  3961. if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
  3962. ctx->invalid_inode_bitmap_flag[i]++;
  3963. ctx->invalid_bitmaps++;
  3964. }
  3965. } else {
  3966. ext2fs_mark_block_bitmap(ctx->block_found_map,
  3967. fs->group_desc[i].bg_inode_bitmap);
  3968. }
  3969. }
  3970. block += fs->super->s_blocks_per_group;
  3971. }
  3972. }
  3973. /*
  3974. * Thes subroutines short circuits ext2fs_get_blocks and
  3975. * ext2fs_check_directory; we use them since we already have the inode
  3976. * structure, so there's no point in letting the ext2fs library read
  3977. * the inode again.
  3978. */
  3979. static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
  3980. blk_t *blocks)
  3981. {
  3982. e2fsck_t ctx = (e2fsck_t) fs->priv_data;
  3983. int i;
  3984. if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
  3985. return EXT2_ET_CALLBACK_NOTHANDLED;
  3986. for (i=0; i < EXT2_N_BLOCKS; i++)
  3987. blocks[i] = ctx->stashed_inode->i_block[i];
  3988. return 0;
  3989. }
  3990. static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
  3991. struct ext2_inode *inode)
  3992. {
  3993. e2fsck_t ctx = (e2fsck_t) fs->priv_data;
  3994. if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
  3995. return EXT2_ET_CALLBACK_NOTHANDLED;
  3996. *inode = *ctx->stashed_inode;
  3997. return 0;
  3998. }
  3999. static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
  4000. struct ext2_inode *inode)
  4001. {
  4002. e2fsck_t ctx = (e2fsck_t) fs->priv_data;
  4003. if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
  4004. *ctx->stashed_inode = *inode;
  4005. return EXT2_ET_CALLBACK_NOTHANDLED;
  4006. }
  4007. static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
  4008. {
  4009. e2fsck_t ctx = (e2fsck_t) fs->priv_data;
  4010. if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
  4011. return EXT2_ET_CALLBACK_NOTHANDLED;
  4012. if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
  4013. return EXT2_ET_NO_DIRECTORY;
  4014. return 0;
  4015. }
  4016. void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
  4017. {
  4018. ext2_filsys fs = ctx->fs;
  4019. if (bool) {
  4020. fs->get_blocks = pass1_get_blocks;
  4021. fs->check_directory = pass1_check_directory;
  4022. fs->read_inode = pass1_read_inode;
  4023. fs->write_inode = pass1_write_inode;
  4024. ctx->stashed_ino = 0;
  4025. } else {
  4026. fs->get_blocks = 0;
  4027. fs->check_directory = 0;
  4028. fs->read_inode = 0;
  4029. fs->write_inode = 0;
  4030. }
  4031. }
  4032. /*
  4033. * pass1b.c --- Pass #1b of e2fsck
  4034. *
  4035. * This file contains pass1B, pass1C, and pass1D of e2fsck. They are
  4036. * only invoked if pass 1 discovered blocks which are in use by more
  4037. * than one inode.
  4038. *
  4039. * Pass1B scans the data blocks of all the inodes again, generating a
  4040. * complete list of duplicate blocks and which inodes have claimed
  4041. * them.
  4042. *
  4043. * Pass1C does a tree-traversal of the filesystem, to determine the
  4044. * parent directories of these inodes. This step is necessary so that
  4045. * e2fsck can print out the pathnames of affected inodes.
  4046. *
  4047. * Pass1D is a reconciliation pass. For each inode with duplicate
  4048. * blocks, the user is prompted if s/he would like to clone the file
  4049. * (so that the file gets a fresh copy of the duplicated blocks) or
  4050. * simply to delete the file.
  4051. *
  4052. */
  4053. /* Needed for architectures where sizeof(int) != sizeof(void *) */
  4054. #define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val))
  4055. #define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr))
  4056. /* Define an extension to the ext2 library's block count information */
  4057. #define BLOCK_COUNT_EXTATTR (-5)
  4058. struct block_el {
  4059. blk_t block;
  4060. struct block_el *next;
  4061. };
  4062. struct inode_el {
  4063. ext2_ino_t inode;
  4064. struct inode_el *next;
  4065. };
  4066. struct dup_block {
  4067. int num_bad;
  4068. struct inode_el *inode_list;
  4069. };
  4070. /*
  4071. * This structure stores information about a particular inode which
  4072. * is sharing blocks with other inodes. This information is collected
  4073. * to display to the user, so that the user knows what files he or she
  4074. * is dealing with, when trying to decide how to resolve the conflict
  4075. * of multiply-claimed blocks.
  4076. */
  4077. struct dup_inode {
  4078. ext2_ino_t dir;
  4079. int num_dupblocks;
  4080. struct ext2_inode inode;
  4081. struct block_el *block_list;
  4082. };
  4083. static int process_pass1b_block(ext2_filsys fs, blk_t *blocknr,
  4084. e2_blkcnt_t blockcnt, blk_t ref_blk,
  4085. int ref_offset, void *priv_data);
  4086. static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
  4087. struct dup_inode *dp, char *block_buf);
  4088. static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
  4089. struct dup_inode *dp, char* block_buf);
  4090. static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
  4091. static void pass1b(e2fsck_t ctx, char *block_buf);
  4092. static void pass1c(e2fsck_t ctx, char *block_buf);
  4093. static void pass1d(e2fsck_t ctx, char *block_buf);
  4094. static int dup_inode_count = 0;
  4095. static dict_t blk_dict, ino_dict;
  4096. static ext2fs_inode_bitmap inode_dup_map;
  4097. static int dict_int_cmp(const void *a, const void *b)
  4098. {
  4099. intptr_t ia, ib;
  4100. ia = (intptr_t)a;
  4101. ib = (intptr_t)b;
  4102. return (ia-ib);
  4103. }
  4104. /*
  4105. * Add a duplicate block record
  4106. */
  4107. static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
  4108. struct ext2_inode *inode)
  4109. {
  4110. dnode_t *n;
  4111. struct dup_block *db;
  4112. struct dup_inode *di;
  4113. struct block_el *blk_el;
  4114. struct inode_el *ino_el;
  4115. n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
  4116. if (n)
  4117. db = (struct dup_block *) dnode_get(n);
  4118. else {
  4119. db = (struct dup_block *) e2fsck_allocate_memory(ctx,
  4120. sizeof(struct dup_block), "duplicate block header");
  4121. db->num_bad = 0;
  4122. db->inode_list = 0;
  4123. dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
  4124. }
  4125. ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
  4126. sizeof(struct inode_el), "inode element");
  4127. ino_el->inode = ino;
  4128. ino_el->next = db->inode_list;
  4129. db->inode_list = ino_el;
  4130. db->num_bad++;
  4131. n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
  4132. if (n)
  4133. di = (struct dup_inode *) dnode_get(n);
  4134. else {
  4135. di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
  4136. sizeof(struct dup_inode), "duplicate inode header");
  4137. di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0;
  4138. di->num_dupblocks = 0;
  4139. di->block_list = 0;
  4140. di->inode = *inode;
  4141. dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
  4142. }
  4143. blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
  4144. sizeof(struct block_el), "block element");
  4145. blk_el->block = blk;
  4146. blk_el->next = di->block_list;
  4147. di->block_list = blk_el;
  4148. di->num_dupblocks++;
  4149. }
  4150. /*
  4151. * Free a duplicate inode record
  4152. */
  4153. static void inode_dnode_free(dnode_t *node)
  4154. {
  4155. struct dup_inode *di;
  4156. struct block_el *p, *next;
  4157. di = (struct dup_inode *) dnode_get(node);
  4158. for (p = di->block_list; p; p = next) {
  4159. next = p->next;
  4160. free(p);
  4161. }
  4162. free(node);
  4163. }
  4164. /*
  4165. * Free a duplicate block record
  4166. */
  4167. static void block_dnode_free(dnode_t *node)
  4168. {
  4169. struct dup_block *db;
  4170. struct inode_el *p, *next;
  4171. db = (struct dup_block *) dnode_get(node);
  4172. for (p = db->inode_list; p; p = next) {
  4173. next = p->next;
  4174. free(p);
  4175. }
  4176. free(node);
  4177. }
  4178. /*
  4179. * Main procedure for handling duplicate blocks
  4180. */
  4181. void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
  4182. {
  4183. ext2_filsys fs = ctx->fs;
  4184. struct problem_context pctx;
  4185. clear_problem_context(&pctx);
  4186. pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
  4187. _("multiply claimed inode map"), &inode_dup_map);
  4188. if (pctx.errcode) {
  4189. fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
  4190. ctx->flags |= E2F_FLAG_ABORT;
  4191. return;
  4192. }
  4193. dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
  4194. dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
  4195. dict_set_allocator(&ino_dict, inode_dnode_free);
  4196. dict_set_allocator(&blk_dict, block_dnode_free);
  4197. pass1b(ctx, block_buf);
  4198. pass1c(ctx, block_buf);
  4199. pass1d(ctx, block_buf);
  4200. /*
  4201. * Time to free all of the accumulated data structures that we
  4202. * don't need anymore.
  4203. */
  4204. dict_free_nodes(&ino_dict);
  4205. dict_free_nodes(&blk_dict);
  4206. }
  4207. /*
  4208. * Scan the inodes looking for inodes that contain duplicate blocks.
  4209. */
  4210. struct process_block_struct_1b {
  4211. e2fsck_t ctx;
  4212. ext2_ino_t ino;
  4213. int dup_blocks;
  4214. struct ext2_inode *inode;
  4215. struct problem_context *pctx;
  4216. };
  4217. static void pass1b(e2fsck_t ctx, char *block_buf)
  4218. {
  4219. ext2_filsys fs = ctx->fs;
  4220. ext2_ino_t ino;
  4221. struct ext2_inode inode;
  4222. ext2_inode_scan scan;
  4223. struct process_block_struct_1b pb;
  4224. struct problem_context pctx;
  4225. clear_problem_context(&pctx);
  4226. if (!(ctx->options & E2F_OPT_PREEN))
  4227. fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
  4228. pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
  4229. &scan);
  4230. if (pctx.errcode) {
  4231. fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
  4232. ctx->flags |= E2F_FLAG_ABORT;
  4233. return;
  4234. }
  4235. ctx->stashed_inode = &inode;
  4236. pb.ctx = ctx;
  4237. pb.pctx = &pctx;
  4238. pctx.str = "pass1b";
  4239. while (1) {
  4240. pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
  4241. if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
  4242. continue;
  4243. if (pctx.errcode) {
  4244. fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
  4245. ctx->flags |= E2F_FLAG_ABORT;
  4246. return;
  4247. }
  4248. if (!ino)
  4249. break;
  4250. pctx.ino = ctx->stashed_ino = ino;
  4251. if ((ino != EXT2_BAD_INO) &&
  4252. !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
  4253. continue;
  4254. pb.ino = ino;
  4255. pb.dup_blocks = 0;
  4256. pb.inode = &inode;
  4257. if (ext2fs_inode_has_valid_blocks(&inode) ||
  4258. (ino == EXT2_BAD_INO))
  4259. pctx.errcode = ext2fs_block_iterate2(fs, ino,
  4260. 0, block_buf, process_pass1b_block, &pb);
  4261. if (inode.i_file_acl)
  4262. process_pass1b_block(fs, &inode.i_file_acl,
  4263. BLOCK_COUNT_EXTATTR, 0, 0, &pb);
  4264. if (pb.dup_blocks) {
  4265. end_problem_latch(ctx, PR_LATCH_DBLOCK);
  4266. if (ino >= EXT2_FIRST_INODE(fs->super) ||
  4267. ino == EXT2_ROOT_INO)
  4268. dup_inode_count++;
  4269. }
  4270. if (pctx.errcode)
  4271. fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
  4272. }
  4273. ext2fs_close_inode_scan(scan);
  4274. e2fsck_use_inode_shortcuts(ctx, 0);
  4275. }
  4276. static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)),
  4277. blk_t *block_nr,
  4278. e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
  4279. blk_t ref_blk FSCK_ATTR((unused)),
  4280. int ref_offset FSCK_ATTR((unused)),
  4281. void *priv_data)
  4282. {
  4283. struct process_block_struct_1b *p;
  4284. e2fsck_t ctx;
  4285. if (HOLE_BLKADDR(*block_nr))
  4286. return 0;
  4287. p = (struct process_block_struct_1b *) priv_data;
  4288. ctx = p->ctx;
  4289. if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
  4290. return 0;
  4291. /* OK, this is a duplicate block */
  4292. if (p->ino != EXT2_BAD_INO) {
  4293. p->pctx->blk = *block_nr;
  4294. fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
  4295. }
  4296. p->dup_blocks++;
  4297. ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
  4298. add_dupe(ctx, p->ino, *block_nr, p->inode);
  4299. return 0;
  4300. }
  4301. /*
  4302. * Pass 1c: Scan directories for inodes with duplicate blocks. This
  4303. * is used so that we can print pathnames when prompting the user for
  4304. * what to do.
  4305. */
  4306. struct search_dir_struct {
  4307. int count;
  4308. ext2_ino_t first_inode;
  4309. ext2_ino_t max_inode;
  4310. };
  4311. static int search_dirent_proc(ext2_ino_t dir, int entry,
  4312. struct ext2_dir_entry *dirent,
  4313. int offset FSCK_ATTR((unused)),
  4314. int blocksize FSCK_ATTR((unused)),
  4315. char *buf FSCK_ATTR((unused)),
  4316. void *priv_data)
  4317. {
  4318. struct search_dir_struct *sd;
  4319. struct dup_inode *p;
  4320. dnode_t *n;
  4321. sd = (struct search_dir_struct *) priv_data;
  4322. if (dirent->inode > sd->max_inode)
  4323. /* Should abort this inode, but not everything */
  4324. return 0;
  4325. if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
  4326. !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
  4327. return 0;
  4328. n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
  4329. if (!n)
  4330. return 0;
  4331. p = (struct dup_inode *) dnode_get(n);
  4332. p->dir = dir;
  4333. sd->count--;
  4334. return sd->count ? 0 : DIRENT_ABORT;
  4335. }
  4336. static void pass1c(e2fsck_t ctx, char *block_buf)
  4337. {
  4338. ext2_filsys fs = ctx->fs;
  4339. struct search_dir_struct sd;
  4340. struct problem_context pctx;
  4341. clear_problem_context(&pctx);
  4342. if (!(ctx->options & E2F_OPT_PREEN))
  4343. fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
  4344. /*
  4345. * Search through all directories to translate inodes to names
  4346. * (by searching for the containing directory for that inode.)
  4347. */
  4348. sd.count = dup_inode_count;
  4349. sd.first_inode = EXT2_FIRST_INODE(fs->super);
  4350. sd.max_inode = fs->super->s_inodes_count;
  4351. ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
  4352. search_dirent_proc, &sd);
  4353. }
  4354. static void pass1d(e2fsck_t ctx, char *block_buf)
  4355. {
  4356. ext2_filsys fs = ctx->fs;
  4357. struct dup_inode *p, *t;
  4358. struct dup_block *q;
  4359. ext2_ino_t *shared, ino;
  4360. int shared_len;
  4361. int i;
  4362. int file_ok;
  4363. int meta_data = 0;
  4364. struct problem_context pctx;
  4365. dnode_t *n, *m;
  4366. struct block_el *s;
  4367. struct inode_el *r;
  4368. clear_problem_context(&pctx);
  4369. if (!(ctx->options & E2F_OPT_PREEN))
  4370. fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
  4371. e2fsck_read_bitmaps(ctx);
  4372. pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
  4373. fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
  4374. shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
  4375. sizeof(ext2_ino_t) * dict_count(&ino_dict),
  4376. "Shared inode list");
  4377. for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
  4378. p = (struct dup_inode *) dnode_get(n);
  4379. shared_len = 0;
  4380. file_ok = 1;
  4381. ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
  4382. if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO)
  4383. continue;
  4384. /*
  4385. * Find all of the inodes which share blocks with this
  4386. * one. First we find all of the duplicate blocks
  4387. * belonging to this inode, and then search each block
  4388. * get the list of inodes, and merge them together.
  4389. */
  4390. for (s = p->block_list; s; s = s->next) {
  4391. m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
  4392. if (!m)
  4393. continue; /* Should never happen... */
  4394. q = (struct dup_block *) dnode_get(m);
  4395. if (q->num_bad > 1)
  4396. file_ok = 0;
  4397. if (check_if_fs_block(ctx, s->block)) {
  4398. file_ok = 0;
  4399. meta_data = 1;
  4400. }
  4401. /*
  4402. * Add all inodes used by this block to the
  4403. * shared[] --- which is a unique list, so
  4404. * if an inode is already in shared[], don't
  4405. * add it again.
  4406. */
  4407. for (r = q->inode_list; r; r = r->next) {
  4408. if (r->inode == ino)
  4409. continue;
  4410. for (i = 0; i < shared_len; i++)
  4411. if (shared[i] == r->inode)
  4412. break;
  4413. if (i == shared_len) {
  4414. shared[shared_len++] = r->inode;
  4415. }
  4416. }
  4417. }
  4418. /*
  4419. * Report the inode that we are working on
  4420. */
  4421. pctx.inode = &p->inode;
  4422. pctx.ino = ino;
  4423. pctx.dir = p->dir;
  4424. pctx.blkcount = p->num_dupblocks;
  4425. pctx.num = meta_data ? shared_len+1 : shared_len;
  4426. fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
  4427. pctx.blkcount = 0;
  4428. pctx.num = 0;
  4429. if (meta_data)
  4430. fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
  4431. for (i = 0; i < shared_len; i++) {
  4432. m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
  4433. if (!m)
  4434. continue; /* should never happen */
  4435. t = (struct dup_inode *) dnode_get(m);
  4436. /*
  4437. * Report the inode that we are sharing with
  4438. */
  4439. pctx.inode = &t->inode;
  4440. pctx.ino = shared[i];
  4441. pctx.dir = t->dir;
  4442. fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
  4443. }
  4444. if (file_ok) {
  4445. fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
  4446. continue;
  4447. }
  4448. if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
  4449. pctx.errcode = clone_file(ctx, ino, p, block_buf);
  4450. if (pctx.errcode)
  4451. fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
  4452. else
  4453. continue;
  4454. }
  4455. if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
  4456. delete_file(ctx, ino, p, block_buf);
  4457. else
  4458. ext2fs_unmark_valid(fs);
  4459. }
  4460. ext2fs_free_mem(&shared);
  4461. }
  4462. /*
  4463. * Drop the refcount on the dup_block structure, and clear the entry
  4464. * in the block_dup_map if appropriate.
  4465. */
  4466. static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
  4467. {
  4468. p->num_bad--;
  4469. if (p->num_bad <= 0 ||
  4470. (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
  4471. ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
  4472. }
  4473. static int delete_file_block(ext2_filsys fs,
  4474. blk_t *block_nr,
  4475. e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
  4476. blk_t ref_block FSCK_ATTR((unused)),
  4477. int ref_offset FSCK_ATTR((unused)),
  4478. void *priv_data)
  4479. {
  4480. struct process_block_struct_1b *pb;
  4481. struct dup_block *p;
  4482. dnode_t *n;
  4483. e2fsck_t ctx;
  4484. pb = (struct process_block_struct_1b *) priv_data;
  4485. ctx = pb->ctx;
  4486. if (HOLE_BLKADDR(*block_nr))
  4487. return 0;
  4488. if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
  4489. n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
  4490. if (n) {
  4491. p = (struct dup_block *) dnode_get(n);
  4492. decrement_badcount(ctx, *block_nr, p);
  4493. } else
  4494. bb_error_msg(_("internal error; can't find dup_blk for %d"),
  4495. *block_nr);
  4496. } else {
  4497. ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
  4498. ext2fs_block_alloc_stats(fs, *block_nr, -1);
  4499. }
  4500. return 0;
  4501. }
  4502. static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
  4503. struct dup_inode *dp, char* block_buf)
  4504. {
  4505. ext2_filsys fs = ctx->fs;
  4506. struct process_block_struct_1b pb;
  4507. struct ext2_inode inode;
  4508. struct problem_context pctx;
  4509. unsigned int count;
  4510. clear_problem_context(&pctx);
  4511. pctx.ino = pb.ino = ino;
  4512. pb.dup_blocks = dp->num_dupblocks;
  4513. pb.ctx = ctx;
  4514. pctx.str = "delete_file";
  4515. e2fsck_read_inode(ctx, ino, &inode, "delete_file");
  4516. if (ext2fs_inode_has_valid_blocks(&inode))
  4517. pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
  4518. delete_file_block, &pb);
  4519. if (pctx.errcode)
  4520. fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
  4521. ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
  4522. ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
  4523. if (ctx->inode_bad_map)
  4524. ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
  4525. ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
  4526. /* Inode may have changed by block_iterate, so reread it */
  4527. e2fsck_read_inode(ctx, ino, &inode, "delete_file");
  4528. inode.i_links_count = 0;
  4529. inode.i_dtime = time(NULL);
  4530. if (inode.i_file_acl &&
  4531. (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
  4532. count = 1;
  4533. pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
  4534. block_buf, -1, &count);
  4535. if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
  4536. pctx.errcode = 0;
  4537. count = 1;
  4538. }
  4539. if (pctx.errcode) {
  4540. pctx.blk = inode.i_file_acl;
  4541. fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
  4542. }
  4543. /*
  4544. * If the count is zero, then arrange to have the
  4545. * block deleted. If the block is in the block_dup_map,
  4546. * also call delete_file_block since it will take care
  4547. * of keeping the accounting straight.
  4548. */
  4549. if ((count == 0) ||
  4550. ext2fs_test_block_bitmap(ctx->block_dup_map,
  4551. inode.i_file_acl))
  4552. delete_file_block(fs, &inode.i_file_acl,
  4553. BLOCK_COUNT_EXTATTR, 0, 0, &pb);
  4554. }
  4555. e2fsck_write_inode(ctx, ino, &inode, "delete_file");
  4556. }
  4557. struct clone_struct {
  4558. errcode_t errcode;
  4559. ext2_ino_t dir;
  4560. char *buf;
  4561. e2fsck_t ctx;
  4562. };
  4563. static int clone_file_block(ext2_filsys fs,
  4564. blk_t *block_nr,
  4565. e2_blkcnt_t blockcnt,
  4566. blk_t ref_block FSCK_ATTR((unused)),
  4567. int ref_offset FSCK_ATTR((unused)),
  4568. void *priv_data)
  4569. {
  4570. struct dup_block *p;
  4571. blk_t new_block;
  4572. errcode_t retval;
  4573. struct clone_struct *cs = (struct clone_struct *) priv_data;
  4574. dnode_t *n;
  4575. e2fsck_t ctx;
  4576. ctx = cs->ctx;
  4577. if (HOLE_BLKADDR(*block_nr))
  4578. return 0;
  4579. if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
  4580. n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
  4581. if (n) {
  4582. p = (struct dup_block *) dnode_get(n);
  4583. retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
  4584. &new_block);
  4585. if (retval) {
  4586. cs->errcode = retval;
  4587. return BLOCK_ABORT;
  4588. }
  4589. if (cs->dir && (blockcnt >= 0)) {
  4590. retval = ext2fs_set_dir_block(fs->dblist,
  4591. cs->dir, new_block, blockcnt);
  4592. if (retval) {
  4593. cs->errcode = retval;
  4594. return BLOCK_ABORT;
  4595. }
  4596. }
  4597. retval = io_channel_read_blk(fs->io, *block_nr, 1,
  4598. cs->buf);
  4599. if (retval) {
  4600. cs->errcode = retval;
  4601. return BLOCK_ABORT;
  4602. }
  4603. retval = io_channel_write_blk(fs->io, new_block, 1,
  4604. cs->buf);
  4605. if (retval) {
  4606. cs->errcode = retval;
  4607. return BLOCK_ABORT;
  4608. }
  4609. decrement_badcount(ctx, *block_nr, p);
  4610. *block_nr = new_block;
  4611. ext2fs_mark_block_bitmap(ctx->block_found_map,
  4612. new_block);
  4613. ext2fs_mark_block_bitmap(fs->block_map, new_block);
  4614. return BLOCK_CHANGED;
  4615. } else
  4616. bb_error_msg(_("internal error; can't find dup_blk for %d"),
  4617. *block_nr);
  4618. }
  4619. return 0;
  4620. }
  4621. static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
  4622. struct dup_inode *dp, char* block_buf)
  4623. {
  4624. ext2_filsys fs = ctx->fs;
  4625. errcode_t retval;
  4626. struct clone_struct cs;
  4627. struct problem_context pctx;
  4628. blk_t blk;
  4629. dnode_t *n;
  4630. struct inode_el *ino_el;
  4631. struct dup_block *db;
  4632. struct dup_inode *di;
  4633. clear_problem_context(&pctx);
  4634. cs.errcode = 0;
  4635. cs.dir = 0;
  4636. cs.ctx = ctx;
  4637. retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
  4638. if (retval)
  4639. return retval;
  4640. if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
  4641. cs.dir = ino;
  4642. pctx.ino = ino;
  4643. pctx.str = "clone_file";
  4644. if (ext2fs_inode_has_valid_blocks(&dp->inode))
  4645. pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
  4646. clone_file_block, &cs);
  4647. ext2fs_mark_bb_dirty(fs);
  4648. if (pctx.errcode) {
  4649. fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
  4650. retval = pctx.errcode;
  4651. goto errout;
  4652. }
  4653. if (cs.errcode) {
  4654. bb_error_msg(_("returned from clone_file_block"));
  4655. retval = cs.errcode;
  4656. goto errout;
  4657. }
  4658. /* The inode may have changed on disk, so we have to re-read it */
  4659. e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
  4660. blk = dp->inode.i_file_acl;
  4661. if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
  4662. BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
  4663. BLOCK_CHANGED)) {
  4664. e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
  4665. /*
  4666. * If we cloned the EA block, find all other inodes
  4667. * which refered to that EA block, and modify
  4668. * them to point to the new EA block.
  4669. */
  4670. n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
  4671. db = (struct dup_block *) dnode_get(n);
  4672. for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
  4673. if (ino_el->inode == ino)
  4674. continue;
  4675. n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
  4676. di = (struct dup_inode *) dnode_get(n);
  4677. if (di->inode.i_file_acl == blk) {
  4678. di->inode.i_file_acl = dp->inode.i_file_acl;
  4679. e2fsck_write_inode(ctx, ino_el->inode,
  4680. &di->inode, "clone file EA");
  4681. decrement_badcount(ctx, blk, db);
  4682. }
  4683. }
  4684. }
  4685. retval = 0;
  4686. errout:
  4687. ext2fs_free_mem(&cs.buf);
  4688. return retval;
  4689. }
  4690. /*
  4691. * This routine returns 1 if a block overlaps with one of the superblocks,
  4692. * group descriptors, inode bitmaps, or block bitmaps.
  4693. */
  4694. static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
  4695. {
  4696. ext2_filsys fs = ctx->fs;
  4697. blk_t block;
  4698. dgrp_t i;
  4699. block = fs->super->s_first_data_block;
  4700. for (i = 0; i < fs->group_desc_count; i++) {
  4701. /* Check superblocks/block group descriptros */
  4702. if (ext2fs_bg_has_super(fs, i)) {
  4703. if (test_block >= block &&
  4704. (test_block <= block + fs->desc_blocks))
  4705. return 1;
  4706. }
  4707. /* Check the inode table */
  4708. if ((fs->group_desc[i].bg_inode_table) &&
  4709. (test_block >= fs->group_desc[i].bg_inode_table) &&
  4710. (test_block < (fs->group_desc[i].bg_inode_table +
  4711. fs->inode_blocks_per_group)))
  4712. return 1;
  4713. /* Check the bitmap blocks */
  4714. if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
  4715. (test_block == fs->group_desc[i].bg_inode_bitmap))
  4716. return 1;
  4717. block += fs->super->s_blocks_per_group;
  4718. }
  4719. return 0;
  4720. }
  4721. /*
  4722. * pass2.c --- check directory structure
  4723. *
  4724. * Pass 2 of e2fsck iterates through all active directory inodes, and
  4725. * applies to following tests to each directory entry in the directory
  4726. * blocks in the inodes:
  4727. *
  4728. * - The length of the directory entry (rec_len) should be at
  4729. * least 8 bytes, and no more than the remaining space
  4730. * left in the directory block.
  4731. * - The length of the name in the directory entry (name_len)
  4732. * should be less than (rec_len - 8).
  4733. * - The inode number in the directory entry should be within
  4734. * legal bounds.
  4735. * - The inode number should refer to a in-use inode.
  4736. * - The first entry should be '.', and its inode should be
  4737. * the inode of the directory.
  4738. * - The second entry should be '..'.
  4739. *
  4740. * To minimize disk seek time, the directory blocks are processed in
  4741. * sorted order of block numbers.
  4742. *
  4743. * Pass 2 also collects the following information:
  4744. * - The inode numbers of the subdirectories for each directory.
  4745. *
  4746. * Pass 2 relies on the following information from previous passes:
  4747. * - The directory information collected in pass 1.
  4748. * - The inode_used_map bitmap
  4749. * - The inode_bad_map bitmap
  4750. * - The inode_dir_map bitmap
  4751. *
  4752. * Pass 2 frees the following data structures
  4753. * - The inode_bad_map bitmap
  4754. * - The inode_reg_map bitmap
  4755. */
  4756. /*
  4757. * Keeps track of how many times an inode is referenced.
  4758. */
  4759. static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
  4760. static int check_dir_block(ext2_filsys fs,
  4761. struct ext2_db_entry *dir_blocks_info,
  4762. void *priv_data);
  4763. static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info,
  4764. struct problem_context *pctx);
  4765. static int update_dir_block(ext2_filsys fs,
  4766. blk_t *block_nr,
  4767. e2_blkcnt_t blockcnt,
  4768. blk_t ref_block,
  4769. int ref_offset,
  4770. void *priv_data);
  4771. static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
  4772. static int htree_depth(struct dx_dir_info *dx_dir,
  4773. struct dx_dirblock_info *dx_db);
  4774. static int special_dir_block_cmp(const void *a, const void *b);
  4775. struct check_dir_struct {
  4776. char *buf;
  4777. struct problem_context pctx;
  4778. int count, max;
  4779. e2fsck_t ctx;
  4780. };
  4781. static void e2fsck_pass2(e2fsck_t ctx)
  4782. {
  4783. struct ext2_super_block *sb = ctx->fs->super;
  4784. struct problem_context pctx;
  4785. ext2_filsys fs = ctx->fs;
  4786. char *buf;
  4787. struct dir_info *dir;
  4788. struct check_dir_struct cd;
  4789. struct dx_dir_info *dx_dir;
  4790. struct dx_dirblock_info *dx_db, *dx_parent;
  4791. int b;
  4792. int i, depth;
  4793. problem_t code;
  4794. int bad_dir;
  4795. clear_problem_context(&cd.pctx);
  4796. /* Pass 2 */
  4797. if (!(ctx->options & E2F_OPT_PREEN))
  4798. fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
  4799. cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
  4800. 0, ctx->inode_link_info,
  4801. &ctx->inode_count);
  4802. if (cd.pctx.errcode) {
  4803. fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
  4804. ctx->flags |= E2F_FLAG_ABORT;
  4805. return;
  4806. }
  4807. buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
  4808. "directory scan buffer");
  4809. /*
  4810. * Set up the parent pointer for the root directory, if
  4811. * present. (If the root directory is not present, we will
  4812. * create it in pass 3.)
  4813. */
  4814. dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
  4815. if (dir)
  4816. dir->parent = EXT2_ROOT_INO;
  4817. cd.buf = buf;
  4818. cd.ctx = ctx;
  4819. cd.count = 1;
  4820. cd.max = ext2fs_dblist_count(fs->dblist);
  4821. if (ctx->progress)
  4822. (void) (ctx->progress)(ctx, 2, 0, cd.max);
  4823. if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
  4824. ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
  4825. cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
  4826. &cd);
  4827. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  4828. return;
  4829. if (cd.pctx.errcode) {
  4830. fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
  4831. ctx->flags |= E2F_FLAG_ABORT;
  4832. return;
  4833. }
  4834. #ifdef ENABLE_HTREE
  4835. for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
  4836. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  4837. return;
  4838. if (dx_dir->numblocks == 0)
  4839. continue;
  4840. clear_problem_context(&pctx);
  4841. bad_dir = 0;
  4842. pctx.dir = dx_dir->ino;
  4843. dx_db = dx_dir->dx_block;
  4844. if (dx_db->flags & DX_FLAG_REFERENCED)
  4845. dx_db->flags |= DX_FLAG_DUP_REF;
  4846. else
  4847. dx_db->flags |= DX_FLAG_REFERENCED;
  4848. /*
  4849. * Find all of the first and last leaf blocks, and
  4850. * update their parent's min and max hash values
  4851. */
  4852. for (b=0, dx_db = dx_dir->dx_block;
  4853. b < dx_dir->numblocks;
  4854. b++, dx_db++) {
  4855. if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
  4856. !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
  4857. continue;
  4858. dx_parent = &dx_dir->dx_block[dx_db->parent];
  4859. /*
  4860. * XXX Make sure dx_parent->min_hash > dx_db->min_hash
  4861. */
  4862. if (dx_db->flags & DX_FLAG_FIRST)
  4863. dx_parent->min_hash = dx_db->min_hash;
  4864. /*
  4865. * XXX Make sure dx_parent->max_hash < dx_db->max_hash
  4866. */
  4867. if (dx_db->flags & DX_FLAG_LAST)
  4868. dx_parent->max_hash = dx_db->max_hash;
  4869. }
  4870. for (b=0, dx_db = dx_dir->dx_block;
  4871. b < dx_dir->numblocks;
  4872. b++, dx_db++) {
  4873. pctx.blkcount = b;
  4874. pctx.group = dx_db->parent;
  4875. code = 0;
  4876. if (!(dx_db->flags & DX_FLAG_FIRST) &&
  4877. (dx_db->min_hash < dx_db->node_min_hash)) {
  4878. pctx.blk = dx_db->min_hash;
  4879. pctx.blk2 = dx_db->node_min_hash;
  4880. code = PR_2_HTREE_MIN_HASH;
  4881. fix_problem(ctx, code, &pctx);
  4882. bad_dir++;
  4883. }
  4884. if (dx_db->type == DX_DIRBLOCK_LEAF) {
  4885. depth = htree_depth(dx_dir, dx_db);
  4886. if (depth != dx_dir->depth) {
  4887. code = PR_2_HTREE_BAD_DEPTH;
  4888. fix_problem(ctx, code, &pctx);
  4889. bad_dir++;
  4890. }
  4891. }
  4892. /*
  4893. * This test doesn't apply for the root block
  4894. * at block #0
  4895. */
  4896. if (b &&
  4897. (dx_db->max_hash > dx_db->node_max_hash)) {
  4898. pctx.blk = dx_db->max_hash;
  4899. pctx.blk2 = dx_db->node_max_hash;
  4900. code = PR_2_HTREE_MAX_HASH;
  4901. fix_problem(ctx, code, &pctx);
  4902. bad_dir++;
  4903. }
  4904. if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
  4905. code = PR_2_HTREE_NOTREF;
  4906. fix_problem(ctx, code, &pctx);
  4907. bad_dir++;
  4908. } else if (dx_db->flags & DX_FLAG_DUP_REF) {
  4909. code = PR_2_HTREE_DUPREF;
  4910. fix_problem(ctx, code, &pctx);
  4911. bad_dir++;
  4912. }
  4913. if (code == 0)
  4914. continue;
  4915. }
  4916. if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
  4917. clear_htree(ctx, dx_dir->ino);
  4918. dx_dir->numblocks = 0;
  4919. }
  4920. }
  4921. #endif
  4922. ext2fs_free_mem(&buf);
  4923. ext2fs_free_dblist(fs->dblist);
  4924. ext2fs_free_inode_bitmap(ctx->inode_bad_map);
  4925. ctx->inode_bad_map = 0;
  4926. ext2fs_free_inode_bitmap(ctx->inode_reg_map);
  4927. ctx->inode_reg_map = 0;
  4928. clear_problem_context(&pctx);
  4929. if (ctx->large_files) {
  4930. if (!(sb->s_feature_ro_compat &
  4931. EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
  4932. fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
  4933. sb->s_feature_ro_compat |=
  4934. EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
  4935. ext2fs_mark_super_dirty(fs);
  4936. }
  4937. if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
  4938. fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
  4939. ext2fs_update_dynamic_rev(fs);
  4940. ext2fs_mark_super_dirty(fs);
  4941. }
  4942. } else if (!ctx->large_files &&
  4943. (sb->s_feature_ro_compat &
  4944. EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
  4945. if (fs->flags & EXT2_FLAG_RW) {
  4946. sb->s_feature_ro_compat &=
  4947. ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
  4948. ext2fs_mark_super_dirty(fs);
  4949. }
  4950. }
  4951. }
  4952. #define MAX_DEPTH 32000
  4953. static int htree_depth(struct dx_dir_info *dx_dir,
  4954. struct dx_dirblock_info *dx_db)
  4955. {
  4956. int depth = 0;
  4957. while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
  4958. dx_db = &dx_dir->dx_block[dx_db->parent];
  4959. depth++;
  4960. }
  4961. return depth;
  4962. }
  4963. static int dict_de_cmp(const void *a, const void *b)
  4964. {
  4965. const struct ext2_dir_entry *de_a, *de_b;
  4966. int a_len, b_len;
  4967. de_a = (const struct ext2_dir_entry *) a;
  4968. a_len = de_a->name_len & 0xFF;
  4969. de_b = (const struct ext2_dir_entry *) b;
  4970. b_len = de_b->name_len & 0xFF;
  4971. if (a_len != b_len)
  4972. return (a_len - b_len);
  4973. return strncmp(de_a->name, de_b->name, a_len);
  4974. }
  4975. /*
  4976. * This is special sort function that makes sure that directory blocks
  4977. * with a dirblock of zero are sorted to the beginning of the list.
  4978. * This guarantees that the root node of the htree directories are
  4979. * processed first, so we know what hash version to use.
  4980. */
  4981. static int special_dir_block_cmp(const void *a, const void *b)
  4982. {
  4983. const struct ext2_db_entry *db_a =
  4984. (const struct ext2_db_entry *) a;
  4985. const struct ext2_db_entry *db_b =
  4986. (const struct ext2_db_entry *) b;
  4987. if (db_a->blockcnt && !db_b->blockcnt)
  4988. return 1;
  4989. if (!db_a->blockcnt && db_b->blockcnt)
  4990. return -1;
  4991. if (db_a->blk != db_b->blk)
  4992. return (int) (db_a->blk - db_b->blk);
  4993. if (db_a->ino != db_b->ino)
  4994. return (int) (db_a->ino - db_b->ino);
  4995. return (int) (db_a->blockcnt - db_b->blockcnt);
  4996. }
  4997. /*
  4998. * Make sure the first entry in the directory is '.', and that the
  4999. * directory entry is sane.
  5000. */
  5001. static int check_dot(e2fsck_t ctx,
  5002. struct ext2_dir_entry *dirent,
  5003. ext2_ino_t ino, struct problem_context *pctx)
  5004. {
  5005. struct ext2_dir_entry *nextdir;
  5006. int status = 0;
  5007. int created = 0;
  5008. int new_len;
  5009. int problem = 0;
  5010. if (!dirent->inode)
  5011. problem = PR_2_MISSING_DOT;
  5012. else if (((dirent->name_len & 0xFF) != 1) ||
  5013. (dirent->name[0] != '.'))
  5014. problem = PR_2_1ST_NOT_DOT;
  5015. else if (dirent->name[1] != '\0')
  5016. problem = PR_2_DOT_NULL_TERM;
  5017. if (problem) {
  5018. if (fix_problem(ctx, problem, pctx)) {
  5019. if (dirent->rec_len < 12)
  5020. dirent->rec_len = 12;
  5021. dirent->inode = ino;
  5022. dirent->name_len = 1;
  5023. dirent->name[0] = '.';
  5024. dirent->name[1] = '\0';
  5025. status = 1;
  5026. created = 1;
  5027. }
  5028. }
  5029. if (dirent->inode != ino) {
  5030. if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
  5031. dirent->inode = ino;
  5032. status = 1;
  5033. }
  5034. }
  5035. if (dirent->rec_len > 12) {
  5036. new_len = dirent->rec_len - 12;
  5037. if (new_len > 12) {
  5038. if (created ||
  5039. fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
  5040. nextdir = (struct ext2_dir_entry *)
  5041. ((char *) dirent + 12);
  5042. dirent->rec_len = 12;
  5043. nextdir->rec_len = new_len;
  5044. nextdir->inode = 0;
  5045. nextdir->name_len = 0;
  5046. status = 1;
  5047. }
  5048. }
  5049. }
  5050. return status;
  5051. }
  5052. /*
  5053. * Make sure the second entry in the directory is '..', and that the
  5054. * directory entry is sane. We do not check the inode number of '..'
  5055. * here; this gets done in pass 3.
  5056. */
  5057. static int check_dotdot(e2fsck_t ctx,
  5058. struct ext2_dir_entry *dirent,
  5059. struct dir_info *dir, struct problem_context *pctx)
  5060. {
  5061. int problem = 0;
  5062. if (!dirent->inode)
  5063. problem = PR_2_MISSING_DOT_DOT;
  5064. else if (((dirent->name_len & 0xFF) != 2) ||
  5065. (dirent->name[0] != '.') ||
  5066. (dirent->name[1] != '.'))
  5067. problem = PR_2_2ND_NOT_DOT_DOT;
  5068. else if (dirent->name[2] != '\0')
  5069. problem = PR_2_DOT_DOT_NULL_TERM;
  5070. if (problem) {
  5071. if (fix_problem(ctx, problem, pctx)) {
  5072. if (dirent->rec_len < 12)
  5073. dirent->rec_len = 12;
  5074. /*
  5075. * Note: we don't have the parent inode just
  5076. * yet, so we will fill it in with the root
  5077. * inode. This will get fixed in pass 3.
  5078. */
  5079. dirent->inode = EXT2_ROOT_INO;
  5080. dirent->name_len = 2;
  5081. dirent->name[0] = '.';
  5082. dirent->name[1] = '.';
  5083. dirent->name[2] = '\0';
  5084. return 1;
  5085. }
  5086. return 0;
  5087. }
  5088. dir->dotdot = dirent->inode;
  5089. return 0;
  5090. }
  5091. /*
  5092. * Check to make sure a directory entry doesn't contain any illegal
  5093. * characters.
  5094. */
  5095. static int check_name(e2fsck_t ctx,
  5096. struct ext2_dir_entry *dirent,
  5097. struct problem_context *pctx)
  5098. {
  5099. int i;
  5100. int fixup = -1;
  5101. int ret = 0;
  5102. for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
  5103. if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
  5104. if (fixup < 0) {
  5105. fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
  5106. }
  5107. if (fixup) {
  5108. dirent->name[i] = '.';
  5109. ret = 1;
  5110. }
  5111. }
  5112. }
  5113. return ret;
  5114. }
  5115. /*
  5116. * Check the directory filetype (if present)
  5117. */
  5118. /*
  5119. * Given a mode, return the ext2 file type
  5120. */
  5121. static int ext2_file_type(unsigned int mode)
  5122. {
  5123. if (LINUX_S_ISREG(mode))
  5124. return EXT2_FT_REG_FILE;
  5125. if (LINUX_S_ISDIR(mode))
  5126. return EXT2_FT_DIR;
  5127. if (LINUX_S_ISCHR(mode))
  5128. return EXT2_FT_CHRDEV;
  5129. if (LINUX_S_ISBLK(mode))
  5130. return EXT2_FT_BLKDEV;
  5131. if (LINUX_S_ISLNK(mode))
  5132. return EXT2_FT_SYMLINK;
  5133. if (LINUX_S_ISFIFO(mode))
  5134. return EXT2_FT_FIFO;
  5135. if (LINUX_S_ISSOCK(mode))
  5136. return EXT2_FT_SOCK;
  5137. return 0;
  5138. }
  5139. static int check_filetype(e2fsck_t ctx,
  5140. struct ext2_dir_entry *dirent,
  5141. struct problem_context *pctx)
  5142. {
  5143. int filetype = dirent->name_len >> 8;
  5144. int should_be = EXT2_FT_UNKNOWN;
  5145. struct ext2_inode inode;
  5146. if (!(ctx->fs->super->s_feature_incompat &
  5147. EXT2_FEATURE_INCOMPAT_FILETYPE)) {
  5148. if (filetype == 0 ||
  5149. !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
  5150. return 0;
  5151. dirent->name_len = dirent->name_len & 0xFF;
  5152. return 1;
  5153. }
  5154. if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
  5155. should_be = EXT2_FT_DIR;
  5156. } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
  5157. dirent->inode)) {
  5158. should_be = EXT2_FT_REG_FILE;
  5159. } else if (ctx->inode_bad_map &&
  5160. ext2fs_test_inode_bitmap(ctx->inode_bad_map,
  5161. dirent->inode))
  5162. should_be = 0;
  5163. else {
  5164. e2fsck_read_inode(ctx, dirent->inode, &inode,
  5165. "check_filetype");
  5166. should_be = ext2_file_type(inode.i_mode);
  5167. }
  5168. if (filetype == should_be)
  5169. return 0;
  5170. pctx->num = should_be;
  5171. if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
  5172. pctx) == 0)
  5173. return 0;
  5174. dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
  5175. return 1;
  5176. }
  5177. #ifdef ENABLE_HTREE
  5178. static void parse_int_node(ext2_filsys fs,
  5179. struct ext2_db_entry *db,
  5180. struct check_dir_struct *cd,
  5181. struct dx_dir_info *dx_dir,
  5182. char *block_buf)
  5183. {
  5184. struct ext2_dx_root_info *root;
  5185. struct ext2_dx_entry *ent;
  5186. struct ext2_dx_countlimit *limit;
  5187. struct dx_dirblock_info *dx_db;
  5188. int i, expect_limit, count;
  5189. blk_t blk;
  5190. ext2_dirhash_t min_hash = 0xffffffff;
  5191. ext2_dirhash_t max_hash = 0;
  5192. ext2_dirhash_t hash = 0, prev_hash;
  5193. if (db->blockcnt == 0) {
  5194. root = (struct ext2_dx_root_info *) (block_buf + 24);
  5195. ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
  5196. } else {
  5197. ent = (struct ext2_dx_entry *) (block_buf+8);
  5198. }
  5199. limit = (struct ext2_dx_countlimit *) ent;
  5200. count = ext2fs_le16_to_cpu(limit->count);
  5201. expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
  5202. sizeof(struct ext2_dx_entry);
  5203. if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
  5204. cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
  5205. if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
  5206. goto clear_and_exit;
  5207. }
  5208. if (count > expect_limit) {
  5209. cd->pctx.num = count;
  5210. if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
  5211. goto clear_and_exit;
  5212. count = expect_limit;
  5213. }
  5214. for (i=0; i < count; i++) {
  5215. prev_hash = hash;
  5216. hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
  5217. blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
  5218. /* Check to make sure the block is valid */
  5219. if (blk > (blk_t) dx_dir->numblocks) {
  5220. cd->pctx.blk = blk;
  5221. if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
  5222. &cd->pctx))
  5223. goto clear_and_exit;
  5224. }
  5225. if (hash < prev_hash &&
  5226. fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
  5227. goto clear_and_exit;
  5228. dx_db = &dx_dir->dx_block[blk];
  5229. if (dx_db->flags & DX_FLAG_REFERENCED) {
  5230. dx_db->flags |= DX_FLAG_DUP_REF;
  5231. } else {
  5232. dx_db->flags |= DX_FLAG_REFERENCED;
  5233. dx_db->parent = db->blockcnt;
  5234. }
  5235. if (hash < min_hash)
  5236. min_hash = hash;
  5237. if (hash > max_hash)
  5238. max_hash = hash;
  5239. dx_db->node_min_hash = hash;
  5240. if ((i+1) < count)
  5241. dx_db->node_max_hash =
  5242. ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
  5243. else {
  5244. dx_db->node_max_hash = 0xfffffffe;
  5245. dx_db->flags |= DX_FLAG_LAST;
  5246. }
  5247. if (i == 0)
  5248. dx_db->flags |= DX_FLAG_FIRST;
  5249. }
  5250. dx_db = &dx_dir->dx_block[db->blockcnt];
  5251. dx_db->min_hash = min_hash;
  5252. dx_db->max_hash = max_hash;
  5253. return;
  5254. clear_and_exit:
  5255. clear_htree(cd->ctx, cd->pctx.ino);
  5256. dx_dir->numblocks = 0;
  5257. }
  5258. #endif /* ENABLE_HTREE */
  5259. /*
  5260. * Given a busted directory, try to salvage it somehow.
  5261. *
  5262. */
  5263. static void salvage_directory(ext2_filsys fs,
  5264. struct ext2_dir_entry *dirent,
  5265. struct ext2_dir_entry *prev,
  5266. unsigned int *offset)
  5267. {
  5268. char *cp = (char *) dirent;
  5269. int left = fs->blocksize - *offset - dirent->rec_len;
  5270. int name_len = dirent->name_len & 0xFF;
  5271. /*
  5272. * Special case of directory entry of size 8: copy what's left
  5273. * of the directory block up to cover up the invalid hole.
  5274. */
  5275. if ((left >= 12) && (dirent->rec_len == 8)) {
  5276. memmove(cp, cp+8, left);
  5277. memset(cp + left, 0, 8);
  5278. return;
  5279. }
  5280. /*
  5281. * If the directory entry overruns the end of the directory
  5282. * block, and the name is small enough to fit, then adjust the
  5283. * record length.
  5284. */
  5285. if ((left < 0) &&
  5286. (name_len + 8 <= dirent->rec_len + left) &&
  5287. dirent->inode <= fs->super->s_inodes_count &&
  5288. strnlen(dirent->name, name_len) == name_len) {
  5289. dirent->rec_len += left;
  5290. return;
  5291. }
  5292. /*
  5293. * If the directory entry is a multiple of four, so it is
  5294. * valid, let the previous directory entry absorb the invalid
  5295. * one.
  5296. */
  5297. if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
  5298. prev->rec_len += dirent->rec_len;
  5299. *offset += dirent->rec_len;
  5300. return;
  5301. }
  5302. /*
  5303. * Default salvage method --- kill all of the directory
  5304. * entries for the rest of the block. We will either try to
  5305. * absorb it into the previous directory entry, or create a
  5306. * new empty directory entry the rest of the directory block.
  5307. */
  5308. if (prev) {
  5309. prev->rec_len += fs->blocksize - *offset;
  5310. *offset = fs->blocksize;
  5311. } else {
  5312. dirent->rec_len = fs->blocksize - *offset;
  5313. dirent->name_len = 0;
  5314. dirent->inode = 0;
  5315. }
  5316. }
  5317. static int check_dir_block(ext2_filsys fs,
  5318. struct ext2_db_entry *db,
  5319. void *priv_data)
  5320. {
  5321. struct dir_info *subdir, *dir;
  5322. struct dx_dir_info *dx_dir;
  5323. #ifdef ENABLE_HTREE
  5324. struct dx_dirblock_info *dx_db = NULL;
  5325. #endif /* ENABLE_HTREE */
  5326. struct ext2_dir_entry *dirent, *prev;
  5327. ext2_dirhash_t hash;
  5328. unsigned int offset = 0;
  5329. int dir_modified = 0;
  5330. int dot_state;
  5331. blk_t block_nr = db->blk;
  5332. ext2_ino_t ino = db->ino;
  5333. __u16 links;
  5334. struct check_dir_struct *cd;
  5335. char *buf;
  5336. e2fsck_t ctx;
  5337. int problem;
  5338. struct ext2_dx_root_info *root;
  5339. struct ext2_dx_countlimit *limit;
  5340. static dict_t de_dict;
  5341. struct problem_context pctx;
  5342. int dups_found = 0;
  5343. cd = (struct check_dir_struct *) priv_data;
  5344. buf = cd->buf;
  5345. ctx = cd->ctx;
  5346. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  5347. return DIRENT_ABORT;
  5348. if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
  5349. return DIRENT_ABORT;
  5350. /*
  5351. * Make sure the inode is still in use (could have been
  5352. * deleted in the duplicate/bad blocks pass.
  5353. */
  5354. if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
  5355. return 0;
  5356. cd->pctx.ino = ino;
  5357. cd->pctx.blk = block_nr;
  5358. cd->pctx.blkcount = db->blockcnt;
  5359. cd->pctx.ino2 = 0;
  5360. cd->pctx.dirent = 0;
  5361. cd->pctx.num = 0;
  5362. if (db->blk == 0) {
  5363. if (allocate_dir_block(ctx, db, &cd->pctx))
  5364. return 0;
  5365. block_nr = db->blk;
  5366. }
  5367. if (db->blockcnt)
  5368. dot_state = 2;
  5369. else
  5370. dot_state = 0;
  5371. if (ctx->dirs_to_hash &&
  5372. ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
  5373. dups_found++;
  5374. cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
  5375. if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
  5376. cd->pctx.errcode = 0; /* We'll handle this ourselves */
  5377. if (cd->pctx.errcode) {
  5378. if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
  5379. ctx->flags |= E2F_FLAG_ABORT;
  5380. return DIRENT_ABORT;
  5381. }
  5382. memset(buf, 0, fs->blocksize);
  5383. }
  5384. #ifdef ENABLE_HTREE
  5385. dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
  5386. if (dx_dir && dx_dir->numblocks) {
  5387. if (db->blockcnt >= dx_dir->numblocks) {
  5388. printf("XXX should never happen!!!\n");
  5389. abort();
  5390. }
  5391. dx_db = &dx_dir->dx_block[db->blockcnt];
  5392. dx_db->type = DX_DIRBLOCK_LEAF;
  5393. dx_db->phys = block_nr;
  5394. dx_db->min_hash = ~0;
  5395. dx_db->max_hash = 0;
  5396. dirent = (struct ext2_dir_entry *) buf;
  5397. limit = (struct ext2_dx_countlimit *) (buf+8);
  5398. if (db->blockcnt == 0) {
  5399. root = (struct ext2_dx_root_info *) (buf + 24);
  5400. dx_db->type = DX_DIRBLOCK_ROOT;
  5401. dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
  5402. if ((root->reserved_zero ||
  5403. root->info_length < 8 ||
  5404. root->indirect_levels > 1) &&
  5405. fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
  5406. clear_htree(ctx, ino);
  5407. dx_dir->numblocks = 0;
  5408. dx_db = 0;
  5409. }
  5410. dx_dir->hashversion = root->hash_version;
  5411. dx_dir->depth = root->indirect_levels + 1;
  5412. } else if ((dirent->inode == 0) &&
  5413. (dirent->rec_len == fs->blocksize) &&
  5414. (dirent->name_len == 0) &&
  5415. (ext2fs_le16_to_cpu(limit->limit) ==
  5416. ((fs->blocksize-8) /
  5417. sizeof(struct ext2_dx_entry))))
  5418. dx_db->type = DX_DIRBLOCK_NODE;
  5419. }
  5420. #endif /* ENABLE_HTREE */
  5421. dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
  5422. prev = 0;
  5423. do {
  5424. problem = 0;
  5425. dirent = (struct ext2_dir_entry *) (buf + offset);
  5426. cd->pctx.dirent = dirent;
  5427. cd->pctx.num = offset;
  5428. if (((offset + dirent->rec_len) > fs->blocksize) ||
  5429. (dirent->rec_len < 12) ||
  5430. ((dirent->rec_len % 4) != 0) ||
  5431. (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
  5432. if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
  5433. salvage_directory(fs, dirent, prev, &offset);
  5434. dir_modified++;
  5435. continue;
  5436. } else
  5437. goto abort_free_dict;
  5438. }
  5439. if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
  5440. if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
  5441. dirent->name_len = EXT2_NAME_LEN;
  5442. dir_modified++;
  5443. }
  5444. }
  5445. if (dot_state == 0) {
  5446. if (check_dot(ctx, dirent, ino, &cd->pctx))
  5447. dir_modified++;
  5448. } else if (dot_state == 1) {
  5449. dir = e2fsck_get_dir_info(ctx, ino);
  5450. if (!dir) {
  5451. fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
  5452. goto abort_free_dict;
  5453. }
  5454. if (check_dotdot(ctx, dirent, dir, &cd->pctx))
  5455. dir_modified++;
  5456. } else if (dirent->inode == ino) {
  5457. problem = PR_2_LINK_DOT;
  5458. if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
  5459. dirent->inode = 0;
  5460. dir_modified++;
  5461. goto next;
  5462. }
  5463. }
  5464. if (!dirent->inode)
  5465. goto next;
  5466. /*
  5467. * Make sure the inode listed is a legal one.
  5468. */
  5469. if (((dirent->inode != EXT2_ROOT_INO) &&
  5470. (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
  5471. (dirent->inode > fs->super->s_inodes_count)) {
  5472. problem = PR_2_BAD_INO;
  5473. } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
  5474. dirent->inode))) {
  5475. /*
  5476. * If the inode is unused, offer to clear it.
  5477. */
  5478. problem = PR_2_UNUSED_INODE;
  5479. } else if ((dot_state > 1) &&
  5480. ((dirent->name_len & 0xFF) == 1) &&
  5481. (dirent->name[0] == '.')) {
  5482. /*
  5483. * If there's a '.' entry in anything other
  5484. * than the first directory entry, it's a
  5485. * duplicate entry that should be removed.
  5486. */
  5487. problem = PR_2_DUP_DOT;
  5488. } else if ((dot_state > 1) &&
  5489. ((dirent->name_len & 0xFF) == 2) &&
  5490. (dirent->name[0] == '.') &&
  5491. (dirent->name[1] == '.')) {
  5492. /*
  5493. * If there's a '..' entry in anything other
  5494. * than the second directory entry, it's a
  5495. * duplicate entry that should be removed.
  5496. */
  5497. problem = PR_2_DUP_DOT_DOT;
  5498. } else if ((dot_state > 1) &&
  5499. (dirent->inode == EXT2_ROOT_INO)) {
  5500. /*
  5501. * Don't allow links to the root directory.
  5502. * We check this specially to make sure we
  5503. * catch this error case even if the root
  5504. * directory hasn't been created yet.
  5505. */
  5506. problem = PR_2_LINK_ROOT;
  5507. } else if ((dot_state > 1) &&
  5508. (dirent->name_len & 0xFF) == 0) {
  5509. /*
  5510. * Don't allow zero-length directory names.
  5511. */
  5512. problem = PR_2_NULL_NAME;
  5513. }
  5514. if (problem) {
  5515. if (fix_problem(ctx, problem, &cd->pctx)) {
  5516. dirent->inode = 0;
  5517. dir_modified++;
  5518. goto next;
  5519. } else {
  5520. ext2fs_unmark_valid(fs);
  5521. if (problem == PR_2_BAD_INO)
  5522. goto next;
  5523. }
  5524. }
  5525. /*
  5526. * If the inode was marked as having bad fields in
  5527. * pass1, process it and offer to fix/clear it.
  5528. * (We wait until now so that we can display the
  5529. * pathname to the user.)
  5530. */
  5531. if (ctx->inode_bad_map &&
  5532. ext2fs_test_inode_bitmap(ctx->inode_bad_map,
  5533. dirent->inode)) {
  5534. if (e2fsck_process_bad_inode(ctx, ino,
  5535. dirent->inode,
  5536. buf + fs->blocksize)) {
  5537. dirent->inode = 0;
  5538. dir_modified++;
  5539. goto next;
  5540. }
  5541. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  5542. return DIRENT_ABORT;
  5543. }
  5544. if (check_name(ctx, dirent, &cd->pctx))
  5545. dir_modified++;
  5546. if (check_filetype(ctx, dirent, &cd->pctx))
  5547. dir_modified++;
  5548. #ifdef ENABLE_HTREE
  5549. if (dx_db) {
  5550. ext2fs_dirhash(dx_dir->hashversion, dirent->name,
  5551. (dirent->name_len & 0xFF),
  5552. fs->super->s_hash_seed, &hash, 0);
  5553. if (hash < dx_db->min_hash)
  5554. dx_db->min_hash = hash;
  5555. if (hash > dx_db->max_hash)
  5556. dx_db->max_hash = hash;
  5557. }
  5558. #endif
  5559. /*
  5560. * If this is a directory, then mark its parent in its
  5561. * dir_info structure. If the parent field is already
  5562. * filled in, then this directory has more than one
  5563. * hard link. We assume the first link is correct,
  5564. * and ask the user if he/she wants to clear this one.
  5565. */
  5566. if ((dot_state > 1) &&
  5567. (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
  5568. dirent->inode))) {
  5569. subdir = e2fsck_get_dir_info(ctx, dirent->inode);
  5570. if (!subdir) {
  5571. cd->pctx.ino = dirent->inode;
  5572. fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
  5573. goto abort_free_dict;
  5574. }
  5575. if (subdir->parent) {
  5576. cd->pctx.ino2 = subdir->parent;
  5577. if (fix_problem(ctx, PR_2_LINK_DIR,
  5578. &cd->pctx)) {
  5579. dirent->inode = 0;
  5580. dir_modified++;
  5581. goto next;
  5582. }
  5583. cd->pctx.ino2 = 0;
  5584. } else
  5585. subdir->parent = ino;
  5586. }
  5587. if (dups_found) {
  5588. ;
  5589. } else if (dict_lookup(&de_dict, dirent)) {
  5590. clear_problem_context(&pctx);
  5591. pctx.ino = ino;
  5592. pctx.dirent = dirent;
  5593. fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
  5594. if (!ctx->dirs_to_hash)
  5595. ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
  5596. if (ctx->dirs_to_hash)
  5597. ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
  5598. dups_found++;
  5599. } else
  5600. dict_alloc_insert(&de_dict, dirent, dirent);
  5601. ext2fs_icount_increment(ctx->inode_count, dirent->inode,
  5602. &links);
  5603. if (links > 1)
  5604. ctx->fs_links_count++;
  5605. ctx->fs_total_count++;
  5606. next:
  5607. prev = dirent;
  5608. offset += dirent->rec_len;
  5609. dot_state++;
  5610. } while (offset < fs->blocksize);
  5611. #ifdef ENABLE_HTREE
  5612. if (dx_db) {
  5613. cd->pctx.dir = cd->pctx.ino;
  5614. if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
  5615. (dx_db->type == DX_DIRBLOCK_NODE))
  5616. parse_int_node(fs, db, cd, dx_dir, buf);
  5617. }
  5618. #endif /* ENABLE_HTREE */
  5619. if (offset != fs->blocksize) {
  5620. cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
  5621. if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
  5622. dirent->rec_len = cd->pctx.num;
  5623. dir_modified++;
  5624. }
  5625. }
  5626. if (dir_modified) {
  5627. cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
  5628. if (cd->pctx.errcode) {
  5629. if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
  5630. &cd->pctx))
  5631. goto abort_free_dict;
  5632. }
  5633. ext2fs_mark_changed(fs);
  5634. }
  5635. dict_free_nodes(&de_dict);
  5636. return 0;
  5637. abort_free_dict:
  5638. dict_free_nodes(&de_dict);
  5639. ctx->flags |= E2F_FLAG_ABORT;
  5640. return DIRENT_ABORT;
  5641. }
  5642. /*
  5643. * This function is called to deallocate a block, and is an interator
  5644. * functioned called by deallocate inode via ext2fs_iterate_block().
  5645. */
  5646. static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr,
  5647. e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
  5648. blk_t ref_block FSCK_ATTR((unused)),
  5649. int ref_offset FSCK_ATTR((unused)),
  5650. void *priv_data)
  5651. {
  5652. e2fsck_t ctx = (e2fsck_t) priv_data;
  5653. if (HOLE_BLKADDR(*block_nr))
  5654. return 0;
  5655. if ((*block_nr < fs->super->s_first_data_block) ||
  5656. (*block_nr >= fs->super->s_blocks_count))
  5657. return 0;
  5658. ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
  5659. ext2fs_block_alloc_stats(fs, *block_nr, -1);
  5660. return 0;
  5661. }
  5662. /*
  5663. * This fuction deallocates an inode
  5664. */
  5665. static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
  5666. {
  5667. ext2_filsys fs = ctx->fs;
  5668. struct ext2_inode inode;
  5669. struct problem_context pctx;
  5670. __u32 count;
  5671. ext2fs_icount_store(ctx->inode_link_info, ino, 0);
  5672. e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
  5673. inode.i_links_count = 0;
  5674. inode.i_dtime = time(NULL);
  5675. e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
  5676. clear_problem_context(&pctx);
  5677. pctx.ino = ino;
  5678. /*
  5679. * Fix up the bitmaps...
  5680. */
  5681. e2fsck_read_bitmaps(ctx);
  5682. ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
  5683. ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
  5684. if (ctx->inode_bad_map)
  5685. ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
  5686. ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
  5687. if (inode.i_file_acl &&
  5688. (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
  5689. pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
  5690. block_buf, -1, &count);
  5691. if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
  5692. pctx.errcode = 0;
  5693. count = 1;
  5694. }
  5695. if (pctx.errcode) {
  5696. pctx.blk = inode.i_file_acl;
  5697. fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
  5698. ctx->flags |= E2F_FLAG_ABORT;
  5699. return;
  5700. }
  5701. if (count == 0) {
  5702. ext2fs_unmark_block_bitmap(ctx->block_found_map,
  5703. inode.i_file_acl);
  5704. ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
  5705. }
  5706. inode.i_file_acl = 0;
  5707. }
  5708. if (!ext2fs_inode_has_valid_blocks(&inode))
  5709. return;
  5710. if (LINUX_S_ISREG(inode.i_mode) &&
  5711. (inode.i_size_high || inode.i_size & 0x80000000UL))
  5712. ctx->large_files--;
  5713. pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
  5714. deallocate_inode_block, ctx);
  5715. if (pctx.errcode) {
  5716. fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
  5717. ctx->flags |= E2F_FLAG_ABORT;
  5718. return;
  5719. }
  5720. }
  5721. /*
  5722. * This fuction clears the htree flag on an inode
  5723. */
  5724. static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
  5725. {
  5726. struct ext2_inode inode;
  5727. e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
  5728. inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
  5729. e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
  5730. if (ctx->dirs_to_hash)
  5731. ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
  5732. }
  5733. static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
  5734. ext2_ino_t ino, char *buf)
  5735. {
  5736. ext2_filsys fs = ctx->fs;
  5737. struct ext2_inode inode;
  5738. int inode_modified = 0;
  5739. int not_fixed = 0;
  5740. unsigned char *frag, *fsize;
  5741. struct problem_context pctx;
  5742. int problem = 0;
  5743. e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
  5744. clear_problem_context(&pctx);
  5745. pctx.ino = ino;
  5746. pctx.dir = dir;
  5747. pctx.inode = &inode;
  5748. if (inode.i_file_acl &&
  5749. !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
  5750. fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
  5751. inode.i_file_acl = 0;
  5752. #if BB_BIG_ENDIAN
  5753. /*
  5754. * This is a special kludge to deal with long symlinks
  5755. * on big endian systems. i_blocks had already been
  5756. * decremented earlier in pass 1, but since i_file_acl
  5757. * hadn't yet been cleared, ext2fs_read_inode()
  5758. * assumed that the file was short symlink and would
  5759. * not have byte swapped i_block[0]. Hence, we have
  5760. * to byte-swap it here.
  5761. */
  5762. if (LINUX_S_ISLNK(inode.i_mode) &&
  5763. (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
  5764. (inode.i_blocks == fs->blocksize >> 9))
  5765. inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
  5766. #endif
  5767. inode_modified++;
  5768. } else
  5769. not_fixed++;
  5770. if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
  5771. !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
  5772. !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
  5773. !(LINUX_S_ISSOCK(inode.i_mode)))
  5774. problem = PR_2_BAD_MODE;
  5775. else if (LINUX_S_ISCHR(inode.i_mode)
  5776. && !e2fsck_pass1_check_device_inode(fs, &inode))
  5777. problem = PR_2_BAD_CHAR_DEV;
  5778. else if (LINUX_S_ISBLK(inode.i_mode)
  5779. && !e2fsck_pass1_check_device_inode(fs, &inode))
  5780. problem = PR_2_BAD_BLOCK_DEV;
  5781. else if (LINUX_S_ISFIFO(inode.i_mode)
  5782. && !e2fsck_pass1_check_device_inode(fs, &inode))
  5783. problem = PR_2_BAD_FIFO;
  5784. else if (LINUX_S_ISSOCK(inode.i_mode)
  5785. && !e2fsck_pass1_check_device_inode(fs, &inode))
  5786. problem = PR_2_BAD_SOCKET;
  5787. else if (LINUX_S_ISLNK(inode.i_mode)
  5788. && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
  5789. problem = PR_2_INVALID_SYMLINK;
  5790. }
  5791. if (problem) {
  5792. if (fix_problem(ctx, problem, &pctx)) {
  5793. deallocate_inode(ctx, ino, 0);
  5794. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  5795. return 0;
  5796. return 1;
  5797. } else
  5798. not_fixed++;
  5799. problem = 0;
  5800. }
  5801. if (inode.i_faddr) {
  5802. if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
  5803. inode.i_faddr = 0;
  5804. inode_modified++;
  5805. } else
  5806. not_fixed++;
  5807. }
  5808. switch (fs->super->s_creator_os) {
  5809. case EXT2_OS_LINUX:
  5810. frag = &inode.osd2.linux2.l_i_frag;
  5811. fsize = &inode.osd2.linux2.l_i_fsize;
  5812. break;
  5813. case EXT2_OS_HURD:
  5814. frag = &inode.osd2.hurd2.h_i_frag;
  5815. fsize = &inode.osd2.hurd2.h_i_fsize;
  5816. break;
  5817. case EXT2_OS_MASIX:
  5818. frag = &inode.osd2.masix2.m_i_frag;
  5819. fsize = &inode.osd2.masix2.m_i_fsize;
  5820. break;
  5821. default:
  5822. frag = fsize = 0;
  5823. }
  5824. if (frag && *frag) {
  5825. pctx.num = *frag;
  5826. if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
  5827. *frag = 0;
  5828. inode_modified++;
  5829. } else
  5830. not_fixed++;
  5831. pctx.num = 0;
  5832. }
  5833. if (fsize && *fsize) {
  5834. pctx.num = *fsize;
  5835. if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
  5836. *fsize = 0;
  5837. inode_modified++;
  5838. } else
  5839. not_fixed++;
  5840. pctx.num = 0;
  5841. }
  5842. if (inode.i_file_acl &&
  5843. ((inode.i_file_acl < fs->super->s_first_data_block) ||
  5844. (inode.i_file_acl >= fs->super->s_blocks_count))) {
  5845. if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
  5846. inode.i_file_acl = 0;
  5847. inode_modified++;
  5848. } else
  5849. not_fixed++;
  5850. }
  5851. if (inode.i_dir_acl &&
  5852. LINUX_S_ISDIR(inode.i_mode)) {
  5853. if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
  5854. inode.i_dir_acl = 0;
  5855. inode_modified++;
  5856. } else
  5857. not_fixed++;
  5858. }
  5859. if (inode_modified)
  5860. e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
  5861. if (!not_fixed)
  5862. ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
  5863. return 0;
  5864. }
  5865. /*
  5866. * allocate_dir_block --- this function allocates a new directory
  5867. * block for a particular inode; this is done if a directory has
  5868. * a "hole" in it, or if a directory has a illegal block number
  5869. * that was zeroed out and now needs to be replaced.
  5870. */
  5871. static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db,
  5872. struct problem_context *pctx)
  5873. {
  5874. ext2_filsys fs = ctx->fs;
  5875. blk_t blk;
  5876. char *block;
  5877. struct ext2_inode inode;
  5878. if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
  5879. return 1;
  5880. /*
  5881. * Read the inode and block bitmaps in; we'll be messing with
  5882. * them.
  5883. */
  5884. e2fsck_read_bitmaps(ctx);
  5885. /*
  5886. * First, find a free block
  5887. */
  5888. pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
  5889. if (pctx->errcode) {
  5890. pctx->str = "ext2fs_new_block";
  5891. fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
  5892. return 1;
  5893. }
  5894. ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
  5895. ext2fs_mark_block_bitmap(fs->block_map, blk);
  5896. ext2fs_mark_bb_dirty(fs);
  5897. /*
  5898. * Now let's create the actual data block for the inode
  5899. */
  5900. if (db->blockcnt)
  5901. pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
  5902. else
  5903. pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
  5904. EXT2_ROOT_INO, &block);
  5905. if (pctx->errcode) {
  5906. pctx->str = "ext2fs_new_dir_block";
  5907. fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
  5908. return 1;
  5909. }
  5910. pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
  5911. ext2fs_free_mem(&block);
  5912. if (pctx->errcode) {
  5913. pctx->str = "ext2fs_write_dir_block";
  5914. fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
  5915. return 1;
  5916. }
  5917. /*
  5918. * Update the inode block count
  5919. */
  5920. e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
  5921. inode.i_blocks += fs->blocksize / 512;
  5922. if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
  5923. inode.i_size = (db->blockcnt+1) * fs->blocksize;
  5924. e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
  5925. /*
  5926. * Finally, update the block pointers for the inode
  5927. */
  5928. db->blk = blk;
  5929. pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
  5930. 0, update_dir_block, db);
  5931. if (pctx->errcode) {
  5932. pctx->str = "ext2fs_block_iterate";
  5933. fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
  5934. return 1;
  5935. }
  5936. return 0;
  5937. }
  5938. /*
  5939. * This is a helper function for allocate_dir_block().
  5940. */
  5941. static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)),
  5942. blk_t *block_nr,
  5943. e2_blkcnt_t blockcnt,
  5944. blk_t ref_block FSCK_ATTR((unused)),
  5945. int ref_offset FSCK_ATTR((unused)),
  5946. void *priv_data)
  5947. {
  5948. struct ext2_db_entry *db;
  5949. db = (struct ext2_db_entry *) priv_data;
  5950. if (db->blockcnt == (int) blockcnt) {
  5951. *block_nr = db->blk;
  5952. return BLOCK_CHANGED;
  5953. }
  5954. return 0;
  5955. }
  5956. /*
  5957. * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
  5958. *
  5959. * Pass #3 assures that all directories are connected to the
  5960. * filesystem tree, using the following algorithm:
  5961. *
  5962. * First, the root directory is checked to make sure it exists; if
  5963. * not, e2fsck will offer to create a new one. It is then marked as
  5964. * "done".
  5965. *
  5966. * Then, pass3 interates over all directory inodes; for each directory
  5967. * it attempts to trace up the filesystem tree, using dirinfo.parent
  5968. * until it reaches a directory which has been marked "done". If it
  5969. * cannot do so, then the directory must be disconnected, and e2fsck
  5970. * will offer to reconnect it to /lost+found. While it is chasing
  5971. * parent pointers up the filesystem tree, if pass3 sees a directory
  5972. * twice, then it has detected a filesystem loop, and it will again
  5973. * offer to reconnect the directory to /lost+found in to break the
  5974. * filesystem loop.
  5975. *
  5976. * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
  5977. * reconnect inodes to /lost+found; this subroutine is also used by
  5978. * pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which
  5979. * is responsible for creating /lost+found if it does not exist.
  5980. *
  5981. * Pass 3 frees the following data structures:
  5982. * - The dirinfo directory information cache.
  5983. */
  5984. static void check_root(e2fsck_t ctx);
  5985. static int check_directory(e2fsck_t ctx, struct dir_info *dir,
  5986. struct problem_context *pctx);
  5987. static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
  5988. static ext2fs_inode_bitmap inode_loop_detect;
  5989. static ext2fs_inode_bitmap inode_done_map;
  5990. static void e2fsck_pass3(e2fsck_t ctx)
  5991. {
  5992. ext2_filsys fs = ctx->fs;
  5993. int i;
  5994. struct problem_context pctx;
  5995. struct dir_info *dir;
  5996. unsigned long maxdirs, count;
  5997. clear_problem_context(&pctx);
  5998. /* Pass 3 */
  5999. if (!(ctx->options & E2F_OPT_PREEN))
  6000. fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
  6001. /*
  6002. * Allocate some bitmaps to do loop detection.
  6003. */
  6004. pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
  6005. &inode_done_map);
  6006. if (pctx.errcode) {
  6007. pctx.num = 2;
  6008. fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
  6009. ctx->flags |= E2F_FLAG_ABORT;
  6010. goto abort_exit;
  6011. }
  6012. check_root(ctx);
  6013. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  6014. goto abort_exit;
  6015. ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
  6016. maxdirs = e2fsck_get_num_dirinfo(ctx);
  6017. count = 1;
  6018. if (ctx->progress)
  6019. if ((ctx->progress)(ctx, 3, 0, maxdirs))
  6020. goto abort_exit;
  6021. for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
  6022. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  6023. goto abort_exit;
  6024. if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
  6025. goto abort_exit;
  6026. if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
  6027. if (check_directory(ctx, dir, &pctx))
  6028. goto abort_exit;
  6029. }
  6030. /*
  6031. * Force the creation of /lost+found if not present
  6032. */
  6033. if ((ctx->flags & E2F_OPT_READONLY) == 0)
  6034. e2fsck_get_lost_and_found(ctx, 1);
  6035. /*
  6036. * If there are any directories that need to be indexed or
  6037. * optimized, do it here.
  6038. */
  6039. e2fsck_rehash_directories(ctx);
  6040. abort_exit:
  6041. e2fsck_free_dir_info(ctx);
  6042. ext2fs_free_inode_bitmap(inode_loop_detect);
  6043. inode_loop_detect = 0;
  6044. ext2fs_free_inode_bitmap(inode_done_map);
  6045. inode_done_map = 0;
  6046. }
  6047. /*
  6048. * This makes sure the root inode is present; if not, we ask if the
  6049. * user wants us to create it. Not creating it is a fatal error.
  6050. */
  6051. static void check_root(e2fsck_t ctx)
  6052. {
  6053. ext2_filsys fs = ctx->fs;
  6054. blk_t blk;
  6055. struct ext2_inode inode;
  6056. char * block;
  6057. struct problem_context pctx;
  6058. clear_problem_context(&pctx);
  6059. if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
  6060. /*
  6061. * If the root inode is not a directory, die here. The
  6062. * user must have answered 'no' in pass1 when we
  6063. * offered to clear it.
  6064. */
  6065. if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
  6066. EXT2_ROOT_INO))) {
  6067. fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
  6068. ctx->flags |= E2F_FLAG_ABORT;
  6069. }
  6070. return;
  6071. }
  6072. if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
  6073. fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
  6074. ctx->flags |= E2F_FLAG_ABORT;
  6075. return;
  6076. }
  6077. e2fsck_read_bitmaps(ctx);
  6078. /*
  6079. * First, find a free block
  6080. */
  6081. pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
  6082. if (pctx.errcode) {
  6083. pctx.str = "ext2fs_new_block";
  6084. fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
  6085. ctx->flags |= E2F_FLAG_ABORT;
  6086. return;
  6087. }
  6088. ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
  6089. ext2fs_mark_block_bitmap(fs->block_map, blk);
  6090. ext2fs_mark_bb_dirty(fs);
  6091. /*
  6092. * Now let's create the actual data block for the inode
  6093. */
  6094. pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
  6095. &block);
  6096. if (pctx.errcode) {
  6097. pctx.str = "ext2fs_new_dir_block";
  6098. fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
  6099. ctx->flags |= E2F_FLAG_ABORT;
  6100. return;
  6101. }
  6102. pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
  6103. if (pctx.errcode) {
  6104. pctx.str = "ext2fs_write_dir_block";
  6105. fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
  6106. ctx->flags |= E2F_FLAG_ABORT;
  6107. return;
  6108. }
  6109. ext2fs_free_mem(&block);
  6110. /*
  6111. * Set up the inode structure
  6112. */
  6113. memset(&inode, 0, sizeof(inode));
  6114. inode.i_mode = 040755;
  6115. inode.i_size = fs->blocksize;
  6116. inode.i_atime = inode.i_ctime = inode.i_mtime = time(NULL);
  6117. inode.i_links_count = 2;
  6118. inode.i_blocks = fs->blocksize / 512;
  6119. inode.i_block[0] = blk;
  6120. /*
  6121. * Write out the inode.
  6122. */
  6123. pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
  6124. if (pctx.errcode) {
  6125. pctx.str = "ext2fs_write_inode";
  6126. fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
  6127. ctx->flags |= E2F_FLAG_ABORT;
  6128. return;
  6129. }
  6130. /*
  6131. * Miscellaneous bookkeeping...
  6132. */
  6133. e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
  6134. ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
  6135. ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
  6136. ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
  6137. ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
  6138. ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
  6139. ext2fs_mark_ib_dirty(fs);
  6140. }
  6141. /*
  6142. * This subroutine is responsible for making sure that a particular
  6143. * directory is connected to the root; if it isn't we trace it up as
  6144. * far as we can go, and then offer to connect the resulting parent to
  6145. * the lost+found. We have to do loop detection; if we ever discover
  6146. * a loop, we treat that as a disconnected directory and offer to
  6147. * reparent it to lost+found.
  6148. *
  6149. * However, loop detection is expensive, because for very large
  6150. * filesystems, the inode_loop_detect bitmap is huge, and clearing it
  6151. * is non-trivial. Loops in filesystems are also a rare error case,
  6152. * and we shouldn't optimize for error cases. So we try two passes of
  6153. * the algorithm. The first time, we ignore loop detection and merely
  6154. * increment a counter; if the counter exceeds some extreme threshold,
  6155. * then we try again with the loop detection bitmap enabled.
  6156. */
  6157. static int check_directory(e2fsck_t ctx, struct dir_info *dir,
  6158. struct problem_context *pctx)
  6159. {
  6160. ext2_filsys fs = ctx->fs;
  6161. struct dir_info *p = dir;
  6162. int loop_pass = 0, parent_count = 0;
  6163. if (!p)
  6164. return 0;
  6165. while (1) {
  6166. /*
  6167. * Mark this inode as being "done"; by the time we
  6168. * return from this function, the inode we either be
  6169. * verified as being connected to the directory tree,
  6170. * or we will have offered to reconnect this to
  6171. * lost+found.
  6172. *
  6173. * If it was marked done already, then we've reached a
  6174. * parent we've already checked.
  6175. */
  6176. if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
  6177. break;
  6178. /*
  6179. * If this directory doesn't have a parent, or we've
  6180. * seen the parent once already, then offer to
  6181. * reparent it to lost+found
  6182. */
  6183. if (!p->parent ||
  6184. (loop_pass &&
  6185. (ext2fs_test_inode_bitmap(inode_loop_detect,
  6186. p->parent)))) {
  6187. pctx->ino = p->ino;
  6188. if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
  6189. if (e2fsck_reconnect_file(ctx, pctx->ino))
  6190. ext2fs_unmark_valid(fs);
  6191. else {
  6192. p = e2fsck_get_dir_info(ctx, pctx->ino);
  6193. p->parent = ctx->lost_and_found;
  6194. fix_dotdot(ctx, p, ctx->lost_and_found);
  6195. }
  6196. }
  6197. break;
  6198. }
  6199. p = e2fsck_get_dir_info(ctx, p->parent);
  6200. if (!p) {
  6201. fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
  6202. return 0;
  6203. }
  6204. if (loop_pass) {
  6205. ext2fs_mark_inode_bitmap(inode_loop_detect,
  6206. p->ino);
  6207. } else if (parent_count++ > 2048) {
  6208. /*
  6209. * If we've run into a path depth that's
  6210. * greater than 2048, try again with the inode
  6211. * loop bitmap turned on and start from the
  6212. * top.
  6213. */
  6214. loop_pass = 1;
  6215. if (inode_loop_detect)
  6216. ext2fs_clear_inode_bitmap(inode_loop_detect);
  6217. else {
  6218. pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
  6219. if (pctx->errcode) {
  6220. pctx->num = 1;
  6221. fix_problem(ctx,
  6222. PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
  6223. ctx->flags |= E2F_FLAG_ABORT;
  6224. return -1;
  6225. }
  6226. }
  6227. p = dir;
  6228. }
  6229. }
  6230. /*
  6231. * Make sure that .. and the parent directory are the same;
  6232. * offer to fix it if not.
  6233. */
  6234. if (dir->parent != dir->dotdot) {
  6235. pctx->ino = dir->ino;
  6236. pctx->ino2 = dir->dotdot;
  6237. pctx->dir = dir->parent;
  6238. if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
  6239. fix_dotdot(ctx, dir, dir->parent);
  6240. }
  6241. return 0;
  6242. }
  6243. /*
  6244. * This routine gets the lost_and_found inode, making it a directory
  6245. * if necessary
  6246. */
  6247. ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
  6248. {
  6249. ext2_filsys fs = ctx->fs;
  6250. ext2_ino_t ino;
  6251. blk_t blk;
  6252. errcode_t retval;
  6253. struct ext2_inode inode;
  6254. char * block;
  6255. static const char name[] = "lost+found";
  6256. struct problem_context pctx;
  6257. struct dir_info *dirinfo;
  6258. if (ctx->lost_and_found)
  6259. return ctx->lost_and_found;
  6260. clear_problem_context(&pctx);
  6261. retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
  6262. sizeof(name)-1, 0, &ino);
  6263. if (retval && !fix)
  6264. return 0;
  6265. if (!retval) {
  6266. if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
  6267. ctx->lost_and_found = ino;
  6268. return ino;
  6269. }
  6270. /* Lost+found isn't a directory! */
  6271. if (!fix)
  6272. return 0;
  6273. pctx.ino = ino;
  6274. if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
  6275. return 0;
  6276. /* OK, unlink the old /lost+found file. */
  6277. pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
  6278. if (pctx.errcode) {
  6279. pctx.str = "ext2fs_unlink";
  6280. fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
  6281. return 0;
  6282. }
  6283. dirinfo = e2fsck_get_dir_info(ctx, ino);
  6284. if (dirinfo)
  6285. dirinfo->parent = 0;
  6286. e2fsck_adjust_inode_count(ctx, ino, -1);
  6287. } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
  6288. pctx.errcode = retval;
  6289. fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
  6290. }
  6291. if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
  6292. return 0;
  6293. /*
  6294. * Read the inode and block bitmaps in; we'll be messing with
  6295. * them.
  6296. */
  6297. e2fsck_read_bitmaps(ctx);
  6298. /*
  6299. * First, find a free block
  6300. */
  6301. retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
  6302. if (retval) {
  6303. pctx.errcode = retval;
  6304. fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
  6305. return 0;
  6306. }
  6307. ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
  6308. ext2fs_block_alloc_stats(fs, blk, +1);
  6309. /*
  6310. * Next find a free inode.
  6311. */
  6312. retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
  6313. ctx->inode_used_map, &ino);
  6314. if (retval) {
  6315. pctx.errcode = retval;
  6316. fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
  6317. return 0;
  6318. }
  6319. ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
  6320. ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
  6321. ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
  6322. /*
  6323. * Now let's create the actual data block for the inode
  6324. */
  6325. retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
  6326. if (retval) {
  6327. pctx.errcode = retval;
  6328. fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
  6329. return 0;
  6330. }
  6331. retval = ext2fs_write_dir_block(fs, blk, block);
  6332. ext2fs_free_mem(&block);
  6333. if (retval) {
  6334. pctx.errcode = retval;
  6335. fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
  6336. return 0;
  6337. }
  6338. /*
  6339. * Set up the inode structure
  6340. */
  6341. memset(&inode, 0, sizeof(inode));
  6342. inode.i_mode = 040700;
  6343. inode.i_size = fs->blocksize;
  6344. inode.i_atime = inode.i_ctime = inode.i_mtime = time(NULL);
  6345. inode.i_links_count = 2;
  6346. inode.i_blocks = fs->blocksize / 512;
  6347. inode.i_block[0] = blk;
  6348. /*
  6349. * Next, write out the inode.
  6350. */
  6351. pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
  6352. if (pctx.errcode) {
  6353. pctx.str = "ext2fs_write_inode";
  6354. fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
  6355. return 0;
  6356. }
  6357. /*
  6358. * Finally, create the directory link
  6359. */
  6360. pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
  6361. if (pctx.errcode) {
  6362. pctx.str = "ext2fs_link";
  6363. fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
  6364. return 0;
  6365. }
  6366. /*
  6367. * Miscellaneous bookkeeping that needs to be kept straight.
  6368. */
  6369. e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
  6370. e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
  6371. ext2fs_icount_store(ctx->inode_count, ino, 2);
  6372. ext2fs_icount_store(ctx->inode_link_info, ino, 2);
  6373. ctx->lost_and_found = ino;
  6374. return ino;
  6375. }
  6376. /*
  6377. * This routine will connect a file to lost+found
  6378. */
  6379. int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
  6380. {
  6381. ext2_filsys fs = ctx->fs;
  6382. errcode_t retval;
  6383. char name[80];
  6384. struct problem_context pctx;
  6385. struct ext2_inode inode;
  6386. int file_type = 0;
  6387. clear_problem_context(&pctx);
  6388. pctx.ino = ino;
  6389. if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
  6390. if (e2fsck_get_lost_and_found(ctx, 1) == 0)
  6391. ctx->bad_lost_and_found++;
  6392. }
  6393. if (ctx->bad_lost_and_found) {
  6394. fix_problem(ctx, PR_3_NO_LPF, &pctx);
  6395. return 1;
  6396. }
  6397. sprintf(name, "#%u", ino);
  6398. if (ext2fs_read_inode(fs, ino, &inode) == 0)
  6399. file_type = ext2_file_type(inode.i_mode);
  6400. retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
  6401. if (retval == EXT2_ET_DIR_NO_SPACE) {
  6402. if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
  6403. return 1;
  6404. retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
  6405. 1, 0);
  6406. if (retval) {
  6407. pctx.errcode = retval;
  6408. fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
  6409. return 1;
  6410. }
  6411. retval = ext2fs_link(fs, ctx->lost_and_found, name,
  6412. ino, file_type);
  6413. }
  6414. if (retval) {
  6415. pctx.errcode = retval;
  6416. fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
  6417. return 1;
  6418. }
  6419. e2fsck_adjust_inode_count(ctx, ino, 1);
  6420. return 0;
  6421. }
  6422. /*
  6423. * Utility routine to adjust the inode counts on an inode.
  6424. */
  6425. errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
  6426. {
  6427. ext2_filsys fs = ctx->fs;
  6428. errcode_t retval;
  6429. struct ext2_inode inode;
  6430. if (!ino)
  6431. return 0;
  6432. retval = ext2fs_read_inode(fs, ino, &inode);
  6433. if (retval)
  6434. return retval;
  6435. if (adj == 1) {
  6436. ext2fs_icount_increment(ctx->inode_count, ino, 0);
  6437. if (inode.i_links_count == (__u16) ~0)
  6438. return 0;
  6439. ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
  6440. inode.i_links_count++;
  6441. } else if (adj == -1) {
  6442. ext2fs_icount_decrement(ctx->inode_count, ino, 0);
  6443. if (inode.i_links_count == 0)
  6444. return 0;
  6445. ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
  6446. inode.i_links_count--;
  6447. }
  6448. retval = ext2fs_write_inode(fs, ino, &inode);
  6449. if (retval)
  6450. return retval;
  6451. return 0;
  6452. }
  6453. /*
  6454. * Fix parent --- this routine fixes up the parent of a directory.
  6455. */
  6456. struct fix_dotdot_struct {
  6457. ext2_filsys fs;
  6458. ext2_ino_t parent;
  6459. int done;
  6460. e2fsck_t ctx;
  6461. };
  6462. static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
  6463. int offset FSCK_ATTR((unused)),
  6464. int blocksize FSCK_ATTR((unused)),
  6465. char *buf FSCK_ATTR((unused)),
  6466. void *priv_data)
  6467. {
  6468. struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
  6469. errcode_t retval;
  6470. struct problem_context pctx;
  6471. if ((dirent->name_len & 0xFF) != 2)
  6472. return 0;
  6473. if (strncmp(dirent->name, "..", 2))
  6474. return 0;
  6475. clear_problem_context(&pctx);
  6476. retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
  6477. if (retval) {
  6478. pctx.errcode = retval;
  6479. fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
  6480. }
  6481. retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
  6482. if (retval) {
  6483. pctx.errcode = retval;
  6484. fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
  6485. }
  6486. dirent->inode = fp->parent;
  6487. fp->done++;
  6488. return DIRENT_ABORT | DIRENT_CHANGED;
  6489. }
  6490. static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
  6491. {
  6492. ext2_filsys fs = ctx->fs;
  6493. errcode_t retval;
  6494. struct fix_dotdot_struct fp;
  6495. struct problem_context pctx;
  6496. fp.fs = fs;
  6497. fp.parent = parent;
  6498. fp.done = 0;
  6499. fp.ctx = ctx;
  6500. retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
  6501. 0, fix_dotdot_proc, &fp);
  6502. if (retval || !fp.done) {
  6503. clear_problem_context(&pctx);
  6504. pctx.ino = dir->ino;
  6505. pctx.errcode = retval;
  6506. fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
  6507. PR_3_FIX_PARENT_NOFIND, &pctx);
  6508. ext2fs_unmark_valid(fs);
  6509. }
  6510. dir->dotdot = parent;
  6511. }
  6512. /*
  6513. * These routines are responsible for expanding a /lost+found if it is
  6514. * too small.
  6515. */
  6516. struct expand_dir_struct {
  6517. int num;
  6518. int guaranteed_size;
  6519. int newblocks;
  6520. int last_block;
  6521. errcode_t err;
  6522. e2fsck_t ctx;
  6523. };
  6524. static int expand_dir_proc(ext2_filsys fs,
  6525. blk_t *blocknr,
  6526. e2_blkcnt_t blockcnt,
  6527. blk_t ref_block FSCK_ATTR((unused)),
  6528. int ref_offset FSCK_ATTR((unused)),
  6529. void *priv_data)
  6530. {
  6531. struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
  6532. blk_t new_blk;
  6533. static blk_t last_blk = 0;
  6534. char *block;
  6535. errcode_t retval;
  6536. e2fsck_t ctx;
  6537. ctx = es->ctx;
  6538. if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
  6539. return BLOCK_ABORT;
  6540. if (blockcnt > 0)
  6541. es->last_block = blockcnt;
  6542. if (*blocknr) {
  6543. last_blk = *blocknr;
  6544. return 0;
  6545. }
  6546. retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
  6547. &new_blk);
  6548. if (retval) {
  6549. es->err = retval;
  6550. return BLOCK_ABORT;
  6551. }
  6552. if (blockcnt > 0) {
  6553. retval = ext2fs_new_dir_block(fs, 0, 0, &block);
  6554. if (retval) {
  6555. es->err = retval;
  6556. return BLOCK_ABORT;
  6557. }
  6558. es->num--;
  6559. retval = ext2fs_write_dir_block(fs, new_blk, block);
  6560. } else {
  6561. retval = ext2fs_get_mem(fs->blocksize, &block);
  6562. if (retval) {
  6563. es->err = retval;
  6564. return BLOCK_ABORT;
  6565. }
  6566. memset(block, 0, fs->blocksize);
  6567. retval = io_channel_write_blk(fs->io, new_blk, 1, block);
  6568. }
  6569. if (retval) {
  6570. es->err = retval;
  6571. return BLOCK_ABORT;
  6572. }
  6573. ext2fs_free_mem(&block);
  6574. *blocknr = new_blk;
  6575. ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
  6576. ext2fs_block_alloc_stats(fs, new_blk, +1);
  6577. es->newblocks++;
  6578. if (es->num == 0)
  6579. return (BLOCK_CHANGED | BLOCK_ABORT);
  6580. else
  6581. return BLOCK_CHANGED;
  6582. }
  6583. errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
  6584. int num, int guaranteed_size)
  6585. {
  6586. ext2_filsys fs = ctx->fs;
  6587. errcode_t retval;
  6588. struct expand_dir_struct es;
  6589. struct ext2_inode inode;
  6590. if (!(fs->flags & EXT2_FLAG_RW))
  6591. return EXT2_ET_RO_FILSYS;
  6592. /*
  6593. * Read the inode and block bitmaps in; we'll be messing with
  6594. * them.
  6595. */
  6596. e2fsck_read_bitmaps(ctx);
  6597. retval = ext2fs_check_directory(fs, dir);
  6598. if (retval)
  6599. return retval;
  6600. es.num = num;
  6601. es.guaranteed_size = guaranteed_size;
  6602. es.last_block = 0;
  6603. es.err = 0;
  6604. es.newblocks = 0;
  6605. es.ctx = ctx;
  6606. retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
  6607. 0, expand_dir_proc, &es);
  6608. if (es.err)
  6609. return es.err;
  6610. /*
  6611. * Update the size and block count fields in the inode.
  6612. */
  6613. retval = ext2fs_read_inode(fs, dir, &inode);
  6614. if (retval)
  6615. return retval;
  6616. inode.i_size = (es.last_block + 1) * fs->blocksize;
  6617. inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
  6618. e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
  6619. return 0;
  6620. }
  6621. /*
  6622. * pass4.c -- pass #4 of e2fsck: Check reference counts
  6623. *
  6624. * Pass 4 frees the following data structures:
  6625. * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
  6626. */
  6627. /*
  6628. * This routine is called when an inode is not connected to the
  6629. * directory tree.
  6630. *
  6631. * This subroutine returns 1 then the caller shouldn't bother with the
  6632. * rest of the pass 4 tests.
  6633. */
  6634. static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
  6635. {
  6636. ext2_filsys fs = ctx->fs;
  6637. struct ext2_inode inode;
  6638. struct problem_context pctx;
  6639. e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
  6640. clear_problem_context(&pctx);
  6641. pctx.ino = i;
  6642. pctx.inode = &inode;
  6643. /*
  6644. * Offer to delete any zero-length files that does not have
  6645. * blocks. If there is an EA block, it might have useful
  6646. * information, so we won't prompt to delete it, but let it be
  6647. * reconnected to lost+found.
  6648. */
  6649. if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
  6650. LINUX_S_ISDIR(inode.i_mode))) {
  6651. if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
  6652. ext2fs_icount_store(ctx->inode_link_info, i, 0);
  6653. inode.i_links_count = 0;
  6654. inode.i_dtime = time(NULL);
  6655. e2fsck_write_inode(ctx, i, &inode,
  6656. "disconnect_inode");
  6657. /*
  6658. * Fix up the bitmaps...
  6659. */
  6660. e2fsck_read_bitmaps(ctx);
  6661. ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
  6662. ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
  6663. ext2fs_inode_alloc_stats2(fs, i, -1,
  6664. LINUX_S_ISDIR(inode.i_mode));
  6665. return 0;
  6666. }
  6667. }
  6668. /*
  6669. * Prompt to reconnect.
  6670. */
  6671. if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
  6672. if (e2fsck_reconnect_file(ctx, i))
  6673. ext2fs_unmark_valid(fs);
  6674. } else {
  6675. /*
  6676. * If we don't attach the inode, then skip the
  6677. * i_links_test since there's no point in trying to
  6678. * force i_links_count to zero.
  6679. */
  6680. ext2fs_unmark_valid(fs);
  6681. return 1;
  6682. }
  6683. return 0;
  6684. }
  6685. static void e2fsck_pass4(e2fsck_t ctx)
  6686. {
  6687. ext2_filsys fs = ctx->fs;
  6688. ext2_ino_t i;
  6689. struct ext2_inode inode;
  6690. struct problem_context pctx;
  6691. __u16 link_count, link_counted;
  6692. char *buf = NULL;
  6693. int group, maxgroup;
  6694. /* Pass 4 */
  6695. clear_problem_context(&pctx);
  6696. if (!(ctx->options & E2F_OPT_PREEN))
  6697. fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
  6698. group = 0;
  6699. maxgroup = fs->group_desc_count;
  6700. if (ctx->progress)
  6701. if ((ctx->progress)(ctx, 4, 0, maxgroup))
  6702. return;
  6703. for (i=1; i <= fs->super->s_inodes_count; i++) {
  6704. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  6705. return;
  6706. if ((i % fs->super->s_inodes_per_group) == 0) {
  6707. group++;
  6708. if (ctx->progress)
  6709. if ((ctx->progress)(ctx, 4, group, maxgroup))
  6710. return;
  6711. }
  6712. if (i == EXT2_BAD_INO ||
  6713. (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
  6714. continue;
  6715. if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
  6716. (ctx->inode_imagic_map &&
  6717. ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)))
  6718. continue;
  6719. ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
  6720. ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
  6721. if (link_counted == 0) {
  6722. if (!buf)
  6723. buf = e2fsck_allocate_memory(ctx,
  6724. fs->blocksize, "bad_inode buffer");
  6725. if (e2fsck_process_bad_inode(ctx, 0, i, buf))
  6726. continue;
  6727. if (disconnect_inode(ctx, i))
  6728. continue;
  6729. ext2fs_icount_fetch(ctx->inode_link_info, i,
  6730. &link_count);
  6731. ext2fs_icount_fetch(ctx->inode_count, i,
  6732. &link_counted);
  6733. }
  6734. if (link_counted != link_count) {
  6735. e2fsck_read_inode(ctx, i, &inode, "pass4");
  6736. pctx.ino = i;
  6737. pctx.inode = &inode;
  6738. if (link_count != inode.i_links_count) {
  6739. pctx.num = link_count;
  6740. fix_problem(ctx,
  6741. PR_4_INCONSISTENT_COUNT, &pctx);
  6742. }
  6743. pctx.num = link_counted;
  6744. if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
  6745. inode.i_links_count = link_counted;
  6746. e2fsck_write_inode(ctx, i, &inode, "pass4");
  6747. }
  6748. }
  6749. }
  6750. ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
  6751. ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
  6752. ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
  6753. ctx->inode_imagic_map = 0;
  6754. ext2fs_free_mem(&buf);
  6755. }
  6756. /*
  6757. * pass5.c --- check block and inode bitmaps against on-disk bitmaps
  6758. */
  6759. #define NO_BLK ((blk_t) -1)
  6760. static void print_bitmap_problem(e2fsck_t ctx, int problem,
  6761. struct problem_context *pctx)
  6762. {
  6763. switch (problem) {
  6764. case PR_5_BLOCK_UNUSED:
  6765. if (pctx->blk == pctx->blk2)
  6766. pctx->blk2 = 0;
  6767. else
  6768. problem = PR_5_BLOCK_RANGE_UNUSED;
  6769. break;
  6770. case PR_5_BLOCK_USED:
  6771. if (pctx->blk == pctx->blk2)
  6772. pctx->blk2 = 0;
  6773. else
  6774. problem = PR_5_BLOCK_RANGE_USED;
  6775. break;
  6776. case PR_5_INODE_UNUSED:
  6777. if (pctx->ino == pctx->ino2)
  6778. pctx->ino2 = 0;
  6779. else
  6780. problem = PR_5_INODE_RANGE_UNUSED;
  6781. break;
  6782. case PR_5_INODE_USED:
  6783. if (pctx->ino == pctx->ino2)
  6784. pctx->ino2 = 0;
  6785. else
  6786. problem = PR_5_INODE_RANGE_USED;
  6787. break;
  6788. }
  6789. fix_problem(ctx, problem, pctx);
  6790. pctx->blk = pctx->blk2 = NO_BLK;
  6791. pctx->ino = pctx->ino2 = 0;
  6792. }
  6793. static void check_block_bitmaps(e2fsck_t ctx)
  6794. {
  6795. ext2_filsys fs = ctx->fs;
  6796. blk_t i;
  6797. int *free_array;
  6798. int group = 0;
  6799. unsigned int blocks = 0;
  6800. unsigned int free_blocks = 0;
  6801. int group_free = 0;
  6802. int actual, bitmap;
  6803. struct problem_context pctx;
  6804. int problem, save_problem, fixit, had_problem;
  6805. errcode_t retval;
  6806. clear_problem_context(&pctx);
  6807. free_array = (int *) e2fsck_allocate_memory(ctx,
  6808. fs->group_desc_count * sizeof(int), "free block count array");
  6809. if ((fs->super->s_first_data_block <
  6810. ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
  6811. (fs->super->s_blocks_count-1 >
  6812. ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
  6813. pctx.num = 1;
  6814. pctx.blk = fs->super->s_first_data_block;
  6815. pctx.blk2 = fs->super->s_blocks_count -1;
  6816. pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
  6817. pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
  6818. fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
  6819. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  6820. return;
  6821. }
  6822. if ((fs->super->s_first_data_block <
  6823. ext2fs_get_block_bitmap_start(fs->block_map)) ||
  6824. (fs->super->s_blocks_count-1 >
  6825. ext2fs_get_block_bitmap_end(fs->block_map))) {
  6826. pctx.num = 2;
  6827. pctx.blk = fs->super->s_first_data_block;
  6828. pctx.blk2 = fs->super->s_blocks_count -1;
  6829. pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
  6830. pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
  6831. fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
  6832. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  6833. return;
  6834. }
  6835. redo_counts:
  6836. had_problem = 0;
  6837. save_problem = 0;
  6838. pctx.blk = pctx.blk2 = NO_BLK;
  6839. for (i = fs->super->s_first_data_block;
  6840. i < fs->super->s_blocks_count;
  6841. i++) {
  6842. actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
  6843. bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
  6844. if (actual == bitmap)
  6845. goto do_counts;
  6846. if (!actual && bitmap) {
  6847. /*
  6848. * Block not used, but marked in use in the bitmap.
  6849. */
  6850. problem = PR_5_BLOCK_UNUSED;
  6851. } else {
  6852. /*
  6853. * Block used, but not marked in use in the bitmap.
  6854. */
  6855. problem = PR_5_BLOCK_USED;
  6856. }
  6857. if (pctx.blk == NO_BLK) {
  6858. pctx.blk = pctx.blk2 = i;
  6859. save_problem = problem;
  6860. } else {
  6861. if ((problem == save_problem) &&
  6862. (pctx.blk2 == i-1))
  6863. pctx.blk2++;
  6864. else {
  6865. print_bitmap_problem(ctx, save_problem, &pctx);
  6866. pctx.blk = pctx.blk2 = i;
  6867. save_problem = problem;
  6868. }
  6869. }
  6870. ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
  6871. had_problem++;
  6872. do_counts:
  6873. if (!bitmap) {
  6874. group_free++;
  6875. free_blocks++;
  6876. }
  6877. blocks ++;
  6878. if ((blocks == fs->super->s_blocks_per_group) ||
  6879. (i == fs->super->s_blocks_count-1)) {
  6880. free_array[group] = group_free;
  6881. group ++;
  6882. blocks = 0;
  6883. group_free = 0;
  6884. if (ctx->progress)
  6885. if ((ctx->progress)(ctx, 5, group,
  6886. fs->group_desc_count*2))
  6887. return;
  6888. }
  6889. }
  6890. if (pctx.blk != NO_BLK)
  6891. print_bitmap_problem(ctx, save_problem, &pctx);
  6892. if (had_problem)
  6893. fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
  6894. else
  6895. fixit = -1;
  6896. ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
  6897. if (fixit == 1) {
  6898. ext2fs_free_block_bitmap(fs->block_map);
  6899. retval = ext2fs_copy_bitmap(ctx->block_found_map,
  6900. &fs->block_map);
  6901. if (retval) {
  6902. clear_problem_context(&pctx);
  6903. fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
  6904. ctx->flags |= E2F_FLAG_ABORT;
  6905. return;
  6906. }
  6907. ext2fs_set_bitmap_padding(fs->block_map);
  6908. ext2fs_mark_bb_dirty(fs);
  6909. /* Redo the counts */
  6910. blocks = 0; free_blocks = 0; group_free = 0; group = 0;
  6911. memset(free_array, 0, fs->group_desc_count * sizeof(int));
  6912. goto redo_counts;
  6913. } else if (fixit == 0)
  6914. ext2fs_unmark_valid(fs);
  6915. for (i = 0; i < fs->group_desc_count; i++) {
  6916. if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
  6917. pctx.group = i;
  6918. pctx.blk = fs->group_desc[i].bg_free_blocks_count;
  6919. pctx.blk2 = free_array[i];
  6920. if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
  6921. &pctx)) {
  6922. fs->group_desc[i].bg_free_blocks_count =
  6923. free_array[i];
  6924. ext2fs_mark_super_dirty(fs);
  6925. } else
  6926. ext2fs_unmark_valid(fs);
  6927. }
  6928. }
  6929. if (free_blocks != fs->super->s_free_blocks_count) {
  6930. pctx.group = 0;
  6931. pctx.blk = fs->super->s_free_blocks_count;
  6932. pctx.blk2 = free_blocks;
  6933. if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
  6934. fs->super->s_free_blocks_count = free_blocks;
  6935. ext2fs_mark_super_dirty(fs);
  6936. } else
  6937. ext2fs_unmark_valid(fs);
  6938. }
  6939. ext2fs_free_mem(&free_array);
  6940. }
  6941. static void check_inode_bitmaps(e2fsck_t ctx)
  6942. {
  6943. ext2_filsys fs = ctx->fs;
  6944. ext2_ino_t i;
  6945. unsigned int free_inodes = 0;
  6946. int group_free = 0;
  6947. int dirs_count = 0;
  6948. int group = 0;
  6949. unsigned int inodes = 0;
  6950. int *free_array;
  6951. int *dir_array;
  6952. int actual, bitmap;
  6953. errcode_t retval;
  6954. struct problem_context pctx;
  6955. int problem, save_problem, fixit, had_problem;
  6956. clear_problem_context(&pctx);
  6957. free_array = (int *) e2fsck_allocate_memory(ctx,
  6958. fs->group_desc_count * sizeof(int), "free inode count array");
  6959. dir_array = (int *) e2fsck_allocate_memory(ctx,
  6960. fs->group_desc_count * sizeof(int), "directory count array");
  6961. if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
  6962. (fs->super->s_inodes_count >
  6963. ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
  6964. pctx.num = 3;
  6965. pctx.blk = 1;
  6966. pctx.blk2 = fs->super->s_inodes_count;
  6967. pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
  6968. pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
  6969. fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
  6970. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  6971. return;
  6972. }
  6973. if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
  6974. (fs->super->s_inodes_count >
  6975. ext2fs_get_inode_bitmap_end(fs->inode_map))) {
  6976. pctx.num = 4;
  6977. pctx.blk = 1;
  6978. pctx.blk2 = fs->super->s_inodes_count;
  6979. pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
  6980. pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
  6981. fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
  6982. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  6983. return;
  6984. }
  6985. redo_counts:
  6986. had_problem = 0;
  6987. save_problem = 0;
  6988. pctx.ino = pctx.ino2 = 0;
  6989. for (i = 1; i <= fs->super->s_inodes_count; i++) {
  6990. actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
  6991. bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
  6992. if (actual == bitmap)
  6993. goto do_counts;
  6994. if (!actual && bitmap) {
  6995. /*
  6996. * Inode wasn't used, but marked in bitmap
  6997. */
  6998. problem = PR_5_INODE_UNUSED;
  6999. } else /* if (actual && !bitmap) */ {
  7000. /*
  7001. * Inode used, but not in bitmap
  7002. */
  7003. problem = PR_5_INODE_USED;
  7004. }
  7005. if (pctx.ino == 0) {
  7006. pctx.ino = pctx.ino2 = i;
  7007. save_problem = problem;
  7008. } else {
  7009. if ((problem == save_problem) &&
  7010. (pctx.ino2 == i-1))
  7011. pctx.ino2++;
  7012. else {
  7013. print_bitmap_problem(ctx, save_problem, &pctx);
  7014. pctx.ino = pctx.ino2 = i;
  7015. save_problem = problem;
  7016. }
  7017. }
  7018. ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
  7019. had_problem++;
  7020. do_counts:
  7021. if (!bitmap) {
  7022. group_free++;
  7023. free_inodes++;
  7024. } else {
  7025. if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
  7026. dirs_count++;
  7027. }
  7028. inodes++;
  7029. if ((inodes == fs->super->s_inodes_per_group) ||
  7030. (i == fs->super->s_inodes_count)) {
  7031. free_array[group] = group_free;
  7032. dir_array[group] = dirs_count;
  7033. group ++;
  7034. inodes = 0;
  7035. group_free = 0;
  7036. dirs_count = 0;
  7037. if (ctx->progress)
  7038. if ((ctx->progress)(ctx, 5,
  7039. group + fs->group_desc_count,
  7040. fs->group_desc_count*2))
  7041. return;
  7042. }
  7043. }
  7044. if (pctx.ino)
  7045. print_bitmap_problem(ctx, save_problem, &pctx);
  7046. if (had_problem)
  7047. fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
  7048. else
  7049. fixit = -1;
  7050. ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
  7051. if (fixit == 1) {
  7052. ext2fs_free_inode_bitmap(fs->inode_map);
  7053. retval = ext2fs_copy_bitmap(ctx->inode_used_map,
  7054. &fs->inode_map);
  7055. if (retval) {
  7056. clear_problem_context(&pctx);
  7057. fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
  7058. ctx->flags |= E2F_FLAG_ABORT;
  7059. return;
  7060. }
  7061. ext2fs_set_bitmap_padding(fs->inode_map);
  7062. ext2fs_mark_ib_dirty(fs);
  7063. /* redo counts */
  7064. inodes = 0; free_inodes = 0; group_free = 0;
  7065. dirs_count = 0; group = 0;
  7066. memset(free_array, 0, fs->group_desc_count * sizeof(int));
  7067. memset(dir_array, 0, fs->group_desc_count * sizeof(int));
  7068. goto redo_counts;
  7069. } else if (fixit == 0)
  7070. ext2fs_unmark_valid(fs);
  7071. for (i = 0; i < fs->group_desc_count; i++) {
  7072. if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
  7073. pctx.group = i;
  7074. pctx.ino = fs->group_desc[i].bg_free_inodes_count;
  7075. pctx.ino2 = free_array[i];
  7076. if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
  7077. &pctx)) {
  7078. fs->group_desc[i].bg_free_inodes_count =
  7079. free_array[i];
  7080. ext2fs_mark_super_dirty(fs);
  7081. } else
  7082. ext2fs_unmark_valid(fs);
  7083. }
  7084. if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
  7085. pctx.group = i;
  7086. pctx.ino = fs->group_desc[i].bg_used_dirs_count;
  7087. pctx.ino2 = dir_array[i];
  7088. if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
  7089. &pctx)) {
  7090. fs->group_desc[i].bg_used_dirs_count =
  7091. dir_array[i];
  7092. ext2fs_mark_super_dirty(fs);
  7093. } else
  7094. ext2fs_unmark_valid(fs);
  7095. }
  7096. }
  7097. if (free_inodes != fs->super->s_free_inodes_count) {
  7098. pctx.group = -1;
  7099. pctx.ino = fs->super->s_free_inodes_count;
  7100. pctx.ino2 = free_inodes;
  7101. if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
  7102. fs->super->s_free_inodes_count = free_inodes;
  7103. ext2fs_mark_super_dirty(fs);
  7104. } else
  7105. ext2fs_unmark_valid(fs);
  7106. }
  7107. ext2fs_free_mem(&free_array);
  7108. ext2fs_free_mem(&dir_array);
  7109. }
  7110. static void check_inode_end(e2fsck_t ctx)
  7111. {
  7112. ext2_filsys fs = ctx->fs;
  7113. ext2_ino_t end, save_inodes_count, i;
  7114. struct problem_context pctx;
  7115. clear_problem_context(&pctx);
  7116. end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
  7117. pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
  7118. &save_inodes_count);
  7119. if (pctx.errcode) {
  7120. pctx.num = 1;
  7121. fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
  7122. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  7123. return;
  7124. }
  7125. if (save_inodes_count == end)
  7126. return;
  7127. for (i = save_inodes_count + 1; i <= end; i++) {
  7128. if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
  7129. if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
  7130. for (i = save_inodes_count + 1; i <= end; i++)
  7131. ext2fs_mark_inode_bitmap(fs->inode_map,
  7132. i);
  7133. ext2fs_mark_ib_dirty(fs);
  7134. } else
  7135. ext2fs_unmark_valid(fs);
  7136. break;
  7137. }
  7138. }
  7139. pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
  7140. save_inodes_count, 0);
  7141. if (pctx.errcode) {
  7142. pctx.num = 2;
  7143. fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
  7144. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  7145. return;
  7146. }
  7147. }
  7148. static void check_block_end(e2fsck_t ctx)
  7149. {
  7150. ext2_filsys fs = ctx->fs;
  7151. blk_t end, save_blocks_count, i;
  7152. struct problem_context pctx;
  7153. clear_problem_context(&pctx);
  7154. end = fs->block_map->start +
  7155. (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
  7156. pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
  7157. &save_blocks_count);
  7158. if (pctx.errcode) {
  7159. pctx.num = 3;
  7160. fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
  7161. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  7162. return;
  7163. }
  7164. if (save_blocks_count == end)
  7165. return;
  7166. for (i = save_blocks_count + 1; i <= end; i++) {
  7167. if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
  7168. if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
  7169. for (i = save_blocks_count + 1; i <= end; i++)
  7170. ext2fs_mark_block_bitmap(fs->block_map,
  7171. i);
  7172. ext2fs_mark_bb_dirty(fs);
  7173. } else
  7174. ext2fs_unmark_valid(fs);
  7175. break;
  7176. }
  7177. }
  7178. pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
  7179. save_blocks_count, 0);
  7180. if (pctx.errcode) {
  7181. pctx.num = 4;
  7182. fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
  7183. ctx->flags |= E2F_FLAG_ABORT; /* fatal */
  7184. return;
  7185. }
  7186. }
  7187. static void e2fsck_pass5(e2fsck_t ctx)
  7188. {
  7189. struct problem_context pctx;
  7190. /* Pass 5 */
  7191. clear_problem_context(&pctx);
  7192. if (!(ctx->options & E2F_OPT_PREEN))
  7193. fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
  7194. if (ctx->progress)
  7195. if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
  7196. return;
  7197. e2fsck_read_bitmaps(ctx);
  7198. check_block_bitmaps(ctx);
  7199. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  7200. return;
  7201. check_inode_bitmaps(ctx);
  7202. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  7203. return;
  7204. check_inode_end(ctx);
  7205. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  7206. return;
  7207. check_block_end(ctx);
  7208. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  7209. return;
  7210. ext2fs_free_inode_bitmap(ctx->inode_used_map);
  7211. ctx->inode_used_map = 0;
  7212. ext2fs_free_inode_bitmap(ctx->inode_dir_map);
  7213. ctx->inode_dir_map = 0;
  7214. ext2fs_free_block_bitmap(ctx->block_found_map);
  7215. ctx->block_found_map = 0;
  7216. }
  7217. /*
  7218. * problem.c --- report filesystem problems to the user
  7219. */
  7220. #define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */
  7221. #define PR_NO_OK 0x000002 /* If user answers no, don't make fs invalid */
  7222. #define PR_NO_DEFAULT 0x000004 /* Default to no */
  7223. #define PR_MSG_ONLY 0x000008 /* Print message only */
  7224. /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
  7225. #define PR_FATAL 0x001000 /* Fatal error */
  7226. #define PR_AFTER_CODE 0x002000 /* After asking the first question, */
  7227. /* ask another */
  7228. #define PR_PREEN_NOMSG 0x004000 /* Don't print a message if we're preening */
  7229. #define PR_NOCOLLATE 0x008000 /* Don't collate answers for this latch */
  7230. #define PR_NO_NOMSG 0x010000 /* Don't print a message if e2fsck -n */
  7231. #define PR_PREEN_NO 0x020000 /* Use No as an answer if preening */
  7232. #define PR_PREEN_NOHDR 0x040000 /* Don't print the preen header */
  7233. #define PROMPT_NONE 0
  7234. #define PROMPT_FIX 1
  7235. #define PROMPT_CLEAR 2
  7236. #define PROMPT_RELOCATE 3
  7237. #define PROMPT_ALLOCATE 4
  7238. #define PROMPT_EXPAND 5
  7239. #define PROMPT_CONNECT 6
  7240. #define PROMPT_CREATE 7
  7241. #define PROMPT_SALVAGE 8
  7242. #define PROMPT_TRUNCATE 9
  7243. #define PROMPT_CLEAR_INODE 10
  7244. #define PROMPT_ABORT 11
  7245. #define PROMPT_SPLIT 12
  7246. #define PROMPT_CONTINUE 13
  7247. #define PROMPT_CLONE 14
  7248. #define PROMPT_DELETE 15
  7249. #define PROMPT_SUPPRESS 16
  7250. #define PROMPT_UNLINK 17
  7251. #define PROMPT_CLEAR_HTREE 18
  7252. #define PROMPT_RECREATE 19
  7253. #define PROMPT_NULL 20
  7254. struct e2fsck_problem {
  7255. problem_t e2p_code;
  7256. const char * e2p_description;
  7257. char prompt;
  7258. int flags;
  7259. problem_t second_code;
  7260. };
  7261. struct latch_descr {
  7262. int latch_code;
  7263. problem_t question;
  7264. problem_t end_message;
  7265. int flags;
  7266. };
  7267. /*
  7268. * These are the prompts which are used to ask the user if they want
  7269. * to fix a problem.
  7270. */
  7271. static const char *const prompt[] = {
  7272. N_("(no prompt)"), /* 0 */
  7273. N_("Fix"), /* 1 */
  7274. N_("Clear"), /* 2 */
  7275. N_("Relocate"), /* 3 */
  7276. N_("Allocate"), /* 4 */
  7277. N_("Expand"), /* 5 */
  7278. N_("Connect to /lost+found"), /* 6 */
  7279. N_("Create"), /* 7 */
  7280. N_("Salvage"), /* 8 */
  7281. N_("Truncate"), /* 9 */
  7282. N_("Clear inode"), /* 10 */
  7283. N_("Abort"), /* 11 */
  7284. N_("Split"), /* 12 */
  7285. N_("Continue"), /* 13 */
  7286. N_("Clone multiply-claimed blocks"), /* 14 */
  7287. N_("Delete file"), /* 15 */
  7288. N_("Suppress messages"),/* 16 */
  7289. N_("Unlink"), /* 17 */
  7290. N_("Clear HTree index"),/* 18 */
  7291. N_("Recreate"), /* 19 */
  7292. "", /* 20 */
  7293. };
  7294. /*
  7295. * These messages are printed when we are preen mode and we will be
  7296. * automatically fixing the problem.
  7297. */
  7298. static const char *const preen_msg[] = {
  7299. N_("(NONE)"), /* 0 */
  7300. N_("FIXED"), /* 1 */
  7301. N_("CLEARED"), /* 2 */
  7302. N_("RELOCATED"), /* 3 */
  7303. N_("ALLOCATED"), /* 4 */
  7304. N_("EXPANDED"), /* 5 */
  7305. N_("RECONNECTED"), /* 6 */
  7306. N_("CREATED"), /* 7 */
  7307. N_("SALVAGED"), /* 8 */
  7308. N_("TRUNCATED"), /* 9 */
  7309. N_("INODE CLEARED"), /* 10 */
  7310. N_("ABORTED"), /* 11 */
  7311. N_("SPLIT"), /* 12 */
  7312. N_("CONTINUING"), /* 13 */
  7313. N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
  7314. N_("FILE DELETED"), /* 15 */
  7315. N_("SUPPRESSED"), /* 16 */
  7316. N_("UNLINKED"), /* 17 */
  7317. N_("HTREE INDEX CLEARED"),/* 18 */
  7318. N_("WILL RECREATE"), /* 19 */
  7319. "", /* 20 */
  7320. };
  7321. static const struct e2fsck_problem problem_table[] = {
  7322. /* Pre-Pass 1 errors */
  7323. /* Block bitmap not in group */
  7324. { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
  7325. PROMPT_RELOCATE, PR_LATCH_RELOC },
  7326. /* Inode bitmap not in group */
  7327. { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
  7328. PROMPT_RELOCATE, PR_LATCH_RELOC },
  7329. /* Inode table not in group */
  7330. { PR_0_ITABLE_NOT_GROUP,
  7331. N_("@i table for @g %g is not in @g. (@b %b)\n"
  7332. "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
  7333. PROMPT_RELOCATE, PR_LATCH_RELOC },
  7334. /* Superblock corrupt */
  7335. { PR_0_SB_CORRUPT,
  7336. N_("\nThe @S could not be read or does not describe a correct ext2\n"
  7337. "@f. If the @v is valid and it really contains an ext2\n"
  7338. "@f (and not swap or ufs or something else), then the @S\n"
  7339. "is corrupt, and you might try running e2fsck with an alternate @S:\n"
  7340. " e2fsck -b %S <@v>\n\n"),
  7341. PROMPT_NONE, PR_FATAL },
  7342. /* Filesystem size is wrong */
  7343. { PR_0_FS_SIZE_WRONG,
  7344. N_("The @f size (according to the @S) is %b @bs\n"
  7345. "The physical size of the @v is %c @bs\n"
  7346. "Either the @S or the partition table is likely to be corrupt!\n"),
  7347. PROMPT_ABORT, 0 },
  7348. /* Fragments not supported */
  7349. { PR_0_NO_FRAGMENTS,
  7350. N_("@S @b_size = %b, fragsize = %c.\n"
  7351. "This version of e2fsck does not support fragment sizes different\n"
  7352. "from the @b size.\n"),
  7353. PROMPT_NONE, PR_FATAL },
  7354. /* Bad blocks_per_group */
  7355. { PR_0_BLOCKS_PER_GROUP,
  7356. N_("@S @bs_per_group = %b, should have been %c\n"),
  7357. PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
  7358. /* Bad first_data_block */
  7359. { PR_0_FIRST_DATA_BLOCK,
  7360. N_("@S first_data_@b = %b, should have been %c\n"),
  7361. PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
  7362. /* Adding UUID to filesystem */
  7363. { PR_0_ADD_UUID,
  7364. N_("@f did not have a UUID; generating one.\n\n"),
  7365. PROMPT_NONE, 0 },
  7366. /* Relocate hint */
  7367. { PR_0_RELOCATE_HINT,
  7368. N_("Note: if several inode or block bitmap blocks or part\n"
  7369. "of the inode table require relocation, you may wish to try\n"
  7370. "running e2fsck with the '-b %S' option first. The problem\n"
  7371. "may lie only with the primary block group descriptors, and\n"
  7372. "the backup block group descriptors may be OK.\n\n"),
  7373. PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
  7374. /* Miscellaneous superblock corruption */
  7375. { PR_0_MISC_CORRUPT_SUPER,
  7376. N_("Corruption found in @S. (%s = %N).\n"),
  7377. PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
  7378. /* Error determing physical device size of filesystem */
  7379. { PR_0_GETSIZE_ERROR,
  7380. N_("Error determining size of the physical @v: %m\n"),
  7381. PROMPT_NONE, PR_FATAL },
  7382. /* Inode count in superblock is incorrect */
  7383. { PR_0_INODE_COUNT_WRONG,
  7384. N_("@i count in @S is %i, @s %j.\n"),
  7385. PROMPT_FIX, 0 },
  7386. { PR_0_HURD_CLEAR_FILETYPE,
  7387. N_("The Hurd does not support the filetype feature.\n"),
  7388. PROMPT_CLEAR, 0 },
  7389. /* Journal inode is invalid */
  7390. { PR_0_JOURNAL_BAD_INODE,
  7391. N_("@S has an @n ext3 @j (@i %i).\n"),
  7392. PROMPT_CLEAR, PR_PREEN_OK },
  7393. /* The external journal has (unsupported) multiple filesystems */
  7394. { PR_0_JOURNAL_UNSUPP_MULTIFS,
  7395. N_("External @j has multiple @f users (unsupported).\n"),
  7396. PROMPT_NONE, PR_FATAL },
  7397. /* Can't find external journal */
  7398. { PR_0_CANT_FIND_JOURNAL,
  7399. N_("Can't find external @j\n"),
  7400. PROMPT_NONE, PR_FATAL },
  7401. /* External journal has bad superblock */
  7402. { PR_0_EXT_JOURNAL_BAD_SUPER,
  7403. N_("External @j has bad @S\n"),
  7404. PROMPT_NONE, PR_FATAL },
  7405. /* Superblock has a bad journal UUID */
  7406. { PR_0_JOURNAL_BAD_UUID,
  7407. N_("External @j does not support this @f\n"),
  7408. PROMPT_NONE, PR_FATAL },
  7409. /* Journal has an unknown superblock type */
  7410. { PR_0_JOURNAL_UNSUPP_SUPER,
  7411. N_("Ext3 @j @S is unknown type %N (unsupported).\n"
  7412. "It is likely that your copy of e2fsck is old and/or doesn't "
  7413. "support this @j format.\n"
  7414. "It is also possible the @j @S is corrupt.\n"),
  7415. PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
  7416. /* Journal superblock is corrupt */
  7417. { PR_0_JOURNAL_BAD_SUPER,
  7418. N_("Ext3 @j @S is corrupt.\n"),
  7419. PROMPT_FIX, PR_PREEN_OK },
  7420. /* Superblock flag should be cleared */
  7421. { PR_0_JOURNAL_HAS_JOURNAL,
  7422. N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
  7423. PROMPT_CLEAR, PR_PREEN_OK },
  7424. /* Superblock flag is incorrect */
  7425. { PR_0_JOURNAL_RECOVER_SET,
  7426. N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
  7427. PROMPT_CLEAR, PR_PREEN_OK },
  7428. /* Journal has data, but recovery flag is clear */
  7429. { PR_0_JOURNAL_RECOVERY_CLEAR,
  7430. N_("ext3 recovery flag is clear, but @j has data.\n"),
  7431. PROMPT_NONE, 0 },
  7432. /* Ask if we should clear the journal */
  7433. { PR_0_JOURNAL_RESET_JOURNAL,
  7434. N_("Clear @j"),
  7435. PROMPT_NULL, PR_PREEN_NOMSG },
  7436. /* Ask if we should run the journal anyway */
  7437. { PR_0_JOURNAL_RUN,
  7438. N_("Run @j anyway"),
  7439. PROMPT_NULL, 0 },
  7440. /* Run the journal by default */
  7441. { PR_0_JOURNAL_RUN_DEFAULT,
  7442. N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
  7443. PROMPT_NONE, 0 },
  7444. /* Clearing orphan inode */
  7445. { PR_0_ORPHAN_CLEAR_INODE,
  7446. N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
  7447. PROMPT_NONE, 0 },
  7448. /* Illegal block found in orphaned inode */
  7449. { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
  7450. N_("@I @b #%B (%b) found in @o @i %i.\n"),
  7451. PROMPT_NONE, 0 },
  7452. /* Already cleared block found in orphaned inode */
  7453. { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
  7454. N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
  7455. PROMPT_NONE, 0 },
  7456. /* Illegal orphan inode in superblock */
  7457. { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
  7458. N_("@I @o @i %i in @S.\n"),
  7459. PROMPT_NONE, 0 },
  7460. /* Illegal inode in orphaned inode list */
  7461. { PR_0_ORPHAN_ILLEGAL_INODE,
  7462. N_("@I @i %i in @o @i list.\n"),
  7463. PROMPT_NONE, 0 },
  7464. /* Filesystem revision is 0, but feature flags are set */
  7465. { PR_0_FS_REV_LEVEL,
  7466. N_("@f has feature flag(s) set, but is a revision 0 @f. "),
  7467. PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
  7468. /* Journal superblock has an unknown read-only feature flag set */
  7469. { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
  7470. N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
  7471. PROMPT_ABORT, 0 },
  7472. /* Journal superblock has an unknown incompatible feature flag set */
  7473. { PR_0_JOURNAL_UNSUPP_INCOMPAT,
  7474. N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
  7475. PROMPT_ABORT, 0 },
  7476. /* Journal has unsupported version number */
  7477. { PR_0_JOURNAL_UNSUPP_VERSION,
  7478. N_("@j version not supported by this e2fsck.\n"),
  7479. PROMPT_ABORT, 0 },
  7480. /* Moving journal to hidden file */
  7481. { PR_0_MOVE_JOURNAL,
  7482. N_("Moving @j from /%s to hidden @i.\n\n"),
  7483. PROMPT_NONE, 0 },
  7484. /* Error moving journal to hidden file */
  7485. { PR_0_ERR_MOVE_JOURNAL,
  7486. N_("Error moving @j: %m\n\n"),
  7487. PROMPT_NONE, 0 },
  7488. /* Clearing V2 journal superblock */
  7489. { PR_0_CLEAR_V2_JOURNAL,
  7490. N_("Found @n V2 @j @S fields (from V1 @j).\n"
  7491. "Clearing fields beyond the V1 @j @S...\n\n"),
  7492. PROMPT_NONE, 0 },
  7493. /* Backup journal inode blocks */
  7494. { PR_0_BACKUP_JNL,
  7495. N_("Backing up @j @i @b information.\n\n"),
  7496. PROMPT_NONE, 0 },
  7497. /* Reserved blocks w/o resize_inode */
  7498. { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
  7499. N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
  7500. "is %N; @s zero. "),
  7501. PROMPT_FIX, 0 },
  7502. /* Resize_inode not enabled, but resize inode is non-zero */
  7503. { PR_0_CLEAR_RESIZE_INODE,
  7504. N_("Resize_@i not enabled, but the resize @i is non-zero. "),
  7505. PROMPT_CLEAR, 0 },
  7506. /* Resize inode invalid */
  7507. { PR_0_RESIZE_INODE_INVALID,
  7508. N_("Resize @i not valid. "),
  7509. PROMPT_RECREATE, 0 },
  7510. /* Pass 1 errors */
  7511. /* Pass 1: Checking inodes, blocks, and sizes */
  7512. { PR_1_PASS_HEADER,
  7513. N_("Pass 1: Checking @is, @bs, and sizes\n"),
  7514. PROMPT_NONE, 0 },
  7515. /* Root directory is not an inode */
  7516. { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
  7517. PROMPT_CLEAR, 0 },
  7518. /* Root directory has dtime set */
  7519. { PR_1_ROOT_DTIME,
  7520. N_("@r has dtime set (probably due to old mke2fs). "),
  7521. PROMPT_FIX, PR_PREEN_OK },
  7522. /* Reserved inode has bad mode */
  7523. { PR_1_RESERVED_BAD_MODE,
  7524. N_("Reserved @i %i (%Q) has @n mode. "),
  7525. PROMPT_CLEAR, PR_PREEN_OK },
  7526. /* Deleted inode has zero dtime */
  7527. { PR_1_ZERO_DTIME,
  7528. N_("@D @i %i has zero dtime. "),
  7529. PROMPT_FIX, PR_PREEN_OK },
  7530. /* Inode in use, but dtime set */
  7531. { PR_1_SET_DTIME,
  7532. N_("@i %i is in use, but has dtime set. "),
  7533. PROMPT_FIX, PR_PREEN_OK },
  7534. /* Zero-length directory */
  7535. { PR_1_ZERO_LENGTH_DIR,
  7536. N_("@i %i is a @z @d. "),
  7537. PROMPT_CLEAR, PR_PREEN_OK },
  7538. /* Block bitmap conflicts with some other fs block */
  7539. { PR_1_BB_CONFLICT,
  7540. N_("@g %g's @b @B at %b @C.\n"),
  7541. PROMPT_RELOCATE, 0 },
  7542. /* Inode bitmap conflicts with some other fs block */
  7543. { PR_1_IB_CONFLICT,
  7544. N_("@g %g's @i @B at %b @C.\n"),
  7545. PROMPT_RELOCATE, 0 },
  7546. /* Inode table conflicts with some other fs block */
  7547. { PR_1_ITABLE_CONFLICT,
  7548. N_("@g %g's @i table at %b @C.\n"),
  7549. PROMPT_RELOCATE, 0 },
  7550. /* Block bitmap is on a bad block */
  7551. { PR_1_BB_BAD_BLOCK,
  7552. N_("@g %g's @b @B (%b) is bad. "),
  7553. PROMPT_RELOCATE, 0 },
  7554. /* Inode bitmap is on a bad block */
  7555. { PR_1_IB_BAD_BLOCK,
  7556. N_("@g %g's @i @B (%b) is bad. "),
  7557. PROMPT_RELOCATE, 0 },
  7558. /* Inode has incorrect i_size */
  7559. { PR_1_BAD_I_SIZE,
  7560. N_("@i %i, i_size is %Is, @s %N. "),
  7561. PROMPT_FIX, PR_PREEN_OK },
  7562. /* Inode has incorrect i_blocks */
  7563. { PR_1_BAD_I_BLOCKS,
  7564. N_("@i %i, i_@bs is %Ib, @s %N. "),
  7565. PROMPT_FIX, PR_PREEN_OK },
  7566. /* Illegal blocknumber in inode */
  7567. { PR_1_ILLEGAL_BLOCK_NUM,
  7568. N_("@I @b #%B (%b) in @i %i. "),
  7569. PROMPT_CLEAR, PR_LATCH_BLOCK },
  7570. /* Block number overlaps fs metadata */
  7571. { PR_1_BLOCK_OVERLAPS_METADATA,
  7572. N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
  7573. PROMPT_CLEAR, PR_LATCH_BLOCK },
  7574. /* Inode has illegal blocks (latch question) */
  7575. { PR_1_INODE_BLOCK_LATCH,
  7576. N_("@i %i has illegal @b(s). "),
  7577. PROMPT_CLEAR, 0 },
  7578. /* Too many bad blocks in inode */
  7579. { PR_1_TOO_MANY_BAD_BLOCKS,
  7580. N_("Too many illegal @bs in @i %i.\n"),
  7581. PROMPT_CLEAR_INODE, PR_NO_OK },
  7582. /* Illegal block number in bad block inode */
  7583. { PR_1_BB_ILLEGAL_BLOCK_NUM,
  7584. N_("@I @b #%B (%b) in bad @b @i. "),
  7585. PROMPT_CLEAR, PR_LATCH_BBLOCK },
  7586. /* Bad block inode has illegal blocks (latch question) */
  7587. { PR_1_INODE_BBLOCK_LATCH,
  7588. N_("Bad @b @i has illegal @b(s). "),
  7589. PROMPT_CLEAR, 0 },
  7590. /* Duplicate or bad blocks in use! */
  7591. { PR_1_DUP_BLOCKS_PREENSTOP,
  7592. N_("Duplicate or bad @b in use!\n"),
  7593. PROMPT_NONE, 0 },
  7594. /* Bad block used as bad block indirect block */
  7595. { PR_1_BBINODE_BAD_METABLOCK,
  7596. N_("Bad @b %b used as bad @b @i indirect @b. "),
  7597. PROMPT_CLEAR, PR_LATCH_BBLOCK },
  7598. /* Inconsistency can't be fixed prompt */
  7599. { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
  7600. N_("\nThe bad @b @i has probably been corrupted. You probably\n"
  7601. "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
  7602. "in the @f.\n"),
  7603. PROMPT_CONTINUE, PR_PREEN_NOMSG },
  7604. /* Bad primary block */
  7605. { PR_1_BAD_PRIMARY_BLOCK,
  7606. N_("\nIf the @b is really bad, the @f cannot be fixed.\n"),
  7607. PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
  7608. /* Bad primary block prompt */
  7609. { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
  7610. N_("You can remove this @b from the bad @b list and hope\n"
  7611. "that the @b is really OK. But there are no guarantees.\n\n"),
  7612. PROMPT_CLEAR, PR_PREEN_NOMSG },
  7613. /* Bad primary superblock */
  7614. { PR_1_BAD_PRIMARY_SUPERBLOCK,
  7615. N_("The primary @S (%b) is on the bad @b list.\n"),
  7616. PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
  7617. /* Bad primary block group descriptors */
  7618. { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
  7619. N_("Block %b in the primary @g descriptors "
  7620. "is on the bad @b list\n"),
  7621. PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
  7622. /* Bad superblock in group */
  7623. { PR_1_BAD_SUPERBLOCK,
  7624. N_("Warning: Group %g's @S (%b) is bad.\n"),
  7625. PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
  7626. /* Bad block group descriptors in group */
  7627. { PR_1_BAD_GROUP_DESCRIPTORS,
  7628. N_("Warning: Group %g's copy of the @g descriptors has a bad "
  7629. "@b (%b).\n"),
  7630. PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
  7631. /* Block claimed for no reason */
  7632. { PR_1_PROGERR_CLAIMED_BLOCK,
  7633. N_("Programming error? @b #%b claimed for no reason in "
  7634. "process_bad_@b.\n"),
  7635. PROMPT_NONE, PR_PREEN_OK },
  7636. /* Error allocating blocks for relocating metadata */
  7637. { PR_1_RELOC_BLOCK_ALLOCATE,
  7638. N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
  7639. PROMPT_NONE, PR_PREEN_OK },
  7640. /* Error allocating block buffer during relocation process */
  7641. { PR_1_RELOC_MEMORY_ALLOCATE,
  7642. N_("@A @b buffer for relocating %s\n"),
  7643. PROMPT_NONE, PR_PREEN_OK },
  7644. /* Relocating metadata group information from X to Y */
  7645. { PR_1_RELOC_FROM_TO,
  7646. N_("Relocating @g %g's %s from %b to %c...\n"),
  7647. PROMPT_NONE, PR_PREEN_OK },
  7648. /* Relocating metatdata group information to X */
  7649. { PR_1_RELOC_TO,
  7650. N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
  7651. PROMPT_NONE, PR_PREEN_OK },
  7652. /* Block read error during relocation process */
  7653. { PR_1_RELOC_READ_ERR,
  7654. N_("Warning: could not read @b %b of %s: %m\n"),
  7655. PROMPT_NONE, PR_PREEN_OK },
  7656. /* Block write error during relocation process */
  7657. { PR_1_RELOC_WRITE_ERR,
  7658. N_("Warning: could not write @b %b for %s: %m\n"),
  7659. PROMPT_NONE, PR_PREEN_OK },
  7660. /* Error allocating inode bitmap */
  7661. { PR_1_ALLOCATE_IBITMAP_ERROR,
  7662. N_("@A @i @B (%N): %m\n"),
  7663. PROMPT_NONE, PR_FATAL },
  7664. /* Error allocating block bitmap */
  7665. { PR_1_ALLOCATE_BBITMAP_ERROR,
  7666. N_("@A @b @B (%N): %m\n"),
  7667. PROMPT_NONE, PR_FATAL },
  7668. /* Error allocating icount structure */
  7669. { PR_1_ALLOCATE_ICOUNT,
  7670. N_("@A icount link information: %m\n"),
  7671. PROMPT_NONE, PR_FATAL },
  7672. /* Error allocating dbcount */
  7673. { PR_1_ALLOCATE_DBCOUNT,
  7674. N_("@A @d @b array: %m\n"),
  7675. PROMPT_NONE, PR_FATAL },
  7676. /* Error while scanning inodes */
  7677. { PR_1_ISCAN_ERROR,
  7678. N_("Error while scanning @is (%i): %m\n"),
  7679. PROMPT_NONE, PR_FATAL },
  7680. /* Error while iterating over blocks */
  7681. { PR_1_BLOCK_ITERATE,
  7682. N_("Error while iterating over @bs in @i %i: %m\n"),
  7683. PROMPT_NONE, PR_FATAL },
  7684. /* Error while storing inode count information */
  7685. { PR_1_ICOUNT_STORE,
  7686. N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
  7687. PROMPT_NONE, PR_FATAL },
  7688. /* Error while storing directory block information */
  7689. { PR_1_ADD_DBLOCK,
  7690. N_("Error storing @d @b information "
  7691. "(@i=%i, @b=%b, num=%N): %m\n"),
  7692. PROMPT_NONE, PR_FATAL },
  7693. /* Error while reading inode (for clearing) */
  7694. { PR_1_READ_INODE,
  7695. N_("Error reading @i %i: %m\n"),
  7696. PROMPT_NONE, PR_FATAL },
  7697. /* Suppress messages prompt */
  7698. { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
  7699. /* Imagic flag set on an inode when filesystem doesn't support it */
  7700. { PR_1_SET_IMAGIC,
  7701. N_("@i %i has imagic flag set. "),
  7702. PROMPT_CLEAR, 0 },
  7703. /* Immutable flag set on a device or socket inode */
  7704. { PR_1_SET_IMMUTABLE,
  7705. N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
  7706. "or append-only flag set. "),
  7707. PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
  7708. /* Compression flag set on an inode when filesystem doesn't support it */
  7709. { PR_1_COMPR_SET,
  7710. N_("@i %i has @cion flag set on @f without @cion support. "),
  7711. PROMPT_CLEAR, 0 },
  7712. /* Non-zero size for device, fifo or socket inode */
  7713. { PR_1_SET_NONZSIZE,
  7714. N_("Special (@v/socket/fifo) @i %i has non-zero size. "),
  7715. PROMPT_FIX, PR_PREEN_OK },
  7716. /* Filesystem revision is 0, but feature flags are set */
  7717. { PR_1_FS_REV_LEVEL,
  7718. N_("@f has feature flag(s) set, but is a revision 0 @f. "),
  7719. PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
  7720. /* Journal inode is not in use, but contains data */
  7721. { PR_1_JOURNAL_INODE_NOT_CLEAR,
  7722. N_("@j @i is not in use, but contains data. "),
  7723. PROMPT_CLEAR, PR_PREEN_OK },
  7724. /* Journal has bad mode */
  7725. { PR_1_JOURNAL_BAD_MODE,
  7726. N_("@j is not regular file. "),
  7727. PROMPT_FIX, PR_PREEN_OK },
  7728. /* Deal with inodes that were part of orphan linked list */
  7729. { PR_1_LOW_DTIME,
  7730. N_("@i %i was part of the @o @i list. "),
  7731. PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
  7732. /* Deal with inodes that were part of corrupted orphan linked
  7733. list (latch question) */
  7734. { PR_1_ORPHAN_LIST_REFUGEES,
  7735. N_("@is that were part of a corrupted orphan linked list found. "),
  7736. PROMPT_FIX, 0 },
  7737. /* Error allocating refcount structure */
  7738. { PR_1_ALLOCATE_REFCOUNT,
  7739. N_("@A refcount structure (%N): %m\n"),
  7740. PROMPT_NONE, PR_FATAL },
  7741. /* Error reading extended attribute block */
  7742. { PR_1_READ_EA_BLOCK,
  7743. N_("Error reading @a @b %b for @i %i. "),
  7744. PROMPT_CLEAR, 0 },
  7745. /* Invalid extended attribute block */
  7746. { PR_1_BAD_EA_BLOCK,
  7747. N_("@i %i has a bad @a @b %b. "),
  7748. PROMPT_CLEAR, 0 },
  7749. /* Error reading Extended Attribute block while fixing refcount */
  7750. { PR_1_EXTATTR_READ_ABORT,
  7751. N_("Error reading @a @b %b (%m). "),
  7752. PROMPT_ABORT, 0 },
  7753. /* Extended attribute reference count incorrect */
  7754. { PR_1_EXTATTR_REFCOUNT,
  7755. N_("@a @b %b has reference count %B, @s %N. "),
  7756. PROMPT_FIX, 0 },
  7757. /* Error writing Extended Attribute block while fixing refcount */
  7758. { PR_1_EXTATTR_WRITE,
  7759. N_("Error writing @a @b %b (%m). "),
  7760. PROMPT_ABORT, 0 },
  7761. /* Multiple EA blocks not supported */
  7762. { PR_1_EA_MULTI_BLOCK,
  7763. N_("@a @b %b has h_@bs > 1. "),
  7764. PROMPT_CLEAR, 0},
  7765. /* Error allocating EA region allocation structure */
  7766. { PR_1_EA_ALLOC_REGION,
  7767. N_("@A @a @b %b. "),
  7768. PROMPT_ABORT, 0},
  7769. /* Error EA allocation collision */
  7770. { PR_1_EA_ALLOC_COLLISION,
  7771. N_("@a @b %b is corrupt (allocation collision). "),
  7772. PROMPT_CLEAR, 0},
  7773. /* Bad extended attribute name */
  7774. { PR_1_EA_BAD_NAME,
  7775. N_("@a @b %b is corrupt (@n name). "),
  7776. PROMPT_CLEAR, 0},
  7777. /* Bad extended attribute value */
  7778. { PR_1_EA_BAD_VALUE,
  7779. N_("@a @b %b is corrupt (@n value). "),
  7780. PROMPT_CLEAR, 0},
  7781. /* Inode too big (latch question) */
  7782. { PR_1_INODE_TOOBIG,
  7783. N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 },
  7784. /* Directory too big */
  7785. { PR_1_TOOBIG_DIR,
  7786. N_("@b #%B (%b) causes @d to be too big. "),
  7787. PROMPT_CLEAR, PR_LATCH_TOOBIG },
  7788. /* Regular file too big */
  7789. { PR_1_TOOBIG_REG,
  7790. N_("@b #%B (%b) causes file to be too big. "),
  7791. PROMPT_CLEAR, PR_LATCH_TOOBIG },
  7792. /* Symlink too big */
  7793. { PR_1_TOOBIG_SYMLINK,
  7794. N_("@b #%B (%b) causes symlink to be too big. "),
  7795. PROMPT_CLEAR, PR_LATCH_TOOBIG },
  7796. /* INDEX_FL flag set on a non-HTREE filesystem */
  7797. { PR_1_HTREE_SET,
  7798. N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
  7799. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  7800. /* INDEX_FL flag set on a non-directory */
  7801. { PR_1_HTREE_NODIR,
  7802. N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
  7803. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  7804. /* Invalid root node in HTREE directory */
  7805. { PR_1_HTREE_BADROOT,
  7806. N_("@h %i has an @n root node.\n"),
  7807. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  7808. /* Unsupported hash version in HTREE directory */
  7809. { PR_1_HTREE_HASHV,
  7810. N_("@h %i has an unsupported hash version (%N)\n"),
  7811. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  7812. /* Incompatible flag in HTREE root node */
  7813. { PR_1_HTREE_INCOMPAT,
  7814. N_("@h %i uses an incompatible htree root node flag.\n"),
  7815. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  7816. /* HTREE too deep */
  7817. { PR_1_HTREE_DEPTH,
  7818. N_("@h %i has a tree depth (%N) which is too big\n"),
  7819. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  7820. /* Bad block has indirect block that conflicts with filesystem block */
  7821. { PR_1_BB_FS_BLOCK,
  7822. N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
  7823. "@f metadata. "),
  7824. PROMPT_CLEAR, PR_LATCH_BBLOCK },
  7825. /* Resize inode failed */
  7826. { PR_1_RESIZE_INODE_CREATE,
  7827. N_("Resize @i (re)creation failed: %m."),
  7828. PROMPT_ABORT, 0 },
  7829. /* invalid inode->i_extra_isize */
  7830. { PR_1_EXTRA_ISIZE,
  7831. N_("@i %i has a extra size (%IS) which is @n\n"),
  7832. PROMPT_FIX, PR_PREEN_OK },
  7833. /* invalid ea entry->e_name_len */
  7834. { PR_1_ATTR_NAME_LEN,
  7835. N_("@a in @i %i has a namelen (%N) which is @n\n"),
  7836. PROMPT_CLEAR, PR_PREEN_OK },
  7837. /* invalid ea entry->e_value_size */
  7838. { PR_1_ATTR_VALUE_SIZE,
  7839. N_("@a in @i %i has a value size (%N) which is @n\n"),
  7840. PROMPT_CLEAR, PR_PREEN_OK },
  7841. /* invalid ea entry->e_value_offs */
  7842. { PR_1_ATTR_VALUE_OFFSET,
  7843. N_("@a in @i %i has a value offset (%N) which is @n\n"),
  7844. PROMPT_CLEAR, PR_PREEN_OK },
  7845. /* invalid ea entry->e_value_block */
  7846. { PR_1_ATTR_VALUE_BLOCK,
  7847. N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
  7848. PROMPT_CLEAR, PR_PREEN_OK },
  7849. /* invalid ea entry->e_hash */
  7850. { PR_1_ATTR_HASH,
  7851. N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
  7852. PROMPT_CLEAR, PR_PREEN_OK },
  7853. /* Pass 1b errors */
  7854. /* Pass 1B: Rescan for duplicate/bad blocks */
  7855. { PR_1B_PASS_HEADER,
  7856. N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
  7857. "Pass 1B: Rescanning for @m @bs\n"),
  7858. PROMPT_NONE, 0 },
  7859. /* Duplicate/bad block(s) header */
  7860. { PR_1B_DUP_BLOCK_HEADER,
  7861. N_("@m @b(s) in @i %i:"),
  7862. PROMPT_NONE, 0 },
  7863. /* Duplicate/bad block(s) in inode */
  7864. { PR_1B_DUP_BLOCK,
  7865. " %b",
  7866. PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
  7867. /* Duplicate/bad block(s) end */
  7868. { PR_1B_DUP_BLOCK_END,
  7869. "\n",
  7870. PROMPT_NONE, PR_PREEN_NOHDR },
  7871. /* Error while scanning inodes */
  7872. { PR_1B_ISCAN_ERROR,
  7873. N_("Error while scanning inodes (%i): %m\n"),
  7874. PROMPT_NONE, PR_FATAL },
  7875. /* Error allocating inode bitmap */
  7876. { PR_1B_ALLOCATE_IBITMAP_ERROR,
  7877. N_("@A @i @B (@i_dup_map): %m\n"),
  7878. PROMPT_NONE, PR_FATAL },
  7879. /* Error while iterating over blocks */
  7880. { PR_1B_BLOCK_ITERATE,
  7881. N_("Error while iterating over @bs in @i %i (%s): %m\n"),
  7882. PROMPT_NONE, 0 },
  7883. /* Error adjusting EA refcount */
  7884. { PR_1B_ADJ_EA_REFCOUNT,
  7885. N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
  7886. PROMPT_NONE, 0 },
  7887. /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
  7888. { PR_1C_PASS_HEADER,
  7889. N_("Pass 1C: Scanning directories for @is with @m @bs.\n"),
  7890. PROMPT_NONE, 0 },
  7891. /* Pass 1D: Reconciling multiply-claimed blocks */
  7892. { PR_1D_PASS_HEADER,
  7893. N_("Pass 1D: Reconciling @m @bs\n"),
  7894. PROMPT_NONE, 0 },
  7895. /* File has duplicate blocks */
  7896. { PR_1D_DUP_FILE,
  7897. N_("File %Q (@i #%i, mod time %IM)\n"
  7898. " has %B @m @b(s), shared with %N file(s):\n"),
  7899. PROMPT_NONE, 0 },
  7900. /* List of files sharing duplicate blocks */
  7901. { PR_1D_DUP_FILE_LIST,
  7902. N_("\t%Q (@i #%i, mod time %IM)\n"),
  7903. PROMPT_NONE, 0 },
  7904. /* File sharing blocks with filesystem metadata */
  7905. { PR_1D_SHARE_METADATA,
  7906. N_("\t<@f metadata>\n"),
  7907. PROMPT_NONE, 0 },
  7908. /* Report of how many duplicate/bad inodes */
  7909. { PR_1D_NUM_DUP_INODES,
  7910. N_("(There are %N @is containing @m @bs.)\n\n"),
  7911. PROMPT_NONE, 0 },
  7912. /* Duplicated blocks already reassigned or cloned. */
  7913. { PR_1D_DUP_BLOCKS_DEALT,
  7914. N_("@m @bs already reassigned or cloned.\n\n"),
  7915. PROMPT_NONE, 0 },
  7916. /* Clone duplicate/bad blocks? */
  7917. { PR_1D_CLONE_QUESTION,
  7918. "", PROMPT_CLONE, PR_NO_OK },
  7919. /* Delete file? */
  7920. { PR_1D_DELETE_QUESTION,
  7921. "", PROMPT_DELETE, 0 },
  7922. /* Couldn't clone file (error) */
  7923. { PR_1D_CLONE_ERROR,
  7924. N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
  7925. /* Pass 2 errors */
  7926. /* Pass 2: Checking directory structure */
  7927. { PR_2_PASS_HEADER,
  7928. N_("Pass 2: Checking @d structure\n"),
  7929. PROMPT_NONE, 0 },
  7930. /* Bad inode number for '.' */
  7931. { PR_2_BAD_INODE_DOT,
  7932. N_("@n @i number for '.' in @d @i %i.\n"),
  7933. PROMPT_FIX, 0 },
  7934. /* Directory entry has bad inode number */
  7935. { PR_2_BAD_INO,
  7936. N_("@E has @n @i #: %Di.\n"),
  7937. PROMPT_CLEAR, 0 },
  7938. /* Directory entry has deleted or unused inode */
  7939. { PR_2_UNUSED_INODE,
  7940. N_("@E has @D/unused @i %Di. "),
  7941. PROMPT_CLEAR, PR_PREEN_OK },
  7942. /* Directry entry is link to '.' */
  7943. { PR_2_LINK_DOT,
  7944. N_("@E @L to '.' "),
  7945. PROMPT_CLEAR, 0 },
  7946. /* Directory entry points to inode now located in a bad block */
  7947. { PR_2_BB_INODE,
  7948. N_("@E points to @i (%Di) located in a bad @b.\n"),
  7949. PROMPT_CLEAR, 0 },
  7950. /* Directory entry contains a link to a directory */
  7951. { PR_2_LINK_DIR,
  7952. N_("@E @L to @d %P (%Di).\n"),
  7953. PROMPT_CLEAR, 0 },
  7954. /* Directory entry contains a link to the root directry */
  7955. { PR_2_LINK_ROOT,
  7956. N_("@E @L to the @r.\n"),
  7957. PROMPT_CLEAR, 0 },
  7958. /* Directory entry has illegal characters in its name */
  7959. { PR_2_BAD_NAME,
  7960. N_("@E has illegal characters in its name.\n"),
  7961. PROMPT_FIX, 0 },
  7962. /* Missing '.' in directory inode */
  7963. { PR_2_MISSING_DOT,
  7964. N_("Missing '.' in @d @i %i.\n"),
  7965. PROMPT_FIX, 0 },
  7966. /* Missing '..' in directory inode */
  7967. { PR_2_MISSING_DOT_DOT,
  7968. N_("Missing '..' in @d @i %i.\n"),
  7969. PROMPT_FIX, 0 },
  7970. /* First entry in directory inode doesn't contain '.' */
  7971. { PR_2_1ST_NOT_DOT,
  7972. N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
  7973. PROMPT_FIX, 0 },
  7974. /* Second entry in directory inode doesn't contain '..' */
  7975. { PR_2_2ND_NOT_DOT_DOT,
  7976. N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
  7977. PROMPT_FIX, 0 },
  7978. /* i_faddr should be zero */
  7979. { PR_2_FADDR_ZERO,
  7980. N_("i_faddr @F %IF, @s zero.\n"),
  7981. PROMPT_CLEAR, 0 },
  7982. /* i_file_acl should be zero */
  7983. { PR_2_FILE_ACL_ZERO,
  7984. N_("i_file_acl @F %If, @s zero.\n"),
  7985. PROMPT_CLEAR, 0 },
  7986. /* i_dir_acl should be zero */
  7987. { PR_2_DIR_ACL_ZERO,
  7988. N_("i_dir_acl @F %Id, @s zero.\n"),
  7989. PROMPT_CLEAR, 0 },
  7990. /* i_frag should be zero */
  7991. { PR_2_FRAG_ZERO,
  7992. N_("i_frag @F %N, @s zero.\n"),
  7993. PROMPT_CLEAR, 0 },
  7994. /* i_fsize should be zero */
  7995. { PR_2_FSIZE_ZERO,
  7996. N_("i_fsize @F %N, @s zero.\n"),
  7997. PROMPT_CLEAR, 0 },
  7998. /* inode has bad mode */
  7999. { PR_2_BAD_MODE,
  8000. N_("@i %i (%Q) has @n mode (%Im).\n"),
  8001. PROMPT_CLEAR, 0 },
  8002. /* directory corrupted */
  8003. { PR_2_DIR_CORRUPTED,
  8004. N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
  8005. PROMPT_SALVAGE, 0 },
  8006. /* filename too long */
  8007. { PR_2_FILENAME_LONG,
  8008. N_("@d @i %i, @b %B, offset %N: filename too long\n"),
  8009. PROMPT_TRUNCATE, 0 },
  8010. /* Directory inode has a missing block (hole) */
  8011. { PR_2_DIRECTORY_HOLE,
  8012. N_("@d @i %i has an unallocated @b #%B. "),
  8013. PROMPT_ALLOCATE, 0 },
  8014. /* '.' is not NULL terminated */
  8015. { PR_2_DOT_NULL_TERM,
  8016. N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
  8017. PROMPT_FIX, 0 },
  8018. /* '..' is not NULL terminated */
  8019. { PR_2_DOT_DOT_NULL_TERM,
  8020. N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
  8021. PROMPT_FIX, 0 },
  8022. /* Illegal character device inode */
  8023. { PR_2_BAD_CHAR_DEV,
  8024. N_("@i %i (%Q) is an @I character @v.\n"),
  8025. PROMPT_CLEAR, 0 },
  8026. /* Illegal block device inode */
  8027. { PR_2_BAD_BLOCK_DEV,
  8028. N_("@i %i (%Q) is an @I @b @v.\n"),
  8029. PROMPT_CLEAR, 0 },
  8030. /* Duplicate '.' entry */
  8031. { PR_2_DUP_DOT,
  8032. N_("@E is duplicate '.' @e.\n"),
  8033. PROMPT_FIX, 0 },
  8034. /* Duplicate '..' entry */
  8035. { PR_2_DUP_DOT_DOT,
  8036. N_("@E is duplicate '..' @e.\n"),
  8037. PROMPT_FIX, 0 },
  8038. /* Internal error: couldn't find dir_info */
  8039. { PR_2_NO_DIRINFO,
  8040. N_("Internal error: cannot find dir_info for %i.\n"),
  8041. PROMPT_NONE, PR_FATAL },
  8042. /* Final rec_len is wrong */
  8043. { PR_2_FINAL_RECLEN,
  8044. N_("@E has rec_len of %Dr, @s %N.\n"),
  8045. PROMPT_FIX, 0 },
  8046. /* Error allocating icount structure */
  8047. { PR_2_ALLOCATE_ICOUNT,
  8048. N_("@A icount structure: %m\n"),
  8049. PROMPT_NONE, PR_FATAL },
  8050. /* Error iterating over directory blocks */
  8051. { PR_2_DBLIST_ITERATE,
  8052. N_("Error iterating over @d @bs: %m\n"),
  8053. PROMPT_NONE, PR_FATAL },
  8054. /* Error reading directory block */
  8055. { PR_2_READ_DIRBLOCK,
  8056. N_("Error reading @d @b %b (@i %i): %m\n"),
  8057. PROMPT_CONTINUE, 0 },
  8058. /* Error writing directory block */
  8059. { PR_2_WRITE_DIRBLOCK,
  8060. N_("Error writing @d @b %b (@i %i): %m\n"),
  8061. PROMPT_CONTINUE, 0 },
  8062. /* Error allocating new directory block */
  8063. { PR_2_ALLOC_DIRBOCK,
  8064. N_("@A new @d @b for @i %i (%s): %m\n"),
  8065. PROMPT_NONE, 0 },
  8066. /* Error deallocating inode */
  8067. { PR_2_DEALLOC_INODE,
  8068. N_("Error deallocating @i %i: %m\n"),
  8069. PROMPT_NONE, PR_FATAL },
  8070. /* Directory entry for '.' is big. Split? */
  8071. { PR_2_SPLIT_DOT,
  8072. N_("@d @e for '.' is big. "),
  8073. PROMPT_SPLIT, PR_NO_OK },
  8074. /* Illegal FIFO inode */
  8075. { PR_2_BAD_FIFO,
  8076. N_("@i %i (%Q) is an @I FIFO.\n"),
  8077. PROMPT_CLEAR, 0 },
  8078. /* Illegal socket inode */
  8079. { PR_2_BAD_SOCKET,
  8080. N_("@i %i (%Q) is an @I socket.\n"),
  8081. PROMPT_CLEAR, 0 },
  8082. /* Directory filetype not set */
  8083. { PR_2_SET_FILETYPE,
  8084. N_("Setting filetype for @E to %N.\n"),
  8085. PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
  8086. /* Directory filetype incorrect */
  8087. { PR_2_BAD_FILETYPE,
  8088. N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
  8089. PROMPT_FIX, 0 },
  8090. /* Directory filetype set on filesystem */
  8091. { PR_2_CLEAR_FILETYPE,
  8092. N_("@E has filetype set.\n"),
  8093. PROMPT_CLEAR, PR_PREEN_OK },
  8094. /* Directory filename is null */
  8095. { PR_2_NULL_NAME,
  8096. N_("@E has a @z name.\n"),
  8097. PROMPT_CLEAR, 0 },
  8098. /* Invalid symlink */
  8099. { PR_2_INVALID_SYMLINK,
  8100. N_("Symlink %Q (@i #%i) is @n.\n"),
  8101. PROMPT_CLEAR, 0 },
  8102. /* i_file_acl (extended attribute block) is bad */
  8103. { PR_2_FILE_ACL_BAD,
  8104. N_("@a @b @F @n (%If).\n"),
  8105. PROMPT_CLEAR, 0 },
  8106. /* Filesystem contains large files, but has no such flag in sb */
  8107. { PR_2_FEATURE_LARGE_FILES,
  8108. N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
  8109. PROMPT_FIX, 0 },
  8110. /* Node in HTREE directory not referenced */
  8111. { PR_2_HTREE_NOTREF,
  8112. N_("@p @h %d: node (%B) not referenced\n"),
  8113. PROMPT_NONE, 0 },
  8114. /* Node in HTREE directory referenced twice */
  8115. { PR_2_HTREE_DUPREF,
  8116. N_("@p @h %d: node (%B) referenced twice\n"),
  8117. PROMPT_NONE, 0 },
  8118. /* Node in HTREE directory has bad min hash */
  8119. { PR_2_HTREE_MIN_HASH,
  8120. N_("@p @h %d: node (%B) has bad min hash\n"),
  8121. PROMPT_NONE, 0 },
  8122. /* Node in HTREE directory has bad max hash */
  8123. { PR_2_HTREE_MAX_HASH,
  8124. N_("@p @h %d: node (%B) has bad max hash\n"),
  8125. PROMPT_NONE, 0 },
  8126. /* Clear invalid HTREE directory */
  8127. { PR_2_HTREE_CLEAR,
  8128. N_("@n @h %d (%q). "), PROMPT_CLEAR, 0 },
  8129. /* Bad block in htree interior node */
  8130. { PR_2_HTREE_BADBLK,
  8131. N_("@p @h %d (%q): bad @b number %b.\n"),
  8132. PROMPT_CLEAR_HTREE, 0 },
  8133. /* Error adjusting EA refcount */
  8134. { PR_2_ADJ_EA_REFCOUNT,
  8135. N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
  8136. PROMPT_NONE, PR_FATAL },
  8137. /* Invalid HTREE root node */
  8138. { PR_2_HTREE_BAD_ROOT,
  8139. N_("@p @h %d: root node is @n\n"),
  8140. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  8141. /* Invalid HTREE limit */
  8142. { PR_2_HTREE_BAD_LIMIT,
  8143. N_("@p @h %d: node (%B) has @n limit (%N)\n"),
  8144. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  8145. /* Invalid HTREE count */
  8146. { PR_2_HTREE_BAD_COUNT,
  8147. N_("@p @h %d: node (%B) has @n count (%N)\n"),
  8148. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  8149. /* HTREE interior node has out-of-order hashes in table */
  8150. { PR_2_HTREE_HASH_ORDER,
  8151. N_("@p @h %d: node (%B) has an unordered hash table\n"),
  8152. PROMPT_CLEAR_HTREE, PR_PREEN_OK },
  8153. /* Node in HTREE directory has invalid depth */
  8154. { PR_2_HTREE_BAD_DEPTH,
  8155. N_("@p @h %d: node (%B) has @n depth\n"),
  8156. PROMPT_NONE, 0 },
  8157. /* Duplicate directory entry found */
  8158. { PR_2_DUPLICATE_DIRENT,
  8159. N_("Duplicate @E found. "),
  8160. PROMPT_CLEAR, 0 },
  8161. /* Non-unique filename found */
  8162. { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
  8163. N_("@E has a non-unique filename.\nRename to %s"),
  8164. PROMPT_NULL, 0 },
  8165. /* Duplicate directory entry found */
  8166. { PR_2_REPORT_DUP_DIRENT,
  8167. N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
  8168. PROMPT_NONE, 0 },
  8169. /* Pass 3 errors */
  8170. /* Pass 3: Checking directory connectivity */
  8171. { PR_3_PASS_HEADER,
  8172. N_("Pass 3: Checking @d connectivity\n"),
  8173. PROMPT_NONE, 0 },
  8174. /* Root inode not allocated */
  8175. { PR_3_NO_ROOT_INODE,
  8176. N_("@r not allocated. "),
  8177. PROMPT_ALLOCATE, 0 },
  8178. /* No room in lost+found */
  8179. { PR_3_EXPAND_LF_DIR,
  8180. N_("No room in @l @d. "),
  8181. PROMPT_EXPAND, 0 },
  8182. /* Unconnected directory inode */
  8183. { PR_3_UNCONNECTED_DIR,
  8184. N_("Unconnected @d @i %i (%p)\n"),
  8185. PROMPT_CONNECT, 0 },
  8186. /* /lost+found not found */
  8187. { PR_3_NO_LF_DIR,
  8188. N_("/@l not found. "),
  8189. PROMPT_CREATE, PR_PREEN_OK },
  8190. /* .. entry is incorrect */
  8191. { PR_3_BAD_DOT_DOT,
  8192. N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
  8193. PROMPT_FIX, 0 },
  8194. /* Bad or non-existent /lost+found. Cannot reconnect */
  8195. { PR_3_NO_LPF,
  8196. N_("Bad or non-existent /@l. Cannot reconnect.\n"),
  8197. PROMPT_NONE, 0 },
  8198. /* Could not expand /lost+found */
  8199. { PR_3_CANT_EXPAND_LPF,
  8200. N_("Could not expand /@l: %m\n"),
  8201. PROMPT_NONE, 0 },
  8202. /* Could not reconnect inode */
  8203. { PR_3_CANT_RECONNECT,
  8204. N_("Could not reconnect %i: %m\n"),
  8205. PROMPT_NONE, 0 },
  8206. /* Error while trying to find /lost+found */
  8207. { PR_3_ERR_FIND_LPF,
  8208. N_("Error while trying to find /@l: %m\n"),
  8209. PROMPT_NONE, 0 },
  8210. /* Error in ext2fs_new_block while creating /lost+found */
  8211. { PR_3_ERR_LPF_NEW_BLOCK,
  8212. N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
  8213. PROMPT_NONE, 0 },
  8214. /* Error in ext2fs_new_inode while creating /lost+found */
  8215. { PR_3_ERR_LPF_NEW_INODE,
  8216. N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
  8217. PROMPT_NONE, 0 },
  8218. /* Error in ext2fs_new_dir_block while creating /lost+found */
  8219. { PR_3_ERR_LPF_NEW_DIR_BLOCK,
  8220. N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
  8221. PROMPT_NONE, 0 },
  8222. /* Error while writing directory block for /lost+found */
  8223. { PR_3_ERR_LPF_WRITE_BLOCK,
  8224. N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
  8225. PROMPT_NONE, 0 },
  8226. /* Error while adjusting inode count */
  8227. { PR_3_ADJUST_INODE,
  8228. N_("Error while adjusting @i count on @i %i\n"),
  8229. PROMPT_NONE, 0 },
  8230. /* Couldn't fix parent directory -- error */
  8231. { PR_3_FIX_PARENT_ERR,
  8232. N_("Couldn't fix parent of @i %i: %m\n\n"),
  8233. PROMPT_NONE, 0 },
  8234. /* Couldn't fix parent directory -- couldn't find it */
  8235. { PR_3_FIX_PARENT_NOFIND,
  8236. N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
  8237. PROMPT_NONE, 0 },
  8238. /* Error allocating inode bitmap */
  8239. { PR_3_ALLOCATE_IBITMAP_ERROR,
  8240. N_("@A @i @B (%N): %m\n"),
  8241. PROMPT_NONE, PR_FATAL },
  8242. /* Error creating root directory */
  8243. { PR_3_CREATE_ROOT_ERROR,
  8244. N_("Error creating root @d (%s): %m\n"),
  8245. PROMPT_NONE, PR_FATAL },
  8246. /* Error creating lost and found directory */
  8247. { PR_3_CREATE_LPF_ERROR,
  8248. N_("Error creating /@l @d (%s): %m\n"),
  8249. PROMPT_NONE, PR_FATAL },
  8250. /* Root inode is not directory; aborting */
  8251. { PR_3_ROOT_NOT_DIR_ABORT,
  8252. N_("@r is not a @d; aborting.\n"),
  8253. PROMPT_NONE, PR_FATAL },
  8254. /* Cannot proceed without a root inode. */
  8255. { PR_3_NO_ROOT_INODE_ABORT,
  8256. N_("can't proceed without a @r.\n"),
  8257. PROMPT_NONE, PR_FATAL },
  8258. /* Internal error: couldn't find dir_info */
  8259. { PR_3_NO_DIRINFO,
  8260. N_("Internal error: cannot find dir_info for %i.\n"),
  8261. PROMPT_NONE, PR_FATAL },
  8262. /* Lost+found not a directory */
  8263. { PR_3_LPF_NOTDIR,
  8264. N_("/@l is not a @d (ino=%i)\n"),
  8265. PROMPT_UNLINK, 0 },
  8266. /* Pass 3A Directory Optimization */
  8267. /* Pass 3A: Optimizing directories */
  8268. { PR_3A_PASS_HEADER,
  8269. N_("Pass 3A: Optimizing directories\n"),
  8270. PROMPT_NONE, PR_PREEN_NOMSG },
  8271. /* Error iterating over directories */
  8272. { PR_3A_OPTIMIZE_ITER,
  8273. N_("Failed to create dirs_to_hash iterator: %m"),
  8274. PROMPT_NONE, 0 },
  8275. /* Error rehash directory */
  8276. { PR_3A_OPTIMIZE_DIR_ERR,
  8277. N_("Failed to optimize directory %q (%d): %m"),
  8278. PROMPT_NONE, 0 },
  8279. /* Rehashing dir header */
  8280. { PR_3A_OPTIMIZE_DIR_HEADER,
  8281. N_("Optimizing directories: "),
  8282. PROMPT_NONE, PR_MSG_ONLY },
  8283. /* Rehashing directory %d */
  8284. { PR_3A_OPTIMIZE_DIR,
  8285. " %d",
  8286. PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
  8287. /* Rehashing dir end */
  8288. { PR_3A_OPTIMIZE_DIR_END,
  8289. "\n",
  8290. PROMPT_NONE, PR_PREEN_NOHDR },
  8291. /* Pass 4 errors */
  8292. /* Pass 4: Checking reference counts */
  8293. { PR_4_PASS_HEADER,
  8294. N_("Pass 4: Checking reference counts\n"),
  8295. PROMPT_NONE, 0 },
  8296. /* Unattached zero-length inode */
  8297. { PR_4_ZERO_LEN_INODE,
  8298. N_("@u @z @i %i. "),
  8299. PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
  8300. /* Unattached inode */
  8301. { PR_4_UNATTACHED_INODE,
  8302. N_("@u @i %i\n"),
  8303. PROMPT_CONNECT, 0 },
  8304. /* Inode ref count wrong */
  8305. { PR_4_BAD_REF_COUNT,
  8306. N_("@i %i ref count is %Il, @s %N. "),
  8307. PROMPT_FIX, PR_PREEN_OK },
  8308. { PR_4_INCONSISTENT_COUNT,
  8309. N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
  8310. "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
  8311. "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
  8312. "They @s the same!\n"),
  8313. PROMPT_NONE, 0 },
  8314. /* Pass 5 errors */
  8315. /* Pass 5: Checking group summary information */
  8316. { PR_5_PASS_HEADER,
  8317. N_("Pass 5: Checking @g summary information\n"),
  8318. PROMPT_NONE, 0 },
  8319. /* Padding at end of inode bitmap is not set. */
  8320. { PR_5_INODE_BMAP_PADDING,
  8321. N_("Padding at end of @i @B is not set. "),
  8322. PROMPT_FIX, PR_PREEN_OK },
  8323. /* Padding at end of block bitmap is not set. */
  8324. { PR_5_BLOCK_BMAP_PADDING,
  8325. N_("Padding at end of @b @B is not set. "),
  8326. PROMPT_FIX, PR_PREEN_OK },
  8327. /* Block bitmap differences header */
  8328. { PR_5_BLOCK_BITMAP_HEADER,
  8329. N_("@b @B differences: "),
  8330. PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
  8331. /* Block not used, but marked in bitmap */
  8332. { PR_5_BLOCK_UNUSED,
  8333. " -%b",
  8334. PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8335. /* Block used, but not marked used in bitmap */
  8336. { PR_5_BLOCK_USED,
  8337. " +%b",
  8338. PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8339. /* Block bitmap differences end */
  8340. { PR_5_BLOCK_BITMAP_END,
  8341. "\n",
  8342. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8343. /* Inode bitmap differences header */
  8344. { PR_5_INODE_BITMAP_HEADER,
  8345. N_("@i @B differences: "),
  8346. PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
  8347. /* Inode not used, but marked in bitmap */
  8348. { PR_5_INODE_UNUSED,
  8349. " -%i",
  8350. PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8351. /* Inode used, but not marked used in bitmap */
  8352. { PR_5_INODE_USED,
  8353. " +%i",
  8354. PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8355. /* Inode bitmap differences end */
  8356. { PR_5_INODE_BITMAP_END,
  8357. "\n",
  8358. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8359. /* Free inodes count for group wrong */
  8360. { PR_5_FREE_INODE_COUNT_GROUP,
  8361. N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
  8362. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8363. /* Directories count for group wrong */
  8364. { PR_5_FREE_DIR_COUNT_GROUP,
  8365. N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
  8366. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8367. /* Free inodes count wrong */
  8368. { PR_5_FREE_INODE_COUNT,
  8369. N_("Free @is count wrong (%i, counted=%j).\n"),
  8370. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8371. /* Free blocks count for group wrong */
  8372. { PR_5_FREE_BLOCK_COUNT_GROUP,
  8373. N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
  8374. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8375. /* Free blocks count wrong */
  8376. { PR_5_FREE_BLOCK_COUNT,
  8377. N_("Free @bs count wrong (%b, counted=%c).\n"),
  8378. PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
  8379. /* Programming error: bitmap endpoints don't match */
  8380. { PR_5_BMAP_ENDPOINTS,
  8381. N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
  8382. "match calculated @B endpoints (%i, %j)\n"),
  8383. PROMPT_NONE, PR_FATAL },
  8384. /* Internal error: fudging end of bitmap */
  8385. { PR_5_FUDGE_BITMAP_ERROR,
  8386. N_("Internal error: fudging end of bitmap (%N)\n"),
  8387. PROMPT_NONE, PR_FATAL },
  8388. /* Error copying in replacement inode bitmap */
  8389. { PR_5_COPY_IBITMAP_ERROR,
  8390. N_("Error copying in replacement @i @B: %m\n"),
  8391. PROMPT_NONE, PR_FATAL },
  8392. /* Error copying in replacement block bitmap */
  8393. { PR_5_COPY_BBITMAP_ERROR,
  8394. N_("Error copying in replacement @b @B: %m\n"),
  8395. PROMPT_NONE, PR_FATAL },
  8396. /* Block range not used, but marked in bitmap */
  8397. { PR_5_BLOCK_RANGE_UNUSED,
  8398. " -(%b--%c)",
  8399. PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8400. /* Block range used, but not marked used in bitmap */
  8401. { PR_5_BLOCK_RANGE_USED,
  8402. " +(%b--%c)",
  8403. PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8404. /* Inode range not used, but marked in bitmap */
  8405. { PR_5_INODE_RANGE_UNUSED,
  8406. " -(%i--%j)",
  8407. PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8408. /* Inode range used, but not marked used in bitmap */
  8409. { PR_5_INODE_RANGE_USED,
  8410. " +(%i--%j)",
  8411. PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
  8412. { 0 }
  8413. };
  8414. /*
  8415. * This is the latch flags register. It allows several problems to be
  8416. * "latched" together. This means that the user has to answer but one
  8417. * question for the set of problems, and all of the associated
  8418. * problems will be either fixed or not fixed.
  8419. */
  8420. static struct latch_descr pr_latch_info[] = {
  8421. { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
  8422. { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
  8423. { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
  8424. { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
  8425. { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
  8426. { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
  8427. { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
  8428. { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
  8429. { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
  8430. { -1, 0, 0 },
  8431. };
  8432. static const struct e2fsck_problem *find_problem(problem_t code)
  8433. {
  8434. int i;
  8435. for (i=0; problem_table[i].e2p_code; i++) {
  8436. if (problem_table[i].e2p_code == code)
  8437. return &problem_table[i];
  8438. }
  8439. return 0;
  8440. }
  8441. static struct latch_descr *find_latch(int code)
  8442. {
  8443. int i;
  8444. for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
  8445. if (pr_latch_info[i].latch_code == code)
  8446. return &pr_latch_info[i];
  8447. }
  8448. return 0;
  8449. }
  8450. int end_problem_latch(e2fsck_t ctx, int mask)
  8451. {
  8452. struct latch_descr *ldesc;
  8453. struct problem_context pctx;
  8454. int answer = -1;
  8455. ldesc = find_latch(mask);
  8456. if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
  8457. clear_problem_context(&pctx);
  8458. answer = fix_problem(ctx, ldesc->end_message, &pctx);
  8459. }
  8460. ldesc->flags &= ~(PRL_VARIABLE);
  8461. return answer;
  8462. }
  8463. int set_latch_flags(int mask, int setflags, int clearflags)
  8464. {
  8465. struct latch_descr *ldesc;
  8466. ldesc = find_latch(mask);
  8467. if (!ldesc)
  8468. return -1;
  8469. ldesc->flags |= setflags;
  8470. ldesc->flags &= ~clearflags;
  8471. return 0;
  8472. }
  8473. void clear_problem_context(struct problem_context *ctx)
  8474. {
  8475. memset(ctx, 0, sizeof(struct problem_context));
  8476. ctx->blkcount = -1;
  8477. ctx->group = -1;
  8478. }
  8479. int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
  8480. {
  8481. ext2_filsys fs = ctx->fs;
  8482. const struct e2fsck_problem *ptr;
  8483. struct latch_descr *ldesc = NULL;
  8484. const char *message;
  8485. int def_yn, answer, ans;
  8486. int print_answer = 0;
  8487. int suppress = 0;
  8488. ptr = find_problem(code);
  8489. if (!ptr) {
  8490. printf(_("Unhandled error code (0x%x)!\n"), code);
  8491. return 0;
  8492. }
  8493. def_yn = 1;
  8494. if ((ptr->flags & PR_NO_DEFAULT) ||
  8495. ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
  8496. (ctx->options & E2F_OPT_NO))
  8497. def_yn= 0;
  8498. /*
  8499. * Do special latch processing. This is where we ask the
  8500. * latch question, if it exists
  8501. */
  8502. if (ptr->flags & PR_LATCH_MASK) {
  8503. ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
  8504. if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
  8505. ans = fix_problem(ctx, ldesc->question, pctx);
  8506. if (ans == 1)
  8507. ldesc->flags |= PRL_YES;
  8508. if (ans == 0)
  8509. ldesc->flags |= PRL_NO;
  8510. ldesc->flags |= PRL_LATCHED;
  8511. }
  8512. if (ldesc->flags & PRL_SUPPRESS)
  8513. suppress++;
  8514. }
  8515. if ((ptr->flags & PR_PREEN_NOMSG) &&
  8516. (ctx->options & E2F_OPT_PREEN))
  8517. suppress++;
  8518. if ((ptr->flags & PR_NO_NOMSG) &&
  8519. (ctx->options & E2F_OPT_NO))
  8520. suppress++;
  8521. if (!suppress) {
  8522. message = ptr->e2p_description;
  8523. if ((ctx->options & E2F_OPT_PREEN) &&
  8524. !(ptr->flags & PR_PREEN_NOHDR)) {
  8525. printf("%s: ", ctx->device_name ?
  8526. ctx->device_name : ctx->filesystem_name);
  8527. }
  8528. if (*message)
  8529. print_e2fsck_message(ctx, _(message), pctx, 1);
  8530. }
  8531. if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
  8532. preenhalt(ctx);
  8533. if (ptr->flags & PR_FATAL)
  8534. bb_error_msg_and_die(0);
  8535. if (ptr->prompt == PROMPT_NONE) {
  8536. if (ptr->flags & PR_NOCOLLATE)
  8537. answer = -1;
  8538. else
  8539. answer = def_yn;
  8540. } else {
  8541. if (ctx->options & E2F_OPT_PREEN) {
  8542. answer = def_yn;
  8543. if (!(ptr->flags & PR_PREEN_NOMSG))
  8544. print_answer = 1;
  8545. } else if ((ptr->flags & PR_LATCH_MASK) &&
  8546. (ldesc->flags & (PRL_YES | PRL_NO))) {
  8547. if (!suppress)
  8548. print_answer = 1;
  8549. if (ldesc->flags & PRL_YES)
  8550. answer = 1;
  8551. else
  8552. answer = 0;
  8553. } else
  8554. answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
  8555. if (!answer && !(ptr->flags & PR_NO_OK))
  8556. ext2fs_unmark_valid(fs);
  8557. if (print_answer)
  8558. printf("%s.\n", answer ?
  8559. _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
  8560. }
  8561. if ((ptr->prompt == PROMPT_ABORT) && answer)
  8562. bb_error_msg_and_die(0);
  8563. if (ptr->flags & PR_AFTER_CODE)
  8564. answer = fix_problem(ctx, ptr->second_code, pctx);
  8565. return answer;
  8566. }
  8567. /*
  8568. * linux/fs/recovery.c
  8569. *
  8570. * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
  8571. */
  8572. /*
  8573. * Maintain information about the progress of the recovery job, so that
  8574. * the different passes can carry information between them.
  8575. */
  8576. struct recovery_info
  8577. {
  8578. tid_t start_transaction;
  8579. tid_t end_transaction;
  8580. int nr_replays;
  8581. int nr_revokes;
  8582. int nr_revoke_hits;
  8583. };
  8584. enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
  8585. static int do_one_pass(journal_t *journal,
  8586. struct recovery_info *info, enum passtype pass);
  8587. static int scan_revoke_records(journal_t *, struct buffer_head *,
  8588. tid_t, struct recovery_info *);
  8589. /*
  8590. * Read a block from the journal
  8591. */
  8592. static int jread(struct buffer_head **bhp, journal_t *journal,
  8593. unsigned int offset)
  8594. {
  8595. int err;
  8596. unsigned long blocknr;
  8597. struct buffer_head *bh;
  8598. *bhp = NULL;
  8599. err = journal_bmap(journal, offset, &blocknr);
  8600. if (err) {
  8601. printf("JBD: bad block at offset %u\n", offset);
  8602. return err;
  8603. }
  8604. bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
  8605. if (!bh)
  8606. return -ENOMEM;
  8607. if (!buffer_uptodate(bh)) {
  8608. /* If this is a brand new buffer, start readahead.
  8609. Otherwise, we assume we are already reading it. */
  8610. if (!buffer_req(bh))
  8611. do_readahead(journal, offset);
  8612. wait_on_buffer(bh);
  8613. }
  8614. if (!buffer_uptodate(bh)) {
  8615. printf("JBD: Failed to read block at offset %u\n", offset);
  8616. brelse(bh);
  8617. return -EIO;
  8618. }
  8619. *bhp = bh;
  8620. return 0;
  8621. }
  8622. /*
  8623. * Count the number of in-use tags in a journal descriptor block.
  8624. */
  8625. static int count_tags(struct buffer_head *bh, int size)
  8626. {
  8627. char * tagp;
  8628. journal_block_tag_t * tag;
  8629. int nr = 0;
  8630. tagp = &bh->b_data[sizeof(journal_header_t)];
  8631. while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
  8632. tag = (journal_block_tag_t *) tagp;
  8633. nr++;
  8634. tagp += sizeof(journal_block_tag_t);
  8635. if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
  8636. tagp += 16;
  8637. if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
  8638. break;
  8639. }
  8640. return nr;
  8641. }
  8642. /* Make sure we wrap around the log correctly! */
  8643. #define wrap(journal, var) \
  8644. do { \
  8645. if (var >= (journal)->j_last) \
  8646. var -= ((journal)->j_last - (journal)->j_first); \
  8647. } while (0)
  8648. /**
  8649. * int journal_recover(journal_t *journal) - recovers a on-disk journal
  8650. * @journal: the journal to recover
  8651. *
  8652. * The primary function for recovering the log contents when mounting a
  8653. * journaled device.
  8654. *
  8655. * Recovery is done in three passes. In the first pass, we look for the
  8656. * end of the log. In the second, we assemble the list of revoke
  8657. * blocks. In the third and final pass, we replay any un-revoked blocks
  8658. * in the log.
  8659. */
  8660. int journal_recover(journal_t *journal)
  8661. {
  8662. int err;
  8663. journal_superblock_t * sb;
  8664. struct recovery_info info;
  8665. memset(&info, 0, sizeof(info));
  8666. sb = journal->j_superblock;
  8667. /*
  8668. * The journal superblock's s_start field (the current log head)
  8669. * is always zero if, and only if, the journal was cleanly
  8670. * unmounted.
  8671. */
  8672. if (!sb->s_start) {
  8673. journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
  8674. return 0;
  8675. }
  8676. err = do_one_pass(journal, &info, PASS_SCAN);
  8677. if (!err)
  8678. err = do_one_pass(journal, &info, PASS_REVOKE);
  8679. if (!err)
  8680. err = do_one_pass(journal, &info, PASS_REPLAY);
  8681. /* Restart the log at the next transaction ID, thus invalidating
  8682. * any existing commit records in the log. */
  8683. journal->j_transaction_sequence = ++info.end_transaction;
  8684. journal_clear_revoke(journal);
  8685. sync_blockdev(journal->j_fs_dev);
  8686. return err;
  8687. }
  8688. static int do_one_pass(journal_t *journal,
  8689. struct recovery_info *info, enum passtype pass)
  8690. {
  8691. unsigned int first_commit_ID, next_commit_ID;
  8692. unsigned long next_log_block;
  8693. int err, success = 0;
  8694. journal_superblock_t * sb;
  8695. journal_header_t * tmp;
  8696. struct buffer_head * bh;
  8697. unsigned int sequence;
  8698. int blocktype;
  8699. /* Precompute the maximum metadata descriptors in a descriptor block */
  8700. int MAX_BLOCKS_PER_DESC;
  8701. MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
  8702. / sizeof(journal_block_tag_t));
  8703. /*
  8704. * First thing is to establish what we expect to find in the log
  8705. * (in terms of transaction IDs), and where (in terms of log
  8706. * block offsets): query the superblock.
  8707. */
  8708. sb = journal->j_superblock;
  8709. next_commit_ID = ntohl(sb->s_sequence);
  8710. next_log_block = ntohl(sb->s_start);
  8711. first_commit_ID = next_commit_ID;
  8712. if (pass == PASS_SCAN)
  8713. info->start_transaction = first_commit_ID;
  8714. /*
  8715. * Now we walk through the log, transaction by transaction,
  8716. * making sure that each transaction has a commit block in the
  8717. * expected place. Each complete transaction gets replayed back
  8718. * into the main filesystem.
  8719. */
  8720. while (1) {
  8721. int flags;
  8722. char * tagp;
  8723. journal_block_tag_t * tag;
  8724. struct buffer_head * obh;
  8725. struct buffer_head * nbh;
  8726. /* If we already know where to stop the log traversal,
  8727. * check right now that we haven't gone past the end of
  8728. * the log. */
  8729. if (pass != PASS_SCAN)
  8730. if (tid_geq(next_commit_ID, info->end_transaction))
  8731. break;
  8732. /* Skip over each chunk of the transaction looking
  8733. * either the next descriptor block or the final commit
  8734. * record. */
  8735. err = jread(&bh, journal, next_log_block);
  8736. if (err)
  8737. goto failed;
  8738. next_log_block++;
  8739. wrap(journal, next_log_block);
  8740. /* What kind of buffer is it?
  8741. *
  8742. * If it is a descriptor block, check that it has the
  8743. * expected sequence number. Otherwise, we're all done
  8744. * here. */
  8745. tmp = (journal_header_t *)bh->b_data;
  8746. if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
  8747. brelse(bh);
  8748. break;
  8749. }
  8750. blocktype = ntohl(tmp->h_blocktype);
  8751. sequence = ntohl(tmp->h_sequence);
  8752. if (sequence != next_commit_ID) {
  8753. brelse(bh);
  8754. break;
  8755. }
  8756. /* OK, we have a valid descriptor block which matches
  8757. * all of the sequence number checks. What are we going
  8758. * to do with it? That depends on the pass... */
  8759. switch (blocktype) {
  8760. case JFS_DESCRIPTOR_BLOCK:
  8761. /* If it is a valid descriptor block, replay it
  8762. * in pass REPLAY; otherwise, just skip over the
  8763. * blocks it describes. */
  8764. if (pass != PASS_REPLAY) {
  8765. next_log_block +=
  8766. count_tags(bh, journal->j_blocksize);
  8767. wrap(journal, next_log_block);
  8768. brelse(bh);
  8769. continue;
  8770. }
  8771. /* A descriptor block: we can now write all of
  8772. * the data blocks. Yay, useful work is finally
  8773. * getting done here! */
  8774. tagp = &bh->b_data[sizeof(journal_header_t)];
  8775. while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
  8776. <= journal->j_blocksize) {
  8777. unsigned long io_block;
  8778. tag = (journal_block_tag_t *) tagp;
  8779. flags = ntohl(tag->t_flags);
  8780. io_block = next_log_block++;
  8781. wrap(journal, next_log_block);
  8782. err = jread(&obh, journal, io_block);
  8783. if (err) {
  8784. /* Recover what we can, but
  8785. * report failure at the end. */
  8786. success = err;
  8787. printf("JBD: IO error %d recovering "
  8788. "block %ld in log\n",
  8789. err, io_block);
  8790. } else {
  8791. unsigned long blocknr;
  8792. blocknr = ntohl(tag->t_blocknr);
  8793. /* If the block has been
  8794. * revoked, then we're all done
  8795. * here. */
  8796. if (journal_test_revoke
  8797. (journal, blocknr,
  8798. next_commit_ID)) {
  8799. brelse(obh);
  8800. ++info->nr_revoke_hits;
  8801. goto skip_write;
  8802. }
  8803. /* Find a buffer for the new
  8804. * data being restored */
  8805. nbh = getblk(journal->j_fs_dev,
  8806. blocknr,
  8807. journal->j_blocksize);
  8808. if (nbh == NULL) {
  8809. printf("JBD: Out of memory "
  8810. "during recovery.\n");
  8811. err = -ENOMEM;
  8812. brelse(bh);
  8813. brelse(obh);
  8814. goto failed;
  8815. }
  8816. lock_buffer(nbh);
  8817. memcpy(nbh->b_data, obh->b_data,
  8818. journal->j_blocksize);
  8819. if (flags & JFS_FLAG_ESCAPE) {
  8820. *((unsigned int *)bh->b_data) =
  8821. htonl(JFS_MAGIC_NUMBER);
  8822. }
  8823. mark_buffer_uptodate(nbh, 1);
  8824. mark_buffer_dirty(nbh);
  8825. ++info->nr_replays;
  8826. /* ll_rw_block(WRITE, 1, &nbh); */
  8827. unlock_buffer(nbh);
  8828. brelse(obh);
  8829. brelse(nbh);
  8830. }
  8831. skip_write:
  8832. tagp += sizeof(journal_block_tag_t);
  8833. if (!(flags & JFS_FLAG_SAME_UUID))
  8834. tagp += 16;
  8835. if (flags & JFS_FLAG_LAST_TAG)
  8836. break;
  8837. }
  8838. brelse(bh);
  8839. continue;
  8840. case JFS_COMMIT_BLOCK:
  8841. /* Found an expected commit block: not much to
  8842. * do other than move on to the next sequence
  8843. * number. */
  8844. brelse(bh);
  8845. next_commit_ID++;
  8846. continue;
  8847. case JFS_REVOKE_BLOCK:
  8848. /* If we aren't in the REVOKE pass, then we can
  8849. * just skip over this block. */
  8850. if (pass != PASS_REVOKE) {
  8851. brelse(bh);
  8852. continue;
  8853. }
  8854. err = scan_revoke_records(journal, bh,
  8855. next_commit_ID, info);
  8856. brelse(bh);
  8857. if (err)
  8858. goto failed;
  8859. continue;
  8860. default:
  8861. goto done;
  8862. }
  8863. }
  8864. done:
  8865. /*
  8866. * We broke out of the log scan loop: either we came to the
  8867. * known end of the log or we found an unexpected block in the
  8868. * log. If the latter happened, then we know that the "current"
  8869. * transaction marks the end of the valid log.
  8870. */
  8871. if (pass == PASS_SCAN)
  8872. info->end_transaction = next_commit_ID;
  8873. else {
  8874. /* It's really bad news if different passes end up at
  8875. * different places (but possible due to IO errors). */
  8876. if (info->end_transaction != next_commit_ID) {
  8877. printf("JBD: recovery pass %d ended at "
  8878. "transaction %u, expected %u\n",
  8879. pass, next_commit_ID, info->end_transaction);
  8880. if (!success)
  8881. success = -EIO;
  8882. }
  8883. }
  8884. return success;
  8885. failed:
  8886. return err;
  8887. }
  8888. /* Scan a revoke record, marking all blocks mentioned as revoked. */
  8889. static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
  8890. tid_t sequence, struct recovery_info *info)
  8891. {
  8892. journal_revoke_header_t *header;
  8893. int offset, max;
  8894. header = (journal_revoke_header_t *) bh->b_data;
  8895. offset = sizeof(journal_revoke_header_t);
  8896. max = ntohl(header->r_count);
  8897. while (offset < max) {
  8898. unsigned long blocknr;
  8899. int err;
  8900. blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
  8901. offset += 4;
  8902. err = journal_set_revoke(journal, blocknr, sequence);
  8903. if (err)
  8904. return err;
  8905. ++info->nr_revokes;
  8906. }
  8907. return 0;
  8908. }
  8909. /*
  8910. * rehash.c --- rebuild hash tree directories
  8911. *
  8912. * This algorithm is designed for simplicity of implementation and to
  8913. * pack the directory as much as possible. It however requires twice
  8914. * as much memory as the size of the directory. The maximum size
  8915. * directory supported using a 4k blocksize is roughly a gigabyte, and
  8916. * so there may very well be problems with machines that don't have
  8917. * virtual memory, and obscenely large directories.
  8918. *
  8919. * An alternate algorithm which is much more disk intensive could be
  8920. * written, and probably will need to be written in the future. The
  8921. * design goals of such an algorithm are: (a) use (roughly) constant
  8922. * amounts of memory, no matter how large the directory, (b) the
  8923. * directory must be safe at all times, even if e2fsck is interrupted
  8924. * in the middle, (c) we must use minimal amounts of extra disk
  8925. * blocks. This pretty much requires an incremental approach, where
  8926. * we are reading from one part of the directory, and inserting into
  8927. * the front half. So the algorithm will have to keep track of a
  8928. * moving block boundary between the new tree and the old tree, and
  8929. * files will need to be moved from the old directory and inserted
  8930. * into the new tree. If the new directory requires space which isn't
  8931. * yet available, blocks from the beginning part of the old directory
  8932. * may need to be moved to the end of the directory to make room for
  8933. * the new tree:
  8934. *
  8935. * --------------------------------------------------------
  8936. * | new tree | | old tree |
  8937. * --------------------------------------------------------
  8938. * ^ ptr ^ptr
  8939. * tail new head old
  8940. *
  8941. * This is going to be a pain in the tuckus to implement, and will
  8942. * require a lot more disk accesses. So I'm going to skip it for now;
  8943. * it's only really going to be an issue for really, really big
  8944. * filesystems (when we reach the level of tens of millions of files
  8945. * in a single directory). It will probably be easier to simply
  8946. * require that e2fsck use VM first.
  8947. */
  8948. struct fill_dir_struct {
  8949. char *buf;
  8950. struct ext2_inode *inode;
  8951. int err;
  8952. e2fsck_t ctx;
  8953. struct hash_entry *harray;
  8954. int max_array, num_array;
  8955. int dir_size;
  8956. int compress;
  8957. ino_t parent;
  8958. };
  8959. struct hash_entry {
  8960. ext2_dirhash_t hash;
  8961. ext2_dirhash_t minor_hash;
  8962. struct ext2_dir_entry *dir;
  8963. };
  8964. struct out_dir {
  8965. int num;
  8966. int max;
  8967. char *buf;
  8968. ext2_dirhash_t *hashes;
  8969. };
  8970. static int fill_dir_block(ext2_filsys fs,
  8971. blk_t *block_nr,
  8972. e2_blkcnt_t blockcnt,
  8973. blk_t ref_block FSCK_ATTR((unused)),
  8974. int ref_offset FSCK_ATTR((unused)),
  8975. void *priv_data)
  8976. {
  8977. struct fill_dir_struct *fd = (struct fill_dir_struct *) priv_data;
  8978. struct hash_entry *new_array, *ent;
  8979. struct ext2_dir_entry *dirent;
  8980. char *dir;
  8981. unsigned int offset, dir_offset;
  8982. if (blockcnt < 0)
  8983. return 0;
  8984. offset = blockcnt * fs->blocksize;
  8985. if (offset + fs->blocksize > fd->inode->i_size) {
  8986. fd->err = EXT2_ET_DIR_CORRUPTED;
  8987. return BLOCK_ABORT;
  8988. }
  8989. dir = (fd->buf+offset);
  8990. if (HOLE_BLKADDR(*block_nr)) {
  8991. memset(dir, 0, fs->blocksize);
  8992. dirent = (struct ext2_dir_entry *) dir;
  8993. dirent->rec_len = fs->blocksize;
  8994. } else {
  8995. fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
  8996. if (fd->err)
  8997. return BLOCK_ABORT;
  8998. }
  8999. /* While the directory block is "hot", index it. */
  9000. dir_offset = 0;
  9001. while (dir_offset < fs->blocksize) {
  9002. dirent = (struct ext2_dir_entry *) (dir + dir_offset);
  9003. if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
  9004. (dirent->rec_len < 8) ||
  9005. ((dirent->rec_len % 4) != 0) ||
  9006. (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
  9007. fd->err = EXT2_ET_DIR_CORRUPTED;
  9008. return BLOCK_ABORT;
  9009. }
  9010. dir_offset += dirent->rec_len;
  9011. if (dirent->inode == 0)
  9012. continue;
  9013. if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
  9014. (dirent->name[0] == '.'))
  9015. continue;
  9016. if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
  9017. (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
  9018. fd->parent = dirent->inode;
  9019. continue;
  9020. }
  9021. if (fd->num_array >= fd->max_array) {
  9022. new_array = xrealloc(fd->harray,
  9023. sizeof(struct hash_entry) * (fd->max_array+500));
  9024. fd->harray = new_array;
  9025. fd->max_array += 500;
  9026. }
  9027. ent = fd->harray + fd->num_array++;
  9028. ent->dir = dirent;
  9029. fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
  9030. if (fd->compress)
  9031. ent->hash = ent->minor_hash = 0;
  9032. else {
  9033. fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
  9034. dirent->name,
  9035. dirent->name_len & 0xFF,
  9036. fs->super->s_hash_seed,
  9037. &ent->hash, &ent->minor_hash);
  9038. if (fd->err)
  9039. return BLOCK_ABORT;
  9040. }
  9041. }
  9042. return 0;
  9043. }
  9044. /* Used for sorting the hash entry */
  9045. static int name_cmp(const void *a, const void *b)
  9046. {
  9047. const struct hash_entry *he_a = (const struct hash_entry *) a;
  9048. const struct hash_entry *he_b = (const struct hash_entry *) b;
  9049. int ret;
  9050. int min_len;
  9051. min_len = he_a->dir->name_len;
  9052. if (min_len > he_b->dir->name_len)
  9053. min_len = he_b->dir->name_len;
  9054. ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
  9055. if (ret == 0) {
  9056. if (he_a->dir->name_len > he_b->dir->name_len)
  9057. ret = 1;
  9058. else if (he_a->dir->name_len < he_b->dir->name_len)
  9059. ret = -1;
  9060. else
  9061. ret = he_b->dir->inode - he_a->dir->inode;
  9062. }
  9063. return ret;
  9064. }
  9065. /* Used for sorting the hash entry */
  9066. static int hash_cmp(const void *a, const void *b)
  9067. {
  9068. const struct hash_entry *he_a = (const struct hash_entry *) a;
  9069. const struct hash_entry *he_b = (const struct hash_entry *) b;
  9070. int ret;
  9071. if (he_a->hash > he_b->hash)
  9072. ret = 1;
  9073. else if (he_a->hash < he_b->hash)
  9074. ret = -1;
  9075. else {
  9076. if (he_a->minor_hash > he_b->minor_hash)
  9077. ret = 1;
  9078. else if (he_a->minor_hash < he_b->minor_hash)
  9079. ret = -1;
  9080. else
  9081. ret = name_cmp(a, b);
  9082. }
  9083. return ret;
  9084. }
  9085. static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
  9086. int blocks)
  9087. {
  9088. void *new_mem;
  9089. if (outdir->max) {
  9090. new_mem = xrealloc(outdir->buf, blocks * fs->blocksize);
  9091. outdir->buf = new_mem;
  9092. new_mem = xrealloc(outdir->hashes,
  9093. blocks * sizeof(ext2_dirhash_t));
  9094. outdir->hashes = new_mem;
  9095. } else {
  9096. outdir->buf = xmalloc(blocks * fs->blocksize);
  9097. outdir->hashes = xmalloc(blocks * sizeof(ext2_dirhash_t));
  9098. outdir->num = 0;
  9099. }
  9100. outdir->max = blocks;
  9101. return 0;
  9102. }
  9103. static void free_out_dir(struct out_dir *outdir)
  9104. {
  9105. free(outdir->buf);
  9106. free(outdir->hashes);
  9107. outdir->max = 0;
  9108. outdir->num =0;
  9109. }
  9110. static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
  9111. char ** ret)
  9112. {
  9113. errcode_t retval;
  9114. if (outdir->num >= outdir->max) {
  9115. retval = alloc_size_dir(fs, outdir, outdir->max + 50);
  9116. if (retval)
  9117. return retval;
  9118. }
  9119. *ret = outdir->buf + (outdir->num++ * fs->blocksize);
  9120. memset(*ret, 0, fs->blocksize);
  9121. return 0;
  9122. }
  9123. /*
  9124. * This function is used to make a unique filename. We do this by
  9125. * appending ~0, and then incrementing the number. However, we cannot
  9126. * expand the length of the filename beyond the padding available in
  9127. * the directory entry.
  9128. */
  9129. static void mutate_name(char *str, __u16 *len)
  9130. {
  9131. int i;
  9132. __u16 l = *len & 0xFF, h = *len & 0xff00;
  9133. /*
  9134. * First check to see if it looks the name has been mutated
  9135. * already
  9136. */
  9137. for (i = l-1; i > 0; i--) {
  9138. if (!isdigit(str[i]))
  9139. break;
  9140. }
  9141. if ((i == l-1) || (str[i] != '~')) {
  9142. if (((l-1) & 3) < 2)
  9143. l += 2;
  9144. else
  9145. l = (l+3) & ~3;
  9146. str[l-2] = '~';
  9147. str[l-1] = '0';
  9148. *len = l | h;
  9149. return;
  9150. }
  9151. for (i = l-1; i >= 0; i--) {
  9152. if (isdigit(str[i])) {
  9153. if (str[i] == '9')
  9154. str[i] = '0';
  9155. else {
  9156. str[i]++;
  9157. return;
  9158. }
  9159. continue;
  9160. }
  9161. if (i == 1) {
  9162. if (str[0] == 'z')
  9163. str[0] = 'A';
  9164. else if (str[0] == 'Z') {
  9165. str[0] = '~';
  9166. str[1] = '0';
  9167. } else
  9168. str[0]++;
  9169. } else if (i > 0) {
  9170. str[i] = '1';
  9171. str[i-1] = '~';
  9172. } else {
  9173. if (str[0] == '~')
  9174. str[0] = 'a';
  9175. else
  9176. str[0]++;
  9177. }
  9178. break;
  9179. }
  9180. }
  9181. static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
  9182. ext2_ino_t ino,
  9183. struct fill_dir_struct *fd)
  9184. {
  9185. struct problem_context pctx;
  9186. struct hash_entry *ent, *prev;
  9187. int i, j;
  9188. int fixed = 0;
  9189. char new_name[256];
  9190. __u16 new_len;
  9191. clear_problem_context(&pctx);
  9192. pctx.ino = ino;
  9193. for (i=1; i < fd->num_array; i++) {
  9194. ent = fd->harray + i;
  9195. prev = ent - 1;
  9196. if (!ent->dir->inode ||
  9197. ((ent->dir->name_len & 0xFF) !=
  9198. (prev->dir->name_len & 0xFF)) ||
  9199. (strncmp(ent->dir->name, prev->dir->name,
  9200. ent->dir->name_len & 0xFF)))
  9201. continue;
  9202. pctx.dirent = ent->dir;
  9203. if ((ent->dir->inode == prev->dir->inode) &&
  9204. fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
  9205. e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
  9206. ent->dir->inode = 0;
  9207. fixed++;
  9208. continue;
  9209. }
  9210. memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
  9211. new_len = ent->dir->name_len;
  9212. mutate_name(new_name, &new_len);
  9213. for (j=0; j < fd->num_array; j++) {
  9214. if ((i==j) ||
  9215. ((ent->dir->name_len & 0xFF) !=
  9216. (fd->harray[j].dir->name_len & 0xFF)) ||
  9217. (strncmp(new_name, fd->harray[j].dir->name,
  9218. new_len & 0xFF)))
  9219. continue;
  9220. mutate_name(new_name, &new_len);
  9221. j = -1;
  9222. }
  9223. new_name[new_len & 0xFF] = 0;
  9224. pctx.str = new_name;
  9225. if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
  9226. memcpy(ent->dir->name, new_name, new_len & 0xFF);
  9227. ent->dir->name_len = new_len;
  9228. ext2fs_dirhash(fs->super->s_def_hash_version,
  9229. ent->dir->name,
  9230. ent->dir->name_len & 0xFF,
  9231. fs->super->s_hash_seed,
  9232. &ent->hash, &ent->minor_hash);
  9233. fixed++;
  9234. }
  9235. }
  9236. return fixed;
  9237. }
  9238. static errcode_t copy_dir_entries(ext2_filsys fs,
  9239. struct fill_dir_struct *fd,
  9240. struct out_dir *outdir)
  9241. {
  9242. errcode_t retval;
  9243. char *block_start;
  9244. struct hash_entry *ent;
  9245. struct ext2_dir_entry *dirent;
  9246. int i, rec_len, left;
  9247. ext2_dirhash_t prev_hash;
  9248. int offset;
  9249. outdir->max = 0;
  9250. retval = alloc_size_dir(fs, outdir,
  9251. (fd->dir_size / fs->blocksize) + 2);
  9252. if (retval)
  9253. return retval;
  9254. outdir->num = fd->compress ? 0 : 1;
  9255. offset = 0;
  9256. outdir->hashes[0] = 0;
  9257. prev_hash = 1;
  9258. if ((retval = get_next_block(fs, outdir, &block_start)))
  9259. return retval;
  9260. dirent = (struct ext2_dir_entry *) block_start;
  9261. left = fs->blocksize;
  9262. for (i=0; i < fd->num_array; i++) {
  9263. ent = fd->harray + i;
  9264. if (ent->dir->inode == 0)
  9265. continue;
  9266. rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
  9267. if (rec_len > left) {
  9268. if (left)
  9269. dirent->rec_len += left;
  9270. if ((retval = get_next_block(fs, outdir,
  9271. &block_start)))
  9272. return retval;
  9273. offset = 0;
  9274. }
  9275. left = fs->blocksize - offset;
  9276. dirent = (struct ext2_dir_entry *) (block_start + offset);
  9277. if (offset == 0) {
  9278. if (ent->hash == prev_hash)
  9279. outdir->hashes[outdir->num-1] = ent->hash | 1;
  9280. else
  9281. outdir->hashes[outdir->num-1] = ent->hash;
  9282. }
  9283. dirent->inode = ent->dir->inode;
  9284. dirent->name_len = ent->dir->name_len;
  9285. dirent->rec_len = rec_len;
  9286. memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
  9287. offset += rec_len;
  9288. left -= rec_len;
  9289. if (left < 12) {
  9290. dirent->rec_len += left;
  9291. offset += left;
  9292. left = 0;
  9293. }
  9294. prev_hash = ent->hash;
  9295. }
  9296. if (left)
  9297. dirent->rec_len += left;
  9298. return 0;
  9299. }
  9300. static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
  9301. ext2_ino_t ino, ext2_ino_t parent)
  9302. {
  9303. struct ext2_dir_entry *dir;
  9304. struct ext2_dx_root_info *root;
  9305. struct ext2_dx_countlimit *limits;
  9306. int filetype = 0;
  9307. if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
  9308. filetype = EXT2_FT_DIR << 8;
  9309. memset(buf, 0, fs->blocksize);
  9310. dir = (struct ext2_dir_entry *) buf;
  9311. dir->inode = ino;
  9312. dir->name[0] = '.';
  9313. dir->name_len = 1 | filetype;
  9314. dir->rec_len = 12;
  9315. dir = (struct ext2_dir_entry *) (buf + 12);
  9316. dir->inode = parent;
  9317. dir->name[0] = '.';
  9318. dir->name[1] = '.';
  9319. dir->name_len = 2 | filetype;
  9320. dir->rec_len = fs->blocksize - 12;
  9321. root = (struct ext2_dx_root_info *) (buf+24);
  9322. root->reserved_zero = 0;
  9323. root->hash_version = fs->super->s_def_hash_version;
  9324. root->info_length = 8;
  9325. root->indirect_levels = 0;
  9326. root->unused_flags = 0;
  9327. limits = (struct ext2_dx_countlimit *) (buf+32);
  9328. limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
  9329. limits->count = 0;
  9330. return root;
  9331. }
  9332. static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
  9333. {
  9334. struct ext2_dir_entry *dir;
  9335. struct ext2_dx_countlimit *limits;
  9336. memset(buf, 0, fs->blocksize);
  9337. dir = (struct ext2_dir_entry *) buf;
  9338. dir->inode = 0;
  9339. dir->rec_len = fs->blocksize;
  9340. limits = (struct ext2_dx_countlimit *) (buf+8);
  9341. limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
  9342. limits->count = 0;
  9343. return (struct ext2_dx_entry *) limits;
  9344. }
  9345. /*
  9346. * This function takes the leaf nodes which have been written in
  9347. * outdir, and populates the root node and any necessary interior nodes.
  9348. */
  9349. static errcode_t calculate_tree(ext2_filsys fs,
  9350. struct out_dir *outdir,
  9351. ext2_ino_t ino,
  9352. ext2_ino_t parent)
  9353. {
  9354. struct ext2_dx_root_info *root_info;
  9355. struct ext2_dx_entry *root, *dx_ent = NULL;
  9356. struct ext2_dx_countlimit *root_limit, *limit;
  9357. errcode_t retval;
  9358. char * block_start;
  9359. int i, c1, c2, nblks;
  9360. int limit_offset, root_offset;
  9361. root_info = set_root_node(fs, outdir->buf, ino, parent);
  9362. root_offset = limit_offset = ((char *) root_info - outdir->buf) +
  9363. root_info->info_length;
  9364. root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
  9365. c1 = root_limit->limit;
  9366. nblks = outdir->num;
  9367. /* Write out the pointer blocks */
  9368. if (nblks-1 <= c1) {
  9369. /* Just write out the root block, and we're done */
  9370. root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
  9371. for (i=1; i < nblks; i++) {
  9372. root->block = ext2fs_cpu_to_le32(i);
  9373. if (i != 1)
  9374. root->hash =
  9375. ext2fs_cpu_to_le32(outdir->hashes[i]);
  9376. root++;
  9377. c1--;
  9378. }
  9379. } else {
  9380. c2 = 0;
  9381. limit = 0;
  9382. root_info->indirect_levels = 1;
  9383. for (i=1; i < nblks; i++) {
  9384. if (c1 == 0)
  9385. return ENOSPC;
  9386. if (c2 == 0) {
  9387. if (limit)
  9388. limit->limit = limit->count =
  9389. ext2fs_cpu_to_le16(limit->limit);
  9390. root = (struct ext2_dx_entry *)
  9391. (outdir->buf + root_offset);
  9392. root->block = ext2fs_cpu_to_le32(outdir->num);
  9393. if (i != 1)
  9394. root->hash =
  9395. ext2fs_cpu_to_le32(outdir->hashes[i]);
  9396. if ((retval = get_next_block(fs, outdir,
  9397. &block_start)))
  9398. return retval;
  9399. dx_ent = set_int_node(fs, block_start);
  9400. limit = (struct ext2_dx_countlimit *) dx_ent;
  9401. c2 = limit->limit;
  9402. root_offset += sizeof(struct ext2_dx_entry);
  9403. c1--;
  9404. }
  9405. dx_ent->block = ext2fs_cpu_to_le32(i);
  9406. if (c2 != limit->limit)
  9407. dx_ent->hash =
  9408. ext2fs_cpu_to_le32(outdir->hashes[i]);
  9409. dx_ent++;
  9410. c2--;
  9411. }
  9412. limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
  9413. limit->limit = ext2fs_cpu_to_le16(limit->limit);
  9414. }
  9415. root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
  9416. root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
  9417. root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
  9418. return 0;
  9419. }
  9420. struct write_dir_struct {
  9421. struct out_dir *outdir;
  9422. errcode_t err;
  9423. e2fsck_t ctx;
  9424. int cleared;
  9425. };
  9426. /*
  9427. * Helper function which writes out a directory block.
  9428. */
  9429. static int write_dir_block(ext2_filsys fs,
  9430. blk_t *block_nr,
  9431. e2_blkcnt_t blockcnt,
  9432. blk_t ref_block FSCK_ATTR((unused)),
  9433. int ref_offset FSCK_ATTR((unused)),
  9434. void *priv_data)
  9435. {
  9436. struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
  9437. blk_t blk;
  9438. char *dir;
  9439. if (*block_nr == 0)
  9440. return 0;
  9441. if (blockcnt >= wd->outdir->num) {
  9442. e2fsck_read_bitmaps(wd->ctx);
  9443. blk = *block_nr;
  9444. ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
  9445. ext2fs_block_alloc_stats(fs, blk, -1);
  9446. *block_nr = 0;
  9447. wd->cleared++;
  9448. return BLOCK_CHANGED;
  9449. }
  9450. if (blockcnt < 0)
  9451. return 0;
  9452. dir = wd->outdir->buf + (blockcnt * fs->blocksize);
  9453. wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
  9454. if (wd->err)
  9455. return BLOCK_ABORT;
  9456. return 0;
  9457. }
  9458. static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
  9459. struct out_dir *outdir,
  9460. ext2_ino_t ino, int compress)
  9461. {
  9462. struct write_dir_struct wd;
  9463. errcode_t retval;
  9464. struct ext2_inode inode;
  9465. retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
  9466. if (retval)
  9467. return retval;
  9468. wd.outdir = outdir;
  9469. wd.err = 0;
  9470. wd.ctx = ctx;
  9471. wd.cleared = 0;
  9472. retval = ext2fs_block_iterate2(fs, ino, 0, 0,
  9473. write_dir_block, &wd);
  9474. if (retval)
  9475. return retval;
  9476. if (wd.err)
  9477. return wd.err;
  9478. e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
  9479. if (compress)
  9480. inode.i_flags &= ~EXT2_INDEX_FL;
  9481. else
  9482. inode.i_flags |= EXT2_INDEX_FL;
  9483. inode.i_size = outdir->num * fs->blocksize;
  9484. inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
  9485. e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
  9486. return 0;
  9487. }
  9488. static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
  9489. {
  9490. ext2_filsys fs = ctx->fs;
  9491. errcode_t retval;
  9492. struct ext2_inode inode;
  9493. char *dir_buf = NULL;
  9494. struct fill_dir_struct fd;
  9495. struct out_dir outdir;
  9496. outdir.max = outdir.num = 0;
  9497. outdir.buf = 0;
  9498. outdir.hashes = 0;
  9499. e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
  9500. retval = ENOMEM;
  9501. fd.harray = 0;
  9502. dir_buf = xmalloc(inode.i_size);
  9503. fd.max_array = inode.i_size / 32;
  9504. fd.num_array = 0;
  9505. fd.harray = xmalloc(fd.max_array * sizeof(struct hash_entry));
  9506. fd.ctx = ctx;
  9507. fd.buf = dir_buf;
  9508. fd.inode = &inode;
  9509. fd.err = 0;
  9510. fd.dir_size = 0;
  9511. fd.compress = 0;
  9512. if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
  9513. (inode.i_size / fs->blocksize) < 2)
  9514. fd.compress = 1;
  9515. fd.parent = 0;
  9516. /* Read in the entire directory into memory */
  9517. retval = ext2fs_block_iterate2(fs, ino, 0, 0,
  9518. fill_dir_block, &fd);
  9519. if (fd.err) {
  9520. retval = fd.err;
  9521. goto errout;
  9522. }
  9523. /* Sort the list */
  9524. resort:
  9525. if (fd.compress)
  9526. qsort(fd.harray+2, fd.num_array-2,
  9527. sizeof(struct hash_entry), name_cmp);
  9528. else
  9529. qsort(fd.harray, fd.num_array,
  9530. sizeof(struct hash_entry), hash_cmp);
  9531. /*
  9532. * Look for duplicates
  9533. */
  9534. if (duplicate_search_and_fix(ctx, fs, ino, &fd))
  9535. goto resort;
  9536. if (ctx->options & E2F_OPT_NO) {
  9537. retval = 0;
  9538. goto errout;
  9539. }
  9540. /*
  9541. * Copy the directory entries. In a htree directory these
  9542. * will become the leaf nodes.
  9543. */
  9544. retval = copy_dir_entries(fs, &fd, &outdir);
  9545. if (retval)
  9546. goto errout;
  9547. free(dir_buf); dir_buf = 0;
  9548. if (!fd.compress) {
  9549. /* Calculate the interior nodes */
  9550. retval = calculate_tree(fs, &outdir, ino, fd.parent);
  9551. if (retval)
  9552. goto errout;
  9553. }
  9554. retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
  9555. errout:
  9556. free(dir_buf);
  9557. free(fd.harray);
  9558. free_out_dir(&outdir);
  9559. return retval;
  9560. }
  9561. void e2fsck_rehash_directories(e2fsck_t ctx)
  9562. {
  9563. struct problem_context pctx;
  9564. struct dir_info *dir;
  9565. ext2_u32_iterate iter;
  9566. ext2_ino_t ino;
  9567. errcode_t retval;
  9568. int i, cur, max, all_dirs, dir_index, first = 1;
  9569. all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
  9570. if (!ctx->dirs_to_hash && !all_dirs)
  9571. return;
  9572. e2fsck_get_lost_and_found(ctx, 0);
  9573. clear_problem_context(&pctx);
  9574. dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
  9575. cur = 0;
  9576. if (all_dirs) {
  9577. i = 0;
  9578. max = e2fsck_get_num_dirinfo(ctx);
  9579. } else {
  9580. retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
  9581. &iter);
  9582. if (retval) {
  9583. pctx.errcode = retval;
  9584. fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
  9585. return;
  9586. }
  9587. max = ext2fs_u32_list_count(ctx->dirs_to_hash);
  9588. }
  9589. while (1) {
  9590. if (all_dirs) {
  9591. if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
  9592. break;
  9593. ino = dir->ino;
  9594. } else {
  9595. if (!ext2fs_u32_list_iterate(iter, &ino))
  9596. break;
  9597. }
  9598. if (ino == ctx->lost_and_found)
  9599. continue;
  9600. pctx.dir = ino;
  9601. if (first) {
  9602. fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
  9603. first = 0;
  9604. }
  9605. pctx.errcode = e2fsck_rehash_dir(ctx, ino);
  9606. if (pctx.errcode) {
  9607. end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
  9608. fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
  9609. }
  9610. if (ctx->progress && !ctx->progress_fd)
  9611. e2fsck_simple_progress(ctx, "Rebuilding directory",
  9612. 100.0 * (float) (++cur) / (float) max, ino);
  9613. }
  9614. end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
  9615. if (!all_dirs)
  9616. ext2fs_u32_list_iterate_end(iter);
  9617. ext2fs_u32_list_free(ctx->dirs_to_hash);
  9618. ctx->dirs_to_hash = 0;
  9619. }
  9620. /*
  9621. * linux/fs/revoke.c
  9622. *
  9623. * Journal revoke routines for the generic filesystem journaling code;
  9624. * part of the ext2fs journaling system.
  9625. *
  9626. * Revoke is the mechanism used to prevent old log records for deleted
  9627. * metadata from being replayed on top of newer data using the same
  9628. * blocks. The revoke mechanism is used in two separate places:
  9629. *
  9630. * + Commit: during commit we write the entire list of the current
  9631. * transaction's revoked blocks to the journal
  9632. *
  9633. * + Recovery: during recovery we record the transaction ID of all
  9634. * revoked blocks. If there are multiple revoke records in the log
  9635. * for a single block, only the last one counts, and if there is a log
  9636. * entry for a block beyond the last revoke, then that log entry still
  9637. * gets replayed.
  9638. *
  9639. * We can get interactions between revokes and new log data within a
  9640. * single transaction:
  9641. *
  9642. * Block is revoked and then journaled:
  9643. * The desired end result is the journaling of the new block, so we
  9644. * cancel the revoke before the transaction commits.
  9645. *
  9646. * Block is journaled and then revoked:
  9647. * The revoke must take precedence over the write of the block, so we
  9648. * need either to cancel the journal entry or to write the revoke
  9649. * later in the log than the log block. In this case, we choose the
  9650. * latter: journaling a block cancels any revoke record for that block
  9651. * in the current transaction, so any revoke for that block in the
  9652. * transaction must have happened after the block was journaled and so
  9653. * the revoke must take precedence.
  9654. *
  9655. * Block is revoked and then written as data:
  9656. * The data write is allowed to succeed, but the revoke is _not_
  9657. * cancelled. We still need to prevent old log records from
  9658. * overwriting the new data. We don't even need to clear the revoke
  9659. * bit here.
  9660. *
  9661. * Revoke information on buffers is a tri-state value:
  9662. *
  9663. * RevokeValid clear: no cached revoke status, need to look it up
  9664. * RevokeValid set, Revoked clear:
  9665. * buffer has not been revoked, and cancel_revoke
  9666. * need do nothing.
  9667. * RevokeValid set, Revoked set:
  9668. * buffer has been revoked.
  9669. */
  9670. static kmem_cache_t *revoke_record_cache;
  9671. static kmem_cache_t *revoke_table_cache;
  9672. /* Each revoke record represents one single revoked block. During
  9673. journal replay, this involves recording the transaction ID of the
  9674. last transaction to revoke this block. */
  9675. struct jbd_revoke_record_s
  9676. {
  9677. struct list_head hash;
  9678. tid_t sequence; /* Used for recovery only */
  9679. unsigned long blocknr;
  9680. };
  9681. /* The revoke table is just a simple hash table of revoke records. */
  9682. struct jbd_revoke_table_s
  9683. {
  9684. /* It is conceivable that we might want a larger hash table
  9685. * for recovery. Must be a power of two. */
  9686. int hash_size;
  9687. int hash_shift;
  9688. struct list_head *hash_table;
  9689. };
  9690. /* Utility functions to maintain the revoke table */
  9691. /* Borrowed from buffer.c: this is a tried and tested block hash function */
  9692. static int hash(journal_t *journal, unsigned long block)
  9693. {
  9694. struct jbd_revoke_table_s *table = journal->j_revoke;
  9695. int hash_shift = table->hash_shift;
  9696. return ((block << (hash_shift - 6)) ^
  9697. (block >> 13) ^
  9698. (block << (hash_shift - 12))) & (table->hash_size - 1);
  9699. }
  9700. static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
  9701. tid_t seq)
  9702. {
  9703. struct list_head *hash_list;
  9704. struct jbd_revoke_record_s *record;
  9705. record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
  9706. if (!record)
  9707. goto oom;
  9708. record->sequence = seq;
  9709. record->blocknr = blocknr;
  9710. hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
  9711. list_add(&record->hash, hash_list);
  9712. return 0;
  9713. oom:
  9714. return -ENOMEM;
  9715. }
  9716. /* Find a revoke record in the journal's hash table. */
  9717. static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
  9718. unsigned long blocknr)
  9719. {
  9720. struct list_head *hash_list;
  9721. struct jbd_revoke_record_s *record;
  9722. hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
  9723. record = (struct jbd_revoke_record_s *) hash_list->next;
  9724. while (&(record->hash) != hash_list) {
  9725. if (record->blocknr == blocknr)
  9726. return record;
  9727. record = (struct jbd_revoke_record_s *) record->hash.next;
  9728. }
  9729. return NULL;
  9730. }
  9731. int journal_init_revoke_caches(void)
  9732. {
  9733. revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s));
  9734. if (revoke_record_cache == 0)
  9735. return -ENOMEM;
  9736. revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s));
  9737. if (revoke_table_cache == 0) {
  9738. do_cache_destroy(revoke_record_cache);
  9739. revoke_record_cache = NULL;
  9740. return -ENOMEM;
  9741. }
  9742. return 0;
  9743. }
  9744. void journal_destroy_revoke_caches(void)
  9745. {
  9746. do_cache_destroy(revoke_record_cache);
  9747. revoke_record_cache = 0;
  9748. do_cache_destroy(revoke_table_cache);
  9749. revoke_table_cache = 0;
  9750. }
  9751. /* Initialise the revoke table for a given journal to a given size. */
  9752. int journal_init_revoke(journal_t *journal, int hash_size)
  9753. {
  9754. int shift, tmp;
  9755. journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
  9756. if (!journal->j_revoke)
  9757. return -ENOMEM;
  9758. /* Check that the hash_size is a power of two */
  9759. journal->j_revoke->hash_size = hash_size;
  9760. shift = 0;
  9761. tmp = hash_size;
  9762. while ((tmp >>= 1UL) != 0UL)
  9763. shift++;
  9764. journal->j_revoke->hash_shift = shift;
  9765. journal->j_revoke->hash_table = xmalloc(hash_size * sizeof(struct list_head));
  9766. for (tmp = 0; tmp < hash_size; tmp++)
  9767. INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
  9768. return 0;
  9769. }
  9770. /* Destoy a journal's revoke table. The table must already be empty! */
  9771. void journal_destroy_revoke(journal_t *journal)
  9772. {
  9773. struct jbd_revoke_table_s *table;
  9774. struct list_head *hash_list;
  9775. int i;
  9776. table = journal->j_revoke;
  9777. if (!table)
  9778. return;
  9779. for (i=0; i<table->hash_size; i++) {
  9780. hash_list = &table->hash_table[i];
  9781. }
  9782. free(table->hash_table);
  9783. free(table);
  9784. journal->j_revoke = NULL;
  9785. }
  9786. /*
  9787. * Revoke support for recovery.
  9788. *
  9789. * Recovery needs to be able to:
  9790. *
  9791. * record all revoke records, including the tid of the latest instance
  9792. * of each revoke in the journal
  9793. *
  9794. * check whether a given block in a given transaction should be replayed
  9795. * (ie. has not been revoked by a revoke record in that or a subsequent
  9796. * transaction)
  9797. *
  9798. * empty the revoke table after recovery.
  9799. */
  9800. /*
  9801. * First, setting revoke records. We create a new revoke record for
  9802. * every block ever revoked in the log as we scan it for recovery, and
  9803. * we update the existing records if we find multiple revokes for a
  9804. * single block.
  9805. */
  9806. int journal_set_revoke(journal_t *journal, unsigned long blocknr,
  9807. tid_t sequence)
  9808. {
  9809. struct jbd_revoke_record_s *record;
  9810. record = find_revoke_record(journal, blocknr);
  9811. if (record) {
  9812. /* If we have multiple occurences, only record the
  9813. * latest sequence number in the hashed record */
  9814. if (tid_gt(sequence, record->sequence))
  9815. record->sequence = sequence;
  9816. return 0;
  9817. }
  9818. return insert_revoke_hash(journal, blocknr, sequence);
  9819. }
  9820. /*
  9821. * Test revoke records. For a given block referenced in the log, has
  9822. * that block been revoked? A revoke record with a given transaction
  9823. * sequence number revokes all blocks in that transaction and earlier
  9824. * ones, but later transactions still need replayed.
  9825. */
  9826. int journal_test_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. return 0;
  9833. if (tid_gt(sequence, record->sequence))
  9834. return 0;
  9835. return 1;
  9836. }
  9837. /*
  9838. * Finally, once recovery is over, we need to clear the revoke table so
  9839. * that it can be reused by the running filesystem.
  9840. */
  9841. void journal_clear_revoke(journal_t *journal)
  9842. {
  9843. int i;
  9844. struct list_head *hash_list;
  9845. struct jbd_revoke_record_s *record;
  9846. struct jbd_revoke_table_s *revoke_var;
  9847. revoke_var = journal->j_revoke;
  9848. for (i = 0; i < revoke_var->hash_size; i++) {
  9849. hash_list = &revoke_var->hash_table[i];
  9850. while (!list_empty(hash_list)) {
  9851. record = (struct jbd_revoke_record_s*) hash_list->next;
  9852. list_del(&record->hash);
  9853. free(record);
  9854. }
  9855. }
  9856. }
  9857. /*
  9858. * e2fsck.c - superblock checks
  9859. */
  9860. #define MIN_CHECK 1
  9861. #define MAX_CHECK 2
  9862. static void check_super_value(e2fsck_t ctx, const char *descr,
  9863. unsigned long value, int flags,
  9864. unsigned long min_val, unsigned long max_val)
  9865. {
  9866. struct problem_context pctx;
  9867. if (((flags & MIN_CHECK) && (value < min_val)) ||
  9868. ((flags & MAX_CHECK) && (value > max_val))) {
  9869. clear_problem_context(&pctx);
  9870. pctx.num = value;
  9871. pctx.str = descr;
  9872. fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
  9873. ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
  9874. }
  9875. }
  9876. /*
  9877. * This routine may get stubbed out in special compilations of the
  9878. * e2fsck code..
  9879. */
  9880. #ifndef EXT2_SPECIAL_DEVICE_SIZE
  9881. static errcode_t e2fsck_get_device_size(e2fsck_t ctx)
  9882. {
  9883. return (ext2fs_get_device_size(ctx->filesystem_name,
  9884. EXT2_BLOCK_SIZE(ctx->fs->super),
  9885. &ctx->num_blocks));
  9886. }
  9887. #endif
  9888. /*
  9889. * helper function to release an inode
  9890. */
  9891. struct process_block_struct {
  9892. e2fsck_t ctx;
  9893. char *buf;
  9894. struct problem_context *pctx;
  9895. int truncating;
  9896. int truncate_offset;
  9897. e2_blkcnt_t truncate_block;
  9898. int truncated_blocks;
  9899. int abort;
  9900. errcode_t errcode;
  9901. };
  9902. static int release_inode_block(ext2_filsys fs, blk_t *block_nr,
  9903. e2_blkcnt_t blockcnt,
  9904. blk_t ref_blk FSCK_ATTR((unused)),
  9905. int ref_offset FSCK_ATTR((unused)),
  9906. void *priv_data)
  9907. {
  9908. struct process_block_struct *pb;
  9909. e2fsck_t ctx;
  9910. struct problem_context *pctx;
  9911. blk_t blk = *block_nr;
  9912. int retval = 0;
  9913. pb = (struct process_block_struct *) priv_data;
  9914. ctx = pb->ctx;
  9915. pctx = pb->pctx;
  9916. pctx->blk = blk;
  9917. pctx->blkcount = blockcnt;
  9918. if (HOLE_BLKADDR(blk))
  9919. return 0;
  9920. if ((blk < fs->super->s_first_data_block) ||
  9921. (blk >= fs->super->s_blocks_count)) {
  9922. fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
  9923. return_abort:
  9924. pb->abort = 1;
  9925. return BLOCK_ABORT;
  9926. }
  9927. if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
  9928. fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
  9929. goto return_abort;
  9930. }
  9931. /*
  9932. * If we are deleting an orphan, then we leave the fields alone.
  9933. * If we are truncating an orphan, then update the inode fields
  9934. * and clean up any partial block data.
  9935. */
  9936. if (pb->truncating) {
  9937. /*
  9938. * We only remove indirect blocks if they are
  9939. * completely empty.
  9940. */
  9941. if (blockcnt < 0) {
  9942. int i, limit;
  9943. blk_t *bp;
  9944. pb->errcode = io_channel_read_blk(fs->io, blk, 1,
  9945. pb->buf);
  9946. if (pb->errcode)
  9947. goto return_abort;
  9948. limit = fs->blocksize >> 2;
  9949. for (i = 0, bp = (blk_t *) pb->buf;
  9950. i < limit; i++, bp++)
  9951. if (*bp)
  9952. return 0;
  9953. }
  9954. /*
  9955. * We don't remove direct blocks until we've reached
  9956. * the truncation block.
  9957. */
  9958. if (blockcnt >= 0 && blockcnt < pb->truncate_block)
  9959. return 0;
  9960. /*
  9961. * If part of the last block needs truncating, we do
  9962. * it here.
  9963. */
  9964. if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
  9965. pb->errcode = io_channel_read_blk(fs->io, blk, 1,
  9966. pb->buf);
  9967. if (pb->errcode)
  9968. goto return_abort;
  9969. memset(pb->buf + pb->truncate_offset, 0,
  9970. fs->blocksize - pb->truncate_offset);
  9971. pb->errcode = io_channel_write_blk(fs->io, blk, 1,
  9972. pb->buf);
  9973. if (pb->errcode)
  9974. goto return_abort;
  9975. }
  9976. pb->truncated_blocks++;
  9977. *block_nr = 0;
  9978. retval |= BLOCK_CHANGED;
  9979. }
  9980. ext2fs_block_alloc_stats(fs, blk, -1);
  9981. return retval;
  9982. }
  9983. /*
  9984. * This function releases an inode. Returns 1 if an inconsistency was
  9985. * found. If the inode has a link count, then it is being truncated and
  9986. * not deleted.
  9987. */
  9988. static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
  9989. struct ext2_inode *inode, char *block_buf,
  9990. struct problem_context *pctx)
  9991. {
  9992. struct process_block_struct pb;
  9993. ext2_filsys fs = ctx->fs;
  9994. errcode_t retval;
  9995. __u32 count;
  9996. if (!ext2fs_inode_has_valid_blocks(inode))
  9997. return 0;
  9998. pb.buf = block_buf + 3 * ctx->fs->blocksize;
  9999. pb.ctx = ctx;
  10000. pb.abort = 0;
  10001. pb.errcode = 0;
  10002. pb.pctx = pctx;
  10003. if (inode->i_links_count) {
  10004. pb.truncating = 1;
  10005. pb.truncate_block = (e2_blkcnt_t)
  10006. ((((long long)inode->i_size_high << 32) +
  10007. inode->i_size + fs->blocksize - 1) /
  10008. fs->blocksize);
  10009. pb.truncate_offset = inode->i_size % fs->blocksize;
  10010. } else {
  10011. pb.truncating = 0;
  10012. pb.truncate_block = 0;
  10013. pb.truncate_offset = 0;
  10014. }
  10015. pb.truncated_blocks = 0;
  10016. retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
  10017. block_buf, release_inode_block, &pb);
  10018. if (retval) {
  10019. bb_error_msg(_("while calling ext2fs_block_iterate for inode %d"),
  10020. ino);
  10021. return 1;
  10022. }
  10023. if (pb.abort)
  10024. return 1;
  10025. /* Refresh the inode since ext2fs_block_iterate may have changed it */
  10026. e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
  10027. if (pb.truncated_blocks)
  10028. inode->i_blocks -= pb.truncated_blocks *
  10029. (fs->blocksize / 512);
  10030. if (inode->i_file_acl) {
  10031. retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
  10032. block_buf, -1, &count);
  10033. if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
  10034. retval = 0;
  10035. count = 1;
  10036. }
  10037. if (retval) {
  10038. bb_error_msg(_("while calling ext2fs_adjust_ea_refocunt for inode %d"),
  10039. ino);
  10040. return 1;
  10041. }
  10042. if (count == 0)
  10043. ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
  10044. inode->i_file_acl = 0;
  10045. }
  10046. return 0;
  10047. }
  10048. /*
  10049. * This function releases all of the orphan inodes. It returns 1 if
  10050. * it hit some error, and 0 on success.
  10051. */
  10052. static int release_orphan_inodes(e2fsck_t ctx)
  10053. {
  10054. ext2_filsys fs = ctx->fs;
  10055. ext2_ino_t ino, next_ino;
  10056. struct ext2_inode inode;
  10057. struct problem_context pctx;
  10058. char *block_buf;
  10059. if ((ino = fs->super->s_last_orphan) == 0)
  10060. return 0;
  10061. /*
  10062. * Win or lose, we won't be using the head of the orphan inode
  10063. * list again.
  10064. */
  10065. fs->super->s_last_orphan = 0;
  10066. ext2fs_mark_super_dirty(fs);
  10067. /*
  10068. * If the filesystem contains errors, don't run the orphan
  10069. * list, since the orphan list can't be trusted; and we're
  10070. * going to be running a full e2fsck run anyway...
  10071. */
  10072. if (fs->super->s_state & EXT2_ERROR_FS)
  10073. return 0;
  10074. if ((ino < EXT2_FIRST_INODE(fs->super)) ||
  10075. (ino > fs->super->s_inodes_count)) {
  10076. clear_problem_context(&pctx);
  10077. pctx.ino = ino;
  10078. fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
  10079. return 1;
  10080. }
  10081. block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
  10082. "block iterate buffer");
  10083. e2fsck_read_bitmaps(ctx);
  10084. while (ino) {
  10085. e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
  10086. clear_problem_context(&pctx);
  10087. pctx.ino = ino;
  10088. pctx.inode = &inode;
  10089. pctx.str = inode.i_links_count ? _("Truncating") :
  10090. _("Clearing");
  10091. fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
  10092. next_ino = inode.i_dtime;
  10093. if (next_ino &&
  10094. ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
  10095. (next_ino > fs->super->s_inodes_count))) {
  10096. pctx.ino = next_ino;
  10097. fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
  10098. goto return_abort;
  10099. }
  10100. if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
  10101. goto return_abort;
  10102. if (!inode.i_links_count) {
  10103. ext2fs_inode_alloc_stats2(fs, ino, -1,
  10104. LINUX_S_ISDIR(inode.i_mode));
  10105. inode.i_dtime = time(NULL);
  10106. } else {
  10107. inode.i_dtime = 0;
  10108. }
  10109. e2fsck_write_inode(ctx, ino, &inode, "delete_file");
  10110. ino = next_ino;
  10111. }
  10112. ext2fs_free_mem(&block_buf);
  10113. return 0;
  10114. return_abort:
  10115. ext2fs_free_mem(&block_buf);
  10116. return 1;
  10117. }
  10118. /*
  10119. * Check the resize inode to make sure it is sane. We check both for
  10120. * the case where on-line resizing is not enabled (in which case the
  10121. * resize inode should be cleared) as well as the case where on-line
  10122. * resizing is enabled.
  10123. */
  10124. static void check_resize_inode(e2fsck_t ctx)
  10125. {
  10126. ext2_filsys fs = ctx->fs;
  10127. struct ext2_inode inode;
  10128. struct problem_context pctx;
  10129. int i, j, gdt_off, ind_off;
  10130. blk_t blk, pblk, expect;
  10131. __u32 *dind_buf = NULL, *ind_buf;
  10132. errcode_t retval;
  10133. clear_problem_context(&pctx);
  10134. /*
  10135. * If the resize inode feature isn't set, then
  10136. * s_reserved_gdt_blocks must be zero.
  10137. */
  10138. if (!(fs->super->s_feature_compat &
  10139. EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
  10140. if (fs->super->s_reserved_gdt_blocks) {
  10141. pctx.num = fs->super->s_reserved_gdt_blocks;
  10142. if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
  10143. &pctx)) {
  10144. fs->super->s_reserved_gdt_blocks = 0;
  10145. ext2fs_mark_super_dirty(fs);
  10146. }
  10147. }
  10148. }
  10149. /* Read the resize inode */
  10150. pctx.ino = EXT2_RESIZE_INO;
  10151. retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
  10152. if (retval) {
  10153. if (fs->super->s_feature_compat &
  10154. EXT2_FEATURE_COMPAT_RESIZE_INODE)
  10155. ctx->flags |= E2F_FLAG_RESIZE_INODE;
  10156. return;
  10157. }
  10158. /*
  10159. * If the resize inode feature isn't set, check to make sure
  10160. * the resize inode is cleared; then we're done.
  10161. */
  10162. if (!(fs->super->s_feature_compat &
  10163. EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
  10164. for (i=0; i < EXT2_N_BLOCKS; i++) {
  10165. if (inode.i_block[i])
  10166. break;
  10167. }
  10168. if ((i < EXT2_N_BLOCKS) &&
  10169. fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
  10170. memset(&inode, 0, sizeof(inode));
  10171. e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
  10172. "clear_resize");
  10173. }
  10174. return;
  10175. }
  10176. /*
  10177. * The resize inode feature is enabled; check to make sure the
  10178. * only block in use is the double indirect block
  10179. */
  10180. blk = inode.i_block[EXT2_DIND_BLOCK];
  10181. for (i=0; i < EXT2_N_BLOCKS; i++) {
  10182. if (i != EXT2_DIND_BLOCK && inode.i_block[i])
  10183. break;
  10184. }
  10185. if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
  10186. !(inode.i_mode & LINUX_S_IFREG) ||
  10187. (blk < fs->super->s_first_data_block ||
  10188. blk >= fs->super->s_blocks_count)) {
  10189. resize_inode_invalid:
  10190. if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
  10191. memset(&inode, 0, sizeof(inode));
  10192. e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
  10193. "clear_resize");
  10194. ctx->flags |= E2F_FLAG_RESIZE_INODE;
  10195. }
  10196. if (!(ctx->options & E2F_OPT_READONLY)) {
  10197. fs->super->s_state &= ~EXT2_VALID_FS;
  10198. ext2fs_mark_super_dirty(fs);
  10199. }
  10200. goto cleanup;
  10201. }
  10202. dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
  10203. "resize dind buffer");
  10204. ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
  10205. retval = ext2fs_read_ind_block(fs, blk, dind_buf);
  10206. if (retval)
  10207. goto resize_inode_invalid;
  10208. gdt_off = fs->desc_blocks;
  10209. pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
  10210. for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
  10211. i++, gdt_off++, pblk++) {
  10212. gdt_off %= fs->blocksize/4;
  10213. if (dind_buf[gdt_off] != pblk)
  10214. goto resize_inode_invalid;
  10215. retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
  10216. if (retval)
  10217. goto resize_inode_invalid;
  10218. ind_off = 0;
  10219. for (j = 1; j < fs->group_desc_count; j++) {
  10220. if (!ext2fs_bg_has_super(fs, j))
  10221. continue;
  10222. expect = pblk + (j * fs->super->s_blocks_per_group);
  10223. if (ind_buf[ind_off] != expect)
  10224. goto resize_inode_invalid;
  10225. ind_off++;
  10226. }
  10227. }
  10228. cleanup:
  10229. ext2fs_free_mem(&dind_buf);
  10230. }
  10231. static void check_super_block(e2fsck_t ctx)
  10232. {
  10233. ext2_filsys fs = ctx->fs;
  10234. blk_t first_block, last_block;
  10235. struct ext2_super_block *sb = fs->super;
  10236. struct ext2_group_desc *gd;
  10237. blk_t blocks_per_group = fs->super->s_blocks_per_group;
  10238. blk_t bpg_max;
  10239. int inodes_per_block;
  10240. int ipg_max;
  10241. int inode_size;
  10242. dgrp_t i;
  10243. blk_t should_be;
  10244. struct problem_context pctx;
  10245. __u32 free_blocks = 0, free_inodes = 0;
  10246. inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
  10247. ipg_max = inodes_per_block * (blocks_per_group - 4);
  10248. if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
  10249. ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
  10250. bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
  10251. if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
  10252. bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
  10253. ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
  10254. sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
  10255. ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
  10256. sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
  10257. ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
  10258. sizeof(int) * fs->group_desc_count, "invalid_inode_table");
  10259. clear_problem_context(&pctx);
  10260. /*
  10261. * Verify the super block constants...
  10262. */
  10263. check_super_value(ctx, "inodes_count", sb->s_inodes_count,
  10264. MIN_CHECK, 1, 0);
  10265. check_super_value(ctx, "blocks_count", sb->s_blocks_count,
  10266. MIN_CHECK, 1, 0);
  10267. check_super_value(ctx, "first_data_block", sb->s_first_data_block,
  10268. MAX_CHECK, 0, sb->s_blocks_count);
  10269. check_super_value(ctx, "log_block_size", sb->s_log_block_size,
  10270. MIN_CHECK | MAX_CHECK, 0,
  10271. EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
  10272. check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
  10273. MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
  10274. check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
  10275. MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
  10276. bpg_max);
  10277. check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
  10278. MIN_CHECK | MAX_CHECK, 8, bpg_max);
  10279. check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
  10280. MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
  10281. check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
  10282. MAX_CHECK, 0, sb->s_blocks_count / 2);
  10283. check_super_value(ctx, "reserved_gdt_blocks",
  10284. sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
  10285. fs->blocksize/4);
  10286. inode_size = EXT2_INODE_SIZE(sb);
  10287. check_super_value(ctx, "inode_size",
  10288. inode_size, MIN_CHECK | MAX_CHECK,
  10289. EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
  10290. if (inode_size & (inode_size - 1)) {
  10291. pctx.num = inode_size;
  10292. pctx.str = "inode_size";
  10293. fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
  10294. ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
  10295. return;
  10296. }
  10297. if (!ctx->num_blocks) {
  10298. pctx.errcode = e2fsck_get_device_size(ctx);
  10299. if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
  10300. fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
  10301. ctx->flags |= E2F_FLAG_ABORT;
  10302. return;
  10303. }
  10304. if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
  10305. (ctx->num_blocks < sb->s_blocks_count)) {
  10306. pctx.blk = sb->s_blocks_count;
  10307. pctx.blk2 = ctx->num_blocks;
  10308. if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
  10309. ctx->flags |= E2F_FLAG_ABORT;
  10310. return;
  10311. }
  10312. }
  10313. }
  10314. if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
  10315. pctx.blk = EXT2_BLOCK_SIZE(sb);
  10316. pctx.blk2 = EXT2_FRAG_SIZE(sb);
  10317. fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
  10318. ctx->flags |= E2F_FLAG_ABORT;
  10319. return;
  10320. }
  10321. should_be = sb->s_frags_per_group >>
  10322. (sb->s_log_block_size - sb->s_log_frag_size);
  10323. if (sb->s_blocks_per_group != should_be) {
  10324. pctx.blk = sb->s_blocks_per_group;
  10325. pctx.blk2 = should_be;
  10326. fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
  10327. ctx->flags |= E2F_FLAG_ABORT;
  10328. return;
  10329. }
  10330. should_be = (sb->s_log_block_size == 0) ? 1 : 0;
  10331. if (sb->s_first_data_block != should_be) {
  10332. pctx.blk = sb->s_first_data_block;
  10333. pctx.blk2 = should_be;
  10334. fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
  10335. ctx->flags |= E2F_FLAG_ABORT;
  10336. return;
  10337. }
  10338. should_be = sb->s_inodes_per_group * fs->group_desc_count;
  10339. if (sb->s_inodes_count != should_be) {
  10340. pctx.ino = sb->s_inodes_count;
  10341. pctx.ino2 = should_be;
  10342. if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
  10343. sb->s_inodes_count = should_be;
  10344. ext2fs_mark_super_dirty(fs);
  10345. }
  10346. }
  10347. /*
  10348. * Verify the group descriptors....
  10349. */
  10350. first_block = sb->s_first_data_block;
  10351. last_block = first_block + blocks_per_group;
  10352. for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
  10353. pctx.group = i;
  10354. if (i == fs->group_desc_count - 1)
  10355. last_block = sb->s_blocks_count;
  10356. if ((gd->bg_block_bitmap < first_block) ||
  10357. (gd->bg_block_bitmap >= last_block)) {
  10358. pctx.blk = gd->bg_block_bitmap;
  10359. if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
  10360. gd->bg_block_bitmap = 0;
  10361. }
  10362. if (gd->bg_block_bitmap == 0) {
  10363. ctx->invalid_block_bitmap_flag[i]++;
  10364. ctx->invalid_bitmaps++;
  10365. }
  10366. if ((gd->bg_inode_bitmap < first_block) ||
  10367. (gd->bg_inode_bitmap >= last_block)) {
  10368. pctx.blk = gd->bg_inode_bitmap;
  10369. if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
  10370. gd->bg_inode_bitmap = 0;
  10371. }
  10372. if (gd->bg_inode_bitmap == 0) {
  10373. ctx->invalid_inode_bitmap_flag[i]++;
  10374. ctx->invalid_bitmaps++;
  10375. }
  10376. if ((gd->bg_inode_table < first_block) ||
  10377. ((gd->bg_inode_table +
  10378. fs->inode_blocks_per_group - 1) >= last_block)) {
  10379. pctx.blk = gd->bg_inode_table;
  10380. if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
  10381. gd->bg_inode_table = 0;
  10382. }
  10383. if (gd->bg_inode_table == 0) {
  10384. ctx->invalid_inode_table_flag[i]++;
  10385. ctx->invalid_bitmaps++;
  10386. }
  10387. free_blocks += gd->bg_free_blocks_count;
  10388. free_inodes += gd->bg_free_inodes_count;
  10389. first_block += sb->s_blocks_per_group;
  10390. last_block += sb->s_blocks_per_group;
  10391. if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
  10392. (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
  10393. (gd->bg_used_dirs_count > sb->s_inodes_per_group))
  10394. ext2fs_unmark_valid(fs);
  10395. }
  10396. /*
  10397. * Update the global counts from the block group counts. This
  10398. * is needed for an experimental patch which eliminates
  10399. * locking the entire filesystem when allocating blocks or
  10400. * inodes; if the filesystem is not unmounted cleanly, the
  10401. * global counts may not be accurate.
  10402. */
  10403. if ((free_blocks != sb->s_free_blocks_count) ||
  10404. (free_inodes != sb->s_free_inodes_count)) {
  10405. if (ctx->options & E2F_OPT_READONLY)
  10406. ext2fs_unmark_valid(fs);
  10407. else {
  10408. sb->s_free_blocks_count = free_blocks;
  10409. sb->s_free_inodes_count = free_inodes;
  10410. ext2fs_mark_super_dirty(fs);
  10411. }
  10412. }
  10413. if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
  10414. (sb->s_free_inodes_count > sb->s_inodes_count))
  10415. ext2fs_unmark_valid(fs);
  10416. /*
  10417. * If we have invalid bitmaps, set the error state of the
  10418. * filesystem.
  10419. */
  10420. if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
  10421. sb->s_state &= ~EXT2_VALID_FS;
  10422. ext2fs_mark_super_dirty(fs);
  10423. }
  10424. clear_problem_context(&pctx);
  10425. /*
  10426. * If the UUID field isn't assigned, assign it.
  10427. */
  10428. if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
  10429. if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
  10430. uuid_generate(sb->s_uuid);
  10431. ext2fs_mark_super_dirty(fs);
  10432. fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
  10433. }
  10434. }
  10435. /* FIXME - HURD support?
  10436. * For the Hurd, check to see if the filetype option is set,
  10437. * since it doesn't support it.
  10438. */
  10439. if (!(ctx->options & E2F_OPT_READONLY) &&
  10440. fs->super->s_creator_os == EXT2_OS_HURD &&
  10441. (fs->super->s_feature_incompat &
  10442. EXT2_FEATURE_INCOMPAT_FILETYPE)) {
  10443. if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
  10444. fs->super->s_feature_incompat &=
  10445. ~EXT2_FEATURE_INCOMPAT_FILETYPE;
  10446. ext2fs_mark_super_dirty(fs);
  10447. }
  10448. }
  10449. /*
  10450. * If we have any of the compatibility flags set, we need to have a
  10451. * revision 1 filesystem. Most kernels will not check the flags on
  10452. * a rev 0 filesystem and we may have corruption issues because of
  10453. * the incompatible changes to the filesystem.
  10454. */
  10455. if (!(ctx->options & E2F_OPT_READONLY) &&
  10456. fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
  10457. (fs->super->s_feature_compat ||
  10458. fs->super->s_feature_ro_compat ||
  10459. fs->super->s_feature_incompat) &&
  10460. fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
  10461. ext2fs_update_dynamic_rev(fs);
  10462. ext2fs_mark_super_dirty(fs);
  10463. }
  10464. check_resize_inode(ctx);
  10465. /*
  10466. * Clean up any orphan inodes, if present.
  10467. */
  10468. if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
  10469. fs->super->s_state &= ~EXT2_VALID_FS;
  10470. ext2fs_mark_super_dirty(fs);
  10471. }
  10472. /*
  10473. * Move the ext3 journal file, if necessary.
  10474. */
  10475. e2fsck_move_ext3_journal(ctx);
  10476. }
  10477. /*
  10478. * swapfs.c --- byte-swap an ext2 filesystem
  10479. */
  10480. #ifdef ENABLE_SWAPFS
  10481. struct swap_block_struct {
  10482. ext2_ino_t ino;
  10483. int isdir;
  10484. errcode_t errcode;
  10485. char *dir_buf;
  10486. struct ext2_inode *inode;
  10487. };
  10488. /*
  10489. * This is a helper function for block_iterate. We mark all of the
  10490. * indirect and direct blocks as changed, so that block_iterate will
  10491. * write them out.
  10492. */
  10493. static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
  10494. void *priv_data)
  10495. {
  10496. errcode_t retval;
  10497. struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
  10498. if (sb->isdir && (blockcnt >= 0) && *block_nr) {
  10499. retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
  10500. if (retval) {
  10501. sb->errcode = retval;
  10502. return BLOCK_ABORT;
  10503. }
  10504. retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
  10505. if (retval) {
  10506. sb->errcode = retval;
  10507. return BLOCK_ABORT;
  10508. }
  10509. }
  10510. if (blockcnt >= 0) {
  10511. if (blockcnt < EXT2_NDIR_BLOCKS)
  10512. return 0;
  10513. return BLOCK_CHANGED;
  10514. }
  10515. if (blockcnt == BLOCK_COUNT_IND) {
  10516. if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
  10517. return 0;
  10518. return BLOCK_CHANGED;
  10519. }
  10520. if (blockcnt == BLOCK_COUNT_DIND) {
  10521. if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
  10522. return 0;
  10523. return BLOCK_CHANGED;
  10524. }
  10525. if (blockcnt == BLOCK_COUNT_TIND) {
  10526. if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
  10527. return 0;
  10528. return BLOCK_CHANGED;
  10529. }
  10530. return BLOCK_CHANGED;
  10531. }
  10532. /*
  10533. * This function is responsible for byte-swapping all of the indirect,
  10534. * block pointers. It is also responsible for byte-swapping directories.
  10535. */
  10536. static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
  10537. struct ext2_inode *inode)
  10538. {
  10539. errcode_t retval;
  10540. struct swap_block_struct sb;
  10541. sb.ino = ino;
  10542. sb.inode = inode;
  10543. sb.dir_buf = block_buf + ctx->fs->blocksize*3;
  10544. sb.errcode = 0;
  10545. sb.isdir = 0;
  10546. if (LINUX_S_ISDIR(inode->i_mode))
  10547. sb.isdir = 1;
  10548. retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
  10549. swap_block, &sb);
  10550. if (retval) {
  10551. bb_error_msg(_("while calling ext2fs_block_iterate"));
  10552. ctx->flags |= E2F_FLAG_ABORT;
  10553. return;
  10554. }
  10555. if (sb.errcode) {
  10556. bb_error_msg(_("while calling iterator function"));
  10557. ctx->flags |= E2F_FLAG_ABORT;
  10558. return;
  10559. }
  10560. }
  10561. static void swap_inodes(e2fsck_t ctx)
  10562. {
  10563. ext2_filsys fs = ctx->fs;
  10564. dgrp_t group;
  10565. unsigned int i;
  10566. ext2_ino_t ino = 1;
  10567. char *buf, *block_buf;
  10568. errcode_t retval;
  10569. struct ext2_inode * inode;
  10570. e2fsck_use_inode_shortcuts(ctx, 1);
  10571. retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
  10572. &buf);
  10573. if (retval) {
  10574. bb_error_msg(_("while allocating inode buffer"));
  10575. ctx->flags |= E2F_FLAG_ABORT;
  10576. return;
  10577. }
  10578. block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
  10579. "block interate buffer");
  10580. for (group = 0; group < fs->group_desc_count; group++) {
  10581. retval = io_channel_read_blk(fs->io,
  10582. fs->group_desc[group].bg_inode_table,
  10583. fs->inode_blocks_per_group, buf);
  10584. if (retval) {
  10585. bb_error_msg(_("while reading inode table (group %d)"),
  10586. group);
  10587. ctx->flags |= E2F_FLAG_ABORT;
  10588. return;
  10589. }
  10590. inode = (struct ext2_inode *) buf;
  10591. for (i=0; i < fs->super->s_inodes_per_group;
  10592. i++, ino++, inode++) {
  10593. ctx->stashed_ino = ino;
  10594. ctx->stashed_inode = inode;
  10595. if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
  10596. ext2fs_swap_inode(fs, inode, inode, 0);
  10597. /*
  10598. * Skip deleted files.
  10599. */
  10600. if (inode->i_links_count == 0)
  10601. continue;
  10602. if (LINUX_S_ISDIR(inode->i_mode) ||
  10603. ((inode->i_block[EXT2_IND_BLOCK] ||
  10604. inode->i_block[EXT2_DIND_BLOCK] ||
  10605. inode->i_block[EXT2_TIND_BLOCK]) &&
  10606. ext2fs_inode_has_valid_blocks(inode)))
  10607. swap_inode_blocks(ctx, ino, block_buf, inode);
  10608. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  10609. return;
  10610. if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
  10611. ext2fs_swap_inode(fs, inode, inode, 1);
  10612. }
  10613. retval = io_channel_write_blk(fs->io,
  10614. fs->group_desc[group].bg_inode_table,
  10615. fs->inode_blocks_per_group, buf);
  10616. if (retval) {
  10617. bb_error_msg(_("while writing inode table (group %d)"),
  10618. group);
  10619. ctx->flags |= E2F_FLAG_ABORT;
  10620. return;
  10621. }
  10622. }
  10623. ext2fs_free_mem(&buf);
  10624. ext2fs_free_mem(&block_buf);
  10625. e2fsck_use_inode_shortcuts(ctx, 0);
  10626. ext2fs_flush_icache(fs);
  10627. }
  10628. #if defined(__powerpc__) && BB_BIG_ENDIAN
  10629. /*
  10630. * On the PowerPC, the big-endian variant of the ext2 filesystem
  10631. * has its bitmaps stored as 32-bit words with bit 0 as the LSB
  10632. * of each word. Thus a bitmap with only bit 0 set would be, as
  10633. * a string of bytes, 00 00 00 01 00 ...
  10634. * To cope with this, we byte-reverse each word of a bitmap if
  10635. * we have a big-endian filesystem, that is, if we are *not*
  10636. * byte-swapping other word-sized numbers.
  10637. */
  10638. #define EXT2_BIG_ENDIAN_BITMAPS
  10639. #endif
  10640. #ifdef EXT2_BIG_ENDIAN_BITMAPS
  10641. static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
  10642. {
  10643. __u32 *p = (__u32 *) bmap->bitmap;
  10644. int n, nbytes = (bmap->end - bmap->start + 7) / 8;
  10645. for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
  10646. *p = ext2fs_swab32(*p);
  10647. }
  10648. #endif
  10649. #ifdef ENABLE_SWAPFS
  10650. static void swap_filesys(e2fsck_t ctx)
  10651. {
  10652. ext2_filsys fs = ctx->fs;
  10653. if (!(ctx->options & E2F_OPT_PREEN))
  10654. printf(_("Pass 0: Doing byte-swap of filesystem\n"));
  10655. /* Byte swap */
  10656. if (fs->super->s_mnt_count) {
  10657. fprintf(stderr, _("%s: the filesystem must be freshly "
  10658. "checked using fsck\n"
  10659. "and not mounted before trying to "
  10660. "byte-swap it.\n"), ctx->device_name);
  10661. ctx->flags |= E2F_FLAG_ABORT;
  10662. return;
  10663. }
  10664. if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
  10665. fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
  10666. EXT2_FLAG_SWAP_BYTES_WRITE);
  10667. fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
  10668. } else {
  10669. fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
  10670. fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
  10671. }
  10672. swap_inodes(ctx);
  10673. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  10674. return;
  10675. if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
  10676. fs->flags |= EXT2_FLAG_SWAP_BYTES;
  10677. fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
  10678. EXT2_FLAG_SWAP_BYTES_WRITE);
  10679. #ifdef EXT2_BIG_ENDIAN_BITMAPS
  10680. e2fsck_read_bitmaps(ctx);
  10681. ext2fs_swap_bitmap(fs->inode_map);
  10682. ext2fs_swap_bitmap(fs->block_map);
  10683. fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
  10684. #endif
  10685. fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
  10686. ext2fs_flush(fs);
  10687. fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
  10688. }
  10689. #endif /* ENABLE_SWAPFS */
  10690. #endif
  10691. /*
  10692. * util.c --- miscellaneous utilities
  10693. */
  10694. void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
  10695. const char *description)
  10696. {
  10697. void *ret;
  10698. char buf[256];
  10699. ret = xzalloc(size);
  10700. return ret;
  10701. }
  10702. static char *string_copy(const char *str, int len)
  10703. {
  10704. char *ret;
  10705. if (!str)
  10706. return NULL;
  10707. if (!len)
  10708. len = strlen(str);
  10709. ret = xmalloc(len+1);
  10710. strncpy(ret, str, len);
  10711. ret[len] = 0;
  10712. return ret;
  10713. }
  10714. #ifndef HAVE_CONIO_H
  10715. static int read_a_char(void)
  10716. {
  10717. char c;
  10718. int r;
  10719. int fail = 0;
  10720. while (1) {
  10721. if (e2fsck_global_ctx &&
  10722. (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
  10723. return 3;
  10724. }
  10725. r = read(0, &c, 1);
  10726. if (r == 1)
  10727. return c;
  10728. if (fail++ > 100)
  10729. break;
  10730. }
  10731. return EOF;
  10732. }
  10733. #endif
  10734. static int ask_yn(const char * string, int def)
  10735. {
  10736. int c;
  10737. const char *defstr;
  10738. static const char short_yes[] = "yY";
  10739. static const char short_no[] = "nN";
  10740. #ifdef HAVE_TERMIOS_H
  10741. struct termios termios, tmp;
  10742. tcgetattr (0, &termios);
  10743. tmp = termios;
  10744. tmp.c_lflag &= ~(ICANON | ECHO);
  10745. tmp.c_cc[VMIN] = 1;
  10746. tmp.c_cc[VTIME] = 0;
  10747. tcsetattr_stdin_TCSANOW(&tmp);
  10748. #endif
  10749. if (def == 1)
  10750. defstr = "<y>";
  10751. else if (def == 0)
  10752. defstr = "<n>";
  10753. else
  10754. defstr = " (y/n)";
  10755. printf("%s%s? ", string, defstr);
  10756. while (1) {
  10757. fflush (stdout);
  10758. if ((c = read_a_char()) == EOF)
  10759. break;
  10760. if (c == 3) {
  10761. #ifdef HAVE_TERMIOS_H
  10762. tcsetattr_stdin_TCSANOW(&termios);
  10763. #endif
  10764. if (e2fsck_global_ctx &&
  10765. e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
  10766. puts("\n");
  10767. longjmp(e2fsck_global_ctx->abort_loc, 1);
  10768. }
  10769. puts(_("cancelled!\n"));
  10770. return 0;
  10771. }
  10772. if (strchr(short_yes, (char) c)) {
  10773. def = 1;
  10774. break;
  10775. }
  10776. else if (strchr(short_no, (char) c)) {
  10777. def = 0;
  10778. break;
  10779. }
  10780. else if ((c == ' ' || c == '\n') && (def != -1))
  10781. break;
  10782. }
  10783. if (def)
  10784. puts("yes\n");
  10785. else
  10786. puts ("no\n");
  10787. #ifdef HAVE_TERMIOS_H
  10788. tcsetattr_stdin_TCSANOW(&termios);
  10789. #endif
  10790. return def;
  10791. }
  10792. int ask (e2fsck_t ctx, const char * string, int def)
  10793. {
  10794. if (ctx->options & E2F_OPT_NO) {
  10795. printf(_("%s? no\n\n"), string);
  10796. return 0;
  10797. }
  10798. if (ctx->options & E2F_OPT_YES) {
  10799. printf(_("%s? yes\n\n"), string);
  10800. return 1;
  10801. }
  10802. if (ctx->options & E2F_OPT_PREEN) {
  10803. printf("%s? %s\n\n", string, def ? _("yes") : _("no"));
  10804. return def;
  10805. }
  10806. return ask_yn(string, def);
  10807. }
  10808. void e2fsck_read_bitmaps(e2fsck_t ctx)
  10809. {
  10810. ext2_filsys fs = ctx->fs;
  10811. errcode_t retval;
  10812. if (ctx->invalid_bitmaps) {
  10813. bb_error_msg(_("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
  10814. ctx->device_name);
  10815. bb_error_msg_and_die(0);
  10816. }
  10817. ehandler_operation(_("reading inode and block bitmaps"));
  10818. retval = ext2fs_read_bitmaps(fs);
  10819. ehandler_operation(0);
  10820. if (retval) {
  10821. bb_error_msg(_("while retrying to read bitmaps for %s"),
  10822. ctx->device_name);
  10823. bb_error_msg_and_die(0);
  10824. }
  10825. }
  10826. static void e2fsck_write_bitmaps(e2fsck_t ctx)
  10827. {
  10828. ext2_filsys fs = ctx->fs;
  10829. errcode_t retval;
  10830. if (ext2fs_test_bb_dirty(fs)) {
  10831. ehandler_operation(_("writing block bitmaps"));
  10832. retval = ext2fs_write_block_bitmap(fs);
  10833. ehandler_operation(0);
  10834. if (retval) {
  10835. bb_error_msg(_("while retrying to write block bitmaps for %s"),
  10836. ctx->device_name);
  10837. bb_error_msg_and_die(0);
  10838. }
  10839. }
  10840. if (ext2fs_test_ib_dirty(fs)) {
  10841. ehandler_operation(_("writing inode bitmaps"));
  10842. retval = ext2fs_write_inode_bitmap(fs);
  10843. ehandler_operation(0);
  10844. if (retval) {
  10845. bb_error_msg(_("while retrying to write inode bitmaps for %s"),
  10846. ctx->device_name);
  10847. bb_error_msg_and_die(0);
  10848. }
  10849. }
  10850. }
  10851. void preenhalt(e2fsck_t ctx)
  10852. {
  10853. ext2_filsys fs = ctx->fs;
  10854. if (!(ctx->options & E2F_OPT_PREEN))
  10855. return;
  10856. fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
  10857. "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
  10858. ctx->device_name);
  10859. if (fs != NULL) {
  10860. fs->super->s_state |= EXT2_ERROR_FS;
  10861. ext2fs_mark_super_dirty(fs);
  10862. ext2fs_close(fs);
  10863. }
  10864. exit(EXIT_UNCORRECTED);
  10865. }
  10866. void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
  10867. struct ext2_inode * inode, const char *proc)
  10868. {
  10869. int retval;
  10870. retval = ext2fs_read_inode(ctx->fs, ino, inode);
  10871. if (retval) {
  10872. bb_error_msg(_("while reading inode %ld in %s"), ino, proc);
  10873. bb_error_msg_and_die(0);
  10874. }
  10875. }
  10876. extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
  10877. struct ext2_inode * inode, int bufsize,
  10878. const char *proc)
  10879. {
  10880. int retval;
  10881. retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
  10882. if (retval) {
  10883. bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
  10884. bb_error_msg_and_die(0);
  10885. }
  10886. }
  10887. extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
  10888. struct ext2_inode * inode, const char *proc)
  10889. {
  10890. int retval;
  10891. retval = ext2fs_write_inode(ctx->fs, ino, inode);
  10892. if (retval) {
  10893. bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
  10894. bb_error_msg_and_die(0);
  10895. }
  10896. }
  10897. blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
  10898. io_manager manager)
  10899. {
  10900. struct ext2_super_block *sb;
  10901. io_channel io = NULL;
  10902. void *buf = NULL;
  10903. int blocksize;
  10904. blk_t superblock, ret_sb = 8193;
  10905. if (fs && fs->super) {
  10906. ret_sb = (fs->super->s_blocks_per_group +
  10907. fs->super->s_first_data_block);
  10908. if (ctx) {
  10909. ctx->superblock = ret_sb;
  10910. ctx->blocksize = fs->blocksize;
  10911. }
  10912. return ret_sb;
  10913. }
  10914. if (ctx) {
  10915. if (ctx->blocksize) {
  10916. ret_sb = ctx->blocksize * 8;
  10917. if (ctx->blocksize == 1024)
  10918. ret_sb++;
  10919. ctx->superblock = ret_sb;
  10920. return ret_sb;
  10921. }
  10922. ctx->superblock = ret_sb;
  10923. ctx->blocksize = 1024;
  10924. }
  10925. if (!name || !manager)
  10926. goto cleanup;
  10927. if (manager->open(name, 0, &io) != 0)
  10928. goto cleanup;
  10929. if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
  10930. goto cleanup;
  10931. sb = (struct ext2_super_block *) buf;
  10932. for (blocksize = EXT2_MIN_BLOCK_SIZE;
  10933. blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
  10934. superblock = blocksize*8;
  10935. if (blocksize == 1024)
  10936. superblock++;
  10937. io_channel_set_blksize(io, blocksize);
  10938. if (io_channel_read_blk(io, superblock,
  10939. -SUPERBLOCK_SIZE, buf))
  10940. continue;
  10941. #if BB_BIG_ENDIAN
  10942. if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
  10943. ext2fs_swap_super(sb);
  10944. #endif
  10945. if (sb->s_magic == EXT2_SUPER_MAGIC) {
  10946. ret_sb = superblock;
  10947. if (ctx) {
  10948. ctx->superblock = superblock;
  10949. ctx->blocksize = blocksize;
  10950. }
  10951. break;
  10952. }
  10953. }
  10954. cleanup:
  10955. if (io)
  10956. io_channel_close(io);
  10957. ext2fs_free_mem(&buf);
  10958. return ret_sb;
  10959. }
  10960. /*
  10961. * This function runs through the e2fsck passes and calls them all,
  10962. * returning restart, abort, or cancel as necessary...
  10963. */
  10964. typedef void (*pass_t)(e2fsck_t ctx);
  10965. static const pass_t e2fsck_passes[] = {
  10966. e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
  10967. e2fsck_pass5, 0 };
  10968. #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
  10969. static int e2fsck_run(e2fsck_t ctx)
  10970. {
  10971. int i;
  10972. pass_t e2fsck_pass;
  10973. if (setjmp(ctx->abort_loc)) {
  10974. ctx->flags &= ~E2F_FLAG_SETJMP_OK;
  10975. return (ctx->flags & E2F_FLAG_RUN_RETURN);
  10976. }
  10977. ctx->flags |= E2F_FLAG_SETJMP_OK;
  10978. for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
  10979. if (ctx->flags & E2F_FLAG_RUN_RETURN)
  10980. break;
  10981. e2fsck_pass(ctx);
  10982. if (ctx->progress)
  10983. (void) (ctx->progress)(ctx, 0, 0, 0);
  10984. }
  10985. ctx->flags &= ~E2F_FLAG_SETJMP_OK;
  10986. if (ctx->flags & E2F_FLAG_RUN_RETURN)
  10987. return (ctx->flags & E2F_FLAG_RUN_RETURN);
  10988. return 0;
  10989. }
  10990. /*
  10991. * unix.c - The unix-specific code for e2fsck
  10992. */
  10993. /* Command line options */
  10994. static int swapfs;
  10995. #ifdef ENABLE_SWAPFS
  10996. static int normalize_swapfs;
  10997. #endif
  10998. static int cflag; /* check disk */
  10999. static int show_version_only;
  11000. static int verbose;
  11001. #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural)
  11002. static void show_stats(e2fsck_t ctx)
  11003. {
  11004. ext2_filsys fs = ctx->fs;
  11005. int inodes, inodes_used, blocks, blocks_used;
  11006. int dir_links;
  11007. int num_files, num_links;
  11008. int frag_percent;
  11009. dir_links = 2 * ctx->fs_directory_count - 1;
  11010. num_files = ctx->fs_total_count - dir_links;
  11011. num_links = ctx->fs_links_count - dir_links;
  11012. inodes = fs->super->s_inodes_count;
  11013. inodes_used = (fs->super->s_inodes_count -
  11014. fs->super->s_free_inodes_count);
  11015. blocks = fs->super->s_blocks_count;
  11016. blocks_used = (fs->super->s_blocks_count -
  11017. fs->super->s_free_blocks_count);
  11018. frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
  11019. frag_percent = (frag_percent + 5) / 10;
  11020. if (!verbose) {
  11021. printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
  11022. ctx->device_name, inodes_used, inodes,
  11023. frag_percent / 10, frag_percent % 10,
  11024. blocks_used, blocks);
  11025. return;
  11026. }
  11027. printf("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used),
  11028. 100 * inodes_used / inodes);
  11029. printf("%8d non-contiguous inode%s (%0d.%d%%)\n",
  11030. P_E2("", "s", ctx->fs_fragmented),
  11031. frag_percent / 10, frag_percent % 10);
  11032. printf(_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
  11033. ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
  11034. printf("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used),
  11035. (int) ((long long) 100 * blocks_used / blocks));
  11036. printf("%8d large file%s\n", P_E2("", "s", ctx->large_files));
  11037. printf("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count));
  11038. printf("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count));
  11039. printf("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count));
  11040. printf("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count));
  11041. printf("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count));
  11042. printf("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links));
  11043. printf("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count));
  11044. printf(" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count));
  11045. printf("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count));
  11046. printf("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links));
  11047. }
  11048. static void check_mount(e2fsck_t ctx)
  11049. {
  11050. errcode_t retval;
  11051. int cont;
  11052. retval = ext2fs_check_if_mounted(ctx->filesystem_name,
  11053. &ctx->mount_flags);
  11054. if (retval) {
  11055. bb_error_msg(_("while determining whether %s is mounted"),
  11056. ctx->filesystem_name);
  11057. return;
  11058. }
  11059. /*
  11060. * If the filesystem isn't mounted, or it's the root filesystem
  11061. * and it's mounted read-only, then everything's fine.
  11062. */
  11063. if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
  11064. ((ctx->mount_flags & EXT2_MF_ISROOT) &&
  11065. (ctx->mount_flags & EXT2_MF_READONLY)))
  11066. return;
  11067. if (ctx->options & E2F_OPT_READONLY) {
  11068. printf(_("Warning! %s is mounted.\n"), ctx->filesystem_name);
  11069. return;
  11070. }
  11071. printf(_("%s is mounted. "), ctx->filesystem_name);
  11072. if (!ctx->interactive)
  11073. bb_error_msg_and_die(_("can't continue, aborting"));
  11074. printf(_("\n\n\007\007\007\007WARNING!!! "
  11075. "Running e2fsck on a mounted filesystem may cause\n"
  11076. "SEVERE filesystem damage.\007\007\007\n\n"));
  11077. cont = ask_yn(_("Do you really want to continue"), -1);
  11078. if (!cont) {
  11079. printf(_("check aborted.\n"));
  11080. exit(0);
  11081. }
  11082. }
  11083. static int is_on_batt(void)
  11084. {
  11085. FILE *f;
  11086. DIR *d;
  11087. char tmp[80], tmp2[80], fname[80];
  11088. unsigned int acflag;
  11089. struct dirent* de;
  11090. f = fopen_for_read("/proc/apm");
  11091. if (f) {
  11092. if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
  11093. acflag = 1;
  11094. fclose(f);
  11095. return (acflag != 1);
  11096. }
  11097. d = opendir("/proc/acpi/ac_adapter");
  11098. if (d) {
  11099. while ((de=readdir(d)) != NULL) {
  11100. if (!strncmp(".", de->d_name, 1))
  11101. continue;
  11102. snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
  11103. de->d_name);
  11104. f = fopen_for_read(fname);
  11105. if (!f)
  11106. continue;
  11107. if (fscanf(f, "%s %s", tmp2, tmp) != 2)
  11108. tmp[0] = 0;
  11109. fclose(f);
  11110. if (strncmp(tmp, "off-line", 8) == 0) {
  11111. closedir(d);
  11112. return 1;
  11113. }
  11114. }
  11115. closedir(d);
  11116. }
  11117. return 0;
  11118. }
  11119. /*
  11120. * This routine checks to see if a filesystem can be skipped; if so,
  11121. * it will exit with EXIT_OK. Under some conditions it will print a
  11122. * message explaining why a check is being forced.
  11123. */
  11124. static void check_if_skip(e2fsck_t ctx)
  11125. {
  11126. ext2_filsys fs = ctx->fs;
  11127. const char *reason = NULL;
  11128. unsigned int reason_arg = 0;
  11129. long next_check;
  11130. int batt = is_on_batt();
  11131. time_t now = time(NULL);
  11132. if ((ctx->options & E2F_OPT_FORCE) || cflag || swapfs)
  11133. return;
  11134. if ((fs->super->s_state & EXT2_ERROR_FS) ||
  11135. !ext2fs_test_valid(fs))
  11136. reason = _(" contains a file system with errors");
  11137. else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
  11138. reason = _(" was not cleanly unmounted");
  11139. else if ((fs->super->s_max_mnt_count > 0) &&
  11140. (fs->super->s_mnt_count >=
  11141. (unsigned) fs->super->s_max_mnt_count)) {
  11142. reason = _(" has been mounted %u times without being checked");
  11143. reason_arg = fs->super->s_mnt_count;
  11144. if (batt && (fs->super->s_mnt_count <
  11145. (unsigned) fs->super->s_max_mnt_count*2))
  11146. reason = 0;
  11147. } else if (fs->super->s_checkinterval &&
  11148. ((now - fs->super->s_lastcheck) >=
  11149. fs->super->s_checkinterval)) {
  11150. reason = _(" has gone %u days without being checked");
  11151. reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
  11152. if (batt && ((now - fs->super->s_lastcheck) <
  11153. fs->super->s_checkinterval*2))
  11154. reason = 0;
  11155. }
  11156. if (reason) {
  11157. fputs(ctx->device_name, stdout);
  11158. printf(reason, reason_arg);
  11159. fputs(_(", check forced.\n"), stdout);
  11160. return;
  11161. }
  11162. printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
  11163. fs->super->s_inodes_count - fs->super->s_free_inodes_count,
  11164. fs->super->s_inodes_count,
  11165. fs->super->s_blocks_count - fs->super->s_free_blocks_count,
  11166. fs->super->s_blocks_count);
  11167. next_check = 100000;
  11168. if (fs->super->s_max_mnt_count > 0) {
  11169. next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
  11170. if (next_check <= 0)
  11171. next_check = 1;
  11172. }
  11173. if (fs->super->s_checkinterval &&
  11174. ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
  11175. next_check = 1;
  11176. if (next_check <= 5) {
  11177. if (next_check == 1)
  11178. fputs(_(" (check after next mount)"), stdout);
  11179. else
  11180. printf(_(" (check in %ld mounts)"), next_check);
  11181. }
  11182. bb_putchar('\n');
  11183. ext2fs_close(fs);
  11184. ctx->fs = NULL;
  11185. e2fsck_free_context(ctx);
  11186. exit(EXIT_OK);
  11187. }
  11188. /*
  11189. * For completion notice
  11190. */
  11191. struct percent_tbl {
  11192. int max_pass;
  11193. int table[32];
  11194. };
  11195. static const struct percent_tbl e2fsck_tbl = {
  11196. 5, { 0, 70, 90, 92, 95, 100 }
  11197. };
  11198. static char bar[128], spaces[128];
  11199. static float calc_percent(const struct percent_tbl *tbl, int pass, int curr,
  11200. int max)
  11201. {
  11202. float percent;
  11203. if (pass <= 0)
  11204. return 0.0;
  11205. if (pass > tbl->max_pass || max == 0)
  11206. return 100.0;
  11207. percent = ((float) curr) / ((float) max);
  11208. return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
  11209. + tbl->table[pass-1]);
  11210. }
  11211. void e2fsck_clear_progbar(e2fsck_t ctx)
  11212. {
  11213. if (!(ctx->flags & E2F_FLAG_PROG_BAR))
  11214. return;
  11215. printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
  11216. ctx->stop_meta);
  11217. fflush(stdout);
  11218. ctx->flags &= ~E2F_FLAG_PROG_BAR;
  11219. }
  11220. int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
  11221. unsigned int dpynum)
  11222. {
  11223. static const char spinner[] = "\\|/-";
  11224. int i;
  11225. unsigned int tick;
  11226. struct timeval tv;
  11227. int dpywidth;
  11228. int fixed_percent;
  11229. if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
  11230. return 0;
  11231. /*
  11232. * Calculate the new progress position. If the
  11233. * percentage hasn't changed, then we skip out right
  11234. * away.
  11235. */
  11236. fixed_percent = (int) ((10 * percent) + 0.5);
  11237. if (ctx->progress_last_percent == fixed_percent)
  11238. return 0;
  11239. ctx->progress_last_percent = fixed_percent;
  11240. /*
  11241. * If we've already updated the spinner once within
  11242. * the last 1/8th of a second, no point doing it
  11243. * again.
  11244. */
  11245. gettimeofday(&tv, NULL);
  11246. tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
  11247. if ((tick == ctx->progress_last_time) &&
  11248. (fixed_percent != 0) && (fixed_percent != 1000))
  11249. return 0;
  11250. ctx->progress_last_time = tick;
  11251. /*
  11252. * Advance the spinner, and note that the progress bar
  11253. * will be on the screen
  11254. */
  11255. ctx->progress_pos = (ctx->progress_pos+1) & 3;
  11256. ctx->flags |= E2F_FLAG_PROG_BAR;
  11257. dpywidth = 66 - strlen(label);
  11258. dpywidth = 8 * (dpywidth / 8);
  11259. if (dpynum)
  11260. dpywidth -= 8;
  11261. i = ((percent * dpywidth) + 50) / 100;
  11262. printf("%s%s: |%s%s", ctx->start_meta, label,
  11263. bar + (sizeof(bar) - (i+1)),
  11264. spaces + (sizeof(spaces) - (dpywidth - i + 1)));
  11265. if (fixed_percent == 1000)
  11266. bb_putchar('|');
  11267. else
  11268. bb_putchar(spinner[ctx->progress_pos & 3]);
  11269. printf(" %4.1f%% ", percent);
  11270. if (dpynum)
  11271. printf("%u\r", dpynum);
  11272. else
  11273. fputs(" \r", stdout);
  11274. fputs(ctx->stop_meta, stdout);
  11275. if (fixed_percent == 1000)
  11276. e2fsck_clear_progbar(ctx);
  11277. fflush(stdout);
  11278. return 0;
  11279. }
  11280. static int e2fsck_update_progress(e2fsck_t ctx, int pass,
  11281. unsigned long cur, unsigned long max)
  11282. {
  11283. char buf[80];
  11284. float percent;
  11285. if (pass == 0)
  11286. return 0;
  11287. if (ctx->progress_fd) {
  11288. sprintf(buf, "%d %lu %lu\n", pass, cur, max);
  11289. xwrite_str(ctx->progress_fd, buf);
  11290. } else {
  11291. percent = calc_percent(&e2fsck_tbl, pass, cur, max);
  11292. e2fsck_simple_progress(ctx, ctx->device_name,
  11293. percent, 0);
  11294. }
  11295. return 0;
  11296. }
  11297. static void reserve_stdio_fds(void)
  11298. {
  11299. int fd;
  11300. while (1) {
  11301. fd = open(bb_dev_null, O_RDWR);
  11302. if (fd > 2)
  11303. break;
  11304. if (fd < 0) {
  11305. fprintf(stderr, _("ERROR: Cannot open "
  11306. "/dev/null (%s)\n"),
  11307. strerror(errno));
  11308. break;
  11309. }
  11310. }
  11311. close(fd);
  11312. }
  11313. static void signal_progress_on(int sig FSCK_ATTR((unused)))
  11314. {
  11315. e2fsck_t ctx = e2fsck_global_ctx;
  11316. if (!ctx)
  11317. return;
  11318. ctx->progress = e2fsck_update_progress;
  11319. ctx->progress_fd = 0;
  11320. }
  11321. static void signal_progress_off(int sig FSCK_ATTR((unused)))
  11322. {
  11323. e2fsck_t ctx = e2fsck_global_ctx;
  11324. if (!ctx)
  11325. return;
  11326. e2fsck_clear_progbar(ctx);
  11327. ctx->progress = 0;
  11328. }
  11329. static void signal_cancel(int sig FSCK_ATTR((unused)))
  11330. {
  11331. e2fsck_t ctx = e2fsck_global_ctx;
  11332. if (!ctx)
  11333. exit(FSCK_CANCELED);
  11334. ctx->flags |= E2F_FLAG_CANCEL;
  11335. }
  11336. static void parse_extended_opts(e2fsck_t ctx, const char *opts)
  11337. {
  11338. char *buf, *token, *next, *p, *arg;
  11339. int ea_ver;
  11340. int extended_usage = 0;
  11341. buf = string_copy(opts, 0);
  11342. for (token = buf; token && *token; token = next) {
  11343. p = strchr(token, ',');
  11344. next = 0;
  11345. if (p) {
  11346. *p = 0;
  11347. next = p+1;
  11348. }
  11349. arg = strchr(token, '=');
  11350. if (arg) {
  11351. *arg = 0;
  11352. arg++;
  11353. }
  11354. if (strcmp(token, "ea_ver") == 0) {
  11355. if (!arg) {
  11356. extended_usage++;
  11357. continue;
  11358. }
  11359. ea_ver = strtoul(arg, &p, 0);
  11360. if (*p ||
  11361. ((ea_ver != 1) && (ea_ver != 2))) {
  11362. fprintf(stderr,
  11363. _("Invalid EA version.\n"));
  11364. extended_usage++;
  11365. continue;
  11366. }
  11367. ctx->ext_attr_ver = ea_ver;
  11368. } else {
  11369. fprintf(stderr, _("Unknown extended option: %s\n"),
  11370. token);
  11371. extended_usage++;
  11372. }
  11373. }
  11374. if (extended_usage) {
  11375. bb_error_msg_and_die(
  11376. "Extended options are separated by commas, "
  11377. "and may take an argument which\n"
  11378. "is set off by an equals ('=') sign. "
  11379. "Valid extended options are:\n"
  11380. "\tea_ver=<ea_version (1 or 2)>\n\n");
  11381. }
  11382. }
  11383. static errcode_t PRS(int argc, char **argv, e2fsck_t *ret_ctx)
  11384. {
  11385. int flush = 0;
  11386. int c, fd;
  11387. e2fsck_t ctx;
  11388. errcode_t retval;
  11389. struct sigaction sa;
  11390. char *extended_opts = NULL;
  11391. retval = e2fsck_allocate_context(&ctx);
  11392. if (retval)
  11393. return retval;
  11394. *ret_ctx = ctx;
  11395. setvbuf(stdout, NULL, _IONBF, BUFSIZ);
  11396. setvbuf(stderr, NULL, _IONBF, BUFSIZ);
  11397. if (isatty(0) && isatty(1)) {
  11398. ctx->interactive = 1;
  11399. } else {
  11400. ctx->start_meta[0] = '\001';
  11401. ctx->stop_meta[0] = '\002';
  11402. }
  11403. memset(bar, '=', sizeof(bar)-1);
  11404. memset(spaces, ' ', sizeof(spaces)-1);
  11405. blkid_get_cache(&ctx->blkid, NULL);
  11406. if (argc && *argv)
  11407. ctx->program_name = *argv;
  11408. else
  11409. ctx->program_name = "e2fsck";
  11410. while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
  11411. switch (c) {
  11412. case 'C':
  11413. ctx->progress = e2fsck_update_progress;
  11414. ctx->progress_fd = atoi(optarg);
  11415. if (!ctx->progress_fd)
  11416. break;
  11417. /* Validate the file descriptor to avoid disasters */
  11418. fd = dup(ctx->progress_fd);
  11419. if (fd < 0) {
  11420. fprintf(stderr,
  11421. _("Error validating file descriptor %d: %s\n"),
  11422. ctx->progress_fd,
  11423. error_message(errno));
  11424. bb_error_msg_and_die(_("Invalid completion information file descriptor"));
  11425. } else
  11426. close(fd);
  11427. break;
  11428. case 'D':
  11429. ctx->options |= E2F_OPT_COMPRESS_DIRS;
  11430. break;
  11431. case 'E':
  11432. extended_opts = optarg;
  11433. break;
  11434. case 'p':
  11435. case 'a':
  11436. if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
  11437. conflict_opt:
  11438. bb_error_msg_and_die(_("only one the options -p/-a, -n or -y may be specified"));
  11439. }
  11440. ctx->options |= E2F_OPT_PREEN;
  11441. break;
  11442. case 'n':
  11443. if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
  11444. goto conflict_opt;
  11445. ctx->options |= E2F_OPT_NO;
  11446. break;
  11447. case 'y':
  11448. if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
  11449. goto conflict_opt;
  11450. ctx->options |= E2F_OPT_YES;
  11451. break;
  11452. case 't':
  11453. /* FIXME - This needs to go away in a future path - will change binary */
  11454. fprintf(stderr, _("The -t option is not "
  11455. "supported on this version of e2fsck.\n"));
  11456. break;
  11457. case 'c':
  11458. if (cflag++)
  11459. ctx->options |= E2F_OPT_WRITECHECK;
  11460. ctx->options |= E2F_OPT_CHECKBLOCKS;
  11461. break;
  11462. case 'r':
  11463. /* What we do by default, anyway! */
  11464. break;
  11465. case 'b':
  11466. ctx->use_superblock = atoi(optarg);
  11467. ctx->flags |= E2F_FLAG_SB_SPECIFIED;
  11468. break;
  11469. case 'B':
  11470. ctx->blocksize = atoi(optarg);
  11471. break;
  11472. case 'I':
  11473. ctx->inode_buffer_blocks = atoi(optarg);
  11474. break;
  11475. case 'j':
  11476. ctx->journal_name = string_copy(optarg, 0);
  11477. break;
  11478. case 'P':
  11479. ctx->process_inode_size = atoi(optarg);
  11480. break;
  11481. case 'd':
  11482. ctx->options |= E2F_OPT_DEBUG;
  11483. break;
  11484. case 'f':
  11485. ctx->options |= E2F_OPT_FORCE;
  11486. break;
  11487. case 'F':
  11488. flush = 1;
  11489. break;
  11490. case 'v':
  11491. verbose = 1;
  11492. break;
  11493. case 'V':
  11494. show_version_only = 1;
  11495. break;
  11496. case 'N':
  11497. ctx->device_name = optarg;
  11498. break;
  11499. #ifdef ENABLE_SWAPFS
  11500. case 's':
  11501. normalize_swapfs = 1;
  11502. case 'S':
  11503. swapfs = 1;
  11504. break;
  11505. #else
  11506. case 's':
  11507. case 'S':
  11508. fprintf(stderr, _("Byte-swapping filesystems "
  11509. "not compiled in this version "
  11510. "of e2fsck\n"));
  11511. exit(1);
  11512. #endif
  11513. default:
  11514. bb_show_usage();
  11515. }
  11516. if (show_version_only)
  11517. return 0;
  11518. if (optind != argc - 1)
  11519. bb_show_usage();
  11520. if ((ctx->options & E2F_OPT_NO) &&
  11521. !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
  11522. ctx->options |= E2F_OPT_READONLY;
  11523. ctx->io_options = strchr(argv[optind], '?');
  11524. if (ctx->io_options)
  11525. *ctx->io_options++ = 0;
  11526. ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
  11527. if (!ctx->filesystem_name) {
  11528. bb_error_msg(_("Unable to resolve '%s'"), argv[optind]);
  11529. bb_error_msg_and_die(0);
  11530. }
  11531. if (extended_opts)
  11532. parse_extended_opts(ctx, extended_opts);
  11533. if (flush) {
  11534. fd = open(ctx->filesystem_name, O_RDONLY, 0);
  11535. if (fd < 0) {
  11536. bb_error_msg(_("while opening %s for flushing"),
  11537. ctx->filesystem_name);
  11538. bb_error_msg_and_die(0);
  11539. }
  11540. if ((retval = ext2fs_sync_device(fd, 1))) {
  11541. bb_error_msg(_("while trying to flush %s"),
  11542. ctx->filesystem_name);
  11543. bb_error_msg_and_die(0);
  11544. }
  11545. close(fd);
  11546. }
  11547. #ifdef ENABLE_SWAPFS
  11548. if (swapfs && cflag) {
  11549. fprintf(stderr, _("Incompatible options not "
  11550. "allowed when byte-swapping.\n"));
  11551. exit(EXIT_USAGE);
  11552. }
  11553. #endif
  11554. /*
  11555. * Set up signal action
  11556. */
  11557. memset(&sa, 0, sizeof(struct sigaction));
  11558. sa.sa_handler = signal_cancel;
  11559. sigaction(SIGINT, &sa, 0);
  11560. sigaction(SIGTERM, &sa, 0);
  11561. #ifdef SA_RESTART
  11562. sa.sa_flags = SA_RESTART;
  11563. #endif
  11564. e2fsck_global_ctx = ctx;
  11565. sa.sa_handler = signal_progress_on;
  11566. sigaction(SIGUSR1, &sa, 0);
  11567. sa.sa_handler = signal_progress_off;
  11568. sigaction(SIGUSR2, &sa, 0);
  11569. /* Update our PATH to include /sbin if we need to run badblocks */
  11570. if (cflag)
  11571. e2fs_set_sbin_path();
  11572. return 0;
  11573. }
  11574. static const char my_ver_string[] = E2FSPROGS_VERSION;
  11575. static const char my_ver_date[] = E2FSPROGS_DATE;
  11576. int e2fsck_main (int argc, char **argv);
  11577. int e2fsck_main (int argc, char **argv)
  11578. {
  11579. errcode_t retval;
  11580. int exit_value = EXIT_OK;
  11581. ext2_filsys fs = 0;
  11582. io_manager io_ptr;
  11583. struct ext2_super_block *sb;
  11584. const char *lib_ver_date;
  11585. int my_ver, lib_ver;
  11586. e2fsck_t ctx;
  11587. struct problem_context pctx;
  11588. int flags, run_result;
  11589. clear_problem_context(&pctx);
  11590. my_ver = ext2fs_parse_version_string(my_ver_string);
  11591. lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
  11592. if (my_ver > lib_ver) {
  11593. fprintf( stderr, _("Error: ext2fs library version "
  11594. "out of date!\n"));
  11595. show_version_only++;
  11596. }
  11597. retval = PRS(argc, argv, &ctx);
  11598. if (retval) {
  11599. bb_error_msg(_("while trying to initialize program"));
  11600. exit(EXIT_ERROR);
  11601. }
  11602. reserve_stdio_fds();
  11603. if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
  11604. fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
  11605. my_ver_date);
  11606. if (show_version_only) {
  11607. fprintf(stderr, _("\tUsing %s, %s\n"),
  11608. error_message(EXT2_ET_BASE), lib_ver_date);
  11609. exit(EXIT_OK);
  11610. }
  11611. check_mount(ctx);
  11612. if (!(ctx->options & E2F_OPT_PREEN) &&
  11613. !(ctx->options & E2F_OPT_NO) &&
  11614. !(ctx->options & E2F_OPT_YES)) {
  11615. if (!ctx->interactive)
  11616. bb_error_msg_and_die(_("need terminal for interactive repairs"));
  11617. }
  11618. ctx->superblock = ctx->use_superblock;
  11619. restart:
  11620. #ifdef CONFIG_TESTIO_DEBUG
  11621. io_ptr = test_io_manager;
  11622. test_io_backing_manager = unix_io_manager;
  11623. #else
  11624. io_ptr = unix_io_manager;
  11625. #endif
  11626. flags = 0;
  11627. if ((ctx->options & E2F_OPT_READONLY) == 0)
  11628. flags |= EXT2_FLAG_RW;
  11629. if (ctx->superblock && ctx->blocksize) {
  11630. retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
  11631. flags, ctx->superblock, ctx->blocksize,
  11632. io_ptr, &fs);
  11633. } else if (ctx->superblock) {
  11634. int blocksize;
  11635. for (blocksize = EXT2_MIN_BLOCK_SIZE;
  11636. blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
  11637. retval = ext2fs_open2(ctx->filesystem_name,
  11638. ctx->io_options, flags,
  11639. ctx->superblock, blocksize,
  11640. io_ptr, &fs);
  11641. if (!retval)
  11642. break;
  11643. }
  11644. } else
  11645. retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
  11646. flags, 0, 0, io_ptr, &fs);
  11647. if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
  11648. !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
  11649. ((retval == EXT2_ET_BAD_MAGIC) ||
  11650. ((retval == 0) && ext2fs_check_desc(fs)))) {
  11651. if (!fs || (fs->group_desc_count > 1)) {
  11652. printf(_("%s trying backup blocks...\n"),
  11653. retval ? _("Couldn't find ext2 superblock,") :
  11654. _("Group descriptors look bad..."));
  11655. get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
  11656. if (fs)
  11657. ext2fs_close(fs);
  11658. goto restart;
  11659. }
  11660. }
  11661. if (retval) {
  11662. bb_error_msg(_("while trying to open %s"),
  11663. ctx->filesystem_name);
  11664. if (retval == EXT2_ET_REV_TOO_HIGH) {
  11665. printf(_("The filesystem revision is apparently "
  11666. "too high for this version of e2fsck.\n"
  11667. "(Or the filesystem superblock "
  11668. "is corrupt)\n\n"));
  11669. fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
  11670. } else if (retval == EXT2_ET_SHORT_READ)
  11671. printf(_("Could this be a zero-length partition?\n"));
  11672. else if ((retval == EPERM) || (retval == EACCES))
  11673. printf(_("You must have %s access to the "
  11674. "filesystem or be root\n"),
  11675. (ctx->options & E2F_OPT_READONLY) ?
  11676. "r/o" : "r/w");
  11677. else if (retval == ENXIO)
  11678. printf(_("Possibly non-existent or swap device?\n"));
  11679. #ifdef EROFS
  11680. else if (retval == EROFS)
  11681. printf(_("Disk write-protected; use the -n option "
  11682. "to do a read-only\n"
  11683. "check of the device.\n"));
  11684. #endif
  11685. else
  11686. fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
  11687. bb_error_msg_and_die(0);
  11688. }
  11689. ctx->fs = fs;
  11690. fs->priv_data = ctx;
  11691. sb = fs->super;
  11692. if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
  11693. bb_error_msg(_("while trying to open %s"),
  11694. ctx->filesystem_name);
  11695. get_newer:
  11696. bb_error_msg_and_die(_("Get a newer version of e2fsck!"));
  11697. }
  11698. /*
  11699. * Set the device name, which is used whenever we print error
  11700. * or informational messages to the user.
  11701. */
  11702. if (ctx->device_name == 0 &&
  11703. (sb->s_volume_name[0] != 0)) {
  11704. ctx->device_name = string_copy(sb->s_volume_name,
  11705. sizeof(sb->s_volume_name));
  11706. }
  11707. if (ctx->device_name == 0)
  11708. ctx->device_name = ctx->filesystem_name;
  11709. /*
  11710. * Make sure the ext3 superblock fields are consistent.
  11711. */
  11712. retval = e2fsck_check_ext3_journal(ctx);
  11713. if (retval) {
  11714. bb_error_msg(_("while checking ext3 journal for %s"),
  11715. ctx->device_name);
  11716. bb_error_msg_and_die(0);
  11717. }
  11718. /*
  11719. * Check to see if we need to do ext3-style recovery. If so,
  11720. * do it, and then restart the fsck.
  11721. */
  11722. if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
  11723. if (ctx->options & E2F_OPT_READONLY) {
  11724. printf(_("Warning: skipping journal recovery "
  11725. "because doing a read-only filesystem "
  11726. "check.\n"));
  11727. io_channel_flush(ctx->fs->io);
  11728. } else {
  11729. if (ctx->flags & E2F_FLAG_RESTARTED) {
  11730. /*
  11731. * Whoops, we attempted to run the
  11732. * journal twice. This should never
  11733. * happen, unless the hardware or
  11734. * device driver is being bogus.
  11735. */
  11736. bb_error_msg(_("can't set superblock flags on %s"), ctx->device_name);
  11737. bb_error_msg_and_die(0);
  11738. }
  11739. retval = e2fsck_run_ext3_journal(ctx);
  11740. if (retval) {
  11741. bb_error_msg(_("while recovering ext3 journal of %s"),
  11742. ctx->device_name);
  11743. bb_error_msg_and_die(0);
  11744. }
  11745. ext2fs_close(ctx->fs);
  11746. ctx->fs = 0;
  11747. ctx->flags |= E2F_FLAG_RESTARTED;
  11748. goto restart;
  11749. }
  11750. }
  11751. /*
  11752. * Check for compatibility with the feature sets. We need to
  11753. * be more stringent than ext2fs_open().
  11754. */
  11755. if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
  11756. (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
  11757. bb_error_msg("(%s)", ctx->device_name);
  11758. goto get_newer;
  11759. }
  11760. if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
  11761. bb_error_msg("(%s)", ctx->device_name);
  11762. goto get_newer;
  11763. }
  11764. #ifdef ENABLE_COMPRESSION
  11765. /* FIXME - do we support this at all? */
  11766. if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
  11767. bb_error_msg(_("warning: compression support is experimental"));
  11768. #endif
  11769. #ifndef ENABLE_HTREE
  11770. if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
  11771. bb_error_msg(_("E2fsck not compiled with HTREE support,\n\t"
  11772. "but filesystem %s has HTREE directories."),
  11773. ctx->device_name);
  11774. goto get_newer;
  11775. }
  11776. #endif
  11777. /*
  11778. * If the user specified a specific superblock, presumably the
  11779. * master superblock has been trashed. So we mark the
  11780. * superblock as dirty, so it can be written out.
  11781. */
  11782. if (ctx->superblock &&
  11783. !(ctx->options & E2F_OPT_READONLY))
  11784. ext2fs_mark_super_dirty(fs);
  11785. /*
  11786. * We only update the master superblock because (a) paranoia;
  11787. * we don't want to corrupt the backup superblocks, and (b) we
  11788. * don't need to update the mount count and last checked
  11789. * fields in the backup superblock (the kernel doesn't
  11790. * update the backup superblocks anyway).
  11791. */
  11792. fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
  11793. ehandler_init(fs->io);
  11794. if (ctx->superblock)
  11795. set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
  11796. ext2fs_mark_valid(fs);
  11797. check_super_block(ctx);
  11798. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  11799. bb_error_msg_and_die(0);
  11800. check_if_skip(ctx);
  11801. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  11802. bb_error_msg_and_die(0);
  11803. #ifdef ENABLE_SWAPFS
  11804. #ifdef WORDS_BIGENDIAN
  11805. #define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES
  11806. #else
  11807. #define NATIVE_FLAG 0
  11808. #endif
  11809. if (normalize_swapfs) {
  11810. if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == NATIVE_FLAG) {
  11811. fprintf(stderr, _("%s: Filesystem byte order "
  11812. "already normalized.\n"), ctx->device_name);
  11813. bb_error_msg_and_die(0);
  11814. }
  11815. }
  11816. if (swapfs) {
  11817. swap_filesys(ctx);
  11818. if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
  11819. bb_error_msg_and_die(0);
  11820. }
  11821. #endif
  11822. /*
  11823. * Mark the system as valid, 'til proven otherwise
  11824. */
  11825. ext2fs_mark_valid(fs);
  11826. retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
  11827. if (retval) {
  11828. bb_error_msg(_("while reading bad blocks inode"));
  11829. preenhalt(ctx);
  11830. printf(_("This doesn't bode well,"
  11831. " but we'll try to go on...\n"));
  11832. }
  11833. run_result = e2fsck_run(ctx);
  11834. e2fsck_clear_progbar(ctx);
  11835. if (run_result == E2F_FLAG_RESTART) {
  11836. printf(_("Restarting e2fsck from the beginning...\n"));
  11837. retval = e2fsck_reset_context(ctx);
  11838. if (retval) {
  11839. bb_error_msg(_("while resetting context"));
  11840. bb_error_msg_and_die(0);
  11841. }
  11842. ext2fs_close(fs);
  11843. goto restart;
  11844. }
  11845. if (run_result & E2F_FLAG_CANCEL) {
  11846. printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
  11847. ctx->device_name : ctx->filesystem_name);
  11848. exit_value |= FSCK_CANCELED;
  11849. }
  11850. if (run_result & E2F_FLAG_ABORT)
  11851. bb_error_msg_and_die(_("aborted"));
  11852. /* Cleanup */
  11853. if (ext2fs_test_changed(fs)) {
  11854. exit_value |= EXIT_NONDESTRUCT;
  11855. if (!(ctx->options & E2F_OPT_PREEN))
  11856. printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
  11857. ctx->device_name);
  11858. if (ctx->mount_flags & EXT2_MF_ISROOT) {
  11859. printf(_("%s: ***** REBOOT LINUX *****\n"),
  11860. ctx->device_name);
  11861. exit_value |= EXIT_DESTRUCT;
  11862. }
  11863. }
  11864. if (!ext2fs_test_valid(fs)) {
  11865. printf(_("\n%s: ********** WARNING: Filesystem still has "
  11866. "errors **********\n\n"), ctx->device_name);
  11867. exit_value |= EXIT_UNCORRECTED;
  11868. exit_value &= ~EXIT_NONDESTRUCT;
  11869. }
  11870. if (exit_value & FSCK_CANCELED)
  11871. exit_value &= ~EXIT_NONDESTRUCT;
  11872. else {
  11873. show_stats(ctx);
  11874. if (!(ctx->options & E2F_OPT_READONLY)) {
  11875. if (ext2fs_test_valid(fs)) {
  11876. if (!(sb->s_state & EXT2_VALID_FS))
  11877. exit_value |= EXIT_NONDESTRUCT;
  11878. sb->s_state = EXT2_VALID_FS;
  11879. } else
  11880. sb->s_state &= ~EXT2_VALID_FS;
  11881. sb->s_mnt_count = 0;
  11882. sb->s_lastcheck = time(NULL);
  11883. ext2fs_mark_super_dirty(fs);
  11884. }
  11885. }
  11886. e2fsck_write_bitmaps(ctx);
  11887. ext2fs_close(fs);
  11888. ctx->fs = NULL;
  11889. free(ctx->filesystem_name);
  11890. free(ctx->journal_name);
  11891. e2fsck_free_context(ctx);
  11892. return exit_value;
  11893. }