aufs2.patch 610 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453
  1. diff -Nur linux-2.6.31.4.orig/Documentation/ABI/testing/debugfs-aufs linux-2.6.31.4/Documentation/ABI/testing/debugfs-aufs
  2. --- linux-2.6.31.4.orig/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100
  3. +++ linux-2.6.31.4/Documentation/ABI/testing/debugfs-aufs 2009-10-18 11:26:01.000000000 +0200
  4. @@ -0,0 +1,40 @@
  5. +What: /debug/aufs/si_<id>/
  6. +Date: March 2009
  7. +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
  8. +Description:
  9. + Under /debug/aufs, a directory named si_<id> is created
  10. + per aufs mount, where <id> is a unique id generated
  11. + internally.
  12. +
  13. +What: /debug/aufs/si_<id>/xib
  14. +Date: March 2009
  15. +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
  16. +Description:
  17. + It shows the consumed blocks by xib (External Inode Number
  18. + Bitmap), its block size and file size.
  19. + When the aufs mount option 'noxino' is specified, it
  20. + will be empty. About XINO files, see
  21. + Documentation/filesystems/aufs/aufs.5 in detail.
  22. +
  23. +What: /debug/aufs/si_<id>/xino0, xino1 ... xinoN
  24. +Date: March 2009
  25. +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
  26. +Description:
  27. + It shows the consumed blocks by xino (External Inode Number
  28. + Translation Table), its link count, block size and file
  29. + size.
  30. + When the aufs mount option 'noxino' is specified, it
  31. + will be empty. About XINO files, see
  32. + Documentation/filesystems/aufs/aufs.5 in detail.
  33. +
  34. +What: /debug/aufs/si_<id>/xigen
  35. +Date: March 2009
  36. +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
  37. +Description:
  38. + It shows the consumed blocks by xigen (External Inode
  39. + Generation Table), its block size and file size.
  40. + If CONFIG_AUFS_EXPORT is disabled, this entry will not
  41. + be created.
  42. + When the aufs mount option 'noxino' is specified, it
  43. + will be empty. About XINO files, see
  44. + Documentation/filesystems/aufs/aufs.5 in detail.
  45. diff -Nur linux-2.6.31.4.orig/Documentation/ABI/testing/sysfs-aufs linux-2.6.31.4/Documentation/ABI/testing/sysfs-aufs
  46. --- linux-2.6.31.4.orig/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100
  47. +++ linux-2.6.31.4/Documentation/ABI/testing/sysfs-aufs 2009-10-18 11:26:01.000000000 +0200
  48. @@ -0,0 +1,25 @@
  49. +What: /sys/fs/aufs/si_<id>/
  50. +Date: March 2009
  51. +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
  52. +Description:
  53. + Under /sys/fs/aufs, a directory named si_<id> is created
  54. + per aufs mount, where <id> is a unique id generated
  55. + internally.
  56. +
  57. +What: /sys/fs/aufs/si_<id>/br0, br1 ... brN
  58. +Date: March 2009
  59. +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
  60. +Description:
  61. + It shows the abolute path of a member directory (which
  62. + is called branch) in aufs, and its permission.
  63. +
  64. +What: /sys/fs/aufs/si_<id>/xi_path
  65. +Date: March 2009
  66. +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
  67. +Description:
  68. + It shows the abolute path of XINO (External Inode Number
  69. + Bitmap, Translation Table and Generation Table) file
  70. + even if it is the default path.
  71. + When the aufs mount option 'noxino' is specified, it
  72. + will be empty. About XINO files, see
  73. + Documentation/filesystems/aufs/aufs.5 in detail.
  74. diff -Nur linux-2.6.31.4.orig/fs/aufs/aufs.h linux-2.6.31.4/fs/aufs/aufs.h
  75. --- linux-2.6.31.4.orig/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100
  76. +++ linux-2.6.31.4/fs/aufs/aufs.h 2009-10-18 11:26:01.000000000 +0200
  77. @@ -0,0 +1,51 @@
  78. +/*
  79. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  80. + *
  81. + * This program, aufs is free software; you can redistribute it and/or modify
  82. + * it under the terms of the GNU General Public License as published by
  83. + * the Free Software Foundation; either version 2 of the License, or
  84. + * (at your option) any later version.
  85. + *
  86. + * This program is distributed in the hope that it will be useful,
  87. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  88. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  89. + * GNU General Public License for more details.
  90. + *
  91. + * You should have received a copy of the GNU General Public License
  92. + * along with this program; if not, write to the Free Software
  93. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  94. + */
  95. +
  96. +/*
  97. + * all header files
  98. + */
  99. +
  100. +#ifndef __AUFS_H__
  101. +#define __AUFS_H__
  102. +
  103. +#ifdef __KERNEL__
  104. +
  105. +#include "debug.h"
  106. +
  107. +#include "branch.h"
  108. +#include "cpup.h"
  109. +#include "dcsub.h"
  110. +#include "dbgaufs.h"
  111. +#include "dentry.h"
  112. +#include "dir.h"
  113. +#include "file.h"
  114. +#include "fstype.h"
  115. +#include "inode.h"
  116. +#include "loop.h"
  117. +#include "module.h"
  118. +#include "opts.h"
  119. +#include "rwsem.h"
  120. +#include "spl.h"
  121. +#include "super.h"
  122. +#include "sysaufs.h"
  123. +#include "vfsub.h"
  124. +#include "whout.h"
  125. +#include "wkq.h"
  126. +
  127. +#endif /* __KERNEL__ */
  128. +#endif /* __AUFS_H__ */
  129. diff -Nur linux-2.6.31.4.orig/fs/aufs/branch.c linux-2.6.31.4/fs/aufs/branch.c
  130. --- linux-2.6.31.4.orig/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100
  131. +++ linux-2.6.31.4/fs/aufs/branch.c 2009-10-18 11:26:01.000000000 +0200
  132. @@ -0,0 +1,974 @@
  133. +/*
  134. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  135. + *
  136. + * This program, aufs is free software; you can redistribute it and/or modify
  137. + * it under the terms of the GNU General Public License as published by
  138. + * the Free Software Foundation; either version 2 of the License, or
  139. + * (at your option) any later version.
  140. + *
  141. + * This program is distributed in the hope that it will be useful,
  142. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  143. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  144. + * GNU General Public License for more details.
  145. + *
  146. + * You should have received a copy of the GNU General Public License
  147. + * along with this program; if not, write to the Free Software
  148. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  149. + */
  150. +
  151. +/*
  152. + * branch management
  153. + */
  154. +
  155. +#include <linux/file.h>
  156. +#include "aufs.h"
  157. +
  158. +/*
  159. + * free a single branch
  160. + */
  161. +static void au_br_do_free(struct au_branch *br)
  162. +{
  163. + int i;
  164. + struct au_wbr *wbr;
  165. +
  166. + if (br->br_xino.xi_file)
  167. + fput(br->br_xino.xi_file);
  168. + mutex_destroy(&br->br_xino.xi_nondir_mtx);
  169. +
  170. + AuDebugOn(atomic_read(&br->br_count));
  171. +
  172. + wbr = br->br_wbr;
  173. + if (wbr) {
  174. + for (i = 0; i < AuBrWh_Last; i++)
  175. + dput(wbr->wbr_wh[i]);
  176. + AuDebugOn(atomic_read(&wbr->wbr_wh_running));
  177. + AuRwDestroy(&wbr->wbr_wh_rwsem);
  178. + }
  179. +
  180. + /* some filesystems acquire extra lock */
  181. + lockdep_off();
  182. + mntput(br->br_mnt);
  183. + lockdep_on();
  184. +
  185. + kfree(wbr);
  186. + kfree(br);
  187. +}
  188. +
  189. +/*
  190. + * frees all branches
  191. + */
  192. +void au_br_free(struct au_sbinfo *sbinfo)
  193. +{
  194. + aufs_bindex_t bmax;
  195. + struct au_branch **br;
  196. +
  197. + AuRwMustWriteLock(&sbinfo->si_rwsem);
  198. +
  199. + bmax = sbinfo->si_bend + 1;
  200. + br = sbinfo->si_branch;
  201. + while (bmax--)
  202. + au_br_do_free(*br++);
  203. +}
  204. +
  205. +/*
  206. + * find the index of a branch which is specified by @br_id.
  207. + */
  208. +int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
  209. +{
  210. + aufs_bindex_t bindex, bend;
  211. +
  212. + bend = au_sbend(sb);
  213. + for (bindex = 0; bindex <= bend; bindex++)
  214. + if (au_sbr_id(sb, bindex) == br_id)
  215. + return bindex;
  216. + return -1;
  217. +}
  218. +
  219. +/* ---------------------------------------------------------------------- */
  220. +
  221. +/*
  222. + * add a branch
  223. + */
  224. +
  225. +static int test_overlap(struct super_block *sb, struct dentry *h_d1,
  226. + struct dentry *h_d2)
  227. +{
  228. + if (unlikely(h_d1 == h_d2))
  229. + return 1;
  230. + return !!au_test_subdir(h_d1, h_d2)
  231. + || !!au_test_subdir(h_d2, h_d1)
  232. + || au_test_loopback_overlap(sb, h_d1, h_d2)
  233. + || au_test_loopback_overlap(sb, h_d2, h_d1);
  234. +}
  235. +
  236. +/*
  237. + * returns a newly allocated branch. @new_nbranch is a number of branches
  238. + * after adding a branch.
  239. + */
  240. +static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
  241. + int perm)
  242. +{
  243. + struct au_branch *add_branch;
  244. + struct dentry *root;
  245. +
  246. + root = sb->s_root;
  247. + add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS);
  248. + if (unlikely(!add_branch))
  249. + goto out;
  250. +
  251. + add_branch->br_wbr = NULL;
  252. + if (au_br_writable(perm)) {
  253. + /* may be freed separately at changing the branch permission */
  254. + add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr),
  255. + GFP_NOFS);
  256. + if (unlikely(!add_branch->br_wbr))
  257. + goto out_br;
  258. + }
  259. +
  260. + if (unlikely(au_sbr_realloc(au_sbi(sb), new_nbranch)
  261. + || au_di_realloc(au_di(root), new_nbranch)
  262. + || au_ii_realloc(au_ii(root->d_inode), new_nbranch)))
  263. + goto out_wbr;
  264. + return add_branch; /* success */
  265. +
  266. + out_wbr:
  267. + kfree(add_branch->br_wbr);
  268. + out_br:
  269. + kfree(add_branch);
  270. + out:
  271. + return ERR_PTR(-ENOMEM);
  272. +}
  273. +
  274. +/*
  275. + * test if the branch permission is legal or not.
  276. + */
  277. +static int test_br(struct inode *inode, int brperm, char *path)
  278. +{
  279. + int err;
  280. +
  281. + err = 0;
  282. + if (unlikely(au_br_writable(brperm) && IS_RDONLY(inode))) {
  283. + AuErr("write permission for readonly mount or inode, %s\n",
  284. + path);
  285. + err = -EINVAL;
  286. + }
  287. +
  288. + return err;
  289. +}
  290. +
  291. +/*
  292. + * returns:
  293. + * 0: success, the caller will add it
  294. + * plus: success, it is already unified, the caller should ignore it
  295. + * minus: error
  296. + */
  297. +static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
  298. +{
  299. + int err;
  300. + aufs_bindex_t bend, bindex;
  301. + struct dentry *root;
  302. + struct inode *inode, *h_inode;
  303. +
  304. + root = sb->s_root;
  305. + bend = au_sbend(sb);
  306. + if (unlikely(bend >= 0
  307. + && au_find_dbindex(root, add->path.dentry) >= 0)) {
  308. + err = 1;
  309. + if (!remount) {
  310. + err = -EINVAL;
  311. + AuErr("%s duplicated\n", add->pathname);
  312. + }
  313. + goto out;
  314. + }
  315. +
  316. + err = -ENOSPC; /* -E2BIG; */
  317. + if (unlikely(AUFS_BRANCH_MAX <= add->bindex
  318. + || AUFS_BRANCH_MAX - 1 <= bend)) {
  319. + AuErr("number of branches exceeded %s\n", add->pathname);
  320. + goto out;
  321. + }
  322. +
  323. + err = -EDOM;
  324. + if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) {
  325. + AuErr("bad index %d\n", add->bindex);
  326. + goto out;
  327. + }
  328. +
  329. + inode = add->path.dentry->d_inode;
  330. + err = -ENOENT;
  331. + if (unlikely(!inode->i_nlink)) {
  332. + AuErr("no existence %s\n", add->pathname);
  333. + goto out;
  334. + }
  335. +
  336. + err = -EINVAL;
  337. + if (unlikely(inode->i_sb == sb)) {
  338. + AuErr("%s must be outside\n", add->pathname);
  339. + goto out;
  340. + }
  341. +
  342. + if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
  343. + AuErr("unsupported filesystem, %s (%s)\n",
  344. + add->pathname, au_sbtype(inode->i_sb));
  345. + goto out;
  346. + }
  347. +
  348. + err = test_br(add->path.dentry->d_inode, add->perm, add->pathname);
  349. + if (unlikely(err))
  350. + goto out;
  351. +
  352. + if (bend < 0)
  353. + return 0; /* success */
  354. +
  355. + err = -EINVAL;
  356. + for (bindex = 0; bindex <= bend; bindex++)
  357. + if (unlikely(test_overlap(sb, add->path.dentry,
  358. + au_h_dptr(root, bindex)))) {
  359. + AuErr("%s is overlapped\n", add->pathname);
  360. + goto out;
  361. + }
  362. +
  363. + err = 0;
  364. + if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
  365. + h_inode = au_h_dptr(root, 0)->d_inode;
  366. + if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
  367. + || h_inode->i_uid != inode->i_uid
  368. + || h_inode->i_gid != inode->i_gid)
  369. + AuWarn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
  370. + add->pathname,
  371. + inode->i_uid, inode->i_gid,
  372. + (inode->i_mode & S_IALLUGO),
  373. + h_inode->i_uid, h_inode->i_gid,
  374. + (h_inode->i_mode & S_IALLUGO));
  375. + }
  376. +
  377. + out:
  378. + return err;
  379. +}
  380. +
  381. +/*
  382. + * initialize or clean the whiteouts for an adding branch
  383. + */
  384. +static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
  385. + int new_perm, struct dentry *h_root)
  386. +{
  387. + int err, old_perm;
  388. + aufs_bindex_t bindex;
  389. + struct mutex *h_mtx;
  390. + struct au_wbr *wbr;
  391. + struct au_hinode *hdir;
  392. +
  393. + wbr = br->br_wbr;
  394. + old_perm = br->br_perm;
  395. + br->br_perm = new_perm;
  396. + hdir = NULL;
  397. + h_mtx = NULL;
  398. + bindex = au_br_index(sb, br->br_id);
  399. + if (0 <= bindex) {
  400. + hdir = au_hi(sb->s_root->d_inode, bindex);
  401. + au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT);
  402. + } else {
  403. + h_mtx = &h_root->d_inode->i_mutex;
  404. + mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
  405. + }
  406. + if (!wbr)
  407. + err = au_wh_init(h_root, br, sb);
  408. + else {
  409. + wbr_wh_write_lock(wbr);
  410. + err = au_wh_init(h_root, br, sb);
  411. + wbr_wh_write_unlock(wbr);
  412. + }
  413. + if (hdir)
  414. + au_hin_imtx_unlock(hdir);
  415. + else
  416. + mutex_unlock(h_mtx);
  417. + br->br_perm = old_perm;
  418. +
  419. + if (!err && wbr && !au_br_writable(new_perm)) {
  420. + kfree(wbr);
  421. + br->br_wbr = NULL;
  422. + }
  423. +
  424. + return err;
  425. +}
  426. +
  427. +static int au_wbr_init(struct au_branch *br, struct super_block *sb,
  428. + int perm, struct path *path)
  429. +{
  430. + int err;
  431. + struct au_wbr *wbr;
  432. +
  433. + wbr = br->br_wbr;
  434. + au_rw_init(&wbr->wbr_wh_rwsem);
  435. + memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh));
  436. + atomic_set(&wbr->wbr_wh_running, 0);
  437. + wbr->wbr_bytes = 0;
  438. +
  439. + err = au_br_init_wh(sb, br, perm, path->dentry);
  440. +
  441. + return err;
  442. +}
  443. +
  444. +/* intialize a new branch */
  445. +static int au_br_init(struct au_branch *br, struct super_block *sb,
  446. + struct au_opt_add *add)
  447. +{
  448. + int err;
  449. +
  450. + err = 0;
  451. + memset(&br->br_xino, 0, sizeof(br->br_xino));
  452. + mutex_init(&br->br_xino.xi_nondir_mtx);
  453. + br->br_perm = add->perm;
  454. + br->br_mnt = add->path.mnt; /* set first, mntget() later */
  455. + atomic_set(&br->br_count, 0);
  456. + br->br_xino_upper = AUFS_XINO_TRUNC_INIT;
  457. + atomic_set(&br->br_xino_running, 0);
  458. + br->br_id = au_new_br_id(sb);
  459. +
  460. + if (au_br_writable(add->perm)) {
  461. + err = au_wbr_init(br, sb, add->perm, &add->path);
  462. + if (unlikely(err))
  463. + goto out;
  464. + }
  465. +
  466. + if (au_opt_test(au_mntflags(sb), XINO)) {
  467. + err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino,
  468. + au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
  469. + if (unlikely(err)) {
  470. + AuDebugOn(br->br_xino.xi_file);
  471. + goto out;
  472. + }
  473. + }
  474. +
  475. + sysaufs_br_init(br);
  476. + mntget(add->path.mnt);
  477. +
  478. + out:
  479. + return err;
  480. +}
  481. +
  482. +static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
  483. + struct au_branch *br, aufs_bindex_t bend,
  484. + aufs_bindex_t amount)
  485. +{
  486. + struct au_branch **brp;
  487. +
  488. + AuRwMustWriteLock(&sbinfo->si_rwsem);
  489. +
  490. + brp = sbinfo->si_branch + bindex;
  491. + memmove(brp + 1, brp, sizeof(*brp) * amount);
  492. + *brp = br;
  493. + sbinfo->si_bend++;
  494. + if (unlikely(bend < 0))
  495. + sbinfo->si_bend = 0;
  496. +}
  497. +
  498. +static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
  499. + aufs_bindex_t bend, aufs_bindex_t amount)
  500. +{
  501. + struct au_hdentry *hdp;
  502. +
  503. + AuRwMustWriteLock(&dinfo->di_rwsem);
  504. +
  505. + hdp = dinfo->di_hdentry + bindex;
  506. + memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
  507. + au_h_dentry_init(hdp);
  508. + dinfo->di_bend++;
  509. + if (unlikely(bend < 0))
  510. + dinfo->di_bstart = 0;
  511. +}
  512. +
  513. +static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
  514. + aufs_bindex_t bend, aufs_bindex_t amount)
  515. +{
  516. + struct au_hinode *hip;
  517. +
  518. + AuRwMustWriteLock(&iinfo->ii_rwsem);
  519. +
  520. + hip = iinfo->ii_hinode + bindex;
  521. + memmove(hip + 1, hip, sizeof(*hip) * amount);
  522. + hip->hi_inode = NULL;
  523. + au_hin_init(hip, NULL);
  524. + iinfo->ii_bend++;
  525. + if (unlikely(bend < 0))
  526. + iinfo->ii_bstart = 0;
  527. +}
  528. +
  529. +static void au_br_do_add(struct super_block *sb, struct dentry *h_dentry,
  530. + struct au_branch *br, aufs_bindex_t bindex)
  531. +{
  532. + struct dentry *root;
  533. + struct inode *root_inode;
  534. + aufs_bindex_t bend, amount;
  535. +
  536. + root = sb->s_root;
  537. + root_inode = root->d_inode;
  538. + au_plink_block_maintain(sb);
  539. + bend = au_sbend(sb);
  540. + amount = bend + 1 - bindex;
  541. + au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount);
  542. + au_br_do_add_hdp(au_di(root), bindex, bend, amount);
  543. + au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount);
  544. + au_set_h_dptr(root, bindex, dget(h_dentry));
  545. + au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode),
  546. + /*flags*/0);
  547. +}
  548. +
  549. +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
  550. +{
  551. + int err;
  552. + unsigned long long maxb;
  553. + aufs_bindex_t bend, add_bindex;
  554. + struct dentry *root, *h_dentry;
  555. + struct inode *root_inode;
  556. + struct au_branch *add_branch;
  557. +
  558. + root = sb->s_root;
  559. + root_inode = root->d_inode;
  560. + IMustLock(root_inode);
  561. + err = test_add(sb, add, remount);
  562. + if (unlikely(err < 0))
  563. + goto out;
  564. + if (err) {
  565. + err = 0;
  566. + goto out; /* success */
  567. + }
  568. +
  569. + bend = au_sbend(sb);
  570. + add_branch = au_br_alloc(sb, bend + 2, add->perm);
  571. + err = PTR_ERR(add_branch);
  572. + if (IS_ERR(add_branch))
  573. + goto out;
  574. +
  575. + err = au_br_init(add_branch, sb, add);
  576. + if (unlikely(err)) {
  577. + au_br_do_free(add_branch);
  578. + goto out;
  579. + }
  580. +
  581. + add_bindex = add->bindex;
  582. + h_dentry = add->path.dentry;
  583. + if (!remount)
  584. + au_br_do_add(sb, h_dentry, add_branch, add_bindex);
  585. + else {
  586. + sysaufs_brs_del(sb, add_bindex);
  587. + au_br_do_add(sb, h_dentry, add_branch, add_bindex);
  588. + sysaufs_brs_add(sb, add_bindex);
  589. + }
  590. +
  591. + if (!add_bindex)
  592. + au_cpup_attr_all(root_inode, /*force*/1);
  593. + else
  594. + au_add_nlink(root_inode, h_dentry->d_inode);
  595. + maxb = h_dentry->d_sb->s_maxbytes;
  596. + if (sb->s_maxbytes < maxb)
  597. + sb->s_maxbytes = maxb;
  598. +
  599. + /*
  600. + * this test/set prevents aufs from handling unnecesary inotify events
  601. + * of xino files, in a case of re-adding a writable branch which was
  602. + * once detached from aufs.
  603. + */
  604. + if (au_xino_brid(sb) < 0
  605. + && au_br_writable(add_branch->br_perm)
  606. + && !au_test_fs_bad_xino(h_dentry->d_sb)
  607. + && add_branch->br_xino.xi_file
  608. + && add_branch->br_xino.xi_file->f_dentry->d_parent == h_dentry)
  609. + au_xino_brid_set(sb, add_branch->br_id);
  610. +
  611. + out:
  612. + return err;
  613. +}
  614. +
  615. +/* ---------------------------------------------------------------------- */
  616. +
  617. +/*
  618. + * delete a branch
  619. + */
  620. +
  621. +/* to show the line number, do not make it inlined function */
  622. +#define AuVerbose(do_info, fmt, args...) do { \
  623. + if (do_info) \
  624. + AuInfo(fmt, ##args); \
  625. +} while (0)
  626. +
  627. +/*
  628. + * test if the branch is deletable or not.
  629. + */
  630. +static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
  631. + unsigned int sigen)
  632. +{
  633. + int err, i, j, ndentry;
  634. + aufs_bindex_t bstart, bend;
  635. + unsigned char verbose;
  636. + struct au_dcsub_pages dpages;
  637. + struct au_dpage *dpage;
  638. + struct dentry *d;
  639. + struct inode *inode;
  640. +
  641. + err = au_dpages_init(&dpages, GFP_NOFS);
  642. + if (unlikely(err))
  643. + goto out;
  644. + err = au_dcsub_pages(&dpages, root, NULL, NULL);
  645. + if (unlikely(err))
  646. + goto out_dpages;
  647. +
  648. + verbose = !!au_opt_test(au_mntflags(root->d_sb), VERBOSE);
  649. + for (i = 0; !err && i < dpages.ndpage; i++) {
  650. + dpage = dpages.dpages + i;
  651. + ndentry = dpage->ndentry;
  652. + for (j = 0; !err && j < ndentry; j++) {
  653. + d = dpage->dentries[j];
  654. + AuDebugOn(!atomic_read(&d->d_count));
  655. + inode = d->d_inode;
  656. + if (au_digen(d) == sigen && au_iigen(inode) == sigen)
  657. + di_read_lock_child(d, AuLock_IR);
  658. + else {
  659. + di_write_lock_child(d);
  660. + err = au_reval_dpath(d, sigen);
  661. + if (!err)
  662. + di_downgrade_lock(d, AuLock_IR);
  663. + else {
  664. + di_write_unlock(d);
  665. + break;
  666. + }
  667. + }
  668. +
  669. + bstart = au_dbstart(d);
  670. + bend = au_dbend(d);
  671. + if (bstart <= bindex
  672. + && bindex <= bend
  673. + && au_h_dptr(d, bindex)
  674. + && (!S_ISDIR(inode->i_mode) || bstart == bend)) {
  675. + err = -EBUSY;
  676. + AuVerbose(verbose, "busy %.*s\n", AuDLNPair(d));
  677. + }
  678. + di_read_unlock(d, AuLock_IR);
  679. + }
  680. + }
  681. +
  682. + out_dpages:
  683. + au_dpages_free(&dpages);
  684. + out:
  685. + return err;
  686. +}
  687. +
  688. +static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
  689. + unsigned int sigen)
  690. +{
  691. + int err;
  692. + struct inode *i;
  693. + aufs_bindex_t bstart, bend;
  694. + unsigned char verbose;
  695. +
  696. + err = 0;
  697. + verbose = !!au_opt_test(au_mntflags(sb), VERBOSE);
  698. + list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
  699. + AuDebugOn(!atomic_read(&i->i_count));
  700. + if (!list_empty(&i->i_dentry))
  701. + continue;
  702. +
  703. + if (au_iigen(i) == sigen)
  704. + ii_read_lock_child(i);
  705. + else {
  706. + ii_write_lock_child(i);
  707. + err = au_refresh_hinode_self(i, /*do_attr*/1);
  708. + if (!err)
  709. + ii_downgrade_lock(i);
  710. + else {
  711. + ii_write_unlock(i);
  712. + break;
  713. + }
  714. + }
  715. +
  716. + bstart = au_ibstart(i);
  717. + bend = au_ibend(i);
  718. + if (bstart <= bindex
  719. + && bindex <= bend
  720. + && au_h_iptr(i, bindex)
  721. + && (!S_ISDIR(i->i_mode) || bstart == bend)) {
  722. + err = -EBUSY;
  723. + AuVerbose(verbose, "busy i%lu\n", i->i_ino);
  724. + ii_read_unlock(i);
  725. + break;
  726. + }
  727. + ii_read_unlock(i);
  728. + }
  729. +
  730. + return err;
  731. +}
  732. +
  733. +static int test_children_busy(struct dentry *root, aufs_bindex_t bindex)
  734. +{
  735. + int err;
  736. + unsigned int sigen;
  737. +
  738. + sigen = au_sigen(root->d_sb);
  739. + DiMustNoWaiters(root);
  740. + IiMustNoWaiters(root->d_inode);
  741. + di_write_unlock(root);
  742. + err = test_dentry_busy(root, bindex, sigen);
  743. + if (!err)
  744. + err = test_inode_busy(root->d_sb, bindex, sigen);
  745. + di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
  746. +
  747. + return err;
  748. +}
  749. +
  750. +static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
  751. + const aufs_bindex_t bindex,
  752. + const aufs_bindex_t bend)
  753. +{
  754. + struct au_branch **brp, **p;
  755. +
  756. + AuRwMustWriteLock(&sbinfo->si_rwsem);
  757. +
  758. + brp = sbinfo->si_branch + bindex;
  759. + if (bindex < bend)
  760. + memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex));
  761. + sbinfo->si_branch[0 + bend] = NULL;
  762. + sbinfo->si_bend--;
  763. +
  764. + p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, GFP_NOFS);
  765. + if (p)
  766. + sbinfo->si_branch = p;
  767. +}
  768. +
  769. +static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
  770. + const aufs_bindex_t bend)
  771. +{
  772. + struct au_hdentry *hdp, *p;
  773. +
  774. + AuRwMustWriteLock(&dinfo->di_rwsem);
  775. +
  776. + hdp = dinfo->di_hdentry + bindex;
  777. + if (bindex < bend)
  778. + memmove(hdp, hdp + 1, sizeof(*hdp) * (bend - bindex));
  779. + dinfo->di_hdentry[0 + bend].hd_dentry = NULL;
  780. + dinfo->di_bend--;
  781. +
  782. + p = krealloc(dinfo->di_hdentry, sizeof(*p) * bend, GFP_NOFS);
  783. + if (p)
  784. + dinfo->di_hdentry = p;
  785. +}
  786. +
  787. +static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
  788. + const aufs_bindex_t bend)
  789. +{
  790. + struct au_hinode *hip, *p;
  791. +
  792. + AuRwMustWriteLock(&iinfo->ii_rwsem);
  793. +
  794. + hip = iinfo->ii_hinode + bindex;
  795. + if (bindex < bend)
  796. + memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex));
  797. + iinfo->ii_hinode[0 + bend].hi_inode = NULL;
  798. + au_hin_init(iinfo->ii_hinode + bend, NULL);
  799. + iinfo->ii_bend--;
  800. +
  801. + p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, GFP_NOFS);
  802. + if (p)
  803. + iinfo->ii_hinode = p;
  804. +}
  805. +
  806. +static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
  807. + struct au_branch *br)
  808. +{
  809. + aufs_bindex_t bend;
  810. + struct au_sbinfo *sbinfo;
  811. + struct dentry *root;
  812. + struct inode *inode;
  813. +
  814. + SiMustWriteLock(sb);
  815. +
  816. + root = sb->s_root;
  817. + inode = root->d_inode;
  818. + au_plink_block_maintain(sb);
  819. + sbinfo = au_sbi(sb);
  820. + bend = sbinfo->si_bend;
  821. +
  822. + dput(au_h_dptr(root, bindex));
  823. + au_hiput(au_hi(inode, bindex));
  824. + au_br_do_free(br);
  825. +
  826. + au_br_do_del_brp(sbinfo, bindex, bend);
  827. + au_br_do_del_hdp(au_di(root), bindex, bend);
  828. + au_br_do_del_hip(au_ii(inode), bindex, bend);
  829. +}
  830. +
  831. +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
  832. +{
  833. + int err, rerr, i;
  834. + unsigned int mnt_flags;
  835. + aufs_bindex_t bindex, bend, br_id;
  836. + unsigned char do_wh, verbose;
  837. + struct au_branch *br;
  838. + struct au_wbr *wbr;
  839. +
  840. + err = 0;
  841. + bindex = au_find_dbindex(sb->s_root, del->h_path.dentry);
  842. + if (bindex < 0) {
  843. + if (remount)
  844. + goto out; /* success */
  845. + err = -ENOENT;
  846. + AuErr("%s no such branch\n", del->pathname);
  847. + goto out;
  848. + }
  849. + AuDbg("bindex b%d\n", bindex);
  850. +
  851. + err = -EBUSY;
  852. + mnt_flags = au_mntflags(sb);
  853. + verbose = !!au_opt_test(mnt_flags, VERBOSE);
  854. + bend = au_sbend(sb);
  855. + if (unlikely(!bend)) {
  856. + AuVerbose(verbose, "no more branches left\n");
  857. + goto out;
  858. + }
  859. + br = au_sbr(sb, bindex);
  860. + i = atomic_read(&br->br_count);
  861. + if (unlikely(i)) {
  862. + AuVerbose(verbose, "%d file(s) opened\n", i);
  863. + goto out;
  864. + }
  865. +
  866. + wbr = br->br_wbr;
  867. + do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
  868. + if (do_wh) {
  869. + /* instead of WbrWhMustWriteLock(wbr) */
  870. + SiMustWriteLock(sb);
  871. + for (i = 0; i < AuBrWh_Last; i++) {
  872. + dput(wbr->wbr_wh[i]);
  873. + wbr->wbr_wh[i] = NULL;
  874. + }
  875. + }
  876. +
  877. + err = test_children_busy(sb->s_root, bindex);
  878. + if (unlikely(err)) {
  879. + if (do_wh)
  880. + goto out_wh;
  881. + goto out;
  882. + }
  883. +
  884. + err = 0;
  885. + br_id = br->br_id;
  886. + if (!remount)
  887. + au_br_do_del(sb, bindex, br);
  888. + else {
  889. + sysaufs_brs_del(sb, bindex);
  890. + au_br_do_del(sb, bindex, br);
  891. + sysaufs_brs_add(sb, bindex);
  892. + }
  893. +
  894. + if (!bindex)
  895. + au_cpup_attr_all(sb->s_root->d_inode, /*force*/1);
  896. + else
  897. + au_sub_nlink(sb->s_root->d_inode, del->h_path.dentry->d_inode);
  898. + if (au_opt_test(mnt_flags, PLINK))
  899. + au_plink_half_refresh(sb, br_id);
  900. +
  901. + if (sb->s_maxbytes == del->h_path.dentry->d_sb->s_maxbytes) {
  902. + bend--;
  903. + sb->s_maxbytes = 0;
  904. + for (bindex = 0; bindex <= bend; bindex++) {
  905. + unsigned long long maxb;
  906. +
  907. + maxb = au_sbr_sb(sb, bindex)->s_maxbytes;
  908. + if (sb->s_maxbytes < maxb)
  909. + sb->s_maxbytes = maxb;
  910. + }
  911. + }
  912. +
  913. + if (au_xino_brid(sb) == br->br_id)
  914. + au_xino_brid_set(sb, -1);
  915. + goto out; /* success */
  916. +
  917. + out_wh:
  918. + /* revert */
  919. + rerr = au_br_init_wh(sb, br, br->br_perm, del->h_path.dentry);
  920. + if (rerr)
  921. + AuWarn("failed re-creating base whiteout, %s. (%d)\n",
  922. + del->pathname, rerr);
  923. + out:
  924. + return err;
  925. +}
  926. +
  927. +/* ---------------------------------------------------------------------- */
  928. +
  929. +/*
  930. + * change a branch permission
  931. + */
  932. +
  933. +static int do_need_sigen_inc(int a, int b)
  934. +{
  935. + return au_br_whable(a) && !au_br_whable(b);
  936. +}
  937. +
  938. +static int need_sigen_inc(int old, int new)
  939. +{
  940. + return do_need_sigen_inc(old, new)
  941. + || do_need_sigen_inc(new, old);
  942. +}
  943. +
  944. +static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
  945. +{
  946. + int err;
  947. + unsigned long n, ul, bytes, files;
  948. + aufs_bindex_t bstart;
  949. + struct file *file, *hf, **a;
  950. + const int step_bytes = 1024, /* memory allocation unit */
  951. + step_files = step_bytes / sizeof(*a);
  952. +
  953. + err = -ENOMEM;
  954. + n = 0;
  955. + bytes = step_bytes;
  956. + files = step_files;
  957. + a = kmalloc(bytes, GFP_NOFS);
  958. + if (unlikely(!a))
  959. + goto out;
  960. +
  961. + /* no need file_list_lock() since sbinfo is locked? defered? */
  962. + list_for_each_entry(file, &sb->s_files, f_u.fu_list) {
  963. + if (special_file(file->f_dentry->d_inode->i_mode))
  964. + continue;
  965. +
  966. + AuDbg("%.*s\n", AuDLNPair(file->f_dentry));
  967. + fi_read_lock(file);
  968. + if (unlikely(au_test_mmapped(file))) {
  969. + err = -EBUSY;
  970. + FiMustNoWaiters(file);
  971. + fi_read_unlock(file);
  972. + goto out_free;
  973. + }
  974. +
  975. + bstart = au_fbstart(file);
  976. + if (!S_ISREG(file->f_dentry->d_inode->i_mode)
  977. + || !(file->f_mode & FMODE_WRITE)
  978. + || bstart != bindex) {
  979. + FiMustNoWaiters(file);
  980. + fi_read_unlock(file);
  981. + continue;
  982. + }
  983. +
  984. + hf = au_h_fptr(file, bstart);
  985. + FiMustNoWaiters(file);
  986. + fi_read_unlock(file);
  987. +
  988. + if (n < files)
  989. + a[n++] = hf;
  990. + else {
  991. + void *p;
  992. +
  993. + err = -ENOMEM;
  994. + bytes += step_bytes;
  995. + files += step_files;
  996. + p = krealloc(a, bytes, GFP_NOFS);
  997. + if (p) {
  998. + a = p;
  999. + a[n++] = hf;
  1000. + } else
  1001. + goto out_free;
  1002. + }
  1003. + }
  1004. +
  1005. + err = 0;
  1006. + for (ul = 0; ul < n; ul++) {
  1007. + /* todo: already flushed? */
  1008. + /* cf. fs/super.c:mark_files_ro() */
  1009. + hf = a[ul];
  1010. + hf->f_mode &= ~FMODE_WRITE;
  1011. + if (!file_check_writeable(hf)) {
  1012. + file_release_write(hf);
  1013. + mnt_drop_write(hf->f_vfsmnt);
  1014. + }
  1015. + }
  1016. +
  1017. + out_free:
  1018. + kfree(a);
  1019. + out:
  1020. + return err;
  1021. +}
  1022. +
  1023. +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
  1024. + int *do_update)
  1025. +{
  1026. + int err, rerr;
  1027. + aufs_bindex_t bindex;
  1028. + struct dentry *root;
  1029. + struct au_branch *br;
  1030. +
  1031. + root = sb->s_root;
  1032. + au_plink_block_maintain(sb);
  1033. + bindex = au_find_dbindex(root, mod->h_root);
  1034. + if (bindex < 0) {
  1035. + if (remount)
  1036. + return 0; /* success */
  1037. + err = -ENOENT;
  1038. + AuErr("%s no such branch\n", mod->path);
  1039. + goto out;
  1040. + }
  1041. + AuDbg("bindex b%d\n", bindex);
  1042. +
  1043. + err = test_br(mod->h_root->d_inode, mod->perm, mod->path);
  1044. + if (unlikely(err))
  1045. + goto out;
  1046. +
  1047. + br = au_sbr(sb, bindex);
  1048. + if (br->br_perm == mod->perm)
  1049. + return 0; /* success */
  1050. +
  1051. + if (au_br_writable(br->br_perm)) {
  1052. + /* remove whiteout base */
  1053. + err = au_br_init_wh(sb, br, mod->perm, mod->h_root);
  1054. + if (unlikely(err))
  1055. + goto out;
  1056. +
  1057. + if (!au_br_writable(mod->perm)) {
  1058. + /* rw --> ro, file might be mmapped */
  1059. + DiMustNoWaiters(root);
  1060. + IiMustNoWaiters(root->d_inode);
  1061. + di_write_unlock(root);
  1062. + err = au_br_mod_files_ro(sb, bindex);
  1063. + /* aufs_write_lock() calls ..._child() */
  1064. + di_write_lock_child(root);
  1065. +
  1066. + if (unlikely(err)) {
  1067. + rerr = -ENOMEM;
  1068. + br->br_wbr = kmalloc(sizeof(*br->br_wbr),
  1069. + GFP_NOFS);
  1070. + if (br->br_wbr)
  1071. + rerr = au_br_init_wh
  1072. + (sb, br, br->br_perm,
  1073. + mod->h_root);
  1074. + if (unlikely(rerr)) {
  1075. + AuIOErr("nested error %d (%d)\n",
  1076. + rerr, err);
  1077. + br->br_perm = mod->perm;
  1078. + }
  1079. + }
  1080. + }
  1081. + } else if (au_br_writable(mod->perm)) {
  1082. + /* ro --> rw */
  1083. + err = -ENOMEM;
  1084. + br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS);
  1085. + if (br->br_wbr) {
  1086. + struct path path = {
  1087. + .mnt = br->br_mnt,
  1088. + .dentry = mod->h_root
  1089. + };
  1090. +
  1091. + err = au_wbr_init(br, sb, mod->perm, &path);
  1092. + if (unlikely(err)) {
  1093. + kfree(br->br_wbr);
  1094. + br->br_wbr = NULL;
  1095. + }
  1096. + }
  1097. + }
  1098. +
  1099. + if (!err) {
  1100. + *do_update |= need_sigen_inc(br->br_perm, mod->perm);
  1101. + br->br_perm = mod->perm;
  1102. + }
  1103. +
  1104. + out:
  1105. + return err;
  1106. +}
  1107. diff -Nur linux-2.6.31.4.orig/fs/aufs/branch.h linux-2.6.31.4/fs/aufs/branch.h
  1108. --- linux-2.6.31.4.orig/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100
  1109. +++ linux-2.6.31.4/fs/aufs/branch.h 2009-10-18 11:26:01.000000000 +0200
  1110. @@ -0,0 +1,219 @@
  1111. +/*
  1112. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  1113. + *
  1114. + * This program, aufs is free software; you can redistribute it and/or modify
  1115. + * it under the terms of the GNU General Public License as published by
  1116. + * the Free Software Foundation; either version 2 of the License, or
  1117. + * (at your option) any later version.
  1118. + *
  1119. + * This program is distributed in the hope that it will be useful,
  1120. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1121. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1122. + * GNU General Public License for more details.
  1123. + *
  1124. + * You should have received a copy of the GNU General Public License
  1125. + * along with this program; if not, write to the Free Software
  1126. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  1127. + */
  1128. +
  1129. +/*
  1130. + * branch filesystems and xino for them
  1131. + */
  1132. +
  1133. +#ifndef __AUFS_BRANCH_H__
  1134. +#define __AUFS_BRANCH_H__
  1135. +
  1136. +#ifdef __KERNEL__
  1137. +
  1138. +#include <linux/fs.h>
  1139. +#include <linux/mount.h>
  1140. +#include <linux/aufs_type.h>
  1141. +#include "rwsem.h"
  1142. +#include "super.h"
  1143. +
  1144. +/* ---------------------------------------------------------------------- */
  1145. +
  1146. +/* a xino file */
  1147. +struct au_xino_file {
  1148. + struct file *xi_file;
  1149. + struct mutex xi_nondir_mtx;
  1150. +
  1151. + /* todo: make xino files an array to support huge inode number */
  1152. +
  1153. +#ifdef CONFIG_DEBUG_FS
  1154. + struct dentry *xi_dbgaufs;
  1155. +#endif
  1156. +};
  1157. +
  1158. +/* members for writable branch only */
  1159. +enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
  1160. +struct au_wbr {
  1161. + struct au_rwsem wbr_wh_rwsem;
  1162. + struct dentry *wbr_wh[AuBrWh_Last];
  1163. + atomic_t wbr_wh_running;
  1164. +#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
  1165. +#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
  1166. +#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
  1167. +
  1168. + /* mfs mode */
  1169. + unsigned long long wbr_bytes;
  1170. +};
  1171. +
  1172. +/* protected by superblock rwsem */
  1173. +struct au_branch {
  1174. + struct au_xino_file br_xino;
  1175. +
  1176. + aufs_bindex_t br_id;
  1177. +
  1178. + int br_perm;
  1179. + struct vfsmount *br_mnt;
  1180. + atomic_t br_count;
  1181. +
  1182. + struct au_wbr *br_wbr;
  1183. +
  1184. + /* xino truncation */
  1185. + blkcnt_t br_xino_upper; /* watermark in blocks */
  1186. + atomic_t br_xino_running;
  1187. +
  1188. +#ifdef CONFIG_SYSFS
  1189. + /* an entry under sysfs per mount-point */
  1190. + char br_name[8];
  1191. + struct attribute br_attr;
  1192. +#endif
  1193. +};
  1194. +
  1195. +/* ---------------------------------------------------------------------- */
  1196. +
  1197. +/* branch permission and attribute */
  1198. +enum {
  1199. + AuBrPerm_RW, /* writable, linkable wh */
  1200. + AuBrPerm_RO, /* readonly, no wh */
  1201. + AuBrPerm_RR, /* natively readonly, no wh */
  1202. +
  1203. + AuBrPerm_RWNoLinkWH, /* un-linkable whiteouts */
  1204. +
  1205. + AuBrPerm_ROWH, /* whiteout-able */
  1206. + AuBrPerm_RRWH, /* whiteout-able */
  1207. +
  1208. + AuBrPerm_Last
  1209. +};
  1210. +
  1211. +static inline int au_br_writable(int brperm)
  1212. +{
  1213. + return brperm == AuBrPerm_RW || brperm == AuBrPerm_RWNoLinkWH;
  1214. +}
  1215. +
  1216. +static inline int au_br_whable(int brperm)
  1217. +{
  1218. + return brperm == AuBrPerm_RW
  1219. + || brperm == AuBrPerm_ROWH
  1220. + || brperm == AuBrPerm_RRWH;
  1221. +}
  1222. +
  1223. +static inline int au_br_rdonly(struct au_branch *br)
  1224. +{
  1225. + return ((br->br_mnt->mnt_sb->s_flags & MS_RDONLY)
  1226. + || !au_br_writable(br->br_perm))
  1227. + ? -EROFS : 0;
  1228. +}
  1229. +
  1230. +static inline int au_br_hinotifyable(int brperm __maybe_unused)
  1231. +{
  1232. +#ifdef CONFIG_AUFS_HINOTIFY
  1233. + return brperm != AuBrPerm_RR && brperm != AuBrPerm_RRWH;
  1234. +#else
  1235. + return 0;
  1236. +#endif
  1237. +}
  1238. +
  1239. +/* ---------------------------------------------------------------------- */
  1240. +
  1241. +/* branch.c */
  1242. +struct au_sbinfo;
  1243. +void au_br_free(struct au_sbinfo *sinfo);
  1244. +int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
  1245. +struct au_opt_add;
  1246. +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
  1247. +struct au_opt_del;
  1248. +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
  1249. +struct au_opt_mod;
  1250. +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
  1251. + int *do_update);
  1252. +
  1253. +/* xino.c */
  1254. +static const loff_t au_loff_max = LLONG_MAX;
  1255. +
  1256. +int au_xib_trunc(struct super_block *sb);
  1257. +ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size,
  1258. + loff_t *pos);
  1259. +ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
  1260. + loff_t *pos);
  1261. +struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
  1262. +struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
  1263. +ino_t au_xino_new_ino(struct super_block *sb);
  1264. +int au_xino_write0(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  1265. + ino_t ino);
  1266. +int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  1267. + ino_t ino);
  1268. +int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  1269. + ino_t *ino);
  1270. +int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
  1271. + struct file *base_file, int do_test);
  1272. +int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
  1273. +
  1274. +struct au_opt_xino;
  1275. +int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
  1276. +void au_xino_clr(struct super_block *sb);
  1277. +struct file *au_xino_def(struct super_block *sb);
  1278. +int au_xino_path(struct seq_file *seq, struct file *file);
  1279. +
  1280. +/* ---------------------------------------------------------------------- */
  1281. +
  1282. +/* Superblock to branch */
  1283. +static inline
  1284. +aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
  1285. +{
  1286. + return au_sbr(sb, bindex)->br_id;
  1287. +}
  1288. +
  1289. +static inline
  1290. +struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
  1291. +{
  1292. + return au_sbr(sb, bindex)->br_mnt;
  1293. +}
  1294. +
  1295. +static inline
  1296. +struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
  1297. +{
  1298. + return au_sbr_mnt(sb, bindex)->mnt_sb;
  1299. +}
  1300. +
  1301. +static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
  1302. +{
  1303. + atomic_dec_return(&au_sbr(sb, bindex)->br_count);
  1304. +}
  1305. +
  1306. +static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
  1307. +{
  1308. + return au_sbr(sb, bindex)->br_perm;
  1309. +}
  1310. +
  1311. +static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
  1312. +{
  1313. + return au_br_whable(au_sbr_perm(sb, bindex));
  1314. +}
  1315. +
  1316. +/* ---------------------------------------------------------------------- */
  1317. +
  1318. +/*
  1319. + * wbr_wh_read_lock, wbr_wh_write_lock
  1320. + * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
  1321. + */
  1322. +AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
  1323. +
  1324. +#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
  1325. +#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
  1326. +#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
  1327. +
  1328. +#endif /* __KERNEL__ */
  1329. +#endif /* __AUFS_BRANCH_H__ */
  1330. diff -Nur linux-2.6.31.4.orig/fs/aufs/cpup.c linux-2.6.31.4/fs/aufs/cpup.c
  1331. --- linux-2.6.31.4.orig/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
  1332. +++ linux-2.6.31.4/fs/aufs/cpup.c 2009-10-18 11:26:01.000000000 +0200
  1333. @@ -0,0 +1,1048 @@
  1334. +/*
  1335. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  1336. + *
  1337. + * This program, aufs is free software; you can redistribute it and/or modify
  1338. + * it under the terms of the GNU General Public License as published by
  1339. + * the Free Software Foundation; either version 2 of the License, or
  1340. + * (at your option) any later version.
  1341. + *
  1342. + * This program is distributed in the hope that it will be useful,
  1343. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1344. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1345. + * GNU General Public License for more details.
  1346. + *
  1347. + * You should have received a copy of the GNU General Public License
  1348. + * along with this program; if not, write to the Free Software
  1349. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  1350. + */
  1351. +
  1352. +/*
  1353. + * copy-up functions, see wbr_policy.c for copy-down
  1354. + */
  1355. +
  1356. +#include <linux/file.h>
  1357. +#include <linux/fs_stack.h>
  1358. +#include <linux/mm.h>
  1359. +#include <linux/uaccess.h>
  1360. +#include "aufs.h"
  1361. +
  1362. +void au_cpup_attr_flags(struct inode *dst, struct inode *src)
  1363. +{
  1364. + const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
  1365. + | S_NOATIME | S_NOCMTIME;
  1366. +
  1367. + dst->i_flags |= src->i_flags & ~mask;
  1368. + if (au_test_fs_notime(dst->i_sb))
  1369. + dst->i_flags |= S_NOATIME | S_NOCMTIME;
  1370. +}
  1371. +
  1372. +void au_cpup_attr_timesizes(struct inode *inode)
  1373. +{
  1374. + struct inode *h_inode;
  1375. +
  1376. + h_inode = au_h_iptr(inode, au_ibstart(inode));
  1377. + fsstack_copy_attr_times(inode, h_inode);
  1378. + vfsub_copy_inode_size(inode, h_inode);
  1379. +}
  1380. +
  1381. +void au_cpup_attr_nlink(struct inode *inode, int force)
  1382. +{
  1383. + struct inode *h_inode;
  1384. + struct super_block *sb;
  1385. + aufs_bindex_t bindex, bend;
  1386. +
  1387. + sb = inode->i_sb;
  1388. + bindex = au_ibstart(inode);
  1389. + h_inode = au_h_iptr(inode, bindex);
  1390. + if (!force
  1391. + && !S_ISDIR(h_inode->i_mode)
  1392. + && au_opt_test(au_mntflags(sb), PLINK)
  1393. + && au_plink_test(inode))
  1394. + return;
  1395. +
  1396. + inode->i_nlink = h_inode->i_nlink;
  1397. +
  1398. + /*
  1399. + * fewer nlink makes find(1) noisy, but larger nlink doesn't.
  1400. + * it may includes whplink directory.
  1401. + */
  1402. + if (S_ISDIR(h_inode->i_mode)) {
  1403. + bend = au_ibend(inode);
  1404. + for (bindex++; bindex <= bend; bindex++) {
  1405. + h_inode = au_h_iptr(inode, bindex);
  1406. + if (h_inode)
  1407. + au_add_nlink(inode, h_inode);
  1408. + }
  1409. + }
  1410. +}
  1411. +
  1412. +void au_cpup_attr_changeable(struct inode *inode)
  1413. +{
  1414. + struct inode *h_inode;
  1415. +
  1416. + h_inode = au_h_iptr(inode, au_ibstart(inode));
  1417. + inode->i_mode = h_inode->i_mode;
  1418. + inode->i_uid = h_inode->i_uid;
  1419. + inode->i_gid = h_inode->i_gid;
  1420. + au_cpup_attr_timesizes(inode);
  1421. + au_cpup_attr_flags(inode, h_inode);
  1422. +}
  1423. +
  1424. +void au_cpup_igen(struct inode *inode, struct inode *h_inode)
  1425. +{
  1426. + struct au_iinfo *iinfo = au_ii(inode);
  1427. +
  1428. + IiMustWriteLock(inode);
  1429. +
  1430. + iinfo->ii_higen = h_inode->i_generation;
  1431. + iinfo->ii_hsb1 = h_inode->i_sb;
  1432. +}
  1433. +
  1434. +void au_cpup_attr_all(struct inode *inode, int force)
  1435. +{
  1436. + struct inode *h_inode;
  1437. +
  1438. + h_inode = au_h_iptr(inode, au_ibstart(inode));
  1439. + au_cpup_attr_changeable(inode);
  1440. + if (inode->i_nlink > 0)
  1441. + au_cpup_attr_nlink(inode, force);
  1442. + inode->i_rdev = h_inode->i_rdev;
  1443. + inode->i_blkbits = h_inode->i_blkbits;
  1444. + au_cpup_igen(inode, h_inode);
  1445. +}
  1446. +
  1447. +/* ---------------------------------------------------------------------- */
  1448. +
  1449. +/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
  1450. +
  1451. +/* keep the timestamps of the parent dir when cpup */
  1452. +void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
  1453. + struct path *h_path)
  1454. +{
  1455. + struct inode *h_inode;
  1456. +
  1457. + dt->dt_dentry = dentry;
  1458. + dt->dt_h_path = *h_path;
  1459. + h_inode = h_path->dentry->d_inode;
  1460. + dt->dt_atime = h_inode->i_atime;
  1461. + dt->dt_mtime = h_inode->i_mtime;
  1462. + /* smp_mb(); */
  1463. +}
  1464. +
  1465. +void au_dtime_revert(struct au_dtime *dt)
  1466. +{
  1467. + struct iattr attr;
  1468. + int err;
  1469. +
  1470. + attr.ia_atime = dt->dt_atime;
  1471. + attr.ia_mtime = dt->dt_mtime;
  1472. + attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
  1473. + | ATTR_ATIME | ATTR_ATIME_SET;
  1474. +
  1475. + err = vfsub_notify_change(&dt->dt_h_path, &attr);
  1476. + if (unlikely(err))
  1477. + AuWarn("restoring timestamps failed(%d). ignored\n", err);
  1478. +}
  1479. +
  1480. +/* ---------------------------------------------------------------------- */
  1481. +
  1482. +static noinline_for_stack
  1483. +int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src)
  1484. +{
  1485. + int err, sbits;
  1486. + struct iattr ia;
  1487. + struct path h_path;
  1488. + struct inode *h_isrc, *h_idst;
  1489. +
  1490. + h_path.dentry = au_h_dptr(dst, bindex);
  1491. + h_idst = h_path.dentry->d_inode;
  1492. + h_path.mnt = au_sbr_mnt(dst->d_sb, bindex);
  1493. + h_isrc = h_src->d_inode;
  1494. + ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
  1495. + | ATTR_ATIME | ATTR_MTIME
  1496. + | ATTR_ATIME_SET | ATTR_MTIME_SET;
  1497. + ia.ia_uid = h_isrc->i_uid;
  1498. + ia.ia_gid = h_isrc->i_gid;
  1499. + ia.ia_atime = h_isrc->i_atime;
  1500. + ia.ia_mtime = h_isrc->i_mtime;
  1501. + if (h_idst->i_mode != h_isrc->i_mode
  1502. + && !S_ISLNK(h_idst->i_mode)) {
  1503. + ia.ia_valid |= ATTR_MODE;
  1504. + ia.ia_mode = h_isrc->i_mode;
  1505. + }
  1506. + sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
  1507. + au_cpup_attr_flags(h_idst, h_isrc);
  1508. + err = vfsub_notify_change(&h_path, &ia);
  1509. +
  1510. + /* is this nfs only? */
  1511. + if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
  1512. + ia.ia_valid = ATTR_FORCE | ATTR_MODE;
  1513. + ia.ia_mode = h_isrc->i_mode;
  1514. + err = vfsub_notify_change(&h_path, &ia);
  1515. + }
  1516. +
  1517. + return err;
  1518. +}
  1519. +
  1520. +/* ---------------------------------------------------------------------- */
  1521. +
  1522. +static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
  1523. + char *buf, unsigned long blksize)
  1524. +{
  1525. + int err;
  1526. + size_t sz, rbytes, wbytes;
  1527. + unsigned char all_zero;
  1528. + char *p, *zp;
  1529. + struct mutex *h_mtx;
  1530. + /* reduce stack usage */
  1531. + struct iattr *ia;
  1532. +
  1533. + zp = page_address(ZERO_PAGE(0));
  1534. + if (unlikely(!zp))
  1535. + return -ENOMEM; /* possible? */
  1536. +
  1537. + err = 0;
  1538. + all_zero = 0;
  1539. + while (len) {
  1540. + AuDbg("len %lld\n", len);
  1541. + sz = blksize;
  1542. + if (len < blksize)
  1543. + sz = len;
  1544. +
  1545. + rbytes = 0;
  1546. + /* todo: signal_pending? */
  1547. + while (!rbytes || err == -EAGAIN || err == -EINTR) {
  1548. + rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
  1549. + err = rbytes;
  1550. + }
  1551. + if (unlikely(err < 0))
  1552. + break;
  1553. +
  1554. + all_zero = 0;
  1555. + if (len >= rbytes && rbytes == blksize)
  1556. + all_zero = !memcmp(buf, zp, rbytes);
  1557. + if (!all_zero) {
  1558. + wbytes = rbytes;
  1559. + p = buf;
  1560. + while (wbytes) {
  1561. + size_t b;
  1562. +
  1563. + b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
  1564. + err = b;
  1565. + /* todo: signal_pending? */
  1566. + if (unlikely(err == -EAGAIN || err == -EINTR))
  1567. + continue;
  1568. + if (unlikely(err < 0))
  1569. + break;
  1570. + wbytes -= b;
  1571. + p += b;
  1572. + }
  1573. + } else {
  1574. + loff_t res;
  1575. +
  1576. + AuLabel(hole);
  1577. + res = vfsub_llseek(dst, rbytes, SEEK_CUR);
  1578. + err = res;
  1579. + if (unlikely(res < 0))
  1580. + break;
  1581. + }
  1582. + len -= rbytes;
  1583. + err = 0;
  1584. + }
  1585. +
  1586. + /* the last block may be a hole */
  1587. + if (!err && all_zero) {
  1588. + AuLabel(last hole);
  1589. +
  1590. + err = 1;
  1591. + if (au_test_nfs(dst->f_dentry->d_sb)) {
  1592. + /* nfs requires this step to make last hole */
  1593. + /* is this only nfs? */
  1594. + do {
  1595. + /* todo: signal_pending? */
  1596. + err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
  1597. + } while (err == -EAGAIN || err == -EINTR);
  1598. + if (err == 1)
  1599. + dst->f_pos--;
  1600. + }
  1601. +
  1602. + if (err == 1) {
  1603. + ia = (void *)buf;
  1604. + ia->ia_size = dst->f_pos;
  1605. + ia->ia_valid = ATTR_SIZE | ATTR_FILE;
  1606. + ia->ia_file = dst;
  1607. + h_mtx = &dst->f_dentry->d_inode->i_mutex;
  1608. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
  1609. + err = vfsub_notify_change(&dst->f_path, ia);
  1610. + mutex_unlock(h_mtx);
  1611. + }
  1612. + }
  1613. +
  1614. + return err;
  1615. +}
  1616. +
  1617. +int au_copy_file(struct file *dst, struct file *src, loff_t len)
  1618. +{
  1619. + int err;
  1620. + unsigned long blksize;
  1621. + unsigned char do_kfree;
  1622. + char *buf;
  1623. +
  1624. + err = -ENOMEM;
  1625. + blksize = dst->f_dentry->d_sb->s_blocksize;
  1626. + if (!blksize || PAGE_SIZE < blksize)
  1627. + blksize = PAGE_SIZE;
  1628. + AuDbg("blksize %lu\n", blksize);
  1629. + do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
  1630. + if (do_kfree)
  1631. + buf = kmalloc(blksize, GFP_NOFS);
  1632. + else
  1633. + buf = (void *)__get_free_page(GFP_NOFS);
  1634. + if (unlikely(!buf))
  1635. + goto out;
  1636. +
  1637. + if (len > (1 << 22))
  1638. + AuDbg("copying a large file %lld\n", (long long)len);
  1639. +
  1640. + src->f_pos = 0;
  1641. + dst->f_pos = 0;
  1642. + err = au_do_copy_file(dst, src, len, buf, blksize);
  1643. + if (do_kfree)
  1644. + kfree(buf);
  1645. + else
  1646. + free_page((unsigned long)buf);
  1647. +
  1648. + out:
  1649. + return err;
  1650. +}
  1651. +
  1652. +/*
  1653. + * to support a sparse file which is opened with O_APPEND,
  1654. + * we need to close the file.
  1655. + */
  1656. +static int au_cp_regular(struct dentry *dentry, aufs_bindex_t bdst,
  1657. + aufs_bindex_t bsrc, loff_t len)
  1658. +{
  1659. + int err, i;
  1660. + enum { SRC, DST };
  1661. + struct {
  1662. + aufs_bindex_t bindex;
  1663. + unsigned int flags;
  1664. + struct dentry *dentry;
  1665. + struct file *file;
  1666. + void *label, *label_file;
  1667. + } *f, file[] = {
  1668. + {
  1669. + .bindex = bsrc,
  1670. + .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
  1671. + .file = NULL,
  1672. + .label = &&out,
  1673. + .label_file = &&out_src
  1674. + },
  1675. + {
  1676. + .bindex = bdst,
  1677. + .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
  1678. + .file = NULL,
  1679. + .label = &&out_src,
  1680. + .label_file = &&out_dst
  1681. + }
  1682. + };
  1683. + struct super_block *sb;
  1684. +
  1685. + /* bsrc branch can be ro/rw. */
  1686. + sb = dentry->d_sb;
  1687. + f = file;
  1688. + for (i = 0; i < 2; i++, f++) {
  1689. + f->dentry = au_h_dptr(dentry, f->bindex);
  1690. + f->file = au_h_open(dentry, f->bindex, f->flags, /*file*/NULL);
  1691. + err = PTR_ERR(f->file);
  1692. + if (IS_ERR(f->file))
  1693. + goto *f->label;
  1694. + err = -EINVAL;
  1695. + if (unlikely(!f->file->f_op))
  1696. + goto *f->label_file;
  1697. + }
  1698. +
  1699. + /* try stopping to update while we copyup */
  1700. + IMustLock(file[SRC].dentry->d_inode);
  1701. + err = au_copy_file(file[DST].file, file[SRC].file, len);
  1702. +
  1703. + out_dst:
  1704. + fput(file[DST].file);
  1705. + au_sbr_put(sb, file[DST].bindex);
  1706. + out_src:
  1707. + fput(file[SRC].file);
  1708. + au_sbr_put(sb, file[SRC].bindex);
  1709. + out:
  1710. + return err;
  1711. +}
  1712. +
  1713. +static int au_do_cpup_regular(struct dentry *dentry, aufs_bindex_t bdst,
  1714. + aufs_bindex_t bsrc, loff_t len,
  1715. + struct inode *h_dir, struct path *h_path)
  1716. +{
  1717. + int err, rerr;
  1718. + loff_t l;
  1719. +
  1720. + err = 0;
  1721. + l = i_size_read(au_h_iptr(dentry->d_inode, bsrc));
  1722. + if (len == -1 || l < len)
  1723. + len = l;
  1724. + if (len)
  1725. + err = au_cp_regular(dentry, bdst, bsrc, len);
  1726. + if (!err)
  1727. + goto out; /* success */
  1728. +
  1729. + rerr = vfsub_unlink(h_dir, h_path, /*force*/0);
  1730. + if (rerr) {
  1731. + AuIOErr("failed unlinking cpup-ed %.*s(%d, %d)\n",
  1732. + AuDLNPair(h_path->dentry), err, rerr);
  1733. + err = -EIO;
  1734. + }
  1735. +
  1736. + out:
  1737. + return err;
  1738. +}
  1739. +
  1740. +static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
  1741. + struct inode *h_dir)
  1742. +{
  1743. + int err, symlen;
  1744. + mm_segment_t old_fs;
  1745. + char *sym;
  1746. +
  1747. + err = -ENOSYS;
  1748. + if (unlikely(!h_src->d_inode->i_op->readlink))
  1749. + goto out;
  1750. +
  1751. + err = -ENOMEM;
  1752. + sym = __getname();
  1753. + if (unlikely(!sym))
  1754. + goto out;
  1755. +
  1756. + old_fs = get_fs();
  1757. + set_fs(KERNEL_DS);
  1758. + symlen = h_src->d_inode->i_op->readlink(h_src, (char __user *)sym,
  1759. + PATH_MAX);
  1760. + err = symlen;
  1761. + set_fs(old_fs);
  1762. +
  1763. + if (symlen > 0) {
  1764. + sym[symlen] = 0;
  1765. + err = vfsub_symlink(h_dir, h_path, sym);
  1766. + }
  1767. + __putname(sym);
  1768. +
  1769. + out:
  1770. + return err;
  1771. +}
  1772. +
  1773. +/* return with the lower dst inode is locked */
  1774. +static noinline_for_stack
  1775. +int cpup_entry(struct dentry *dentry, aufs_bindex_t bdst,
  1776. + aufs_bindex_t bsrc, loff_t len, unsigned int flags,
  1777. + struct dentry *dst_parent)
  1778. +{
  1779. + int err;
  1780. + umode_t mode;
  1781. + unsigned int mnt_flags;
  1782. + unsigned char isdir;
  1783. + const unsigned char do_dt = !!au_ftest_cpup(flags, DTIME);
  1784. + struct au_dtime dt;
  1785. + struct path h_path;
  1786. + struct dentry *h_src, *h_dst, *h_parent;
  1787. + struct inode *h_inode, *h_dir;
  1788. + struct super_block *sb;
  1789. +
  1790. + /* bsrc branch can be ro/rw. */
  1791. + h_src = au_h_dptr(dentry, bsrc);
  1792. + h_inode = h_src->d_inode;
  1793. + AuDebugOn(h_inode != au_h_iptr(dentry->d_inode, bsrc));
  1794. +
  1795. + /* try stopping to be referenced while we are creating */
  1796. + h_dst = au_h_dptr(dentry, bdst);
  1797. + h_parent = h_dst->d_parent; /* dir inode is locked */
  1798. + h_dir = h_parent->d_inode;
  1799. + IMustLock(h_dir);
  1800. + AuDebugOn(h_parent != h_dst->d_parent);
  1801. +
  1802. + sb = dentry->d_sb;
  1803. + h_path.mnt = au_sbr_mnt(sb, bdst);
  1804. + if (do_dt) {
  1805. + h_path.dentry = h_parent;
  1806. + au_dtime_store(&dt, dst_parent, &h_path);
  1807. + }
  1808. + h_path.dentry = h_dst;
  1809. +
  1810. + isdir = 0;
  1811. + mode = h_inode->i_mode;
  1812. + switch (mode & S_IFMT) {
  1813. + case S_IFREG:
  1814. + /* try stopping to update while we are referencing */
  1815. + IMustLock(h_inode);
  1816. + err = vfsub_create(h_dir, &h_path, mode | S_IWUSR);
  1817. + if (!err)
  1818. + err = au_do_cpup_regular
  1819. + (dentry, bdst, bsrc, len,
  1820. + au_h_iptr(dst_parent->d_inode, bdst), &h_path);
  1821. + break;
  1822. + case S_IFDIR:
  1823. + isdir = 1;
  1824. + err = vfsub_mkdir(h_dir, &h_path, mode);
  1825. + if (!err) {
  1826. + /*
  1827. + * strange behaviour from the users view,
  1828. + * particularry setattr case
  1829. + */
  1830. + if (au_ibstart(dst_parent->d_inode) == bdst)
  1831. + au_cpup_attr_nlink(dst_parent->d_inode,
  1832. + /*force*/1);
  1833. + au_cpup_attr_nlink(dentry->d_inode, /*force*/1);
  1834. + }
  1835. + break;
  1836. + case S_IFLNK:
  1837. + err = au_do_cpup_symlink(&h_path, h_src, h_dir);
  1838. + break;
  1839. + case S_IFCHR:
  1840. + case S_IFBLK:
  1841. + AuDebugOn(!capable(CAP_MKNOD));
  1842. + /*FALLTHROUGH*/
  1843. + case S_IFIFO:
  1844. + case S_IFSOCK:
  1845. + err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
  1846. + break;
  1847. + default:
  1848. + AuIOErr("Unknown inode type 0%o\n", mode);
  1849. + err = -EIO;
  1850. + }
  1851. +
  1852. + mnt_flags = au_mntflags(sb);
  1853. + if (!au_opt_test(mnt_flags, UDBA_NONE)
  1854. + && !isdir
  1855. + && au_opt_test(mnt_flags, XINO)
  1856. + && h_inode->i_nlink == 1
  1857. + /* todo: unnecessary? */
  1858. + /* && dentry->d_inode->i_nlink == 1 */
  1859. + && bdst < bsrc
  1860. + && !au_ftest_cpup(flags, KEEPLINO))
  1861. + au_xino_write(sb, bsrc, h_inode->i_ino, /*ino*/0);
  1862. + /* ignore this error */
  1863. +
  1864. + if (do_dt)
  1865. + au_dtime_revert(&dt);
  1866. + return err;
  1867. +}
  1868. +
  1869. +/*
  1870. + * copyup the @dentry from @bsrc to @bdst.
  1871. + * the caller must set the both of lower dentries.
  1872. + * @len is for truncating when it is -1 copyup the entire file.
  1873. + * in link/rename cases, @dst_parent may be different from the real one.
  1874. + */
  1875. +static int au_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
  1876. + aufs_bindex_t bsrc, loff_t len, unsigned int flags,
  1877. + struct dentry *dst_parent)
  1878. +{
  1879. + int err, rerr;
  1880. + aufs_bindex_t old_ibstart;
  1881. + unsigned char isdir, plink;
  1882. + struct au_dtime dt;
  1883. + struct path h_path;
  1884. + struct dentry *h_src, *h_dst, *h_parent;
  1885. + struct inode *dst_inode, *h_dir, *inode;
  1886. + struct super_block *sb;
  1887. +
  1888. + AuDebugOn(bsrc <= bdst);
  1889. +
  1890. + sb = dentry->d_sb;
  1891. + h_path.mnt = au_sbr_mnt(sb, bdst);
  1892. + h_dst = au_h_dptr(dentry, bdst);
  1893. + h_parent = h_dst->d_parent; /* dir inode is locked */
  1894. + h_dir = h_parent->d_inode;
  1895. + IMustLock(h_dir);
  1896. +
  1897. + h_src = au_h_dptr(dentry, bsrc);
  1898. + inode = dentry->d_inode;
  1899. +
  1900. + if (!dst_parent)
  1901. + dst_parent = dget_parent(dentry);
  1902. + else
  1903. + dget(dst_parent);
  1904. +
  1905. + plink = !!au_opt_test(au_mntflags(sb), PLINK);
  1906. + dst_inode = au_h_iptr(inode, bdst);
  1907. + if (dst_inode) {
  1908. + if (unlikely(!plink)) {
  1909. + err = -EIO;
  1910. + AuIOErr("i%lu exists on a upper branch "
  1911. + "but plink is disabled\n", inode->i_ino);
  1912. + goto out;
  1913. + }
  1914. +
  1915. + if (dst_inode->i_nlink) {
  1916. + const int do_dt = au_ftest_cpup(flags, DTIME);
  1917. +
  1918. + h_src = au_plink_lkup(inode, bdst);
  1919. + err = PTR_ERR(h_src);
  1920. + if (IS_ERR(h_src))
  1921. + goto out;
  1922. + if (unlikely(!h_src->d_inode)) {
  1923. + err = -EIO;
  1924. + AuIOErr("i%lu exists on a upper branch "
  1925. + "but plink is broken\n", inode->i_ino);
  1926. + dput(h_src);
  1927. + goto out;
  1928. + }
  1929. +
  1930. + if (do_dt) {
  1931. + h_path.dentry = h_parent;
  1932. + au_dtime_store(&dt, dst_parent, &h_path);
  1933. + }
  1934. + h_path.dentry = h_dst;
  1935. + err = vfsub_link(h_src, h_dir, &h_path);
  1936. + if (do_dt)
  1937. + au_dtime_revert(&dt);
  1938. + dput(h_src);
  1939. + goto out;
  1940. + } else
  1941. + /* todo: cpup_wh_file? */
  1942. + /* udba work */
  1943. + au_update_brange(inode, 1);
  1944. + }
  1945. +
  1946. + old_ibstart = au_ibstart(inode);
  1947. + err = cpup_entry(dentry, bdst, bsrc, len, flags, dst_parent);
  1948. + if (unlikely(err))
  1949. + goto out;
  1950. + dst_inode = h_dst->d_inode;
  1951. + mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
  1952. +
  1953. + err = cpup_iattr(dentry, bdst, h_src);
  1954. + isdir = S_ISDIR(dst_inode->i_mode);
  1955. + if (!err) {
  1956. + if (bdst < old_ibstart)
  1957. + au_set_ibstart(inode, bdst);
  1958. + au_set_h_iptr(inode, bdst, au_igrab(dst_inode),
  1959. + au_hi_flags(inode, isdir));
  1960. + mutex_unlock(&dst_inode->i_mutex);
  1961. + if (!isdir
  1962. + && h_src->d_inode->i_nlink > 1
  1963. + && plink)
  1964. + au_plink_append(inode, bdst, h_dst);
  1965. + goto out; /* success */
  1966. + }
  1967. +
  1968. + /* revert */
  1969. + h_path.dentry = h_parent;
  1970. + mutex_unlock(&dst_inode->i_mutex);
  1971. + au_dtime_store(&dt, dst_parent, &h_path);
  1972. + h_path.dentry = h_dst;
  1973. + if (!isdir)
  1974. + rerr = vfsub_unlink(h_dir, &h_path, /*force*/0);
  1975. + else
  1976. + rerr = vfsub_rmdir(h_dir, &h_path);
  1977. + au_dtime_revert(&dt);
  1978. + if (rerr) {
  1979. + AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
  1980. + err = -EIO;
  1981. + }
  1982. +
  1983. + out:
  1984. + dput(dst_parent);
  1985. + return err;
  1986. +}
  1987. +
  1988. +struct au_cpup_single_args {
  1989. + int *errp;
  1990. + struct dentry *dentry;
  1991. + aufs_bindex_t bdst, bsrc;
  1992. + loff_t len;
  1993. + unsigned int flags;
  1994. + struct dentry *dst_parent;
  1995. +};
  1996. +
  1997. +static void au_call_cpup_single(void *args)
  1998. +{
  1999. + struct au_cpup_single_args *a = args;
  2000. + *a->errp = au_cpup_single(a->dentry, a->bdst, a->bsrc, a->len,
  2001. + a->flags, a->dst_parent);
  2002. +}
  2003. +
  2004. +int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
  2005. + aufs_bindex_t bsrc, loff_t len, unsigned int flags,
  2006. + struct dentry *dst_parent)
  2007. +{
  2008. + int err, wkq_err;
  2009. + umode_t mode;
  2010. + struct dentry *h_dentry;
  2011. +
  2012. + h_dentry = au_h_dptr(dentry, bsrc);
  2013. + mode = h_dentry->d_inode->i_mode & S_IFMT;
  2014. + if ((mode != S_IFCHR && mode != S_IFBLK)
  2015. + || capable(CAP_MKNOD))
  2016. + err = au_cpup_single(dentry, bdst, bsrc, len, flags,
  2017. + dst_parent);
  2018. + else {
  2019. + struct au_cpup_single_args args = {
  2020. + .errp = &err,
  2021. + .dentry = dentry,
  2022. + .bdst = bdst,
  2023. + .bsrc = bsrc,
  2024. + .len = len,
  2025. + .flags = flags,
  2026. + .dst_parent = dst_parent
  2027. + };
  2028. + wkq_err = au_wkq_wait(au_call_cpup_single, &args);
  2029. + if (unlikely(wkq_err))
  2030. + err = wkq_err;
  2031. + }
  2032. +
  2033. + return err;
  2034. +}
  2035. +
  2036. +/*
  2037. + * copyup the @dentry from the first active lower branch to @bdst,
  2038. + * using au_cpup_single().
  2039. + */
  2040. +static int au_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
  2041. + unsigned int flags)
  2042. +{
  2043. + int err;
  2044. + aufs_bindex_t bsrc, bend;
  2045. +
  2046. + bend = au_dbend(dentry);
  2047. + for (bsrc = bdst + 1; bsrc <= bend; bsrc++)
  2048. + if (au_h_dptr(dentry, bsrc))
  2049. + break;
  2050. +
  2051. + err = au_lkup_neg(dentry, bdst);
  2052. + if (!err) {
  2053. + err = au_cpup_single(dentry, bdst, bsrc, len, flags, NULL);
  2054. + if (!err)
  2055. + return 0; /* success */
  2056. +
  2057. + /* revert */
  2058. + au_set_h_dptr(dentry, bdst, NULL);
  2059. + au_set_dbstart(dentry, bsrc);
  2060. + }
  2061. +
  2062. + return err;
  2063. +}
  2064. +
  2065. +struct au_cpup_simple_args {
  2066. + int *errp;
  2067. + struct dentry *dentry;
  2068. + aufs_bindex_t bdst;
  2069. + loff_t len;
  2070. + unsigned int flags;
  2071. +};
  2072. +
  2073. +static void au_call_cpup_simple(void *args)
  2074. +{
  2075. + struct au_cpup_simple_args *a = args;
  2076. + *a->errp = au_cpup_simple(a->dentry, a->bdst, a->len, a->flags);
  2077. +}
  2078. +
  2079. +int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
  2080. + unsigned int flags)
  2081. +{
  2082. + int err, wkq_err;
  2083. + unsigned char do_sio;
  2084. + struct dentry *parent;
  2085. + struct inode *h_dir;
  2086. +
  2087. + parent = dget_parent(dentry);
  2088. + h_dir = au_h_iptr(parent->d_inode, bdst);
  2089. + do_sio = !!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE);
  2090. + if (!do_sio) {
  2091. + /*
  2092. + * testing CAP_MKNOD is for generic fs,
  2093. + * but CAP_FSETID is for xfs only, currently.
  2094. + */
  2095. + umode_t mode = dentry->d_inode->i_mode;
  2096. + do_sio = (((mode & (S_IFCHR | S_IFBLK))
  2097. + && !capable(CAP_MKNOD))
  2098. + || ((mode & (S_ISUID | S_ISGID))
  2099. + && !capable(CAP_FSETID)));
  2100. + }
  2101. + if (!do_sio)
  2102. + err = au_cpup_simple(dentry, bdst, len, flags);
  2103. + else {
  2104. + struct au_cpup_simple_args args = {
  2105. + .errp = &err,
  2106. + .dentry = dentry,
  2107. + .bdst = bdst,
  2108. + .len = len,
  2109. + .flags = flags
  2110. + };
  2111. + wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
  2112. + if (unlikely(wkq_err))
  2113. + err = wkq_err;
  2114. + }
  2115. +
  2116. + dput(parent);
  2117. + return err;
  2118. +}
  2119. +
  2120. +/* ---------------------------------------------------------------------- */
  2121. +
  2122. +/*
  2123. + * copyup the deleted file for writing.
  2124. + */
  2125. +static int au_do_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst,
  2126. + struct dentry *wh_dentry, struct file *file,
  2127. + loff_t len)
  2128. +{
  2129. + int err;
  2130. + aufs_bindex_t bstart;
  2131. + struct au_dinfo *dinfo;
  2132. + struct dentry *h_d_dst, *h_d_start;
  2133. +
  2134. + dinfo = au_di(dentry);
  2135. + AuRwMustWriteLock(&dinfo->di_rwsem);
  2136. +
  2137. + bstart = dinfo->di_bstart;
  2138. + h_d_dst = dinfo->di_hdentry[0 + bdst].hd_dentry;
  2139. + dinfo->di_bstart = bdst;
  2140. + dinfo->di_hdentry[0 + bdst].hd_dentry = wh_dentry;
  2141. + h_d_start = dinfo->di_hdentry[0 + bstart].hd_dentry;
  2142. + if (file)
  2143. + dinfo->di_hdentry[0 + bstart].hd_dentry
  2144. + = au_h_fptr(file, au_fbstart(file))->f_dentry;
  2145. + err = au_cpup_single(dentry, bdst, bstart, len, !AuCpup_DTIME,
  2146. + /*h_parent*/NULL);
  2147. + if (!err && file) {
  2148. + err = au_reopen_nondir(file);
  2149. + dinfo->di_hdentry[0 + bstart].hd_dentry = h_d_start;
  2150. + }
  2151. + dinfo->di_hdentry[0 + bdst].hd_dentry = h_d_dst;
  2152. + dinfo->di_bstart = bstart;
  2153. +
  2154. + return err;
  2155. +}
  2156. +
  2157. +static int au_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
  2158. + struct file *file)
  2159. +{
  2160. + int err;
  2161. + struct au_dtime dt;
  2162. + struct dentry *parent, *h_parent, *wh_dentry;
  2163. + struct au_branch *br;
  2164. + struct path h_path;
  2165. +
  2166. + br = au_sbr(dentry->d_sb, bdst);
  2167. + parent = dget_parent(dentry);
  2168. + h_parent = au_h_dptr(parent, bdst);
  2169. + wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
  2170. + err = PTR_ERR(wh_dentry);
  2171. + if (IS_ERR(wh_dentry))
  2172. + goto out;
  2173. +
  2174. + h_path.dentry = h_parent;
  2175. + h_path.mnt = br->br_mnt;
  2176. + au_dtime_store(&dt, parent, &h_path);
  2177. + err = au_do_cpup_wh(dentry, bdst, wh_dentry, file, len);
  2178. + if (unlikely(err))
  2179. + goto out_wh;
  2180. +
  2181. + dget(wh_dentry);
  2182. + h_path.dentry = wh_dentry;
  2183. + err = vfsub_unlink(h_parent->d_inode, &h_path, /*force*/0);
  2184. + if (unlikely(err)) {
  2185. + AuIOErr("failed remove copied-up tmp file %.*s(%d)\n",
  2186. + AuDLNPair(wh_dentry), err);
  2187. + err = -EIO;
  2188. + }
  2189. + au_dtime_revert(&dt);
  2190. + au_set_hi_wh(dentry->d_inode, bdst, wh_dentry);
  2191. +
  2192. + out_wh:
  2193. + dput(wh_dentry);
  2194. + out:
  2195. + dput(parent);
  2196. + return err;
  2197. +}
  2198. +
  2199. +struct au_cpup_wh_args {
  2200. + int *errp;
  2201. + struct dentry *dentry;
  2202. + aufs_bindex_t bdst;
  2203. + loff_t len;
  2204. + struct file *file;
  2205. +};
  2206. +
  2207. +static void au_call_cpup_wh(void *args)
  2208. +{
  2209. + struct au_cpup_wh_args *a = args;
  2210. + *a->errp = au_cpup_wh(a->dentry, a->bdst, a->len, a->file);
  2211. +}
  2212. +
  2213. +int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
  2214. + struct file *file)
  2215. +{
  2216. + int err, wkq_err;
  2217. + struct dentry *parent, *h_orph, *h_parent, *h_dentry;
  2218. + struct inode *dir, *h_dir, *h_tmpdir, *h_inode;
  2219. + struct au_wbr *wbr;
  2220. +
  2221. + parent = dget_parent(dentry);
  2222. + dir = parent->d_inode;
  2223. + h_orph = NULL;
  2224. + h_parent = NULL;
  2225. + h_dir = au_igrab(au_h_iptr(dir, bdst));
  2226. + h_tmpdir = h_dir;
  2227. + if (!h_dir->i_nlink) {
  2228. + wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
  2229. + h_orph = wbr->wbr_orph;
  2230. +
  2231. + h_parent = dget(au_h_dptr(parent, bdst));
  2232. + au_set_h_dptr(parent, bdst, NULL);
  2233. + au_set_h_dptr(parent, bdst, dget(h_orph));
  2234. + h_tmpdir = h_orph->d_inode;
  2235. + au_set_h_iptr(dir, bdst, NULL, 0);
  2236. + au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
  2237. +
  2238. + /* this temporary unlock is safe */
  2239. + if (file)
  2240. + h_dentry = au_h_fptr(file, au_fbstart(file))->f_dentry;
  2241. + else
  2242. + h_dentry = au_h_dptr(dentry, au_dbstart(dentry));
  2243. + h_inode = h_dentry->d_inode;
  2244. + IMustLock(h_inode);
  2245. + mutex_unlock(&h_inode->i_mutex);
  2246. + mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
  2247. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  2248. + }
  2249. +
  2250. + if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE))
  2251. + err = au_cpup_wh(dentry, bdst, len, file);
  2252. + else {
  2253. + struct au_cpup_wh_args args = {
  2254. + .errp = &err,
  2255. + .dentry = dentry,
  2256. + .bdst = bdst,
  2257. + .len = len,
  2258. + .file = file
  2259. + };
  2260. + wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
  2261. + if (unlikely(wkq_err))
  2262. + err = wkq_err;
  2263. + }
  2264. +
  2265. + if (h_orph) {
  2266. + mutex_unlock(&h_tmpdir->i_mutex);
  2267. + au_set_h_iptr(dir, bdst, NULL, 0);
  2268. + au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
  2269. + au_set_h_dptr(parent, bdst, NULL);
  2270. + au_set_h_dptr(parent, bdst, h_parent);
  2271. + }
  2272. + iput(h_dir);
  2273. + dput(parent);
  2274. +
  2275. + return err;
  2276. +}
  2277. +
  2278. +/* ---------------------------------------------------------------------- */
  2279. +
  2280. +/*
  2281. + * generic routine for both of copy-up and copy-down.
  2282. + */
  2283. +/* cf. revalidate function in file.c */
  2284. +int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
  2285. + int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
  2286. + struct dentry *h_parent, void *arg),
  2287. + void *arg)
  2288. +{
  2289. + int err;
  2290. + struct au_pin pin;
  2291. + struct dentry *d, *parent, *h_parent, *real_parent;
  2292. +
  2293. + err = 0;
  2294. + parent = dget_parent(dentry);
  2295. + if (IS_ROOT(parent))
  2296. + goto out;
  2297. +
  2298. + au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
  2299. + au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
  2300. +
  2301. + /* do not use au_dpage */
  2302. + real_parent = parent;
  2303. + while (1) {
  2304. + dput(parent);
  2305. + parent = dget_parent(dentry);
  2306. + h_parent = au_h_dptr(parent, bdst);
  2307. + if (h_parent)
  2308. + goto out; /* success */
  2309. +
  2310. + /* find top dir which is necessary to cpup */
  2311. + do {
  2312. + d = parent;
  2313. + dput(parent);
  2314. + parent = dget_parent(d);
  2315. + di_read_lock_parent3(parent, !AuLock_IR);
  2316. + h_parent = au_h_dptr(parent, bdst);
  2317. + di_read_unlock(parent, !AuLock_IR);
  2318. + } while (!h_parent);
  2319. +
  2320. + if (d != real_parent)
  2321. + di_write_lock_child3(d);
  2322. +
  2323. + /* somebody else might create while we were sleeping */
  2324. + if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) {
  2325. + if (au_h_dptr(d, bdst))
  2326. + au_update_dbstart(d);
  2327. +
  2328. + au_pin_set_dentry(&pin, d);
  2329. + err = au_do_pin(&pin);
  2330. + if (!err) {
  2331. + err = cp(d, bdst, h_parent, arg);
  2332. + au_unpin(&pin);
  2333. + }
  2334. + }
  2335. +
  2336. + if (d != real_parent)
  2337. + di_write_unlock(d);
  2338. + if (unlikely(err))
  2339. + break;
  2340. + }
  2341. +
  2342. + out:
  2343. + dput(parent);
  2344. + return err;
  2345. +}
  2346. +
  2347. +static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
  2348. + struct dentry *h_parent __maybe_unused ,
  2349. + void *arg __maybe_unused)
  2350. +{
  2351. + return au_sio_cpup_simple(dentry, bdst, -1, AuCpup_DTIME);
  2352. +}
  2353. +
  2354. +int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
  2355. +{
  2356. + return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
  2357. +}
  2358. +
  2359. +int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
  2360. +{
  2361. + int err;
  2362. + struct dentry *parent;
  2363. + struct inode *dir;
  2364. +
  2365. + parent = dget_parent(dentry);
  2366. + dir = parent->d_inode;
  2367. + err = 0;
  2368. + if (au_h_iptr(dir, bdst))
  2369. + goto out;
  2370. +
  2371. + di_read_unlock(parent, AuLock_IR);
  2372. + di_write_lock_parent(parent);
  2373. + /* someone else might change our inode while we were sleeping */
  2374. + if (!au_h_iptr(dir, bdst))
  2375. + err = au_cpup_dirs(dentry, bdst);
  2376. + di_downgrade_lock(parent, AuLock_IR);
  2377. +
  2378. + out:
  2379. + dput(parent);
  2380. + return err;
  2381. +}
  2382. diff -Nur linux-2.6.31.4.orig/fs/aufs/cpup.h linux-2.6.31.4/fs/aufs/cpup.h
  2383. --- linux-2.6.31.4.orig/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100
  2384. +++ linux-2.6.31.4/fs/aufs/cpup.h 2009-10-18 11:26:01.000000000 +0200
  2385. @@ -0,0 +1,81 @@
  2386. +/*
  2387. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  2388. + *
  2389. + * This program, aufs is free software; you can redistribute it and/or modify
  2390. + * it under the terms of the GNU General Public License as published by
  2391. + * the Free Software Foundation; either version 2 of the License, or
  2392. + * (at your option) any later version.
  2393. + *
  2394. + * This program is distributed in the hope that it will be useful,
  2395. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2396. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2397. + * GNU General Public License for more details.
  2398. + *
  2399. + * You should have received a copy of the GNU General Public License
  2400. + * along with this program; if not, write to the Free Software
  2401. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  2402. + */
  2403. +
  2404. +/*
  2405. + * copy-up/down functions
  2406. + */
  2407. +
  2408. +#ifndef __AUFS_CPUP_H__
  2409. +#define __AUFS_CPUP_H__
  2410. +
  2411. +#ifdef __KERNEL__
  2412. +
  2413. +#include <linux/path.h>
  2414. +#include <linux/time.h>
  2415. +#include <linux/aufs_type.h>
  2416. +
  2417. +struct inode;
  2418. +struct file;
  2419. +
  2420. +void au_cpup_attr_flags(struct inode *dst, struct inode *src);
  2421. +void au_cpup_attr_timesizes(struct inode *inode);
  2422. +void au_cpup_attr_nlink(struct inode *inode, int force);
  2423. +void au_cpup_attr_changeable(struct inode *inode);
  2424. +void au_cpup_igen(struct inode *inode, struct inode *h_inode);
  2425. +void au_cpup_attr_all(struct inode *inode, int force);
  2426. +
  2427. +/* ---------------------------------------------------------------------- */
  2428. +
  2429. +/* cpup flags */
  2430. +#define AuCpup_DTIME 1 /* do dtime_store/revert */
  2431. +#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino,
  2432. + for link(2) */
  2433. +#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name)
  2434. +#define au_fset_cpup(flags, name) { (flags) |= AuCpup_##name; }
  2435. +#define au_fclr_cpup(flags, name) { (flags) &= ~AuCpup_##name; }
  2436. +
  2437. +int au_copy_file(struct file *dst, struct file *src, loff_t len);
  2438. +int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
  2439. + aufs_bindex_t bsrc, loff_t len, unsigned int flags,
  2440. + struct dentry *dst_parent);
  2441. +int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
  2442. + unsigned int flags);
  2443. +int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
  2444. + struct file *file);
  2445. +
  2446. +int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
  2447. + int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
  2448. + struct dentry *h_parent, void *arg),
  2449. + void *arg);
  2450. +int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
  2451. +int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
  2452. +
  2453. +/* ---------------------------------------------------------------------- */
  2454. +
  2455. +/* keep timestamps when copyup */
  2456. +struct au_dtime {
  2457. + struct dentry *dt_dentry;
  2458. + struct path dt_h_path;
  2459. + struct timespec dt_atime, dt_mtime;
  2460. +};
  2461. +void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
  2462. + struct path *h_path);
  2463. +void au_dtime_revert(struct au_dtime *dt);
  2464. +
  2465. +#endif /* __KERNEL__ */
  2466. +#endif /* __AUFS_CPUP_H__ */
  2467. diff -Nur linux-2.6.31.4.orig/fs/aufs/dbgaufs.c linux-2.6.31.4/fs/aufs/dbgaufs.c
  2468. --- linux-2.6.31.4.orig/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
  2469. +++ linux-2.6.31.4/fs/aufs/dbgaufs.c 2009-10-18 11:26:01.000000000 +0200
  2470. @@ -0,0 +1,331 @@
  2471. +/*
  2472. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  2473. + *
  2474. + * This program, aufs is free software; you can redistribute it and/or modify
  2475. + * it under the terms of the GNU General Public License as published by
  2476. + * the Free Software Foundation; either version 2 of the License, or
  2477. + * (at your option) any later version.
  2478. + *
  2479. + * This program is distributed in the hope that it will be useful,
  2480. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2481. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2482. + * GNU General Public License for more details.
  2483. + *
  2484. + * You should have received a copy of the GNU General Public License
  2485. + * along with this program; if not, write to the Free Software
  2486. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  2487. + */
  2488. +
  2489. +/*
  2490. + * debugfs interface
  2491. + */
  2492. +
  2493. +#include <linux/debugfs.h>
  2494. +#include "aufs.h"
  2495. +
  2496. +#ifndef CONFIG_SYSFS
  2497. +#error DEBUG_FS depends upon SYSFS
  2498. +#endif
  2499. +
  2500. +static struct dentry *dbgaufs;
  2501. +static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
  2502. +
  2503. +/* 20 is max digits length of ulong 64 */
  2504. +struct dbgaufs_arg {
  2505. + int n;
  2506. + char a[20 * 4];
  2507. +};
  2508. +
  2509. +/*
  2510. + * common function for all XINO files
  2511. + */
  2512. +static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
  2513. + struct file *file)
  2514. +{
  2515. + kfree(file->private_data);
  2516. + return 0;
  2517. +}
  2518. +
  2519. +static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
  2520. +{
  2521. + int err;
  2522. + struct kstat st;
  2523. + struct dbgaufs_arg *p;
  2524. +
  2525. + err = -ENOMEM;
  2526. + p = kmalloc(sizeof(*p), GFP_NOFS);
  2527. + if (unlikely(!p))
  2528. + goto out;
  2529. +
  2530. + err = 0;
  2531. + p->n = 0;
  2532. + file->private_data = p;
  2533. + if (!xf)
  2534. + goto out;
  2535. +
  2536. + err = vfs_getattr(xf->f_vfsmnt, xf->f_dentry, &st);
  2537. + if (!err) {
  2538. + if (do_fcnt)
  2539. + p->n = snprintf
  2540. + (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n",
  2541. + (long)file_count(xf), st.blocks, st.blksize,
  2542. + (long long)st.size);
  2543. + else
  2544. + p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n",
  2545. + st.blocks, st.blksize,
  2546. + (long long)st.size);
  2547. + AuDebugOn(p->n >= sizeof(p->a));
  2548. + } else {
  2549. + p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
  2550. + err = 0;
  2551. + }
  2552. +
  2553. + out:
  2554. + return err;
  2555. +
  2556. +}
  2557. +
  2558. +static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
  2559. + size_t count, loff_t *ppos)
  2560. +{
  2561. + struct dbgaufs_arg *p;
  2562. +
  2563. + p = file->private_data;
  2564. + return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
  2565. +}
  2566. +
  2567. +/* ---------------------------------------------------------------------- */
  2568. +
  2569. +static int dbgaufs_xib_open(struct inode *inode, struct file *file)
  2570. +{
  2571. + int err;
  2572. + struct au_sbinfo *sbinfo;
  2573. + struct super_block *sb;
  2574. +
  2575. + sbinfo = inode->i_private;
  2576. + sb = sbinfo->si_sb;
  2577. + si_noflush_read_lock(sb);
  2578. + err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0);
  2579. + si_read_unlock(sb);
  2580. + return err;
  2581. +}
  2582. +
  2583. +static const struct file_operations dbgaufs_xib_fop = {
  2584. + .open = dbgaufs_xib_open,
  2585. + .release = dbgaufs_xi_release,
  2586. + .read = dbgaufs_xi_read
  2587. +};
  2588. +
  2589. +/* ---------------------------------------------------------------------- */
  2590. +
  2591. +#define DbgaufsXi_PREFIX "xi"
  2592. +
  2593. +static int dbgaufs_xino_open(struct inode *inode, struct file *file)
  2594. +{
  2595. + int err;
  2596. + long l;
  2597. + struct au_sbinfo *sbinfo;
  2598. + struct super_block *sb;
  2599. + struct file *xf;
  2600. + struct qstr *name;
  2601. +
  2602. + err = -ENOENT;
  2603. + xf = NULL;
  2604. + name = &file->f_dentry->d_name;
  2605. + if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
  2606. + || memcmp(name->name, DbgaufsXi_PREFIX,
  2607. + sizeof(DbgaufsXi_PREFIX) - 1)))
  2608. + goto out;
  2609. + err = strict_strtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
  2610. + if (unlikely(err))
  2611. + goto out;
  2612. +
  2613. + sbinfo = inode->i_private;
  2614. + sb = sbinfo->si_sb;
  2615. + si_noflush_read_lock(sb);
  2616. + if (l <= au_sbend(sb)) {
  2617. + xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file;
  2618. + err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1);
  2619. + } else
  2620. + err = -ENOENT;
  2621. + si_read_unlock(sb);
  2622. +
  2623. + out:
  2624. + return err;
  2625. +}
  2626. +
  2627. +static const struct file_operations dbgaufs_xino_fop = {
  2628. + .open = dbgaufs_xino_open,
  2629. + .release = dbgaufs_xi_release,
  2630. + .read = dbgaufs_xi_read
  2631. +};
  2632. +
  2633. +void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
  2634. +{
  2635. + aufs_bindex_t bend;
  2636. + struct au_branch *br;
  2637. + struct au_xino_file *xi;
  2638. +
  2639. + if (!au_sbi(sb)->si_dbgaufs)
  2640. + return;
  2641. +
  2642. + bend = au_sbend(sb);
  2643. + for (; bindex <= bend; bindex++) {
  2644. + br = au_sbr(sb, bindex);
  2645. + xi = &br->br_xino;
  2646. + if (xi->xi_dbgaufs) {
  2647. + debugfs_remove(xi->xi_dbgaufs);
  2648. + xi->xi_dbgaufs = NULL;
  2649. + }
  2650. + }
  2651. +}
  2652. +
  2653. +void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
  2654. +{
  2655. + struct au_sbinfo *sbinfo;
  2656. + struct dentry *parent;
  2657. + struct au_branch *br;
  2658. + struct au_xino_file *xi;
  2659. + aufs_bindex_t bend;
  2660. + char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */
  2661. +
  2662. + sbinfo = au_sbi(sb);
  2663. + parent = sbinfo->si_dbgaufs;
  2664. + if (!parent)
  2665. + return;
  2666. +
  2667. + bend = au_sbend(sb);
  2668. + for (; bindex <= bend; bindex++) {
  2669. + snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
  2670. + br = au_sbr(sb, bindex);
  2671. + xi = &br->br_xino;
  2672. + AuDebugOn(xi->xi_dbgaufs);
  2673. + xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
  2674. + sbinfo, &dbgaufs_xino_fop);
  2675. + /* ignore an error */
  2676. + if (unlikely(!xi->xi_dbgaufs))
  2677. + AuWarn1("failed %s under debugfs\n", name);
  2678. + }
  2679. +}
  2680. +
  2681. +/* ---------------------------------------------------------------------- */
  2682. +
  2683. +#ifdef CONFIG_AUFS_EXPORT
  2684. +static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
  2685. +{
  2686. + int err;
  2687. + struct au_sbinfo *sbinfo;
  2688. + struct super_block *sb;
  2689. +
  2690. + sbinfo = inode->i_private;
  2691. + sb = sbinfo->si_sb;
  2692. + si_noflush_read_lock(sb);
  2693. + err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0);
  2694. + si_read_unlock(sb);
  2695. + return err;
  2696. +}
  2697. +
  2698. +static const struct file_operations dbgaufs_xigen_fop = {
  2699. + .open = dbgaufs_xigen_open,
  2700. + .release = dbgaufs_xi_release,
  2701. + .read = dbgaufs_xi_read
  2702. +};
  2703. +
  2704. +static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
  2705. +{
  2706. + int err;
  2707. +
  2708. + /*
  2709. + * This function is a dynamic '__init' fucntion actually,
  2710. + * so the tiny check for si_rwsem is unnecessary.
  2711. + */
  2712. + /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
  2713. +
  2714. + err = -EIO;
  2715. + sbinfo->si_dbgaufs_xigen = debugfs_create_file
  2716. + ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
  2717. + &dbgaufs_xigen_fop);
  2718. + if (sbinfo->si_dbgaufs_xigen)
  2719. + err = 0;
  2720. +
  2721. + return err;
  2722. +}
  2723. +#else
  2724. +static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
  2725. +{
  2726. + return 0;
  2727. +}
  2728. +#endif /* CONFIG_AUFS_EXPORT */
  2729. +
  2730. +/* ---------------------------------------------------------------------- */
  2731. +
  2732. +void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
  2733. +{
  2734. + /*
  2735. + * This function is a dynamic '__init' fucntion actually,
  2736. + * so the tiny check for si_rwsem is unnecessary.
  2737. + */
  2738. + /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
  2739. +
  2740. + debugfs_remove_recursive(sbinfo->si_dbgaufs);
  2741. + sbinfo->si_dbgaufs = NULL;
  2742. + kobject_put(&sbinfo->si_kobj);
  2743. +}
  2744. +
  2745. +int dbgaufs_si_init(struct au_sbinfo *sbinfo)
  2746. +{
  2747. + int err;
  2748. + char name[SysaufsSiNameLen];
  2749. +
  2750. + /*
  2751. + * This function is a dynamic '__init' fucntion actually,
  2752. + * so the tiny check for si_rwsem is unnecessary.
  2753. + */
  2754. + /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
  2755. +
  2756. + err = -ENOENT;
  2757. + if (!dbgaufs) {
  2758. + AuErr1("/debug/aufs is uninitialized\n");
  2759. + goto out;
  2760. + }
  2761. +
  2762. + err = -EIO;
  2763. + sysaufs_name(sbinfo, name);
  2764. + sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
  2765. + if (unlikely(!sbinfo->si_dbgaufs))
  2766. + goto out;
  2767. + kobject_get(&sbinfo->si_kobj);
  2768. +
  2769. + sbinfo->si_dbgaufs_xib = debugfs_create_file
  2770. + ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
  2771. + &dbgaufs_xib_fop);
  2772. + if (unlikely(!sbinfo->si_dbgaufs_xib))
  2773. + goto out_dir;
  2774. +
  2775. + err = dbgaufs_xigen_init(sbinfo);
  2776. + if (!err)
  2777. + goto out; /* success */
  2778. +
  2779. + out_dir:
  2780. + dbgaufs_si_fin(sbinfo);
  2781. + out:
  2782. + return err;
  2783. +}
  2784. +
  2785. +/* ---------------------------------------------------------------------- */
  2786. +
  2787. +void dbgaufs_fin(void)
  2788. +{
  2789. + debugfs_remove(dbgaufs);
  2790. +}
  2791. +
  2792. +int __init dbgaufs_init(void)
  2793. +{
  2794. + int err;
  2795. +
  2796. + err = -EIO;
  2797. + dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
  2798. + if (dbgaufs)
  2799. + err = 0;
  2800. + return err;
  2801. +}
  2802. diff -Nur linux-2.6.31.4.orig/fs/aufs/dbgaufs.h linux-2.6.31.4/fs/aufs/dbgaufs.h
  2803. --- linux-2.6.31.4.orig/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
  2804. +++ linux-2.6.31.4/fs/aufs/dbgaufs.h 2009-10-18 11:26:01.000000000 +0200
  2805. @@ -0,0 +1,79 @@
  2806. +/*
  2807. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  2808. + *
  2809. + * This program, aufs is free software; you can redistribute it and/or modify
  2810. + * it under the terms of the GNU General Public License as published by
  2811. + * the Free Software Foundation; either version 2 of the License, or
  2812. + * (at your option) any later version.
  2813. + *
  2814. + * This program is distributed in the hope that it will be useful,
  2815. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2816. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2817. + * GNU General Public License for more details.
  2818. + *
  2819. + * You should have received a copy of the GNU General Public License
  2820. + * along with this program; if not, write to the Free Software
  2821. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  2822. + */
  2823. +
  2824. +/*
  2825. + * debugfs interface
  2826. + */
  2827. +
  2828. +#ifndef __DBGAUFS_H__
  2829. +#define __DBGAUFS_H__
  2830. +
  2831. +#ifdef __KERNEL__
  2832. +
  2833. +#include <linux/init.h>
  2834. +#include <linux/aufs_type.h>
  2835. +
  2836. +struct super_block;
  2837. +struct au_sbinfo;
  2838. +
  2839. +#ifdef CONFIG_DEBUG_FS
  2840. +/* dbgaufs.c */
  2841. +void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
  2842. +void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
  2843. +void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
  2844. +int dbgaufs_si_init(struct au_sbinfo *sbinfo);
  2845. +void dbgaufs_fin(void);
  2846. +int __init dbgaufs_init(void);
  2847. +
  2848. +#else
  2849. +
  2850. +static inline
  2851. +void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
  2852. +{
  2853. + /* empty */
  2854. +}
  2855. +
  2856. +static inline
  2857. +void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
  2858. +{
  2859. + /* empty */
  2860. +}
  2861. +
  2862. +static inline
  2863. +void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
  2864. +{
  2865. + /* empty */
  2866. +}
  2867. +
  2868. +static inline
  2869. +int dbgaufs_si_init(struct au_sbinfo *sbinfo)
  2870. +{
  2871. + return 0;
  2872. +}
  2873. +
  2874. +#define dbgaufs_fin() do {} while (0)
  2875. +
  2876. +static inline
  2877. +int __init dbgaufs_init(void)
  2878. +{
  2879. + return 0;
  2880. +}
  2881. +#endif /* CONFIG_DEBUG_FS */
  2882. +
  2883. +#endif /* __KERNEL__ */
  2884. +#endif /* __DBGAUFS_H__ */
  2885. diff -Nur linux-2.6.31.4.orig/fs/aufs/dcsub.c linux-2.6.31.4/fs/aufs/dcsub.c
  2886. --- linux-2.6.31.4.orig/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100
  2887. +++ linux-2.6.31.4/fs/aufs/dcsub.c 2009-10-18 11:26:01.000000000 +0200
  2888. @@ -0,0 +1,223 @@
  2889. +/*
  2890. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  2891. + *
  2892. + * This program, aufs is free software; you can redistribute it and/or modify
  2893. + * it under the terms of the GNU General Public License as published by
  2894. + * the Free Software Foundation; either version 2 of the License, or
  2895. + * (at your option) any later version.
  2896. + *
  2897. + * This program is distributed in the hope that it will be useful,
  2898. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2899. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2900. + * GNU General Public License for more details.
  2901. + *
  2902. + * You should have received a copy of the GNU General Public License
  2903. + * along with this program; if not, write to the Free Software
  2904. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  2905. + */
  2906. +
  2907. +/*
  2908. + * sub-routines for dentry cache
  2909. + */
  2910. +
  2911. +#include "aufs.h"
  2912. +
  2913. +static void au_dpage_free(struct au_dpage *dpage)
  2914. +{
  2915. + int i;
  2916. + struct dentry **p;
  2917. +
  2918. + p = dpage->dentries;
  2919. + for (i = 0; i < dpage->ndentry; i++)
  2920. + dput(*p++);
  2921. + free_page((unsigned long)dpage->dentries);
  2922. +}
  2923. +
  2924. +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
  2925. +{
  2926. + int err;
  2927. + void *p;
  2928. +
  2929. + err = -ENOMEM;
  2930. + dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
  2931. + if (unlikely(!dpages->dpages))
  2932. + goto out;
  2933. +
  2934. + p = (void *)__get_free_page(gfp);
  2935. + if (unlikely(!p))
  2936. + goto out_dpages;
  2937. +
  2938. + dpages->dpages[0].ndentry = 0;
  2939. + dpages->dpages[0].dentries = p;
  2940. + dpages->ndpage = 1;
  2941. + return 0; /* success */
  2942. +
  2943. + out_dpages:
  2944. + kfree(dpages->dpages);
  2945. + out:
  2946. + return err;
  2947. +}
  2948. +
  2949. +void au_dpages_free(struct au_dcsub_pages *dpages)
  2950. +{
  2951. + int i;
  2952. + struct au_dpage *p;
  2953. +
  2954. + p = dpages->dpages;
  2955. + for (i = 0; i < dpages->ndpage; i++)
  2956. + au_dpage_free(p++);
  2957. + kfree(dpages->dpages);
  2958. +}
  2959. +
  2960. +static int au_dpages_append(struct au_dcsub_pages *dpages,
  2961. + struct dentry *dentry, gfp_t gfp)
  2962. +{
  2963. + int err, sz;
  2964. + struct au_dpage *dpage;
  2965. + void *p;
  2966. +
  2967. + dpage = dpages->dpages + dpages->ndpage - 1;
  2968. + sz = PAGE_SIZE / sizeof(dentry);
  2969. + if (unlikely(dpage->ndentry >= sz)) {
  2970. + AuLabel(new dpage);
  2971. + err = -ENOMEM;
  2972. + sz = dpages->ndpage * sizeof(*dpages->dpages);
  2973. + p = au_kzrealloc(dpages->dpages, sz,
  2974. + sz + sizeof(*dpages->dpages), gfp);
  2975. + if (unlikely(!p))
  2976. + goto out;
  2977. +
  2978. + dpages->dpages = p;
  2979. + dpage = dpages->dpages + dpages->ndpage;
  2980. + p = (void *)__get_free_page(gfp);
  2981. + if (unlikely(!p))
  2982. + goto out;
  2983. +
  2984. + dpage->ndentry = 0;
  2985. + dpage->dentries = p;
  2986. + dpages->ndpage++;
  2987. + }
  2988. +
  2989. + dpage->dentries[dpage->ndentry++] = dget(dentry);
  2990. + return 0; /* success */
  2991. +
  2992. + out:
  2993. + return err;
  2994. +}
  2995. +
  2996. +int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
  2997. + au_dpages_test test, void *arg)
  2998. +{
  2999. + int err;
  3000. + struct dentry *this_parent = root;
  3001. + struct list_head *next;
  3002. + struct super_block *sb = root->d_sb;
  3003. +
  3004. + err = 0;
  3005. + spin_lock(&dcache_lock);
  3006. + repeat:
  3007. + next = this_parent->d_subdirs.next;
  3008. + resume:
  3009. + if (this_parent->d_sb == sb
  3010. + && !IS_ROOT(this_parent)
  3011. + && atomic_read(&this_parent->d_count)
  3012. + && this_parent->d_inode
  3013. + && (!test || test(this_parent, arg))) {
  3014. + err = au_dpages_append(dpages, this_parent, GFP_ATOMIC);
  3015. + if (unlikely(err))
  3016. + goto out;
  3017. + }
  3018. +
  3019. + while (next != &this_parent->d_subdirs) {
  3020. + struct list_head *tmp = next;
  3021. + struct dentry *dentry = list_entry(tmp, struct dentry,
  3022. + d_u.d_child);
  3023. + next = tmp->next;
  3024. + if (/*d_unhashed(dentry) || */!dentry->d_inode)
  3025. + continue;
  3026. + if (!list_empty(&dentry->d_subdirs)) {
  3027. + this_parent = dentry;
  3028. + goto repeat;
  3029. + }
  3030. + if (dentry->d_sb == sb
  3031. + && atomic_read(&dentry->d_count)
  3032. + && (!test || test(dentry, arg))) {
  3033. + err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
  3034. + if (unlikely(err))
  3035. + goto out;
  3036. + }
  3037. + }
  3038. +
  3039. + if (this_parent != root) {
  3040. + next = this_parent->d_u.d_child.next;
  3041. + this_parent = this_parent->d_parent; /* dcache_lock is locked */
  3042. + goto resume;
  3043. + }
  3044. + out:
  3045. + spin_unlock(&dcache_lock);
  3046. + return err;
  3047. +}
  3048. +
  3049. +int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
  3050. + int do_include, au_dpages_test test, void *arg)
  3051. +{
  3052. + int err;
  3053. +
  3054. + err = 0;
  3055. + spin_lock(&dcache_lock);
  3056. + if (do_include && (!test || test(dentry, arg))) {
  3057. + err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
  3058. + if (unlikely(err))
  3059. + goto out;
  3060. + }
  3061. + while (!IS_ROOT(dentry)) {
  3062. + dentry = dentry->d_parent; /* dcache_lock is locked */
  3063. + if (!test || test(dentry, arg)) {
  3064. + err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
  3065. + if (unlikely(err))
  3066. + break;
  3067. + }
  3068. + }
  3069. +
  3070. + out:
  3071. + spin_unlock(&dcache_lock);
  3072. +
  3073. + return err;
  3074. +}
  3075. +
  3076. +struct dentry *au_test_subdir(struct dentry *d1, struct dentry *d2)
  3077. +{
  3078. + struct dentry *trap, **dentries;
  3079. + int err, i, j;
  3080. + struct au_dcsub_pages dpages;
  3081. + struct au_dpage *dpage;
  3082. +
  3083. + trap = ERR_PTR(-ENOMEM);
  3084. + err = au_dpages_init(&dpages, GFP_NOFS);
  3085. + if (unlikely(err))
  3086. + goto out;
  3087. + err = au_dcsub_pages_rev(&dpages, d1, /*do_include*/1, NULL, NULL);
  3088. + if (unlikely(err))
  3089. + goto out_dpages;
  3090. +
  3091. + trap = d1;
  3092. + for (i = 0; !err && i < dpages.ndpage; i++) {
  3093. + dpage = dpages.dpages + i;
  3094. + dentries = dpage->dentries;
  3095. + for (j = 0; !err && j < dpage->ndentry; j++) {
  3096. + struct dentry *d;
  3097. +
  3098. + d = dentries[j];
  3099. + err = (d == d2);
  3100. + if (!err)
  3101. + trap = d;
  3102. + }
  3103. + }
  3104. + if (!err)
  3105. + trap = NULL;
  3106. +
  3107. + out_dpages:
  3108. + au_dpages_free(&dpages);
  3109. + out:
  3110. + return trap;
  3111. +}
  3112. diff -Nur linux-2.6.31.4.orig/fs/aufs/dcsub.h linux-2.6.31.4/fs/aufs/dcsub.h
  3113. --- linux-2.6.31.4.orig/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100
  3114. +++ linux-2.6.31.4/fs/aufs/dcsub.h 2009-10-18 11:26:01.000000000 +0200
  3115. @@ -0,0 +1,54 @@
  3116. +/*
  3117. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  3118. + *
  3119. + * This program, aufs is free software; you can redistribute it and/or modify
  3120. + * it under the terms of the GNU General Public License as published by
  3121. + * the Free Software Foundation; either version 2 of the License, or
  3122. + * (at your option) any later version.
  3123. + *
  3124. + * This program is distributed in the hope that it will be useful,
  3125. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3126. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3127. + * GNU General Public License for more details.
  3128. + *
  3129. + * You should have received a copy of the GNU General Public License
  3130. + * along with this program; if not, write to the Free Software
  3131. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  3132. + */
  3133. +
  3134. +/*
  3135. + * sub-routines for dentry cache
  3136. + */
  3137. +
  3138. +#ifndef __AUFS_DCSUB_H__
  3139. +#define __AUFS_DCSUB_H__
  3140. +
  3141. +#ifdef __KERNEL__
  3142. +
  3143. +#include <linux/types.h>
  3144. +
  3145. +struct dentry;
  3146. +
  3147. +struct au_dpage {
  3148. + int ndentry;
  3149. + struct dentry **dentries;
  3150. +};
  3151. +
  3152. +struct au_dcsub_pages {
  3153. + int ndpage;
  3154. + struct au_dpage *dpages;
  3155. +};
  3156. +
  3157. +/* ---------------------------------------------------------------------- */
  3158. +
  3159. +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
  3160. +void au_dpages_free(struct au_dcsub_pages *dpages);
  3161. +typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
  3162. +int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
  3163. + au_dpages_test test, void *arg);
  3164. +int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
  3165. + int do_include, au_dpages_test test, void *arg);
  3166. +struct dentry *au_test_subdir(struct dentry *d1, struct dentry *d2);
  3167. +
  3168. +#endif /* __KERNEL__ */
  3169. +#endif /* __AUFS_DCSUB_H__ */
  3170. diff -Nur linux-2.6.31.4.orig/fs/aufs/debug.c linux-2.6.31.4/fs/aufs/debug.c
  3171. --- linux-2.6.31.4.orig/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
  3172. +++ linux-2.6.31.4/fs/aufs/debug.c 2009-10-18 11:26:01.000000000 +0200
  3173. @@ -0,0 +1,427 @@
  3174. +/*
  3175. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  3176. + *
  3177. + * This program, aufs is free software; you can redistribute it and/or modify
  3178. + * it under the terms of the GNU General Public License as published by
  3179. + * the Free Software Foundation; either version 2 of the License, or
  3180. + * (at your option) any later version.
  3181. + *
  3182. + * This program is distributed in the hope that it will be useful,
  3183. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3184. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3185. + * GNU General Public License for more details.
  3186. + *
  3187. + * You should have received a copy of the GNU General Public License
  3188. + * along with this program; if not, write to the Free Software
  3189. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  3190. + */
  3191. +
  3192. +/*
  3193. + * debug print functions
  3194. + */
  3195. +
  3196. +#include <linux/module.h>
  3197. +#include <linux/vt_kern.h>
  3198. +#include "aufs.h"
  3199. +
  3200. +int aufs_debug;
  3201. +MODULE_PARM_DESC(debug, "debug print");
  3202. +module_param_named(debug, aufs_debug, int, S_IRUGO | S_IWUSR | S_IWGRP);
  3203. +
  3204. +char *au_plevel = KERN_DEBUG;
  3205. +#define dpri(fmt, arg...) do { \
  3206. + if (au_debug_test()) \
  3207. + printk("%s" fmt, au_plevel, ##arg); \
  3208. +} while (0)
  3209. +
  3210. +/* ---------------------------------------------------------------------- */
  3211. +
  3212. +void au_dpri_whlist(struct au_nhash *whlist)
  3213. +{
  3214. + unsigned long ul, n;
  3215. + struct hlist_head *head;
  3216. + struct au_vdir_wh *tpos;
  3217. + struct hlist_node *pos;
  3218. +
  3219. + n = whlist->nh_num;
  3220. + head = whlist->nh_head;
  3221. + for (ul = 0; ul < n; ul++) {
  3222. + hlist_for_each_entry(tpos, pos, head, wh_hash)
  3223. + dpri("b%d, %.*s, %d\n",
  3224. + tpos->wh_bindex,
  3225. + tpos->wh_str.len, tpos->wh_str.name,
  3226. + tpos->wh_str.len);
  3227. + head++;
  3228. + }
  3229. +}
  3230. +
  3231. +void au_dpri_vdir(struct au_vdir *vdir)
  3232. +{
  3233. + unsigned long ul;
  3234. + union au_vdir_deblk_p p;
  3235. + unsigned char *o;
  3236. +
  3237. + if (!vdir || IS_ERR(vdir)) {
  3238. + dpri("err %ld\n", PTR_ERR(vdir));
  3239. + return;
  3240. + }
  3241. +
  3242. + dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n",
  3243. + vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
  3244. + vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
  3245. + for (ul = 0; ul < vdir->vd_nblk; ul++) {
  3246. + p.deblk = vdir->vd_deblk[ul];
  3247. + o = p.deblk;
  3248. + dpri("[%lu]: %p\n", ul, o);
  3249. + }
  3250. +}
  3251. +
  3252. +static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode,
  3253. + struct dentry *wh)
  3254. +{
  3255. + char *n = NULL;
  3256. + int l = 0;
  3257. +
  3258. + if (!inode || IS_ERR(inode)) {
  3259. + dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
  3260. + return -1;
  3261. + }
  3262. +
  3263. + /* the type of i_blocks depends upon CONFIG_LSF */
  3264. + BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
  3265. + && sizeof(inode->i_blocks) != sizeof(u64));
  3266. + if (wh) {
  3267. + n = (void *)wh->d_name.name;
  3268. + l = wh->d_name.len;
  3269. + }
  3270. +
  3271. + dpri("i%d: i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
  3272. + " ct %lld, np %lu, st 0x%lx, f 0x%x, g %x%s%.*s\n",
  3273. + bindex,
  3274. + inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
  3275. + atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
  3276. + i_size_read(inode), (unsigned long long)inode->i_blocks,
  3277. + (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
  3278. + inode->i_mapping ? inode->i_mapping->nrpages : 0,
  3279. + inode->i_state, inode->i_flags, inode->i_generation,
  3280. + l ? ", wh " : "", l, n);
  3281. + return 0;
  3282. +}
  3283. +
  3284. +void au_dpri_inode(struct inode *inode)
  3285. +{
  3286. + struct au_iinfo *iinfo;
  3287. + aufs_bindex_t bindex;
  3288. + int err;
  3289. +
  3290. + err = do_pri_inode(-1, inode, NULL);
  3291. + if (err || !au_test_aufs(inode->i_sb))
  3292. + return;
  3293. +
  3294. + iinfo = au_ii(inode);
  3295. + if (!iinfo)
  3296. + return;
  3297. + dpri("i-1: bstart %d, bend %d, gen %d\n",
  3298. + iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode));
  3299. + if (iinfo->ii_bstart < 0)
  3300. + return;
  3301. + for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++)
  3302. + do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode,
  3303. + iinfo->ii_hinode[0 + bindex].hi_whdentry);
  3304. +}
  3305. +
  3306. +static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
  3307. +{
  3308. + struct dentry *wh = NULL;
  3309. +
  3310. + if (!dentry || IS_ERR(dentry)) {
  3311. + dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
  3312. + return -1;
  3313. + }
  3314. + /* do not call dget_parent() here */
  3315. + dpri("d%d: %.*s?/%.*s, %s, cnt %d, flags 0x%x\n",
  3316. + bindex,
  3317. + AuDLNPair(dentry->d_parent), AuDLNPair(dentry),
  3318. + dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
  3319. + atomic_read(&dentry->d_count), dentry->d_flags);
  3320. + if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) {
  3321. + struct au_iinfo *iinfo = au_ii(dentry->d_inode);
  3322. + if (iinfo)
  3323. + wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
  3324. + }
  3325. + do_pri_inode(bindex, dentry->d_inode, wh);
  3326. + return 0;
  3327. +}
  3328. +
  3329. +void au_dpri_dentry(struct dentry *dentry)
  3330. +{
  3331. + struct au_dinfo *dinfo;
  3332. + aufs_bindex_t bindex;
  3333. + int err;
  3334. +
  3335. + err = do_pri_dentry(-1, dentry);
  3336. + if (err || !au_test_aufs(dentry->d_sb))
  3337. + return;
  3338. +
  3339. + dinfo = au_di(dentry);
  3340. + if (!dinfo)
  3341. + return;
  3342. + dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d\n",
  3343. + dinfo->di_bstart, dinfo->di_bend,
  3344. + dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry));
  3345. + if (dinfo->di_bstart < 0)
  3346. + return;
  3347. + for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++)
  3348. + do_pri_dentry(bindex, dinfo->di_hdentry[0 + bindex].hd_dentry);
  3349. +}
  3350. +
  3351. +static int do_pri_file(aufs_bindex_t bindex, struct file *file)
  3352. +{
  3353. + char a[32];
  3354. +
  3355. + if (!file || IS_ERR(file)) {
  3356. + dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
  3357. + return -1;
  3358. + }
  3359. + a[0] = 0;
  3360. + if (bindex < 0
  3361. + && file->f_dentry
  3362. + && au_test_aufs(file->f_dentry->d_sb)
  3363. + && au_fi(file))
  3364. + snprintf(a, sizeof(a), ", mmapped %d", au_test_mmapped(file));
  3365. + dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, pos %llu%s\n",
  3366. + bindex, file->f_mode, file->f_flags, (long)file_count(file),
  3367. + file->f_pos, a);
  3368. + if (file->f_dentry)
  3369. + do_pri_dentry(bindex, file->f_dentry);
  3370. + return 0;
  3371. +}
  3372. +
  3373. +void au_dpri_file(struct file *file)
  3374. +{
  3375. + struct au_finfo *finfo;
  3376. + aufs_bindex_t bindex;
  3377. + int err;
  3378. +
  3379. + err = do_pri_file(-1, file);
  3380. + if (err || !file->f_dentry || !au_test_aufs(file->f_dentry->d_sb))
  3381. + return;
  3382. +
  3383. + finfo = au_fi(file);
  3384. + if (!finfo)
  3385. + return;
  3386. + if (finfo->fi_bstart < 0)
  3387. + return;
  3388. + for (bindex = finfo->fi_bstart; bindex <= finfo->fi_bend; bindex++) {
  3389. + struct au_hfile *hf;
  3390. +
  3391. + hf = finfo->fi_hfile + bindex;
  3392. + do_pri_file(bindex, hf ? hf->hf_file : NULL);
  3393. + }
  3394. +}
  3395. +
  3396. +static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
  3397. +{
  3398. + struct vfsmount *mnt;
  3399. + struct super_block *sb;
  3400. +
  3401. + if (!br || IS_ERR(br))
  3402. + goto out;
  3403. + mnt = br->br_mnt;
  3404. + if (!mnt || IS_ERR(mnt))
  3405. + goto out;
  3406. + sb = mnt->mnt_sb;
  3407. + if (!sb || IS_ERR(sb))
  3408. + goto out;
  3409. +
  3410. + dpri("s%d: {perm 0x%x, cnt %d, wbr %p}, "
  3411. + "%s, dev 0x%02x%02x, flags 0x%lx, cnt(BIAS) %d, active %d, "
  3412. + "xino %d\n",
  3413. + bindex, br->br_perm, atomic_read(&br->br_count), br->br_wbr,
  3414. + au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
  3415. + sb->s_flags, sb->s_count - S_BIAS,
  3416. + atomic_read(&sb->s_active), !!br->br_xino.xi_file);
  3417. + return 0;
  3418. +
  3419. + out:
  3420. + dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
  3421. + return -1;
  3422. +}
  3423. +
  3424. +void au_dpri_sb(struct super_block *sb)
  3425. +{
  3426. + struct au_sbinfo *sbinfo;
  3427. + aufs_bindex_t bindex;
  3428. + int err;
  3429. + /* to reuduce stack size */
  3430. + struct {
  3431. + struct vfsmount mnt;
  3432. + struct au_branch fake;
  3433. + } *a;
  3434. +
  3435. + /* this function can be called from magic sysrq */
  3436. + a = kzalloc(sizeof(*a), GFP_ATOMIC);
  3437. + if (unlikely(!a)) {
  3438. + dpri("no memory\n");
  3439. + return;
  3440. + }
  3441. +
  3442. + a->mnt.mnt_sb = sb;
  3443. + a->fake.br_perm = 0;
  3444. + a->fake.br_mnt = &a->mnt;
  3445. + a->fake.br_xino.xi_file = NULL;
  3446. + atomic_set(&a->fake.br_count, 0);
  3447. + smp_mb(); /* atomic_set */
  3448. + err = do_pri_br(-1, &a->fake);
  3449. + kfree(a);
  3450. + dpri("dev 0x%x\n", sb->s_dev);
  3451. + if (err || !au_test_aufs(sb))
  3452. + return;
  3453. +
  3454. + sbinfo = au_sbi(sb);
  3455. + if (!sbinfo)
  3456. + return;
  3457. + dpri("nw %d, gen %u, kobj %d\n",
  3458. + atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
  3459. + atomic_read(&sbinfo->si_kobj.kref.refcount));
  3460. + for (bindex = 0; bindex <= sbinfo->si_bend; bindex++)
  3461. + do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
  3462. +}
  3463. +
  3464. +/* ---------------------------------------------------------------------- */
  3465. +
  3466. +void au_dbg_sleep_jiffy(int jiffy)
  3467. +{
  3468. + while (jiffy)
  3469. + jiffy = schedule_timeout_uninterruptible(jiffy);
  3470. +}
  3471. +
  3472. +void au_dbg_iattr(struct iattr *ia)
  3473. +{
  3474. +#define AuBit(name) if (ia->ia_valid & ATTR_ ## name) \
  3475. + dpri(#name "\n")
  3476. + AuBit(MODE);
  3477. + AuBit(UID);
  3478. + AuBit(GID);
  3479. + AuBit(SIZE);
  3480. + AuBit(ATIME);
  3481. + AuBit(MTIME);
  3482. + AuBit(CTIME);
  3483. + AuBit(ATIME_SET);
  3484. + AuBit(MTIME_SET);
  3485. + AuBit(FORCE);
  3486. + AuBit(ATTR_FLAG);
  3487. + AuBit(KILL_SUID);
  3488. + AuBit(KILL_SGID);
  3489. + AuBit(FILE);
  3490. + AuBit(KILL_PRIV);
  3491. + AuBit(OPEN);
  3492. + AuBit(TIMES_SET);
  3493. +#undef AuBit
  3494. + dpri("ia_file %p\n", ia->ia_file);
  3495. +}
  3496. +
  3497. +/* ---------------------------------------------------------------------- */
  3498. +
  3499. +void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen)
  3500. +{
  3501. + struct dentry *parent;
  3502. +
  3503. + parent = dget_parent(dentry);
  3504. + AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode)
  3505. + || IS_ROOT(dentry)
  3506. + || au_digen(parent) != sigen);
  3507. + dput(parent);
  3508. +}
  3509. +
  3510. +void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen)
  3511. +{
  3512. + struct dentry *parent;
  3513. +
  3514. + parent = dget_parent(dentry);
  3515. + AuDebugOn(S_ISDIR(dentry->d_inode->i_mode)
  3516. + || au_digen(parent) != sigen);
  3517. + dput(parent);
  3518. +}
  3519. +
  3520. +void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
  3521. +{
  3522. + int err, i, j;
  3523. + struct au_dcsub_pages dpages;
  3524. + struct au_dpage *dpage;
  3525. + struct dentry **dentries;
  3526. +
  3527. + err = au_dpages_init(&dpages, GFP_NOFS);
  3528. + AuDebugOn(err);
  3529. + err = au_dcsub_pages_rev(&dpages, parent, /*do_include*/1, NULL, NULL);
  3530. + AuDebugOn(err);
  3531. + for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
  3532. + dpage = dpages.dpages + i;
  3533. + dentries = dpage->dentries;
  3534. + for (j = dpage->ndentry - 1; !err && j >= 0; j--)
  3535. + AuDebugOn(au_digen(dentries[j]) != sigen);
  3536. + }
  3537. + au_dpages_free(&dpages);
  3538. +}
  3539. +
  3540. +void au_dbg_verify_hf(struct au_finfo *finfo)
  3541. +{
  3542. + struct au_hfile *hf;
  3543. + aufs_bindex_t bend, bindex;
  3544. +
  3545. + if (finfo->fi_bstart >= 0) {
  3546. + bend = finfo->fi_bend;
  3547. + for (bindex = finfo->fi_bstart; bindex <= bend; bindex++) {
  3548. + hf = finfo->fi_hfile + bindex;
  3549. + AuDebugOn(hf->hf_file || hf->hf_br);
  3550. + }
  3551. + }
  3552. +}
  3553. +
  3554. +void au_dbg_verify_kthread(void)
  3555. +{
  3556. + if (au_test_wkq(current)) {
  3557. + au_dbg_blocked();
  3558. + BUG();
  3559. + }
  3560. +}
  3561. +
  3562. +/* ---------------------------------------------------------------------- */
  3563. +
  3564. +void au_debug_sbinfo_init(struct au_sbinfo *sbinfo __maybe_unused)
  3565. +{
  3566. +#ifdef AuForceNoPlink
  3567. + au_opt_clr(sbinfo->si_mntflags, PLINK);
  3568. +#endif
  3569. +#ifdef AuForceNoXino
  3570. + au_opt_clr(sbinfo->si_mntflags, XINO);
  3571. +#endif
  3572. +#ifdef AuForceNoRefrof
  3573. + au_opt_clr(sbinfo->si_mntflags, REFROF);
  3574. +#endif
  3575. +#ifdef AuForceHinotify
  3576. + au_opt_set_udba(sbinfo->si_mntflags, UDBA_HINOTIFY);
  3577. +#endif
  3578. +}
  3579. +
  3580. +int __init au_debug_init(void)
  3581. +{
  3582. + aufs_bindex_t bindex;
  3583. + struct au_vdir_destr destr;
  3584. +
  3585. + bindex = -1;
  3586. + AuDebugOn(bindex >= 0);
  3587. +
  3588. + destr.len = -1;
  3589. + AuDebugOn(destr.len < NAME_MAX);
  3590. +
  3591. +#ifdef CONFIG_4KSTACKS
  3592. + AuWarn("CONFIG_4KSTACKS is defined.\n");
  3593. +#endif
  3594. +
  3595. +#ifdef AuForceNoBrs
  3596. + sysaufs_brs = 0;
  3597. +#endif
  3598. +
  3599. + return 0;
  3600. +}
  3601. diff -Nur linux-2.6.31.4.orig/fs/aufs/debug.h linux-2.6.31.4/fs/aufs/debug.h
  3602. --- linux-2.6.31.4.orig/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100
  3603. +++ linux-2.6.31.4/fs/aufs/debug.h 2009-10-18 11:26:01.000000000 +0200
  3604. @@ -0,0 +1,260 @@
  3605. +/*
  3606. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  3607. + *
  3608. + * This program, aufs is free software; you can redistribute it and/or modify
  3609. + * it under the terms of the GNU General Public License as published by
  3610. + * the Free Software Foundation; either version 2 of the License, or
  3611. + * (at your option) any later version.
  3612. + *
  3613. + * This program is distributed in the hope that it will be useful,
  3614. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3615. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3616. + * GNU General Public License for more details.
  3617. + *
  3618. + * You should have received a copy of the GNU General Public License
  3619. + * along with this program; if not, write to the Free Software
  3620. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  3621. + */
  3622. +
  3623. +/*
  3624. + * debug print functions
  3625. + */
  3626. +
  3627. +#ifndef __AUFS_DEBUG_H__
  3628. +#define __AUFS_DEBUG_H__
  3629. +
  3630. +#ifdef __KERNEL__
  3631. +
  3632. +#include <linux/bug.h>
  3633. +/* #include <linux/err.h> */
  3634. +/* #include <linux/init.h> */
  3635. +/* #include <linux/kernel.h> */
  3636. +#include <linux/delay.h>
  3637. +/* #include <linux/kd.h> */
  3638. +/* #include <linux/vt_kern.h> */
  3639. +#include <linux/sysrq.h>
  3640. +#include <linux/aufs_type.h>
  3641. +
  3642. +#ifdef CONFIG_AUFS_DEBUG
  3643. +#define AuDebugOn(a) BUG_ON(a)
  3644. +
  3645. +/* module parameter */
  3646. +extern int aufs_debug;
  3647. +static inline void au_debug(int n)
  3648. +{
  3649. + aufs_debug = n;
  3650. + smp_mb();
  3651. +}
  3652. +
  3653. +static inline int au_debug_test(void)
  3654. +{
  3655. + return aufs_debug;
  3656. +}
  3657. +#else
  3658. +#define AuDebugOn(a) do {} while (0)
  3659. +#define au_debug() do {} while (0)
  3660. +static inline int au_debug_test(void)
  3661. +{
  3662. + return 0;
  3663. +}
  3664. +#endif /* CONFIG_AUFS_DEBUG */
  3665. +
  3666. +/* ---------------------------------------------------------------------- */
  3667. +
  3668. +/* debug print */
  3669. +
  3670. +#define AuDpri(lvl, fmt, arg...) \
  3671. + printk(lvl AUFS_NAME " %s:%d:%s[%d]: " fmt, \
  3672. + __func__, __LINE__, current->comm, current->pid, ##arg)
  3673. +#define AuDbg(fmt, arg...) do { \
  3674. + if (au_debug_test()) \
  3675. + AuDpri(KERN_DEBUG, "DEBUG: " fmt, ##arg); \
  3676. +} while (0)
  3677. +#define AuLabel(l) AuDbg(#l "\n")
  3678. +#define AuInfo(fmt, arg...) AuDpri(KERN_INFO, fmt, ##arg)
  3679. +#define AuWarn(fmt, arg...) AuDpri(KERN_WARNING, fmt, ##arg)
  3680. +#define AuErr(fmt, arg...) AuDpri(KERN_ERR, fmt, ##arg)
  3681. +#define AuIOErr(fmt, arg...) AuErr("I/O Error, " fmt, ##arg)
  3682. +#define AuWarn1(fmt, arg...) do { \
  3683. + static unsigned char _c; \
  3684. + if (!_c++) \
  3685. + AuWarn(fmt, ##arg); \
  3686. +} while (0)
  3687. +
  3688. +#define AuErr1(fmt, arg...) do { \
  3689. + static unsigned char _c; \
  3690. + if (!_c++) \
  3691. + AuErr(fmt, ##arg); \
  3692. +} while (0)
  3693. +
  3694. +#define AuIOErr1(fmt, arg...) do { \
  3695. + static unsigned char _c; \
  3696. + if (!_c++) \
  3697. + AuIOErr(fmt, ##arg); \
  3698. +} while (0)
  3699. +
  3700. +#define AuUnsupportMsg "This operation is not supported." \
  3701. + " Please report this application to aufs-users ML."
  3702. +#define AuUnsupport(fmt, args...) do { \
  3703. + AuErr(AuUnsupportMsg "\n" fmt, ##args); \
  3704. + dump_stack(); \
  3705. +} while (0)
  3706. +
  3707. +#define AuTraceErr(e) do { \
  3708. + if (unlikely((e) < 0)) \
  3709. + AuDbg("err %d\n", (int)(e)); \
  3710. +} while (0)
  3711. +
  3712. +#define AuTraceErrPtr(p) do { \
  3713. + if (IS_ERR(p)) \
  3714. + AuDbg("err %ld\n", PTR_ERR(p)); \
  3715. +} while (0)
  3716. +
  3717. +/* dirty macros for debug print, use with "%.*s" and caution */
  3718. +#define AuLNPair(qstr) (qstr)->len, (qstr)->name
  3719. +#define AuDLNPair(d) AuLNPair(&(d)->d_name)
  3720. +
  3721. +/* ---------------------------------------------------------------------- */
  3722. +
  3723. +struct au_sbinfo;
  3724. +struct au_finfo;
  3725. +struct dentry;
  3726. +#ifdef CONFIG_AUFS_DEBUG
  3727. +extern char *au_plevel;
  3728. +struct au_nhash;
  3729. +void au_dpri_whlist(struct au_nhash *whlist);
  3730. +struct au_vdir;
  3731. +void au_dpri_vdir(struct au_vdir *vdir);
  3732. +struct inode;
  3733. +void au_dpri_inode(struct inode *inode);
  3734. +void au_dpri_dentry(struct dentry *dentry);
  3735. +struct file;
  3736. +void au_dpri_file(struct file *filp);
  3737. +struct super_block;
  3738. +void au_dpri_sb(struct super_block *sb);
  3739. +
  3740. +void au_dbg_sleep_jiffy(int jiffy);
  3741. +struct iattr;
  3742. +void au_dbg_iattr(struct iattr *ia);
  3743. +
  3744. +void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen);
  3745. +void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen);
  3746. +void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
  3747. +void au_dbg_verify_hf(struct au_finfo *finfo);
  3748. +void au_dbg_verify_kthread(void);
  3749. +
  3750. +int __init au_debug_init(void);
  3751. +void au_debug_sbinfo_init(struct au_sbinfo *sbinfo);
  3752. +#define AuDbgWhlist(w) do { \
  3753. + AuDbg(#w "\n"); \
  3754. + au_dpri_whlist(w); \
  3755. +} while (0)
  3756. +
  3757. +#define AuDbgVdir(v) do { \
  3758. + AuDbg(#v "\n"); \
  3759. + au_dpri_vdir(v); \
  3760. +} while (0)
  3761. +
  3762. +#define AuDbgInode(i) do { \
  3763. + AuDbg(#i "\n"); \
  3764. + au_dpri_inode(i); \
  3765. +} while (0)
  3766. +
  3767. +#define AuDbgDentry(d) do { \
  3768. + AuDbg(#d "\n"); \
  3769. + au_dpri_dentry(d); \
  3770. +} while (0)
  3771. +
  3772. +#define AuDbgFile(f) do { \
  3773. + AuDbg(#f "\n"); \
  3774. + au_dpri_file(f); \
  3775. +} while (0)
  3776. +
  3777. +#define AuDbgSb(sb) do { \
  3778. + AuDbg(#sb "\n"); \
  3779. + au_dpri_sb(sb); \
  3780. +} while (0)
  3781. +
  3782. +#define AuDbgSleep(sec) do { \
  3783. + AuDbg("sleep %d sec\n", sec); \
  3784. + ssleep(sec); \
  3785. +} while (0)
  3786. +
  3787. +#define AuDbgSleepJiffy(jiffy) do { \
  3788. + AuDbg("sleep %d jiffies\n", jiffy); \
  3789. + au_dbg_sleep_jiffy(jiffy); \
  3790. +} while (0)
  3791. +
  3792. +#define AuDbgIAttr(ia) do { \
  3793. + AuDbg("ia_valid 0x%x\n", (ia)->ia_valid); \
  3794. + au_dbg_iattr(ia); \
  3795. +} while (0)
  3796. +#else
  3797. +static inline void au_dbg_verify_dir_parent(struct dentry *dentry,
  3798. + unsigned int sigen)
  3799. +{
  3800. + /* empty */
  3801. +}
  3802. +static inline void au_dbg_verify_nondir_parent(struct dentry *dentry,
  3803. + unsigned int sigen)
  3804. +{
  3805. + /* empty */
  3806. +}
  3807. +static inline void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
  3808. +{
  3809. + /* empty */
  3810. +}
  3811. +static inline void au_dbg_verify_hf(struct au_finfo *finfo)
  3812. +{
  3813. + /* empty */
  3814. +}
  3815. +static inline void au_dbg_verify_kthread(void)
  3816. +{
  3817. + /* empty */
  3818. +}
  3819. +
  3820. +static inline int au_debug_init(void)
  3821. +{
  3822. + return 0;
  3823. +}
  3824. +static inline void au_debug_sbinfo_init(struct au_sbinfo *sbinfo)
  3825. +{
  3826. + /* empty */
  3827. +}
  3828. +#define AuDbgWhlist(w) do {} while (0)
  3829. +#define AuDbgVdir(v) do {} while (0)
  3830. +#define AuDbgInode(i) do {} while (0)
  3831. +#define AuDbgDentry(d) do {} while (0)
  3832. +#define AuDbgFile(f) do {} while (0)
  3833. +#define AuDbgSb(sb) do {} while (0)
  3834. +#define AuDbgSleep(sec) do {} while (0)
  3835. +#define AuDbgSleepJiffy(jiffy) do {} while (0)
  3836. +#define AuDbgIAttr(ia) do {} while (0)
  3837. +#endif /* CONFIG_AUFS_DEBUG */
  3838. +
  3839. +/* ---------------------------------------------------------------------- */
  3840. +
  3841. +#ifdef CONFIG_AUFS_MAGIC_SYSRQ
  3842. +int __init au_sysrq_init(void);
  3843. +void au_sysrq_fin(void);
  3844. +
  3845. +#ifdef CONFIG_HW_CONSOLE
  3846. +#define au_dbg_blocked() do { \
  3847. + WARN_ON(1); \
  3848. + handle_sysrq('w', vc_cons[fg_console].d->vc_tty); \
  3849. +} while (0)
  3850. +#else
  3851. +#define au_dbg_blocked() do {} while (0)
  3852. +#endif
  3853. +
  3854. +#else
  3855. +static inline int au_sysrq_init(void)
  3856. +{
  3857. + return 0;
  3858. +}
  3859. +#define au_sysrq_fin() do {} while (0)
  3860. +#define au_dbg_blocked() do {} while (0)
  3861. +#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
  3862. +
  3863. +#endif /* __KERNEL__ */
  3864. +#endif /* __AUFS_DEBUG_H__ */
  3865. diff -Nur linux-2.6.31.4.orig/fs/aufs/dentry.c linux-2.6.31.4/fs/aufs/dentry.c
  3866. --- linux-2.6.31.4.orig/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100
  3867. +++ linux-2.6.31.4/fs/aufs/dentry.c 2009-10-18 11:26:01.000000000 +0200
  3868. @@ -0,0 +1,880 @@
  3869. +/*
  3870. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  3871. + *
  3872. + * This program, aufs is free software; you can redistribute it and/or modify
  3873. + * it under the terms of the GNU General Public License as published by
  3874. + * the Free Software Foundation; either version 2 of the License, or
  3875. + * (at your option) any later version.
  3876. + *
  3877. + * This program is distributed in the hope that it will be useful,
  3878. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3879. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3880. + * GNU General Public License for more details.
  3881. + *
  3882. + * You should have received a copy of the GNU General Public License
  3883. + * along with this program; if not, write to the Free Software
  3884. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  3885. + */
  3886. +
  3887. +/*
  3888. + * lookup and dentry operations
  3889. + */
  3890. +
  3891. +#include <linux/namei.h>
  3892. +#include "aufs.h"
  3893. +
  3894. +static void au_h_nd(struct nameidata *h_nd, struct nameidata *nd)
  3895. +{
  3896. + if (nd) {
  3897. + *h_nd = *nd;
  3898. +
  3899. + /*
  3900. + * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
  3901. + * due to whiteout and branch permission.
  3902. + */
  3903. + h_nd->flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
  3904. + | LOOKUP_FOLLOW);
  3905. + /* unnecessary? */
  3906. + h_nd->intent.open.file = NULL;
  3907. + } else
  3908. + memset(h_nd, 0, sizeof(*h_nd));
  3909. +}
  3910. +
  3911. +struct au_lkup_one_args {
  3912. + struct dentry **errp;
  3913. + struct qstr *name;
  3914. + struct dentry *h_parent;
  3915. + struct au_branch *br;
  3916. + struct nameidata *nd;
  3917. +};
  3918. +
  3919. +struct dentry *au_lkup_one(struct qstr *name, struct dentry *h_parent,
  3920. + struct au_branch *br, struct nameidata *nd)
  3921. +{
  3922. + struct dentry *h_dentry;
  3923. + int err;
  3924. + struct nameidata h_nd;
  3925. +
  3926. + if (au_test_fs_null_nd(h_parent->d_sb))
  3927. + return vfsub_lookup_one_len(name->name, h_parent, name->len);
  3928. +
  3929. + au_h_nd(&h_nd, nd);
  3930. + h_nd.path.dentry = h_parent;
  3931. + h_nd.path.mnt = br->br_mnt;
  3932. +
  3933. + err = __lookup_one_len(name->name, &h_nd.last, NULL, name->len);
  3934. + h_dentry = ERR_PTR(err);
  3935. + if (!err) {
  3936. + path_get(&h_nd.path);
  3937. + h_dentry = vfsub_lookup_hash(&h_nd);
  3938. + path_put(&h_nd.path);
  3939. + }
  3940. +
  3941. + return h_dentry;
  3942. +}
  3943. +
  3944. +static void au_call_lkup_one(void *args)
  3945. +{
  3946. + struct au_lkup_one_args *a = args;
  3947. + *a->errp = au_lkup_one(a->name, a->h_parent, a->br, a->nd);
  3948. +}
  3949. +
  3950. +#define AuLkup_ALLOW_NEG 1
  3951. +#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name)
  3952. +#define au_fset_lkup(flags, name) { (flags) |= AuLkup_##name; }
  3953. +#define au_fclr_lkup(flags, name) { (flags) &= ~AuLkup_##name; }
  3954. +
  3955. +struct au_do_lookup_args {
  3956. + unsigned int flags;
  3957. + mode_t type;
  3958. + struct nameidata *nd;
  3959. +};
  3960. +
  3961. +/*
  3962. + * returns positive/negative dentry, NULL or an error.
  3963. + * NULL means whiteout-ed or not-found.
  3964. + */
  3965. +static struct dentry*
  3966. +au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
  3967. + aufs_bindex_t bindex, struct qstr *wh_name,
  3968. + struct au_do_lookup_args *args)
  3969. +{
  3970. + struct dentry *h_dentry;
  3971. + struct inode *h_inode, *inode;
  3972. + struct qstr *name;
  3973. + struct au_branch *br;
  3974. + int wh_found, opq;
  3975. + unsigned char wh_able;
  3976. + const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
  3977. +
  3978. + name = &dentry->d_name;
  3979. + wh_found = 0;
  3980. + br = au_sbr(dentry->d_sb, bindex);
  3981. + wh_able = !!au_br_whable(br->br_perm);
  3982. + if (wh_able)
  3983. + wh_found = au_wh_test(h_parent, wh_name, br, /*try_sio*/0);
  3984. + h_dentry = ERR_PTR(wh_found);
  3985. + if (!wh_found)
  3986. + goto real_lookup;
  3987. + if (unlikely(wh_found < 0))
  3988. + goto out;
  3989. +
  3990. + /* We found a whiteout */
  3991. + /* au_set_dbend(dentry, bindex); */
  3992. + au_set_dbwh(dentry, bindex);
  3993. + if (!allow_neg)
  3994. + return NULL; /* success */
  3995. +
  3996. + real_lookup:
  3997. + h_dentry = au_lkup_one(name, h_parent, br, args->nd);
  3998. + if (IS_ERR(h_dentry))
  3999. + goto out;
  4000. +
  4001. + h_inode = h_dentry->d_inode;
  4002. + if (!h_inode) {
  4003. + if (!allow_neg)
  4004. + goto out_neg;
  4005. + } else if (wh_found
  4006. + || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
  4007. + goto out_neg;
  4008. +
  4009. + if (au_dbend(dentry) <= bindex)
  4010. + au_set_dbend(dentry, bindex);
  4011. + if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
  4012. + au_set_dbstart(dentry, bindex);
  4013. + au_set_h_dptr(dentry, bindex, h_dentry);
  4014. +
  4015. + inode = dentry->d_inode;
  4016. + if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able
  4017. + || (inode && !S_ISDIR(inode->i_mode)))
  4018. + goto out; /* success */
  4019. +
  4020. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  4021. + opq = au_diropq_test(h_dentry, br);
  4022. + mutex_unlock(&h_inode->i_mutex);
  4023. + if (opq > 0)
  4024. + au_set_dbdiropq(dentry, bindex);
  4025. + else if (unlikely(opq < 0)) {
  4026. + au_set_h_dptr(dentry, bindex, NULL);
  4027. + h_dentry = ERR_PTR(opq);
  4028. + }
  4029. + goto out;
  4030. +
  4031. + out_neg:
  4032. + dput(h_dentry);
  4033. + h_dentry = NULL;
  4034. + out:
  4035. + return h_dentry;
  4036. +}
  4037. +
  4038. +static int au_test_shwh(struct super_block *sb, const struct qstr *name)
  4039. +{
  4040. + if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
  4041. + && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
  4042. + return -EPERM;
  4043. + return 0;
  4044. +}
  4045. +
  4046. +/*
  4047. + * returns the number of lower positive dentries,
  4048. + * otherwise an error.
  4049. + * can be called at unlinking with @type is zero.
  4050. + */
  4051. +int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type,
  4052. + struct nameidata *nd)
  4053. +{
  4054. + int npositive, err;
  4055. + aufs_bindex_t bindex, btail, bdiropq;
  4056. + unsigned char isdir;
  4057. + struct qstr whname;
  4058. + struct au_do_lookup_args args = {
  4059. + .flags = 0,
  4060. + .type = type,
  4061. + .nd = nd
  4062. + };
  4063. + const struct qstr *name = &dentry->d_name;
  4064. + struct dentry *parent;
  4065. + struct inode *inode;
  4066. +
  4067. + parent = dget_parent(dentry);
  4068. + err = au_test_shwh(dentry->d_sb, name);
  4069. + if (unlikely(err))
  4070. + goto out;
  4071. +
  4072. + err = au_wh_name_alloc(&whname, name);
  4073. + if (unlikely(err))
  4074. + goto out;
  4075. +
  4076. + inode = dentry->d_inode;
  4077. + isdir = !!(inode && S_ISDIR(inode->i_mode));
  4078. + if (!type)
  4079. + au_fset_lkup(args.flags, ALLOW_NEG);
  4080. +
  4081. + npositive = 0;
  4082. + btail = au_dbtaildir(parent);
  4083. + for (bindex = bstart; bindex <= btail; bindex++) {
  4084. + struct dentry *h_parent, *h_dentry;
  4085. + struct inode *h_inode, *h_dir;
  4086. +
  4087. + h_dentry = au_h_dptr(dentry, bindex);
  4088. + if (h_dentry) {
  4089. + if (h_dentry->d_inode)
  4090. + npositive++;
  4091. + if (type != S_IFDIR)
  4092. + break;
  4093. + continue;
  4094. + }
  4095. + h_parent = au_h_dptr(parent, bindex);
  4096. + if (!h_parent)
  4097. + continue;
  4098. + h_dir = h_parent->d_inode;
  4099. + if (!h_dir || !S_ISDIR(h_dir->i_mode))
  4100. + continue;
  4101. +
  4102. + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
  4103. + h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
  4104. + &args);
  4105. + mutex_unlock(&h_dir->i_mutex);
  4106. + err = PTR_ERR(h_dentry);
  4107. + if (IS_ERR(h_dentry))
  4108. + goto out_wh;
  4109. + au_fclr_lkup(args.flags, ALLOW_NEG);
  4110. +
  4111. + if (au_dbwh(dentry) >= 0)
  4112. + break;
  4113. + if (!h_dentry)
  4114. + continue;
  4115. + h_inode = h_dentry->d_inode;
  4116. + if (!h_inode)
  4117. + continue;
  4118. + npositive++;
  4119. + if (!args.type)
  4120. + args.type = h_inode->i_mode & S_IFMT;
  4121. + if (args.type != S_IFDIR)
  4122. + break;
  4123. + else if (isdir) {
  4124. + /* the type of lower may be different */
  4125. + bdiropq = au_dbdiropq(dentry);
  4126. + if (bdiropq >= 0 && bdiropq <= bindex)
  4127. + break;
  4128. + }
  4129. + }
  4130. +
  4131. + if (npositive) {
  4132. + AuLabel(positive);
  4133. + au_update_dbstart(dentry);
  4134. + }
  4135. + err = npositive;
  4136. + if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
  4137. + && au_dbstart(dentry) < 0))
  4138. + /* both of real entry and whiteout found */
  4139. + err = -EIO;
  4140. +
  4141. + out_wh:
  4142. + kfree(whname.name);
  4143. + out:
  4144. + dput(parent);
  4145. + return err;
  4146. +}
  4147. +
  4148. +struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
  4149. + struct au_branch *br)
  4150. +{
  4151. + struct dentry *dentry;
  4152. + int wkq_err;
  4153. +
  4154. + if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC))
  4155. + dentry = au_lkup_one(name, parent, br, /*nd*/NULL);
  4156. + else {
  4157. + struct au_lkup_one_args args = {
  4158. + .errp = &dentry,
  4159. + .name = name,
  4160. + .h_parent = parent,
  4161. + .br = br,
  4162. + .nd = NULL
  4163. + };
  4164. +
  4165. + wkq_err = au_wkq_wait(au_call_lkup_one, &args);
  4166. + if (unlikely(wkq_err))
  4167. + dentry = ERR_PTR(wkq_err);
  4168. + }
  4169. +
  4170. + return dentry;
  4171. +}
  4172. +
  4173. +/*
  4174. + * lookup @dentry on @bindex which should be negative.
  4175. + */
  4176. +int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex)
  4177. +{
  4178. + int err;
  4179. + struct dentry *parent, *h_parent, *h_dentry;
  4180. + struct qstr *name;
  4181. +
  4182. + name = &dentry->d_name;
  4183. + parent = dget_parent(dentry);
  4184. + h_parent = au_h_dptr(parent, bindex);
  4185. + h_dentry = au_sio_lkup_one(name, h_parent,
  4186. + au_sbr(dentry->d_sb, bindex));
  4187. + err = PTR_ERR(h_dentry);
  4188. + if (IS_ERR(h_dentry))
  4189. + goto out;
  4190. + if (unlikely(h_dentry->d_inode)) {
  4191. + err = -EIO;
  4192. + AuIOErr("b%d %.*s should be negative.\n",
  4193. + bindex, AuDLNPair(h_dentry));
  4194. + dput(h_dentry);
  4195. + goto out;
  4196. + }
  4197. +
  4198. + if (bindex < au_dbstart(dentry))
  4199. + au_set_dbstart(dentry, bindex);
  4200. + if (au_dbend(dentry) < bindex)
  4201. + au_set_dbend(dentry, bindex);
  4202. + au_set_h_dptr(dentry, bindex, h_dentry);
  4203. + err = 0;
  4204. +
  4205. + out:
  4206. + dput(parent);
  4207. + return err;
  4208. +}
  4209. +
  4210. +/* ---------------------------------------------------------------------- */
  4211. +
  4212. +/* subset of struct inode */
  4213. +struct au_iattr {
  4214. + unsigned long i_ino;
  4215. + /* unsigned int i_nlink; */
  4216. + uid_t i_uid;
  4217. + gid_t i_gid;
  4218. + u64 i_version;
  4219. +/*
  4220. + loff_t i_size;
  4221. + blkcnt_t i_blocks;
  4222. +*/
  4223. + umode_t i_mode;
  4224. +};
  4225. +
  4226. +static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
  4227. +{
  4228. + ia->i_ino = h_inode->i_ino;
  4229. + /* ia->i_nlink = h_inode->i_nlink; */
  4230. + ia->i_uid = h_inode->i_uid;
  4231. + ia->i_gid = h_inode->i_gid;
  4232. + ia->i_version = h_inode->i_version;
  4233. +/*
  4234. + ia->i_size = h_inode->i_size;
  4235. + ia->i_blocks = h_inode->i_blocks;
  4236. +*/
  4237. + ia->i_mode = (h_inode->i_mode & S_IFMT);
  4238. +}
  4239. +
  4240. +static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
  4241. +{
  4242. + return ia->i_ino != h_inode->i_ino
  4243. + /* || ia->i_nlink != h_inode->i_nlink */
  4244. + || ia->i_uid != h_inode->i_uid
  4245. + || ia->i_gid != h_inode->i_gid
  4246. + || ia->i_version != h_inode->i_version
  4247. +/*
  4248. + || ia->i_size != h_inode->i_size
  4249. + || ia->i_blocks != h_inode->i_blocks
  4250. +*/
  4251. + || ia->i_mode != (h_inode->i_mode & S_IFMT);
  4252. +}
  4253. +
  4254. +static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
  4255. + struct au_branch *br)
  4256. +{
  4257. + int err;
  4258. + struct au_iattr ia;
  4259. + struct inode *h_inode;
  4260. + struct dentry *h_d;
  4261. + struct super_block *h_sb;
  4262. +
  4263. + err = 0;
  4264. + memset(&ia, -1, sizeof(ia));
  4265. + h_sb = h_dentry->d_sb;
  4266. + h_inode = h_dentry->d_inode;
  4267. + if (h_inode)
  4268. + au_iattr_save(&ia, h_inode);
  4269. + else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
  4270. + /* nfs d_revalidate may return 0 for negative dentry */
  4271. + /* fuse d_revalidate always return 0 for negative dentry */
  4272. + goto out;
  4273. +
  4274. + /* main purpose is namei.c:cached_lookup() and d_revalidate */
  4275. + h_d = au_lkup_one(&h_dentry->d_name, h_parent, br, /*nd*/NULL);
  4276. + err = PTR_ERR(h_d);
  4277. + if (IS_ERR(h_d))
  4278. + goto out;
  4279. +
  4280. + err = 0;
  4281. + if (unlikely(h_d != h_dentry
  4282. + || h_d->d_inode != h_inode
  4283. + || (h_inode && au_iattr_test(&ia, h_inode))))
  4284. + err = au_busy_or_stale();
  4285. + dput(h_d);
  4286. +
  4287. + out:
  4288. + AuTraceErr(err);
  4289. + return err;
  4290. +}
  4291. +
  4292. +int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
  4293. + struct dentry *h_parent, struct au_branch *br)
  4294. +{
  4295. + int err;
  4296. +
  4297. + err = 0;
  4298. + if (udba == AuOpt_UDBA_REVAL) {
  4299. + IMustLock(h_dir);
  4300. + err = (h_dentry->d_parent->d_inode != h_dir);
  4301. + } else if (udba == AuOpt_UDBA_HINOTIFY)
  4302. + err = au_h_verify_dentry(h_dentry, h_parent, br);
  4303. +
  4304. + return err;
  4305. +}
  4306. +
  4307. +/* ---------------------------------------------------------------------- */
  4308. +
  4309. +static void au_do_refresh_hdentry(struct au_hdentry *p, struct au_dinfo *dinfo,
  4310. + struct dentry *parent)
  4311. +{
  4312. + struct dentry *h_d, *h_dp;
  4313. + struct au_hdentry tmp, *q;
  4314. + struct super_block *sb;
  4315. + aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq;
  4316. +
  4317. + AuRwMustWriteLock(&dinfo->di_rwsem);
  4318. +
  4319. + bend = dinfo->di_bend;
  4320. + bwh = dinfo->di_bwh;
  4321. + bdiropq = dinfo->di_bdiropq;
  4322. + for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
  4323. + h_d = p->hd_dentry;
  4324. + if (!h_d)
  4325. + continue;
  4326. +
  4327. + h_dp = dget_parent(h_d);
  4328. + if (h_dp == au_h_dptr(parent, bindex)) {
  4329. + dput(h_dp);
  4330. + continue;
  4331. + }
  4332. +
  4333. + new_bindex = au_find_dbindex(parent, h_dp);
  4334. + dput(h_dp);
  4335. + if (dinfo->di_bwh == bindex)
  4336. + bwh = new_bindex;
  4337. + if (dinfo->di_bdiropq == bindex)
  4338. + bdiropq = new_bindex;
  4339. + if (new_bindex < 0) {
  4340. + au_hdput(p);
  4341. + p->hd_dentry = NULL;
  4342. + continue;
  4343. + }
  4344. +
  4345. + /* swap two lower dentries, and loop again */
  4346. + q = dinfo->di_hdentry + new_bindex;
  4347. + tmp = *q;
  4348. + *q = *p;
  4349. + *p = tmp;
  4350. + if (tmp.hd_dentry) {
  4351. + bindex--;
  4352. + p--;
  4353. + }
  4354. + }
  4355. +
  4356. + sb = parent->d_sb;
  4357. + dinfo->di_bwh = -1;
  4358. + if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))
  4359. + dinfo->di_bwh = bwh;
  4360. +
  4361. + dinfo->di_bdiropq = -1;
  4362. + if (bdiropq >= 0
  4363. + && bdiropq <= au_sbend(sb)
  4364. + && au_sbr_whable(sb, bdiropq))
  4365. + dinfo->di_bdiropq = bdiropq;
  4366. +
  4367. + bend = au_dbend(parent);
  4368. + p = dinfo->di_hdentry;
  4369. + for (bindex = 0; bindex <= bend; bindex++, p++)
  4370. + if (p->hd_dentry) {
  4371. + dinfo->di_bstart = bindex;
  4372. + break;
  4373. + }
  4374. +
  4375. + p = dinfo->di_hdentry + bend;
  4376. + for (bindex = bend; bindex >= 0; bindex--, p--)
  4377. + if (p->hd_dentry) {
  4378. + dinfo->di_bend = bindex;
  4379. + break;
  4380. + }
  4381. +}
  4382. +
  4383. +/*
  4384. + * returns the number of found lower positive dentries,
  4385. + * otherwise an error.
  4386. + */
  4387. +int au_refresh_hdentry(struct dentry *dentry, mode_t type)
  4388. +{
  4389. + int npositive, err;
  4390. + unsigned int sigen;
  4391. + aufs_bindex_t bstart;
  4392. + struct au_dinfo *dinfo;
  4393. + struct super_block *sb;
  4394. + struct dentry *parent;
  4395. +
  4396. + DiMustWriteLock(dentry);
  4397. +
  4398. + sb = dentry->d_sb;
  4399. + AuDebugOn(IS_ROOT(dentry));
  4400. + sigen = au_sigen(sb);
  4401. + parent = dget_parent(dentry);
  4402. + AuDebugOn(au_digen(parent) != sigen
  4403. + || au_iigen(parent->d_inode) != sigen);
  4404. +
  4405. + dinfo = au_di(dentry);
  4406. + err = au_di_realloc(dinfo, au_sbend(sb) + 1);
  4407. + npositive = err;
  4408. + if (unlikely(err))
  4409. + goto out;
  4410. + au_do_refresh_hdentry(dinfo->di_hdentry + dinfo->di_bstart, dinfo,
  4411. + parent);
  4412. +
  4413. + npositive = 0;
  4414. + bstart = au_dbstart(parent);
  4415. + if (type != S_IFDIR && dinfo->di_bstart == bstart)
  4416. + goto out_dgen; /* success */
  4417. +
  4418. + npositive = au_lkup_dentry(dentry, bstart, type, /*nd*/NULL);
  4419. + if (npositive < 0)
  4420. + goto out;
  4421. + if (dinfo->di_bwh >= 0 && dinfo->di_bwh <= dinfo->di_bstart)
  4422. + d_drop(dentry);
  4423. +
  4424. + out_dgen:
  4425. + au_update_digen(dentry);
  4426. + out:
  4427. + dput(parent);
  4428. + AuTraceErr(npositive);
  4429. + return npositive;
  4430. +}
  4431. +
  4432. +static noinline_for_stack
  4433. +int au_do_h_d_reval(struct dentry *h_dentry, struct nameidata *nd,
  4434. + struct dentry *dentry, aufs_bindex_t bindex)
  4435. +{
  4436. + int err, valid;
  4437. + int (*reval)(struct dentry *, struct nameidata *);
  4438. +
  4439. + err = 0;
  4440. + reval = NULL;
  4441. + if (h_dentry->d_op)
  4442. + reval = h_dentry->d_op->d_revalidate;
  4443. + if (!reval)
  4444. + goto out;
  4445. +
  4446. + AuDbg("b%d\n", bindex);
  4447. + if (au_test_fs_null_nd(h_dentry->d_sb))
  4448. + /* it may return tri-state */
  4449. + valid = reval(h_dentry, NULL);
  4450. + else {
  4451. + struct nameidata h_nd;
  4452. + int locked;
  4453. + struct dentry *parent;
  4454. +
  4455. + au_h_nd(&h_nd, nd);
  4456. + parent = nd->path.dentry;
  4457. + locked = (nd && nd->path.dentry != dentry);
  4458. + if (locked)
  4459. + di_read_lock_parent(parent, AuLock_IR);
  4460. + BUG_ON(bindex > au_dbend(parent));
  4461. + h_nd.path.dentry = au_h_dptr(parent, bindex);
  4462. + BUG_ON(!h_nd.path.dentry);
  4463. + h_nd.path.mnt = au_sbr(parent->d_sb, bindex)->br_mnt;
  4464. + path_get(&h_nd.path);
  4465. + valid = reval(h_dentry, &h_nd);
  4466. + path_put(&h_nd.path);
  4467. + if (locked)
  4468. + di_read_unlock(parent, AuLock_IR);
  4469. + }
  4470. +
  4471. + if (unlikely(valid < 0))
  4472. + err = valid;
  4473. + else if (!valid)
  4474. + err = -EINVAL;
  4475. +
  4476. + out:
  4477. + AuTraceErr(err);
  4478. + return err;
  4479. +}
  4480. +
  4481. +/* todo: remove this */
  4482. +static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
  4483. + struct nameidata *nd, int do_udba)
  4484. +{
  4485. + int err;
  4486. + umode_t mode, h_mode;
  4487. + aufs_bindex_t bindex, btail, bstart, ibs, ibe;
  4488. + unsigned char plus, unhashed, is_root, h_plus;
  4489. + struct inode *first, *h_inode, *h_cached_inode;
  4490. + struct dentry *h_dentry;
  4491. + struct qstr *name, *h_name;
  4492. +
  4493. + err = 0;
  4494. + plus = 0;
  4495. + mode = 0;
  4496. + first = NULL;
  4497. + ibs = -1;
  4498. + ibe = -1;
  4499. + unhashed = !!d_unhashed(dentry);
  4500. + is_root = !!IS_ROOT(dentry);
  4501. + name = &dentry->d_name;
  4502. +
  4503. + /*
  4504. + * Theoretically, REVAL test should be unnecessary in case of INOTIFY.
  4505. + * But inotify doesn't fire some necessary events,
  4506. + * IN_ATTRIB for atime/nlink/pageio
  4507. + * IN_DELETE for NFS dentry
  4508. + * Let's do REVAL test too.
  4509. + */
  4510. + if (do_udba && inode) {
  4511. + mode = (inode->i_mode & S_IFMT);
  4512. + plus = (inode->i_nlink > 0);
  4513. + first = au_h_iptr(inode, au_ibstart(inode));
  4514. + ibs = au_ibstart(inode);
  4515. + ibe = au_ibend(inode);
  4516. + }
  4517. +
  4518. + bstart = au_dbstart(dentry);
  4519. + btail = bstart;
  4520. + if (inode && S_ISDIR(inode->i_mode))
  4521. + btail = au_dbtaildir(dentry);
  4522. + for (bindex = bstart; bindex <= btail; bindex++) {
  4523. + h_dentry = au_h_dptr(dentry, bindex);
  4524. + if (!h_dentry)
  4525. + continue;
  4526. +
  4527. + AuDbg("b%d, %.*s\n", bindex, AuDLNPair(h_dentry));
  4528. + h_name = &h_dentry->d_name;
  4529. + if (unlikely(do_udba
  4530. + && !is_root
  4531. + && (unhashed != !!d_unhashed(h_dentry)
  4532. + || name->len != h_name->len
  4533. + || memcmp(name->name, h_name->name, name->len))
  4534. + )) {
  4535. + AuDbg("unhash 0x%x 0x%x, %.*s %.*s\n",
  4536. + unhashed, d_unhashed(h_dentry),
  4537. + AuDLNPair(dentry), AuDLNPair(h_dentry));
  4538. + goto err;
  4539. + }
  4540. +
  4541. + err = au_do_h_d_reval(h_dentry, nd, dentry, bindex);
  4542. + if (unlikely(err))
  4543. + /* do not goto err, to keep the errno */
  4544. + break;
  4545. +
  4546. + /* todo: plink too? */
  4547. + if (!do_udba)
  4548. + continue;
  4549. +
  4550. + /* UDBA tests */
  4551. + h_inode = h_dentry->d_inode;
  4552. + if (unlikely(!!inode != !!h_inode))
  4553. + goto err;
  4554. +
  4555. + h_plus = plus;
  4556. + h_mode = mode;
  4557. + h_cached_inode = h_inode;
  4558. + if (h_inode) {
  4559. + h_mode = (h_inode->i_mode & S_IFMT);
  4560. + h_plus = (h_inode->i_nlink > 0);
  4561. + }
  4562. + if (inode && ibs <= bindex && bindex <= ibe)
  4563. + h_cached_inode = au_h_iptr(inode, bindex);
  4564. +
  4565. + if (unlikely(plus != h_plus
  4566. + || mode != h_mode
  4567. + || h_cached_inode != h_inode))
  4568. + goto err;
  4569. + continue;
  4570. +
  4571. + err:
  4572. + err = -EINVAL;
  4573. + break;
  4574. + }
  4575. +
  4576. + return err;
  4577. +}
  4578. +
  4579. +static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
  4580. +{
  4581. + int err;
  4582. + struct dentry *parent;
  4583. + struct inode *inode;
  4584. +
  4585. + inode = dentry->d_inode;
  4586. + if (au_digen(dentry) == sigen && au_iigen(inode) == sigen)
  4587. + return 0;
  4588. +
  4589. + parent = dget_parent(dentry);
  4590. + di_read_lock_parent(parent, AuLock_IR);
  4591. + AuDebugOn(au_digen(parent) != sigen
  4592. + || au_iigen(parent->d_inode) != sigen);
  4593. + au_dbg_verify_gen(parent, sigen);
  4594. +
  4595. + /* returns a number of positive dentries */
  4596. + err = au_refresh_hdentry(dentry, inode->i_mode & S_IFMT);
  4597. + if (err >= 0)
  4598. + err = au_refresh_hinode(inode, dentry);
  4599. +
  4600. + di_read_unlock(parent, AuLock_IR);
  4601. + dput(parent);
  4602. + return err;
  4603. +}
  4604. +
  4605. +int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
  4606. +{
  4607. + int err;
  4608. + struct dentry *d, *parent;
  4609. + struct inode *inode;
  4610. +
  4611. + if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS))
  4612. + return simple_reval_dpath(dentry, sigen);
  4613. +
  4614. + /* slow loop, keep it simple and stupid */
  4615. + /* cf: au_cpup_dirs() */
  4616. + err = 0;
  4617. + parent = NULL;
  4618. + while (au_digen(dentry) != sigen
  4619. + || au_iigen(dentry->d_inode) != sigen) {
  4620. + d = dentry;
  4621. + while (1) {
  4622. + dput(parent);
  4623. + parent = dget_parent(d);
  4624. + if (au_digen(parent) == sigen
  4625. + && au_iigen(parent->d_inode) == sigen)
  4626. + break;
  4627. + d = parent;
  4628. + }
  4629. +
  4630. + inode = d->d_inode;
  4631. + if (d != dentry)
  4632. + di_write_lock_child(d);
  4633. +
  4634. + /* someone might update our dentry while we were sleeping */
  4635. + if (au_digen(d) != sigen || au_iigen(d->d_inode) != sigen) {
  4636. + di_read_lock_parent(parent, AuLock_IR);
  4637. + /* returns a number of positive dentries */
  4638. + err = au_refresh_hdentry(d, inode->i_mode & S_IFMT);
  4639. + if (err >= 0)
  4640. + err = au_refresh_hinode(inode, d);
  4641. + di_read_unlock(parent, AuLock_IR);
  4642. + }
  4643. +
  4644. + if (d != dentry)
  4645. + di_write_unlock(d);
  4646. + dput(parent);
  4647. + if (unlikely(err))
  4648. + break;
  4649. + }
  4650. +
  4651. + return err;
  4652. +}
  4653. +
  4654. +/*
  4655. + * if valid returns 1, otherwise 0.
  4656. + */
  4657. +static int aufs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
  4658. +{
  4659. + int valid, err;
  4660. + unsigned int sigen;
  4661. + unsigned char do_udba;
  4662. + struct super_block *sb;
  4663. + struct inode *inode;
  4664. +
  4665. + err = -EINVAL;
  4666. + sb = dentry->d_sb;
  4667. + inode = dentry->d_inode;
  4668. + aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW);
  4669. + sigen = au_sigen(sb);
  4670. + if (au_digen(dentry) != sigen) {
  4671. + AuDebugOn(IS_ROOT(dentry));
  4672. + if (inode)
  4673. + err = au_reval_dpath(dentry, sigen);
  4674. + if (unlikely(err))
  4675. + goto out_dgrade;
  4676. + AuDebugOn(au_digen(dentry) != sigen);
  4677. + }
  4678. + if (inode && au_iigen(inode) != sigen) {
  4679. + AuDebugOn(IS_ROOT(dentry));
  4680. + err = au_refresh_hinode(inode, dentry);
  4681. + if (unlikely(err))
  4682. + goto out_dgrade;
  4683. + AuDebugOn(au_iigen(inode) != sigen);
  4684. + }
  4685. + di_downgrade_lock(dentry, AuLock_IR);
  4686. +
  4687. + AuDebugOn(au_digen(dentry) != sigen);
  4688. + AuDebugOn(inode && au_iigen(inode) != sigen);
  4689. + err = -EINVAL;
  4690. + do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
  4691. + if (do_udba && inode) {
  4692. + aufs_bindex_t bstart = au_ibstart(inode);
  4693. +
  4694. + if (bstart >= 0
  4695. + && au_test_higen(inode, au_h_iptr(inode, bstart)))
  4696. + goto out;
  4697. + }
  4698. +
  4699. + err = h_d_revalidate(dentry, inode, nd, do_udba);
  4700. + if (unlikely(!err && do_udba && au_dbstart(dentry) < 0))
  4701. + /* both of real entry and whiteout found */
  4702. + err = -EIO;
  4703. + goto out;
  4704. +
  4705. + out_dgrade:
  4706. + di_downgrade_lock(dentry, AuLock_IR);
  4707. + out:
  4708. + au_store_oflag(nd, inode);
  4709. + aufs_read_unlock(dentry, AuLock_IR);
  4710. + AuTraceErr(err);
  4711. + valid = !err;
  4712. + if (!valid)
  4713. + AuDbg("%.*s invalid\n", AuDLNPair(dentry));
  4714. + return valid;
  4715. +}
  4716. +
  4717. +static void aufs_d_release(struct dentry *dentry)
  4718. +{
  4719. + struct au_dinfo *dinfo;
  4720. + aufs_bindex_t bend, bindex;
  4721. +
  4722. + dinfo = dentry->d_fsdata;
  4723. + if (!dinfo)
  4724. + return;
  4725. +
  4726. + /* dentry may not be revalidated */
  4727. + bindex = dinfo->di_bstart;
  4728. + if (bindex >= 0) {
  4729. + struct au_hdentry *p;
  4730. +
  4731. + bend = dinfo->di_bend;
  4732. + p = dinfo->di_hdentry + bindex;
  4733. + while (bindex++ <= bend) {
  4734. + if (p->hd_dentry)
  4735. + au_hdput(p);
  4736. + p++;
  4737. + }
  4738. + }
  4739. + kfree(dinfo->di_hdentry);
  4740. + AuRwDestroy(&dinfo->di_rwsem);
  4741. + au_cache_free_dinfo(dinfo);
  4742. + au_hin_di_reinit(dentry);
  4743. +}
  4744. +
  4745. +struct dentry_operations aufs_dop = {
  4746. + .d_revalidate = aufs_d_revalidate,
  4747. + .d_release = aufs_d_release
  4748. +};
  4749. diff -Nur linux-2.6.31.4.orig/fs/aufs/dentry.h linux-2.6.31.4/fs/aufs/dentry.h
  4750. --- linux-2.6.31.4.orig/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
  4751. +++ linux-2.6.31.4/fs/aufs/dentry.h 2009-10-18 11:26:01.000000000 +0200
  4752. @@ -0,0 +1,231 @@
  4753. +/*
  4754. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  4755. + *
  4756. + * This program, aufs is free software; you can redistribute it and/or modify
  4757. + * it under the terms of the GNU General Public License as published by
  4758. + * the Free Software Foundation; either version 2 of the License, or
  4759. + * (at your option) any later version.
  4760. + *
  4761. + * This program is distributed in the hope that it will be useful,
  4762. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4763. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4764. + * GNU General Public License for more details.
  4765. + *
  4766. + * You should have received a copy of the GNU General Public License
  4767. + * along with this program; if not, write to the Free Software
  4768. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  4769. + */
  4770. +
  4771. +/*
  4772. + * lookup and dentry operations
  4773. + */
  4774. +
  4775. +#ifndef __AUFS_DENTRY_H__
  4776. +#define __AUFS_DENTRY_H__
  4777. +
  4778. +#ifdef __KERNEL__
  4779. +
  4780. +#include <linux/dcache.h>
  4781. +#include <linux/aufs_type.h>
  4782. +#include "rwsem.h"
  4783. +
  4784. +/* make a single member structure for future use */
  4785. +/* todo: remove this structure */
  4786. +struct au_hdentry {
  4787. + struct dentry *hd_dentry;
  4788. +};
  4789. +
  4790. +struct au_dinfo {
  4791. + atomic_t di_generation;
  4792. +
  4793. + struct au_rwsem di_rwsem;
  4794. + aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq;
  4795. + struct au_hdentry *di_hdentry;
  4796. +};
  4797. +
  4798. +/* ---------------------------------------------------------------------- */
  4799. +
  4800. +/* dentry.c */
  4801. +extern struct dentry_operations aufs_dop;
  4802. +struct au_branch;
  4803. +struct dentry *au_lkup_one(struct qstr *name, struct dentry *h_parent,
  4804. + struct au_branch *br, struct nameidata *nd);
  4805. +struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
  4806. + struct au_branch *br);
  4807. +int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
  4808. + struct dentry *h_parent, struct au_branch *br);
  4809. +
  4810. +int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type,
  4811. + struct nameidata *nd);
  4812. +int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex);
  4813. +int au_refresh_hdentry(struct dentry *dentry, mode_t type);
  4814. +int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
  4815. +
  4816. +/* dinfo.c */
  4817. +int au_alloc_dinfo(struct dentry *dentry);
  4818. +int au_di_realloc(struct au_dinfo *dinfo, int nbr);
  4819. +
  4820. +void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
  4821. +void di_read_unlock(struct dentry *d, int flags);
  4822. +void di_downgrade_lock(struct dentry *d, int flags);
  4823. +void di_write_lock(struct dentry *d, unsigned int lsc);
  4824. +void di_write_unlock(struct dentry *d);
  4825. +void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
  4826. +void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
  4827. +void di_write_unlock2(struct dentry *d1, struct dentry *d2);
  4828. +
  4829. +struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
  4830. +aufs_bindex_t au_dbtail(struct dentry *dentry);
  4831. +aufs_bindex_t au_dbtaildir(struct dentry *dentry);
  4832. +
  4833. +void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
  4834. + struct dentry *h_dentry);
  4835. +void au_update_digen(struct dentry *dentry);
  4836. +void au_update_dbrange(struct dentry *dentry, int do_put_zero);
  4837. +void au_update_dbstart(struct dentry *dentry);
  4838. +void au_update_dbend(struct dentry *dentry);
  4839. +int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
  4840. +
  4841. +/* ---------------------------------------------------------------------- */
  4842. +
  4843. +static inline struct au_dinfo *au_di(struct dentry *dentry)
  4844. +{
  4845. + return dentry->d_fsdata;
  4846. +}
  4847. +
  4848. +/* ---------------------------------------------------------------------- */
  4849. +
  4850. +/* lock subclass for dinfo */
  4851. +enum {
  4852. + AuLsc_DI_CHILD, /* child first */
  4853. + AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hinotify */
  4854. + AuLsc_DI_CHILD3, /* copyup dirs */
  4855. + AuLsc_DI_PARENT,
  4856. + AuLsc_DI_PARENT2,
  4857. + AuLsc_DI_PARENT3
  4858. +};
  4859. +
  4860. +/*
  4861. + * di_read_lock_child, di_write_lock_child,
  4862. + * di_read_lock_child2, di_write_lock_child2,
  4863. + * di_read_lock_child3, di_write_lock_child3,
  4864. + * di_read_lock_parent, di_write_lock_parent,
  4865. + * di_read_lock_parent2, di_write_lock_parent2,
  4866. + * di_read_lock_parent3, di_write_lock_parent3,
  4867. + */
  4868. +#define AuReadLockFunc(name, lsc) \
  4869. +static inline void di_read_lock_##name(struct dentry *d, int flags) \
  4870. +{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
  4871. +
  4872. +#define AuWriteLockFunc(name, lsc) \
  4873. +static inline void di_write_lock_##name(struct dentry *d) \
  4874. +{ di_write_lock(d, AuLsc_DI_##lsc); }
  4875. +
  4876. +#define AuRWLockFuncs(name, lsc) \
  4877. + AuReadLockFunc(name, lsc) \
  4878. + AuWriteLockFunc(name, lsc)
  4879. +
  4880. +AuRWLockFuncs(child, CHILD);
  4881. +AuRWLockFuncs(child2, CHILD2);
  4882. +AuRWLockFuncs(child3, CHILD3);
  4883. +AuRWLockFuncs(parent, PARENT);
  4884. +AuRWLockFuncs(parent2, PARENT2);
  4885. +AuRWLockFuncs(parent3, PARENT3);
  4886. +
  4887. +#undef AuReadLockFunc
  4888. +#undef AuWriteLockFunc
  4889. +#undef AuRWLockFuncs
  4890. +
  4891. +#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
  4892. +#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
  4893. +#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
  4894. +
  4895. +/* ---------------------------------------------------------------------- */
  4896. +
  4897. +/* todo: memory barrier? */
  4898. +static inline unsigned int au_digen(struct dentry *d)
  4899. +{
  4900. + return atomic_read(&au_di(d)->di_generation);
  4901. +}
  4902. +
  4903. +static inline void au_h_dentry_init(struct au_hdentry *hdentry)
  4904. +{
  4905. + hdentry->hd_dentry = NULL;
  4906. +}
  4907. +
  4908. +static inline void au_hdput(struct au_hdentry *hd)
  4909. +{
  4910. + dput(hd->hd_dentry);
  4911. +}
  4912. +
  4913. +static inline aufs_bindex_t au_dbstart(struct dentry *dentry)
  4914. +{
  4915. + DiMustAnyLock(dentry);
  4916. + return au_di(dentry)->di_bstart;
  4917. +}
  4918. +
  4919. +static inline aufs_bindex_t au_dbend(struct dentry *dentry)
  4920. +{
  4921. + DiMustAnyLock(dentry);
  4922. + return au_di(dentry)->di_bend;
  4923. +}
  4924. +
  4925. +static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
  4926. +{
  4927. + DiMustAnyLock(dentry);
  4928. + return au_di(dentry)->di_bwh;
  4929. +}
  4930. +
  4931. +static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
  4932. +{
  4933. + DiMustAnyLock(dentry);
  4934. + return au_di(dentry)->di_bdiropq;
  4935. +}
  4936. +
  4937. +/* todo: hard/soft set? */
  4938. +static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex)
  4939. +{
  4940. + DiMustWriteLock(dentry);
  4941. + au_di(dentry)->di_bstart = bindex;
  4942. +}
  4943. +
  4944. +static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex)
  4945. +{
  4946. + DiMustWriteLock(dentry);
  4947. + au_di(dentry)->di_bend = bindex;
  4948. +}
  4949. +
  4950. +static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
  4951. +{
  4952. + DiMustWriteLock(dentry);
  4953. + /* dbwh can be outside of bstart - bend range */
  4954. + au_di(dentry)->di_bwh = bindex;
  4955. +}
  4956. +
  4957. +static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
  4958. +{
  4959. + DiMustWriteLock(dentry);
  4960. + au_di(dentry)->di_bdiropq = bindex;
  4961. +}
  4962. +
  4963. +/* ---------------------------------------------------------------------- */
  4964. +
  4965. +#ifdef CONFIG_AUFS_HINOTIFY
  4966. +static inline void au_digen_dec(struct dentry *d)
  4967. +{
  4968. + atomic_dec_return(&au_di(d)->di_generation);
  4969. +}
  4970. +
  4971. +static inline void au_hin_di_reinit(struct dentry *dentry)
  4972. +{
  4973. + dentry->d_fsdata = NULL;
  4974. +}
  4975. +#else
  4976. +static inline void au_hin_di_reinit(struct dentry *dentry __maybe_unused)
  4977. +{
  4978. + /* empty */
  4979. +}
  4980. +#endif /* CONFIG_AUFS_HINOTIFY */
  4981. +
  4982. +#endif /* __KERNEL__ */
  4983. +#endif /* __AUFS_DENTRY_H__ */
  4984. diff -Nur linux-2.6.31.4.orig/fs/aufs/dinfo.c linux-2.6.31.4/fs/aufs/dinfo.c
  4985. --- linux-2.6.31.4.orig/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100
  4986. +++ linux-2.6.31.4/fs/aufs/dinfo.c 2009-10-18 11:26:01.000000000 +0200
  4987. @@ -0,0 +1,367 @@
  4988. +/*
  4989. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  4990. + *
  4991. + * This program, aufs is free software; you can redistribute it and/or modify
  4992. + * it under the terms of the GNU General Public License as published by
  4993. + * the Free Software Foundation; either version 2 of the License, or
  4994. + * (at your option) any later version.
  4995. + *
  4996. + * This program is distributed in the hope that it will be useful,
  4997. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4998. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4999. + * GNU General Public License for more details.
  5000. + *
  5001. + * You should have received a copy of the GNU General Public License
  5002. + * along with this program; if not, write to the Free Software
  5003. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  5004. + */
  5005. +
  5006. +/*
  5007. + * dentry private data
  5008. + */
  5009. +
  5010. +#include "aufs.h"
  5011. +
  5012. +int au_alloc_dinfo(struct dentry *dentry)
  5013. +{
  5014. + struct au_dinfo *dinfo;
  5015. + struct super_block *sb;
  5016. + int nbr;
  5017. +
  5018. + dinfo = au_cache_alloc_dinfo();
  5019. + if (unlikely(!dinfo))
  5020. + goto out;
  5021. +
  5022. + sb = dentry->d_sb;
  5023. + nbr = au_sbend(sb) + 1;
  5024. + if (nbr <= 0)
  5025. + nbr = 1;
  5026. + dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
  5027. + if (unlikely(!dinfo->di_hdentry))
  5028. + goto out_dinfo;
  5029. +
  5030. + atomic_set(&dinfo->di_generation, au_sigen(sb));
  5031. + /* smp_mb(); */ /* atomic_set */
  5032. + au_rw_init_wlock_nested(&dinfo->di_rwsem, AuLsc_DI_CHILD);
  5033. + dinfo->di_bstart = -1;
  5034. + dinfo->di_bend = -1;
  5035. + dinfo->di_bwh = -1;
  5036. + dinfo->di_bdiropq = -1;
  5037. +
  5038. + dentry->d_fsdata = dinfo;
  5039. + dentry->d_op = &aufs_dop;
  5040. + return 0; /* success */
  5041. +
  5042. + out_dinfo:
  5043. + au_cache_free_dinfo(dinfo);
  5044. + out:
  5045. + return -ENOMEM;
  5046. +}
  5047. +
  5048. +int au_di_realloc(struct au_dinfo *dinfo, int nbr)
  5049. +{
  5050. + int err, sz;
  5051. + struct au_hdentry *hdp;
  5052. +
  5053. + AuRwMustWriteLock(&dinfo->di_rwsem);
  5054. +
  5055. + err = -ENOMEM;
  5056. + sz = sizeof(*hdp) * (dinfo->di_bend + 1);
  5057. + if (!sz)
  5058. + sz = sizeof(*hdp);
  5059. + hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS);
  5060. + if (hdp) {
  5061. + dinfo->di_hdentry = hdp;
  5062. + err = 0;
  5063. + }
  5064. +
  5065. + return err;
  5066. +}
  5067. +
  5068. +/* ---------------------------------------------------------------------- */
  5069. +
  5070. +static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
  5071. +{
  5072. + switch (lsc) {
  5073. + case AuLsc_DI_CHILD:
  5074. + ii_write_lock_child(inode);
  5075. + break;
  5076. + case AuLsc_DI_CHILD2:
  5077. + ii_write_lock_child2(inode);
  5078. + break;
  5079. + case AuLsc_DI_CHILD3:
  5080. + ii_write_lock_child3(inode);
  5081. + break;
  5082. + case AuLsc_DI_PARENT:
  5083. + ii_write_lock_parent(inode);
  5084. + break;
  5085. + case AuLsc_DI_PARENT2:
  5086. + ii_write_lock_parent2(inode);
  5087. + break;
  5088. + case AuLsc_DI_PARENT3:
  5089. + ii_write_lock_parent3(inode);
  5090. + break;
  5091. + default:
  5092. + BUG();
  5093. + }
  5094. +}
  5095. +
  5096. +static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
  5097. +{
  5098. + switch (lsc) {
  5099. + case AuLsc_DI_CHILD:
  5100. + ii_read_lock_child(inode);
  5101. + break;
  5102. + case AuLsc_DI_CHILD2:
  5103. + ii_read_lock_child2(inode);
  5104. + break;
  5105. + case AuLsc_DI_CHILD3:
  5106. + ii_read_lock_child3(inode);
  5107. + break;
  5108. + case AuLsc_DI_PARENT:
  5109. + ii_read_lock_parent(inode);
  5110. + break;
  5111. + case AuLsc_DI_PARENT2:
  5112. + ii_read_lock_parent2(inode);
  5113. + break;
  5114. + case AuLsc_DI_PARENT3:
  5115. + ii_read_lock_parent3(inode);
  5116. + break;
  5117. + default:
  5118. + BUG();
  5119. + }
  5120. +}
  5121. +
  5122. +void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
  5123. +{
  5124. + au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
  5125. + if (d->d_inode) {
  5126. + if (au_ftest_lock(flags, IW))
  5127. + do_ii_write_lock(d->d_inode, lsc);
  5128. + else if (au_ftest_lock(flags, IR))
  5129. + do_ii_read_lock(d->d_inode, lsc);
  5130. + }
  5131. +}
  5132. +
  5133. +void di_read_unlock(struct dentry *d, int flags)
  5134. +{
  5135. + if (d->d_inode) {
  5136. + if (au_ftest_lock(flags, IW))
  5137. + ii_write_unlock(d->d_inode);
  5138. + else if (au_ftest_lock(flags, IR))
  5139. + ii_read_unlock(d->d_inode);
  5140. + }
  5141. + au_rw_read_unlock(&au_di(d)->di_rwsem);
  5142. +}
  5143. +
  5144. +void di_downgrade_lock(struct dentry *d, int flags)
  5145. +{
  5146. + if (d->d_inode && au_ftest_lock(flags, IR))
  5147. + ii_downgrade_lock(d->d_inode);
  5148. + au_rw_dgrade_lock(&au_di(d)->di_rwsem);
  5149. +}
  5150. +
  5151. +void di_write_lock(struct dentry *d, unsigned int lsc)
  5152. +{
  5153. + au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
  5154. + if (d->d_inode)
  5155. + do_ii_write_lock(d->d_inode, lsc);
  5156. +}
  5157. +
  5158. +void di_write_unlock(struct dentry *d)
  5159. +{
  5160. + if (d->d_inode)
  5161. + ii_write_unlock(d->d_inode);
  5162. + au_rw_write_unlock(&au_di(d)->di_rwsem);
  5163. +}
  5164. +
  5165. +void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
  5166. +{
  5167. + AuDebugOn(d1 == d2
  5168. + || d1->d_inode == d2->d_inode
  5169. + || d1->d_sb != d2->d_sb);
  5170. +
  5171. + if (isdir && au_test_subdir(d1, d2)) {
  5172. + di_write_lock_child(d1);
  5173. + di_write_lock_child2(d2);
  5174. + } else {
  5175. + /* there should be no races */
  5176. + di_write_lock_child(d2);
  5177. + di_write_lock_child2(d1);
  5178. + }
  5179. +}
  5180. +
  5181. +void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
  5182. +{
  5183. + AuDebugOn(d1 == d2
  5184. + || d1->d_inode == d2->d_inode
  5185. + || d1->d_sb != d2->d_sb);
  5186. +
  5187. + if (isdir && au_test_subdir(d1, d2)) {
  5188. + di_write_lock_parent(d1);
  5189. + di_write_lock_parent2(d2);
  5190. + } else {
  5191. + /* there should be no races */
  5192. + di_write_lock_parent(d2);
  5193. + di_write_lock_parent2(d1);
  5194. + }
  5195. +}
  5196. +
  5197. +void di_write_unlock2(struct dentry *d1, struct dentry *d2)
  5198. +{
  5199. + di_write_unlock(d1);
  5200. + if (d1->d_inode == d2->d_inode)
  5201. + au_rw_write_unlock(&au_di(d2)->di_rwsem);
  5202. + else
  5203. + di_write_unlock(d2);
  5204. +}
  5205. +
  5206. +/* ---------------------------------------------------------------------- */
  5207. +
  5208. +struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
  5209. +{
  5210. + struct dentry *d;
  5211. +
  5212. + DiMustAnyLock(dentry);
  5213. +
  5214. + if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
  5215. + return NULL;
  5216. + AuDebugOn(bindex < 0);
  5217. + d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry;
  5218. + AuDebugOn(d && (atomic_read(&d->d_count) <= 0));
  5219. + return d;
  5220. +}
  5221. +
  5222. +aufs_bindex_t au_dbtail(struct dentry *dentry)
  5223. +{
  5224. + aufs_bindex_t bend, bwh;
  5225. +
  5226. + bend = au_dbend(dentry);
  5227. + if (0 <= bend) {
  5228. + bwh = au_dbwh(dentry);
  5229. + if (!bwh)
  5230. + return bwh;
  5231. + if (0 < bwh && bwh < bend)
  5232. + return bwh - 1;
  5233. + }
  5234. + return bend;
  5235. +}
  5236. +
  5237. +aufs_bindex_t au_dbtaildir(struct dentry *dentry)
  5238. +{
  5239. + aufs_bindex_t bend, bopq;
  5240. +
  5241. + bend = au_dbtail(dentry);
  5242. + if (0 <= bend) {
  5243. + bopq = au_dbdiropq(dentry);
  5244. + if (0 <= bopq && bopq < bend)
  5245. + bend = bopq;
  5246. + }
  5247. + return bend;
  5248. +}
  5249. +
  5250. +/* ---------------------------------------------------------------------- */
  5251. +
  5252. +void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
  5253. + struct dentry *h_dentry)
  5254. +{
  5255. + struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
  5256. +
  5257. + DiMustWriteLock(dentry);
  5258. +
  5259. + if (hd->hd_dentry)
  5260. + au_hdput(hd);
  5261. + hd->hd_dentry = h_dentry;
  5262. +}
  5263. +
  5264. +void au_update_digen(struct dentry *dentry)
  5265. +{
  5266. + atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
  5267. + /* smp_mb(); */ /* atomic_set */
  5268. +}
  5269. +
  5270. +void au_update_dbrange(struct dentry *dentry, int do_put_zero)
  5271. +{
  5272. + struct au_dinfo *dinfo;
  5273. + struct dentry *h_d;
  5274. +
  5275. + DiMustWriteLock(dentry);
  5276. +
  5277. + dinfo = au_di(dentry);
  5278. + if (!dinfo || dinfo->di_bstart < 0)
  5279. + return;
  5280. +
  5281. + if (do_put_zero) {
  5282. + aufs_bindex_t bindex, bend;
  5283. +
  5284. + bend = dinfo->di_bend;
  5285. + for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) {
  5286. + h_d = dinfo->di_hdentry[0 + bindex].hd_dentry;
  5287. + if (h_d && !h_d->d_inode)
  5288. + au_set_h_dptr(dentry, bindex, NULL);
  5289. + }
  5290. + }
  5291. +
  5292. + dinfo->di_bstart = -1;
  5293. + while (++dinfo->di_bstart <= dinfo->di_bend)
  5294. + if (dinfo->di_hdentry[0 + dinfo->di_bstart].hd_dentry)
  5295. + break;
  5296. + if (dinfo->di_bstart > dinfo->di_bend) {
  5297. + dinfo->di_bstart = -1;
  5298. + dinfo->di_bend = -1;
  5299. + return;
  5300. + }
  5301. +
  5302. + dinfo->di_bend++;
  5303. + while (0 <= --dinfo->di_bend)
  5304. + if (dinfo->di_hdentry[0 + dinfo->di_bend].hd_dentry)
  5305. + break;
  5306. + AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0);
  5307. +}
  5308. +
  5309. +void au_update_dbstart(struct dentry *dentry)
  5310. +{
  5311. + aufs_bindex_t bindex, bend;
  5312. + struct dentry *h_dentry;
  5313. +
  5314. + bend = au_dbend(dentry);
  5315. + for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
  5316. + h_dentry = au_h_dptr(dentry, bindex);
  5317. + if (!h_dentry)
  5318. + continue;
  5319. + if (h_dentry->d_inode) {
  5320. + au_set_dbstart(dentry, bindex);
  5321. + return;
  5322. + }
  5323. + au_set_h_dptr(dentry, bindex, NULL);
  5324. + }
  5325. +}
  5326. +
  5327. +void au_update_dbend(struct dentry *dentry)
  5328. +{
  5329. + aufs_bindex_t bindex, bstart;
  5330. + struct dentry *h_dentry;
  5331. +
  5332. + bstart = au_dbstart(dentry);
  5333. + for (bindex = au_dbend(dentry); bindex <= bstart; bindex--) {
  5334. + h_dentry = au_h_dptr(dentry, bindex);
  5335. + if (!h_dentry)
  5336. + continue;
  5337. + if (h_dentry->d_inode) {
  5338. + au_set_dbend(dentry, bindex);
  5339. + return;
  5340. + }
  5341. + au_set_h_dptr(dentry, bindex, NULL);
  5342. + }
  5343. +}
  5344. +
  5345. +int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
  5346. +{
  5347. + aufs_bindex_t bindex, bend;
  5348. +
  5349. + bend = au_dbend(dentry);
  5350. + for (bindex = au_dbstart(dentry); bindex <= bend; bindex++)
  5351. + if (au_h_dptr(dentry, bindex) == h_dentry)
  5352. + return bindex;
  5353. + return -1;
  5354. +}
  5355. diff -Nur linux-2.6.31.4.orig/fs/aufs/dir.c linux-2.6.31.4/fs/aufs/dir.c
  5356. --- linux-2.6.31.4.orig/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
  5357. +++ linux-2.6.31.4/fs/aufs/dir.c 2009-10-18 11:26:01.000000000 +0200
  5358. @@ -0,0 +1,538 @@
  5359. +/*
  5360. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  5361. + *
  5362. + * This program, aufs is free software; you can redistribute it and/or modify
  5363. + * it under the terms of the GNU General Public License as published by
  5364. + * the Free Software Foundation; either version 2 of the License, or
  5365. + * (at your option) any later version.
  5366. + *
  5367. + * This program is distributed in the hope that it will be useful,
  5368. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  5369. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  5370. + * GNU General Public License for more details.
  5371. + *
  5372. + * You should have received a copy of the GNU General Public License
  5373. + * along with this program; if not, write to the Free Software
  5374. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  5375. + */
  5376. +
  5377. +/*
  5378. + * directory operations
  5379. + */
  5380. +
  5381. +#include <linux/file.h>
  5382. +#include <linux/fs_stack.h>
  5383. +#include "aufs.h"
  5384. +
  5385. +void au_add_nlink(struct inode *dir, struct inode *h_dir)
  5386. +{
  5387. + AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
  5388. +
  5389. + dir->i_nlink += h_dir->i_nlink - 2;
  5390. + if (h_dir->i_nlink < 2)
  5391. + dir->i_nlink += 2;
  5392. +}
  5393. +
  5394. +void au_sub_nlink(struct inode *dir, struct inode *h_dir)
  5395. +{
  5396. + AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
  5397. +
  5398. + dir->i_nlink -= h_dir->i_nlink - 2;
  5399. + if (h_dir->i_nlink < 2)
  5400. + dir->i_nlink -= 2;
  5401. +}
  5402. +
  5403. +/* ---------------------------------------------------------------------- */
  5404. +
  5405. +static int reopen_dir(struct file *file)
  5406. +{
  5407. + int err;
  5408. + unsigned int flags;
  5409. + aufs_bindex_t bindex, btail, bstart;
  5410. + struct dentry *dentry, *h_dentry;
  5411. + struct file *h_file;
  5412. +
  5413. + /* open all lower dirs */
  5414. + dentry = file->f_dentry;
  5415. + bstart = au_dbstart(dentry);
  5416. + for (bindex = au_fbstart(file); bindex < bstart; bindex++)
  5417. + au_set_h_fptr(file, bindex, NULL);
  5418. + au_set_fbstart(file, bstart);
  5419. +
  5420. + btail = au_dbtaildir(dentry);
  5421. + for (bindex = au_fbend(file); btail < bindex; bindex--)
  5422. + au_set_h_fptr(file, bindex, NULL);
  5423. + au_set_fbend(file, btail);
  5424. +
  5425. + flags = file->f_flags;
  5426. + for (bindex = bstart; bindex <= btail; bindex++) {
  5427. + h_dentry = au_h_dptr(dentry, bindex);
  5428. + if (!h_dentry)
  5429. + continue;
  5430. + h_file = au_h_fptr(file, bindex);
  5431. + if (h_file)
  5432. + continue;
  5433. +
  5434. + h_file = au_h_open(dentry, bindex, flags, file);
  5435. + err = PTR_ERR(h_file);
  5436. + if (IS_ERR(h_file))
  5437. + goto out; /* close all? */
  5438. + au_set_h_fptr(file, bindex, h_file);
  5439. + }
  5440. + au_update_figen(file);
  5441. + /* todo: necessary? */
  5442. + /* file->f_ra = h_file->f_ra; */
  5443. + err = 0;
  5444. +
  5445. + out:
  5446. + return err;
  5447. +}
  5448. +
  5449. +static int do_open_dir(struct file *file, int flags)
  5450. +{
  5451. + int err;
  5452. + aufs_bindex_t bindex, btail;
  5453. + struct dentry *dentry, *h_dentry;
  5454. + struct file *h_file;
  5455. +
  5456. + FiMustWriteLock(file);
  5457. +
  5458. + err = 0;
  5459. + dentry = file->f_dentry;
  5460. + au_set_fvdir_cache(file, NULL);
  5461. + au_fi(file)->fi_maintain_plink = 0;
  5462. + file->f_version = dentry->d_inode->i_version;
  5463. + bindex = au_dbstart(dentry);
  5464. + au_set_fbstart(file, bindex);
  5465. + btail = au_dbtaildir(dentry);
  5466. + au_set_fbend(file, btail);
  5467. + for (; !err && bindex <= btail; bindex++) {
  5468. + h_dentry = au_h_dptr(dentry, bindex);
  5469. + if (!h_dentry)
  5470. + continue;
  5471. +
  5472. + h_file = au_h_open(dentry, bindex, flags, file);
  5473. + if (IS_ERR(h_file)) {
  5474. + err = PTR_ERR(h_file);
  5475. + break;
  5476. + }
  5477. + au_set_h_fptr(file, bindex, h_file);
  5478. + }
  5479. + au_update_figen(file);
  5480. + /* todo: necessary? */
  5481. + /* file->f_ra = h_file->f_ra; */
  5482. + if (!err)
  5483. + return 0; /* success */
  5484. +
  5485. + /* close all */
  5486. + for (bindex = au_fbstart(file); bindex <= btail; bindex++)
  5487. + au_set_h_fptr(file, bindex, NULL);
  5488. + au_set_fbstart(file, -1);
  5489. + au_set_fbend(file, -1);
  5490. + return err;
  5491. +}
  5492. +
  5493. +static int aufs_open_dir(struct inode *inode __maybe_unused,
  5494. + struct file *file)
  5495. +{
  5496. + return au_do_open(file, do_open_dir);
  5497. +}
  5498. +
  5499. +static int aufs_release_dir(struct inode *inode __maybe_unused,
  5500. + struct file *file)
  5501. +{
  5502. + struct au_vdir *vdir_cache;
  5503. + struct super_block *sb;
  5504. + struct au_sbinfo *sbinfo;
  5505. +
  5506. + sb = file->f_dentry->d_sb;
  5507. + si_noflush_read_lock(sb);
  5508. + fi_write_lock(file);
  5509. + vdir_cache = au_fvdir_cache(file);
  5510. + if (vdir_cache)
  5511. + au_vdir_free(vdir_cache);
  5512. + if (au_fi(file)->fi_maintain_plink) {
  5513. + sbinfo = au_sbi(sb);
  5514. + /* clear the flag without write-lock */
  5515. + sbinfo->au_si_status &= ~AuSi_MAINTAIN_PLINK;
  5516. + smp_mb();
  5517. + wake_up_all(&sbinfo->si_plink_wq);
  5518. + }
  5519. + fi_write_unlock(file);
  5520. + au_finfo_fin(file);
  5521. + si_read_unlock(sb);
  5522. + return 0;
  5523. +}
  5524. +
  5525. +/* ---------------------------------------------------------------------- */
  5526. +
  5527. +static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
  5528. +{
  5529. + int err;
  5530. + aufs_bindex_t bend, bindex;
  5531. + struct inode *inode;
  5532. + struct super_block *sb;
  5533. +
  5534. + err = 0;
  5535. + sb = dentry->d_sb;
  5536. + inode = dentry->d_inode;
  5537. + IMustLock(inode);
  5538. + bend = au_dbend(dentry);
  5539. + for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) {
  5540. + struct path h_path;
  5541. + struct inode *h_inode;
  5542. +
  5543. + if (au_test_ro(sb, bindex, inode))
  5544. + continue;
  5545. + h_path.dentry = au_h_dptr(dentry, bindex);
  5546. + if (!h_path.dentry)
  5547. + continue;
  5548. + h_inode = h_path.dentry->d_inode;
  5549. + if (!h_inode)
  5550. + continue;
  5551. +
  5552. + /* no mnt_want_write() */
  5553. + /* cf. fs/nsfd/vfs.c and fs/nfsd/nfs4recover.c */
  5554. + /* todo: inotiry fired? */
  5555. + h_path.mnt = au_sbr_mnt(sb, bindex);
  5556. + mutex_lock(&h_inode->i_mutex);
  5557. + err = filemap_fdatawrite(h_inode->i_mapping);
  5558. + AuDebugOn(!h_inode->i_fop);
  5559. + if (!err && h_inode->i_fop->fsync)
  5560. + err = h_inode->i_fop->fsync(NULL, h_path.dentry,
  5561. + datasync);
  5562. + if (!err)
  5563. + err = filemap_fdatawrite(h_inode->i_mapping);
  5564. + if (!err)
  5565. + vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
  5566. + mutex_unlock(&h_inode->i_mutex);
  5567. + }
  5568. +
  5569. + return err;
  5570. +}
  5571. +
  5572. +static int au_do_fsync_dir(struct file *file, int datasync)
  5573. +{
  5574. + int err;
  5575. + aufs_bindex_t bend, bindex;
  5576. + struct file *h_file;
  5577. + struct super_block *sb;
  5578. + struct inode *inode;
  5579. + struct mutex *h_mtx;
  5580. +
  5581. + err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
  5582. + if (unlikely(err))
  5583. + goto out;
  5584. +
  5585. + sb = file->f_dentry->d_sb;
  5586. + inode = file->f_dentry->d_inode;
  5587. + bend = au_fbend(file);
  5588. + for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
  5589. + h_file = au_h_fptr(file, bindex);
  5590. + if (!h_file || au_test_ro(sb, bindex, inode))
  5591. + continue;
  5592. +
  5593. + err = vfs_fsync(h_file, h_file->f_dentry, datasync);
  5594. + if (!err) {
  5595. + h_mtx = &h_file->f_dentry->d_inode->i_mutex;
  5596. + mutex_lock(h_mtx);
  5597. + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
  5598. + /*ignore*/
  5599. + mutex_unlock(h_mtx);
  5600. + }
  5601. + }
  5602. +
  5603. + out:
  5604. + return err;
  5605. +}
  5606. +
  5607. +/*
  5608. + * @file may be NULL
  5609. + */
  5610. +static int aufs_fsync_dir(struct file *file, struct dentry *dentry,
  5611. + int datasync)
  5612. +{
  5613. + int err;
  5614. + struct super_block *sb;
  5615. +
  5616. + IMustLock(dentry->d_inode);
  5617. +
  5618. + err = 0;
  5619. + sb = dentry->d_sb;
  5620. + si_noflush_read_lock(sb);
  5621. + if (file)
  5622. + err = au_do_fsync_dir(file, datasync);
  5623. + else {
  5624. + di_write_lock_child(dentry);
  5625. + err = au_do_fsync_dir_no_file(dentry, datasync);
  5626. + }
  5627. + au_cpup_attr_timesizes(dentry->d_inode);
  5628. + di_write_unlock(dentry);
  5629. + if (file)
  5630. + fi_write_unlock(file);
  5631. +
  5632. + si_read_unlock(sb);
  5633. + return err;
  5634. +}
  5635. +
  5636. +/* ---------------------------------------------------------------------- */
  5637. +
  5638. +static int aufs_readdir(struct file *file, void *dirent, filldir_t filldir)
  5639. +{
  5640. + int err;
  5641. + struct dentry *dentry;
  5642. + struct inode *inode;
  5643. + struct super_block *sb;
  5644. +
  5645. + dentry = file->f_dentry;
  5646. + inode = dentry->d_inode;
  5647. + IMustLock(inode);
  5648. +
  5649. + sb = dentry->d_sb;
  5650. + si_read_lock(sb, AuLock_FLUSH);
  5651. + err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
  5652. + if (unlikely(err))
  5653. + goto out;
  5654. + err = au_vdir_init(file);
  5655. + di_downgrade_lock(dentry, AuLock_IR);
  5656. + if (unlikely(err))
  5657. + goto out_unlock;
  5658. +
  5659. + if (!au_test_nfsd(current)) {
  5660. + err = au_vdir_fill_de(file, dirent, filldir);
  5661. + fsstack_copy_attr_atime(inode,
  5662. + au_h_iptr(inode, au_ibstart(inode)));
  5663. + } else {
  5664. + /*
  5665. + * nfsd filldir may call lookup_one_len(), vfs_getattr(),
  5666. + * encode_fh() and others.
  5667. + */
  5668. + struct inode *h_inode = au_h_iptr(inode, au_ibstart(inode));
  5669. +
  5670. + di_read_unlock(dentry, AuLock_IR);
  5671. + si_read_unlock(sb);
  5672. + lockdep_off();
  5673. + err = au_vdir_fill_de(file, dirent, filldir);
  5674. + lockdep_on();
  5675. + fsstack_copy_attr_atime(inode, h_inode);
  5676. + fi_write_unlock(file);
  5677. +
  5678. + AuTraceErr(err);
  5679. + return err;
  5680. + }
  5681. +
  5682. + out_unlock:
  5683. + di_read_unlock(dentry, AuLock_IR);
  5684. + fi_write_unlock(file);
  5685. + out:
  5686. + si_read_unlock(sb);
  5687. + return err;
  5688. +}
  5689. +
  5690. +/* ---------------------------------------------------------------------- */
  5691. +
  5692. +#define AuTestEmpty_WHONLY 1
  5693. +#define AuTestEmpty_CALLED (1 << 1)
  5694. +#define AuTestEmpty_SHWH (1 << 2)
  5695. +#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
  5696. +#define au_fset_testempty(flags, name) { (flags) |= AuTestEmpty_##name; }
  5697. +#define au_fclr_testempty(flags, name) { (flags) &= ~AuTestEmpty_##name; }
  5698. +
  5699. +#ifndef CONFIG_AUFS_SHWH
  5700. +#undef AuTestEmpty_SHWH
  5701. +#define AuTestEmpty_SHWH 0
  5702. +#endif
  5703. +
  5704. +struct test_empty_arg {
  5705. + struct au_nhash whlist;
  5706. + unsigned int flags;
  5707. + int err;
  5708. + aufs_bindex_t bindex;
  5709. +};
  5710. +
  5711. +static int test_empty_cb(void *__arg, const char *__name, int namelen,
  5712. + loff_t offset __maybe_unused, u64 ino,
  5713. + unsigned int d_type)
  5714. +{
  5715. + struct test_empty_arg *arg = __arg;
  5716. + char *name = (void *)__name;
  5717. +
  5718. + arg->err = 0;
  5719. + au_fset_testempty(arg->flags, CALLED);
  5720. + /* smp_mb(); */
  5721. + if (name[0] == '.'
  5722. + && (namelen == 1 || (name[1] == '.' && namelen == 2)))
  5723. + goto out; /* success */
  5724. +
  5725. + if (namelen <= AUFS_WH_PFX_LEN
  5726. + || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
  5727. + if (au_ftest_testempty(arg->flags, WHONLY)
  5728. + && !au_nhash_test_known_wh(&arg->whlist, name, namelen))
  5729. + arg->err = -ENOTEMPTY;
  5730. + goto out;
  5731. + }
  5732. +
  5733. + name += AUFS_WH_PFX_LEN;
  5734. + namelen -= AUFS_WH_PFX_LEN;
  5735. + if (!au_nhash_test_known_wh(&arg->whlist, name, namelen))
  5736. + arg->err = au_nhash_append_wh
  5737. + (&arg->whlist, name, namelen, ino, d_type, arg->bindex,
  5738. + au_ftest_testempty(arg->flags, SHWH));
  5739. +
  5740. + out:
  5741. + /* smp_mb(); */
  5742. + AuTraceErr(arg->err);
  5743. + return arg->err;
  5744. +}
  5745. +
  5746. +static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
  5747. +{
  5748. + int err;
  5749. + struct file *h_file;
  5750. +
  5751. + h_file = au_h_open(dentry, arg->bindex,
  5752. + O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
  5753. + /*file*/NULL);
  5754. + err = PTR_ERR(h_file);
  5755. + if (IS_ERR(h_file))
  5756. + goto out;
  5757. +
  5758. + err = 0;
  5759. + if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
  5760. + && !h_file->f_dentry->d_inode->i_nlink)
  5761. + goto out_put;
  5762. +
  5763. + do {
  5764. + arg->err = 0;
  5765. + au_fclr_testempty(arg->flags, CALLED);
  5766. + /* smp_mb(); */
  5767. + err = vfsub_readdir(h_file, test_empty_cb, arg);
  5768. + if (err >= 0)
  5769. + err = arg->err;
  5770. + } while (!err && au_ftest_testempty(arg->flags, CALLED));
  5771. +
  5772. + out_put:
  5773. + fput(h_file);
  5774. + au_sbr_put(dentry->d_sb, arg->bindex);
  5775. + out:
  5776. + return err;
  5777. +}
  5778. +
  5779. +struct do_test_empty_args {
  5780. + int *errp;
  5781. + struct dentry *dentry;
  5782. + struct test_empty_arg *arg;
  5783. +};
  5784. +
  5785. +static void call_do_test_empty(void *args)
  5786. +{
  5787. + struct do_test_empty_args *a = args;
  5788. + *a->errp = do_test_empty(a->dentry, a->arg);
  5789. +}
  5790. +
  5791. +static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
  5792. +{
  5793. + int err, wkq_err;
  5794. + struct dentry *h_dentry;
  5795. + struct inode *h_inode;
  5796. +
  5797. + h_dentry = au_h_dptr(dentry, arg->bindex);
  5798. + h_inode = h_dentry->d_inode;
  5799. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  5800. + err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
  5801. + mutex_unlock(&h_inode->i_mutex);
  5802. + if (!err)
  5803. + err = do_test_empty(dentry, arg);
  5804. + else {
  5805. + struct do_test_empty_args args = {
  5806. + .errp = &err,
  5807. + .dentry = dentry,
  5808. + .arg = arg
  5809. + };
  5810. + unsigned int flags = arg->flags;
  5811. +
  5812. + wkq_err = au_wkq_wait(call_do_test_empty, &args);
  5813. + if (unlikely(wkq_err))
  5814. + err = wkq_err;
  5815. + arg->flags = flags;
  5816. + }
  5817. +
  5818. + return err;
  5819. +}
  5820. +
  5821. +int au_test_empty_lower(struct dentry *dentry)
  5822. +{
  5823. + int err;
  5824. + aufs_bindex_t bindex, bstart, btail;
  5825. + struct test_empty_arg arg;
  5826. +
  5827. + SiMustAnyLock(dentry->d_sb);
  5828. +
  5829. + err = au_nhash_alloc(&arg.whlist, au_sbi(dentry->d_sb)->si_rdhash,
  5830. + GFP_NOFS);
  5831. + if (unlikely(err))
  5832. + goto out;
  5833. +
  5834. + bstart = au_dbstart(dentry);
  5835. + arg.flags = 0;
  5836. + if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
  5837. + au_fset_testempty(arg.flags, SHWH);
  5838. + arg.bindex = bstart;
  5839. + err = do_test_empty(dentry, &arg);
  5840. + if (unlikely(err))
  5841. + goto out_whlist;
  5842. +
  5843. + au_fset_testempty(arg.flags, WHONLY);
  5844. + btail = au_dbtaildir(dentry);
  5845. + for (bindex = bstart + 1; !err && bindex <= btail; bindex++) {
  5846. + struct dentry *h_dentry;
  5847. +
  5848. + h_dentry = au_h_dptr(dentry, bindex);
  5849. + if (h_dentry && h_dentry->d_inode) {
  5850. + arg.bindex = bindex;
  5851. + err = do_test_empty(dentry, &arg);
  5852. + }
  5853. + }
  5854. +
  5855. + out_whlist:
  5856. + au_nhash_wh_free(&arg.whlist);
  5857. + out:
  5858. + return err;
  5859. +}
  5860. +
  5861. +int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
  5862. +{
  5863. + int err;
  5864. + struct test_empty_arg arg;
  5865. + aufs_bindex_t bindex, btail;
  5866. +
  5867. + err = 0;
  5868. + arg.whlist = *whlist;
  5869. + arg.flags = AuTestEmpty_WHONLY;
  5870. + if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
  5871. + au_fset_testempty(arg.flags, SHWH);
  5872. + btail = au_dbtaildir(dentry);
  5873. + for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) {
  5874. + struct dentry *h_dentry;
  5875. +
  5876. + h_dentry = au_h_dptr(dentry, bindex);
  5877. + if (h_dentry && h_dentry->d_inode) {
  5878. + arg.bindex = bindex;
  5879. + err = sio_test_empty(dentry, &arg);
  5880. + }
  5881. + }
  5882. +
  5883. + return err;
  5884. +}
  5885. +
  5886. +/* ---------------------------------------------------------------------- */
  5887. +
  5888. +const struct file_operations aufs_dir_fop = {
  5889. + .read = generic_read_dir,
  5890. + .readdir = aufs_readdir,
  5891. + .unlocked_ioctl = aufs_ioctl_dir,
  5892. + .open = aufs_open_dir,
  5893. + .release = aufs_release_dir,
  5894. + .flush = aufs_flush,
  5895. + .fsync = aufs_fsync_dir
  5896. +};
  5897. diff -Nur linux-2.6.31.4.orig/fs/aufs/dir.h linux-2.6.31.4/fs/aufs/dir.h
  5898. --- linux-2.6.31.4.orig/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100
  5899. +++ linux-2.6.31.4/fs/aufs/dir.h 2009-10-18 11:26:01.000000000 +0200
  5900. @@ -0,0 +1,114 @@
  5901. +/*
  5902. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  5903. + *
  5904. + * This program, aufs is free software; you can redistribute it and/or modify
  5905. + * it under the terms of the GNU General Public License as published by
  5906. + * the Free Software Foundation; either version 2 of the License, or
  5907. + * (at your option) any later version.
  5908. + *
  5909. + * This program is distributed in the hope that it will be useful,
  5910. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  5911. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  5912. + * GNU General Public License for more details.
  5913. + *
  5914. + * You should have received a copy of the GNU General Public License
  5915. + * along with this program; if not, write to the Free Software
  5916. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  5917. + */
  5918. +
  5919. +/*
  5920. + * directory operations
  5921. + */
  5922. +
  5923. +#ifndef __AUFS_DIR_H__
  5924. +#define __AUFS_DIR_H__
  5925. +
  5926. +#ifdef __KERNEL__
  5927. +
  5928. +#include <linux/fs.h>
  5929. +#include <linux/aufs_type.h>
  5930. +
  5931. +/* ---------------------------------------------------------------------- */
  5932. +
  5933. +/* need to be faster and smaller */
  5934. +
  5935. +struct au_nhash {
  5936. + unsigned int nh_num;
  5937. + struct hlist_head *nh_head;
  5938. +};
  5939. +
  5940. +struct au_vdir_destr {
  5941. + unsigned char len;
  5942. + unsigned char name[0];
  5943. +} __packed;
  5944. +
  5945. +struct au_vdir_dehstr {
  5946. + struct hlist_node hash;
  5947. + struct au_vdir_destr *str;
  5948. +};
  5949. +
  5950. +struct au_vdir_de {
  5951. + ino_t de_ino;
  5952. + unsigned char de_type;
  5953. + /* caution: packed */
  5954. + struct au_vdir_destr de_str;
  5955. +} __packed;
  5956. +
  5957. +struct au_vdir_wh {
  5958. + struct hlist_node wh_hash;
  5959. +#ifdef CONFIG_AUFS_SHWH
  5960. + ino_t wh_ino;
  5961. + aufs_bindex_t wh_bindex;
  5962. + unsigned char wh_type;
  5963. +#else
  5964. + aufs_bindex_t wh_bindex;
  5965. +#endif
  5966. + /* caution: packed */
  5967. + struct au_vdir_destr wh_str;
  5968. +} __packed;
  5969. +
  5970. +union au_vdir_deblk_p {
  5971. + unsigned char *deblk;
  5972. + struct au_vdir_de *de;
  5973. +};
  5974. +
  5975. +struct au_vdir {
  5976. + unsigned char **vd_deblk;
  5977. + unsigned long vd_nblk;
  5978. + struct {
  5979. + unsigned long ul;
  5980. + union au_vdir_deblk_p p;
  5981. + } vd_last;
  5982. +
  5983. + unsigned long vd_version;
  5984. + unsigned int vd_deblk_sz;
  5985. + unsigned long vd_jiffy;
  5986. +};
  5987. +
  5988. +/* ---------------------------------------------------------------------- */
  5989. +
  5990. +/* dir.c */
  5991. +extern const struct file_operations aufs_dir_fop;
  5992. +void au_add_nlink(struct inode *dir, struct inode *h_dir);
  5993. +void au_sub_nlink(struct inode *dir, struct inode *h_dir);
  5994. +int au_test_empty_lower(struct dentry *dentry);
  5995. +int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
  5996. +
  5997. +/* vdir.c */
  5998. +int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
  5999. +void au_nhash_wh_free(struct au_nhash *whlist);
  6000. +int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
  6001. + int limit);
  6002. +int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
  6003. +int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
  6004. + unsigned int d_type, aufs_bindex_t bindex,
  6005. + unsigned char shwh);
  6006. +void au_vdir_free(struct au_vdir *vdir);
  6007. +int au_vdir_init(struct file *file);
  6008. +int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir);
  6009. +
  6010. +/* ioctl.c */
  6011. +long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
  6012. +
  6013. +#endif /* __KERNEL__ */
  6014. +#endif /* __AUFS_DIR_H__ */
  6015. diff -Nur linux-2.6.31.4.orig/fs/aufs/export.c linux-2.6.31.4/fs/aufs/export.c
  6016. --- linux-2.6.31.4.orig/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
  6017. +++ linux-2.6.31.4/fs/aufs/export.c 2009-10-18 11:26:01.000000000 +0200
  6018. @@ -0,0 +1,745 @@
  6019. +/*
  6020. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  6021. + *
  6022. + * This program, aufs is free software; you can redistribute it and/or modify
  6023. + * it under the terms of the GNU General Public License as published by
  6024. + * the Free Software Foundation; either version 2 of the License, or
  6025. + * (at your option) any later version.
  6026. + *
  6027. + * This program is distributed in the hope that it will be useful,
  6028. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  6029. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  6030. + * GNU General Public License for more details.
  6031. + *
  6032. + * You should have received a copy of the GNU General Public License
  6033. + * along with this program; if not, write to the Free Software
  6034. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  6035. + */
  6036. +
  6037. +/*
  6038. + * export via nfs
  6039. + */
  6040. +
  6041. +#include <linux/exportfs.h>
  6042. +#include <linux/file.h>
  6043. +#include <linux/mnt_namespace.h>
  6044. +#include <linux/namei.h>
  6045. +#include <linux/random.h>
  6046. +#include "aufs.h"
  6047. +
  6048. +union conv {
  6049. +#ifdef CONFIG_AUFS_INO_T_64
  6050. + __u32 a[2];
  6051. +#else
  6052. + __u32 a[1];
  6053. +#endif
  6054. + ino_t ino;
  6055. +};
  6056. +
  6057. +static ino_t decode_ino(__u32 *a)
  6058. +{
  6059. + union conv u;
  6060. +
  6061. + BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
  6062. + u.a[0] = a[0];
  6063. +#ifdef CONFIG_AUFS_INO_T_64
  6064. + u.a[1] = a[1];
  6065. +#endif
  6066. + return u.ino;
  6067. +}
  6068. +
  6069. +static void encode_ino(__u32 *a, ino_t ino)
  6070. +{
  6071. + union conv u;
  6072. +
  6073. + u.ino = ino;
  6074. + a[0] = u.a[0];
  6075. +#ifdef CONFIG_AUFS_INO_T_64
  6076. + a[1] = u.a[1];
  6077. +#endif
  6078. +}
  6079. +
  6080. +/* NFS file handle */
  6081. +enum {
  6082. + Fh_br_id,
  6083. + Fh_sigen,
  6084. +#ifdef CONFIG_AUFS_INO_T_64
  6085. + /* support 64bit inode number */
  6086. + Fh_ino1,
  6087. + Fh_ino2,
  6088. + Fh_dir_ino1,
  6089. + Fh_dir_ino2,
  6090. +#else
  6091. + Fh_ino1,
  6092. + Fh_dir_ino1,
  6093. +#endif
  6094. + Fh_igen,
  6095. + Fh_h_type,
  6096. + Fh_tail,
  6097. +
  6098. + Fh_ino = Fh_ino1,
  6099. + Fh_dir_ino = Fh_dir_ino1
  6100. +};
  6101. +
  6102. +static int au_test_anon(struct dentry *dentry)
  6103. +{
  6104. + return !!(dentry->d_flags & DCACHE_DISCONNECTED);
  6105. +}
  6106. +
  6107. +/* ---------------------------------------------------------------------- */
  6108. +/* inode generation external table */
  6109. +
  6110. +int au_xigen_inc(struct inode *inode)
  6111. +{
  6112. + int err;
  6113. + loff_t pos;
  6114. + ssize_t sz;
  6115. + __u32 igen;
  6116. + struct super_block *sb;
  6117. + struct au_sbinfo *sbinfo;
  6118. +
  6119. + err = 0;
  6120. + sb = inode->i_sb;
  6121. + sbinfo = au_sbi(sb);
  6122. + /*
  6123. + * temporary workaround for escaping from SiMustAnyLock() in
  6124. + * au_mntflags(), since this function is called from au_iinfo_fin().
  6125. + */
  6126. + if (unlikely(!au_opt_test(sbinfo->si_mntflags, XINO)))
  6127. + goto out;
  6128. +
  6129. + pos = inode->i_ino;
  6130. + pos *= sizeof(igen);
  6131. + igen = inode->i_generation + 1;
  6132. + sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
  6133. + sizeof(igen), &pos);
  6134. + if (sz == sizeof(igen))
  6135. + goto out; /* success */
  6136. +
  6137. + err = sz;
  6138. + if (unlikely(sz >= 0)) {
  6139. + err = -EIO;
  6140. + AuIOErr("xigen error (%zd)\n", sz);
  6141. + }
  6142. +
  6143. + out:
  6144. + return err;
  6145. +}
  6146. +
  6147. +int au_xigen_new(struct inode *inode)
  6148. +{
  6149. + int err;
  6150. + loff_t pos;
  6151. + ssize_t sz;
  6152. + struct super_block *sb;
  6153. + struct au_sbinfo *sbinfo;
  6154. + struct file *file;
  6155. +
  6156. + err = 0;
  6157. + /* todo: dirty, at mount time */
  6158. + if (inode->i_ino == AUFS_ROOT_INO)
  6159. + goto out;
  6160. + sb = inode->i_sb;
  6161. + SiMustAnyLock(sb);
  6162. + if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
  6163. + goto out;
  6164. +
  6165. + err = -EFBIG;
  6166. + pos = inode->i_ino;
  6167. + if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
  6168. + AuIOErr1("too large i%lld\n", pos);
  6169. + goto out;
  6170. + }
  6171. + pos *= sizeof(inode->i_generation);
  6172. +
  6173. + err = 0;
  6174. + sbinfo = au_sbi(sb);
  6175. + file = sbinfo->si_xigen;
  6176. + BUG_ON(!file);
  6177. +
  6178. + if (i_size_read(file->f_dentry->d_inode)
  6179. + < pos + sizeof(inode->i_generation)) {
  6180. + inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
  6181. + sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
  6182. + sizeof(inode->i_generation), &pos);
  6183. + } else
  6184. + sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
  6185. + sizeof(inode->i_generation), &pos);
  6186. + if (sz == sizeof(inode->i_generation))
  6187. + goto out; /* success */
  6188. +
  6189. + err = sz;
  6190. + if (unlikely(sz >= 0)) {
  6191. + err = -EIO;
  6192. + AuIOErr("xigen error (%zd)\n", sz);
  6193. + }
  6194. +
  6195. + out:
  6196. + return err;
  6197. +}
  6198. +
  6199. +int au_xigen_set(struct super_block *sb, struct file *base)
  6200. +{
  6201. + int err;
  6202. + struct au_sbinfo *sbinfo;
  6203. + struct file *file;
  6204. +
  6205. + SiMustWriteLock(sb);
  6206. +
  6207. + sbinfo = au_sbi(sb);
  6208. + file = au_xino_create2(base, sbinfo->si_xigen);
  6209. + err = PTR_ERR(file);
  6210. + if (IS_ERR(file))
  6211. + goto out;
  6212. + err = 0;
  6213. + if (sbinfo->si_xigen)
  6214. + fput(sbinfo->si_xigen);
  6215. + sbinfo->si_xigen = file;
  6216. +
  6217. + out:
  6218. + return err;
  6219. +}
  6220. +
  6221. +void au_xigen_clr(struct super_block *sb)
  6222. +{
  6223. + struct au_sbinfo *sbinfo;
  6224. +
  6225. + SiMustWriteLock(sb);
  6226. +
  6227. + sbinfo = au_sbi(sb);
  6228. + if (sbinfo->si_xigen) {
  6229. + fput(sbinfo->si_xigen);
  6230. + sbinfo->si_xigen = NULL;
  6231. + }
  6232. +}
  6233. +
  6234. +/* ---------------------------------------------------------------------- */
  6235. +
  6236. +static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
  6237. + ino_t dir_ino)
  6238. +{
  6239. + struct dentry *dentry, *d;
  6240. + struct inode *inode;
  6241. + unsigned int sigen;
  6242. +
  6243. + dentry = NULL;
  6244. + inode = ilookup(sb, ino);
  6245. + if (!inode)
  6246. + goto out;
  6247. +
  6248. + dentry = ERR_PTR(-ESTALE);
  6249. + sigen = au_sigen(sb);
  6250. + if (unlikely(is_bad_inode(inode)
  6251. + || IS_DEADDIR(inode)
  6252. + || sigen != au_iigen(inode)))
  6253. + goto out_iput;
  6254. +
  6255. + dentry = NULL;
  6256. + if (!dir_ino || S_ISDIR(inode->i_mode))
  6257. + dentry = d_find_alias(inode);
  6258. + else {
  6259. + spin_lock(&dcache_lock);
  6260. + list_for_each_entry(d, &inode->i_dentry, d_alias)
  6261. + if (!au_test_anon(d)
  6262. + && d->d_parent->d_inode->i_ino == dir_ino) {
  6263. + dentry = dget_locked(d);
  6264. + break;
  6265. + }
  6266. + spin_unlock(&dcache_lock);
  6267. + }
  6268. + if (unlikely(dentry && sigen != au_digen(dentry))) {
  6269. + dput(dentry);
  6270. + dentry = ERR_PTR(-ESTALE);
  6271. + }
  6272. +
  6273. + out_iput:
  6274. + iput(inode);
  6275. + out:
  6276. + return dentry;
  6277. +}
  6278. +
  6279. +/* ---------------------------------------------------------------------- */
  6280. +
  6281. +/* todo: dirty? */
  6282. +/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
  6283. +static struct vfsmount *au_mnt_get(struct super_block *sb)
  6284. +{
  6285. + struct mnt_namespace *ns;
  6286. + struct vfsmount *pos, *mnt;
  6287. +
  6288. + spin_lock(&vfsmount_lock);
  6289. + /* no get/put ?? */
  6290. + AuDebugOn(!current->nsproxy);
  6291. + ns = current->nsproxy->mnt_ns;
  6292. + AuDebugOn(!ns);
  6293. + mnt = NULL;
  6294. + /* the order (reverse) will not be a problem */
  6295. + list_for_each_entry(pos, &ns->list, mnt_list)
  6296. + if (pos->mnt_sb == sb) {
  6297. + mnt = mntget(pos);
  6298. + break;
  6299. + }
  6300. + spin_unlock(&vfsmount_lock);
  6301. + AuDebugOn(!mnt);
  6302. +
  6303. + return mnt;
  6304. +}
  6305. +
  6306. +struct au_nfsd_si_lock {
  6307. + const unsigned int sigen;
  6308. + const aufs_bindex_t br_id;
  6309. + unsigned char force_lock;
  6310. +};
  6311. +
  6312. +static aufs_bindex_t si_nfsd_read_lock(struct super_block *sb,
  6313. + struct au_nfsd_si_lock *nsi_lock)
  6314. +{
  6315. + aufs_bindex_t bindex;
  6316. +
  6317. + si_read_lock(sb, AuLock_FLUSH);
  6318. +
  6319. + /* branch id may be wrapped around */
  6320. + bindex = au_br_index(sb, nsi_lock->br_id);
  6321. + if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
  6322. + goto out; /* success */
  6323. +
  6324. + if (!nsi_lock->force_lock)
  6325. + si_read_unlock(sb);
  6326. + bindex = -1;
  6327. +
  6328. + out:
  6329. + return bindex;
  6330. +}
  6331. +
  6332. +struct find_name_by_ino {
  6333. + int called, found;
  6334. + ino_t ino;
  6335. + char *name;
  6336. + int namelen;
  6337. +};
  6338. +
  6339. +static int
  6340. +find_name_by_ino(void *arg, const char *name, int namelen, loff_t offset,
  6341. + u64 ino, unsigned int d_type)
  6342. +{
  6343. + struct find_name_by_ino *a = arg;
  6344. +
  6345. + a->called++;
  6346. + if (a->ino != ino)
  6347. + return 0;
  6348. +
  6349. + memcpy(a->name, name, namelen);
  6350. + a->namelen = namelen;
  6351. + a->found = 1;
  6352. + return 1;
  6353. +}
  6354. +
  6355. +static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
  6356. + struct au_nfsd_si_lock *nsi_lock)
  6357. +{
  6358. + struct dentry *dentry, *parent;
  6359. + struct file *file;
  6360. + struct inode *dir;
  6361. + struct find_name_by_ino arg;
  6362. + int err;
  6363. +
  6364. + parent = path->dentry;
  6365. + if (nsi_lock)
  6366. + si_read_unlock(parent->d_sb);
  6367. + path_get(path);
  6368. + file = dentry_open(parent, path->mnt, au_dir_roflags, current_cred());
  6369. + dentry = (void *)file;
  6370. + if (IS_ERR(file))
  6371. + goto out;
  6372. +
  6373. + dentry = ERR_PTR(-ENOMEM);
  6374. + arg.name = __getname();
  6375. + if (unlikely(!arg.name))
  6376. + goto out_file;
  6377. + arg.ino = ino;
  6378. + arg.found = 0;
  6379. + do {
  6380. + arg.called = 0;
  6381. + /* smp_mb(); */
  6382. + err = vfsub_readdir(file, find_name_by_ino, &arg);
  6383. + } while (!err && !arg.found && arg.called);
  6384. + dentry = ERR_PTR(err);
  6385. + if (unlikely(err))
  6386. + goto out_name;
  6387. + dentry = ERR_PTR(-ENOENT);
  6388. + if (!arg.found)
  6389. + goto out_name;
  6390. +
  6391. + /* do not call au_lkup_one() */
  6392. + dir = parent->d_inode;
  6393. + mutex_lock(&dir->i_mutex);
  6394. + dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
  6395. + mutex_unlock(&dir->i_mutex);
  6396. + AuTraceErrPtr(dentry);
  6397. + if (IS_ERR(dentry))
  6398. + goto out_name;
  6399. + AuDebugOn(au_test_anon(dentry));
  6400. + if (unlikely(!dentry->d_inode)) {
  6401. + dput(dentry);
  6402. + dentry = ERR_PTR(-ENOENT);
  6403. + }
  6404. +
  6405. + out_name:
  6406. + __putname(arg.name);
  6407. + out_file:
  6408. + fput(file);
  6409. + out:
  6410. + if (unlikely(nsi_lock
  6411. + && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
  6412. + if (!IS_ERR(dentry)) {
  6413. + dput(dentry);
  6414. + dentry = ERR_PTR(-ESTALE);
  6415. + }
  6416. + AuTraceErrPtr(dentry);
  6417. + return dentry;
  6418. +}
  6419. +
  6420. +static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
  6421. + ino_t dir_ino,
  6422. + struct au_nfsd_si_lock *nsi_lock)
  6423. +{
  6424. + struct dentry *dentry;
  6425. + struct path path;
  6426. +
  6427. + if (dir_ino != AUFS_ROOT_INO) {
  6428. + path.dentry = decode_by_ino(sb, dir_ino, 0);
  6429. + dentry = path.dentry;
  6430. + if (!path.dentry || IS_ERR(path.dentry))
  6431. + goto out;
  6432. + AuDebugOn(au_test_anon(path.dentry));
  6433. + } else
  6434. + path.dentry = dget(sb->s_root);
  6435. +
  6436. + path.mnt = au_mnt_get(sb);
  6437. + dentry = au_lkup_by_ino(&path, ino, nsi_lock);
  6438. + path_put(&path);
  6439. +
  6440. + out:
  6441. + AuTraceErrPtr(dentry);
  6442. + return dentry;
  6443. +}
  6444. +
  6445. +/* ---------------------------------------------------------------------- */
  6446. +
  6447. +static int h_acceptable(void *expv, struct dentry *dentry)
  6448. +{
  6449. + return 1;
  6450. +}
  6451. +
  6452. +static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
  6453. + char *buf, int len, struct super_block *sb)
  6454. +{
  6455. + char *p;
  6456. + int n;
  6457. + struct path path;
  6458. +
  6459. + p = d_path(h_rootpath, buf, len);
  6460. + if (IS_ERR(p))
  6461. + goto out;
  6462. + n = strlen(p);
  6463. +
  6464. + path.mnt = h_rootpath->mnt;
  6465. + path.dentry = h_parent;
  6466. + p = d_path(&path, buf, len);
  6467. + if (IS_ERR(p))
  6468. + goto out;
  6469. + if (n != 1)
  6470. + p += n;
  6471. +
  6472. + path.mnt = au_mnt_get(sb);
  6473. + path.dentry = sb->s_root;
  6474. + p = d_path(&path, buf, len - strlen(p));
  6475. + mntput(path.mnt);
  6476. + if (IS_ERR(p))
  6477. + goto out;
  6478. + if (n != 1)
  6479. + p[strlen(p)] = '/';
  6480. +
  6481. + out:
  6482. + AuTraceErrPtr(p);
  6483. + return p;
  6484. +}
  6485. +
  6486. +static
  6487. +struct dentry *decode_by_path(struct super_block *sb, aufs_bindex_t bindex,
  6488. + ino_t ino, __u32 *fh, int fh_len,
  6489. + struct au_nfsd_si_lock *nsi_lock)
  6490. +{
  6491. + struct dentry *dentry, *h_parent, *root;
  6492. + struct super_block *h_sb;
  6493. + char *pathname, *p;
  6494. + struct vfsmount *h_mnt;
  6495. + struct au_branch *br;
  6496. + int err;
  6497. + struct path path;
  6498. +
  6499. + br = au_sbr(sb, bindex);
  6500. + /* au_br_get(br); */
  6501. + h_mnt = br->br_mnt;
  6502. + h_sb = h_mnt->mnt_sb;
  6503. + /* todo: call lower fh_to_dentry()? fh_to_parent()? */
  6504. + h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
  6505. + fh_len - Fh_tail, fh[Fh_h_type],
  6506. + h_acceptable, /*context*/NULL);
  6507. + dentry = h_parent;
  6508. + if (unlikely(!h_parent || IS_ERR(h_parent))) {
  6509. + AuWarn1("%s decode_fh failed, %ld\n",
  6510. + au_sbtype(h_sb), PTR_ERR(h_parent));
  6511. + goto out;
  6512. + }
  6513. + dentry = NULL;
  6514. + if (unlikely(au_test_anon(h_parent))) {
  6515. + AuWarn1("%s decode_fh returned a disconnected dentry\n",
  6516. + au_sbtype(h_sb));
  6517. + goto out_h_parent;
  6518. + }
  6519. +
  6520. + dentry = ERR_PTR(-ENOMEM);
  6521. + pathname = (void *)__get_free_page(GFP_NOFS);
  6522. + if (unlikely(!pathname))
  6523. + goto out_h_parent;
  6524. +
  6525. + root = sb->s_root;
  6526. + path.mnt = h_mnt;
  6527. + di_read_lock_parent(root, !AuLock_IR);
  6528. + path.dentry = au_h_dptr(root, bindex);
  6529. + di_read_unlock(root, !AuLock_IR);
  6530. + p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
  6531. + dentry = (void *)p;
  6532. + if (IS_ERR(p))
  6533. + goto out_pathname;
  6534. +
  6535. + si_read_unlock(sb);
  6536. + err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
  6537. + dentry = ERR_PTR(err);
  6538. + if (unlikely(err))
  6539. + goto out_relock;
  6540. +
  6541. + dentry = ERR_PTR(-ENOENT);
  6542. + AuDebugOn(au_test_anon(path.dentry));
  6543. + if (unlikely(!path.dentry->d_inode))
  6544. + goto out_path;
  6545. +
  6546. + if (ino != path.dentry->d_inode->i_ino)
  6547. + dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
  6548. + else
  6549. + dentry = dget(path.dentry);
  6550. +
  6551. + out_path:
  6552. + path_put(&path);
  6553. + out_relock:
  6554. + if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
  6555. + if (!IS_ERR(dentry)) {
  6556. + dput(dentry);
  6557. + dentry = ERR_PTR(-ESTALE);
  6558. + }
  6559. + out_pathname:
  6560. + free_page((unsigned long)pathname);
  6561. + out_h_parent:
  6562. + dput(h_parent);
  6563. + out:
  6564. + /* au_br_put(br); */
  6565. + AuTraceErrPtr(dentry);
  6566. + return dentry;
  6567. +}
  6568. +
  6569. +/* ---------------------------------------------------------------------- */
  6570. +
  6571. +static struct dentry *
  6572. +aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
  6573. + int fh_type)
  6574. +{
  6575. + struct dentry *dentry;
  6576. + __u32 *fh = fid->raw;
  6577. + ino_t ino, dir_ino;
  6578. + aufs_bindex_t bindex;
  6579. + struct au_nfsd_si_lock nsi_lock = {
  6580. + .sigen = fh[Fh_sigen],
  6581. + .br_id = fh[Fh_br_id],
  6582. + .force_lock = 0
  6583. + };
  6584. +
  6585. + AuDebugOn(fh_len < Fh_tail);
  6586. +
  6587. + dentry = ERR_PTR(-ESTALE);
  6588. + /* branch id may be wrapped around */
  6589. + bindex = si_nfsd_read_lock(sb, &nsi_lock);
  6590. + if (unlikely(bindex < 0))
  6591. + goto out;
  6592. + nsi_lock.force_lock = 1;
  6593. +
  6594. + /* is this inode still cached? */
  6595. + ino = decode_ino(fh + Fh_ino);
  6596. + AuDebugOn(ino == AUFS_ROOT_INO);
  6597. + dir_ino = decode_ino(fh + Fh_dir_ino);
  6598. + dentry = decode_by_ino(sb, ino, dir_ino);
  6599. + if (IS_ERR(dentry))
  6600. + goto out_unlock;
  6601. + if (dentry)
  6602. + goto accept;
  6603. +
  6604. + /* is the parent dir cached? */
  6605. + dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
  6606. + if (IS_ERR(dentry))
  6607. + goto out_unlock;
  6608. + if (dentry)
  6609. + goto accept;
  6610. +
  6611. + /* lookup path */
  6612. + dentry = decode_by_path(sb, bindex, ino, fh, fh_len, &nsi_lock);
  6613. + if (IS_ERR(dentry))
  6614. + goto out_unlock;
  6615. + if (unlikely(!dentry))
  6616. + /* todo?: make it ESTALE */
  6617. + goto out_unlock;
  6618. +
  6619. + accept:
  6620. + if (dentry->d_inode->i_generation == fh[Fh_igen])
  6621. + goto out_unlock; /* success */
  6622. +
  6623. + dput(dentry);
  6624. + dentry = ERR_PTR(-ESTALE);
  6625. + out_unlock:
  6626. + si_read_unlock(sb);
  6627. + out:
  6628. + AuTraceErrPtr(dentry);
  6629. + return dentry;
  6630. +}
  6631. +
  6632. +#if 0 /* reserved for future use */
  6633. +/* support subtreecheck option */
  6634. +static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
  6635. + int fh_len, int fh_type)
  6636. +{
  6637. + struct dentry *parent;
  6638. + __u32 *fh = fid->raw;
  6639. + ino_t dir_ino;
  6640. +
  6641. + dir_ino = decode_ino(fh + Fh_dir_ino);
  6642. + parent = decode_by_ino(sb, dir_ino, 0);
  6643. + if (IS_ERR(parent))
  6644. + goto out;
  6645. + if (!parent)
  6646. + parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
  6647. + dir_ino, fh, fh_len);
  6648. +
  6649. + out:
  6650. + AuTraceErrPtr(parent);
  6651. + return parent;
  6652. +}
  6653. +#endif
  6654. +
  6655. +/* ---------------------------------------------------------------------- */
  6656. +
  6657. +static int aufs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
  6658. + int connectable)
  6659. +{
  6660. + int err;
  6661. + aufs_bindex_t bindex, bend;
  6662. + struct super_block *sb, *h_sb;
  6663. + struct inode *inode;
  6664. + struct dentry *parent, *h_parent;
  6665. + struct au_branch *br;
  6666. +
  6667. + AuDebugOn(au_test_anon(dentry));
  6668. +
  6669. + parent = NULL;
  6670. + err = -ENOSPC;
  6671. + if (unlikely(*max_len <= Fh_tail)) {
  6672. + AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
  6673. + goto out;
  6674. + }
  6675. +
  6676. + err = FILEID_ROOT;
  6677. + if (IS_ROOT(dentry)) {
  6678. + AuDebugOn(dentry->d_inode->i_ino != AUFS_ROOT_INO);
  6679. + goto out;
  6680. + }
  6681. +
  6682. + err = -EIO;
  6683. + h_parent = NULL;
  6684. + sb = dentry->d_sb;
  6685. + aufs_read_lock(dentry, AuLock_FLUSH | AuLock_IR);
  6686. + parent = dget_parent(dentry);
  6687. + di_read_lock_parent(parent, !AuLock_IR);
  6688. + inode = dentry->d_inode;
  6689. + AuDebugOn(!inode);
  6690. +#ifdef CONFIG_AUFS_DEBUG
  6691. + if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
  6692. + AuWarn1("NFS-exporting requires xino\n");
  6693. +#endif
  6694. +
  6695. + bend = au_dbtaildir(parent);
  6696. + for (bindex = au_dbstart(parent); bindex <= bend; bindex++) {
  6697. + h_parent = au_h_dptr(parent, bindex);
  6698. + if (h_parent) {
  6699. + dget(h_parent);
  6700. + break;
  6701. + }
  6702. + }
  6703. + if (unlikely(!h_parent))
  6704. + goto out_unlock;
  6705. +
  6706. + err = -EPERM;
  6707. + br = au_sbr(sb, bindex);
  6708. + h_sb = br->br_mnt->mnt_sb;
  6709. + if (unlikely(!h_sb->s_export_op)) {
  6710. + AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
  6711. + goto out_dput;
  6712. + }
  6713. +
  6714. + fh[Fh_br_id] = br->br_id;
  6715. + fh[Fh_sigen] = au_sigen(sb);
  6716. + encode_ino(fh + Fh_ino, inode->i_ino);
  6717. + encode_ino(fh + Fh_dir_ino, parent->d_inode->i_ino);
  6718. + fh[Fh_igen] = inode->i_generation;
  6719. +
  6720. + *max_len -= Fh_tail;
  6721. + fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
  6722. + max_len,
  6723. + /*connectable or subtreecheck*/0);
  6724. + err = fh[Fh_h_type];
  6725. + *max_len += Fh_tail;
  6726. + /* todo: macros? */
  6727. + if (err != 255)
  6728. + err = 99;
  6729. + else
  6730. + AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
  6731. +
  6732. + out_dput:
  6733. + dput(h_parent);
  6734. + out_unlock:
  6735. + di_read_unlock(parent, !AuLock_IR);
  6736. + dput(parent);
  6737. + aufs_read_unlock(dentry, AuLock_IR);
  6738. + out:
  6739. + if (unlikely(err < 0))
  6740. + err = 255;
  6741. + return err;
  6742. +}
  6743. +
  6744. +/* ---------------------------------------------------------------------- */
  6745. +
  6746. +static struct export_operations aufs_export_op = {
  6747. + .fh_to_dentry = aufs_fh_to_dentry,
  6748. + /* .fh_to_parent = aufs_fh_to_parent, */
  6749. + .encode_fh = aufs_encode_fh
  6750. +};
  6751. +
  6752. +void au_export_init(struct super_block *sb)
  6753. +{
  6754. + struct au_sbinfo *sbinfo;
  6755. + __u32 u;
  6756. +
  6757. + sb->s_export_op = &aufs_export_op;
  6758. + sbinfo = au_sbi(sb);
  6759. + sbinfo->si_xigen = NULL;
  6760. + get_random_bytes(&u, sizeof(u));
  6761. + BUILD_BUG_ON(sizeof(u) != sizeof(int));
  6762. + atomic_set(&sbinfo->si_xigen_next, u);
  6763. +}
  6764. diff -Nur linux-2.6.31.4.orig/fs/aufs/file.c linux-2.6.31.4/fs/aufs/file.c
  6765. --- linux-2.6.31.4.orig/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
  6766. +++ linux-2.6.31.4/fs/aufs/file.c 2009-10-18 11:26:01.000000000 +0200
  6767. @@ -0,0 +1,578 @@
  6768. +/*
  6769. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  6770. + *
  6771. + * This program, aufs is free software; you can redistribute it and/or modify
  6772. + * it under the terms of the GNU General Public License as published by
  6773. + * the Free Software Foundation; either version 2 of the License, or
  6774. + * (at your option) any later version.
  6775. + *
  6776. + * This program is distributed in the hope that it will be useful,
  6777. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  6778. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  6779. + * GNU General Public License for more details.
  6780. + *
  6781. + * You should have received a copy of the GNU General Public License
  6782. + * along with this program; if not, write to the Free Software
  6783. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  6784. + */
  6785. +
  6786. +/*
  6787. + * handling file/dir, and address_space operation
  6788. + */
  6789. +
  6790. +#include <linux/file.h>
  6791. +#include <linux/fsnotify.h>
  6792. +#include <linux/namei.h>
  6793. +#include <linux/pagemap.h>
  6794. +#include "aufs.h"
  6795. +
  6796. +/*
  6797. + * a dirty trick for handling deny_write_access().
  6798. + * because FMODE_EXEC flag is not passed to f_op->open(),
  6799. + * set it to file->private_data temporary.
  6800. + */
  6801. +void au_store_oflag(struct nameidata *nd, struct inode *inode)
  6802. +{
  6803. + if (nd
  6804. + /* && !(nd->flags & LOOKUP_CONTINUE) */
  6805. + && (nd->flags & LOOKUP_OPEN)
  6806. + && (nd->intent.open.flags & vfsub_fmode_to_uint(FMODE_EXEC))
  6807. + && inode
  6808. + && S_ISREG(inode->i_mode)) {
  6809. + /* suppress a warning in lp64 */
  6810. + unsigned long flags = nd->intent.open.flags;
  6811. + nd->intent.open.file->private_data = (void *)flags;
  6812. + /* smp_mb(); */
  6813. + }
  6814. +}
  6815. +
  6816. +/* drop flags for writing */
  6817. +unsigned int au_file_roflags(unsigned int flags)
  6818. +{
  6819. + flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
  6820. + flags |= O_RDONLY | O_NOATIME;
  6821. + return flags;
  6822. +}
  6823. +
  6824. +/* common functions to regular file and dir */
  6825. +struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
  6826. + struct file *file)
  6827. +{
  6828. + struct file *h_file;
  6829. + struct dentry *h_dentry;
  6830. + struct inode *h_inode;
  6831. + struct super_block *sb;
  6832. + struct au_branch *br;
  6833. + int err;
  6834. +
  6835. + /* a race condition can happen between open and unlink/rmdir */
  6836. + h_file = ERR_PTR(-ENOENT);
  6837. + h_dentry = au_h_dptr(dentry, bindex);
  6838. + if (au_test_nfsd(current) && !h_dentry)
  6839. + goto out;
  6840. + h_inode = h_dentry->d_inode;
  6841. + if (au_test_nfsd(current) && !h_inode)
  6842. + goto out;
  6843. + if (unlikely((!d_unhashed(dentry) && d_unhashed(h_dentry))
  6844. + || !h_inode))
  6845. + goto out;
  6846. +
  6847. + sb = dentry->d_sb;
  6848. + br = au_sbr(sb, bindex);
  6849. + h_file = ERR_PTR(-EACCES);
  6850. + if (file && (file->f_mode & FMODE_EXEC)
  6851. + && (br->br_mnt->mnt_flags & MNT_NOEXEC))
  6852. + goto out;
  6853. +
  6854. + /* drop flags for writing */
  6855. + if (au_test_ro(sb, bindex, dentry->d_inode))
  6856. + flags = au_file_roflags(flags);
  6857. + flags &= ~O_CREAT;
  6858. + atomic_inc(&br->br_count);
  6859. + h_file = dentry_open(dget(h_dentry), mntget(br->br_mnt), flags,
  6860. + current_cred());
  6861. + if (IS_ERR(h_file))
  6862. + goto out_br;
  6863. +
  6864. + if (file && (file->f_mode & FMODE_EXEC)) {
  6865. + h_file->f_mode |= FMODE_EXEC;
  6866. + err = deny_write_access(h_file);
  6867. + if (unlikely(err)) {
  6868. + fput(h_file);
  6869. + h_file = ERR_PTR(err);
  6870. + goto out_br;
  6871. + }
  6872. + }
  6873. + fsnotify_open(h_dentry);
  6874. + goto out; /* success */
  6875. +
  6876. + out_br:
  6877. + atomic_dec(&br->br_count);
  6878. + out:
  6879. + return h_file;
  6880. +}
  6881. +
  6882. +int au_do_open(struct file *file, int (*open)(struct file *file, int flags))
  6883. +{
  6884. + int err;
  6885. + struct dentry *dentry;
  6886. + struct super_block *sb;
  6887. +
  6888. + dentry = file->f_dentry;
  6889. + sb = dentry->d_sb;
  6890. + si_read_lock(sb, AuLock_FLUSH);
  6891. + err = au_finfo_init(file);
  6892. + if (unlikely(err))
  6893. + goto out;
  6894. +
  6895. + di_read_lock_child(dentry, AuLock_IR);
  6896. + err = open(file, file->f_flags);
  6897. + di_read_unlock(dentry, AuLock_IR);
  6898. +
  6899. + fi_write_unlock(file);
  6900. + if (unlikely(err))
  6901. + au_finfo_fin(file);
  6902. + out:
  6903. + si_read_unlock(sb);
  6904. + return err;
  6905. +}
  6906. +
  6907. +int au_reopen_nondir(struct file *file)
  6908. +{
  6909. + int err;
  6910. + aufs_bindex_t bstart, bindex, bend;
  6911. + struct dentry *dentry;
  6912. + struct file *h_file, *h_file_tmp;
  6913. +
  6914. + dentry = file->f_dentry;
  6915. + bstart = au_dbstart(dentry);
  6916. + h_file_tmp = NULL;
  6917. + if (au_fbstart(file) == bstart) {
  6918. + h_file = au_h_fptr(file, bstart);
  6919. + if (file->f_mode == h_file->f_mode)
  6920. + return 0; /* success */
  6921. + h_file_tmp = h_file;
  6922. + get_file(h_file_tmp);
  6923. + au_set_h_fptr(file, bstart, NULL);
  6924. + }
  6925. + AuDebugOn(au_fbstart(file) < bstart
  6926. + || au_fi(file)->fi_hfile[0 + bstart].hf_file);
  6927. +
  6928. + h_file = au_h_open(dentry, bstart, file->f_flags & ~O_TRUNC, file);
  6929. + err = PTR_ERR(h_file);
  6930. + if (IS_ERR(h_file))
  6931. + goto out; /* todo: close all? */
  6932. +
  6933. + err = 0;
  6934. + au_set_fbstart(file, bstart);
  6935. + au_set_h_fptr(file, bstart, h_file);
  6936. + au_update_figen(file);
  6937. + /* todo: necessary? */
  6938. + /* file->f_ra = h_file->f_ra; */
  6939. +
  6940. + /* close lower files */
  6941. + bend = au_fbend(file);
  6942. + for (bindex = bstart + 1; bindex <= bend; bindex++)
  6943. + au_set_h_fptr(file, bindex, NULL);
  6944. + au_set_fbend(file, bstart);
  6945. +
  6946. + out:
  6947. + if (h_file_tmp)
  6948. + fput(h_file_tmp);
  6949. + return err;
  6950. +}
  6951. +
  6952. +/* ---------------------------------------------------------------------- */
  6953. +
  6954. +static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
  6955. + struct dentry *hi_wh)
  6956. +{
  6957. + int err;
  6958. + aufs_bindex_t bstart;
  6959. + struct au_dinfo *dinfo;
  6960. + struct dentry *h_dentry;
  6961. +
  6962. + dinfo = au_di(file->f_dentry);
  6963. + AuRwMustWriteLock(&dinfo->di_rwsem);
  6964. +
  6965. + bstart = dinfo->di_bstart;
  6966. + dinfo->di_bstart = btgt;
  6967. + h_dentry = dinfo->di_hdentry[0 + btgt].hd_dentry;
  6968. + dinfo->di_hdentry[0 + btgt].hd_dentry = hi_wh;
  6969. + err = au_reopen_nondir(file);
  6970. + dinfo->di_hdentry[0 + btgt].hd_dentry = h_dentry;
  6971. + dinfo->di_bstart = bstart;
  6972. +
  6973. + return err;
  6974. +}
  6975. +
  6976. +static int au_ready_to_write_wh(struct file *file, loff_t len,
  6977. + aufs_bindex_t bcpup)
  6978. +{
  6979. + int err;
  6980. + struct inode *inode;
  6981. + struct dentry *dentry, *hi_wh;
  6982. + struct super_block *sb;
  6983. +
  6984. + dentry = file->f_dentry;
  6985. + inode = dentry->d_inode;
  6986. + hi_wh = au_hi_wh(inode, bcpup);
  6987. + if (!hi_wh)
  6988. + err = au_sio_cpup_wh(dentry, bcpup, len, file);
  6989. + else
  6990. + /* already copied-up after unlink */
  6991. + err = au_reopen_wh(file, bcpup, hi_wh);
  6992. +
  6993. + sb = dentry->d_sb;
  6994. + if (!err && inode->i_nlink > 1 && au_opt_test(au_mntflags(sb), PLINK))
  6995. + au_plink_append(inode, bcpup, au_h_dptr(dentry, bcpup));
  6996. +
  6997. + return err;
  6998. +}
  6999. +
  7000. +/*
  7001. + * prepare the @file for writing.
  7002. + */
  7003. +int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
  7004. +{
  7005. + int err;
  7006. + aufs_bindex_t bstart, bcpup;
  7007. + struct dentry *dentry, *parent, *h_dentry;
  7008. + struct inode *h_inode, *inode;
  7009. + struct super_block *sb;
  7010. +
  7011. + dentry = file->f_dentry;
  7012. + sb = dentry->d_sb;
  7013. + bstart = au_fbstart(file);
  7014. + inode = dentry->d_inode;
  7015. + err = au_test_ro(sb, bstart, inode);
  7016. + if (!err && (au_h_fptr(file, bstart)->f_mode & FMODE_WRITE)) {
  7017. + err = au_pin(pin, dentry, bstart, AuOpt_UDBA_NONE, /*flags*/0);
  7018. + goto out;
  7019. + }
  7020. +
  7021. + /* need to cpup */
  7022. + parent = dget_parent(dentry);
  7023. + di_write_lock_parent(parent);
  7024. + err = AuWbrCopyup(au_sbi(sb), dentry);
  7025. + bcpup = err;
  7026. + if (unlikely(err < 0))
  7027. + goto out_dgrade;
  7028. + err = 0;
  7029. +
  7030. + if (!au_h_dptr(parent, bcpup)) {
  7031. + err = au_cpup_dirs(dentry, bcpup);
  7032. + if (unlikely(err))
  7033. + goto out_dgrade;
  7034. + }
  7035. +
  7036. + err = au_pin(pin, dentry, bcpup, AuOpt_UDBA_NONE,
  7037. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  7038. + if (unlikely(err))
  7039. + goto out_dgrade;
  7040. +
  7041. + h_dentry = au_h_fptr(file, bstart)->f_dentry;
  7042. + h_inode = h_dentry->d_inode;
  7043. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  7044. + if (d_unhashed(dentry) /* || d_unhashed(h_dentry) */
  7045. + /* || !h_inode->i_nlink */) {
  7046. + err = au_ready_to_write_wh(file, len, bcpup);
  7047. + di_downgrade_lock(parent, AuLock_IR);
  7048. + } else {
  7049. + di_downgrade_lock(parent, AuLock_IR);
  7050. + if (!au_h_dptr(dentry, bcpup))
  7051. + err = au_sio_cpup_simple(dentry, bcpup, len,
  7052. + AuCpup_DTIME);
  7053. + if (!err)
  7054. + err = au_reopen_nondir(file);
  7055. + }
  7056. + mutex_unlock(&h_inode->i_mutex);
  7057. +
  7058. + if (!err) {
  7059. + au_pin_set_parent_lflag(pin, /*lflag*/0);
  7060. + goto out_dput; /* success */
  7061. + }
  7062. + au_unpin(pin);
  7063. + goto out_unlock;
  7064. +
  7065. + out_dgrade:
  7066. + di_downgrade_lock(parent, AuLock_IR);
  7067. + out_unlock:
  7068. + di_read_unlock(parent, AuLock_IR);
  7069. + out_dput:
  7070. + dput(parent);
  7071. + out:
  7072. + return err;
  7073. +}
  7074. +
  7075. +/* ---------------------------------------------------------------------- */
  7076. +
  7077. +static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
  7078. +{
  7079. + int err;
  7080. + aufs_bindex_t bstart;
  7081. + struct au_pin pin;
  7082. + struct au_finfo *finfo;
  7083. + struct dentry *dentry, *parent, *hi_wh;
  7084. + struct inode *inode;
  7085. + struct super_block *sb;
  7086. +
  7087. + FiMustWriteLock(file);
  7088. +
  7089. + err = 0;
  7090. + finfo = au_fi(file);
  7091. + dentry = file->f_dentry;
  7092. + sb = dentry->d_sb;
  7093. + inode = dentry->d_inode;
  7094. + bstart = au_ibstart(inode);
  7095. + if (bstart == finfo->fi_bstart)
  7096. + goto out;
  7097. +
  7098. + parent = dget_parent(dentry);
  7099. + if (au_test_ro(sb, bstart, inode)) {
  7100. + di_read_lock_parent(parent, !AuLock_IR);
  7101. + err = AuWbrCopyup(au_sbi(sb), dentry);
  7102. + bstart = err;
  7103. + di_read_unlock(parent, !AuLock_IR);
  7104. + if (unlikely(err < 0))
  7105. + goto out_parent;
  7106. + err = 0;
  7107. + }
  7108. +
  7109. + di_read_lock_parent(parent, AuLock_IR);
  7110. + hi_wh = au_hi_wh(inode, bstart);
  7111. + if (au_opt_test(au_mntflags(sb), PLINK)
  7112. + && au_plink_test(inode)
  7113. + && !d_unhashed(dentry)) {
  7114. + err = au_test_and_cpup_dirs(dentry, bstart);
  7115. + if (unlikely(err))
  7116. + goto out_unlock;
  7117. +
  7118. + /* always superio. */
  7119. + err = au_pin(&pin, dentry, bstart, AuOpt_UDBA_NONE,
  7120. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  7121. + if (!err)
  7122. + err = au_sio_cpup_simple(dentry, bstart, -1,
  7123. + AuCpup_DTIME);
  7124. + au_unpin(&pin);
  7125. + } else if (hi_wh) {
  7126. + /* already copied-up after unlink */
  7127. + err = au_reopen_wh(file, bstart, hi_wh);
  7128. + *need_reopen = 0;
  7129. + }
  7130. +
  7131. + out_unlock:
  7132. + di_read_unlock(parent, AuLock_IR);
  7133. + out_parent:
  7134. + dput(parent);
  7135. + out:
  7136. + return err;
  7137. +}
  7138. +
  7139. +static void au_do_refresh_file(struct file *file)
  7140. +{
  7141. + aufs_bindex_t bindex, bend, new_bindex, brid;
  7142. + struct au_hfile *p, tmp, *q;
  7143. + struct au_finfo *finfo;
  7144. + struct super_block *sb;
  7145. +
  7146. + FiMustWriteLock(file);
  7147. +
  7148. + sb = file->f_dentry->d_sb;
  7149. + finfo = au_fi(file);
  7150. + p = finfo->fi_hfile + finfo->fi_bstart;
  7151. + brid = p->hf_br->br_id;
  7152. + bend = finfo->fi_bend;
  7153. + for (bindex = finfo->fi_bstart; bindex <= bend; bindex++, p++) {
  7154. + if (!p->hf_file)
  7155. + continue;
  7156. +
  7157. + new_bindex = au_br_index(sb, p->hf_br->br_id);
  7158. + if (new_bindex == bindex)
  7159. + continue;
  7160. + if (new_bindex < 0) {
  7161. + au_set_h_fptr(file, bindex, NULL);
  7162. + continue;
  7163. + }
  7164. +
  7165. + /* swap two lower inode, and loop again */
  7166. + q = finfo->fi_hfile + new_bindex;
  7167. + tmp = *q;
  7168. + *q = *p;
  7169. + *p = tmp;
  7170. + if (tmp.hf_file) {
  7171. + bindex--;
  7172. + p--;
  7173. + }
  7174. + }
  7175. +
  7176. + p = finfo->fi_hfile;
  7177. + if (!au_test_mmapped(file) && !d_unhashed(file->f_dentry)) {
  7178. + bend = au_sbend(sb);
  7179. + for (finfo->fi_bstart = 0; finfo->fi_bstart <= bend;
  7180. + finfo->fi_bstart++, p++)
  7181. + if (p->hf_file) {
  7182. + if (p->hf_file->f_dentry
  7183. + && p->hf_file->f_dentry->d_inode)
  7184. + break;
  7185. + else
  7186. + au_hfput(p, file);
  7187. + }
  7188. + } else {
  7189. + bend = au_br_index(sb, brid);
  7190. + for (finfo->fi_bstart = 0; finfo->fi_bstart < bend;
  7191. + finfo->fi_bstart++, p++)
  7192. + if (p->hf_file)
  7193. + au_hfput(p, file);
  7194. + bend = au_sbend(sb);
  7195. + }
  7196. +
  7197. + p = finfo->fi_hfile + bend;
  7198. + for (finfo->fi_bend = bend; finfo->fi_bend >= finfo->fi_bstart;
  7199. + finfo->fi_bend--, p--)
  7200. + if (p->hf_file) {
  7201. + if (p->hf_file->f_dentry
  7202. + && p->hf_file->f_dentry->d_inode)
  7203. + break;
  7204. + else
  7205. + au_hfput(p, file);
  7206. + }
  7207. + AuDebugOn(finfo->fi_bend < finfo->fi_bstart);
  7208. +}
  7209. +
  7210. +/*
  7211. + * after branch manipulating, refresh the file.
  7212. + */
  7213. +static int refresh_file(struct file *file, int (*reopen)(struct file *file))
  7214. +{
  7215. + int err, need_reopen;
  7216. + struct dentry *dentry;
  7217. + aufs_bindex_t bend, bindex;
  7218. +
  7219. + dentry = file->f_dentry;
  7220. + err = au_fi_realloc(au_fi(file), au_sbend(dentry->d_sb) + 1);
  7221. + if (unlikely(err))
  7222. + goto out;
  7223. + au_do_refresh_file(file);
  7224. +
  7225. + err = 0;
  7226. + need_reopen = 1;
  7227. + if (!au_test_mmapped(file))
  7228. + err = au_file_refresh_by_inode(file, &need_reopen);
  7229. + if (!err && need_reopen && !d_unhashed(dentry))
  7230. + err = reopen(file);
  7231. + if (!err) {
  7232. + au_update_figen(file);
  7233. + return 0; /* success */
  7234. + }
  7235. +
  7236. + /* error, close all lower files */
  7237. + bend = au_fbend(file);
  7238. + for (bindex = au_fbstart(file); bindex <= bend; bindex++)
  7239. + au_set_h_fptr(file, bindex, NULL);
  7240. +
  7241. + out:
  7242. + return err;
  7243. +}
  7244. +
  7245. +/* common function to regular file and dir */
  7246. +int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
  7247. + int wlock)
  7248. +{
  7249. + int err;
  7250. + unsigned int sigen, figen;
  7251. + aufs_bindex_t bstart;
  7252. + unsigned char pseudo_link;
  7253. + struct dentry *dentry;
  7254. +
  7255. + err = 0;
  7256. + dentry = file->f_dentry;
  7257. + sigen = au_sigen(dentry->d_sb);
  7258. + fi_write_lock(file);
  7259. + figen = au_figen(file);
  7260. + di_write_lock_child(dentry);
  7261. + bstart = au_dbstart(dentry);
  7262. + pseudo_link = (bstart != au_ibstart(dentry->d_inode));
  7263. + if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) {
  7264. + if (!wlock) {
  7265. + di_downgrade_lock(dentry, AuLock_IR);
  7266. + fi_downgrade_lock(file);
  7267. + }
  7268. + goto out; /* success */
  7269. + }
  7270. +
  7271. + AuDbg("sigen %d, figen %d\n", sigen, figen);
  7272. + if (sigen != au_digen(dentry)
  7273. + || sigen != au_iigen(dentry->d_inode)) {
  7274. + err = au_reval_dpath(dentry, sigen);
  7275. + if (unlikely(err < 0))
  7276. + goto out;
  7277. + AuDebugOn(au_digen(dentry) != sigen
  7278. + || au_iigen(dentry->d_inode) != sigen);
  7279. + }
  7280. +
  7281. + err = refresh_file(file, reopen);
  7282. + if (!err) {
  7283. + if (!wlock) {
  7284. + di_downgrade_lock(dentry, AuLock_IR);
  7285. + fi_downgrade_lock(file);
  7286. + }
  7287. + } else {
  7288. + di_write_unlock(dentry);
  7289. + fi_write_unlock(file);
  7290. + }
  7291. +
  7292. + out:
  7293. + return err;
  7294. +}
  7295. +
  7296. +/* ---------------------------------------------------------------------- */
  7297. +
  7298. +/* cf. aufs_nopage() */
  7299. +/* for madvise(2) */
  7300. +static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
  7301. +{
  7302. + unlock_page(page);
  7303. + return 0;
  7304. +}
  7305. +
  7306. +/* they will never be called. */
  7307. +#ifdef CONFIG_AUFS_DEBUG
  7308. +static int aufs_write_begin(struct file *file, struct address_space *mapping,
  7309. + loff_t pos, unsigned len, unsigned flags,
  7310. + struct page **pagep, void **fsdata)
  7311. +{ AuUnsupport(); return 0; }
  7312. +static int aufs_write_end(struct file *file, struct address_space *mapping,
  7313. + loff_t pos, unsigned len, unsigned copied,
  7314. + struct page *page, void *fsdata)
  7315. +{ AuUnsupport(); return 0; }
  7316. +static int aufs_writepage(struct page *page, struct writeback_control *wbc)
  7317. +{ AuUnsupport(); return 0; }
  7318. +static void aufs_sync_page(struct page *page)
  7319. +{ AuUnsupport(); }
  7320. +
  7321. +static int aufs_set_page_dirty(struct page *page)
  7322. +{ AuUnsupport(); return 0; }
  7323. +static void aufs_invalidatepage(struct page *page, unsigned long offset)
  7324. +{ AuUnsupport(); }
  7325. +static int aufs_releasepage(struct page *page, gfp_t gfp)
  7326. +{ AuUnsupport(); return 0; }
  7327. +static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb,
  7328. + const struct iovec *iov, loff_t offset,
  7329. + unsigned long nr_segs)
  7330. +{ AuUnsupport(); return 0; }
  7331. +#endif /* CONFIG_AUFS_DEBUG */
  7332. +
  7333. +struct address_space_operations aufs_aop = {
  7334. + .readpage = aufs_readpage,
  7335. +#ifdef CONFIG_AUFS_DEBUG
  7336. + .writepage = aufs_writepage,
  7337. + .sync_page = aufs_sync_page,
  7338. + .set_page_dirty = aufs_set_page_dirty,
  7339. + .write_begin = aufs_write_begin,
  7340. + .write_end = aufs_write_end,
  7341. + .invalidatepage = aufs_invalidatepage,
  7342. + .releasepage = aufs_releasepage,
  7343. + .direct_IO = aufs_direct_IO,
  7344. +#endif /* CONFIG_AUFS_DEBUG */
  7345. +};
  7346. diff -Nur linux-2.6.31.4.orig/fs/aufs/file.h linux-2.6.31.4/fs/aufs/file.h
  7347. --- linux-2.6.31.4.orig/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100
  7348. +++ linux-2.6.31.4/fs/aufs/file.h 2009-10-18 11:26:01.000000000 +0200
  7349. @@ -0,0 +1,175 @@
  7350. +/*
  7351. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  7352. + *
  7353. + * This program, aufs is free software; you can redistribute it and/or modify
  7354. + * it under the terms of the GNU General Public License as published by
  7355. + * the Free Software Foundation; either version 2 of the License, or
  7356. + * (at your option) any later version.
  7357. + *
  7358. + * This program is distributed in the hope that it will be useful,
  7359. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7360. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  7361. + * GNU General Public License for more details.
  7362. + *
  7363. + * You should have received a copy of the GNU General Public License
  7364. + * along with this program; if not, write to the Free Software
  7365. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  7366. + */
  7367. +
  7368. +/*
  7369. + * file operations
  7370. + */
  7371. +
  7372. +#ifndef __AUFS_FILE_H__
  7373. +#define __AUFS_FILE_H__
  7374. +
  7375. +#ifdef __KERNEL__
  7376. +
  7377. +#include <linux/fs.h>
  7378. +#include <linux/poll.h>
  7379. +#include <linux/aufs_type.h>
  7380. +#include "rwsem.h"
  7381. +
  7382. +struct au_branch;
  7383. +struct au_hfile {
  7384. + struct file *hf_file;
  7385. + struct au_branch *hf_br;
  7386. +};
  7387. +
  7388. +struct au_vdir;
  7389. +struct au_finfo {
  7390. + atomic_t fi_generation;
  7391. +
  7392. + struct au_rwsem fi_rwsem;
  7393. + struct au_hfile *fi_hfile;
  7394. + aufs_bindex_t fi_bstart, fi_bend;
  7395. +
  7396. + union {
  7397. + /* non-dir only */
  7398. + struct {
  7399. + struct vm_operations_struct *fi_h_vm_ops;
  7400. + struct vm_operations_struct *fi_vm_ops;
  7401. + };
  7402. +
  7403. + /* dir only */
  7404. + struct {
  7405. + struct au_vdir *fi_vdir_cache;
  7406. + int fi_maintain_plink;
  7407. + };
  7408. + };
  7409. +};
  7410. +
  7411. +/* ---------------------------------------------------------------------- */
  7412. +
  7413. +/* file.c */
  7414. +extern struct address_space_operations aufs_aop;
  7415. +void au_store_oflag(struct nameidata *nd, struct inode *inode);
  7416. +unsigned int au_file_roflags(unsigned int flags);
  7417. +struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
  7418. + struct file *file);
  7419. +int au_do_open(struct file *file, int (*open)(struct file *file, int flags));
  7420. +int au_reopen_nondir(struct file *file);
  7421. +struct au_pin;
  7422. +int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
  7423. +int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
  7424. + int wlock);
  7425. +
  7426. +/* poll.c */
  7427. +#ifdef CONFIG_AUFS_POLL
  7428. +unsigned int aufs_poll(struct file *file, poll_table *wait);
  7429. +#endif
  7430. +
  7431. +/* f_op.c */
  7432. +extern const struct file_operations aufs_file_fop;
  7433. +int aufs_flush(struct file *file, fl_owner_t id);
  7434. +
  7435. +/* finfo.c */
  7436. +void au_hfput(struct au_hfile *hf, struct file *file);
  7437. +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
  7438. + struct file *h_file);
  7439. +
  7440. +void au_update_figen(struct file *file);
  7441. +
  7442. +void au_finfo_fin(struct file *file);
  7443. +int au_finfo_init(struct file *file);
  7444. +int au_fi_realloc(struct au_finfo *finfo, int nbr);
  7445. +
  7446. +/* ---------------------------------------------------------------------- */
  7447. +
  7448. +static inline struct au_finfo *au_fi(struct file *file)
  7449. +{
  7450. + return file->private_data;
  7451. +}
  7452. +
  7453. +/* ---------------------------------------------------------------------- */
  7454. +
  7455. +/*
  7456. + * fi_read_lock, fi_write_lock,
  7457. + * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
  7458. + */
  7459. +AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
  7460. +
  7461. +#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
  7462. +#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
  7463. +#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
  7464. +
  7465. +/* ---------------------------------------------------------------------- */
  7466. +
  7467. +/* todo: hard/soft set? */
  7468. +static inline aufs_bindex_t au_fbstart(struct file *file)
  7469. +{
  7470. + FiMustAnyLock(file);
  7471. + return au_fi(file)->fi_bstart;
  7472. +}
  7473. +
  7474. +static inline aufs_bindex_t au_fbend(struct file *file)
  7475. +{
  7476. + FiMustAnyLock(file);
  7477. + return au_fi(file)->fi_bend;
  7478. +}
  7479. +
  7480. +static inline struct au_vdir *au_fvdir_cache(struct file *file)
  7481. +{
  7482. + FiMustAnyLock(file);
  7483. + return au_fi(file)->fi_vdir_cache;
  7484. +}
  7485. +
  7486. +static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex)
  7487. +{
  7488. + FiMustWriteLock(file);
  7489. + au_fi(file)->fi_bstart = bindex;
  7490. +}
  7491. +
  7492. +static inline void au_set_fbend(struct file *file, aufs_bindex_t bindex)
  7493. +{
  7494. + FiMustWriteLock(file);
  7495. + au_fi(file)->fi_bend = bindex;
  7496. +}
  7497. +
  7498. +static inline void au_set_fvdir_cache(struct file *file,
  7499. + struct au_vdir *vdir_cache)
  7500. +{
  7501. + FiMustWriteLock(file);
  7502. + au_fi(file)->fi_vdir_cache = vdir_cache;
  7503. +}
  7504. +
  7505. +static inline struct file *au_h_fptr(struct file *file, aufs_bindex_t bindex)
  7506. +{
  7507. + FiMustAnyLock(file);
  7508. + return au_fi(file)->fi_hfile[0 + bindex].hf_file;
  7509. +}
  7510. +
  7511. +/* todo: memory barrier? */
  7512. +static inline unsigned int au_figen(struct file *f)
  7513. +{
  7514. + return atomic_read(&au_fi(f)->fi_generation);
  7515. +}
  7516. +
  7517. +static inline int au_test_mmapped(struct file *f)
  7518. +{
  7519. + FiMustAnyLock(f);
  7520. + return !!(au_fi(f)->fi_h_vm_ops);
  7521. +}
  7522. +
  7523. +#endif /* __KERNEL__ */
  7524. +#endif /* __AUFS_FILE_H__ */
  7525. diff -Nur linux-2.6.31.4.orig/fs/aufs/finfo.c linux-2.6.31.4/fs/aufs/finfo.c
  7526. --- linux-2.6.31.4.orig/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100
  7527. +++ linux-2.6.31.4/fs/aufs/finfo.c 2009-10-18 11:26:01.000000000 +0200
  7528. @@ -0,0 +1,133 @@
  7529. +/*
  7530. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  7531. + *
  7532. + * This program, aufs is free software; you can redistribute it and/or modify
  7533. + * it under the terms of the GNU General Public License as published by
  7534. + * the Free Software Foundation; either version 2 of the License, or
  7535. + * (at your option) any later version.
  7536. + *
  7537. + * This program is distributed in the hope that it will be useful,
  7538. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7539. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  7540. + * GNU General Public License for more details.
  7541. + *
  7542. + * You should have received a copy of the GNU General Public License
  7543. + * along with this program; if not, write to the Free Software
  7544. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  7545. + */
  7546. +
  7547. +/*
  7548. + * file private data
  7549. + */
  7550. +
  7551. +#include <linux/file.h>
  7552. +#include "aufs.h"
  7553. +
  7554. +void au_hfput(struct au_hfile *hf, struct file *file)
  7555. +{
  7556. + if (file->f_mode & FMODE_EXEC)
  7557. + allow_write_access(hf->hf_file);
  7558. + fput(hf->hf_file);
  7559. + hf->hf_file = NULL;
  7560. + atomic_dec_return(&hf->hf_br->br_count);
  7561. + hf->hf_br = NULL;
  7562. +}
  7563. +
  7564. +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
  7565. +{
  7566. + struct au_finfo *finfo = au_fi(file);
  7567. + struct au_hfile *hf;
  7568. +
  7569. + hf = finfo->fi_hfile + bindex;
  7570. + if (hf->hf_file)
  7571. + au_hfput(hf, file);
  7572. + if (val) {
  7573. + hf->hf_file = val;
  7574. + hf->hf_br = au_sbr(file->f_dentry->d_sb, bindex);
  7575. + }
  7576. +}
  7577. +
  7578. +void au_update_figen(struct file *file)
  7579. +{
  7580. + atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_dentry));
  7581. + /* smp_mb(); */ /* atomic_set */
  7582. +}
  7583. +
  7584. +/* ---------------------------------------------------------------------- */
  7585. +
  7586. +void au_finfo_fin(struct file *file)
  7587. +{
  7588. + struct au_finfo *finfo;
  7589. + aufs_bindex_t bindex, bend;
  7590. +
  7591. + fi_write_lock(file);
  7592. + bend = au_fbend(file);
  7593. + bindex = au_fbstart(file);
  7594. + if (bindex >= 0)
  7595. + /*
  7596. + * calls fput() instead of filp_close(),
  7597. + * since no dnotify or lock for the lower file.
  7598. + */
  7599. + for (; bindex <= bend; bindex++)
  7600. + au_set_h_fptr(file, bindex, NULL);
  7601. +
  7602. + finfo = au_fi(file);
  7603. + au_dbg_verify_hf(finfo);
  7604. + kfree(finfo->fi_hfile);
  7605. + fi_write_unlock(file);
  7606. + AuRwDestroy(&finfo->fi_rwsem);
  7607. + au_cache_free_finfo(finfo);
  7608. +}
  7609. +
  7610. +int au_finfo_init(struct file *file)
  7611. +{
  7612. + struct au_finfo *finfo;
  7613. + struct dentry *dentry;
  7614. + unsigned long ul;
  7615. +
  7616. + dentry = file->f_dentry;
  7617. + finfo = au_cache_alloc_finfo();
  7618. + if (unlikely(!finfo))
  7619. + goto out;
  7620. +
  7621. + finfo->fi_hfile = kcalloc(au_sbend(dentry->d_sb) + 1,
  7622. + sizeof(*finfo->fi_hfile), GFP_NOFS);
  7623. + if (unlikely(!finfo->fi_hfile))
  7624. + goto out_finfo;
  7625. +
  7626. + au_rw_init_wlock(&finfo->fi_rwsem);
  7627. + finfo->fi_bstart = -1;
  7628. + finfo->fi_bend = -1;
  7629. + atomic_set(&finfo->fi_generation, au_digen(dentry));
  7630. + /* smp_mb(); */ /* atomic_set */
  7631. +
  7632. + /* cf. au_store_oflag() */
  7633. + /* suppress a warning in lp64 */
  7634. + ul = (unsigned long)file->private_data;
  7635. + file->f_mode |= (vfsub_uint_to_fmode(ul) & FMODE_EXEC);
  7636. + file->private_data = finfo;
  7637. + return 0; /* success */
  7638. +
  7639. + out_finfo:
  7640. + au_cache_free_finfo(finfo);
  7641. + out:
  7642. + return -ENOMEM;
  7643. +}
  7644. +
  7645. +int au_fi_realloc(struct au_finfo *finfo, int nbr)
  7646. +{
  7647. + int err, sz;
  7648. + struct au_hfile *hfp;
  7649. +
  7650. + err = -ENOMEM;
  7651. + sz = sizeof(*hfp) * (finfo->fi_bend + 1);
  7652. + if (!sz)
  7653. + sz = sizeof(*hfp);
  7654. + hfp = au_kzrealloc(finfo->fi_hfile, sz, sizeof(*hfp) * nbr, GFP_NOFS);
  7655. + if (hfp) {
  7656. + finfo->fi_hfile = hfp;
  7657. + err = 0;
  7658. + }
  7659. +
  7660. + return err;
  7661. +}
  7662. diff -Nur linux-2.6.31.4.orig/fs/aufs/f_op.c linux-2.6.31.4/fs/aufs/f_op.c
  7663. --- linux-2.6.31.4.orig/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100
  7664. +++ linux-2.6.31.4/fs/aufs/f_op.c 2009-10-18 11:26:01.000000000 +0200
  7665. @@ -0,0 +1,802 @@
  7666. +/*
  7667. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  7668. + *
  7669. + * This program, aufs is free software; you can redistribute it and/or modify
  7670. + * it under the terms of the GNU General Public License as published by
  7671. + * the Free Software Foundation; either version 2 of the License, or
  7672. + * (at your option) any later version.
  7673. + *
  7674. + * This program is distributed in the hope that it will be useful,
  7675. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7676. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  7677. + * GNU General Public License for more details.
  7678. + *
  7679. + * You should have received a copy of the GNU General Public License
  7680. + * along with this program; if not, write to the Free Software
  7681. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  7682. + */
  7683. +
  7684. +/*
  7685. + * file and vm operations
  7686. + */
  7687. +
  7688. +#include <linux/file.h>
  7689. +#include <linux/fs_stack.h>
  7690. +#include <linux/mm.h>
  7691. +#include <linux/security.h>
  7692. +#include "aufs.h"
  7693. +
  7694. +/* common function to regular file and dir */
  7695. +int aufs_flush(struct file *file, fl_owner_t id)
  7696. +{
  7697. + int err;
  7698. + aufs_bindex_t bindex, bend;
  7699. + struct dentry *dentry;
  7700. + struct file *h_file;
  7701. +
  7702. + dentry = file->f_dentry;
  7703. + si_noflush_read_lock(dentry->d_sb);
  7704. + fi_read_lock(file);
  7705. + di_read_lock_child(dentry, AuLock_IW);
  7706. +
  7707. + err = 0;
  7708. + bend = au_fbend(file);
  7709. + for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
  7710. + h_file = au_h_fptr(file, bindex);
  7711. + if (!h_file || !h_file->f_op || !h_file->f_op->flush)
  7712. + continue;
  7713. +
  7714. + err = h_file->f_op->flush(h_file, id);
  7715. + if (!err)
  7716. + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
  7717. + /*ignore*/
  7718. + }
  7719. + au_cpup_attr_timesizes(dentry->d_inode);
  7720. +
  7721. + di_read_unlock(dentry, AuLock_IW);
  7722. + fi_read_unlock(file);
  7723. + si_read_unlock(dentry->d_sb);
  7724. + return err;
  7725. +}
  7726. +
  7727. +/* ---------------------------------------------------------------------- */
  7728. +
  7729. +static int do_open_nondir(struct file *file, int flags)
  7730. +{
  7731. + int err;
  7732. + aufs_bindex_t bindex;
  7733. + struct file *h_file;
  7734. + struct dentry *dentry;
  7735. + struct au_finfo *finfo;
  7736. +
  7737. + FiMustWriteLock(file);
  7738. +
  7739. + err = 0;
  7740. + dentry = file->f_dentry;
  7741. + finfo = au_fi(file);
  7742. + finfo->fi_h_vm_ops = NULL;
  7743. + finfo->fi_vm_ops = NULL;
  7744. + bindex = au_dbstart(dentry);
  7745. + /* O_TRUNC is processed already */
  7746. + BUG_ON(au_test_ro(dentry->d_sb, bindex, dentry->d_inode)
  7747. + && (flags & O_TRUNC));
  7748. +
  7749. + h_file = au_h_open(dentry, bindex, flags, file);
  7750. + if (IS_ERR(h_file))
  7751. + err = PTR_ERR(h_file);
  7752. + else {
  7753. + au_set_fbstart(file, bindex);
  7754. + au_set_fbend(file, bindex);
  7755. + au_set_h_fptr(file, bindex, h_file);
  7756. + au_update_figen(file);
  7757. + /* todo: necessary? */
  7758. + /* file->f_ra = h_file->f_ra; */
  7759. + }
  7760. + return err;
  7761. +}
  7762. +
  7763. +static int aufs_open_nondir(struct inode *inode __maybe_unused,
  7764. + struct file *file)
  7765. +{
  7766. + return au_do_open(file, do_open_nondir);
  7767. +}
  7768. +
  7769. +static int aufs_release_nondir(struct inode *inode __maybe_unused,
  7770. + struct file *file)
  7771. +{
  7772. + struct super_block *sb = file->f_dentry->d_sb;
  7773. +
  7774. + si_noflush_read_lock(sb);
  7775. + kfree(au_fi(file)->fi_vm_ops);
  7776. + au_finfo_fin(file);
  7777. + si_read_unlock(sb);
  7778. + return 0;
  7779. +}
  7780. +
  7781. +/* ---------------------------------------------------------------------- */
  7782. +
  7783. +static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
  7784. + loff_t *ppos)
  7785. +{
  7786. + ssize_t err;
  7787. + struct dentry *dentry;
  7788. + struct file *h_file;
  7789. + struct super_block *sb;
  7790. +
  7791. + dentry = file->f_dentry;
  7792. + sb = dentry->d_sb;
  7793. + si_read_lock(sb, AuLock_FLUSH);
  7794. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
  7795. + if (unlikely(err))
  7796. + goto out;
  7797. +
  7798. + h_file = au_h_fptr(file, au_fbstart(file));
  7799. + err = vfsub_read_u(h_file, buf, count, ppos);
  7800. + /* todo: necessary? */
  7801. + /* file->f_ra = h_file->f_ra; */
  7802. + fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
  7803. +
  7804. + di_read_unlock(dentry, AuLock_IR);
  7805. + fi_read_unlock(file);
  7806. + out:
  7807. + si_read_unlock(sb);
  7808. + return err;
  7809. +}
  7810. +
  7811. +static ssize_t aufs_write(struct file *file, const char __user *ubuf,
  7812. + size_t count, loff_t *ppos)
  7813. +{
  7814. + ssize_t err;
  7815. + aufs_bindex_t bstart;
  7816. + struct au_pin pin;
  7817. + struct dentry *dentry;
  7818. + struct inode *inode;
  7819. + struct super_block *sb;
  7820. + struct file *h_file;
  7821. + char __user *buf = (char __user *)ubuf;
  7822. +
  7823. + dentry = file->f_dentry;
  7824. + sb = dentry->d_sb;
  7825. + inode = dentry->d_inode;
  7826. + mutex_lock(&inode->i_mutex);
  7827. + si_read_lock(sb, AuLock_FLUSH);
  7828. +
  7829. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  7830. + if (unlikely(err))
  7831. + goto out;
  7832. +
  7833. + err = au_ready_to_write(file, -1, &pin);
  7834. + di_downgrade_lock(dentry, AuLock_IR);
  7835. + if (unlikely(err))
  7836. + goto out_unlock;
  7837. +
  7838. + bstart = au_fbstart(file);
  7839. + h_file = au_h_fptr(file, bstart);
  7840. + au_unpin(&pin);
  7841. + err = vfsub_write_u(h_file, buf, count, ppos);
  7842. + au_cpup_attr_timesizes(inode);
  7843. + inode->i_mode = h_file->f_dentry->d_inode->i_mode;
  7844. +
  7845. + out_unlock:
  7846. + di_read_unlock(dentry, AuLock_IR);
  7847. + fi_write_unlock(file);
  7848. + out:
  7849. + si_read_unlock(sb);
  7850. + mutex_unlock(&inode->i_mutex);
  7851. + return err;
  7852. +}
  7853. +
  7854. +static ssize_t aufs_aio_read(struct kiocb *kio, const struct iovec *iov,
  7855. + unsigned long nv, loff_t pos)
  7856. +{
  7857. + ssize_t err;
  7858. + struct file *file, *h_file;
  7859. + struct dentry *dentry;
  7860. + struct super_block *sb;
  7861. +
  7862. + file = kio->ki_filp;
  7863. + dentry = file->f_dentry;
  7864. + sb = dentry->d_sb;
  7865. + si_read_lock(sb, AuLock_FLUSH);
  7866. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
  7867. + if (unlikely(err))
  7868. + goto out;
  7869. +
  7870. + err = -ENOSYS;
  7871. + h_file = au_h_fptr(file, au_fbstart(file));
  7872. + if (h_file->f_op && h_file->f_op->aio_read) {
  7873. + err = security_file_permission(h_file, MAY_READ);
  7874. + if (unlikely(err))
  7875. + goto out_unlock;
  7876. + if (!is_sync_kiocb(kio)) {
  7877. + get_file(h_file);
  7878. + fput(file);
  7879. + }
  7880. + kio->ki_filp = h_file;
  7881. + err = h_file->f_op->aio_read(kio, iov, nv, pos);
  7882. + /* todo: necessary? */
  7883. + /* file->f_ra = h_file->f_ra; */
  7884. + fsstack_copy_attr_atime(dentry->d_inode,
  7885. + h_file->f_dentry->d_inode);
  7886. + } else
  7887. + /* currently there is no such fs */
  7888. + WARN_ON_ONCE(h_file->f_op && h_file->f_op->read);
  7889. +
  7890. + out_unlock:
  7891. + di_read_unlock(dentry, AuLock_IR);
  7892. + fi_read_unlock(file);
  7893. + out:
  7894. + si_read_unlock(sb);
  7895. + return err;
  7896. +}
  7897. +
  7898. +static ssize_t aufs_aio_write(struct kiocb *kio, const struct iovec *iov,
  7899. + unsigned long nv, loff_t pos)
  7900. +{
  7901. + ssize_t err;
  7902. + aufs_bindex_t bstart;
  7903. + struct au_pin pin;
  7904. + struct dentry *dentry;
  7905. + struct inode *inode;
  7906. + struct super_block *sb;
  7907. + struct file *file, *h_file;
  7908. +
  7909. + file = kio->ki_filp;
  7910. + dentry = file->f_dentry;
  7911. + sb = dentry->d_sb;
  7912. + inode = dentry->d_inode;
  7913. + mutex_lock(&inode->i_mutex);
  7914. + si_read_lock(sb, AuLock_FLUSH);
  7915. +
  7916. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  7917. + if (unlikely(err))
  7918. + goto out;
  7919. +
  7920. + err = au_ready_to_write(file, -1, &pin);
  7921. + di_downgrade_lock(dentry, AuLock_IR);
  7922. + if (unlikely(err))
  7923. + goto out_unlock;
  7924. +
  7925. + err = -ENOSYS;
  7926. + bstart = au_fbstart(file);
  7927. + h_file = au_h_fptr(file, bstart);
  7928. + au_unpin(&pin);
  7929. + if (h_file->f_op && h_file->f_op->aio_write) {
  7930. + err = security_file_permission(h_file, MAY_WRITE);
  7931. + if (unlikely(err))
  7932. + goto out_unlock;
  7933. + if (!is_sync_kiocb(kio)) {
  7934. + get_file(h_file);
  7935. + fput(file);
  7936. + }
  7937. + kio->ki_filp = h_file;
  7938. + err = h_file->f_op->aio_write(kio, iov, nv, pos);
  7939. + au_cpup_attr_timesizes(inode);
  7940. + inode->i_mode = h_file->f_dentry->d_inode->i_mode;
  7941. + } else
  7942. + /* currently there is no such fs */
  7943. + WARN_ON_ONCE(h_file->f_op && h_file->f_op->write);
  7944. +
  7945. + out_unlock:
  7946. + di_read_unlock(dentry, AuLock_IR);
  7947. + fi_write_unlock(file);
  7948. + out:
  7949. + si_read_unlock(sb);
  7950. + mutex_unlock(&inode->i_mutex);
  7951. + return err;
  7952. +}
  7953. +
  7954. +static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
  7955. + struct pipe_inode_info *pipe, size_t len,
  7956. + unsigned int flags)
  7957. +{
  7958. + ssize_t err;
  7959. + struct file *h_file;
  7960. + struct dentry *dentry;
  7961. + struct super_block *sb;
  7962. +
  7963. + dentry = file->f_dentry;
  7964. + sb = dentry->d_sb;
  7965. + si_read_lock(sb, AuLock_FLUSH);
  7966. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
  7967. + if (unlikely(err))
  7968. + goto out;
  7969. +
  7970. + err = -EINVAL;
  7971. + h_file = au_h_fptr(file, au_fbstart(file));
  7972. + if (au_test_loopback_kthread()) {
  7973. + file->f_mapping = h_file->f_mapping;
  7974. + smp_mb(); /* unnecessary? */
  7975. + }
  7976. + err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
  7977. + /* todo: necessasry? */
  7978. + /* file->f_ra = h_file->f_ra; */
  7979. + fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
  7980. +
  7981. + di_read_unlock(dentry, AuLock_IR);
  7982. + fi_read_unlock(file);
  7983. +
  7984. + out:
  7985. + si_read_unlock(sb);
  7986. + return err;
  7987. +}
  7988. +
  7989. +static ssize_t
  7990. +aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
  7991. + size_t len, unsigned int flags)
  7992. +{
  7993. + ssize_t err;
  7994. + struct au_pin pin;
  7995. + struct dentry *dentry;
  7996. + struct inode *inode;
  7997. + struct super_block *sb;
  7998. + struct file *h_file;
  7999. +
  8000. + dentry = file->f_dentry;
  8001. + inode = dentry->d_inode;
  8002. + mutex_lock(&inode->i_mutex);
  8003. + sb = dentry->d_sb;
  8004. + si_read_lock(sb, AuLock_FLUSH);
  8005. +
  8006. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  8007. + if (unlikely(err))
  8008. + goto out;
  8009. +
  8010. + err = au_ready_to_write(file, -1, &pin);
  8011. + di_downgrade_lock(dentry, AuLock_IR);
  8012. + if (unlikely(err))
  8013. + goto out_unlock;
  8014. +
  8015. + h_file = au_h_fptr(file, au_fbstart(file));
  8016. + au_unpin(&pin);
  8017. + err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
  8018. + au_cpup_attr_timesizes(inode);
  8019. + inode->i_mode = h_file->f_dentry->d_inode->i_mode;
  8020. +
  8021. + out_unlock:
  8022. + di_read_unlock(dentry, AuLock_IR);
  8023. + fi_write_unlock(file);
  8024. + out:
  8025. + si_read_unlock(sb);
  8026. + mutex_unlock(&inode->i_mutex);
  8027. + return err;
  8028. +}
  8029. +
  8030. +/* ---------------------------------------------------------------------- */
  8031. +
  8032. +static struct file *au_safe_file(struct vm_area_struct *vma)
  8033. +{
  8034. + struct file *file;
  8035. +
  8036. + file = vma->vm_file;
  8037. + if (file->private_data && au_test_aufs(file->f_dentry->d_sb))
  8038. + return file;
  8039. + return NULL;
  8040. +}
  8041. +
  8042. +static void au_reset_file(struct vm_area_struct *vma, struct file *file)
  8043. +{
  8044. + vma->vm_file = file;
  8045. + /* smp_mb(); */ /* flush vm_file */
  8046. +}
  8047. +
  8048. +static int aufs_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
  8049. +{
  8050. + int err;
  8051. + static DECLARE_WAIT_QUEUE_HEAD(wq);
  8052. + struct file *file, *h_file;
  8053. + struct au_finfo *finfo;
  8054. +
  8055. + /* todo: non-robr mode, user vm_file as it is? */
  8056. + wait_event(wq, (file = au_safe_file(vma)));
  8057. +
  8058. + /* do not revalidate, no si lock */
  8059. + finfo = au_fi(file);
  8060. + h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file;
  8061. + AuDebugOn(!h_file || !finfo->fi_h_vm_ops);
  8062. +
  8063. + fi_write_lock(file);
  8064. + vma->vm_file = h_file;
  8065. + err = finfo->fi_h_vm_ops->fault(vma, vmf);
  8066. + /* todo: necessary? */
  8067. + /* file->f_ra = h_file->f_ra; */
  8068. + au_reset_file(vma, file);
  8069. + fi_write_unlock(file);
  8070. +#if 0 /* def CONFIG_SMP */
  8071. + /* wake_up_nr(&wq, online_cpu - 1); */
  8072. + wake_up_all(&wq);
  8073. +#else
  8074. + wake_up(&wq);
  8075. +#endif
  8076. +
  8077. + return err;
  8078. +}
  8079. +
  8080. +static int aufs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
  8081. +{
  8082. + int err;
  8083. + static DECLARE_WAIT_QUEUE_HEAD(wq);
  8084. + struct file *file, *h_file;
  8085. + struct au_finfo *finfo;
  8086. +
  8087. + wait_event(wq, (file = au_safe_file(vma)));
  8088. +
  8089. + finfo = au_fi(file);
  8090. + h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file;
  8091. + AuDebugOn(!h_file || !finfo->fi_h_vm_ops);
  8092. +
  8093. + fi_write_lock(file);
  8094. + vma->vm_file = h_file;
  8095. + err = finfo->fi_h_vm_ops->page_mkwrite(vma, vmf);
  8096. + au_reset_file(vma, file);
  8097. + fi_write_unlock(file);
  8098. + wake_up(&wq);
  8099. +
  8100. + return err;
  8101. +}
  8102. +
  8103. +static void aufs_vm_close(struct vm_area_struct *vma)
  8104. +{
  8105. + static DECLARE_WAIT_QUEUE_HEAD(wq);
  8106. + struct file *file, *h_file;
  8107. + struct au_finfo *finfo;
  8108. +
  8109. + wait_event(wq, (file = au_safe_file(vma)));
  8110. +
  8111. + finfo = au_fi(file);
  8112. + h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file;
  8113. + AuDebugOn(!h_file || !finfo->fi_h_vm_ops);
  8114. +
  8115. + fi_write_lock(file);
  8116. + vma->vm_file = h_file;
  8117. + finfo->fi_h_vm_ops->close(vma);
  8118. + au_reset_file(vma, file);
  8119. + fi_write_unlock(file);
  8120. + wake_up(&wq);
  8121. +}
  8122. +
  8123. +static struct vm_operations_struct aufs_vm_ops = {
  8124. + /* .close and .page_mkwrite are not set by default */
  8125. + .fault = aufs_fault,
  8126. +};
  8127. +
  8128. +/* ---------------------------------------------------------------------- */
  8129. +
  8130. +static struct vm_operations_struct *au_vm_ops(struct file *h_file,
  8131. + struct vm_area_struct *vma)
  8132. +{
  8133. + struct vm_operations_struct *vm_ops;
  8134. + int err;
  8135. +
  8136. + vm_ops = ERR_PTR(-ENODEV);
  8137. + if (!h_file->f_op || !h_file->f_op->mmap)
  8138. + goto out;
  8139. +
  8140. + err = h_file->f_op->mmap(h_file, vma);
  8141. + vm_ops = ERR_PTR(err);
  8142. + if (unlikely(err))
  8143. + goto out;
  8144. +
  8145. + vm_ops = vma->vm_ops;
  8146. + err = do_munmap(current->mm, vma->vm_start,
  8147. + vma->vm_end - vma->vm_start);
  8148. + if (unlikely(err)) {
  8149. + AuIOErr("failed internal unmapping %.*s, %d\n",
  8150. + AuDLNPair(h_file->f_dentry), err);
  8151. + vm_ops = ERR_PTR(-EIO);
  8152. + }
  8153. +
  8154. + out:
  8155. + return vm_ops;
  8156. +}
  8157. +
  8158. +static int au_custom_vm_ops(struct au_finfo *finfo, struct vm_area_struct *vma)
  8159. +{
  8160. + int err;
  8161. + struct vm_operations_struct *h_ops;
  8162. +
  8163. + AuRwMustAnyLock(&finfo->fi_rwsem);
  8164. +
  8165. + err = 0;
  8166. + h_ops = finfo->fi_h_vm_ops;
  8167. + AuDebugOn(!h_ops);
  8168. + if ((!h_ops->page_mkwrite && !h_ops->close)
  8169. + || finfo->fi_vm_ops)
  8170. + goto out;
  8171. +
  8172. + err = -ENOMEM;
  8173. + finfo->fi_vm_ops = kmemdup(&aufs_vm_ops, sizeof(aufs_vm_ops), GFP_NOFS);
  8174. + if (unlikely(!finfo->fi_vm_ops))
  8175. + goto out;
  8176. +
  8177. + err = 0;
  8178. + if (h_ops->page_mkwrite)
  8179. + finfo->fi_vm_ops->page_mkwrite = aufs_page_mkwrite;
  8180. + if (h_ops->close)
  8181. + finfo->fi_vm_ops->close = aufs_vm_close;
  8182. +
  8183. + vma->vm_ops = finfo->fi_vm_ops;
  8184. +
  8185. + out:
  8186. + return err;
  8187. +}
  8188. +
  8189. +static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
  8190. +{
  8191. + int err;
  8192. + unsigned char wlock, mmapped;
  8193. + struct dentry *dentry;
  8194. + struct super_block *sb;
  8195. + struct file *h_file;
  8196. + struct vm_operations_struct *vm_ops;
  8197. +
  8198. + dentry = file->f_dentry;
  8199. + wlock = !!(file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
  8200. + sb = dentry->d_sb;
  8201. + si_read_lock(sb, AuLock_FLUSH);
  8202. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  8203. + if (unlikely(err))
  8204. + goto out;
  8205. +
  8206. + mmapped = !!au_test_mmapped(file);
  8207. + if (wlock) {
  8208. + struct au_pin pin;
  8209. +
  8210. + err = au_ready_to_write(file, -1, &pin);
  8211. + di_downgrade_lock(dentry, AuLock_IR);
  8212. + if (unlikely(err))
  8213. + goto out_unlock;
  8214. + au_unpin(&pin);
  8215. + } else
  8216. + di_downgrade_lock(dentry, AuLock_IR);
  8217. +
  8218. + h_file = au_h_fptr(file, au_fbstart(file));
  8219. + if (!mmapped && au_test_fs_bad_mapping(h_file->f_dentry->d_sb)) {
  8220. + /*
  8221. + * by this assignment, f_mapping will differs from aufs inode
  8222. + * i_mapping.
  8223. + * if someone else mixes the use of f_dentry->d_inode and
  8224. + * f_mapping->host, then a problem may arise.
  8225. + */
  8226. + file->f_mapping = h_file->f_mapping;
  8227. + }
  8228. +
  8229. + vm_ops = NULL;
  8230. + if (!mmapped) {
  8231. + vm_ops = au_vm_ops(h_file, vma);
  8232. + err = PTR_ERR(vm_ops);
  8233. + if (IS_ERR(vm_ops))
  8234. + goto out_unlock;
  8235. + }
  8236. +
  8237. + /*
  8238. + * unnecessary to handle MAP_DENYWRITE and deny_write_access()?
  8239. + * currently MAP_DENYWRITE from userspace is ignored, but elf loader
  8240. + * sets it. when FMODE_EXEC is set (by open_exec() or sys_uselib()),
  8241. + * both of the aufs file and the lower file is deny_write_access()-ed.
  8242. + * finally I hope we can skip handlling MAP_DENYWRITE here.
  8243. + */
  8244. + err = generic_file_mmap(file, vma);
  8245. + if (unlikely(err))
  8246. + goto out_unlock;
  8247. +
  8248. + vma->vm_ops = &aufs_vm_ops;
  8249. + /* test again */
  8250. + if (!au_test_mmapped(file))
  8251. + au_fi(file)->fi_h_vm_ops = vm_ops;
  8252. +
  8253. + err = au_custom_vm_ops(au_fi(file), vma);
  8254. + if (unlikely(err))
  8255. + goto out_unlock;
  8256. +
  8257. + vfsub_file_accessed(h_file);
  8258. + fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
  8259. +
  8260. + out_unlock:
  8261. + di_read_unlock(dentry, AuLock_IR);
  8262. + fi_write_unlock(file);
  8263. + out:
  8264. + si_read_unlock(sb);
  8265. + return err;
  8266. +}
  8267. +
  8268. +/* ---------------------------------------------------------------------- */
  8269. +
  8270. +static int aufs_fsync_nondir(struct file *file, struct dentry *dentry,
  8271. + int datasync)
  8272. +{
  8273. + int err;
  8274. + struct au_pin pin;
  8275. + struct inode *inode;
  8276. + struct file *h_file;
  8277. + struct super_block *sb;
  8278. +
  8279. + inode = dentry->d_inode;
  8280. + IMustLock(file->f_mapping->host);
  8281. + if (inode != file->f_mapping->host) {
  8282. + mutex_unlock(&file->f_mapping->host->i_mutex);
  8283. + mutex_lock(&inode->i_mutex);
  8284. + }
  8285. + IMustLock(inode);
  8286. +
  8287. + sb = dentry->d_sb;
  8288. + si_read_lock(sb, AuLock_FLUSH);
  8289. +
  8290. + err = 0; /* -EBADF; */ /* posix? */
  8291. + if (unlikely(!(file->f_mode & FMODE_WRITE)))
  8292. + goto out;
  8293. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  8294. + if (unlikely(err))
  8295. + goto out;
  8296. +
  8297. + err = au_ready_to_write(file, -1, &pin);
  8298. + di_downgrade_lock(dentry, AuLock_IR);
  8299. + if (unlikely(err))
  8300. + goto out_unlock;
  8301. + au_unpin(&pin);
  8302. +
  8303. + err = -EINVAL;
  8304. + h_file = au_h_fptr(file, au_fbstart(file));
  8305. + if (h_file->f_op && h_file->f_op->fsync) {
  8306. + struct dentry *h_d;
  8307. + struct mutex *h_mtx;
  8308. +
  8309. + /*
  8310. + * no filemap_fdatawrite() since aufs file has no its own
  8311. + * mapping, but dir.
  8312. + */
  8313. + h_d = h_file->f_dentry;
  8314. + h_mtx = &h_d->d_inode->i_mutex;
  8315. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  8316. + err = h_file->f_op->fsync(h_file, h_d, datasync);
  8317. + if (!err)
  8318. + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
  8319. + /*ignore*/
  8320. + au_cpup_attr_timesizes(inode);
  8321. + mutex_unlock(h_mtx);
  8322. + }
  8323. +
  8324. + out_unlock:
  8325. + di_read_unlock(dentry, AuLock_IR);
  8326. + fi_write_unlock(file);
  8327. + out:
  8328. + si_read_unlock(sb);
  8329. + if (inode != file->f_mapping->host) {
  8330. + mutex_unlock(&inode->i_mutex);
  8331. + mutex_lock(&file->f_mapping->host->i_mutex);
  8332. + }
  8333. + return err;
  8334. +}
  8335. +
  8336. +/* no one supports this operation, currently */
  8337. +#if 0
  8338. +static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync)
  8339. +{
  8340. + int err;
  8341. + struct au_pin pin;
  8342. + struct dentry *dentry;
  8343. + struct inode *inode;
  8344. + struct file *file, *h_file;
  8345. + struct super_block *sb;
  8346. +
  8347. + file = kio->ki_filp;
  8348. + dentry = file->f_dentry;
  8349. + inode = dentry->d_inode;
  8350. + mutex_lock(&inode->i_mutex);
  8351. +
  8352. + sb = dentry->d_sb;
  8353. + si_read_lock(sb, AuLock_FLUSH);
  8354. +
  8355. + err = 0; /* -EBADF; */ /* posix? */
  8356. + if (unlikely(!(file->f_mode & FMODE_WRITE)))
  8357. + goto out;
  8358. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  8359. + if (unlikely(err))
  8360. + goto out;
  8361. +
  8362. + err = au_ready_to_write(file, -1, &pin);
  8363. + di_downgrade_lock(dentry, AuLock_IR);
  8364. + if (unlikely(err))
  8365. + goto out_unlock;
  8366. + au_unpin(&pin);
  8367. +
  8368. + err = -ENOSYS;
  8369. + h_file = au_h_fptr(file, au_fbstart(file));
  8370. + if (h_file->f_op && h_file->f_op->aio_fsync) {
  8371. + struct dentry *h_d;
  8372. + struct mutex *h_mtx;
  8373. +
  8374. + h_d = h_file->f_dentry;
  8375. + h_mtx = &h_d->d_inode->i_mutex;
  8376. + if (!is_sync_kiocb(kio)) {
  8377. + get_file(h_file);
  8378. + fput(file);
  8379. + }
  8380. + kio->ki_filp = h_file;
  8381. + err = h_file->f_op->aio_fsync(kio, datasync);
  8382. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  8383. + if (!err)
  8384. + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
  8385. + /*ignore*/
  8386. + au_cpup_attr_timesizes(inode);
  8387. + mutex_unlock(h_mtx);
  8388. + }
  8389. +
  8390. + out_unlock:
  8391. + di_read_unlock(dentry, AuLock_IR);
  8392. + fi_write_unlock(file);
  8393. + out:
  8394. + si_read_unlock(sb);
  8395. + mutex_unlock(&inode->i_mutex);
  8396. + return err;
  8397. +}
  8398. +#endif
  8399. +
  8400. +static int aufs_fasync(int fd, struct file *file, int flag)
  8401. +{
  8402. + int err;
  8403. + struct file *h_file;
  8404. + struct dentry *dentry;
  8405. + struct super_block *sb;
  8406. +
  8407. + dentry = file->f_dentry;
  8408. + sb = dentry->d_sb;
  8409. + si_read_lock(sb, AuLock_FLUSH);
  8410. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
  8411. + if (unlikely(err))
  8412. + goto out;
  8413. +
  8414. + h_file = au_h_fptr(file, au_fbstart(file));
  8415. + if (h_file->f_op && h_file->f_op->fasync)
  8416. + err = h_file->f_op->fasync(fd, h_file, flag);
  8417. +
  8418. + di_read_unlock(dentry, AuLock_IR);
  8419. + fi_read_unlock(file);
  8420. +
  8421. + out:
  8422. + si_read_unlock(sb);
  8423. + return err;
  8424. +}
  8425. +
  8426. +/* ---------------------------------------------------------------------- */
  8427. +
  8428. +/* no one supports this operation, currently */
  8429. +#if 0
  8430. +static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
  8431. + size_t len, loff_t *pos , int more)
  8432. +{
  8433. +}
  8434. +#endif
  8435. +
  8436. +/* ---------------------------------------------------------------------- */
  8437. +
  8438. +const struct file_operations aufs_file_fop = {
  8439. + /*
  8440. + * while generic_file_llseek/_unlocked() don't use BKL,
  8441. + * don't use it since it operates file->f_mapping->host.
  8442. + * in aufs, it may be a real file and may confuse users by UDBA.
  8443. + */
  8444. + /* .llseek = generic_file_llseek, */
  8445. +
  8446. + .read = aufs_read,
  8447. + .write = aufs_write,
  8448. + .aio_read = aufs_aio_read,
  8449. + .aio_write = aufs_aio_write,
  8450. +#ifdef CONFIG_AUFS_POLL
  8451. + .poll = aufs_poll,
  8452. +#endif
  8453. + .mmap = aufs_mmap,
  8454. + .open = aufs_open_nondir,
  8455. + .flush = aufs_flush,
  8456. + .release = aufs_release_nondir,
  8457. + .fsync = aufs_fsync_nondir,
  8458. + /* .aio_fsync = aufs_aio_fsync_nondir, */
  8459. + .fasync = aufs_fasync,
  8460. + /* .sendpage = aufs_sendpage, */
  8461. + .splice_write = aufs_splice_write,
  8462. + .splice_read = aufs_splice_read,
  8463. +#if 0
  8464. + .aio_splice_write = aufs_aio_splice_write,
  8465. + .aio_splice_read = aufs_aio_splice_read
  8466. +#endif
  8467. +};
  8468. diff -Nur linux-2.6.31.4.orig/fs/aufs/fstype.h linux-2.6.31.4/fs/aufs/fstype.h
  8469. --- linux-2.6.31.4.orig/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100
  8470. +++ linux-2.6.31.4/fs/aufs/fstype.h 2009-10-18 11:26:01.000000000 +0200
  8471. @@ -0,0 +1,474 @@
  8472. +/*
  8473. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  8474. + *
  8475. + * This program, aufs is free software; you can redistribute it and/or modify
  8476. + * it under the terms of the GNU General Public License as published by
  8477. + * the Free Software Foundation; either version 2 of the License, or
  8478. + * (at your option) any later version.
  8479. + *
  8480. + * This program is distributed in the hope that it will be useful,
  8481. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  8482. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8483. + * GNU General Public License for more details.
  8484. + *
  8485. + * You should have received a copy of the GNU General Public License
  8486. + * along with this program; if not, write to the Free Software
  8487. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  8488. + */
  8489. +
  8490. +/*
  8491. + * judging filesystem type
  8492. + */
  8493. +
  8494. +#ifndef __AUFS_FSTYPE_H__
  8495. +#define __AUFS_FSTYPE_H__
  8496. +
  8497. +#ifdef __KERNEL__
  8498. +
  8499. +#include <linux/cramfs_fs.h>
  8500. +#include <linux/fs.h>
  8501. +#include <linux/magic.h>
  8502. +#include <linux/romfs_fs.h>
  8503. +#include <linux/aufs_type.h>
  8504. +
  8505. +static inline int au_test_aufs(struct super_block *sb)
  8506. +{
  8507. + return sb->s_magic == AUFS_SUPER_MAGIC;
  8508. +}
  8509. +
  8510. +static inline const char *au_sbtype(struct super_block *sb)
  8511. +{
  8512. + return sb->s_type->name;
  8513. +}
  8514. +
  8515. +static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
  8516. +{
  8517. +#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE)
  8518. + return sb->s_magic == ROMFS_MAGIC;
  8519. +#else
  8520. + return 0;
  8521. +#endif
  8522. +}
  8523. +
  8524. +static inline int au_test_romfs(struct super_block *sb __maybe_unused)
  8525. +{
  8526. +#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE)
  8527. + return sb->s_magic == ISOFS_SUPER_MAGIC;
  8528. +#else
  8529. + return 0;
  8530. +#endif
  8531. +}
  8532. +
  8533. +static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
  8534. +{
  8535. +#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE)
  8536. + return sb->s_magic == CRAMFS_MAGIC;
  8537. +#endif
  8538. + return 0;
  8539. +}
  8540. +
  8541. +static inline int au_test_nfs(struct super_block *sb __maybe_unused)
  8542. +{
  8543. +#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE)
  8544. + return sb->s_magic == NFS_SUPER_MAGIC;
  8545. +#else
  8546. + return 0;
  8547. +#endif
  8548. +}
  8549. +
  8550. +static inline int au_test_fuse(struct super_block *sb __maybe_unused)
  8551. +{
  8552. +#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE)
  8553. + return sb->s_magic == FUSE_SUPER_MAGIC;
  8554. +#else
  8555. + return 0;
  8556. +#endif
  8557. +}
  8558. +
  8559. +static inline int au_test_xfs(struct super_block *sb __maybe_unused)
  8560. +{
  8561. +#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE)
  8562. + return sb->s_magic == XFS_SB_MAGIC;
  8563. +#else
  8564. + return 0;
  8565. +#endif
  8566. +}
  8567. +
  8568. +static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
  8569. +{
  8570. +#ifdef CONFIG_TMPFS
  8571. + return sb->s_magic == TMPFS_MAGIC;
  8572. +#else
  8573. + return 0;
  8574. +#endif
  8575. +}
  8576. +
  8577. +static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
  8578. +{
  8579. +#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE)
  8580. + return !strcmp(au_sbtype(sb), "ecryptfs");
  8581. +#else
  8582. + return 0;
  8583. +#endif
  8584. +}
  8585. +
  8586. +static inline int au_test_smbfs(struct super_block *sb __maybe_unused)
  8587. +{
  8588. +#if defined(CONFIG_SMB_FS) || defined(CONFIG_SMB_FS_MODULE)
  8589. + return sb->s_magic == SMB_SUPER_MAGIC;
  8590. +#else
  8591. + return 0;
  8592. +#endif
  8593. +}
  8594. +
  8595. +static inline int au_test_ocfs2(struct super_block *sb __maybe_unused)
  8596. +{
  8597. +#if defined(CONFIG_OCFS2_FS) || defined(CONFIG_OCFS2_FS_MODULE)
  8598. + return sb->s_magic == OCFS2_SUPER_MAGIC;
  8599. +#else
  8600. + return 0;
  8601. +#endif
  8602. +}
  8603. +
  8604. +static inline int au_test_ocfs2_dlmfs(struct super_block *sb __maybe_unused)
  8605. +{
  8606. +#if defined(CONFIG_OCFS2_FS_O2CB) || defined(CONFIG_OCFS2_FS_O2CB_MODULE)
  8607. + return sb->s_magic == DLMFS_MAGIC;
  8608. +#else
  8609. + return 0;
  8610. +#endif
  8611. +}
  8612. +
  8613. +static inline int au_test_coda(struct super_block *sb __maybe_unused)
  8614. +{
  8615. +#if defined(CONFIG_CODA_FS) || defined(CONFIG_CODA_FS_MODULE)
  8616. + return sb->s_magic == CODA_SUPER_MAGIC;
  8617. +#else
  8618. + return 0;
  8619. +#endif
  8620. +}
  8621. +
  8622. +static inline int au_test_v9fs(struct super_block *sb __maybe_unused)
  8623. +{
  8624. +#if defined(CONFIG_9P_FS) || defined(CONFIG_9P_FS_MODULE)
  8625. + return sb->s_magic == V9FS_MAGIC;
  8626. +#else
  8627. + return 0;
  8628. +#endif
  8629. +}
  8630. +
  8631. +static inline int au_test_ext4(struct super_block *sb __maybe_unused)
  8632. +{
  8633. +#if defined(CONFIG_EXT4DEV_FS) || defined(CONFIG_EXT4DEV_FS_MODULE)
  8634. + return sb->s_magic == EXT4_SUPER_MAGIC;
  8635. +#else
  8636. + return 0;
  8637. +#endif
  8638. +}
  8639. +
  8640. +static inline int au_test_sysv(struct super_block *sb __maybe_unused)
  8641. +{
  8642. +#if defined(CONFIG_SYSV_FS) || defined(CONFIG_SYSV_FS_MODULE)
  8643. + return !strcmp(au_sbtype(sb), "sysv");
  8644. +#else
  8645. + return 0;
  8646. +#endif
  8647. +}
  8648. +
  8649. +static inline int au_test_ramfs(struct super_block *sb)
  8650. +{
  8651. + return sb->s_magic == RAMFS_MAGIC;
  8652. +}
  8653. +
  8654. +static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
  8655. +{
  8656. +#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE)
  8657. + return sb->s_magic == UBIFS_SUPER_MAGIC;
  8658. +#else
  8659. + return 0;
  8660. +#endif
  8661. +}
  8662. +
  8663. +static inline int au_test_procfs(struct super_block *sb __maybe_unused)
  8664. +{
  8665. +#ifdef CONFIG_PROC_FS
  8666. + return sb->s_magic == PROC_SUPER_MAGIC;
  8667. +#else
  8668. + return 0;
  8669. +#endif
  8670. +}
  8671. +
  8672. +static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
  8673. +{
  8674. +#ifdef CONFIG_SYSFS
  8675. + return sb->s_magic == SYSFS_MAGIC;
  8676. +#else
  8677. + return 0;
  8678. +#endif
  8679. +}
  8680. +
  8681. +static inline int au_test_configfs(struct super_block *sb __maybe_unused)
  8682. +{
  8683. +#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE)
  8684. + return sb->s_magic == CONFIGFS_MAGIC;
  8685. +#else
  8686. + return 0;
  8687. +#endif
  8688. +}
  8689. +
  8690. +static inline int au_test_minix(struct super_block *sb __maybe_unused)
  8691. +{
  8692. +#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE)
  8693. + return sb->s_magic == MINIX3_SUPER_MAGIC
  8694. + || sb->s_magic == MINIX2_SUPER_MAGIC
  8695. + || sb->s_magic == MINIX2_SUPER_MAGIC2
  8696. + || sb->s_magic == MINIX_SUPER_MAGIC
  8697. + || sb->s_magic == MINIX_SUPER_MAGIC2;
  8698. +#else
  8699. + return 0;
  8700. +#endif
  8701. +}
  8702. +
  8703. +static inline int au_test_cifs(struct super_block *sb __maybe_unused)
  8704. +{
  8705. +#if defined(CONFIG_CIFS_FS) || defined(CONFIGCIFS_FS_MODULE)
  8706. + return sb->s_magic == CIFS_MAGIC_NUMBER;
  8707. +#else
  8708. + return 0;
  8709. +#endif
  8710. +}
  8711. +
  8712. +static inline int au_test_fat(struct super_block *sb __maybe_unused)
  8713. +{
  8714. +#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE)
  8715. + return sb->s_magic == MSDOS_SUPER_MAGIC;
  8716. +#else
  8717. + return 0;
  8718. +#endif
  8719. +}
  8720. +
  8721. +static inline int au_test_msdos(struct super_block *sb)
  8722. +{
  8723. + return au_test_fat(sb);
  8724. +}
  8725. +
  8726. +static inline int au_test_vfat(struct super_block *sb)
  8727. +{
  8728. + return au_test_fat(sb);
  8729. +}
  8730. +
  8731. +static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
  8732. +{
  8733. +#ifdef CONFIG_SECURITYFS
  8734. + return sb->s_magic == SECURITYFS_MAGIC;
  8735. +#else
  8736. + return 0;
  8737. +#endif
  8738. +}
  8739. +
  8740. +static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
  8741. +{
  8742. +#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE)
  8743. + return sb->s_magic == SQUASHFS_MAGIC;
  8744. +#else
  8745. + return 0;
  8746. +#endif
  8747. +}
  8748. +
  8749. +static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
  8750. +{
  8751. +#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE)
  8752. + return sb->s_magic == BTRFS_SUPER_MAGIC;
  8753. +#else
  8754. + return 0;
  8755. +#endif
  8756. +}
  8757. +
  8758. +static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
  8759. +{
  8760. +#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE)
  8761. + return sb->s_magic == XENFS_SUPER_MAGIC;
  8762. +#else
  8763. + return 0;
  8764. +#endif
  8765. +}
  8766. +
  8767. +static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
  8768. +{
  8769. +#ifdef CONFIG_DEBUG_FS
  8770. + return sb->s_magic == DEBUGFS_MAGIC;
  8771. +#else
  8772. + return 0;
  8773. +#endif
  8774. +}
  8775. +
  8776. +/* ---------------------------------------------------------------------- */
  8777. +/*
  8778. + * they can't be an aufs branch.
  8779. + */
  8780. +static inline int au_test_fs_unsuppoted(struct super_block *sb)
  8781. +{
  8782. + return
  8783. +#ifndef CONFIG_AUFS_BR_RAMFS
  8784. + au_test_ramfs(sb) ||
  8785. +#endif
  8786. + au_test_procfs(sb)
  8787. + || au_test_sysfs(sb)
  8788. + || au_test_configfs(sb)
  8789. + || au_test_debugfs(sb)
  8790. + || au_test_securityfs(sb)
  8791. + || au_test_xenfs(sb)
  8792. + /* || !strcmp(au_sbtype(sb), "unionfs") */
  8793. + || au_test_aufs(sb); /* will be supported in next version */
  8794. +}
  8795. +
  8796. +/*
  8797. + * If the filesystem supports NFS-export, then it has to support NULL as
  8798. + * a nameidata parameter for ->create(), ->lookup() and ->d_revalidate().
  8799. + * We can apply this principle when we handle a lower filesystem.
  8800. + */
  8801. +static inline int au_test_fs_null_nd(struct super_block *sb)
  8802. +{
  8803. + return !!sb->s_export_op;
  8804. +}
  8805. +
  8806. +static inline int au_test_fs_remote(struct super_block *sb)
  8807. +{
  8808. + return !au_test_tmpfs(sb)
  8809. +#ifdef CONFIG_AUFS_BR_RAMFS
  8810. + && !au_test_ramfs(sb)
  8811. +#endif
  8812. + && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
  8813. +}
  8814. +
  8815. +/* ---------------------------------------------------------------------- */
  8816. +
  8817. +/*
  8818. + * Note: these functions (below) are created after reading ->getattr() in all
  8819. + * filesystems under linux/fs. it means we have to do so in every update...
  8820. + */
  8821. +
  8822. +/*
  8823. + * some filesystems require getattr to refresh the inode attributes before
  8824. + * referencing.
  8825. + * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
  8826. + * and leave the work for d_revalidate()
  8827. + */
  8828. +static inline int au_test_fs_refresh_iattr(struct super_block *sb)
  8829. +{
  8830. + return au_test_nfs(sb)
  8831. + || au_test_fuse(sb)
  8832. + /* || au_test_smbfs(sb) */ /* untested */
  8833. + /* || au_test_ocfs2(sb) */ /* untested */
  8834. + /* || au_test_btrfs(sb) */ /* untested */
  8835. + /* || au_test_coda(sb) */ /* untested */
  8836. + /* || au_test_v9fs(sb) */ /* untested */
  8837. + ;
  8838. +}
  8839. +
  8840. +/*
  8841. + * filesystems which don't maintain i_size or i_blocks.
  8842. + */
  8843. +static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
  8844. +{
  8845. + return au_test_xfs(sb)
  8846. + /* || au_test_ext4(sb) */ /* untested */
  8847. + /* || au_test_ocfs2(sb) */ /* untested */
  8848. + /* || au_test_ocfs2_dlmfs(sb) */ /* untested */
  8849. + /* || au_test_sysv(sb) */ /* untested */
  8850. + /* || au_test_ubifs(sb) */ /* untested */
  8851. + /* || au_test_minix(sb) */ /* untested */
  8852. + ;
  8853. +}
  8854. +
  8855. +/*
  8856. + * filesystems which don't store the correct value in some of their inode
  8857. + * attributes.
  8858. + */
  8859. +static inline int au_test_fs_bad_iattr(struct super_block *sb)
  8860. +{
  8861. + return au_test_fs_bad_iattr_size(sb)
  8862. + /* || au_test_cifs(sb) */ /* untested */
  8863. + || au_test_fat(sb)
  8864. + || au_test_msdos(sb)
  8865. + || au_test_vfat(sb);
  8866. +}
  8867. +
  8868. +/* they don't check i_nlink in link(2) */
  8869. +static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
  8870. +{
  8871. + return au_test_tmpfs(sb)
  8872. +#ifdef CONFIG_AUFS_BR_RAMFS
  8873. + || au_test_ramfs(sb)
  8874. +#endif
  8875. + || au_test_ubifs(sb);
  8876. +}
  8877. +
  8878. +/*
  8879. + * filesystems which sets S_NOATIME and S_NOCMTIME.
  8880. + */
  8881. +static inline int au_test_fs_notime(struct super_block *sb)
  8882. +{
  8883. + return au_test_nfs(sb)
  8884. + || au_test_fuse(sb)
  8885. + || au_test_ubifs(sb)
  8886. + /* || au_test_cifs(sb) */ /* untested */
  8887. + ;
  8888. +}
  8889. +
  8890. +/*
  8891. + * filesystems which requires replacing i_mapping.
  8892. + */
  8893. +static inline int au_test_fs_bad_mapping(struct super_block *sb)
  8894. +{
  8895. + return au_test_fuse(sb)
  8896. + || au_test_ubifs(sb);
  8897. +}
  8898. +
  8899. +/* temporary support for i#1 in cramfs */
  8900. +static inline int au_test_fs_unique_ino(struct inode *inode)
  8901. +{
  8902. + if (au_test_cramfs(inode->i_sb))
  8903. + return inode->i_ino != 1;
  8904. + return 1;
  8905. +}
  8906. +
  8907. +/* ---------------------------------------------------------------------- */
  8908. +
  8909. +/*
  8910. + * the filesystem where the xino files placed must support i/o after unlink and
  8911. + * maintain i_size and i_blocks.
  8912. + */
  8913. +static inline int au_test_fs_bad_xino(struct super_block *sb)
  8914. +{
  8915. + return au_test_fs_remote(sb)
  8916. + || au_test_fs_bad_iattr_size(sb)
  8917. +#ifdef CONFIG_AUFS_BR_RAMFS
  8918. + || !(au_test_ramfs(sb) || au_test_fs_null_nd(sb))
  8919. +#else
  8920. + || !au_test_fs_null_nd(sb) /* to keep xino code simple */
  8921. +#endif
  8922. + /* don't want unnecessary work for xino */
  8923. + || au_test_aufs(sb)
  8924. + || au_test_ecryptfs(sb);
  8925. +}
  8926. +
  8927. +static inline int au_test_fs_trunc_xino(struct super_block *sb)
  8928. +{
  8929. + return au_test_tmpfs(sb)
  8930. + || au_test_ramfs(sb);
  8931. +}
  8932. +
  8933. +/*
  8934. + * test if the @sb is real-readonly.
  8935. + */
  8936. +static inline int au_test_fs_rr(struct super_block *sb)
  8937. +{
  8938. + return au_test_squashfs(sb)
  8939. + || au_test_iso9660(sb)
  8940. + || au_test_cramfs(sb)
  8941. + || au_test_romfs(sb);
  8942. +}
  8943. +
  8944. +#endif /* __KERNEL__ */
  8945. +#endif /* __AUFS_FSTYPE_H__ */
  8946. diff -Nur linux-2.6.31.4.orig/fs/aufs/hinotify.c linux-2.6.31.4/fs/aufs/hinotify.c
  8947. --- linux-2.6.31.4.orig/fs/aufs/hinotify.c 1970-01-01 01:00:00.000000000 +0100
  8948. +++ linux-2.6.31.4/fs/aufs/hinotify.c 2009-10-18 11:26:01.000000000 +0200
  8949. @@ -0,0 +1,755 @@
  8950. +/*
  8951. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  8952. + *
  8953. + * This program, aufs is free software; you can redistribute it and/or modify
  8954. + * it under the terms of the GNU General Public License as published by
  8955. + * the Free Software Foundation; either version 2 of the License, or
  8956. + * (at your option) any later version.
  8957. + *
  8958. + * This program is distributed in the hope that it will be useful,
  8959. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  8960. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8961. + * GNU General Public License for more details.
  8962. + *
  8963. + * You should have received a copy of the GNU General Public License
  8964. + * along with this program; if not, write to the Free Software
  8965. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  8966. + */
  8967. +
  8968. +/*
  8969. + * inotify for the lower directories
  8970. + */
  8971. +
  8972. +#include "aufs.h"
  8973. +
  8974. +static const __u32 AuHinMask = (IN_MOVE | IN_DELETE | IN_CREATE);
  8975. +static struct inotify_handle *au_hin_handle;
  8976. +
  8977. +AuCacheFuncs(hinotify, HINOTIFY);
  8978. +
  8979. +int au_hin_alloc(struct au_hinode *hinode, struct inode *inode,
  8980. + struct inode *h_inode)
  8981. +{
  8982. + int err;
  8983. + struct au_hinotify *hin;
  8984. + s32 wd;
  8985. +
  8986. + err = -ENOMEM;
  8987. + hin = au_cache_alloc_hinotify();
  8988. + if (hin) {
  8989. + AuDebugOn(hinode->hi_notify);
  8990. + hinode->hi_notify = hin;
  8991. + hin->hin_aufs_inode = inode;
  8992. +
  8993. + inotify_init_watch(&hin->hin_watch);
  8994. + wd = inotify_add_watch(au_hin_handle, &hin->hin_watch, h_inode,
  8995. + AuHinMask);
  8996. + if (wd >= 0)
  8997. + return 0; /* success */
  8998. +
  8999. + err = wd;
  9000. + put_inotify_watch(&hin->hin_watch);
  9001. + au_cache_free_hinotify(hin);
  9002. + hinode->hi_notify = NULL;
  9003. + }
  9004. +
  9005. + return err;
  9006. +}
  9007. +
  9008. +void au_hin_free(struct au_hinode *hinode)
  9009. +{
  9010. + int err;
  9011. + struct au_hinotify *hin;
  9012. +
  9013. + hin = hinode->hi_notify;
  9014. + if (hin) {
  9015. + err = 0;
  9016. + if (atomic_read(&hin->hin_watch.count))
  9017. + err = inotify_rm_watch(au_hin_handle, &hin->hin_watch);
  9018. + if (unlikely(err))
  9019. + /* it means the watch is already removed */
  9020. + AuWarn("failed inotify_rm_watch() %d\n", err);
  9021. + au_cache_free_hinotify(hin);
  9022. + hinode->hi_notify = NULL;
  9023. + }
  9024. +}
  9025. +
  9026. +/* ---------------------------------------------------------------------- */
  9027. +
  9028. +void au_hin_ctl(struct au_hinode *hinode, int do_set)
  9029. +{
  9030. + struct inode *h_inode;
  9031. + struct inotify_watch *watch;
  9032. +
  9033. + if (!hinode->hi_notify)
  9034. + return;
  9035. +
  9036. + h_inode = hinode->hi_inode;
  9037. + IMustLock(h_inode);
  9038. +
  9039. + /* todo: try inotify_find_update_watch()? */
  9040. + watch = &hinode->hi_notify->hin_watch;
  9041. + mutex_lock(&h_inode->inotify_mutex);
  9042. + /* mutex_lock(&watch->ih->mutex); */
  9043. + if (do_set) {
  9044. + AuDebugOn(watch->mask & AuHinMask);
  9045. + watch->mask |= AuHinMask;
  9046. + } else {
  9047. + AuDebugOn(!(watch->mask & AuHinMask));
  9048. + watch->mask &= ~AuHinMask;
  9049. + }
  9050. + /* mutex_unlock(&watch->ih->mutex); */
  9051. + mutex_unlock(&h_inode->inotify_mutex);
  9052. +}
  9053. +
  9054. +void au_reset_hinotify(struct inode *inode, unsigned int flags)
  9055. +{
  9056. + aufs_bindex_t bindex, bend;
  9057. + struct inode *hi;
  9058. + struct dentry *iwhdentry;
  9059. +
  9060. + bend = au_ibend(inode);
  9061. + for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
  9062. + hi = au_h_iptr(inode, bindex);
  9063. + if (!hi)
  9064. + continue;
  9065. +
  9066. + /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */
  9067. + iwhdentry = au_hi_wh(inode, bindex);
  9068. + if (iwhdentry)
  9069. + dget(iwhdentry);
  9070. + au_igrab(hi);
  9071. + au_set_h_iptr(inode, bindex, NULL, 0);
  9072. + au_set_h_iptr(inode, bindex, au_igrab(hi),
  9073. + flags & ~AuHi_XINO);
  9074. + iput(hi);
  9075. + dput(iwhdentry);
  9076. + /* mutex_unlock(&hi->i_mutex); */
  9077. + }
  9078. +}
  9079. +
  9080. +/* ---------------------------------------------------------------------- */
  9081. +
  9082. +static int hin_xino(struct inode *inode, struct inode *h_inode)
  9083. +{
  9084. + int err;
  9085. + aufs_bindex_t bindex, bend, bfound, bstart;
  9086. + struct inode *h_i;
  9087. +
  9088. + err = 0;
  9089. + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
  9090. + AuWarn("branch root dir was changed\n");
  9091. + goto out;
  9092. + }
  9093. +
  9094. + bfound = -1;
  9095. + bend = au_ibend(inode);
  9096. + bstart = au_ibstart(inode);
  9097. +#if 0 /* reserved for future use */
  9098. + if (bindex == bend) {
  9099. + /* keep this ino in rename case */
  9100. + goto out;
  9101. + }
  9102. +#endif
  9103. + for (bindex = bstart; bindex <= bend; bindex++) {
  9104. + if (au_h_iptr(inode, bindex) == h_inode) {
  9105. + bfound = bindex;
  9106. + break;
  9107. + }
  9108. + }
  9109. + if (bfound < 0)
  9110. + goto out;
  9111. +
  9112. + for (bindex = bstart; bindex <= bend; bindex++) {
  9113. + h_i = au_h_iptr(inode, bindex);
  9114. + if (!h_i)
  9115. + continue;
  9116. +
  9117. + err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
  9118. + /* ignore this error */
  9119. + /* bad action? */
  9120. + }
  9121. +
  9122. + /* children inode number will be broken */
  9123. +
  9124. + out:
  9125. + AuTraceErr(err);
  9126. + return err;
  9127. +}
  9128. +
  9129. +static int hin_gen_tree(struct dentry *dentry)
  9130. +{
  9131. + int err, i, j, ndentry;
  9132. + struct au_dcsub_pages dpages;
  9133. + struct au_dpage *dpage;
  9134. + struct dentry **dentries;
  9135. +
  9136. + err = au_dpages_init(&dpages, GFP_NOFS);
  9137. + if (unlikely(err))
  9138. + goto out;
  9139. + err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
  9140. + if (unlikely(err))
  9141. + goto out_dpages;
  9142. +
  9143. + for (i = 0; i < dpages.ndpage; i++) {
  9144. + dpage = dpages.dpages + i;
  9145. + dentries = dpage->dentries;
  9146. + ndentry = dpage->ndentry;
  9147. + for (j = 0; j < ndentry; j++) {
  9148. + struct dentry *d;
  9149. +
  9150. + d = dentries[j];
  9151. + if (IS_ROOT(d))
  9152. + continue;
  9153. +
  9154. + d_drop(d);
  9155. + au_digen_dec(d);
  9156. + if (d->d_inode)
  9157. + /* todo: reset children xino?
  9158. + cached children only? */
  9159. + au_iigen_dec(d->d_inode);
  9160. + }
  9161. + }
  9162. +
  9163. + out_dpages:
  9164. + au_dpages_free(&dpages);
  9165. +
  9166. + /* discard children */
  9167. + dentry_unhash(dentry);
  9168. + dput(dentry);
  9169. + out:
  9170. + return err;
  9171. +}
  9172. +
  9173. +/*
  9174. + * return 0 if processed.
  9175. + */
  9176. +static int hin_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
  9177. + const unsigned int isdir)
  9178. +{
  9179. + int err;
  9180. + struct dentry *d;
  9181. + struct qstr *dname;
  9182. +
  9183. + err = 1;
  9184. + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
  9185. + AuWarn("branch root dir was changed\n");
  9186. + err = 0;
  9187. + goto out;
  9188. + }
  9189. +
  9190. + if (!isdir) {
  9191. + AuDebugOn(!name);
  9192. + au_iigen_dec(inode);
  9193. + spin_lock(&dcache_lock);
  9194. + list_for_each_entry(d, &inode->i_dentry, d_alias) {
  9195. + dname = &d->d_name;
  9196. + if (dname->len != nlen
  9197. + && memcmp(dname->name, name, nlen))
  9198. + continue;
  9199. + err = 0;
  9200. + spin_lock(&d->d_lock);
  9201. + __d_drop(d);
  9202. + au_digen_dec(d);
  9203. + spin_unlock(&d->d_lock);
  9204. + break;
  9205. + }
  9206. + spin_unlock(&dcache_lock);
  9207. + } else {
  9208. + au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIRS);
  9209. + d = d_find_alias(inode);
  9210. + if (!d) {
  9211. + au_iigen_dec(inode);
  9212. + goto out;
  9213. + }
  9214. +
  9215. + dname = &d->d_name;
  9216. + if (dname->len == nlen && !memcmp(dname->name, name, nlen))
  9217. + err = hin_gen_tree(d);
  9218. + dput(d);
  9219. + }
  9220. +
  9221. + out:
  9222. + AuTraceErr(err);
  9223. + return err;
  9224. +}
  9225. +
  9226. +static int hin_gen_by_name(struct dentry *dentry, const unsigned int isdir)
  9227. +{
  9228. + int err;
  9229. + struct inode *inode;
  9230. +
  9231. + inode = dentry->d_inode;
  9232. + if (IS_ROOT(dentry)
  9233. + /* || (inode && inode->i_ino == AUFS_ROOT_INO) */
  9234. + ) {
  9235. + AuWarn("branch root dir was changed\n");
  9236. + return 0;
  9237. + }
  9238. +
  9239. + err = 0;
  9240. + if (!isdir) {
  9241. + d_drop(dentry);
  9242. + au_digen_dec(dentry);
  9243. + if (inode)
  9244. + au_iigen_dec(inode);
  9245. + } else {
  9246. + au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS);
  9247. + if (inode)
  9248. + err = hin_gen_tree(dentry);
  9249. + }
  9250. +
  9251. + AuTraceErr(err);
  9252. + return err;
  9253. +}
  9254. +
  9255. +/* ---------------------------------------------------------------------- */
  9256. +
  9257. +/* hinotify job flags */
  9258. +#define AuHinJob_XINO0 1
  9259. +#define AuHinJob_GEN (1 << 1)
  9260. +#define AuHinJob_DIRENT (1 << 2)
  9261. +#define AuHinJob_ISDIR (1 << 3)
  9262. +#define AuHinJob_TRYXINO0 (1 << 4)
  9263. +#define AuHinJob_MNTPNT (1 << 5)
  9264. +#define au_ftest_hinjob(flags, name) ((flags) & AuHinJob_##name)
  9265. +#define au_fset_hinjob(flags, name) { (flags) |= AuHinJob_##name; }
  9266. +#define au_fclr_hinjob(flags, name) { (flags) &= ~AuHinJob_##name; }
  9267. +
  9268. +struct hin_job_args {
  9269. + unsigned int flags;
  9270. + struct inode *inode, *h_inode, *dir, *h_dir;
  9271. + struct dentry *dentry;
  9272. + char *h_name;
  9273. + int h_nlen;
  9274. +};
  9275. +
  9276. +static int hin_job(struct hin_job_args *a)
  9277. +{
  9278. + const unsigned int isdir = au_ftest_hinjob(a->flags, ISDIR);
  9279. +
  9280. + /* reset xino */
  9281. + if (au_ftest_hinjob(a->flags, XINO0) && a->inode)
  9282. + hin_xino(a->inode, a->h_inode); /* ignore this error */
  9283. +
  9284. + if (au_ftest_hinjob(a->flags, TRYXINO0)
  9285. + && a->inode
  9286. + && a->h_inode) {
  9287. + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
  9288. + if (!a->h_inode->i_nlink)
  9289. + hin_xino(a->inode, a->h_inode); /* ignore this error */
  9290. + mutex_unlock(&a->h_inode->i_mutex);
  9291. + }
  9292. +
  9293. + /* make the generation obsolete */
  9294. + if (au_ftest_hinjob(a->flags, GEN)) {
  9295. + int err = -1;
  9296. + if (a->inode)
  9297. + err = hin_gen_by_inode(a->h_name, a->h_nlen, a->inode,
  9298. + isdir);
  9299. + if (err && a->dentry)
  9300. + hin_gen_by_name(a->dentry, isdir);
  9301. + /* ignore this error */
  9302. + }
  9303. +
  9304. + /* make dir entries obsolete */
  9305. + if (au_ftest_hinjob(a->flags, DIRENT) && a->inode) {
  9306. + struct au_vdir *vdir;
  9307. +
  9308. + vdir = au_ivdir(a->inode);
  9309. + if (vdir)
  9310. + vdir->vd_jiffy = 0;
  9311. + /* IMustLock(a->inode); */
  9312. + /* a->inode->i_version++; */
  9313. + }
  9314. +
  9315. + /* can do nothing but warn */
  9316. + if (au_ftest_hinjob(a->flags, MNTPNT)
  9317. + && a->dentry
  9318. + && d_mountpoint(a->dentry))
  9319. + AuWarn("mount-point %.*s is removed or renamed\n",
  9320. + AuDLNPair(a->dentry));
  9321. +
  9322. + return 0;
  9323. +}
  9324. +
  9325. +/* ---------------------------------------------------------------------- */
  9326. +
  9327. +static char *in_name(u32 mask)
  9328. +{
  9329. +#ifdef CONFIG_AUFS_DEBUG
  9330. +#define test_ret(flag) if (mask & flag) \
  9331. + return #flag;
  9332. + test_ret(IN_ACCESS);
  9333. + test_ret(IN_MODIFY);
  9334. + test_ret(IN_ATTRIB);
  9335. + test_ret(IN_CLOSE_WRITE);
  9336. + test_ret(IN_CLOSE_NOWRITE);
  9337. + test_ret(IN_OPEN);
  9338. + test_ret(IN_MOVED_FROM);
  9339. + test_ret(IN_MOVED_TO);
  9340. + test_ret(IN_CREATE);
  9341. + test_ret(IN_DELETE);
  9342. + test_ret(IN_DELETE_SELF);
  9343. + test_ret(IN_MOVE_SELF);
  9344. + test_ret(IN_UNMOUNT);
  9345. + test_ret(IN_Q_OVERFLOW);
  9346. + test_ret(IN_IGNORED);
  9347. + return "";
  9348. +#undef test_ret
  9349. +#else
  9350. + return "??";
  9351. +#endif
  9352. +}
  9353. +
  9354. +static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
  9355. + struct inode *dir)
  9356. +{
  9357. + struct dentry *dentry, *d, *parent;
  9358. + struct qstr *dname;
  9359. +
  9360. + parent = d_find_alias(dir);
  9361. + if (!parent)
  9362. + return NULL;
  9363. +
  9364. + dentry = NULL;
  9365. + spin_lock(&dcache_lock);
  9366. + list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) {
  9367. + /* AuDbg("%.*s\n", AuDLNPair(d)); */
  9368. + dname = &d->d_name;
  9369. + if (dname->len != nlen || memcmp(dname->name, name, nlen))
  9370. + continue;
  9371. + if (!atomic_read(&d->d_count) || !d->d_fsdata) {
  9372. + spin_lock(&d->d_lock);
  9373. + __d_drop(d);
  9374. + spin_unlock(&d->d_lock);
  9375. + continue;
  9376. + }
  9377. +
  9378. + dentry = dget(d);
  9379. + break;
  9380. + }
  9381. + spin_unlock(&dcache_lock);
  9382. + dput(parent);
  9383. +
  9384. + if (dentry)
  9385. + di_write_lock_child(dentry);
  9386. +
  9387. + return dentry;
  9388. +}
  9389. +
  9390. +static struct inode *lookup_wlock_by_ino(struct super_block *sb,
  9391. + aufs_bindex_t bindex, ino_t h_ino)
  9392. +{
  9393. + struct inode *inode;
  9394. + ino_t ino;
  9395. + int err;
  9396. +
  9397. + inode = NULL;
  9398. + err = au_xino_read(sb, bindex, h_ino, &ino);
  9399. + if (!err && ino)
  9400. + inode = ilookup(sb, ino);
  9401. + if (!inode)
  9402. + goto out;
  9403. +
  9404. + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
  9405. + AuWarn("wrong root branch\n");
  9406. + iput(inode);
  9407. + inode = NULL;
  9408. + goto out;
  9409. + }
  9410. +
  9411. + ii_write_lock_child(inode);
  9412. +
  9413. + out:
  9414. + return inode;
  9415. +}
  9416. +
  9417. +enum { CHILD, PARENT };
  9418. +struct postproc_args {
  9419. + struct inode *h_dir, *dir, *h_child_inode;
  9420. + u32 mask;
  9421. + unsigned int flags[2];
  9422. + unsigned int h_child_nlen;
  9423. + char h_child_name[];
  9424. +};
  9425. +
  9426. +static void postproc(void *_args)
  9427. +{
  9428. + struct postproc_args *a = _args;
  9429. + struct super_block *sb;
  9430. + aufs_bindex_t bindex, bend, bfound;
  9431. + unsigned char xino, try_iput;
  9432. + int err;
  9433. + struct inode *inode;
  9434. + ino_t h_ino;
  9435. + struct hin_job_args args;
  9436. + struct dentry *dentry;
  9437. + struct au_sbinfo *sbinfo;
  9438. +
  9439. + AuDebugOn(!_args);
  9440. + AuDebugOn(!a->h_dir);
  9441. + AuDebugOn(!a->dir);
  9442. + AuDebugOn(!a->mask);
  9443. + AuDbg("mask 0x%x %s, i%lu, hi%lu, hci%lu\n",
  9444. + a->mask, in_name(a->mask), a->dir->i_ino, a->h_dir->i_ino,
  9445. + a->h_child_inode ? a->h_child_inode->i_ino : 0);
  9446. +
  9447. + inode = NULL;
  9448. + dentry = NULL;
  9449. + /*
  9450. + * do not lock a->dir->i_mutex here
  9451. + * because of d_revalidate() may cause a deadlock.
  9452. + */
  9453. + sb = a->dir->i_sb;
  9454. + AuDebugOn(!sb);
  9455. + sbinfo = au_sbi(sb);
  9456. + AuDebugOn(!sbinfo);
  9457. + /* big aufs lock */
  9458. + si_noflush_write_lock(sb);
  9459. +
  9460. + ii_read_lock_parent(a->dir);
  9461. + bfound = -1;
  9462. + bend = au_ibend(a->dir);
  9463. + for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
  9464. + if (au_h_iptr(a->dir, bindex) == a->h_dir) {
  9465. + bfound = bindex;
  9466. + break;
  9467. + }
  9468. + ii_read_unlock(a->dir);
  9469. + if (unlikely(bfound < 0))
  9470. + goto out;
  9471. +
  9472. + xino = !!au_opt_test(au_mntflags(sb), XINO);
  9473. + h_ino = 0;
  9474. + if (a->h_child_inode)
  9475. + h_ino = a->h_child_inode->i_ino;
  9476. +
  9477. + if (a->h_child_nlen
  9478. + && (au_ftest_hinjob(a->flags[CHILD], GEN)
  9479. + || au_ftest_hinjob(a->flags[CHILD], MNTPNT)))
  9480. + dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
  9481. + a->dir);
  9482. + try_iput = 0;
  9483. + if (dentry)
  9484. + inode = dentry->d_inode;
  9485. + if (xino && !inode && h_ino
  9486. + && (au_ftest_hinjob(a->flags[CHILD], XINO0)
  9487. + || au_ftest_hinjob(a->flags[CHILD], TRYXINO0)
  9488. + || au_ftest_hinjob(a->flags[CHILD], GEN))) {
  9489. + inode = lookup_wlock_by_ino(sb, bfound, h_ino);
  9490. + try_iput = 1;
  9491. + }
  9492. +
  9493. + args.flags = a->flags[CHILD];
  9494. + args.dentry = dentry;
  9495. + args.inode = inode;
  9496. + args.h_inode = a->h_child_inode;
  9497. + args.dir = a->dir;
  9498. + args.h_dir = a->h_dir;
  9499. + args.h_name = a->h_child_name;
  9500. + args.h_nlen = a->h_child_nlen;
  9501. + err = hin_job(&args);
  9502. + if (dentry) {
  9503. + if (dentry->d_fsdata)
  9504. + di_write_unlock(dentry);
  9505. + dput(dentry);
  9506. + }
  9507. + if (inode && try_iput) {
  9508. + ii_write_unlock(inode);
  9509. + iput(inode);
  9510. + }
  9511. +
  9512. + ii_write_lock_parent(a->dir);
  9513. + args.flags = a->flags[PARENT];
  9514. + args.dentry = NULL;
  9515. + args.inode = a->dir;
  9516. + args.h_inode = a->h_dir;
  9517. + args.dir = NULL;
  9518. + args.h_dir = NULL;
  9519. + args.h_name = NULL;
  9520. + args.h_nlen = 0;
  9521. + err = hin_job(&args);
  9522. + ii_write_unlock(a->dir);
  9523. +
  9524. + out:
  9525. + au_nwt_done(&sbinfo->si_nowait);
  9526. + si_write_unlock(sb);
  9527. +
  9528. + iput(a->h_child_inode);
  9529. + iput(a->h_dir);
  9530. + iput(a->dir);
  9531. + kfree(a);
  9532. +}
  9533. +
  9534. +/* ---------------------------------------------------------------------- */
  9535. +
  9536. +static void aufs_inotify(struct inotify_watch *watch, u32 wd __maybe_unused,
  9537. + u32 mask, u32 cookie __maybe_unused,
  9538. + const char *h_child_name, struct inode *h_child_inode)
  9539. +{
  9540. + struct au_hinotify *hinotify;
  9541. + struct postproc_args *args;
  9542. + int len, wkq_err;
  9543. + unsigned char isdir, isroot, wh;
  9544. + char *p;
  9545. + struct inode *dir;
  9546. + unsigned int flags[2];
  9547. +
  9548. + /* if IN_UNMOUNT happens, there must be another bug */
  9549. + AuDebugOn(mask & IN_UNMOUNT);
  9550. + if (mask & (IN_IGNORED | IN_UNMOUNT)) {
  9551. + put_inotify_watch(watch);
  9552. + return;
  9553. + }
  9554. +#ifdef AuDbgHinotify
  9555. + au_debug(1);
  9556. + if (1 || !h_child_name || strcmp(h_child_name, AUFS_XINO_FNAME)) {
  9557. + AuDbg("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s,"
  9558. + " hi%lu\n",
  9559. + watch->inode->i_ino, wd, mask, in_name(mask), cookie,
  9560. + h_child_name ? h_child_name : "",
  9561. + h_child_inode ? h_child_inode->i_ino : 0);
  9562. + WARN_ON(1);
  9563. + }
  9564. + au_debug(0);
  9565. +#endif
  9566. +
  9567. + hinotify = container_of(watch, struct au_hinotify, hin_watch);
  9568. + AuDebugOn(!hinotify || !hinotify->hin_aufs_inode);
  9569. + dir = igrab(hinotify->hin_aufs_inode);
  9570. + if (!dir)
  9571. + return;
  9572. +
  9573. + isroot = (dir->i_ino == AUFS_ROOT_INO);
  9574. + len = 0;
  9575. + wh = 0;
  9576. + if (h_child_name) {
  9577. + len = strlen(h_child_name);
  9578. + if (!memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
  9579. + h_child_name += AUFS_WH_PFX_LEN;
  9580. + len -= AUFS_WH_PFX_LEN;
  9581. + wh = 1;
  9582. + }
  9583. + }
  9584. +
  9585. + isdir = 0;
  9586. + if (h_child_inode)
  9587. + isdir = !!S_ISDIR(h_child_inode->i_mode);
  9588. + flags[PARENT] = AuHinJob_ISDIR;
  9589. + flags[CHILD] = 0;
  9590. + if (isdir)
  9591. + flags[CHILD] = AuHinJob_ISDIR;
  9592. + switch (mask & IN_ALL_EVENTS) {
  9593. + case IN_MOVED_FROM:
  9594. + case IN_MOVED_TO:
  9595. + AuDebugOn(!h_child_name || !h_child_inode);
  9596. + au_fset_hinjob(flags[CHILD], GEN);
  9597. + au_fset_hinjob(flags[CHILD], XINO0);
  9598. + au_fset_hinjob(flags[CHILD], MNTPNT);
  9599. + au_fset_hinjob(flags[PARENT], DIRENT);
  9600. + break;
  9601. +
  9602. + case IN_CREATE:
  9603. + AuDebugOn(!h_child_name || !h_child_inode);
  9604. + au_fset_hinjob(flags[PARENT], DIRENT);
  9605. + au_fset_hinjob(flags[CHILD], GEN);
  9606. + break;
  9607. +
  9608. + case IN_DELETE:
  9609. + /*
  9610. + * aufs never be able to get this child inode.
  9611. + * revalidation should be in d_revalidate()
  9612. + * by checking i_nlink, i_generation or d_unhashed().
  9613. + */
  9614. + AuDebugOn(!h_child_name);
  9615. + au_fset_hinjob(flags[PARENT], DIRENT);
  9616. + au_fset_hinjob(flags[CHILD], GEN);
  9617. + au_fset_hinjob(flags[CHILD], TRYXINO0);
  9618. + au_fset_hinjob(flags[CHILD], MNTPNT);
  9619. + break;
  9620. +
  9621. + default:
  9622. + AuDebugOn(1);
  9623. + }
  9624. +
  9625. + if (wh)
  9626. + h_child_inode = NULL;
  9627. +
  9628. + /* iput() and kfree() will be called in postproc() */
  9629. + /*
  9630. + * inotify_mutex is already acquired and kmalloc/prune_icache may lock
  9631. + * iprune_mutex. strange.
  9632. + */
  9633. + lockdep_off();
  9634. + args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
  9635. + lockdep_on();
  9636. + if (unlikely(!args)) {
  9637. + AuErr1("no memory\n");
  9638. + iput(dir);
  9639. + return;
  9640. + }
  9641. + args->flags[PARENT] = flags[PARENT];
  9642. + args->flags[CHILD] = flags[CHILD];
  9643. + args->mask = mask;
  9644. + args->dir = dir;
  9645. + args->h_dir = igrab(watch->inode);
  9646. + if (h_child_inode)
  9647. + h_child_inode = igrab(h_child_inode); /* can be NULL */
  9648. + args->h_child_inode = h_child_inode;
  9649. + args->h_child_nlen = len;
  9650. + if (len) {
  9651. + p = (void *)args;
  9652. + p += sizeof(*args);
  9653. + memcpy(p, h_child_name, len + 1);
  9654. + }
  9655. +
  9656. + lockdep_off();
  9657. + wkq_err = au_wkq_nowait(postproc, args, dir->i_sb);
  9658. + lockdep_on();
  9659. + if (unlikely(wkq_err))
  9660. + AuErr("wkq %d\n", wkq_err);
  9661. +}
  9662. +
  9663. +static void aufs_inotify_destroy(struct inotify_watch *watch __maybe_unused)
  9664. +{
  9665. + return;
  9666. +}
  9667. +
  9668. +static struct inotify_operations aufs_inotify_ops = {
  9669. + .handle_event = aufs_inotify,
  9670. + .destroy_watch = aufs_inotify_destroy
  9671. +};
  9672. +
  9673. +/* ---------------------------------------------------------------------- */
  9674. +
  9675. +static void au_hin_destroy_cache(void)
  9676. +{
  9677. + kmem_cache_destroy(au_cachep[AuCache_HINOTIFY]);
  9678. + au_cachep[AuCache_HINOTIFY] = NULL;
  9679. +}
  9680. +
  9681. +int __init au_hinotify_init(void)
  9682. +{
  9683. + int err;
  9684. +
  9685. + err = -ENOMEM;
  9686. + au_cachep[AuCache_HINOTIFY] = AuCache(au_hinotify);
  9687. + if (au_cachep[AuCache_HINOTIFY]) {
  9688. + err = 0;
  9689. + au_hin_handle = inotify_init(&aufs_inotify_ops);
  9690. + if (IS_ERR(au_hin_handle)) {
  9691. + err = PTR_ERR(au_hin_handle);
  9692. + au_hin_destroy_cache();
  9693. + }
  9694. + }
  9695. + AuTraceErr(err);
  9696. + return err;
  9697. +}
  9698. +
  9699. +void au_hinotify_fin(void)
  9700. +{
  9701. + inotify_destroy(au_hin_handle);
  9702. + if (au_cachep[AuCache_HINOTIFY])
  9703. + au_hin_destroy_cache();
  9704. +}
  9705. diff -Nur linux-2.6.31.4.orig/fs/aufs/iinfo.c linux-2.6.31.4/fs/aufs/iinfo.c
  9706. --- linux-2.6.31.4.orig/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100
  9707. +++ linux-2.6.31.4/fs/aufs/iinfo.c 2009-10-18 11:26:01.000000000 +0200
  9708. @@ -0,0 +1,283 @@
  9709. +/*
  9710. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  9711. + *
  9712. + * This program, aufs is free software; you can redistribute it and/or modify
  9713. + * it under the terms of the GNU General Public License as published by
  9714. + * the Free Software Foundation; either version 2 of the License, or
  9715. + * (at your option) any later version.
  9716. + *
  9717. + * This program is distributed in the hope that it will be useful,
  9718. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9719. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9720. + * GNU General Public License for more details.
  9721. + *
  9722. + * You should have received a copy of the GNU General Public License
  9723. + * along with this program; if not, write to the Free Software
  9724. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  9725. + */
  9726. +
  9727. +/*
  9728. + * inode private data
  9729. + */
  9730. +
  9731. +#include "aufs.h"
  9732. +
  9733. +struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
  9734. +{
  9735. + struct inode *h_inode;
  9736. +
  9737. + IiMustAnyLock(inode);
  9738. +
  9739. + h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode;
  9740. + AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
  9741. + return h_inode;
  9742. +}
  9743. +
  9744. +/* todo: hard/soft set? */
  9745. +void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex)
  9746. +{
  9747. + struct au_iinfo *iinfo = au_ii(inode);
  9748. + struct inode *h_inode;
  9749. +
  9750. + IiMustWriteLock(inode);
  9751. +
  9752. + iinfo->ii_bstart = bindex;
  9753. + h_inode = iinfo->ii_hinode[bindex + 0].hi_inode;
  9754. + if (h_inode)
  9755. + au_cpup_igen(inode, h_inode);
  9756. +}
  9757. +
  9758. +void au_hiput(struct au_hinode *hinode)
  9759. +{
  9760. + au_hin_free(hinode);
  9761. + dput(hinode->hi_whdentry);
  9762. + iput(hinode->hi_inode);
  9763. +}
  9764. +
  9765. +unsigned int au_hi_flags(struct inode *inode, int isdir)
  9766. +{
  9767. + unsigned int flags;
  9768. + const unsigned int mnt_flags = au_mntflags(inode->i_sb);
  9769. +
  9770. + flags = 0;
  9771. + if (au_opt_test(mnt_flags, XINO))
  9772. + au_fset_hi(flags, XINO);
  9773. + if (isdir && au_opt_test(mnt_flags, UDBA_HINOTIFY))
  9774. + au_fset_hi(flags, HINOTIFY);
  9775. + return flags;
  9776. +}
  9777. +
  9778. +void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
  9779. + struct inode *h_inode, unsigned int flags)
  9780. +{
  9781. + struct au_hinode *hinode;
  9782. + struct inode *hi;
  9783. + struct au_iinfo *iinfo = au_ii(inode);
  9784. +
  9785. + IiMustWriteLock(inode);
  9786. +
  9787. + hinode = iinfo->ii_hinode + bindex;
  9788. + hi = hinode->hi_inode;
  9789. + AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
  9790. + AuDebugOn(h_inode && hi);
  9791. +
  9792. + if (hi)
  9793. + au_hiput(hinode);
  9794. + hinode->hi_inode = h_inode;
  9795. + if (h_inode) {
  9796. + int err;
  9797. + struct super_block *sb = inode->i_sb;
  9798. + struct au_branch *br;
  9799. +
  9800. + if (bindex == iinfo->ii_bstart)
  9801. + au_cpup_igen(inode, h_inode);
  9802. + br = au_sbr(sb, bindex);
  9803. + hinode->hi_id = br->br_id;
  9804. + if (au_ftest_hi(flags, XINO)) {
  9805. + err = au_xino_write(sb, bindex, h_inode->i_ino,
  9806. + inode->i_ino);
  9807. + if (unlikely(err))
  9808. + AuIOErr1("failed au_xino_write() %d\n", err);
  9809. + }
  9810. +
  9811. + if (au_ftest_hi(flags, HINOTIFY)
  9812. + && au_br_hinotifyable(br->br_perm)) {
  9813. + err = au_hin_alloc(hinode, inode, h_inode);
  9814. + if (unlikely(err))
  9815. + AuIOErr1("au_hin_alloc() %d\n", err);
  9816. + }
  9817. + }
  9818. +}
  9819. +
  9820. +void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
  9821. + struct dentry *h_wh)
  9822. +{
  9823. + struct au_hinode *hinode;
  9824. +
  9825. + IiMustWriteLock(inode);
  9826. +
  9827. + hinode = au_ii(inode)->ii_hinode + bindex;
  9828. + AuDebugOn(hinode->hi_whdentry);
  9829. + hinode->hi_whdentry = h_wh;
  9830. +}
  9831. +
  9832. +void au_update_iigen(struct inode *inode)
  9833. +{
  9834. + atomic_set(&au_ii(inode)->ii_generation, au_sigen(inode->i_sb));
  9835. + /* smp_mb(); */ /* atomic_set */
  9836. +}
  9837. +
  9838. +/* it may be called at remount time, too */
  9839. +void au_update_brange(struct inode *inode, int do_put_zero)
  9840. +{
  9841. + struct au_iinfo *iinfo;
  9842. +
  9843. + iinfo = au_ii(inode);
  9844. + if (!iinfo || iinfo->ii_bstart < 0)
  9845. + return;
  9846. +
  9847. + IiMustWriteLock(inode);
  9848. +
  9849. + if (do_put_zero) {
  9850. + aufs_bindex_t bindex;
  9851. +
  9852. + for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
  9853. + bindex++) {
  9854. + struct inode *h_i;
  9855. +
  9856. + h_i = iinfo->ii_hinode[0 + bindex].hi_inode;
  9857. + if (h_i && !h_i->i_nlink)
  9858. + au_set_h_iptr(inode, bindex, NULL, 0);
  9859. + }
  9860. + }
  9861. +
  9862. + iinfo->ii_bstart = -1;
  9863. + while (++iinfo->ii_bstart <= iinfo->ii_bend)
  9864. + if (iinfo->ii_hinode[0 + iinfo->ii_bstart].hi_inode)
  9865. + break;
  9866. + if (iinfo->ii_bstart > iinfo->ii_bend) {
  9867. + iinfo->ii_bstart = -1;
  9868. + iinfo->ii_bend = -1;
  9869. + return;
  9870. + }
  9871. +
  9872. + iinfo->ii_bend++;
  9873. + while (0 <= --iinfo->ii_bend)
  9874. + if (iinfo->ii_hinode[0 + iinfo->ii_bend].hi_inode)
  9875. + break;
  9876. + AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend || iinfo->ii_bend < 0);
  9877. +}
  9878. +
  9879. +/* ---------------------------------------------------------------------- */
  9880. +
  9881. +int au_iinfo_init(struct inode *inode)
  9882. +{
  9883. + struct au_iinfo *iinfo;
  9884. + struct super_block *sb;
  9885. + int nbr, i;
  9886. +
  9887. + sb = inode->i_sb;
  9888. + iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
  9889. + nbr = au_sbend(sb) + 1;
  9890. + if (unlikely(nbr <= 0))
  9891. + nbr = 1;
  9892. + iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
  9893. + if (iinfo->ii_hinode) {
  9894. + for (i = 0; i < nbr; i++)
  9895. + iinfo->ii_hinode[i].hi_id = -1;
  9896. +
  9897. + atomic_set(&iinfo->ii_generation, au_sigen(sb));
  9898. + /* smp_mb(); */ /* atomic_set */
  9899. + au_rw_init(&iinfo->ii_rwsem);
  9900. + iinfo->ii_bstart = -1;
  9901. + iinfo->ii_bend = -1;
  9902. + iinfo->ii_vdir = NULL;
  9903. + return 0;
  9904. + }
  9905. + return -ENOMEM;
  9906. +}
  9907. +
  9908. +int au_ii_realloc(struct au_iinfo *iinfo, int nbr)
  9909. +{
  9910. + int err, sz;
  9911. + struct au_hinode *hip;
  9912. +
  9913. + AuRwMustWriteLock(&iinfo->ii_rwsem);
  9914. +
  9915. + err = -ENOMEM;
  9916. + sz = sizeof(*hip) * (iinfo->ii_bend + 1);
  9917. + if (!sz)
  9918. + sz = sizeof(*hip);
  9919. + hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS);
  9920. + if (hip) {
  9921. + iinfo->ii_hinode = hip;
  9922. + err = 0;
  9923. + }
  9924. +
  9925. + return err;
  9926. +}
  9927. +
  9928. +static int au_iinfo_write0(struct super_block *sb, struct au_hinode *hinode,
  9929. + ino_t ino)
  9930. +{
  9931. + int err;
  9932. + aufs_bindex_t bindex;
  9933. + unsigned char locked;
  9934. +
  9935. + err = 0;
  9936. + locked = !!si_noflush_read_trylock(sb);
  9937. + bindex = au_br_index(sb, hinode->hi_id);
  9938. + if (bindex >= 0)
  9939. + err = au_xino_write0(sb, bindex, hinode->hi_inode->i_ino, ino);
  9940. + /* error action? */
  9941. + if (locked)
  9942. + si_read_unlock(sb);
  9943. + return err;
  9944. +}
  9945. +
  9946. +void au_iinfo_fin(struct inode *inode)
  9947. +{
  9948. + ino_t ino;
  9949. + aufs_bindex_t bend;
  9950. + unsigned char unlinked = !inode->i_nlink;
  9951. + struct au_iinfo *iinfo;
  9952. + struct au_hinode *hi;
  9953. + struct super_block *sb;
  9954. +
  9955. + if (unlinked) {
  9956. + int err = au_xigen_inc(inode);
  9957. + if (unlikely(err))
  9958. + AuWarn1("failed resetting i_generation, %d\n", err);
  9959. + }
  9960. +
  9961. + iinfo = au_ii(inode);
  9962. + /* bad_inode case */
  9963. + if (!iinfo)
  9964. + return;
  9965. +
  9966. + if (iinfo->ii_vdir)
  9967. + au_vdir_free(iinfo->ii_vdir);
  9968. +
  9969. + if (iinfo->ii_bstart >= 0) {
  9970. + sb = inode->i_sb;
  9971. + ino = 0;
  9972. + if (unlinked)
  9973. + ino = inode->i_ino;
  9974. + hi = iinfo->ii_hinode + iinfo->ii_bstart;
  9975. + bend = iinfo->ii_bend;
  9976. + while (iinfo->ii_bstart++ <= bend) {
  9977. + if (hi->hi_inode) {
  9978. + if (unlinked || !hi->hi_inode->i_nlink) {
  9979. + au_iinfo_write0(sb, hi, ino);
  9980. + /* ignore this error */
  9981. + ino = 0;
  9982. + }
  9983. + au_hiput(hi);
  9984. + }
  9985. + hi++;
  9986. + }
  9987. + }
  9988. +
  9989. + kfree(iinfo->ii_hinode);
  9990. + AuRwDestroy(&iinfo->ii_rwsem);
  9991. +}
  9992. diff -Nur linux-2.6.31.4.orig/fs/aufs/inode.c linux-2.6.31.4/fs/aufs/inode.c
  9993. --- linux-2.6.31.4.orig/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100
  9994. +++ linux-2.6.31.4/fs/aufs/inode.c 2009-10-18 11:26:01.000000000 +0200
  9995. @@ -0,0 +1,380 @@
  9996. +/*
  9997. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  9998. + *
  9999. + * This program, aufs is free software; you can redistribute it and/or modify
  10000. + * it under the terms of the GNU General Public License as published by
  10001. + * the Free Software Foundation; either version 2 of the License, or
  10002. + * (at your option) any later version.
  10003. + *
  10004. + * This program is distributed in the hope that it will be useful,
  10005. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10006. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10007. + * GNU General Public License for more details.
  10008. + *
  10009. + * You should have received a copy of the GNU General Public License
  10010. + * along with this program; if not, write to the Free Software
  10011. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  10012. + */
  10013. +
  10014. +/*
  10015. + * inode functions
  10016. + */
  10017. +
  10018. +#include "aufs.h"
  10019. +
  10020. +struct inode *au_igrab(struct inode *inode)
  10021. +{
  10022. + if (inode) {
  10023. + AuDebugOn(!atomic_read(&inode->i_count));
  10024. + atomic_inc_return(&inode->i_count);
  10025. + }
  10026. + return inode;
  10027. +}
  10028. +
  10029. +static void au_refresh_hinode_attr(struct inode *inode, int do_version)
  10030. +{
  10031. + au_cpup_attr_all(inode, /*force*/0);
  10032. + au_update_iigen(inode);
  10033. + if (do_version)
  10034. + inode->i_version++;
  10035. +}
  10036. +
  10037. +int au_refresh_hinode_self(struct inode *inode, int do_attr)
  10038. +{
  10039. + int err;
  10040. + aufs_bindex_t bindex, new_bindex;
  10041. + unsigned char update;
  10042. + struct inode *first;
  10043. + struct au_hinode *p, *q, tmp;
  10044. + struct super_block *sb;
  10045. + struct au_iinfo *iinfo;
  10046. +
  10047. + IiMustWriteLock(inode);
  10048. +
  10049. + update = 0;
  10050. + sb = inode->i_sb;
  10051. + iinfo = au_ii(inode);
  10052. + err = au_ii_realloc(iinfo, au_sbend(sb) + 1);
  10053. + if (unlikely(err))
  10054. + goto out;
  10055. +
  10056. + p = iinfo->ii_hinode + iinfo->ii_bstart;
  10057. + first = p->hi_inode;
  10058. + err = 0;
  10059. + for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
  10060. + bindex++, p++) {
  10061. + if (!p->hi_inode)
  10062. + continue;
  10063. +
  10064. + new_bindex = au_br_index(sb, p->hi_id);
  10065. + if (new_bindex == bindex)
  10066. + continue;
  10067. +
  10068. + if (new_bindex < 0) {
  10069. + update++;
  10070. + au_hiput(p);
  10071. + p->hi_inode = NULL;
  10072. + continue;
  10073. + }
  10074. +
  10075. + if (new_bindex < iinfo->ii_bstart)
  10076. + iinfo->ii_bstart = new_bindex;
  10077. + if (iinfo->ii_bend < new_bindex)
  10078. + iinfo->ii_bend = new_bindex;
  10079. + /* swap two lower inode, and loop again */
  10080. + q = iinfo->ii_hinode + new_bindex;
  10081. + tmp = *q;
  10082. + *q = *p;
  10083. + *p = tmp;
  10084. + if (tmp.hi_inode) {
  10085. + bindex--;
  10086. + p--;
  10087. + }
  10088. + }
  10089. + au_update_brange(inode, /*do_put_zero*/0);
  10090. + if (do_attr)
  10091. + au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
  10092. +
  10093. + out:
  10094. + return err;
  10095. +}
  10096. +
  10097. +int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
  10098. +{
  10099. + int err, update;
  10100. + unsigned int flags;
  10101. + aufs_bindex_t bindex, bend;
  10102. + unsigned char isdir;
  10103. + struct inode *first;
  10104. + struct au_hinode *p;
  10105. + struct au_iinfo *iinfo;
  10106. +
  10107. + err = au_refresh_hinode_self(inode, /*do_attr*/0);
  10108. + if (unlikely(err))
  10109. + goto out;
  10110. +
  10111. + update = 0;
  10112. + iinfo = au_ii(inode);
  10113. + p = iinfo->ii_hinode + iinfo->ii_bstart;
  10114. + first = p->hi_inode;
  10115. + isdir = S_ISDIR(inode->i_mode);
  10116. + flags = au_hi_flags(inode, isdir);
  10117. + bend = au_dbend(dentry);
  10118. + for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
  10119. + struct inode *h_i;
  10120. + struct dentry *h_d;
  10121. +
  10122. + h_d = au_h_dptr(dentry, bindex);
  10123. + if (!h_d || !h_d->d_inode)
  10124. + continue;
  10125. +
  10126. + if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) {
  10127. + h_i = au_h_iptr(inode, bindex);
  10128. + if (h_i) {
  10129. + if (h_i == h_d->d_inode)
  10130. + continue;
  10131. + err = -EIO;
  10132. + break;
  10133. + }
  10134. + }
  10135. + if (bindex < iinfo->ii_bstart)
  10136. + iinfo->ii_bstart = bindex;
  10137. + if (iinfo->ii_bend < bindex)
  10138. + iinfo->ii_bend = bindex;
  10139. + au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags);
  10140. + update = 1;
  10141. + }
  10142. + au_update_brange(inode, /*do_put_zero*/0);
  10143. +
  10144. + if (unlikely(err))
  10145. + goto out;
  10146. +
  10147. + au_refresh_hinode_attr(inode, update && isdir);
  10148. +
  10149. + out:
  10150. + return err;
  10151. +}
  10152. +
  10153. +static int set_inode(struct inode *inode, struct dentry *dentry)
  10154. +{
  10155. + int err;
  10156. + unsigned int flags;
  10157. + umode_t mode;
  10158. + aufs_bindex_t bindex, bstart, btail;
  10159. + unsigned char isdir;
  10160. + struct dentry *h_dentry;
  10161. + struct inode *h_inode;
  10162. + struct au_iinfo *iinfo;
  10163. +
  10164. + IiMustWriteLock(inode);
  10165. +
  10166. + err = 0;
  10167. + isdir = 0;
  10168. + bstart = au_dbstart(dentry);
  10169. + h_inode = au_h_dptr(dentry, bstart)->d_inode;
  10170. + mode = h_inode->i_mode;
  10171. + switch (mode & S_IFMT) {
  10172. + case S_IFREG:
  10173. + btail = au_dbtail(dentry);
  10174. + inode->i_op = &aufs_iop;
  10175. + inode->i_fop = &aufs_file_fop;
  10176. + inode->i_mapping->a_ops = &aufs_aop;
  10177. + break;
  10178. + case S_IFDIR:
  10179. + isdir = 1;
  10180. + btail = au_dbtaildir(dentry);
  10181. + inode->i_op = &aufs_dir_iop;
  10182. + inode->i_fop = &aufs_dir_fop;
  10183. + break;
  10184. + case S_IFLNK:
  10185. + btail = au_dbtail(dentry);
  10186. + inode->i_op = &aufs_symlink_iop;
  10187. + break;
  10188. + case S_IFBLK:
  10189. + case S_IFCHR:
  10190. + case S_IFIFO:
  10191. + case S_IFSOCK:
  10192. + btail = au_dbtail(dentry);
  10193. + inode->i_op = &aufs_iop;
  10194. + init_special_inode(inode, mode, h_inode->i_rdev);
  10195. + break;
  10196. + default:
  10197. + AuIOErr("Unknown file type 0%o\n", mode);
  10198. + err = -EIO;
  10199. + goto out;
  10200. + }
  10201. +
  10202. + /* do not set inotify for whiteouted dirs (SHWH mode) */
  10203. + flags = au_hi_flags(inode, isdir);
  10204. + if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
  10205. + && au_ftest_hi(flags, HINOTIFY)
  10206. + && dentry->d_name.len > AUFS_WH_PFX_LEN
  10207. + && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
  10208. + au_fclr_hi(flags, HINOTIFY);
  10209. + iinfo = au_ii(inode);
  10210. + iinfo->ii_bstart = bstart;
  10211. + iinfo->ii_bend = btail;
  10212. + for (bindex = bstart; bindex <= btail; bindex++) {
  10213. + h_dentry = au_h_dptr(dentry, bindex);
  10214. + if (h_dentry)
  10215. + au_set_h_iptr(inode, bindex,
  10216. + au_igrab(h_dentry->d_inode), flags);
  10217. + }
  10218. + au_cpup_attr_all(inode, /*force*/1);
  10219. +
  10220. + out:
  10221. + return err;
  10222. +}
  10223. +
  10224. +/* successful returns with iinfo write_locked */
  10225. +static int reval_inode(struct inode *inode, struct dentry *dentry, int *matched)
  10226. +{
  10227. + int err;
  10228. + aufs_bindex_t bindex, bend;
  10229. + struct inode *h_inode, *h_dinode;
  10230. +
  10231. + *matched = 0;
  10232. +
  10233. + /*
  10234. + * before this function, if aufs got any iinfo lock, it must be only
  10235. + * one, the parent dir.
  10236. + * it can happen by UDBA and the obsoleted inode number.
  10237. + */
  10238. + err = -EIO;
  10239. + if (unlikely(inode->i_ino == parent_ino(dentry)))
  10240. + goto out;
  10241. +
  10242. + err = 0;
  10243. + ii_write_lock_new_child(inode);
  10244. + h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode;
  10245. + bend = au_ibend(inode);
  10246. + for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
  10247. + h_inode = au_h_iptr(inode, bindex);
  10248. + if (h_inode && h_inode == h_dinode) {
  10249. + *matched = 1;
  10250. + err = 0;
  10251. + if (au_iigen(inode) != au_digen(dentry))
  10252. + err = au_refresh_hinode(inode, dentry);
  10253. + break;
  10254. + }
  10255. + }
  10256. +
  10257. + if (unlikely(err))
  10258. + ii_write_unlock(inode);
  10259. + out:
  10260. + return err;
  10261. +}
  10262. +
  10263. +/* successful returns with iinfo write_locked */
  10264. +/* todo: return with unlocked? */
  10265. +struct inode *au_new_inode(struct dentry *dentry, int must_new)
  10266. +{
  10267. + struct inode *inode;
  10268. + struct dentry *h_dentry;
  10269. + struct super_block *sb;
  10270. + ino_t h_ino, ino;
  10271. + int err, match;
  10272. + aufs_bindex_t bstart;
  10273. +
  10274. + sb = dentry->d_sb;
  10275. + bstart = au_dbstart(dentry);
  10276. + h_dentry = au_h_dptr(dentry, bstart);
  10277. + h_ino = h_dentry->d_inode->i_ino;
  10278. + err = au_xino_read(sb, bstart, h_ino, &ino);
  10279. + inode = ERR_PTR(err);
  10280. + if (unlikely(err))
  10281. + goto out;
  10282. + new_ino:
  10283. + if (!ino) {
  10284. + ino = au_xino_new_ino(sb);
  10285. + if (unlikely(!ino)) {
  10286. + inode = ERR_PTR(-EIO);
  10287. + goto out;
  10288. + }
  10289. + }
  10290. +
  10291. + AuDbg("i%lu\n", (unsigned long)ino);
  10292. + inode = au_iget_locked(sb, ino);
  10293. + err = PTR_ERR(inode);
  10294. + if (IS_ERR(inode))
  10295. + goto out;
  10296. +
  10297. + AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
  10298. + if (inode->i_state & I_NEW) {
  10299. + ii_write_lock_new_child(inode);
  10300. + err = set_inode(inode, dentry);
  10301. + unlock_new_inode(inode);
  10302. + if (!err)
  10303. + goto out; /* success */
  10304. +
  10305. + iget_failed(inode);
  10306. + ii_write_unlock(inode);
  10307. + goto out_iput;
  10308. + } else if (!must_new) {
  10309. + err = reval_inode(inode, dentry, &match);
  10310. + if (!err)
  10311. + goto out; /* success */
  10312. + else if (match)
  10313. + goto out_iput;
  10314. + }
  10315. +
  10316. + if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode)))
  10317. + AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
  10318. + " b%d, %s, %.*s, hi%lu, i%lu.\n",
  10319. + bstart, au_sbtype(h_dentry->d_sb), AuDLNPair(dentry),
  10320. + (unsigned long)h_ino, (unsigned long)ino);
  10321. + ino = 0;
  10322. + err = au_xino_write(sb, bstart, h_ino, /*ino*/0);
  10323. + if (!err) {
  10324. + iput(inode);
  10325. + goto new_ino;
  10326. + }
  10327. +
  10328. + out_iput:
  10329. + iput(inode);
  10330. + inode = ERR_PTR(err);
  10331. + out:
  10332. + return inode;
  10333. +}
  10334. +
  10335. +/* ---------------------------------------------------------------------- */
  10336. +
  10337. +int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
  10338. + struct inode *inode)
  10339. +{
  10340. + int err;
  10341. +
  10342. + err = au_br_rdonly(au_sbr(sb, bindex));
  10343. +
  10344. + /* pseudo-link after flushed may happen out of bounds */
  10345. + if (!err
  10346. + && inode
  10347. + && au_ibstart(inode) <= bindex
  10348. + && bindex <= au_ibend(inode)) {
  10349. + /*
  10350. + * permission check is unnecessary since vfsub routine
  10351. + * will be called later
  10352. + */
  10353. + struct inode *hi = au_h_iptr(inode, bindex);
  10354. + if (hi)
  10355. + err = IS_IMMUTABLE(hi) ? -EROFS : 0;
  10356. + }
  10357. +
  10358. + return err;
  10359. +}
  10360. +
  10361. +int au_test_h_perm(struct inode *h_inode, int mask)
  10362. +{
  10363. + if (!current_fsuid())
  10364. + return 0;
  10365. + return inode_permission(h_inode, mask);
  10366. +}
  10367. +
  10368. +int au_test_h_perm_sio(struct inode *h_inode, int mask)
  10369. +{
  10370. + if (au_test_nfs(h_inode->i_sb)
  10371. + && (mask & MAY_WRITE)
  10372. + && S_ISDIR(h_inode->i_mode))
  10373. + mask |= MAY_READ; /* force permission check */
  10374. + return au_test_h_perm(h_inode, mask);
  10375. +}
  10376. diff -Nur linux-2.6.31.4.orig/fs/aufs/inode.h linux-2.6.31.4/fs/aufs/inode.h
  10377. --- linux-2.6.31.4.orig/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
  10378. +++ linux-2.6.31.4/fs/aufs/inode.h 2009-10-18 11:26:01.000000000 +0200
  10379. @@ -0,0 +1,484 @@
  10380. +/*
  10381. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  10382. + *
  10383. + * This program, aufs is free software; you can redistribute it and/or modify
  10384. + * it under the terms of the GNU General Public License as published by
  10385. + * the Free Software Foundation; either version 2 of the License, or
  10386. + * (at your option) any later version.
  10387. + *
  10388. + * This program is distributed in the hope that it will be useful,
  10389. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10390. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10391. + * GNU General Public License for more details.
  10392. + *
  10393. + * You should have received a copy of the GNU General Public License
  10394. + * along with this program; if not, write to the Free Software
  10395. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  10396. + */
  10397. +
  10398. +/*
  10399. + * inode operations
  10400. + */
  10401. +
  10402. +#ifndef __AUFS_INODE_H__
  10403. +#define __AUFS_INODE_H__
  10404. +
  10405. +#ifdef __KERNEL__
  10406. +
  10407. +#include <linux/fs.h>
  10408. +#include <linux/inotify.h>
  10409. +#include <linux/aufs_type.h>
  10410. +#include "rwsem.h"
  10411. +
  10412. +struct vfsmount;
  10413. +
  10414. +struct au_hinotify {
  10415. +#ifdef CONFIG_AUFS_HINOTIFY
  10416. + struct inotify_watch hin_watch;
  10417. + struct inode *hin_aufs_inode; /* no get/put */
  10418. +#endif
  10419. +};
  10420. +
  10421. +struct au_hinode {
  10422. + struct inode *hi_inode;
  10423. + aufs_bindex_t hi_id;
  10424. +#ifdef CONFIG_AUFS_HINOTIFY
  10425. + struct au_hinotify *hi_notify;
  10426. +#endif
  10427. +
  10428. + /* reference to the copied-up whiteout with get/put */
  10429. + struct dentry *hi_whdentry;
  10430. +};
  10431. +
  10432. +struct au_vdir;
  10433. +struct au_iinfo {
  10434. + atomic_t ii_generation;
  10435. + struct super_block *ii_hsb1; /* no get/put */
  10436. +
  10437. + struct au_rwsem ii_rwsem;
  10438. + aufs_bindex_t ii_bstart, ii_bend;
  10439. + __u32 ii_higen;
  10440. + struct au_hinode *ii_hinode;
  10441. + struct au_vdir *ii_vdir;
  10442. +};
  10443. +
  10444. +struct au_icntnr {
  10445. + struct au_iinfo iinfo;
  10446. + struct inode vfs_inode;
  10447. +};
  10448. +
  10449. +/* au_pin flags */
  10450. +#define AuPin_DI_LOCKED 1
  10451. +#define AuPin_MNT_WRITE (1 << 1)
  10452. +#define au_ftest_pin(flags, name) ((flags) & AuPin_##name)
  10453. +#define au_fset_pin(flags, name) { (flags) |= AuPin_##name; }
  10454. +#define au_fclr_pin(flags, name) { (flags) &= ~AuPin_##name; }
  10455. +
  10456. +struct au_pin {
  10457. + /* input */
  10458. + struct dentry *dentry;
  10459. + unsigned int udba;
  10460. + unsigned char lsc_di, lsc_hi, flags;
  10461. + aufs_bindex_t bindex;
  10462. +
  10463. + /* output */
  10464. + struct dentry *parent;
  10465. + struct au_hinode *hdir;
  10466. + struct vfsmount *h_mnt;
  10467. +};
  10468. +
  10469. +/* ---------------------------------------------------------------------- */
  10470. +
  10471. +static inline struct au_iinfo *au_ii(struct inode *inode)
  10472. +{
  10473. + struct au_iinfo *iinfo;
  10474. +
  10475. + iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
  10476. + if (iinfo->ii_hinode)
  10477. + return iinfo;
  10478. + return NULL; /* debugging bad_inode case */
  10479. +}
  10480. +
  10481. +/* ---------------------------------------------------------------------- */
  10482. +
  10483. +/* inode.c */
  10484. +struct inode *au_igrab(struct inode *inode);
  10485. +int au_refresh_hinode_self(struct inode *inode, int do_attr);
  10486. +int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
  10487. +struct inode *au_new_inode(struct dentry *dentry, int must_new);
  10488. +int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
  10489. + struct inode *inode);
  10490. +int au_test_h_perm(struct inode *h_inode, int mask);
  10491. +int au_test_h_perm_sio(struct inode *h_inode, int mask);
  10492. +
  10493. +/* i_op.c */
  10494. +extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
  10495. +
  10496. +/* au_wr_dir flags */
  10497. +#define AuWrDir_ADD_ENTRY 1
  10498. +#define AuWrDir_ISDIR (1 << 1)
  10499. +#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
  10500. +#define au_fset_wrdir(flags, name) { (flags) |= AuWrDir_##name; }
  10501. +#define au_fclr_wrdir(flags, name) { (flags) &= ~AuWrDir_##name; }
  10502. +
  10503. +struct au_wr_dir_args {
  10504. + aufs_bindex_t force_btgt;
  10505. + unsigned char flags;
  10506. +};
  10507. +int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
  10508. + struct au_wr_dir_args *args);
  10509. +
  10510. +struct dentry *au_pinned_h_parent(struct au_pin *pin);
  10511. +void au_pin_init(struct au_pin *pin, struct dentry *dentry,
  10512. + aufs_bindex_t bindex, int lsc_di, int lsc_hi,
  10513. + unsigned int udba, unsigned char flags);
  10514. +int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
  10515. + unsigned int udba, unsigned char flags) __must_check;
  10516. +int au_do_pin(struct au_pin *pin) __must_check;
  10517. +void au_unpin(struct au_pin *pin);
  10518. +
  10519. +/* i_op_add.c */
  10520. +int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
  10521. + struct dentry *h_parent, int isdir);
  10522. +int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev);
  10523. +int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
  10524. +int aufs_create(struct inode *dir, struct dentry *dentry, int mode,
  10525. + struct nameidata *nd);
  10526. +int aufs_link(struct dentry *src_dentry, struct inode *dir,
  10527. + struct dentry *dentry);
  10528. +int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
  10529. +
  10530. +/* i_op_del.c */
  10531. +int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
  10532. +int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
  10533. + struct dentry *h_parent, int isdir);
  10534. +int aufs_unlink(struct inode *dir, struct dentry *dentry);
  10535. +int aufs_rmdir(struct inode *dir, struct dentry *dentry);
  10536. +
  10537. +/* i_op_ren.c */
  10538. +int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
  10539. +int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
  10540. + struct inode *dir, struct dentry *dentry);
  10541. +
  10542. +/* iinfo.c */
  10543. +struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
  10544. +void au_hiput(struct au_hinode *hinode);
  10545. +void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex);
  10546. +void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
  10547. + struct dentry *h_wh);
  10548. +unsigned int au_hi_flags(struct inode *inode, int isdir);
  10549. +
  10550. +/* hinode flags */
  10551. +#define AuHi_XINO 1
  10552. +#define AuHi_HINOTIFY (1 << 1)
  10553. +#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
  10554. +#define au_fset_hi(flags, name) { (flags) |= AuHi_##name; }
  10555. +#define au_fclr_hi(flags, name) { (flags) &= ~AuHi_##name; }
  10556. +
  10557. +#ifndef CONFIG_AUFS_HINOTIFY
  10558. +#undef AuHi_HINOTIFY
  10559. +#define AuHi_HINOTIFY 0
  10560. +#endif
  10561. +
  10562. +void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
  10563. + struct inode *h_inode, unsigned int flags);
  10564. +
  10565. +void au_update_iigen(struct inode *inode);
  10566. +void au_update_brange(struct inode *inode, int do_put_zero);
  10567. +
  10568. +int au_iinfo_init(struct inode *inode);
  10569. +void au_iinfo_fin(struct inode *inode);
  10570. +int au_ii_realloc(struct au_iinfo *iinfo, int nbr);
  10571. +
  10572. +/* plink.c */
  10573. +void au_plink_block_maintain(struct super_block *sb);
  10574. +#ifdef CONFIG_AUFS_DEBUG
  10575. +void au_plink_list(struct super_block *sb);
  10576. +#else
  10577. +static inline void au_plink_list(struct super_block *sb)
  10578. +{
  10579. + /* nothing */
  10580. +}
  10581. +#endif
  10582. +int au_plink_test(struct inode *inode);
  10583. +struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
  10584. +void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
  10585. + struct dentry *h_dentry);
  10586. +void au_plink_put(struct super_block *sb);
  10587. +void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
  10588. +
  10589. +/* ---------------------------------------------------------------------- */
  10590. +
  10591. +/* lock subclass for iinfo */
  10592. +enum {
  10593. + AuLsc_II_CHILD, /* child first */
  10594. + AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hinotify */
  10595. + AuLsc_II_CHILD3, /* copyup dirs */
  10596. + AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
  10597. + AuLsc_II_PARENT2,
  10598. + AuLsc_II_PARENT3, /* copyup dirs */
  10599. + AuLsc_II_NEW_CHILD
  10600. +};
  10601. +
  10602. +/*
  10603. + * ii_read_lock_child, ii_write_lock_child,
  10604. + * ii_read_lock_child2, ii_write_lock_child2,
  10605. + * ii_read_lock_child3, ii_write_lock_child3,
  10606. + * ii_read_lock_parent, ii_write_lock_parent,
  10607. + * ii_read_lock_parent2, ii_write_lock_parent2,
  10608. + * ii_read_lock_parent3, ii_write_lock_parent3,
  10609. + * ii_read_lock_new_child, ii_write_lock_new_child,
  10610. + */
  10611. +#define AuReadLockFunc(name, lsc) \
  10612. +static inline void ii_read_lock_##name(struct inode *i) \
  10613. +{ \
  10614. + au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
  10615. +}
  10616. +
  10617. +#define AuWriteLockFunc(name, lsc) \
  10618. +static inline void ii_write_lock_##name(struct inode *i) \
  10619. +{ \
  10620. + au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
  10621. +}
  10622. +
  10623. +#define AuRWLockFuncs(name, lsc) \
  10624. + AuReadLockFunc(name, lsc) \
  10625. + AuWriteLockFunc(name, lsc)
  10626. +
  10627. +AuRWLockFuncs(child, CHILD);
  10628. +AuRWLockFuncs(child2, CHILD2);
  10629. +AuRWLockFuncs(child3, CHILD3);
  10630. +AuRWLockFuncs(parent, PARENT);
  10631. +AuRWLockFuncs(parent2, PARENT2);
  10632. +AuRWLockFuncs(parent3, PARENT3);
  10633. +AuRWLockFuncs(new_child, NEW_CHILD);
  10634. +
  10635. +#undef AuReadLockFunc
  10636. +#undef AuWriteLockFunc
  10637. +#undef AuRWLockFuncs
  10638. +
  10639. +/*
  10640. + * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
  10641. + */
  10642. +AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
  10643. +
  10644. +#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
  10645. +#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
  10646. +#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
  10647. +
  10648. +/* ---------------------------------------------------------------------- */
  10649. +
  10650. +static inline unsigned int au_iigen(struct inode *inode)
  10651. +{
  10652. + return atomic_read(&au_ii(inode)->ii_generation);
  10653. +}
  10654. +
  10655. +/* tiny test for inode number */
  10656. +/* tmpfs generation is too rough */
  10657. +static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
  10658. +{
  10659. + struct au_iinfo *iinfo;
  10660. +
  10661. + iinfo = au_ii(inode);
  10662. + AuRwMustAnyLock(&iinfo->ii_rwsem);
  10663. + return !(iinfo->ii_hsb1 == h_inode->i_sb
  10664. + && iinfo->ii_higen == h_inode->i_generation);
  10665. +}
  10666. +
  10667. +/* ---------------------------------------------------------------------- */
  10668. +
  10669. +static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
  10670. + aufs_bindex_t bindex)
  10671. +{
  10672. + IiMustAnyLock(inode);
  10673. + return au_ii(inode)->ii_hinode[0 + bindex].hi_id;
  10674. +}
  10675. +
  10676. +static inline aufs_bindex_t au_ibstart(struct inode *inode)
  10677. +{
  10678. + IiMustAnyLock(inode);
  10679. + return au_ii(inode)->ii_bstart;
  10680. +}
  10681. +
  10682. +static inline aufs_bindex_t au_ibend(struct inode *inode)
  10683. +{
  10684. + IiMustAnyLock(inode);
  10685. + return au_ii(inode)->ii_bend;
  10686. +}
  10687. +
  10688. +static inline struct au_vdir *au_ivdir(struct inode *inode)
  10689. +{
  10690. + IiMustAnyLock(inode);
  10691. + return au_ii(inode)->ii_vdir;
  10692. +}
  10693. +
  10694. +static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
  10695. +{
  10696. + IiMustAnyLock(inode);
  10697. + return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry;
  10698. +}
  10699. +
  10700. +static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex)
  10701. +{
  10702. + IiMustWriteLock(inode);
  10703. + au_ii(inode)->ii_bend = bindex;
  10704. +}
  10705. +
  10706. +static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
  10707. +{
  10708. + IiMustWriteLock(inode);
  10709. + au_ii(inode)->ii_vdir = vdir;
  10710. +}
  10711. +
  10712. +static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
  10713. +{
  10714. + IiMustAnyLock(inode);
  10715. + return au_ii(inode)->ii_hinode + bindex;
  10716. +}
  10717. +
  10718. +/* ---------------------------------------------------------------------- */
  10719. +
  10720. +static inline struct dentry *au_pinned_parent(struct au_pin *pin)
  10721. +{
  10722. + if (pin)
  10723. + return pin->parent;
  10724. + return NULL;
  10725. +}
  10726. +
  10727. +static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
  10728. +{
  10729. + if (pin && pin->hdir)
  10730. + return pin->hdir->hi_inode;
  10731. + return NULL;
  10732. +}
  10733. +
  10734. +static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
  10735. +{
  10736. + if (pin)
  10737. + return pin->hdir;
  10738. + return NULL;
  10739. +}
  10740. +
  10741. +static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
  10742. +{
  10743. + if (pin)
  10744. + pin->dentry = dentry;
  10745. +}
  10746. +
  10747. +static inline void au_pin_set_parent_lflag(struct au_pin *pin,
  10748. + unsigned char lflag)
  10749. +{
  10750. + if (pin) {
  10751. + /* dirty macros require brackets */
  10752. + if (lflag) {
  10753. + au_fset_pin(pin->flags, DI_LOCKED);
  10754. + } else {
  10755. + au_fclr_pin(pin->flags, DI_LOCKED);
  10756. + }
  10757. + }
  10758. +}
  10759. +
  10760. +static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
  10761. +{
  10762. + if (pin) {
  10763. + dput(pin->parent);
  10764. + pin->parent = dget(parent);
  10765. + }
  10766. +}
  10767. +
  10768. +/* ---------------------------------------------------------------------- */
  10769. +
  10770. +#ifdef CONFIG_AUFS_HINOTIFY
  10771. +/* hinotify.c */
  10772. +int au_hin_alloc(struct au_hinode *hinode, struct inode *inode,
  10773. + struct inode *h_inode);
  10774. +void au_hin_free(struct au_hinode *hinode);
  10775. +void au_hin_ctl(struct au_hinode *hinode, int do_set);
  10776. +void au_reset_hinotify(struct inode *inode, unsigned int flags);
  10777. +
  10778. +int __init au_hinotify_init(void);
  10779. +void au_hinotify_fin(void);
  10780. +
  10781. +static inline
  10782. +void au_hin_init(struct au_hinode *hinode, struct au_hinotify *val)
  10783. +{
  10784. + hinode->hi_notify = val;
  10785. +}
  10786. +
  10787. +static inline void au_iigen_dec(struct inode *inode)
  10788. +{
  10789. + atomic_dec_return(&au_ii(inode)->ii_generation);
  10790. +}
  10791. +
  10792. +#else
  10793. +static inline
  10794. +int au_hin_alloc(struct au_hinode *hinode __maybe_unused,
  10795. + struct inode *inode __maybe_unused,
  10796. + struct inode *h_inode __maybe_unused)
  10797. +{
  10798. + return -EOPNOTSUPP;
  10799. +}
  10800. +
  10801. +static inline void au_hin_free(struct au_hinode *hinode __maybe_unused)
  10802. +{
  10803. + /* nothing */
  10804. +}
  10805. +
  10806. +static inline void au_hin_ctl(struct au_hinode *hinode __maybe_unused,
  10807. + int do_set __maybe_unused)
  10808. +{
  10809. + /* nothing */
  10810. +}
  10811. +
  10812. +static inline void au_reset_hinotify(struct inode *inode __maybe_unused,
  10813. + unsigned int flags __maybe_unused)
  10814. +{
  10815. + /* nothing */
  10816. +}
  10817. +
  10818. +static inline int au_hinotify_init(void)
  10819. +{
  10820. + return 0;
  10821. +}
  10822. +
  10823. +#define au_hinotify_fin() do {} while (0)
  10824. +
  10825. +static inline
  10826. +void au_hin_init(struct au_hinode *hinode __maybe_unused,
  10827. + struct au_hinotify *val __maybe_unused)
  10828. +{
  10829. + /* empty */
  10830. +}
  10831. +#endif /* CONFIG_AUFS_HINOTIFY */
  10832. +
  10833. +static inline void au_hin_suspend(struct au_hinode *hdir)
  10834. +{
  10835. + au_hin_ctl(hdir, /*do_set*/0);
  10836. +}
  10837. +
  10838. +static inline void au_hin_resume(struct au_hinode *hdir)
  10839. +{
  10840. + au_hin_ctl(hdir, /*do_set*/1);
  10841. +}
  10842. +
  10843. +static inline void au_hin_imtx_lock(struct au_hinode *hdir)
  10844. +{
  10845. + mutex_lock(&hdir->hi_inode->i_mutex);
  10846. + au_hin_suspend(hdir);
  10847. +}
  10848. +
  10849. +static inline void au_hin_imtx_lock_nested(struct au_hinode *hdir,
  10850. + unsigned int sc __maybe_unused)
  10851. +{
  10852. + mutex_lock_nested(&hdir->hi_inode->i_mutex, sc);
  10853. + au_hin_suspend(hdir);
  10854. +}
  10855. +
  10856. +static inline void au_hin_imtx_unlock(struct au_hinode *hdir)
  10857. +{
  10858. + au_hin_resume(hdir);
  10859. + mutex_unlock(&hdir->hi_inode->i_mutex);
  10860. +}
  10861. +
  10862. +#endif /* __KERNEL__ */
  10863. +#endif /* __AUFS_INODE_H__ */
  10864. diff -Nur linux-2.6.31.4.orig/fs/aufs/ioctl.c linux-2.6.31.4/fs/aufs/ioctl.c
  10865. --- linux-2.6.31.4.orig/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100
  10866. +++ linux-2.6.31.4/fs/aufs/ioctl.c 2009-10-18 11:26:01.000000000 +0200
  10867. @@ -0,0 +1,67 @@
  10868. +/*
  10869. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  10870. + *
  10871. + * This program, aufs is free software; you can redistribute it and/or modify
  10872. + * it under the terms of the GNU General Public License as published by
  10873. + * the Free Software Foundation; either version 2 of the License, or
  10874. + * (at your option) any later version.
  10875. + *
  10876. + * This program is distributed in the hope that it will be useful,
  10877. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10878. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10879. + * GNU General Public License for more details.
  10880. + *
  10881. + * You should have received a copy of the GNU General Public License
  10882. + * along with this program; if not, write to the Free Software
  10883. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  10884. + */
  10885. +
  10886. +/*
  10887. + * ioctl
  10888. + * currently plink-management only.
  10889. + */
  10890. +
  10891. +#include <linux/uaccess.h>
  10892. +#include "aufs.h"
  10893. +
  10894. +long aufs_ioctl_dir(struct file *file, unsigned int cmd,
  10895. + unsigned long arg __maybe_unused)
  10896. +{
  10897. + long err;
  10898. + struct super_block *sb;
  10899. + struct au_sbinfo *sbinfo;
  10900. +
  10901. + err = -EACCES;
  10902. + if (!capable(CAP_SYS_ADMIN))
  10903. + goto out;
  10904. +
  10905. + err = 0;
  10906. + sb = file->f_dentry->d_sb;
  10907. + sbinfo = au_sbi(sb);
  10908. + switch (cmd) {
  10909. + case AUFS_CTL_PLINK_MAINT:
  10910. + /*
  10911. + * pseudo-link maintenance mode,
  10912. + * cleared by aufs_release_dir()
  10913. + */
  10914. + si_write_lock(sb);
  10915. + if (!au_ftest_si(sbinfo, MAINTAIN_PLINK)) {
  10916. + au_fset_si(sbinfo, MAINTAIN_PLINK);
  10917. + au_fi(file)->fi_maintain_plink = 1;
  10918. + } else
  10919. + err = -EBUSY;
  10920. + si_write_unlock(sb);
  10921. + break;
  10922. + case AUFS_CTL_PLINK_CLEAN:
  10923. + aufs_write_lock(sb->s_root);
  10924. + if (au_opt_test(sbinfo->si_mntflags, PLINK))
  10925. + au_plink_put(sb);
  10926. + aufs_write_unlock(sb->s_root);
  10927. + break;
  10928. + default:
  10929. + err = -EINVAL;
  10930. + }
  10931. +
  10932. + out:
  10933. + return err;
  10934. +}
  10935. diff -Nur linux-2.6.31.4.orig/fs/aufs/i_op_add.c linux-2.6.31.4/fs/aufs/i_op_add.c
  10936. --- linux-2.6.31.4.orig/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
  10937. +++ linux-2.6.31.4/fs/aufs/i_op_add.c 2009-10-18 11:26:01.000000000 +0200
  10938. @@ -0,0 +1,649 @@
  10939. +/*
  10940. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  10941. + *
  10942. + * This program, aufs is free software; you can redistribute it and/or modify
  10943. + * it under the terms of the GNU General Public License as published by
  10944. + * the Free Software Foundation; either version 2 of the License, or
  10945. + * (at your option) any later version.
  10946. + *
  10947. + * This program is distributed in the hope that it will be useful,
  10948. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10949. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10950. + * GNU General Public License for more details.
  10951. + *
  10952. + * You should have received a copy of the GNU General Public License
  10953. + * along with this program; if not, write to the Free Software
  10954. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  10955. + */
  10956. +
  10957. +/*
  10958. + * inode operations (add entry)
  10959. + */
  10960. +
  10961. +#include "aufs.h"
  10962. +
  10963. +/*
  10964. + * final procedure of adding a new entry, except link(2).
  10965. + * remove whiteout, instantiate, copyup the parent dir's times and size
  10966. + * and update version.
  10967. + * if it failed, re-create the removed whiteout.
  10968. + */
  10969. +static int epilog(struct inode *dir, aufs_bindex_t bindex,
  10970. + struct dentry *wh_dentry, struct dentry *dentry)
  10971. +{
  10972. + int err, rerr;
  10973. + aufs_bindex_t bwh;
  10974. + struct path h_path;
  10975. + struct inode *inode, *h_dir;
  10976. + struct dentry *wh;
  10977. +
  10978. + bwh = -1;
  10979. + if (wh_dentry) {
  10980. + h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
  10981. + IMustLock(h_dir);
  10982. + AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
  10983. + bwh = au_dbwh(dentry);
  10984. + h_path.dentry = wh_dentry;
  10985. + h_path.mnt = au_sbr_mnt(dir->i_sb, bindex);
  10986. + err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
  10987. + dentry);
  10988. + if (unlikely(err))
  10989. + goto out;
  10990. + }
  10991. +
  10992. + inode = au_new_inode(dentry, /*must_new*/1);
  10993. + if (!IS_ERR(inode)) {
  10994. + d_instantiate(dentry, inode);
  10995. + dir = dentry->d_parent->d_inode; /* dir inode is locked */
  10996. + IMustLock(dir);
  10997. + if (au_ibstart(dir) == au_dbstart(dentry))
  10998. + au_cpup_attr_timesizes(dir);
  10999. + dir->i_version++;
  11000. + return 0; /* success */
  11001. + }
  11002. +
  11003. + err = PTR_ERR(inode);
  11004. + if (!wh_dentry)
  11005. + goto out;
  11006. +
  11007. + /* revert */
  11008. + /* dir inode is locked */
  11009. + wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
  11010. + rerr = PTR_ERR(wh);
  11011. + if (IS_ERR(wh)) {
  11012. + AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
  11013. + AuDLNPair(dentry), err, rerr);
  11014. + err = -EIO;
  11015. + } else
  11016. + dput(wh);
  11017. +
  11018. + out:
  11019. + return err;
  11020. +}
  11021. +
  11022. +/*
  11023. + * simple tests for the adding inode operations.
  11024. + * following the checks in vfs, plus the parent-child relationship.
  11025. + */
  11026. +int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
  11027. + struct dentry *h_parent, int isdir)
  11028. +{
  11029. + int err;
  11030. + umode_t h_mode;
  11031. + struct dentry *h_dentry;
  11032. + struct inode *h_inode;
  11033. +
  11034. + h_dentry = au_h_dptr(dentry, bindex);
  11035. + h_inode = h_dentry->d_inode;
  11036. + if (!dentry->d_inode) {
  11037. + err = -EEXIST;
  11038. + if (unlikely(h_inode))
  11039. + goto out;
  11040. + } else {
  11041. + /* rename(2) case */
  11042. + err = -EIO;
  11043. + if (unlikely(!h_inode || !h_inode->i_nlink))
  11044. + goto out;
  11045. +
  11046. + h_mode = h_inode->i_mode;
  11047. + if (!isdir) {
  11048. + err = -EISDIR;
  11049. + if (unlikely(S_ISDIR(h_mode)))
  11050. + goto out;
  11051. + } else if (unlikely(!S_ISDIR(h_mode))) {
  11052. + err = -ENOTDIR;
  11053. + goto out;
  11054. + }
  11055. + }
  11056. +
  11057. + err = -EIO;
  11058. + /* expected parent dir is locked */
  11059. + if (unlikely(h_parent != h_dentry->d_parent))
  11060. + goto out;
  11061. + err = 0;
  11062. +
  11063. + out:
  11064. + return err;
  11065. +}
  11066. +
  11067. +/*
  11068. + * initial procedure of adding a new entry.
  11069. + * prepare writable branch and the parent dir, lock it,
  11070. + * and lookup whiteout for the new entry.
  11071. + */
  11072. +static struct dentry*
  11073. +lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
  11074. + struct dentry *src_dentry, struct au_pin *pin,
  11075. + struct au_wr_dir_args *wr_dir_args)
  11076. +{
  11077. + struct dentry *wh_dentry, *h_parent;
  11078. + struct super_block *sb;
  11079. + struct au_branch *br;
  11080. + int err;
  11081. + unsigned int udba;
  11082. + aufs_bindex_t bcpup;
  11083. +
  11084. + err = au_wr_dir(dentry, src_dentry, wr_dir_args);
  11085. + bcpup = err;
  11086. + wh_dentry = ERR_PTR(err);
  11087. + if (unlikely(err < 0))
  11088. + goto out;
  11089. +
  11090. + sb = dentry->d_sb;
  11091. + udba = au_opt_udba(sb);
  11092. + err = au_pin(pin, dentry, bcpup, udba,
  11093. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  11094. + wh_dentry = ERR_PTR(err);
  11095. + if (unlikely(err))
  11096. + goto out;
  11097. +
  11098. + h_parent = au_pinned_h_parent(pin);
  11099. + if (udba != AuOpt_UDBA_NONE
  11100. + && au_dbstart(dentry) == bcpup) {
  11101. + err = au_may_add(dentry, bcpup, h_parent,
  11102. + au_ftest_wrdir(wr_dir_args->flags, ISDIR));
  11103. + wh_dentry = ERR_PTR(err);
  11104. + if (unlikely(err))
  11105. + goto out_unpin;
  11106. + }
  11107. +
  11108. + br = au_sbr(sb, bcpup);
  11109. + if (dt) {
  11110. + struct path tmp = {
  11111. + .dentry = h_parent,
  11112. + .mnt = br->br_mnt
  11113. + };
  11114. + au_dtime_store(dt, au_pinned_parent(pin), &tmp);
  11115. + }
  11116. +
  11117. + wh_dentry = NULL;
  11118. + if (bcpup != au_dbwh(dentry))
  11119. + goto out; /* success */
  11120. +
  11121. + wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
  11122. +
  11123. + out_unpin:
  11124. + if (IS_ERR(wh_dentry))
  11125. + au_unpin(pin);
  11126. + out:
  11127. + return wh_dentry;
  11128. +}
  11129. +
  11130. +/* ---------------------------------------------------------------------- */
  11131. +
  11132. +enum { Mknod, Symlink, Creat };
  11133. +struct simple_arg {
  11134. + int type;
  11135. + union {
  11136. + struct {
  11137. + int mode;
  11138. + struct nameidata *nd;
  11139. + } c;
  11140. + struct {
  11141. + const char *symname;
  11142. + } s;
  11143. + struct {
  11144. + int mode;
  11145. + dev_t dev;
  11146. + } m;
  11147. + } u;
  11148. +};
  11149. +
  11150. +static int add_simple(struct inode *dir, struct dentry *dentry,
  11151. + struct simple_arg *arg)
  11152. +{
  11153. + int err;
  11154. + aufs_bindex_t bstart;
  11155. + unsigned char created;
  11156. + struct au_dtime dt;
  11157. + struct au_pin pin;
  11158. + struct path h_path;
  11159. + struct dentry *wh_dentry, *parent;
  11160. + struct inode *h_dir;
  11161. + struct au_wr_dir_args wr_dir_args = {
  11162. + .force_btgt = -1,
  11163. + .flags = AuWrDir_ADD_ENTRY
  11164. + };
  11165. +
  11166. + IMustLock(dir);
  11167. +
  11168. + parent = dentry->d_parent; /* dir inode is locked */
  11169. + aufs_read_lock(dentry, AuLock_DW);
  11170. + di_write_lock_parent(parent);
  11171. + wh_dentry = lock_hdir_lkup_wh(dentry, &dt, /*src_dentry*/NULL, &pin,
  11172. + &wr_dir_args);
  11173. + err = PTR_ERR(wh_dentry);
  11174. + if (IS_ERR(wh_dentry))
  11175. + goto out;
  11176. +
  11177. + bstart = au_dbstart(dentry);
  11178. + h_path.dentry = au_h_dptr(dentry, bstart);
  11179. + h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
  11180. + h_dir = au_pinned_h_dir(&pin);
  11181. + switch (arg->type) {
  11182. + case Creat:
  11183. + err = vfsub_create(h_dir, &h_path, arg->u.c.mode);
  11184. + break;
  11185. + case Symlink:
  11186. + err = vfsub_symlink(h_dir, &h_path, arg->u.s.symname);
  11187. + break;
  11188. + case Mknod:
  11189. + err = vfsub_mknod(h_dir, &h_path, arg->u.m.mode, arg->u.m.dev);
  11190. + break;
  11191. + default:
  11192. + BUG();
  11193. + }
  11194. + created = !err;
  11195. + if (!err)
  11196. + err = epilog(dir, bstart, wh_dentry, dentry);
  11197. +
  11198. + /* revert */
  11199. + if (unlikely(created && err && h_path.dentry->d_inode)) {
  11200. + int rerr;
  11201. + rerr = vfsub_unlink(h_dir, &h_path, /*force*/0);
  11202. + if (rerr) {
  11203. + AuIOErr("%.*s revert failure(%d, %d)\n",
  11204. + AuDLNPair(dentry), err, rerr);
  11205. + err = -EIO;
  11206. + }
  11207. + au_dtime_revert(&dt);
  11208. + d_drop(dentry);
  11209. + }
  11210. +
  11211. + au_unpin(&pin);
  11212. + dput(wh_dentry);
  11213. +
  11214. + out:
  11215. + if (unlikely(err)) {
  11216. + au_update_dbstart(dentry);
  11217. + d_drop(dentry);
  11218. + }
  11219. + di_write_unlock(parent);
  11220. + aufs_read_unlock(dentry, AuLock_DW);
  11221. + return err;
  11222. +}
  11223. +
  11224. +int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
  11225. +{
  11226. + struct simple_arg arg = {
  11227. + .type = Mknod,
  11228. + .u.m = {
  11229. + .mode = mode,
  11230. + .dev = dev
  11231. + }
  11232. + };
  11233. + return add_simple(dir, dentry, &arg);
  11234. +}
  11235. +
  11236. +int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
  11237. +{
  11238. + struct simple_arg arg = {
  11239. + .type = Symlink,
  11240. + .u.s.symname = symname
  11241. + };
  11242. + return add_simple(dir, dentry, &arg);
  11243. +}
  11244. +
  11245. +int aufs_create(struct inode *dir, struct dentry *dentry, int mode,
  11246. + struct nameidata *nd)
  11247. +{
  11248. + struct simple_arg arg = {
  11249. + .type = Creat,
  11250. + .u.c = {
  11251. + .mode = mode,
  11252. + .nd = nd
  11253. + }
  11254. + };
  11255. + return add_simple(dir, dentry, &arg);
  11256. +}
  11257. +
  11258. +/* ---------------------------------------------------------------------- */
  11259. +
  11260. +struct au_link_args {
  11261. + aufs_bindex_t bdst, bsrc;
  11262. + struct au_pin pin;
  11263. + struct path h_path;
  11264. + struct dentry *src_parent, *parent;
  11265. +};
  11266. +
  11267. +static int au_cpup_before_link(struct dentry *src_dentry,
  11268. + struct au_link_args *a)
  11269. +{
  11270. + int err;
  11271. + struct dentry *h_src_dentry;
  11272. + struct mutex *h_mtx;
  11273. +
  11274. + di_read_lock_parent(a->src_parent, AuLock_IR);
  11275. + err = au_test_and_cpup_dirs(src_dentry, a->bdst);
  11276. + if (unlikely(err))
  11277. + goto out;
  11278. +
  11279. + h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
  11280. + h_mtx = &h_src_dentry->d_inode->i_mutex;
  11281. + err = au_pin(&a->pin, src_dentry, a->bdst,
  11282. + au_opt_udba(src_dentry->d_sb),
  11283. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  11284. + if (unlikely(err))
  11285. + goto out;
  11286. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  11287. + err = au_sio_cpup_simple(src_dentry, a->bdst, -1,
  11288. + AuCpup_DTIME /* | AuCpup_KEEPLINO */);
  11289. + mutex_unlock(h_mtx);
  11290. + au_unpin(&a->pin);
  11291. +
  11292. + out:
  11293. + di_read_unlock(a->src_parent, AuLock_IR);
  11294. + return err;
  11295. +}
  11296. +
  11297. +static int au_cpup_or_link(struct dentry *src_dentry, struct au_link_args *a)
  11298. +{
  11299. + int err;
  11300. + unsigned char plink;
  11301. + struct inode *h_inode, *inode;
  11302. + struct dentry *h_src_dentry;
  11303. + struct super_block *sb;
  11304. +
  11305. + plink = 0;
  11306. + h_inode = NULL;
  11307. + sb = src_dentry->d_sb;
  11308. + inode = src_dentry->d_inode;
  11309. + if (au_ibstart(inode) <= a->bdst)
  11310. + h_inode = au_h_iptr(inode, a->bdst);
  11311. + if (!h_inode || !h_inode->i_nlink) {
  11312. + /* copyup src_dentry as the name of dentry. */
  11313. + au_set_dbstart(src_dentry, a->bdst);
  11314. + au_set_h_dptr(src_dentry, a->bdst, dget(a->h_path.dentry));
  11315. + h_inode = au_h_dptr(src_dentry, a->bsrc)->d_inode;
  11316. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  11317. + err = au_sio_cpup_single(src_dentry, a->bdst, a->bsrc, -1,
  11318. + AuCpup_KEEPLINO, a->parent);
  11319. + mutex_unlock(&h_inode->i_mutex);
  11320. + au_set_h_dptr(src_dentry, a->bdst, NULL);
  11321. + au_set_dbstart(src_dentry, a->bsrc);
  11322. + } else {
  11323. + /* the inode of src_dentry already exists on a.bdst branch */
  11324. + h_src_dentry = d_find_alias(h_inode);
  11325. + if (!h_src_dentry && au_plink_test(inode)) {
  11326. + plink = 1;
  11327. + h_src_dentry = au_plink_lkup(inode, a->bdst);
  11328. + err = PTR_ERR(h_src_dentry);
  11329. + if (IS_ERR(h_src_dentry))
  11330. + goto out;
  11331. +
  11332. + if (unlikely(!h_src_dentry->d_inode)) {
  11333. + dput(h_src_dentry);
  11334. + h_src_dentry = NULL;
  11335. + }
  11336. +
  11337. + }
  11338. + if (h_src_dentry) {
  11339. + err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
  11340. + &a->h_path);
  11341. + dput(h_src_dentry);
  11342. + } else {
  11343. + AuIOErr("no dentry found for hi%lu on b%d\n",
  11344. + h_inode->i_ino, a->bdst);
  11345. + err = -EIO;
  11346. + }
  11347. + }
  11348. +
  11349. + if (!err && !plink)
  11350. + au_plink_append(inode, a->bdst, a->h_path.dentry);
  11351. +
  11352. +out:
  11353. + return err;
  11354. +}
  11355. +
  11356. +int aufs_link(struct dentry *src_dentry, struct inode *dir,
  11357. + struct dentry *dentry)
  11358. +{
  11359. + int err, rerr;
  11360. + struct au_dtime dt;
  11361. + struct au_link_args *a;
  11362. + struct dentry *wh_dentry, *h_src_dentry;
  11363. + struct inode *inode;
  11364. + struct super_block *sb;
  11365. + struct au_wr_dir_args wr_dir_args = {
  11366. + /* .force_btgt = -1, */
  11367. + .flags = AuWrDir_ADD_ENTRY
  11368. + };
  11369. +
  11370. + IMustLock(dir);
  11371. + inode = src_dentry->d_inode;
  11372. + IMustLock(inode);
  11373. +
  11374. + err = -ENOENT;
  11375. + if (unlikely(!inode->i_nlink))
  11376. + goto out;
  11377. +
  11378. + err = -ENOMEM;
  11379. + a = kzalloc(sizeof(*a), GFP_NOFS);
  11380. + if (unlikely(!a))
  11381. + goto out;
  11382. +
  11383. + a->parent = dentry->d_parent; /* dir inode is locked */
  11384. + aufs_read_and_write_lock2(dentry, src_dentry, /*AuLock_FLUSH*/0);
  11385. + a->src_parent = dget_parent(src_dentry);
  11386. + wr_dir_args.force_btgt = au_dbstart(src_dentry);
  11387. +
  11388. + di_write_lock_parent(a->parent);
  11389. + wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
  11390. + wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
  11391. + &wr_dir_args);
  11392. + err = PTR_ERR(wh_dentry);
  11393. + if (IS_ERR(wh_dentry))
  11394. + goto out_unlock;
  11395. +
  11396. + err = 0;
  11397. + sb = dentry->d_sb;
  11398. + a->bdst = au_dbstart(dentry);
  11399. + a->h_path.dentry = au_h_dptr(dentry, a->bdst);
  11400. + a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
  11401. + a->bsrc = au_dbstart(src_dentry);
  11402. + if (au_opt_test(au_mntflags(sb), PLINK)) {
  11403. + if (a->bdst < a->bsrc
  11404. + /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
  11405. + err = au_cpup_or_link(src_dentry, a);
  11406. + else {
  11407. + h_src_dentry = au_h_dptr(src_dentry, a->bdst);
  11408. + err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
  11409. + &a->h_path);
  11410. + }
  11411. + } else {
  11412. + /*
  11413. + * copyup src_dentry to the branch we process,
  11414. + * and then link(2) to it.
  11415. + */
  11416. + if (a->bdst < a->bsrc
  11417. + /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
  11418. + au_unpin(&a->pin);
  11419. + di_write_unlock(a->parent);
  11420. + err = au_cpup_before_link(src_dentry, a);
  11421. + di_write_lock_parent(a->parent);
  11422. + if (!err)
  11423. + err = au_pin(&a->pin, dentry, a->bdst,
  11424. + au_opt_udba(sb),
  11425. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  11426. + if (unlikely(err))
  11427. + goto out_wh;
  11428. + }
  11429. + if (!err) {
  11430. + h_src_dentry = au_h_dptr(src_dentry, a->bdst);
  11431. + err = -ENOENT;
  11432. + if (h_src_dentry && h_src_dentry->d_inode)
  11433. + err = vfsub_link(h_src_dentry,
  11434. + au_pinned_h_dir(&a->pin),
  11435. + &a->h_path);
  11436. + }
  11437. + }
  11438. + if (unlikely(err))
  11439. + goto out_unpin;
  11440. +
  11441. + if (wh_dentry) {
  11442. + a->h_path.dentry = wh_dentry;
  11443. + err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
  11444. + dentry);
  11445. + if (unlikely(err))
  11446. + goto out_revert;
  11447. + }
  11448. +
  11449. + dir->i_version++;
  11450. + if (au_ibstart(dir) == au_dbstart(dentry))
  11451. + au_cpup_attr_timesizes(dir);
  11452. + inc_nlink(inode);
  11453. + inode->i_ctime = dir->i_ctime;
  11454. + if (!d_unhashed(a->h_path.dentry))
  11455. + d_instantiate(dentry, au_igrab(inode));
  11456. + else
  11457. + /* some filesystem calls d_drop() */
  11458. + d_drop(dentry);
  11459. + goto out_unpin; /* success */
  11460. +
  11461. + out_revert:
  11462. + rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path, /*force*/0);
  11463. + if (!rerr)
  11464. + goto out_dt;
  11465. + AuIOErr("%.*s reverting failed(%d, %d)\n",
  11466. + AuDLNPair(dentry), err, rerr);
  11467. + err = -EIO;
  11468. + out_dt:
  11469. + d_drop(dentry);
  11470. + au_dtime_revert(&dt);
  11471. + out_unpin:
  11472. + au_unpin(&a->pin);
  11473. + out_wh:
  11474. + dput(wh_dentry);
  11475. + out_unlock:
  11476. + if (unlikely(err)) {
  11477. + au_update_dbstart(dentry);
  11478. + d_drop(dentry);
  11479. + }
  11480. + di_write_unlock(a->parent);
  11481. + dput(a->src_parent);
  11482. + aufs_read_and_write_unlock2(dentry, src_dentry);
  11483. + kfree(a);
  11484. + out:
  11485. + return err;
  11486. +}
  11487. +
  11488. +int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
  11489. +{
  11490. + int err, rerr;
  11491. + aufs_bindex_t bindex;
  11492. + unsigned char diropq;
  11493. + struct path h_path;
  11494. + struct dentry *wh_dentry, *parent, *opq_dentry;
  11495. + struct mutex *h_mtx;
  11496. + struct super_block *sb;
  11497. + struct {
  11498. + struct au_pin pin;
  11499. + struct au_dtime dt;
  11500. + } *a; /* reduce the stack usage */
  11501. + struct au_wr_dir_args wr_dir_args = {
  11502. + .force_btgt = -1,
  11503. + .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
  11504. + };
  11505. +
  11506. + IMustLock(dir);
  11507. +
  11508. + err = -ENOMEM;
  11509. + a = kmalloc(sizeof(*a), GFP_NOFS);
  11510. + if (unlikely(!a))
  11511. + goto out;
  11512. +
  11513. + aufs_read_lock(dentry, AuLock_DW);
  11514. + parent = dentry->d_parent; /* dir inode is locked */
  11515. + di_write_lock_parent(parent);
  11516. + wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
  11517. + &a->pin, &wr_dir_args);
  11518. + err = PTR_ERR(wh_dentry);
  11519. + if (IS_ERR(wh_dentry))
  11520. + goto out_free;
  11521. +
  11522. + sb = dentry->d_sb;
  11523. + bindex = au_dbstart(dentry);
  11524. + h_path.dentry = au_h_dptr(dentry, bindex);
  11525. + h_path.mnt = au_sbr_mnt(sb, bindex);
  11526. + err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
  11527. + if (unlikely(err))
  11528. + goto out_unlock;
  11529. +
  11530. + /* make the dir opaque */
  11531. + diropq = 0;
  11532. + h_mtx = &h_path.dentry->d_inode->i_mutex;
  11533. + if (wh_dentry
  11534. + || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
  11535. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  11536. + opq_dentry = au_diropq_create(dentry, bindex);
  11537. + mutex_unlock(h_mtx);
  11538. + err = PTR_ERR(opq_dentry);
  11539. + if (IS_ERR(opq_dentry))
  11540. + goto out_dir;
  11541. + dput(opq_dentry);
  11542. + diropq = 1;
  11543. + }
  11544. +
  11545. + err = epilog(dir, bindex, wh_dentry, dentry);
  11546. + if (!err) {
  11547. + inc_nlink(dir);
  11548. + goto out_unlock; /* success */
  11549. + }
  11550. +
  11551. + /* revert */
  11552. + if (diropq) {
  11553. + AuLabel(revert opq);
  11554. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  11555. + rerr = au_diropq_remove(dentry, bindex);
  11556. + mutex_unlock(h_mtx);
  11557. + if (rerr) {
  11558. + AuIOErr("%.*s reverting diropq failed(%d, %d)\n",
  11559. + AuDLNPair(dentry), err, rerr);
  11560. + err = -EIO;
  11561. + }
  11562. + }
  11563. +
  11564. + out_dir:
  11565. + AuLabel(revert dir);
  11566. + rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
  11567. + if (rerr) {
  11568. + AuIOErr("%.*s reverting dir failed(%d, %d)\n",
  11569. + AuDLNPair(dentry), err, rerr);
  11570. + err = -EIO;
  11571. + }
  11572. + d_drop(dentry);
  11573. + au_dtime_revert(&a->dt);
  11574. + out_unlock:
  11575. + au_unpin(&a->pin);
  11576. + dput(wh_dentry);
  11577. + out_free:
  11578. + if (unlikely(err)) {
  11579. + au_update_dbstart(dentry);
  11580. + d_drop(dentry);
  11581. + }
  11582. + di_write_unlock(parent);
  11583. + aufs_read_unlock(dentry, AuLock_DW);
  11584. + kfree(a);
  11585. + out:
  11586. + return err;
  11587. +}
  11588. diff -Nur linux-2.6.31.4.orig/fs/aufs/i_op.c linux-2.6.31.4/fs/aufs/i_op.c
  11589. --- linux-2.6.31.4.orig/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
  11590. +++ linux-2.6.31.4/fs/aufs/i_op.c 2009-10-18 11:26:01.000000000 +0200
  11591. @@ -0,0 +1,872 @@
  11592. +/*
  11593. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  11594. + *
  11595. + * This program, aufs is free software; you can redistribute it and/or modify
  11596. + * it under the terms of the GNU General Public License as published by
  11597. + * the Free Software Foundation; either version 2 of the License, or
  11598. + * (at your option) any later version.
  11599. + *
  11600. + * This program is distributed in the hope that it will be useful,
  11601. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11602. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11603. + * GNU General Public License for more details.
  11604. + *
  11605. + * You should have received a copy of the GNU General Public License
  11606. + * along with this program; if not, write to the Free Software
  11607. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  11608. + */
  11609. +
  11610. +/*
  11611. + * inode operations (except add/del/rename)
  11612. + */
  11613. +
  11614. +#include <linux/device_cgroup.h>
  11615. +#include <linux/fs_stack.h>
  11616. +#include <linux/mm.h>
  11617. +#include <linux/namei.h>
  11618. +#include <linux/security.h>
  11619. +#include <linux/uaccess.h>
  11620. +#include "aufs.h"
  11621. +
  11622. +static int h_permission(struct inode *h_inode, int mask,
  11623. + struct vfsmount *h_mnt, int brperm)
  11624. +{
  11625. + int err;
  11626. + const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
  11627. +
  11628. + err = -EACCES;
  11629. + if ((write_mask && IS_IMMUTABLE(h_inode))
  11630. + || ((mask & MAY_EXEC)
  11631. + && S_ISREG(h_inode->i_mode)
  11632. + && ((h_mnt->mnt_flags & MNT_NOEXEC)
  11633. + || !(h_inode->i_mode & S_IXUGO))))
  11634. + goto out;
  11635. +
  11636. + /*
  11637. + * - skip the lower fs test in the case of write to ro branch.
  11638. + * - nfs dir permission write check is optimized, but a policy for
  11639. + * link/rename requires a real check.
  11640. + */
  11641. + if ((write_mask && !au_br_writable(brperm))
  11642. + || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
  11643. + && write_mask && !(mask & MAY_READ))
  11644. + || !h_inode->i_op->permission) {
  11645. + /* AuLabel(generic_permission); */
  11646. + err = generic_permission(h_inode, mask, NULL);
  11647. + } else {
  11648. + /* AuLabel(h_inode->permission); */
  11649. + err = h_inode->i_op->permission(h_inode, mask);
  11650. + AuTraceErr(err);
  11651. + }
  11652. +
  11653. + if (!err)
  11654. + err = devcgroup_inode_permission(h_inode, mask);
  11655. + if (!err)
  11656. + err = security_inode_permission
  11657. + (h_inode, mask & (MAY_READ | MAY_WRITE | MAY_EXEC
  11658. + | MAY_APPEND));
  11659. +
  11660. + out:
  11661. + return err;
  11662. +}
  11663. +
  11664. +static int aufs_permission(struct inode *inode, int mask)
  11665. +{
  11666. + int err;
  11667. + aufs_bindex_t bindex, bend;
  11668. + const unsigned char isdir = !!S_ISDIR(inode->i_mode);
  11669. + const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
  11670. + struct inode *h_inode;
  11671. + struct super_block *sb;
  11672. + struct au_branch *br;
  11673. +
  11674. + sb = inode->i_sb;
  11675. + si_read_lock(sb, AuLock_FLUSH);
  11676. + ii_read_lock_child(inode);
  11677. +
  11678. + if (!isdir || write_mask) {
  11679. + h_inode = au_h_iptr(inode, au_ibstart(inode));
  11680. + AuDebugOn(!h_inode
  11681. + || ((h_inode->i_mode & S_IFMT)
  11682. + != (inode->i_mode & S_IFMT)));
  11683. + err = 0;
  11684. + bindex = au_ibstart(inode);
  11685. + br = au_sbr(sb, bindex);
  11686. + err = h_permission(h_inode, mask, br->br_mnt, br->br_perm);
  11687. +
  11688. + if (write_mask && !err) {
  11689. + /* test whether the upper writable branch exists */
  11690. + err = -EROFS;
  11691. + for (; bindex >= 0; bindex--)
  11692. + if (!au_br_rdonly(au_sbr(sb, bindex))) {
  11693. + err = 0;
  11694. + break;
  11695. + }
  11696. + }
  11697. + goto out;
  11698. + }
  11699. +
  11700. + /* non-write to dir */
  11701. + err = 0;
  11702. + bend = au_ibend(inode);
  11703. + for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) {
  11704. + h_inode = au_h_iptr(inode, bindex);
  11705. + if (h_inode) {
  11706. + AuDebugOn(!S_ISDIR(h_inode->i_mode));
  11707. + br = au_sbr(sb, bindex);
  11708. + err = h_permission(h_inode, mask, br->br_mnt,
  11709. + br->br_perm);
  11710. + }
  11711. + }
  11712. +
  11713. + out:
  11714. + ii_read_unlock(inode);
  11715. + si_read_unlock(sb);
  11716. + return err;
  11717. +}
  11718. +
  11719. +/* ---------------------------------------------------------------------- */
  11720. +
  11721. +static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
  11722. + struct nameidata *nd)
  11723. +{
  11724. + struct dentry *ret, *parent;
  11725. + struct inode *inode, *h_inode;
  11726. + struct mutex *mtx;
  11727. + struct super_block *sb;
  11728. + int err, npositive;
  11729. + aufs_bindex_t bstart;
  11730. +
  11731. + /* temporary workaround for a bug in NFSD readdir */
  11732. + if (!au_test_nfsd(current))
  11733. + IMustLock(dir);
  11734. + else
  11735. + WARN_ONCE(!mutex_is_locked(&dir->i_mutex),
  11736. + "a known problem of NFSD readdir since 2.6.28\n");
  11737. +
  11738. + sb = dir->i_sb;
  11739. + si_read_lock(sb, AuLock_FLUSH);
  11740. + err = au_alloc_dinfo(dentry);
  11741. + ret = ERR_PTR(err);
  11742. + if (unlikely(err))
  11743. + goto out;
  11744. +
  11745. + parent = dentry->d_parent; /* dir inode is locked */
  11746. + di_read_lock_parent(parent, AuLock_IR);
  11747. + npositive = au_lkup_dentry(dentry, au_dbstart(parent), /*type*/0, nd);
  11748. + di_read_unlock(parent, AuLock_IR);
  11749. + err = npositive;
  11750. + ret = ERR_PTR(err);
  11751. + if (unlikely(err < 0))
  11752. + goto out_unlock;
  11753. +
  11754. + inode = NULL;
  11755. + if (npositive) {
  11756. + bstart = au_dbstart(dentry);
  11757. + h_inode = au_h_dptr(dentry, bstart)->d_inode;
  11758. + if (!S_ISDIR(h_inode->i_mode)) {
  11759. + /*
  11760. + * stop 'race'-ing between hardlinks under different
  11761. + * parents.
  11762. + */
  11763. + mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;
  11764. + mutex_lock(mtx);
  11765. + inode = au_new_inode(dentry, /*must_new*/0);
  11766. + mutex_unlock(mtx);
  11767. + } else
  11768. + inode = au_new_inode(dentry, /*must_new*/0);
  11769. + ret = (void *)inode;
  11770. + }
  11771. + if (IS_ERR(inode))
  11772. + goto out_unlock;
  11773. +
  11774. + ret = d_splice_alias(inode, dentry);
  11775. + if (unlikely(IS_ERR(ret) && inode))
  11776. + ii_write_unlock(inode);
  11777. + au_store_oflag(nd, inode);
  11778. +
  11779. + out_unlock:
  11780. + di_write_unlock(dentry);
  11781. + out:
  11782. + si_read_unlock(sb);
  11783. + return ret;
  11784. +}
  11785. +
  11786. +/* ---------------------------------------------------------------------- */
  11787. +
  11788. +static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
  11789. + const unsigned char add_entry, aufs_bindex_t bcpup,
  11790. + aufs_bindex_t bstart)
  11791. +{
  11792. + int err;
  11793. + struct dentry *h_parent;
  11794. + struct inode *h_dir;
  11795. +
  11796. + if (add_entry) {
  11797. + au_update_dbstart(dentry);
  11798. + IMustLock(parent->d_inode);
  11799. + } else
  11800. + di_write_lock_parent(parent);
  11801. +
  11802. + err = 0;
  11803. + if (!au_h_dptr(parent, bcpup)) {
  11804. + if (bstart < bcpup)
  11805. + err = au_cpdown_dirs(dentry, bcpup);
  11806. + else
  11807. + err = au_cpup_dirs(dentry, bcpup);
  11808. + }
  11809. + if (!err && add_entry) {
  11810. + h_parent = au_h_dptr(parent, bcpup);
  11811. + h_dir = h_parent->d_inode;
  11812. + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
  11813. + err = au_lkup_neg(dentry, bcpup);
  11814. + /* todo: no unlock here */
  11815. + mutex_unlock(&h_dir->i_mutex);
  11816. + if (bstart < bcpup && au_dbstart(dentry) < 0) {
  11817. + au_set_dbstart(dentry, 0);
  11818. + au_update_dbrange(dentry, /*do_put_zero*/0);
  11819. + }
  11820. + }
  11821. +
  11822. + if (!add_entry)
  11823. + di_write_unlock(parent);
  11824. + if (!err)
  11825. + err = bcpup; /* success */
  11826. +
  11827. + return err;
  11828. +}
  11829. +
  11830. +/*
  11831. + * decide the branch and the parent dir where we will create a new entry.
  11832. + * returns new bindex or an error.
  11833. + * copyup the parent dir if needed.
  11834. + */
  11835. +int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
  11836. + struct au_wr_dir_args *args)
  11837. +{
  11838. + int err;
  11839. + aufs_bindex_t bcpup, bstart, src_bstart;
  11840. + const unsigned char add_entry = !!au_ftest_wrdir(args->flags,
  11841. + ADD_ENTRY);
  11842. + struct super_block *sb;
  11843. + struct dentry *parent;
  11844. + struct au_sbinfo *sbinfo;
  11845. +
  11846. + sb = dentry->d_sb;
  11847. + sbinfo = au_sbi(sb);
  11848. + parent = dget_parent(dentry);
  11849. + bstart = au_dbstart(dentry);
  11850. + bcpup = bstart;
  11851. + if (args->force_btgt < 0) {
  11852. + if (src_dentry) {
  11853. + src_bstart = au_dbstart(src_dentry);
  11854. + if (src_bstart < bstart)
  11855. + bcpup = src_bstart;
  11856. + } else if (add_entry) {
  11857. + err = AuWbrCreate(sbinfo, dentry,
  11858. + au_ftest_wrdir(args->flags, ISDIR));
  11859. + bcpup = err;
  11860. + }
  11861. +
  11862. + if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) {
  11863. + if (add_entry)
  11864. + err = AuWbrCopyup(sbinfo, dentry);
  11865. + else {
  11866. + if (!IS_ROOT(dentry)) {
  11867. + di_read_lock_parent(parent, !AuLock_IR);
  11868. + err = AuWbrCopyup(sbinfo, dentry);
  11869. + di_read_unlock(parent, !AuLock_IR);
  11870. + } else
  11871. + err = AuWbrCopyup(sbinfo, dentry);
  11872. + }
  11873. + bcpup = err;
  11874. + if (unlikely(err < 0))
  11875. + goto out;
  11876. + }
  11877. + } else {
  11878. + bcpup = args->force_btgt;
  11879. + AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode));
  11880. + }
  11881. + AuDbg("bstart %d, bcpup %d\n", bstart, bcpup);
  11882. + if (bstart < bcpup)
  11883. + au_update_dbrange(dentry, /*do_put_zero*/1);
  11884. +
  11885. + err = bcpup;
  11886. + if (bcpup == bstart)
  11887. + goto out; /* success */
  11888. +
  11889. + /* copyup the new parent into the branch we process */
  11890. + err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart);
  11891. +
  11892. + out:
  11893. + dput(parent);
  11894. + return err;
  11895. +}
  11896. +
  11897. +/* ---------------------------------------------------------------------- */
  11898. +
  11899. +struct dentry *au_pinned_h_parent(struct au_pin *pin)
  11900. +{
  11901. + if (pin && pin->parent)
  11902. + return au_h_dptr(pin->parent, pin->bindex);
  11903. + return NULL;
  11904. +}
  11905. +
  11906. +void au_unpin(struct au_pin *p)
  11907. +{
  11908. + if (au_ftest_pin(p->flags, MNT_WRITE))
  11909. + mnt_drop_write(p->h_mnt);
  11910. + if (!p->hdir)
  11911. + return;
  11912. +
  11913. + au_hin_imtx_unlock(p->hdir);
  11914. + if (!au_ftest_pin(p->flags, DI_LOCKED))
  11915. + di_read_unlock(p->parent, AuLock_IR);
  11916. + iput(p->hdir->hi_inode);
  11917. + dput(p->parent);
  11918. + p->parent = NULL;
  11919. + p->hdir = NULL;
  11920. + p->h_mnt = NULL;
  11921. +}
  11922. +
  11923. +int au_do_pin(struct au_pin *p)
  11924. +{
  11925. + int err;
  11926. + struct super_block *sb;
  11927. + struct dentry *h_dentry, *h_parent;
  11928. + struct au_branch *br;
  11929. + struct inode *h_dir;
  11930. +
  11931. + err = 0;
  11932. + sb = p->dentry->d_sb;
  11933. + br = au_sbr(sb, p->bindex);
  11934. + if (IS_ROOT(p->dentry)) {
  11935. + if (au_ftest_pin(p->flags, MNT_WRITE)) {
  11936. + p->h_mnt = br->br_mnt;
  11937. + err = mnt_want_write(p->h_mnt);
  11938. + if (unlikely(err)) {
  11939. + au_fclr_pin(p->flags, MNT_WRITE);
  11940. + goto out_err;
  11941. + }
  11942. + }
  11943. + goto out;
  11944. + }
  11945. +
  11946. + h_dentry = NULL;
  11947. + if (p->bindex <= au_dbend(p->dentry))
  11948. + h_dentry = au_h_dptr(p->dentry, p->bindex);
  11949. +
  11950. + p->parent = dget_parent(p->dentry);
  11951. + if (!au_ftest_pin(p->flags, DI_LOCKED))
  11952. + di_read_lock(p->parent, AuLock_IR, p->lsc_di);
  11953. +
  11954. + h_dir = NULL;
  11955. + h_parent = au_h_dptr(p->parent, p->bindex);
  11956. + p->hdir = au_hi(p->parent->d_inode, p->bindex);
  11957. + if (p->hdir)
  11958. + h_dir = p->hdir->hi_inode;
  11959. +
  11960. + /* udba case */
  11961. + if (unlikely(!p->hdir || !h_dir)) {
  11962. + if (!au_ftest_pin(p->flags, DI_LOCKED))
  11963. + di_read_unlock(p->parent, AuLock_IR);
  11964. + dput(p->parent);
  11965. + p->parent = NULL;
  11966. + goto out_err;
  11967. + }
  11968. +
  11969. + au_igrab(h_dir);
  11970. + au_hin_imtx_lock_nested(p->hdir, p->lsc_hi);
  11971. +
  11972. + if (unlikely(p->hdir->hi_inode != h_parent->d_inode)) {
  11973. + err = -EBUSY;
  11974. + goto out_unpin;
  11975. + }
  11976. + if (h_dentry) {
  11977. + err = au_h_verify(h_dentry, p->udba, h_dir, h_parent, br);
  11978. + if (unlikely(err)) {
  11979. + au_fclr_pin(p->flags, MNT_WRITE);
  11980. + goto out_unpin;
  11981. + }
  11982. + }
  11983. +
  11984. + if (au_ftest_pin(p->flags, MNT_WRITE)) {
  11985. + p->h_mnt = br->br_mnt;
  11986. + err = mnt_want_write(p->h_mnt);
  11987. + if (unlikely(err)) {
  11988. + au_fclr_pin(p->flags, MNT_WRITE);
  11989. + goto out_unpin;
  11990. + }
  11991. + }
  11992. + goto out; /* success */
  11993. +
  11994. + out_unpin:
  11995. + au_unpin(p);
  11996. + out_err:
  11997. + AuErr("err %d\n", err);
  11998. + err = au_busy_or_stale();
  11999. + out:
  12000. + return err;
  12001. +}
  12002. +
  12003. +void au_pin_init(struct au_pin *p, struct dentry *dentry,
  12004. + aufs_bindex_t bindex, int lsc_di, int lsc_hi,
  12005. + unsigned int udba, unsigned char flags)
  12006. +{
  12007. + p->dentry = dentry;
  12008. + p->udba = udba;
  12009. + p->lsc_di = lsc_di;
  12010. + p->lsc_hi = lsc_hi;
  12011. + p->flags = flags;
  12012. + p->bindex = bindex;
  12013. +
  12014. + p->parent = NULL;
  12015. + p->hdir = NULL;
  12016. + p->h_mnt = NULL;
  12017. +}
  12018. +
  12019. +int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
  12020. + unsigned int udba, unsigned char flags)
  12021. +{
  12022. + au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
  12023. + udba, flags);
  12024. + return au_do_pin(pin);
  12025. +}
  12026. +
  12027. +/* ---------------------------------------------------------------------- */
  12028. +
  12029. +#define AuIcpup_DID_CPUP 1
  12030. +#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
  12031. +#define au_fset_icpup(flags, name) { (flags) |= AuIcpup_##name; }
  12032. +#define au_fclr_icpup(flags, name) { (flags) &= ~AuIcpup_##name; }
  12033. +
  12034. +struct au_icpup_args {
  12035. + unsigned char flags;
  12036. + unsigned char pin_flags;
  12037. + aufs_bindex_t btgt;
  12038. + struct au_pin pin;
  12039. + struct path h_path;
  12040. + struct inode *h_inode;
  12041. +};
  12042. +
  12043. +static int au_lock_and_icpup(struct dentry *dentry, struct iattr *ia,
  12044. + struct au_icpup_args *a)
  12045. +{
  12046. + int err;
  12047. + unsigned int udba;
  12048. + loff_t sz;
  12049. + aufs_bindex_t bstart;
  12050. + struct dentry *hi_wh, *parent;
  12051. + struct inode *inode;
  12052. + struct au_wr_dir_args wr_dir_args = {
  12053. + .force_btgt = -1,
  12054. + .flags = 0
  12055. + };
  12056. +
  12057. + di_write_lock_child(dentry);
  12058. + bstart = au_dbstart(dentry);
  12059. + inode = dentry->d_inode;
  12060. + if (S_ISDIR(inode->i_mode))
  12061. + au_fset_wrdir(wr_dir_args.flags, ISDIR);
  12062. + /* plink or hi_wh() case */
  12063. + if (bstart != au_ibstart(inode))
  12064. + wr_dir_args.force_btgt = au_ibstart(inode);
  12065. + err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
  12066. + if (unlikely(err < 0))
  12067. + goto out_dentry;
  12068. + a->btgt = err;
  12069. + if (err != bstart)
  12070. + au_fset_icpup(a->flags, DID_CPUP);
  12071. +
  12072. + err = 0;
  12073. + a->pin_flags = AuPin_MNT_WRITE;
  12074. + parent = NULL;
  12075. + if (!IS_ROOT(dentry)) {
  12076. + au_fset_pin(a->pin_flags, DI_LOCKED);
  12077. + parent = dget_parent(dentry);
  12078. + di_write_lock_parent(parent);
  12079. + }
  12080. +
  12081. + udba = au_opt_udba(dentry->d_sb);
  12082. + if (d_unhashed(dentry) || (ia->ia_valid & ATTR_FILE))
  12083. + udba = AuOpt_UDBA_NONE;
  12084. + err = au_pin(&a->pin, dentry, a->btgt, udba, a->pin_flags);
  12085. + if (unlikely(err)) {
  12086. + if (parent) {
  12087. + di_write_unlock(parent);
  12088. + dput(parent);
  12089. + }
  12090. + goto out_dentry;
  12091. + }
  12092. + a->h_path.dentry = au_h_dptr(dentry, bstart);
  12093. + a->h_inode = a->h_path.dentry->d_inode;
  12094. + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
  12095. + sz = -1;
  12096. + if ((ia->ia_valid & ATTR_SIZE) && ia->ia_size < i_size_read(a->h_inode))
  12097. + sz = ia->ia_size;
  12098. +
  12099. + hi_wh = NULL;
  12100. + if (au_ftest_icpup(a->flags, DID_CPUP) && d_unhashed(dentry)) {
  12101. + hi_wh = au_hi_wh(inode, a->btgt);
  12102. + if (!hi_wh) {
  12103. + err = au_sio_cpup_wh(dentry, a->btgt, sz, /*file*/NULL);
  12104. + if (unlikely(err))
  12105. + goto out_unlock;
  12106. + hi_wh = au_hi_wh(inode, a->btgt);
  12107. + /* todo: revalidate hi_wh? */
  12108. + }
  12109. + }
  12110. +
  12111. + if (parent) {
  12112. + au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
  12113. + di_downgrade_lock(parent, AuLock_IR);
  12114. + dput(parent);
  12115. + }
  12116. + if (!au_ftest_icpup(a->flags, DID_CPUP))
  12117. + goto out; /* success */
  12118. +
  12119. + if (!d_unhashed(dentry)) {
  12120. + err = au_sio_cpup_simple(dentry, a->btgt, sz, AuCpup_DTIME);
  12121. + if (!err)
  12122. + a->h_path.dentry = au_h_dptr(dentry, a->btgt);
  12123. + } else if (!hi_wh)
  12124. + a->h_path.dentry = au_h_dptr(dentry, a->btgt);
  12125. + else
  12126. + a->h_path.dentry = hi_wh; /* do not dget here */
  12127. +
  12128. + out_unlock:
  12129. + mutex_unlock(&a->h_inode->i_mutex);
  12130. + a->h_inode = a->h_path.dentry->d_inode;
  12131. + if (!err) {
  12132. + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
  12133. + goto out; /* success */
  12134. + }
  12135. +
  12136. + au_unpin(&a->pin);
  12137. +
  12138. + out_dentry:
  12139. + di_write_unlock(dentry);
  12140. + out:
  12141. + return err;
  12142. +}
  12143. +
  12144. +static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
  12145. +{
  12146. + int err;
  12147. + struct inode *inode;
  12148. + struct super_block *sb;
  12149. + struct file *file;
  12150. + struct au_icpup_args *a;
  12151. +
  12152. + err = -ENOMEM;
  12153. + a = kzalloc(sizeof(*a), GFP_NOFS);
  12154. + if (unlikely(!a))
  12155. + goto out;
  12156. +
  12157. + inode = dentry->d_inode;
  12158. + IMustLock(inode);
  12159. + sb = dentry->d_sb;
  12160. + si_read_lock(sb, AuLock_FLUSH);
  12161. +
  12162. + file = NULL;
  12163. + if (ia->ia_valid & ATTR_FILE) {
  12164. + /* currently ftruncate(2) only */
  12165. + file = ia->ia_file;
  12166. + fi_write_lock(file);
  12167. + ia->ia_file = au_h_fptr(file, au_fbstart(file));
  12168. + }
  12169. +
  12170. + if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
  12171. + ia->ia_valid &= ~ATTR_MODE;
  12172. +
  12173. + err = au_lock_and_icpup(dentry, ia, a);
  12174. + if (unlikely(err < 0))
  12175. + goto out_si;
  12176. + if (au_ftest_icpup(a->flags, DID_CPUP)) {
  12177. + ia->ia_file = NULL;
  12178. + ia->ia_valid &= ~ATTR_FILE;
  12179. + }
  12180. +
  12181. + a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
  12182. + if (ia->ia_valid & ATTR_SIZE) {
  12183. + struct file *f;
  12184. +
  12185. + if (ia->ia_size < i_size_read(inode)) {
  12186. + /* unmap only */
  12187. + err = vmtruncate(inode, ia->ia_size);
  12188. + if (unlikely(err))
  12189. + goto out_unlock;
  12190. + }
  12191. +
  12192. + f = NULL;
  12193. + if (ia->ia_valid & ATTR_FILE)
  12194. + f = ia->ia_file;
  12195. + mutex_unlock(&a->h_inode->i_mutex);
  12196. + err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
  12197. + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
  12198. + } else
  12199. + err = vfsub_notify_change(&a->h_path, ia);
  12200. + if (!err)
  12201. + au_cpup_attr_changeable(inode);
  12202. +
  12203. + out_unlock:
  12204. + mutex_unlock(&a->h_inode->i_mutex);
  12205. + au_unpin(&a->pin);
  12206. + di_write_unlock(dentry);
  12207. + out_si:
  12208. + if (file) {
  12209. + fi_write_unlock(file);
  12210. + ia->ia_file = file;
  12211. + ia->ia_valid |= ATTR_FILE;
  12212. + }
  12213. + si_read_unlock(sb);
  12214. + kfree(a);
  12215. + out:
  12216. + return err;
  12217. +}
  12218. +
  12219. +static int au_getattr_lock_reval(struct dentry *dentry, unsigned int sigen)
  12220. +{
  12221. + int err;
  12222. + struct inode *inode;
  12223. + struct dentry *parent;
  12224. +
  12225. + err = 0;
  12226. + inode = dentry->d_inode;
  12227. + di_write_lock_child(dentry);
  12228. + if (au_digen(dentry) != sigen || au_iigen(inode) != sigen) {
  12229. + parent = dget_parent(dentry);
  12230. + di_read_lock_parent(parent, AuLock_IR);
  12231. + /* returns a number of positive dentries */
  12232. + err = au_refresh_hdentry(dentry, inode->i_mode & S_IFMT);
  12233. + if (err > 0)
  12234. + err = au_refresh_hinode(inode, dentry);
  12235. + di_read_unlock(parent, AuLock_IR);
  12236. + dput(parent);
  12237. + if (unlikely(!err))
  12238. + err = -EIO;
  12239. + }
  12240. + di_downgrade_lock(dentry, AuLock_IR);
  12241. + if (unlikely(err))
  12242. + di_read_unlock(dentry, AuLock_IR);
  12243. +
  12244. + return err;
  12245. +}
  12246. +
  12247. +static void au_refresh_iattr(struct inode *inode, struct kstat *st,
  12248. + unsigned int nlink)
  12249. +{
  12250. + inode->i_mode = st->mode;
  12251. + inode->i_uid = st->uid;
  12252. + inode->i_gid = st->gid;
  12253. + inode->i_atime = st->atime;
  12254. + inode->i_mtime = st->mtime;
  12255. + inode->i_ctime = st->ctime;
  12256. +
  12257. + au_cpup_attr_nlink(inode, /*force*/0);
  12258. + if (S_ISDIR(inode->i_mode)) {
  12259. + inode->i_nlink -= nlink;
  12260. + inode->i_nlink += st->nlink;
  12261. + }
  12262. +
  12263. + spin_lock(&inode->i_lock);
  12264. + inode->i_blocks = st->blocks;
  12265. + i_size_write(inode, st->size);
  12266. + spin_unlock(&inode->i_lock);
  12267. +}
  12268. +
  12269. +static int aufs_getattr(struct vfsmount *mnt __maybe_unused,
  12270. + struct dentry *dentry, struct kstat *st)
  12271. +{
  12272. + int err;
  12273. + unsigned int mnt_flags;
  12274. + aufs_bindex_t bindex;
  12275. + unsigned char udba_none, positive;
  12276. + struct super_block *sb, *h_sb;
  12277. + struct inode *inode;
  12278. + struct vfsmount *h_mnt;
  12279. + struct dentry *h_dentry;
  12280. +
  12281. + err = 0;
  12282. + sb = dentry->d_sb;
  12283. + inode = dentry->d_inode;
  12284. + si_read_lock(sb, AuLock_FLUSH);
  12285. + mnt_flags = au_mntflags(sb);
  12286. + udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
  12287. +
  12288. + /* support fstat(2) */
  12289. + if (!d_unhashed(dentry) && !udba_none) {
  12290. + unsigned int sigen = au_sigen(sb);
  12291. + if (au_digen(dentry) == sigen && au_iigen(inode) == sigen)
  12292. + di_read_lock_child(dentry, AuLock_IR);
  12293. + else {
  12294. + AuDebugOn(!IS_ROOT(dentry));
  12295. + err = au_getattr_lock_reval(dentry, sigen);
  12296. + if (unlikely(err))
  12297. + goto out;
  12298. + }
  12299. + } else
  12300. + di_read_lock_child(dentry, AuLock_IR);
  12301. +
  12302. + bindex = au_ibstart(inode);
  12303. + h_mnt = au_sbr_mnt(sb, bindex);
  12304. + h_sb = h_mnt->mnt_sb;
  12305. + if (!au_test_fs_bad_iattr(h_sb) && udba_none)
  12306. + goto out_fill; /* success */
  12307. +
  12308. + h_dentry = NULL;
  12309. + if (au_dbstart(dentry) == bindex)
  12310. + h_dentry = dget(au_h_dptr(dentry, bindex));
  12311. + else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
  12312. + h_dentry = au_plink_lkup(inode, bindex);
  12313. + if (IS_ERR(h_dentry))
  12314. + goto out_fill; /* pretending success */
  12315. + }
  12316. + /* illegally overlapped or something */
  12317. + if (unlikely(!h_dentry))
  12318. + goto out_fill; /* pretending success */
  12319. +
  12320. + positive = !!h_dentry->d_inode;
  12321. + if (positive)
  12322. + err = vfs_getattr(h_mnt, h_dentry, st);
  12323. + dput(h_dentry);
  12324. + if (!err) {
  12325. + if (positive)
  12326. + au_refresh_iattr(inode, st, h_dentry->d_inode->i_nlink);
  12327. + goto out_fill; /* success */
  12328. + }
  12329. + goto out_unlock;
  12330. +
  12331. + out_fill:
  12332. + generic_fillattr(inode, st);
  12333. + out_unlock:
  12334. + di_read_unlock(dentry, AuLock_IR);
  12335. + out:
  12336. + si_read_unlock(sb);
  12337. + return err;
  12338. +}
  12339. +
  12340. +/* ---------------------------------------------------------------------- */
  12341. +
  12342. +static int h_readlink(struct dentry *dentry, int bindex, char __user *buf,
  12343. + int bufsiz)
  12344. +{
  12345. + int err;
  12346. + struct super_block *sb;
  12347. + struct dentry *h_dentry;
  12348. +
  12349. + err = -EINVAL;
  12350. + h_dentry = au_h_dptr(dentry, bindex);
  12351. + if (unlikely(/* !h_dentry
  12352. + || !h_dentry->d_inode
  12353. + || !h_dentry->d_inode->i_op
  12354. + || */ !h_dentry->d_inode->i_op->readlink))
  12355. + goto out;
  12356. +
  12357. + err = security_inode_readlink(h_dentry);
  12358. + if (unlikely(err))
  12359. + goto out;
  12360. +
  12361. + sb = dentry->d_sb;
  12362. + if (!au_test_ro(sb, bindex, dentry->d_inode)) {
  12363. + vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry);
  12364. + fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode);
  12365. + }
  12366. + err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz);
  12367. +
  12368. + out:
  12369. + return err;
  12370. +}
  12371. +
  12372. +static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
  12373. +{
  12374. + int err;
  12375. +
  12376. + aufs_read_lock(dentry, AuLock_IR);
  12377. + err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz);
  12378. + aufs_read_unlock(dentry, AuLock_IR);
  12379. +
  12380. + return err;
  12381. +}
  12382. +
  12383. +static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd)
  12384. +{
  12385. + int err;
  12386. + char *buf;
  12387. + mm_segment_t old_fs;
  12388. +
  12389. + err = -ENOMEM;
  12390. + buf = __getname();
  12391. + if (unlikely(!buf))
  12392. + goto out;
  12393. +
  12394. + aufs_read_lock(dentry, AuLock_IR);
  12395. + old_fs = get_fs();
  12396. + set_fs(KERNEL_DS);
  12397. + err = h_readlink(dentry, au_dbstart(dentry), (char __user *)buf,
  12398. + PATH_MAX);
  12399. + set_fs(old_fs);
  12400. + aufs_read_unlock(dentry, AuLock_IR);
  12401. +
  12402. + if (err >= 0) {
  12403. + buf[err] = 0;
  12404. + /* will be freed by put_link */
  12405. + nd_set_link(nd, buf);
  12406. + return NULL; /* success */
  12407. + }
  12408. + __putname(buf);
  12409. +
  12410. + out:
  12411. + path_put(&nd->path);
  12412. + AuTraceErr(err);
  12413. + return ERR_PTR(err);
  12414. +}
  12415. +
  12416. +static void aufs_put_link(struct dentry *dentry __maybe_unused,
  12417. + struct nameidata *nd, void *cookie __maybe_unused)
  12418. +{
  12419. + __putname(nd_get_link(nd));
  12420. +}
  12421. +
  12422. +/* ---------------------------------------------------------------------- */
  12423. +
  12424. +static void aufs_truncate_range(struct inode *inode __maybe_unused,
  12425. + loff_t start __maybe_unused,
  12426. + loff_t end __maybe_unused)
  12427. +{
  12428. + AuUnsupport();
  12429. +}
  12430. +
  12431. +/* ---------------------------------------------------------------------- */
  12432. +
  12433. +struct inode_operations aufs_symlink_iop = {
  12434. + .permission = aufs_permission,
  12435. + .setattr = aufs_setattr,
  12436. + .getattr = aufs_getattr,
  12437. + .readlink = aufs_readlink,
  12438. + .follow_link = aufs_follow_link,
  12439. + .put_link = aufs_put_link
  12440. +};
  12441. +
  12442. +struct inode_operations aufs_dir_iop = {
  12443. + .create = aufs_create,
  12444. + .lookup = aufs_lookup,
  12445. + .link = aufs_link,
  12446. + .unlink = aufs_unlink,
  12447. + .symlink = aufs_symlink,
  12448. + .mkdir = aufs_mkdir,
  12449. + .rmdir = aufs_rmdir,
  12450. + .mknod = aufs_mknod,
  12451. + .rename = aufs_rename,
  12452. +
  12453. + .permission = aufs_permission,
  12454. + .setattr = aufs_setattr,
  12455. + .getattr = aufs_getattr
  12456. +};
  12457. +
  12458. +struct inode_operations aufs_iop = {
  12459. + .permission = aufs_permission,
  12460. + .setattr = aufs_setattr,
  12461. + .getattr = aufs_getattr,
  12462. + .truncate_range = aufs_truncate_range
  12463. +};
  12464. diff -Nur linux-2.6.31.4.orig/fs/aufs/i_op_del.c linux-2.6.31.4/fs/aufs/i_op_del.c
  12465. --- linux-2.6.31.4.orig/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
  12466. +++ linux-2.6.31.4/fs/aufs/i_op_del.c 2009-10-18 11:26:01.000000000 +0200
  12467. @@ -0,0 +1,468 @@
  12468. +/*
  12469. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  12470. + *
  12471. + * This program, aufs is free software; you can redistribute it and/or modify
  12472. + * it under the terms of the GNU General Public License as published by
  12473. + * the Free Software Foundation; either version 2 of the License, or
  12474. + * (at your option) any later version.
  12475. + *
  12476. + * This program is distributed in the hope that it will be useful,
  12477. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12478. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12479. + * GNU General Public License for more details.
  12480. + *
  12481. + * You should have received a copy of the GNU General Public License
  12482. + * along with this program; if not, write to the Free Software
  12483. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  12484. + */
  12485. +
  12486. +/*
  12487. + * inode operations (del entry)
  12488. + */
  12489. +
  12490. +#include "aufs.h"
  12491. +
  12492. +/*
  12493. + * decide if a new whiteout for @dentry is necessary or not.
  12494. + * when it is necessary, prepare the parent dir for the upper branch whose
  12495. + * branch index is @bcpup for creation. the actual creation of the whiteout will
  12496. + * be done by caller.
  12497. + * return value:
  12498. + * 0: wh is unnecessary
  12499. + * plus: wh is necessary
  12500. + * minus: error
  12501. + */
  12502. +int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
  12503. +{
  12504. + int need_wh, err;
  12505. + aufs_bindex_t bstart;
  12506. + struct super_block *sb;
  12507. +
  12508. + sb = dentry->d_sb;
  12509. + bstart = au_dbstart(dentry);
  12510. + if (*bcpup < 0) {
  12511. + *bcpup = bstart;
  12512. + if (au_test_ro(sb, bstart, dentry->d_inode)) {
  12513. + err = AuWbrCopyup(au_sbi(sb), dentry);
  12514. + *bcpup = err;
  12515. + if (unlikely(err < 0))
  12516. + goto out;
  12517. + }
  12518. + } else
  12519. + AuDebugOn(bstart < *bcpup
  12520. + || au_test_ro(sb, *bcpup, dentry->d_inode));
  12521. + AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
  12522. +
  12523. + if (*bcpup != bstart) {
  12524. + err = au_cpup_dirs(dentry, *bcpup);
  12525. + if (unlikely(err))
  12526. + goto out;
  12527. + need_wh = 1;
  12528. + } else {
  12529. + aufs_bindex_t old_bend, new_bend, bdiropq = -1;
  12530. +
  12531. + old_bend = au_dbend(dentry);
  12532. + if (isdir) {
  12533. + bdiropq = au_dbdiropq(dentry);
  12534. + au_set_dbdiropq(dentry, -1);
  12535. + }
  12536. + need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0,
  12537. + /*nd*/NULL);
  12538. + err = need_wh;
  12539. + if (isdir)
  12540. + au_set_dbdiropq(dentry, bdiropq);
  12541. + if (unlikely(err < 0))
  12542. + goto out;
  12543. + new_bend = au_dbend(dentry);
  12544. + if (!need_wh && old_bend != new_bend) {
  12545. + au_set_h_dptr(dentry, new_bend, NULL);
  12546. + au_set_dbend(dentry, old_bend);
  12547. + }
  12548. + }
  12549. + AuDbg("need_wh %d\n", need_wh);
  12550. + err = need_wh;
  12551. +
  12552. + out:
  12553. + return err;
  12554. +}
  12555. +
  12556. +/*
  12557. + * simple tests for the del-entry operations.
  12558. + * following the checks in vfs, plus the parent-child relationship.
  12559. + */
  12560. +int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
  12561. + struct dentry *h_parent, int isdir)
  12562. +{
  12563. + int err;
  12564. + umode_t h_mode;
  12565. + struct dentry *h_dentry, *h_latest;
  12566. + struct inode *h_inode;
  12567. +
  12568. + h_dentry = au_h_dptr(dentry, bindex);
  12569. + h_inode = h_dentry->d_inode;
  12570. + if (dentry->d_inode) {
  12571. + err = -ENOENT;
  12572. + if (unlikely(!h_inode || !h_inode->i_nlink))
  12573. + goto out;
  12574. +
  12575. + h_mode = h_inode->i_mode;
  12576. + if (!isdir) {
  12577. + err = -EISDIR;
  12578. + if (unlikely(S_ISDIR(h_mode)))
  12579. + goto out;
  12580. + } else if (unlikely(!S_ISDIR(h_mode))) {
  12581. + err = -ENOTDIR;
  12582. + goto out;
  12583. + }
  12584. + } else {
  12585. + /* rename(2) case */
  12586. + err = -EIO;
  12587. + if (unlikely(h_inode))
  12588. + goto out;
  12589. + }
  12590. +
  12591. + err = -ENOENT;
  12592. + /* expected parent dir is locked */
  12593. + if (unlikely(h_parent != h_dentry->d_parent))
  12594. + goto out;
  12595. + err = 0;
  12596. +
  12597. + /*
  12598. + * rmdir a dir may break the consistency on some filesystem.
  12599. + * let's try heavy test.
  12600. + */
  12601. + err = -EACCES;
  12602. + if (unlikely(au_test_h_perm(h_parent->d_inode, MAY_EXEC | MAY_WRITE)))
  12603. + goto out;
  12604. +
  12605. + h_latest = au_sio_lkup_one(&dentry->d_name, h_parent,
  12606. + au_sbr(dentry->d_sb, bindex));
  12607. + err = -EIO;
  12608. + if (IS_ERR(h_latest))
  12609. + goto out;
  12610. + if (h_latest == h_dentry)
  12611. + err = 0;
  12612. + dput(h_latest);
  12613. +
  12614. + out:
  12615. + return err;
  12616. +}
  12617. +
  12618. +/*
  12619. + * decide the branch where we operate for @dentry. the branch index will be set
  12620. + * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
  12621. + * dir for reverting.
  12622. + * when a new whiteout is necessary, create it.
  12623. + */
  12624. +static struct dentry*
  12625. +lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
  12626. + struct au_dtime *dt, struct au_pin *pin)
  12627. +{
  12628. + struct dentry *wh_dentry;
  12629. + struct super_block *sb;
  12630. + struct path h_path;
  12631. + int err, need_wh;
  12632. + unsigned int udba;
  12633. + aufs_bindex_t bcpup;
  12634. +
  12635. + need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
  12636. + wh_dentry = ERR_PTR(need_wh);
  12637. + if (unlikely(need_wh < 0))
  12638. + goto out;
  12639. +
  12640. + sb = dentry->d_sb;
  12641. + udba = au_opt_udba(sb);
  12642. + bcpup = *rbcpup;
  12643. + err = au_pin(pin, dentry, bcpup, udba,
  12644. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  12645. + wh_dentry = ERR_PTR(err);
  12646. + if (unlikely(err))
  12647. + goto out;
  12648. +
  12649. + h_path.dentry = au_pinned_h_parent(pin);
  12650. + if (udba != AuOpt_UDBA_NONE
  12651. + && au_dbstart(dentry) == bcpup) {
  12652. + err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
  12653. + wh_dentry = ERR_PTR(err);
  12654. + if (unlikely(err))
  12655. + goto out_unpin;
  12656. + }
  12657. +
  12658. + h_path.mnt = au_sbr_mnt(sb, bcpup);
  12659. + au_dtime_store(dt, au_pinned_parent(pin), &h_path);
  12660. + wh_dentry = NULL;
  12661. + if (!need_wh)
  12662. + goto out; /* success, no need to create whiteout */
  12663. +
  12664. + wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
  12665. + if (!IS_ERR(wh_dentry))
  12666. + goto out; /* success */
  12667. + /* returns with the parent is locked and wh_dentry is dget-ed */
  12668. +
  12669. + out_unpin:
  12670. + au_unpin(pin);
  12671. + out:
  12672. + return wh_dentry;
  12673. +}
  12674. +
  12675. +/*
  12676. + * when removing a dir, rename it to a unique temporary whiteout-ed name first
  12677. + * in order to be revertible and save time for removing many child whiteouts
  12678. + * under the dir.
  12679. + * returns 1 when there are too many child whiteout and caller should remove
  12680. + * them asynchronously. returns 0 when the number of children is enough small to
  12681. + * remove now or the branch fs is a remote fs.
  12682. + * otherwise return an error.
  12683. + */
  12684. +static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
  12685. + struct au_nhash *whlist, struct inode *dir)
  12686. +{
  12687. + int rmdir_later, err, dirwh;
  12688. + struct dentry *h_dentry;
  12689. + struct super_block *sb;
  12690. +
  12691. + sb = dentry->d_sb;
  12692. + SiMustAnyLock(sb);
  12693. + h_dentry = au_h_dptr(dentry, bindex);
  12694. + err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
  12695. + if (unlikely(err))
  12696. + goto out;
  12697. +
  12698. + /* stop monitoring */
  12699. + au_hin_free(au_hi(dentry->d_inode, bindex));
  12700. +
  12701. + if (!au_test_fs_remote(h_dentry->d_sb)) {
  12702. + dirwh = au_sbi(sb)->si_dirwh;
  12703. + rmdir_later = (dirwh <= 1);
  12704. + if (!rmdir_later)
  12705. + rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
  12706. + dirwh);
  12707. + if (rmdir_later)
  12708. + return rmdir_later;
  12709. + }
  12710. +
  12711. + err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
  12712. + if (unlikely(err)) {
  12713. + AuIOErr("rmdir %.*s, b%d failed, %d. ignored\n",
  12714. + AuDLNPair(h_dentry), bindex, err);
  12715. + err = 0;
  12716. + }
  12717. +
  12718. + out:
  12719. + return err;
  12720. +}
  12721. +
  12722. +/*
  12723. + * final procedure for deleting a entry.
  12724. + * maintain dentry and iattr.
  12725. + */
  12726. +static void epilog(struct inode *dir, struct dentry *dentry,
  12727. + aufs_bindex_t bindex)
  12728. +{
  12729. + struct inode *inode;
  12730. +
  12731. + inode = dentry->d_inode;
  12732. + d_drop(dentry);
  12733. + inode->i_ctime = dir->i_ctime;
  12734. +
  12735. + if (atomic_read(&dentry->d_count) == 1) {
  12736. + au_set_h_dptr(dentry, au_dbstart(dentry), NULL);
  12737. + au_update_dbstart(dentry);
  12738. + }
  12739. + if (au_ibstart(dir) == bindex)
  12740. + au_cpup_attr_timesizes(dir);
  12741. + dir->i_version++;
  12742. +}
  12743. +
  12744. +/*
  12745. + * when an error happened, remove the created whiteout and revert everything.
  12746. + */
  12747. +static int do_revert(int err, struct inode *dir, aufs_bindex_t bwh,
  12748. + struct dentry *wh_dentry, struct dentry *dentry,
  12749. + struct au_dtime *dt)
  12750. +{
  12751. + int rerr;
  12752. + struct path h_path = {
  12753. + .dentry = wh_dentry,
  12754. + .mnt = au_sbr_mnt(dir->i_sb, bwh)
  12755. + };
  12756. +
  12757. + rerr = au_wh_unlink_dentry(au_h_iptr(dir, bwh), &h_path, dentry);
  12758. + if (!rerr) {
  12759. + au_set_dbwh(dentry, bwh);
  12760. + au_dtime_revert(dt);
  12761. + return 0;
  12762. + }
  12763. +
  12764. + AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
  12765. + AuDLNPair(dentry), err, rerr);
  12766. + return -EIO;
  12767. +}
  12768. +
  12769. +/* ---------------------------------------------------------------------- */
  12770. +
  12771. +int aufs_unlink(struct inode *dir, struct dentry *dentry)
  12772. +{
  12773. + int err;
  12774. + aufs_bindex_t bwh, bindex, bstart;
  12775. + struct au_dtime dt;
  12776. + struct au_pin pin;
  12777. + struct path h_path;
  12778. + struct inode *inode, *h_dir;
  12779. + struct dentry *parent, *wh_dentry;
  12780. +
  12781. + IMustLock(dir);
  12782. + inode = dentry->d_inode;
  12783. + if (unlikely(!inode))
  12784. + return -ENOENT; /* possible? */
  12785. + IMustLock(inode);
  12786. +
  12787. + aufs_read_lock(dentry, AuLock_DW);
  12788. + parent = dentry->d_parent; /* dir inode is locked */
  12789. + di_write_lock_parent(parent);
  12790. +
  12791. + bstart = au_dbstart(dentry);
  12792. + bwh = au_dbwh(dentry);
  12793. + bindex = -1;
  12794. + wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt, &pin);
  12795. + err = PTR_ERR(wh_dentry);
  12796. + if (IS_ERR(wh_dentry))
  12797. + goto out;
  12798. +
  12799. + h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
  12800. + h_path.dentry = au_h_dptr(dentry, bstart);
  12801. + dget(h_path.dentry);
  12802. + if (bindex == bstart) {
  12803. + h_dir = au_pinned_h_dir(&pin);
  12804. + err = vfsub_unlink(h_dir, &h_path, /*force*/0);
  12805. + } else {
  12806. + /* dir inode is locked */
  12807. + h_dir = wh_dentry->d_parent->d_inode;
  12808. + IMustLock(h_dir);
  12809. + err = 0;
  12810. + }
  12811. +
  12812. + if (!err) {
  12813. + drop_nlink(inode);
  12814. + epilog(dir, dentry, bindex);
  12815. +
  12816. + /* update target timestamps */
  12817. + if (bindex == bstart) {
  12818. + vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
  12819. + inode->i_ctime = h_path.dentry->d_inode->i_ctime;
  12820. + } else
  12821. + /* todo: this timestamp may be reverted later */
  12822. + inode->i_ctime = h_dir->i_ctime;
  12823. + goto out_unlock; /* success */
  12824. + }
  12825. +
  12826. + /* revert */
  12827. + if (wh_dentry) {
  12828. + int rerr;
  12829. +
  12830. + rerr = do_revert(err, dir, bwh, wh_dentry, dentry, &dt);
  12831. + if (rerr)
  12832. + err = rerr;
  12833. + }
  12834. +
  12835. + out_unlock:
  12836. + au_unpin(&pin);
  12837. + dput(wh_dentry);
  12838. + dput(h_path.dentry);
  12839. + out:
  12840. + di_write_unlock(parent);
  12841. + aufs_read_unlock(dentry, AuLock_DW);
  12842. + return err;
  12843. +}
  12844. +
  12845. +int aufs_rmdir(struct inode *dir, struct dentry *dentry)
  12846. +{
  12847. + int err, rmdir_later;
  12848. + aufs_bindex_t bwh, bindex, bstart;
  12849. + struct au_dtime dt;
  12850. + struct au_pin pin;
  12851. + struct inode *inode;
  12852. + struct dentry *parent, *wh_dentry, *h_dentry;
  12853. + struct au_whtmp_rmdir *args;
  12854. +
  12855. + IMustLock(dir);
  12856. + inode = dentry->d_inode;
  12857. + err = -ENOENT; /* possible? */
  12858. + if (unlikely(!inode))
  12859. + goto out;
  12860. + IMustLock(inode);
  12861. +
  12862. + aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH);
  12863. + err = -ENOMEM;
  12864. + args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
  12865. + if (unlikely(!args))
  12866. + goto out_unlock;
  12867. +
  12868. + parent = dentry->d_parent; /* dir inode is locked */
  12869. + di_write_lock_parent(parent);
  12870. + err = au_test_empty(dentry, &args->whlist);
  12871. + if (unlikely(err))
  12872. + goto out_args;
  12873. +
  12874. + bstart = au_dbstart(dentry);
  12875. + bwh = au_dbwh(dentry);
  12876. + bindex = -1;
  12877. + wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &dt, &pin);
  12878. + err = PTR_ERR(wh_dentry);
  12879. + if (IS_ERR(wh_dentry))
  12880. + goto out_args;
  12881. +
  12882. + h_dentry = au_h_dptr(dentry, bstart);
  12883. + dget(h_dentry);
  12884. + rmdir_later = 0;
  12885. + if (bindex == bstart) {
  12886. + err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir);
  12887. + if (err > 0) {
  12888. + rmdir_later = err;
  12889. + err = 0;
  12890. + }
  12891. + } else {
  12892. + /* stop monitoring */
  12893. + au_hin_free(au_hi(inode, bstart));
  12894. +
  12895. + /* dir inode is locked */
  12896. + IMustLock(wh_dentry->d_parent->d_inode);
  12897. + err = 0;
  12898. + }
  12899. +
  12900. + if (!err) {
  12901. + clear_nlink(inode);
  12902. + au_set_dbdiropq(dentry, -1);
  12903. + epilog(dir, dentry, bindex);
  12904. +
  12905. + if (rmdir_later) {
  12906. + au_whtmp_kick_rmdir(dir, bstart, h_dentry, args);
  12907. + args = NULL;
  12908. + }
  12909. +
  12910. + goto out_unpin; /* success */
  12911. + }
  12912. +
  12913. + /* revert */
  12914. + AuLabel(revert);
  12915. + if (wh_dentry) {
  12916. + int rerr;
  12917. +
  12918. + rerr = do_revert(err, dir, bwh, wh_dentry, dentry, &dt);
  12919. + if (rerr)
  12920. + err = rerr;
  12921. + }
  12922. +
  12923. + out_unpin:
  12924. + au_unpin(&pin);
  12925. + dput(wh_dentry);
  12926. + dput(h_dentry);
  12927. + out_args:
  12928. + di_write_unlock(parent);
  12929. + if (args)
  12930. + au_whtmp_rmdir_free(args);
  12931. + out_unlock:
  12932. + aufs_read_unlock(dentry, AuLock_DW);
  12933. + out:
  12934. + return err;
  12935. +}
  12936. diff -Nur linux-2.6.31.4.orig/fs/aufs/i_op_ren.c linux-2.6.31.4/fs/aufs/i_op_ren.c
  12937. --- linux-2.6.31.4.orig/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
  12938. +++ linux-2.6.31.4/fs/aufs/i_op_ren.c 2009-10-18 11:26:01.000000000 +0200
  12939. @@ -0,0 +1,948 @@
  12940. +/*
  12941. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  12942. + *
  12943. + * This program, aufs is free software; you can redistribute it and/or modify
  12944. + * it under the terms of the GNU General Public License as published by
  12945. + * the Free Software Foundation; either version 2 of the License, or
  12946. + * (at your option) any later version.
  12947. + *
  12948. + * This program is distributed in the hope that it will be useful,
  12949. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12950. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12951. + * GNU General Public License for more details.
  12952. + *
  12953. + * You should have received a copy of the GNU General Public License
  12954. + * along with this program; if not, write to the Free Software
  12955. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  12956. + */
  12957. +
  12958. +/*
  12959. + * inode operation (rename entry)
  12960. + * todo: this is crazy monster
  12961. + */
  12962. +
  12963. +#include "aufs.h"
  12964. +
  12965. +enum { AuSRC, AuDST, AuSrcDst };
  12966. +enum { AuPARENT, AuCHILD, AuParentChild };
  12967. +
  12968. +#define AuRen_ISDIR 1
  12969. +#define AuRen_ISSAMEDIR (1 << 1)
  12970. +#define AuRen_WHSRC (1 << 2)
  12971. +#define AuRen_WHDST (1 << 3)
  12972. +#define AuRen_MNT_WRITE (1 << 4)
  12973. +#define AuRen_DT_DSTDIR (1 << 5)
  12974. +#define AuRen_DIROPQ (1 << 6)
  12975. +#define AuRen_CPUP (1 << 7)
  12976. +#define au_ftest_ren(flags, name) ((flags) & AuRen_##name)
  12977. +#define au_fset_ren(flags, name) { (flags) |= AuRen_##name; }
  12978. +#define au_fclr_ren(flags, name) { (flags) &= ~AuRen_##name; }
  12979. +
  12980. +struct au_ren_args {
  12981. + struct {
  12982. + struct dentry *dentry, *h_dentry, *parent, *h_parent,
  12983. + *wh_dentry;
  12984. + struct inode *dir, *inode;
  12985. + struct au_hinode *hdir;
  12986. + struct au_dtime dt[AuParentChild];
  12987. + aufs_bindex_t bstart;
  12988. + } sd[AuSrcDst];
  12989. +
  12990. +#define src_dentry sd[AuSRC].dentry
  12991. +#define src_dir sd[AuSRC].dir
  12992. +#define src_inode sd[AuSRC].inode
  12993. +#define src_h_dentry sd[AuSRC].h_dentry
  12994. +#define src_parent sd[AuSRC].parent
  12995. +#define src_h_parent sd[AuSRC].h_parent
  12996. +#define src_wh_dentry sd[AuSRC].wh_dentry
  12997. +#define src_hdir sd[AuSRC].hdir
  12998. +#define src_h_dir sd[AuSRC].hdir->hi_inode
  12999. +#define src_dt sd[AuSRC].dt
  13000. +#define src_bstart sd[AuSRC].bstart
  13001. +
  13002. +#define dst_dentry sd[AuDST].dentry
  13003. +#define dst_dir sd[AuDST].dir
  13004. +#define dst_inode sd[AuDST].inode
  13005. +#define dst_h_dentry sd[AuDST].h_dentry
  13006. +#define dst_parent sd[AuDST].parent
  13007. +#define dst_h_parent sd[AuDST].h_parent
  13008. +#define dst_wh_dentry sd[AuDST].wh_dentry
  13009. +#define dst_hdir sd[AuDST].hdir
  13010. +#define dst_h_dir sd[AuDST].hdir->hi_inode
  13011. +#define dst_dt sd[AuDST].dt
  13012. +#define dst_bstart sd[AuDST].bstart
  13013. +
  13014. + struct dentry *h_trap;
  13015. + struct au_branch *br;
  13016. + struct au_hinode *src_hinode;
  13017. + struct path h_path;
  13018. + struct au_nhash whlist;
  13019. + aufs_bindex_t btgt;
  13020. +
  13021. + unsigned int flags;
  13022. +
  13023. + struct au_whtmp_rmdir *thargs;
  13024. + struct dentry *h_dst;
  13025. +};
  13026. +
  13027. +/* ---------------------------------------------------------------------- */
  13028. +
  13029. +/*
  13030. + * functions for reverting.
  13031. + * when an error happened in a single rename systemcall, we should revert
  13032. + * everything as if nothing happend.
  13033. + * we don't need to revert the copied-up/down the parent dir since they are
  13034. + * harmless.
  13035. + */
  13036. +
  13037. +#define RevertFailure(fmt, args...) do { \
  13038. + AuIOErr("revert failure: " fmt " (%d, %d)\n", \
  13039. + ##args, err, rerr); \
  13040. + err = -EIO; \
  13041. +} while (0)
  13042. +
  13043. +static void au_ren_rev_diropq(int err, struct au_ren_args *a)
  13044. +{
  13045. + int rerr;
  13046. +
  13047. + au_hin_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
  13048. + rerr = au_diropq_remove(a->src_dentry, a->btgt);
  13049. + au_hin_imtx_unlock(a->src_hinode);
  13050. + if (rerr)
  13051. + RevertFailure("remove diropq %.*s", AuDLNPair(a->src_dentry));
  13052. +}
  13053. +
  13054. +
  13055. +static void au_ren_rev_rename(int err, struct au_ren_args *a)
  13056. +{
  13057. + int rerr;
  13058. +
  13059. + a->h_path.dentry = au_lkup_one(&a->src_dentry->d_name, a->src_h_parent,
  13060. + a->br, /*nd*/NULL);
  13061. + rerr = PTR_ERR(a->h_path.dentry);
  13062. + if (IS_ERR(a->h_path.dentry)) {
  13063. + RevertFailure("au_lkup_one %.*s", AuDLNPair(a->src_dentry));
  13064. + return;
  13065. + }
  13066. +
  13067. + rerr = vfsub_rename(a->dst_h_dir,
  13068. + au_h_dptr(a->src_dentry, a->btgt),
  13069. + a->src_h_dir, &a->h_path);
  13070. + d_drop(a->h_path.dentry);
  13071. + dput(a->h_path.dentry);
  13072. + /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
  13073. + if (rerr)
  13074. + RevertFailure("rename %.*s", AuDLNPair(a->src_dentry));
  13075. +}
  13076. +
  13077. +static void au_ren_rev_cpup(int err, struct au_ren_args *a)
  13078. +{
  13079. + int rerr;
  13080. +
  13081. + a->h_path.dentry = a->dst_h_dentry;
  13082. + rerr = vfsub_unlink(a->dst_h_dir, &a->h_path, /*force*/0);
  13083. + au_set_h_dptr(a->src_dentry, a->btgt, NULL);
  13084. + au_set_dbstart(a->src_dentry, a->src_bstart);
  13085. + if (rerr)
  13086. + RevertFailure("unlink %.*s", AuDLNPair(a->dst_h_dentry));
  13087. +}
  13088. +
  13089. +
  13090. +static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
  13091. +{
  13092. + int rerr;
  13093. +
  13094. + a->h_path.dentry = au_lkup_one(&a->dst_dentry->d_name, a->dst_h_parent,
  13095. + a->br, /*nd*/NULL);
  13096. + rerr = PTR_ERR(a->h_path.dentry);
  13097. + if (IS_ERR(a->h_path.dentry)) {
  13098. + RevertFailure("lookup %.*s", AuDLNPair(a->dst_dentry));
  13099. + return;
  13100. + }
  13101. + if (a->h_path.dentry->d_inode) {
  13102. + d_drop(a->h_path.dentry);
  13103. + dput(a->h_path.dentry);
  13104. + return;
  13105. + }
  13106. +
  13107. + rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path);
  13108. + d_drop(a->h_path.dentry);
  13109. + dput(a->h_path.dentry);
  13110. + if (!rerr) {
  13111. + au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
  13112. + au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
  13113. + } else
  13114. + RevertFailure("rename %.*s", AuDLNPair(a->h_dst));
  13115. +}
  13116. +
  13117. +static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
  13118. +{
  13119. + int rerr;
  13120. +
  13121. + a->h_path.dentry = a->src_wh_dentry;
  13122. + rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
  13123. + if (rerr)
  13124. + RevertFailure("unlink %.*s", AuDLNPair(a->src_wh_dentry));
  13125. +}
  13126. +
  13127. +static void au_ren_rev_drop(struct au_ren_args *a)
  13128. +{
  13129. + struct dentry *d, *h_d;
  13130. + int i;
  13131. + aufs_bindex_t bend, bindex;
  13132. +
  13133. + for (i = 0; i < AuSrcDst; i++) {
  13134. + d = a->sd[i].dentry;
  13135. + d_drop(d);
  13136. + bend = au_dbend(d);
  13137. + for (bindex = au_dbstart(d); bindex <= bend; bindex++) {
  13138. + h_d = au_h_dptr(d, bindex);
  13139. + if (h_d)
  13140. + d_drop(h_d);
  13141. + }
  13142. + }
  13143. +
  13144. + au_update_dbstart(a->dst_dentry);
  13145. + if (a->thargs)
  13146. + d_drop(a->h_dst);
  13147. +}
  13148. +#undef RevertFailure
  13149. +
  13150. +/* ---------------------------------------------------------------------- */
  13151. +
  13152. +/*
  13153. + * when we have to copyup the renaming entry, do it with the rename-target name
  13154. + * in order to minimize the cost (the later actual rename is unnecessary).
  13155. + * otherwise rename it on the target branch.
  13156. + */
  13157. +static int au_ren_or_cpup(struct au_ren_args *a)
  13158. +{
  13159. + int err;
  13160. + struct dentry *d;
  13161. +
  13162. + d = a->src_dentry;
  13163. + if (au_dbstart(d) == a->btgt) {
  13164. + a->h_path.dentry = a->dst_h_dentry;
  13165. + if (au_ftest_ren(a->flags, DIROPQ)
  13166. + && au_dbdiropq(d) == a->btgt)
  13167. + au_fclr_ren(a->flags, DIROPQ);
  13168. + AuDebugOn(au_dbstart(d) != a->btgt);
  13169. + err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
  13170. + a->dst_h_dir, &a->h_path);
  13171. + } else {
  13172. + struct mutex *h_mtx = &a->src_h_dentry->d_inode->i_mutex;
  13173. +
  13174. + au_fset_ren(a->flags, CPUP);
  13175. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  13176. + au_set_dbstart(d, a->btgt);
  13177. + au_set_h_dptr(d, a->btgt, dget(a->dst_h_dentry));
  13178. + err = au_sio_cpup_single(d, a->btgt, a->src_bstart, -1,
  13179. + !AuCpup_DTIME, a->dst_parent);
  13180. + if (unlikely(err)) {
  13181. + au_set_h_dptr(d, a->btgt, NULL);
  13182. + au_set_dbstart(d, a->src_bstart);
  13183. + }
  13184. + mutex_unlock(h_mtx);
  13185. + }
  13186. +
  13187. + return err;
  13188. +}
  13189. +
  13190. +/* cf. aufs_rmdir() */
  13191. +static int au_ren_del_whtmp(struct au_ren_args *a)
  13192. +{
  13193. + int err;
  13194. + struct inode *dir;
  13195. +
  13196. + dir = a->dst_dir;
  13197. + SiMustAnyLock(dir->i_sb);
  13198. + if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
  13199. + au_sbi(dir->i_sb)->si_dirwh)
  13200. + || au_test_fs_remote(a->h_dst->d_sb)) {
  13201. + err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
  13202. + if (unlikely(err))
  13203. + AuWarn("failed removing whtmp dir %.*s (%d), "
  13204. + "ignored.\n", AuDLNPair(a->h_dst), err);
  13205. + } else {
  13206. + au_nhash_wh_free(&a->thargs->whlist);
  13207. + a->thargs->whlist = a->whlist;
  13208. + a->whlist.nh_num = 0;
  13209. + au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
  13210. + dput(a->h_dst);
  13211. + a->thargs = NULL;
  13212. + }
  13213. +
  13214. + return 0;
  13215. +}
  13216. +
  13217. +/* make it 'opaque' dir. */
  13218. +static int au_ren_diropq(struct au_ren_args *a)
  13219. +{
  13220. + int err;
  13221. + struct dentry *diropq;
  13222. +
  13223. + err = 0;
  13224. + a->src_hinode = au_hi(a->src_inode, a->btgt);
  13225. + au_hin_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
  13226. + diropq = au_diropq_create(a->src_dentry, a->btgt);
  13227. + au_hin_imtx_unlock(a->src_hinode);
  13228. + if (IS_ERR(diropq))
  13229. + err = PTR_ERR(diropq);
  13230. + dput(diropq);
  13231. +
  13232. + return err;
  13233. +}
  13234. +
  13235. +static int do_rename(struct au_ren_args *a)
  13236. +{
  13237. + int err;
  13238. + struct dentry *d, *h_d;
  13239. +
  13240. + /* prepare workqueue args for asynchronous rmdir */
  13241. + h_d = a->dst_h_dentry;
  13242. + if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) {
  13243. + err = -ENOMEM;
  13244. + a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS);
  13245. + if (unlikely(!a->thargs))
  13246. + goto out;
  13247. + a->h_dst = dget(h_d);
  13248. + }
  13249. +
  13250. + /* create whiteout for src_dentry */
  13251. + if (au_ftest_ren(a->flags, WHSRC)) {
  13252. + a->src_wh_dentry
  13253. + = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent);
  13254. + err = PTR_ERR(a->src_wh_dentry);
  13255. + if (IS_ERR(a->src_wh_dentry))
  13256. + goto out_thargs;
  13257. + }
  13258. +
  13259. + /* lookup whiteout for dentry */
  13260. + if (au_ftest_ren(a->flags, WHDST)) {
  13261. + h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name,
  13262. + a->br);
  13263. + err = PTR_ERR(h_d);
  13264. + if (IS_ERR(h_d))
  13265. + goto out_whsrc;
  13266. + if (!h_d->d_inode)
  13267. + dput(h_d);
  13268. + else
  13269. + a->dst_wh_dentry = h_d;
  13270. + }
  13271. +
  13272. + /* rename dentry to tmpwh */
  13273. + if (a->thargs) {
  13274. + err = au_whtmp_ren(a->dst_h_dentry, a->br);
  13275. + if (unlikely(err))
  13276. + goto out_whdst;
  13277. +
  13278. + d = a->dst_dentry;
  13279. + au_set_h_dptr(d, a->btgt, NULL);
  13280. + err = au_lkup_neg(d, a->btgt);
  13281. + if (unlikely(err))
  13282. + goto out_whtmp;
  13283. + a->dst_h_dentry = au_h_dptr(d, a->btgt);
  13284. + }
  13285. +
  13286. + /* cpup src */
  13287. + if (a->dst_h_dentry->d_inode && a->src_bstart != a->btgt) {
  13288. + struct mutex *h_mtx = &a->src_h_dentry->d_inode->i_mutex;
  13289. +
  13290. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  13291. + err = au_sio_cpup_simple(a->src_dentry, a->btgt, -1,
  13292. + !AuCpup_DTIME);
  13293. + mutex_unlock(h_mtx);
  13294. + if (unlikely(err))
  13295. + goto out_whtmp;
  13296. + }
  13297. +
  13298. + /* rename by vfs_rename or cpup */
  13299. + d = a->dst_dentry;
  13300. + if (au_ftest_ren(a->flags, ISDIR)
  13301. + && (a->dst_wh_dentry
  13302. + || au_dbdiropq(d) == a->btgt
  13303. + /* hide the lower to keep xino */
  13304. + || a->btgt < au_dbend(d)
  13305. + || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ)))
  13306. + au_fset_ren(a->flags, DIROPQ);
  13307. + err = au_ren_or_cpup(a);
  13308. + if (unlikely(err))
  13309. + /* leave the copied-up one */
  13310. + goto out_whtmp;
  13311. +
  13312. + /* make dir opaque */
  13313. + if (au_ftest_ren(a->flags, DIROPQ)) {
  13314. + err = au_ren_diropq(a);
  13315. + if (unlikely(err))
  13316. + goto out_rename;
  13317. + }
  13318. +
  13319. + /* update target timestamps */
  13320. + AuDebugOn(au_dbstart(a->src_dentry) != a->btgt);
  13321. + a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
  13322. + vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
  13323. + a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
  13324. +
  13325. + /* remove whiteout for dentry */
  13326. + if (a->dst_wh_dentry) {
  13327. + a->h_path.dentry = a->dst_wh_dentry;
  13328. + err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
  13329. + a->dst_dentry);
  13330. + if (unlikely(err))
  13331. + goto out_diropq;
  13332. + }
  13333. +
  13334. + /* remove whtmp */
  13335. + if (a->thargs)
  13336. + au_ren_del_whtmp(a); /* ignore this error */
  13337. +
  13338. + err = 0;
  13339. + goto out_success;
  13340. +
  13341. + out_diropq:
  13342. + if (au_ftest_ren(a->flags, DIROPQ))
  13343. + au_ren_rev_diropq(err, a);
  13344. + out_rename:
  13345. + if (!au_ftest_ren(a->flags, CPUP))
  13346. + au_ren_rev_rename(err, a);
  13347. + else
  13348. + au_ren_rev_cpup(err, a);
  13349. + out_whtmp:
  13350. + if (a->thargs)
  13351. + au_ren_rev_whtmp(err, a);
  13352. + out_whdst:
  13353. + dput(a->dst_wh_dentry);
  13354. + a->dst_wh_dentry = NULL;
  13355. + out_whsrc:
  13356. + if (a->src_wh_dentry)
  13357. + au_ren_rev_whsrc(err, a);
  13358. + au_ren_rev_drop(a);
  13359. + out_success:
  13360. + dput(a->src_wh_dentry);
  13361. + dput(a->dst_wh_dentry);
  13362. + out_thargs:
  13363. + if (a->thargs) {
  13364. + dput(a->h_dst);
  13365. + au_whtmp_rmdir_free(a->thargs);
  13366. + a->thargs = NULL;
  13367. + }
  13368. + out:
  13369. + return err;
  13370. +}
  13371. +
  13372. +/* ---------------------------------------------------------------------- */
  13373. +
  13374. +/*
  13375. + * test if @dentry dir can be rename destination or not.
  13376. + * success means, it is a logically empty dir.
  13377. + */
  13378. +static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
  13379. +{
  13380. + return au_test_empty(dentry, whlist);
  13381. +}
  13382. +
  13383. +/*
  13384. + * test if @dentry dir can be rename source or not.
  13385. + * if it can, return 0 and @children is filled.
  13386. + * success means,
  13387. + * - it is a logically empty dir.
  13388. + * - or, it exists on writable branch and has no children including whiteouts
  13389. + * on the lower branch.
  13390. + */
  13391. +static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt)
  13392. +{
  13393. + int err;
  13394. + aufs_bindex_t bstart;
  13395. +
  13396. + bstart = au_dbstart(dentry);
  13397. + if (bstart != btgt) {
  13398. + struct au_nhash whlist;
  13399. +
  13400. + SiMustAnyLock(dentry->d_sb);
  13401. + err = au_nhash_alloc(&whlist, au_sbi(dentry->d_sb)->si_rdhash,
  13402. + GFP_NOFS);
  13403. + if (unlikely(err))
  13404. + goto out;
  13405. + err = au_test_empty(dentry, &whlist);
  13406. + au_nhash_wh_free(&whlist);
  13407. + goto out;
  13408. + }
  13409. +
  13410. + if (bstart == au_dbtaildir(dentry))
  13411. + return 0; /* success */
  13412. +
  13413. + err = au_test_empty_lower(dentry);
  13414. +
  13415. + out:
  13416. + if (err == -ENOTEMPTY) {
  13417. + AuWarn1("renaming dir who has child(ren) on multiple branches,"
  13418. + " is not supported\n");
  13419. + err = -EXDEV;
  13420. + }
  13421. + return err;
  13422. +}
  13423. +
  13424. +/* side effect: sets whlist and h_dentry */
  13425. +static int au_ren_may_dir(struct au_ren_args *a)
  13426. +{
  13427. + int err;
  13428. + struct dentry *d;
  13429. +
  13430. + d = a->dst_dentry;
  13431. + SiMustAnyLock(d->d_sb);
  13432. + err = au_nhash_alloc(&a->whlist, au_sbi(d->d_sb)->si_rdhash, GFP_NOFS);
  13433. + if (unlikely(err))
  13434. + goto out;
  13435. +
  13436. + err = 0;
  13437. + if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) {
  13438. + au_set_dbstart(d, a->dst_bstart);
  13439. + err = may_rename_dstdir(d, &a->whlist);
  13440. + au_set_dbstart(d, a->btgt);
  13441. + }
  13442. + a->dst_h_dentry = au_h_dptr(d, au_dbstart(d));
  13443. + if (unlikely(err))
  13444. + goto out;
  13445. +
  13446. + d = a->src_dentry;
  13447. + a->src_h_dentry = au_h_dptr(d, au_dbstart(d));
  13448. + if (au_ftest_ren(a->flags, ISDIR)) {
  13449. + err = may_rename_srcdir(d, a->btgt);
  13450. + if (unlikely(err)) {
  13451. + au_nhash_wh_free(&a->whlist);
  13452. + a->whlist.nh_num = 0;
  13453. + }
  13454. + }
  13455. + out:
  13456. + return err;
  13457. +}
  13458. +
  13459. +/* ---------------------------------------------------------------------- */
  13460. +
  13461. +/*
  13462. + * simple tests for rename.
  13463. + * following the checks in vfs, plus the parent-child relationship.
  13464. + */
  13465. +static int au_may_ren(struct au_ren_args *a)
  13466. +{
  13467. + int err, isdir;
  13468. + struct inode *h_inode;
  13469. +
  13470. + if (a->src_bstart == a->btgt) {
  13471. + err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
  13472. + au_ftest_ren(a->flags, ISDIR));
  13473. + if (unlikely(err))
  13474. + goto out;
  13475. + err = -EINVAL;
  13476. + if (unlikely(a->src_h_dentry == a->h_trap))
  13477. + goto out;
  13478. + }
  13479. +
  13480. + err = 0;
  13481. + if (a->dst_bstart != a->btgt)
  13482. + goto out;
  13483. +
  13484. + err = -EIO;
  13485. + h_inode = a->dst_h_dentry->d_inode;
  13486. + isdir = !!au_ftest_ren(a->flags, ISDIR);
  13487. + if (!a->dst_dentry->d_inode) {
  13488. + if (unlikely(h_inode))
  13489. + goto out;
  13490. + err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent,
  13491. + isdir);
  13492. + } else {
  13493. + if (unlikely(!h_inode || !h_inode->i_nlink))
  13494. + goto out;
  13495. + err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent,
  13496. + isdir);
  13497. + if (unlikely(err))
  13498. + goto out;
  13499. + err = -ENOTEMPTY;
  13500. + if (unlikely(a->dst_h_dentry == a->h_trap))
  13501. + goto out;
  13502. + err = 0;
  13503. + }
  13504. +
  13505. + out:
  13506. + if (unlikely(err == -ENOENT || err == -EEXIST))
  13507. + err = -EIO;
  13508. + return err;
  13509. +}
  13510. +
  13511. +/* ---------------------------------------------------------------------- */
  13512. +
  13513. +/*
  13514. + * locking order
  13515. + * (VFS)
  13516. + * - src_dir and dir by lock_rename()
  13517. + * - inode if exitsts
  13518. + * (aufs)
  13519. + * - lock all
  13520. + * + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
  13521. + * + si_read_lock
  13522. + * + di_write_lock2_child()
  13523. + * + di_write_lock_child()
  13524. + * + ii_write_lock_child()
  13525. + * + di_write_lock_child2()
  13526. + * + ii_write_lock_child2()
  13527. + * + src_parent and parent
  13528. + * + di_write_lock_parent()
  13529. + * + ii_write_lock_parent()
  13530. + * + di_write_lock_parent2()
  13531. + * + ii_write_lock_parent2()
  13532. + * + lower src_dir and dir by vfsub_lock_rename()
  13533. + * + verify the every relationships between child and parent. if any
  13534. + * of them failed, unlock all and return -EBUSY.
  13535. + */
  13536. +static void au_ren_unlock(struct au_ren_args *a)
  13537. +{
  13538. + struct super_block *sb;
  13539. +
  13540. + sb = a->dst_dentry->d_sb;
  13541. + if (au_ftest_ren(a->flags, MNT_WRITE))
  13542. + mnt_drop_write(a->br->br_mnt);
  13543. + vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
  13544. + a->dst_h_parent, a->dst_hdir);
  13545. +}
  13546. +
  13547. +static int au_ren_lock(struct au_ren_args *a)
  13548. +{
  13549. + int err;
  13550. + unsigned int udba;
  13551. +
  13552. + err = 0;
  13553. + a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
  13554. + a->src_hdir = au_hi(a->src_dir, a->btgt);
  13555. + a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
  13556. + a->dst_hdir = au_hi(a->dst_dir, a->btgt);
  13557. + a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
  13558. + a->dst_h_parent, a->dst_hdir);
  13559. + udba = au_opt_udba(a->src_dentry->d_sb);
  13560. + if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode
  13561. + || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode))
  13562. + err = au_busy_or_stale();
  13563. + if (!err && au_dbstart(a->src_dentry) == a->btgt)
  13564. + err = au_h_verify(a->src_h_dentry, udba,
  13565. + a->src_h_parent->d_inode, a->src_h_parent,
  13566. + a->br);
  13567. + if (!err && au_dbstart(a->dst_dentry) == a->btgt)
  13568. + err = au_h_verify(a->dst_h_dentry, udba,
  13569. + a->dst_h_parent->d_inode, a->dst_h_parent,
  13570. + a->br);
  13571. + if (!err) {
  13572. + err = mnt_want_write(a->br->br_mnt);
  13573. + if (unlikely(err))
  13574. + goto out_unlock;
  13575. + au_fset_ren(a->flags, MNT_WRITE);
  13576. + goto out; /* success */
  13577. + }
  13578. +
  13579. + err = au_busy_or_stale();
  13580. +
  13581. + out_unlock:
  13582. + au_ren_unlock(a);
  13583. + out:
  13584. + return err;
  13585. +}
  13586. +
  13587. +/* ---------------------------------------------------------------------- */
  13588. +
  13589. +static void au_ren_refresh_dir(struct au_ren_args *a)
  13590. +{
  13591. + struct inode *dir;
  13592. +
  13593. + dir = a->dst_dir;
  13594. + dir->i_version++;
  13595. + if (au_ftest_ren(a->flags, ISDIR)) {
  13596. + /* is this updating defined in POSIX? */
  13597. + au_cpup_attr_timesizes(a->src_inode);
  13598. + au_cpup_attr_nlink(dir, /*force*/1);
  13599. + if (a->dst_inode) {
  13600. + clear_nlink(a->dst_inode);
  13601. + au_cpup_attr_timesizes(a->dst_inode);
  13602. + }
  13603. + }
  13604. + if (au_ibstart(dir) == a->btgt)
  13605. + au_cpup_attr_timesizes(dir);
  13606. +
  13607. + if (au_ftest_ren(a->flags, ISSAMEDIR))
  13608. + return;
  13609. +
  13610. + dir = a->src_dir;
  13611. + dir->i_version++;
  13612. + if (au_ftest_ren(a->flags, ISDIR))
  13613. + au_cpup_attr_nlink(dir, /*force*/1);
  13614. + if (au_ibstart(dir) == a->btgt)
  13615. + au_cpup_attr_timesizes(dir);
  13616. +}
  13617. +
  13618. +static void au_ren_refresh(struct au_ren_args *a)
  13619. +{
  13620. + aufs_bindex_t bend, bindex;
  13621. + struct dentry *d, *h_d;
  13622. + struct inode *i, *h_i;
  13623. + struct super_block *sb;
  13624. +
  13625. + d = a->src_dentry;
  13626. + au_set_dbwh(d, -1);
  13627. + bend = au_dbend(d);
  13628. + for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
  13629. + h_d = au_h_dptr(d, bindex);
  13630. + if (h_d)
  13631. + au_set_h_dptr(d, bindex, NULL);
  13632. + }
  13633. + au_set_dbend(d, a->btgt);
  13634. +
  13635. + sb = d->d_sb;
  13636. + i = a->src_inode;
  13637. + if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
  13638. + return; /* success */
  13639. +
  13640. + bend = au_ibend(i);
  13641. + for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
  13642. + h_i = au_h_iptr(i, bindex);
  13643. + if (h_i) {
  13644. + au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
  13645. + /* ignore this error */
  13646. + au_set_h_iptr(i, bindex, NULL, 0);
  13647. + }
  13648. + }
  13649. + au_set_ibend(i, a->btgt);
  13650. +}
  13651. +
  13652. +/* ---------------------------------------------------------------------- */
  13653. +
  13654. +/* mainly for link(2) and rename(2) */
  13655. +int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
  13656. +{
  13657. + aufs_bindex_t bdiropq, bwh;
  13658. + struct dentry *parent;
  13659. + struct au_branch *br;
  13660. +
  13661. + parent = dentry->d_parent;
  13662. + IMustLock(parent->d_inode); /* dir is locked */
  13663. +
  13664. + bdiropq = au_dbdiropq(parent);
  13665. + bwh = au_dbwh(dentry);
  13666. + br = au_sbr(dentry->d_sb, btgt);
  13667. + if (au_br_rdonly(br)
  13668. + || (0 <= bdiropq && bdiropq < btgt)
  13669. + || (0 <= bwh && bwh < btgt))
  13670. + btgt = -1;
  13671. +
  13672. + AuDbg("btgt %d\n", btgt);
  13673. + return btgt;
  13674. +}
  13675. +
  13676. +/* sets src_bstart, dst_bstart and btgt */
  13677. +static int au_ren_wbr(struct au_ren_args *a)
  13678. +{
  13679. + int err;
  13680. + struct au_wr_dir_args wr_dir_args = {
  13681. + /* .force_btgt = -1, */
  13682. + .flags = AuWrDir_ADD_ENTRY
  13683. + };
  13684. +
  13685. + a->src_bstart = au_dbstart(a->src_dentry);
  13686. + a->dst_bstart = au_dbstart(a->dst_dentry);
  13687. + if (au_ftest_ren(a->flags, ISDIR))
  13688. + au_fset_wrdir(wr_dir_args.flags, ISDIR);
  13689. + wr_dir_args.force_btgt = a->src_bstart;
  13690. + if (a->dst_inode && a->dst_bstart < a->src_bstart)
  13691. + wr_dir_args.force_btgt = a->dst_bstart;
  13692. + wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
  13693. + err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
  13694. + a->btgt = err;
  13695. +
  13696. + return err;
  13697. +}
  13698. +
  13699. +static void au_ren_dt(struct au_ren_args *a)
  13700. +{
  13701. + a->h_path.dentry = a->src_h_parent;
  13702. + au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
  13703. + if (!au_ftest_ren(a->flags, ISSAMEDIR)) {
  13704. + a->h_path.dentry = a->dst_h_parent;
  13705. + au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
  13706. + }
  13707. +
  13708. + au_fclr_ren(a->flags, DT_DSTDIR);
  13709. + if (!au_ftest_ren(a->flags, ISDIR))
  13710. + return;
  13711. +
  13712. + a->h_path.dentry = a->src_h_dentry;
  13713. + au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
  13714. + if (a->dst_h_dentry->d_inode) {
  13715. + au_fset_ren(a->flags, DT_DSTDIR);
  13716. + a->h_path.dentry = a->dst_h_dentry;
  13717. + au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
  13718. + }
  13719. +}
  13720. +
  13721. +static void au_ren_rev_dt(int err, struct au_ren_args *a)
  13722. +{
  13723. + struct dentry *h_d;
  13724. + struct mutex *h_mtx;
  13725. +
  13726. + au_dtime_revert(a->src_dt + AuPARENT);
  13727. + if (!au_ftest_ren(a->flags, ISSAMEDIR))
  13728. + au_dtime_revert(a->dst_dt + AuPARENT);
  13729. +
  13730. + if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) {
  13731. + h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
  13732. + h_mtx = &h_d->d_inode->i_mutex;
  13733. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  13734. + au_dtime_revert(a->src_dt + AuCHILD);
  13735. + mutex_unlock(h_mtx);
  13736. +
  13737. + if (au_ftest_ren(a->flags, DT_DSTDIR)) {
  13738. + h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
  13739. + h_mtx = &h_d->d_inode->i_mutex;
  13740. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  13741. + au_dtime_revert(a->dst_dt + AuCHILD);
  13742. + mutex_unlock(h_mtx);
  13743. + }
  13744. + }
  13745. +}
  13746. +
  13747. +/* ---------------------------------------------------------------------- */
  13748. +
  13749. +int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
  13750. + struct inode *_dst_dir, struct dentry *_dst_dentry)
  13751. +{
  13752. + int err;
  13753. + /* reduce stack space */
  13754. + struct au_ren_args *a;
  13755. +
  13756. + IMustLock(_src_dir);
  13757. + IMustLock(_dst_dir);
  13758. +
  13759. + err = -ENOMEM;
  13760. + BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
  13761. + a = kzalloc(sizeof(*a), GFP_NOFS);
  13762. + if (unlikely(!a))
  13763. + goto out;
  13764. +
  13765. + a->src_dir = _src_dir;
  13766. + a->src_dentry = _src_dentry;
  13767. + a->src_inode = a->src_dentry->d_inode;
  13768. + a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
  13769. + a->dst_dir = _dst_dir;
  13770. + a->dst_dentry = _dst_dentry;
  13771. + a->dst_inode = a->dst_dentry->d_inode;
  13772. + a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
  13773. + if (a->dst_inode) {
  13774. + IMustLock(a->dst_inode);
  13775. + au_igrab(a->dst_inode);
  13776. + }
  13777. +
  13778. + err = -ENOTDIR;
  13779. + if (S_ISDIR(a->src_inode->i_mode)) {
  13780. + au_fset_ren(a->flags, ISDIR);
  13781. + if (unlikely(a->dst_inode && !S_ISDIR(a->dst_inode->i_mode)))
  13782. + goto out_free;
  13783. + aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
  13784. + AuLock_DIR | AuLock_FLUSH);
  13785. + } else
  13786. + aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
  13787. + AuLock_FLUSH);
  13788. +
  13789. + au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
  13790. + di_write_lock_parent(a->dst_parent);
  13791. +
  13792. + /* which branch we process */
  13793. + err = au_ren_wbr(a);
  13794. + if (unlikely(err < 0))
  13795. + goto out_unlock;
  13796. + a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
  13797. + a->h_path.mnt = a->br->br_mnt;
  13798. +
  13799. + /* are they available to be renamed */
  13800. + err = au_ren_may_dir(a);
  13801. + if (unlikely(err))
  13802. + goto out_unlock;
  13803. +
  13804. + /* prepare the writable parent dir on the same branch */
  13805. + if (a->dst_bstart == a->btgt) {
  13806. + au_fset_ren(a->flags, WHDST);
  13807. + } else {
  13808. + err = au_cpup_dirs(a->dst_dentry, a->btgt);
  13809. + if (unlikely(err))
  13810. + goto out_children;
  13811. + }
  13812. +
  13813. + if (a->src_dir != a->dst_dir) {
  13814. + /*
  13815. + * this temporary unlock is safe,
  13816. + * because both dir->i_mutex are locked.
  13817. + */
  13818. + di_write_unlock(a->dst_parent);
  13819. + di_write_lock_parent(a->src_parent);
  13820. + err = au_wr_dir_need_wh(a->src_dentry,
  13821. + au_ftest_ren(a->flags, ISDIR),
  13822. + &a->btgt);
  13823. + di_write_unlock(a->src_parent);
  13824. + di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1);
  13825. + au_fclr_ren(a->flags, ISSAMEDIR);
  13826. + } else
  13827. + err = au_wr_dir_need_wh(a->src_dentry,
  13828. + au_ftest_ren(a->flags, ISDIR),
  13829. + &a->btgt);
  13830. + if (unlikely(err < 0))
  13831. + goto out_children;
  13832. + if (err)
  13833. + au_fset_ren(a->flags, WHSRC);
  13834. +
  13835. + /* lock them all */
  13836. + err = au_ren_lock(a);
  13837. + if (unlikely(err))
  13838. + goto out_children;
  13839. +
  13840. + if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE)) {
  13841. + err = au_may_ren(a);
  13842. + if (unlikely(err))
  13843. + goto out_hdir;
  13844. + }
  13845. +
  13846. + /* store timestamps to be revertible */
  13847. + au_ren_dt(a);
  13848. +
  13849. + /* here we go */
  13850. + err = do_rename(a);
  13851. + if (unlikely(err))
  13852. + goto out_dt;
  13853. +
  13854. + /* update dir attributes */
  13855. + au_ren_refresh_dir(a);
  13856. +
  13857. + /* dput/iput all lower dentries */
  13858. + au_ren_refresh(a);
  13859. +
  13860. + goto out_hdir; /* success */
  13861. +
  13862. + out_dt:
  13863. + au_ren_rev_dt(err, a);
  13864. + out_hdir:
  13865. + au_ren_unlock(a);
  13866. + out_children:
  13867. + au_nhash_wh_free(&a->whlist);
  13868. + out_unlock:
  13869. + if (unlikely(err && au_ftest_ren(a->flags, ISDIR))) {
  13870. + au_update_dbstart(a->dst_dentry);
  13871. + d_drop(a->dst_dentry);
  13872. + }
  13873. + if (!err)
  13874. + d_move(a->src_dentry, a->dst_dentry);
  13875. + if (au_ftest_ren(a->flags, ISSAMEDIR))
  13876. + di_write_unlock(a->dst_parent);
  13877. + else
  13878. + di_write_unlock2(a->src_parent, a->dst_parent);
  13879. + aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
  13880. + out_free:
  13881. + iput(a->dst_inode);
  13882. + if (a->thargs)
  13883. + au_whtmp_rmdir_free(a->thargs);
  13884. + kfree(a);
  13885. + out:
  13886. + return err;
  13887. +}
  13888. diff -Nur linux-2.6.31.4.orig/fs/aufs/Kconfig linux-2.6.31.4/fs/aufs/Kconfig
  13889. --- linux-2.6.31.4.orig/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100
  13890. +++ linux-2.6.31.4/fs/aufs/Kconfig 2009-10-18 11:26:01.000000000 +0200
  13891. @@ -0,0 +1,132 @@
  13892. +config AUFS_FS
  13893. + tristate "Aufs (Advanced multi layered unification filesystem) support"
  13894. + depends on EXPERIMENTAL
  13895. + help
  13896. + Aufs is a stackable unification filesystem such as Unionfs,
  13897. + which unifies several directories and provides a merged single
  13898. + directory.
  13899. + In the early days, aufs was entirely re-designed and
  13900. + re-implemented Unionfs Version 1.x series. Introducing many
  13901. + original ideas, approaches and improvements, it becomes totally
  13902. + different from Unionfs while keeping the basic features.
  13903. +
  13904. +if AUFS_FS
  13905. +choice
  13906. + prompt "Maximum number of branches"
  13907. + default AUFS_BRANCH_MAX_127
  13908. + help
  13909. + Specifies the maximum number of branches (or member directories)
  13910. + in a single aufs. The larger value consumes more system
  13911. + resources and has a minor impact to performance.
  13912. +config AUFS_BRANCH_MAX_127
  13913. + bool "127"
  13914. + help
  13915. + Specifies the maximum number of branches (or member directories)
  13916. + in a single aufs. The larger value consumes more system
  13917. + resources and has a minor impact to performance.
  13918. +config AUFS_BRANCH_MAX_511
  13919. + bool "511"
  13920. + help
  13921. + Specifies the maximum number of branches (or member directories)
  13922. + in a single aufs. The larger value consumes more system
  13923. + resources and has a minor impact to performance.
  13924. +config AUFS_BRANCH_MAX_1023
  13925. + bool "1023"
  13926. + help
  13927. + Specifies the maximum number of branches (or member directories)
  13928. + in a single aufs. The larger value consumes more system
  13929. + resources and has a minor impact to performance.
  13930. +config AUFS_BRANCH_MAX_32767
  13931. + bool "32767"
  13932. + help
  13933. + Specifies the maximum number of branches (or member directories)
  13934. + in a single aufs. The larger value consumes more system
  13935. + resources and has a minor impact to performance.
  13936. +endchoice
  13937. +
  13938. +config AUFS_HINOTIFY
  13939. + bool "Use inotify to detect actions on a branch"
  13940. + depends on INOTIFY
  13941. + help
  13942. + If you want to modify files on branches directly, eg. bypassing aufs,
  13943. + and want aufs to detect the changes of them fully, then enable this
  13944. + option and use 'udba=inotify' mount option.
  13945. + It will have a negative impact to the performance.
  13946. + See detail in aufs.5.
  13947. +
  13948. +config AUFS_EXPORT
  13949. + bool "NFS-exportable aufs"
  13950. + depends on (AUFS_FS = y && EXPORTFS = y) || (AUFS_FS = m && EXPORTFS)
  13951. + help
  13952. + If you want to export your mounted aufs via NFS, then enable this
  13953. + option. There are several requirements for this configuration.
  13954. + See detail in aufs.5.
  13955. +
  13956. +config AUFS_SHWH
  13957. + bool "Show whiteouts"
  13958. + help
  13959. + If you want to make the whiteouts in aufs visible, then enable
  13960. + this option and specify 'shwh' mount option. Although it may
  13961. + sounds like philosophy or something, but in technically it
  13962. + simply shows the name of whiteout with keeping its behaviour.
  13963. +
  13964. +config AUFS_BR_RAMFS
  13965. + bool "Ramfs (initramfs/rootfs) as an aufs branch"
  13966. + help
  13967. + If you want to use ramfs as an aufs branch fs, then enable this
  13968. + option. Generally tmpfs is recommended.
  13969. + Aufs prohibited them to be a branch fs by default, because
  13970. + initramfs becomes unusable after switch_root or something
  13971. + generally. If you sets initramfs as an aufs branch and boot your
  13972. + system by switch_root, you will meet a problem easily since the
  13973. + files in initramfs may be inaccessible.
  13974. + Unless you are going to use ramfs as an aufs branch fs without
  13975. + switch_root or something, leave it N.
  13976. +
  13977. +config AUFS_BR_FUSE
  13978. + bool "Fuse fs as an aufs branch"
  13979. + depends on FUSE_FS
  13980. + select AUFS_POLL
  13981. + help
  13982. + If you want to use fuse-based userspace filesystem as an aufs
  13983. + branch fs, then enable this option.
  13984. + It implements the internal poll(2) operation which is
  13985. + implemented by fuse only (curretnly).
  13986. +
  13987. +config AUFS_DEBUG
  13988. + bool "Debug aufs"
  13989. + help
  13990. + Enable this to compile aufs internal debug code.
  13991. + It will have a negative impact to the performance.
  13992. +
  13993. +config AUFS_MAGIC_SYSRQ
  13994. + bool
  13995. + depends on AUFS_DEBUG && MAGIC_SYSRQ
  13996. + default y
  13997. + help
  13998. + Automatic configuration for internal use.
  13999. + When aufs supports Magic SysRq, enabled automatically.
  14000. +
  14001. +config AUFS_BDEV_LOOP
  14002. + bool
  14003. + depends on BLK_DEV_LOOP
  14004. + default y
  14005. + help
  14006. + Automatic configuration for internal use.
  14007. + Convert =[ym] into =y.
  14008. +
  14009. +config AUFS_INO_T_64
  14010. + bool
  14011. + depends on AUFS_EXPORT
  14012. + depends on 64BIT && !(ALPHA || S390)
  14013. + default y
  14014. + help
  14015. + Automatic configuration for internal use.
  14016. + /* typedef unsigned long/int __kernel_ino_t */
  14017. + /* alpha and s390x are int */
  14018. +
  14019. +config AUFS_POLL
  14020. + bool
  14021. + help
  14022. + Automatic configuration for internal use.
  14023. +endif
  14024. diff -Nur linux-2.6.31.4.orig/fs/aufs/loop.c linux-2.6.31.4/fs/aufs/loop.c
  14025. --- linux-2.6.31.4.orig/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100
  14026. +++ linux-2.6.31.4/fs/aufs/loop.c 2009-10-18 11:26:01.000000000 +0200
  14027. @@ -0,0 +1,55 @@
  14028. +/*
  14029. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  14030. + *
  14031. + * This program, aufs is free software; you can redistribute it and/or modify
  14032. + * it under the terms of the GNU General Public License as published by
  14033. + * the Free Software Foundation; either version 2 of the License, or
  14034. + * (at your option) any later version.
  14035. + *
  14036. + * This program is distributed in the hope that it will be useful,
  14037. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14038. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14039. + * GNU General Public License for more details.
  14040. + *
  14041. + * You should have received a copy of the GNU General Public License
  14042. + * along with this program; if not, write to the Free Software
  14043. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14044. + */
  14045. +
  14046. +/*
  14047. + * support for loopback block device as a branch
  14048. + */
  14049. +
  14050. +#include <linux/loop.h>
  14051. +#include "aufs.h"
  14052. +
  14053. +/*
  14054. + * test if two lower dentries have overlapping branches.
  14055. + */
  14056. +int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_d1,
  14057. + struct dentry *h_d2)
  14058. +{
  14059. + struct inode *h_inode;
  14060. + struct loop_device *l;
  14061. +
  14062. + h_inode = h_d1->d_inode;
  14063. + if (MAJOR(h_inode->i_sb->s_dev) != LOOP_MAJOR)
  14064. + return 0;
  14065. +
  14066. + l = h_inode->i_sb->s_bdev->bd_disk->private_data;
  14067. + h_d1 = l->lo_backing_file->f_dentry;
  14068. + /* h_d1 can be local NFS. in this case aufs cannot detect the loop */
  14069. + if (unlikely(h_d1->d_sb == sb))
  14070. + return 1;
  14071. + return !!au_test_subdir(h_d1, h_d2);
  14072. +}
  14073. +
  14074. +/* true if a kernel thread named 'loop[0-9].*' accesses a file */
  14075. +int au_test_loopback_kthread(void)
  14076. +{
  14077. + const char c = current->comm[4];
  14078. +
  14079. + return current->mm == NULL
  14080. + && '0' <= c && c <= '9'
  14081. + && strncmp(current->comm, "loop", 4) == 0;
  14082. +}
  14083. diff -Nur linux-2.6.31.4.orig/fs/aufs/loop.h linux-2.6.31.4/fs/aufs/loop.h
  14084. --- linux-2.6.31.4.orig/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
  14085. +++ linux-2.6.31.4/fs/aufs/loop.h 2009-10-18 11:26:01.000000000 +0200
  14086. @@ -0,0 +1,51 @@
  14087. +/*
  14088. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  14089. + *
  14090. + * This program, aufs is free software; you can redistribute it and/or modify
  14091. + * it under the terms of the GNU General Public License as published by
  14092. + * the Free Software Foundation; either version 2 of the License, or
  14093. + * (at your option) any later version.
  14094. + *
  14095. + * This program is distributed in the hope that it will be useful,
  14096. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14097. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14098. + * GNU General Public License for more details.
  14099. + *
  14100. + * You should have received a copy of the GNU General Public License
  14101. + * along with this program; if not, write to the Free Software
  14102. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14103. + */
  14104. +
  14105. +/*
  14106. + * support for loopback mount as a branch
  14107. + */
  14108. +
  14109. +#ifndef __AUFS_LOOP_H__
  14110. +#define __AUFS_LOOP_H__
  14111. +
  14112. +#ifdef __KERNEL__
  14113. +
  14114. +struct dentry;
  14115. +struct super_block;
  14116. +
  14117. +#ifdef CONFIG_AUFS_BDEV_LOOP
  14118. +/* loop.c */
  14119. +int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_d1,
  14120. + struct dentry *h_d2);
  14121. +int au_test_loopback_kthread(void);
  14122. +#else
  14123. +static inline
  14124. +int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_d1,
  14125. + struct dentry *h_d2)
  14126. +{
  14127. + return 0;
  14128. +}
  14129. +
  14130. +static inline int au_test_loopback_kthread(void)
  14131. +{
  14132. + return 0;
  14133. +}
  14134. +#endif /* BLK_DEV_LOOP */
  14135. +
  14136. +#endif /* __KERNEL__ */
  14137. +#endif /* __AUFS_LOOP_H__ */
  14138. diff -Nur linux-2.6.31.4.orig/fs/aufs/magic.mk linux-2.6.31.4/fs/aufs/magic.mk
  14139. --- linux-2.6.31.4.orig/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100
  14140. +++ linux-2.6.31.4/fs/aufs/magic.mk 2009-10-18 11:26:01.000000000 +0200
  14141. @@ -0,0 +1,52 @@
  14142. +
  14143. +# defined in ${srctree}/fs/fuse/inode.c
  14144. +# tristate
  14145. +ifdef CONFIG_FUSE_FS
  14146. +ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
  14147. +endif
  14148. +
  14149. +# defined in ${srctree}/fs/ocfs2/ocfs2_fs.h
  14150. +# tristate
  14151. +ifdef CONFIG_OCFS2_FS
  14152. +ccflags-y += -DOCFS2_SUPER_MAGIC=0x7461636f
  14153. +endif
  14154. +
  14155. +# defined in ${srctree}/fs/ocfs2/dlm/userdlm.h
  14156. +# tristate
  14157. +ifdef CONFIG_OCFS2_FS_O2CB
  14158. +ccflags-y += -DDLMFS_MAGIC=0x76a9f425
  14159. +endif
  14160. +
  14161. +# defined in ${srctree}/fs/ramfs/inode.c
  14162. +# always true
  14163. +ccflags-y += -DRAMFS_MAGIC=0x858458f6
  14164. +
  14165. +# defined in ${srctree}/fs/cifs/cifsfs.c
  14166. +# tristate
  14167. +ifdef CONFIG_CIFS_FS
  14168. +ccflags-y += -DCIFS_MAGIC_NUMBER=0xFF534D42
  14169. +endif
  14170. +
  14171. +# defined in ${srctree}/fs/xfs/xfs_sb.h
  14172. +# tristate
  14173. +ifdef CONFIG_XFS_FS
  14174. +ccflags-y += -DXFS_SB_MAGIC=0x58465342
  14175. +endif
  14176. +
  14177. +# defined in ${srctree}/fs/configfs/mount.c
  14178. +# tristate
  14179. +ifdef CONFIG_CONFIGFS_FS
  14180. +ccflags-y += -DCONFIGFS_MAGIC=0x62656570
  14181. +endif
  14182. +
  14183. +# defined in ${srctree}/fs/9p/v9fs.h
  14184. +# tristate
  14185. +ifdef CONFIG_9P_FS
  14186. +ccflags-y += -DV9FS_MAGIC=0x01021997
  14187. +endif
  14188. +
  14189. +# defined in ${srctree}/fs/ubifs/ubifs.h
  14190. +# tristate
  14191. +ifdef CONFIG_UBIFS_FS
  14192. +ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
  14193. +endif
  14194. diff -Nur linux-2.6.31.4.orig/fs/aufs/Makefile linux-2.6.31.4/fs/aufs/Makefile
  14195. --- linux-2.6.31.4.orig/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100
  14196. +++ linux-2.6.31.4/fs/aufs/Makefile 2009-10-18 11:26:01.000000000 +0200
  14197. @@ -0,0 +1,23 @@
  14198. +
  14199. +include ${src}/magic.mk
  14200. +-include ${src}/priv_def.mk
  14201. +
  14202. +obj-$(CONFIG_AUFS_FS) += aufs.o
  14203. +aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
  14204. + wkq.o vfsub.o dcsub.o \
  14205. + cpup.o whout.o plink.o wbr_policy.o \
  14206. + dinfo.o dentry.o \
  14207. + finfo.o file.o f_op.o \
  14208. + dir.o vdir.o \
  14209. + iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
  14210. + ioctl.o
  14211. +
  14212. +# all are boolean
  14213. +aufs-$(CONFIG_SYSFS) += sysfs.o
  14214. +aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
  14215. +aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
  14216. +aufs-$(CONFIG_AUFS_HINOTIFY) += hinotify.o
  14217. +aufs-$(CONFIG_AUFS_EXPORT) += export.o
  14218. +aufs-$(CONFIG_AUFS_POLL) += poll.o
  14219. +aufs-$(CONFIG_AUFS_DEBUG) += debug.o
  14220. +aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
  14221. diff -Nur linux-2.6.31.4.orig/fs/aufs/module.c linux-2.6.31.4/fs/aufs/module.c
  14222. --- linux-2.6.31.4.orig/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100
  14223. +++ linux-2.6.31.4/fs/aufs/module.c 2009-10-18 11:26:01.000000000 +0200
  14224. @@ -0,0 +1,173 @@
  14225. +/*
  14226. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  14227. + *
  14228. + * This program, aufs is free software; you can redistribute it and/or modify
  14229. + * it under the terms of the GNU General Public License as published by
  14230. + * the Free Software Foundation; either version 2 of the License, or
  14231. + * (at your option) any later version.
  14232. + *
  14233. + * This program is distributed in the hope that it will be useful,
  14234. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14235. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14236. + * GNU General Public License for more details.
  14237. + *
  14238. + * You should have received a copy of the GNU General Public License
  14239. + * along with this program; if not, write to the Free Software
  14240. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14241. + */
  14242. +
  14243. +/*
  14244. + * module global variables and operations
  14245. + */
  14246. +
  14247. +#include <linux/module.h>
  14248. +#include <linux/seq_file.h>
  14249. +#include "aufs.h"
  14250. +
  14251. +void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp)
  14252. +{
  14253. + if (new_sz <= nused)
  14254. + return p;
  14255. +
  14256. + p = krealloc(p, new_sz, gfp);
  14257. + if (p)
  14258. + memset(p + nused, 0, new_sz - nused);
  14259. + return p;
  14260. +}
  14261. +
  14262. +/* ---------------------------------------------------------------------- */
  14263. +
  14264. +/*
  14265. + * aufs caches
  14266. + */
  14267. +struct kmem_cache *au_cachep[AuCache_Last];
  14268. +static int __init au_cache_init(void)
  14269. +{
  14270. + au_cachep[AuCache_DINFO] = AuCache(au_dinfo);
  14271. + if (au_cachep[AuCache_DINFO])
  14272. + au_cachep[AuCache_ICNTNR] = AuCache(au_icntnr);
  14273. + if (au_cachep[AuCache_ICNTNR])
  14274. + au_cachep[AuCache_FINFO] = AuCache(au_finfo);
  14275. + if (au_cachep[AuCache_FINFO])
  14276. + au_cachep[AuCache_VDIR] = AuCache(au_vdir);
  14277. + if (au_cachep[AuCache_VDIR])
  14278. + au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
  14279. + if (au_cachep[AuCache_DEHSTR])
  14280. + return 0;
  14281. +
  14282. + return -ENOMEM;
  14283. +}
  14284. +
  14285. +static void au_cache_fin(void)
  14286. +{
  14287. + int i;
  14288. + for (i = 0; i < AuCache_Last; i++)
  14289. + if (au_cachep[i]) {
  14290. + kmem_cache_destroy(au_cachep[i]);
  14291. + au_cachep[i] = NULL;
  14292. + }
  14293. +}
  14294. +
  14295. +/* ---------------------------------------------------------------------- */
  14296. +
  14297. +int au_dir_roflags;
  14298. +
  14299. +/*
  14300. + * functions for module interface.
  14301. + */
  14302. +MODULE_LICENSE("GPL");
  14303. +/* MODULE_LICENSE("GPL v2"); */
  14304. +MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
  14305. +MODULE_DESCRIPTION(AUFS_NAME
  14306. + " -- Advanced multi layered unification filesystem");
  14307. +MODULE_VERSION(AUFS_VERSION);
  14308. +
  14309. +/* it should be 'byte', but param_set_byte() prints it by "%c" */
  14310. +short aufs_nwkq = AUFS_NWKQ_DEF;
  14311. +MODULE_PARM_DESC(nwkq, "the number of workqueue thread, " AUFS_WKQ_NAME);
  14312. +module_param_named(nwkq, aufs_nwkq, short, S_IRUGO);
  14313. +
  14314. +/* this module parameter has no meaning when SYSFS is disabled */
  14315. +int sysaufs_brs = 1;
  14316. +MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
  14317. +module_param_named(brs, sysaufs_brs, int, S_IRUGO);
  14318. +
  14319. +/* ---------------------------------------------------------------------- */
  14320. +
  14321. +static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
  14322. +
  14323. +int au_seq_path(struct seq_file *seq, struct path *path)
  14324. +{
  14325. + return seq_path(seq, path, au_esc_chars);
  14326. +}
  14327. +
  14328. +/* ---------------------------------------------------------------------- */
  14329. +
  14330. +static int __init aufs_init(void)
  14331. +{
  14332. + int err, i;
  14333. + char *p;
  14334. +
  14335. + p = au_esc_chars;
  14336. + for (i = 1; i <= ' '; i++)
  14337. + *p++ = i;
  14338. + *p++ = '\\';
  14339. + *p++ = '\x7f';
  14340. + *p = 0;
  14341. +
  14342. + au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
  14343. +
  14344. + sysaufs_brs_init();
  14345. + au_debug_init();
  14346. +
  14347. + err = -EINVAL;
  14348. + if (unlikely(aufs_nwkq <= 0))
  14349. + goto out;
  14350. +
  14351. + err = sysaufs_init();
  14352. + if (unlikely(err))
  14353. + goto out;
  14354. + err = au_wkq_init();
  14355. + if (unlikely(err))
  14356. + goto out_sysaufs;
  14357. + err = au_hinotify_init();
  14358. + if (unlikely(err))
  14359. + goto out_wkq;
  14360. + err = au_sysrq_init();
  14361. + if (unlikely(err))
  14362. + goto out_hin;
  14363. + err = au_cache_init();
  14364. + if (unlikely(err))
  14365. + goto out_sysrq;
  14366. + err = register_filesystem(&aufs_fs_type);
  14367. + if (unlikely(err))
  14368. + goto out_cache;
  14369. + pr_info(AUFS_NAME " " AUFS_VERSION "\n");
  14370. + goto out; /* success */
  14371. +
  14372. + out_cache:
  14373. + au_cache_fin();
  14374. + out_sysrq:
  14375. + au_sysrq_fin();
  14376. + out_hin:
  14377. + au_hinotify_fin();
  14378. + out_wkq:
  14379. + au_wkq_fin();
  14380. + out_sysaufs:
  14381. + sysaufs_fin();
  14382. + out:
  14383. + return err;
  14384. +}
  14385. +
  14386. +static void __exit aufs_exit(void)
  14387. +{
  14388. + unregister_filesystem(&aufs_fs_type);
  14389. + au_cache_fin();
  14390. + au_sysrq_fin();
  14391. + au_hinotify_fin();
  14392. + au_wkq_fin();
  14393. + sysaufs_fin();
  14394. +}
  14395. +
  14396. +module_init(aufs_init);
  14397. +module_exit(aufs_exit);
  14398. diff -Nur linux-2.6.31.4.orig/fs/aufs/module.h linux-2.6.31.4/fs/aufs/module.h
  14399. --- linux-2.6.31.4.orig/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100
  14400. +++ linux-2.6.31.4/fs/aufs/module.h 2009-10-18 11:26:01.000000000 +0200
  14401. @@ -0,0 +1,78 @@
  14402. +/*
  14403. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  14404. + *
  14405. + * This program, aufs is free software; you can redistribute it and/or modify
  14406. + * it under the terms of the GNU General Public License as published by
  14407. + * the Free Software Foundation; either version 2 of the License, or
  14408. + * (at your option) any later version.
  14409. + *
  14410. + * This program is distributed in the hope that it will be useful,
  14411. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14412. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14413. + * GNU General Public License for more details.
  14414. + *
  14415. + * You should have received a copy of the GNU General Public License
  14416. + * along with this program; if not, write to the Free Software
  14417. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14418. + */
  14419. +
  14420. +/*
  14421. + * module initialization and module-global
  14422. + */
  14423. +
  14424. +#ifndef __AUFS_MODULE_H__
  14425. +#define __AUFS_MODULE_H__
  14426. +
  14427. +#ifdef __KERNEL__
  14428. +
  14429. +#include <linux/slab.h>
  14430. +
  14431. +struct path;
  14432. +struct seq_file;
  14433. +
  14434. +/* module parameters */
  14435. +extern short aufs_nwkq;
  14436. +extern int sysaufs_brs;
  14437. +
  14438. +/* ---------------------------------------------------------------------- */
  14439. +
  14440. +extern int au_dir_roflags;
  14441. +
  14442. +void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp);
  14443. +int au_seq_path(struct seq_file *seq, struct path *path);
  14444. +
  14445. +/* ---------------------------------------------------------------------- */
  14446. +
  14447. +/* kmem cache */
  14448. +enum {
  14449. + AuCache_DINFO,
  14450. + AuCache_ICNTNR,
  14451. + AuCache_FINFO,
  14452. + AuCache_VDIR,
  14453. + AuCache_DEHSTR,
  14454. +#ifdef CONFIG_AUFS_HINOTIFY
  14455. + AuCache_HINOTIFY,
  14456. +#endif
  14457. + AuCache_Last
  14458. +};
  14459. +
  14460. +#define AuCache(type) KMEM_CACHE(type, SLAB_RECLAIM_ACCOUNT)
  14461. +
  14462. +extern struct kmem_cache *au_cachep[];
  14463. +
  14464. +#define AuCacheFuncs(name, index) \
  14465. +static inline void *au_cache_alloc_##name(void) \
  14466. +{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \
  14467. +static inline void au_cache_free_##name(void *p) \
  14468. +{ kmem_cache_free(au_cachep[AuCache_##index], p); }
  14469. +
  14470. +AuCacheFuncs(dinfo, DINFO);
  14471. +AuCacheFuncs(icntnr, ICNTNR);
  14472. +AuCacheFuncs(finfo, FINFO);
  14473. +AuCacheFuncs(vdir, VDIR);
  14474. +AuCacheFuncs(dehstr, DEHSTR);
  14475. +
  14476. +/* ---------------------------------------------------------------------- */
  14477. +
  14478. +#endif /* __KERNEL__ */
  14479. +#endif /* __AUFS_MODULE_H__ */
  14480. diff -Nur linux-2.6.31.4.orig/fs/aufs/opts.c linux-2.6.31.4/fs/aufs/opts.c
  14481. --- linux-2.6.31.4.orig/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100
  14482. +++ linux-2.6.31.4/fs/aufs/opts.c 2009-10-18 11:26:01.000000000 +0200
  14483. @@ -0,0 +1,1543 @@
  14484. +/*
  14485. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  14486. + *
  14487. + * This program, aufs is free software; you can redistribute it and/or modify
  14488. + * it under the terms of the GNU General Public License as published by
  14489. + * the Free Software Foundation; either version 2 of the License, or
  14490. + * (at your option) any later version.
  14491. + *
  14492. + * This program is distributed in the hope that it will be useful,
  14493. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14494. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14495. + * GNU General Public License for more details.
  14496. + *
  14497. + * You should have received a copy of the GNU General Public License
  14498. + * along with this program; if not, write to the Free Software
  14499. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14500. + */
  14501. +
  14502. +/*
  14503. + * mount options/flags
  14504. + */
  14505. +
  14506. +#include <linux/file.h>
  14507. +#include <linux/namei.h>
  14508. +#include <linux/types.h> /* a distribution requires */
  14509. +#include <linux/parser.h>
  14510. +#include "aufs.h"
  14511. +
  14512. +/* ---------------------------------------------------------------------- */
  14513. +
  14514. +enum {
  14515. + Opt_br,
  14516. + Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend,
  14517. + Opt_idel, Opt_imod, Opt_ireorder,
  14518. + Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, Opt_rendir,
  14519. + Opt_rdblk_def, Opt_rdhash_def,
  14520. + Opt_xino, Opt_zxino, Opt_noxino,
  14521. + Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
  14522. + Opt_trunc_xino_path, Opt_itrunc_xino,
  14523. + Opt_trunc_xib, Opt_notrunc_xib,
  14524. + Opt_shwh, Opt_noshwh,
  14525. + Opt_plink, Opt_noplink, Opt_list_plink,
  14526. + Opt_udba,
  14527. + /* Opt_lock, Opt_unlock, */
  14528. + Opt_cmd, Opt_cmd_args,
  14529. + Opt_diropq_a, Opt_diropq_w,
  14530. + Opt_warn_perm, Opt_nowarn_perm,
  14531. + Opt_wbr_copyup, Opt_wbr_create,
  14532. + Opt_refrof, Opt_norefrof,
  14533. + Opt_verbose, Opt_noverbose,
  14534. + Opt_sum, Opt_nosum, Opt_wsum,
  14535. + Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
  14536. +};
  14537. +
  14538. +static match_table_t options = {
  14539. + {Opt_br, "br=%s"},
  14540. + {Opt_br, "br:%s"},
  14541. +
  14542. + {Opt_add, "add=%d:%s"},
  14543. + {Opt_add, "add:%d:%s"},
  14544. + {Opt_add, "ins=%d:%s"},
  14545. + {Opt_add, "ins:%d:%s"},
  14546. + {Opt_append, "append=%s"},
  14547. + {Opt_append, "append:%s"},
  14548. + {Opt_prepend, "prepend=%s"},
  14549. + {Opt_prepend, "prepend:%s"},
  14550. +
  14551. + {Opt_del, "del=%s"},
  14552. + {Opt_del, "del:%s"},
  14553. + /* {Opt_idel, "idel:%d"}, */
  14554. + {Opt_mod, "mod=%s"},
  14555. + {Opt_mod, "mod:%s"},
  14556. + /* {Opt_imod, "imod:%d:%s"}, */
  14557. +
  14558. + {Opt_dirwh, "dirwh=%d"},
  14559. +
  14560. + {Opt_xino, "xino=%s"},
  14561. + {Opt_noxino, "noxino"},
  14562. + {Opt_trunc_xino, "trunc_xino"},
  14563. + {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
  14564. + {Opt_notrunc_xino, "notrunc_xino"},
  14565. + {Opt_trunc_xino_path, "trunc_xino=%s"},
  14566. + {Opt_itrunc_xino, "itrunc_xino=%d"},
  14567. + /* {Opt_zxino, "zxino=%s"}, */
  14568. + {Opt_trunc_xib, "trunc_xib"},
  14569. + {Opt_notrunc_xib, "notrunc_xib"},
  14570. +
  14571. + {Opt_plink, "plink"},
  14572. + {Opt_noplink, "noplink"},
  14573. +#ifdef CONFIG_AUFS_DEBUG
  14574. + {Opt_list_plink, "list_plink"},
  14575. +#endif
  14576. +
  14577. + {Opt_udba, "udba=%s"},
  14578. +
  14579. + {Opt_diropq_a, "diropq=always"},
  14580. + {Opt_diropq_a, "diropq=a"},
  14581. + {Opt_diropq_w, "diropq=whiteouted"},
  14582. + {Opt_diropq_w, "diropq=w"},
  14583. +
  14584. + {Opt_warn_perm, "warn_perm"},
  14585. + {Opt_nowarn_perm, "nowarn_perm"},
  14586. +
  14587. + /* keep them temporary */
  14588. + {Opt_ignore_silent, "coo=%s"},
  14589. + {Opt_ignore_silent, "nodlgt"},
  14590. + {Opt_ignore_silent, "nodirperm1"},
  14591. + {Opt_ignore_silent, "clean_plink"},
  14592. +
  14593. +#ifdef CONFIG_AUFS_SHWH
  14594. + {Opt_shwh, "shwh"},
  14595. +#endif
  14596. + {Opt_noshwh, "noshwh"},
  14597. +
  14598. + {Opt_rendir, "rendir=%d"},
  14599. +
  14600. + {Opt_refrof, "refrof"},
  14601. + {Opt_norefrof, "norefrof"},
  14602. +
  14603. + {Opt_verbose, "verbose"},
  14604. + {Opt_verbose, "v"},
  14605. + {Opt_noverbose, "noverbose"},
  14606. + {Opt_noverbose, "quiet"},
  14607. + {Opt_noverbose, "q"},
  14608. + {Opt_noverbose, "silent"},
  14609. +
  14610. + {Opt_sum, "sum"},
  14611. + {Opt_nosum, "nosum"},
  14612. + {Opt_wsum, "wsum"},
  14613. +
  14614. + {Opt_rdcache, "rdcache=%d"},
  14615. + {Opt_rdblk, "rdblk=%d"},
  14616. + {Opt_rdblk_def, "rdblk=def"},
  14617. + {Opt_rdhash, "rdhash=%d"},
  14618. + {Opt_rdhash_def, "rdhash=def"},
  14619. +
  14620. + {Opt_wbr_create, "create=%s"},
  14621. + {Opt_wbr_create, "create_policy=%s"},
  14622. + {Opt_wbr_copyup, "cpup=%s"},
  14623. + {Opt_wbr_copyup, "copyup=%s"},
  14624. + {Opt_wbr_copyup, "copyup_policy=%s"},
  14625. +
  14626. + /* internal use for the scripts */
  14627. + {Opt_ignore_silent, "si=%s"},
  14628. +
  14629. + {Opt_br, "dirs=%s"},
  14630. + {Opt_ignore, "debug=%d"},
  14631. + {Opt_ignore, "delete=whiteout"},
  14632. + {Opt_ignore, "delete=all"},
  14633. + {Opt_ignore, "imap=%s"},
  14634. +
  14635. + {Opt_err, NULL}
  14636. +};
  14637. +
  14638. +/* ---------------------------------------------------------------------- */
  14639. +
  14640. +static const char *au_parser_pattern(int val, struct match_token *token)
  14641. +{
  14642. + while (token->pattern) {
  14643. + if (token->token == val)
  14644. + return token->pattern;
  14645. + token++;
  14646. + }
  14647. + BUG();
  14648. + return "??";
  14649. +}
  14650. +
  14651. +/* ---------------------------------------------------------------------- */
  14652. +
  14653. +static match_table_t brperms = {
  14654. + {AuBrPerm_RO, AUFS_BRPERM_RO},
  14655. + {AuBrPerm_RR, AUFS_BRPERM_RR},
  14656. + {AuBrPerm_RW, AUFS_BRPERM_RW},
  14657. +
  14658. + {AuBrPerm_ROWH, AUFS_BRPERM_ROWH},
  14659. + {AuBrPerm_RRWH, AUFS_BRPERM_RRWH},
  14660. + {AuBrPerm_RWNoLinkWH, AUFS_BRPERM_RWNLWH},
  14661. +
  14662. + {AuBrPerm_ROWH, "nfsro"},
  14663. + {AuBrPerm_RO, NULL}
  14664. +};
  14665. +
  14666. +static int br_perm_val(char *perm)
  14667. +{
  14668. + int val;
  14669. + substring_t args[MAX_OPT_ARGS];
  14670. +
  14671. + val = match_token(perm, brperms, args);
  14672. + return val;
  14673. +}
  14674. +
  14675. +const char *au_optstr_br_perm(int brperm)
  14676. +{
  14677. + return au_parser_pattern(brperm, (void *)brperms);
  14678. +}
  14679. +
  14680. +/* ---------------------------------------------------------------------- */
  14681. +
  14682. +static match_table_t udbalevel = {
  14683. + {AuOpt_UDBA_REVAL, "reval"},
  14684. + {AuOpt_UDBA_NONE, "none"},
  14685. +#ifdef CONFIG_AUFS_HINOTIFY
  14686. + {AuOpt_UDBA_HINOTIFY, "inotify"},
  14687. +#endif
  14688. + {-1, NULL}
  14689. +};
  14690. +
  14691. +static int udba_val(char *str)
  14692. +{
  14693. + substring_t args[MAX_OPT_ARGS];
  14694. +
  14695. + return match_token(str, udbalevel, args);
  14696. +}
  14697. +
  14698. +const char *au_optstr_udba(int udba)
  14699. +{
  14700. + return au_parser_pattern(udba, (void *)udbalevel);
  14701. +}
  14702. +
  14703. +/* ---------------------------------------------------------------------- */
  14704. +
  14705. +static match_table_t au_wbr_create_policy = {
  14706. + {AuWbrCreate_TDP, "tdp"},
  14707. + {AuWbrCreate_TDP, "top-down-parent"},
  14708. + {AuWbrCreate_RR, "rr"},
  14709. + {AuWbrCreate_RR, "round-robin"},
  14710. + {AuWbrCreate_MFS, "mfs"},
  14711. + {AuWbrCreate_MFS, "most-free-space"},
  14712. + {AuWbrCreate_MFSV, "mfs:%d"},
  14713. + {AuWbrCreate_MFSV, "most-free-space:%d"},
  14714. +
  14715. + {AuWbrCreate_MFSRR, "mfsrr:%d"},
  14716. + {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
  14717. + {AuWbrCreate_PMFS, "pmfs"},
  14718. + {AuWbrCreate_PMFSV, "pmfs:%d"},
  14719. +
  14720. + {-1, NULL}
  14721. +};
  14722. +
  14723. +/*
  14724. + * cf. linux/lib/parser.c and cmdline.c
  14725. + * gave up calling memparse() since it uses simple_strtoull() instead of
  14726. + * strict_...().
  14727. + */
  14728. +static int au_match_ull(substring_t *s, unsigned long long *result)
  14729. +{
  14730. + int err;
  14731. + unsigned int len;
  14732. + char a[32];
  14733. +
  14734. + err = -ERANGE;
  14735. + len = s->to - s->from;
  14736. + if (len + 1 <= sizeof(a)) {
  14737. + memcpy(a, s->from, len);
  14738. + a[len] = '\0';
  14739. + err = strict_strtoull(a, 0, result);
  14740. + }
  14741. + return err;
  14742. +}
  14743. +
  14744. +static int au_wbr_mfs_wmark(substring_t *arg, char *str,
  14745. + struct au_opt_wbr_create *create)
  14746. +{
  14747. + int err;
  14748. + unsigned long long ull;
  14749. +
  14750. + err = 0;
  14751. + if (!au_match_ull(arg, &ull))
  14752. + create->mfsrr_watermark = ull;
  14753. + else {
  14754. + AuErr("bad integer in %s\n", str);
  14755. + err = -EINVAL;
  14756. + }
  14757. +
  14758. + return err;
  14759. +}
  14760. +
  14761. +static int au_wbr_mfs_sec(substring_t *arg, char *str,
  14762. + struct au_opt_wbr_create *create)
  14763. +{
  14764. + int n, err;
  14765. +
  14766. + err = 0;
  14767. + if (!match_int(arg, &n) && 0 <= n)
  14768. + create->mfs_second = n;
  14769. + else {
  14770. + AuErr("bad integer in %s\n", str);
  14771. + err = -EINVAL;
  14772. + }
  14773. +
  14774. + return err;
  14775. +}
  14776. +
  14777. +static int au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
  14778. +{
  14779. + int err, e;
  14780. + substring_t args[MAX_OPT_ARGS];
  14781. +
  14782. + err = match_token(str, au_wbr_create_policy, args);
  14783. + create->wbr_create = err;
  14784. + switch (err) {
  14785. + case AuWbrCreate_MFSRRV:
  14786. + e = au_wbr_mfs_wmark(&args[0], str, create);
  14787. + if (!e)
  14788. + e = au_wbr_mfs_sec(&args[1], str, create);
  14789. + if (unlikely(e))
  14790. + err = e;
  14791. + break;
  14792. + case AuWbrCreate_MFSRR:
  14793. + e = au_wbr_mfs_wmark(&args[0], str, create);
  14794. + if (unlikely(e)) {
  14795. + err = e;
  14796. + break;
  14797. + }
  14798. + /*FALLTHROUGH*/
  14799. + case AuWbrCreate_MFS:
  14800. + case AuWbrCreate_PMFS:
  14801. + create->mfs_second = AUFS_MFS_SECOND_DEF;
  14802. + break;
  14803. + case AuWbrCreate_MFSV:
  14804. + case AuWbrCreate_PMFSV:
  14805. + e = au_wbr_mfs_sec(&args[0], str, create);
  14806. + if (unlikely(e))
  14807. + err = e;
  14808. + break;
  14809. + }
  14810. +
  14811. + return err;
  14812. +}
  14813. +
  14814. +const char *au_optstr_wbr_create(int wbr_create)
  14815. +{
  14816. + return au_parser_pattern(wbr_create, (void *)au_wbr_create_policy);
  14817. +}
  14818. +
  14819. +static match_table_t au_wbr_copyup_policy = {
  14820. + {AuWbrCopyup_TDP, "tdp"},
  14821. + {AuWbrCopyup_TDP, "top-down-parent"},
  14822. + {AuWbrCopyup_BUP, "bup"},
  14823. + {AuWbrCopyup_BUP, "bottom-up-parent"},
  14824. + {AuWbrCopyup_BU, "bu"},
  14825. + {AuWbrCopyup_BU, "bottom-up"},
  14826. + {-1, NULL}
  14827. +};
  14828. +
  14829. +static int au_wbr_copyup_val(char *str)
  14830. +{
  14831. + substring_t args[MAX_OPT_ARGS];
  14832. +
  14833. + return match_token(str, au_wbr_copyup_policy, args);
  14834. +}
  14835. +
  14836. +const char *au_optstr_wbr_copyup(int wbr_copyup)
  14837. +{
  14838. + return au_parser_pattern(wbr_copyup, (void *)au_wbr_copyup_policy);
  14839. +}
  14840. +
  14841. +/* ---------------------------------------------------------------------- */
  14842. +
  14843. +static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
  14844. +
  14845. +static void dump_opts(struct au_opts *opts)
  14846. +{
  14847. +#ifdef CONFIG_AUFS_DEBUG
  14848. + /* reduce stack space */
  14849. + union {
  14850. + struct au_opt_add *add;
  14851. + struct au_opt_del *del;
  14852. + struct au_opt_mod *mod;
  14853. + struct au_opt_xino *xino;
  14854. + struct au_opt_xino_itrunc *xino_itrunc;
  14855. + struct au_opt_wbr_create *create;
  14856. + } u;
  14857. + struct au_opt *opt;
  14858. +
  14859. + opt = opts->opt;
  14860. + while (opt->type != Opt_tail) {
  14861. + switch (opt->type) {
  14862. + case Opt_add:
  14863. + u.add = &opt->add;
  14864. + AuDbg("add {b%d, %s, 0x%x, %p}\n",
  14865. + u.add->bindex, u.add->pathname, u.add->perm,
  14866. + u.add->path.dentry);
  14867. + break;
  14868. + case Opt_del:
  14869. + case Opt_idel:
  14870. + u.del = &opt->del;
  14871. + AuDbg("del {%s, %p}\n",
  14872. + u.del->pathname, u.del->h_path.dentry);
  14873. + break;
  14874. + case Opt_mod:
  14875. + case Opt_imod:
  14876. + u.mod = &opt->mod;
  14877. + AuDbg("mod {%s, 0x%x, %p}\n",
  14878. + u.mod->path, u.mod->perm, u.mod->h_root);
  14879. + break;
  14880. + case Opt_append:
  14881. + u.add = &opt->add;
  14882. + AuDbg("append {b%d, %s, 0x%x, %p}\n",
  14883. + u.add->bindex, u.add->pathname, u.add->perm,
  14884. + u.add->path.dentry);
  14885. + break;
  14886. + case Opt_prepend:
  14887. + u.add = &opt->add;
  14888. + AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
  14889. + u.add->bindex, u.add->pathname, u.add->perm,
  14890. + u.add->path.dentry);
  14891. + break;
  14892. + case Opt_dirwh:
  14893. + AuDbg("dirwh %d\n", opt->dirwh);
  14894. + break;
  14895. + case Opt_rdcache:
  14896. + AuDbg("rdcache %d\n", opt->rdcache);
  14897. + break;
  14898. + case Opt_rdblk:
  14899. + AuDbg("rdblk %u\n", opt->rdblk);
  14900. + break;
  14901. + case Opt_rdblk_def:
  14902. + AuDbg("rdblk_def\n");
  14903. + break;
  14904. + case Opt_rdhash:
  14905. + AuDbg("rdhash %u\n", opt->rdhash);
  14906. + break;
  14907. + case Opt_rdhash_def:
  14908. + AuDbg("rdhash_def\n");
  14909. + break;
  14910. + case Opt_xino:
  14911. + u.xino = &opt->xino;
  14912. + AuDbg("xino {%s %.*s}\n",
  14913. + u.xino->path,
  14914. + AuDLNPair(u.xino->file->f_dentry));
  14915. + break;
  14916. + case Opt_trunc_xino:
  14917. + AuLabel(trunc_xino);
  14918. + break;
  14919. + case Opt_notrunc_xino:
  14920. + AuLabel(notrunc_xino);
  14921. + break;
  14922. + case Opt_trunc_xino_path:
  14923. + case Opt_itrunc_xino:
  14924. + u.xino_itrunc = &opt->xino_itrunc;
  14925. + AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
  14926. + break;
  14927. +
  14928. + case Opt_noxino:
  14929. + AuLabel(noxino);
  14930. + break;
  14931. + case Opt_trunc_xib:
  14932. + AuLabel(trunc_xib);
  14933. + break;
  14934. + case Opt_notrunc_xib:
  14935. + AuLabel(notrunc_xib);
  14936. + break;
  14937. + case Opt_shwh:
  14938. + AuLabel(shwh);
  14939. + break;
  14940. + case Opt_noshwh:
  14941. + AuLabel(noshwh);
  14942. + break;
  14943. + case Opt_plink:
  14944. + AuLabel(plink);
  14945. + break;
  14946. + case Opt_noplink:
  14947. + AuLabel(noplink);
  14948. + break;
  14949. + case Opt_list_plink:
  14950. + AuLabel(list_plink);
  14951. + break;
  14952. + case Opt_udba:
  14953. + AuDbg("udba %d, %s\n",
  14954. + opt->udba, au_optstr_udba(opt->udba));
  14955. + break;
  14956. + case Opt_diropq_a:
  14957. + AuLabel(diropq_a);
  14958. + break;
  14959. + case Opt_diropq_w:
  14960. + AuLabel(diropq_w);
  14961. + break;
  14962. + case Opt_warn_perm:
  14963. + AuLabel(warn_perm);
  14964. + break;
  14965. + case Opt_nowarn_perm:
  14966. + AuLabel(nowarn_perm);
  14967. + break;
  14968. + case Opt_refrof:
  14969. + AuLabel(refrof);
  14970. + break;
  14971. + case Opt_norefrof:
  14972. + AuLabel(norefrof);
  14973. + break;
  14974. + case Opt_verbose:
  14975. + AuLabel(verbose);
  14976. + break;
  14977. + case Opt_noverbose:
  14978. + AuLabel(noverbose);
  14979. + break;
  14980. + case Opt_sum:
  14981. + AuLabel(sum);
  14982. + break;
  14983. + case Opt_nosum:
  14984. + AuLabel(nosum);
  14985. + break;
  14986. + case Opt_wsum:
  14987. + AuLabel(wsum);
  14988. + break;
  14989. + case Opt_wbr_create:
  14990. + u.create = &opt->wbr_create;
  14991. + AuDbg("create %d, %s\n", u.create->wbr_create,
  14992. + au_optstr_wbr_create(u.create->wbr_create));
  14993. + switch (u.create->wbr_create) {
  14994. + case AuWbrCreate_MFSV:
  14995. + case AuWbrCreate_PMFSV:
  14996. + AuDbg("%d sec\n", u.create->mfs_second);
  14997. + break;
  14998. + case AuWbrCreate_MFSRR:
  14999. + AuDbg("%llu watermark\n",
  15000. + u.create->mfsrr_watermark);
  15001. + break;
  15002. + case AuWbrCreate_MFSRRV:
  15003. + AuDbg("%llu watermark, %d sec\n",
  15004. + u.create->mfsrr_watermark,
  15005. + u.create->mfs_second);
  15006. + break;
  15007. + }
  15008. + break;
  15009. + case Opt_wbr_copyup:
  15010. + AuDbg("copyup %d, %s\n", opt->wbr_copyup,
  15011. + au_optstr_wbr_copyup(opt->wbr_copyup));
  15012. + break;
  15013. + default:
  15014. + BUG();
  15015. + }
  15016. + opt++;
  15017. + }
  15018. +#endif
  15019. +}
  15020. +
  15021. +void au_opts_free(struct au_opts *opts)
  15022. +{
  15023. + struct au_opt *opt;
  15024. +
  15025. + opt = opts->opt;
  15026. + while (opt->type != Opt_tail) {
  15027. + switch (opt->type) {
  15028. + case Opt_add:
  15029. + case Opt_append:
  15030. + case Opt_prepend:
  15031. + path_put(&opt->add.path);
  15032. + break;
  15033. + case Opt_del:
  15034. + case Opt_idel:
  15035. + path_put(&opt->del.h_path);
  15036. + break;
  15037. + case Opt_mod:
  15038. + case Opt_imod:
  15039. + dput(opt->mod.h_root);
  15040. + break;
  15041. + case Opt_xino:
  15042. + fput(opt->xino.file);
  15043. + break;
  15044. + }
  15045. + opt++;
  15046. + }
  15047. +}
  15048. +
  15049. +static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
  15050. + aufs_bindex_t bindex)
  15051. +{
  15052. + int err;
  15053. + struct au_opt_add *add = &opt->add;
  15054. + char *p;
  15055. +
  15056. + add->bindex = bindex;
  15057. + add->perm = AuBrPerm_Last;
  15058. + add->pathname = opt_str;
  15059. + p = strchr(opt_str, '=');
  15060. + if (p) {
  15061. + *p++ = 0;
  15062. + if (*p)
  15063. + add->perm = br_perm_val(p);
  15064. + }
  15065. +
  15066. + err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
  15067. + if (!err) {
  15068. + if (!p) {
  15069. + add->perm = AuBrPerm_RO;
  15070. + if (au_test_fs_rr(add->path.dentry->d_sb))
  15071. + add->perm = AuBrPerm_RR;
  15072. + else if (!bindex && !(sb_flags & MS_RDONLY))
  15073. + add->perm = AuBrPerm_RW;
  15074. + }
  15075. + opt->type = Opt_add;
  15076. + goto out;
  15077. + }
  15078. + AuErr("lookup failed %s (%d)\n", add->pathname, err);
  15079. + err = -EINVAL;
  15080. +
  15081. + out:
  15082. + return err;
  15083. +}
  15084. +
  15085. +static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
  15086. +{
  15087. + int err;
  15088. +
  15089. + del->pathname = args[0].from;
  15090. + AuDbg("del path %s\n", del->pathname);
  15091. +
  15092. + err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
  15093. + if (unlikely(err))
  15094. + AuErr("lookup failed %s (%d)\n", del->pathname, err);
  15095. +
  15096. + return err;
  15097. +}
  15098. +
  15099. +#if 0 /* reserved for future use */
  15100. +static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
  15101. + struct au_opt_del *del, substring_t args[])
  15102. +{
  15103. + int err;
  15104. + struct dentry *root;
  15105. +
  15106. + err = -EINVAL;
  15107. + root = sb->s_root;
  15108. + aufs_read_lock(root, AuLock_FLUSH);
  15109. + if (bindex < 0 || au_sbend(sb) < bindex) {
  15110. + AuErr("out of bounds, %d\n", bindex);
  15111. + goto out;
  15112. + }
  15113. +
  15114. + err = 0;
  15115. + del->h_path.dentry = dget(au_h_dptr(root, bindex));
  15116. + del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
  15117. +
  15118. + out:
  15119. + aufs_read_unlock(root, !AuLock_IR);
  15120. + return err;
  15121. +}
  15122. +#endif
  15123. +
  15124. +static int au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
  15125. +{
  15126. + int err;
  15127. + struct path path;
  15128. + char *p;
  15129. +
  15130. + err = -EINVAL;
  15131. + mod->path = args[0].from;
  15132. + p = strchr(mod->path, '=');
  15133. + if (unlikely(!p)) {
  15134. + AuErr("no permssion %s\n", args[0].from);
  15135. + goto out;
  15136. + }
  15137. +
  15138. + *p++ = 0;
  15139. + err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
  15140. + if (unlikely(err)) {
  15141. + AuErr("lookup failed %s (%d)\n", mod->path, err);
  15142. + goto out;
  15143. + }
  15144. +
  15145. + mod->perm = br_perm_val(p);
  15146. + AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
  15147. + mod->h_root = dget(path.dentry);
  15148. + path_put(&path);
  15149. +
  15150. + out:
  15151. + return err;
  15152. +}
  15153. +
  15154. +#if 0 /* reserved for future use */
  15155. +static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
  15156. + struct au_opt_mod *mod, substring_t args[])
  15157. +{
  15158. + int err;
  15159. + struct dentry *root;
  15160. +
  15161. + err = -EINVAL;
  15162. + root = sb->s_root;
  15163. + aufs_read_lock(root, AuLock_FLUSH);
  15164. + if (bindex < 0 || au_sbend(sb) < bindex) {
  15165. + AuErr("out of bounds, %d\n", bindex);
  15166. + goto out;
  15167. + }
  15168. +
  15169. + err = 0;
  15170. + mod->perm = br_perm_val(args[1].from);
  15171. + AuDbg("mod path %s, perm 0x%x, %s\n",
  15172. + mod->path, mod->perm, args[1].from);
  15173. + mod->h_root = dget(au_h_dptr(root, bindex));
  15174. +
  15175. + out:
  15176. + aufs_read_unlock(root, !AuLock_IR);
  15177. + return err;
  15178. +}
  15179. +#endif
  15180. +
  15181. +static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
  15182. + substring_t args[])
  15183. +{
  15184. + int err;
  15185. + struct file *file;
  15186. +
  15187. + file = au_xino_create(sb, args[0].from, /*silent*/0);
  15188. + err = PTR_ERR(file);
  15189. + if (IS_ERR(file))
  15190. + goto out;
  15191. +
  15192. + err = -EINVAL;
  15193. + if (unlikely(file->f_dentry->d_sb == sb)) {
  15194. + fput(file);
  15195. + AuErr("%s must be outside\n", args[0].from);
  15196. + goto out;
  15197. + }
  15198. +
  15199. + err = 0;
  15200. + xino->file = file;
  15201. + xino->path = args[0].from;
  15202. +
  15203. + out:
  15204. + return err;
  15205. +}
  15206. +
  15207. +static
  15208. +int au_opts_parse_xino_itrunc_path(struct super_block *sb,
  15209. + struct au_opt_xino_itrunc *xino_itrunc,
  15210. + substring_t args[])
  15211. +{
  15212. + int err;
  15213. + aufs_bindex_t bend, bindex;
  15214. + struct path path;
  15215. + struct dentry *root;
  15216. +
  15217. + err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
  15218. + if (unlikely(err)) {
  15219. + AuErr("lookup failed %s (%d)\n", args[0].from, err);
  15220. + goto out;
  15221. + }
  15222. +
  15223. + xino_itrunc->bindex = -1;
  15224. + root = sb->s_root;
  15225. + aufs_read_lock(root, AuLock_FLUSH);
  15226. + bend = au_sbend(sb);
  15227. + for (bindex = 0; bindex <= bend; bindex++) {
  15228. + if (au_h_dptr(root, bindex) == path.dentry) {
  15229. + xino_itrunc->bindex = bindex;
  15230. + break;
  15231. + }
  15232. + }
  15233. + aufs_read_unlock(root, !AuLock_IR);
  15234. + path_put(&path);
  15235. +
  15236. + if (unlikely(xino_itrunc->bindex < 0)) {
  15237. + AuErr("no such branch %s\n", args[0].from);
  15238. + err = -EINVAL;
  15239. + }
  15240. +
  15241. + out:
  15242. + return err;
  15243. +}
  15244. +
  15245. +/* called without aufs lock */
  15246. +int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
  15247. +{
  15248. + int err, n, token;
  15249. + aufs_bindex_t bindex;
  15250. + unsigned char skipped;
  15251. + struct dentry *root;
  15252. + struct au_opt *opt, *opt_tail;
  15253. + char *opt_str;
  15254. + /* reduce the stack space */
  15255. + union {
  15256. + struct au_opt_xino_itrunc *xino_itrunc;
  15257. + struct au_opt_wbr_create *create;
  15258. + } u;
  15259. + struct {
  15260. + substring_t args[MAX_OPT_ARGS];
  15261. + } *a;
  15262. +
  15263. + err = -ENOMEM;
  15264. + a = kmalloc(sizeof(*a), GFP_NOFS);
  15265. + if (unlikely(!a))
  15266. + goto out;
  15267. +
  15268. + root = sb->s_root;
  15269. + err = 0;
  15270. + bindex = 0;
  15271. + opt = opts->opt;
  15272. + opt_tail = opt + opts->max_opt - 1;
  15273. + opt->type = Opt_tail;
  15274. + while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
  15275. + err = -EINVAL;
  15276. + skipped = 0;
  15277. + token = match_token(opt_str, options, a->args);
  15278. + switch (token) {
  15279. + case Opt_br:
  15280. + err = 0;
  15281. + while (!err && (opt_str = strsep(&a->args[0].from, ":"))
  15282. + && *opt_str) {
  15283. + err = opt_add(opt, opt_str, opts->sb_flags,
  15284. + bindex++);
  15285. + if (unlikely(!err && ++opt > opt_tail)) {
  15286. + err = -E2BIG;
  15287. + break;
  15288. + }
  15289. + opt->type = Opt_tail;
  15290. + skipped = 1;
  15291. + }
  15292. + break;
  15293. + case Opt_add:
  15294. + if (unlikely(match_int(&a->args[0], &n))) {
  15295. + AuErr("bad integer in %s\n", opt_str);
  15296. + break;
  15297. + }
  15298. + bindex = n;
  15299. + err = opt_add(opt, a->args[1].from, opts->sb_flags,
  15300. + bindex);
  15301. + if (!err)
  15302. + opt->type = token;
  15303. + break;
  15304. + case Opt_append:
  15305. + err = opt_add(opt, a->args[0].from, opts->sb_flags,
  15306. + /*dummy bindex*/1);
  15307. + if (!err)
  15308. + opt->type = token;
  15309. + break;
  15310. + case Opt_prepend:
  15311. + err = opt_add(opt, a->args[0].from, opts->sb_flags,
  15312. + /*bindex*/0);
  15313. + if (!err)
  15314. + opt->type = token;
  15315. + break;
  15316. + case Opt_del:
  15317. + err = au_opts_parse_del(&opt->del, a->args);
  15318. + if (!err)
  15319. + opt->type = token;
  15320. + break;
  15321. +#if 0 /* reserved for future use */
  15322. + case Opt_idel:
  15323. + del->pathname = "(indexed)";
  15324. + if (unlikely(match_int(&args[0], &n))) {
  15325. + AuErr("bad integer in %s\n", opt_str);
  15326. + break;
  15327. + }
  15328. + err = au_opts_parse_idel(sb, n, &opt->del, a->args);
  15329. + if (!err)
  15330. + opt->type = token;
  15331. + break;
  15332. +#endif
  15333. + case Opt_mod:
  15334. + err = au_opts_parse_mod(&opt->mod, a->args);
  15335. + if (!err)
  15336. + opt->type = token;
  15337. + break;
  15338. +#ifdef IMOD /* reserved for future use */
  15339. + case Opt_imod:
  15340. + u.mod->path = "(indexed)";
  15341. + if (unlikely(match_int(&a->args[0], &n))) {
  15342. + AuErr("bad integer in %s\n", opt_str);
  15343. + break;
  15344. + }
  15345. + err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
  15346. + if (!err)
  15347. + opt->type = token;
  15348. + break;
  15349. +#endif
  15350. + case Opt_xino:
  15351. + err = au_opts_parse_xino(sb, &opt->xino, a->args);
  15352. + if (!err)
  15353. + opt->type = token;
  15354. + break;
  15355. +
  15356. + case Opt_trunc_xino_path:
  15357. + err = au_opts_parse_xino_itrunc_path
  15358. + (sb, &opt->xino_itrunc, a->args);
  15359. + if (!err)
  15360. + opt->type = token;
  15361. + break;
  15362. +
  15363. + case Opt_itrunc_xino:
  15364. + u.xino_itrunc = &opt->xino_itrunc;
  15365. + if (unlikely(match_int(&a->args[0], &n))) {
  15366. + AuErr("bad integer in %s\n", opt_str);
  15367. + break;
  15368. + }
  15369. + u.xino_itrunc->bindex = n;
  15370. + aufs_read_lock(root, AuLock_FLUSH);
  15371. + if (n < 0 || au_sbend(sb) < n) {
  15372. + AuErr("out of bounds, %d\n", n);
  15373. + aufs_read_unlock(root, !AuLock_IR);
  15374. + break;
  15375. + }
  15376. + aufs_read_unlock(root, !AuLock_IR);
  15377. + err = 0;
  15378. + opt->type = token;
  15379. + break;
  15380. +
  15381. + case Opt_dirwh:
  15382. + if (unlikely(match_int(&a->args[0], &opt->dirwh)))
  15383. + break;
  15384. + err = 0;
  15385. + opt->type = token;
  15386. + break;
  15387. +
  15388. + case Opt_rdcache:
  15389. + if (unlikely(match_int(&a->args[0], &opt->rdcache)))
  15390. + break;
  15391. + err = 0;
  15392. + opt->type = token;
  15393. + break;
  15394. + case Opt_rdblk:
  15395. + if (unlikely(match_int(&a->args[0], &n)
  15396. + || n <= 0
  15397. + || n > KMALLOC_MAX_SIZE)) {
  15398. + AuErr("bad integer in %s\n", opt_str);
  15399. + break;
  15400. + }
  15401. + if (unlikely(n < NAME_MAX)) {
  15402. + AuErr("rdblk must be larger than %d\n",
  15403. + NAME_MAX);
  15404. + break;
  15405. + }
  15406. + opt->rdblk = n;
  15407. + err = 0;
  15408. + opt->type = token;
  15409. + break;
  15410. + case Opt_rdhash:
  15411. + if (unlikely(match_int(&a->args[0], &n)
  15412. + || n <= 0
  15413. + || n * sizeof(struct hlist_head)
  15414. + > KMALLOC_MAX_SIZE)) {
  15415. + AuErr("bad integer in %s\n", opt_str);
  15416. + break;
  15417. + }
  15418. + opt->rdhash = n;
  15419. + err = 0;
  15420. + opt->type = token;
  15421. + break;
  15422. +
  15423. + case Opt_trunc_xino:
  15424. + case Opt_notrunc_xino:
  15425. + case Opt_noxino:
  15426. + case Opt_trunc_xib:
  15427. + case Opt_notrunc_xib:
  15428. + case Opt_shwh:
  15429. + case Opt_noshwh:
  15430. + case Opt_plink:
  15431. + case Opt_noplink:
  15432. + case Opt_list_plink:
  15433. + case Opt_diropq_a:
  15434. + case Opt_diropq_w:
  15435. + case Opt_warn_perm:
  15436. + case Opt_nowarn_perm:
  15437. + case Opt_refrof:
  15438. + case Opt_norefrof:
  15439. + case Opt_verbose:
  15440. + case Opt_noverbose:
  15441. + case Opt_sum:
  15442. + case Opt_nosum:
  15443. + case Opt_wsum:
  15444. + case Opt_rdblk_def:
  15445. + case Opt_rdhash_def:
  15446. + err = 0;
  15447. + opt->type = token;
  15448. + break;
  15449. +
  15450. + case Opt_udba:
  15451. + opt->udba = udba_val(a->args[0].from);
  15452. + if (opt->udba >= 0) {
  15453. + err = 0;
  15454. + opt->type = token;
  15455. + } else
  15456. + AuErr("wrong value, %s\n", opt_str);
  15457. + break;
  15458. +
  15459. + case Opt_wbr_create:
  15460. + u.create = &opt->wbr_create;
  15461. + u.create->wbr_create
  15462. + = au_wbr_create_val(a->args[0].from, u.create);
  15463. + if (u.create->wbr_create >= 0) {
  15464. + err = 0;
  15465. + opt->type = token;
  15466. + } else
  15467. + AuErr("wrong value, %s\n", opt_str);
  15468. + break;
  15469. + case Opt_wbr_copyup:
  15470. + opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
  15471. + if (opt->wbr_copyup >= 0) {
  15472. + err = 0;
  15473. + opt->type = token;
  15474. + } else
  15475. + AuErr("wrong value, %s\n", opt_str);
  15476. + break;
  15477. +
  15478. + case Opt_ignore:
  15479. + AuWarn("ignored %s\n", opt_str);
  15480. + /*FALLTHROUGH*/
  15481. + case Opt_ignore_silent:
  15482. + skipped = 1;
  15483. + err = 0;
  15484. + break;
  15485. + case Opt_err:
  15486. + AuErr("unknown option %s\n", opt_str);
  15487. + break;
  15488. + }
  15489. +
  15490. + if (!err && !skipped) {
  15491. + if (unlikely(++opt > opt_tail)) {
  15492. + err = -E2BIG;
  15493. + opt--;
  15494. + opt->type = Opt_tail;
  15495. + break;
  15496. + }
  15497. + opt->type = Opt_tail;
  15498. + }
  15499. + }
  15500. +
  15501. + kfree(a);
  15502. + dump_opts(opts);
  15503. + if (unlikely(err))
  15504. + au_opts_free(opts);
  15505. +
  15506. + out:
  15507. + return err;
  15508. +}
  15509. +
  15510. +static int au_opt_wbr_create(struct super_block *sb,
  15511. + struct au_opt_wbr_create *create)
  15512. +{
  15513. + int err;
  15514. + struct au_sbinfo *sbinfo;
  15515. +
  15516. + SiMustWriteLock(sb);
  15517. +
  15518. + err = 1; /* handled */
  15519. + sbinfo = au_sbi(sb);
  15520. + if (sbinfo->si_wbr_create_ops->fin) {
  15521. + err = sbinfo->si_wbr_create_ops->fin(sb);
  15522. + if (!err)
  15523. + err = 1;
  15524. + }
  15525. +
  15526. + sbinfo->si_wbr_create = create->wbr_create;
  15527. + sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
  15528. + switch (create->wbr_create) {
  15529. + case AuWbrCreate_MFSRRV:
  15530. + case AuWbrCreate_MFSRR:
  15531. + sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
  15532. + /*FALLTHROUGH*/
  15533. + case AuWbrCreate_MFS:
  15534. + case AuWbrCreate_MFSV:
  15535. + case AuWbrCreate_PMFS:
  15536. + case AuWbrCreate_PMFSV:
  15537. + sbinfo->si_wbr_mfs.mfs_expire = create->mfs_second * HZ;
  15538. + break;
  15539. + }
  15540. +
  15541. + if (sbinfo->si_wbr_create_ops->init)
  15542. + sbinfo->si_wbr_create_ops->init(sb); /* ignore */
  15543. +
  15544. + return err;
  15545. +}
  15546. +
  15547. +/*
  15548. + * returns,
  15549. + * plus: processed without an error
  15550. + * zero: unprocessed
  15551. + */
  15552. +static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
  15553. + struct au_opts *opts)
  15554. +{
  15555. + int err;
  15556. + struct au_sbinfo *sbinfo;
  15557. +
  15558. + SiMustWriteLock(sb);
  15559. +
  15560. + err = 1; /* handled */
  15561. + sbinfo = au_sbi(sb);
  15562. + switch (opt->type) {
  15563. + case Opt_udba:
  15564. + sbinfo->si_mntflags &= ~AuOptMask_UDBA;
  15565. + sbinfo->si_mntflags |= opt->udba;
  15566. + opts->given_udba |= opt->udba;
  15567. + break;
  15568. +
  15569. + case Opt_plink:
  15570. + au_opt_set(sbinfo->si_mntflags, PLINK);
  15571. + break;
  15572. + case Opt_noplink:
  15573. + if (au_opt_test(sbinfo->si_mntflags, PLINK))
  15574. + au_plink_put(sb);
  15575. + au_opt_clr(sbinfo->si_mntflags, PLINK);
  15576. + break;
  15577. + case Opt_list_plink:
  15578. + if (au_opt_test(sbinfo->si_mntflags, PLINK))
  15579. + au_plink_list(sb);
  15580. + break;
  15581. +
  15582. + case Opt_diropq_a:
  15583. + au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
  15584. + break;
  15585. + case Opt_diropq_w:
  15586. + au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
  15587. + break;
  15588. +
  15589. + case Opt_warn_perm:
  15590. + au_opt_set(sbinfo->si_mntflags, WARN_PERM);
  15591. + break;
  15592. + case Opt_nowarn_perm:
  15593. + au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
  15594. + break;
  15595. +
  15596. + case Opt_refrof:
  15597. + au_opt_set(sbinfo->si_mntflags, REFROF);
  15598. + break;
  15599. + case Opt_norefrof:
  15600. + au_opt_clr(sbinfo->si_mntflags, REFROF);
  15601. + break;
  15602. +
  15603. + case Opt_verbose:
  15604. + au_opt_set(sbinfo->si_mntflags, VERBOSE);
  15605. + break;
  15606. + case Opt_noverbose:
  15607. + au_opt_clr(sbinfo->si_mntflags, VERBOSE);
  15608. + break;
  15609. +
  15610. + case Opt_sum:
  15611. + au_opt_set(sbinfo->si_mntflags, SUM);
  15612. + break;
  15613. + case Opt_wsum:
  15614. + au_opt_clr(sbinfo->si_mntflags, SUM);
  15615. + au_opt_set(sbinfo->si_mntflags, SUM_W);
  15616. + case Opt_nosum:
  15617. + au_opt_clr(sbinfo->si_mntflags, SUM);
  15618. + au_opt_clr(sbinfo->si_mntflags, SUM_W);
  15619. + break;
  15620. +
  15621. + case Opt_wbr_create:
  15622. + err = au_opt_wbr_create(sb, &opt->wbr_create);
  15623. + break;
  15624. + case Opt_wbr_copyup:
  15625. + sbinfo->si_wbr_copyup = opt->wbr_copyup;
  15626. + sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
  15627. + break;
  15628. +
  15629. + case Opt_dirwh:
  15630. + sbinfo->si_dirwh = opt->dirwh;
  15631. + break;
  15632. +
  15633. + case Opt_rdcache:
  15634. + sbinfo->si_rdcache = opt->rdcache * HZ;
  15635. + break;
  15636. + case Opt_rdblk:
  15637. + sbinfo->si_rdblk = opt->rdblk;
  15638. + break;
  15639. + case Opt_rdblk_def:
  15640. + sbinfo->si_rdblk = AUFS_RDBLK_DEF;
  15641. + break;
  15642. + case Opt_rdhash:
  15643. + sbinfo->si_rdhash = opt->rdhash;
  15644. + break;
  15645. + case Opt_rdhash_def:
  15646. + sbinfo->si_rdhash = AUFS_RDHASH_DEF;
  15647. + break;
  15648. +
  15649. + case Opt_shwh:
  15650. + au_opt_set(sbinfo->si_mntflags, SHWH);
  15651. + break;
  15652. + case Opt_noshwh:
  15653. + au_opt_clr(sbinfo->si_mntflags, SHWH);
  15654. + break;
  15655. +
  15656. + case Opt_trunc_xino:
  15657. + au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
  15658. + break;
  15659. + case Opt_notrunc_xino:
  15660. + au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
  15661. + break;
  15662. +
  15663. + case Opt_trunc_xino_path:
  15664. + case Opt_itrunc_xino:
  15665. + err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
  15666. + if (!err)
  15667. + err = 1;
  15668. + break;
  15669. +
  15670. + case Opt_trunc_xib:
  15671. + au_fset_opts(opts->flags, TRUNC_XIB);
  15672. + break;
  15673. + case Opt_notrunc_xib:
  15674. + au_fclr_opts(opts->flags, TRUNC_XIB);
  15675. + break;
  15676. +
  15677. + default:
  15678. + err = 0;
  15679. + break;
  15680. + }
  15681. +
  15682. + return err;
  15683. +}
  15684. +
  15685. +/*
  15686. + * returns tri-state.
  15687. + * plus: processed without an error
  15688. + * zero: unprocessed
  15689. + * minus: error
  15690. + */
  15691. +static int au_opt_br(struct super_block *sb, struct au_opt *opt,
  15692. + struct au_opts *opts)
  15693. +{
  15694. + int err, do_refresh;
  15695. +
  15696. + err = 0;
  15697. + switch (opt->type) {
  15698. + case Opt_append:
  15699. + opt->add.bindex = au_sbend(sb) + 1;
  15700. + if (opt->add.bindex < 0)
  15701. + opt->add.bindex = 0;
  15702. + goto add;
  15703. + case Opt_prepend:
  15704. + opt->add.bindex = 0;
  15705. + add:
  15706. + case Opt_add:
  15707. + err = au_br_add(sb, &opt->add,
  15708. + au_ftest_opts(opts->flags, REMOUNT));
  15709. + if (!err) {
  15710. + err = 1;
  15711. + au_fset_opts(opts->flags, REFRESH_DIR);
  15712. + if (au_br_whable(opt->add.perm))
  15713. + au_fset_opts(opts->flags, REFRESH_NONDIR);
  15714. + }
  15715. + break;
  15716. +
  15717. + case Opt_del:
  15718. + case Opt_idel:
  15719. + err = au_br_del(sb, &opt->del,
  15720. + au_ftest_opts(opts->flags, REMOUNT));
  15721. + if (!err) {
  15722. + err = 1;
  15723. + au_fset_opts(opts->flags, TRUNC_XIB);
  15724. + au_fset_opts(opts->flags, REFRESH_DIR);
  15725. + au_fset_opts(opts->flags, REFRESH_NONDIR);
  15726. + }
  15727. + break;
  15728. +
  15729. + case Opt_mod:
  15730. + case Opt_imod:
  15731. + err = au_br_mod(sb, &opt->mod,
  15732. + au_ftest_opts(opts->flags, REMOUNT),
  15733. + &do_refresh);
  15734. + if (!err) {
  15735. + err = 1;
  15736. + if (do_refresh) {
  15737. + au_fset_opts(opts->flags, REFRESH_DIR);
  15738. + au_fset_opts(opts->flags, REFRESH_NONDIR);
  15739. + }
  15740. + }
  15741. + break;
  15742. + }
  15743. +
  15744. + return err;
  15745. +}
  15746. +
  15747. +static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
  15748. + struct au_opt_xino **opt_xino,
  15749. + struct au_opts *opts)
  15750. +{
  15751. + int err;
  15752. + aufs_bindex_t bend, bindex;
  15753. + struct dentry *root, *parent, *h_root;
  15754. +
  15755. + err = 0;
  15756. + switch (opt->type) {
  15757. + case Opt_xino:
  15758. + err = au_xino_set(sb, &opt->xino,
  15759. + !!au_ftest_opts(opts->flags, REMOUNT));
  15760. + if (unlikely(err))
  15761. + break;
  15762. +
  15763. + *opt_xino = &opt->xino;
  15764. + au_xino_brid_set(sb, -1);
  15765. +
  15766. + /* safe d_parent access */
  15767. + parent = opt->xino.file->f_dentry->d_parent;
  15768. + root = sb->s_root;
  15769. + bend = au_sbend(sb);
  15770. + for (bindex = 0; bindex <= bend; bindex++) {
  15771. + h_root = au_h_dptr(root, bindex);
  15772. + if (h_root == parent) {
  15773. + au_xino_brid_set(sb, au_sbr_id(sb, bindex));
  15774. + break;
  15775. + }
  15776. + }
  15777. + break;
  15778. +
  15779. + case Opt_noxino:
  15780. + au_xino_clr(sb);
  15781. + au_xino_brid_set(sb, -1);
  15782. + *opt_xino = (void *)-1;
  15783. + break;
  15784. + }
  15785. +
  15786. + return err;
  15787. +}
  15788. +
  15789. +int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
  15790. + unsigned int pending)
  15791. +{
  15792. + int err;
  15793. + aufs_bindex_t bindex, bend;
  15794. + unsigned char do_plink, skip, do_free;
  15795. + struct au_branch *br;
  15796. + struct au_wbr *wbr;
  15797. + struct dentry *root;
  15798. + struct inode *dir, *h_dir;
  15799. + struct au_sbinfo *sbinfo;
  15800. + struct au_hinode *hdir;
  15801. +
  15802. + SiMustAnyLock(sb);
  15803. +
  15804. + sbinfo = au_sbi(sb);
  15805. + AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
  15806. +
  15807. + if (!(sb_flags & MS_RDONLY)) {
  15808. + if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
  15809. + AuWarn("first branch should be rw\n");
  15810. + if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
  15811. + AuWarn("shwh should be used with ro\n");
  15812. + }
  15813. +
  15814. + if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HINOTIFY)
  15815. + && !au_opt_test(sbinfo->si_mntflags, XINO))
  15816. + AuWarn("udba=inotify requires xino\n");
  15817. +
  15818. + err = 0;
  15819. + root = sb->s_root;
  15820. + dir = sb->s_root->d_inode;
  15821. + do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
  15822. + bend = au_sbend(sb);
  15823. + for (bindex = 0; !err && bindex <= bend; bindex++) {
  15824. + skip = 0;
  15825. + h_dir = au_h_iptr(dir, bindex);
  15826. + br = au_sbr(sb, bindex);
  15827. + do_free = 0;
  15828. +
  15829. + wbr = br->br_wbr;
  15830. + if (wbr)
  15831. + wbr_wh_read_lock(wbr);
  15832. +
  15833. + switch (br->br_perm) {
  15834. + case AuBrPerm_RO:
  15835. + case AuBrPerm_ROWH:
  15836. + case AuBrPerm_RR:
  15837. + case AuBrPerm_RRWH:
  15838. + do_free = !!wbr;
  15839. + skip = (!wbr
  15840. + || (!wbr->wbr_whbase
  15841. + && !wbr->wbr_plink
  15842. + && !wbr->wbr_orph));
  15843. + break;
  15844. +
  15845. + case AuBrPerm_RWNoLinkWH:
  15846. + /* skip = (!br->br_whbase && !br->br_orph); */
  15847. + skip = (!wbr || !wbr->wbr_whbase);
  15848. + if (skip && wbr) {
  15849. + if (do_plink)
  15850. + skip = !!wbr->wbr_plink;
  15851. + else
  15852. + skip = !wbr->wbr_plink;
  15853. + }
  15854. + break;
  15855. +
  15856. + case AuBrPerm_RW:
  15857. + /* skip = (br->br_whbase && br->br_ohph); */
  15858. + skip = (wbr && wbr->wbr_whbase);
  15859. + if (skip) {
  15860. + if (do_plink)
  15861. + skip = !!wbr->wbr_plink;
  15862. + else
  15863. + skip = !wbr->wbr_plink;
  15864. + }
  15865. + break;
  15866. +
  15867. + default:
  15868. + BUG();
  15869. + }
  15870. + if (wbr)
  15871. + wbr_wh_read_unlock(wbr);
  15872. +
  15873. + if (skip)
  15874. + continue;
  15875. +
  15876. + hdir = au_hi(dir, bindex);
  15877. + au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT);
  15878. + if (wbr)
  15879. + wbr_wh_write_lock(wbr);
  15880. + err = au_wh_init(au_h_dptr(root, bindex), br, sb);
  15881. + if (wbr)
  15882. + wbr_wh_write_unlock(wbr);
  15883. + au_hin_imtx_unlock(hdir);
  15884. +
  15885. + if (!err && do_free) {
  15886. + kfree(wbr);
  15887. + br->br_wbr = NULL;
  15888. + }
  15889. + }
  15890. +
  15891. + return err;
  15892. +}
  15893. +
  15894. +int au_opts_mount(struct super_block *sb, struct au_opts *opts)
  15895. +{
  15896. + int err;
  15897. + unsigned int tmp;
  15898. + aufs_bindex_t bend;
  15899. + struct au_opt *opt;
  15900. + struct au_opt_xino *opt_xino, xino;
  15901. + struct au_sbinfo *sbinfo;
  15902. +
  15903. + SiMustWriteLock(sb);
  15904. +
  15905. + err = 0;
  15906. + opt_xino = NULL;
  15907. + opt = opts->opt;
  15908. + while (err >= 0 && opt->type != Opt_tail)
  15909. + err = au_opt_simple(sb, opt++, opts);
  15910. + if (err > 0)
  15911. + err = 0;
  15912. + else if (unlikely(err < 0))
  15913. + goto out;
  15914. +
  15915. + /* disable xino and udba temporary */
  15916. + sbinfo = au_sbi(sb);
  15917. + tmp = sbinfo->si_mntflags;
  15918. + au_opt_clr(sbinfo->si_mntflags, XINO);
  15919. + au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
  15920. +
  15921. + opt = opts->opt;
  15922. + while (err >= 0 && opt->type != Opt_tail)
  15923. + err = au_opt_br(sb, opt++, opts);
  15924. + if (err > 0)
  15925. + err = 0;
  15926. + else if (unlikely(err < 0))
  15927. + goto out;
  15928. +
  15929. + bend = au_sbend(sb);
  15930. + if (unlikely(bend < 0)) {
  15931. + err = -EINVAL;
  15932. + AuErr("no branches\n");
  15933. + goto out;
  15934. + }
  15935. +
  15936. + if (au_opt_test(tmp, XINO))
  15937. + au_opt_set(sbinfo->si_mntflags, XINO);
  15938. + opt = opts->opt;
  15939. + while (!err && opt->type != Opt_tail)
  15940. + err = au_opt_xino(sb, opt++, &opt_xino, opts);
  15941. + if (unlikely(err))
  15942. + goto out;
  15943. +
  15944. + err = au_opts_verify(sb, sb->s_flags, tmp);
  15945. + if (unlikely(err))
  15946. + goto out;
  15947. +
  15948. + /* restore xino */
  15949. + if (au_opt_test(tmp, XINO) && !opt_xino) {
  15950. + xino.file = au_xino_def(sb);
  15951. + err = PTR_ERR(xino.file);
  15952. + if (IS_ERR(xino.file))
  15953. + goto out;
  15954. +
  15955. + err = au_xino_set(sb, &xino, /*remount*/0);
  15956. + fput(xino.file);
  15957. + if (unlikely(err))
  15958. + goto out;
  15959. + }
  15960. +
  15961. + /* restore udba */
  15962. + sbinfo->si_mntflags &= ~AuOptMask_UDBA;
  15963. + sbinfo->si_mntflags |= (tmp & AuOptMask_UDBA);
  15964. + if (au_opt_test(tmp, UDBA_HINOTIFY)) {
  15965. + struct inode *dir = sb->s_root->d_inode;
  15966. + au_reset_hinotify(dir,
  15967. + au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
  15968. + }
  15969. +
  15970. + out:
  15971. + return err;
  15972. +}
  15973. +
  15974. +int au_opts_remount(struct super_block *sb, struct au_opts *opts)
  15975. +{
  15976. + int err, rerr;
  15977. + struct inode *dir;
  15978. + struct au_opt_xino *opt_xino;
  15979. + struct au_opt *opt;
  15980. + struct au_sbinfo *sbinfo;
  15981. +
  15982. + SiMustWriteLock(sb);
  15983. +
  15984. + dir = sb->s_root->d_inode;
  15985. + sbinfo = au_sbi(sb);
  15986. + err = 0;
  15987. + opt_xino = NULL;
  15988. + opt = opts->opt;
  15989. + while (err >= 0 && opt->type != Opt_tail) {
  15990. + err = au_opt_simple(sb, opt, opts);
  15991. + if (!err)
  15992. + err = au_opt_br(sb, opt, opts);
  15993. + if (!err)
  15994. + err = au_opt_xino(sb, opt, &opt_xino, opts);
  15995. + opt++;
  15996. + }
  15997. + if (err > 0)
  15998. + err = 0;
  15999. + AuTraceErr(err);
  16000. + /* go on even err */
  16001. +
  16002. + rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
  16003. + if (unlikely(rerr && !err))
  16004. + err = rerr;
  16005. +
  16006. + if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
  16007. + rerr = au_xib_trunc(sb);
  16008. + if (unlikely(rerr && !err))
  16009. + err = rerr;
  16010. + }
  16011. +
  16012. + /* will be handled by the caller */
  16013. + if (!au_ftest_opts(opts->flags, REFRESH_DIR)
  16014. + && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO)))
  16015. + au_fset_opts(opts->flags, REFRESH_DIR);
  16016. +
  16017. + AuDbg("status 0x%x\n", opts->flags);
  16018. + return err;
  16019. +}
  16020. +
  16021. +/* ---------------------------------------------------------------------- */
  16022. +
  16023. +unsigned int au_opt_udba(struct super_block *sb)
  16024. +{
  16025. + return au_mntflags(sb) & AuOptMask_UDBA;
  16026. +}
  16027. diff -Nur linux-2.6.31.4.orig/fs/aufs/opts.h linux-2.6.31.4/fs/aufs/opts.h
  16028. --- linux-2.6.31.4.orig/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100
  16029. +++ linux-2.6.31.4/fs/aufs/opts.h 2009-10-18 11:26:01.000000000 +0200
  16030. @@ -0,0 +1,196 @@
  16031. +/*
  16032. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  16033. + *
  16034. + * This program, aufs is free software; you can redistribute it and/or modify
  16035. + * it under the terms of the GNU General Public License as published by
  16036. + * the Free Software Foundation; either version 2 of the License, or
  16037. + * (at your option) any later version.
  16038. + *
  16039. + * This program is distributed in the hope that it will be useful,
  16040. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16041. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16042. + * GNU General Public License for more details.
  16043. + *
  16044. + * You should have received a copy of the GNU General Public License
  16045. + * along with this program; if not, write to the Free Software
  16046. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16047. + */
  16048. +
  16049. +/*
  16050. + * mount options/flags
  16051. + */
  16052. +
  16053. +#ifndef __AUFS_OPTS_H__
  16054. +#define __AUFS_OPTS_H__
  16055. +
  16056. +#ifdef __KERNEL__
  16057. +
  16058. +#include <linux/path.h>
  16059. +#include <linux/aufs_type.h>
  16060. +
  16061. +struct file;
  16062. +struct super_block;
  16063. +
  16064. +/* ---------------------------------------------------------------------- */
  16065. +
  16066. +/* mount flags */
  16067. +#define AuOpt_XINO 1 /* external inode number bitmap
  16068. + and translation table */
  16069. +#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */
  16070. +#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */
  16071. +#define AuOpt_UDBA_REVAL (1 << 3)
  16072. +#define AuOpt_UDBA_HINOTIFY (1 << 4)
  16073. +#define AuOpt_SHWH (1 << 5) /* show whiteout */
  16074. +#define AuOpt_PLINK (1 << 6) /* pseudo-link */
  16075. +#define AuOpt_DIRPERM1 (1 << 7) /* unimplemented */
  16076. +#define AuOpt_REFROF (1 << 8) /* unimplemented */
  16077. +#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */
  16078. +#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
  16079. +#define AuOpt_SUM_W (1 << 11) /* unimplemented */
  16080. +#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */
  16081. +#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */
  16082. +
  16083. +#ifndef CONFIG_AUFS_HINOTIFY
  16084. +#undef AuOpt_UDBA_HINOTIFY
  16085. +#define AuOpt_UDBA_HINOTIFY 0
  16086. +#endif
  16087. +#ifndef CONFIG_AUFS_SHWH
  16088. +#undef AuOpt_SHWH
  16089. +#define AuOpt_SHWH 0
  16090. +#endif
  16091. +
  16092. +#define AuOpt_Def (AuOpt_XINO \
  16093. + | AuOpt_UDBA_REVAL \
  16094. + | AuOpt_PLINK \
  16095. + /* | AuOpt_DIRPERM1 */ \
  16096. + | AuOpt_WARN_PERM)
  16097. +#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
  16098. + | AuOpt_UDBA_REVAL \
  16099. + | AuOpt_UDBA_HINOTIFY)
  16100. +
  16101. +#define au_opt_test(flags, name) (flags & AuOpt_##name)
  16102. +#define au_opt_set(flags, name) do { \
  16103. + BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
  16104. + ((flags) |= AuOpt_##name); \
  16105. +} while (0)
  16106. +#define au_opt_set_udba(flags, name) do { \
  16107. + (flags) &= ~AuOptMask_UDBA; \
  16108. + ((flags) |= AuOpt_##name); \
  16109. +} while (0)
  16110. +#define au_opt_clr(flags, name) { ((flags) &= ~AuOpt_##name); }
  16111. +
  16112. +/* ---------------------------------------------------------------------- */
  16113. +
  16114. +/* policies to select one among multiple writable branches */
  16115. +enum {
  16116. + AuWbrCreate_TDP, /* top down parent */
  16117. + AuWbrCreate_RR, /* round robin */
  16118. + AuWbrCreate_MFS, /* most free space */
  16119. + AuWbrCreate_MFSV, /* mfs with seconds */
  16120. + AuWbrCreate_MFSRR, /* mfs then rr */
  16121. + AuWbrCreate_MFSRRV, /* mfs then rr with seconds */
  16122. + AuWbrCreate_PMFS, /* parent and mfs */
  16123. + AuWbrCreate_PMFSV, /* parent and mfs with seconds */
  16124. +
  16125. + AuWbrCreate_Def = AuWbrCreate_TDP
  16126. +};
  16127. +
  16128. +enum {
  16129. + AuWbrCopyup_TDP, /* top down parent */
  16130. + AuWbrCopyup_BUP, /* bottom up parent */
  16131. + AuWbrCopyup_BU, /* bottom up */
  16132. +
  16133. + AuWbrCopyup_Def = AuWbrCopyup_TDP
  16134. +};
  16135. +
  16136. +/* ---------------------------------------------------------------------- */
  16137. +
  16138. +struct au_opt_add {
  16139. + aufs_bindex_t bindex;
  16140. + char *pathname;
  16141. + int perm;
  16142. + struct path path;
  16143. +};
  16144. +
  16145. +struct au_opt_del {
  16146. + char *pathname;
  16147. + struct path h_path;
  16148. +};
  16149. +
  16150. +struct au_opt_mod {
  16151. + char *path;
  16152. + int perm;
  16153. + struct dentry *h_root;
  16154. +};
  16155. +
  16156. +struct au_opt_xino {
  16157. + char *path;
  16158. + struct file *file;
  16159. +};
  16160. +
  16161. +struct au_opt_xino_itrunc {
  16162. + aufs_bindex_t bindex;
  16163. +};
  16164. +
  16165. +struct au_opt_wbr_create {
  16166. + int wbr_create;
  16167. + int mfs_second;
  16168. + unsigned long long mfsrr_watermark;
  16169. +};
  16170. +
  16171. +struct au_opt {
  16172. + int type;
  16173. + union {
  16174. + struct au_opt_xino xino;
  16175. + struct au_opt_xino_itrunc xino_itrunc;
  16176. + struct au_opt_add add;
  16177. + struct au_opt_del del;
  16178. + struct au_opt_mod mod;
  16179. + int dirwh;
  16180. + int rdcache;
  16181. + unsigned int rdblk;
  16182. + unsigned int rdhash;
  16183. + int udba;
  16184. + struct au_opt_wbr_create wbr_create;
  16185. + int wbr_copyup;
  16186. + };
  16187. +};
  16188. +
  16189. +/* opts flags */
  16190. +#define AuOpts_REMOUNT 1
  16191. +#define AuOpts_REFRESH_DIR (1 << 1)
  16192. +#define AuOpts_REFRESH_NONDIR (1 << 2)
  16193. +#define AuOpts_TRUNC_XIB (1 << 3)
  16194. +#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
  16195. +#define au_fset_opts(flags, name) { (flags) |= AuOpts_##name; }
  16196. +#define au_fclr_opts(flags, name) { (flags) &= ~AuOpts_##name; }
  16197. +
  16198. +struct au_opts {
  16199. + struct au_opt *opt;
  16200. + int max_opt;
  16201. +
  16202. + unsigned int given_udba;
  16203. + unsigned int flags;
  16204. + unsigned long sb_flags;
  16205. +};
  16206. +
  16207. +/* ---------------------------------------------------------------------- */
  16208. +
  16209. +const char *au_optstr_br_perm(int brperm);
  16210. +const char *au_optstr_udba(int udba);
  16211. +const char *au_optstr_wbr_copyup(int wbr_copyup);
  16212. +const char *au_optstr_wbr_create(int wbr_create);
  16213. +
  16214. +void au_opts_free(struct au_opts *opts);
  16215. +int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
  16216. +int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
  16217. + unsigned int pending);
  16218. +int au_opts_mount(struct super_block *sb, struct au_opts *opts);
  16219. +int au_opts_remount(struct super_block *sb, struct au_opts *opts);
  16220. +
  16221. +unsigned int au_opt_udba(struct super_block *sb);
  16222. +
  16223. +/* ---------------------------------------------------------------------- */
  16224. +
  16225. +#endif /* __KERNEL__ */
  16226. +#endif /* __AUFS_OPTS_H__ */
  16227. diff -Nur linux-2.6.31.4.orig/fs/aufs/plink.c linux-2.6.31.4/fs/aufs/plink.c
  16228. --- linux-2.6.31.4.orig/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100
  16229. +++ linux-2.6.31.4/fs/aufs/plink.c 2009-10-18 11:26:01.000000000 +0200
  16230. @@ -0,0 +1,354 @@
  16231. +/*
  16232. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  16233. + *
  16234. + * This program, aufs is free software; you can redistribute it and/or modify
  16235. + * it under the terms of the GNU General Public License as published by
  16236. + * the Free Software Foundation; either version 2 of the License, or
  16237. + * (at your option) any later version.
  16238. + *
  16239. + * This program is distributed in the hope that it will be useful,
  16240. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16241. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16242. + * GNU General Public License for more details.
  16243. + *
  16244. + * You should have received a copy of the GNU General Public License
  16245. + * along with this program; if not, write to the Free Software
  16246. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16247. + */
  16248. +
  16249. +/*
  16250. + * pseudo-link
  16251. + */
  16252. +
  16253. +#include "aufs.h"
  16254. +
  16255. +/*
  16256. + * during a user process maintains the pseudo-links,
  16257. + * prohibit adding a new plink and branch manipulation.
  16258. + */
  16259. +void au_plink_block_maintain(struct super_block *sb)
  16260. +{
  16261. + struct au_sbinfo *sbi = au_sbi(sb);
  16262. +
  16263. + SiMustAnyLock(sb);
  16264. +
  16265. + /* gave up wake_up_bit() */
  16266. + wait_event(sbi->si_plink_wq, !au_ftest_si(sbi, MAINTAIN_PLINK));
  16267. +}
  16268. +
  16269. +/* ---------------------------------------------------------------------- */
  16270. +
  16271. +struct pseudo_link {
  16272. + struct list_head list;
  16273. + struct inode *inode;
  16274. +};
  16275. +
  16276. +#ifdef CONFIG_AUFS_DEBUG
  16277. +void au_plink_list(struct super_block *sb)
  16278. +{
  16279. + struct au_sbinfo *sbinfo;
  16280. + struct list_head *plink_list;
  16281. + struct pseudo_link *plink;
  16282. +
  16283. + SiMustAnyLock(sb);
  16284. +
  16285. + sbinfo = au_sbi(sb);
  16286. + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
  16287. +
  16288. + plink_list = &sbinfo->si_plink.head;
  16289. + spin_lock(&sbinfo->si_plink.spin);
  16290. + list_for_each_entry(plink, plink_list, list)
  16291. + AuDbg("%lu\n", plink->inode->i_ino);
  16292. + spin_unlock(&sbinfo->si_plink.spin);
  16293. +}
  16294. +#endif
  16295. +
  16296. +/* is the inode pseudo-linked? */
  16297. +int au_plink_test(struct inode *inode)
  16298. +{
  16299. + int found;
  16300. + struct au_sbinfo *sbinfo;
  16301. + struct list_head *plink_list;
  16302. + struct pseudo_link *plink;
  16303. +
  16304. + sbinfo = au_sbi(inode->i_sb);
  16305. + AuRwMustAnyLock(&sbinfo->si_rwsem);
  16306. + AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
  16307. +
  16308. + found = 0;
  16309. + plink_list = &sbinfo->si_plink.head;
  16310. + spin_lock(&sbinfo->si_plink.spin);
  16311. + list_for_each_entry(plink, plink_list, list)
  16312. + if (plink->inode == inode) {
  16313. + found = 1;
  16314. + break;
  16315. + }
  16316. + spin_unlock(&sbinfo->si_plink.spin);
  16317. + return found;
  16318. +}
  16319. +
  16320. +/* ---------------------------------------------------------------------- */
  16321. +
  16322. +/*
  16323. + * generate a name for plink.
  16324. + * the file will be stored under AUFS_WH_PLINKDIR.
  16325. + */
  16326. +/* 20 is max digits length of ulong 64 */
  16327. +#define PLINK_NAME_LEN ((20 + 1) * 2)
  16328. +
  16329. +static int plink_name(char *name, int len, struct inode *inode,
  16330. + aufs_bindex_t bindex)
  16331. +{
  16332. + int rlen;
  16333. + struct inode *h_inode;
  16334. +
  16335. + h_inode = au_h_iptr(inode, bindex);
  16336. + rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
  16337. + return rlen;
  16338. +}
  16339. +
  16340. +/* lookup the plink-ed @inode under the branch at @bindex */
  16341. +struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
  16342. +{
  16343. + struct dentry *h_dentry, *h_parent;
  16344. + struct au_branch *br;
  16345. + struct inode *h_dir;
  16346. + char a[PLINK_NAME_LEN];
  16347. + struct qstr tgtname = {
  16348. + .name = a
  16349. + };
  16350. +
  16351. + br = au_sbr(inode->i_sb, bindex);
  16352. + h_parent = br->br_wbr->wbr_plink;
  16353. + h_dir = h_parent->d_inode;
  16354. + tgtname.len = plink_name(a, sizeof(a), inode, bindex);
  16355. +
  16356. + /* always superio. */
  16357. + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
  16358. + h_dentry = au_sio_lkup_one(&tgtname, h_parent, br);
  16359. + mutex_unlock(&h_dir->i_mutex);
  16360. + return h_dentry;
  16361. +}
  16362. +
  16363. +/* create a pseudo-link */
  16364. +static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
  16365. + struct dentry *h_dentry, struct au_branch *br)
  16366. +{
  16367. + int err;
  16368. + struct path h_path = {
  16369. + .mnt = br->br_mnt
  16370. + };
  16371. + struct inode *h_dir;
  16372. +
  16373. + h_dir = h_parent->d_inode;
  16374. + again:
  16375. + h_path.dentry = au_lkup_one(tgt, h_parent, br, /*nd*/NULL);
  16376. + err = PTR_ERR(h_path.dentry);
  16377. + if (IS_ERR(h_path.dentry))
  16378. + goto out;
  16379. +
  16380. + err = 0;
  16381. + /* wh.plink dir is not monitored */
  16382. + if (h_path.dentry->d_inode
  16383. + && h_path.dentry->d_inode != h_dentry->d_inode) {
  16384. + err = vfsub_unlink(h_dir, &h_path, /*force*/0);
  16385. + dput(h_path.dentry);
  16386. + h_path.dentry = NULL;
  16387. + if (!err)
  16388. + goto again;
  16389. + }
  16390. + if (!err && !h_path.dentry->d_inode)
  16391. + err = vfsub_link(h_dentry, h_dir, &h_path);
  16392. + dput(h_path.dentry);
  16393. +
  16394. + out:
  16395. + return err;
  16396. +}
  16397. +
  16398. +struct do_whplink_args {
  16399. + int *errp;
  16400. + struct qstr *tgt;
  16401. + struct dentry *h_parent;
  16402. + struct dentry *h_dentry;
  16403. + struct au_branch *br;
  16404. +};
  16405. +
  16406. +static void call_do_whplink(void *args)
  16407. +{
  16408. + struct do_whplink_args *a = args;
  16409. + *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
  16410. +}
  16411. +
  16412. +static int whplink(struct dentry *h_dentry, struct inode *inode,
  16413. + aufs_bindex_t bindex, struct au_branch *br)
  16414. +{
  16415. + int err, wkq_err;
  16416. + struct au_wbr *wbr;
  16417. + struct dentry *h_parent;
  16418. + struct inode *h_dir;
  16419. + char a[PLINK_NAME_LEN];
  16420. + struct qstr tgtname = {
  16421. + .name = a
  16422. + };
  16423. +
  16424. + wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
  16425. + h_parent = wbr->wbr_plink;
  16426. + h_dir = h_parent->d_inode;
  16427. + tgtname.len = plink_name(a, sizeof(a), inode, bindex);
  16428. +
  16429. + /* always superio. */
  16430. + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
  16431. + if (!au_test_wkq(current)) {
  16432. + struct do_whplink_args args = {
  16433. + .errp = &err,
  16434. + .tgt = &tgtname,
  16435. + .h_parent = h_parent,
  16436. + .h_dentry = h_dentry,
  16437. + .br = br
  16438. + };
  16439. + wkq_err = au_wkq_wait(call_do_whplink, &args);
  16440. + if (unlikely(wkq_err))
  16441. + err = wkq_err;
  16442. + } else
  16443. + err = do_whplink(&tgtname, h_parent, h_dentry, br);
  16444. + mutex_unlock(&h_dir->i_mutex);
  16445. +
  16446. + return err;
  16447. +}
  16448. +
  16449. +/* free a single plink */
  16450. +static void do_put_plink(struct pseudo_link *plink, int do_del)
  16451. +{
  16452. + iput(plink->inode);
  16453. + if (do_del)
  16454. + list_del(&plink->list);
  16455. + kfree(plink);
  16456. +}
  16457. +
  16458. +/*
  16459. + * create a new pseudo-link for @h_dentry on @bindex.
  16460. + * the linked inode is held in aufs @inode.
  16461. + */
  16462. +void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
  16463. + struct dentry *h_dentry)
  16464. +{
  16465. + struct super_block *sb;
  16466. + struct au_sbinfo *sbinfo;
  16467. + struct list_head *plink_list;
  16468. + struct pseudo_link *plink;
  16469. + int found, err, cnt;
  16470. +
  16471. + sb = inode->i_sb;
  16472. + sbinfo = au_sbi(sb);
  16473. + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
  16474. +
  16475. + err = 0;
  16476. + cnt = 0;
  16477. + found = 0;
  16478. + plink_list = &sbinfo->si_plink.head;
  16479. + spin_lock(&sbinfo->si_plink.spin);
  16480. + list_for_each_entry(plink, plink_list, list) {
  16481. + cnt++;
  16482. + if (plink->inode == inode) {
  16483. + found = 1;
  16484. + break;
  16485. + }
  16486. + }
  16487. + if (found) {
  16488. + spin_unlock(&sbinfo->si_plink.spin);
  16489. + return;
  16490. + }
  16491. +
  16492. + plink = NULL;
  16493. + if (!found) {
  16494. + plink = kmalloc(sizeof(*plink), GFP_ATOMIC);
  16495. + if (plink) {
  16496. + plink->inode = au_igrab(inode);
  16497. + list_add(&plink->list, plink_list);
  16498. + cnt++;
  16499. + } else
  16500. + err = -ENOMEM;
  16501. + }
  16502. + spin_unlock(&sbinfo->si_plink.spin);
  16503. +
  16504. + if (!err) {
  16505. + au_plink_block_maintain(sb);
  16506. + err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
  16507. + }
  16508. +
  16509. + if (unlikely(cnt > AUFS_PLINK_WARN))
  16510. + AuWarn1("unexpectedly many pseudo links, %d\n", cnt);
  16511. + if (unlikely(err)) {
  16512. + AuWarn("err %d, damaged pseudo link.\n", err);
  16513. + if (!found && plink)
  16514. + do_put_plink(plink, /*do_del*/1);
  16515. + }
  16516. +}
  16517. +
  16518. +/* free all plinks */
  16519. +void au_plink_put(struct super_block *sb)
  16520. +{
  16521. + struct au_sbinfo *sbinfo;
  16522. + struct list_head *plink_list;
  16523. + struct pseudo_link *plink, *tmp;
  16524. +
  16525. + SiMustWriteLock(sb);
  16526. +
  16527. + sbinfo = au_sbi(sb);
  16528. + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
  16529. +
  16530. + plink_list = &sbinfo->si_plink.head;
  16531. + /* no spin_lock since sbinfo is write-locked */
  16532. + list_for_each_entry_safe(plink, tmp, plink_list, list)
  16533. + do_put_plink(plink, 0);
  16534. + INIT_LIST_HEAD(plink_list);
  16535. +}
  16536. +
  16537. +/* free the plinks on a branch specified by @br_id */
  16538. +void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
  16539. +{
  16540. + struct au_sbinfo *sbinfo;
  16541. + struct list_head *plink_list;
  16542. + struct pseudo_link *plink, *tmp;
  16543. + struct inode *inode;
  16544. + aufs_bindex_t bstart, bend, bindex;
  16545. + unsigned char do_put;
  16546. +
  16547. + SiMustWriteLock(sb);
  16548. +
  16549. + sbinfo = au_sbi(sb);
  16550. + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
  16551. +
  16552. + plink_list = &sbinfo->si_plink.head;
  16553. + /* no spin_lock since sbinfo is write-locked */
  16554. + list_for_each_entry_safe(plink, tmp, plink_list, list) {
  16555. + do_put = 0;
  16556. + inode = au_igrab(plink->inode);
  16557. + ii_write_lock_child(inode);
  16558. + bstart = au_ibstart(inode);
  16559. + bend = au_ibend(inode);
  16560. + if (bstart >= 0) {
  16561. + for (bindex = bstart; bindex <= bend; bindex++) {
  16562. + if (!au_h_iptr(inode, bindex)
  16563. + || au_ii_br_id(inode, bindex) != br_id)
  16564. + continue;
  16565. + au_set_h_iptr(inode, bindex, NULL, 0);
  16566. + do_put = 1;
  16567. + break;
  16568. + }
  16569. + } else
  16570. + do_put_plink(plink, 1);
  16571. +
  16572. + if (do_put) {
  16573. + for (bindex = bstart; bindex <= bend; bindex++)
  16574. + if (au_h_iptr(inode, bindex)) {
  16575. + do_put = 0;
  16576. + break;
  16577. + }
  16578. + if (do_put)
  16579. + do_put_plink(plink, 1);
  16580. + }
  16581. + ii_write_unlock(inode);
  16582. + iput(inode);
  16583. + }
  16584. +}
  16585. diff -Nur linux-2.6.31.4.orig/fs/aufs/poll.c linux-2.6.31.4/fs/aufs/poll.c
  16586. --- linux-2.6.31.4.orig/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100
  16587. +++ linux-2.6.31.4/fs/aufs/poll.c 2009-10-18 11:26:01.000000000 +0200
  16588. @@ -0,0 +1,56 @@
  16589. +/*
  16590. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  16591. + *
  16592. + * This program, aufs is free software; you can redistribute it and/or modify
  16593. + * it under the terms of the GNU General Public License as published by
  16594. + * the Free Software Foundation; either version 2 of the License, or
  16595. + * (at your option) any later version.
  16596. + *
  16597. + * This program is distributed in the hope that it will be useful,
  16598. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16599. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16600. + * GNU General Public License for more details.
  16601. + *
  16602. + * You should have received a copy of the GNU General Public License
  16603. + * along with this program; if not, write to the Free Software
  16604. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16605. + */
  16606. +
  16607. +/*
  16608. + * poll operation
  16609. + * There is only one filesystem which implements ->poll operation, currently.
  16610. + */
  16611. +
  16612. +#include "aufs.h"
  16613. +
  16614. +unsigned int aufs_poll(struct file *file, poll_table *wait)
  16615. +{
  16616. + unsigned int mask;
  16617. + int err;
  16618. + struct file *h_file;
  16619. + struct dentry *dentry;
  16620. + struct super_block *sb;
  16621. +
  16622. + /* We should pretend an error happened. */
  16623. + mask = POLLERR /* | POLLIN | POLLOUT */;
  16624. + dentry = file->f_dentry;
  16625. + sb = dentry->d_sb;
  16626. + si_read_lock(sb, AuLock_FLUSH);
  16627. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
  16628. + if (unlikely(err))
  16629. + goto out;
  16630. +
  16631. + /* it is not an error if h_file has no operation */
  16632. + mask = DEFAULT_POLLMASK;
  16633. + h_file = au_h_fptr(file, au_fbstart(file));
  16634. + if (h_file->f_op && h_file->f_op->poll)
  16635. + mask = h_file->f_op->poll(h_file, wait);
  16636. +
  16637. + di_read_unlock(dentry, AuLock_IR);
  16638. + fi_read_unlock(file);
  16639. +
  16640. + out:
  16641. + si_read_unlock(sb);
  16642. + AuTraceErr((int)mask);
  16643. + return mask;
  16644. +}
  16645. diff -Nur linux-2.6.31.4.orig/fs/aufs/rwsem.h linux-2.6.31.4/fs/aufs/rwsem.h
  16646. --- linux-2.6.31.4.orig/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100
  16647. +++ linux-2.6.31.4/fs/aufs/rwsem.h 2009-10-18 11:26:01.000000000 +0200
  16648. @@ -0,0 +1,186 @@
  16649. +/*
  16650. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  16651. + *
  16652. + * This program, aufs is free software; you can redistribute it and/or modify
  16653. + * it under the terms of the GNU General Public License as published by
  16654. + * the Free Software Foundation; either version 2 of the License, or
  16655. + * (at your option) any later version.
  16656. + *
  16657. + * This program is distributed in the hope that it will be useful,
  16658. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16659. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16660. + * GNU General Public License for more details.
  16661. + *
  16662. + * You should have received a copy of the GNU General Public License
  16663. + * along with this program; if not, write to the Free Software
  16664. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16665. + */
  16666. +
  16667. +/*
  16668. + * simple read-write semaphore wrappers
  16669. + */
  16670. +
  16671. +#ifndef __AUFS_RWSEM_H__
  16672. +#define __AUFS_RWSEM_H__
  16673. +
  16674. +#ifdef __KERNEL__
  16675. +
  16676. +#include <linux/rwsem.h>
  16677. +
  16678. +struct au_rwsem {
  16679. + struct rw_semaphore rwsem;
  16680. +#ifdef CONFIG_AUFS_DEBUG
  16681. + /* just for debugging, not almighty counter */
  16682. + atomic_t rcnt, wcnt;
  16683. +#endif
  16684. +};
  16685. +
  16686. +#ifdef CONFIG_AUFS_DEBUG
  16687. +#define AuDbgCntInit(rw) do { \
  16688. + atomic_set(&(rw)->rcnt, 0); \
  16689. + atomic_set(&(rw)->wcnt, 0); \
  16690. + smp_mb(); /* atomic set */ \
  16691. +} while (0)
  16692. +
  16693. +#define AuDbgRcntInc(rw) atomic_inc_return(&(rw)->rcnt)
  16694. +#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0)
  16695. +#define AuDbgWcntInc(rw) WARN_ON(atomic_inc_return(&(rw)->wcnt) > 1)
  16696. +#define AuDbgWcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->wcnt) < 0)
  16697. +#else
  16698. +#define AuDbgCntInit(rw) do {} while (0)
  16699. +#define AuDbgRcntInc(rw) do {} while (0)
  16700. +#define AuDbgRcntDec(rw) do {} while (0)
  16701. +#define AuDbgWcntInc(rw) do {} while (0)
  16702. +#define AuDbgWcntDec(rw) do {} while (0)
  16703. +#endif /* CONFIG_AUFS_DEBUG */
  16704. +
  16705. +/* to debug easier, do not make them inlined functions */
  16706. +#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->rwsem.wait_list))
  16707. +/* rwsem_is_locked() is unusable */
  16708. +#define AuRwMustReadLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0)
  16709. +#define AuRwMustWriteLock(rw) AuDebugOn(atomic_read(&(rw)->wcnt) <= 0)
  16710. +#define AuRwMustAnyLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0 \
  16711. + && atomic_read(&(rw)->wcnt) <= 0)
  16712. +#define AuRwDestroy(rw) AuDebugOn(atomic_read(&(rw)->rcnt) \
  16713. + || atomic_read(&(rw)->wcnt))
  16714. +
  16715. +static inline void au_rw_init(struct au_rwsem *rw)
  16716. +{
  16717. + AuDbgCntInit(rw);
  16718. + init_rwsem(&rw->rwsem);
  16719. +}
  16720. +
  16721. +static inline void au_rw_init_wlock(struct au_rwsem *rw)
  16722. +{
  16723. + au_rw_init(rw);
  16724. + down_write(&rw->rwsem);
  16725. + AuDbgWcntInc(rw);
  16726. +}
  16727. +
  16728. +static inline void au_rw_init_wlock_nested(struct au_rwsem *rw,
  16729. + unsigned int lsc)
  16730. +{
  16731. + au_rw_init(rw);
  16732. + down_write_nested(&rw->rwsem, lsc);
  16733. + AuDbgWcntInc(rw);
  16734. +}
  16735. +
  16736. +static inline void au_rw_read_lock(struct au_rwsem *rw)
  16737. +{
  16738. + down_read(&rw->rwsem);
  16739. + AuDbgRcntInc(rw);
  16740. +}
  16741. +
  16742. +static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc)
  16743. +{
  16744. + down_read_nested(&rw->rwsem, lsc);
  16745. + AuDbgRcntInc(rw);
  16746. +}
  16747. +
  16748. +static inline void au_rw_read_unlock(struct au_rwsem *rw)
  16749. +{
  16750. + AuRwMustReadLock(rw);
  16751. + AuDbgRcntDec(rw);
  16752. + up_read(&rw->rwsem);
  16753. +}
  16754. +
  16755. +static inline void au_rw_dgrade_lock(struct au_rwsem *rw)
  16756. +{
  16757. + AuRwMustWriteLock(rw);
  16758. + AuDbgRcntInc(rw);
  16759. + AuDbgWcntDec(rw);
  16760. + downgrade_write(&rw->rwsem);
  16761. +}
  16762. +
  16763. +static inline void au_rw_write_lock(struct au_rwsem *rw)
  16764. +{
  16765. + down_write(&rw->rwsem);
  16766. + AuDbgWcntInc(rw);
  16767. +}
  16768. +
  16769. +static inline void au_rw_write_lock_nested(struct au_rwsem *rw,
  16770. + unsigned int lsc)
  16771. +{
  16772. + down_write_nested(&rw->rwsem, lsc);
  16773. + AuDbgWcntInc(rw);
  16774. +}
  16775. +
  16776. +static inline void au_rw_write_unlock(struct au_rwsem *rw)
  16777. +{
  16778. + AuRwMustWriteLock(rw);
  16779. + AuDbgWcntDec(rw);
  16780. + up_write(&rw->rwsem);
  16781. +}
  16782. +
  16783. +/* why is not _nested version defined */
  16784. +static inline int au_rw_read_trylock(struct au_rwsem *rw)
  16785. +{
  16786. + int ret = down_read_trylock(&rw->rwsem);
  16787. + if (ret)
  16788. + AuDbgRcntInc(rw);
  16789. + return ret;
  16790. +}
  16791. +
  16792. +static inline int au_rw_write_trylock(struct au_rwsem *rw)
  16793. +{
  16794. + int ret = down_write_trylock(&rw->rwsem);
  16795. + if (ret)
  16796. + AuDbgWcntInc(rw);
  16797. + return ret;
  16798. +}
  16799. +
  16800. +#undef AuDbgCntInit
  16801. +#undef AuDbgRcntInc
  16802. +#undef AuDbgRcntDec
  16803. +#undef AuDbgWcntInc
  16804. +#undef AuDbgWcntDec
  16805. +
  16806. +#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
  16807. +static inline void prefix##_read_lock(param) \
  16808. +{ au_rw_read_lock(rwsem); } \
  16809. +static inline void prefix##_write_lock(param) \
  16810. +{ au_rw_write_lock(rwsem); } \
  16811. +static inline int prefix##_read_trylock(param) \
  16812. +{ return au_rw_read_trylock(rwsem); } \
  16813. +static inline int prefix##_write_trylock(param) \
  16814. +{ return au_rw_write_trylock(rwsem); }
  16815. +/* why is not _nested version defined */
  16816. +/* static inline void prefix##_read_trylock_nested(param, lsc)
  16817. +{ au_rw_read_trylock_nested(rwsem, lsc)); }
  16818. +static inline void prefix##_write_trylock_nestd(param, lsc)
  16819. +{ au_rw_write_trylock_nested(rwsem, lsc); } */
  16820. +
  16821. +#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
  16822. +static inline void prefix##_read_unlock(param) \
  16823. +{ au_rw_read_unlock(rwsem); } \
  16824. +static inline void prefix##_write_unlock(param) \
  16825. +{ au_rw_write_unlock(rwsem); } \
  16826. +static inline void prefix##_downgrade_lock(param) \
  16827. +{ au_rw_dgrade_lock(rwsem); }
  16828. +
  16829. +#define AuSimpleRwsemFuncs(prefix, param, rwsem) \
  16830. + AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
  16831. + AuSimpleUnlockRwsemFuncs(prefix, param, rwsem)
  16832. +
  16833. +#endif /* __KERNEL__ */
  16834. +#endif /* __AUFS_RWSEM_H__ */
  16835. diff -Nur linux-2.6.31.4.orig/fs/aufs/sbinfo.c linux-2.6.31.4/fs/aufs/sbinfo.c
  16836. --- linux-2.6.31.4.orig/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100
  16837. +++ linux-2.6.31.4/fs/aufs/sbinfo.c 2009-10-18 11:26:01.000000000 +0200
  16838. @@ -0,0 +1,208 @@
  16839. +/*
  16840. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  16841. + *
  16842. + * This program, aufs is free software; you can redistribute it and/or modify
  16843. + * it under the terms of the GNU General Public License as published by
  16844. + * the Free Software Foundation; either version 2 of the License, or
  16845. + * (at your option) any later version.
  16846. + *
  16847. + * This program is distributed in the hope that it will be useful,
  16848. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16849. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16850. + * GNU General Public License for more details.
  16851. + *
  16852. + * You should have received a copy of the GNU General Public License
  16853. + * along with this program; if not, write to the Free Software
  16854. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16855. + */
  16856. +
  16857. +/*
  16858. + * superblock private data
  16859. + */
  16860. +
  16861. +#include "aufs.h"
  16862. +
  16863. +/*
  16864. + * they are necessary regardless sysfs is disabled.
  16865. + */
  16866. +void au_si_free(struct kobject *kobj)
  16867. +{
  16868. + struct au_sbinfo *sbinfo;
  16869. + struct super_block *sb;
  16870. +
  16871. + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
  16872. + AuDebugOn(!list_empty(&sbinfo->si_plink.head));
  16873. +
  16874. + sb = sbinfo->si_sb;
  16875. + si_write_lock(sb);
  16876. + au_xino_clr(sb);
  16877. + au_br_free(sbinfo);
  16878. + kfree(sbinfo->si_branch);
  16879. + mutex_destroy(&sbinfo->si_xib_mtx);
  16880. + si_write_unlock(sb);
  16881. + AuRwDestroy(&sbinfo->si_rwsem);
  16882. +
  16883. + kfree(sbinfo);
  16884. +}
  16885. +
  16886. +int au_si_alloc(struct super_block *sb)
  16887. +{
  16888. + int err;
  16889. + struct au_sbinfo *sbinfo;
  16890. +
  16891. + err = -ENOMEM;
  16892. + sbinfo = kmalloc(sizeof(*sbinfo), GFP_NOFS);
  16893. + if (unlikely(!sbinfo))
  16894. + goto out;
  16895. +
  16896. + /* will be reallocated separately */
  16897. + sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
  16898. + if (unlikely(!sbinfo->si_branch))
  16899. + goto out_sbinfo;
  16900. +
  16901. + memset(&sbinfo->si_kobj, 0, sizeof(sbinfo->si_kobj));
  16902. + err = sysaufs_si_init(sbinfo);
  16903. + if (unlikely(err))
  16904. + goto out_br;
  16905. +
  16906. + au_nwt_init(&sbinfo->si_nowait);
  16907. + au_rw_init_wlock(&sbinfo->si_rwsem);
  16908. + sbinfo->si_generation = 0;
  16909. + sbinfo->au_si_status = 0;
  16910. + sbinfo->si_bend = -1;
  16911. + sbinfo->si_last_br_id = 0;
  16912. +
  16913. + sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
  16914. + sbinfo->si_wbr_create = AuWbrCreate_Def;
  16915. + sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + AuWbrCopyup_Def;
  16916. + sbinfo->si_wbr_create_ops = au_wbr_create_ops + AuWbrCreate_Def;
  16917. +
  16918. + sbinfo->si_mntflags = AuOpt_Def;
  16919. +
  16920. + sbinfo->si_xread = NULL;
  16921. + sbinfo->si_xwrite = NULL;
  16922. + sbinfo->si_xib = NULL;
  16923. + mutex_init(&sbinfo->si_xib_mtx);
  16924. + sbinfo->si_xib_buf = NULL;
  16925. + sbinfo->si_xino_brid = -1;
  16926. + /* leave si_xib_last_pindex and si_xib_next_bit */
  16927. +
  16928. + sbinfo->si_rdcache = AUFS_RDCACHE_DEF * HZ;
  16929. + sbinfo->si_rdblk = AUFS_RDBLK_DEF;
  16930. + sbinfo->si_rdhash = AUFS_RDHASH_DEF;
  16931. + sbinfo->si_dirwh = AUFS_DIRWH_DEF;
  16932. +
  16933. + au_spl_init(&sbinfo->si_plink);
  16934. + init_waitqueue_head(&sbinfo->si_plink_wq);
  16935. +
  16936. + /* leave other members for sysaufs and si_mnt. */
  16937. + sbinfo->si_sb = sb;
  16938. + sb->s_fs_info = sbinfo;
  16939. + au_debug_sbinfo_init(sbinfo);
  16940. + return 0; /* success */
  16941. +
  16942. + out_br:
  16943. + kfree(sbinfo->si_branch);
  16944. + out_sbinfo:
  16945. + kfree(sbinfo);
  16946. + out:
  16947. + return err;
  16948. +}
  16949. +
  16950. +int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr)
  16951. +{
  16952. + int err, sz;
  16953. + struct au_branch **brp;
  16954. +
  16955. + AuRwMustWriteLock(&sbinfo->si_rwsem);
  16956. +
  16957. + err = -ENOMEM;
  16958. + sz = sizeof(*brp) * (sbinfo->si_bend + 1);
  16959. + if (unlikely(!sz))
  16960. + sz = sizeof(*brp);
  16961. + brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS);
  16962. + if (brp) {
  16963. + sbinfo->si_branch = brp;
  16964. + err = 0;
  16965. + }
  16966. +
  16967. + return err;
  16968. +}
  16969. +
  16970. +/* ---------------------------------------------------------------------- */
  16971. +
  16972. +unsigned int au_sigen_inc(struct super_block *sb)
  16973. +{
  16974. + unsigned int gen;
  16975. +
  16976. + SiMustWriteLock(sb);
  16977. +
  16978. + gen = ++au_sbi(sb)->si_generation;
  16979. + au_update_digen(sb->s_root);
  16980. + au_update_iigen(sb->s_root->d_inode);
  16981. + sb->s_root->d_inode->i_version++;
  16982. + return gen;
  16983. +}
  16984. +
  16985. +aufs_bindex_t au_new_br_id(struct super_block *sb)
  16986. +{
  16987. + aufs_bindex_t br_id;
  16988. + int i;
  16989. + struct au_sbinfo *sbinfo;
  16990. +
  16991. + SiMustWriteLock(sb);
  16992. +
  16993. + sbinfo = au_sbi(sb);
  16994. + for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
  16995. + br_id = ++sbinfo->si_last_br_id;
  16996. + if (br_id && au_br_index(sb, br_id) < 0)
  16997. + return br_id;
  16998. + }
  16999. +
  17000. + return -1;
  17001. +}
  17002. +
  17003. +/* ---------------------------------------------------------------------- */
  17004. +
  17005. +/* dentry and super_block lock. call at entry point */
  17006. +void aufs_read_lock(struct dentry *dentry, int flags)
  17007. +{
  17008. + si_read_lock(dentry->d_sb, flags);
  17009. + if (au_ftest_lock(flags, DW))
  17010. + di_write_lock_child(dentry);
  17011. + else
  17012. + di_read_lock_child(dentry, flags);
  17013. +}
  17014. +
  17015. +void aufs_read_unlock(struct dentry *dentry, int flags)
  17016. +{
  17017. + if (au_ftest_lock(flags, DW))
  17018. + di_write_unlock(dentry);
  17019. + else
  17020. + di_read_unlock(dentry, flags);
  17021. + si_read_unlock(dentry->d_sb);
  17022. +}
  17023. +
  17024. +void aufs_write_lock(struct dentry *dentry)
  17025. +{
  17026. + si_write_lock(dentry->d_sb);
  17027. + di_write_lock_child(dentry);
  17028. +}
  17029. +
  17030. +void aufs_write_unlock(struct dentry *dentry)
  17031. +{
  17032. + di_write_unlock(dentry);
  17033. + si_write_unlock(dentry->d_sb);
  17034. +}
  17035. +
  17036. +void aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
  17037. +{
  17038. + si_read_lock(d1->d_sb, flags);
  17039. + di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR));
  17040. +}
  17041. +
  17042. +void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
  17043. +{
  17044. + di_write_unlock2(d1, d2);
  17045. + si_read_unlock(d1->d_sb);
  17046. +}
  17047. diff -Nur linux-2.6.31.4.orig/fs/aufs/spl.h linux-2.6.31.4/fs/aufs/spl.h
  17048. --- linux-2.6.31.4.orig/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100
  17049. +++ linux-2.6.31.4/fs/aufs/spl.h 2009-10-18 11:26:01.000000000 +0200
  17050. @@ -0,0 +1,57 @@
  17051. +/*
  17052. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  17053. + *
  17054. + * This program, aufs is free software; you can redistribute it and/or modify
  17055. + * it under the terms of the GNU General Public License as published by
  17056. + * the Free Software Foundation; either version 2 of the License, or
  17057. + * (at your option) any later version.
  17058. + *
  17059. + * This program is distributed in the hope that it will be useful,
  17060. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17061. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17062. + * GNU General Public License for more details.
  17063. + *
  17064. + * You should have received a copy of the GNU General Public License
  17065. + * along with this program; if not, write to the Free Software
  17066. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17067. + */
  17068. +
  17069. +/*
  17070. + * simple list protected by a spinlock
  17071. + */
  17072. +
  17073. +#ifndef __AUFS_SPL_H__
  17074. +#define __AUFS_SPL_H__
  17075. +
  17076. +#ifdef __KERNEL__
  17077. +
  17078. +#include <linux/spinlock.h>
  17079. +#include <linux/list.h>
  17080. +
  17081. +struct au_splhead {
  17082. + spinlock_t spin;
  17083. + struct list_head head;
  17084. +};
  17085. +
  17086. +static inline void au_spl_init(struct au_splhead *spl)
  17087. +{
  17088. + spin_lock_init(&spl->spin);
  17089. + INIT_LIST_HEAD(&spl->head);
  17090. +}
  17091. +
  17092. +static inline void au_spl_add(struct list_head *list, struct au_splhead *spl)
  17093. +{
  17094. + spin_lock(&spl->spin);
  17095. + list_add(list, &spl->head);
  17096. + spin_unlock(&spl->spin);
  17097. +}
  17098. +
  17099. +static inline void au_spl_del(struct list_head *list, struct au_splhead *spl)
  17100. +{
  17101. + spin_lock(&spl->spin);
  17102. + list_del(list);
  17103. + spin_unlock(&spl->spin);
  17104. +}
  17105. +
  17106. +#endif /* __KERNEL__ */
  17107. +#endif /* __AUFS_SPL_H__ */
  17108. diff -Nur linux-2.6.31.4.orig/fs/aufs/super.c linux-2.6.31.4/fs/aufs/super.c
  17109. --- linux-2.6.31.4.orig/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
  17110. +++ linux-2.6.31.4/fs/aufs/super.c 2009-10-18 11:26:01.000000000 +0200
  17111. @@ -0,0 +1,874 @@
  17112. +/*
  17113. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  17114. + *
  17115. + * This program, aufs is free software; you can redistribute it and/or modify
  17116. + * it under the terms of the GNU General Public License as published by
  17117. + * the Free Software Foundation; either version 2 of the License, or
  17118. + * (at your option) any later version.
  17119. + *
  17120. + * This program is distributed in the hope that it will be useful,
  17121. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17122. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17123. + * GNU General Public License for more details.
  17124. + *
  17125. + * You should have received a copy of the GNU General Public License
  17126. + * along with this program; if not, write to the Free Software
  17127. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17128. + */
  17129. +
  17130. +/*
  17131. + * mount and super_block operations
  17132. + */
  17133. +
  17134. +#include <linux/buffer_head.h>
  17135. +#include <linux/module.h>
  17136. +#include <linux/seq_file.h>
  17137. +#include <linux/statfs.h>
  17138. +#include "aufs.h"
  17139. +
  17140. +/*
  17141. + * super_operations
  17142. + */
  17143. +static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
  17144. +{
  17145. + struct au_icntnr *c;
  17146. +
  17147. + c = au_cache_alloc_icntnr();
  17148. + if (c) {
  17149. + inode_init_once(&c->vfs_inode);
  17150. + c->vfs_inode.i_version = 1; /* sigen(sb); */
  17151. + c->iinfo.ii_hinode = NULL;
  17152. + return &c->vfs_inode;
  17153. + }
  17154. + return NULL;
  17155. +}
  17156. +
  17157. +static void aufs_destroy_inode(struct inode *inode)
  17158. +{
  17159. + au_iinfo_fin(inode);
  17160. + au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
  17161. +}
  17162. +
  17163. +struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
  17164. +{
  17165. + struct inode *inode;
  17166. + int err;
  17167. +
  17168. + inode = iget_locked(sb, ino);
  17169. + if (unlikely(!inode)) {
  17170. + inode = ERR_PTR(-ENOMEM);
  17171. + goto out;
  17172. + }
  17173. + if (!(inode->i_state & I_NEW))
  17174. + goto out;
  17175. +
  17176. + err = au_xigen_new(inode);
  17177. + if (!err)
  17178. + err = au_iinfo_init(inode);
  17179. + if (!err)
  17180. + inode->i_version++;
  17181. + else {
  17182. + iget_failed(inode);
  17183. + inode = ERR_PTR(err);
  17184. + }
  17185. +
  17186. + out:
  17187. + /* never return NULL */
  17188. + AuDebugOn(!inode);
  17189. + AuTraceErrPtr(inode);
  17190. + return inode;
  17191. +}
  17192. +
  17193. +/* lock free root dinfo */
  17194. +static int au_show_brs(struct seq_file *seq, struct super_block *sb)
  17195. +{
  17196. + int err;
  17197. + aufs_bindex_t bindex, bend;
  17198. + struct path path;
  17199. + struct au_hdentry *hd;
  17200. + struct au_branch *br;
  17201. +
  17202. + err = 0;
  17203. + bend = au_sbend(sb);
  17204. + hd = au_di(sb->s_root)->di_hdentry;
  17205. + for (bindex = 0; !err && bindex <= bend; bindex++) {
  17206. + br = au_sbr(sb, bindex);
  17207. + path.mnt = br->br_mnt;
  17208. + path.dentry = hd[bindex].hd_dentry;
  17209. + err = au_seq_path(seq, &path);
  17210. + if (err > 0)
  17211. + err = seq_printf(seq, "=%s",
  17212. + au_optstr_br_perm(br->br_perm));
  17213. + if (!err && bindex != bend)
  17214. + err = seq_putc(seq, ':');
  17215. + }
  17216. +
  17217. + return err;
  17218. +}
  17219. +
  17220. +static void au_show_wbr_create(struct seq_file *m, int v,
  17221. + struct au_sbinfo *sbinfo)
  17222. +{
  17223. + const char *pat;
  17224. +
  17225. + AuRwMustAnyLock(&sbinfo->si_rwsem);
  17226. +
  17227. + seq_printf(m, ",create=");
  17228. + pat = au_optstr_wbr_create(v);
  17229. + switch (v) {
  17230. + case AuWbrCreate_TDP:
  17231. + case AuWbrCreate_RR:
  17232. + case AuWbrCreate_MFS:
  17233. + case AuWbrCreate_PMFS:
  17234. + seq_printf(m, pat);
  17235. + break;
  17236. + case AuWbrCreate_MFSV:
  17237. + seq_printf(m, /*pat*/"mfs:%lu",
  17238. + sbinfo->si_wbr_mfs.mfs_expire / HZ);
  17239. + break;
  17240. + case AuWbrCreate_PMFSV:
  17241. + seq_printf(m, /*pat*/"pmfs:%lu",
  17242. + sbinfo->si_wbr_mfs.mfs_expire / HZ);
  17243. + break;
  17244. + case AuWbrCreate_MFSRR:
  17245. + seq_printf(m, /*pat*/"mfsrr:%llu",
  17246. + sbinfo->si_wbr_mfs.mfsrr_watermark);
  17247. + break;
  17248. + case AuWbrCreate_MFSRRV:
  17249. + seq_printf(m, /*pat*/"mfsrr:%llu:%lu",
  17250. + sbinfo->si_wbr_mfs.mfsrr_watermark,
  17251. + sbinfo->si_wbr_mfs.mfs_expire / HZ);
  17252. + break;
  17253. + }
  17254. +}
  17255. +
  17256. +static int au_show_xino(struct seq_file *seq, struct vfsmount *mnt)
  17257. +{
  17258. +#ifdef CONFIG_SYSFS
  17259. + return 0;
  17260. +#else
  17261. + int err;
  17262. + const int len = sizeof(AUFS_XINO_FNAME) - 1;
  17263. + aufs_bindex_t bindex, brid;
  17264. + struct super_block *sb;
  17265. + struct qstr *name;
  17266. + struct file *f;
  17267. + struct dentry *d, *h_root;
  17268. +
  17269. + AuRwMustAnyLock(&sbinfo->si_rwsem);
  17270. +
  17271. + err = 0;
  17272. + sb = mnt->mnt_sb;
  17273. + f = au_sbi(sb)->si_xib;
  17274. + if (!f)
  17275. + goto out;
  17276. +
  17277. + /* stop printing the default xino path on the first writable branch */
  17278. + h_root = NULL;
  17279. + brid = au_xino_brid(sb);
  17280. + if (brid >= 0) {
  17281. + bindex = au_br_index(sb, brid);
  17282. + h_root = au_di(sb->s_root)->di_hdentry[0 + bindex].hd_dentry;
  17283. + }
  17284. + d = f->f_dentry;
  17285. + name = &d->d_name;
  17286. + /* safe ->d_parent because the file is unlinked */
  17287. + if (d->d_parent == h_root
  17288. + && name->len == len
  17289. + && !memcmp(name->name, AUFS_XINO_FNAME, len))
  17290. + goto out;
  17291. +
  17292. + seq_puts(seq, ",xino=");
  17293. + err = au_xino_path(seq, f);
  17294. +
  17295. + out:
  17296. + return err;
  17297. +#endif
  17298. +}
  17299. +
  17300. +/* seq_file will re-call me in case of too long string */
  17301. +static int aufs_show_options(struct seq_file *m, struct vfsmount *mnt)
  17302. +{
  17303. + int err, n;
  17304. + unsigned int mnt_flags, v;
  17305. + struct super_block *sb;
  17306. + struct au_sbinfo *sbinfo;
  17307. +
  17308. +#define AuBool(name, str) do { \
  17309. + v = au_opt_test(mnt_flags, name); \
  17310. + if (v != au_opt_test(AuOpt_Def, name)) \
  17311. + seq_printf(m, ",%s" #str, v ? "" : "no"); \
  17312. +} while (0)
  17313. +
  17314. +#define AuStr(name, str) do { \
  17315. + v = mnt_flags & AuOptMask_##name; \
  17316. + if (v != (AuOpt_Def & AuOptMask_##name)) \
  17317. + seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
  17318. +} while (0)
  17319. +
  17320. +#define AuUInt(name, str, val) do { \
  17321. + if (val != AUFS_##name##_DEF) \
  17322. + seq_printf(m, "," #str "=%u", val); \
  17323. +} while (0)
  17324. +
  17325. + /* lock free root dinfo */
  17326. + sb = mnt->mnt_sb;
  17327. + si_noflush_read_lock(sb);
  17328. + sbinfo = au_sbi(sb);
  17329. + seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
  17330. +
  17331. + mnt_flags = au_mntflags(sb);
  17332. + if (au_opt_test(mnt_flags, XINO)) {
  17333. + err = au_show_xino(m, mnt);
  17334. + if (unlikely(err))
  17335. + goto out;
  17336. + } else
  17337. + seq_puts(m, ",noxino");
  17338. +
  17339. + AuBool(TRUNC_XINO, trunc_xino);
  17340. + AuStr(UDBA, udba);
  17341. + AuBool(SHWH, shwh);
  17342. + AuBool(PLINK, plink);
  17343. + /* AuBool(DIRPERM1, dirperm1); */
  17344. + /* AuBool(REFROF, refrof); */
  17345. +
  17346. + v = sbinfo->si_wbr_create;
  17347. + if (v != AuWbrCreate_Def)
  17348. + au_show_wbr_create(m, v, sbinfo);
  17349. +
  17350. + v = sbinfo->si_wbr_copyup;
  17351. + if (v != AuWbrCopyup_Def)
  17352. + seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
  17353. +
  17354. + v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
  17355. + if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
  17356. + seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
  17357. +
  17358. + AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
  17359. +
  17360. + n = sbinfo->si_rdcache / HZ;
  17361. + AuUInt(RDCACHE, rdcache, n);
  17362. +
  17363. + AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
  17364. + AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
  17365. +
  17366. + AuBool(SUM, sum);
  17367. + /* AuBool(SUM_W, wsum); */
  17368. + AuBool(WARN_PERM, warn_perm);
  17369. + AuBool(VERBOSE, verbose);
  17370. +
  17371. + out:
  17372. + /* be sure to print "br:" last */
  17373. + if (!sysaufs_brs) {
  17374. + seq_puts(m, ",br:");
  17375. + au_show_brs(m, sb);
  17376. + }
  17377. + si_read_unlock(sb);
  17378. + return 0;
  17379. +
  17380. +#undef Deleted
  17381. +#undef AuBool
  17382. +#undef AuStr
  17383. +}
  17384. +
  17385. +/* ---------------------------------------------------------------------- */
  17386. +
  17387. +/* sum mode which returns the summation for statfs(2) */
  17388. +
  17389. +static u64 au_add_till_max(u64 a, u64 b)
  17390. +{
  17391. + u64 old;
  17392. +
  17393. + old = a;
  17394. + a += b;
  17395. + if (old < a)
  17396. + return a;
  17397. + return ULLONG_MAX;
  17398. +}
  17399. +
  17400. +static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
  17401. +{
  17402. + int err;
  17403. + u64 blocks, bfree, bavail, files, ffree;
  17404. + aufs_bindex_t bend, bindex, i;
  17405. + unsigned char shared;
  17406. + struct vfsmount *h_mnt;
  17407. + struct super_block *h_sb;
  17408. +
  17409. + blocks = 0;
  17410. + bfree = 0;
  17411. + bavail = 0;
  17412. + files = 0;
  17413. + ffree = 0;
  17414. +
  17415. + err = 0;
  17416. + bend = au_sbend(sb);
  17417. + for (bindex = bend; bindex >= 0; bindex--) {
  17418. + h_mnt = au_sbr_mnt(sb, bindex);
  17419. + h_sb = h_mnt->mnt_sb;
  17420. + shared = 0;
  17421. + for (i = bindex + 1; !shared && i <= bend; i++)
  17422. + shared = (au_sbr_sb(sb, i) == h_sb);
  17423. + if (shared)
  17424. + continue;
  17425. +
  17426. + /* sb->s_root for NFS is unreliable */
  17427. + err = vfs_statfs(h_mnt->mnt_root, buf);
  17428. + if (unlikely(err))
  17429. + goto out;
  17430. +
  17431. + blocks = au_add_till_max(blocks, buf->f_blocks);
  17432. + bfree = au_add_till_max(bfree, buf->f_bfree);
  17433. + bavail = au_add_till_max(bavail, buf->f_bavail);
  17434. + files = au_add_till_max(files, buf->f_files);
  17435. + ffree = au_add_till_max(ffree, buf->f_ffree);
  17436. + }
  17437. +
  17438. + buf->f_blocks = blocks;
  17439. + buf->f_bfree = bfree;
  17440. + buf->f_bavail = bavail;
  17441. + buf->f_files = files;
  17442. + buf->f_ffree = ffree;
  17443. +
  17444. + out:
  17445. + return err;
  17446. +}
  17447. +
  17448. +static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
  17449. +{
  17450. + int err;
  17451. + struct super_block *sb;
  17452. +
  17453. + /* lock free root dinfo */
  17454. + sb = dentry->d_sb;
  17455. + si_noflush_read_lock(sb);
  17456. + if (!au_opt_test(au_mntflags(sb), SUM))
  17457. + /* sb->s_root for NFS is unreliable */
  17458. + err = vfs_statfs(au_sbr_mnt(sb, 0)->mnt_root, buf);
  17459. + else
  17460. + err = au_statfs_sum(sb, buf);
  17461. + si_read_unlock(sb);
  17462. +
  17463. + if (!err) {
  17464. + buf->f_type = AUFS_SUPER_MAGIC;
  17465. + buf->f_namelen -= AUFS_WH_PFX_LEN;
  17466. + memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
  17467. + }
  17468. + /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
  17469. +
  17470. + return err;
  17471. +}
  17472. +
  17473. +/* ---------------------------------------------------------------------- */
  17474. +
  17475. +/* try flushing the lower fs at aufs remount/unmount time */
  17476. +
  17477. +static void au_fsync_br(struct super_block *sb)
  17478. +{
  17479. + aufs_bindex_t bend, bindex;
  17480. + int brperm;
  17481. + struct au_branch *br;
  17482. + struct super_block *h_sb;
  17483. +
  17484. + bend = au_sbend(sb);
  17485. + for (bindex = 0; bindex < bend; bindex++) {
  17486. + br = au_sbr(sb, bindex);
  17487. + brperm = br->br_perm;
  17488. + if (brperm == AuBrPerm_RR || brperm == AuBrPerm_RRWH)
  17489. + continue;
  17490. + h_sb = br->br_mnt->mnt_sb;
  17491. + if (bdev_read_only(h_sb->s_bdev))
  17492. + continue;
  17493. +
  17494. + lockdep_off();
  17495. + down_write(&h_sb->s_umount);
  17496. + shrink_dcache_sb(h_sb);
  17497. + fsync_super(h_sb);
  17498. + up_write(&h_sb->s_umount);
  17499. + lockdep_on();
  17500. + }
  17501. +}
  17502. +
  17503. +/*
  17504. + * this IS NOT for super_operations.
  17505. + * I guess it will be reverted someday.
  17506. + */
  17507. +static void aufs_umount_begin(struct super_block *sb)
  17508. +{
  17509. + struct au_sbinfo *sbinfo;
  17510. +
  17511. + sbinfo = au_sbi(sb);
  17512. + if (!sbinfo)
  17513. + return;
  17514. +
  17515. + si_write_lock(sb);
  17516. + au_fsync_br(sb);
  17517. + if (au_opt_test(au_mntflags(sb), PLINK))
  17518. + au_plink_put(sb);
  17519. + if (sbinfo->si_wbr_create_ops->fin)
  17520. + sbinfo->si_wbr_create_ops->fin(sb);
  17521. + si_write_unlock(sb);
  17522. +}
  17523. +
  17524. +/* final actions when unmounting a file system */
  17525. +static void aufs_put_super(struct super_block *sb)
  17526. +{
  17527. + struct au_sbinfo *sbinfo;
  17528. +
  17529. + sbinfo = au_sbi(sb);
  17530. + if (!sbinfo)
  17531. + return;
  17532. +
  17533. + aufs_umount_begin(sb);
  17534. + dbgaufs_si_fin(sbinfo);
  17535. + kobject_put(&sbinfo->si_kobj);
  17536. +}
  17537. +
  17538. +/* ---------------------------------------------------------------------- */
  17539. +
  17540. +/*
  17541. + * refresh dentry and inode at remount time.
  17542. + */
  17543. +static int do_refresh(struct dentry *dentry, mode_t type,
  17544. + unsigned int dir_flags)
  17545. +{
  17546. + int err;
  17547. + struct dentry *parent;
  17548. +
  17549. + di_write_lock_child(dentry);
  17550. + parent = dget_parent(dentry);
  17551. + di_read_lock_parent(parent, AuLock_IR);
  17552. +
  17553. + /* returns the number of positive dentries */
  17554. + err = au_refresh_hdentry(dentry, type);
  17555. + if (err >= 0) {
  17556. + struct inode *inode = dentry->d_inode;
  17557. + err = au_refresh_hinode(inode, dentry);
  17558. + if (!err && type == S_IFDIR)
  17559. + au_reset_hinotify(inode, dir_flags);
  17560. + }
  17561. + if (unlikely(err))
  17562. + AuErr("unrecoverable error %d, %.*s\n", err, AuDLNPair(dentry));
  17563. +
  17564. + di_read_unlock(parent, AuLock_IR);
  17565. + dput(parent);
  17566. + di_write_unlock(dentry);
  17567. +
  17568. + return err;
  17569. +}
  17570. +
  17571. +static int test_dir(struct dentry *dentry, void *arg __maybe_unused)
  17572. +{
  17573. + return S_ISDIR(dentry->d_inode->i_mode);
  17574. +}
  17575. +
  17576. +/* gave up consolidating with refresh_nondir() */
  17577. +static int refresh_dir(struct dentry *root, unsigned int sigen)
  17578. +{
  17579. + int err, i, j, ndentry, e;
  17580. + struct au_dcsub_pages dpages;
  17581. + struct au_dpage *dpage;
  17582. + struct dentry **dentries;
  17583. + struct inode *inode;
  17584. + const unsigned int flags = au_hi_flags(root->d_inode, /*isdir*/1);
  17585. +
  17586. + err = 0;
  17587. + list_for_each_entry(inode, &root->d_sb->s_inodes, i_sb_list)
  17588. + if (S_ISDIR(inode->i_mode) && au_iigen(inode) != sigen) {
  17589. + ii_write_lock_child(inode);
  17590. + e = au_refresh_hinode_self(inode, /*do_attr*/1);
  17591. + ii_write_unlock(inode);
  17592. + if (unlikely(e)) {
  17593. + AuDbg("e %d, i%lu\n", e, inode->i_ino);
  17594. + if (!err)
  17595. + err = e;
  17596. + /* go on even if err */
  17597. + }
  17598. + }
  17599. +
  17600. + e = au_dpages_init(&dpages, GFP_NOFS);
  17601. + if (unlikely(e)) {
  17602. + if (!err)
  17603. + err = e;
  17604. + goto out;
  17605. + }
  17606. + e = au_dcsub_pages(&dpages, root, test_dir, NULL);
  17607. + if (unlikely(e)) {
  17608. + if (!err)
  17609. + err = e;
  17610. + goto out_dpages;
  17611. + }
  17612. +
  17613. + for (i = 0; !e && i < dpages.ndpage; i++) {
  17614. + dpage = dpages.dpages + i;
  17615. + dentries = dpage->dentries;
  17616. + ndentry = dpage->ndentry;
  17617. + for (j = 0; !e && j < ndentry; j++) {
  17618. + struct dentry *d;
  17619. +
  17620. + d = dentries[j];
  17621. + au_dbg_verify_dir_parent(d, sigen);
  17622. + if (au_digen(d) != sigen) {
  17623. + e = do_refresh(d, S_IFDIR, flags);
  17624. + if (unlikely(e && !err))
  17625. + err = e;
  17626. + /* break on err */
  17627. + }
  17628. + }
  17629. + }
  17630. +
  17631. + out_dpages:
  17632. + au_dpages_free(&dpages);
  17633. + out:
  17634. + return err;
  17635. +}
  17636. +
  17637. +static int test_nondir(struct dentry *dentry, void *arg __maybe_unused)
  17638. +{
  17639. + return !S_ISDIR(dentry->d_inode->i_mode);
  17640. +}
  17641. +
  17642. +static int refresh_nondir(struct dentry *root, unsigned int sigen,
  17643. + int do_dentry)
  17644. +{
  17645. + int err, i, j, ndentry, e;
  17646. + struct au_dcsub_pages dpages;
  17647. + struct au_dpage *dpage;
  17648. + struct dentry **dentries;
  17649. + struct inode *inode;
  17650. +
  17651. + err = 0;
  17652. + list_for_each_entry(inode, &root->d_sb->s_inodes, i_sb_list)
  17653. + if (!S_ISDIR(inode->i_mode) && au_iigen(inode) != sigen) {
  17654. + ii_write_lock_child(inode);
  17655. + e = au_refresh_hinode_self(inode, /*do_attr*/1);
  17656. + ii_write_unlock(inode);
  17657. + if (unlikely(e)) {
  17658. + AuDbg("e %d, i%lu\n", e, inode->i_ino);
  17659. + if (!err)
  17660. + err = e;
  17661. + /* go on even if err */
  17662. + }
  17663. + }
  17664. +
  17665. + if (!do_dentry)
  17666. + goto out;
  17667. +
  17668. + e = au_dpages_init(&dpages, GFP_NOFS);
  17669. + if (unlikely(e)) {
  17670. + if (!err)
  17671. + err = e;
  17672. + goto out;
  17673. + }
  17674. + e = au_dcsub_pages(&dpages, root, test_nondir, NULL);
  17675. + if (unlikely(e)) {
  17676. + if (!err)
  17677. + err = e;
  17678. + goto out_dpages;
  17679. + }
  17680. +
  17681. + for (i = 0; i < dpages.ndpage; i++) {
  17682. + dpage = dpages.dpages + i;
  17683. + dentries = dpage->dentries;
  17684. + ndentry = dpage->ndentry;
  17685. + for (j = 0; j < ndentry; j++) {
  17686. + struct dentry *d;
  17687. +
  17688. + d = dentries[j];
  17689. + au_dbg_verify_nondir_parent(d, sigen);
  17690. + inode = d->d_inode;
  17691. + if (inode && au_digen(d) != sigen) {
  17692. + e = do_refresh(d, inode->i_mode & S_IFMT,
  17693. + /*dir_flags*/0);
  17694. + if (unlikely(e && !err))
  17695. + err = e;
  17696. + /* go on even err */
  17697. + }
  17698. + }
  17699. + }
  17700. +
  17701. + out_dpages:
  17702. + au_dpages_free(&dpages);
  17703. + out:
  17704. + return err;
  17705. +}
  17706. +
  17707. +static void au_remount_refresh(struct super_block *sb, unsigned int flags)
  17708. +{
  17709. + int err;
  17710. + unsigned int sigen;
  17711. + struct au_sbinfo *sbinfo;
  17712. + struct dentry *root;
  17713. + struct inode *inode;
  17714. +
  17715. + au_sigen_inc(sb);
  17716. + sigen = au_sigen(sb);
  17717. + sbinfo = au_sbi(sb);
  17718. + au_fclr_si(sbinfo, FAILED_REFRESH_DIRS);
  17719. +
  17720. + root = sb->s_root;
  17721. + DiMustNoWaiters(root);
  17722. + inode = root->d_inode;
  17723. + IiMustNoWaiters(inode);
  17724. + au_reset_hinotify(inode, au_hi_flags(inode, /*isdir*/1));
  17725. + di_write_unlock(root);
  17726. +
  17727. + err = refresh_dir(root, sigen);
  17728. + if (unlikely(err)) {
  17729. + au_fset_si(sbinfo, FAILED_REFRESH_DIRS);
  17730. + AuWarn("Refreshing directories failed, ignored (%d)\n", err);
  17731. + }
  17732. +
  17733. + if (au_ftest_opts(flags, REFRESH_NONDIR)) {
  17734. + err = refresh_nondir(root, sigen, !err);
  17735. + if (unlikely(err))
  17736. + AuWarn("Refreshing non-directories failed, ignored"
  17737. + "(%d)\n", err);
  17738. + }
  17739. +
  17740. + /* aufs_write_lock() calls ..._child() */
  17741. + di_write_lock_child(root);
  17742. + au_cpup_attr_all(root->d_inode, /*force*/1);
  17743. +}
  17744. +
  17745. +/* stop extra interpretation of errno in mount(8), and strange error messages */
  17746. +static int cvt_err(int err)
  17747. +{
  17748. + AuTraceErr(err);
  17749. +
  17750. + switch (err) {
  17751. + case -ENOENT:
  17752. + case -ENOTDIR:
  17753. + case -EEXIST:
  17754. + case -EIO:
  17755. + err = -EINVAL;
  17756. + }
  17757. + return err;
  17758. +}
  17759. +
  17760. +static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
  17761. +{
  17762. + int err;
  17763. + struct au_opts opts;
  17764. + struct dentry *root;
  17765. + struct inode *inode;
  17766. + struct au_sbinfo *sbinfo;
  17767. +
  17768. + err = 0;
  17769. + root = sb->s_root;
  17770. + if (!data || !*data) {
  17771. + aufs_write_lock(root);
  17772. + err = au_opts_verify(sb, *flags, /*pending*/0);
  17773. + if (!err)
  17774. + au_fsync_br(sb);
  17775. + aufs_write_unlock(root);
  17776. + goto out;
  17777. + }
  17778. +
  17779. + err = -ENOMEM;
  17780. + memset(&opts, 0, sizeof(opts));
  17781. + opts.opt = (void *)__get_free_page(GFP_NOFS);
  17782. + if (unlikely(!opts.opt))
  17783. + goto out;
  17784. + opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
  17785. + opts.flags = AuOpts_REMOUNT;
  17786. + opts.sb_flags = *flags;
  17787. +
  17788. + /* parse it before aufs lock */
  17789. + err = au_opts_parse(sb, data, &opts);
  17790. + if (unlikely(err))
  17791. + goto out_opts;
  17792. +
  17793. + sbinfo = au_sbi(sb);
  17794. + inode = root->d_inode;
  17795. + mutex_lock(&inode->i_mutex);
  17796. + aufs_write_lock(root);
  17797. + au_fsync_br(sb);
  17798. +
  17799. + /* au_opts_remount() may return an error */
  17800. + err = au_opts_remount(sb, &opts);
  17801. + au_opts_free(&opts);
  17802. +
  17803. + if (au_ftest_opts(opts.flags, REFRESH_DIR)
  17804. + || au_ftest_opts(opts.flags, REFRESH_NONDIR))
  17805. + au_remount_refresh(sb, opts.flags);
  17806. +
  17807. + aufs_write_unlock(root);
  17808. + mutex_unlock(&inode->i_mutex);
  17809. +
  17810. + out_opts:
  17811. + free_page((unsigned long)opts.opt);
  17812. + out:
  17813. + err = cvt_err(err);
  17814. + AuTraceErr(err);
  17815. + return err;
  17816. +}
  17817. +
  17818. +static struct super_operations aufs_sop = {
  17819. + .alloc_inode = aufs_alloc_inode,
  17820. + .destroy_inode = aufs_destroy_inode,
  17821. + .drop_inode = generic_delete_inode,
  17822. + .show_options = aufs_show_options,
  17823. + .statfs = aufs_statfs,
  17824. + .put_super = aufs_put_super,
  17825. + .remount_fs = aufs_remount_fs
  17826. +};
  17827. +
  17828. +/* ---------------------------------------------------------------------- */
  17829. +
  17830. +static int alloc_root(struct super_block *sb)
  17831. +{
  17832. + int err;
  17833. + struct inode *inode;
  17834. + struct dentry *root;
  17835. +
  17836. + err = -ENOMEM;
  17837. + inode = au_iget_locked(sb, AUFS_ROOT_INO);
  17838. + err = PTR_ERR(inode);
  17839. + if (IS_ERR(inode))
  17840. + goto out;
  17841. +
  17842. + inode->i_op = &aufs_dir_iop;
  17843. + inode->i_fop = &aufs_dir_fop;
  17844. + inode->i_mode = S_IFDIR;
  17845. + inode->i_nlink = 2;
  17846. + unlock_new_inode(inode);
  17847. +
  17848. + root = d_alloc_root(inode);
  17849. + if (unlikely(!root))
  17850. + goto out_iput;
  17851. + err = PTR_ERR(root);
  17852. + if (IS_ERR(root))
  17853. + goto out_iput;
  17854. +
  17855. + err = au_alloc_dinfo(root);
  17856. + if (!err) {
  17857. + sb->s_root = root;
  17858. + return 0; /* success */
  17859. + }
  17860. + dput(root);
  17861. + goto out; /* do not iput */
  17862. +
  17863. + out_iput:
  17864. + iget_failed(inode);
  17865. + iput(inode);
  17866. + out:
  17867. + return err;
  17868. +
  17869. +}
  17870. +
  17871. +static int aufs_fill_super(struct super_block *sb, void *raw_data,
  17872. + int silent __maybe_unused)
  17873. +{
  17874. + int err;
  17875. + struct au_opts opts;
  17876. + struct dentry *root;
  17877. + struct inode *inode;
  17878. + char *arg = raw_data;
  17879. +
  17880. + if (unlikely(!arg || !*arg)) {
  17881. + err = -EINVAL;
  17882. + AuErr("no arg\n");
  17883. + goto out;
  17884. + }
  17885. +
  17886. + err = -ENOMEM;
  17887. + memset(&opts, 0, sizeof(opts));
  17888. + opts.opt = (void *)__get_free_page(GFP_NOFS);
  17889. + if (unlikely(!opts.opt))
  17890. + goto out;
  17891. + opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
  17892. + opts.sb_flags = sb->s_flags;
  17893. +
  17894. + err = au_si_alloc(sb);
  17895. + if (unlikely(err))
  17896. + goto out_opts;
  17897. +
  17898. + /* all timestamps always follow the ones on the branch */
  17899. + sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
  17900. + sb->s_op = &aufs_sop;
  17901. + sb->s_magic = AUFS_SUPER_MAGIC;
  17902. + sb->s_maxbytes = 0;
  17903. + au_export_init(sb);
  17904. +
  17905. + err = alloc_root(sb);
  17906. + if (unlikely(err)) {
  17907. + si_write_unlock(sb);
  17908. + goto out_info;
  17909. + }
  17910. + root = sb->s_root;
  17911. + inode = root->d_inode;
  17912. +
  17913. + /*
  17914. + * actually we can parse options regardless aufs lock here.
  17915. + * but at remount time, parsing must be done before aufs lock.
  17916. + * so we follow the same rule.
  17917. + */
  17918. + ii_write_lock_parent(inode);
  17919. + aufs_write_unlock(root);
  17920. + err = au_opts_parse(sb, arg, &opts);
  17921. + if (unlikely(err))
  17922. + goto out_root;
  17923. +
  17924. + /* lock vfs_inode first, then aufs. */
  17925. + mutex_lock(&inode->i_mutex);
  17926. + inode->i_op = &aufs_dir_iop;
  17927. + inode->i_fop = &aufs_dir_fop;
  17928. + aufs_write_lock(root);
  17929. + err = au_opts_mount(sb, &opts);
  17930. + au_opts_free(&opts);
  17931. + if (unlikely(err))
  17932. + goto out_unlock;
  17933. + aufs_write_unlock(root);
  17934. + mutex_unlock(&inode->i_mutex);
  17935. + goto out_opts; /* success */
  17936. +
  17937. + out_unlock:
  17938. + aufs_write_unlock(root);
  17939. + mutex_unlock(&inode->i_mutex);
  17940. + out_root:
  17941. + dput(root);
  17942. + sb->s_root = NULL;
  17943. + out_info:
  17944. + kobject_put(&au_sbi(sb)->si_kobj);
  17945. + sb->s_fs_info = NULL;
  17946. + out_opts:
  17947. + free_page((unsigned long)opts.opt);
  17948. + out:
  17949. + AuTraceErr(err);
  17950. + err = cvt_err(err);
  17951. + AuTraceErr(err);
  17952. + return err;
  17953. +}
  17954. +
  17955. +/* ---------------------------------------------------------------------- */
  17956. +
  17957. +static int aufs_get_sb(struct file_system_type *fs_type, int flags,
  17958. + const char *dev_name __maybe_unused, void *raw_data,
  17959. + struct vfsmount *mnt)
  17960. +{
  17961. + int err;
  17962. + struct super_block *sb;
  17963. +
  17964. + /* all timestamps always follow the ones on the branch */
  17965. + /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
  17966. + err = get_sb_nodev(fs_type, flags, raw_data, aufs_fill_super, mnt);
  17967. + if (!err) {
  17968. + sb = mnt->mnt_sb;
  17969. + si_write_lock(sb);
  17970. + sysaufs_brs_add(sb, 0);
  17971. + si_write_unlock(sb);
  17972. + }
  17973. + return err;
  17974. +}
  17975. +
  17976. +struct file_system_type aufs_fs_type = {
  17977. + .name = AUFS_FSTYPE,
  17978. + .fs_flags =
  17979. + FS_RENAME_DOES_D_MOVE /* a race between rename and others */
  17980. + | FS_REVAL_DOT, /* for NFS branch and udba */
  17981. + .get_sb = aufs_get_sb,
  17982. + .kill_sb = generic_shutdown_super,
  17983. + /* no need to __module_get() and module_put(). */
  17984. + .owner = THIS_MODULE,
  17985. +};
  17986. diff -Nur linux-2.6.31.4.orig/fs/aufs/super.h linux-2.6.31.4/fs/aufs/super.h
  17987. --- linux-2.6.31.4.orig/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100
  17988. +++ linux-2.6.31.4/fs/aufs/super.h 2009-10-18 11:26:01.000000000 +0200
  17989. @@ -0,0 +1,384 @@
  17990. +/*
  17991. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  17992. + *
  17993. + * This program, aufs is free software; you can redistribute it and/or modify
  17994. + * it under the terms of the GNU General Public License as published by
  17995. + * the Free Software Foundation; either version 2 of the License, or
  17996. + * (at your option) any later version.
  17997. + *
  17998. + * This program is distributed in the hope that it will be useful,
  17999. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18000. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18001. + * GNU General Public License for more details.
  18002. + *
  18003. + * You should have received a copy of the GNU General Public License
  18004. + * along with this program; if not, write to the Free Software
  18005. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18006. + */
  18007. +
  18008. +/*
  18009. + * super_block operations
  18010. + */
  18011. +
  18012. +#ifndef __AUFS_SUPER_H__
  18013. +#define __AUFS_SUPER_H__
  18014. +
  18015. +#ifdef __KERNEL__
  18016. +
  18017. +#include <linux/fs.h>
  18018. +#include <linux/aufs_type.h>
  18019. +#include "rwsem.h"
  18020. +#include "spl.h"
  18021. +#include "wkq.h"
  18022. +
  18023. +typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *);
  18024. +typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t,
  18025. + loff_t *);
  18026. +
  18027. +/* policies to select one among multiple writable branches */
  18028. +struct au_wbr_copyup_operations {
  18029. + int (*copyup)(struct dentry *dentry);
  18030. +};
  18031. +
  18032. +struct au_wbr_create_operations {
  18033. + int (*create)(struct dentry *dentry, int isdir);
  18034. + int (*init)(struct super_block *sb);
  18035. + int (*fin)(struct super_block *sb);
  18036. +};
  18037. +
  18038. +struct au_wbr_mfs {
  18039. + struct mutex mfs_lock; /* protect this structure */
  18040. + unsigned long mfs_jiffy;
  18041. + unsigned long mfs_expire;
  18042. + aufs_bindex_t mfs_bindex;
  18043. +
  18044. + unsigned long long mfsrr_bytes;
  18045. + unsigned long long mfsrr_watermark;
  18046. +};
  18047. +
  18048. +struct au_branch;
  18049. +struct au_sbinfo {
  18050. + /* nowait tasks in the system-wide workqueue */
  18051. + struct au_nowait_tasks si_nowait;
  18052. +
  18053. + struct au_rwsem si_rwsem;
  18054. +
  18055. + /* branch management */
  18056. + unsigned int si_generation;
  18057. +
  18058. + /* see above flags */
  18059. + unsigned char au_si_status;
  18060. +
  18061. + aufs_bindex_t si_bend;
  18062. + aufs_bindex_t si_last_br_id;
  18063. + struct au_branch **si_branch;
  18064. +
  18065. + /* policy to select a writable branch */
  18066. + unsigned char si_wbr_copyup;
  18067. + unsigned char si_wbr_create;
  18068. + struct au_wbr_copyup_operations *si_wbr_copyup_ops;
  18069. + struct au_wbr_create_operations *si_wbr_create_ops;
  18070. +
  18071. + /* round robin */
  18072. + atomic_t si_wbr_rr_next;
  18073. +
  18074. + /* most free space */
  18075. + struct au_wbr_mfs si_wbr_mfs;
  18076. +
  18077. + /* mount flags */
  18078. + /* include/asm-ia64/siginfo.h defines a macro named si_flags */
  18079. + unsigned int si_mntflags;
  18080. +
  18081. + /* external inode number (bitmap and translation table) */
  18082. + au_readf_t si_xread;
  18083. + au_writef_t si_xwrite;
  18084. + struct file *si_xib;
  18085. + struct mutex si_xib_mtx; /* protect xib members */
  18086. + unsigned long *si_xib_buf;
  18087. + unsigned long si_xib_last_pindex;
  18088. + int si_xib_next_bit;
  18089. + aufs_bindex_t si_xino_brid;
  18090. + /* reserved for future use */
  18091. + /* unsigned long long si_xib_limit; */ /* Max xib file size */
  18092. +
  18093. +#ifdef CONFIG_AUFS_EXPORT
  18094. + /* i_generation */
  18095. + struct file *si_xigen;
  18096. + atomic_t si_xigen_next;
  18097. +#endif
  18098. +
  18099. + /* vdir parameters */
  18100. + unsigned long si_rdcache; /* max cache time in HZ */
  18101. + unsigned int si_rdblk; /* deblk size */
  18102. + unsigned int si_rdhash; /* hash size */
  18103. +
  18104. + /*
  18105. + * If the number of whiteouts are larger than si_dirwh, leave all of
  18106. + * them after au_whtmp_ren to reduce the cost of rmdir(2).
  18107. + * future fsck.aufs or kernel thread will remove them later.
  18108. + * Otherwise, remove all whiteouts and the dir in rmdir(2).
  18109. + */
  18110. + unsigned int si_dirwh;
  18111. +
  18112. + /*
  18113. + * rename(2) a directory with all children.
  18114. + */
  18115. + /* reserved for future use */
  18116. + /* int si_rendir; */
  18117. +
  18118. + /* pseudo_link list */
  18119. + struct au_splhead si_plink;
  18120. + wait_queue_head_t si_plink_wq;
  18121. +
  18122. + /*
  18123. + * sysfs and lifetime management.
  18124. + * this is not a small structure and it may be a waste of memory in case
  18125. + * of sysfs is disabled, particulary when many aufs-es are mounted.
  18126. + * but using sysfs is majority.
  18127. + */
  18128. + struct kobject si_kobj;
  18129. +#ifdef CONFIG_DEBUG_FS
  18130. + struct dentry *si_dbgaufs, *si_dbgaufs_xib;
  18131. +#ifdef CONFIG_AUFS_EXPORT
  18132. + struct dentry *si_dbgaufs_xigen;
  18133. +#endif
  18134. +#endif
  18135. +
  18136. + /* dirty, necessary for unmounting, sysfs and sysrq */
  18137. + struct super_block *si_sb;
  18138. +};
  18139. +
  18140. +/* sbinfo status flags */
  18141. +/*
  18142. + * set true when refresh_dirs() failed at remount time.
  18143. + * then try refreshing dirs at access time again.
  18144. + * if it is false, refreshing dirs at access time is unnecesary
  18145. + */
  18146. +#define AuSi_FAILED_REFRESH_DIRS 1
  18147. +#define AuSi_MAINTAIN_PLINK (1 << 1) /* ioctl */
  18148. +static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
  18149. + unsigned int flag)
  18150. +{
  18151. + AuRwMustAnyLock(&sbi->si_rwsem);
  18152. + return sbi->au_si_status & flag;
  18153. +}
  18154. +#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name)
  18155. +#define au_fset_si(sbinfo, name) do { \
  18156. + AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
  18157. + (sbinfo)->au_si_status |= AuSi_##name; \
  18158. +} while (0)
  18159. +#define au_fclr_si(sbinfo, name) do { \
  18160. + AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
  18161. + (sbinfo)->au_si_status &= ~AuSi_##name; \
  18162. +} while (0)
  18163. +
  18164. +/* ---------------------------------------------------------------------- */
  18165. +
  18166. +/* policy to select one among writable branches */
  18167. +#define AuWbrCopyup(sbinfo, args...) \
  18168. + ((sbinfo)->si_wbr_copyup_ops->copyup(args))
  18169. +#define AuWbrCreate(sbinfo, args...) \
  18170. + ((sbinfo)->si_wbr_create_ops->create(args))
  18171. +
  18172. +/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
  18173. +#define AuLock_DW 1 /* write-lock dentry */
  18174. +#define AuLock_IR (1 << 1) /* read-lock inode */
  18175. +#define AuLock_IW (1 << 2) /* write-lock inode */
  18176. +#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
  18177. +#define AuLock_DIR (1 << 4) /* target is a dir */
  18178. +#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
  18179. +#define au_fset_lock(flags, name) { (flags) |= AuLock_##name; }
  18180. +#define au_fclr_lock(flags, name) { (flags) &= ~AuLock_##name; }
  18181. +
  18182. +/* ---------------------------------------------------------------------- */
  18183. +
  18184. +/* super.c */
  18185. +extern struct file_system_type aufs_fs_type;
  18186. +struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
  18187. +
  18188. +/* sbinfo.c */
  18189. +void au_si_free(struct kobject *kobj);
  18190. +int au_si_alloc(struct super_block *sb);
  18191. +int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr);
  18192. +
  18193. +unsigned int au_sigen_inc(struct super_block *sb);
  18194. +aufs_bindex_t au_new_br_id(struct super_block *sb);
  18195. +
  18196. +void aufs_read_lock(struct dentry *dentry, int flags);
  18197. +void aufs_read_unlock(struct dentry *dentry, int flags);
  18198. +void aufs_write_lock(struct dentry *dentry);
  18199. +void aufs_write_unlock(struct dentry *dentry);
  18200. +void aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int isdir);
  18201. +void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
  18202. +
  18203. +/* wbr_policy.c */
  18204. +extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
  18205. +extern struct au_wbr_create_operations au_wbr_create_ops[];
  18206. +int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
  18207. +
  18208. +/* ---------------------------------------------------------------------- */
  18209. +
  18210. +static inline struct au_sbinfo *au_sbi(struct super_block *sb)
  18211. +{
  18212. + return sb->s_fs_info;
  18213. +}
  18214. +
  18215. +/* ---------------------------------------------------------------------- */
  18216. +
  18217. +#ifdef CONFIG_AUFS_EXPORT
  18218. +void au_export_init(struct super_block *sb);
  18219. +
  18220. +static inline int au_test_nfsd(struct task_struct *tsk)
  18221. +{
  18222. + return !tsk->mm && !strcmp(tsk->comm, "nfsd");
  18223. +}
  18224. +
  18225. +int au_xigen_inc(struct inode *inode);
  18226. +int au_xigen_new(struct inode *inode);
  18227. +int au_xigen_set(struct super_block *sb, struct file *base);
  18228. +void au_xigen_clr(struct super_block *sb);
  18229. +
  18230. +static inline int au_busy_or_stale(void)
  18231. +{
  18232. + if (!au_test_nfsd(current))
  18233. + return -EBUSY;
  18234. + return -ESTALE;
  18235. +}
  18236. +#else
  18237. +static inline void au_export_init(struct super_block *sb)
  18238. +{
  18239. + /* nothing */
  18240. +}
  18241. +
  18242. +static inline int au_test_nfsd(struct task_struct *tsk)
  18243. +{
  18244. + return 0;
  18245. +}
  18246. +
  18247. +static inline int au_xigen_inc(struct inode *inode)
  18248. +{
  18249. + return 0;
  18250. +}
  18251. +
  18252. +static inline int au_xigen_new(struct inode *inode)
  18253. +{
  18254. + return 0;
  18255. +}
  18256. +
  18257. +static inline int au_xigen_set(struct super_block *sb, struct file *base)
  18258. +{
  18259. + return 0;
  18260. +}
  18261. +
  18262. +static inline void au_xigen_clr(struct super_block *sb)
  18263. +{
  18264. + /* empty */
  18265. +}
  18266. +
  18267. +static inline int au_busy_or_stale(void)
  18268. +{
  18269. + return -EBUSY;
  18270. +}
  18271. +#endif /* CONFIG_AUFS_EXPORT */
  18272. +
  18273. +/* ---------------------------------------------------------------------- */
  18274. +
  18275. +static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
  18276. +{
  18277. + /*
  18278. + * This function is a dynamic '__init' fucntion actually,
  18279. + * so the tiny check for si_rwsem is unnecessary.
  18280. + */
  18281. + /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
  18282. +#ifdef CONFIG_DEBUG_FS
  18283. + sbinfo->si_dbgaufs = NULL;
  18284. + sbinfo->si_dbgaufs_xib = NULL;
  18285. +#ifdef CONFIG_AUFS_EXPORT
  18286. + sbinfo->si_dbgaufs_xigen = NULL;
  18287. +#endif
  18288. +#endif
  18289. +}
  18290. +
  18291. +/* ---------------------------------------------------------------------- */
  18292. +
  18293. +/* lock superblock. mainly for entry point functions */
  18294. +/*
  18295. + * si_noflush_read_lock, si_noflush_write_lock,
  18296. + * si_read_unlock, si_write_unlock, si_downgrade_lock
  18297. + */
  18298. +AuSimpleLockRwsemFuncs(si_noflush, struct super_block *sb,
  18299. + &au_sbi(sb)->si_rwsem);
  18300. +AuSimpleUnlockRwsemFuncs(si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
  18301. +
  18302. +#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
  18303. +#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
  18304. +#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
  18305. +
  18306. +static inline void si_read_lock(struct super_block *sb, int flags)
  18307. +{
  18308. + if (au_ftest_lock(flags, FLUSH))
  18309. + au_nwt_flush(&au_sbi(sb)->si_nowait);
  18310. + si_noflush_read_lock(sb);
  18311. +}
  18312. +
  18313. +static inline void si_write_lock(struct super_block *sb)
  18314. +{
  18315. + au_nwt_flush(&au_sbi(sb)->si_nowait);
  18316. + si_noflush_write_lock(sb);
  18317. +}
  18318. +
  18319. +static inline int si_read_trylock(struct super_block *sb, int flags)
  18320. +{
  18321. + if (au_ftest_lock(flags, FLUSH))
  18322. + au_nwt_flush(&au_sbi(sb)->si_nowait);
  18323. + return si_noflush_read_trylock(sb);
  18324. +}
  18325. +
  18326. +static inline int si_write_trylock(struct super_block *sb, int flags)
  18327. +{
  18328. + if (au_ftest_lock(flags, FLUSH))
  18329. + au_nwt_flush(&au_sbi(sb)->si_nowait);
  18330. + return si_noflush_write_trylock(sb);
  18331. +}
  18332. +
  18333. +/* ---------------------------------------------------------------------- */
  18334. +
  18335. +static inline aufs_bindex_t au_sbend(struct super_block *sb)
  18336. +{
  18337. + SiMustAnyLock(sb);
  18338. + return au_sbi(sb)->si_bend;
  18339. +}
  18340. +
  18341. +static inline unsigned int au_mntflags(struct super_block *sb)
  18342. +{
  18343. + SiMustAnyLock(sb);
  18344. + return au_sbi(sb)->si_mntflags;
  18345. +}
  18346. +
  18347. +static inline unsigned int au_sigen(struct super_block *sb)
  18348. +{
  18349. + SiMustAnyLock(sb);
  18350. + return au_sbi(sb)->si_generation;
  18351. +}
  18352. +
  18353. +static inline struct au_branch *au_sbr(struct super_block *sb,
  18354. + aufs_bindex_t bindex)
  18355. +{
  18356. + SiMustAnyLock(sb);
  18357. + return au_sbi(sb)->si_branch[0 + bindex];
  18358. +}
  18359. +
  18360. +static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid)
  18361. +{
  18362. + SiMustWriteLock(sb);
  18363. + au_sbi(sb)->si_xino_brid = brid;
  18364. +}
  18365. +
  18366. +static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
  18367. +{
  18368. + SiMustAnyLock(sb);
  18369. + return au_sbi(sb)->si_xino_brid;
  18370. +}
  18371. +
  18372. +#endif /* __KERNEL__ */
  18373. +#endif /* __AUFS_SUPER_H__ */
  18374. diff -Nur linux-2.6.31.4.orig/fs/aufs/sysaufs.c linux-2.6.31.4/fs/aufs/sysaufs.c
  18375. --- linux-2.6.31.4.orig/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
  18376. +++ linux-2.6.31.4/fs/aufs/sysaufs.c 2009-10-18 11:26:01.000000000 +0200
  18377. @@ -0,0 +1,104 @@
  18378. +/*
  18379. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  18380. + *
  18381. + * This program, aufs is free software; you can redistribute it and/or modify
  18382. + * it under the terms of the GNU General Public License as published by
  18383. + * the Free Software Foundation; either version 2 of the License, or
  18384. + * (at your option) any later version.
  18385. + *
  18386. + * This program is distributed in the hope that it will be useful,
  18387. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18388. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18389. + * GNU General Public License for more details.
  18390. + *
  18391. + * You should have received a copy of the GNU General Public License
  18392. + * along with this program; if not, write to the Free Software
  18393. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18394. + */
  18395. +
  18396. +/*
  18397. + * sysfs interface and lifetime management
  18398. + * they are necessary regardless sysfs is disabled.
  18399. + */
  18400. +
  18401. +#include <linux/fs.h>
  18402. +#include <linux/random.h>
  18403. +#include <linux/sysfs.h>
  18404. +#include "aufs.h"
  18405. +
  18406. +unsigned long sysaufs_si_mask;
  18407. +struct kset *sysaufs_ket;
  18408. +
  18409. +#define AuSiAttr(_name) { \
  18410. + .attr = { .name = __stringify(_name), .mode = 0444 }, \
  18411. + .show = sysaufs_si_##_name, \
  18412. +}
  18413. +
  18414. +static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
  18415. +struct attribute *sysaufs_si_attrs[] = {
  18416. + &sysaufs_si_attr_xi_path.attr,
  18417. + NULL,
  18418. +};
  18419. +
  18420. +static struct sysfs_ops au_sbi_ops = {
  18421. + .show = sysaufs_si_show
  18422. +};
  18423. +
  18424. +static struct kobj_type au_sbi_ktype = {
  18425. + .release = au_si_free,
  18426. + .sysfs_ops = &au_sbi_ops,
  18427. + .default_attrs = sysaufs_si_attrs
  18428. +};
  18429. +
  18430. +/* ---------------------------------------------------------------------- */
  18431. +
  18432. +int sysaufs_si_init(struct au_sbinfo *sbinfo)
  18433. +{
  18434. + int err;
  18435. +
  18436. + sbinfo->si_kobj.kset = sysaufs_ket;
  18437. + /* cf. sysaufs_name() */
  18438. + err = kobject_init_and_add
  18439. + (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_ket->kobj*/NULL,
  18440. + SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
  18441. +
  18442. + dbgaufs_si_null(sbinfo);
  18443. + if (!err) {
  18444. + err = dbgaufs_si_init(sbinfo);
  18445. + if (unlikely(err))
  18446. + kobject_put(&sbinfo->si_kobj);
  18447. + }
  18448. + return err;
  18449. +}
  18450. +
  18451. +void sysaufs_fin(void)
  18452. +{
  18453. + dbgaufs_fin();
  18454. + sysfs_remove_group(&sysaufs_ket->kobj, sysaufs_attr_group);
  18455. + kset_unregister(sysaufs_ket);
  18456. +}
  18457. +
  18458. +int __init sysaufs_init(void)
  18459. +{
  18460. + int err;
  18461. +
  18462. + do {
  18463. + get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
  18464. + } while (!sysaufs_si_mask);
  18465. +
  18466. + sysaufs_ket = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
  18467. + err = PTR_ERR(sysaufs_ket);
  18468. + if (IS_ERR(sysaufs_ket))
  18469. + goto out;
  18470. + err = sysfs_create_group(&sysaufs_ket->kobj, sysaufs_attr_group);
  18471. + if (unlikely(err)) {
  18472. + kset_unregister(sysaufs_ket);
  18473. + goto out;
  18474. + }
  18475. +
  18476. + err = dbgaufs_init();
  18477. + if (unlikely(err))
  18478. + sysaufs_fin();
  18479. + out:
  18480. + return err;
  18481. +}
  18482. diff -Nur linux-2.6.31.4.orig/fs/aufs/sysaufs.h linux-2.6.31.4/fs/aufs/sysaufs.h
  18483. --- linux-2.6.31.4.orig/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
  18484. +++ linux-2.6.31.4/fs/aufs/sysaufs.h 2009-10-18 11:26:01.000000000 +0200
  18485. @@ -0,0 +1,120 @@
  18486. +/*
  18487. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  18488. + *
  18489. + * This program, aufs is free software; you can redistribute it and/or modify
  18490. + * it under the terms of the GNU General Public License as published by
  18491. + * the Free Software Foundation; either version 2 of the License, or
  18492. + * (at your option) any later version.
  18493. + *
  18494. + * This program is distributed in the hope that it will be useful,
  18495. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18496. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18497. + * GNU General Public License for more details.
  18498. + *
  18499. + * You should have received a copy of the GNU General Public License
  18500. + * along with this program; if not, write to the Free Software
  18501. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18502. + */
  18503. +
  18504. +/*
  18505. + * sysfs interface and mount lifetime management
  18506. + */
  18507. +
  18508. +#ifndef __SYSAUFS_H__
  18509. +#define __SYSAUFS_H__
  18510. +
  18511. +#ifdef __KERNEL__
  18512. +
  18513. +#include <linux/sysfs.h>
  18514. +#include <linux/aufs_type.h>
  18515. +#include "module.h"
  18516. +
  18517. +struct super_block;
  18518. +struct au_sbinfo;
  18519. +
  18520. +struct sysaufs_si_attr {
  18521. + struct attribute attr;
  18522. + int (*show)(struct seq_file *seq, struct super_block *sb);
  18523. +};
  18524. +
  18525. +/* ---------------------------------------------------------------------- */
  18526. +
  18527. +/* sysaufs.c */
  18528. +extern unsigned long sysaufs_si_mask;
  18529. +extern struct kset *sysaufs_ket;
  18530. +extern struct attribute *sysaufs_si_attrs[];
  18531. +int sysaufs_si_init(struct au_sbinfo *sbinfo);
  18532. +int __init sysaufs_init(void);
  18533. +void sysaufs_fin(void);
  18534. +
  18535. +/* ---------------------------------------------------------------------- */
  18536. +
  18537. +/* some people doesn't like to show a pointer in kernel */
  18538. +static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
  18539. +{
  18540. + return sysaufs_si_mask ^ (unsigned long)sbinfo;
  18541. +}
  18542. +
  18543. +#define SysaufsSiNamePrefix "si_"
  18544. +#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16)
  18545. +static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
  18546. +{
  18547. + snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
  18548. + sysaufs_si_id(sbinfo));
  18549. +}
  18550. +
  18551. +struct au_branch;
  18552. +#ifdef CONFIG_SYSFS
  18553. +/* sysfs.c */
  18554. +extern struct attribute_group *sysaufs_attr_group;
  18555. +
  18556. +int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
  18557. +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
  18558. + char *buf);
  18559. +
  18560. +void sysaufs_br_init(struct au_branch *br);
  18561. +void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
  18562. +void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
  18563. +
  18564. +#define sysaufs_brs_init() do {} while (0)
  18565. +
  18566. +#else
  18567. +#define sysaufs_attr_group NULL
  18568. +
  18569. +static inline
  18570. +int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
  18571. +{
  18572. + return 0;
  18573. +}
  18574. +
  18575. +static inline
  18576. +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
  18577. + char *buf)
  18578. +{
  18579. + return 0;
  18580. +}
  18581. +
  18582. +static inline void sysaufs_br_init(struct au_branch *br)
  18583. +{
  18584. + /* empty */
  18585. +}
  18586. +
  18587. +static inline void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
  18588. +{
  18589. + /* nothing */
  18590. +}
  18591. +
  18592. +static inline void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
  18593. +{
  18594. + /* nothing */
  18595. +}
  18596. +
  18597. +static inline void sysaufs_brs_init(void)
  18598. +{
  18599. + sysaufs_brs = 0;
  18600. +}
  18601. +
  18602. +#endif /* CONFIG_SYSFS */
  18603. +
  18604. +#endif /* __KERNEL__ */
  18605. +#endif /* __SYSAUFS_H__ */
  18606. diff -Nur linux-2.6.31.4.orig/fs/aufs/sysfs.c linux-2.6.31.4/fs/aufs/sysfs.c
  18607. --- linux-2.6.31.4.orig/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100
  18608. +++ linux-2.6.31.4/fs/aufs/sysfs.c 2009-10-18 11:26:01.000000000 +0200
  18609. @@ -0,0 +1,210 @@
  18610. +/*
  18611. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  18612. + *
  18613. + * This program, aufs is free software; you can redistribute it and/or modify
  18614. + * it under the terms of the GNU General Public License as published by
  18615. + * the Free Software Foundation; either version 2 of the License, or
  18616. + * (at your option) any later version.
  18617. + *
  18618. + * This program is distributed in the hope that it will be useful,
  18619. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18620. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18621. + * GNU General Public License for more details.
  18622. + *
  18623. + * You should have received a copy of the GNU General Public License
  18624. + * along with this program; if not, write to the Free Software
  18625. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18626. + */
  18627. +
  18628. +/*
  18629. + * sysfs interface
  18630. + */
  18631. +
  18632. +#include <linux/fs.h>
  18633. +#include <linux/module.h>
  18634. +#include <linux/seq_file.h>
  18635. +#include <linux/sysfs.h>
  18636. +#include "aufs.h"
  18637. +
  18638. +static struct attribute *au_attr[] = {
  18639. + NULL, /* need to NULL terminate the list of attributes */
  18640. +};
  18641. +
  18642. +static struct attribute_group sysaufs_attr_group_body = {
  18643. + .attrs = au_attr
  18644. +};
  18645. +
  18646. +struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
  18647. +
  18648. +/* ---------------------------------------------------------------------- */
  18649. +
  18650. +int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
  18651. +{
  18652. + int err;
  18653. +
  18654. + SiMustAnyLock(sb);
  18655. +
  18656. + err = 0;
  18657. + if (au_opt_test(au_mntflags(sb), XINO)) {
  18658. + err = au_xino_path(seq, au_sbi(sb)->si_xib);
  18659. + seq_putc(seq, '\n');
  18660. + }
  18661. + return err;
  18662. +}
  18663. +
  18664. +/*
  18665. + * the lifetime of branch is independent from the entry under sysfs.
  18666. + * sysfs handles the lifetime of the entry, and never call ->show() after it is
  18667. + * unlinked.
  18668. + */
  18669. +static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
  18670. + aufs_bindex_t bindex)
  18671. +{
  18672. + struct path path;
  18673. + struct dentry *root;
  18674. + struct au_branch *br;
  18675. +
  18676. + AuDbg("b%d\n", bindex);
  18677. +
  18678. + root = sb->s_root;
  18679. + di_read_lock_parent(root, !AuLock_IR);
  18680. + br = au_sbr(sb, bindex);
  18681. + path.mnt = br->br_mnt;
  18682. + path.dentry = au_h_dptr(root, bindex);
  18683. + au_seq_path(seq, &path);
  18684. + di_read_unlock(root, !AuLock_IR);
  18685. + seq_printf(seq, "=%s\n", au_optstr_br_perm(br->br_perm));
  18686. + return 0;
  18687. +}
  18688. +
  18689. +/* ---------------------------------------------------------------------- */
  18690. +
  18691. +static struct seq_file *au_seq(char *p, ssize_t len)
  18692. +{
  18693. + struct seq_file *seq;
  18694. +
  18695. + seq = kzalloc(sizeof(*seq), GFP_NOFS);
  18696. + if (seq) {
  18697. + /* mutex_init(&seq.lock); */
  18698. + seq->buf = p;
  18699. + seq->size = len;
  18700. + return seq; /* success */
  18701. + }
  18702. +
  18703. + seq = ERR_PTR(-ENOMEM);
  18704. + return seq;
  18705. +}
  18706. +
  18707. +#define SysaufsBr_PREFIX "br"
  18708. +
  18709. +/* todo: file size may exceed PAGE_SIZE */
  18710. +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
  18711. + char *buf)
  18712. +{
  18713. + ssize_t err;
  18714. + long l;
  18715. + aufs_bindex_t bend;
  18716. + struct au_sbinfo *sbinfo;
  18717. + struct super_block *sb;
  18718. + struct seq_file *seq;
  18719. + char *name;
  18720. + struct attribute **cattr;
  18721. +
  18722. + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
  18723. + sb = sbinfo->si_sb;
  18724. + si_noflush_read_lock(sb);
  18725. +
  18726. + seq = au_seq(buf, PAGE_SIZE);
  18727. + err = PTR_ERR(seq);
  18728. + if (IS_ERR(seq))
  18729. + goto out;
  18730. +
  18731. + name = (void *)attr->name;
  18732. + cattr = sysaufs_si_attrs;
  18733. + while (*cattr) {
  18734. + if (!strcmp(name, (*cattr)->name)) {
  18735. + err = container_of(*cattr, struct sysaufs_si_attr, attr)
  18736. + ->show(seq, sb);
  18737. + goto out_seq;
  18738. + }
  18739. + cattr++;
  18740. + }
  18741. +
  18742. + bend = au_sbend(sb);
  18743. + if (!strncmp(name, SysaufsBr_PREFIX, sizeof(SysaufsBr_PREFIX) - 1)) {
  18744. + name += sizeof(SysaufsBr_PREFIX) - 1;
  18745. + err = strict_strtol(name, 10, &l);
  18746. + if (!err) {
  18747. + if (l <= bend)
  18748. + err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l);
  18749. + else
  18750. + err = -ENOENT;
  18751. + }
  18752. + goto out_seq;
  18753. + }
  18754. + BUG();
  18755. +
  18756. + out_seq:
  18757. + if (!err) {
  18758. + err = seq->count;
  18759. + /* sysfs limit */
  18760. + if (unlikely(err == PAGE_SIZE))
  18761. + err = -EFBIG;
  18762. + }
  18763. + kfree(seq);
  18764. + out:
  18765. + si_read_unlock(sb);
  18766. + return err;
  18767. +}
  18768. +
  18769. +/* ---------------------------------------------------------------------- */
  18770. +
  18771. +void sysaufs_br_init(struct au_branch *br)
  18772. +{
  18773. + br->br_attr.name = br->br_name;
  18774. + br->br_attr.mode = S_IRUGO;
  18775. + br->br_attr.owner = THIS_MODULE;
  18776. +}
  18777. +
  18778. +void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
  18779. +{
  18780. + struct au_branch *br;
  18781. + struct kobject *kobj;
  18782. + aufs_bindex_t bend;
  18783. +
  18784. + dbgaufs_brs_del(sb, bindex);
  18785. +
  18786. + if (!sysaufs_brs)
  18787. + return;
  18788. +
  18789. + kobj = &au_sbi(sb)->si_kobj;
  18790. + bend = au_sbend(sb);
  18791. + for (; bindex <= bend; bindex++) {
  18792. + br = au_sbr(sb, bindex);
  18793. + sysfs_remove_file(kobj, &br->br_attr);
  18794. + }
  18795. +}
  18796. +
  18797. +void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
  18798. +{
  18799. + int err;
  18800. + aufs_bindex_t bend;
  18801. + struct kobject *kobj;
  18802. + struct au_branch *br;
  18803. +
  18804. + dbgaufs_brs_add(sb, bindex);
  18805. +
  18806. + if (!sysaufs_brs)
  18807. + return;
  18808. +
  18809. + kobj = &au_sbi(sb)->si_kobj;
  18810. + bend = au_sbend(sb);
  18811. + for (; bindex <= bend; bindex++) {
  18812. + br = au_sbr(sb, bindex);
  18813. + snprintf(br->br_name, sizeof(br->br_name), SysaufsBr_PREFIX
  18814. + "%d", bindex);
  18815. + err = sysfs_create_file(kobj, &br->br_attr);
  18816. + if (unlikely(err))
  18817. + AuWarn("failed %s under sysfs(%d)\n", br->br_name, err);
  18818. + }
  18819. +}
  18820. diff -Nur linux-2.6.31.4.orig/fs/aufs/sysrq.c linux-2.6.31.4/fs/aufs/sysrq.c
  18821. --- linux-2.6.31.4.orig/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100
  18822. +++ linux-2.6.31.4/fs/aufs/sysrq.c 2009-10-18 11:26:01.000000000 +0200
  18823. @@ -0,0 +1,115 @@
  18824. +/*
  18825. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  18826. + *
  18827. + * This program, aufs is free software; you can redistribute it and/or modify
  18828. + * it under the terms of the GNU General Public License as published by
  18829. + * the Free Software Foundation; either version 2 of the License, or
  18830. + * (at your option) any later version.
  18831. + *
  18832. + * This program is distributed in the hope that it will be useful,
  18833. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18834. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18835. + * GNU General Public License for more details.
  18836. + *
  18837. + * You should have received a copy of the GNU General Public License
  18838. + * along with this program; if not, write to the Free Software
  18839. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18840. + */
  18841. +
  18842. +/*
  18843. + * magic sysrq hanlder
  18844. + */
  18845. +
  18846. +#include <linux/fs.h>
  18847. +#include <linux/module.h>
  18848. +#include <linux/moduleparam.h>
  18849. +/* #include <linux/sysrq.h> */
  18850. +#include "aufs.h"
  18851. +
  18852. +/* ---------------------------------------------------------------------- */
  18853. +
  18854. +static void sysrq_sb(struct super_block *sb)
  18855. +{
  18856. + char *plevel;
  18857. + struct au_sbinfo *sbinfo;
  18858. + struct file *file;
  18859. +
  18860. + plevel = au_plevel;
  18861. + au_plevel = KERN_WARNING;
  18862. + au_debug(1);
  18863. +
  18864. + sbinfo = au_sbi(sb);
  18865. + pr_warning("si=%lx\n", sysaufs_si_id(sbinfo));
  18866. + pr_warning(AUFS_NAME ": superblock\n");
  18867. + au_dpri_sb(sb);
  18868. + pr_warning(AUFS_NAME ": root dentry\n");
  18869. + au_dpri_dentry(sb->s_root);
  18870. + pr_warning(AUFS_NAME ": root inode\n");
  18871. + au_dpri_inode(sb->s_root->d_inode);
  18872. +#if 0
  18873. + struct inode *i;
  18874. + pr_warning(AUFS_NAME ": isolated inode\n");
  18875. + list_for_each_entry(i, &sb->s_inodes, i_sb_list)
  18876. + if (list_empty(&i->i_dentry))
  18877. + au_dpri_inode(i);
  18878. +#endif
  18879. + pr_warning(AUFS_NAME ": files\n");
  18880. + list_for_each_entry(file, &sb->s_files, f_u.fu_list)
  18881. + if (!special_file(file->f_dentry->d_inode->i_mode))
  18882. + au_dpri_file(file);
  18883. +
  18884. + au_plevel = plevel;
  18885. + au_debug(0);
  18886. +}
  18887. +
  18888. +/* ---------------------------------------------------------------------- */
  18889. +
  18890. +/* module parameter */
  18891. +static char *aufs_sysrq_key = "a";
  18892. +module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO);
  18893. +MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
  18894. +
  18895. +static void au_sysrq(int key __maybe_unused,
  18896. + struct tty_struct *tty __maybe_unused)
  18897. +{
  18898. + struct kobject *kobj;
  18899. + struct au_sbinfo *sbinfo;
  18900. +
  18901. + /* spin_lock(&sysaufs_ket->list_lock); */
  18902. + list_for_each_entry(kobj, &sysaufs_ket->list, entry) {
  18903. + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
  18904. + sysrq_sb(sbinfo->si_sb);
  18905. + }
  18906. + /* spin_unlock(&sysaufs_ket->list_lock); */
  18907. +}
  18908. +
  18909. +static struct sysrq_key_op au_sysrq_op = {
  18910. + .handler = au_sysrq,
  18911. + .help_msg = "Aufs",
  18912. + .action_msg = "Aufs",
  18913. + .enable_mask = SYSRQ_ENABLE_DUMP
  18914. +};
  18915. +
  18916. +/* ---------------------------------------------------------------------- */
  18917. +
  18918. +int __init au_sysrq_init(void)
  18919. +{
  18920. + int err;
  18921. + char key;
  18922. +
  18923. + err = -1;
  18924. + key = *aufs_sysrq_key;
  18925. + if ('a' <= key && key <= 'z')
  18926. + err = register_sysrq_key(key, &au_sysrq_op);
  18927. + if (unlikely(err))
  18928. + AuErr("err %d, sysrq=%c\n", err, key);
  18929. + return err;
  18930. +}
  18931. +
  18932. +void au_sysrq_fin(void)
  18933. +{
  18934. + int err;
  18935. + err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
  18936. + if (unlikely(err))
  18937. + AuErr("err %d (ignored)\n", err);
  18938. +}
  18939. diff -Nur linux-2.6.31.4.orig/fs/aufs/vdir.c linux-2.6.31.4/fs/aufs/vdir.c
  18940. --- linux-2.6.31.4.orig/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100
  18941. +++ linux-2.6.31.4/fs/aufs/vdir.c 2009-10-18 11:26:01.000000000 +0200
  18942. @@ -0,0 +1,882 @@
  18943. +/*
  18944. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  18945. + *
  18946. + * This program, aufs is free software; you can redistribute it and/or modify
  18947. + * it under the terms of the GNU General Public License as published by
  18948. + * the Free Software Foundation; either version 2 of the License, or
  18949. + * (at your option) any later version.
  18950. + *
  18951. + * This program is distributed in the hope that it will be useful,
  18952. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18953. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18954. + * GNU General Public License for more details.
  18955. + *
  18956. + * You should have received a copy of the GNU General Public License
  18957. + * along with this program; if not, write to the Free Software
  18958. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18959. + */
  18960. +
  18961. +/*
  18962. + * virtual or vertical directory
  18963. + */
  18964. +
  18965. +#include <linux/hash.h>
  18966. +#include "aufs.h"
  18967. +
  18968. +static unsigned int calc_size(int nlen)
  18969. +{
  18970. + BUILD_BUG_ON(sizeof(ino_t) != sizeof(long));
  18971. + return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
  18972. +}
  18973. +
  18974. +static int set_deblk_end(union au_vdir_deblk_p *p,
  18975. + union au_vdir_deblk_p *deblk_end)
  18976. +{
  18977. + if (calc_size(0) <= deblk_end->deblk - p->deblk) {
  18978. + p->de->de_str.len = 0;
  18979. + /* smp_mb(); */
  18980. + return 0;
  18981. + }
  18982. + return -1; /* error */
  18983. +}
  18984. +
  18985. +/* returns true or false */
  18986. +static int is_deblk_end(union au_vdir_deblk_p *p,
  18987. + union au_vdir_deblk_p *deblk_end)
  18988. +{
  18989. + if (calc_size(0) <= deblk_end->deblk - p->deblk)
  18990. + return !p->de->de_str.len;
  18991. + return 1;
  18992. +}
  18993. +
  18994. +static unsigned char *last_deblk(struct au_vdir *vdir)
  18995. +{
  18996. + return vdir->vd_deblk[vdir->vd_nblk - 1];
  18997. +}
  18998. +
  18999. +/* ---------------------------------------------------------------------- */
  19000. +
  19001. +/*
  19002. + * the allocated memory has to be freed by
  19003. + * au_nhash_wh_free() or au_nhash_de_free().
  19004. + */
  19005. +int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
  19006. +{
  19007. + struct hlist_head *head;
  19008. + unsigned int u;
  19009. +
  19010. + head = kmalloc(sizeof(*nhash->nh_head) * num_hash, gfp);
  19011. + if (head) {
  19012. + nhash->nh_num = num_hash;
  19013. + nhash->nh_head = head;
  19014. + for (u = 0; u < num_hash; u++)
  19015. + INIT_HLIST_HEAD(head++);
  19016. + return 0; /* success */
  19017. + }
  19018. +
  19019. + return -ENOMEM;
  19020. +}
  19021. +
  19022. +static void nhash_count(struct hlist_head *head)
  19023. +{
  19024. +#if 0
  19025. + unsigned long n;
  19026. + struct hlist_node *pos;
  19027. +
  19028. + n = 0;
  19029. + hlist_for_each(pos, head)
  19030. + n++;
  19031. + AuInfo("%lu\n", n);
  19032. +#endif
  19033. +}
  19034. +
  19035. +static void au_nhash_wh_do_free(struct hlist_head *head)
  19036. +{
  19037. + struct au_vdir_wh *tpos;
  19038. + struct hlist_node *pos, *node;
  19039. +
  19040. + hlist_for_each_entry_safe(tpos, pos, node, head, wh_hash) {
  19041. + /* hlist_del(pos); */
  19042. + kfree(tpos);
  19043. + }
  19044. +}
  19045. +
  19046. +static void au_nhash_de_do_free(struct hlist_head *head)
  19047. +{
  19048. + struct au_vdir_dehstr *tpos;
  19049. + struct hlist_node *pos, *node;
  19050. +
  19051. + hlist_for_each_entry_safe(tpos, pos, node, head, hash) {
  19052. + /* hlist_del(pos); */
  19053. + au_cache_free_dehstr(tpos);
  19054. + }
  19055. +}
  19056. +
  19057. +static void au_nhash_do_free(struct au_nhash *nhash,
  19058. + void (*free)(struct hlist_head *head))
  19059. +{
  19060. + unsigned int u, n;
  19061. + struct hlist_head *head;
  19062. +
  19063. + n = nhash->nh_num;
  19064. + head = nhash->nh_head;
  19065. + for (u = 0; u < n; u++) {
  19066. + nhash_count(head);
  19067. + free(head++);
  19068. + }
  19069. + kfree(nhash->nh_head);
  19070. +}
  19071. +
  19072. +void au_nhash_wh_free(struct au_nhash *whlist)
  19073. +{
  19074. + au_nhash_do_free(whlist, au_nhash_wh_do_free);
  19075. +}
  19076. +
  19077. +static void au_nhash_de_free(struct au_nhash *delist)
  19078. +{
  19079. + au_nhash_do_free(delist, au_nhash_de_do_free);
  19080. +}
  19081. +
  19082. +/* ---------------------------------------------------------------------- */
  19083. +
  19084. +int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
  19085. + int limit)
  19086. +{
  19087. + int num;
  19088. + unsigned int u, n;
  19089. + struct hlist_head *head;
  19090. + struct au_vdir_wh *tpos;
  19091. + struct hlist_node *pos;
  19092. +
  19093. + num = 0;
  19094. + n = whlist->nh_num;
  19095. + head = whlist->nh_head;
  19096. + for (u = 0; u < n; u++) {
  19097. + hlist_for_each_entry(tpos, pos, head, wh_hash)
  19098. + if (tpos->wh_bindex == btgt && ++num > limit)
  19099. + return 1;
  19100. + head++;
  19101. + }
  19102. + return 0;
  19103. +}
  19104. +
  19105. +static struct hlist_head *au_name_hash(struct au_nhash *nhash,
  19106. + unsigned char *name,
  19107. + unsigned int len)
  19108. +{
  19109. + unsigned int v;
  19110. + /* const unsigned int magic_bit = 12; */
  19111. +
  19112. + v = 0;
  19113. + while (len--)
  19114. + v += *name++;
  19115. + /* v = hash_long(v, magic_bit); */
  19116. + v %= nhash->nh_num;
  19117. + return nhash->nh_head + v;
  19118. +}
  19119. +
  19120. +static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
  19121. + int nlen)
  19122. +{
  19123. + return str->len == nlen && !memcmp(str->name, name, nlen);
  19124. +}
  19125. +
  19126. +/* returns found or not */
  19127. +int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
  19128. +{
  19129. + struct hlist_head *head;
  19130. + struct au_vdir_wh *tpos;
  19131. + struct hlist_node *pos;
  19132. + struct au_vdir_destr *str;
  19133. +
  19134. + head = au_name_hash(whlist, name, nlen);
  19135. + hlist_for_each_entry(tpos, pos, head, wh_hash) {
  19136. + str = &tpos->wh_str;
  19137. + AuDbg("%.*s\n", str->len, str->name);
  19138. + if (au_nhash_test_name(str, name, nlen))
  19139. + return 1;
  19140. + }
  19141. + return 0;
  19142. +}
  19143. +
  19144. +/* returns found(true) or not */
  19145. +static int test_known(struct au_nhash *delist, char *name, int nlen)
  19146. +{
  19147. + struct hlist_head *head;
  19148. + struct au_vdir_dehstr *tpos;
  19149. + struct hlist_node *pos;
  19150. + struct au_vdir_destr *str;
  19151. +
  19152. + head = au_name_hash(delist, name, nlen);
  19153. + hlist_for_each_entry(tpos, pos, head, hash) {
  19154. + str = tpos->str;
  19155. + AuDbg("%.*s\n", str->len, str->name);
  19156. + if (au_nhash_test_name(str, name, nlen))
  19157. + return 1;
  19158. + }
  19159. + return 0;
  19160. +}
  19161. +
  19162. +static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
  19163. + unsigned char d_type)
  19164. +{
  19165. +#ifdef CONFIG_AUFS_SHWH
  19166. + wh->wh_ino = ino;
  19167. + wh->wh_type = d_type;
  19168. +#endif
  19169. +}
  19170. +
  19171. +/* ---------------------------------------------------------------------- */
  19172. +
  19173. +int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
  19174. + unsigned int d_type, aufs_bindex_t bindex,
  19175. + unsigned char shwh)
  19176. +{
  19177. + int err;
  19178. + struct au_vdir_destr *str;
  19179. + struct au_vdir_wh *wh;
  19180. +
  19181. + AuDbg("%.*s\n", nlen, name);
  19182. + err = -ENOMEM;
  19183. + wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
  19184. + if (unlikely(!wh))
  19185. + goto out;
  19186. +
  19187. + err = 0;
  19188. + wh->wh_bindex = bindex;
  19189. + if (shwh)
  19190. + au_shwh_init_wh(wh, ino, d_type);
  19191. + str = &wh->wh_str;
  19192. + str->len = nlen;
  19193. + memcpy(str->name, name, nlen);
  19194. + hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
  19195. + /* smp_mb(); */
  19196. +
  19197. + out:
  19198. + return err;
  19199. +}
  19200. +
  19201. +static int append_deblk(struct au_vdir *vdir)
  19202. +{
  19203. + int err;
  19204. + unsigned long ul;
  19205. + const unsigned int deblk_sz = vdir->vd_deblk_sz;
  19206. + union au_vdir_deblk_p p, deblk_end;
  19207. + unsigned char **o;
  19208. +
  19209. + err = -ENOMEM;
  19210. + o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
  19211. + GFP_NOFS);
  19212. + if (unlikely(!o))
  19213. + goto out;
  19214. +
  19215. + vdir->vd_deblk = o;
  19216. + p.deblk = kmalloc(deblk_sz, GFP_NOFS);
  19217. + if (p.deblk) {
  19218. + ul = vdir->vd_nblk++;
  19219. + vdir->vd_deblk[ul] = p.deblk;
  19220. + vdir->vd_last.ul = ul;
  19221. + vdir->vd_last.p.deblk = p.deblk;
  19222. + deblk_end.deblk = p.deblk + deblk_sz;
  19223. + err = set_deblk_end(&p, &deblk_end);
  19224. + }
  19225. +
  19226. + out:
  19227. + return err;
  19228. +}
  19229. +
  19230. +static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
  19231. + unsigned int d_type, struct au_nhash *delist)
  19232. +{
  19233. + int err;
  19234. + unsigned int sz;
  19235. + const unsigned int deblk_sz = vdir->vd_deblk_sz;
  19236. + union au_vdir_deblk_p p, *room, deblk_end;
  19237. + struct au_vdir_dehstr *dehstr;
  19238. +
  19239. + p.deblk = last_deblk(vdir);
  19240. + deblk_end.deblk = p.deblk + deblk_sz;
  19241. + room = &vdir->vd_last.p;
  19242. + AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
  19243. + || !is_deblk_end(room, &deblk_end));
  19244. +
  19245. + sz = calc_size(nlen);
  19246. + if (unlikely(sz > deblk_end.deblk - room->deblk)) {
  19247. + err = append_deblk(vdir);
  19248. + if (unlikely(err))
  19249. + goto out;
  19250. +
  19251. + p.deblk = last_deblk(vdir);
  19252. + deblk_end.deblk = p.deblk + deblk_sz;
  19253. + /* smp_mb(); */
  19254. + AuDebugOn(room->deblk != p.deblk);
  19255. + }
  19256. +
  19257. + err = -ENOMEM;
  19258. + dehstr = au_cache_alloc_dehstr();
  19259. + if (unlikely(!dehstr))
  19260. + goto out;
  19261. +
  19262. + dehstr->str = &room->de->de_str;
  19263. + hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
  19264. + room->de->de_ino = ino;
  19265. + room->de->de_type = d_type;
  19266. + room->de->de_str.len = nlen;
  19267. + memcpy(room->de->de_str.name, name, nlen);
  19268. +
  19269. + err = 0;
  19270. + room->deblk += sz;
  19271. + if (unlikely(set_deblk_end(room, &deblk_end)))
  19272. + err = append_deblk(vdir);
  19273. + /* smp_mb(); */
  19274. +
  19275. + out:
  19276. + return err;
  19277. +}
  19278. +
  19279. +/* ---------------------------------------------------------------------- */
  19280. +
  19281. +void au_vdir_free(struct au_vdir *vdir)
  19282. +{
  19283. + unsigned char **deblk;
  19284. +
  19285. + deblk = vdir->vd_deblk;
  19286. + while (vdir->vd_nblk--)
  19287. + kfree(*deblk++);
  19288. + kfree(vdir->vd_deblk);
  19289. + au_cache_free_vdir(vdir);
  19290. +}
  19291. +
  19292. +static struct au_vdir *alloc_vdir(struct super_block *sb)
  19293. +{
  19294. + struct au_vdir *vdir;
  19295. + int err;
  19296. +
  19297. + SiMustAnyLock(sb);
  19298. +
  19299. + err = -ENOMEM;
  19300. + vdir = au_cache_alloc_vdir();
  19301. + if (unlikely(!vdir))
  19302. + goto out;
  19303. +
  19304. + vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
  19305. + if (unlikely(!vdir->vd_deblk))
  19306. + goto out_free;
  19307. +
  19308. + vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
  19309. + vdir->vd_nblk = 0;
  19310. + vdir->vd_version = 0;
  19311. + vdir->vd_jiffy = 0;
  19312. + err = append_deblk(vdir);
  19313. + if (!err)
  19314. + return vdir; /* success */
  19315. +
  19316. + kfree(vdir->vd_deblk);
  19317. +
  19318. + out_free:
  19319. + au_cache_free_vdir(vdir);
  19320. + out:
  19321. + vdir = ERR_PTR(err);
  19322. + return vdir;
  19323. +}
  19324. +
  19325. +static int reinit_vdir(struct au_vdir *vdir)
  19326. +{
  19327. + int err;
  19328. + union au_vdir_deblk_p p, deblk_end;
  19329. +
  19330. + while (vdir->vd_nblk > 1) {
  19331. + kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
  19332. + /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
  19333. + vdir->vd_nblk--;
  19334. + }
  19335. + p.deblk = vdir->vd_deblk[0];
  19336. + deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
  19337. + err = set_deblk_end(&p, &deblk_end);
  19338. + /* keep vd_dblk_sz */
  19339. + vdir->vd_last.ul = 0;
  19340. + vdir->vd_last.p.deblk = vdir->vd_deblk[0];
  19341. + vdir->vd_version = 0;
  19342. + vdir->vd_jiffy = 0;
  19343. + /* smp_mb(); */
  19344. + return err;
  19345. +}
  19346. +
  19347. +/* ---------------------------------------------------------------------- */
  19348. +
  19349. +static int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  19350. + unsigned int d_type, ino_t *ino)
  19351. +{
  19352. + int err;
  19353. + struct mutex *mtx;
  19354. + const int isdir = (d_type == DT_DIR);
  19355. +
  19356. + /* prevent hardlinks from race condition */
  19357. + mtx = NULL;
  19358. + if (!isdir) {
  19359. + mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx;
  19360. + mutex_lock(mtx);
  19361. + }
  19362. + err = au_xino_read(sb, bindex, h_ino, ino);
  19363. + if (unlikely(err))
  19364. + goto out;
  19365. +
  19366. + if (!*ino) {
  19367. + err = -EIO;
  19368. + *ino = au_xino_new_ino(sb);
  19369. + if (unlikely(!*ino))
  19370. + goto out;
  19371. + err = au_xino_write(sb, bindex, h_ino, *ino);
  19372. + if (unlikely(err))
  19373. + goto out;
  19374. + }
  19375. +
  19376. + out:
  19377. + if (!isdir)
  19378. + mutex_unlock(mtx);
  19379. + return err;
  19380. +}
  19381. +
  19382. +static int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  19383. + unsigned int d_type, ino_t *ino)
  19384. +{
  19385. +#ifdef CONFIG_AUFS_SHWH
  19386. + return au_ino(sb, bindex, h_ino, d_type, ino);
  19387. +#else
  19388. + return 0;
  19389. +#endif
  19390. +}
  19391. +
  19392. +#define AuFillVdir_CALLED 1
  19393. +#define AuFillVdir_WHABLE (1 << 1)
  19394. +#define AuFillVdir_SHWH (1 << 2)
  19395. +#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
  19396. +#define au_fset_fillvdir(flags, name) { (flags) |= AuFillVdir_##name; }
  19397. +#define au_fclr_fillvdir(flags, name) { (flags) &= ~AuFillVdir_##name; }
  19398. +
  19399. +#ifndef CONFIG_AUFS_SHWH
  19400. +#undef AuFillVdir_SHWH
  19401. +#define AuFillVdir_SHWH 0
  19402. +#endif
  19403. +
  19404. +struct fillvdir_arg {
  19405. + struct file *file;
  19406. + struct au_vdir *vdir;
  19407. + struct au_nhash delist;
  19408. + struct au_nhash whlist;
  19409. + aufs_bindex_t bindex;
  19410. + unsigned int flags;
  19411. + int err;
  19412. +};
  19413. +
  19414. +static int fillvdir(void *__arg, const char *__name, int nlen,
  19415. + loff_t offset __maybe_unused, u64 h_ino,
  19416. + unsigned int d_type)
  19417. +{
  19418. + struct fillvdir_arg *arg = __arg;
  19419. + char *name = (void *)__name;
  19420. + struct super_block *sb;
  19421. + ino_t ino;
  19422. + const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
  19423. +
  19424. + arg->err = 0;
  19425. + sb = arg->file->f_dentry->d_sb;
  19426. + au_fset_fillvdir(arg->flags, CALLED);
  19427. + /* smp_mb(); */
  19428. + if (nlen <= AUFS_WH_PFX_LEN
  19429. + || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
  19430. + if (test_known(&arg->delist, name, nlen)
  19431. + || au_nhash_test_known_wh(&arg->whlist, name, nlen))
  19432. + goto out; /* already exists or whiteouted */
  19433. +
  19434. + sb = arg->file->f_dentry->d_sb;
  19435. + arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
  19436. + if (!arg->err)
  19437. + arg->err = append_de(arg->vdir, name, nlen, ino,
  19438. + d_type, &arg->delist);
  19439. + } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
  19440. + name += AUFS_WH_PFX_LEN;
  19441. + nlen -= AUFS_WH_PFX_LEN;
  19442. + if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
  19443. + goto out; /* already whiteouted */
  19444. +
  19445. + if (shwh)
  19446. + arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
  19447. + &ino);
  19448. + if (!arg->err)
  19449. + arg->err = au_nhash_append_wh
  19450. + (&arg->whlist, name, nlen, ino, d_type,
  19451. + arg->bindex, shwh);
  19452. + }
  19453. +
  19454. + out:
  19455. + if (!arg->err)
  19456. + arg->vdir->vd_jiffy = jiffies;
  19457. + /* smp_mb(); */
  19458. + AuTraceErr(arg->err);
  19459. + return arg->err;
  19460. +}
  19461. +
  19462. +static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
  19463. + struct au_nhash *whlist, struct au_nhash *delist)
  19464. +{
  19465. +#ifdef CONFIG_AUFS_SHWH
  19466. + int err;
  19467. + unsigned int nh, u;
  19468. + struct hlist_head *head;
  19469. + struct au_vdir_wh *tpos;
  19470. + struct hlist_node *pos, *n;
  19471. + char *p, *o;
  19472. + struct au_vdir_destr *destr;
  19473. +
  19474. + AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
  19475. +
  19476. + err = -ENOMEM;
  19477. + o = p = __getname();
  19478. + if (unlikely(!p))
  19479. + goto out;
  19480. +
  19481. + err = 0;
  19482. + nh = whlist->nh_num;
  19483. + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
  19484. + p += AUFS_WH_PFX_LEN;
  19485. + for (u = 0; u < nh; u++) {
  19486. + head = whlist->nh_head + u;
  19487. + hlist_for_each_entry_safe(tpos, pos, n, head, wh_hash) {
  19488. + destr = &tpos->wh_str;
  19489. + memcpy(p, destr->name, destr->len);
  19490. + err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
  19491. + tpos->wh_ino, tpos->wh_type, delist);
  19492. + if (unlikely(err))
  19493. + break;
  19494. + }
  19495. + }
  19496. +
  19497. + __putname(o);
  19498. +
  19499. + out:
  19500. + AuTraceErr(err);
  19501. + return err;
  19502. +#else
  19503. + return 0;
  19504. +#endif
  19505. +}
  19506. +
  19507. +static int au_do_read_vdir(struct fillvdir_arg *arg)
  19508. +{
  19509. + int err;
  19510. + unsigned int rdhash;
  19511. + loff_t offset;
  19512. + aufs_bindex_t bend, bindex, bstart;
  19513. + unsigned char shwh;
  19514. + struct file *hf, *file;
  19515. + struct super_block *sb;
  19516. +
  19517. + file = arg->file;
  19518. + sb = file->f_dentry->d_sb;
  19519. + SiMustAnyLock(sb);
  19520. +
  19521. + rdhash = au_sbi(sb)->si_rdhash;
  19522. + err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
  19523. + if (unlikely(err))
  19524. + goto out;
  19525. + err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
  19526. + if (unlikely(err))
  19527. + goto out_delist;
  19528. +
  19529. + err = 0;
  19530. + arg->flags = 0;
  19531. + shwh = 0;
  19532. + if (au_opt_test(au_mntflags(sb), SHWH)) {
  19533. + shwh = 1;
  19534. + au_fset_fillvdir(arg->flags, SHWH);
  19535. + }
  19536. + bstart = au_fbstart(file);
  19537. + bend = au_fbend(file);
  19538. + for (bindex = bstart; !err && bindex <= bend; bindex++) {
  19539. + hf = au_h_fptr(file, bindex);
  19540. + if (!hf)
  19541. + continue;
  19542. +
  19543. + offset = vfsub_llseek(hf, 0, SEEK_SET);
  19544. + err = offset;
  19545. + if (unlikely(offset))
  19546. + break;
  19547. +
  19548. + arg->bindex = bindex;
  19549. + au_fclr_fillvdir(arg->flags, WHABLE);
  19550. + if (shwh
  19551. + || (bindex != bend
  19552. + && au_br_whable(au_sbr_perm(sb, bindex))))
  19553. + au_fset_fillvdir(arg->flags, WHABLE);
  19554. + do {
  19555. + arg->err = 0;
  19556. + au_fclr_fillvdir(arg->flags, CALLED);
  19557. + /* smp_mb(); */
  19558. + err = vfsub_readdir(hf, fillvdir, arg);
  19559. + if (err >= 0)
  19560. + err = arg->err;
  19561. + } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
  19562. + }
  19563. +
  19564. + if (!err && shwh)
  19565. + err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
  19566. +
  19567. + au_nhash_wh_free(&arg->whlist);
  19568. +
  19569. + out_delist:
  19570. + au_nhash_de_free(&arg->delist);
  19571. + out:
  19572. + return err;
  19573. +}
  19574. +
  19575. +static int read_vdir(struct file *file, int may_read)
  19576. +{
  19577. + int err;
  19578. + unsigned long expire;
  19579. + unsigned char do_read;
  19580. + struct fillvdir_arg arg;
  19581. + struct inode *inode;
  19582. + struct au_vdir *vdir, *allocated;
  19583. +
  19584. + err = 0;
  19585. + inode = file->f_dentry->d_inode;
  19586. + IMustLock(inode);
  19587. + SiMustAnyLock(inode->i_sb);
  19588. +
  19589. + allocated = NULL;
  19590. + do_read = 0;
  19591. + expire = au_sbi(inode->i_sb)->si_rdcache;
  19592. + vdir = au_ivdir(inode);
  19593. + if (!vdir) {
  19594. + do_read = 1;
  19595. + vdir = alloc_vdir(inode->i_sb);
  19596. + err = PTR_ERR(vdir);
  19597. + if (IS_ERR(vdir))
  19598. + goto out;
  19599. + err = 0;
  19600. + allocated = vdir;
  19601. + } else if (may_read
  19602. + && (inode->i_version != vdir->vd_version
  19603. + || time_after(jiffies, vdir->vd_jiffy + expire))) {
  19604. + do_read = 1;
  19605. + err = reinit_vdir(vdir);
  19606. + if (unlikely(err))
  19607. + goto out;
  19608. + }
  19609. +
  19610. + if (!do_read)
  19611. + return 0; /* success */
  19612. +
  19613. + arg.file = file;
  19614. + arg.vdir = vdir;
  19615. + err = au_do_read_vdir(&arg);
  19616. + if (!err) {
  19617. + /* file->f_pos = 0; */
  19618. + vdir->vd_version = inode->i_version;
  19619. + vdir->vd_last.ul = 0;
  19620. + vdir->vd_last.p.deblk = vdir->vd_deblk[0];
  19621. + if (allocated)
  19622. + au_set_ivdir(inode, allocated);
  19623. + } else if (allocated)
  19624. + au_vdir_free(allocated);
  19625. +
  19626. + out:
  19627. + return err;
  19628. +}
  19629. +
  19630. +static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
  19631. +{
  19632. + int err, rerr;
  19633. + unsigned long ul, n;
  19634. + const unsigned int deblk_sz = src->vd_deblk_sz;
  19635. +
  19636. + AuDebugOn(tgt->vd_nblk != 1);
  19637. +
  19638. + err = -ENOMEM;
  19639. + if (tgt->vd_nblk < src->vd_nblk) {
  19640. + unsigned char **p;
  19641. +
  19642. + p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
  19643. + GFP_NOFS);
  19644. + if (unlikely(!p))
  19645. + goto out;
  19646. + tgt->vd_deblk = p;
  19647. + }
  19648. +
  19649. + tgt->vd_nblk = src->vd_nblk;
  19650. + tgt->vd_deblk_sz = deblk_sz;
  19651. + memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
  19652. + /* tgt->vd_last.i = 0; */
  19653. + /* tgt->vd_last.p.deblk = tgt->vd_deblk[0]; */
  19654. + tgt->vd_version = src->vd_version;
  19655. + tgt->vd_jiffy = src->vd_jiffy;
  19656. +
  19657. + n = src->vd_nblk;
  19658. + for (ul = 1; ul < n; ul++) {
  19659. + tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
  19660. + GFP_NOFS);
  19661. + if (unlikely(!tgt->vd_deblk[ul]))
  19662. + goto out;
  19663. + }
  19664. + /* smp_mb(); */
  19665. + return 0; /* success */
  19666. +
  19667. + out:
  19668. + rerr = reinit_vdir(tgt);
  19669. + BUG_ON(rerr);
  19670. + return err;
  19671. +}
  19672. +
  19673. +int au_vdir_init(struct file *file)
  19674. +{
  19675. + int err;
  19676. + struct inode *inode;
  19677. + struct au_vdir *vdir_cache, *allocated;
  19678. +
  19679. + err = read_vdir(file, !file->f_pos);
  19680. + if (unlikely(err))
  19681. + goto out;
  19682. +
  19683. + allocated = NULL;
  19684. + vdir_cache = au_fvdir_cache(file);
  19685. + if (!vdir_cache) {
  19686. + vdir_cache = alloc_vdir(file->f_dentry->d_sb);
  19687. + err = PTR_ERR(vdir_cache);
  19688. + if (IS_ERR(vdir_cache))
  19689. + goto out;
  19690. + allocated = vdir_cache;
  19691. + } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
  19692. + err = reinit_vdir(vdir_cache);
  19693. + if (unlikely(err))
  19694. + goto out;
  19695. + } else
  19696. + return 0; /* success */
  19697. +
  19698. + inode = file->f_dentry->d_inode;
  19699. + err = copy_vdir(vdir_cache, au_ivdir(inode));
  19700. + if (!err) {
  19701. + file->f_version = inode->i_version;
  19702. + if (allocated)
  19703. + au_set_fvdir_cache(file, allocated);
  19704. + } else if (allocated)
  19705. + au_vdir_free(allocated);
  19706. +
  19707. + out:
  19708. + return err;
  19709. +}
  19710. +
  19711. +static loff_t calc_offset(struct au_vdir *vdir)
  19712. +{
  19713. + loff_t offset;
  19714. + union au_vdir_deblk_p p;
  19715. +
  19716. + p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
  19717. + offset = vdir->vd_last.p.deblk - p.deblk;
  19718. + offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
  19719. + return offset;
  19720. +}
  19721. +
  19722. +/* returns true or false */
  19723. +static int seek_vdir(struct file *file)
  19724. +{
  19725. + int valid;
  19726. + unsigned int deblk_sz;
  19727. + unsigned long ul, n;
  19728. + loff_t offset;
  19729. + union au_vdir_deblk_p p, deblk_end;
  19730. + struct au_vdir *vdir_cache;
  19731. +
  19732. + valid = 1;
  19733. + vdir_cache = au_fvdir_cache(file);
  19734. + offset = calc_offset(vdir_cache);
  19735. + AuDbg("offset %lld\n", offset);
  19736. + if (file->f_pos == offset)
  19737. + goto out;
  19738. +
  19739. + vdir_cache->vd_last.ul = 0;
  19740. + vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
  19741. + if (!file->f_pos)
  19742. + goto out;
  19743. +
  19744. + valid = 0;
  19745. + deblk_sz = vdir_cache->vd_deblk_sz;
  19746. + ul = div64_u64(file->f_pos, deblk_sz);
  19747. + AuDbg("ul %lu\n", ul);
  19748. + if (ul >= vdir_cache->vd_nblk)
  19749. + goto out;
  19750. +
  19751. + n = vdir_cache->vd_nblk;
  19752. + for (; ul < n; ul++) {
  19753. + p.deblk = vdir_cache->vd_deblk[ul];
  19754. + deblk_end.deblk = p.deblk + deblk_sz;
  19755. + offset = ul;
  19756. + offset *= deblk_sz;
  19757. + while (!is_deblk_end(&p, &deblk_end) && offset < file->f_pos) {
  19758. + unsigned int l;
  19759. +
  19760. + l = calc_size(p.de->de_str.len);
  19761. + offset += l;
  19762. + p.deblk += l;
  19763. + }
  19764. + if (!is_deblk_end(&p, &deblk_end)) {
  19765. + valid = 1;
  19766. + vdir_cache->vd_last.ul = ul;
  19767. + vdir_cache->vd_last.p = p;
  19768. + break;
  19769. + }
  19770. + }
  19771. +
  19772. + out:
  19773. + /* smp_mb(); */
  19774. + AuTraceErr(!valid);
  19775. + return valid;
  19776. +}
  19777. +
  19778. +int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir)
  19779. +{
  19780. + int err;
  19781. + unsigned int l, deblk_sz;
  19782. + union au_vdir_deblk_p deblk_end;
  19783. + struct au_vdir *vdir_cache;
  19784. + struct au_vdir_de *de;
  19785. +
  19786. + vdir_cache = au_fvdir_cache(file);
  19787. + if (!seek_vdir(file))
  19788. + return 0;
  19789. +
  19790. + deblk_sz = vdir_cache->vd_deblk_sz;
  19791. + while (1) {
  19792. + deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
  19793. + deblk_end.deblk += deblk_sz;
  19794. + while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
  19795. + de = vdir_cache->vd_last.p.de;
  19796. + AuDbg("%.*s, off%lld, i%lu, dt%d\n",
  19797. + de->de_str.len, de->de_str.name, file->f_pos,
  19798. + (unsigned long)de->de_ino, de->de_type);
  19799. + err = filldir(dirent, de->de_str.name, de->de_str.len,
  19800. + file->f_pos, de->de_ino, de->de_type);
  19801. + if (unlikely(err)) {
  19802. + AuTraceErr(err);
  19803. + /* todo: ignore the error caused by udba? */
  19804. + /* return err; */
  19805. + return 0;
  19806. + }
  19807. +
  19808. + l = calc_size(de->de_str.len);
  19809. + vdir_cache->vd_last.p.deblk += l;
  19810. + file->f_pos += l;
  19811. + }
  19812. + if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
  19813. + vdir_cache->vd_last.ul++;
  19814. + vdir_cache->vd_last.p.deblk
  19815. + = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
  19816. + file->f_pos = deblk_sz * vdir_cache->vd_last.ul;
  19817. + continue;
  19818. + }
  19819. + break;
  19820. + }
  19821. +
  19822. + /* smp_mb(); */
  19823. + return 0;
  19824. +}
  19825. diff -Nur linux-2.6.31.4.orig/fs/aufs/vfsub.c linux-2.6.31.4/fs/aufs/vfsub.c
  19826. --- linux-2.6.31.4.orig/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100
  19827. +++ linux-2.6.31.4/fs/aufs/vfsub.c 2009-10-18 11:26:01.000000000 +0200
  19828. @@ -0,0 +1,740 @@
  19829. +/*
  19830. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  19831. + *
  19832. + * This program, aufs is free software; you can redistribute it and/or modify
  19833. + * it under the terms of the GNU General Public License as published by
  19834. + * the Free Software Foundation; either version 2 of the License, or
  19835. + * (at your option) any later version.
  19836. + *
  19837. + * This program is distributed in the hope that it will be useful,
  19838. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19839. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19840. + * GNU General Public License for more details.
  19841. + *
  19842. + * You should have received a copy of the GNU General Public License
  19843. + * along with this program; if not, write to the Free Software
  19844. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  19845. + */
  19846. +
  19847. +/*
  19848. + * sub-routines for VFS
  19849. + */
  19850. +
  19851. +#include <linux/namei.h>
  19852. +#include <linux/security.h>
  19853. +#include <linux/splice.h>
  19854. +#include <linux/uaccess.h>
  19855. +#include "aufs.h"
  19856. +
  19857. +int vfsub_update_h_iattr(struct path *h_path, int *did)
  19858. +{
  19859. + int err;
  19860. + struct kstat st;
  19861. + struct super_block *h_sb;
  19862. +
  19863. + /* for remote fs, leave work for its getattr or d_revalidate */
  19864. + /* for bad i_attr fs, handle them in aufs_getattr() */
  19865. + /* still some fs may acquire i_mutex. we need to skip them */
  19866. + err = 0;
  19867. + if (!did)
  19868. + did = &err;
  19869. + h_sb = h_path->dentry->d_sb;
  19870. + *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
  19871. + if (*did)
  19872. + err = vfs_getattr(h_path->mnt, h_path->dentry, &st);
  19873. +
  19874. + return err;
  19875. +}
  19876. +
  19877. +/* ---------------------------------------------------------------------- */
  19878. +
  19879. +#ifdef CONFIG_IMA
  19880. +#error IMA is not supported since it does not work well. Wait for their fixing.
  19881. +#endif
  19882. +
  19883. +struct file *vfsub_filp_open(const char *path, int oflags, int mode)
  19884. +{
  19885. + struct file *file;
  19886. +
  19887. + lockdep_off();
  19888. + file = filp_open(path, oflags, mode);
  19889. + lockdep_on();
  19890. + if (IS_ERR(file))
  19891. + goto out;
  19892. + vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
  19893. +
  19894. + out:
  19895. + return file;
  19896. +}
  19897. +
  19898. +int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
  19899. +{
  19900. + int err;
  19901. +
  19902. + /* lockdep_off(); */
  19903. + err = kern_path(name, flags, path);
  19904. + /* lockdep_on(); */
  19905. + if (!err && path->dentry->d_inode)
  19906. + vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
  19907. + return err;
  19908. +}
  19909. +
  19910. +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
  19911. + int len)
  19912. +{
  19913. + struct path path = {
  19914. + .mnt = NULL
  19915. + };
  19916. +
  19917. + IMustLock(parent->d_inode);
  19918. +
  19919. + path.dentry = lookup_one_len(name, parent, len);
  19920. + if (IS_ERR(path.dentry))
  19921. + goto out;
  19922. + if (path.dentry->d_inode)
  19923. + vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
  19924. +
  19925. + out:
  19926. + return path.dentry;
  19927. +}
  19928. +
  19929. +struct dentry *vfsub_lookup_hash(struct nameidata *nd)
  19930. +{
  19931. + struct path path = {
  19932. + .mnt = nd->path.mnt
  19933. + };
  19934. +
  19935. + IMustLock(nd->path.dentry->d_inode);
  19936. +
  19937. + path.dentry = lookup_hash(nd);
  19938. + if (!IS_ERR(path.dentry) && path.dentry->d_inode)
  19939. + vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
  19940. +
  19941. + return path.dentry;
  19942. +}
  19943. +
  19944. +/* ---------------------------------------------------------------------- */
  19945. +
  19946. +struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
  19947. + struct dentry *d2, struct au_hinode *hdir2)
  19948. +{
  19949. + struct dentry *d;
  19950. +
  19951. + lockdep_off();
  19952. + d = lock_rename(d1, d2);
  19953. + lockdep_on();
  19954. + au_hin_suspend(hdir1);
  19955. + if (hdir1 != hdir2)
  19956. + au_hin_suspend(hdir2);
  19957. +
  19958. + return d;
  19959. +}
  19960. +
  19961. +void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
  19962. + struct dentry *d2, struct au_hinode *hdir2)
  19963. +{
  19964. + au_hin_resume(hdir1);
  19965. + if (hdir1 != hdir2)
  19966. + au_hin_resume(hdir2);
  19967. + lockdep_off();
  19968. + unlock_rename(d1, d2);
  19969. + lockdep_on();
  19970. +}
  19971. +
  19972. +/* ---------------------------------------------------------------------- */
  19973. +
  19974. +int vfsub_create(struct inode *dir, struct path *path, int mode)
  19975. +{
  19976. + int err;
  19977. + struct dentry *d;
  19978. +
  19979. + IMustLock(dir);
  19980. +
  19981. + d = path->dentry;
  19982. + path->dentry = d->d_parent;
  19983. + err = security_path_mknod(path, path->dentry, mode, 0);
  19984. + path->dentry = d;
  19985. + if (unlikely(err))
  19986. + goto out;
  19987. +
  19988. + if (au_test_fs_null_nd(dir->i_sb))
  19989. + err = vfs_create(dir, path->dentry, mode, NULL);
  19990. + else {
  19991. + struct nameidata h_nd;
  19992. +
  19993. + memset(&h_nd, 0, sizeof(h_nd));
  19994. + h_nd.flags = LOOKUP_CREATE;
  19995. + h_nd.intent.open.flags = O_CREAT
  19996. + | vfsub_fmode_to_uint(FMODE_READ);
  19997. + h_nd.intent.open.create_mode = mode;
  19998. + h_nd.path.dentry = path->dentry->d_parent;
  19999. + h_nd.path.mnt = path->mnt;
  20000. + path_get(&h_nd.path);
  20001. + err = vfs_create(dir, path->dentry, mode, &h_nd);
  20002. + path_put(&h_nd.path);
  20003. + }
  20004. +
  20005. + if (!err) {
  20006. + struct path tmp = *path;
  20007. + int did;
  20008. +
  20009. + vfsub_update_h_iattr(&tmp, &did);
  20010. + if (did) {
  20011. + tmp.dentry = path->dentry->d_parent;
  20012. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20013. + }
  20014. + /*ignore*/
  20015. + }
  20016. +
  20017. + out:
  20018. + return err;
  20019. +}
  20020. +
  20021. +int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
  20022. +{
  20023. + int err;
  20024. + struct dentry *d;
  20025. +
  20026. + IMustLock(dir);
  20027. +
  20028. + d = path->dentry;
  20029. + path->dentry = d->d_parent;
  20030. + err = security_path_symlink(path, path->dentry, symname);
  20031. + path->dentry = d;
  20032. + if (unlikely(err))
  20033. + goto out;
  20034. +
  20035. + err = vfs_symlink(dir, path->dentry, symname);
  20036. + if (!err) {
  20037. + struct path tmp = *path;
  20038. + int did;
  20039. +
  20040. + vfsub_update_h_iattr(&tmp, &did);
  20041. + if (did) {
  20042. + tmp.dentry = path->dentry->d_parent;
  20043. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20044. + }
  20045. + /*ignore*/
  20046. + }
  20047. +
  20048. + out:
  20049. + return err;
  20050. +}
  20051. +
  20052. +int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
  20053. +{
  20054. + int err;
  20055. + struct dentry *d;
  20056. +
  20057. + IMustLock(dir);
  20058. +
  20059. + d = path->dentry;
  20060. + path->dentry = d->d_parent;
  20061. + err = security_path_mknod(path, path->dentry, mode, dev);
  20062. + path->dentry = d;
  20063. + if (unlikely(err))
  20064. + goto out;
  20065. +
  20066. + err = vfs_mknod(dir, path->dentry, mode, dev);
  20067. + if (!err) {
  20068. + struct path tmp = *path;
  20069. + int did;
  20070. +
  20071. + vfsub_update_h_iattr(&tmp, &did);
  20072. + if (did) {
  20073. + tmp.dentry = path->dentry->d_parent;
  20074. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20075. + }
  20076. + /*ignore*/
  20077. + }
  20078. +
  20079. + out:
  20080. + return err;
  20081. +}
  20082. +
  20083. +static int au_test_nlink(struct inode *inode)
  20084. +{
  20085. + const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
  20086. +
  20087. + if (!au_test_fs_no_limit_nlink(inode->i_sb)
  20088. + || inode->i_nlink < link_max)
  20089. + return 0;
  20090. + return -EMLINK;
  20091. +}
  20092. +
  20093. +int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path)
  20094. +{
  20095. + int err;
  20096. + struct dentry *d;
  20097. +
  20098. + IMustLock(dir);
  20099. +
  20100. + err = au_test_nlink(src_dentry->d_inode);
  20101. + if (unlikely(err))
  20102. + return err;
  20103. +
  20104. + d = path->dentry;
  20105. + path->dentry = d->d_parent;
  20106. + err = security_path_link(src_dentry, path, path->dentry);
  20107. + path->dentry = d;
  20108. + if (unlikely(err))
  20109. + goto out;
  20110. +
  20111. + lockdep_off();
  20112. + err = vfs_link(src_dentry, dir, path->dentry);
  20113. + lockdep_on();
  20114. + if (!err) {
  20115. + struct path tmp = *path;
  20116. + int did;
  20117. +
  20118. + /* fuse has different memory inode for the same inumber */
  20119. + vfsub_update_h_iattr(&tmp, &did);
  20120. + if (did) {
  20121. + tmp.dentry = path->dentry->d_parent;
  20122. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20123. + tmp.dentry = src_dentry;
  20124. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20125. + }
  20126. + /*ignore*/
  20127. + }
  20128. +
  20129. + out:
  20130. + return err;
  20131. +}
  20132. +
  20133. +int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
  20134. + struct inode *dir, struct path *path)
  20135. +{
  20136. + int err;
  20137. + struct path tmp = {
  20138. + .mnt = path->mnt
  20139. + };
  20140. + struct dentry *d;
  20141. +
  20142. + IMustLock(dir);
  20143. + IMustLock(src_dir);
  20144. +
  20145. + d = path->dentry;
  20146. + path->dentry = d->d_parent;
  20147. + tmp.dentry = src_dentry->d_parent;
  20148. + err = security_path_rename(&tmp, src_dentry, path, path->dentry);
  20149. + path->dentry = d;
  20150. + if (unlikely(err))
  20151. + goto out;
  20152. +
  20153. + lockdep_off();
  20154. + err = vfs_rename(src_dir, src_dentry, dir, path->dentry);
  20155. + lockdep_on();
  20156. + if (!err) {
  20157. + int did;
  20158. +
  20159. + tmp.dentry = d->d_parent;
  20160. + vfsub_update_h_iattr(&tmp, &did);
  20161. + if (did) {
  20162. + tmp.dentry = src_dentry;
  20163. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20164. + tmp.dentry = src_dentry->d_parent;
  20165. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20166. + }
  20167. + /*ignore*/
  20168. + }
  20169. +
  20170. + out:
  20171. + return err;
  20172. +}
  20173. +
  20174. +int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
  20175. +{
  20176. + int err;
  20177. + struct dentry *d;
  20178. +
  20179. + IMustLock(dir);
  20180. +
  20181. + d = path->dentry;
  20182. + path->dentry = d->d_parent;
  20183. + err = security_path_mkdir(path, path->dentry, mode);
  20184. + path->dentry = d;
  20185. + if (unlikely(err))
  20186. + goto out;
  20187. +
  20188. + err = vfs_mkdir(dir, path->dentry, mode);
  20189. + if (!err) {
  20190. + struct path tmp = *path;
  20191. + int did;
  20192. +
  20193. + vfsub_update_h_iattr(&tmp, &did);
  20194. + if (did) {
  20195. + tmp.dentry = path->dentry->d_parent;
  20196. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20197. + }
  20198. + /*ignore*/
  20199. + }
  20200. +
  20201. + out:
  20202. + return err;
  20203. +}
  20204. +
  20205. +int vfsub_rmdir(struct inode *dir, struct path *path)
  20206. +{
  20207. + int err;
  20208. + struct dentry *d;
  20209. +
  20210. + IMustLock(dir);
  20211. +
  20212. + d = path->dentry;
  20213. + path->dentry = d->d_parent;
  20214. + err = security_path_rmdir(path, path->dentry);
  20215. + path->dentry = d;
  20216. + if (unlikely(err))
  20217. + goto out;
  20218. +
  20219. + lockdep_off();
  20220. + err = vfs_rmdir(dir, path->dentry);
  20221. + lockdep_on();
  20222. + if (!err) {
  20223. + struct path tmp = {
  20224. + .dentry = path->dentry->d_parent,
  20225. + .mnt = path->mnt
  20226. + };
  20227. +
  20228. + vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
  20229. + }
  20230. +
  20231. + out:
  20232. + return err;
  20233. +}
  20234. +
  20235. +/* ---------------------------------------------------------------------- */
  20236. +
  20237. +ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
  20238. + loff_t *ppos)
  20239. +{
  20240. + ssize_t err;
  20241. +
  20242. + err = vfs_read(file, ubuf, count, ppos);
  20243. + if (err >= 0)
  20244. + vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
  20245. + return err;
  20246. +}
  20247. +
  20248. +/* todo: kernel_read()? */
  20249. +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
  20250. + loff_t *ppos)
  20251. +{
  20252. + ssize_t err;
  20253. + mm_segment_t oldfs;
  20254. +
  20255. + oldfs = get_fs();
  20256. + set_fs(KERNEL_DS);
  20257. + err = vfsub_read_u(file, (char __user *)kbuf, count, ppos);
  20258. + set_fs(oldfs);
  20259. + return err;
  20260. +}
  20261. +
  20262. +ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
  20263. + loff_t *ppos)
  20264. +{
  20265. + ssize_t err;
  20266. +
  20267. + lockdep_off();
  20268. + err = vfs_write(file, ubuf, count, ppos);
  20269. + lockdep_on();
  20270. + if (err >= 0)
  20271. + vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
  20272. + return err;
  20273. +}
  20274. +
  20275. +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
  20276. +{
  20277. + ssize_t err;
  20278. + mm_segment_t oldfs;
  20279. +
  20280. + oldfs = get_fs();
  20281. + set_fs(KERNEL_DS);
  20282. + err = vfsub_write_u(file, (const char __user *)kbuf, count, ppos);
  20283. + set_fs(oldfs);
  20284. + return err;
  20285. +}
  20286. +
  20287. +int vfsub_readdir(struct file *file, filldir_t filldir, void *arg)
  20288. +{
  20289. + int err;
  20290. +
  20291. + lockdep_off();
  20292. + err = vfs_readdir(file, filldir, arg);
  20293. + lockdep_on();
  20294. + if (err >= 0)
  20295. + vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
  20296. + return err;
  20297. +}
  20298. +
  20299. +long vfsub_splice_to(struct file *in, loff_t *ppos,
  20300. + struct pipe_inode_info *pipe, size_t len,
  20301. + unsigned int flags)
  20302. +{
  20303. + long err;
  20304. +
  20305. + lockdep_off();
  20306. + err = do_splice_to(in, ppos, pipe, len, flags);
  20307. + lockdep_on();
  20308. + if (err >= 0)
  20309. + vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
  20310. + return err;
  20311. +}
  20312. +
  20313. +long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
  20314. + loff_t *ppos, size_t len, unsigned int flags)
  20315. +{
  20316. + long err;
  20317. +
  20318. + lockdep_off();
  20319. + err = do_splice_from(pipe, out, ppos, len, flags);
  20320. + lockdep_on();
  20321. + if (err >= 0)
  20322. + vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
  20323. + return err;
  20324. +}
  20325. +
  20326. +/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
  20327. +int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
  20328. + struct file *h_file)
  20329. +{
  20330. + int err;
  20331. + struct inode *h_inode;
  20332. +
  20333. + h_inode = h_path->dentry->d_inode;
  20334. + if (!h_file) {
  20335. + err = mnt_want_write(h_path->mnt);
  20336. + if (err)
  20337. + goto out;
  20338. + err = inode_permission(h_inode, MAY_WRITE);
  20339. + if (err)
  20340. + goto out_mnt;
  20341. + err = get_write_access(h_inode);
  20342. + if (err)
  20343. + goto out_mnt;
  20344. + err = break_lease(h_inode, vfsub_fmode_to_uint(FMODE_WRITE));
  20345. + if (err)
  20346. + goto out_inode;
  20347. + }
  20348. +
  20349. + err = locks_verify_truncate(h_inode, h_file, length);
  20350. + if (!err)
  20351. + err = security_path_truncate(h_path, length, attr);
  20352. + if (!err) {
  20353. + lockdep_off();
  20354. + err = do_truncate(h_path->dentry, length, attr, h_file);
  20355. + lockdep_on();
  20356. + }
  20357. +
  20358. + out_inode:
  20359. + if (!h_file)
  20360. + put_write_access(h_inode);
  20361. + out_mnt:
  20362. + if (!h_file)
  20363. + mnt_drop_write(h_path->mnt);
  20364. + out:
  20365. + return err;
  20366. +}
  20367. +
  20368. +/* ---------------------------------------------------------------------- */
  20369. +
  20370. +struct au_vfsub_mkdir_args {
  20371. + int *errp;
  20372. + struct inode *dir;
  20373. + struct path *path;
  20374. + int mode;
  20375. +};
  20376. +
  20377. +static void au_call_vfsub_mkdir(void *args)
  20378. +{
  20379. + struct au_vfsub_mkdir_args *a = args;
  20380. + *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
  20381. +}
  20382. +
  20383. +int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
  20384. +{
  20385. + int err, do_sio, wkq_err;
  20386. +
  20387. + do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
  20388. + if (!do_sio)
  20389. + err = vfsub_mkdir(dir, path, mode);
  20390. + else {
  20391. + struct au_vfsub_mkdir_args args = {
  20392. + .errp = &err,
  20393. + .dir = dir,
  20394. + .path = path,
  20395. + .mode = mode
  20396. + };
  20397. + wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
  20398. + if (unlikely(wkq_err))
  20399. + err = wkq_err;
  20400. + }
  20401. +
  20402. + return err;
  20403. +}
  20404. +
  20405. +struct au_vfsub_rmdir_args {
  20406. + int *errp;
  20407. + struct inode *dir;
  20408. + struct path *path;
  20409. +};
  20410. +
  20411. +static void au_call_vfsub_rmdir(void *args)
  20412. +{
  20413. + struct au_vfsub_rmdir_args *a = args;
  20414. + *a->errp = vfsub_rmdir(a->dir, a->path);
  20415. +}
  20416. +
  20417. +int vfsub_sio_rmdir(struct inode *dir, struct path *path)
  20418. +{
  20419. + int err, do_sio, wkq_err;
  20420. +
  20421. + do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
  20422. + if (!do_sio)
  20423. + err = vfsub_rmdir(dir, path);
  20424. + else {
  20425. + struct au_vfsub_rmdir_args args = {
  20426. + .errp = &err,
  20427. + .dir = dir,
  20428. + .path = path
  20429. + };
  20430. + wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
  20431. + if (unlikely(wkq_err))
  20432. + err = wkq_err;
  20433. + }
  20434. +
  20435. + return err;
  20436. +}
  20437. +
  20438. +/* ---------------------------------------------------------------------- */
  20439. +
  20440. +struct notify_change_args {
  20441. + int *errp;
  20442. + struct path *path;
  20443. + struct iattr *ia;
  20444. +};
  20445. +
  20446. +static void call_notify_change(void *args)
  20447. +{
  20448. + struct notify_change_args *a = args;
  20449. + struct inode *h_inode;
  20450. +
  20451. + h_inode = a->path->dentry->d_inode;
  20452. + IMustLock(h_inode);
  20453. +
  20454. + *a->errp = -EPERM;
  20455. + if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
  20456. + lockdep_off();
  20457. + *a->errp = notify_change(a->path->dentry, a->ia);
  20458. + lockdep_on();
  20459. + if (!*a->errp)
  20460. + vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
  20461. + }
  20462. + AuTraceErr(*a->errp);
  20463. +}
  20464. +
  20465. +int vfsub_notify_change(struct path *path, struct iattr *ia)
  20466. +{
  20467. + int err;
  20468. + struct notify_change_args args = {
  20469. + .errp = &err,
  20470. + .path = path,
  20471. + .ia = ia
  20472. + };
  20473. +
  20474. + call_notify_change(&args);
  20475. +
  20476. + return err;
  20477. +}
  20478. +
  20479. +int vfsub_sio_notify_change(struct path *path, struct iattr *ia)
  20480. +{
  20481. + int err, wkq_err;
  20482. + struct notify_change_args args = {
  20483. + .errp = &err,
  20484. + .path = path,
  20485. + .ia = ia
  20486. + };
  20487. +
  20488. + wkq_err = au_wkq_wait(call_notify_change, &args);
  20489. + if (unlikely(wkq_err))
  20490. + err = wkq_err;
  20491. +
  20492. + return err;
  20493. +}
  20494. +
  20495. +/* ---------------------------------------------------------------------- */
  20496. +
  20497. +struct unlink_args {
  20498. + int *errp;
  20499. + struct inode *dir;
  20500. + struct path *path;
  20501. +};
  20502. +
  20503. +static void call_unlink(void *args)
  20504. +{
  20505. + struct unlink_args *a = args;
  20506. + struct dentry *d = a->path->dentry;
  20507. + struct inode *h_inode;
  20508. + const int stop_sillyrename = (au_test_nfs(d->d_sb)
  20509. + && atomic_read(&d->d_count) == 1);
  20510. +
  20511. + IMustLock(a->dir);
  20512. +
  20513. + a->path->dentry = d->d_parent;
  20514. + *a->errp = security_path_unlink(a->path, d);
  20515. + a->path->dentry = d;
  20516. + if (unlikely(*a->errp))
  20517. + return;
  20518. +
  20519. + if (!stop_sillyrename)
  20520. + dget(d);
  20521. + h_inode = d->d_inode;
  20522. + if (h_inode)
  20523. + atomic_inc(&h_inode->i_count);
  20524. +
  20525. + lockdep_off();
  20526. + *a->errp = vfs_unlink(a->dir, d);
  20527. + lockdep_on();
  20528. + if (!*a->errp) {
  20529. + struct path tmp = {
  20530. + .dentry = d->d_parent,
  20531. + .mnt = a->path->mnt
  20532. + };
  20533. + vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
  20534. + }
  20535. +
  20536. + if (!stop_sillyrename)
  20537. + dput(d);
  20538. + if (h_inode)
  20539. + iput(h_inode);
  20540. +
  20541. + AuTraceErr(*a->errp);
  20542. +}
  20543. +
  20544. +/*
  20545. + * @dir: must be locked.
  20546. + * @dentry: target dentry.
  20547. + */
  20548. +int vfsub_unlink(struct inode *dir, struct path *path, int force)
  20549. +{
  20550. + int err;
  20551. + struct unlink_args args = {
  20552. + .errp = &err,
  20553. + .dir = dir,
  20554. + .path = path
  20555. + };
  20556. +
  20557. + if (!force)
  20558. + call_unlink(&args);
  20559. + else {
  20560. + int wkq_err;
  20561. +
  20562. + wkq_err = au_wkq_wait(call_unlink, &args);
  20563. + if (unlikely(wkq_err))
  20564. + err = wkq_err;
  20565. + }
  20566. +
  20567. + return err;
  20568. +}
  20569. diff -Nur linux-2.6.31.4.orig/fs/aufs/vfsub.h linux-2.6.31.4/fs/aufs/vfsub.h
  20570. --- linux-2.6.31.4.orig/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
  20571. +++ linux-2.6.31.4/fs/aufs/vfsub.h 2009-10-18 11:26:01.000000000 +0200
  20572. @@ -0,0 +1,172 @@
  20573. +/*
  20574. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  20575. + *
  20576. + * This program, aufs is free software; you can redistribute it and/or modify
  20577. + * it under the terms of the GNU General Public License as published by
  20578. + * the Free Software Foundation; either version 2 of the License, or
  20579. + * (at your option) any later version.
  20580. + *
  20581. + * This program is distributed in the hope that it will be useful,
  20582. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20583. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20584. + * GNU General Public License for more details.
  20585. + *
  20586. + * You should have received a copy of the GNU General Public License
  20587. + * along with this program; if not, write to the Free Software
  20588. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20589. + */
  20590. +
  20591. +/*
  20592. + * sub-routines for VFS
  20593. + */
  20594. +
  20595. +#ifndef __AUFS_VFSUB_H__
  20596. +#define __AUFS_VFSUB_H__
  20597. +
  20598. +#ifdef __KERNEL__
  20599. +
  20600. +#include <linux/fs.h>
  20601. +#include <linux/fs_stack.h>
  20602. +
  20603. +/* ---------------------------------------------------------------------- */
  20604. +
  20605. +/* lock subclass for lower inode */
  20606. +/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
  20607. +/* reduce? gave up. */
  20608. +enum {
  20609. + AuLsc_I_Begin = I_MUTEX_QUOTA, /* 4 */
  20610. + AuLsc_I_PARENT, /* lower inode, parent first */
  20611. + AuLsc_I_PARENT2, /* copyup dirs */
  20612. + AuLsc_I_PARENT3, /* copyup wh */
  20613. + AuLsc_I_CHILD,
  20614. + AuLsc_I_CHILD2,
  20615. + AuLsc_I_End
  20616. +};
  20617. +
  20618. +/* to debug easier, do not make them inlined functions */
  20619. +#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
  20620. +#define IMustLock(i) MtxMustLock(&(i)->i_mutex)
  20621. +
  20622. +/* ---------------------------------------------------------------------- */
  20623. +
  20624. +static inline void vfsub_copy_inode_size(struct inode *inode,
  20625. + struct inode *h_inode)
  20626. +{
  20627. + spin_lock(&inode->i_lock);
  20628. + fsstack_copy_inode_size(inode, h_inode);
  20629. + spin_unlock(&inode->i_lock);
  20630. +}
  20631. +
  20632. +int vfsub_update_h_iattr(struct path *h_path, int *did);
  20633. +struct file *vfsub_filp_open(const char *path, int oflags, int mode);
  20634. +int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
  20635. +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
  20636. + int len);
  20637. +struct dentry *vfsub_lookup_hash(struct nameidata *nd);
  20638. +
  20639. +/* ---------------------------------------------------------------------- */
  20640. +
  20641. +struct au_hinode;
  20642. +struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
  20643. + struct dentry *d2, struct au_hinode *hdir2);
  20644. +void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
  20645. + struct dentry *d2, struct au_hinode *hdir2);
  20646. +
  20647. +int vfsub_create(struct inode *dir, struct path *path, int mode);
  20648. +int vfsub_symlink(struct inode *dir, struct path *path,
  20649. + const char *symname);
  20650. +int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
  20651. +int vfsub_link(struct dentry *src_dentry, struct inode *dir,
  20652. + struct path *path);
  20653. +int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
  20654. + struct inode *hdir, struct path *path);
  20655. +int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
  20656. +int vfsub_rmdir(struct inode *dir, struct path *path);
  20657. +
  20658. +/* ---------------------------------------------------------------------- */
  20659. +
  20660. +ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
  20661. + loff_t *ppos);
  20662. +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
  20663. + loff_t *ppos);
  20664. +ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
  20665. + loff_t *ppos);
  20666. +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
  20667. + loff_t *ppos);
  20668. +int vfsub_readdir(struct file *file, filldir_t filldir, void *arg);
  20669. +
  20670. +static inline void vfsub_file_accessed(struct file *h_file)
  20671. +{
  20672. + file_accessed(h_file);
  20673. + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
  20674. +}
  20675. +
  20676. +static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
  20677. + struct dentry *h_dentry)
  20678. +{
  20679. + struct path h_path = {
  20680. + .dentry = h_dentry,
  20681. + .mnt = h_mnt
  20682. + };
  20683. + touch_atime(h_mnt, h_dentry);
  20684. + vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
  20685. +}
  20686. +
  20687. +long vfsub_splice_to(struct file *in, loff_t *ppos,
  20688. + struct pipe_inode_info *pipe, size_t len,
  20689. + unsigned int flags);
  20690. +long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
  20691. + loff_t *ppos, size_t len, unsigned int flags);
  20692. +int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
  20693. + struct file *h_file);
  20694. +
  20695. +/* ---------------------------------------------------------------------- */
  20696. +
  20697. +static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
  20698. +{
  20699. + loff_t err;
  20700. +
  20701. + lockdep_off();
  20702. + err = vfs_llseek(file, offset, origin);
  20703. + lockdep_on();
  20704. + return err;
  20705. +}
  20706. +
  20707. +/* ---------------------------------------------------------------------- */
  20708. +
  20709. +/* dirty workaround for strict type of fmode_t */
  20710. +union vfsub_fmu {
  20711. + fmode_t fm;
  20712. + unsigned int ui;
  20713. +};
  20714. +
  20715. +static inline unsigned int vfsub_fmode_to_uint(fmode_t fm)
  20716. +{
  20717. + union vfsub_fmu u = {
  20718. + .fm = fm
  20719. + };
  20720. +
  20721. + BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui));
  20722. +
  20723. + return u.ui;
  20724. +}
  20725. +
  20726. +static inline fmode_t vfsub_uint_to_fmode(unsigned int ui)
  20727. +{
  20728. + union vfsub_fmu u = {
  20729. + .ui = ui
  20730. + };
  20731. +
  20732. + return u.fm;
  20733. +}
  20734. +
  20735. +/* ---------------------------------------------------------------------- */
  20736. +
  20737. +int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
  20738. +int vfsub_sio_rmdir(struct inode *dir, struct path *path);
  20739. +int vfsub_sio_notify_change(struct path *path, struct iattr *ia);
  20740. +int vfsub_notify_change(struct path *path, struct iattr *ia);
  20741. +int vfsub_unlink(struct inode *dir, struct path *path, int force);
  20742. +
  20743. +#endif /* __KERNEL__ */
  20744. +#endif /* __AUFS_VFSUB_H__ */
  20745. diff -Nur linux-2.6.31.4.orig/fs/aufs/wbr_policy.c linux-2.6.31.4/fs/aufs/wbr_policy.c
  20746. --- linux-2.6.31.4.orig/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100
  20747. +++ linux-2.6.31.4/fs/aufs/wbr_policy.c 2009-10-18 11:26:01.000000000 +0200
  20748. @@ -0,0 +1,641 @@
  20749. +/*
  20750. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  20751. + *
  20752. + * This program, aufs is free software; you can redistribute it and/or modify
  20753. + * it under the terms of the GNU General Public License as published by
  20754. + * the Free Software Foundation; either version 2 of the License, or
  20755. + * (at your option) any later version.
  20756. + *
  20757. + * This program is distributed in the hope that it will be useful,
  20758. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20759. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20760. + * GNU General Public License for more details.
  20761. + *
  20762. + * You should have received a copy of the GNU General Public License
  20763. + * along with this program; if not, write to the Free Software
  20764. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20765. + */
  20766. +
  20767. +/*
  20768. + * policies for selecting one among multiple writable branches
  20769. + */
  20770. +
  20771. +#include <linux/statfs.h>
  20772. +#include "aufs.h"
  20773. +
  20774. +/* subset of cpup_attr() */
  20775. +static noinline_for_stack
  20776. +int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
  20777. +{
  20778. + int err, sbits;
  20779. + struct iattr ia;
  20780. + struct inode *h_isrc;
  20781. +
  20782. + h_isrc = h_src->d_inode;
  20783. + ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
  20784. + ia.ia_mode = h_isrc->i_mode;
  20785. + ia.ia_uid = h_isrc->i_uid;
  20786. + ia.ia_gid = h_isrc->i_gid;
  20787. + sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
  20788. + au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc);
  20789. + err = vfsub_sio_notify_change(h_path, &ia);
  20790. +
  20791. + /* is this nfs only? */
  20792. + if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
  20793. + ia.ia_valid = ATTR_FORCE | ATTR_MODE;
  20794. + ia.ia_mode = h_isrc->i_mode;
  20795. + err = vfsub_sio_notify_change(h_path, &ia);
  20796. + }
  20797. +
  20798. + return err;
  20799. +}
  20800. +
  20801. +#define AuCpdown_PARENT_OPQ 1
  20802. +#define AuCpdown_WHED (1 << 1)
  20803. +#define AuCpdown_MADE_DIR (1 << 2)
  20804. +#define AuCpdown_DIROPQ (1 << 3)
  20805. +#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name)
  20806. +#define au_fset_cpdown(flags, name) { (flags) |= AuCpdown_##name; }
  20807. +#define au_fclr_cpdown(flags, name) { (flags) &= ~AuCpdown_##name; }
  20808. +
  20809. +struct au_cpdown_dir_args {
  20810. + struct dentry *parent;
  20811. + unsigned int flags;
  20812. +};
  20813. +
  20814. +static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
  20815. + struct au_cpdown_dir_args *a)
  20816. +{
  20817. + int err;
  20818. + struct dentry *opq_dentry;
  20819. +
  20820. + opq_dentry = au_diropq_create(dentry, bdst);
  20821. + err = PTR_ERR(opq_dentry);
  20822. + if (IS_ERR(opq_dentry))
  20823. + goto out;
  20824. + dput(opq_dentry);
  20825. + au_fset_cpdown(a->flags, DIROPQ);
  20826. +
  20827. + out:
  20828. + return err;
  20829. +}
  20830. +
  20831. +static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
  20832. + struct inode *dir, aufs_bindex_t bdst)
  20833. +{
  20834. + int err;
  20835. + struct path h_path;
  20836. + struct au_branch *br;
  20837. +
  20838. + br = au_sbr(dentry->d_sb, bdst);
  20839. + h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
  20840. + err = PTR_ERR(h_path.dentry);
  20841. + if (IS_ERR(h_path.dentry))
  20842. + goto out;
  20843. +
  20844. + err = 0;
  20845. + if (h_path.dentry->d_inode) {
  20846. + h_path.mnt = br->br_mnt;
  20847. + err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
  20848. + dentry);
  20849. + }
  20850. + dput(h_path.dentry);
  20851. +
  20852. + out:
  20853. + return err;
  20854. +}
  20855. +
  20856. +static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
  20857. + struct dentry *h_parent, void *arg)
  20858. +{
  20859. + int err, rerr;
  20860. + aufs_bindex_t bend, bopq, bstart;
  20861. + unsigned char parent_opq;
  20862. + struct path h_path;
  20863. + struct dentry *parent;
  20864. + struct inode *h_dir, *h_inode, *inode, *dir;
  20865. + struct au_cpdown_dir_args *args = arg;
  20866. +
  20867. + bstart = au_dbstart(dentry);
  20868. + /* dentry is di-locked */
  20869. + parent = dget_parent(dentry);
  20870. + dir = parent->d_inode;
  20871. + h_dir = h_parent->d_inode;
  20872. + AuDebugOn(h_dir != au_h_iptr(dir, bdst));
  20873. + IMustLock(h_dir);
  20874. +
  20875. + err = au_lkup_neg(dentry, bdst);
  20876. + if (unlikely(err < 0))
  20877. + goto out;
  20878. + h_path.dentry = au_h_dptr(dentry, bdst);
  20879. + h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
  20880. + err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path,
  20881. + S_IRWXU | S_IRUGO | S_IXUGO);
  20882. + if (unlikely(err))
  20883. + goto out_put;
  20884. + au_fset_cpdown(args->flags, MADE_DIR);
  20885. +
  20886. + bend = au_dbend(dentry);
  20887. + bopq = au_dbdiropq(dentry);
  20888. + au_fclr_cpdown(args->flags, WHED);
  20889. + au_fclr_cpdown(args->flags, DIROPQ);
  20890. + if (au_dbwh(dentry) == bdst)
  20891. + au_fset_cpdown(args->flags, WHED);
  20892. + if (!au_ftest_cpdown(args->flags, PARENT_OPQ) && bopq <= bdst)
  20893. + au_fset_cpdown(args->flags, PARENT_OPQ);
  20894. + parent_opq = (au_ftest_cpdown(args->flags, PARENT_OPQ)
  20895. + && args->parent == dentry);
  20896. + h_inode = h_path.dentry->d_inode;
  20897. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  20898. + if (au_ftest_cpdown(args->flags, WHED)) {
  20899. + err = au_cpdown_dir_opq(dentry, bdst, args);
  20900. + if (unlikely(err)) {
  20901. + mutex_unlock(&h_inode->i_mutex);
  20902. + goto out_dir;
  20903. + }
  20904. + }
  20905. +
  20906. + err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart));
  20907. + mutex_unlock(&h_inode->i_mutex);
  20908. + if (unlikely(err))
  20909. + goto out_opq;
  20910. +
  20911. + if (au_ftest_cpdown(args->flags, WHED)) {
  20912. + err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
  20913. + if (unlikely(err))
  20914. + goto out_opq;
  20915. + }
  20916. +
  20917. + inode = dentry->d_inode;
  20918. + if (au_ibend(inode) < bdst)
  20919. + au_set_ibend(inode, bdst);
  20920. + au_set_h_iptr(inode, bdst, au_igrab(h_inode),
  20921. + au_hi_flags(inode, /*isdir*/1));
  20922. + goto out; /* success */
  20923. +
  20924. + /* revert */
  20925. + out_opq:
  20926. + if (au_ftest_cpdown(args->flags, DIROPQ)) {
  20927. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  20928. + rerr = au_diropq_remove(dentry, bdst);
  20929. + mutex_unlock(&h_inode->i_mutex);
  20930. + if (unlikely(rerr)) {
  20931. + AuIOErr("failed removing diropq for %.*s b%d (%d)\n",
  20932. + AuDLNPair(dentry), bdst, rerr);
  20933. + err = -EIO;
  20934. + goto out;
  20935. + }
  20936. + }
  20937. + out_dir:
  20938. + if (au_ftest_cpdown(args->flags, MADE_DIR)) {
  20939. + rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
  20940. + if (unlikely(rerr)) {
  20941. + AuIOErr("failed removing %.*s b%d (%d)\n",
  20942. + AuDLNPair(dentry), bdst, rerr);
  20943. + err = -EIO;
  20944. + }
  20945. + }
  20946. + out_put:
  20947. + au_set_h_dptr(dentry, bdst, NULL);
  20948. + if (au_dbend(dentry) == bdst)
  20949. + au_update_dbend(dentry);
  20950. + out:
  20951. + dput(parent);
  20952. + return err;
  20953. +}
  20954. +
  20955. +int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
  20956. +{
  20957. + int err;
  20958. + struct au_cpdown_dir_args args = {
  20959. + .parent = dget_parent(dentry),
  20960. + .flags = 0
  20961. + };
  20962. +
  20963. + err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &args);
  20964. + dput(args.parent);
  20965. +
  20966. + return err;
  20967. +}
  20968. +
  20969. +/* ---------------------------------------------------------------------- */
  20970. +
  20971. +/* policies for create */
  20972. +
  20973. +static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
  20974. +{
  20975. + for (; bindex >= 0; bindex--)
  20976. + if (!au_br_rdonly(au_sbr(sb, bindex)))
  20977. + return bindex;
  20978. + return -EROFS;
  20979. +}
  20980. +
  20981. +/* top down parent */
  20982. +static int au_wbr_create_tdp(struct dentry *dentry, int isdir __maybe_unused)
  20983. +{
  20984. + int err;
  20985. + aufs_bindex_t bstart, bindex;
  20986. + struct super_block *sb;
  20987. + struct dentry *parent, *h_parent;
  20988. +
  20989. + sb = dentry->d_sb;
  20990. + bstart = au_dbstart(dentry);
  20991. + err = bstart;
  20992. + if (!au_br_rdonly(au_sbr(sb, bstart)))
  20993. + goto out;
  20994. +
  20995. + err = -EROFS;
  20996. + parent = dget_parent(dentry);
  20997. + for (bindex = au_dbstart(parent); bindex < bstart; bindex++) {
  20998. + h_parent = au_h_dptr(parent, bindex);
  20999. + if (!h_parent || !h_parent->d_inode)
  21000. + continue;
  21001. +
  21002. + if (!au_br_rdonly(au_sbr(sb, bindex))) {
  21003. + err = bindex;
  21004. + break;
  21005. + }
  21006. + }
  21007. + dput(parent);
  21008. +
  21009. + /* bottom up here */
  21010. + if (unlikely(err < 0))
  21011. + err = au_wbr_bu(sb, bstart - 1);
  21012. +
  21013. + out:
  21014. + AuDbg("b%d\n", err);
  21015. + return err;
  21016. +}
  21017. +
  21018. +/* ---------------------------------------------------------------------- */
  21019. +
  21020. +/* an exception for the policy other than tdp */
  21021. +static int au_wbr_create_exp(struct dentry *dentry)
  21022. +{
  21023. + int err;
  21024. + aufs_bindex_t bwh, bdiropq;
  21025. + struct dentry *parent;
  21026. +
  21027. + err = -1;
  21028. + bwh = au_dbwh(dentry);
  21029. + parent = dget_parent(dentry);
  21030. + bdiropq = au_dbdiropq(parent);
  21031. + if (bwh >= 0) {
  21032. + if (bdiropq >= 0)
  21033. + err = min(bdiropq, bwh);
  21034. + else
  21035. + err = bwh;
  21036. + AuDbg("%d\n", err);
  21037. + } else if (bdiropq >= 0) {
  21038. + err = bdiropq;
  21039. + AuDbg("%d\n", err);
  21040. + }
  21041. + dput(parent);
  21042. +
  21043. + if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
  21044. + err = -1;
  21045. +
  21046. + AuDbg("%d\n", err);
  21047. + return err;
  21048. +}
  21049. +
  21050. +/* ---------------------------------------------------------------------- */
  21051. +
  21052. +/* round robin */
  21053. +static int au_wbr_create_init_rr(struct super_block *sb)
  21054. +{
  21055. + int err;
  21056. +
  21057. + err = au_wbr_bu(sb, au_sbend(sb));
  21058. + atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
  21059. + /* smp_mb(); */
  21060. +
  21061. + AuDbg("b%d\n", err);
  21062. + return err;
  21063. +}
  21064. +
  21065. +static int au_wbr_create_rr(struct dentry *dentry, int isdir)
  21066. +{
  21067. + int err, nbr;
  21068. + unsigned int u;
  21069. + aufs_bindex_t bindex, bend;
  21070. + struct super_block *sb;
  21071. + atomic_t *next;
  21072. +
  21073. + err = au_wbr_create_exp(dentry);
  21074. + if (err >= 0)
  21075. + goto out;
  21076. +
  21077. + sb = dentry->d_sb;
  21078. + next = &au_sbi(sb)->si_wbr_rr_next;
  21079. + bend = au_sbend(sb);
  21080. + nbr = bend + 1;
  21081. + for (bindex = 0; bindex <= bend; bindex++) {
  21082. + if (!isdir) {
  21083. + err = atomic_dec_return(next) + 1;
  21084. + /* modulo for 0 is meaningless */
  21085. + if (unlikely(!err))
  21086. + err = atomic_dec_return(next) + 1;
  21087. + } else
  21088. + err = atomic_read(next);
  21089. + AuDbg("%d\n", err);
  21090. + u = err;
  21091. + err = u % nbr;
  21092. + AuDbg("%d\n", err);
  21093. + if (!au_br_rdonly(au_sbr(sb, err)))
  21094. + break;
  21095. + err = -EROFS;
  21096. + }
  21097. +
  21098. + out:
  21099. + AuDbg("%d\n", err);
  21100. + return err;
  21101. +}
  21102. +
  21103. +/* ---------------------------------------------------------------------- */
  21104. +
  21105. +/* most free space */
  21106. +static void au_mfs(struct dentry *dentry)
  21107. +{
  21108. + struct super_block *sb;
  21109. + struct au_branch *br;
  21110. + struct au_wbr_mfs *mfs;
  21111. + aufs_bindex_t bindex, bend;
  21112. + int err;
  21113. + unsigned long long b, bavail;
  21114. + /* reduce the stack usage */
  21115. + struct kstatfs *st;
  21116. +
  21117. + st = kmalloc(sizeof(*st), GFP_NOFS);
  21118. + if (unlikely(!st)) {
  21119. + AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
  21120. + return;
  21121. + }
  21122. +
  21123. + bavail = 0;
  21124. + sb = dentry->d_sb;
  21125. + mfs = &au_sbi(sb)->si_wbr_mfs;
  21126. + MtxMustLock(&mfs->mfs_lock);
  21127. + mfs->mfs_bindex = -EROFS;
  21128. + mfs->mfsrr_bytes = 0;
  21129. + bend = au_sbend(sb);
  21130. + for (bindex = 0; bindex <= bend; bindex++) {
  21131. + br = au_sbr(sb, bindex);
  21132. + if (au_br_rdonly(br))
  21133. + continue;
  21134. +
  21135. + /* sb->s_root for NFS is unreliable */
  21136. + err = vfs_statfs(br->br_mnt->mnt_root, st);
  21137. + if (unlikely(err)) {
  21138. + AuWarn1("failed statfs, b%d, %d\n", bindex, err);
  21139. + continue;
  21140. + }
  21141. +
  21142. + /* when the available size is equal, select the lower one */
  21143. + BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
  21144. + || sizeof(b) < sizeof(st->f_bsize));
  21145. + b = st->f_bavail * st->f_bsize;
  21146. + br->br_wbr->wbr_bytes = b;
  21147. + if (b >= bavail) {
  21148. + bavail = b;
  21149. + mfs->mfs_bindex = bindex;
  21150. + mfs->mfs_jiffy = jiffies;
  21151. + }
  21152. + }
  21153. +
  21154. + mfs->mfsrr_bytes = bavail;
  21155. + AuDbg("b%d\n", mfs->mfs_bindex);
  21156. + kfree(st);
  21157. +}
  21158. +
  21159. +static int au_wbr_create_mfs(struct dentry *dentry, int isdir __maybe_unused)
  21160. +{
  21161. + int err;
  21162. + struct super_block *sb;
  21163. + struct au_wbr_mfs *mfs;
  21164. +
  21165. + err = au_wbr_create_exp(dentry);
  21166. + if (err >= 0)
  21167. + goto out;
  21168. +
  21169. + sb = dentry->d_sb;
  21170. + mfs = &au_sbi(sb)->si_wbr_mfs;
  21171. + mutex_lock(&mfs->mfs_lock);
  21172. + if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
  21173. + || mfs->mfs_bindex < 0
  21174. + || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
  21175. + au_mfs(dentry);
  21176. + mutex_unlock(&mfs->mfs_lock);
  21177. + err = mfs->mfs_bindex;
  21178. +
  21179. + out:
  21180. + AuDbg("b%d\n", err);
  21181. + return err;
  21182. +}
  21183. +
  21184. +static int au_wbr_create_init_mfs(struct super_block *sb)
  21185. +{
  21186. + struct au_wbr_mfs *mfs;
  21187. +
  21188. + mfs = &au_sbi(sb)->si_wbr_mfs;
  21189. + mutex_init(&mfs->mfs_lock);
  21190. + mfs->mfs_jiffy = 0;
  21191. + mfs->mfs_bindex = -EROFS;
  21192. +
  21193. + return 0;
  21194. +}
  21195. +
  21196. +static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
  21197. +{
  21198. + mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
  21199. + return 0;
  21200. +}
  21201. +
  21202. +/* ---------------------------------------------------------------------- */
  21203. +
  21204. +/* most free space and then round robin */
  21205. +static int au_wbr_create_mfsrr(struct dentry *dentry, int isdir)
  21206. +{
  21207. + int err;
  21208. + struct au_wbr_mfs *mfs;
  21209. +
  21210. + err = au_wbr_create_mfs(dentry, isdir);
  21211. + if (err >= 0) {
  21212. + mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
  21213. + mutex_lock(&mfs->mfs_lock);
  21214. + if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
  21215. + err = au_wbr_create_rr(dentry, isdir);
  21216. + mutex_unlock(&mfs->mfs_lock);
  21217. + }
  21218. +
  21219. + AuDbg("b%d\n", err);
  21220. + return err;
  21221. +}
  21222. +
  21223. +static int au_wbr_create_init_mfsrr(struct super_block *sb)
  21224. +{
  21225. + int err;
  21226. +
  21227. + au_wbr_create_init_mfs(sb); /* ignore */
  21228. + err = au_wbr_create_init_rr(sb);
  21229. +
  21230. + return err;
  21231. +}
  21232. +
  21233. +/* ---------------------------------------------------------------------- */
  21234. +
  21235. +/* top down parent and most free space */
  21236. +static int au_wbr_create_pmfs(struct dentry *dentry, int isdir)
  21237. +{
  21238. + int err, e2;
  21239. + unsigned long long b;
  21240. + aufs_bindex_t bindex, bstart, bend;
  21241. + struct super_block *sb;
  21242. + struct dentry *parent, *h_parent;
  21243. + struct au_branch *br;
  21244. +
  21245. + err = au_wbr_create_tdp(dentry, isdir);
  21246. + if (unlikely(err < 0))
  21247. + goto out;
  21248. + parent = dget_parent(dentry);
  21249. + bstart = au_dbstart(parent);
  21250. + bend = au_dbtaildir(parent);
  21251. + if (bstart == bend)
  21252. + goto out_parent; /* success */
  21253. +
  21254. + e2 = au_wbr_create_mfs(dentry, isdir);
  21255. + if (e2 < 0)
  21256. + goto out_parent; /* success */
  21257. +
  21258. + /* when the available size is equal, select upper one */
  21259. + sb = dentry->d_sb;
  21260. + br = au_sbr(sb, err);
  21261. + b = br->br_wbr->wbr_bytes;
  21262. + AuDbg("b%d, %llu\n", err, b);
  21263. +
  21264. + for (bindex = bstart; bindex <= bend; bindex++) {
  21265. + h_parent = au_h_dptr(parent, bindex);
  21266. + if (!h_parent || !h_parent->d_inode)
  21267. + continue;
  21268. +
  21269. + br = au_sbr(sb, bindex);
  21270. + if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
  21271. + b = br->br_wbr->wbr_bytes;
  21272. + err = bindex;
  21273. + AuDbg("b%d, %llu\n", err, b);
  21274. + }
  21275. + }
  21276. +
  21277. + out_parent:
  21278. + dput(parent);
  21279. + out:
  21280. + AuDbg("b%d\n", err);
  21281. + return err;
  21282. +}
  21283. +
  21284. +/* ---------------------------------------------------------------------- */
  21285. +
  21286. +/* policies for copyup */
  21287. +
  21288. +/* top down parent */
  21289. +static int au_wbr_copyup_tdp(struct dentry *dentry)
  21290. +{
  21291. + return au_wbr_create_tdp(dentry, /*isdir, anything is ok*/0);
  21292. +}
  21293. +
  21294. +/* bottom up parent */
  21295. +static int au_wbr_copyup_bup(struct dentry *dentry)
  21296. +{
  21297. + int err;
  21298. + aufs_bindex_t bindex, bstart;
  21299. + struct dentry *parent, *h_parent;
  21300. + struct super_block *sb;
  21301. +
  21302. + err = -EROFS;
  21303. + sb = dentry->d_sb;
  21304. + parent = dget_parent(dentry);
  21305. + bstart = au_dbstart(parent);
  21306. + for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) {
  21307. + h_parent = au_h_dptr(parent, bindex);
  21308. + if (!h_parent || !h_parent->d_inode)
  21309. + continue;
  21310. +
  21311. + if (!au_br_rdonly(au_sbr(sb, bindex))) {
  21312. + err = bindex;
  21313. + break;
  21314. + }
  21315. + }
  21316. + dput(parent);
  21317. +
  21318. + /* bottom up here */
  21319. + if (unlikely(err < 0))
  21320. + err = au_wbr_bu(sb, bstart - 1);
  21321. +
  21322. + AuDbg("b%d\n", err);
  21323. + return err;
  21324. +}
  21325. +
  21326. +/* bottom up */
  21327. +static int au_wbr_copyup_bu(struct dentry *dentry)
  21328. +{
  21329. + int err;
  21330. +
  21331. + err = au_wbr_bu(dentry->d_sb, au_dbstart(dentry));
  21332. +
  21333. + AuDbg("b%d\n", err);
  21334. + return err;
  21335. +}
  21336. +
  21337. +/* ---------------------------------------------------------------------- */
  21338. +
  21339. +struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
  21340. + [AuWbrCopyup_TDP] = {
  21341. + .copyup = au_wbr_copyup_tdp
  21342. + },
  21343. + [AuWbrCopyup_BUP] = {
  21344. + .copyup = au_wbr_copyup_bup
  21345. + },
  21346. + [AuWbrCopyup_BU] = {
  21347. + .copyup = au_wbr_copyup_bu
  21348. + }
  21349. +};
  21350. +
  21351. +struct au_wbr_create_operations au_wbr_create_ops[] = {
  21352. + [AuWbrCreate_TDP] = {
  21353. + .create = au_wbr_create_tdp
  21354. + },
  21355. + [AuWbrCreate_RR] = {
  21356. + .create = au_wbr_create_rr,
  21357. + .init = au_wbr_create_init_rr
  21358. + },
  21359. + [AuWbrCreate_MFS] = {
  21360. + .create = au_wbr_create_mfs,
  21361. + .init = au_wbr_create_init_mfs,
  21362. + .fin = au_wbr_create_fin_mfs
  21363. + },
  21364. + [AuWbrCreate_MFSV] = {
  21365. + .create = au_wbr_create_mfs,
  21366. + .init = au_wbr_create_init_mfs,
  21367. + .fin = au_wbr_create_fin_mfs
  21368. + },
  21369. + [AuWbrCreate_MFSRR] = {
  21370. + .create = au_wbr_create_mfsrr,
  21371. + .init = au_wbr_create_init_mfsrr,
  21372. + .fin = au_wbr_create_fin_mfs
  21373. + },
  21374. + [AuWbrCreate_MFSRRV] = {
  21375. + .create = au_wbr_create_mfsrr,
  21376. + .init = au_wbr_create_init_mfsrr,
  21377. + .fin = au_wbr_create_fin_mfs
  21378. + },
  21379. + [AuWbrCreate_PMFS] = {
  21380. + .create = au_wbr_create_pmfs,
  21381. + .init = au_wbr_create_init_mfs,
  21382. + .fin = au_wbr_create_fin_mfs
  21383. + },
  21384. + [AuWbrCreate_PMFSV] = {
  21385. + .create = au_wbr_create_pmfs,
  21386. + .init = au_wbr_create_init_mfs,
  21387. + .fin = au_wbr_create_fin_mfs
  21388. + }
  21389. +};
  21390. diff -Nur linux-2.6.31.4.orig/fs/aufs/whout.c linux-2.6.31.4/fs/aufs/whout.c
  21391. --- linux-2.6.31.4.orig/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100
  21392. +++ linux-2.6.31.4/fs/aufs/whout.c 2009-10-18 11:26:01.000000000 +0200
  21393. @@ -0,0 +1,1048 @@
  21394. +/*
  21395. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  21396. + *
  21397. + * This program, aufs is free software; you can redistribute it and/or modify
  21398. + * it under the terms of the GNU General Public License as published by
  21399. + * the Free Software Foundation; either version 2 of the License, or
  21400. + * (at your option) any later version.
  21401. + *
  21402. + * This program is distributed in the hope that it will be useful,
  21403. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21404. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21405. + * GNU General Public License for more details.
  21406. + *
  21407. + * You should have received a copy of the GNU General Public License
  21408. + * along with this program; if not, write to the Free Software
  21409. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  21410. + */
  21411. +
  21412. +/*
  21413. + * whiteout for logical deletion and opaque directory
  21414. + */
  21415. +
  21416. +#include <linux/fs.h>
  21417. +#include "aufs.h"
  21418. +
  21419. +#define WH_MASK S_IRUGO
  21420. +
  21421. +/*
  21422. + * If a directory contains this file, then it is opaque. We start with the
  21423. + * .wh. flag so that it is blocked by lookup.
  21424. + */
  21425. +static struct qstr diropq_name = {
  21426. + .name = AUFS_WH_DIROPQ,
  21427. + .len = sizeof(AUFS_WH_DIROPQ) - 1
  21428. +};
  21429. +
  21430. +/*
  21431. + * generate whiteout name, which is NOT terminated by NULL.
  21432. + * @name: original d_name.name
  21433. + * @len: original d_name.len
  21434. + * @wh: whiteout qstr
  21435. + * returns zero when succeeds, otherwise error.
  21436. + * succeeded value as wh->name should be freed by kfree().
  21437. + */
  21438. +int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
  21439. +{
  21440. + char *p;
  21441. +
  21442. + if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
  21443. + return -ENAMETOOLONG;
  21444. +
  21445. + wh->len = name->len + AUFS_WH_PFX_LEN;
  21446. + p = kmalloc(wh->len, GFP_NOFS);
  21447. + wh->name = p;
  21448. + if (p) {
  21449. + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
  21450. + memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
  21451. + /* smp_mb(); */
  21452. + return 0;
  21453. + }
  21454. + return -ENOMEM;
  21455. +}
  21456. +
  21457. +/* ---------------------------------------------------------------------- */
  21458. +
  21459. +/*
  21460. + * test if the @wh_name exists under @h_parent.
  21461. + * @try_sio specifies the necessary of super-io.
  21462. + */
  21463. +int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
  21464. + struct au_branch *br, int try_sio)
  21465. +{
  21466. + int err;
  21467. + struct dentry *wh_dentry;
  21468. + struct inode *h_dir;
  21469. +
  21470. + h_dir = h_parent->d_inode;
  21471. + if (!try_sio)
  21472. + wh_dentry = au_lkup_one(wh_name, h_parent, br, /*nd*/NULL);
  21473. + else
  21474. + wh_dentry = au_sio_lkup_one(wh_name, h_parent, br);
  21475. + err = PTR_ERR(wh_dentry);
  21476. + if (IS_ERR(wh_dentry))
  21477. + goto out;
  21478. +
  21479. + err = 0;
  21480. + if (!wh_dentry->d_inode)
  21481. + goto out_wh; /* success */
  21482. +
  21483. + err = 1;
  21484. + if (S_ISREG(wh_dentry->d_inode->i_mode))
  21485. + goto out_wh; /* success */
  21486. +
  21487. + err = -EIO;
  21488. + AuIOErr("%.*s Invalid whiteout entry type 0%o.\n",
  21489. + AuDLNPair(wh_dentry), wh_dentry->d_inode->i_mode);
  21490. +
  21491. + out_wh:
  21492. + dput(wh_dentry);
  21493. + out:
  21494. + return err;
  21495. +}
  21496. +
  21497. +/*
  21498. + * test if the @h_dentry sets opaque or not.
  21499. + */
  21500. +int au_diropq_test(struct dentry *h_dentry, struct au_branch *br)
  21501. +{
  21502. + int err;
  21503. + struct inode *h_dir;
  21504. +
  21505. + h_dir = h_dentry->d_inode;
  21506. + err = au_wh_test(h_dentry, &diropq_name, br,
  21507. + au_test_h_perm_sio(h_dir, MAY_EXEC));
  21508. + return err;
  21509. +}
  21510. +
  21511. +/*
  21512. + * returns a negative dentry whose name is unique and temporary.
  21513. + */
  21514. +struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
  21515. + struct qstr *prefix)
  21516. +{
  21517. +#define HEX_LEN 4
  21518. + struct dentry *dentry;
  21519. + int i;
  21520. + char defname[AUFS_WH_PFX_LEN * 2 + DNAME_INLINE_LEN_MIN + 1
  21521. + + HEX_LEN + 1], *name, *p;
  21522. + static unsigned short cnt;
  21523. + struct qstr qs;
  21524. +
  21525. + name = defname;
  21526. + qs.len = sizeof(defname) - DNAME_INLINE_LEN_MIN + prefix->len - 1;
  21527. + if (unlikely(prefix->len > DNAME_INLINE_LEN_MIN)) {
  21528. + dentry = ERR_PTR(-ENAMETOOLONG);
  21529. + if (unlikely(qs.len >= PATH_MAX))
  21530. + goto out;
  21531. + dentry = ERR_PTR(-ENOMEM);
  21532. + name = kmalloc(qs.len + 1, GFP_NOFS);
  21533. + if (unlikely(!name))
  21534. + goto out;
  21535. + }
  21536. +
  21537. + /* doubly whiteout-ed */
  21538. + memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
  21539. + p = name + AUFS_WH_PFX_LEN * 2;
  21540. + memcpy(p, prefix->name, prefix->len);
  21541. + p += prefix->len;
  21542. + *p++ = '.';
  21543. + AuDebugOn(name + qs.len + 1 - p <= HEX_LEN);
  21544. +
  21545. + qs.name = name;
  21546. + for (i = 0; i < 3; i++) {
  21547. + sprintf(p, "%.*d", HEX_LEN, cnt++);
  21548. + dentry = au_sio_lkup_one(&qs, h_parent, br);
  21549. + if (IS_ERR(dentry) || !dentry->d_inode)
  21550. + goto out_name;
  21551. + dput(dentry);
  21552. + }
  21553. + /* AuWarn("could not get random name\n"); */
  21554. + dentry = ERR_PTR(-EEXIST);
  21555. + AuDbg("%.*s\n", AuLNPair(&qs));
  21556. + BUG();
  21557. +
  21558. + out_name:
  21559. + if (name != defname)
  21560. + kfree(name);
  21561. + out:
  21562. + return dentry;
  21563. +#undef HEX_LEN
  21564. +}
  21565. +
  21566. +/*
  21567. + * rename the @h_dentry on @br to the whiteouted temporary name.
  21568. + */
  21569. +int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
  21570. +{
  21571. + int err;
  21572. + struct path h_path = {
  21573. + .mnt = br->br_mnt
  21574. + };
  21575. + struct inode *h_dir;
  21576. + struct dentry *h_parent;
  21577. +
  21578. + h_parent = h_dentry->d_parent; /* dir inode is locked */
  21579. + h_dir = h_parent->d_inode;
  21580. + IMustLock(h_dir);
  21581. +
  21582. + h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
  21583. + err = PTR_ERR(h_path.dentry);
  21584. + if (IS_ERR(h_path.dentry))
  21585. + goto out;
  21586. +
  21587. + /* under the same dir, no need to lock_rename() */
  21588. + err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path);
  21589. + AuTraceErr(err);
  21590. + dput(h_path.dentry);
  21591. +
  21592. + out:
  21593. + return err;
  21594. +}
  21595. +
  21596. +/* ---------------------------------------------------------------------- */
  21597. +/*
  21598. + * functions for removing a whiteout
  21599. + */
  21600. +
  21601. +static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
  21602. +{
  21603. + int force;
  21604. +
  21605. + /*
  21606. + * forces superio when the dir has a sticky bit.
  21607. + * this may be a violation of unix fs semantics.
  21608. + */
  21609. + force = (h_dir->i_mode & S_ISVTX)
  21610. + && h_path->dentry->d_inode->i_uid != current_fsuid();
  21611. + return vfsub_unlink(h_dir, h_path, force);
  21612. +}
  21613. +
  21614. +int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
  21615. + struct dentry *dentry)
  21616. +{
  21617. + int err;
  21618. +
  21619. + err = do_unlink_wh(h_dir, h_path);
  21620. + if (!err && dentry)
  21621. + au_set_dbwh(dentry, -1);
  21622. +
  21623. + return err;
  21624. +}
  21625. +
  21626. +static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
  21627. + struct au_branch *br)
  21628. +{
  21629. + int err;
  21630. + struct path h_path = {
  21631. + .mnt = br->br_mnt
  21632. + };
  21633. +
  21634. + err = 0;
  21635. + h_path.dentry = au_lkup_one(wh, h_parent, br, /*nd*/NULL);
  21636. + if (IS_ERR(h_path.dentry))
  21637. + err = PTR_ERR(h_path.dentry);
  21638. + else {
  21639. + if (h_path.dentry->d_inode
  21640. + && S_ISREG(h_path.dentry->d_inode->i_mode))
  21641. + err = do_unlink_wh(h_parent->d_inode, &h_path);
  21642. + dput(h_path.dentry);
  21643. + }
  21644. +
  21645. + return err;
  21646. +}
  21647. +
  21648. +/* ---------------------------------------------------------------------- */
  21649. +/*
  21650. + * initialize/clean whiteout for a branch
  21651. + */
  21652. +
  21653. +static void au_wh_clean(struct inode *h_dir, struct path *whpath,
  21654. + const int isdir)
  21655. +{
  21656. + int err;
  21657. +
  21658. + if (!whpath->dentry->d_inode)
  21659. + return;
  21660. +
  21661. + err = mnt_want_write(whpath->mnt);
  21662. + if (!err) {
  21663. + if (isdir)
  21664. + err = vfsub_rmdir(h_dir, whpath);
  21665. + else
  21666. + err = vfsub_unlink(h_dir, whpath, /*force*/0);
  21667. + mnt_drop_write(whpath->mnt);
  21668. + }
  21669. + if (unlikely(err))
  21670. + AuWarn("failed removing %.*s (%d), ignored.\n",
  21671. + AuDLNPair(whpath->dentry), err);
  21672. +}
  21673. +
  21674. +static int test_linkable(struct dentry *h_root)
  21675. +{
  21676. + struct inode *h_dir = h_root->d_inode;
  21677. +
  21678. + if (h_dir->i_op->link)
  21679. + return 0;
  21680. +
  21681. + AuErr("%.*s (%s) doesn't support link(2), use noplink and rw+nolwh\n",
  21682. + AuDLNPair(h_root), au_sbtype(h_root->d_sb));
  21683. + return -ENOSYS;
  21684. +}
  21685. +
  21686. +/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
  21687. +static int au_whdir(struct inode *h_dir, struct path *path)
  21688. +{
  21689. + int err;
  21690. +
  21691. + err = -EEXIST;
  21692. + if (!path->dentry->d_inode) {
  21693. + int mode = S_IRWXU;
  21694. +
  21695. + if (au_test_nfs(path->dentry->d_sb))
  21696. + mode |= S_IXUGO;
  21697. + err = mnt_want_write(path->mnt);
  21698. + if (!err) {
  21699. + err = vfsub_mkdir(h_dir, path, mode);
  21700. + mnt_drop_write(path->mnt);
  21701. + }
  21702. + } else if (S_ISDIR(path->dentry->d_inode->i_mode))
  21703. + err = 0;
  21704. + else
  21705. + AuErr("unknown %.*s exists\n", AuDLNPair(path->dentry));
  21706. +
  21707. + return err;
  21708. +}
  21709. +
  21710. +struct au_wh_base {
  21711. + const struct qstr *name;
  21712. + struct dentry *dentry;
  21713. +};
  21714. +
  21715. +static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
  21716. + struct path *h_path)
  21717. +{
  21718. + h_path->dentry = base[AuBrWh_BASE].dentry;
  21719. + au_wh_clean(h_dir, h_path, /*isdir*/0);
  21720. + h_path->dentry = base[AuBrWh_PLINK].dentry;
  21721. + au_wh_clean(h_dir, h_path, /*isdir*/1);
  21722. + h_path->dentry = base[AuBrWh_ORPH].dentry;
  21723. + au_wh_clean(h_dir, h_path, /*isdir*/1);
  21724. +}
  21725. +
  21726. +/*
  21727. + * returns tri-state,
  21728. + * minus: error, caller should print the mesage
  21729. + * zero: succuess
  21730. + * plus: error, caller should NOT print the mesage
  21731. + */
  21732. +static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
  21733. + int do_plink, struct au_wh_base base[],
  21734. + struct path *h_path)
  21735. +{
  21736. + int err;
  21737. + struct inode *h_dir;
  21738. +
  21739. + h_dir = h_root->d_inode;
  21740. + h_path->dentry = base[AuBrWh_BASE].dentry;
  21741. + au_wh_clean(h_dir, h_path, /*isdir*/0);
  21742. + h_path->dentry = base[AuBrWh_PLINK].dentry;
  21743. + if (do_plink) {
  21744. + err = test_linkable(h_root);
  21745. + if (unlikely(err)) {
  21746. + err = 1;
  21747. + goto out;
  21748. + }
  21749. +
  21750. + err = au_whdir(h_dir, h_path);
  21751. + if (unlikely(err))
  21752. + goto out;
  21753. + wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
  21754. + } else
  21755. + au_wh_clean(h_dir, h_path, /*isdir*/1);
  21756. + h_path->dentry = base[AuBrWh_ORPH].dentry;
  21757. + err = au_whdir(h_dir, h_path);
  21758. + if (unlikely(err))
  21759. + goto out;
  21760. + wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
  21761. +
  21762. + out:
  21763. + return err;
  21764. +}
  21765. +
  21766. +/*
  21767. + * for the moment, aufs supports the branch filesystem which does not support
  21768. + * link(2). testing on FAT which does not support i_op->setattr() fully either,
  21769. + * copyup failed. finally, such filesystem will not be used as the writable
  21770. + * branch.
  21771. + *
  21772. + * returns tri-state, see above.
  21773. + */
  21774. +static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
  21775. + int do_plink, struct au_wh_base base[],
  21776. + struct path *h_path)
  21777. +{
  21778. + int err;
  21779. + struct inode *h_dir;
  21780. +
  21781. + WbrWhMustWriteLock(wbr);
  21782. +
  21783. + err = test_linkable(h_root);
  21784. + if (unlikely(err)) {
  21785. + err = 1;
  21786. + goto out;
  21787. + }
  21788. +
  21789. + /*
  21790. + * todo: should this create be done in /sbin/mount.aufs helper?
  21791. + */
  21792. + err = -EEXIST;
  21793. + h_dir = h_root->d_inode;
  21794. + if (!base[AuBrWh_BASE].dentry->d_inode) {
  21795. + err = mnt_want_write(h_path->mnt);
  21796. + if (!err) {
  21797. + h_path->dentry = base[AuBrWh_BASE].dentry;
  21798. + err = vfsub_create(h_dir, h_path, WH_MASK);
  21799. + mnt_drop_write(h_path->mnt);
  21800. + }
  21801. + } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode))
  21802. + err = 0;
  21803. + else
  21804. + AuErr("unknown %.*s/%.*s exists\n",
  21805. + AuDLNPair(h_root), AuDLNPair(base[AuBrWh_BASE].dentry));
  21806. + if (unlikely(err))
  21807. + goto out;
  21808. +
  21809. + h_path->dentry = base[AuBrWh_PLINK].dentry;
  21810. + if (do_plink) {
  21811. + err = au_whdir(h_dir, h_path);
  21812. + if (unlikely(err))
  21813. + goto out;
  21814. + wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
  21815. + } else
  21816. + au_wh_clean(h_dir, h_path, /*isdir*/1);
  21817. + wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
  21818. +
  21819. + h_path->dentry = base[AuBrWh_ORPH].dentry;
  21820. + err = au_whdir(h_dir, h_path);
  21821. + if (unlikely(err))
  21822. + goto out;
  21823. + wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
  21824. +
  21825. + out:
  21826. + return err;
  21827. +}
  21828. +
  21829. +/*
  21830. + * initialize the whiteout base file/dir for @br.
  21831. + */
  21832. +int au_wh_init(struct dentry *h_root, struct au_branch *br,
  21833. + struct super_block *sb)
  21834. +{
  21835. + int err, i;
  21836. + const unsigned char do_plink
  21837. + = !!au_opt_test(au_mntflags(sb), PLINK);
  21838. + struct path path = {
  21839. + .mnt = br->br_mnt
  21840. + };
  21841. + struct inode *h_dir;
  21842. + struct au_wbr *wbr = br->br_wbr;
  21843. + static const struct qstr base_name[] = {
  21844. + [AuBrWh_BASE] = {
  21845. + .name = AUFS_BASE_NAME,
  21846. + .len = sizeof(AUFS_BASE_NAME) - 1
  21847. + },
  21848. + [AuBrWh_PLINK] = {
  21849. + .name = AUFS_PLINKDIR_NAME,
  21850. + .len = sizeof(AUFS_PLINKDIR_NAME) - 1
  21851. + },
  21852. + [AuBrWh_ORPH] = {
  21853. + .name = AUFS_ORPHDIR_NAME,
  21854. + .len = sizeof(AUFS_ORPHDIR_NAME) - 1
  21855. + }
  21856. + };
  21857. + struct au_wh_base base[] = {
  21858. + [AuBrWh_BASE] = {
  21859. + .name = base_name + AuBrWh_BASE,
  21860. + .dentry = NULL
  21861. + },
  21862. + [AuBrWh_PLINK] = {
  21863. + .name = base_name + AuBrWh_PLINK,
  21864. + .dentry = NULL
  21865. + },
  21866. + [AuBrWh_ORPH] = {
  21867. + .name = base_name + AuBrWh_ORPH,
  21868. + .dentry = NULL
  21869. + }
  21870. + };
  21871. +
  21872. + if (wbr)
  21873. + WbrWhMustWriteLock(wbr);
  21874. +
  21875. + h_dir = h_root->d_inode;
  21876. + for (i = 0; i < AuBrWh_Last; i++) {
  21877. + /* doubly whiteouted */
  21878. + struct dentry *d;
  21879. +
  21880. + d = au_wh_lkup(h_root, (void *)base[i].name, br);
  21881. + err = PTR_ERR(d);
  21882. + if (IS_ERR(d))
  21883. + goto out;
  21884. +
  21885. + base[i].dentry = d;
  21886. + AuDebugOn(wbr
  21887. + && wbr->wbr_wh[i]
  21888. + && wbr->wbr_wh[i] != base[i].dentry);
  21889. + }
  21890. +
  21891. + if (wbr)
  21892. + for (i = 0; i < AuBrWh_Last; i++) {
  21893. + dput(wbr->wbr_wh[i]);
  21894. + wbr->wbr_wh[i] = NULL;
  21895. + }
  21896. +
  21897. + err = 0;
  21898. +
  21899. + switch (br->br_perm) {
  21900. + case AuBrPerm_RO:
  21901. + case AuBrPerm_ROWH:
  21902. + case AuBrPerm_RR:
  21903. + case AuBrPerm_RRWH:
  21904. + au_wh_init_ro(h_dir, base, &path);
  21905. + break;
  21906. +
  21907. + case AuBrPerm_RWNoLinkWH:
  21908. + err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
  21909. + if (err > 0)
  21910. + goto out;
  21911. + else if (err)
  21912. + goto out_err;
  21913. + break;
  21914. +
  21915. + case AuBrPerm_RW:
  21916. + err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
  21917. + if (err > 0)
  21918. + goto out;
  21919. + else if (err)
  21920. + goto out_err;
  21921. + break;
  21922. +
  21923. + default:
  21924. + BUG();
  21925. + }
  21926. + goto out; /* success */
  21927. +
  21928. + out_err:
  21929. + AuErr("an error(%d) on the writable branch %.*s(%s)\n",
  21930. + err, AuDLNPair(h_root), au_sbtype(h_root->d_sb));
  21931. + out:
  21932. + for (i = 0; i < AuBrWh_Last; i++)
  21933. + dput(base[i].dentry);
  21934. + return err;
  21935. +}
  21936. +
  21937. +/* ---------------------------------------------------------------------- */
  21938. +/*
  21939. + * whiteouts are all hard-linked usually.
  21940. + * when its link count reaches a ceiling, we create a new whiteout base
  21941. + * asynchronously.
  21942. + */
  21943. +
  21944. +struct reinit_br_wh {
  21945. + struct super_block *sb;
  21946. + struct au_branch *br;
  21947. +};
  21948. +
  21949. +static void reinit_br_wh(void *arg)
  21950. +{
  21951. + int err;
  21952. + aufs_bindex_t bindex;
  21953. + struct path h_path;
  21954. + struct reinit_br_wh *a = arg;
  21955. + struct au_wbr *wbr;
  21956. + struct inode *dir;
  21957. + struct dentry *h_root;
  21958. + struct au_hinode *hdir;
  21959. +
  21960. + err = 0;
  21961. + wbr = a->br->br_wbr;
  21962. + /* big aufs lock */
  21963. + si_noflush_write_lock(a->sb);
  21964. + if (!au_br_writable(a->br->br_perm))
  21965. + goto out;
  21966. + bindex = au_br_index(a->sb, a->br->br_id);
  21967. + if (unlikely(bindex < 0))
  21968. + goto out;
  21969. +
  21970. + di_read_lock_parent(a->sb->s_root, AuLock_IR);
  21971. + dir = a->sb->s_root->d_inode;
  21972. + hdir = au_hi(dir, bindex);
  21973. + h_root = au_h_dptr(a->sb->s_root, bindex);
  21974. +
  21975. + au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT);
  21976. + wbr_wh_write_lock(wbr);
  21977. + err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
  21978. + h_root, a->br);
  21979. + if (!err) {
  21980. + err = mnt_want_write(a->br->br_mnt);
  21981. + if (!err) {
  21982. + h_path.dentry = wbr->wbr_whbase;
  21983. + h_path.mnt = a->br->br_mnt;
  21984. + err = vfsub_unlink(hdir->hi_inode, &h_path, /*force*/0);
  21985. + mnt_drop_write(a->br->br_mnt);
  21986. + }
  21987. + } else {
  21988. + AuWarn("%.*s is moved, ignored\n", AuDLNPair(wbr->wbr_whbase));
  21989. + err = 0;
  21990. + }
  21991. + dput(wbr->wbr_whbase);
  21992. + wbr->wbr_whbase = NULL;
  21993. + if (!err)
  21994. + err = au_wh_init(h_root, a->br, a->sb);
  21995. + wbr_wh_write_unlock(wbr);
  21996. + au_hin_imtx_unlock(hdir);
  21997. + di_read_unlock(a->sb->s_root, AuLock_IR);
  21998. +
  21999. + out:
  22000. + if (wbr)
  22001. + atomic_dec(&wbr->wbr_wh_running);
  22002. + atomic_dec(&a->br->br_count);
  22003. + au_nwt_done(&au_sbi(a->sb)->si_nowait);
  22004. + si_write_unlock(a->sb);
  22005. + kfree(arg);
  22006. + if (unlikely(err))
  22007. + AuIOErr("err %d\n", err);
  22008. +}
  22009. +
  22010. +static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
  22011. +{
  22012. + int do_dec, wkq_err;
  22013. + struct reinit_br_wh *arg;
  22014. +
  22015. + do_dec = 1;
  22016. + if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
  22017. + goto out;
  22018. +
  22019. + /* ignore ENOMEM */
  22020. + arg = kmalloc(sizeof(*arg), GFP_NOFS);
  22021. + if (arg) {
  22022. + /*
  22023. + * dec(wh_running), kfree(arg) and dec(br_count)
  22024. + * in reinit function
  22025. + */
  22026. + arg->sb = sb;
  22027. + arg->br = br;
  22028. + atomic_inc(&br->br_count);
  22029. + wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb);
  22030. + if (unlikely(wkq_err)) {
  22031. + atomic_dec(&br->br_wbr->wbr_wh_running);
  22032. + atomic_dec(&br->br_count);
  22033. + kfree(arg);
  22034. + }
  22035. + do_dec = 0;
  22036. + }
  22037. +
  22038. + out:
  22039. + if (do_dec)
  22040. + atomic_dec(&br->br_wbr->wbr_wh_running);
  22041. +}
  22042. +
  22043. +/* ---------------------------------------------------------------------- */
  22044. +
  22045. +/*
  22046. + * create the whiteout @wh.
  22047. + */
  22048. +static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
  22049. + struct dentry *wh)
  22050. +{
  22051. + int err;
  22052. + struct path h_path = {
  22053. + .dentry = wh
  22054. + };
  22055. + struct au_branch *br;
  22056. + struct au_wbr *wbr;
  22057. + struct dentry *h_parent;
  22058. + struct inode *h_dir;
  22059. +
  22060. + h_parent = wh->d_parent; /* dir inode is locked */
  22061. + h_dir = h_parent->d_inode;
  22062. + IMustLock(h_dir);
  22063. +
  22064. + br = au_sbr(sb, bindex);
  22065. + h_path.mnt = br->br_mnt;
  22066. + wbr = br->br_wbr;
  22067. + wbr_wh_read_lock(wbr);
  22068. + if (wbr->wbr_whbase) {
  22069. + err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path);
  22070. + if (!err || err != -EMLINK)
  22071. + goto out;
  22072. +
  22073. + /* link count full. re-initialize br_whbase. */
  22074. + kick_reinit_br_wh(sb, br);
  22075. + }
  22076. +
  22077. + /* return this error in this context */
  22078. + err = vfsub_create(h_dir, &h_path, WH_MASK);
  22079. +
  22080. + out:
  22081. + wbr_wh_read_unlock(wbr);
  22082. + return err;
  22083. +}
  22084. +
  22085. +/* ---------------------------------------------------------------------- */
  22086. +
  22087. +/*
  22088. + * create or remove the diropq.
  22089. + */
  22090. +static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
  22091. + unsigned int flags)
  22092. +{
  22093. + struct dentry *opq_dentry, *h_dentry;
  22094. + struct super_block *sb;
  22095. + struct au_branch *br;
  22096. + int err;
  22097. +
  22098. + sb = dentry->d_sb;
  22099. + br = au_sbr(sb, bindex);
  22100. + h_dentry = au_h_dptr(dentry, bindex);
  22101. + opq_dentry = au_lkup_one(&diropq_name, h_dentry, br, /*nd*/NULL);
  22102. + if (IS_ERR(opq_dentry))
  22103. + goto out;
  22104. +
  22105. + if (au_ftest_diropq(flags, CREATE)) {
  22106. + err = link_or_create_wh(sb, bindex, opq_dentry);
  22107. + if (!err) {
  22108. + au_set_dbdiropq(dentry, bindex);
  22109. + goto out; /* success */
  22110. + }
  22111. + } else {
  22112. + struct path tmp = {
  22113. + .dentry = opq_dentry,
  22114. + .mnt = br->br_mnt
  22115. + };
  22116. + err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp);
  22117. + if (!err)
  22118. + au_set_dbdiropq(dentry, -1);
  22119. + }
  22120. + dput(opq_dentry);
  22121. + opq_dentry = ERR_PTR(err);
  22122. +
  22123. + out:
  22124. + return opq_dentry;
  22125. +}
  22126. +
  22127. +struct do_diropq_args {
  22128. + struct dentry **errp;
  22129. + struct dentry *dentry;
  22130. + aufs_bindex_t bindex;
  22131. + unsigned int flags;
  22132. +};
  22133. +
  22134. +static void call_do_diropq(void *args)
  22135. +{
  22136. + struct do_diropq_args *a = args;
  22137. + *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
  22138. +}
  22139. +
  22140. +struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
  22141. + unsigned int flags)
  22142. +{
  22143. + struct dentry *diropq, *h_dentry;
  22144. +
  22145. + h_dentry = au_h_dptr(dentry, bindex);
  22146. + if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE))
  22147. + diropq = do_diropq(dentry, bindex, flags);
  22148. + else {
  22149. + int wkq_err;
  22150. + struct do_diropq_args args = {
  22151. + .errp = &diropq,
  22152. + .dentry = dentry,
  22153. + .bindex = bindex,
  22154. + .flags = flags
  22155. + };
  22156. +
  22157. + wkq_err = au_wkq_wait(call_do_diropq, &args);
  22158. + if (unlikely(wkq_err))
  22159. + diropq = ERR_PTR(wkq_err);
  22160. + }
  22161. +
  22162. + return diropq;
  22163. +}
  22164. +
  22165. +/* ---------------------------------------------------------------------- */
  22166. +
  22167. +/*
  22168. + * lookup whiteout dentry.
  22169. + * @h_parent: lower parent dentry which must exist and be locked
  22170. + * @base_name: name of dentry which will be whiteouted
  22171. + * returns dentry for whiteout.
  22172. + */
  22173. +struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
  22174. + struct au_branch *br)
  22175. +{
  22176. + int err;
  22177. + struct qstr wh_name;
  22178. + struct dentry *wh_dentry;
  22179. +
  22180. + err = au_wh_name_alloc(&wh_name, base_name);
  22181. + wh_dentry = ERR_PTR(err);
  22182. + if (!err) {
  22183. + wh_dentry = au_lkup_one(&wh_name, h_parent, br, /*nd*/NULL);
  22184. + kfree(wh_name.name);
  22185. + }
  22186. + return wh_dentry;
  22187. +}
  22188. +
  22189. +/*
  22190. + * link/create a whiteout for @dentry on @bindex.
  22191. + */
  22192. +struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
  22193. + struct dentry *h_parent)
  22194. +{
  22195. + struct dentry *wh_dentry;
  22196. + struct super_block *sb;
  22197. + int err;
  22198. +
  22199. + sb = dentry->d_sb;
  22200. + wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
  22201. + if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) {
  22202. + err = link_or_create_wh(sb, bindex, wh_dentry);
  22203. + if (!err)
  22204. + au_set_dbwh(dentry, bindex);
  22205. + else {
  22206. + dput(wh_dentry);
  22207. + wh_dentry = ERR_PTR(err);
  22208. + }
  22209. + }
  22210. +
  22211. + return wh_dentry;
  22212. +}
  22213. +
  22214. +/* ---------------------------------------------------------------------- */
  22215. +
  22216. +/* Delete all whiteouts in this directory on branch bindex. */
  22217. +static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
  22218. + aufs_bindex_t bindex, struct au_branch *br)
  22219. +{
  22220. + int err;
  22221. + unsigned long ul, n;
  22222. + struct qstr wh_name;
  22223. + char *p;
  22224. + struct hlist_head *head;
  22225. + struct au_vdir_wh *tpos;
  22226. + struct hlist_node *pos;
  22227. + struct au_vdir_destr *str;
  22228. +
  22229. + err = -ENOMEM;
  22230. + p = __getname();
  22231. + wh_name.name = p;
  22232. + if (unlikely(!wh_name.name))
  22233. + goto out;
  22234. +
  22235. + err = 0;
  22236. + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
  22237. + p += AUFS_WH_PFX_LEN;
  22238. + n = whlist->nh_num;
  22239. + head = whlist->nh_head;
  22240. + for (ul = 0; !err && ul < n; ul++, head++) {
  22241. + hlist_for_each_entry(tpos, pos, head, wh_hash) {
  22242. + if (tpos->wh_bindex != bindex)
  22243. + continue;
  22244. +
  22245. + str = &tpos->wh_str;
  22246. + if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
  22247. + memcpy(p, str->name, str->len);
  22248. + wh_name.len = AUFS_WH_PFX_LEN + str->len;
  22249. + err = unlink_wh_name(h_dentry, &wh_name, br);
  22250. + if (!err)
  22251. + continue;
  22252. + break;
  22253. + }
  22254. + AuIOErr("whiteout name too long %.*s\n",
  22255. + str->len, str->name);
  22256. + err = -EIO;
  22257. + break;
  22258. + }
  22259. + }
  22260. + __putname(wh_name.name);
  22261. +
  22262. + out:
  22263. + return err;
  22264. +}
  22265. +
  22266. +struct del_wh_children_args {
  22267. + int *errp;
  22268. + struct dentry *h_dentry;
  22269. + struct au_nhash whlist;
  22270. + aufs_bindex_t bindex;
  22271. + struct au_branch *br;
  22272. +};
  22273. +
  22274. +static void call_del_wh_children(void *args)
  22275. +{
  22276. + struct del_wh_children_args *a = args;
  22277. + *a->errp = del_wh_children(a->h_dentry, &a->whlist, a->bindex, a->br);
  22278. +}
  22279. +
  22280. +/* ---------------------------------------------------------------------- */
  22281. +
  22282. +struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
  22283. +{
  22284. + struct au_whtmp_rmdir *whtmp;
  22285. + int err;
  22286. +
  22287. + SiMustAnyLock(sb);
  22288. +
  22289. + whtmp = kmalloc(sizeof(*whtmp), gfp);
  22290. + if (unlikely(!whtmp)) {
  22291. + whtmp = ERR_PTR(-ENOMEM);
  22292. + goto out;
  22293. + }
  22294. +
  22295. + whtmp->dir = NULL;
  22296. + whtmp->wh_dentry = NULL;
  22297. + err = au_nhash_alloc(&whtmp->whlist, au_sbi(sb)->si_rdhash, gfp);
  22298. + if (!err)
  22299. + return whtmp; /* success */
  22300. +
  22301. + kfree(whtmp);
  22302. + whtmp = ERR_PTR(err);
  22303. +
  22304. + out:
  22305. + return whtmp;
  22306. +}
  22307. +
  22308. +void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
  22309. +{
  22310. + dput(whtmp->wh_dentry);
  22311. + iput(whtmp->dir);
  22312. + au_nhash_wh_free(&whtmp->whlist);
  22313. + kfree(whtmp);
  22314. +}
  22315. +
  22316. +/*
  22317. + * rmdir the whiteouted temporary named dir @h_dentry.
  22318. + * @whlist: whiteouted children.
  22319. + */
  22320. +int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
  22321. + struct dentry *wh_dentry, struct au_nhash *whlist)
  22322. +{
  22323. + int err;
  22324. + struct path h_tmp;
  22325. + struct inode *wh_inode, *h_dir;
  22326. + struct au_branch *br;
  22327. +
  22328. + h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
  22329. + IMustLock(h_dir);
  22330. +
  22331. + br = au_sbr(dir->i_sb, bindex);
  22332. + wh_inode = wh_dentry->d_inode;
  22333. + mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
  22334. +
  22335. + /*
  22336. + * someone else might change some whiteouts while we were sleeping.
  22337. + * it means this whlist may have an obsoleted entry.
  22338. + */
  22339. + if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
  22340. + err = del_wh_children(wh_dentry, whlist, bindex, br);
  22341. + else {
  22342. + int wkq_err;
  22343. + struct del_wh_children_args args = {
  22344. + .errp = &err,
  22345. + .h_dentry = wh_dentry,
  22346. + .whlist = *whlist,
  22347. + .bindex = bindex,
  22348. + .br = br
  22349. + };
  22350. +
  22351. + wkq_err = au_wkq_wait(call_del_wh_children, &args);
  22352. + if (unlikely(wkq_err))
  22353. + err = wkq_err;
  22354. + }
  22355. + mutex_unlock(&wh_inode->i_mutex);
  22356. +
  22357. + if (!err) {
  22358. + h_tmp.dentry = wh_dentry;
  22359. + h_tmp.mnt = br->br_mnt;
  22360. + err = vfsub_rmdir(h_dir, &h_tmp);
  22361. + /* d_drop(h_dentry); */
  22362. + }
  22363. +
  22364. + if (!err) {
  22365. + if (au_ibstart(dir) == bindex) {
  22366. + au_cpup_attr_timesizes(dir);
  22367. + drop_nlink(dir);
  22368. + }
  22369. + return 0; /* success */
  22370. + }
  22371. +
  22372. + AuWarn("failed removing %.*s(%d), ignored\n",
  22373. + AuDLNPair(wh_dentry), err);
  22374. + return err;
  22375. +}
  22376. +
  22377. +static void call_rmdir_whtmp(void *args)
  22378. +{
  22379. + int err;
  22380. + struct au_whtmp_rmdir *a = args;
  22381. + struct super_block *sb;
  22382. + struct dentry *h_parent;
  22383. + struct inode *h_dir;
  22384. + struct au_branch *br;
  22385. + struct au_hinode *hdir;
  22386. +
  22387. + /* rmdir by nfsd may cause deadlock with this i_mutex */
  22388. + /* mutex_lock(&a->dir->i_mutex); */
  22389. + sb = a->dir->i_sb;
  22390. + si_noflush_read_lock(sb);
  22391. + err = au_test_ro(sb, a->bindex, NULL);
  22392. + if (unlikely(err))
  22393. + goto out;
  22394. +
  22395. + err = -EIO;
  22396. + br = au_sbr(sb, a->bindex);
  22397. + ii_write_lock_parent(a->dir);
  22398. + h_parent = dget_parent(a->wh_dentry);
  22399. + h_dir = h_parent->d_inode;
  22400. + hdir = au_hi(a->dir, a->bindex);
  22401. + au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT);
  22402. + err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent, br);
  22403. + if (!err) {
  22404. + err = mnt_want_write(br->br_mnt);
  22405. + if (!err) {
  22406. + err = au_whtmp_rmdir(a->dir, a->bindex, a->wh_dentry,
  22407. + &a->whlist);
  22408. + mnt_drop_write(br->br_mnt);
  22409. + }
  22410. + }
  22411. + au_hin_imtx_unlock(hdir);
  22412. + dput(h_parent);
  22413. + ii_write_unlock(a->dir);
  22414. +
  22415. + out:
  22416. + /* mutex_unlock(&a->dir->i_mutex); */
  22417. + au_nwt_done(&au_sbi(sb)->si_nowait);
  22418. + si_read_unlock(sb);
  22419. + au_whtmp_rmdir_free(a);
  22420. + if (unlikely(err))
  22421. + AuIOErr("err %d\n", err);
  22422. +}
  22423. +
  22424. +void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
  22425. + struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
  22426. +{
  22427. + int wkq_err;
  22428. +
  22429. + IMustLock(dir);
  22430. +
  22431. + /* all post-process will be done in do_rmdir_whtmp(). */
  22432. + args->dir = au_igrab(dir);
  22433. + args->bindex = bindex;
  22434. + args->wh_dentry = dget(wh_dentry);
  22435. + wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, dir->i_sb);
  22436. + if (unlikely(wkq_err)) {
  22437. + AuWarn("rmdir error %.*s (%d), ignored\n",
  22438. + AuDLNPair(wh_dentry), wkq_err);
  22439. + au_whtmp_rmdir_free(args);
  22440. + }
  22441. +}
  22442. diff -Nur linux-2.6.31.4.orig/fs/aufs/whout.h linux-2.6.31.4/fs/aufs/whout.h
  22443. --- linux-2.6.31.4.orig/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100
  22444. +++ linux-2.6.31.4/fs/aufs/whout.h 2009-10-18 11:26:01.000000000 +0200
  22445. @@ -0,0 +1,87 @@
  22446. +/*
  22447. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  22448. + *
  22449. + * This program, aufs is free software; you can redistribute it and/or modify
  22450. + * it under the terms of the GNU General Public License as published by
  22451. + * the Free Software Foundation; either version 2 of the License, or
  22452. + * (at your option) any later version.
  22453. + *
  22454. + * This program is distributed in the hope that it will be useful,
  22455. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22456. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22457. + * GNU General Public License for more details.
  22458. + *
  22459. + * You should have received a copy of the GNU General Public License
  22460. + * along with this program; if not, write to the Free Software
  22461. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22462. + */
  22463. +
  22464. +/*
  22465. + * whiteout for logical deletion and opaque directory
  22466. + */
  22467. +
  22468. +#ifndef __AUFS_WHOUT_H__
  22469. +#define __AUFS_WHOUT_H__
  22470. +
  22471. +#ifdef __KERNEL__
  22472. +
  22473. +#include <linux/aufs_type.h>
  22474. +#include "dir.h"
  22475. +
  22476. +/* whout.c */
  22477. +int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
  22478. +struct au_branch;
  22479. +int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
  22480. + struct au_branch *br, int try_sio);
  22481. +int au_diropq_test(struct dentry *h_dentry, struct au_branch *br);
  22482. +struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
  22483. + struct qstr *prefix);
  22484. +int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
  22485. +int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
  22486. + struct dentry *dentry);
  22487. +int au_wh_init(struct dentry *h_parent, struct au_branch *br,
  22488. + struct super_block *sb);
  22489. +
  22490. +/* diropq flags */
  22491. +#define AuDiropq_CREATE 1
  22492. +#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name)
  22493. +#define au_fset_diropq(flags, name) { (flags) |= AuDiropq_##name; }
  22494. +#define au_fclr_diropq(flags, name) { (flags) &= ~AuDiropq_##name; }
  22495. +
  22496. +struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
  22497. + unsigned int flags);
  22498. +struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
  22499. + struct au_branch *br);
  22500. +struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
  22501. + struct dentry *h_parent);
  22502. +
  22503. +/* real rmdir for the whiteout-ed dir */
  22504. +struct au_whtmp_rmdir {
  22505. + struct inode *dir;
  22506. + aufs_bindex_t bindex;
  22507. + struct dentry *wh_dentry;
  22508. + struct au_nhash whlist;
  22509. +};
  22510. +
  22511. +struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
  22512. +void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
  22513. +int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
  22514. + struct dentry *wh_dentry, struct au_nhash *whlist);
  22515. +void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
  22516. + struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
  22517. +
  22518. +/* ---------------------------------------------------------------------- */
  22519. +
  22520. +static inline struct dentry *au_diropq_create(struct dentry *dentry,
  22521. + aufs_bindex_t bindex)
  22522. +{
  22523. + return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
  22524. +}
  22525. +
  22526. +static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
  22527. +{
  22528. + return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
  22529. +}
  22530. +
  22531. +#endif /* __KERNEL__ */
  22532. +#endif /* __AUFS_WHOUT_H__ */
  22533. diff -Nur linux-2.6.31.4.orig/fs/aufs/wkq.c linux-2.6.31.4/fs/aufs/wkq.c
  22534. --- linux-2.6.31.4.orig/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100
  22535. +++ linux-2.6.31.4/fs/aufs/wkq.c 2009-10-18 11:26:01.000000000 +0200
  22536. @@ -0,0 +1,259 @@
  22537. +/*
  22538. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  22539. + *
  22540. + * This program, aufs is free software; you can redistribute it and/or modify
  22541. + * it under the terms of the GNU General Public License as published by
  22542. + * the Free Software Foundation; either version 2 of the License, or
  22543. + * (at your option) any later version.
  22544. + *
  22545. + * This program is distributed in the hope that it will be useful,
  22546. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22547. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22548. + * GNU General Public License for more details.
  22549. + *
  22550. + * You should have received a copy of the GNU General Public License
  22551. + * along with this program; if not, write to the Free Software
  22552. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22553. + */
  22554. +
  22555. +/*
  22556. + * workqueue for asynchronous/super-io operations
  22557. + * todo: try new dredential scheme
  22558. + */
  22559. +
  22560. +#include <linux/module.h>
  22561. +#include "aufs.h"
  22562. +
  22563. +/* internal workqueue named AUFS_WKQ_NAME */
  22564. +static struct au_wkq {
  22565. + struct workqueue_struct *q;
  22566. +
  22567. + /* balancing */
  22568. + atomic_t busy;
  22569. +} *au_wkq;
  22570. +
  22571. +struct au_wkinfo {
  22572. + struct work_struct wk;
  22573. + struct super_block *sb;
  22574. +
  22575. + unsigned int flags; /* see wkq.h */
  22576. +
  22577. + au_wkq_func_t func;
  22578. + void *args;
  22579. +
  22580. + atomic_t *busyp;
  22581. + struct completion *comp;
  22582. +};
  22583. +
  22584. +/* ---------------------------------------------------------------------- */
  22585. +
  22586. +static int enqueue(struct au_wkq *wkq, struct au_wkinfo *wkinfo)
  22587. +{
  22588. + wkinfo->busyp = &wkq->busy;
  22589. + if (au_ftest_wkq(wkinfo->flags, WAIT))
  22590. + return !queue_work(wkq->q, &wkinfo->wk);
  22591. + else
  22592. + return !schedule_work(&wkinfo->wk);
  22593. +}
  22594. +
  22595. +static void do_wkq(struct au_wkinfo *wkinfo)
  22596. +{
  22597. + unsigned int idle, n;
  22598. + int i, idle_idx;
  22599. +
  22600. + while (1) {
  22601. + if (au_ftest_wkq(wkinfo->flags, WAIT)) {
  22602. + idle_idx = 0;
  22603. + idle = UINT_MAX;
  22604. + for (i = 0; i < aufs_nwkq; i++) {
  22605. + n = atomic_inc_return(&au_wkq[i].busy);
  22606. + if (n == 1 && !enqueue(au_wkq + i, wkinfo))
  22607. + return; /* success */
  22608. +
  22609. + if (n < idle) {
  22610. + idle_idx = i;
  22611. + idle = n;
  22612. + }
  22613. + atomic_dec(&au_wkq[i].busy);
  22614. + }
  22615. + } else
  22616. + idle_idx = aufs_nwkq;
  22617. +
  22618. + atomic_inc(&au_wkq[idle_idx].busy);
  22619. + if (!enqueue(au_wkq + idle_idx, wkinfo))
  22620. + return; /* success */
  22621. +
  22622. + /* impossible? */
  22623. + AuWarn1("failed to queue_work()\n");
  22624. + yield();
  22625. + }
  22626. +}
  22627. +
  22628. +static void wkq_func(struct work_struct *wk)
  22629. +{
  22630. + struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
  22631. +
  22632. + wkinfo->func(wkinfo->args);
  22633. + atomic_dec_return(wkinfo->busyp);
  22634. + if (au_ftest_wkq(wkinfo->flags, WAIT))
  22635. + complete(wkinfo->comp);
  22636. + else {
  22637. + kobject_put(&au_sbi(wkinfo->sb)->si_kobj);
  22638. + module_put(THIS_MODULE);
  22639. + kfree(wkinfo);
  22640. + }
  22641. +}
  22642. +
  22643. +/*
  22644. + * Since struct completion is large, try allocating it dynamically.
  22645. + */
  22646. +#if defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS)
  22647. +#define AuWkqCompDeclare(name) struct completion *comp = NULL
  22648. +
  22649. +static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
  22650. +{
  22651. + *comp = kmalloc(sizeof(**comp), GFP_NOFS);
  22652. + if (*comp) {
  22653. + init_completion(*comp);
  22654. + wkinfo->comp = *comp;
  22655. + return 0;
  22656. + }
  22657. + return -ENOMEM;
  22658. +}
  22659. +
  22660. +static void au_wkq_comp_free(struct completion *comp)
  22661. +{
  22662. + kfree(comp);
  22663. +}
  22664. +
  22665. +#else
  22666. +
  22667. +/* no braces */
  22668. +#define AuWkqCompDeclare(name) \
  22669. + DECLARE_COMPLETION_ONSTACK(_ ## name); \
  22670. + struct completion *comp = &_ ## name
  22671. +
  22672. +static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
  22673. +{
  22674. + wkinfo->comp = *comp;
  22675. + return 0;
  22676. +}
  22677. +
  22678. +static void au_wkq_comp_free(struct completion *comp __maybe_unused)
  22679. +{
  22680. + /* empty */
  22681. +}
  22682. +#endif /* 4KSTACKS */
  22683. +
  22684. +static void au_wkq_run(struct au_wkinfo *wkinfo)
  22685. +{
  22686. + au_dbg_verify_kthread();
  22687. + INIT_WORK(&wkinfo->wk, wkq_func);
  22688. + do_wkq(wkinfo);
  22689. +}
  22690. +
  22691. +int au_wkq_wait(au_wkq_func_t func, void *args)
  22692. +{
  22693. + int err;
  22694. + AuWkqCompDeclare(comp);
  22695. + struct au_wkinfo wkinfo = {
  22696. + .flags = AuWkq_WAIT,
  22697. + .func = func,
  22698. + .args = args
  22699. + };
  22700. +
  22701. + err = au_wkq_comp_alloc(&wkinfo, &comp);
  22702. + if (!err) {
  22703. + au_wkq_run(&wkinfo);
  22704. + /* no timeout, no interrupt */
  22705. + wait_for_completion(wkinfo.comp);
  22706. + au_wkq_comp_free(comp);
  22707. + }
  22708. +
  22709. + return err;
  22710. +
  22711. +}
  22712. +
  22713. +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb)
  22714. +{
  22715. + int err;
  22716. + struct au_wkinfo *wkinfo;
  22717. +
  22718. + atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
  22719. +
  22720. + /*
  22721. + * wkq_func() must free this wkinfo.
  22722. + * it highly depends upon the implementation of workqueue.
  22723. + */
  22724. + err = 0;
  22725. + wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
  22726. + if (wkinfo) {
  22727. + wkinfo->sb = sb;
  22728. + wkinfo->flags = !AuWkq_WAIT;
  22729. + wkinfo->func = func;
  22730. + wkinfo->args = args;
  22731. + wkinfo->comp = NULL;
  22732. + kobject_get(&au_sbi(sb)->si_kobj);
  22733. + __module_get(THIS_MODULE);
  22734. +
  22735. + au_wkq_run(wkinfo);
  22736. + } else {
  22737. + err = -ENOMEM;
  22738. + atomic_dec(&au_sbi(sb)->si_nowait.nw_len);
  22739. + }
  22740. +
  22741. + return err;
  22742. +}
  22743. +
  22744. +/* ---------------------------------------------------------------------- */
  22745. +
  22746. +void au_nwt_init(struct au_nowait_tasks *nwt)
  22747. +{
  22748. + atomic_set(&nwt->nw_len, 0);
  22749. + /* smp_mb();*/ /* atomic_set */
  22750. + init_waitqueue_head(&nwt->nw_wq);
  22751. +}
  22752. +
  22753. +void au_wkq_fin(void)
  22754. +{
  22755. + int i;
  22756. +
  22757. + for (i = 0; i < aufs_nwkq; i++)
  22758. + if (au_wkq[i].q && !IS_ERR(au_wkq[i].q))
  22759. + destroy_workqueue(au_wkq[i].q);
  22760. + kfree(au_wkq);
  22761. +}
  22762. +
  22763. +int __init au_wkq_init(void)
  22764. +{
  22765. + int err, i;
  22766. + struct au_wkq *nowaitq;
  22767. +
  22768. + /* '+1' is for accounting of nowait queue */
  22769. + err = -ENOMEM;
  22770. + au_wkq = kcalloc(aufs_nwkq + 1, sizeof(*au_wkq), GFP_NOFS);
  22771. + if (unlikely(!au_wkq))
  22772. + goto out;
  22773. +
  22774. + err = 0;
  22775. + for (i = 0; i < aufs_nwkq; i++) {
  22776. + au_wkq[i].q = create_singlethread_workqueue(AUFS_WKQ_NAME);
  22777. + if (au_wkq[i].q && !IS_ERR(au_wkq[i].q)) {
  22778. + atomic_set(&au_wkq[i].busy, 0);
  22779. + continue;
  22780. + }
  22781. +
  22782. + err = PTR_ERR(au_wkq[i].q);
  22783. + au_wkq_fin();
  22784. + goto out;
  22785. + }
  22786. +
  22787. + /* nowait accounting */
  22788. + nowaitq = au_wkq + aufs_nwkq;
  22789. + atomic_set(&nowaitq->busy, 0);
  22790. + nowaitq->q = NULL;
  22791. + /* smp_mb(); */ /* atomic_set */
  22792. +
  22793. + out:
  22794. + return err;
  22795. +}
  22796. diff -Nur linux-2.6.31.4.orig/fs/aufs/wkq.h linux-2.6.31.4/fs/aufs/wkq.h
  22797. --- linux-2.6.31.4.orig/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100
  22798. +++ linux-2.6.31.4/fs/aufs/wkq.h 2009-10-18 11:26:01.000000000 +0200
  22799. @@ -0,0 +1,82 @@
  22800. +/*
  22801. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  22802. + *
  22803. + * This program, aufs is free software; you can redistribute it and/or modify
  22804. + * it under the terms of the GNU General Public License as published by
  22805. + * the Free Software Foundation; either version 2 of the License, or
  22806. + * (at your option) any later version.
  22807. + *
  22808. + * This program is distributed in the hope that it will be useful,
  22809. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22810. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22811. + * GNU General Public License for more details.
  22812. + *
  22813. + * You should have received a copy of the GNU General Public License
  22814. + * along with this program; if not, write to the Free Software
  22815. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22816. + */
  22817. +
  22818. +/*
  22819. + * workqueue for asynchronous/super-io operations
  22820. + * todo: try new credentials management scheme
  22821. + */
  22822. +
  22823. +#ifndef __AUFS_WKQ_H__
  22824. +#define __AUFS_WKQ_H__
  22825. +
  22826. +#ifdef __KERNEL__
  22827. +
  22828. +#include <linux/sched.h>
  22829. +#include <linux/wait.h>
  22830. +#include <linux/aufs_type.h>
  22831. +
  22832. +struct super_block;
  22833. +
  22834. +/* ---------------------------------------------------------------------- */
  22835. +
  22836. +/*
  22837. + * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
  22838. + */
  22839. +struct au_nowait_tasks {
  22840. + atomic_t nw_len;
  22841. + wait_queue_head_t nw_wq;
  22842. +};
  22843. +
  22844. +/* ---------------------------------------------------------------------- */
  22845. +
  22846. +typedef void (*au_wkq_func_t)(void *args);
  22847. +
  22848. +/* wkq flags */
  22849. +#define AuWkq_WAIT 1
  22850. +#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name)
  22851. +#define au_fset_wkq(flags, name) { (flags) |= AuWkq_##name; }
  22852. +#define au_fclr_wkq(flags, name) { (flags) &= ~AuWkq_##name; }
  22853. +
  22854. +/* wkq.c */
  22855. +int au_wkq_wait(au_wkq_func_t func, void *args);
  22856. +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb);
  22857. +void au_nwt_init(struct au_nowait_tasks *nwt);
  22858. +int __init au_wkq_init(void);
  22859. +void au_wkq_fin(void);
  22860. +
  22861. +/* ---------------------------------------------------------------------- */
  22862. +
  22863. +static inline int au_test_wkq(struct task_struct *tsk)
  22864. +{
  22865. + return !tsk->mm && !strcmp(tsk->comm, AUFS_WKQ_NAME);
  22866. +}
  22867. +
  22868. +static inline void au_nwt_done(struct au_nowait_tasks *nwt)
  22869. +{
  22870. + if (!atomic_dec_return(&nwt->nw_len))
  22871. + wake_up_all(&nwt->nw_wq);
  22872. +}
  22873. +
  22874. +static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
  22875. +{
  22876. + wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
  22877. + return 0;
  22878. +}
  22879. +
  22880. +#endif /* __KERNEL__ */
  22881. +#endif /* __AUFS_WKQ_H__ */
  22882. diff -Nur linux-2.6.31.4.orig/fs/aufs/xino.c linux-2.6.31.4/fs/aufs/xino.c
  22883. --- linux-2.6.31.4.orig/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100
  22884. +++ linux-2.6.31.4/fs/aufs/xino.c 2009-10-18 11:26:01.000000000 +0200
  22885. @@ -0,0 +1,1200 @@
  22886. +/*
  22887. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  22888. + *
  22889. + * This program, aufs is free software; you can redistribute it and/or modify
  22890. + * it under the terms of the GNU General Public License as published by
  22891. + * the Free Software Foundation; either version 2 of the License, or
  22892. + * (at your option) any later version.
  22893. + *
  22894. + * This program is distributed in the hope that it will be useful,
  22895. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22896. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22897. + * GNU General Public License for more details.
  22898. + *
  22899. + * You should have received a copy of the GNU General Public License
  22900. + * along with this program; if not, write to the Free Software
  22901. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22902. + */
  22903. +
  22904. +/*
  22905. + * external inode number translation table and bitmap
  22906. + */
  22907. +
  22908. +#include <linux/file.h>
  22909. +#include <linux/seq_file.h>
  22910. +#include <linux/uaccess.h>
  22911. +#include "aufs.h"
  22912. +
  22913. +ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size,
  22914. + loff_t *pos)
  22915. +{
  22916. + ssize_t err;
  22917. + mm_segment_t oldfs;
  22918. +
  22919. + oldfs = get_fs();
  22920. + set_fs(KERNEL_DS);
  22921. + do {
  22922. + /* todo: signal_pending? */
  22923. + err = func(file, (char __user *)buf, size, pos);
  22924. + } while (err == -EAGAIN || err == -EINTR);
  22925. + set_fs(oldfs);
  22926. +
  22927. +#if 0 /* reserved for future use */
  22928. + if (err > 0)
  22929. + fsnotify_access(file->f_dentry);
  22930. +#endif
  22931. +
  22932. + return err;
  22933. +}
  22934. +
  22935. +/* ---------------------------------------------------------------------- */
  22936. +
  22937. +static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *buf,
  22938. + size_t size, loff_t *pos)
  22939. +{
  22940. + ssize_t err;
  22941. + mm_segment_t oldfs;
  22942. +
  22943. + oldfs = get_fs();
  22944. + set_fs(KERNEL_DS);
  22945. + lockdep_off();
  22946. + do {
  22947. + /* todo: signal_pending? */
  22948. + err = func(file, (const char __user *)buf, size, pos);
  22949. + } while (err == -EAGAIN || err == -EINTR);
  22950. + lockdep_on();
  22951. + set_fs(oldfs);
  22952. +
  22953. +#if 0 /* reserved for future use */
  22954. + if (err > 0)
  22955. + fsnotify_modify(file->f_dentry);
  22956. +#endif
  22957. +
  22958. + return err;
  22959. +}
  22960. +
  22961. +struct do_xino_fwrite_args {
  22962. + ssize_t *errp;
  22963. + au_writef_t func;
  22964. + struct file *file;
  22965. + void *buf;
  22966. + size_t size;
  22967. + loff_t *pos;
  22968. +};
  22969. +
  22970. +static void call_do_xino_fwrite(void *args)
  22971. +{
  22972. + struct do_xino_fwrite_args *a = args;
  22973. + *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
  22974. +}
  22975. +
  22976. +ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
  22977. + loff_t *pos)
  22978. +{
  22979. + ssize_t err;
  22980. +
  22981. + /* todo: signal block and no wkq? */
  22982. + /* todo: new credential scheme */
  22983. + /*
  22984. + * it breaks RLIMIT_FSIZE and normal user's limit,
  22985. + * users should care about quota and real 'filesystem full.'
  22986. + */
  22987. + if (!au_test_wkq(current)) {
  22988. + int wkq_err;
  22989. + struct do_xino_fwrite_args args = {
  22990. + .errp = &err,
  22991. + .func = func,
  22992. + .file = file,
  22993. + .buf = buf,
  22994. + .size = size,
  22995. + .pos = pos
  22996. + };
  22997. +
  22998. + wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
  22999. + if (unlikely(wkq_err))
  23000. + err = wkq_err;
  23001. + } else
  23002. + err = do_xino_fwrite(func, file, buf, size, pos);
  23003. +
  23004. + return err;
  23005. +}
  23006. +
  23007. +/* ---------------------------------------------------------------------- */
  23008. +
  23009. +/*
  23010. + * create a new xinofile at the same place/path as @base_file.
  23011. + */
  23012. +struct file *au_xino_create2(struct file *base_file, struct file *copy_src)
  23013. +{
  23014. + struct file *file;
  23015. + struct dentry *base, *dentry, *parent;
  23016. + struct inode *dir;
  23017. + struct qstr *name;
  23018. + int err;
  23019. +
  23020. + base = base_file->f_dentry;
  23021. + parent = base->d_parent; /* dir inode is locked */
  23022. + dir = parent->d_inode;
  23023. + IMustLock(dir);
  23024. +
  23025. + file = ERR_PTR(-EINVAL);
  23026. + name = &base->d_name;
  23027. + dentry = vfsub_lookup_one_len(name->name, parent, name->len);
  23028. + if (IS_ERR(dentry)) {
  23029. + file = (void *)dentry;
  23030. + AuErr("%.*s lookup err %ld\n", AuLNPair(name), PTR_ERR(dentry));
  23031. + goto out;
  23032. + }
  23033. +
  23034. + /* no need to mnt_want_write() since we call dentry_open() later */
  23035. + err = vfs_create(dir, dentry, S_IRUGO | S_IWUGO, NULL);
  23036. + if (unlikely(err)) {
  23037. + file = ERR_PTR(err);
  23038. + AuErr("%.*s create err %d\n", AuLNPair(name), err);
  23039. + goto out_dput;
  23040. + }
  23041. +
  23042. + file = dentry_open(dget(dentry), mntget(base_file->f_vfsmnt),
  23043. + O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE,
  23044. + current_cred());
  23045. + if (IS_ERR(file)) {
  23046. + AuErr("%.*s open err %ld\n", AuLNPair(name), PTR_ERR(file));
  23047. + goto out_dput;
  23048. + }
  23049. +
  23050. + err = vfsub_unlink(dir, &file->f_path, /*force*/0);
  23051. + if (unlikely(err)) {
  23052. + AuErr("%.*s unlink err %d\n", AuLNPair(name), err);
  23053. + goto out_fput;
  23054. + }
  23055. +
  23056. + if (copy_src) {
  23057. + /* no one can touch copy_src xino */
  23058. + err = au_copy_file(file, copy_src,
  23059. + i_size_read(copy_src->f_dentry->d_inode));
  23060. + if (unlikely(err)) {
  23061. + AuErr("%.*s copy err %d\n", AuLNPair(name), err);
  23062. + goto out_fput;
  23063. + }
  23064. + }
  23065. + goto out_dput; /* success */
  23066. +
  23067. + out_fput:
  23068. + fput(file);
  23069. + file = ERR_PTR(err);
  23070. + out_dput:
  23071. + dput(dentry);
  23072. + out:
  23073. + return file;
  23074. +}
  23075. +
  23076. +struct au_xino_lock_dir {
  23077. + struct au_hinode *hdir;
  23078. + struct dentry *parent;
  23079. + struct mutex *mtx;
  23080. +};
  23081. +
  23082. +static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
  23083. + struct au_xino_lock_dir *ldir)
  23084. +{
  23085. + aufs_bindex_t brid, bindex;
  23086. +
  23087. + ldir->hdir = NULL;
  23088. + bindex = -1;
  23089. + brid = au_xino_brid(sb);
  23090. + if (brid >= 0)
  23091. + bindex = au_br_index(sb, brid);
  23092. + if (bindex >= 0) {
  23093. + ldir->hdir = au_hi(sb->s_root->d_inode, bindex);
  23094. + au_hin_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
  23095. + } else {
  23096. + ldir->parent = dget_parent(xino->f_dentry);
  23097. + ldir->mtx = &ldir->parent->d_inode->i_mutex;
  23098. + mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT);
  23099. + }
  23100. +}
  23101. +
  23102. +static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
  23103. +{
  23104. + if (ldir->hdir)
  23105. + au_hin_imtx_unlock(ldir->hdir);
  23106. + else {
  23107. + mutex_unlock(ldir->mtx);
  23108. + dput(ldir->parent);
  23109. + }
  23110. +}
  23111. +
  23112. +/* ---------------------------------------------------------------------- */
  23113. +
  23114. +/* trucate xino files asynchronously */
  23115. +
  23116. +int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex)
  23117. +{
  23118. + int err;
  23119. + aufs_bindex_t bi, bend;
  23120. + struct au_branch *br;
  23121. + struct file *new_xino, *file;
  23122. + struct super_block *h_sb;
  23123. + struct au_xino_lock_dir ldir;
  23124. +
  23125. + err = -EINVAL;
  23126. + bend = au_sbend(sb);
  23127. + if (unlikely(bindex < 0 || bend < bindex))
  23128. + goto out;
  23129. + br = au_sbr(sb, bindex);
  23130. + file = br->br_xino.xi_file;
  23131. + if (!file)
  23132. + goto out;
  23133. +
  23134. + au_xino_lock_dir(sb, file, &ldir);
  23135. + /* mnt_want_write() is unnecessary here */
  23136. + new_xino = au_xino_create2(file, file);
  23137. + au_xino_unlock_dir(&ldir);
  23138. + err = PTR_ERR(new_xino);
  23139. + if (IS_ERR(new_xino))
  23140. + goto out;
  23141. + err = 0;
  23142. + fput(file);
  23143. + br->br_xino.xi_file = new_xino;
  23144. +
  23145. + h_sb = br->br_mnt->mnt_sb;
  23146. + for (bi = 0; bi <= bend; bi++) {
  23147. + if (unlikely(bi == bindex))
  23148. + continue;
  23149. + br = au_sbr(sb, bi);
  23150. + if (br->br_mnt->mnt_sb != h_sb)
  23151. + continue;
  23152. +
  23153. + fput(br->br_xino.xi_file);
  23154. + br->br_xino.xi_file = new_xino;
  23155. + get_file(new_xino);
  23156. + }
  23157. +
  23158. + out:
  23159. + return err;
  23160. +}
  23161. +
  23162. +struct xino_do_trunc_args {
  23163. + struct super_block *sb;
  23164. + struct au_branch *br;
  23165. +};
  23166. +
  23167. +static void xino_do_trunc(void *_args)
  23168. +{
  23169. + struct xino_do_trunc_args *args = _args;
  23170. + struct super_block *sb;
  23171. + struct au_branch *br;
  23172. + struct inode *dir;
  23173. + int err;
  23174. + aufs_bindex_t bindex;
  23175. +
  23176. + err = 0;
  23177. + sb = args->sb;
  23178. + dir = sb->s_root->d_inode;
  23179. + br = args->br;
  23180. +
  23181. + si_noflush_write_lock(sb);
  23182. + ii_read_lock_parent(dir);
  23183. + bindex = au_br_index(sb, br->br_id);
  23184. + err = au_xino_trunc(sb, bindex);
  23185. + if (!err
  23186. + && br->br_xino.xi_file->f_dentry->d_inode->i_blocks
  23187. + >= br->br_xino_upper)
  23188. + br->br_xino_upper += AUFS_XINO_TRUNC_STEP;
  23189. +
  23190. + ii_read_unlock(dir);
  23191. + if (unlikely(err))
  23192. + AuWarn("err b%d, (%d)\n", bindex, err);
  23193. + atomic_dec(&br->br_xino_running);
  23194. + atomic_dec(&br->br_count);
  23195. + au_nwt_done(&au_sbi(sb)->si_nowait);
  23196. + si_write_unlock(sb);
  23197. + kfree(args);
  23198. +}
  23199. +
  23200. +static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
  23201. +{
  23202. + struct xino_do_trunc_args *args;
  23203. + int wkq_err;
  23204. +
  23205. + if (br->br_xino.xi_file->f_dentry->d_inode->i_blocks
  23206. + < br->br_xino_upper)
  23207. + return;
  23208. +
  23209. + if (atomic_inc_return(&br->br_xino_running) > 1)
  23210. + goto out;
  23211. +
  23212. + /* lock and kfree() will be called in trunc_xino() */
  23213. + args = kmalloc(sizeof(*args), GFP_NOFS);
  23214. + if (unlikely(!args)) {
  23215. + AuErr1("no memory\n");
  23216. + goto out_args;
  23217. + }
  23218. +
  23219. + atomic_inc_return(&br->br_count);
  23220. + args->sb = sb;
  23221. + args->br = br;
  23222. + wkq_err = au_wkq_nowait(xino_do_trunc, args, sb);
  23223. + if (!wkq_err)
  23224. + return; /* success */
  23225. +
  23226. + AuErr("wkq %d\n", wkq_err);
  23227. + atomic_dec_return(&br->br_count);
  23228. +
  23229. + out_args:
  23230. + kfree(args);
  23231. + out:
  23232. + atomic_dec_return(&br->br_xino_running);
  23233. +}
  23234. +
  23235. +/* ---------------------------------------------------------------------- */
  23236. +
  23237. +static int au_xino_do_write(au_writef_t write, struct file *file,
  23238. + ino_t h_ino, ino_t ino)
  23239. +{
  23240. + loff_t pos;
  23241. + ssize_t sz;
  23242. +
  23243. + pos = h_ino;
  23244. + if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) {
  23245. + AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
  23246. + return -EFBIG;
  23247. + }
  23248. + pos *= sizeof(ino);
  23249. + sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos);
  23250. + if (sz == sizeof(ino))
  23251. + return 0; /* success */
  23252. +
  23253. + AuIOErr("write failed (%zd)\n", sz);
  23254. + return -EIO;
  23255. +}
  23256. +
  23257. +/*
  23258. + * write @ino to the xinofile for the specified branch{@sb, @bindex}
  23259. + * at the position of @h_ino.
  23260. + * even if @ino is zero, it is written to the xinofile and means no entry.
  23261. + * if the size of the xino file on a specific filesystem exceeds the watermark,
  23262. + * try truncating it.
  23263. + */
  23264. +int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  23265. + ino_t ino)
  23266. +{
  23267. + int err;
  23268. + unsigned int mnt_flags;
  23269. + struct au_branch *br;
  23270. +
  23271. + BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max)
  23272. + || ((loff_t)-1) > 0);
  23273. + SiMustAnyLock(sb);
  23274. +
  23275. + mnt_flags = au_mntflags(sb);
  23276. + if (!au_opt_test(mnt_flags, XINO))
  23277. + return 0;
  23278. +
  23279. + br = au_sbr(sb, bindex);
  23280. + err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
  23281. + h_ino, ino);
  23282. + if (!err) {
  23283. + if (au_opt_test(mnt_flags, TRUNC_XINO)
  23284. + && au_test_fs_trunc_xino(br->br_mnt->mnt_sb))
  23285. + xino_try_trunc(sb, br);
  23286. + return 0; /* success */
  23287. + }
  23288. +
  23289. + AuIOErr("write failed (%d)\n", err);
  23290. + return -EIO;
  23291. +}
  23292. +
  23293. +/* ---------------------------------------------------------------------- */
  23294. +
  23295. +/* aufs inode number bitmap */
  23296. +
  23297. +static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
  23298. +static ino_t xib_calc_ino(unsigned long pindex, int bit)
  23299. +{
  23300. + ino_t ino;
  23301. +
  23302. + AuDebugOn(bit < 0 || page_bits <= bit);
  23303. + ino = AUFS_FIRST_INO + pindex * page_bits + bit;
  23304. + return ino;
  23305. +}
  23306. +
  23307. +static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
  23308. +{
  23309. + AuDebugOn(ino < AUFS_FIRST_INO);
  23310. + ino -= AUFS_FIRST_INO;
  23311. + *pindex = ino / page_bits;
  23312. + *bit = ino % page_bits;
  23313. +}
  23314. +
  23315. +static int xib_pindex(struct super_block *sb, unsigned long pindex)
  23316. +{
  23317. + int err;
  23318. + loff_t pos;
  23319. + ssize_t sz;
  23320. + struct au_sbinfo *sbinfo;
  23321. + struct file *xib;
  23322. + unsigned long *p;
  23323. +
  23324. + sbinfo = au_sbi(sb);
  23325. + MtxMustLock(&sbinfo->si_xib_mtx);
  23326. + AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
  23327. + || !au_opt_test(sbinfo->si_mntflags, XINO));
  23328. +
  23329. + if (pindex == sbinfo->si_xib_last_pindex)
  23330. + return 0;
  23331. +
  23332. + xib = sbinfo->si_xib;
  23333. + p = sbinfo->si_xib_buf;
  23334. + pos = sbinfo->si_xib_last_pindex;
  23335. + pos *= PAGE_SIZE;
  23336. + sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
  23337. + if (unlikely(sz != PAGE_SIZE))
  23338. + goto out;
  23339. +
  23340. + pos = pindex;
  23341. + pos *= PAGE_SIZE;
  23342. + if (i_size_read(xib->f_dentry->d_inode) >= pos + PAGE_SIZE)
  23343. + sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
  23344. + else {
  23345. + memset(p, 0, PAGE_SIZE);
  23346. + sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
  23347. + }
  23348. + if (sz == PAGE_SIZE) {
  23349. + sbinfo->si_xib_last_pindex = pindex;
  23350. + return 0; /* success */
  23351. + }
  23352. +
  23353. + out:
  23354. + AuIOErr1("write failed (%zd)\n", sz);
  23355. + err = sz;
  23356. + if (sz >= 0)
  23357. + err = -EIO;
  23358. + return err;
  23359. +}
  23360. +
  23361. +/* ---------------------------------------------------------------------- */
  23362. +
  23363. +int au_xino_write0(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  23364. + ino_t ino)
  23365. +{
  23366. + int err, bit;
  23367. + unsigned long pindex;
  23368. + struct au_sbinfo *sbinfo;
  23369. +
  23370. + if (!au_opt_test(au_mntflags(sb), XINO))
  23371. + return 0;
  23372. +
  23373. + err = 0;
  23374. + if (ino) {
  23375. + sbinfo = au_sbi(sb);
  23376. + xib_calc_bit(ino, &pindex, &bit);
  23377. + AuDebugOn(page_bits <= bit);
  23378. + mutex_lock(&sbinfo->si_xib_mtx);
  23379. + err = xib_pindex(sb, pindex);
  23380. + if (!err) {
  23381. + clear_bit(bit, sbinfo->si_xib_buf);
  23382. + sbinfo->si_xib_next_bit = bit;
  23383. + }
  23384. + mutex_unlock(&sbinfo->si_xib_mtx);
  23385. + }
  23386. +
  23387. + if (!err)
  23388. + err = au_xino_write(sb, bindex, h_ino, 0);
  23389. + return err;
  23390. +}
  23391. +
  23392. +/* get an unused inode number from bitmap */
  23393. +ino_t au_xino_new_ino(struct super_block *sb)
  23394. +{
  23395. + ino_t ino;
  23396. + unsigned long *p, pindex, ul, pend;
  23397. + struct au_sbinfo *sbinfo;
  23398. + struct file *file;
  23399. + int free_bit, err;
  23400. +
  23401. + if (!au_opt_test(au_mntflags(sb), XINO))
  23402. + return iunique(sb, AUFS_FIRST_INO);
  23403. +
  23404. + sbinfo = au_sbi(sb);
  23405. + mutex_lock(&sbinfo->si_xib_mtx);
  23406. + p = sbinfo->si_xib_buf;
  23407. + free_bit = sbinfo->si_xib_next_bit;
  23408. + if (free_bit < page_bits && !test_bit(free_bit, p))
  23409. + goto out; /* success */
  23410. + free_bit = find_first_zero_bit(p, page_bits);
  23411. + if (free_bit < page_bits)
  23412. + goto out; /* success */
  23413. +
  23414. + pindex = sbinfo->si_xib_last_pindex;
  23415. + for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
  23416. + err = xib_pindex(sb, ul);
  23417. + if (unlikely(err))
  23418. + goto out_err;
  23419. + free_bit = find_first_zero_bit(p, page_bits);
  23420. + if (free_bit < page_bits)
  23421. + goto out; /* success */
  23422. + }
  23423. +
  23424. + file = sbinfo->si_xib;
  23425. + pend = i_size_read(file->f_dentry->d_inode) / PAGE_SIZE;
  23426. + for (ul = pindex + 1; ul <= pend; ul++) {
  23427. + err = xib_pindex(sb, ul);
  23428. + if (unlikely(err))
  23429. + goto out_err;
  23430. + free_bit = find_first_zero_bit(p, page_bits);
  23431. + if (free_bit < page_bits)
  23432. + goto out; /* success */
  23433. + }
  23434. + BUG();
  23435. +
  23436. + out:
  23437. + set_bit(free_bit, p);
  23438. + sbinfo->si_xib_next_bit++;
  23439. + pindex = sbinfo->si_xib_last_pindex;
  23440. + mutex_unlock(&sbinfo->si_xib_mtx);
  23441. + ino = xib_calc_ino(pindex, free_bit);
  23442. + AuDbg("i%lu\n", (unsigned long)ino);
  23443. + return ino;
  23444. + out_err:
  23445. + mutex_unlock(&sbinfo->si_xib_mtx);
  23446. + AuDbg("i0\n");
  23447. + return 0;
  23448. +}
  23449. +
  23450. +/*
  23451. + * read @ino from xinofile for the specified branch{@sb, @bindex}
  23452. + * at the position of @h_ino.
  23453. + * if @ino does not exist and @do_new is true, get new one.
  23454. + */
  23455. +int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  23456. + ino_t *ino)
  23457. +{
  23458. + int err;
  23459. + ssize_t sz;
  23460. + loff_t pos;
  23461. + struct file *file;
  23462. + struct au_sbinfo *sbinfo;
  23463. +
  23464. + *ino = 0;
  23465. + if (!au_opt_test(au_mntflags(sb), XINO))
  23466. + return 0; /* no xino */
  23467. +
  23468. + err = 0;
  23469. + sbinfo = au_sbi(sb);
  23470. + pos = h_ino;
  23471. + if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) {
  23472. + AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
  23473. + return -EFBIG;
  23474. + }
  23475. + pos *= sizeof(*ino);
  23476. +
  23477. + file = au_sbr(sb, bindex)->br_xino.xi_file;
  23478. + if (i_size_read(file->f_dentry->d_inode) < pos + sizeof(*ino))
  23479. + return 0; /* no ino */
  23480. +
  23481. + sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos);
  23482. + if (sz == sizeof(*ino))
  23483. + return 0; /* success */
  23484. +
  23485. + err = sz;
  23486. + if (unlikely(sz >= 0)) {
  23487. + err = -EIO;
  23488. + AuIOErr("xino read error (%zd)\n", sz);
  23489. + }
  23490. +
  23491. + return err;
  23492. +}
  23493. +
  23494. +/* ---------------------------------------------------------------------- */
  23495. +
  23496. +/* create and set a new xino file */
  23497. +
  23498. +struct file *au_xino_create(struct super_block *sb, char *fname, int silent)
  23499. +{
  23500. + struct file *file;
  23501. + struct dentry *h_parent, *d;
  23502. + struct inode *h_dir;
  23503. + int err;
  23504. +
  23505. + /*
  23506. + * at mount-time, and the xino file is the default path,
  23507. + * hinotify is disabled so we have no inotify events to ignore.
  23508. + * when a user specified the xino, we cannot get au_hdir to be ignored.
  23509. + */
  23510. + file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE,
  23511. + S_IRUGO | S_IWUGO);
  23512. + if (IS_ERR(file)) {
  23513. + if (!silent)
  23514. + AuErr("open %s(%ld)\n", fname, PTR_ERR(file));
  23515. + return file;
  23516. + }
  23517. +
  23518. + /* keep file count */
  23519. + h_parent = dget_parent(file->f_dentry);
  23520. + h_dir = h_parent->d_inode;
  23521. + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
  23522. + /* mnt_want_write() is unnecessary here */
  23523. + err = vfsub_unlink(h_dir, &file->f_path, /*force*/0);
  23524. + mutex_unlock(&h_dir->i_mutex);
  23525. + dput(h_parent);
  23526. + if (unlikely(err)) {
  23527. + if (!silent)
  23528. + AuErr("unlink %s(%d)\n", fname, err);
  23529. + goto out;
  23530. + }
  23531. +
  23532. + err = -EINVAL;
  23533. + d = file->f_dentry;
  23534. + if (unlikely(sb == d->d_sb)) {
  23535. + if (!silent)
  23536. + AuErr("%s must be outside\n", fname);
  23537. + goto out;
  23538. + }
  23539. + if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
  23540. + if (!silent)
  23541. + AuErr("xino doesn't support %s(%s)\n",
  23542. + fname, au_sbtype(d->d_sb));
  23543. + goto out;
  23544. + }
  23545. + return file; /* success */
  23546. +
  23547. + out:
  23548. + fput(file);
  23549. + file = ERR_PTR(err);
  23550. + return file;
  23551. +}
  23552. +
  23553. +/*
  23554. + * find another branch who is on the same filesystem of the specified
  23555. + * branch{@btgt}. search until @bend.
  23556. + */
  23557. +static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
  23558. + aufs_bindex_t bend)
  23559. +{
  23560. + aufs_bindex_t bindex;
  23561. + struct super_block *tgt_sb = au_sbr_sb(sb, btgt);
  23562. +
  23563. + for (bindex = 0; bindex < btgt; bindex++)
  23564. + if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
  23565. + return bindex;
  23566. + for (bindex++; bindex <= bend; bindex++)
  23567. + if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
  23568. + return bindex;
  23569. + return -1;
  23570. +}
  23571. +
  23572. +/* ---------------------------------------------------------------------- */
  23573. +
  23574. +/*
  23575. + * initialize the xinofile for the specified branch @br
  23576. + * at the place/path where @base_file indicates.
  23577. + * test whether another branch is on the same filesystem or not,
  23578. + * if @do_test is true.
  23579. + */
  23580. +int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
  23581. + struct file *base_file, int do_test)
  23582. +{
  23583. + int err;
  23584. + ino_t ino;
  23585. + aufs_bindex_t bend, bindex;
  23586. + struct au_branch *shared_br, *b;
  23587. + struct file *file;
  23588. + struct super_block *tgt_sb;
  23589. +
  23590. + shared_br = NULL;
  23591. + bend = au_sbend(sb);
  23592. + if (do_test) {
  23593. + tgt_sb = br->br_mnt->mnt_sb;
  23594. + for (bindex = 0; bindex <= bend; bindex++) {
  23595. + b = au_sbr(sb, bindex);
  23596. + if (tgt_sb == b->br_mnt->mnt_sb) {
  23597. + shared_br = b;
  23598. + break;
  23599. + }
  23600. + }
  23601. + }
  23602. +
  23603. + if (!shared_br || !shared_br->br_xino.xi_file) {
  23604. + struct au_xino_lock_dir ldir;
  23605. +
  23606. + au_xino_lock_dir(sb, base_file, &ldir);
  23607. + /* mnt_want_write() is unnecessary here */
  23608. + file = au_xino_create2(base_file, NULL);
  23609. + au_xino_unlock_dir(&ldir);
  23610. + err = PTR_ERR(file);
  23611. + if (IS_ERR(file))
  23612. + goto out;
  23613. + br->br_xino.xi_file = file;
  23614. + } else {
  23615. + br->br_xino.xi_file = shared_br->br_xino.xi_file;
  23616. + get_file(br->br_xino.xi_file);
  23617. + }
  23618. +
  23619. + ino = AUFS_ROOT_INO;
  23620. + err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
  23621. + h_ino, ino);
  23622. + if (!err)
  23623. + return 0; /* success */
  23624. +
  23625. +
  23626. + out:
  23627. + return err;
  23628. +}
  23629. +
  23630. +/* ---------------------------------------------------------------------- */
  23631. +
  23632. +/* trucate a xino bitmap file */
  23633. +
  23634. +/* todo: slow */
  23635. +static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
  23636. +{
  23637. + int err, bit;
  23638. + ssize_t sz;
  23639. + unsigned long pindex;
  23640. + loff_t pos, pend;
  23641. + struct au_sbinfo *sbinfo;
  23642. + au_readf_t func;
  23643. + ino_t *ino;
  23644. + unsigned long *p;
  23645. +
  23646. + err = 0;
  23647. + sbinfo = au_sbi(sb);
  23648. + MtxMustLock(&sbinfo->si_xib_mtx);
  23649. + p = sbinfo->si_xib_buf;
  23650. + func = sbinfo->si_xread;
  23651. + pend = i_size_read(file->f_dentry->d_inode);
  23652. + pos = 0;
  23653. + while (pos < pend) {
  23654. + sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
  23655. + err = sz;
  23656. + if (unlikely(sz <= 0))
  23657. + goto out;
  23658. +
  23659. + err = 0;
  23660. + for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
  23661. + if (unlikely(*ino < AUFS_FIRST_INO))
  23662. + continue;
  23663. +
  23664. + xib_calc_bit(*ino, &pindex, &bit);
  23665. + AuDebugOn(page_bits <= bit);
  23666. + err = xib_pindex(sb, pindex);
  23667. + if (!err)
  23668. + set_bit(bit, p);
  23669. + else
  23670. + goto out;
  23671. + }
  23672. + }
  23673. +
  23674. + out:
  23675. + return err;
  23676. +}
  23677. +
  23678. +static int xib_restore(struct super_block *sb)
  23679. +{
  23680. + int err;
  23681. + aufs_bindex_t bindex, bend;
  23682. + void *page;
  23683. +
  23684. + err = -ENOMEM;
  23685. + page = (void *)__get_free_page(GFP_NOFS);
  23686. + if (unlikely(!page))
  23687. + goto out;
  23688. +
  23689. + err = 0;
  23690. + bend = au_sbend(sb);
  23691. + for (bindex = 0; !err && bindex <= bend; bindex++)
  23692. + if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0)
  23693. + err = do_xib_restore
  23694. + (sb, au_sbr(sb, bindex)->br_xino.xi_file, page);
  23695. + else
  23696. + AuDbg("b%d\n", bindex);
  23697. + free_page((unsigned long)page);
  23698. +
  23699. + out:
  23700. + return err;
  23701. +}
  23702. +
  23703. +int au_xib_trunc(struct super_block *sb)
  23704. +{
  23705. + int err;
  23706. + ssize_t sz;
  23707. + loff_t pos;
  23708. + struct au_xino_lock_dir ldir;
  23709. + struct au_sbinfo *sbinfo;
  23710. + unsigned long *p;
  23711. + struct file *file;
  23712. +
  23713. + SiMustWriteLock(sb);
  23714. +
  23715. + err = 0;
  23716. + sbinfo = au_sbi(sb);
  23717. + if (!au_opt_test(sbinfo->si_mntflags, XINO))
  23718. + goto out;
  23719. +
  23720. + file = sbinfo->si_xib;
  23721. + if (i_size_read(file->f_dentry->d_inode) <= PAGE_SIZE)
  23722. + goto out;
  23723. +
  23724. + au_xino_lock_dir(sb, file, &ldir);
  23725. + /* mnt_want_write() is unnecessary here */
  23726. + file = au_xino_create2(sbinfo->si_xib, NULL);
  23727. + au_xino_unlock_dir(&ldir);
  23728. + err = PTR_ERR(file);
  23729. + if (IS_ERR(file))
  23730. + goto out;
  23731. + fput(sbinfo->si_xib);
  23732. + sbinfo->si_xib = file;
  23733. +
  23734. + p = sbinfo->si_xib_buf;
  23735. + memset(p, 0, PAGE_SIZE);
  23736. + pos = 0;
  23737. + sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
  23738. + if (unlikely(sz != PAGE_SIZE)) {
  23739. + err = sz;
  23740. + AuIOErr("err %d\n", err);
  23741. + if (sz >= 0)
  23742. + err = -EIO;
  23743. + goto out;
  23744. + }
  23745. +
  23746. + mutex_lock(&sbinfo->si_xib_mtx);
  23747. + /* mnt_want_write() is unnecessary here */
  23748. + err = xib_restore(sb);
  23749. + mutex_unlock(&sbinfo->si_xib_mtx);
  23750. +
  23751. +out:
  23752. + return err;
  23753. +}
  23754. +
  23755. +/* ---------------------------------------------------------------------- */
  23756. +
  23757. +/*
  23758. + * xino mount option handlers
  23759. + */
  23760. +static au_readf_t find_readf(struct file *h_file)
  23761. +{
  23762. + const struct file_operations *fop = h_file->f_op;
  23763. +
  23764. + if (fop) {
  23765. + if (fop->read)
  23766. + return fop->read;
  23767. + if (fop->aio_read)
  23768. + return do_sync_read;
  23769. + }
  23770. + return ERR_PTR(-ENOSYS);
  23771. +}
  23772. +
  23773. +static au_writef_t find_writef(struct file *h_file)
  23774. +{
  23775. + const struct file_operations *fop = h_file->f_op;
  23776. +
  23777. + if (fop) {
  23778. + if (fop->write)
  23779. + return fop->write;
  23780. + if (fop->aio_write)
  23781. + return do_sync_write;
  23782. + }
  23783. + return ERR_PTR(-ENOSYS);
  23784. +}
  23785. +
  23786. +/* xino bitmap */
  23787. +static void xino_clear_xib(struct super_block *sb)
  23788. +{
  23789. + struct au_sbinfo *sbinfo;
  23790. +
  23791. + SiMustWriteLock(sb);
  23792. +
  23793. + sbinfo = au_sbi(sb);
  23794. + sbinfo->si_xread = NULL;
  23795. + sbinfo->si_xwrite = NULL;
  23796. + if (sbinfo->si_xib)
  23797. + fput(sbinfo->si_xib);
  23798. + sbinfo->si_xib = NULL;
  23799. + free_page((unsigned long)sbinfo->si_xib_buf);
  23800. + sbinfo->si_xib_buf = NULL;
  23801. +}
  23802. +
  23803. +static int au_xino_set_xib(struct super_block *sb, struct file *base)
  23804. +{
  23805. + int err;
  23806. + loff_t pos;
  23807. + struct au_sbinfo *sbinfo;
  23808. + struct file *file;
  23809. +
  23810. + SiMustWriteLock(sb);
  23811. +
  23812. + sbinfo = au_sbi(sb);
  23813. + file = au_xino_create2(base, sbinfo->si_xib);
  23814. + err = PTR_ERR(file);
  23815. + if (IS_ERR(file))
  23816. + goto out;
  23817. + if (sbinfo->si_xib)
  23818. + fput(sbinfo->si_xib);
  23819. + sbinfo->si_xib = file;
  23820. + sbinfo->si_xread = find_readf(file);
  23821. + sbinfo->si_xwrite = find_writef(file);
  23822. +
  23823. + err = -ENOMEM;
  23824. + if (!sbinfo->si_xib_buf)
  23825. + sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
  23826. + if (unlikely(!sbinfo->si_xib_buf))
  23827. + goto out_unset;
  23828. +
  23829. + sbinfo->si_xib_last_pindex = 0;
  23830. + sbinfo->si_xib_next_bit = 0;
  23831. + if (i_size_read(file->f_dentry->d_inode) < PAGE_SIZE) {
  23832. + pos = 0;
  23833. + err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
  23834. + PAGE_SIZE, &pos);
  23835. + if (unlikely(err != PAGE_SIZE))
  23836. + goto out_free;
  23837. + }
  23838. + err = 0;
  23839. + goto out; /* success */
  23840. +
  23841. + out_free:
  23842. + free_page((unsigned long)sbinfo->si_xib_buf);
  23843. + sbinfo->si_xib_buf = NULL;
  23844. + if (err >= 0)
  23845. + err = -EIO;
  23846. + out_unset:
  23847. + fput(sbinfo->si_xib);
  23848. + sbinfo->si_xib = NULL;
  23849. + sbinfo->si_xread = NULL;
  23850. + sbinfo->si_xwrite = NULL;
  23851. + out:
  23852. + return err;
  23853. +}
  23854. +
  23855. +/* xino for each branch */
  23856. +static void xino_clear_br(struct super_block *sb)
  23857. +{
  23858. + aufs_bindex_t bindex, bend;
  23859. + struct au_branch *br;
  23860. +
  23861. + bend = au_sbend(sb);
  23862. + for (bindex = 0; bindex <= bend; bindex++) {
  23863. + br = au_sbr(sb, bindex);
  23864. + if (!br || !br->br_xino.xi_file)
  23865. + continue;
  23866. +
  23867. + fput(br->br_xino.xi_file);
  23868. + br->br_xino.xi_file = NULL;
  23869. + }
  23870. +}
  23871. +
  23872. +static int au_xino_set_br(struct super_block *sb, struct file *base)
  23873. +{
  23874. + int err;
  23875. + ino_t ino;
  23876. + aufs_bindex_t bindex, bend, bshared;
  23877. + struct {
  23878. + struct file *old, *new;
  23879. + } *fpair, *p;
  23880. + struct au_branch *br;
  23881. + struct inode *inode;
  23882. + au_writef_t writef;
  23883. +
  23884. + SiMustWriteLock(sb);
  23885. +
  23886. + err = -ENOMEM;
  23887. + bend = au_sbend(sb);
  23888. + fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS);
  23889. + if (unlikely(!fpair))
  23890. + goto out;
  23891. +
  23892. + inode = sb->s_root->d_inode;
  23893. + ino = AUFS_ROOT_INO;
  23894. + writef = au_sbi(sb)->si_xwrite;
  23895. + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
  23896. + br = au_sbr(sb, bindex);
  23897. + bshared = is_sb_shared(sb, bindex, bindex - 1);
  23898. + if (bshared >= 0) {
  23899. + /* shared xino */
  23900. + *p = fpair[bshared];
  23901. + get_file(p->new);
  23902. + }
  23903. +
  23904. + if (!p->new) {
  23905. + /* new xino */
  23906. + p->old = br->br_xino.xi_file;
  23907. + p->new = au_xino_create2(base, br->br_xino.xi_file);
  23908. + err = PTR_ERR(p->new);
  23909. + if (IS_ERR(p->new)) {
  23910. + p->new = NULL;
  23911. + goto out_pair;
  23912. + }
  23913. + }
  23914. +
  23915. + err = au_xino_do_write(writef, p->new,
  23916. + au_h_iptr(inode, bindex)->i_ino, ino);
  23917. + if (unlikely(err))
  23918. + goto out_pair;
  23919. + }
  23920. +
  23921. + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
  23922. + br = au_sbr(sb, bindex);
  23923. + if (br->br_xino.xi_file)
  23924. + fput(br->br_xino.xi_file);
  23925. + get_file(p->new);
  23926. + br->br_xino.xi_file = p->new;
  23927. + }
  23928. +
  23929. + out_pair:
  23930. + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++)
  23931. + if (p->new)
  23932. + fput(p->new);
  23933. + else
  23934. + break;
  23935. + kfree(fpair);
  23936. + out:
  23937. + return err;
  23938. +}
  23939. +
  23940. +void au_xino_clr(struct super_block *sb)
  23941. +{
  23942. + struct au_sbinfo *sbinfo;
  23943. +
  23944. + au_xigen_clr(sb);
  23945. + xino_clear_xib(sb);
  23946. + xino_clear_br(sb);
  23947. + sbinfo = au_sbi(sb);
  23948. + /* lvalue, do not call au_mntflags() */
  23949. + au_opt_clr(sbinfo->si_mntflags, XINO);
  23950. +}
  23951. +
  23952. +int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount)
  23953. +{
  23954. + int err, skip;
  23955. + struct dentry *parent, *cur_parent;
  23956. + struct qstr *dname, *cur_name;
  23957. + struct file *cur_xino;
  23958. + struct inode *dir;
  23959. + struct au_sbinfo *sbinfo;
  23960. +
  23961. + SiMustWriteLock(sb);
  23962. +
  23963. + err = 0;
  23964. + sbinfo = au_sbi(sb);
  23965. + parent = dget_parent(xino->file->f_dentry);
  23966. + if (remount) {
  23967. + skip = 0;
  23968. + dname = &xino->file->f_dentry->d_name;
  23969. + cur_xino = sbinfo->si_xib;
  23970. + if (cur_xino) {
  23971. + cur_parent = dget_parent(cur_xino->f_dentry);
  23972. + cur_name = &cur_xino->f_dentry->d_name;
  23973. + skip = (cur_parent == parent
  23974. + && dname->len == cur_name->len
  23975. + && !memcmp(dname->name, cur_name->name,
  23976. + dname->len));
  23977. + dput(cur_parent);
  23978. + }
  23979. + if (skip)
  23980. + goto out;
  23981. + }
  23982. +
  23983. + au_opt_set(sbinfo->si_mntflags, XINO);
  23984. + dir = parent->d_inode;
  23985. + mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT);
  23986. + /* mnt_want_write() is unnecessary here */
  23987. + err = au_xino_set_xib(sb, xino->file);
  23988. + if (!err)
  23989. + err = au_xigen_set(sb, xino->file);
  23990. + if (!err)
  23991. + err = au_xino_set_br(sb, xino->file);
  23992. + mutex_unlock(&dir->i_mutex);
  23993. + if (!err)
  23994. + goto out; /* success */
  23995. +
  23996. + /* reset all */
  23997. + AuIOErr("failed creating xino(%d).\n", err);
  23998. +
  23999. + out:
  24000. + dput(parent);
  24001. + return err;
  24002. +}
  24003. +
  24004. +/* ---------------------------------------------------------------------- */
  24005. +
  24006. +/*
  24007. + * create a xinofile at the default place/path.
  24008. + */
  24009. +struct file *au_xino_def(struct super_block *sb)
  24010. +{
  24011. + struct file *file;
  24012. + char *page, *p;
  24013. + struct au_branch *br;
  24014. + struct super_block *h_sb;
  24015. + struct path path;
  24016. + aufs_bindex_t bend, bindex, bwr;
  24017. +
  24018. + br = NULL;
  24019. + bend = au_sbend(sb);
  24020. + bwr = -1;
  24021. + for (bindex = 0; bindex <= bend; bindex++) {
  24022. + br = au_sbr(sb, bindex);
  24023. + if (au_br_writable(br->br_perm)
  24024. + && !au_test_fs_bad_xino(br->br_mnt->mnt_sb)) {
  24025. + bwr = bindex;
  24026. + break;
  24027. + }
  24028. + }
  24029. +
  24030. + if (bwr >= 0) {
  24031. + file = ERR_PTR(-ENOMEM);
  24032. + page = __getname();
  24033. + if (unlikely(!page))
  24034. + goto out;
  24035. + path.mnt = br->br_mnt;
  24036. + path.dentry = au_h_dptr(sb->s_root, bwr);
  24037. + p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
  24038. + file = (void *)p;
  24039. + if (!IS_ERR(p)) {
  24040. + strcat(p, "/" AUFS_XINO_FNAME);
  24041. + AuDbg("%s\n", p);
  24042. + file = au_xino_create(sb, p, /*silent*/0);
  24043. + if (!IS_ERR(file))
  24044. + au_xino_brid_set(sb, br->br_id);
  24045. + }
  24046. + __putname(page);
  24047. + } else {
  24048. + file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
  24049. + if (IS_ERR(file))
  24050. + goto out;
  24051. + h_sb = file->f_dentry->d_sb;
  24052. + if (unlikely(au_test_fs_bad_xino(h_sb))) {
  24053. + AuErr("xino doesn't support %s(%s)\n",
  24054. + AUFS_XINO_DEFPATH, au_sbtype(h_sb));
  24055. + fput(file);
  24056. + file = ERR_PTR(-EINVAL);
  24057. + }
  24058. + if (!IS_ERR(file))
  24059. + au_xino_brid_set(sb, -1);
  24060. + }
  24061. +
  24062. + out:
  24063. + return file;
  24064. +}
  24065. +
  24066. +/* ---------------------------------------------------------------------- */
  24067. +
  24068. +int au_xino_path(struct seq_file *seq, struct file *file)
  24069. +{
  24070. + int err;
  24071. +
  24072. + err = au_seq_path(seq, &file->f_path);
  24073. + if (unlikely(err < 0))
  24074. + goto out;
  24075. +
  24076. + err = 0;
  24077. +#define Deleted "\\040(deleted)"
  24078. + seq->count -= sizeof(Deleted) - 1;
  24079. + AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
  24080. + sizeof(Deleted) - 1));
  24081. +#undef Deleted
  24082. +
  24083. + out:
  24084. + return err;
  24085. +}
  24086. diff -Nur linux-2.6.31.4.orig/fs/Kconfig linux-2.6.31.4/fs/Kconfig
  24087. --- linux-2.6.31.4.orig/fs/Kconfig 2009-10-12 22:15:40.000000000 +0200
  24088. +++ linux-2.6.31.4/fs/Kconfig 2009-10-18 11:26:53.000000000 +0200
  24089. @@ -187,6 +187,7 @@
  24090. source "fs/ufs/Kconfig"
  24091. source "fs/exofs/Kconfig"
  24092. source "fs/nilfs2/Kconfig"
  24093. +source "fs/aufs/Kconfig"
  24094. endif # MISC_FILESYSTEMS
  24095. diff -Nur linux-2.6.31.4.orig/fs/Makefile linux-2.6.31.4/fs/Makefile
  24096. --- linux-2.6.31.4.orig/fs/Makefile 2009-10-12 22:15:40.000000000 +0200
  24097. +++ linux-2.6.31.4/fs/Makefile 2009-10-18 11:26:01.000000000 +0200
  24098. @@ -85,6 +85,7 @@
  24099. obj-$(CONFIG_HFS_FS) += hfs/
  24100. obj-$(CONFIG_ECRYPT_FS) += ecryptfs/
  24101. obj-$(CONFIG_VXFS_FS) += freevxfs/
  24102. +obj-$(CONFIG_AUFS_FS) += aufs/
  24103. obj-$(CONFIG_NFS_FS) += nfs/
  24104. obj-$(CONFIG_EXPORTFS) += exportfs/
  24105. obj-$(CONFIG_NFSD) += nfsd/
  24106. diff -Nur linux-2.6.31.4.orig/fs/namei.c linux-2.6.31.4/fs/namei.c
  24107. --- linux-2.6.31.4.orig/fs/namei.c 2009-10-12 22:15:40.000000000 +0200
  24108. +++ linux-2.6.31.4/fs/namei.c 2009-10-18 11:26:01.000000000 +0200
  24109. @@ -337,6 +337,7 @@
  24110. return 0;
  24111. }
  24112. +EXPORT_SYMBOL(deny_write_access);
  24113. /**
  24114. * path_get - get a reference to a path
  24115. @@ -1219,7 +1220,7 @@
  24116. * needs parent already locked. Doesn't follow mounts.
  24117. * SMP-safe.
  24118. */
  24119. -static struct dentry *lookup_hash(struct nameidata *nd)
  24120. +struct dentry *lookup_hash(struct nameidata *nd)
  24121. {
  24122. int err;
  24123. @@ -1228,8 +1229,9 @@
  24124. return ERR_PTR(err);
  24125. return __lookup_hash(&nd->last, nd->path.dentry, nd);
  24126. }
  24127. +EXPORT_SYMBOL(lookup_hash);
  24128. -static int __lookup_one_len(const char *name, struct qstr *this,
  24129. +int __lookup_one_len(const char *name, struct qstr *this,
  24130. struct dentry *base, int len)
  24131. {
  24132. unsigned long hash;
  24133. @@ -1250,6 +1252,7 @@
  24134. this->hash = end_name_hash(hash);
  24135. return 0;
  24136. }
  24137. +EXPORT_SYMBOL(__lookup_one_len);
  24138. /**
  24139. * lookup_one_len - filesystem helper to lookup single pathname component
  24140. diff -Nur linux-2.6.31.4.orig/fs/namespace.c linux-2.6.31.4/fs/namespace.c
  24141. --- linux-2.6.31.4.orig/fs/namespace.c 2009-10-12 22:15:40.000000000 +0200
  24142. +++ linux-2.6.31.4/fs/namespace.c 2009-10-18 11:26:01.000000000 +0200
  24143. @@ -39,6 +39,7 @@
  24144. /* spinlock for vfsmount related operations, inplace of dcache_lock */
  24145. __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock);
  24146. +EXPORT_SYMBOL(vfsmount_lock);
  24147. static int event;
  24148. static DEFINE_IDA(mnt_id_ida);
  24149. diff -Nur linux-2.6.31.4.orig/fs/open.c linux-2.6.31.4/fs/open.c
  24150. --- linux-2.6.31.4.orig/fs/open.c 2009-10-12 22:15:40.000000000 +0200
  24151. +++ linux-2.6.31.4/fs/open.c 2009-10-18 11:26:01.000000000 +0200
  24152. @@ -221,6 +221,7 @@
  24153. mutex_unlock(&dentry->d_inode->i_mutex);
  24154. return err;
  24155. }
  24156. +EXPORT_SYMBOL(do_truncate);
  24157. static long do_sys_truncate(const char __user *pathname, loff_t length)
  24158. {
  24159. diff -Nur linux-2.6.31.4.orig/fs/splice.c linux-2.6.31.4/fs/splice.c
  24160. --- linux-2.6.31.4.orig/fs/splice.c 2009-10-12 22:15:40.000000000 +0200
  24161. +++ linux-2.6.31.4/fs/splice.c 2009-10-18 11:26:01.000000000 +0200
  24162. @@ -1057,8 +1057,8 @@
  24163. /*
  24164. * Attempt to initiate a splice from pipe to file.
  24165. */
  24166. -static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  24167. - loff_t *ppos, size_t len, unsigned int flags)
  24168. +long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  24169. + loff_t *ppos, size_t len, unsigned int flags)
  24170. {
  24171. ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
  24172. loff_t *, size_t, unsigned int);
  24173. @@ -1080,13 +1080,14 @@
  24174. return splice_write(pipe, out, ppos, len, flags);
  24175. }
  24176. +EXPORT_SYMBOL(do_splice_from);
  24177. /*
  24178. * Attempt to initiate a splice from a file to a pipe.
  24179. */
  24180. -static long do_splice_to(struct file *in, loff_t *ppos,
  24181. - struct pipe_inode_info *pipe, size_t len,
  24182. - unsigned int flags)
  24183. +long do_splice_to(struct file *in, loff_t *ppos,
  24184. + struct pipe_inode_info *pipe, size_t len,
  24185. + unsigned int flags)
  24186. {
  24187. ssize_t (*splice_read)(struct file *, loff_t *,
  24188. struct pipe_inode_info *, size_t, unsigned int);
  24189. @@ -1105,6 +1106,7 @@
  24190. return splice_read(in, ppos, pipe, len, flags);
  24191. }
  24192. +EXPORT_SYMBOL(do_splice_to);
  24193. /**
  24194. * splice_direct_to_actor - splices data directly between two non-pipes
  24195. diff -Nur linux-2.6.31.4.orig/include/linux/aufs_type.h linux-2.6.31.4/include/linux/aufs_type.h
  24196. --- linux-2.6.31.4.orig/include/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
  24197. +++ linux-2.6.31.4/include/linux/aufs_type.h 2009-10-18 11:26:01.000000000 +0200
  24198. @@ -0,0 +1,109 @@
  24199. +/*
  24200. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  24201. + *
  24202. + * This program, aufs is free software; you can redistribute it and/or modify
  24203. + * it under the terms of the GNU General Public License as published by
  24204. + * the Free Software Foundation; either version 2 of the License, or
  24205. + * (at your option) any later version.
  24206. + *
  24207. + * This program is distributed in the hope that it will be useful,
  24208. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24209. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24210. + * GNU General Public License for more details.
  24211. + *
  24212. + * You should have received a copy of the GNU General Public License
  24213. + * along with this program; if not, write to the Free Software
  24214. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  24215. + */
  24216. +
  24217. +#ifndef __AUFS_TYPE_H__
  24218. +#define __AUFS_TYPE_H__
  24219. +
  24220. +#include <linux/ioctl.h>
  24221. +
  24222. +#define AUFS_VERSION "2-standalone.tree-30-20090803"
  24223. +
  24224. +/* todo? move this to linux-2.6.19/include/magic.h */
  24225. +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
  24226. +
  24227. +/* ---------------------------------------------------------------------- */
  24228. +
  24229. +#ifdef CONFIG_AUFS_BRANCH_MAX_127
  24230. +/* some environments treat 'char' as 'unsigned char' by default */
  24231. +typedef signed char aufs_bindex_t;
  24232. +#define AUFS_BRANCH_MAX 127
  24233. +#else
  24234. +typedef short aufs_bindex_t;
  24235. +#ifdef CONFIG_AUFS_BRANCH_MAX_511
  24236. +#define AUFS_BRANCH_MAX 511
  24237. +#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
  24238. +#define AUFS_BRANCH_MAX 1023
  24239. +#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
  24240. +#define AUFS_BRANCH_MAX 32767
  24241. +#endif
  24242. +#endif
  24243. +
  24244. +#ifdef __KERNEL__
  24245. +#ifndef AUFS_BRANCH_MAX
  24246. +#error unknown CONFIG_AUFS_BRANCH_MAX value
  24247. +#endif
  24248. +#endif /* __KERNEL__ */
  24249. +
  24250. +/* ---------------------------------------------------------------------- */
  24251. +
  24252. +#define AUFS_NAME "aufs"
  24253. +#define AUFS_FSTYPE AUFS_NAME
  24254. +
  24255. +#define AUFS_ROOT_INO 2
  24256. +#define AUFS_FIRST_INO 11
  24257. +
  24258. +#define AUFS_WH_PFX ".wh."
  24259. +#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1)
  24260. +#define AUFS_XINO_FNAME "." AUFS_NAME ".xino"
  24261. +#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME
  24262. +#define AUFS_XINO_TRUNC_INIT 64 /* blocks */
  24263. +#define AUFS_XINO_TRUNC_STEP 4 /* blocks */
  24264. +#define AUFS_DIRWH_DEF 3
  24265. +#define AUFS_RDCACHE_DEF 10 /* seconds */
  24266. +#define AUFS_RDBLK_DEF 512 /* bytes */
  24267. +#define AUFS_RDHASH_DEF 32
  24268. +#define AUFS_WKQ_NAME AUFS_NAME "d"
  24269. +#define AUFS_NWKQ_DEF 4
  24270. +#define AUFS_MFS_SECOND_DEF 30 /* seconds */
  24271. +#define AUFS_PLINK_WARN 100 /* number of plinks */
  24272. +
  24273. +#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */
  24274. +#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME
  24275. +
  24276. +#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME
  24277. +#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk"
  24278. +#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph"
  24279. +
  24280. +/* doubly whiteouted */
  24281. +#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME
  24282. +#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME
  24283. +#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME
  24284. +
  24285. +/* branch permission */
  24286. +#define AUFS_BRPERM_RW "rw"
  24287. +#define AUFS_BRPERM_RO "ro"
  24288. +#define AUFS_BRPERM_RR "rr"
  24289. +#define AUFS_BRPERM_WH "wh"
  24290. +#define AUFS_BRPERM_NLWH "nolwh"
  24291. +#define AUFS_BRPERM_ROWH AUFS_BRPERM_RO "+" AUFS_BRPERM_WH
  24292. +#define AUFS_BRPERM_RRWH AUFS_BRPERM_RR "+" AUFS_BRPERM_WH
  24293. +#define AUFS_BRPERM_RWNLWH AUFS_BRPERM_RW "+" AUFS_BRPERM_NLWH
  24294. +
  24295. +/* ---------------------------------------------------------------------- */
  24296. +
  24297. +/* ioctl */
  24298. +enum {
  24299. + AuCtl_PLINK_MAINT,
  24300. + AuCtl_PLINK_CLEAN
  24301. +};
  24302. +
  24303. +#define AuCtlType 'A'
  24304. +#define AUFS_CTL_PLINK_MAINT _IO(AuCtlType, AuCtl_PLINK_MAINT)
  24305. +#define AUFS_CTL_PLINK_CLEAN _IO(AuCtlType, AuCtl_PLINK_CLEAN)
  24306. +
  24307. +#endif /* __AUFS_TYPE_H__ */
  24308. diff -Nur linux-2.6.31.4.orig/include/linux/Kbuild linux-2.6.31.4/include/linux/Kbuild
  24309. --- linux-2.6.31.4.orig/include/linux/Kbuild 2009-10-12 22:15:40.000000000 +0200
  24310. +++ linux-2.6.31.4/include/linux/Kbuild 2009-10-18 11:26:01.000000000 +0200
  24311. @@ -34,6 +34,7 @@
  24312. header-y += atmsap.h
  24313. header-y += atmsvc.h
  24314. header-y += atm_zatm.h
  24315. +header-y += aufs_type.h
  24316. header-y += auto_fs4.h
  24317. header-y += ax25.h
  24318. header-y += b1lli.h
  24319. diff -Nur linux-2.6.31.4.orig/include/linux/namei.h linux-2.6.31.4/include/linux/namei.h
  24320. --- linux-2.6.31.4.orig/include/linux/namei.h 2009-10-12 22:15:40.000000000 +0200
  24321. +++ linux-2.6.31.4/include/linux/namei.h 2009-10-18 11:26:01.000000000 +0200
  24322. @@ -75,6 +75,9 @@
  24323. extern struct file *nameidata_to_filp(struct nameidata *nd, int flags);
  24324. extern void release_open_intent(struct nameidata *);
  24325. +extern struct dentry *lookup_hash(struct nameidata *nd);
  24326. +extern int __lookup_one_len(const char *name, struct qstr *this,
  24327. + struct dentry *base, int len);
  24328. extern struct dentry *lookup_one_len(const char *, struct dentry *, int);
  24329. extern struct dentry *lookup_one_noperm(const char *, struct dentry *);
  24330. diff -Nur linux-2.6.31.4.orig/include/linux/splice.h linux-2.6.31.4/include/linux/splice.h
  24331. --- linux-2.6.31.4.orig/include/linux/splice.h 2009-10-12 22:15:40.000000000 +0200
  24332. +++ linux-2.6.31.4/include/linux/splice.h 2009-10-18 11:26:01.000000000 +0200
  24333. @@ -82,4 +82,10 @@
  24334. extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *,
  24335. splice_direct_actor *);
  24336. +extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  24337. + loff_t *ppos, size_t len, unsigned int flags);
  24338. +extern long do_splice_to(struct file *in, loff_t *ppos,
  24339. + struct pipe_inode_info *pipe, size_t len,
  24340. + unsigned int flags);
  24341. +
  24342. #endif
  24343. diff -Nur linux-2.6.31.4.orig/security/device_cgroup.c linux-2.6.31.4/security/device_cgroup.c
  24344. --- linux-2.6.31.4.orig/security/device_cgroup.c 2009-10-12 22:15:40.000000000 +0200
  24345. +++ linux-2.6.31.4/security/device_cgroup.c 2009-10-18 11:26:01.000000000 +0200
  24346. @@ -513,6 +513,7 @@
  24347. return -EPERM;
  24348. }
  24349. +EXPORT_SYMBOL(devcgroup_inode_permission);
  24350. int devcgroup_inode_mknod(int mode, dev_t dev)
  24351. {
  24352. diff -Nur linux-2.6.31.4.orig/security/security.c linux-2.6.31.4/security/security.c
  24353. --- linux-2.6.31.4.orig/security/security.c 2009-10-12 22:15:40.000000000 +0200
  24354. +++ linux-2.6.31.4/security/security.c 2009-10-18 11:26:01.000000000 +0200
  24355. @@ -386,6 +386,7 @@
  24356. return 0;
  24357. return security_ops->path_mkdir(path, dentry, mode);
  24358. }
  24359. +EXPORT_SYMBOL(security_path_mkdir);
  24360. int security_path_rmdir(struct path *path, struct dentry *dentry)
  24361. {
  24362. @@ -393,6 +394,7 @@
  24363. return 0;
  24364. return security_ops->path_rmdir(path, dentry);
  24365. }
  24366. +EXPORT_SYMBOL(security_path_rmdir);
  24367. int security_path_unlink(struct path *path, struct dentry *dentry)
  24368. {
  24369. @@ -400,6 +402,7 @@
  24370. return 0;
  24371. return security_ops->path_unlink(path, dentry);
  24372. }
  24373. +EXPORT_SYMBOL(security_path_unlink);
  24374. int security_path_symlink(struct path *path, struct dentry *dentry,
  24375. const char *old_name)
  24376. @@ -408,6 +411,7 @@
  24377. return 0;
  24378. return security_ops->path_symlink(path, dentry, old_name);
  24379. }
  24380. +EXPORT_SYMBOL(security_path_symlink);
  24381. int security_path_link(struct dentry *old_dentry, struct path *new_dir,
  24382. struct dentry *new_dentry)
  24383. @@ -416,6 +420,7 @@
  24384. return 0;
  24385. return security_ops->path_link(old_dentry, new_dir, new_dentry);
  24386. }
  24387. +EXPORT_SYMBOL(security_path_link);
  24388. int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
  24389. struct path *new_dir, struct dentry *new_dentry)
  24390. @@ -426,6 +431,7 @@
  24391. return security_ops->path_rename(old_dir, old_dentry, new_dir,
  24392. new_dentry);
  24393. }
  24394. +EXPORT_SYMBOL(security_path_rename);
  24395. int security_path_truncate(struct path *path, loff_t length,
  24396. unsigned int time_attrs)
  24397. @@ -434,6 +440,7 @@
  24398. return 0;
  24399. return security_ops->path_truncate(path, length, time_attrs);
  24400. }
  24401. +EXPORT_SYMBOL(security_path_truncate);
  24402. #endif
  24403. int security_inode_create(struct inode *dir, struct dentry *dentry, int mode)
  24404. @@ -505,6 +512,7 @@
  24405. return 0;
  24406. return security_ops->inode_readlink(dentry);
  24407. }
  24408. +EXPORT_SYMBOL(security_inode_readlink);
  24409. int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
  24410. {
  24411. @@ -519,6 +527,7 @@
  24412. return 0;
  24413. return security_ops->inode_permission(inode, mask);
  24414. }
  24415. +EXPORT_SYMBOL(security_inode_permission);
  24416. int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
  24417. {
  24418. @@ -619,6 +628,7 @@
  24419. {
  24420. return security_ops->file_permission(file, mask);
  24421. }
  24422. +EXPORT_SYMBOL(security_file_permission);
  24423. int security_file_alloc(struct file *file)
  24424. {