aufs2.patch 610 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456
  1. diff -Nur linux-2.6.34.orig/Documentation/ABI/testing/debugfs-aufs linux-2.6.34/Documentation/ABI/testing/debugfs-aufs
  2. --- linux-2.6.34.orig/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100
  3. +++ linux-2.6.34/Documentation/ABI/testing/debugfs-aufs 2010-05-23 23:33:19.223473085 +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.34.orig/Documentation/ABI/testing/sysfs-aufs linux-2.6.34/Documentation/ABI/testing/sysfs-aufs
  46. --- linux-2.6.34.orig/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100
  47. +++ linux-2.6.34/Documentation/ABI/testing/sysfs-aufs 2010-05-23 23:33:19.243464626 +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.34.orig/fs/aufs/aufs.h linux-2.6.34/fs/aufs/aufs.h
  75. --- linux-2.6.34.orig/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100
  76. +++ linux-2.6.34/fs/aufs/aufs.h 2010-05-23 23:33:19.313473179 +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.34.orig/fs/aufs/branch.c linux-2.6.34/fs/aufs/branch.c
  130. --- linux-2.6.34.orig/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100
  131. +++ linux-2.6.34/fs/aufs/branch.c 2010-05-23 23:33:19.351420621 +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.34.orig/fs/aufs/branch.h linux-2.6.34/fs/aufs/branch.h
  1108. --- linux-2.6.34.orig/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100
  1109. +++ linux-2.6.34/fs/aufs/branch.h 2010-05-23 23:33:19.393473115 +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.34.orig/fs/aufs/cpup.c linux-2.6.34/fs/aufs/cpup.c
  1331. --- linux-2.6.34.orig/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
  1332. +++ linux-2.6.34/fs/aufs/cpup.c 2010-05-23 23:33:19.453728246 +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.34.orig/fs/aufs/cpup.h linux-2.6.34/fs/aufs/cpup.h
  2383. --- linux-2.6.34.orig/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100
  2384. +++ linux-2.6.34/fs/aufs/cpup.h 2010-05-23 23:33:19.493473084 +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.34.orig/fs/aufs/dbgaufs.c linux-2.6.34/fs/aufs/dbgaufs.c
  2468. --- linux-2.6.34.orig/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
  2469. +++ linux-2.6.34/fs/aufs/dbgaufs.c 2010-05-23 23:33:19.532223041 +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.34.orig/fs/aufs/dbgaufs.h linux-2.6.34/fs/aufs/dbgaufs.h
  2803. --- linux-2.6.34.orig/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
  2804. +++ linux-2.6.34/fs/aufs/dbgaufs.h 2010-05-23 23:33:19.573473097 +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.34.orig/fs/aufs/dcsub.c linux-2.6.34/fs/aufs/dcsub.c
  2886. --- linux-2.6.34.orig/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100
  2887. +++ linux-2.6.34/fs/aufs/dcsub.c 2010-05-23 23:33:19.603473096 +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.34.orig/fs/aufs/dcsub.h linux-2.6.34/fs/aufs/dcsub.h
  3113. --- linux-2.6.34.orig/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100
  3114. +++ linux-2.6.34/fs/aufs/dcsub.h 2010-05-23 23:33:19.643473001 +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.34.orig/fs/aufs/debug.c linux-2.6.34/fs/aufs/debug.c
  3171. --- linux-2.6.34.orig/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
  3172. +++ linux-2.6.34/fs/aufs/debug.c 2010-05-23 23:33:19.680978144 +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.34.orig/fs/aufs/debug.h linux-2.6.34/fs/aufs/debug.h
  3602. --- linux-2.6.34.orig/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100
  3603. +++ linux-2.6.34/fs/aufs/debug.h 2010-05-23 23:33:19.723473058 +0200
  3604. @@ -0,0 +1,261 @@
  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 <asm/system.h>
  3633. +#include <linux/bug.h>
  3634. +/* #include <linux/err.h> */
  3635. +#include <linux/init.h>
  3636. +/* #include <linux/kernel.h> */
  3637. +#include <linux/delay.h>
  3638. +/* #include <linux/kd.h> */
  3639. +/* #include <linux/vt_kern.h> */
  3640. +#include <linux/sysrq.h>
  3641. +#include <linux/aufs_type.h>
  3642. +
  3643. +#ifdef CONFIG_AUFS_DEBUG
  3644. +#define AuDebugOn(a) BUG_ON(a)
  3645. +
  3646. +/* module parameter */
  3647. +extern int aufs_debug;
  3648. +static inline void au_debug(int n)
  3649. +{
  3650. + aufs_debug = n;
  3651. + smp_mb();
  3652. +}
  3653. +
  3654. +static inline int au_debug_test(void)
  3655. +{
  3656. + return aufs_debug;
  3657. +}
  3658. +#else
  3659. +#define AuDebugOn(a) do {} while (0)
  3660. +#define au_debug() do {} while (0)
  3661. +static inline int au_debug_test(void)
  3662. +{
  3663. + return 0;
  3664. +}
  3665. +#endif /* CONFIG_AUFS_DEBUG */
  3666. +
  3667. +/* ---------------------------------------------------------------------- */
  3668. +
  3669. +/* debug print */
  3670. +
  3671. +#define AuDpri(lvl, fmt, arg...) \
  3672. + printk(lvl AUFS_NAME " %s:%d:%s[%d]: " fmt, \
  3673. + __func__, __LINE__, current->comm, current->pid, ##arg)
  3674. +#define AuDbg(fmt, arg...) do { \
  3675. + if (au_debug_test()) \
  3676. + AuDpri(KERN_DEBUG, "DEBUG: " fmt, ##arg); \
  3677. +} while (0)
  3678. +#define AuLabel(l) AuDbg(#l "\n")
  3679. +#define AuInfo(fmt, arg...) AuDpri(KERN_INFO, fmt, ##arg)
  3680. +#define AuWarn(fmt, arg...) AuDpri(KERN_WARNING, fmt, ##arg)
  3681. +#define AuErr(fmt, arg...) AuDpri(KERN_ERR, fmt, ##arg)
  3682. +#define AuIOErr(fmt, arg...) AuErr("I/O Error, " fmt, ##arg)
  3683. +#define AuWarn1(fmt, arg...) do { \
  3684. + static unsigned char _c; \
  3685. + if (!_c++) \
  3686. + AuWarn(fmt, ##arg); \
  3687. +} while (0)
  3688. +
  3689. +#define AuErr1(fmt, arg...) do { \
  3690. + static unsigned char _c; \
  3691. + if (!_c++) \
  3692. + AuErr(fmt, ##arg); \
  3693. +} while (0)
  3694. +
  3695. +#define AuIOErr1(fmt, arg...) do { \
  3696. + static unsigned char _c; \
  3697. + if (!_c++) \
  3698. + AuIOErr(fmt, ##arg); \
  3699. +} while (0)
  3700. +
  3701. +#define AuUnsupportMsg "This operation is not supported." \
  3702. + " Please report this application to aufs-users ML."
  3703. +#define AuUnsupport(fmt, args...) do { \
  3704. + AuErr(AuUnsupportMsg "\n" fmt, ##args); \
  3705. + dump_stack(); \
  3706. +} while (0)
  3707. +
  3708. +#define AuTraceErr(e) do { \
  3709. + if (unlikely((e) < 0)) \
  3710. + AuDbg("err %d\n", (int)(e)); \
  3711. +} while (0)
  3712. +
  3713. +#define AuTraceErrPtr(p) do { \
  3714. + if (IS_ERR(p)) \
  3715. + AuDbg("err %ld\n", PTR_ERR(p)); \
  3716. +} while (0)
  3717. +
  3718. +/* dirty macros for debug print, use with "%.*s" and caution */
  3719. +#define AuLNPair(qstr) (qstr)->len, (qstr)->name
  3720. +#define AuDLNPair(d) AuLNPair(&(d)->d_name)
  3721. +
  3722. +/* ---------------------------------------------------------------------- */
  3723. +
  3724. +struct au_sbinfo;
  3725. +struct au_finfo;
  3726. +struct dentry;
  3727. +#ifdef CONFIG_AUFS_DEBUG
  3728. +extern char *au_plevel;
  3729. +struct au_nhash;
  3730. +void au_dpri_whlist(struct au_nhash *whlist);
  3731. +struct au_vdir;
  3732. +void au_dpri_vdir(struct au_vdir *vdir);
  3733. +struct inode;
  3734. +void au_dpri_inode(struct inode *inode);
  3735. +void au_dpri_dentry(struct dentry *dentry);
  3736. +struct file;
  3737. +void au_dpri_file(struct file *filp);
  3738. +struct super_block;
  3739. +void au_dpri_sb(struct super_block *sb);
  3740. +
  3741. +void au_dbg_sleep_jiffy(int jiffy);
  3742. +struct iattr;
  3743. +void au_dbg_iattr(struct iattr *ia);
  3744. +
  3745. +void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen);
  3746. +void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen);
  3747. +void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
  3748. +void au_dbg_verify_hf(struct au_finfo *finfo);
  3749. +void au_dbg_verify_kthread(void);
  3750. +
  3751. +int __init au_debug_init(void);
  3752. +void au_debug_sbinfo_init(struct au_sbinfo *sbinfo);
  3753. +#define AuDbgWhlist(w) do { \
  3754. + AuDbg(#w "\n"); \
  3755. + au_dpri_whlist(w); \
  3756. +} while (0)
  3757. +
  3758. +#define AuDbgVdir(v) do { \
  3759. + AuDbg(#v "\n"); \
  3760. + au_dpri_vdir(v); \
  3761. +} while (0)
  3762. +
  3763. +#define AuDbgInode(i) do { \
  3764. + AuDbg(#i "\n"); \
  3765. + au_dpri_inode(i); \
  3766. +} while (0)
  3767. +
  3768. +#define AuDbgDentry(d) do { \
  3769. + AuDbg(#d "\n"); \
  3770. + au_dpri_dentry(d); \
  3771. +} while (0)
  3772. +
  3773. +#define AuDbgFile(f) do { \
  3774. + AuDbg(#f "\n"); \
  3775. + au_dpri_file(f); \
  3776. +} while (0)
  3777. +
  3778. +#define AuDbgSb(sb) do { \
  3779. + AuDbg(#sb "\n"); \
  3780. + au_dpri_sb(sb); \
  3781. +} while (0)
  3782. +
  3783. +#define AuDbgSleep(sec) do { \
  3784. + AuDbg("sleep %d sec\n", sec); \
  3785. + ssleep(sec); \
  3786. +} while (0)
  3787. +
  3788. +#define AuDbgSleepJiffy(jiffy) do { \
  3789. + AuDbg("sleep %d jiffies\n", jiffy); \
  3790. + au_dbg_sleep_jiffy(jiffy); \
  3791. +} while (0)
  3792. +
  3793. +#define AuDbgIAttr(ia) do { \
  3794. + AuDbg("ia_valid 0x%x\n", (ia)->ia_valid); \
  3795. + au_dbg_iattr(ia); \
  3796. +} while (0)
  3797. +#else
  3798. +static inline void au_dbg_verify_dir_parent(struct dentry *dentry,
  3799. + unsigned int sigen)
  3800. +{
  3801. + /* empty */
  3802. +}
  3803. +static inline void au_dbg_verify_nondir_parent(struct dentry *dentry,
  3804. + unsigned int sigen)
  3805. +{
  3806. + /* empty */
  3807. +}
  3808. +static inline void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
  3809. +{
  3810. + /* empty */
  3811. +}
  3812. +static inline void au_dbg_verify_hf(struct au_finfo *finfo)
  3813. +{
  3814. + /* empty */
  3815. +}
  3816. +static inline void au_dbg_verify_kthread(void)
  3817. +{
  3818. + /* empty */
  3819. +}
  3820. +
  3821. +static inline int au_debug_init(void)
  3822. +{
  3823. + return 0;
  3824. +}
  3825. +static inline void au_debug_sbinfo_init(struct au_sbinfo *sbinfo)
  3826. +{
  3827. + /* empty */
  3828. +}
  3829. +#define AuDbgWhlist(w) do {} while (0)
  3830. +#define AuDbgVdir(v) do {} while (0)
  3831. +#define AuDbgInode(i) do {} while (0)
  3832. +#define AuDbgDentry(d) do {} while (0)
  3833. +#define AuDbgFile(f) do {} while (0)
  3834. +#define AuDbgSb(sb) do {} while (0)
  3835. +#define AuDbgSleep(sec) do {} while (0)
  3836. +#define AuDbgSleepJiffy(jiffy) do {} while (0)
  3837. +#define AuDbgIAttr(ia) do {} while (0)
  3838. +#endif /* CONFIG_AUFS_DEBUG */
  3839. +
  3840. +/* ---------------------------------------------------------------------- */
  3841. +
  3842. +#ifdef CONFIG_AUFS_MAGIC_SYSRQ
  3843. +int __init au_sysrq_init(void);
  3844. +void au_sysrq_fin(void);
  3845. +
  3846. +#ifdef CONFIG_HW_CONSOLE
  3847. +#define au_dbg_blocked() do { \
  3848. + WARN_ON(1); \
  3849. + handle_sysrq('w', vc_cons[fg_console].d->vc_tty); \
  3850. +} while (0)
  3851. +#else
  3852. +#define au_dbg_blocked() do {} while (0)
  3853. +#endif
  3854. +
  3855. +#else
  3856. +static inline int au_sysrq_init(void)
  3857. +{
  3858. + return 0;
  3859. +}
  3860. +#define au_sysrq_fin() do {} while (0)
  3861. +#define au_dbg_blocked() do {} while (0)
  3862. +#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
  3863. +
  3864. +#endif /* __KERNEL__ */
  3865. +#endif /* __AUFS_DEBUG_H__ */
  3866. diff -Nur linux-2.6.34.orig/fs/aufs/dentry.c linux-2.6.34/fs/aufs/dentry.c
  3867. --- linux-2.6.34.orig/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100
  3868. +++ linux-2.6.34/fs/aufs/dentry.c 2010-05-23 23:33:19.785918972 +0200
  3869. @@ -0,0 +1,880 @@
  3870. +/*
  3871. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  3872. + *
  3873. + * This program, aufs is free software; you can redistribute it and/or modify
  3874. + * it under the terms of the GNU General Public License as published by
  3875. + * the Free Software Foundation; either version 2 of the License, or
  3876. + * (at your option) any later version.
  3877. + *
  3878. + * This program is distributed in the hope that it will be useful,
  3879. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3880. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3881. + * GNU General Public License for more details.
  3882. + *
  3883. + * You should have received a copy of the GNU General Public License
  3884. + * along with this program; if not, write to the Free Software
  3885. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  3886. + */
  3887. +
  3888. +/*
  3889. + * lookup and dentry operations
  3890. + */
  3891. +
  3892. +#include <linux/namei.h>
  3893. +#include "aufs.h"
  3894. +
  3895. +static void au_h_nd(struct nameidata *h_nd, struct nameidata *nd)
  3896. +{
  3897. + if (nd) {
  3898. + *h_nd = *nd;
  3899. +
  3900. + /*
  3901. + * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
  3902. + * due to whiteout and branch permission.
  3903. + */
  3904. + h_nd->flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
  3905. + | LOOKUP_FOLLOW);
  3906. + /* unnecessary? */
  3907. + h_nd->intent.open.file = NULL;
  3908. + } else
  3909. + memset(h_nd, 0, sizeof(*h_nd));
  3910. +}
  3911. +
  3912. +struct au_lkup_one_args {
  3913. + struct dentry **errp;
  3914. + struct qstr *name;
  3915. + struct dentry *h_parent;
  3916. + struct au_branch *br;
  3917. + struct nameidata *nd;
  3918. +};
  3919. +
  3920. +struct dentry *au_lkup_one(struct qstr *name, struct dentry *h_parent,
  3921. + struct au_branch *br, struct nameidata *nd)
  3922. +{
  3923. + struct dentry *h_dentry;
  3924. + int err;
  3925. + struct nameidata h_nd;
  3926. +
  3927. + if (au_test_fs_null_nd(h_parent->d_sb))
  3928. + return vfsub_lookup_one_len(name->name, h_parent, name->len);
  3929. +
  3930. + au_h_nd(&h_nd, nd);
  3931. + h_nd.path.dentry = h_parent;
  3932. + h_nd.path.mnt = br->br_mnt;
  3933. +
  3934. + err = __lookup_one_len(name->name, &h_nd.last, NULL, name->len);
  3935. + h_dentry = ERR_PTR(err);
  3936. + if (!err) {
  3937. + path_get(&h_nd.path);
  3938. + h_dentry = vfsub_lookup_hash(&h_nd);
  3939. + path_put(&h_nd.path);
  3940. + }
  3941. +
  3942. + return h_dentry;
  3943. +}
  3944. +
  3945. +static void au_call_lkup_one(void *args)
  3946. +{
  3947. + struct au_lkup_one_args *a = args;
  3948. + *a->errp = au_lkup_one(a->name, a->h_parent, a->br, a->nd);
  3949. +}
  3950. +
  3951. +#define AuLkup_ALLOW_NEG 1
  3952. +#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name)
  3953. +#define au_fset_lkup(flags, name) { (flags) |= AuLkup_##name; }
  3954. +#define au_fclr_lkup(flags, name) { (flags) &= ~AuLkup_##name; }
  3955. +
  3956. +struct au_do_lookup_args {
  3957. + unsigned int flags;
  3958. + mode_t type;
  3959. + struct nameidata *nd;
  3960. +};
  3961. +
  3962. +/*
  3963. + * returns positive/negative dentry, NULL or an error.
  3964. + * NULL means whiteout-ed or not-found.
  3965. + */
  3966. +static struct dentry*
  3967. +au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
  3968. + aufs_bindex_t bindex, struct qstr *wh_name,
  3969. + struct au_do_lookup_args *args)
  3970. +{
  3971. + struct dentry *h_dentry;
  3972. + struct inode *h_inode, *inode;
  3973. + struct qstr *name;
  3974. + struct au_branch *br;
  3975. + int wh_found, opq;
  3976. + unsigned char wh_able;
  3977. + const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
  3978. +
  3979. + name = &dentry->d_name;
  3980. + wh_found = 0;
  3981. + br = au_sbr(dentry->d_sb, bindex);
  3982. + wh_able = !!au_br_whable(br->br_perm);
  3983. + if (wh_able)
  3984. + wh_found = au_wh_test(h_parent, wh_name, br, /*try_sio*/0);
  3985. + h_dentry = ERR_PTR(wh_found);
  3986. + if (!wh_found)
  3987. + goto real_lookup;
  3988. + if (unlikely(wh_found < 0))
  3989. + goto out;
  3990. +
  3991. + /* We found a whiteout */
  3992. + /* au_set_dbend(dentry, bindex); */
  3993. + au_set_dbwh(dentry, bindex);
  3994. + if (!allow_neg)
  3995. + return NULL; /* success */
  3996. +
  3997. + real_lookup:
  3998. + h_dentry = au_lkup_one(name, h_parent, br, args->nd);
  3999. + if (IS_ERR(h_dentry))
  4000. + goto out;
  4001. +
  4002. + h_inode = h_dentry->d_inode;
  4003. + if (!h_inode) {
  4004. + if (!allow_neg)
  4005. + goto out_neg;
  4006. + } else if (wh_found
  4007. + || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
  4008. + goto out_neg;
  4009. +
  4010. + if (au_dbend(dentry) <= bindex)
  4011. + au_set_dbend(dentry, bindex);
  4012. + if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
  4013. + au_set_dbstart(dentry, bindex);
  4014. + au_set_h_dptr(dentry, bindex, h_dentry);
  4015. +
  4016. + inode = dentry->d_inode;
  4017. + if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able
  4018. + || (inode && !S_ISDIR(inode->i_mode)))
  4019. + goto out; /* success */
  4020. +
  4021. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  4022. + opq = au_diropq_test(h_dentry, br);
  4023. + mutex_unlock(&h_inode->i_mutex);
  4024. + if (opq > 0)
  4025. + au_set_dbdiropq(dentry, bindex);
  4026. + else if (unlikely(opq < 0)) {
  4027. + au_set_h_dptr(dentry, bindex, NULL);
  4028. + h_dentry = ERR_PTR(opq);
  4029. + }
  4030. + goto out;
  4031. +
  4032. + out_neg:
  4033. + dput(h_dentry);
  4034. + h_dentry = NULL;
  4035. + out:
  4036. + return h_dentry;
  4037. +}
  4038. +
  4039. +static int au_test_shwh(struct super_block *sb, const struct qstr *name)
  4040. +{
  4041. + if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
  4042. + && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
  4043. + return -EPERM;
  4044. + return 0;
  4045. +}
  4046. +
  4047. +/*
  4048. + * returns the number of lower positive dentries,
  4049. + * otherwise an error.
  4050. + * can be called at unlinking with @type is zero.
  4051. + */
  4052. +int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type,
  4053. + struct nameidata *nd)
  4054. +{
  4055. + int npositive, err;
  4056. + aufs_bindex_t bindex, btail, bdiropq;
  4057. + unsigned char isdir;
  4058. + struct qstr whname;
  4059. + struct au_do_lookup_args args = {
  4060. + .flags = 0,
  4061. + .type = type,
  4062. + .nd = nd
  4063. + };
  4064. + const struct qstr *name = &dentry->d_name;
  4065. + struct dentry *parent;
  4066. + struct inode *inode;
  4067. +
  4068. + parent = dget_parent(dentry);
  4069. + err = au_test_shwh(dentry->d_sb, name);
  4070. + if (unlikely(err))
  4071. + goto out;
  4072. +
  4073. + err = au_wh_name_alloc(&whname, name);
  4074. + if (unlikely(err))
  4075. + goto out;
  4076. +
  4077. + inode = dentry->d_inode;
  4078. + isdir = !!(inode && S_ISDIR(inode->i_mode));
  4079. + if (!type)
  4080. + au_fset_lkup(args.flags, ALLOW_NEG);
  4081. +
  4082. + npositive = 0;
  4083. + btail = au_dbtaildir(parent);
  4084. + for (bindex = bstart; bindex <= btail; bindex++) {
  4085. + struct dentry *h_parent, *h_dentry;
  4086. + struct inode *h_inode, *h_dir;
  4087. +
  4088. + h_dentry = au_h_dptr(dentry, bindex);
  4089. + if (h_dentry) {
  4090. + if (h_dentry->d_inode)
  4091. + npositive++;
  4092. + if (type != S_IFDIR)
  4093. + break;
  4094. + continue;
  4095. + }
  4096. + h_parent = au_h_dptr(parent, bindex);
  4097. + if (!h_parent)
  4098. + continue;
  4099. + h_dir = h_parent->d_inode;
  4100. + if (!h_dir || !S_ISDIR(h_dir->i_mode))
  4101. + continue;
  4102. +
  4103. + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
  4104. + h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
  4105. + &args);
  4106. + mutex_unlock(&h_dir->i_mutex);
  4107. + err = PTR_ERR(h_dentry);
  4108. + if (IS_ERR(h_dentry))
  4109. + goto out_wh;
  4110. + au_fclr_lkup(args.flags, ALLOW_NEG);
  4111. +
  4112. + if (au_dbwh(dentry) >= 0)
  4113. + break;
  4114. + if (!h_dentry)
  4115. + continue;
  4116. + h_inode = h_dentry->d_inode;
  4117. + if (!h_inode)
  4118. + continue;
  4119. + npositive++;
  4120. + if (!args.type)
  4121. + args.type = h_inode->i_mode & S_IFMT;
  4122. + if (args.type != S_IFDIR)
  4123. + break;
  4124. + else if (isdir) {
  4125. + /* the type of lower may be different */
  4126. + bdiropq = au_dbdiropq(dentry);
  4127. + if (bdiropq >= 0 && bdiropq <= bindex)
  4128. + break;
  4129. + }
  4130. + }
  4131. +
  4132. + if (npositive) {
  4133. + AuLabel(positive);
  4134. + au_update_dbstart(dentry);
  4135. + }
  4136. + err = npositive;
  4137. + if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
  4138. + && au_dbstart(dentry) < 0))
  4139. + /* both of real entry and whiteout found */
  4140. + err = -EIO;
  4141. +
  4142. + out_wh:
  4143. + kfree(whname.name);
  4144. + out:
  4145. + dput(parent);
  4146. + return err;
  4147. +}
  4148. +
  4149. +struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
  4150. + struct au_branch *br)
  4151. +{
  4152. + struct dentry *dentry;
  4153. + int wkq_err;
  4154. +
  4155. + if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC))
  4156. + dentry = au_lkup_one(name, parent, br, /*nd*/NULL);
  4157. + else {
  4158. + struct au_lkup_one_args args = {
  4159. + .errp = &dentry,
  4160. + .name = name,
  4161. + .h_parent = parent,
  4162. + .br = br,
  4163. + .nd = NULL
  4164. + };
  4165. +
  4166. + wkq_err = au_wkq_wait(au_call_lkup_one, &args);
  4167. + if (unlikely(wkq_err))
  4168. + dentry = ERR_PTR(wkq_err);
  4169. + }
  4170. +
  4171. + return dentry;
  4172. +}
  4173. +
  4174. +/*
  4175. + * lookup @dentry on @bindex which should be negative.
  4176. + */
  4177. +int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex)
  4178. +{
  4179. + int err;
  4180. + struct dentry *parent, *h_parent, *h_dentry;
  4181. + struct qstr *name;
  4182. +
  4183. + name = &dentry->d_name;
  4184. + parent = dget_parent(dentry);
  4185. + h_parent = au_h_dptr(parent, bindex);
  4186. + h_dentry = au_sio_lkup_one(name, h_parent,
  4187. + au_sbr(dentry->d_sb, bindex));
  4188. + err = PTR_ERR(h_dentry);
  4189. + if (IS_ERR(h_dentry))
  4190. + goto out;
  4191. + if (unlikely(h_dentry->d_inode)) {
  4192. + err = -EIO;
  4193. + AuIOErr("b%d %.*s should be negative.\n",
  4194. + bindex, AuDLNPair(h_dentry));
  4195. + dput(h_dentry);
  4196. + goto out;
  4197. + }
  4198. +
  4199. + if (bindex < au_dbstart(dentry))
  4200. + au_set_dbstart(dentry, bindex);
  4201. + if (au_dbend(dentry) < bindex)
  4202. + au_set_dbend(dentry, bindex);
  4203. + au_set_h_dptr(dentry, bindex, h_dentry);
  4204. + err = 0;
  4205. +
  4206. + out:
  4207. + dput(parent);
  4208. + return err;
  4209. +}
  4210. +
  4211. +/* ---------------------------------------------------------------------- */
  4212. +
  4213. +/* subset of struct inode */
  4214. +struct au_iattr {
  4215. + unsigned long i_ino;
  4216. + /* unsigned int i_nlink; */
  4217. + uid_t i_uid;
  4218. + gid_t i_gid;
  4219. + u64 i_version;
  4220. +/*
  4221. + loff_t i_size;
  4222. + blkcnt_t i_blocks;
  4223. +*/
  4224. + umode_t i_mode;
  4225. +};
  4226. +
  4227. +static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
  4228. +{
  4229. + ia->i_ino = h_inode->i_ino;
  4230. + /* ia->i_nlink = h_inode->i_nlink; */
  4231. + ia->i_uid = h_inode->i_uid;
  4232. + ia->i_gid = h_inode->i_gid;
  4233. + ia->i_version = h_inode->i_version;
  4234. +/*
  4235. + ia->i_size = h_inode->i_size;
  4236. + ia->i_blocks = h_inode->i_blocks;
  4237. +*/
  4238. + ia->i_mode = (h_inode->i_mode & S_IFMT);
  4239. +}
  4240. +
  4241. +static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
  4242. +{
  4243. + return ia->i_ino != h_inode->i_ino
  4244. + /* || ia->i_nlink != h_inode->i_nlink */
  4245. + || ia->i_uid != h_inode->i_uid
  4246. + || ia->i_gid != h_inode->i_gid
  4247. + || ia->i_version != h_inode->i_version
  4248. +/*
  4249. + || ia->i_size != h_inode->i_size
  4250. + || ia->i_blocks != h_inode->i_blocks
  4251. +*/
  4252. + || ia->i_mode != (h_inode->i_mode & S_IFMT);
  4253. +}
  4254. +
  4255. +static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
  4256. + struct au_branch *br)
  4257. +{
  4258. + int err;
  4259. + struct au_iattr ia;
  4260. + struct inode *h_inode;
  4261. + struct dentry *h_d;
  4262. + struct super_block *h_sb;
  4263. +
  4264. + err = 0;
  4265. + memset(&ia, -1, sizeof(ia));
  4266. + h_sb = h_dentry->d_sb;
  4267. + h_inode = h_dentry->d_inode;
  4268. + if (h_inode)
  4269. + au_iattr_save(&ia, h_inode);
  4270. + else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
  4271. + /* nfs d_revalidate may return 0 for negative dentry */
  4272. + /* fuse d_revalidate always return 0 for negative dentry */
  4273. + goto out;
  4274. +
  4275. + /* main purpose is namei.c:cached_lookup() and d_revalidate */
  4276. + h_d = au_lkup_one(&h_dentry->d_name, h_parent, br, /*nd*/NULL);
  4277. + err = PTR_ERR(h_d);
  4278. + if (IS_ERR(h_d))
  4279. + goto out;
  4280. +
  4281. + err = 0;
  4282. + if (unlikely(h_d != h_dentry
  4283. + || h_d->d_inode != h_inode
  4284. + || (h_inode && au_iattr_test(&ia, h_inode))))
  4285. + err = au_busy_or_stale();
  4286. + dput(h_d);
  4287. +
  4288. + out:
  4289. + AuTraceErr(err);
  4290. + return err;
  4291. +}
  4292. +
  4293. +int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
  4294. + struct dentry *h_parent, struct au_branch *br)
  4295. +{
  4296. + int err;
  4297. +
  4298. + err = 0;
  4299. + if (udba == AuOpt_UDBA_REVAL) {
  4300. + IMustLock(h_dir);
  4301. + err = (h_dentry->d_parent->d_inode != h_dir);
  4302. + } else if (udba == AuOpt_UDBA_HINOTIFY)
  4303. + err = au_h_verify_dentry(h_dentry, h_parent, br);
  4304. +
  4305. + return err;
  4306. +}
  4307. +
  4308. +/* ---------------------------------------------------------------------- */
  4309. +
  4310. +static void au_do_refresh_hdentry(struct au_hdentry *p, struct au_dinfo *dinfo,
  4311. + struct dentry *parent)
  4312. +{
  4313. + struct dentry *h_d, *h_dp;
  4314. + struct au_hdentry tmp, *q;
  4315. + struct super_block *sb;
  4316. + aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq;
  4317. +
  4318. + AuRwMustWriteLock(&dinfo->di_rwsem);
  4319. +
  4320. + bend = dinfo->di_bend;
  4321. + bwh = dinfo->di_bwh;
  4322. + bdiropq = dinfo->di_bdiropq;
  4323. + for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
  4324. + h_d = p->hd_dentry;
  4325. + if (!h_d)
  4326. + continue;
  4327. +
  4328. + h_dp = dget_parent(h_d);
  4329. + if (h_dp == au_h_dptr(parent, bindex)) {
  4330. + dput(h_dp);
  4331. + continue;
  4332. + }
  4333. +
  4334. + new_bindex = au_find_dbindex(parent, h_dp);
  4335. + dput(h_dp);
  4336. + if (dinfo->di_bwh == bindex)
  4337. + bwh = new_bindex;
  4338. + if (dinfo->di_bdiropq == bindex)
  4339. + bdiropq = new_bindex;
  4340. + if (new_bindex < 0) {
  4341. + au_hdput(p);
  4342. + p->hd_dentry = NULL;
  4343. + continue;
  4344. + }
  4345. +
  4346. + /* swap two lower dentries, and loop again */
  4347. + q = dinfo->di_hdentry + new_bindex;
  4348. + tmp = *q;
  4349. + *q = *p;
  4350. + *p = tmp;
  4351. + if (tmp.hd_dentry) {
  4352. + bindex--;
  4353. + p--;
  4354. + }
  4355. + }
  4356. +
  4357. + sb = parent->d_sb;
  4358. + dinfo->di_bwh = -1;
  4359. + if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))
  4360. + dinfo->di_bwh = bwh;
  4361. +
  4362. + dinfo->di_bdiropq = -1;
  4363. + if (bdiropq >= 0
  4364. + && bdiropq <= au_sbend(sb)
  4365. + && au_sbr_whable(sb, bdiropq))
  4366. + dinfo->di_bdiropq = bdiropq;
  4367. +
  4368. + bend = au_dbend(parent);
  4369. + p = dinfo->di_hdentry;
  4370. + for (bindex = 0; bindex <= bend; bindex++, p++)
  4371. + if (p->hd_dentry) {
  4372. + dinfo->di_bstart = bindex;
  4373. + break;
  4374. + }
  4375. +
  4376. + p = dinfo->di_hdentry + bend;
  4377. + for (bindex = bend; bindex >= 0; bindex--, p--)
  4378. + if (p->hd_dentry) {
  4379. + dinfo->di_bend = bindex;
  4380. + break;
  4381. + }
  4382. +}
  4383. +
  4384. +/*
  4385. + * returns the number of found lower positive dentries,
  4386. + * otherwise an error.
  4387. + */
  4388. +int au_refresh_hdentry(struct dentry *dentry, mode_t type)
  4389. +{
  4390. + int npositive, err;
  4391. + unsigned int sigen;
  4392. + aufs_bindex_t bstart;
  4393. + struct au_dinfo *dinfo;
  4394. + struct super_block *sb;
  4395. + struct dentry *parent;
  4396. +
  4397. + DiMustWriteLock(dentry);
  4398. +
  4399. + sb = dentry->d_sb;
  4400. + AuDebugOn(IS_ROOT(dentry));
  4401. + sigen = au_sigen(sb);
  4402. + parent = dget_parent(dentry);
  4403. + AuDebugOn(au_digen(parent) != sigen
  4404. + || au_iigen(parent->d_inode) != sigen);
  4405. +
  4406. + dinfo = au_di(dentry);
  4407. + err = au_di_realloc(dinfo, au_sbend(sb) + 1);
  4408. + npositive = err;
  4409. + if (unlikely(err))
  4410. + goto out;
  4411. + au_do_refresh_hdentry(dinfo->di_hdentry + dinfo->di_bstart, dinfo,
  4412. + parent);
  4413. +
  4414. + npositive = 0;
  4415. + bstart = au_dbstart(parent);
  4416. + if (type != S_IFDIR && dinfo->di_bstart == bstart)
  4417. + goto out_dgen; /* success */
  4418. +
  4419. + npositive = au_lkup_dentry(dentry, bstart, type, /*nd*/NULL);
  4420. + if (npositive < 0)
  4421. + goto out;
  4422. + if (dinfo->di_bwh >= 0 && dinfo->di_bwh <= dinfo->di_bstart)
  4423. + d_drop(dentry);
  4424. +
  4425. + out_dgen:
  4426. + au_update_digen(dentry);
  4427. + out:
  4428. + dput(parent);
  4429. + AuTraceErr(npositive);
  4430. + return npositive;
  4431. +}
  4432. +
  4433. +static noinline_for_stack
  4434. +int au_do_h_d_reval(struct dentry *h_dentry, struct nameidata *nd,
  4435. + struct dentry *dentry, aufs_bindex_t bindex)
  4436. +{
  4437. + int err, valid;
  4438. + int (*reval)(struct dentry *, struct nameidata *);
  4439. +
  4440. + err = 0;
  4441. + reval = NULL;
  4442. + if (h_dentry->d_op)
  4443. + reval = h_dentry->d_op->d_revalidate;
  4444. + if (!reval)
  4445. + goto out;
  4446. +
  4447. + AuDbg("b%d\n", bindex);
  4448. + if (au_test_fs_null_nd(h_dentry->d_sb))
  4449. + /* it may return tri-state */
  4450. + valid = reval(h_dentry, NULL);
  4451. + else {
  4452. + struct nameidata h_nd;
  4453. + int locked;
  4454. + struct dentry *parent;
  4455. +
  4456. + au_h_nd(&h_nd, nd);
  4457. + parent = nd->path.dentry;
  4458. + locked = (nd && nd->path.dentry != dentry);
  4459. + if (locked)
  4460. + di_read_lock_parent(parent, AuLock_IR);
  4461. + BUG_ON(bindex > au_dbend(parent));
  4462. + h_nd.path.dentry = au_h_dptr(parent, bindex);
  4463. + BUG_ON(!h_nd.path.dentry);
  4464. + h_nd.path.mnt = au_sbr(parent->d_sb, bindex)->br_mnt;
  4465. + path_get(&h_nd.path);
  4466. + valid = reval(h_dentry, &h_nd);
  4467. + path_put(&h_nd.path);
  4468. + if (locked)
  4469. + di_read_unlock(parent, AuLock_IR);
  4470. + }
  4471. +
  4472. + if (unlikely(valid < 0))
  4473. + err = valid;
  4474. + else if (!valid)
  4475. + err = -EINVAL;
  4476. +
  4477. + out:
  4478. + AuTraceErr(err);
  4479. + return err;
  4480. +}
  4481. +
  4482. +/* todo: remove this */
  4483. +static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
  4484. + struct nameidata *nd, int do_udba)
  4485. +{
  4486. + int err;
  4487. + umode_t mode, h_mode;
  4488. + aufs_bindex_t bindex, btail, bstart, ibs, ibe;
  4489. + unsigned char plus, unhashed, is_root, h_plus;
  4490. + struct inode *first, *h_inode, *h_cached_inode;
  4491. + struct dentry *h_dentry;
  4492. + struct qstr *name, *h_name;
  4493. +
  4494. + err = 0;
  4495. + plus = 0;
  4496. + mode = 0;
  4497. + first = NULL;
  4498. + ibs = -1;
  4499. + ibe = -1;
  4500. + unhashed = !!d_unhashed(dentry);
  4501. + is_root = !!IS_ROOT(dentry);
  4502. + name = &dentry->d_name;
  4503. +
  4504. + /*
  4505. + * Theoretically, REVAL test should be unnecessary in case of INOTIFY.
  4506. + * But inotify doesn't fire some necessary events,
  4507. + * IN_ATTRIB for atime/nlink/pageio
  4508. + * IN_DELETE for NFS dentry
  4509. + * Let's do REVAL test too.
  4510. + */
  4511. + if (do_udba && inode) {
  4512. + mode = (inode->i_mode & S_IFMT);
  4513. + plus = (inode->i_nlink > 0);
  4514. + first = au_h_iptr(inode, au_ibstart(inode));
  4515. + ibs = au_ibstart(inode);
  4516. + ibe = au_ibend(inode);
  4517. + }
  4518. +
  4519. + bstart = au_dbstart(dentry);
  4520. + btail = bstart;
  4521. + if (inode && S_ISDIR(inode->i_mode))
  4522. + btail = au_dbtaildir(dentry);
  4523. + for (bindex = bstart; bindex <= btail; bindex++) {
  4524. + h_dentry = au_h_dptr(dentry, bindex);
  4525. + if (!h_dentry)
  4526. + continue;
  4527. +
  4528. + AuDbg("b%d, %.*s\n", bindex, AuDLNPair(h_dentry));
  4529. + h_name = &h_dentry->d_name;
  4530. + if (unlikely(do_udba
  4531. + && !is_root
  4532. + && (unhashed != !!d_unhashed(h_dentry)
  4533. + || name->len != h_name->len
  4534. + || memcmp(name->name, h_name->name, name->len))
  4535. + )) {
  4536. + AuDbg("unhash 0x%x 0x%x, %.*s %.*s\n",
  4537. + unhashed, d_unhashed(h_dentry),
  4538. + AuDLNPair(dentry), AuDLNPair(h_dentry));
  4539. + goto err;
  4540. + }
  4541. +
  4542. + err = au_do_h_d_reval(h_dentry, nd, dentry, bindex);
  4543. + if (unlikely(err))
  4544. + /* do not goto err, to keep the errno */
  4545. + break;
  4546. +
  4547. + /* todo: plink too? */
  4548. + if (!do_udba)
  4549. + continue;
  4550. +
  4551. + /* UDBA tests */
  4552. + h_inode = h_dentry->d_inode;
  4553. + if (unlikely(!!inode != !!h_inode))
  4554. + goto err;
  4555. +
  4556. + h_plus = plus;
  4557. + h_mode = mode;
  4558. + h_cached_inode = h_inode;
  4559. + if (h_inode) {
  4560. + h_mode = (h_inode->i_mode & S_IFMT);
  4561. + h_plus = (h_inode->i_nlink > 0);
  4562. + }
  4563. + if (inode && ibs <= bindex && bindex <= ibe)
  4564. + h_cached_inode = au_h_iptr(inode, bindex);
  4565. +
  4566. + if (unlikely(plus != h_plus
  4567. + || mode != h_mode
  4568. + || h_cached_inode != h_inode))
  4569. + goto err;
  4570. + continue;
  4571. +
  4572. + err:
  4573. + err = -EINVAL;
  4574. + break;
  4575. + }
  4576. +
  4577. + return err;
  4578. +}
  4579. +
  4580. +static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
  4581. +{
  4582. + int err;
  4583. + struct dentry *parent;
  4584. + struct inode *inode;
  4585. +
  4586. + inode = dentry->d_inode;
  4587. + if (au_digen(dentry) == sigen && au_iigen(inode) == sigen)
  4588. + return 0;
  4589. +
  4590. + parent = dget_parent(dentry);
  4591. + di_read_lock_parent(parent, AuLock_IR);
  4592. + AuDebugOn(au_digen(parent) != sigen
  4593. + || au_iigen(parent->d_inode) != sigen);
  4594. + au_dbg_verify_gen(parent, sigen);
  4595. +
  4596. + /* returns a number of positive dentries */
  4597. + err = au_refresh_hdentry(dentry, inode->i_mode & S_IFMT);
  4598. + if (err >= 0)
  4599. + err = au_refresh_hinode(inode, dentry);
  4600. +
  4601. + di_read_unlock(parent, AuLock_IR);
  4602. + dput(parent);
  4603. + return err;
  4604. +}
  4605. +
  4606. +int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
  4607. +{
  4608. + int err;
  4609. + struct dentry *d, *parent;
  4610. + struct inode *inode;
  4611. +
  4612. + if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS))
  4613. + return simple_reval_dpath(dentry, sigen);
  4614. +
  4615. + /* slow loop, keep it simple and stupid */
  4616. + /* cf: au_cpup_dirs() */
  4617. + err = 0;
  4618. + parent = NULL;
  4619. + while (au_digen(dentry) != sigen
  4620. + || au_iigen(dentry->d_inode) != sigen) {
  4621. + d = dentry;
  4622. + while (1) {
  4623. + dput(parent);
  4624. + parent = dget_parent(d);
  4625. + if (au_digen(parent) == sigen
  4626. + && au_iigen(parent->d_inode) == sigen)
  4627. + break;
  4628. + d = parent;
  4629. + }
  4630. +
  4631. + inode = d->d_inode;
  4632. + if (d != dentry)
  4633. + di_write_lock_child(d);
  4634. +
  4635. + /* someone might update our dentry while we were sleeping */
  4636. + if (au_digen(d) != sigen || au_iigen(d->d_inode) != sigen) {
  4637. + di_read_lock_parent(parent, AuLock_IR);
  4638. + /* returns a number of positive dentries */
  4639. + err = au_refresh_hdentry(d, inode->i_mode & S_IFMT);
  4640. + if (err >= 0)
  4641. + err = au_refresh_hinode(inode, d);
  4642. + di_read_unlock(parent, AuLock_IR);
  4643. + }
  4644. +
  4645. + if (d != dentry)
  4646. + di_write_unlock(d);
  4647. + dput(parent);
  4648. + if (unlikely(err))
  4649. + break;
  4650. + }
  4651. +
  4652. + return err;
  4653. +}
  4654. +
  4655. +/*
  4656. + * if valid returns 1, otherwise 0.
  4657. + */
  4658. +static int aufs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
  4659. +{
  4660. + int valid, err;
  4661. + unsigned int sigen;
  4662. + unsigned char do_udba;
  4663. + struct super_block *sb;
  4664. + struct inode *inode;
  4665. +
  4666. + err = -EINVAL;
  4667. + sb = dentry->d_sb;
  4668. + inode = dentry->d_inode;
  4669. + aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW);
  4670. + sigen = au_sigen(sb);
  4671. + if (au_digen(dentry) != sigen) {
  4672. + AuDebugOn(IS_ROOT(dentry));
  4673. + if (inode)
  4674. + err = au_reval_dpath(dentry, sigen);
  4675. + if (unlikely(err))
  4676. + goto out_dgrade;
  4677. + AuDebugOn(au_digen(dentry) != sigen);
  4678. + }
  4679. + if (inode && au_iigen(inode) != sigen) {
  4680. + AuDebugOn(IS_ROOT(dentry));
  4681. + err = au_refresh_hinode(inode, dentry);
  4682. + if (unlikely(err))
  4683. + goto out_dgrade;
  4684. + AuDebugOn(au_iigen(inode) != sigen);
  4685. + }
  4686. + di_downgrade_lock(dentry, AuLock_IR);
  4687. +
  4688. + AuDebugOn(au_digen(dentry) != sigen);
  4689. + AuDebugOn(inode && au_iigen(inode) != sigen);
  4690. + err = -EINVAL;
  4691. + do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
  4692. + if (do_udba && inode) {
  4693. + aufs_bindex_t bstart = au_ibstart(inode);
  4694. +
  4695. + if (bstart >= 0
  4696. + && au_test_higen(inode, au_h_iptr(inode, bstart)))
  4697. + goto out;
  4698. + }
  4699. +
  4700. + err = h_d_revalidate(dentry, inode, nd, do_udba);
  4701. + if (unlikely(!err && do_udba && au_dbstart(dentry) < 0))
  4702. + /* both of real entry and whiteout found */
  4703. + err = -EIO;
  4704. + goto out;
  4705. +
  4706. + out_dgrade:
  4707. + di_downgrade_lock(dentry, AuLock_IR);
  4708. + out:
  4709. + au_store_oflag(nd, inode);
  4710. + aufs_read_unlock(dentry, AuLock_IR);
  4711. + AuTraceErr(err);
  4712. + valid = !err;
  4713. + if (!valid)
  4714. + AuDbg("%.*s invalid\n", AuDLNPair(dentry));
  4715. + return valid;
  4716. +}
  4717. +
  4718. +static void aufs_d_release(struct dentry *dentry)
  4719. +{
  4720. + struct au_dinfo *dinfo;
  4721. + aufs_bindex_t bend, bindex;
  4722. +
  4723. + dinfo = dentry->d_fsdata;
  4724. + if (!dinfo)
  4725. + return;
  4726. +
  4727. + /* dentry may not be revalidated */
  4728. + bindex = dinfo->di_bstart;
  4729. + if (bindex >= 0) {
  4730. + struct au_hdentry *p;
  4731. +
  4732. + bend = dinfo->di_bend;
  4733. + p = dinfo->di_hdentry + bindex;
  4734. + while (bindex++ <= bend) {
  4735. + if (p->hd_dentry)
  4736. + au_hdput(p);
  4737. + p++;
  4738. + }
  4739. + }
  4740. + kfree(dinfo->di_hdentry);
  4741. + AuRwDestroy(&dinfo->di_rwsem);
  4742. + au_cache_free_dinfo(dinfo);
  4743. + au_hin_di_reinit(dentry);
  4744. +}
  4745. +
  4746. +struct dentry_operations aufs_dop = {
  4747. + .d_revalidate = aufs_d_revalidate,
  4748. + .d_release = aufs_d_release
  4749. +};
  4750. diff -Nur linux-2.6.34.orig/fs/aufs/dentry.h linux-2.6.34/fs/aufs/dentry.h
  4751. --- linux-2.6.34.orig/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
  4752. +++ linux-2.6.34/fs/aufs/dentry.h 2010-05-23 23:33:19.820978219 +0200
  4753. @@ -0,0 +1,231 @@
  4754. +/*
  4755. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  4756. + *
  4757. + * This program, aufs is free software; you can redistribute it and/or modify
  4758. + * it under the terms of the GNU General Public License as published by
  4759. + * the Free Software Foundation; either version 2 of the License, or
  4760. + * (at your option) any later version.
  4761. + *
  4762. + * This program is distributed in the hope that it will be useful,
  4763. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4764. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4765. + * GNU General Public License for more details.
  4766. + *
  4767. + * You should have received a copy of the GNU General Public License
  4768. + * along with this program; if not, write to the Free Software
  4769. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  4770. + */
  4771. +
  4772. +/*
  4773. + * lookup and dentry operations
  4774. + */
  4775. +
  4776. +#ifndef __AUFS_DENTRY_H__
  4777. +#define __AUFS_DENTRY_H__
  4778. +
  4779. +#ifdef __KERNEL__
  4780. +
  4781. +#include <linux/dcache.h>
  4782. +#include <linux/aufs_type.h>
  4783. +#include "rwsem.h"
  4784. +
  4785. +/* make a single member structure for future use */
  4786. +/* todo: remove this structure */
  4787. +struct au_hdentry {
  4788. + struct dentry *hd_dentry;
  4789. +};
  4790. +
  4791. +struct au_dinfo {
  4792. + atomic_t di_generation;
  4793. +
  4794. + struct au_rwsem di_rwsem;
  4795. + aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq;
  4796. + struct au_hdentry *di_hdentry;
  4797. +};
  4798. +
  4799. +/* ---------------------------------------------------------------------- */
  4800. +
  4801. +/* dentry.c */
  4802. +extern struct dentry_operations aufs_dop;
  4803. +struct au_branch;
  4804. +struct dentry *au_lkup_one(struct qstr *name, struct dentry *h_parent,
  4805. + struct au_branch *br, struct nameidata *nd);
  4806. +struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
  4807. + struct au_branch *br);
  4808. +int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
  4809. + struct dentry *h_parent, struct au_branch *br);
  4810. +
  4811. +int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type,
  4812. + struct nameidata *nd);
  4813. +int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex);
  4814. +int au_refresh_hdentry(struct dentry *dentry, mode_t type);
  4815. +int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
  4816. +
  4817. +/* dinfo.c */
  4818. +int au_alloc_dinfo(struct dentry *dentry);
  4819. +int au_di_realloc(struct au_dinfo *dinfo, int nbr);
  4820. +
  4821. +void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
  4822. +void di_read_unlock(struct dentry *d, int flags);
  4823. +void di_downgrade_lock(struct dentry *d, int flags);
  4824. +void di_write_lock(struct dentry *d, unsigned int lsc);
  4825. +void di_write_unlock(struct dentry *d);
  4826. +void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
  4827. +void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
  4828. +void di_write_unlock2(struct dentry *d1, struct dentry *d2);
  4829. +
  4830. +struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
  4831. +aufs_bindex_t au_dbtail(struct dentry *dentry);
  4832. +aufs_bindex_t au_dbtaildir(struct dentry *dentry);
  4833. +
  4834. +void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
  4835. + struct dentry *h_dentry);
  4836. +void au_update_digen(struct dentry *dentry);
  4837. +void au_update_dbrange(struct dentry *dentry, int do_put_zero);
  4838. +void au_update_dbstart(struct dentry *dentry);
  4839. +void au_update_dbend(struct dentry *dentry);
  4840. +int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
  4841. +
  4842. +/* ---------------------------------------------------------------------- */
  4843. +
  4844. +static inline struct au_dinfo *au_di(struct dentry *dentry)
  4845. +{
  4846. + return dentry->d_fsdata;
  4847. +}
  4848. +
  4849. +/* ---------------------------------------------------------------------- */
  4850. +
  4851. +/* lock subclass for dinfo */
  4852. +enum {
  4853. + AuLsc_DI_CHILD, /* child first */
  4854. + AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hinotify */
  4855. + AuLsc_DI_CHILD3, /* copyup dirs */
  4856. + AuLsc_DI_PARENT,
  4857. + AuLsc_DI_PARENT2,
  4858. + AuLsc_DI_PARENT3
  4859. +};
  4860. +
  4861. +/*
  4862. + * di_read_lock_child, di_write_lock_child,
  4863. + * di_read_lock_child2, di_write_lock_child2,
  4864. + * di_read_lock_child3, di_write_lock_child3,
  4865. + * di_read_lock_parent, di_write_lock_parent,
  4866. + * di_read_lock_parent2, di_write_lock_parent2,
  4867. + * di_read_lock_parent3, di_write_lock_parent3,
  4868. + */
  4869. +#define AuReadLockFunc(name, lsc) \
  4870. +static inline void di_read_lock_##name(struct dentry *d, int flags) \
  4871. +{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
  4872. +
  4873. +#define AuWriteLockFunc(name, lsc) \
  4874. +static inline void di_write_lock_##name(struct dentry *d) \
  4875. +{ di_write_lock(d, AuLsc_DI_##lsc); }
  4876. +
  4877. +#define AuRWLockFuncs(name, lsc) \
  4878. + AuReadLockFunc(name, lsc) \
  4879. + AuWriteLockFunc(name, lsc)
  4880. +
  4881. +AuRWLockFuncs(child, CHILD);
  4882. +AuRWLockFuncs(child2, CHILD2);
  4883. +AuRWLockFuncs(child3, CHILD3);
  4884. +AuRWLockFuncs(parent, PARENT);
  4885. +AuRWLockFuncs(parent2, PARENT2);
  4886. +AuRWLockFuncs(parent3, PARENT3);
  4887. +
  4888. +#undef AuReadLockFunc
  4889. +#undef AuWriteLockFunc
  4890. +#undef AuRWLockFuncs
  4891. +
  4892. +#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
  4893. +#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
  4894. +#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
  4895. +
  4896. +/* ---------------------------------------------------------------------- */
  4897. +
  4898. +/* todo: memory barrier? */
  4899. +static inline unsigned int au_digen(struct dentry *d)
  4900. +{
  4901. + return atomic_read(&au_di(d)->di_generation);
  4902. +}
  4903. +
  4904. +static inline void au_h_dentry_init(struct au_hdentry *hdentry)
  4905. +{
  4906. + hdentry->hd_dentry = NULL;
  4907. +}
  4908. +
  4909. +static inline void au_hdput(struct au_hdentry *hd)
  4910. +{
  4911. + dput(hd->hd_dentry);
  4912. +}
  4913. +
  4914. +static inline aufs_bindex_t au_dbstart(struct dentry *dentry)
  4915. +{
  4916. + DiMustAnyLock(dentry);
  4917. + return au_di(dentry)->di_bstart;
  4918. +}
  4919. +
  4920. +static inline aufs_bindex_t au_dbend(struct dentry *dentry)
  4921. +{
  4922. + DiMustAnyLock(dentry);
  4923. + return au_di(dentry)->di_bend;
  4924. +}
  4925. +
  4926. +static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
  4927. +{
  4928. + DiMustAnyLock(dentry);
  4929. + return au_di(dentry)->di_bwh;
  4930. +}
  4931. +
  4932. +static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
  4933. +{
  4934. + DiMustAnyLock(dentry);
  4935. + return au_di(dentry)->di_bdiropq;
  4936. +}
  4937. +
  4938. +/* todo: hard/soft set? */
  4939. +static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex)
  4940. +{
  4941. + DiMustWriteLock(dentry);
  4942. + au_di(dentry)->di_bstart = bindex;
  4943. +}
  4944. +
  4945. +static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex)
  4946. +{
  4947. + DiMustWriteLock(dentry);
  4948. + au_di(dentry)->di_bend = bindex;
  4949. +}
  4950. +
  4951. +static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
  4952. +{
  4953. + DiMustWriteLock(dentry);
  4954. + /* dbwh can be outside of bstart - bend range */
  4955. + au_di(dentry)->di_bwh = bindex;
  4956. +}
  4957. +
  4958. +static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
  4959. +{
  4960. + DiMustWriteLock(dentry);
  4961. + au_di(dentry)->di_bdiropq = bindex;
  4962. +}
  4963. +
  4964. +/* ---------------------------------------------------------------------- */
  4965. +
  4966. +#ifdef CONFIG_AUFS_HINOTIFY
  4967. +static inline void au_digen_dec(struct dentry *d)
  4968. +{
  4969. + atomic_dec_return(&au_di(d)->di_generation);
  4970. +}
  4971. +
  4972. +static inline void au_hin_di_reinit(struct dentry *dentry)
  4973. +{
  4974. + dentry->d_fsdata = NULL;
  4975. +}
  4976. +#else
  4977. +static inline void au_hin_di_reinit(struct dentry *dentry __maybe_unused)
  4978. +{
  4979. + /* empty */
  4980. +}
  4981. +#endif /* CONFIG_AUFS_HINOTIFY */
  4982. +
  4983. +#endif /* __KERNEL__ */
  4984. +#endif /* __AUFS_DENTRY_H__ */
  4985. diff -Nur linux-2.6.34.orig/fs/aufs/dinfo.c linux-2.6.34/fs/aufs/dinfo.c
  4986. --- linux-2.6.34.orig/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100
  4987. +++ linux-2.6.34/fs/aufs/dinfo.c 2010-05-23 23:33:19.863473142 +0200
  4988. @@ -0,0 +1,367 @@
  4989. +/*
  4990. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  4991. + *
  4992. + * This program, aufs is free software; you can redistribute it and/or modify
  4993. + * it under the terms of the GNU General Public License as published by
  4994. + * the Free Software Foundation; either version 2 of the License, or
  4995. + * (at your option) any later version.
  4996. + *
  4997. + * This program is distributed in the hope that it will be useful,
  4998. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4999. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  5000. + * GNU General Public License for more details.
  5001. + *
  5002. + * You should have received a copy of the GNU General Public License
  5003. + * along with this program; if not, write to the Free Software
  5004. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  5005. + */
  5006. +
  5007. +/*
  5008. + * dentry private data
  5009. + */
  5010. +
  5011. +#include "aufs.h"
  5012. +
  5013. +int au_alloc_dinfo(struct dentry *dentry)
  5014. +{
  5015. + struct au_dinfo *dinfo;
  5016. + struct super_block *sb;
  5017. + int nbr;
  5018. +
  5019. + dinfo = au_cache_alloc_dinfo();
  5020. + if (unlikely(!dinfo))
  5021. + goto out;
  5022. +
  5023. + sb = dentry->d_sb;
  5024. + nbr = au_sbend(sb) + 1;
  5025. + if (nbr <= 0)
  5026. + nbr = 1;
  5027. + dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
  5028. + if (unlikely(!dinfo->di_hdentry))
  5029. + goto out_dinfo;
  5030. +
  5031. + atomic_set(&dinfo->di_generation, au_sigen(sb));
  5032. + /* smp_mb(); */ /* atomic_set */
  5033. + au_rw_init_wlock_nested(&dinfo->di_rwsem, AuLsc_DI_CHILD);
  5034. + dinfo->di_bstart = -1;
  5035. + dinfo->di_bend = -1;
  5036. + dinfo->di_bwh = -1;
  5037. + dinfo->di_bdiropq = -1;
  5038. +
  5039. + dentry->d_fsdata = dinfo;
  5040. + dentry->d_op = &aufs_dop;
  5041. + return 0; /* success */
  5042. +
  5043. + out_dinfo:
  5044. + au_cache_free_dinfo(dinfo);
  5045. + out:
  5046. + return -ENOMEM;
  5047. +}
  5048. +
  5049. +int au_di_realloc(struct au_dinfo *dinfo, int nbr)
  5050. +{
  5051. + int err, sz;
  5052. + struct au_hdentry *hdp;
  5053. +
  5054. + AuRwMustWriteLock(&dinfo->di_rwsem);
  5055. +
  5056. + err = -ENOMEM;
  5057. + sz = sizeof(*hdp) * (dinfo->di_bend + 1);
  5058. + if (!sz)
  5059. + sz = sizeof(*hdp);
  5060. + hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS);
  5061. + if (hdp) {
  5062. + dinfo->di_hdentry = hdp;
  5063. + err = 0;
  5064. + }
  5065. +
  5066. + return err;
  5067. +}
  5068. +
  5069. +/* ---------------------------------------------------------------------- */
  5070. +
  5071. +static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
  5072. +{
  5073. + switch (lsc) {
  5074. + case AuLsc_DI_CHILD:
  5075. + ii_write_lock_child(inode);
  5076. + break;
  5077. + case AuLsc_DI_CHILD2:
  5078. + ii_write_lock_child2(inode);
  5079. + break;
  5080. + case AuLsc_DI_CHILD3:
  5081. + ii_write_lock_child3(inode);
  5082. + break;
  5083. + case AuLsc_DI_PARENT:
  5084. + ii_write_lock_parent(inode);
  5085. + break;
  5086. + case AuLsc_DI_PARENT2:
  5087. + ii_write_lock_parent2(inode);
  5088. + break;
  5089. + case AuLsc_DI_PARENT3:
  5090. + ii_write_lock_parent3(inode);
  5091. + break;
  5092. + default:
  5093. + BUG();
  5094. + }
  5095. +}
  5096. +
  5097. +static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
  5098. +{
  5099. + switch (lsc) {
  5100. + case AuLsc_DI_CHILD:
  5101. + ii_read_lock_child(inode);
  5102. + break;
  5103. + case AuLsc_DI_CHILD2:
  5104. + ii_read_lock_child2(inode);
  5105. + break;
  5106. + case AuLsc_DI_CHILD3:
  5107. + ii_read_lock_child3(inode);
  5108. + break;
  5109. + case AuLsc_DI_PARENT:
  5110. + ii_read_lock_parent(inode);
  5111. + break;
  5112. + case AuLsc_DI_PARENT2:
  5113. + ii_read_lock_parent2(inode);
  5114. + break;
  5115. + case AuLsc_DI_PARENT3:
  5116. + ii_read_lock_parent3(inode);
  5117. + break;
  5118. + default:
  5119. + BUG();
  5120. + }
  5121. +}
  5122. +
  5123. +void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
  5124. +{
  5125. + au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
  5126. + if (d->d_inode) {
  5127. + if (au_ftest_lock(flags, IW))
  5128. + do_ii_write_lock(d->d_inode, lsc);
  5129. + else if (au_ftest_lock(flags, IR))
  5130. + do_ii_read_lock(d->d_inode, lsc);
  5131. + }
  5132. +}
  5133. +
  5134. +void di_read_unlock(struct dentry *d, int flags)
  5135. +{
  5136. + if (d->d_inode) {
  5137. + if (au_ftest_lock(flags, IW))
  5138. + ii_write_unlock(d->d_inode);
  5139. + else if (au_ftest_lock(flags, IR))
  5140. + ii_read_unlock(d->d_inode);
  5141. + }
  5142. + au_rw_read_unlock(&au_di(d)->di_rwsem);
  5143. +}
  5144. +
  5145. +void di_downgrade_lock(struct dentry *d, int flags)
  5146. +{
  5147. + if (d->d_inode && au_ftest_lock(flags, IR))
  5148. + ii_downgrade_lock(d->d_inode);
  5149. + au_rw_dgrade_lock(&au_di(d)->di_rwsem);
  5150. +}
  5151. +
  5152. +void di_write_lock(struct dentry *d, unsigned int lsc)
  5153. +{
  5154. + au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
  5155. + if (d->d_inode)
  5156. + do_ii_write_lock(d->d_inode, lsc);
  5157. +}
  5158. +
  5159. +void di_write_unlock(struct dentry *d)
  5160. +{
  5161. + if (d->d_inode)
  5162. + ii_write_unlock(d->d_inode);
  5163. + au_rw_write_unlock(&au_di(d)->di_rwsem);
  5164. +}
  5165. +
  5166. +void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
  5167. +{
  5168. + AuDebugOn(d1 == d2
  5169. + || d1->d_inode == d2->d_inode
  5170. + || d1->d_sb != d2->d_sb);
  5171. +
  5172. + if (isdir && au_test_subdir(d1, d2)) {
  5173. + di_write_lock_child(d1);
  5174. + di_write_lock_child2(d2);
  5175. + } else {
  5176. + /* there should be no races */
  5177. + di_write_lock_child(d2);
  5178. + di_write_lock_child2(d1);
  5179. + }
  5180. +}
  5181. +
  5182. +void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
  5183. +{
  5184. + AuDebugOn(d1 == d2
  5185. + || d1->d_inode == d2->d_inode
  5186. + || d1->d_sb != d2->d_sb);
  5187. +
  5188. + if (isdir && au_test_subdir(d1, d2)) {
  5189. + di_write_lock_parent(d1);
  5190. + di_write_lock_parent2(d2);
  5191. + } else {
  5192. + /* there should be no races */
  5193. + di_write_lock_parent(d2);
  5194. + di_write_lock_parent2(d1);
  5195. + }
  5196. +}
  5197. +
  5198. +void di_write_unlock2(struct dentry *d1, struct dentry *d2)
  5199. +{
  5200. + di_write_unlock(d1);
  5201. + if (d1->d_inode == d2->d_inode)
  5202. + au_rw_write_unlock(&au_di(d2)->di_rwsem);
  5203. + else
  5204. + di_write_unlock(d2);
  5205. +}
  5206. +
  5207. +/* ---------------------------------------------------------------------- */
  5208. +
  5209. +struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
  5210. +{
  5211. + struct dentry *d;
  5212. +
  5213. + DiMustAnyLock(dentry);
  5214. +
  5215. + if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
  5216. + return NULL;
  5217. + AuDebugOn(bindex < 0);
  5218. + d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry;
  5219. + AuDebugOn(d && (atomic_read(&d->d_count) <= 0));
  5220. + return d;
  5221. +}
  5222. +
  5223. +aufs_bindex_t au_dbtail(struct dentry *dentry)
  5224. +{
  5225. + aufs_bindex_t bend, bwh;
  5226. +
  5227. + bend = au_dbend(dentry);
  5228. + if (0 <= bend) {
  5229. + bwh = au_dbwh(dentry);
  5230. + if (!bwh)
  5231. + return bwh;
  5232. + if (0 < bwh && bwh < bend)
  5233. + return bwh - 1;
  5234. + }
  5235. + return bend;
  5236. +}
  5237. +
  5238. +aufs_bindex_t au_dbtaildir(struct dentry *dentry)
  5239. +{
  5240. + aufs_bindex_t bend, bopq;
  5241. +
  5242. + bend = au_dbtail(dentry);
  5243. + if (0 <= bend) {
  5244. + bopq = au_dbdiropq(dentry);
  5245. + if (0 <= bopq && bopq < bend)
  5246. + bend = bopq;
  5247. + }
  5248. + return bend;
  5249. +}
  5250. +
  5251. +/* ---------------------------------------------------------------------- */
  5252. +
  5253. +void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
  5254. + struct dentry *h_dentry)
  5255. +{
  5256. + struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
  5257. +
  5258. + DiMustWriteLock(dentry);
  5259. +
  5260. + if (hd->hd_dentry)
  5261. + au_hdput(hd);
  5262. + hd->hd_dentry = h_dentry;
  5263. +}
  5264. +
  5265. +void au_update_digen(struct dentry *dentry)
  5266. +{
  5267. + atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
  5268. + /* smp_mb(); */ /* atomic_set */
  5269. +}
  5270. +
  5271. +void au_update_dbrange(struct dentry *dentry, int do_put_zero)
  5272. +{
  5273. + struct au_dinfo *dinfo;
  5274. + struct dentry *h_d;
  5275. +
  5276. + DiMustWriteLock(dentry);
  5277. +
  5278. + dinfo = au_di(dentry);
  5279. + if (!dinfo || dinfo->di_bstart < 0)
  5280. + return;
  5281. +
  5282. + if (do_put_zero) {
  5283. + aufs_bindex_t bindex, bend;
  5284. +
  5285. + bend = dinfo->di_bend;
  5286. + for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) {
  5287. + h_d = dinfo->di_hdentry[0 + bindex].hd_dentry;
  5288. + if (h_d && !h_d->d_inode)
  5289. + au_set_h_dptr(dentry, bindex, NULL);
  5290. + }
  5291. + }
  5292. +
  5293. + dinfo->di_bstart = -1;
  5294. + while (++dinfo->di_bstart <= dinfo->di_bend)
  5295. + if (dinfo->di_hdentry[0 + dinfo->di_bstart].hd_dentry)
  5296. + break;
  5297. + if (dinfo->di_bstart > dinfo->di_bend) {
  5298. + dinfo->di_bstart = -1;
  5299. + dinfo->di_bend = -1;
  5300. + return;
  5301. + }
  5302. +
  5303. + dinfo->di_bend++;
  5304. + while (0 <= --dinfo->di_bend)
  5305. + if (dinfo->di_hdentry[0 + dinfo->di_bend].hd_dentry)
  5306. + break;
  5307. + AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0);
  5308. +}
  5309. +
  5310. +void au_update_dbstart(struct dentry *dentry)
  5311. +{
  5312. + aufs_bindex_t bindex, bend;
  5313. + struct dentry *h_dentry;
  5314. +
  5315. + bend = au_dbend(dentry);
  5316. + for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
  5317. + h_dentry = au_h_dptr(dentry, bindex);
  5318. + if (!h_dentry)
  5319. + continue;
  5320. + if (h_dentry->d_inode) {
  5321. + au_set_dbstart(dentry, bindex);
  5322. + return;
  5323. + }
  5324. + au_set_h_dptr(dentry, bindex, NULL);
  5325. + }
  5326. +}
  5327. +
  5328. +void au_update_dbend(struct dentry *dentry)
  5329. +{
  5330. + aufs_bindex_t bindex, bstart;
  5331. + struct dentry *h_dentry;
  5332. +
  5333. + bstart = au_dbstart(dentry);
  5334. + for (bindex = au_dbend(dentry); bindex <= bstart; bindex--) {
  5335. + h_dentry = au_h_dptr(dentry, bindex);
  5336. + if (!h_dentry)
  5337. + continue;
  5338. + if (h_dentry->d_inode) {
  5339. + au_set_dbend(dentry, bindex);
  5340. + return;
  5341. + }
  5342. + au_set_h_dptr(dentry, bindex, NULL);
  5343. + }
  5344. +}
  5345. +
  5346. +int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
  5347. +{
  5348. + aufs_bindex_t bindex, bend;
  5349. +
  5350. + bend = au_dbend(dentry);
  5351. + for (bindex = au_dbstart(dentry); bindex <= bend; bindex++)
  5352. + if (au_h_dptr(dentry, bindex) == h_dentry)
  5353. + return bindex;
  5354. + return -1;
  5355. +}
  5356. diff -Nur linux-2.6.34.orig/fs/aufs/dir.c linux-2.6.34/fs/aufs/dir.c
  5357. --- linux-2.6.34.orig/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
  5358. +++ linux-2.6.34/fs/aufs/dir.c 2010-05-23 23:33:19.893473066 +0200
  5359. @@ -0,0 +1,538 @@
  5360. +/*
  5361. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  5362. + *
  5363. + * This program, aufs is free software; you can redistribute it and/or modify
  5364. + * it under the terms of the GNU General Public License as published by
  5365. + * the Free Software Foundation; either version 2 of the License, or
  5366. + * (at your option) any later version.
  5367. + *
  5368. + * This program is distributed in the hope that it will be useful,
  5369. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  5370. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  5371. + * GNU General Public License for more details.
  5372. + *
  5373. + * You should have received a copy of the GNU General Public License
  5374. + * along with this program; if not, write to the Free Software
  5375. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  5376. + */
  5377. +
  5378. +/*
  5379. + * directory operations
  5380. + */
  5381. +
  5382. +#include <linux/file.h>
  5383. +#include <linux/fs_stack.h>
  5384. +#include "aufs.h"
  5385. +
  5386. +void au_add_nlink(struct inode *dir, struct inode *h_dir)
  5387. +{
  5388. + AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
  5389. +
  5390. + dir->i_nlink += h_dir->i_nlink - 2;
  5391. + if (h_dir->i_nlink < 2)
  5392. + dir->i_nlink += 2;
  5393. +}
  5394. +
  5395. +void au_sub_nlink(struct inode *dir, struct inode *h_dir)
  5396. +{
  5397. + AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
  5398. +
  5399. + dir->i_nlink -= h_dir->i_nlink - 2;
  5400. + if (h_dir->i_nlink < 2)
  5401. + dir->i_nlink -= 2;
  5402. +}
  5403. +
  5404. +/* ---------------------------------------------------------------------- */
  5405. +
  5406. +static int reopen_dir(struct file *file)
  5407. +{
  5408. + int err;
  5409. + unsigned int flags;
  5410. + aufs_bindex_t bindex, btail, bstart;
  5411. + struct dentry *dentry, *h_dentry;
  5412. + struct file *h_file;
  5413. +
  5414. + /* open all lower dirs */
  5415. + dentry = file->f_dentry;
  5416. + bstart = au_dbstart(dentry);
  5417. + for (bindex = au_fbstart(file); bindex < bstart; bindex++)
  5418. + au_set_h_fptr(file, bindex, NULL);
  5419. + au_set_fbstart(file, bstart);
  5420. +
  5421. + btail = au_dbtaildir(dentry);
  5422. + for (bindex = au_fbend(file); btail < bindex; bindex--)
  5423. + au_set_h_fptr(file, bindex, NULL);
  5424. + au_set_fbend(file, btail);
  5425. +
  5426. + flags = file->f_flags;
  5427. + for (bindex = bstart; bindex <= btail; bindex++) {
  5428. + h_dentry = au_h_dptr(dentry, bindex);
  5429. + if (!h_dentry)
  5430. + continue;
  5431. + h_file = au_h_fptr(file, bindex);
  5432. + if (h_file)
  5433. + continue;
  5434. +
  5435. + h_file = au_h_open(dentry, bindex, flags, file);
  5436. + err = PTR_ERR(h_file);
  5437. + if (IS_ERR(h_file))
  5438. + goto out; /* close all? */
  5439. + au_set_h_fptr(file, bindex, h_file);
  5440. + }
  5441. + au_update_figen(file);
  5442. + /* todo: necessary? */
  5443. + /* file->f_ra = h_file->f_ra; */
  5444. + err = 0;
  5445. +
  5446. + out:
  5447. + return err;
  5448. +}
  5449. +
  5450. +static int do_open_dir(struct file *file, int flags)
  5451. +{
  5452. + int err;
  5453. + aufs_bindex_t bindex, btail;
  5454. + struct dentry *dentry, *h_dentry;
  5455. + struct file *h_file;
  5456. +
  5457. + FiMustWriteLock(file);
  5458. +
  5459. + err = 0;
  5460. + dentry = file->f_dentry;
  5461. + au_set_fvdir_cache(file, NULL);
  5462. + au_fi(file)->fi_maintain_plink = 0;
  5463. + file->f_version = dentry->d_inode->i_version;
  5464. + bindex = au_dbstart(dentry);
  5465. + au_set_fbstart(file, bindex);
  5466. + btail = au_dbtaildir(dentry);
  5467. + au_set_fbend(file, btail);
  5468. + for (; !err && bindex <= btail; bindex++) {
  5469. + h_dentry = au_h_dptr(dentry, bindex);
  5470. + if (!h_dentry)
  5471. + continue;
  5472. +
  5473. + h_file = au_h_open(dentry, bindex, flags, file);
  5474. + if (IS_ERR(h_file)) {
  5475. + err = PTR_ERR(h_file);
  5476. + break;
  5477. + }
  5478. + au_set_h_fptr(file, bindex, h_file);
  5479. + }
  5480. + au_update_figen(file);
  5481. + /* todo: necessary? */
  5482. + /* file->f_ra = h_file->f_ra; */
  5483. + if (!err)
  5484. + return 0; /* success */
  5485. +
  5486. + /* close all */
  5487. + for (bindex = au_fbstart(file); bindex <= btail; bindex++)
  5488. + au_set_h_fptr(file, bindex, NULL);
  5489. + au_set_fbstart(file, -1);
  5490. + au_set_fbend(file, -1);
  5491. + return err;
  5492. +}
  5493. +
  5494. +static int aufs_open_dir(struct inode *inode __maybe_unused,
  5495. + struct file *file)
  5496. +{
  5497. + return au_do_open(file, do_open_dir);
  5498. +}
  5499. +
  5500. +static int aufs_release_dir(struct inode *inode __maybe_unused,
  5501. + struct file *file)
  5502. +{
  5503. + struct au_vdir *vdir_cache;
  5504. + struct super_block *sb;
  5505. + struct au_sbinfo *sbinfo;
  5506. +
  5507. + sb = file->f_dentry->d_sb;
  5508. + si_noflush_read_lock(sb);
  5509. + fi_write_lock(file);
  5510. + vdir_cache = au_fvdir_cache(file);
  5511. + if (vdir_cache)
  5512. + au_vdir_free(vdir_cache);
  5513. + if (au_fi(file)->fi_maintain_plink) {
  5514. + sbinfo = au_sbi(sb);
  5515. + /* clear the flag without write-lock */
  5516. + sbinfo->au_si_status &= ~AuSi_MAINTAIN_PLINK;
  5517. + smp_mb();
  5518. + wake_up_all(&sbinfo->si_plink_wq);
  5519. + }
  5520. + fi_write_unlock(file);
  5521. + au_finfo_fin(file);
  5522. + si_read_unlock(sb);
  5523. + return 0;
  5524. +}
  5525. +
  5526. +/* ---------------------------------------------------------------------- */
  5527. +
  5528. +static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
  5529. +{
  5530. + int err;
  5531. + aufs_bindex_t bend, bindex;
  5532. + struct inode *inode;
  5533. + struct super_block *sb;
  5534. +
  5535. + err = 0;
  5536. + sb = dentry->d_sb;
  5537. + inode = dentry->d_inode;
  5538. + IMustLock(inode);
  5539. + bend = au_dbend(dentry);
  5540. + for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) {
  5541. + struct path h_path;
  5542. + struct inode *h_inode;
  5543. +
  5544. + if (au_test_ro(sb, bindex, inode))
  5545. + continue;
  5546. + h_path.dentry = au_h_dptr(dentry, bindex);
  5547. + if (!h_path.dentry)
  5548. + continue;
  5549. + h_inode = h_path.dentry->d_inode;
  5550. + if (!h_inode)
  5551. + continue;
  5552. +
  5553. + /* no mnt_want_write() */
  5554. + /* cf. fs/nsfd/vfs.c and fs/nfsd/nfs4recover.c */
  5555. + /* todo: inotiry fired? */
  5556. + h_path.mnt = au_sbr_mnt(sb, bindex);
  5557. + mutex_lock(&h_inode->i_mutex);
  5558. + err = filemap_fdatawrite(h_inode->i_mapping);
  5559. + AuDebugOn(!h_inode->i_fop);
  5560. + if (!err && h_inode->i_fop->fsync)
  5561. + err = h_inode->i_fop->fsync(NULL, h_path.dentry,
  5562. + datasync);
  5563. + if (!err)
  5564. + err = filemap_fdatawrite(h_inode->i_mapping);
  5565. + if (!err)
  5566. + vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
  5567. + mutex_unlock(&h_inode->i_mutex);
  5568. + }
  5569. +
  5570. + return err;
  5571. +}
  5572. +
  5573. +static int au_do_fsync_dir(struct file *file, int datasync)
  5574. +{
  5575. + int err;
  5576. + aufs_bindex_t bend, bindex;
  5577. + struct file *h_file;
  5578. + struct super_block *sb;
  5579. + struct inode *inode;
  5580. + struct mutex *h_mtx;
  5581. +
  5582. + err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
  5583. + if (unlikely(err))
  5584. + goto out;
  5585. +
  5586. + sb = file->f_dentry->d_sb;
  5587. + inode = file->f_dentry->d_inode;
  5588. + bend = au_fbend(file);
  5589. + for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
  5590. + h_file = au_h_fptr(file, bindex);
  5591. + if (!h_file || au_test_ro(sb, bindex, inode))
  5592. + continue;
  5593. +
  5594. + err = vfs_fsync(h_file, h_file->f_dentry, datasync);
  5595. + if (!err) {
  5596. + h_mtx = &h_file->f_dentry->d_inode->i_mutex;
  5597. + mutex_lock(h_mtx);
  5598. + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
  5599. + /*ignore*/
  5600. + mutex_unlock(h_mtx);
  5601. + }
  5602. + }
  5603. +
  5604. + out:
  5605. + return err;
  5606. +}
  5607. +
  5608. +/*
  5609. + * @file may be NULL
  5610. + */
  5611. +static int aufs_fsync_dir(struct file *file, struct dentry *dentry,
  5612. + int datasync)
  5613. +{
  5614. + int err;
  5615. + struct super_block *sb;
  5616. +
  5617. + IMustLock(dentry->d_inode);
  5618. +
  5619. + err = 0;
  5620. + sb = dentry->d_sb;
  5621. + si_noflush_read_lock(sb);
  5622. + if (file)
  5623. + err = au_do_fsync_dir(file, datasync);
  5624. + else {
  5625. + di_write_lock_child(dentry);
  5626. + err = au_do_fsync_dir_no_file(dentry, datasync);
  5627. + }
  5628. + au_cpup_attr_timesizes(dentry->d_inode);
  5629. + di_write_unlock(dentry);
  5630. + if (file)
  5631. + fi_write_unlock(file);
  5632. +
  5633. + si_read_unlock(sb);
  5634. + return err;
  5635. +}
  5636. +
  5637. +/* ---------------------------------------------------------------------- */
  5638. +
  5639. +static int aufs_readdir(struct file *file, void *dirent, filldir_t filldir)
  5640. +{
  5641. + int err;
  5642. + struct dentry *dentry;
  5643. + struct inode *inode;
  5644. + struct super_block *sb;
  5645. +
  5646. + dentry = file->f_dentry;
  5647. + inode = dentry->d_inode;
  5648. + IMustLock(inode);
  5649. +
  5650. + sb = dentry->d_sb;
  5651. + si_read_lock(sb, AuLock_FLUSH);
  5652. + err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
  5653. + if (unlikely(err))
  5654. + goto out;
  5655. + err = au_vdir_init(file);
  5656. + di_downgrade_lock(dentry, AuLock_IR);
  5657. + if (unlikely(err))
  5658. + goto out_unlock;
  5659. +
  5660. + if (!au_test_nfsd(current)) {
  5661. + err = au_vdir_fill_de(file, dirent, filldir);
  5662. + fsstack_copy_attr_atime(inode,
  5663. + au_h_iptr(inode, au_ibstart(inode)));
  5664. + } else {
  5665. + /*
  5666. + * nfsd filldir may call lookup_one_len(), vfs_getattr(),
  5667. + * encode_fh() and others.
  5668. + */
  5669. + struct inode *h_inode = au_h_iptr(inode, au_ibstart(inode));
  5670. +
  5671. + di_read_unlock(dentry, AuLock_IR);
  5672. + si_read_unlock(sb);
  5673. + lockdep_off();
  5674. + err = au_vdir_fill_de(file, dirent, filldir);
  5675. + lockdep_on();
  5676. + fsstack_copy_attr_atime(inode, h_inode);
  5677. + fi_write_unlock(file);
  5678. +
  5679. + AuTraceErr(err);
  5680. + return err;
  5681. + }
  5682. +
  5683. + out_unlock:
  5684. + di_read_unlock(dentry, AuLock_IR);
  5685. + fi_write_unlock(file);
  5686. + out:
  5687. + si_read_unlock(sb);
  5688. + return err;
  5689. +}
  5690. +
  5691. +/* ---------------------------------------------------------------------- */
  5692. +
  5693. +#define AuTestEmpty_WHONLY 1
  5694. +#define AuTestEmpty_CALLED (1 << 1)
  5695. +#define AuTestEmpty_SHWH (1 << 2)
  5696. +#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
  5697. +#define au_fset_testempty(flags, name) { (flags) |= AuTestEmpty_##name; }
  5698. +#define au_fclr_testempty(flags, name) { (flags) &= ~AuTestEmpty_##name; }
  5699. +
  5700. +#ifndef CONFIG_AUFS_SHWH
  5701. +#undef AuTestEmpty_SHWH
  5702. +#define AuTestEmpty_SHWH 0
  5703. +#endif
  5704. +
  5705. +struct test_empty_arg {
  5706. + struct au_nhash whlist;
  5707. + unsigned int flags;
  5708. + int err;
  5709. + aufs_bindex_t bindex;
  5710. +};
  5711. +
  5712. +static int test_empty_cb(void *__arg, const char *__name, int namelen,
  5713. + loff_t offset __maybe_unused, u64 ino,
  5714. + unsigned int d_type)
  5715. +{
  5716. + struct test_empty_arg *arg = __arg;
  5717. + char *name = (void *)__name;
  5718. +
  5719. + arg->err = 0;
  5720. + au_fset_testempty(arg->flags, CALLED);
  5721. + /* smp_mb(); */
  5722. + if (name[0] == '.'
  5723. + && (namelen == 1 || (name[1] == '.' && namelen == 2)))
  5724. + goto out; /* success */
  5725. +
  5726. + if (namelen <= AUFS_WH_PFX_LEN
  5727. + || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
  5728. + if (au_ftest_testempty(arg->flags, WHONLY)
  5729. + && !au_nhash_test_known_wh(&arg->whlist, name, namelen))
  5730. + arg->err = -ENOTEMPTY;
  5731. + goto out;
  5732. + }
  5733. +
  5734. + name += AUFS_WH_PFX_LEN;
  5735. + namelen -= AUFS_WH_PFX_LEN;
  5736. + if (!au_nhash_test_known_wh(&arg->whlist, name, namelen))
  5737. + arg->err = au_nhash_append_wh
  5738. + (&arg->whlist, name, namelen, ino, d_type, arg->bindex,
  5739. + au_ftest_testempty(arg->flags, SHWH));
  5740. +
  5741. + out:
  5742. + /* smp_mb(); */
  5743. + AuTraceErr(arg->err);
  5744. + return arg->err;
  5745. +}
  5746. +
  5747. +static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
  5748. +{
  5749. + int err;
  5750. + struct file *h_file;
  5751. +
  5752. + h_file = au_h_open(dentry, arg->bindex,
  5753. + O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
  5754. + /*file*/NULL);
  5755. + err = PTR_ERR(h_file);
  5756. + if (IS_ERR(h_file))
  5757. + goto out;
  5758. +
  5759. + err = 0;
  5760. + if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
  5761. + && !h_file->f_dentry->d_inode->i_nlink)
  5762. + goto out_put;
  5763. +
  5764. + do {
  5765. + arg->err = 0;
  5766. + au_fclr_testempty(arg->flags, CALLED);
  5767. + /* smp_mb(); */
  5768. + err = vfsub_readdir(h_file, test_empty_cb, arg);
  5769. + if (err >= 0)
  5770. + err = arg->err;
  5771. + } while (!err && au_ftest_testempty(arg->flags, CALLED));
  5772. +
  5773. + out_put:
  5774. + fput(h_file);
  5775. + au_sbr_put(dentry->d_sb, arg->bindex);
  5776. + out:
  5777. + return err;
  5778. +}
  5779. +
  5780. +struct do_test_empty_args {
  5781. + int *errp;
  5782. + struct dentry *dentry;
  5783. + struct test_empty_arg *arg;
  5784. +};
  5785. +
  5786. +static void call_do_test_empty(void *args)
  5787. +{
  5788. + struct do_test_empty_args *a = args;
  5789. + *a->errp = do_test_empty(a->dentry, a->arg);
  5790. +}
  5791. +
  5792. +static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
  5793. +{
  5794. + int err, wkq_err;
  5795. + struct dentry *h_dentry;
  5796. + struct inode *h_inode;
  5797. +
  5798. + h_dentry = au_h_dptr(dentry, arg->bindex);
  5799. + h_inode = h_dentry->d_inode;
  5800. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  5801. + err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
  5802. + mutex_unlock(&h_inode->i_mutex);
  5803. + if (!err)
  5804. + err = do_test_empty(dentry, arg);
  5805. + else {
  5806. + struct do_test_empty_args args = {
  5807. + .errp = &err,
  5808. + .dentry = dentry,
  5809. + .arg = arg
  5810. + };
  5811. + unsigned int flags = arg->flags;
  5812. +
  5813. + wkq_err = au_wkq_wait(call_do_test_empty, &args);
  5814. + if (unlikely(wkq_err))
  5815. + err = wkq_err;
  5816. + arg->flags = flags;
  5817. + }
  5818. +
  5819. + return err;
  5820. +}
  5821. +
  5822. +int au_test_empty_lower(struct dentry *dentry)
  5823. +{
  5824. + int err;
  5825. + aufs_bindex_t bindex, bstart, btail;
  5826. + struct test_empty_arg arg;
  5827. +
  5828. + SiMustAnyLock(dentry->d_sb);
  5829. +
  5830. + err = au_nhash_alloc(&arg.whlist, au_sbi(dentry->d_sb)->si_rdhash,
  5831. + GFP_NOFS);
  5832. + if (unlikely(err))
  5833. + goto out;
  5834. +
  5835. + bstart = au_dbstart(dentry);
  5836. + arg.flags = 0;
  5837. + if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
  5838. + au_fset_testempty(arg.flags, SHWH);
  5839. + arg.bindex = bstart;
  5840. + err = do_test_empty(dentry, &arg);
  5841. + if (unlikely(err))
  5842. + goto out_whlist;
  5843. +
  5844. + au_fset_testempty(arg.flags, WHONLY);
  5845. + btail = au_dbtaildir(dentry);
  5846. + for (bindex = bstart + 1; !err && bindex <= btail; bindex++) {
  5847. + struct dentry *h_dentry;
  5848. +
  5849. + h_dentry = au_h_dptr(dentry, bindex);
  5850. + if (h_dentry && h_dentry->d_inode) {
  5851. + arg.bindex = bindex;
  5852. + err = do_test_empty(dentry, &arg);
  5853. + }
  5854. + }
  5855. +
  5856. + out_whlist:
  5857. + au_nhash_wh_free(&arg.whlist);
  5858. + out:
  5859. + return err;
  5860. +}
  5861. +
  5862. +int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
  5863. +{
  5864. + int err;
  5865. + struct test_empty_arg arg;
  5866. + aufs_bindex_t bindex, btail;
  5867. +
  5868. + err = 0;
  5869. + arg.whlist = *whlist;
  5870. + arg.flags = AuTestEmpty_WHONLY;
  5871. + if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
  5872. + au_fset_testempty(arg.flags, SHWH);
  5873. + btail = au_dbtaildir(dentry);
  5874. + for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) {
  5875. + struct dentry *h_dentry;
  5876. +
  5877. + h_dentry = au_h_dptr(dentry, bindex);
  5878. + if (h_dentry && h_dentry->d_inode) {
  5879. + arg.bindex = bindex;
  5880. + err = sio_test_empty(dentry, &arg);
  5881. + }
  5882. + }
  5883. +
  5884. + return err;
  5885. +}
  5886. +
  5887. +/* ---------------------------------------------------------------------- */
  5888. +
  5889. +const struct file_operations aufs_dir_fop = {
  5890. + .read = generic_read_dir,
  5891. + .readdir = aufs_readdir,
  5892. + .unlocked_ioctl = aufs_ioctl_dir,
  5893. + .open = aufs_open_dir,
  5894. + .release = aufs_release_dir,
  5895. + .flush = aufs_flush,
  5896. + .fsync = aufs_fsync_dir
  5897. +};
  5898. diff -Nur linux-2.6.34.orig/fs/aufs/dir.h linux-2.6.34/fs/aufs/dir.h
  5899. --- linux-2.6.34.orig/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100
  5900. +++ linux-2.6.34/fs/aufs/dir.h 2010-05-23 23:33:19.933473101 +0200
  5901. @@ -0,0 +1,114 @@
  5902. +/*
  5903. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  5904. + *
  5905. + * This program, aufs is free software; you can redistribute it and/or modify
  5906. + * it under the terms of the GNU General Public License as published by
  5907. + * the Free Software Foundation; either version 2 of the License, or
  5908. + * (at your option) any later version.
  5909. + *
  5910. + * This program is distributed in the hope that it will be useful,
  5911. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  5912. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  5913. + * GNU General Public License for more details.
  5914. + *
  5915. + * You should have received a copy of the GNU General Public License
  5916. + * along with this program; if not, write to the Free Software
  5917. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  5918. + */
  5919. +
  5920. +/*
  5921. + * directory operations
  5922. + */
  5923. +
  5924. +#ifndef __AUFS_DIR_H__
  5925. +#define __AUFS_DIR_H__
  5926. +
  5927. +#ifdef __KERNEL__
  5928. +
  5929. +#include <linux/fs.h>
  5930. +#include <linux/aufs_type.h>
  5931. +
  5932. +/* ---------------------------------------------------------------------- */
  5933. +
  5934. +/* need to be faster and smaller */
  5935. +
  5936. +struct au_nhash {
  5937. + unsigned int nh_num;
  5938. + struct hlist_head *nh_head;
  5939. +};
  5940. +
  5941. +struct au_vdir_destr {
  5942. + unsigned char len;
  5943. + unsigned char name[0];
  5944. +} __packed;
  5945. +
  5946. +struct au_vdir_dehstr {
  5947. + struct hlist_node hash;
  5948. + struct au_vdir_destr *str;
  5949. +};
  5950. +
  5951. +struct au_vdir_de {
  5952. + ino_t de_ino;
  5953. + unsigned char de_type;
  5954. + /* caution: packed */
  5955. + struct au_vdir_destr de_str;
  5956. +} __packed;
  5957. +
  5958. +struct au_vdir_wh {
  5959. + struct hlist_node wh_hash;
  5960. +#ifdef CONFIG_AUFS_SHWH
  5961. + ino_t wh_ino;
  5962. + aufs_bindex_t wh_bindex;
  5963. + unsigned char wh_type;
  5964. +#else
  5965. + aufs_bindex_t wh_bindex;
  5966. +#endif
  5967. + /* caution: packed */
  5968. + struct au_vdir_destr wh_str;
  5969. +} __packed;
  5970. +
  5971. +union au_vdir_deblk_p {
  5972. + unsigned char *deblk;
  5973. + struct au_vdir_de *de;
  5974. +};
  5975. +
  5976. +struct au_vdir {
  5977. + unsigned char **vd_deblk;
  5978. + unsigned long vd_nblk;
  5979. + struct {
  5980. + unsigned long ul;
  5981. + union au_vdir_deblk_p p;
  5982. + } vd_last;
  5983. +
  5984. + unsigned long vd_version;
  5985. + unsigned int vd_deblk_sz;
  5986. + unsigned long vd_jiffy;
  5987. +};
  5988. +
  5989. +/* ---------------------------------------------------------------------- */
  5990. +
  5991. +/* dir.c */
  5992. +extern const struct file_operations aufs_dir_fop;
  5993. +void au_add_nlink(struct inode *dir, struct inode *h_dir);
  5994. +void au_sub_nlink(struct inode *dir, struct inode *h_dir);
  5995. +int au_test_empty_lower(struct dentry *dentry);
  5996. +int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
  5997. +
  5998. +/* vdir.c */
  5999. +int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
  6000. +void au_nhash_wh_free(struct au_nhash *whlist);
  6001. +int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
  6002. + int limit);
  6003. +int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
  6004. +int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
  6005. + unsigned int d_type, aufs_bindex_t bindex,
  6006. + unsigned char shwh);
  6007. +void au_vdir_free(struct au_vdir *vdir);
  6008. +int au_vdir_init(struct file *file);
  6009. +int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir);
  6010. +
  6011. +/* ioctl.c */
  6012. +long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
  6013. +
  6014. +#endif /* __KERNEL__ */
  6015. +#endif /* __AUFS_DIR_H__ */
  6016. diff -Nur linux-2.6.34.orig/fs/aufs/export.c linux-2.6.34/fs/aufs/export.c
  6017. --- linux-2.6.34.orig/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
  6018. +++ linux-2.6.34/fs/aufs/export.c 2010-05-23 23:59:08.473464298 +0200
  6019. @@ -0,0 +1,747 @@
  6020. +/*
  6021. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  6022. + *
  6023. + * This program, aufs is free software; you can redistribute it and/or modify
  6024. + * it under the terms of the GNU General Public License as published by
  6025. + * the Free Software Foundation; either version 2 of the License, or
  6026. + * (at your option) any later version.
  6027. + *
  6028. + * This program is distributed in the hope that it will be useful,
  6029. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  6030. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  6031. + * GNU General Public License for more details.
  6032. + *
  6033. + * You should have received a copy of the GNU General Public License
  6034. + * along with this program; if not, write to the Free Software
  6035. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  6036. + */
  6037. +
  6038. +/*
  6039. + * export via nfs
  6040. + */
  6041. +
  6042. +#include <linux/exportfs.h>
  6043. +#include <linux/file.h>
  6044. +#include <linux/mnt_namespace.h>
  6045. +#include <linux/nsproxy.h>
  6046. +#include <linux/namei.h>
  6047. +#include <linux/random.h>
  6048. +#include "../internal.h"
  6049. +#include "aufs.h"
  6050. +
  6051. +union conv {
  6052. +#ifdef CONFIG_AUFS_INO_T_64
  6053. + __u32 a[2];
  6054. +#else
  6055. + __u32 a[1];
  6056. +#endif
  6057. + ino_t ino;
  6058. +};
  6059. +
  6060. +static ino_t decode_ino(__u32 *a)
  6061. +{
  6062. + union conv u;
  6063. +
  6064. + BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
  6065. + u.a[0] = a[0];
  6066. +#ifdef CONFIG_AUFS_INO_T_64
  6067. + u.a[1] = a[1];
  6068. +#endif
  6069. + return u.ino;
  6070. +}
  6071. +
  6072. +static void encode_ino(__u32 *a, ino_t ino)
  6073. +{
  6074. + union conv u;
  6075. +
  6076. + u.ino = ino;
  6077. + a[0] = u.a[0];
  6078. +#ifdef CONFIG_AUFS_INO_T_64
  6079. + a[1] = u.a[1];
  6080. +#endif
  6081. +}
  6082. +
  6083. +/* NFS file handle */
  6084. +enum {
  6085. + Fh_br_id,
  6086. + Fh_sigen,
  6087. +#ifdef CONFIG_AUFS_INO_T_64
  6088. + /* support 64bit inode number */
  6089. + Fh_ino1,
  6090. + Fh_ino2,
  6091. + Fh_dir_ino1,
  6092. + Fh_dir_ino2,
  6093. +#else
  6094. + Fh_ino1,
  6095. + Fh_dir_ino1,
  6096. +#endif
  6097. + Fh_igen,
  6098. + Fh_h_type,
  6099. + Fh_tail,
  6100. +
  6101. + Fh_ino = Fh_ino1,
  6102. + Fh_dir_ino = Fh_dir_ino1
  6103. +};
  6104. +
  6105. +static int au_test_anon(struct dentry *dentry)
  6106. +{
  6107. + return !!(dentry->d_flags & DCACHE_DISCONNECTED);
  6108. +}
  6109. +
  6110. +/* ---------------------------------------------------------------------- */
  6111. +/* inode generation external table */
  6112. +
  6113. +int au_xigen_inc(struct inode *inode)
  6114. +{
  6115. + int err;
  6116. + loff_t pos;
  6117. + ssize_t sz;
  6118. + __u32 igen;
  6119. + struct super_block *sb;
  6120. + struct au_sbinfo *sbinfo;
  6121. +
  6122. + err = 0;
  6123. + sb = inode->i_sb;
  6124. + sbinfo = au_sbi(sb);
  6125. + /*
  6126. + * temporary workaround for escaping from SiMustAnyLock() in
  6127. + * au_mntflags(), since this function is called from au_iinfo_fin().
  6128. + */
  6129. + if (unlikely(!au_opt_test(sbinfo->si_mntflags, XINO)))
  6130. + goto out;
  6131. +
  6132. + pos = inode->i_ino;
  6133. + pos *= sizeof(igen);
  6134. + igen = inode->i_generation + 1;
  6135. + sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
  6136. + sizeof(igen), &pos);
  6137. + if (sz == sizeof(igen))
  6138. + goto out; /* success */
  6139. +
  6140. + err = sz;
  6141. + if (unlikely(sz >= 0)) {
  6142. + err = -EIO;
  6143. + AuIOErr("xigen error (%zd)\n", sz);
  6144. + }
  6145. +
  6146. + out:
  6147. + return err;
  6148. +}
  6149. +
  6150. +int au_xigen_new(struct inode *inode)
  6151. +{
  6152. + int err;
  6153. + loff_t pos;
  6154. + ssize_t sz;
  6155. + struct super_block *sb;
  6156. + struct au_sbinfo *sbinfo;
  6157. + struct file *file;
  6158. +
  6159. + err = 0;
  6160. + /* todo: dirty, at mount time */
  6161. + if (inode->i_ino == AUFS_ROOT_INO)
  6162. + goto out;
  6163. + sb = inode->i_sb;
  6164. + SiMustAnyLock(sb);
  6165. + if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
  6166. + goto out;
  6167. +
  6168. + err = -EFBIG;
  6169. + pos = inode->i_ino;
  6170. + if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
  6171. + AuIOErr1("too large i%lld\n", pos);
  6172. + goto out;
  6173. + }
  6174. + pos *= sizeof(inode->i_generation);
  6175. +
  6176. + err = 0;
  6177. + sbinfo = au_sbi(sb);
  6178. + file = sbinfo->si_xigen;
  6179. + BUG_ON(!file);
  6180. +
  6181. + if (i_size_read(file->f_dentry->d_inode)
  6182. + < pos + sizeof(inode->i_generation)) {
  6183. + inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
  6184. + sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
  6185. + sizeof(inode->i_generation), &pos);
  6186. + } else
  6187. + sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
  6188. + sizeof(inode->i_generation), &pos);
  6189. + if (sz == sizeof(inode->i_generation))
  6190. + goto out; /* success */
  6191. +
  6192. + err = sz;
  6193. + if (unlikely(sz >= 0)) {
  6194. + err = -EIO;
  6195. + AuIOErr("xigen error (%zd)\n", sz);
  6196. + }
  6197. +
  6198. + out:
  6199. + return err;
  6200. +}
  6201. +
  6202. +int au_xigen_set(struct super_block *sb, struct file *base)
  6203. +{
  6204. + int err;
  6205. + struct au_sbinfo *sbinfo;
  6206. + struct file *file;
  6207. +
  6208. + SiMustWriteLock(sb);
  6209. +
  6210. + sbinfo = au_sbi(sb);
  6211. + file = au_xino_create2(base, sbinfo->si_xigen);
  6212. + err = PTR_ERR(file);
  6213. + if (IS_ERR(file))
  6214. + goto out;
  6215. + err = 0;
  6216. + if (sbinfo->si_xigen)
  6217. + fput(sbinfo->si_xigen);
  6218. + sbinfo->si_xigen = file;
  6219. +
  6220. + out:
  6221. + return err;
  6222. +}
  6223. +
  6224. +void au_xigen_clr(struct super_block *sb)
  6225. +{
  6226. + struct au_sbinfo *sbinfo;
  6227. +
  6228. + SiMustWriteLock(sb);
  6229. +
  6230. + sbinfo = au_sbi(sb);
  6231. + if (sbinfo->si_xigen) {
  6232. + fput(sbinfo->si_xigen);
  6233. + sbinfo->si_xigen = NULL;
  6234. + }
  6235. +}
  6236. +
  6237. +/* ---------------------------------------------------------------------- */
  6238. +
  6239. +static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
  6240. + ino_t dir_ino)
  6241. +{
  6242. + struct dentry *dentry, *d;
  6243. + struct inode *inode;
  6244. + unsigned int sigen;
  6245. +
  6246. + dentry = NULL;
  6247. + inode = ilookup(sb, ino);
  6248. + if (!inode)
  6249. + goto out;
  6250. +
  6251. + dentry = ERR_PTR(-ESTALE);
  6252. + sigen = au_sigen(sb);
  6253. + if (unlikely(is_bad_inode(inode)
  6254. + || IS_DEADDIR(inode)
  6255. + || sigen != au_iigen(inode)))
  6256. + goto out_iput;
  6257. +
  6258. + dentry = NULL;
  6259. + if (!dir_ino || S_ISDIR(inode->i_mode))
  6260. + dentry = d_find_alias(inode);
  6261. + else {
  6262. + spin_lock(&dcache_lock);
  6263. + list_for_each_entry(d, &inode->i_dentry, d_alias)
  6264. + if (!au_test_anon(d)
  6265. + && d->d_parent->d_inode->i_ino == dir_ino) {
  6266. + dentry = dget_locked(d);
  6267. + break;
  6268. + }
  6269. + spin_unlock(&dcache_lock);
  6270. + }
  6271. + if (unlikely(dentry && sigen != au_digen(dentry))) {
  6272. + dput(dentry);
  6273. + dentry = ERR_PTR(-ESTALE);
  6274. + }
  6275. +
  6276. + out_iput:
  6277. + iput(inode);
  6278. + out:
  6279. + return dentry;
  6280. +}
  6281. +
  6282. +/* ---------------------------------------------------------------------- */
  6283. +
  6284. +/* todo: dirty? */
  6285. +/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
  6286. +static struct vfsmount *au_mnt_get(struct super_block *sb)
  6287. +{
  6288. + struct mnt_namespace *ns;
  6289. + struct vfsmount *pos, *mnt;
  6290. +
  6291. + spin_lock(&vfsmount_lock);
  6292. + /* no get/put ?? */
  6293. + AuDebugOn(!current->nsproxy);
  6294. + ns = current->nsproxy->mnt_ns;
  6295. + AuDebugOn(!ns);
  6296. + mnt = NULL;
  6297. + /* the order (reverse) will not be a problem */
  6298. + list_for_each_entry(pos, &ns->list, mnt_list)
  6299. + if (pos->mnt_sb == sb) {
  6300. + mnt = mntget(pos);
  6301. + break;
  6302. + }
  6303. + spin_unlock(&vfsmount_lock);
  6304. + AuDebugOn(!mnt);
  6305. +
  6306. + return mnt;
  6307. +}
  6308. +
  6309. +struct au_nfsd_si_lock {
  6310. + const unsigned int sigen;
  6311. + const aufs_bindex_t br_id;
  6312. + unsigned char force_lock;
  6313. +};
  6314. +
  6315. +static aufs_bindex_t si_nfsd_read_lock(struct super_block *sb,
  6316. + struct au_nfsd_si_lock *nsi_lock)
  6317. +{
  6318. + aufs_bindex_t bindex;
  6319. +
  6320. + si_read_lock(sb, AuLock_FLUSH);
  6321. +
  6322. + /* branch id may be wrapped around */
  6323. + bindex = au_br_index(sb, nsi_lock->br_id);
  6324. + if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
  6325. + goto out; /* success */
  6326. +
  6327. + if (!nsi_lock->force_lock)
  6328. + si_read_unlock(sb);
  6329. + bindex = -1;
  6330. +
  6331. + out:
  6332. + return bindex;
  6333. +}
  6334. +
  6335. +struct find_name_by_ino {
  6336. + int called, found;
  6337. + ino_t ino;
  6338. + char *name;
  6339. + int namelen;
  6340. +};
  6341. +
  6342. +static int
  6343. +find_name_by_ino(void *arg, const char *name, int namelen, loff_t offset,
  6344. + u64 ino, unsigned int d_type)
  6345. +{
  6346. + struct find_name_by_ino *a = arg;
  6347. +
  6348. + a->called++;
  6349. + if (a->ino != ino)
  6350. + return 0;
  6351. +
  6352. + memcpy(a->name, name, namelen);
  6353. + a->namelen = namelen;
  6354. + a->found = 1;
  6355. + return 1;
  6356. +}
  6357. +
  6358. +static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
  6359. + struct au_nfsd_si_lock *nsi_lock)
  6360. +{
  6361. + struct dentry *dentry, *parent;
  6362. + struct file *file;
  6363. + struct inode *dir;
  6364. + struct find_name_by_ino arg;
  6365. + int err;
  6366. +
  6367. + parent = path->dentry;
  6368. + if (nsi_lock)
  6369. + si_read_unlock(parent->d_sb);
  6370. + path_get(path);
  6371. + file = dentry_open(parent, path->mnt, au_dir_roflags, current_cred());
  6372. + dentry = (void *)file;
  6373. + if (IS_ERR(file))
  6374. + goto out;
  6375. +
  6376. + dentry = ERR_PTR(-ENOMEM);
  6377. + arg.name = __getname();
  6378. + if (unlikely(!arg.name))
  6379. + goto out_file;
  6380. + arg.ino = ino;
  6381. + arg.found = 0;
  6382. + do {
  6383. + arg.called = 0;
  6384. + /* smp_mb(); */
  6385. + err = vfsub_readdir(file, find_name_by_ino, &arg);
  6386. + } while (!err && !arg.found && arg.called);
  6387. + dentry = ERR_PTR(err);
  6388. + if (unlikely(err))
  6389. + goto out_name;
  6390. + dentry = ERR_PTR(-ENOENT);
  6391. + if (!arg.found)
  6392. + goto out_name;
  6393. +
  6394. + /* do not call au_lkup_one() */
  6395. + dir = parent->d_inode;
  6396. + mutex_lock(&dir->i_mutex);
  6397. + dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
  6398. + mutex_unlock(&dir->i_mutex);
  6399. + AuTraceErrPtr(dentry);
  6400. + if (IS_ERR(dentry))
  6401. + goto out_name;
  6402. + AuDebugOn(au_test_anon(dentry));
  6403. + if (unlikely(!dentry->d_inode)) {
  6404. + dput(dentry);
  6405. + dentry = ERR_PTR(-ENOENT);
  6406. + }
  6407. +
  6408. + out_name:
  6409. + __putname(arg.name);
  6410. + out_file:
  6411. + fput(file);
  6412. + out:
  6413. + if (unlikely(nsi_lock
  6414. + && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
  6415. + if (!IS_ERR(dentry)) {
  6416. + dput(dentry);
  6417. + dentry = ERR_PTR(-ESTALE);
  6418. + }
  6419. + AuTraceErrPtr(dentry);
  6420. + return dentry;
  6421. +}
  6422. +
  6423. +static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
  6424. + ino_t dir_ino,
  6425. + struct au_nfsd_si_lock *nsi_lock)
  6426. +{
  6427. + struct dentry *dentry;
  6428. + struct path path;
  6429. +
  6430. + if (dir_ino != AUFS_ROOT_INO) {
  6431. + path.dentry = decode_by_ino(sb, dir_ino, 0);
  6432. + dentry = path.dentry;
  6433. + if (!path.dentry || IS_ERR(path.dentry))
  6434. + goto out;
  6435. + AuDebugOn(au_test_anon(path.dentry));
  6436. + } else
  6437. + path.dentry = dget(sb->s_root);
  6438. +
  6439. + path.mnt = au_mnt_get(sb);
  6440. + dentry = au_lkup_by_ino(&path, ino, nsi_lock);
  6441. + path_put(&path);
  6442. +
  6443. + out:
  6444. + AuTraceErrPtr(dentry);
  6445. + return dentry;
  6446. +}
  6447. +
  6448. +/* ---------------------------------------------------------------------- */
  6449. +
  6450. +static int h_acceptable(void *expv, struct dentry *dentry)
  6451. +{
  6452. + return 1;
  6453. +}
  6454. +
  6455. +static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
  6456. + char *buf, int len, struct super_block *sb)
  6457. +{
  6458. + char *p;
  6459. + int n;
  6460. + struct path path;
  6461. +
  6462. + p = d_path(h_rootpath, buf, len);
  6463. + if (IS_ERR(p))
  6464. + goto out;
  6465. + n = strlen(p);
  6466. +
  6467. + path.mnt = h_rootpath->mnt;
  6468. + path.dentry = h_parent;
  6469. + p = d_path(&path, buf, len);
  6470. + if (IS_ERR(p))
  6471. + goto out;
  6472. + if (n != 1)
  6473. + p += n;
  6474. +
  6475. + path.mnt = au_mnt_get(sb);
  6476. + path.dentry = sb->s_root;
  6477. + p = d_path(&path, buf, len - strlen(p));
  6478. + mntput(path.mnt);
  6479. + if (IS_ERR(p))
  6480. + goto out;
  6481. + if (n != 1)
  6482. + p[strlen(p)] = '/';
  6483. +
  6484. + out:
  6485. + AuTraceErrPtr(p);
  6486. + return p;
  6487. +}
  6488. +
  6489. +static
  6490. +struct dentry *decode_by_path(struct super_block *sb, aufs_bindex_t bindex,
  6491. + ino_t ino, __u32 *fh, int fh_len,
  6492. + struct au_nfsd_si_lock *nsi_lock)
  6493. +{
  6494. + struct dentry *dentry, *h_parent, *root;
  6495. + struct super_block *h_sb;
  6496. + char *pathname, *p;
  6497. + struct vfsmount *h_mnt;
  6498. + struct au_branch *br;
  6499. + int err;
  6500. + struct path path;
  6501. +
  6502. + br = au_sbr(sb, bindex);
  6503. + /* au_br_get(br); */
  6504. + h_mnt = br->br_mnt;
  6505. + h_sb = h_mnt->mnt_sb;
  6506. + /* todo: call lower fh_to_dentry()? fh_to_parent()? */
  6507. + h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
  6508. + fh_len - Fh_tail, fh[Fh_h_type],
  6509. + h_acceptable, /*context*/NULL);
  6510. + dentry = h_parent;
  6511. + if (unlikely(!h_parent || IS_ERR(h_parent))) {
  6512. + AuWarn1("%s decode_fh failed, %ld\n",
  6513. + au_sbtype(h_sb), PTR_ERR(h_parent));
  6514. + goto out;
  6515. + }
  6516. + dentry = NULL;
  6517. + if (unlikely(au_test_anon(h_parent))) {
  6518. + AuWarn1("%s decode_fh returned a disconnected dentry\n",
  6519. + au_sbtype(h_sb));
  6520. + goto out_h_parent;
  6521. + }
  6522. +
  6523. + dentry = ERR_PTR(-ENOMEM);
  6524. + pathname = (void *)__get_free_page(GFP_NOFS);
  6525. + if (unlikely(!pathname))
  6526. + goto out_h_parent;
  6527. +
  6528. + root = sb->s_root;
  6529. + path.mnt = h_mnt;
  6530. + di_read_lock_parent(root, !AuLock_IR);
  6531. + path.dentry = au_h_dptr(root, bindex);
  6532. + di_read_unlock(root, !AuLock_IR);
  6533. + p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
  6534. + dentry = (void *)p;
  6535. + if (IS_ERR(p))
  6536. + goto out_pathname;
  6537. +
  6538. + si_read_unlock(sb);
  6539. + err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
  6540. + dentry = ERR_PTR(err);
  6541. + if (unlikely(err))
  6542. + goto out_relock;
  6543. +
  6544. + dentry = ERR_PTR(-ENOENT);
  6545. + AuDebugOn(au_test_anon(path.dentry));
  6546. + if (unlikely(!path.dentry->d_inode))
  6547. + goto out_path;
  6548. +
  6549. + if (ino != path.dentry->d_inode->i_ino)
  6550. + dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
  6551. + else
  6552. + dentry = dget(path.dentry);
  6553. +
  6554. + out_path:
  6555. + path_put(&path);
  6556. + out_relock:
  6557. + if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
  6558. + if (!IS_ERR(dentry)) {
  6559. + dput(dentry);
  6560. + dentry = ERR_PTR(-ESTALE);
  6561. + }
  6562. + out_pathname:
  6563. + free_page((unsigned long)pathname);
  6564. + out_h_parent:
  6565. + dput(h_parent);
  6566. + out:
  6567. + /* au_br_put(br); */
  6568. + AuTraceErrPtr(dentry);
  6569. + return dentry;
  6570. +}
  6571. +
  6572. +/* ---------------------------------------------------------------------- */
  6573. +
  6574. +static struct dentry *
  6575. +aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
  6576. + int fh_type)
  6577. +{
  6578. + struct dentry *dentry;
  6579. + __u32 *fh = fid->raw;
  6580. + ino_t ino, dir_ino;
  6581. + aufs_bindex_t bindex;
  6582. + struct au_nfsd_si_lock nsi_lock = {
  6583. + .sigen = fh[Fh_sigen],
  6584. + .br_id = fh[Fh_br_id],
  6585. + .force_lock = 0
  6586. + };
  6587. +
  6588. + AuDebugOn(fh_len < Fh_tail);
  6589. +
  6590. + dentry = ERR_PTR(-ESTALE);
  6591. + /* branch id may be wrapped around */
  6592. + bindex = si_nfsd_read_lock(sb, &nsi_lock);
  6593. + if (unlikely(bindex < 0))
  6594. + goto out;
  6595. + nsi_lock.force_lock = 1;
  6596. +
  6597. + /* is this inode still cached? */
  6598. + ino = decode_ino(fh + Fh_ino);
  6599. + AuDebugOn(ino == AUFS_ROOT_INO);
  6600. + dir_ino = decode_ino(fh + Fh_dir_ino);
  6601. + dentry = decode_by_ino(sb, ino, dir_ino);
  6602. + if (IS_ERR(dentry))
  6603. + goto out_unlock;
  6604. + if (dentry)
  6605. + goto accept;
  6606. +
  6607. + /* is the parent dir cached? */
  6608. + dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
  6609. + if (IS_ERR(dentry))
  6610. + goto out_unlock;
  6611. + if (dentry)
  6612. + goto accept;
  6613. +
  6614. + /* lookup path */
  6615. + dentry = decode_by_path(sb, bindex, ino, fh, fh_len, &nsi_lock);
  6616. + if (IS_ERR(dentry))
  6617. + goto out_unlock;
  6618. + if (unlikely(!dentry))
  6619. + /* todo?: make it ESTALE */
  6620. + goto out_unlock;
  6621. +
  6622. + accept:
  6623. + if (dentry->d_inode->i_generation == fh[Fh_igen])
  6624. + goto out_unlock; /* success */
  6625. +
  6626. + dput(dentry);
  6627. + dentry = ERR_PTR(-ESTALE);
  6628. + out_unlock:
  6629. + si_read_unlock(sb);
  6630. + out:
  6631. + AuTraceErrPtr(dentry);
  6632. + return dentry;
  6633. +}
  6634. +
  6635. +#if 0 /* reserved for future use */
  6636. +/* support subtreecheck option */
  6637. +static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
  6638. + int fh_len, int fh_type)
  6639. +{
  6640. + struct dentry *parent;
  6641. + __u32 *fh = fid->raw;
  6642. + ino_t dir_ino;
  6643. +
  6644. + dir_ino = decode_ino(fh + Fh_dir_ino);
  6645. + parent = decode_by_ino(sb, dir_ino, 0);
  6646. + if (IS_ERR(parent))
  6647. + goto out;
  6648. + if (!parent)
  6649. + parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
  6650. + dir_ino, fh, fh_len);
  6651. +
  6652. + out:
  6653. + AuTraceErrPtr(parent);
  6654. + return parent;
  6655. +}
  6656. +#endif
  6657. +
  6658. +/* ---------------------------------------------------------------------- */
  6659. +
  6660. +static int aufs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
  6661. + int connectable)
  6662. +{
  6663. + int err;
  6664. + aufs_bindex_t bindex, bend;
  6665. + struct super_block *sb, *h_sb;
  6666. + struct inode *inode;
  6667. + struct dentry *parent, *h_parent;
  6668. + struct au_branch *br;
  6669. +
  6670. + AuDebugOn(au_test_anon(dentry));
  6671. +
  6672. + parent = NULL;
  6673. + err = -ENOSPC;
  6674. + if (unlikely(*max_len <= Fh_tail)) {
  6675. + AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
  6676. + goto out;
  6677. + }
  6678. +
  6679. + err = FILEID_ROOT;
  6680. + if (IS_ROOT(dentry)) {
  6681. + AuDebugOn(dentry->d_inode->i_ino != AUFS_ROOT_INO);
  6682. + goto out;
  6683. + }
  6684. +
  6685. + err = -EIO;
  6686. + h_parent = NULL;
  6687. + sb = dentry->d_sb;
  6688. + aufs_read_lock(dentry, AuLock_FLUSH | AuLock_IR);
  6689. + parent = dget_parent(dentry);
  6690. + di_read_lock_parent(parent, !AuLock_IR);
  6691. + inode = dentry->d_inode;
  6692. + AuDebugOn(!inode);
  6693. +#ifdef CONFIG_AUFS_DEBUG
  6694. + if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
  6695. + AuWarn1("NFS-exporting requires xino\n");
  6696. +#endif
  6697. +
  6698. + bend = au_dbtaildir(parent);
  6699. + for (bindex = au_dbstart(parent); bindex <= bend; bindex++) {
  6700. + h_parent = au_h_dptr(parent, bindex);
  6701. + if (h_parent) {
  6702. + dget(h_parent);
  6703. + break;
  6704. + }
  6705. + }
  6706. + if (unlikely(!h_parent))
  6707. + goto out_unlock;
  6708. +
  6709. + err = -EPERM;
  6710. + br = au_sbr(sb, bindex);
  6711. + h_sb = br->br_mnt->mnt_sb;
  6712. + if (unlikely(!h_sb->s_export_op)) {
  6713. + AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
  6714. + goto out_dput;
  6715. + }
  6716. +
  6717. + fh[Fh_br_id] = br->br_id;
  6718. + fh[Fh_sigen] = au_sigen(sb);
  6719. + encode_ino(fh + Fh_ino, inode->i_ino);
  6720. + encode_ino(fh + Fh_dir_ino, parent->d_inode->i_ino);
  6721. + fh[Fh_igen] = inode->i_generation;
  6722. +
  6723. + *max_len -= Fh_tail;
  6724. + fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
  6725. + max_len,
  6726. + /*connectable or subtreecheck*/0);
  6727. + err = fh[Fh_h_type];
  6728. + *max_len += Fh_tail;
  6729. + /* todo: macros? */
  6730. + if (err != 255)
  6731. + err = 99;
  6732. + else
  6733. + AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
  6734. +
  6735. + out_dput:
  6736. + dput(h_parent);
  6737. + out_unlock:
  6738. + di_read_unlock(parent, !AuLock_IR);
  6739. + dput(parent);
  6740. + aufs_read_unlock(dentry, AuLock_IR);
  6741. + out:
  6742. + if (unlikely(err < 0))
  6743. + err = 255;
  6744. + return err;
  6745. +}
  6746. +
  6747. +/* ---------------------------------------------------------------------- */
  6748. +
  6749. +static struct export_operations aufs_export_op = {
  6750. + .fh_to_dentry = aufs_fh_to_dentry,
  6751. + /* .fh_to_parent = aufs_fh_to_parent, */
  6752. + .encode_fh = aufs_encode_fh
  6753. +};
  6754. +
  6755. +void au_export_init(struct super_block *sb)
  6756. +{
  6757. + struct au_sbinfo *sbinfo;
  6758. + __u32 u;
  6759. +
  6760. + sb->s_export_op = &aufs_export_op;
  6761. + sbinfo = au_sbi(sb);
  6762. + sbinfo->si_xigen = NULL;
  6763. + get_random_bytes(&u, sizeof(u));
  6764. + BUILD_BUG_ON(sizeof(u) != sizeof(int));
  6765. + atomic_set(&sbinfo->si_xigen_next, u);
  6766. +}
  6767. diff -Nur linux-2.6.34.orig/fs/aufs/file.c linux-2.6.34/fs/aufs/file.c
  6768. --- linux-2.6.34.orig/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
  6769. +++ linux-2.6.34/fs/aufs/file.c 2010-05-23 23:33:20.032223033 +0200
  6770. @@ -0,0 +1,578 @@
  6771. +/*
  6772. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  6773. + *
  6774. + * This program, aufs is free software; you can redistribute it and/or modify
  6775. + * it under the terms of the GNU General Public License as published by
  6776. + * the Free Software Foundation; either version 2 of the License, or
  6777. + * (at your option) any later version.
  6778. + *
  6779. + * This program is distributed in the hope that it will be useful,
  6780. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  6781. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  6782. + * GNU General Public License for more details.
  6783. + *
  6784. + * You should have received a copy of the GNU General Public License
  6785. + * along with this program; if not, write to the Free Software
  6786. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  6787. + */
  6788. +
  6789. +/*
  6790. + * handling file/dir, and address_space operation
  6791. + */
  6792. +
  6793. +#include <linux/file.h>
  6794. +#include <linux/fsnotify.h>
  6795. +#include <linux/namei.h>
  6796. +#include <linux/pagemap.h>
  6797. +#include "aufs.h"
  6798. +
  6799. +/*
  6800. + * a dirty trick for handling deny_write_access().
  6801. + * because FMODE_EXEC flag is not passed to f_op->open(),
  6802. + * set it to file->private_data temporary.
  6803. + */
  6804. +void au_store_oflag(struct nameidata *nd, struct inode *inode)
  6805. +{
  6806. + if (nd
  6807. + /* && !(nd->flags & LOOKUP_CONTINUE) */
  6808. + && (nd->flags & LOOKUP_OPEN)
  6809. + && (nd->intent.open.flags & vfsub_fmode_to_uint(FMODE_EXEC))
  6810. + && inode
  6811. + && S_ISREG(inode->i_mode)) {
  6812. + /* suppress a warning in lp64 */
  6813. + unsigned long flags = nd->intent.open.flags;
  6814. + nd->intent.open.file->private_data = (void *)flags;
  6815. + /* smp_mb(); */
  6816. + }
  6817. +}
  6818. +
  6819. +/* drop flags for writing */
  6820. +unsigned int au_file_roflags(unsigned int flags)
  6821. +{
  6822. + flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
  6823. + flags |= O_RDONLY | O_NOATIME;
  6824. + return flags;
  6825. +}
  6826. +
  6827. +/* common functions to regular file and dir */
  6828. +struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
  6829. + struct file *file)
  6830. +{
  6831. + struct file *h_file;
  6832. + struct dentry *h_dentry;
  6833. + struct inode *h_inode;
  6834. + struct super_block *sb;
  6835. + struct au_branch *br;
  6836. + int err;
  6837. +
  6838. + /* a race condition can happen between open and unlink/rmdir */
  6839. + h_file = ERR_PTR(-ENOENT);
  6840. + h_dentry = au_h_dptr(dentry, bindex);
  6841. + if (au_test_nfsd(current) && !h_dentry)
  6842. + goto out;
  6843. + h_inode = h_dentry->d_inode;
  6844. + if (au_test_nfsd(current) && !h_inode)
  6845. + goto out;
  6846. + if (unlikely((!d_unhashed(dentry) && d_unhashed(h_dentry))
  6847. + || !h_inode))
  6848. + goto out;
  6849. +
  6850. + sb = dentry->d_sb;
  6851. + br = au_sbr(sb, bindex);
  6852. + h_file = ERR_PTR(-EACCES);
  6853. + if (file && (file->f_mode & FMODE_EXEC)
  6854. + && (br->br_mnt->mnt_flags & MNT_NOEXEC))
  6855. + goto out;
  6856. +
  6857. + /* drop flags for writing */
  6858. + if (au_test_ro(sb, bindex, dentry->d_inode))
  6859. + flags = au_file_roflags(flags);
  6860. + flags &= ~O_CREAT;
  6861. + atomic_inc(&br->br_count);
  6862. + h_file = dentry_open(dget(h_dentry), mntget(br->br_mnt), flags,
  6863. + current_cred());
  6864. + if (IS_ERR(h_file))
  6865. + goto out_br;
  6866. +
  6867. + if (file && (file->f_mode & FMODE_EXEC)) {
  6868. + h_file->f_mode |= FMODE_EXEC;
  6869. + err = deny_write_access(h_file);
  6870. + if (unlikely(err)) {
  6871. + fput(h_file);
  6872. + h_file = ERR_PTR(err);
  6873. + goto out_br;
  6874. + }
  6875. + }
  6876. + fsnotify_open(h_dentry);
  6877. + goto out; /* success */
  6878. +
  6879. + out_br:
  6880. + atomic_dec(&br->br_count);
  6881. + out:
  6882. + return h_file;
  6883. +}
  6884. +
  6885. +int au_do_open(struct file *file, int (*open)(struct file *file, int flags))
  6886. +{
  6887. + int err;
  6888. + struct dentry *dentry;
  6889. + struct super_block *sb;
  6890. +
  6891. + dentry = file->f_dentry;
  6892. + sb = dentry->d_sb;
  6893. + si_read_lock(sb, AuLock_FLUSH);
  6894. + err = au_finfo_init(file);
  6895. + if (unlikely(err))
  6896. + goto out;
  6897. +
  6898. + di_read_lock_child(dentry, AuLock_IR);
  6899. + err = open(file, file->f_flags);
  6900. + di_read_unlock(dentry, AuLock_IR);
  6901. +
  6902. + fi_write_unlock(file);
  6903. + if (unlikely(err))
  6904. + au_finfo_fin(file);
  6905. + out:
  6906. + si_read_unlock(sb);
  6907. + return err;
  6908. +}
  6909. +
  6910. +int au_reopen_nondir(struct file *file)
  6911. +{
  6912. + int err;
  6913. + aufs_bindex_t bstart, bindex, bend;
  6914. + struct dentry *dentry;
  6915. + struct file *h_file, *h_file_tmp;
  6916. +
  6917. + dentry = file->f_dentry;
  6918. + bstart = au_dbstart(dentry);
  6919. + h_file_tmp = NULL;
  6920. + if (au_fbstart(file) == bstart) {
  6921. + h_file = au_h_fptr(file, bstart);
  6922. + if (file->f_mode == h_file->f_mode)
  6923. + return 0; /* success */
  6924. + h_file_tmp = h_file;
  6925. + get_file(h_file_tmp);
  6926. + au_set_h_fptr(file, bstart, NULL);
  6927. + }
  6928. + AuDebugOn(au_fbstart(file) < bstart
  6929. + || au_fi(file)->fi_hfile[0 + bstart].hf_file);
  6930. +
  6931. + h_file = au_h_open(dentry, bstart, file->f_flags & ~O_TRUNC, file);
  6932. + err = PTR_ERR(h_file);
  6933. + if (IS_ERR(h_file))
  6934. + goto out; /* todo: close all? */
  6935. +
  6936. + err = 0;
  6937. + au_set_fbstart(file, bstart);
  6938. + au_set_h_fptr(file, bstart, h_file);
  6939. + au_update_figen(file);
  6940. + /* todo: necessary? */
  6941. + /* file->f_ra = h_file->f_ra; */
  6942. +
  6943. + /* close lower files */
  6944. + bend = au_fbend(file);
  6945. + for (bindex = bstart + 1; bindex <= bend; bindex++)
  6946. + au_set_h_fptr(file, bindex, NULL);
  6947. + au_set_fbend(file, bstart);
  6948. +
  6949. + out:
  6950. + if (h_file_tmp)
  6951. + fput(h_file_tmp);
  6952. + return err;
  6953. +}
  6954. +
  6955. +/* ---------------------------------------------------------------------- */
  6956. +
  6957. +static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
  6958. + struct dentry *hi_wh)
  6959. +{
  6960. + int err;
  6961. + aufs_bindex_t bstart;
  6962. + struct au_dinfo *dinfo;
  6963. + struct dentry *h_dentry;
  6964. +
  6965. + dinfo = au_di(file->f_dentry);
  6966. + AuRwMustWriteLock(&dinfo->di_rwsem);
  6967. +
  6968. + bstart = dinfo->di_bstart;
  6969. + dinfo->di_bstart = btgt;
  6970. + h_dentry = dinfo->di_hdentry[0 + btgt].hd_dentry;
  6971. + dinfo->di_hdentry[0 + btgt].hd_dentry = hi_wh;
  6972. + err = au_reopen_nondir(file);
  6973. + dinfo->di_hdentry[0 + btgt].hd_dentry = h_dentry;
  6974. + dinfo->di_bstart = bstart;
  6975. +
  6976. + return err;
  6977. +}
  6978. +
  6979. +static int au_ready_to_write_wh(struct file *file, loff_t len,
  6980. + aufs_bindex_t bcpup)
  6981. +{
  6982. + int err;
  6983. + struct inode *inode;
  6984. + struct dentry *dentry, *hi_wh;
  6985. + struct super_block *sb;
  6986. +
  6987. + dentry = file->f_dentry;
  6988. + inode = dentry->d_inode;
  6989. + hi_wh = au_hi_wh(inode, bcpup);
  6990. + if (!hi_wh)
  6991. + err = au_sio_cpup_wh(dentry, bcpup, len, file);
  6992. + else
  6993. + /* already copied-up after unlink */
  6994. + err = au_reopen_wh(file, bcpup, hi_wh);
  6995. +
  6996. + sb = dentry->d_sb;
  6997. + if (!err && inode->i_nlink > 1 && au_opt_test(au_mntflags(sb), PLINK))
  6998. + au_plink_append(inode, bcpup, au_h_dptr(dentry, bcpup));
  6999. +
  7000. + return err;
  7001. +}
  7002. +
  7003. +/*
  7004. + * prepare the @file for writing.
  7005. + */
  7006. +int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
  7007. +{
  7008. + int err;
  7009. + aufs_bindex_t bstart, bcpup;
  7010. + struct dentry *dentry, *parent, *h_dentry;
  7011. + struct inode *h_inode, *inode;
  7012. + struct super_block *sb;
  7013. +
  7014. + dentry = file->f_dentry;
  7015. + sb = dentry->d_sb;
  7016. + bstart = au_fbstart(file);
  7017. + inode = dentry->d_inode;
  7018. + err = au_test_ro(sb, bstart, inode);
  7019. + if (!err && (au_h_fptr(file, bstart)->f_mode & FMODE_WRITE)) {
  7020. + err = au_pin(pin, dentry, bstart, AuOpt_UDBA_NONE, /*flags*/0);
  7021. + goto out;
  7022. + }
  7023. +
  7024. + /* need to cpup */
  7025. + parent = dget_parent(dentry);
  7026. + di_write_lock_parent(parent);
  7027. + err = AuWbrCopyup(au_sbi(sb), dentry);
  7028. + bcpup = err;
  7029. + if (unlikely(err < 0))
  7030. + goto out_dgrade;
  7031. + err = 0;
  7032. +
  7033. + if (!au_h_dptr(parent, bcpup)) {
  7034. + err = au_cpup_dirs(dentry, bcpup);
  7035. + if (unlikely(err))
  7036. + goto out_dgrade;
  7037. + }
  7038. +
  7039. + err = au_pin(pin, dentry, bcpup, AuOpt_UDBA_NONE,
  7040. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  7041. + if (unlikely(err))
  7042. + goto out_dgrade;
  7043. +
  7044. + h_dentry = au_h_fptr(file, bstart)->f_dentry;
  7045. + h_inode = h_dentry->d_inode;
  7046. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  7047. + if (d_unhashed(dentry) /* || d_unhashed(h_dentry) */
  7048. + /* || !h_inode->i_nlink */) {
  7049. + err = au_ready_to_write_wh(file, len, bcpup);
  7050. + di_downgrade_lock(parent, AuLock_IR);
  7051. + } else {
  7052. + di_downgrade_lock(parent, AuLock_IR);
  7053. + if (!au_h_dptr(dentry, bcpup))
  7054. + err = au_sio_cpup_simple(dentry, bcpup, len,
  7055. + AuCpup_DTIME);
  7056. + if (!err)
  7057. + err = au_reopen_nondir(file);
  7058. + }
  7059. + mutex_unlock(&h_inode->i_mutex);
  7060. +
  7061. + if (!err) {
  7062. + au_pin_set_parent_lflag(pin, /*lflag*/0);
  7063. + goto out_dput; /* success */
  7064. + }
  7065. + au_unpin(pin);
  7066. + goto out_unlock;
  7067. +
  7068. + out_dgrade:
  7069. + di_downgrade_lock(parent, AuLock_IR);
  7070. + out_unlock:
  7071. + di_read_unlock(parent, AuLock_IR);
  7072. + out_dput:
  7073. + dput(parent);
  7074. + out:
  7075. + return err;
  7076. +}
  7077. +
  7078. +/* ---------------------------------------------------------------------- */
  7079. +
  7080. +static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
  7081. +{
  7082. + int err;
  7083. + aufs_bindex_t bstart;
  7084. + struct au_pin pin;
  7085. + struct au_finfo *finfo;
  7086. + struct dentry *dentry, *parent, *hi_wh;
  7087. + struct inode *inode;
  7088. + struct super_block *sb;
  7089. +
  7090. + FiMustWriteLock(file);
  7091. +
  7092. + err = 0;
  7093. + finfo = au_fi(file);
  7094. + dentry = file->f_dentry;
  7095. + sb = dentry->d_sb;
  7096. + inode = dentry->d_inode;
  7097. + bstart = au_ibstart(inode);
  7098. + if (bstart == finfo->fi_bstart)
  7099. + goto out;
  7100. +
  7101. + parent = dget_parent(dentry);
  7102. + if (au_test_ro(sb, bstart, inode)) {
  7103. + di_read_lock_parent(parent, !AuLock_IR);
  7104. + err = AuWbrCopyup(au_sbi(sb), dentry);
  7105. + bstart = err;
  7106. + di_read_unlock(parent, !AuLock_IR);
  7107. + if (unlikely(err < 0))
  7108. + goto out_parent;
  7109. + err = 0;
  7110. + }
  7111. +
  7112. + di_read_lock_parent(parent, AuLock_IR);
  7113. + hi_wh = au_hi_wh(inode, bstart);
  7114. + if (au_opt_test(au_mntflags(sb), PLINK)
  7115. + && au_plink_test(inode)
  7116. + && !d_unhashed(dentry)) {
  7117. + err = au_test_and_cpup_dirs(dentry, bstart);
  7118. + if (unlikely(err))
  7119. + goto out_unlock;
  7120. +
  7121. + /* always superio. */
  7122. + err = au_pin(&pin, dentry, bstart, AuOpt_UDBA_NONE,
  7123. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  7124. + if (!err)
  7125. + err = au_sio_cpup_simple(dentry, bstart, -1,
  7126. + AuCpup_DTIME);
  7127. + au_unpin(&pin);
  7128. + } else if (hi_wh) {
  7129. + /* already copied-up after unlink */
  7130. + err = au_reopen_wh(file, bstart, hi_wh);
  7131. + *need_reopen = 0;
  7132. + }
  7133. +
  7134. + out_unlock:
  7135. + di_read_unlock(parent, AuLock_IR);
  7136. + out_parent:
  7137. + dput(parent);
  7138. + out:
  7139. + return err;
  7140. +}
  7141. +
  7142. +static void au_do_refresh_file(struct file *file)
  7143. +{
  7144. + aufs_bindex_t bindex, bend, new_bindex, brid;
  7145. + struct au_hfile *p, tmp, *q;
  7146. + struct au_finfo *finfo;
  7147. + struct super_block *sb;
  7148. +
  7149. + FiMustWriteLock(file);
  7150. +
  7151. + sb = file->f_dentry->d_sb;
  7152. + finfo = au_fi(file);
  7153. + p = finfo->fi_hfile + finfo->fi_bstart;
  7154. + brid = p->hf_br->br_id;
  7155. + bend = finfo->fi_bend;
  7156. + for (bindex = finfo->fi_bstart; bindex <= bend; bindex++, p++) {
  7157. + if (!p->hf_file)
  7158. + continue;
  7159. +
  7160. + new_bindex = au_br_index(sb, p->hf_br->br_id);
  7161. + if (new_bindex == bindex)
  7162. + continue;
  7163. + if (new_bindex < 0) {
  7164. + au_set_h_fptr(file, bindex, NULL);
  7165. + continue;
  7166. + }
  7167. +
  7168. + /* swap two lower inode, and loop again */
  7169. + q = finfo->fi_hfile + new_bindex;
  7170. + tmp = *q;
  7171. + *q = *p;
  7172. + *p = tmp;
  7173. + if (tmp.hf_file) {
  7174. + bindex--;
  7175. + p--;
  7176. + }
  7177. + }
  7178. +
  7179. + p = finfo->fi_hfile;
  7180. + if (!au_test_mmapped(file) && !d_unhashed(file->f_dentry)) {
  7181. + bend = au_sbend(sb);
  7182. + for (finfo->fi_bstart = 0; finfo->fi_bstart <= bend;
  7183. + finfo->fi_bstart++, p++)
  7184. + if (p->hf_file) {
  7185. + if (p->hf_file->f_dentry
  7186. + && p->hf_file->f_dentry->d_inode)
  7187. + break;
  7188. + else
  7189. + au_hfput(p, file);
  7190. + }
  7191. + } else {
  7192. + bend = au_br_index(sb, brid);
  7193. + for (finfo->fi_bstart = 0; finfo->fi_bstart < bend;
  7194. + finfo->fi_bstart++, p++)
  7195. + if (p->hf_file)
  7196. + au_hfput(p, file);
  7197. + bend = au_sbend(sb);
  7198. + }
  7199. +
  7200. + p = finfo->fi_hfile + bend;
  7201. + for (finfo->fi_bend = bend; finfo->fi_bend >= finfo->fi_bstart;
  7202. + finfo->fi_bend--, p--)
  7203. + if (p->hf_file) {
  7204. + if (p->hf_file->f_dentry
  7205. + && p->hf_file->f_dentry->d_inode)
  7206. + break;
  7207. + else
  7208. + au_hfput(p, file);
  7209. + }
  7210. + AuDebugOn(finfo->fi_bend < finfo->fi_bstart);
  7211. +}
  7212. +
  7213. +/*
  7214. + * after branch manipulating, refresh the file.
  7215. + */
  7216. +static int refresh_file(struct file *file, int (*reopen)(struct file *file))
  7217. +{
  7218. + int err, need_reopen;
  7219. + struct dentry *dentry;
  7220. + aufs_bindex_t bend, bindex;
  7221. +
  7222. + dentry = file->f_dentry;
  7223. + err = au_fi_realloc(au_fi(file), au_sbend(dentry->d_sb) + 1);
  7224. + if (unlikely(err))
  7225. + goto out;
  7226. + au_do_refresh_file(file);
  7227. +
  7228. + err = 0;
  7229. + need_reopen = 1;
  7230. + if (!au_test_mmapped(file))
  7231. + err = au_file_refresh_by_inode(file, &need_reopen);
  7232. + if (!err && need_reopen && !d_unhashed(dentry))
  7233. + err = reopen(file);
  7234. + if (!err) {
  7235. + au_update_figen(file);
  7236. + return 0; /* success */
  7237. + }
  7238. +
  7239. + /* error, close all lower files */
  7240. + bend = au_fbend(file);
  7241. + for (bindex = au_fbstart(file); bindex <= bend; bindex++)
  7242. + au_set_h_fptr(file, bindex, NULL);
  7243. +
  7244. + out:
  7245. + return err;
  7246. +}
  7247. +
  7248. +/* common function to regular file and dir */
  7249. +int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
  7250. + int wlock)
  7251. +{
  7252. + int err;
  7253. + unsigned int sigen, figen;
  7254. + aufs_bindex_t bstart;
  7255. + unsigned char pseudo_link;
  7256. + struct dentry *dentry;
  7257. +
  7258. + err = 0;
  7259. + dentry = file->f_dentry;
  7260. + sigen = au_sigen(dentry->d_sb);
  7261. + fi_write_lock(file);
  7262. + figen = au_figen(file);
  7263. + di_write_lock_child(dentry);
  7264. + bstart = au_dbstart(dentry);
  7265. + pseudo_link = (bstart != au_ibstart(dentry->d_inode));
  7266. + if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) {
  7267. + if (!wlock) {
  7268. + di_downgrade_lock(dentry, AuLock_IR);
  7269. + fi_downgrade_lock(file);
  7270. + }
  7271. + goto out; /* success */
  7272. + }
  7273. +
  7274. + AuDbg("sigen %d, figen %d\n", sigen, figen);
  7275. + if (sigen != au_digen(dentry)
  7276. + || sigen != au_iigen(dentry->d_inode)) {
  7277. + err = au_reval_dpath(dentry, sigen);
  7278. + if (unlikely(err < 0))
  7279. + goto out;
  7280. + AuDebugOn(au_digen(dentry) != sigen
  7281. + || au_iigen(dentry->d_inode) != sigen);
  7282. + }
  7283. +
  7284. + err = refresh_file(file, reopen);
  7285. + if (!err) {
  7286. + if (!wlock) {
  7287. + di_downgrade_lock(dentry, AuLock_IR);
  7288. + fi_downgrade_lock(file);
  7289. + }
  7290. + } else {
  7291. + di_write_unlock(dentry);
  7292. + fi_write_unlock(file);
  7293. + }
  7294. +
  7295. + out:
  7296. + return err;
  7297. +}
  7298. +
  7299. +/* ---------------------------------------------------------------------- */
  7300. +
  7301. +/* cf. aufs_nopage() */
  7302. +/* for madvise(2) */
  7303. +static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
  7304. +{
  7305. + unlock_page(page);
  7306. + return 0;
  7307. +}
  7308. +
  7309. +/* they will never be called. */
  7310. +#ifdef CONFIG_AUFS_DEBUG
  7311. +static int aufs_write_begin(struct file *file, struct address_space *mapping,
  7312. + loff_t pos, unsigned len, unsigned flags,
  7313. + struct page **pagep, void **fsdata)
  7314. +{ AuUnsupport(); return 0; }
  7315. +static int aufs_write_end(struct file *file, struct address_space *mapping,
  7316. + loff_t pos, unsigned len, unsigned copied,
  7317. + struct page *page, void *fsdata)
  7318. +{ AuUnsupport(); return 0; }
  7319. +static int aufs_writepage(struct page *page, struct writeback_control *wbc)
  7320. +{ AuUnsupport(); return 0; }
  7321. +static void aufs_sync_page(struct page *page)
  7322. +{ AuUnsupport(); }
  7323. +
  7324. +static int aufs_set_page_dirty(struct page *page)
  7325. +{ AuUnsupport(); return 0; }
  7326. +static void aufs_invalidatepage(struct page *page, unsigned long offset)
  7327. +{ AuUnsupport(); }
  7328. +static int aufs_releasepage(struct page *page, gfp_t gfp)
  7329. +{ AuUnsupport(); return 0; }
  7330. +static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb,
  7331. + const struct iovec *iov, loff_t offset,
  7332. + unsigned long nr_segs)
  7333. +{ AuUnsupport(); return 0; }
  7334. +#endif /* CONFIG_AUFS_DEBUG */
  7335. +
  7336. +struct address_space_operations aufs_aop = {
  7337. + .readpage = aufs_readpage,
  7338. +#ifdef CONFIG_AUFS_DEBUG
  7339. + .writepage = aufs_writepage,
  7340. + .sync_page = aufs_sync_page,
  7341. + .set_page_dirty = aufs_set_page_dirty,
  7342. + .write_begin = aufs_write_begin,
  7343. + .write_end = aufs_write_end,
  7344. + .invalidatepage = aufs_invalidatepage,
  7345. + .releasepage = aufs_releasepage,
  7346. + .direct_IO = aufs_direct_IO,
  7347. +#endif /* CONFIG_AUFS_DEBUG */
  7348. +};
  7349. diff -Nur linux-2.6.34.orig/fs/aufs/file.h linux-2.6.34/fs/aufs/file.h
  7350. --- linux-2.6.34.orig/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100
  7351. +++ linux-2.6.34/fs/aufs/file.h 2010-05-23 23:33:20.070971333 +0200
  7352. @@ -0,0 +1,175 @@
  7353. +/*
  7354. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  7355. + *
  7356. + * This program, aufs is free software; you can redistribute it and/or modify
  7357. + * it under the terms of the GNU General Public License as published by
  7358. + * the Free Software Foundation; either version 2 of the License, or
  7359. + * (at your option) any later version.
  7360. + *
  7361. + * This program is distributed in the hope that it will be useful,
  7362. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7363. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  7364. + * GNU General Public License for more details.
  7365. + *
  7366. + * You should have received a copy of the GNU General Public License
  7367. + * along with this program; if not, write to the Free Software
  7368. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  7369. + */
  7370. +
  7371. +/*
  7372. + * file operations
  7373. + */
  7374. +
  7375. +#ifndef __AUFS_FILE_H__
  7376. +#define __AUFS_FILE_H__
  7377. +
  7378. +#ifdef __KERNEL__
  7379. +
  7380. +#include <linux/fs.h>
  7381. +#include <linux/poll.h>
  7382. +#include <linux/aufs_type.h>
  7383. +#include "rwsem.h"
  7384. +
  7385. +struct au_branch;
  7386. +struct au_hfile {
  7387. + struct file *hf_file;
  7388. + struct au_branch *hf_br;
  7389. +};
  7390. +
  7391. +struct au_vdir;
  7392. +struct au_finfo {
  7393. + atomic_t fi_generation;
  7394. +
  7395. + struct au_rwsem fi_rwsem;
  7396. + struct au_hfile *fi_hfile;
  7397. + aufs_bindex_t fi_bstart, fi_bend;
  7398. +
  7399. + union {
  7400. + /* non-dir only */
  7401. + struct {
  7402. + struct vm_operations_struct *fi_h_vm_ops;
  7403. + struct vm_operations_struct *fi_vm_ops;
  7404. + };
  7405. +
  7406. + /* dir only */
  7407. + struct {
  7408. + struct au_vdir *fi_vdir_cache;
  7409. + int fi_maintain_plink;
  7410. + };
  7411. + };
  7412. +};
  7413. +
  7414. +/* ---------------------------------------------------------------------- */
  7415. +
  7416. +/* file.c */
  7417. +extern struct address_space_operations aufs_aop;
  7418. +void au_store_oflag(struct nameidata *nd, struct inode *inode);
  7419. +unsigned int au_file_roflags(unsigned int flags);
  7420. +struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
  7421. + struct file *file);
  7422. +int au_do_open(struct file *file, int (*open)(struct file *file, int flags));
  7423. +int au_reopen_nondir(struct file *file);
  7424. +struct au_pin;
  7425. +int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
  7426. +int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
  7427. + int wlock);
  7428. +
  7429. +/* poll.c */
  7430. +#ifdef CONFIG_AUFS_POLL
  7431. +unsigned int aufs_poll(struct file *file, poll_table *wait);
  7432. +#endif
  7433. +
  7434. +/* f_op.c */
  7435. +extern const struct file_operations aufs_file_fop;
  7436. +int aufs_flush(struct file *file, fl_owner_t id);
  7437. +
  7438. +/* finfo.c */
  7439. +void au_hfput(struct au_hfile *hf, struct file *file);
  7440. +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
  7441. + struct file *h_file);
  7442. +
  7443. +void au_update_figen(struct file *file);
  7444. +
  7445. +void au_finfo_fin(struct file *file);
  7446. +int au_finfo_init(struct file *file);
  7447. +int au_fi_realloc(struct au_finfo *finfo, int nbr);
  7448. +
  7449. +/* ---------------------------------------------------------------------- */
  7450. +
  7451. +static inline struct au_finfo *au_fi(struct file *file)
  7452. +{
  7453. + return file->private_data;
  7454. +}
  7455. +
  7456. +/* ---------------------------------------------------------------------- */
  7457. +
  7458. +/*
  7459. + * fi_read_lock, fi_write_lock,
  7460. + * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
  7461. + */
  7462. +AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
  7463. +
  7464. +#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
  7465. +#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
  7466. +#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
  7467. +
  7468. +/* ---------------------------------------------------------------------- */
  7469. +
  7470. +/* todo: hard/soft set? */
  7471. +static inline aufs_bindex_t au_fbstart(struct file *file)
  7472. +{
  7473. + FiMustAnyLock(file);
  7474. + return au_fi(file)->fi_bstart;
  7475. +}
  7476. +
  7477. +static inline aufs_bindex_t au_fbend(struct file *file)
  7478. +{
  7479. + FiMustAnyLock(file);
  7480. + return au_fi(file)->fi_bend;
  7481. +}
  7482. +
  7483. +static inline struct au_vdir *au_fvdir_cache(struct file *file)
  7484. +{
  7485. + FiMustAnyLock(file);
  7486. + return au_fi(file)->fi_vdir_cache;
  7487. +}
  7488. +
  7489. +static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex)
  7490. +{
  7491. + FiMustWriteLock(file);
  7492. + au_fi(file)->fi_bstart = bindex;
  7493. +}
  7494. +
  7495. +static inline void au_set_fbend(struct file *file, aufs_bindex_t bindex)
  7496. +{
  7497. + FiMustWriteLock(file);
  7498. + au_fi(file)->fi_bend = bindex;
  7499. +}
  7500. +
  7501. +static inline void au_set_fvdir_cache(struct file *file,
  7502. + struct au_vdir *vdir_cache)
  7503. +{
  7504. + FiMustWriteLock(file);
  7505. + au_fi(file)->fi_vdir_cache = vdir_cache;
  7506. +}
  7507. +
  7508. +static inline struct file *au_h_fptr(struct file *file, aufs_bindex_t bindex)
  7509. +{
  7510. + FiMustAnyLock(file);
  7511. + return au_fi(file)->fi_hfile[0 + bindex].hf_file;
  7512. +}
  7513. +
  7514. +/* todo: memory barrier? */
  7515. +static inline unsigned int au_figen(struct file *f)
  7516. +{
  7517. + return atomic_read(&au_fi(f)->fi_generation);
  7518. +}
  7519. +
  7520. +static inline int au_test_mmapped(struct file *f)
  7521. +{
  7522. + FiMustAnyLock(f);
  7523. + return !!(au_fi(f)->fi_h_vm_ops);
  7524. +}
  7525. +
  7526. +#endif /* __KERNEL__ */
  7527. +#endif /* __AUFS_FILE_H__ */
  7528. diff -Nur linux-2.6.34.orig/fs/aufs/finfo.c linux-2.6.34/fs/aufs/finfo.c
  7529. --- linux-2.6.34.orig/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100
  7530. +++ linux-2.6.34/fs/aufs/finfo.c 2010-05-23 23:33:20.161805224 +0200
  7531. @@ -0,0 +1,133 @@
  7532. +/*
  7533. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  7534. + *
  7535. + * This program, aufs is free software; you can redistribute it and/or modify
  7536. + * it under the terms of the GNU General Public License as published by
  7537. + * the Free Software Foundation; either version 2 of the License, or
  7538. + * (at your option) any later version.
  7539. + *
  7540. + * This program is distributed in the hope that it will be useful,
  7541. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7542. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  7543. + * GNU General Public License for more details.
  7544. + *
  7545. + * You should have received a copy of the GNU General Public License
  7546. + * along with this program; if not, write to the Free Software
  7547. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  7548. + */
  7549. +
  7550. +/*
  7551. + * file private data
  7552. + */
  7553. +
  7554. +#include <linux/file.h>
  7555. +#include "aufs.h"
  7556. +
  7557. +void au_hfput(struct au_hfile *hf, struct file *file)
  7558. +{
  7559. + if (file->f_mode & FMODE_EXEC)
  7560. + allow_write_access(hf->hf_file);
  7561. + fput(hf->hf_file);
  7562. + hf->hf_file = NULL;
  7563. + atomic_dec_return(&hf->hf_br->br_count);
  7564. + hf->hf_br = NULL;
  7565. +}
  7566. +
  7567. +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
  7568. +{
  7569. + struct au_finfo *finfo = au_fi(file);
  7570. + struct au_hfile *hf;
  7571. +
  7572. + hf = finfo->fi_hfile + bindex;
  7573. + if (hf->hf_file)
  7574. + au_hfput(hf, file);
  7575. + if (val) {
  7576. + hf->hf_file = val;
  7577. + hf->hf_br = au_sbr(file->f_dentry->d_sb, bindex);
  7578. + }
  7579. +}
  7580. +
  7581. +void au_update_figen(struct file *file)
  7582. +{
  7583. + atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_dentry));
  7584. + /* smp_mb(); */ /* atomic_set */
  7585. +}
  7586. +
  7587. +/* ---------------------------------------------------------------------- */
  7588. +
  7589. +void au_finfo_fin(struct file *file)
  7590. +{
  7591. + struct au_finfo *finfo;
  7592. + aufs_bindex_t bindex, bend;
  7593. +
  7594. + fi_write_lock(file);
  7595. + bend = au_fbend(file);
  7596. + bindex = au_fbstart(file);
  7597. + if (bindex >= 0)
  7598. + /*
  7599. + * calls fput() instead of filp_close(),
  7600. + * since no dnotify or lock for the lower file.
  7601. + */
  7602. + for (; bindex <= bend; bindex++)
  7603. + au_set_h_fptr(file, bindex, NULL);
  7604. +
  7605. + finfo = au_fi(file);
  7606. + au_dbg_verify_hf(finfo);
  7607. + kfree(finfo->fi_hfile);
  7608. + fi_write_unlock(file);
  7609. + AuRwDestroy(&finfo->fi_rwsem);
  7610. + au_cache_free_finfo(finfo);
  7611. +}
  7612. +
  7613. +int au_finfo_init(struct file *file)
  7614. +{
  7615. + struct au_finfo *finfo;
  7616. + struct dentry *dentry;
  7617. + unsigned long ul;
  7618. +
  7619. + dentry = file->f_dentry;
  7620. + finfo = au_cache_alloc_finfo();
  7621. + if (unlikely(!finfo))
  7622. + goto out;
  7623. +
  7624. + finfo->fi_hfile = kcalloc(au_sbend(dentry->d_sb) + 1,
  7625. + sizeof(*finfo->fi_hfile), GFP_NOFS);
  7626. + if (unlikely(!finfo->fi_hfile))
  7627. + goto out_finfo;
  7628. +
  7629. + au_rw_init_wlock(&finfo->fi_rwsem);
  7630. + finfo->fi_bstart = -1;
  7631. + finfo->fi_bend = -1;
  7632. + atomic_set(&finfo->fi_generation, au_digen(dentry));
  7633. + /* smp_mb(); */ /* atomic_set */
  7634. +
  7635. + /* cf. au_store_oflag() */
  7636. + /* suppress a warning in lp64 */
  7637. + ul = (unsigned long)file->private_data;
  7638. + file->f_mode |= (vfsub_uint_to_fmode(ul) & FMODE_EXEC);
  7639. + file->private_data = finfo;
  7640. + return 0; /* success */
  7641. +
  7642. + out_finfo:
  7643. + au_cache_free_finfo(finfo);
  7644. + out:
  7645. + return -ENOMEM;
  7646. +}
  7647. +
  7648. +int au_fi_realloc(struct au_finfo *finfo, int nbr)
  7649. +{
  7650. + int err, sz;
  7651. + struct au_hfile *hfp;
  7652. +
  7653. + err = -ENOMEM;
  7654. + sz = sizeof(*hfp) * (finfo->fi_bend + 1);
  7655. + if (!sz)
  7656. + sz = sizeof(*hfp);
  7657. + hfp = au_kzrealloc(finfo->fi_hfile, sz, sizeof(*hfp) * nbr, GFP_NOFS);
  7658. + if (hfp) {
  7659. + finfo->fi_hfile = hfp;
  7660. + err = 0;
  7661. + }
  7662. +
  7663. + return err;
  7664. +}
  7665. diff -Nur linux-2.6.34.orig/fs/aufs/f_op.c linux-2.6.34/fs/aufs/f_op.c
  7666. --- linux-2.6.34.orig/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100
  7667. +++ linux-2.6.34/fs/aufs/f_op.c 2010-05-23 23:33:20.203473018 +0200
  7668. @@ -0,0 +1,802 @@
  7669. +/*
  7670. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  7671. + *
  7672. + * This program, aufs is free software; you can redistribute it and/or modify
  7673. + * it under the terms of the GNU General Public License as published by
  7674. + * the Free Software Foundation; either version 2 of the License, or
  7675. + * (at your option) any later version.
  7676. + *
  7677. + * This program is distributed in the hope that it will be useful,
  7678. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7679. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  7680. + * GNU General Public License for more details.
  7681. + *
  7682. + * You should have received a copy of the GNU General Public License
  7683. + * along with this program; if not, write to the Free Software
  7684. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  7685. + */
  7686. +
  7687. +/*
  7688. + * file and vm operations
  7689. + */
  7690. +
  7691. +#include <linux/file.h>
  7692. +#include <linux/fs_stack.h>
  7693. +#include <linux/mm.h>
  7694. +#include <linux/security.h>
  7695. +#include "aufs.h"
  7696. +
  7697. +/* common function to regular file and dir */
  7698. +int aufs_flush(struct file *file, fl_owner_t id)
  7699. +{
  7700. + int err;
  7701. + aufs_bindex_t bindex, bend;
  7702. + struct dentry *dentry;
  7703. + struct file *h_file;
  7704. +
  7705. + dentry = file->f_dentry;
  7706. + si_noflush_read_lock(dentry->d_sb);
  7707. + fi_read_lock(file);
  7708. + di_read_lock_child(dentry, AuLock_IW);
  7709. +
  7710. + err = 0;
  7711. + bend = au_fbend(file);
  7712. + for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
  7713. + h_file = au_h_fptr(file, bindex);
  7714. + if (!h_file || !h_file->f_op || !h_file->f_op->flush)
  7715. + continue;
  7716. +
  7717. + err = h_file->f_op->flush(h_file, id);
  7718. + if (!err)
  7719. + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
  7720. + /*ignore*/
  7721. + }
  7722. + au_cpup_attr_timesizes(dentry->d_inode);
  7723. +
  7724. + di_read_unlock(dentry, AuLock_IW);
  7725. + fi_read_unlock(file);
  7726. + si_read_unlock(dentry->d_sb);
  7727. + return err;
  7728. +}
  7729. +
  7730. +/* ---------------------------------------------------------------------- */
  7731. +
  7732. +static int do_open_nondir(struct file *file, int flags)
  7733. +{
  7734. + int err;
  7735. + aufs_bindex_t bindex;
  7736. + struct file *h_file;
  7737. + struct dentry *dentry;
  7738. + struct au_finfo *finfo;
  7739. +
  7740. + FiMustWriteLock(file);
  7741. +
  7742. + err = 0;
  7743. + dentry = file->f_dentry;
  7744. + finfo = au_fi(file);
  7745. + finfo->fi_h_vm_ops = NULL;
  7746. + finfo->fi_vm_ops = NULL;
  7747. + bindex = au_dbstart(dentry);
  7748. + /* O_TRUNC is processed already */
  7749. + BUG_ON(au_test_ro(dentry->d_sb, bindex, dentry->d_inode)
  7750. + && (flags & O_TRUNC));
  7751. +
  7752. + h_file = au_h_open(dentry, bindex, flags, file);
  7753. + if (IS_ERR(h_file))
  7754. + err = PTR_ERR(h_file);
  7755. + else {
  7756. + au_set_fbstart(file, bindex);
  7757. + au_set_fbend(file, bindex);
  7758. + au_set_h_fptr(file, bindex, h_file);
  7759. + au_update_figen(file);
  7760. + /* todo: necessary? */
  7761. + /* file->f_ra = h_file->f_ra; */
  7762. + }
  7763. + return err;
  7764. +}
  7765. +
  7766. +static int aufs_open_nondir(struct inode *inode __maybe_unused,
  7767. + struct file *file)
  7768. +{
  7769. + return au_do_open(file, do_open_nondir);
  7770. +}
  7771. +
  7772. +static int aufs_release_nondir(struct inode *inode __maybe_unused,
  7773. + struct file *file)
  7774. +{
  7775. + struct super_block *sb = file->f_dentry->d_sb;
  7776. +
  7777. + si_noflush_read_lock(sb);
  7778. + kfree(au_fi(file)->fi_vm_ops);
  7779. + au_finfo_fin(file);
  7780. + si_read_unlock(sb);
  7781. + return 0;
  7782. +}
  7783. +
  7784. +/* ---------------------------------------------------------------------- */
  7785. +
  7786. +static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
  7787. + loff_t *ppos)
  7788. +{
  7789. + ssize_t err;
  7790. + struct dentry *dentry;
  7791. + struct file *h_file;
  7792. + struct super_block *sb;
  7793. +
  7794. + dentry = file->f_dentry;
  7795. + sb = dentry->d_sb;
  7796. + si_read_lock(sb, AuLock_FLUSH);
  7797. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
  7798. + if (unlikely(err))
  7799. + goto out;
  7800. +
  7801. + h_file = au_h_fptr(file, au_fbstart(file));
  7802. + err = vfsub_read_u(h_file, buf, count, ppos);
  7803. + /* todo: necessary? */
  7804. + /* file->f_ra = h_file->f_ra; */
  7805. + fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
  7806. +
  7807. + di_read_unlock(dentry, AuLock_IR);
  7808. + fi_read_unlock(file);
  7809. + out:
  7810. + si_read_unlock(sb);
  7811. + return err;
  7812. +}
  7813. +
  7814. +static ssize_t aufs_write(struct file *file, const char __user *ubuf,
  7815. + size_t count, loff_t *ppos)
  7816. +{
  7817. + ssize_t err;
  7818. + aufs_bindex_t bstart;
  7819. + struct au_pin pin;
  7820. + struct dentry *dentry;
  7821. + struct inode *inode;
  7822. + struct super_block *sb;
  7823. + struct file *h_file;
  7824. + char __user *buf = (char __user *)ubuf;
  7825. +
  7826. + dentry = file->f_dentry;
  7827. + sb = dentry->d_sb;
  7828. + inode = dentry->d_inode;
  7829. + mutex_lock(&inode->i_mutex);
  7830. + si_read_lock(sb, AuLock_FLUSH);
  7831. +
  7832. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  7833. + if (unlikely(err))
  7834. + goto out;
  7835. +
  7836. + err = au_ready_to_write(file, -1, &pin);
  7837. + di_downgrade_lock(dentry, AuLock_IR);
  7838. + if (unlikely(err))
  7839. + goto out_unlock;
  7840. +
  7841. + bstart = au_fbstart(file);
  7842. + h_file = au_h_fptr(file, bstart);
  7843. + au_unpin(&pin);
  7844. + err = vfsub_write_u(h_file, buf, count, ppos);
  7845. + au_cpup_attr_timesizes(inode);
  7846. + inode->i_mode = h_file->f_dentry->d_inode->i_mode;
  7847. +
  7848. + out_unlock:
  7849. + di_read_unlock(dentry, AuLock_IR);
  7850. + fi_write_unlock(file);
  7851. + out:
  7852. + si_read_unlock(sb);
  7853. + mutex_unlock(&inode->i_mutex);
  7854. + return err;
  7855. +}
  7856. +
  7857. +static ssize_t aufs_aio_read(struct kiocb *kio, const struct iovec *iov,
  7858. + unsigned long nv, loff_t pos)
  7859. +{
  7860. + ssize_t err;
  7861. + struct file *file, *h_file;
  7862. + struct dentry *dentry;
  7863. + struct super_block *sb;
  7864. +
  7865. + file = kio->ki_filp;
  7866. + dentry = file->f_dentry;
  7867. + sb = dentry->d_sb;
  7868. + si_read_lock(sb, AuLock_FLUSH);
  7869. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
  7870. + if (unlikely(err))
  7871. + goto out;
  7872. +
  7873. + err = -ENOSYS;
  7874. + h_file = au_h_fptr(file, au_fbstart(file));
  7875. + if (h_file->f_op && h_file->f_op->aio_read) {
  7876. + err = security_file_permission(h_file, MAY_READ);
  7877. + if (unlikely(err))
  7878. + goto out_unlock;
  7879. + if (!is_sync_kiocb(kio)) {
  7880. + get_file(h_file);
  7881. + fput(file);
  7882. + }
  7883. + kio->ki_filp = h_file;
  7884. + err = h_file->f_op->aio_read(kio, iov, nv, pos);
  7885. + /* todo: necessary? */
  7886. + /* file->f_ra = h_file->f_ra; */
  7887. + fsstack_copy_attr_atime(dentry->d_inode,
  7888. + h_file->f_dentry->d_inode);
  7889. + } else
  7890. + /* currently there is no such fs */
  7891. + WARN_ON_ONCE(h_file->f_op && h_file->f_op->read);
  7892. +
  7893. + out_unlock:
  7894. + di_read_unlock(dentry, AuLock_IR);
  7895. + fi_read_unlock(file);
  7896. + out:
  7897. + si_read_unlock(sb);
  7898. + return err;
  7899. +}
  7900. +
  7901. +static ssize_t aufs_aio_write(struct kiocb *kio, const struct iovec *iov,
  7902. + unsigned long nv, loff_t pos)
  7903. +{
  7904. + ssize_t err;
  7905. + aufs_bindex_t bstart;
  7906. + struct au_pin pin;
  7907. + struct dentry *dentry;
  7908. + struct inode *inode;
  7909. + struct super_block *sb;
  7910. + struct file *file, *h_file;
  7911. +
  7912. + file = kio->ki_filp;
  7913. + dentry = file->f_dentry;
  7914. + sb = dentry->d_sb;
  7915. + inode = dentry->d_inode;
  7916. + mutex_lock(&inode->i_mutex);
  7917. + si_read_lock(sb, AuLock_FLUSH);
  7918. +
  7919. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  7920. + if (unlikely(err))
  7921. + goto out;
  7922. +
  7923. + err = au_ready_to_write(file, -1, &pin);
  7924. + di_downgrade_lock(dentry, AuLock_IR);
  7925. + if (unlikely(err))
  7926. + goto out_unlock;
  7927. +
  7928. + err = -ENOSYS;
  7929. + bstart = au_fbstart(file);
  7930. + h_file = au_h_fptr(file, bstart);
  7931. + au_unpin(&pin);
  7932. + if (h_file->f_op && h_file->f_op->aio_write) {
  7933. + err = security_file_permission(h_file, MAY_WRITE);
  7934. + if (unlikely(err))
  7935. + goto out_unlock;
  7936. + if (!is_sync_kiocb(kio)) {
  7937. + get_file(h_file);
  7938. + fput(file);
  7939. + }
  7940. + kio->ki_filp = h_file;
  7941. + err = h_file->f_op->aio_write(kio, iov, nv, pos);
  7942. + au_cpup_attr_timesizes(inode);
  7943. + inode->i_mode = h_file->f_dentry->d_inode->i_mode;
  7944. + } else
  7945. + /* currently there is no such fs */
  7946. + WARN_ON_ONCE(h_file->f_op && h_file->f_op->write);
  7947. +
  7948. + out_unlock:
  7949. + di_read_unlock(dentry, AuLock_IR);
  7950. + fi_write_unlock(file);
  7951. + out:
  7952. + si_read_unlock(sb);
  7953. + mutex_unlock(&inode->i_mutex);
  7954. + return err;
  7955. +}
  7956. +
  7957. +static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
  7958. + struct pipe_inode_info *pipe, size_t len,
  7959. + unsigned int flags)
  7960. +{
  7961. + ssize_t err;
  7962. + struct file *h_file;
  7963. + struct dentry *dentry;
  7964. + struct super_block *sb;
  7965. +
  7966. + dentry = file->f_dentry;
  7967. + sb = dentry->d_sb;
  7968. + si_read_lock(sb, AuLock_FLUSH);
  7969. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
  7970. + if (unlikely(err))
  7971. + goto out;
  7972. +
  7973. + err = -EINVAL;
  7974. + h_file = au_h_fptr(file, au_fbstart(file));
  7975. + if (au_test_loopback_kthread()) {
  7976. + file->f_mapping = h_file->f_mapping;
  7977. + smp_mb(); /* unnecessary? */
  7978. + }
  7979. + err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
  7980. + /* todo: necessasry? */
  7981. + /* file->f_ra = h_file->f_ra; */
  7982. + fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
  7983. +
  7984. + di_read_unlock(dentry, AuLock_IR);
  7985. + fi_read_unlock(file);
  7986. +
  7987. + out:
  7988. + si_read_unlock(sb);
  7989. + return err;
  7990. +}
  7991. +
  7992. +static ssize_t
  7993. +aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
  7994. + size_t len, unsigned int flags)
  7995. +{
  7996. + ssize_t err;
  7997. + struct au_pin pin;
  7998. + struct dentry *dentry;
  7999. + struct inode *inode;
  8000. + struct super_block *sb;
  8001. + struct file *h_file;
  8002. +
  8003. + dentry = file->f_dentry;
  8004. + inode = dentry->d_inode;
  8005. + mutex_lock(&inode->i_mutex);
  8006. + sb = dentry->d_sb;
  8007. + si_read_lock(sb, AuLock_FLUSH);
  8008. +
  8009. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  8010. + if (unlikely(err))
  8011. + goto out;
  8012. +
  8013. + err = au_ready_to_write(file, -1, &pin);
  8014. + di_downgrade_lock(dentry, AuLock_IR);
  8015. + if (unlikely(err))
  8016. + goto out_unlock;
  8017. +
  8018. + h_file = au_h_fptr(file, au_fbstart(file));
  8019. + au_unpin(&pin);
  8020. + err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
  8021. + au_cpup_attr_timesizes(inode);
  8022. + inode->i_mode = h_file->f_dentry->d_inode->i_mode;
  8023. +
  8024. + out_unlock:
  8025. + di_read_unlock(dentry, AuLock_IR);
  8026. + fi_write_unlock(file);
  8027. + out:
  8028. + si_read_unlock(sb);
  8029. + mutex_unlock(&inode->i_mutex);
  8030. + return err;
  8031. +}
  8032. +
  8033. +/* ---------------------------------------------------------------------- */
  8034. +
  8035. +static struct file *au_safe_file(struct vm_area_struct *vma)
  8036. +{
  8037. + struct file *file;
  8038. +
  8039. + file = vma->vm_file;
  8040. + if (file->private_data && au_test_aufs(file->f_dentry->d_sb))
  8041. + return file;
  8042. + return NULL;
  8043. +}
  8044. +
  8045. +static void au_reset_file(struct vm_area_struct *vma, struct file *file)
  8046. +{
  8047. + vma->vm_file = file;
  8048. + /* smp_mb(); */ /* flush vm_file */
  8049. +}
  8050. +
  8051. +static int aufs_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
  8052. +{
  8053. + int err;
  8054. + static DECLARE_WAIT_QUEUE_HEAD(wq);
  8055. + struct file *file, *h_file;
  8056. + struct au_finfo *finfo;
  8057. +
  8058. + /* todo: non-robr mode, user vm_file as it is? */
  8059. + wait_event(wq, (file = au_safe_file(vma)));
  8060. +
  8061. + /* do not revalidate, no si lock */
  8062. + finfo = au_fi(file);
  8063. + h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file;
  8064. + AuDebugOn(!h_file || !finfo->fi_h_vm_ops);
  8065. +
  8066. + fi_write_lock(file);
  8067. + vma->vm_file = h_file;
  8068. + err = finfo->fi_h_vm_ops->fault(vma, vmf);
  8069. + /* todo: necessary? */
  8070. + /* file->f_ra = h_file->f_ra; */
  8071. + au_reset_file(vma, file);
  8072. + fi_write_unlock(file);
  8073. +#if 0 /* def CONFIG_SMP */
  8074. + /* wake_up_nr(&wq, online_cpu - 1); */
  8075. + wake_up_all(&wq);
  8076. +#else
  8077. + wake_up(&wq);
  8078. +#endif
  8079. +
  8080. + return err;
  8081. +}
  8082. +
  8083. +static int aufs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
  8084. +{
  8085. + int err;
  8086. + static DECLARE_WAIT_QUEUE_HEAD(wq);
  8087. + struct file *file, *h_file;
  8088. + struct au_finfo *finfo;
  8089. +
  8090. + wait_event(wq, (file = au_safe_file(vma)));
  8091. +
  8092. + finfo = au_fi(file);
  8093. + h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file;
  8094. + AuDebugOn(!h_file || !finfo->fi_h_vm_ops);
  8095. +
  8096. + fi_write_lock(file);
  8097. + vma->vm_file = h_file;
  8098. + err = finfo->fi_h_vm_ops->page_mkwrite(vma, vmf);
  8099. + au_reset_file(vma, file);
  8100. + fi_write_unlock(file);
  8101. + wake_up(&wq);
  8102. +
  8103. + return err;
  8104. +}
  8105. +
  8106. +static void aufs_vm_close(struct vm_area_struct *vma)
  8107. +{
  8108. + static DECLARE_WAIT_QUEUE_HEAD(wq);
  8109. + struct file *file, *h_file;
  8110. + struct au_finfo *finfo;
  8111. +
  8112. + wait_event(wq, (file = au_safe_file(vma)));
  8113. +
  8114. + finfo = au_fi(file);
  8115. + h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file;
  8116. + AuDebugOn(!h_file || !finfo->fi_h_vm_ops);
  8117. +
  8118. + fi_write_lock(file);
  8119. + vma->vm_file = h_file;
  8120. + finfo->fi_h_vm_ops->close(vma);
  8121. + au_reset_file(vma, file);
  8122. + fi_write_unlock(file);
  8123. + wake_up(&wq);
  8124. +}
  8125. +
  8126. +static struct vm_operations_struct aufs_vm_ops = {
  8127. + /* .close and .page_mkwrite are not set by default */
  8128. + .fault = aufs_fault,
  8129. +};
  8130. +
  8131. +/* ---------------------------------------------------------------------- */
  8132. +
  8133. +static struct vm_operations_struct *au_vm_ops(struct file *h_file,
  8134. + struct vm_area_struct *vma)
  8135. +{
  8136. + struct vm_operations_struct *vm_ops;
  8137. + int err;
  8138. +
  8139. + vm_ops = ERR_PTR(-ENODEV);
  8140. + if (!h_file->f_op || !h_file->f_op->mmap)
  8141. + goto out;
  8142. +
  8143. + err = h_file->f_op->mmap(h_file, vma);
  8144. + vm_ops = ERR_PTR(err);
  8145. + if (unlikely(err))
  8146. + goto out;
  8147. +
  8148. + vm_ops = vma->vm_ops;
  8149. + err = do_munmap(current->mm, vma->vm_start,
  8150. + vma->vm_end - vma->vm_start);
  8151. + if (unlikely(err)) {
  8152. + AuIOErr("failed internal unmapping %.*s, %d\n",
  8153. + AuDLNPair(h_file->f_dentry), err);
  8154. + vm_ops = ERR_PTR(-EIO);
  8155. + }
  8156. +
  8157. + out:
  8158. + return vm_ops;
  8159. +}
  8160. +
  8161. +static int au_custom_vm_ops(struct au_finfo *finfo, struct vm_area_struct *vma)
  8162. +{
  8163. + int err;
  8164. + struct vm_operations_struct *h_ops;
  8165. +
  8166. + AuRwMustAnyLock(&finfo->fi_rwsem);
  8167. +
  8168. + err = 0;
  8169. + h_ops = finfo->fi_h_vm_ops;
  8170. + AuDebugOn(!h_ops);
  8171. + if ((!h_ops->page_mkwrite && !h_ops->close)
  8172. + || finfo->fi_vm_ops)
  8173. + goto out;
  8174. +
  8175. + err = -ENOMEM;
  8176. + finfo->fi_vm_ops = kmemdup(&aufs_vm_ops, sizeof(aufs_vm_ops), GFP_NOFS);
  8177. + if (unlikely(!finfo->fi_vm_ops))
  8178. + goto out;
  8179. +
  8180. + err = 0;
  8181. + if (h_ops->page_mkwrite)
  8182. + finfo->fi_vm_ops->page_mkwrite = aufs_page_mkwrite;
  8183. + if (h_ops->close)
  8184. + finfo->fi_vm_ops->close = aufs_vm_close;
  8185. +
  8186. + vma->vm_ops = finfo->fi_vm_ops;
  8187. +
  8188. + out:
  8189. + return err;
  8190. +}
  8191. +
  8192. +static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
  8193. +{
  8194. + int err;
  8195. + unsigned char wlock, mmapped;
  8196. + struct dentry *dentry;
  8197. + struct super_block *sb;
  8198. + struct file *h_file;
  8199. + struct vm_operations_struct *vm_ops;
  8200. +
  8201. + dentry = file->f_dentry;
  8202. + wlock = !!(file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
  8203. + sb = dentry->d_sb;
  8204. + si_read_lock(sb, AuLock_FLUSH);
  8205. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  8206. + if (unlikely(err))
  8207. + goto out;
  8208. +
  8209. + mmapped = !!au_test_mmapped(file);
  8210. + if (wlock) {
  8211. + struct au_pin pin;
  8212. +
  8213. + err = au_ready_to_write(file, -1, &pin);
  8214. + di_downgrade_lock(dentry, AuLock_IR);
  8215. + if (unlikely(err))
  8216. + goto out_unlock;
  8217. + au_unpin(&pin);
  8218. + } else
  8219. + di_downgrade_lock(dentry, AuLock_IR);
  8220. +
  8221. + h_file = au_h_fptr(file, au_fbstart(file));
  8222. + if (!mmapped && au_test_fs_bad_mapping(h_file->f_dentry->d_sb)) {
  8223. + /*
  8224. + * by this assignment, f_mapping will differs from aufs inode
  8225. + * i_mapping.
  8226. + * if someone else mixes the use of f_dentry->d_inode and
  8227. + * f_mapping->host, then a problem may arise.
  8228. + */
  8229. + file->f_mapping = h_file->f_mapping;
  8230. + }
  8231. +
  8232. + vm_ops = NULL;
  8233. + if (!mmapped) {
  8234. + vm_ops = au_vm_ops(h_file, vma);
  8235. + err = PTR_ERR(vm_ops);
  8236. + if (IS_ERR(vm_ops))
  8237. + goto out_unlock;
  8238. + }
  8239. +
  8240. + /*
  8241. + * unnecessary to handle MAP_DENYWRITE and deny_write_access()?
  8242. + * currently MAP_DENYWRITE from userspace is ignored, but elf loader
  8243. + * sets it. when FMODE_EXEC is set (by open_exec() or sys_uselib()),
  8244. + * both of the aufs file and the lower file is deny_write_access()-ed.
  8245. + * finally I hope we can skip handlling MAP_DENYWRITE here.
  8246. + */
  8247. + err = generic_file_mmap(file, vma);
  8248. + if (unlikely(err))
  8249. + goto out_unlock;
  8250. +
  8251. + vma->vm_ops = &aufs_vm_ops;
  8252. + /* test again */
  8253. + if (!au_test_mmapped(file))
  8254. + au_fi(file)->fi_h_vm_ops = vm_ops;
  8255. +
  8256. + err = au_custom_vm_ops(au_fi(file), vma);
  8257. + if (unlikely(err))
  8258. + goto out_unlock;
  8259. +
  8260. + vfsub_file_accessed(h_file);
  8261. + fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
  8262. +
  8263. + out_unlock:
  8264. + di_read_unlock(dentry, AuLock_IR);
  8265. + fi_write_unlock(file);
  8266. + out:
  8267. + si_read_unlock(sb);
  8268. + return err;
  8269. +}
  8270. +
  8271. +/* ---------------------------------------------------------------------- */
  8272. +
  8273. +static int aufs_fsync_nondir(struct file *file, struct dentry *dentry,
  8274. + int datasync)
  8275. +{
  8276. + int err;
  8277. + struct au_pin pin;
  8278. + struct inode *inode;
  8279. + struct file *h_file;
  8280. + struct super_block *sb;
  8281. +
  8282. + inode = dentry->d_inode;
  8283. + IMustLock(file->f_mapping->host);
  8284. + if (inode != file->f_mapping->host) {
  8285. + mutex_unlock(&file->f_mapping->host->i_mutex);
  8286. + mutex_lock(&inode->i_mutex);
  8287. + }
  8288. + IMustLock(inode);
  8289. +
  8290. + sb = dentry->d_sb;
  8291. + si_read_lock(sb, AuLock_FLUSH);
  8292. +
  8293. + err = 0; /* -EBADF; */ /* posix? */
  8294. + if (unlikely(!(file->f_mode & FMODE_WRITE)))
  8295. + goto out;
  8296. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  8297. + if (unlikely(err))
  8298. + goto out;
  8299. +
  8300. + err = au_ready_to_write(file, -1, &pin);
  8301. + di_downgrade_lock(dentry, AuLock_IR);
  8302. + if (unlikely(err))
  8303. + goto out_unlock;
  8304. + au_unpin(&pin);
  8305. +
  8306. + err = -EINVAL;
  8307. + h_file = au_h_fptr(file, au_fbstart(file));
  8308. + if (h_file->f_op && h_file->f_op->fsync) {
  8309. + struct dentry *h_d;
  8310. + struct mutex *h_mtx;
  8311. +
  8312. + /*
  8313. + * no filemap_fdatawrite() since aufs file has no its own
  8314. + * mapping, but dir.
  8315. + */
  8316. + h_d = h_file->f_dentry;
  8317. + h_mtx = &h_d->d_inode->i_mutex;
  8318. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  8319. + err = h_file->f_op->fsync(h_file, h_d, datasync);
  8320. + if (!err)
  8321. + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
  8322. + /*ignore*/
  8323. + au_cpup_attr_timesizes(inode);
  8324. + mutex_unlock(h_mtx);
  8325. + }
  8326. +
  8327. + out_unlock:
  8328. + di_read_unlock(dentry, AuLock_IR);
  8329. + fi_write_unlock(file);
  8330. + out:
  8331. + si_read_unlock(sb);
  8332. + if (inode != file->f_mapping->host) {
  8333. + mutex_unlock(&inode->i_mutex);
  8334. + mutex_lock(&file->f_mapping->host->i_mutex);
  8335. + }
  8336. + return err;
  8337. +}
  8338. +
  8339. +/* no one supports this operation, currently */
  8340. +#if 0
  8341. +static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync)
  8342. +{
  8343. + int err;
  8344. + struct au_pin pin;
  8345. + struct dentry *dentry;
  8346. + struct inode *inode;
  8347. + struct file *file, *h_file;
  8348. + struct super_block *sb;
  8349. +
  8350. + file = kio->ki_filp;
  8351. + dentry = file->f_dentry;
  8352. + inode = dentry->d_inode;
  8353. + mutex_lock(&inode->i_mutex);
  8354. +
  8355. + sb = dentry->d_sb;
  8356. + si_read_lock(sb, AuLock_FLUSH);
  8357. +
  8358. + err = 0; /* -EBADF; */ /* posix? */
  8359. + if (unlikely(!(file->f_mode & FMODE_WRITE)))
  8360. + goto out;
  8361. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  8362. + if (unlikely(err))
  8363. + goto out;
  8364. +
  8365. + err = au_ready_to_write(file, -1, &pin);
  8366. + di_downgrade_lock(dentry, AuLock_IR);
  8367. + if (unlikely(err))
  8368. + goto out_unlock;
  8369. + au_unpin(&pin);
  8370. +
  8371. + err = -ENOSYS;
  8372. + h_file = au_h_fptr(file, au_fbstart(file));
  8373. + if (h_file->f_op && h_file->f_op->aio_fsync) {
  8374. + struct dentry *h_d;
  8375. + struct mutex *h_mtx;
  8376. +
  8377. + h_d = h_file->f_dentry;
  8378. + h_mtx = &h_d->d_inode->i_mutex;
  8379. + if (!is_sync_kiocb(kio)) {
  8380. + get_file(h_file);
  8381. + fput(file);
  8382. + }
  8383. + kio->ki_filp = h_file;
  8384. + err = h_file->f_op->aio_fsync(kio, datasync);
  8385. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  8386. + if (!err)
  8387. + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
  8388. + /*ignore*/
  8389. + au_cpup_attr_timesizes(inode);
  8390. + mutex_unlock(h_mtx);
  8391. + }
  8392. +
  8393. + out_unlock:
  8394. + di_read_unlock(dentry, AuLock_IR);
  8395. + fi_write_unlock(file);
  8396. + out:
  8397. + si_read_unlock(sb);
  8398. + mutex_unlock(&inode->i_mutex);
  8399. + return err;
  8400. +}
  8401. +#endif
  8402. +
  8403. +static int aufs_fasync(int fd, struct file *file, int flag)
  8404. +{
  8405. + int err;
  8406. + struct file *h_file;
  8407. + struct dentry *dentry;
  8408. + struct super_block *sb;
  8409. +
  8410. + dentry = file->f_dentry;
  8411. + sb = dentry->d_sb;
  8412. + si_read_lock(sb, AuLock_FLUSH);
  8413. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
  8414. + if (unlikely(err))
  8415. + goto out;
  8416. +
  8417. + h_file = au_h_fptr(file, au_fbstart(file));
  8418. + if (h_file->f_op && h_file->f_op->fasync)
  8419. + err = h_file->f_op->fasync(fd, h_file, flag);
  8420. +
  8421. + di_read_unlock(dentry, AuLock_IR);
  8422. + fi_read_unlock(file);
  8423. +
  8424. + out:
  8425. + si_read_unlock(sb);
  8426. + return err;
  8427. +}
  8428. +
  8429. +/* ---------------------------------------------------------------------- */
  8430. +
  8431. +/* no one supports this operation, currently */
  8432. +#if 0
  8433. +static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
  8434. + size_t len, loff_t *pos , int more)
  8435. +{
  8436. +}
  8437. +#endif
  8438. +
  8439. +/* ---------------------------------------------------------------------- */
  8440. +
  8441. +const struct file_operations aufs_file_fop = {
  8442. + /*
  8443. + * while generic_file_llseek/_unlocked() don't use BKL,
  8444. + * don't use it since it operates file->f_mapping->host.
  8445. + * in aufs, it may be a real file and may confuse users by UDBA.
  8446. + */
  8447. + /* .llseek = generic_file_llseek, */
  8448. +
  8449. + .read = aufs_read,
  8450. + .write = aufs_write,
  8451. + .aio_read = aufs_aio_read,
  8452. + .aio_write = aufs_aio_write,
  8453. +#ifdef CONFIG_AUFS_POLL
  8454. + .poll = aufs_poll,
  8455. +#endif
  8456. + .mmap = aufs_mmap,
  8457. + .open = aufs_open_nondir,
  8458. + .flush = aufs_flush,
  8459. + .release = aufs_release_nondir,
  8460. + .fsync = aufs_fsync_nondir,
  8461. + /* .aio_fsync = aufs_aio_fsync_nondir, */
  8462. + .fasync = aufs_fasync,
  8463. + /* .sendpage = aufs_sendpage, */
  8464. + .splice_write = aufs_splice_write,
  8465. + .splice_read = aufs_splice_read,
  8466. +#if 0
  8467. + .aio_splice_write = aufs_aio_splice_write,
  8468. + .aio_splice_read = aufs_aio_splice_read
  8469. +#endif
  8470. +};
  8471. diff -Nur linux-2.6.34.orig/fs/aufs/fstype.h linux-2.6.34/fs/aufs/fstype.h
  8472. --- linux-2.6.34.orig/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100
  8473. +++ linux-2.6.34/fs/aufs/fstype.h 2010-05-23 23:33:20.243464010 +0200
  8474. @@ -0,0 +1,474 @@
  8475. +/*
  8476. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  8477. + *
  8478. + * This program, aufs is free software; you can redistribute it and/or modify
  8479. + * it under the terms of the GNU General Public License as published by
  8480. + * the Free Software Foundation; either version 2 of the License, or
  8481. + * (at your option) any later version.
  8482. + *
  8483. + * This program is distributed in the hope that it will be useful,
  8484. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  8485. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8486. + * GNU General Public License for more details.
  8487. + *
  8488. + * You should have received a copy of the GNU General Public License
  8489. + * along with this program; if not, write to the Free Software
  8490. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  8491. + */
  8492. +
  8493. +/*
  8494. + * judging filesystem type
  8495. + */
  8496. +
  8497. +#ifndef __AUFS_FSTYPE_H__
  8498. +#define __AUFS_FSTYPE_H__
  8499. +
  8500. +#ifdef __KERNEL__
  8501. +
  8502. +#include <linux/cramfs_fs.h>
  8503. +#include <linux/fs.h>
  8504. +#include <linux/magic.h>
  8505. +#include <linux/romfs_fs.h>
  8506. +#include <linux/aufs_type.h>
  8507. +
  8508. +static inline int au_test_aufs(struct super_block *sb)
  8509. +{
  8510. + return sb->s_magic == AUFS_SUPER_MAGIC;
  8511. +}
  8512. +
  8513. +static inline const char *au_sbtype(struct super_block *sb)
  8514. +{
  8515. + return sb->s_type->name;
  8516. +}
  8517. +
  8518. +static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
  8519. +{
  8520. +#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE)
  8521. + return sb->s_magic == ROMFS_MAGIC;
  8522. +#else
  8523. + return 0;
  8524. +#endif
  8525. +}
  8526. +
  8527. +static inline int au_test_romfs(struct super_block *sb __maybe_unused)
  8528. +{
  8529. +#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE)
  8530. + return sb->s_magic == ISOFS_SUPER_MAGIC;
  8531. +#else
  8532. + return 0;
  8533. +#endif
  8534. +}
  8535. +
  8536. +static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
  8537. +{
  8538. +#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE)
  8539. + return sb->s_magic == CRAMFS_MAGIC;
  8540. +#endif
  8541. + return 0;
  8542. +}
  8543. +
  8544. +static inline int au_test_nfs(struct super_block *sb __maybe_unused)
  8545. +{
  8546. +#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE)
  8547. + return sb->s_magic == NFS_SUPER_MAGIC;
  8548. +#else
  8549. + return 0;
  8550. +#endif
  8551. +}
  8552. +
  8553. +static inline int au_test_fuse(struct super_block *sb __maybe_unused)
  8554. +{
  8555. +#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE)
  8556. + return sb->s_magic == FUSE_SUPER_MAGIC;
  8557. +#else
  8558. + return 0;
  8559. +#endif
  8560. +}
  8561. +
  8562. +static inline int au_test_xfs(struct super_block *sb __maybe_unused)
  8563. +{
  8564. +#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE)
  8565. + return sb->s_magic == XFS_SB_MAGIC;
  8566. +#else
  8567. + return 0;
  8568. +#endif
  8569. +}
  8570. +
  8571. +static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
  8572. +{
  8573. +#ifdef CONFIG_TMPFS
  8574. + return sb->s_magic == TMPFS_MAGIC;
  8575. +#else
  8576. + return 0;
  8577. +#endif
  8578. +}
  8579. +
  8580. +static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
  8581. +{
  8582. +#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE)
  8583. + return !strcmp(au_sbtype(sb), "ecryptfs");
  8584. +#else
  8585. + return 0;
  8586. +#endif
  8587. +}
  8588. +
  8589. +static inline int au_test_smbfs(struct super_block *sb __maybe_unused)
  8590. +{
  8591. +#if defined(CONFIG_SMB_FS) || defined(CONFIG_SMB_FS_MODULE)
  8592. + return sb->s_magic == SMB_SUPER_MAGIC;
  8593. +#else
  8594. + return 0;
  8595. +#endif
  8596. +}
  8597. +
  8598. +static inline int au_test_ocfs2(struct super_block *sb __maybe_unused)
  8599. +{
  8600. +#if defined(CONFIG_OCFS2_FS) || defined(CONFIG_OCFS2_FS_MODULE)
  8601. + return sb->s_magic == OCFS2_SUPER_MAGIC;
  8602. +#else
  8603. + return 0;
  8604. +#endif
  8605. +}
  8606. +
  8607. +static inline int au_test_ocfs2_dlmfs(struct super_block *sb __maybe_unused)
  8608. +{
  8609. +#if defined(CONFIG_OCFS2_FS_O2CB) || defined(CONFIG_OCFS2_FS_O2CB_MODULE)
  8610. + return sb->s_magic == DLMFS_MAGIC;
  8611. +#else
  8612. + return 0;
  8613. +#endif
  8614. +}
  8615. +
  8616. +static inline int au_test_coda(struct super_block *sb __maybe_unused)
  8617. +{
  8618. +#if defined(CONFIG_CODA_FS) || defined(CONFIG_CODA_FS_MODULE)
  8619. + return sb->s_magic == CODA_SUPER_MAGIC;
  8620. +#else
  8621. + return 0;
  8622. +#endif
  8623. +}
  8624. +
  8625. +static inline int au_test_v9fs(struct super_block *sb __maybe_unused)
  8626. +{
  8627. +#if defined(CONFIG_9P_FS) || defined(CONFIG_9P_FS_MODULE)
  8628. + return sb->s_magic == V9FS_MAGIC;
  8629. +#else
  8630. + return 0;
  8631. +#endif
  8632. +}
  8633. +
  8634. +static inline int au_test_ext4(struct super_block *sb __maybe_unused)
  8635. +{
  8636. +#if defined(CONFIG_EXT4DEV_FS) || defined(CONFIG_EXT4DEV_FS_MODULE)
  8637. + return sb->s_magic == EXT4_SUPER_MAGIC;
  8638. +#else
  8639. + return 0;
  8640. +#endif
  8641. +}
  8642. +
  8643. +static inline int au_test_sysv(struct super_block *sb __maybe_unused)
  8644. +{
  8645. +#if defined(CONFIG_SYSV_FS) || defined(CONFIG_SYSV_FS_MODULE)
  8646. + return !strcmp(au_sbtype(sb), "sysv");
  8647. +#else
  8648. + return 0;
  8649. +#endif
  8650. +}
  8651. +
  8652. +static inline int au_test_ramfs(struct super_block *sb)
  8653. +{
  8654. + return sb->s_magic == RAMFS_MAGIC;
  8655. +}
  8656. +
  8657. +static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
  8658. +{
  8659. +#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE)
  8660. + return sb->s_magic == UBIFS_SUPER_MAGIC;
  8661. +#else
  8662. + return 0;
  8663. +#endif
  8664. +}
  8665. +
  8666. +static inline int au_test_procfs(struct super_block *sb __maybe_unused)
  8667. +{
  8668. +#ifdef CONFIG_PROC_FS
  8669. + return sb->s_magic == PROC_SUPER_MAGIC;
  8670. +#else
  8671. + return 0;
  8672. +#endif
  8673. +}
  8674. +
  8675. +static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
  8676. +{
  8677. +#ifdef CONFIG_SYSFS
  8678. + return sb->s_magic == SYSFS_MAGIC;
  8679. +#else
  8680. + return 0;
  8681. +#endif
  8682. +}
  8683. +
  8684. +static inline int au_test_configfs(struct super_block *sb __maybe_unused)
  8685. +{
  8686. +#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE)
  8687. + return sb->s_magic == CONFIGFS_MAGIC;
  8688. +#else
  8689. + return 0;
  8690. +#endif
  8691. +}
  8692. +
  8693. +static inline int au_test_minix(struct super_block *sb __maybe_unused)
  8694. +{
  8695. +#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE)
  8696. + return sb->s_magic == MINIX3_SUPER_MAGIC
  8697. + || sb->s_magic == MINIX2_SUPER_MAGIC
  8698. + || sb->s_magic == MINIX2_SUPER_MAGIC2
  8699. + || sb->s_magic == MINIX_SUPER_MAGIC
  8700. + || sb->s_magic == MINIX_SUPER_MAGIC2;
  8701. +#else
  8702. + return 0;
  8703. +#endif
  8704. +}
  8705. +
  8706. +static inline int au_test_cifs(struct super_block *sb __maybe_unused)
  8707. +{
  8708. +#if defined(CONFIG_CIFS_FS) || defined(CONFIGCIFS_FS_MODULE)
  8709. + return sb->s_magic == CIFS_MAGIC_NUMBER;
  8710. +#else
  8711. + return 0;
  8712. +#endif
  8713. +}
  8714. +
  8715. +static inline int au_test_fat(struct super_block *sb __maybe_unused)
  8716. +{
  8717. +#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE)
  8718. + return sb->s_magic == MSDOS_SUPER_MAGIC;
  8719. +#else
  8720. + return 0;
  8721. +#endif
  8722. +}
  8723. +
  8724. +static inline int au_test_msdos(struct super_block *sb)
  8725. +{
  8726. + return au_test_fat(sb);
  8727. +}
  8728. +
  8729. +static inline int au_test_vfat(struct super_block *sb)
  8730. +{
  8731. + return au_test_fat(sb);
  8732. +}
  8733. +
  8734. +static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
  8735. +{
  8736. +#ifdef CONFIG_SECURITYFS
  8737. + return sb->s_magic == SECURITYFS_MAGIC;
  8738. +#else
  8739. + return 0;
  8740. +#endif
  8741. +}
  8742. +
  8743. +static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
  8744. +{
  8745. +#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE)
  8746. + return sb->s_magic == SQUASHFS_MAGIC;
  8747. +#else
  8748. + return 0;
  8749. +#endif
  8750. +}
  8751. +
  8752. +static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
  8753. +{
  8754. +#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE)
  8755. + return sb->s_magic == BTRFS_SUPER_MAGIC;
  8756. +#else
  8757. + return 0;
  8758. +#endif
  8759. +}
  8760. +
  8761. +static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
  8762. +{
  8763. +#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE)
  8764. + return sb->s_magic == XENFS_SUPER_MAGIC;
  8765. +#else
  8766. + return 0;
  8767. +#endif
  8768. +}
  8769. +
  8770. +static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
  8771. +{
  8772. +#ifdef CONFIG_DEBUG_FS
  8773. + return sb->s_magic == DEBUGFS_MAGIC;
  8774. +#else
  8775. + return 0;
  8776. +#endif
  8777. +}
  8778. +
  8779. +/* ---------------------------------------------------------------------- */
  8780. +/*
  8781. + * they can't be an aufs branch.
  8782. + */
  8783. +static inline int au_test_fs_unsuppoted(struct super_block *sb)
  8784. +{
  8785. + return
  8786. +#ifndef CONFIG_AUFS_BR_RAMFS
  8787. + au_test_ramfs(sb) ||
  8788. +#endif
  8789. + au_test_procfs(sb)
  8790. + || au_test_sysfs(sb)
  8791. + || au_test_configfs(sb)
  8792. + || au_test_debugfs(sb)
  8793. + || au_test_securityfs(sb)
  8794. + || au_test_xenfs(sb)
  8795. + /* || !strcmp(au_sbtype(sb), "unionfs") */
  8796. + || au_test_aufs(sb); /* will be supported in next version */
  8797. +}
  8798. +
  8799. +/*
  8800. + * If the filesystem supports NFS-export, then it has to support NULL as
  8801. + * a nameidata parameter for ->create(), ->lookup() and ->d_revalidate().
  8802. + * We can apply this principle when we handle a lower filesystem.
  8803. + */
  8804. +static inline int au_test_fs_null_nd(struct super_block *sb)
  8805. +{
  8806. + return !!sb->s_export_op;
  8807. +}
  8808. +
  8809. +static inline int au_test_fs_remote(struct super_block *sb)
  8810. +{
  8811. + return !au_test_tmpfs(sb)
  8812. +#ifdef CONFIG_AUFS_BR_RAMFS
  8813. + && !au_test_ramfs(sb)
  8814. +#endif
  8815. + && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
  8816. +}
  8817. +
  8818. +/* ---------------------------------------------------------------------- */
  8819. +
  8820. +/*
  8821. + * Note: these functions (below) are created after reading ->getattr() in all
  8822. + * filesystems under linux/fs. it means we have to do so in every update...
  8823. + */
  8824. +
  8825. +/*
  8826. + * some filesystems require getattr to refresh the inode attributes before
  8827. + * referencing.
  8828. + * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
  8829. + * and leave the work for d_revalidate()
  8830. + */
  8831. +static inline int au_test_fs_refresh_iattr(struct super_block *sb)
  8832. +{
  8833. + return au_test_nfs(sb)
  8834. + || au_test_fuse(sb)
  8835. + /* || au_test_smbfs(sb) */ /* untested */
  8836. + /* || au_test_ocfs2(sb) */ /* untested */
  8837. + /* || au_test_btrfs(sb) */ /* untested */
  8838. + /* || au_test_coda(sb) */ /* untested */
  8839. + /* || au_test_v9fs(sb) */ /* untested */
  8840. + ;
  8841. +}
  8842. +
  8843. +/*
  8844. + * filesystems which don't maintain i_size or i_blocks.
  8845. + */
  8846. +static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
  8847. +{
  8848. + return au_test_xfs(sb)
  8849. + /* || au_test_ext4(sb) */ /* untested */
  8850. + /* || au_test_ocfs2(sb) */ /* untested */
  8851. + /* || au_test_ocfs2_dlmfs(sb) */ /* untested */
  8852. + /* || au_test_sysv(sb) */ /* untested */
  8853. + /* || au_test_ubifs(sb) */ /* untested */
  8854. + /* || au_test_minix(sb) */ /* untested */
  8855. + ;
  8856. +}
  8857. +
  8858. +/*
  8859. + * filesystems which don't store the correct value in some of their inode
  8860. + * attributes.
  8861. + */
  8862. +static inline int au_test_fs_bad_iattr(struct super_block *sb)
  8863. +{
  8864. + return au_test_fs_bad_iattr_size(sb)
  8865. + /* || au_test_cifs(sb) */ /* untested */
  8866. + || au_test_fat(sb)
  8867. + || au_test_msdos(sb)
  8868. + || au_test_vfat(sb);
  8869. +}
  8870. +
  8871. +/* they don't check i_nlink in link(2) */
  8872. +static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
  8873. +{
  8874. + return au_test_tmpfs(sb)
  8875. +#ifdef CONFIG_AUFS_BR_RAMFS
  8876. + || au_test_ramfs(sb)
  8877. +#endif
  8878. + || au_test_ubifs(sb);
  8879. +}
  8880. +
  8881. +/*
  8882. + * filesystems which sets S_NOATIME and S_NOCMTIME.
  8883. + */
  8884. +static inline int au_test_fs_notime(struct super_block *sb)
  8885. +{
  8886. + return au_test_nfs(sb)
  8887. + || au_test_fuse(sb)
  8888. + || au_test_ubifs(sb)
  8889. + /* || au_test_cifs(sb) */ /* untested */
  8890. + ;
  8891. +}
  8892. +
  8893. +/*
  8894. + * filesystems which requires replacing i_mapping.
  8895. + */
  8896. +static inline int au_test_fs_bad_mapping(struct super_block *sb)
  8897. +{
  8898. + return au_test_fuse(sb)
  8899. + || au_test_ubifs(sb);
  8900. +}
  8901. +
  8902. +/* temporary support for i#1 in cramfs */
  8903. +static inline int au_test_fs_unique_ino(struct inode *inode)
  8904. +{
  8905. + if (au_test_cramfs(inode->i_sb))
  8906. + return inode->i_ino != 1;
  8907. + return 1;
  8908. +}
  8909. +
  8910. +/* ---------------------------------------------------------------------- */
  8911. +
  8912. +/*
  8913. + * the filesystem where the xino files placed must support i/o after unlink and
  8914. + * maintain i_size and i_blocks.
  8915. + */
  8916. +static inline int au_test_fs_bad_xino(struct super_block *sb)
  8917. +{
  8918. + return au_test_fs_remote(sb)
  8919. + || au_test_fs_bad_iattr_size(sb)
  8920. +#ifdef CONFIG_AUFS_BR_RAMFS
  8921. + || !(au_test_ramfs(sb) || au_test_fs_null_nd(sb))
  8922. +#else
  8923. + || !au_test_fs_null_nd(sb) /* to keep xino code simple */
  8924. +#endif
  8925. + /* don't want unnecessary work for xino */
  8926. + || au_test_aufs(sb)
  8927. + || au_test_ecryptfs(sb);
  8928. +}
  8929. +
  8930. +static inline int au_test_fs_trunc_xino(struct super_block *sb)
  8931. +{
  8932. + return au_test_tmpfs(sb)
  8933. + || au_test_ramfs(sb);
  8934. +}
  8935. +
  8936. +/*
  8937. + * test if the @sb is real-readonly.
  8938. + */
  8939. +static inline int au_test_fs_rr(struct super_block *sb)
  8940. +{
  8941. + return au_test_squashfs(sb)
  8942. + || au_test_iso9660(sb)
  8943. + || au_test_cramfs(sb)
  8944. + || au_test_romfs(sb);
  8945. +}
  8946. +
  8947. +#endif /* __KERNEL__ */
  8948. +#endif /* __AUFS_FSTYPE_H__ */
  8949. diff -Nur linux-2.6.34.orig/fs/aufs/hinotify.c linux-2.6.34/fs/aufs/hinotify.c
  8950. --- linux-2.6.34.orig/fs/aufs/hinotify.c 1970-01-01 01:00:00.000000000 +0100
  8951. +++ linux-2.6.34/fs/aufs/hinotify.c 2010-05-23 23:33:20.283473120 +0200
  8952. @@ -0,0 +1,755 @@
  8953. +/*
  8954. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  8955. + *
  8956. + * This program, aufs is free software; you can redistribute it and/or modify
  8957. + * it under the terms of the GNU General Public License as published by
  8958. + * the Free Software Foundation; either version 2 of the License, or
  8959. + * (at your option) any later version.
  8960. + *
  8961. + * This program is distributed in the hope that it will be useful,
  8962. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  8963. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8964. + * GNU General Public License for more details.
  8965. + *
  8966. + * You should have received a copy of the GNU General Public License
  8967. + * along with this program; if not, write to the Free Software
  8968. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  8969. + */
  8970. +
  8971. +/*
  8972. + * inotify for the lower directories
  8973. + */
  8974. +
  8975. +#include "aufs.h"
  8976. +
  8977. +static const __u32 AuHinMask = (IN_MOVE | IN_DELETE | IN_CREATE);
  8978. +static struct inotify_handle *au_hin_handle;
  8979. +
  8980. +AuCacheFuncs(hinotify, HINOTIFY);
  8981. +
  8982. +int au_hin_alloc(struct au_hinode *hinode, struct inode *inode,
  8983. + struct inode *h_inode)
  8984. +{
  8985. + int err;
  8986. + struct au_hinotify *hin;
  8987. + s32 wd;
  8988. +
  8989. + err = -ENOMEM;
  8990. + hin = au_cache_alloc_hinotify();
  8991. + if (hin) {
  8992. + AuDebugOn(hinode->hi_notify);
  8993. + hinode->hi_notify = hin;
  8994. + hin->hin_aufs_inode = inode;
  8995. +
  8996. + inotify_init_watch(&hin->hin_watch);
  8997. + wd = inotify_add_watch(au_hin_handle, &hin->hin_watch, h_inode,
  8998. + AuHinMask);
  8999. + if (wd >= 0)
  9000. + return 0; /* success */
  9001. +
  9002. + err = wd;
  9003. + put_inotify_watch(&hin->hin_watch);
  9004. + au_cache_free_hinotify(hin);
  9005. + hinode->hi_notify = NULL;
  9006. + }
  9007. +
  9008. + return err;
  9009. +}
  9010. +
  9011. +void au_hin_free(struct au_hinode *hinode)
  9012. +{
  9013. + int err;
  9014. + struct au_hinotify *hin;
  9015. +
  9016. + hin = hinode->hi_notify;
  9017. + if (hin) {
  9018. + err = 0;
  9019. + if (atomic_read(&hin->hin_watch.count))
  9020. + err = inotify_rm_watch(au_hin_handle, &hin->hin_watch);
  9021. + if (unlikely(err))
  9022. + /* it means the watch is already removed */
  9023. + AuWarn("failed inotify_rm_watch() %d\n", err);
  9024. + au_cache_free_hinotify(hin);
  9025. + hinode->hi_notify = NULL;
  9026. + }
  9027. +}
  9028. +
  9029. +/* ---------------------------------------------------------------------- */
  9030. +
  9031. +void au_hin_ctl(struct au_hinode *hinode, int do_set)
  9032. +{
  9033. + struct inode *h_inode;
  9034. + struct inotify_watch *watch;
  9035. +
  9036. + if (!hinode->hi_notify)
  9037. + return;
  9038. +
  9039. + h_inode = hinode->hi_inode;
  9040. + IMustLock(h_inode);
  9041. +
  9042. + /* todo: try inotify_find_update_watch()? */
  9043. + watch = &hinode->hi_notify->hin_watch;
  9044. + mutex_lock(&h_inode->inotify_mutex);
  9045. + /* mutex_lock(&watch->ih->mutex); */
  9046. + if (do_set) {
  9047. + AuDebugOn(watch->mask & AuHinMask);
  9048. + watch->mask |= AuHinMask;
  9049. + } else {
  9050. + AuDebugOn(!(watch->mask & AuHinMask));
  9051. + watch->mask &= ~AuHinMask;
  9052. + }
  9053. + /* mutex_unlock(&watch->ih->mutex); */
  9054. + mutex_unlock(&h_inode->inotify_mutex);
  9055. +}
  9056. +
  9057. +void au_reset_hinotify(struct inode *inode, unsigned int flags)
  9058. +{
  9059. + aufs_bindex_t bindex, bend;
  9060. + struct inode *hi;
  9061. + struct dentry *iwhdentry;
  9062. +
  9063. + bend = au_ibend(inode);
  9064. + for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
  9065. + hi = au_h_iptr(inode, bindex);
  9066. + if (!hi)
  9067. + continue;
  9068. +
  9069. + /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */
  9070. + iwhdentry = au_hi_wh(inode, bindex);
  9071. + if (iwhdentry)
  9072. + dget(iwhdentry);
  9073. + au_igrab(hi);
  9074. + au_set_h_iptr(inode, bindex, NULL, 0);
  9075. + au_set_h_iptr(inode, bindex, au_igrab(hi),
  9076. + flags & ~AuHi_XINO);
  9077. + iput(hi);
  9078. + dput(iwhdentry);
  9079. + /* mutex_unlock(&hi->i_mutex); */
  9080. + }
  9081. +}
  9082. +
  9083. +/* ---------------------------------------------------------------------- */
  9084. +
  9085. +static int hin_xino(struct inode *inode, struct inode *h_inode)
  9086. +{
  9087. + int err;
  9088. + aufs_bindex_t bindex, bend, bfound, bstart;
  9089. + struct inode *h_i;
  9090. +
  9091. + err = 0;
  9092. + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
  9093. + AuWarn("branch root dir was changed\n");
  9094. + goto out;
  9095. + }
  9096. +
  9097. + bfound = -1;
  9098. + bend = au_ibend(inode);
  9099. + bstart = au_ibstart(inode);
  9100. +#if 0 /* reserved for future use */
  9101. + if (bindex == bend) {
  9102. + /* keep this ino in rename case */
  9103. + goto out;
  9104. + }
  9105. +#endif
  9106. + for (bindex = bstart; bindex <= bend; bindex++) {
  9107. + if (au_h_iptr(inode, bindex) == h_inode) {
  9108. + bfound = bindex;
  9109. + break;
  9110. + }
  9111. + }
  9112. + if (bfound < 0)
  9113. + goto out;
  9114. +
  9115. + for (bindex = bstart; bindex <= bend; bindex++) {
  9116. + h_i = au_h_iptr(inode, bindex);
  9117. + if (!h_i)
  9118. + continue;
  9119. +
  9120. + err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
  9121. + /* ignore this error */
  9122. + /* bad action? */
  9123. + }
  9124. +
  9125. + /* children inode number will be broken */
  9126. +
  9127. + out:
  9128. + AuTraceErr(err);
  9129. + return err;
  9130. +}
  9131. +
  9132. +static int hin_gen_tree(struct dentry *dentry)
  9133. +{
  9134. + int err, i, j, ndentry;
  9135. + struct au_dcsub_pages dpages;
  9136. + struct au_dpage *dpage;
  9137. + struct dentry **dentries;
  9138. +
  9139. + err = au_dpages_init(&dpages, GFP_NOFS);
  9140. + if (unlikely(err))
  9141. + goto out;
  9142. + err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
  9143. + if (unlikely(err))
  9144. + goto out_dpages;
  9145. +
  9146. + for (i = 0; i < dpages.ndpage; i++) {
  9147. + dpage = dpages.dpages + i;
  9148. + dentries = dpage->dentries;
  9149. + ndentry = dpage->ndentry;
  9150. + for (j = 0; j < ndentry; j++) {
  9151. + struct dentry *d;
  9152. +
  9153. + d = dentries[j];
  9154. + if (IS_ROOT(d))
  9155. + continue;
  9156. +
  9157. + d_drop(d);
  9158. + au_digen_dec(d);
  9159. + if (d->d_inode)
  9160. + /* todo: reset children xino?
  9161. + cached children only? */
  9162. + au_iigen_dec(d->d_inode);
  9163. + }
  9164. + }
  9165. +
  9166. + out_dpages:
  9167. + au_dpages_free(&dpages);
  9168. +
  9169. + /* discard children */
  9170. + dentry_unhash(dentry);
  9171. + dput(dentry);
  9172. + out:
  9173. + return err;
  9174. +}
  9175. +
  9176. +/*
  9177. + * return 0 if processed.
  9178. + */
  9179. +static int hin_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
  9180. + const unsigned int isdir)
  9181. +{
  9182. + int err;
  9183. + struct dentry *d;
  9184. + struct qstr *dname;
  9185. +
  9186. + err = 1;
  9187. + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
  9188. + AuWarn("branch root dir was changed\n");
  9189. + err = 0;
  9190. + goto out;
  9191. + }
  9192. +
  9193. + if (!isdir) {
  9194. + AuDebugOn(!name);
  9195. + au_iigen_dec(inode);
  9196. + spin_lock(&dcache_lock);
  9197. + list_for_each_entry(d, &inode->i_dentry, d_alias) {
  9198. + dname = &d->d_name;
  9199. + if (dname->len != nlen
  9200. + && memcmp(dname->name, name, nlen))
  9201. + continue;
  9202. + err = 0;
  9203. + spin_lock(&d->d_lock);
  9204. + __d_drop(d);
  9205. + au_digen_dec(d);
  9206. + spin_unlock(&d->d_lock);
  9207. + break;
  9208. + }
  9209. + spin_unlock(&dcache_lock);
  9210. + } else {
  9211. + au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIRS);
  9212. + d = d_find_alias(inode);
  9213. + if (!d) {
  9214. + au_iigen_dec(inode);
  9215. + goto out;
  9216. + }
  9217. +
  9218. + dname = &d->d_name;
  9219. + if (dname->len == nlen && !memcmp(dname->name, name, nlen))
  9220. + err = hin_gen_tree(d);
  9221. + dput(d);
  9222. + }
  9223. +
  9224. + out:
  9225. + AuTraceErr(err);
  9226. + return err;
  9227. +}
  9228. +
  9229. +static int hin_gen_by_name(struct dentry *dentry, const unsigned int isdir)
  9230. +{
  9231. + int err;
  9232. + struct inode *inode;
  9233. +
  9234. + inode = dentry->d_inode;
  9235. + if (IS_ROOT(dentry)
  9236. + /* || (inode && inode->i_ino == AUFS_ROOT_INO) */
  9237. + ) {
  9238. + AuWarn("branch root dir was changed\n");
  9239. + return 0;
  9240. + }
  9241. +
  9242. + err = 0;
  9243. + if (!isdir) {
  9244. + d_drop(dentry);
  9245. + au_digen_dec(dentry);
  9246. + if (inode)
  9247. + au_iigen_dec(inode);
  9248. + } else {
  9249. + au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS);
  9250. + if (inode)
  9251. + err = hin_gen_tree(dentry);
  9252. + }
  9253. +
  9254. + AuTraceErr(err);
  9255. + return err;
  9256. +}
  9257. +
  9258. +/* ---------------------------------------------------------------------- */
  9259. +
  9260. +/* hinotify job flags */
  9261. +#define AuHinJob_XINO0 1
  9262. +#define AuHinJob_GEN (1 << 1)
  9263. +#define AuHinJob_DIRENT (1 << 2)
  9264. +#define AuHinJob_ISDIR (1 << 3)
  9265. +#define AuHinJob_TRYXINO0 (1 << 4)
  9266. +#define AuHinJob_MNTPNT (1 << 5)
  9267. +#define au_ftest_hinjob(flags, name) ((flags) & AuHinJob_##name)
  9268. +#define au_fset_hinjob(flags, name) { (flags) |= AuHinJob_##name; }
  9269. +#define au_fclr_hinjob(flags, name) { (flags) &= ~AuHinJob_##name; }
  9270. +
  9271. +struct hin_job_args {
  9272. + unsigned int flags;
  9273. + struct inode *inode, *h_inode, *dir, *h_dir;
  9274. + struct dentry *dentry;
  9275. + char *h_name;
  9276. + int h_nlen;
  9277. +};
  9278. +
  9279. +static int hin_job(struct hin_job_args *a)
  9280. +{
  9281. + const unsigned int isdir = au_ftest_hinjob(a->flags, ISDIR);
  9282. +
  9283. + /* reset xino */
  9284. + if (au_ftest_hinjob(a->flags, XINO0) && a->inode)
  9285. + hin_xino(a->inode, a->h_inode); /* ignore this error */
  9286. +
  9287. + if (au_ftest_hinjob(a->flags, TRYXINO0)
  9288. + && a->inode
  9289. + && a->h_inode) {
  9290. + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
  9291. + if (!a->h_inode->i_nlink)
  9292. + hin_xino(a->inode, a->h_inode); /* ignore this error */
  9293. + mutex_unlock(&a->h_inode->i_mutex);
  9294. + }
  9295. +
  9296. + /* make the generation obsolete */
  9297. + if (au_ftest_hinjob(a->flags, GEN)) {
  9298. + int err = -1;
  9299. + if (a->inode)
  9300. + err = hin_gen_by_inode(a->h_name, a->h_nlen, a->inode,
  9301. + isdir);
  9302. + if (err && a->dentry)
  9303. + hin_gen_by_name(a->dentry, isdir);
  9304. + /* ignore this error */
  9305. + }
  9306. +
  9307. + /* make dir entries obsolete */
  9308. + if (au_ftest_hinjob(a->flags, DIRENT) && a->inode) {
  9309. + struct au_vdir *vdir;
  9310. +
  9311. + vdir = au_ivdir(a->inode);
  9312. + if (vdir)
  9313. + vdir->vd_jiffy = 0;
  9314. + /* IMustLock(a->inode); */
  9315. + /* a->inode->i_version++; */
  9316. + }
  9317. +
  9318. + /* can do nothing but warn */
  9319. + if (au_ftest_hinjob(a->flags, MNTPNT)
  9320. + && a->dentry
  9321. + && d_mountpoint(a->dentry))
  9322. + AuWarn("mount-point %.*s is removed or renamed\n",
  9323. + AuDLNPair(a->dentry));
  9324. +
  9325. + return 0;
  9326. +}
  9327. +
  9328. +/* ---------------------------------------------------------------------- */
  9329. +
  9330. +static char *in_name(u32 mask)
  9331. +{
  9332. +#ifdef CONFIG_AUFS_DEBUG
  9333. +#define test_ret(flag) if (mask & flag) \
  9334. + return #flag;
  9335. + test_ret(IN_ACCESS);
  9336. + test_ret(IN_MODIFY);
  9337. + test_ret(IN_ATTRIB);
  9338. + test_ret(IN_CLOSE_WRITE);
  9339. + test_ret(IN_CLOSE_NOWRITE);
  9340. + test_ret(IN_OPEN);
  9341. + test_ret(IN_MOVED_FROM);
  9342. + test_ret(IN_MOVED_TO);
  9343. + test_ret(IN_CREATE);
  9344. + test_ret(IN_DELETE);
  9345. + test_ret(IN_DELETE_SELF);
  9346. + test_ret(IN_MOVE_SELF);
  9347. + test_ret(IN_UNMOUNT);
  9348. + test_ret(IN_Q_OVERFLOW);
  9349. + test_ret(IN_IGNORED);
  9350. + return "";
  9351. +#undef test_ret
  9352. +#else
  9353. + return "??";
  9354. +#endif
  9355. +}
  9356. +
  9357. +static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
  9358. + struct inode *dir)
  9359. +{
  9360. + struct dentry *dentry, *d, *parent;
  9361. + struct qstr *dname;
  9362. +
  9363. + parent = d_find_alias(dir);
  9364. + if (!parent)
  9365. + return NULL;
  9366. +
  9367. + dentry = NULL;
  9368. + spin_lock(&dcache_lock);
  9369. + list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) {
  9370. + /* AuDbg("%.*s\n", AuDLNPair(d)); */
  9371. + dname = &d->d_name;
  9372. + if (dname->len != nlen || memcmp(dname->name, name, nlen))
  9373. + continue;
  9374. + if (!atomic_read(&d->d_count) || !d->d_fsdata) {
  9375. + spin_lock(&d->d_lock);
  9376. + __d_drop(d);
  9377. + spin_unlock(&d->d_lock);
  9378. + continue;
  9379. + }
  9380. +
  9381. + dentry = dget(d);
  9382. + break;
  9383. + }
  9384. + spin_unlock(&dcache_lock);
  9385. + dput(parent);
  9386. +
  9387. + if (dentry)
  9388. + di_write_lock_child(dentry);
  9389. +
  9390. + return dentry;
  9391. +}
  9392. +
  9393. +static struct inode *lookup_wlock_by_ino(struct super_block *sb,
  9394. + aufs_bindex_t bindex, ino_t h_ino)
  9395. +{
  9396. + struct inode *inode;
  9397. + ino_t ino;
  9398. + int err;
  9399. +
  9400. + inode = NULL;
  9401. + err = au_xino_read(sb, bindex, h_ino, &ino);
  9402. + if (!err && ino)
  9403. + inode = ilookup(sb, ino);
  9404. + if (!inode)
  9405. + goto out;
  9406. +
  9407. + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
  9408. + AuWarn("wrong root branch\n");
  9409. + iput(inode);
  9410. + inode = NULL;
  9411. + goto out;
  9412. + }
  9413. +
  9414. + ii_write_lock_child(inode);
  9415. +
  9416. + out:
  9417. + return inode;
  9418. +}
  9419. +
  9420. +enum { CHILD, PARENT };
  9421. +struct postproc_args {
  9422. + struct inode *h_dir, *dir, *h_child_inode;
  9423. + u32 mask;
  9424. + unsigned int flags[2];
  9425. + unsigned int h_child_nlen;
  9426. + char h_child_name[];
  9427. +};
  9428. +
  9429. +static void postproc(void *_args)
  9430. +{
  9431. + struct postproc_args *a = _args;
  9432. + struct super_block *sb;
  9433. + aufs_bindex_t bindex, bend, bfound;
  9434. + unsigned char xino, try_iput;
  9435. + int err;
  9436. + struct inode *inode;
  9437. + ino_t h_ino;
  9438. + struct hin_job_args args;
  9439. + struct dentry *dentry;
  9440. + struct au_sbinfo *sbinfo;
  9441. +
  9442. + AuDebugOn(!_args);
  9443. + AuDebugOn(!a->h_dir);
  9444. + AuDebugOn(!a->dir);
  9445. + AuDebugOn(!a->mask);
  9446. + AuDbg("mask 0x%x %s, i%lu, hi%lu, hci%lu\n",
  9447. + a->mask, in_name(a->mask), a->dir->i_ino, a->h_dir->i_ino,
  9448. + a->h_child_inode ? a->h_child_inode->i_ino : 0);
  9449. +
  9450. + inode = NULL;
  9451. + dentry = NULL;
  9452. + /*
  9453. + * do not lock a->dir->i_mutex here
  9454. + * because of d_revalidate() may cause a deadlock.
  9455. + */
  9456. + sb = a->dir->i_sb;
  9457. + AuDebugOn(!sb);
  9458. + sbinfo = au_sbi(sb);
  9459. + AuDebugOn(!sbinfo);
  9460. + /* big aufs lock */
  9461. + si_noflush_write_lock(sb);
  9462. +
  9463. + ii_read_lock_parent(a->dir);
  9464. + bfound = -1;
  9465. + bend = au_ibend(a->dir);
  9466. + for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
  9467. + if (au_h_iptr(a->dir, bindex) == a->h_dir) {
  9468. + bfound = bindex;
  9469. + break;
  9470. + }
  9471. + ii_read_unlock(a->dir);
  9472. + if (unlikely(bfound < 0))
  9473. + goto out;
  9474. +
  9475. + xino = !!au_opt_test(au_mntflags(sb), XINO);
  9476. + h_ino = 0;
  9477. + if (a->h_child_inode)
  9478. + h_ino = a->h_child_inode->i_ino;
  9479. +
  9480. + if (a->h_child_nlen
  9481. + && (au_ftest_hinjob(a->flags[CHILD], GEN)
  9482. + || au_ftest_hinjob(a->flags[CHILD], MNTPNT)))
  9483. + dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
  9484. + a->dir);
  9485. + try_iput = 0;
  9486. + if (dentry)
  9487. + inode = dentry->d_inode;
  9488. + if (xino && !inode && h_ino
  9489. + && (au_ftest_hinjob(a->flags[CHILD], XINO0)
  9490. + || au_ftest_hinjob(a->flags[CHILD], TRYXINO0)
  9491. + || au_ftest_hinjob(a->flags[CHILD], GEN))) {
  9492. + inode = lookup_wlock_by_ino(sb, bfound, h_ino);
  9493. + try_iput = 1;
  9494. + }
  9495. +
  9496. + args.flags = a->flags[CHILD];
  9497. + args.dentry = dentry;
  9498. + args.inode = inode;
  9499. + args.h_inode = a->h_child_inode;
  9500. + args.dir = a->dir;
  9501. + args.h_dir = a->h_dir;
  9502. + args.h_name = a->h_child_name;
  9503. + args.h_nlen = a->h_child_nlen;
  9504. + err = hin_job(&args);
  9505. + if (dentry) {
  9506. + if (dentry->d_fsdata)
  9507. + di_write_unlock(dentry);
  9508. + dput(dentry);
  9509. + }
  9510. + if (inode && try_iput) {
  9511. + ii_write_unlock(inode);
  9512. + iput(inode);
  9513. + }
  9514. +
  9515. + ii_write_lock_parent(a->dir);
  9516. + args.flags = a->flags[PARENT];
  9517. + args.dentry = NULL;
  9518. + args.inode = a->dir;
  9519. + args.h_inode = a->h_dir;
  9520. + args.dir = NULL;
  9521. + args.h_dir = NULL;
  9522. + args.h_name = NULL;
  9523. + args.h_nlen = 0;
  9524. + err = hin_job(&args);
  9525. + ii_write_unlock(a->dir);
  9526. +
  9527. + out:
  9528. + au_nwt_done(&sbinfo->si_nowait);
  9529. + si_write_unlock(sb);
  9530. +
  9531. + iput(a->h_child_inode);
  9532. + iput(a->h_dir);
  9533. + iput(a->dir);
  9534. + kfree(a);
  9535. +}
  9536. +
  9537. +/* ---------------------------------------------------------------------- */
  9538. +
  9539. +static void aufs_inotify(struct inotify_watch *watch, u32 wd __maybe_unused,
  9540. + u32 mask, u32 cookie __maybe_unused,
  9541. + const char *h_child_name, struct inode *h_child_inode)
  9542. +{
  9543. + struct au_hinotify *hinotify;
  9544. + struct postproc_args *args;
  9545. + int len, wkq_err;
  9546. + unsigned char isdir, isroot, wh;
  9547. + char *p;
  9548. + struct inode *dir;
  9549. + unsigned int flags[2];
  9550. +
  9551. + /* if IN_UNMOUNT happens, there must be another bug */
  9552. + AuDebugOn(mask & IN_UNMOUNT);
  9553. + if (mask & (IN_IGNORED | IN_UNMOUNT)) {
  9554. + put_inotify_watch(watch);
  9555. + return;
  9556. + }
  9557. +#ifdef AuDbgHinotify
  9558. + au_debug(1);
  9559. + if (1 || !h_child_name || strcmp(h_child_name, AUFS_XINO_FNAME)) {
  9560. + AuDbg("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s,"
  9561. + " hi%lu\n",
  9562. + watch->inode->i_ino, wd, mask, in_name(mask), cookie,
  9563. + h_child_name ? h_child_name : "",
  9564. + h_child_inode ? h_child_inode->i_ino : 0);
  9565. + WARN_ON(1);
  9566. + }
  9567. + au_debug(0);
  9568. +#endif
  9569. +
  9570. + hinotify = container_of(watch, struct au_hinotify, hin_watch);
  9571. + AuDebugOn(!hinotify || !hinotify->hin_aufs_inode);
  9572. + dir = igrab(hinotify->hin_aufs_inode);
  9573. + if (!dir)
  9574. + return;
  9575. +
  9576. + isroot = (dir->i_ino == AUFS_ROOT_INO);
  9577. + len = 0;
  9578. + wh = 0;
  9579. + if (h_child_name) {
  9580. + len = strlen(h_child_name);
  9581. + if (!memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
  9582. + h_child_name += AUFS_WH_PFX_LEN;
  9583. + len -= AUFS_WH_PFX_LEN;
  9584. + wh = 1;
  9585. + }
  9586. + }
  9587. +
  9588. + isdir = 0;
  9589. + if (h_child_inode)
  9590. + isdir = !!S_ISDIR(h_child_inode->i_mode);
  9591. + flags[PARENT] = AuHinJob_ISDIR;
  9592. + flags[CHILD] = 0;
  9593. + if (isdir)
  9594. + flags[CHILD] = AuHinJob_ISDIR;
  9595. + switch (mask & IN_ALL_EVENTS) {
  9596. + case IN_MOVED_FROM:
  9597. + case IN_MOVED_TO:
  9598. + AuDebugOn(!h_child_name || !h_child_inode);
  9599. + au_fset_hinjob(flags[CHILD], GEN);
  9600. + au_fset_hinjob(flags[CHILD], XINO0);
  9601. + au_fset_hinjob(flags[CHILD], MNTPNT);
  9602. + au_fset_hinjob(flags[PARENT], DIRENT);
  9603. + break;
  9604. +
  9605. + case IN_CREATE:
  9606. + AuDebugOn(!h_child_name || !h_child_inode);
  9607. + au_fset_hinjob(flags[PARENT], DIRENT);
  9608. + au_fset_hinjob(flags[CHILD], GEN);
  9609. + break;
  9610. +
  9611. + case IN_DELETE:
  9612. + /*
  9613. + * aufs never be able to get this child inode.
  9614. + * revalidation should be in d_revalidate()
  9615. + * by checking i_nlink, i_generation or d_unhashed().
  9616. + */
  9617. + AuDebugOn(!h_child_name);
  9618. + au_fset_hinjob(flags[PARENT], DIRENT);
  9619. + au_fset_hinjob(flags[CHILD], GEN);
  9620. + au_fset_hinjob(flags[CHILD], TRYXINO0);
  9621. + au_fset_hinjob(flags[CHILD], MNTPNT);
  9622. + break;
  9623. +
  9624. + default:
  9625. + AuDebugOn(1);
  9626. + }
  9627. +
  9628. + if (wh)
  9629. + h_child_inode = NULL;
  9630. +
  9631. + /* iput() and kfree() will be called in postproc() */
  9632. + /*
  9633. + * inotify_mutex is already acquired and kmalloc/prune_icache may lock
  9634. + * iprune_mutex. strange.
  9635. + */
  9636. + lockdep_off();
  9637. + args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
  9638. + lockdep_on();
  9639. + if (unlikely(!args)) {
  9640. + AuErr1("no memory\n");
  9641. + iput(dir);
  9642. + return;
  9643. + }
  9644. + args->flags[PARENT] = flags[PARENT];
  9645. + args->flags[CHILD] = flags[CHILD];
  9646. + args->mask = mask;
  9647. + args->dir = dir;
  9648. + args->h_dir = igrab(watch->inode);
  9649. + if (h_child_inode)
  9650. + h_child_inode = igrab(h_child_inode); /* can be NULL */
  9651. + args->h_child_inode = h_child_inode;
  9652. + args->h_child_nlen = len;
  9653. + if (len) {
  9654. + p = (void *)args;
  9655. + p += sizeof(*args);
  9656. + memcpy(p, h_child_name, len + 1);
  9657. + }
  9658. +
  9659. + lockdep_off();
  9660. + wkq_err = au_wkq_nowait(postproc, args, dir->i_sb);
  9661. + lockdep_on();
  9662. + if (unlikely(wkq_err))
  9663. + AuErr("wkq %d\n", wkq_err);
  9664. +}
  9665. +
  9666. +static void aufs_inotify_destroy(struct inotify_watch *watch __maybe_unused)
  9667. +{
  9668. + return;
  9669. +}
  9670. +
  9671. +static struct inotify_operations aufs_inotify_ops = {
  9672. + .handle_event = aufs_inotify,
  9673. + .destroy_watch = aufs_inotify_destroy
  9674. +};
  9675. +
  9676. +/* ---------------------------------------------------------------------- */
  9677. +
  9678. +static void au_hin_destroy_cache(void)
  9679. +{
  9680. + kmem_cache_destroy(au_cachep[AuCache_HINOTIFY]);
  9681. + au_cachep[AuCache_HINOTIFY] = NULL;
  9682. +}
  9683. +
  9684. +int __init au_hinotify_init(void)
  9685. +{
  9686. + int err;
  9687. +
  9688. + err = -ENOMEM;
  9689. + au_cachep[AuCache_HINOTIFY] = AuCache(au_hinotify);
  9690. + if (au_cachep[AuCache_HINOTIFY]) {
  9691. + err = 0;
  9692. + au_hin_handle = inotify_init(&aufs_inotify_ops);
  9693. + if (IS_ERR(au_hin_handle)) {
  9694. + err = PTR_ERR(au_hin_handle);
  9695. + au_hin_destroy_cache();
  9696. + }
  9697. + }
  9698. + AuTraceErr(err);
  9699. + return err;
  9700. +}
  9701. +
  9702. +void au_hinotify_fin(void)
  9703. +{
  9704. + inotify_destroy(au_hin_handle);
  9705. + if (au_cachep[AuCache_HINOTIFY])
  9706. + au_hin_destroy_cache();
  9707. +}
  9708. diff -Nur linux-2.6.34.orig/fs/aufs/iinfo.c linux-2.6.34/fs/aufs/iinfo.c
  9709. --- linux-2.6.34.orig/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100
  9710. +++ linux-2.6.34/fs/aufs/iinfo.c 2010-05-23 23:33:20.323473189 +0200
  9711. @@ -0,0 +1,283 @@
  9712. +/*
  9713. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  9714. + *
  9715. + * This program, aufs is free software; you can redistribute it and/or modify
  9716. + * it under the terms of the GNU General Public License as published by
  9717. + * the Free Software Foundation; either version 2 of the License, or
  9718. + * (at your option) any later version.
  9719. + *
  9720. + * This program is distributed in the hope that it will be useful,
  9721. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9722. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9723. + * GNU General Public License for more details.
  9724. + *
  9725. + * You should have received a copy of the GNU General Public License
  9726. + * along with this program; if not, write to the Free Software
  9727. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  9728. + */
  9729. +
  9730. +/*
  9731. + * inode private data
  9732. + */
  9733. +
  9734. +#include "aufs.h"
  9735. +
  9736. +struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
  9737. +{
  9738. + struct inode *h_inode;
  9739. +
  9740. + IiMustAnyLock(inode);
  9741. +
  9742. + h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode;
  9743. + AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
  9744. + return h_inode;
  9745. +}
  9746. +
  9747. +/* todo: hard/soft set? */
  9748. +void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex)
  9749. +{
  9750. + struct au_iinfo *iinfo = au_ii(inode);
  9751. + struct inode *h_inode;
  9752. +
  9753. + IiMustWriteLock(inode);
  9754. +
  9755. + iinfo->ii_bstart = bindex;
  9756. + h_inode = iinfo->ii_hinode[bindex + 0].hi_inode;
  9757. + if (h_inode)
  9758. + au_cpup_igen(inode, h_inode);
  9759. +}
  9760. +
  9761. +void au_hiput(struct au_hinode *hinode)
  9762. +{
  9763. + au_hin_free(hinode);
  9764. + dput(hinode->hi_whdentry);
  9765. + iput(hinode->hi_inode);
  9766. +}
  9767. +
  9768. +unsigned int au_hi_flags(struct inode *inode, int isdir)
  9769. +{
  9770. + unsigned int flags;
  9771. + const unsigned int mnt_flags = au_mntflags(inode->i_sb);
  9772. +
  9773. + flags = 0;
  9774. + if (au_opt_test(mnt_flags, XINO))
  9775. + au_fset_hi(flags, XINO);
  9776. + if (isdir && au_opt_test(mnt_flags, UDBA_HINOTIFY))
  9777. + au_fset_hi(flags, HINOTIFY);
  9778. + return flags;
  9779. +}
  9780. +
  9781. +void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
  9782. + struct inode *h_inode, unsigned int flags)
  9783. +{
  9784. + struct au_hinode *hinode;
  9785. + struct inode *hi;
  9786. + struct au_iinfo *iinfo = au_ii(inode);
  9787. +
  9788. + IiMustWriteLock(inode);
  9789. +
  9790. + hinode = iinfo->ii_hinode + bindex;
  9791. + hi = hinode->hi_inode;
  9792. + AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
  9793. + AuDebugOn(h_inode && hi);
  9794. +
  9795. + if (hi)
  9796. + au_hiput(hinode);
  9797. + hinode->hi_inode = h_inode;
  9798. + if (h_inode) {
  9799. + int err;
  9800. + struct super_block *sb = inode->i_sb;
  9801. + struct au_branch *br;
  9802. +
  9803. + if (bindex == iinfo->ii_bstart)
  9804. + au_cpup_igen(inode, h_inode);
  9805. + br = au_sbr(sb, bindex);
  9806. + hinode->hi_id = br->br_id;
  9807. + if (au_ftest_hi(flags, XINO)) {
  9808. + err = au_xino_write(sb, bindex, h_inode->i_ino,
  9809. + inode->i_ino);
  9810. + if (unlikely(err))
  9811. + AuIOErr1("failed au_xino_write() %d\n", err);
  9812. + }
  9813. +
  9814. + if (au_ftest_hi(flags, HINOTIFY)
  9815. + && au_br_hinotifyable(br->br_perm)) {
  9816. + err = au_hin_alloc(hinode, inode, h_inode);
  9817. + if (unlikely(err))
  9818. + AuIOErr1("au_hin_alloc() %d\n", err);
  9819. + }
  9820. + }
  9821. +}
  9822. +
  9823. +void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
  9824. + struct dentry *h_wh)
  9825. +{
  9826. + struct au_hinode *hinode;
  9827. +
  9828. + IiMustWriteLock(inode);
  9829. +
  9830. + hinode = au_ii(inode)->ii_hinode + bindex;
  9831. + AuDebugOn(hinode->hi_whdentry);
  9832. + hinode->hi_whdentry = h_wh;
  9833. +}
  9834. +
  9835. +void au_update_iigen(struct inode *inode)
  9836. +{
  9837. + atomic_set(&au_ii(inode)->ii_generation, au_sigen(inode->i_sb));
  9838. + /* smp_mb(); */ /* atomic_set */
  9839. +}
  9840. +
  9841. +/* it may be called at remount time, too */
  9842. +void au_update_brange(struct inode *inode, int do_put_zero)
  9843. +{
  9844. + struct au_iinfo *iinfo;
  9845. +
  9846. + iinfo = au_ii(inode);
  9847. + if (!iinfo || iinfo->ii_bstart < 0)
  9848. + return;
  9849. +
  9850. + IiMustWriteLock(inode);
  9851. +
  9852. + if (do_put_zero) {
  9853. + aufs_bindex_t bindex;
  9854. +
  9855. + for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
  9856. + bindex++) {
  9857. + struct inode *h_i;
  9858. +
  9859. + h_i = iinfo->ii_hinode[0 + bindex].hi_inode;
  9860. + if (h_i && !h_i->i_nlink)
  9861. + au_set_h_iptr(inode, bindex, NULL, 0);
  9862. + }
  9863. + }
  9864. +
  9865. + iinfo->ii_bstart = -1;
  9866. + while (++iinfo->ii_bstart <= iinfo->ii_bend)
  9867. + if (iinfo->ii_hinode[0 + iinfo->ii_bstart].hi_inode)
  9868. + break;
  9869. + if (iinfo->ii_bstart > iinfo->ii_bend) {
  9870. + iinfo->ii_bstart = -1;
  9871. + iinfo->ii_bend = -1;
  9872. + return;
  9873. + }
  9874. +
  9875. + iinfo->ii_bend++;
  9876. + while (0 <= --iinfo->ii_bend)
  9877. + if (iinfo->ii_hinode[0 + iinfo->ii_bend].hi_inode)
  9878. + break;
  9879. + AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend || iinfo->ii_bend < 0);
  9880. +}
  9881. +
  9882. +/* ---------------------------------------------------------------------- */
  9883. +
  9884. +int au_iinfo_init(struct inode *inode)
  9885. +{
  9886. + struct au_iinfo *iinfo;
  9887. + struct super_block *sb;
  9888. + int nbr, i;
  9889. +
  9890. + sb = inode->i_sb;
  9891. + iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
  9892. + nbr = au_sbend(sb) + 1;
  9893. + if (unlikely(nbr <= 0))
  9894. + nbr = 1;
  9895. + iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
  9896. + if (iinfo->ii_hinode) {
  9897. + for (i = 0; i < nbr; i++)
  9898. + iinfo->ii_hinode[i].hi_id = -1;
  9899. +
  9900. + atomic_set(&iinfo->ii_generation, au_sigen(sb));
  9901. + /* smp_mb(); */ /* atomic_set */
  9902. + au_rw_init(&iinfo->ii_rwsem);
  9903. + iinfo->ii_bstart = -1;
  9904. + iinfo->ii_bend = -1;
  9905. + iinfo->ii_vdir = NULL;
  9906. + return 0;
  9907. + }
  9908. + return -ENOMEM;
  9909. +}
  9910. +
  9911. +int au_ii_realloc(struct au_iinfo *iinfo, int nbr)
  9912. +{
  9913. + int err, sz;
  9914. + struct au_hinode *hip;
  9915. +
  9916. + AuRwMustWriteLock(&iinfo->ii_rwsem);
  9917. +
  9918. + err = -ENOMEM;
  9919. + sz = sizeof(*hip) * (iinfo->ii_bend + 1);
  9920. + if (!sz)
  9921. + sz = sizeof(*hip);
  9922. + hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS);
  9923. + if (hip) {
  9924. + iinfo->ii_hinode = hip;
  9925. + err = 0;
  9926. + }
  9927. +
  9928. + return err;
  9929. +}
  9930. +
  9931. +static int au_iinfo_write0(struct super_block *sb, struct au_hinode *hinode,
  9932. + ino_t ino)
  9933. +{
  9934. + int err;
  9935. + aufs_bindex_t bindex;
  9936. + unsigned char locked;
  9937. +
  9938. + err = 0;
  9939. + locked = !!si_noflush_read_trylock(sb);
  9940. + bindex = au_br_index(sb, hinode->hi_id);
  9941. + if (bindex >= 0)
  9942. + err = au_xino_write0(sb, bindex, hinode->hi_inode->i_ino, ino);
  9943. + /* error action? */
  9944. + if (locked)
  9945. + si_read_unlock(sb);
  9946. + return err;
  9947. +}
  9948. +
  9949. +void au_iinfo_fin(struct inode *inode)
  9950. +{
  9951. + ino_t ino;
  9952. + aufs_bindex_t bend;
  9953. + unsigned char unlinked = !inode->i_nlink;
  9954. + struct au_iinfo *iinfo;
  9955. + struct au_hinode *hi;
  9956. + struct super_block *sb;
  9957. +
  9958. + if (unlinked) {
  9959. + int err = au_xigen_inc(inode);
  9960. + if (unlikely(err))
  9961. + AuWarn1("failed resetting i_generation, %d\n", err);
  9962. + }
  9963. +
  9964. + iinfo = au_ii(inode);
  9965. + /* bad_inode case */
  9966. + if (!iinfo)
  9967. + return;
  9968. +
  9969. + if (iinfo->ii_vdir)
  9970. + au_vdir_free(iinfo->ii_vdir);
  9971. +
  9972. + if (iinfo->ii_bstart >= 0) {
  9973. + sb = inode->i_sb;
  9974. + ino = 0;
  9975. + if (unlinked)
  9976. + ino = inode->i_ino;
  9977. + hi = iinfo->ii_hinode + iinfo->ii_bstart;
  9978. + bend = iinfo->ii_bend;
  9979. + while (iinfo->ii_bstart++ <= bend) {
  9980. + if (hi->hi_inode) {
  9981. + if (unlinked || !hi->hi_inode->i_nlink) {
  9982. + au_iinfo_write0(sb, hi, ino);
  9983. + /* ignore this error */
  9984. + ino = 0;
  9985. + }
  9986. + au_hiput(hi);
  9987. + }
  9988. + hi++;
  9989. + }
  9990. + }
  9991. +
  9992. + kfree(iinfo->ii_hinode);
  9993. + AuRwDestroy(&iinfo->ii_rwsem);
  9994. +}
  9995. diff -Nur linux-2.6.34.orig/fs/aufs/inode.c linux-2.6.34/fs/aufs/inode.c
  9996. --- linux-2.6.34.orig/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100
  9997. +++ linux-2.6.34/fs/aufs/inode.c 2010-05-23 23:33:20.363473043 +0200
  9998. @@ -0,0 +1,380 @@
  9999. +/*
  10000. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  10001. + *
  10002. + * This program, aufs is free software; you can redistribute it and/or modify
  10003. + * it under the terms of the GNU General Public License as published by
  10004. + * the Free Software Foundation; either version 2 of the License, or
  10005. + * (at your option) any later version.
  10006. + *
  10007. + * This program is distributed in the hope that it will be useful,
  10008. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10009. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10010. + * GNU General Public License for more details.
  10011. + *
  10012. + * You should have received a copy of the GNU General Public License
  10013. + * along with this program; if not, write to the Free Software
  10014. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  10015. + */
  10016. +
  10017. +/*
  10018. + * inode functions
  10019. + */
  10020. +
  10021. +#include "aufs.h"
  10022. +
  10023. +struct inode *au_igrab(struct inode *inode)
  10024. +{
  10025. + if (inode) {
  10026. + AuDebugOn(!atomic_read(&inode->i_count));
  10027. + atomic_inc_return(&inode->i_count);
  10028. + }
  10029. + return inode;
  10030. +}
  10031. +
  10032. +static void au_refresh_hinode_attr(struct inode *inode, int do_version)
  10033. +{
  10034. + au_cpup_attr_all(inode, /*force*/0);
  10035. + au_update_iigen(inode);
  10036. + if (do_version)
  10037. + inode->i_version++;
  10038. +}
  10039. +
  10040. +int au_refresh_hinode_self(struct inode *inode, int do_attr)
  10041. +{
  10042. + int err;
  10043. + aufs_bindex_t bindex, new_bindex;
  10044. + unsigned char update;
  10045. + struct inode *first;
  10046. + struct au_hinode *p, *q, tmp;
  10047. + struct super_block *sb;
  10048. + struct au_iinfo *iinfo;
  10049. +
  10050. + IiMustWriteLock(inode);
  10051. +
  10052. + update = 0;
  10053. + sb = inode->i_sb;
  10054. + iinfo = au_ii(inode);
  10055. + err = au_ii_realloc(iinfo, au_sbend(sb) + 1);
  10056. + if (unlikely(err))
  10057. + goto out;
  10058. +
  10059. + p = iinfo->ii_hinode + iinfo->ii_bstart;
  10060. + first = p->hi_inode;
  10061. + err = 0;
  10062. + for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
  10063. + bindex++, p++) {
  10064. + if (!p->hi_inode)
  10065. + continue;
  10066. +
  10067. + new_bindex = au_br_index(sb, p->hi_id);
  10068. + if (new_bindex == bindex)
  10069. + continue;
  10070. +
  10071. + if (new_bindex < 0) {
  10072. + update++;
  10073. + au_hiput(p);
  10074. + p->hi_inode = NULL;
  10075. + continue;
  10076. + }
  10077. +
  10078. + if (new_bindex < iinfo->ii_bstart)
  10079. + iinfo->ii_bstart = new_bindex;
  10080. + if (iinfo->ii_bend < new_bindex)
  10081. + iinfo->ii_bend = new_bindex;
  10082. + /* swap two lower inode, and loop again */
  10083. + q = iinfo->ii_hinode + new_bindex;
  10084. + tmp = *q;
  10085. + *q = *p;
  10086. + *p = tmp;
  10087. + if (tmp.hi_inode) {
  10088. + bindex--;
  10089. + p--;
  10090. + }
  10091. + }
  10092. + au_update_brange(inode, /*do_put_zero*/0);
  10093. + if (do_attr)
  10094. + au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
  10095. +
  10096. + out:
  10097. + return err;
  10098. +}
  10099. +
  10100. +int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
  10101. +{
  10102. + int err, update;
  10103. + unsigned int flags;
  10104. + aufs_bindex_t bindex, bend;
  10105. + unsigned char isdir;
  10106. + struct inode *first;
  10107. + struct au_hinode *p;
  10108. + struct au_iinfo *iinfo;
  10109. +
  10110. + err = au_refresh_hinode_self(inode, /*do_attr*/0);
  10111. + if (unlikely(err))
  10112. + goto out;
  10113. +
  10114. + update = 0;
  10115. + iinfo = au_ii(inode);
  10116. + p = iinfo->ii_hinode + iinfo->ii_bstart;
  10117. + first = p->hi_inode;
  10118. + isdir = S_ISDIR(inode->i_mode);
  10119. + flags = au_hi_flags(inode, isdir);
  10120. + bend = au_dbend(dentry);
  10121. + for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
  10122. + struct inode *h_i;
  10123. + struct dentry *h_d;
  10124. +
  10125. + h_d = au_h_dptr(dentry, bindex);
  10126. + if (!h_d || !h_d->d_inode)
  10127. + continue;
  10128. +
  10129. + if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) {
  10130. + h_i = au_h_iptr(inode, bindex);
  10131. + if (h_i) {
  10132. + if (h_i == h_d->d_inode)
  10133. + continue;
  10134. + err = -EIO;
  10135. + break;
  10136. + }
  10137. + }
  10138. + if (bindex < iinfo->ii_bstart)
  10139. + iinfo->ii_bstart = bindex;
  10140. + if (iinfo->ii_bend < bindex)
  10141. + iinfo->ii_bend = bindex;
  10142. + au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags);
  10143. + update = 1;
  10144. + }
  10145. + au_update_brange(inode, /*do_put_zero*/0);
  10146. +
  10147. + if (unlikely(err))
  10148. + goto out;
  10149. +
  10150. + au_refresh_hinode_attr(inode, update && isdir);
  10151. +
  10152. + out:
  10153. + return err;
  10154. +}
  10155. +
  10156. +static int set_inode(struct inode *inode, struct dentry *dentry)
  10157. +{
  10158. + int err;
  10159. + unsigned int flags;
  10160. + umode_t mode;
  10161. + aufs_bindex_t bindex, bstart, btail;
  10162. + unsigned char isdir;
  10163. + struct dentry *h_dentry;
  10164. + struct inode *h_inode;
  10165. + struct au_iinfo *iinfo;
  10166. +
  10167. + IiMustWriteLock(inode);
  10168. +
  10169. + err = 0;
  10170. + isdir = 0;
  10171. + bstart = au_dbstart(dentry);
  10172. + h_inode = au_h_dptr(dentry, bstart)->d_inode;
  10173. + mode = h_inode->i_mode;
  10174. + switch (mode & S_IFMT) {
  10175. + case S_IFREG:
  10176. + btail = au_dbtail(dentry);
  10177. + inode->i_op = &aufs_iop;
  10178. + inode->i_fop = &aufs_file_fop;
  10179. + inode->i_mapping->a_ops = &aufs_aop;
  10180. + break;
  10181. + case S_IFDIR:
  10182. + isdir = 1;
  10183. + btail = au_dbtaildir(dentry);
  10184. + inode->i_op = &aufs_dir_iop;
  10185. + inode->i_fop = &aufs_dir_fop;
  10186. + break;
  10187. + case S_IFLNK:
  10188. + btail = au_dbtail(dentry);
  10189. + inode->i_op = &aufs_symlink_iop;
  10190. + break;
  10191. + case S_IFBLK:
  10192. + case S_IFCHR:
  10193. + case S_IFIFO:
  10194. + case S_IFSOCK:
  10195. + btail = au_dbtail(dentry);
  10196. + inode->i_op = &aufs_iop;
  10197. + init_special_inode(inode, mode, h_inode->i_rdev);
  10198. + break;
  10199. + default:
  10200. + AuIOErr("Unknown file type 0%o\n", mode);
  10201. + err = -EIO;
  10202. + goto out;
  10203. + }
  10204. +
  10205. + /* do not set inotify for whiteouted dirs (SHWH mode) */
  10206. + flags = au_hi_flags(inode, isdir);
  10207. + if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
  10208. + && au_ftest_hi(flags, HINOTIFY)
  10209. + && dentry->d_name.len > AUFS_WH_PFX_LEN
  10210. + && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
  10211. + au_fclr_hi(flags, HINOTIFY);
  10212. + iinfo = au_ii(inode);
  10213. + iinfo->ii_bstart = bstart;
  10214. + iinfo->ii_bend = btail;
  10215. + for (bindex = bstart; bindex <= btail; bindex++) {
  10216. + h_dentry = au_h_dptr(dentry, bindex);
  10217. + if (h_dentry)
  10218. + au_set_h_iptr(inode, bindex,
  10219. + au_igrab(h_dentry->d_inode), flags);
  10220. + }
  10221. + au_cpup_attr_all(inode, /*force*/1);
  10222. +
  10223. + out:
  10224. + return err;
  10225. +}
  10226. +
  10227. +/* successful returns with iinfo write_locked */
  10228. +static int reval_inode(struct inode *inode, struct dentry *dentry, int *matched)
  10229. +{
  10230. + int err;
  10231. + aufs_bindex_t bindex, bend;
  10232. + struct inode *h_inode, *h_dinode;
  10233. +
  10234. + *matched = 0;
  10235. +
  10236. + /*
  10237. + * before this function, if aufs got any iinfo lock, it must be only
  10238. + * one, the parent dir.
  10239. + * it can happen by UDBA and the obsoleted inode number.
  10240. + */
  10241. + err = -EIO;
  10242. + if (unlikely(inode->i_ino == parent_ino(dentry)))
  10243. + goto out;
  10244. +
  10245. + err = 0;
  10246. + ii_write_lock_new_child(inode);
  10247. + h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode;
  10248. + bend = au_ibend(inode);
  10249. + for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
  10250. + h_inode = au_h_iptr(inode, bindex);
  10251. + if (h_inode && h_inode == h_dinode) {
  10252. + *matched = 1;
  10253. + err = 0;
  10254. + if (au_iigen(inode) != au_digen(dentry))
  10255. + err = au_refresh_hinode(inode, dentry);
  10256. + break;
  10257. + }
  10258. + }
  10259. +
  10260. + if (unlikely(err))
  10261. + ii_write_unlock(inode);
  10262. + out:
  10263. + return err;
  10264. +}
  10265. +
  10266. +/* successful returns with iinfo write_locked */
  10267. +/* todo: return with unlocked? */
  10268. +struct inode *au_new_inode(struct dentry *dentry, int must_new)
  10269. +{
  10270. + struct inode *inode;
  10271. + struct dentry *h_dentry;
  10272. + struct super_block *sb;
  10273. + ino_t h_ino, ino;
  10274. + int err, match;
  10275. + aufs_bindex_t bstart;
  10276. +
  10277. + sb = dentry->d_sb;
  10278. + bstart = au_dbstart(dentry);
  10279. + h_dentry = au_h_dptr(dentry, bstart);
  10280. + h_ino = h_dentry->d_inode->i_ino;
  10281. + err = au_xino_read(sb, bstart, h_ino, &ino);
  10282. + inode = ERR_PTR(err);
  10283. + if (unlikely(err))
  10284. + goto out;
  10285. + new_ino:
  10286. + if (!ino) {
  10287. + ino = au_xino_new_ino(sb);
  10288. + if (unlikely(!ino)) {
  10289. + inode = ERR_PTR(-EIO);
  10290. + goto out;
  10291. + }
  10292. + }
  10293. +
  10294. + AuDbg("i%lu\n", (unsigned long)ino);
  10295. + inode = au_iget_locked(sb, ino);
  10296. + err = PTR_ERR(inode);
  10297. + if (IS_ERR(inode))
  10298. + goto out;
  10299. +
  10300. + AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
  10301. + if (inode->i_state & I_NEW) {
  10302. + ii_write_lock_new_child(inode);
  10303. + err = set_inode(inode, dentry);
  10304. + unlock_new_inode(inode);
  10305. + if (!err)
  10306. + goto out; /* success */
  10307. +
  10308. + iget_failed(inode);
  10309. + ii_write_unlock(inode);
  10310. + goto out_iput;
  10311. + } else if (!must_new) {
  10312. + err = reval_inode(inode, dentry, &match);
  10313. + if (!err)
  10314. + goto out; /* success */
  10315. + else if (match)
  10316. + goto out_iput;
  10317. + }
  10318. +
  10319. + if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode)))
  10320. + AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
  10321. + " b%d, %s, %.*s, hi%lu, i%lu.\n",
  10322. + bstart, au_sbtype(h_dentry->d_sb), AuDLNPair(dentry),
  10323. + (unsigned long)h_ino, (unsigned long)ino);
  10324. + ino = 0;
  10325. + err = au_xino_write(sb, bstart, h_ino, /*ino*/0);
  10326. + if (!err) {
  10327. + iput(inode);
  10328. + goto new_ino;
  10329. + }
  10330. +
  10331. + out_iput:
  10332. + iput(inode);
  10333. + inode = ERR_PTR(err);
  10334. + out:
  10335. + return inode;
  10336. +}
  10337. +
  10338. +/* ---------------------------------------------------------------------- */
  10339. +
  10340. +int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
  10341. + struct inode *inode)
  10342. +{
  10343. + int err;
  10344. +
  10345. + err = au_br_rdonly(au_sbr(sb, bindex));
  10346. +
  10347. + /* pseudo-link after flushed may happen out of bounds */
  10348. + if (!err
  10349. + && inode
  10350. + && au_ibstart(inode) <= bindex
  10351. + && bindex <= au_ibend(inode)) {
  10352. + /*
  10353. + * permission check is unnecessary since vfsub routine
  10354. + * will be called later
  10355. + */
  10356. + struct inode *hi = au_h_iptr(inode, bindex);
  10357. + if (hi)
  10358. + err = IS_IMMUTABLE(hi) ? -EROFS : 0;
  10359. + }
  10360. +
  10361. + return err;
  10362. +}
  10363. +
  10364. +int au_test_h_perm(struct inode *h_inode, int mask)
  10365. +{
  10366. + if (!current_fsuid())
  10367. + return 0;
  10368. + return inode_permission(h_inode, mask);
  10369. +}
  10370. +
  10371. +int au_test_h_perm_sio(struct inode *h_inode, int mask)
  10372. +{
  10373. + if (au_test_nfs(h_inode->i_sb)
  10374. + && (mask & MAY_WRITE)
  10375. + && S_ISDIR(h_inode->i_mode))
  10376. + mask |= MAY_READ; /* force permission check */
  10377. + return au_test_h_perm(h_inode, mask);
  10378. +}
  10379. diff -Nur linux-2.6.34.orig/fs/aufs/inode.h linux-2.6.34/fs/aufs/inode.h
  10380. --- linux-2.6.34.orig/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
  10381. +++ linux-2.6.34/fs/aufs/inode.h 2010-05-23 23:33:20.403473045 +0200
  10382. @@ -0,0 +1,484 @@
  10383. +/*
  10384. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  10385. + *
  10386. + * This program, aufs is free software; you can redistribute it and/or modify
  10387. + * it under the terms of the GNU General Public License as published by
  10388. + * the Free Software Foundation; either version 2 of the License, or
  10389. + * (at your option) any later version.
  10390. + *
  10391. + * This program is distributed in the hope that it will be useful,
  10392. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10393. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10394. + * GNU General Public License for more details.
  10395. + *
  10396. + * You should have received a copy of the GNU General Public License
  10397. + * along with this program; if not, write to the Free Software
  10398. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  10399. + */
  10400. +
  10401. +/*
  10402. + * inode operations
  10403. + */
  10404. +
  10405. +#ifndef __AUFS_INODE_H__
  10406. +#define __AUFS_INODE_H__
  10407. +
  10408. +#ifdef __KERNEL__
  10409. +
  10410. +#include <linux/fs.h>
  10411. +#include <linux/inotify.h>
  10412. +#include <linux/aufs_type.h>
  10413. +#include "rwsem.h"
  10414. +
  10415. +struct vfsmount;
  10416. +
  10417. +struct au_hinotify {
  10418. +#ifdef CONFIG_AUFS_HINOTIFY
  10419. + struct inotify_watch hin_watch;
  10420. + struct inode *hin_aufs_inode; /* no get/put */
  10421. +#endif
  10422. +};
  10423. +
  10424. +struct au_hinode {
  10425. + struct inode *hi_inode;
  10426. + aufs_bindex_t hi_id;
  10427. +#ifdef CONFIG_AUFS_HINOTIFY
  10428. + struct au_hinotify *hi_notify;
  10429. +#endif
  10430. +
  10431. + /* reference to the copied-up whiteout with get/put */
  10432. + struct dentry *hi_whdentry;
  10433. +};
  10434. +
  10435. +struct au_vdir;
  10436. +struct au_iinfo {
  10437. + atomic_t ii_generation;
  10438. + struct super_block *ii_hsb1; /* no get/put */
  10439. +
  10440. + struct au_rwsem ii_rwsem;
  10441. + aufs_bindex_t ii_bstart, ii_bend;
  10442. + __u32 ii_higen;
  10443. + struct au_hinode *ii_hinode;
  10444. + struct au_vdir *ii_vdir;
  10445. +};
  10446. +
  10447. +struct au_icntnr {
  10448. + struct au_iinfo iinfo;
  10449. + struct inode vfs_inode;
  10450. +};
  10451. +
  10452. +/* au_pin flags */
  10453. +#define AuPin_DI_LOCKED 1
  10454. +#define AuPin_MNT_WRITE (1 << 1)
  10455. +#define au_ftest_pin(flags, name) ((flags) & AuPin_##name)
  10456. +#define au_fset_pin(flags, name) { (flags) |= AuPin_##name; }
  10457. +#define au_fclr_pin(flags, name) { (flags) &= ~AuPin_##name; }
  10458. +
  10459. +struct au_pin {
  10460. + /* input */
  10461. + struct dentry *dentry;
  10462. + unsigned int udba;
  10463. + unsigned char lsc_di, lsc_hi, flags;
  10464. + aufs_bindex_t bindex;
  10465. +
  10466. + /* output */
  10467. + struct dentry *parent;
  10468. + struct au_hinode *hdir;
  10469. + struct vfsmount *h_mnt;
  10470. +};
  10471. +
  10472. +/* ---------------------------------------------------------------------- */
  10473. +
  10474. +static inline struct au_iinfo *au_ii(struct inode *inode)
  10475. +{
  10476. + struct au_iinfo *iinfo;
  10477. +
  10478. + iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
  10479. + if (iinfo->ii_hinode)
  10480. + return iinfo;
  10481. + return NULL; /* debugging bad_inode case */
  10482. +}
  10483. +
  10484. +/* ---------------------------------------------------------------------- */
  10485. +
  10486. +/* inode.c */
  10487. +struct inode *au_igrab(struct inode *inode);
  10488. +int au_refresh_hinode_self(struct inode *inode, int do_attr);
  10489. +int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
  10490. +struct inode *au_new_inode(struct dentry *dentry, int must_new);
  10491. +int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
  10492. + struct inode *inode);
  10493. +int au_test_h_perm(struct inode *h_inode, int mask);
  10494. +int au_test_h_perm_sio(struct inode *h_inode, int mask);
  10495. +
  10496. +/* i_op.c */
  10497. +extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
  10498. +
  10499. +/* au_wr_dir flags */
  10500. +#define AuWrDir_ADD_ENTRY 1
  10501. +#define AuWrDir_ISDIR (1 << 1)
  10502. +#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
  10503. +#define au_fset_wrdir(flags, name) { (flags) |= AuWrDir_##name; }
  10504. +#define au_fclr_wrdir(flags, name) { (flags) &= ~AuWrDir_##name; }
  10505. +
  10506. +struct au_wr_dir_args {
  10507. + aufs_bindex_t force_btgt;
  10508. + unsigned char flags;
  10509. +};
  10510. +int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
  10511. + struct au_wr_dir_args *args);
  10512. +
  10513. +struct dentry *au_pinned_h_parent(struct au_pin *pin);
  10514. +void au_pin_init(struct au_pin *pin, struct dentry *dentry,
  10515. + aufs_bindex_t bindex, int lsc_di, int lsc_hi,
  10516. + unsigned int udba, unsigned char flags);
  10517. +int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
  10518. + unsigned int udba, unsigned char flags) __must_check;
  10519. +int au_do_pin(struct au_pin *pin) __must_check;
  10520. +void au_unpin(struct au_pin *pin);
  10521. +
  10522. +/* i_op_add.c */
  10523. +int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
  10524. + struct dentry *h_parent, int isdir);
  10525. +int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev);
  10526. +int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
  10527. +int aufs_create(struct inode *dir, struct dentry *dentry, int mode,
  10528. + struct nameidata *nd);
  10529. +int aufs_link(struct dentry *src_dentry, struct inode *dir,
  10530. + struct dentry *dentry);
  10531. +int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
  10532. +
  10533. +/* i_op_del.c */
  10534. +int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
  10535. +int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
  10536. + struct dentry *h_parent, int isdir);
  10537. +int aufs_unlink(struct inode *dir, struct dentry *dentry);
  10538. +int aufs_rmdir(struct inode *dir, struct dentry *dentry);
  10539. +
  10540. +/* i_op_ren.c */
  10541. +int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
  10542. +int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
  10543. + struct inode *dir, struct dentry *dentry);
  10544. +
  10545. +/* iinfo.c */
  10546. +struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
  10547. +void au_hiput(struct au_hinode *hinode);
  10548. +void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex);
  10549. +void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
  10550. + struct dentry *h_wh);
  10551. +unsigned int au_hi_flags(struct inode *inode, int isdir);
  10552. +
  10553. +/* hinode flags */
  10554. +#define AuHi_XINO 1
  10555. +#define AuHi_HINOTIFY (1 << 1)
  10556. +#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
  10557. +#define au_fset_hi(flags, name) { (flags) |= AuHi_##name; }
  10558. +#define au_fclr_hi(flags, name) { (flags) &= ~AuHi_##name; }
  10559. +
  10560. +#ifndef CONFIG_AUFS_HINOTIFY
  10561. +#undef AuHi_HINOTIFY
  10562. +#define AuHi_HINOTIFY 0
  10563. +#endif
  10564. +
  10565. +void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
  10566. + struct inode *h_inode, unsigned int flags);
  10567. +
  10568. +void au_update_iigen(struct inode *inode);
  10569. +void au_update_brange(struct inode *inode, int do_put_zero);
  10570. +
  10571. +int au_iinfo_init(struct inode *inode);
  10572. +void au_iinfo_fin(struct inode *inode);
  10573. +int au_ii_realloc(struct au_iinfo *iinfo, int nbr);
  10574. +
  10575. +/* plink.c */
  10576. +void au_plink_block_maintain(struct super_block *sb);
  10577. +#ifdef CONFIG_AUFS_DEBUG
  10578. +void au_plink_list(struct super_block *sb);
  10579. +#else
  10580. +static inline void au_plink_list(struct super_block *sb)
  10581. +{
  10582. + /* nothing */
  10583. +}
  10584. +#endif
  10585. +int au_plink_test(struct inode *inode);
  10586. +struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
  10587. +void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
  10588. + struct dentry *h_dentry);
  10589. +void au_plink_put(struct super_block *sb);
  10590. +void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
  10591. +
  10592. +/* ---------------------------------------------------------------------- */
  10593. +
  10594. +/* lock subclass for iinfo */
  10595. +enum {
  10596. + AuLsc_II_CHILD, /* child first */
  10597. + AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hinotify */
  10598. + AuLsc_II_CHILD3, /* copyup dirs */
  10599. + AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
  10600. + AuLsc_II_PARENT2,
  10601. + AuLsc_II_PARENT3, /* copyup dirs */
  10602. + AuLsc_II_NEW_CHILD
  10603. +};
  10604. +
  10605. +/*
  10606. + * ii_read_lock_child, ii_write_lock_child,
  10607. + * ii_read_lock_child2, ii_write_lock_child2,
  10608. + * ii_read_lock_child3, ii_write_lock_child3,
  10609. + * ii_read_lock_parent, ii_write_lock_parent,
  10610. + * ii_read_lock_parent2, ii_write_lock_parent2,
  10611. + * ii_read_lock_parent3, ii_write_lock_parent3,
  10612. + * ii_read_lock_new_child, ii_write_lock_new_child,
  10613. + */
  10614. +#define AuReadLockFunc(name, lsc) \
  10615. +static inline void ii_read_lock_##name(struct inode *i) \
  10616. +{ \
  10617. + au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
  10618. +}
  10619. +
  10620. +#define AuWriteLockFunc(name, lsc) \
  10621. +static inline void ii_write_lock_##name(struct inode *i) \
  10622. +{ \
  10623. + au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
  10624. +}
  10625. +
  10626. +#define AuRWLockFuncs(name, lsc) \
  10627. + AuReadLockFunc(name, lsc) \
  10628. + AuWriteLockFunc(name, lsc)
  10629. +
  10630. +AuRWLockFuncs(child, CHILD);
  10631. +AuRWLockFuncs(child2, CHILD2);
  10632. +AuRWLockFuncs(child3, CHILD3);
  10633. +AuRWLockFuncs(parent, PARENT);
  10634. +AuRWLockFuncs(parent2, PARENT2);
  10635. +AuRWLockFuncs(parent3, PARENT3);
  10636. +AuRWLockFuncs(new_child, NEW_CHILD);
  10637. +
  10638. +#undef AuReadLockFunc
  10639. +#undef AuWriteLockFunc
  10640. +#undef AuRWLockFuncs
  10641. +
  10642. +/*
  10643. + * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
  10644. + */
  10645. +AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
  10646. +
  10647. +#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
  10648. +#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
  10649. +#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
  10650. +
  10651. +/* ---------------------------------------------------------------------- */
  10652. +
  10653. +static inline unsigned int au_iigen(struct inode *inode)
  10654. +{
  10655. + return atomic_read(&au_ii(inode)->ii_generation);
  10656. +}
  10657. +
  10658. +/* tiny test for inode number */
  10659. +/* tmpfs generation is too rough */
  10660. +static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
  10661. +{
  10662. + struct au_iinfo *iinfo;
  10663. +
  10664. + iinfo = au_ii(inode);
  10665. + AuRwMustAnyLock(&iinfo->ii_rwsem);
  10666. + return !(iinfo->ii_hsb1 == h_inode->i_sb
  10667. + && iinfo->ii_higen == h_inode->i_generation);
  10668. +}
  10669. +
  10670. +/* ---------------------------------------------------------------------- */
  10671. +
  10672. +static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
  10673. + aufs_bindex_t bindex)
  10674. +{
  10675. + IiMustAnyLock(inode);
  10676. + return au_ii(inode)->ii_hinode[0 + bindex].hi_id;
  10677. +}
  10678. +
  10679. +static inline aufs_bindex_t au_ibstart(struct inode *inode)
  10680. +{
  10681. + IiMustAnyLock(inode);
  10682. + return au_ii(inode)->ii_bstart;
  10683. +}
  10684. +
  10685. +static inline aufs_bindex_t au_ibend(struct inode *inode)
  10686. +{
  10687. + IiMustAnyLock(inode);
  10688. + return au_ii(inode)->ii_bend;
  10689. +}
  10690. +
  10691. +static inline struct au_vdir *au_ivdir(struct inode *inode)
  10692. +{
  10693. + IiMustAnyLock(inode);
  10694. + return au_ii(inode)->ii_vdir;
  10695. +}
  10696. +
  10697. +static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
  10698. +{
  10699. + IiMustAnyLock(inode);
  10700. + return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry;
  10701. +}
  10702. +
  10703. +static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex)
  10704. +{
  10705. + IiMustWriteLock(inode);
  10706. + au_ii(inode)->ii_bend = bindex;
  10707. +}
  10708. +
  10709. +static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
  10710. +{
  10711. + IiMustWriteLock(inode);
  10712. + au_ii(inode)->ii_vdir = vdir;
  10713. +}
  10714. +
  10715. +static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
  10716. +{
  10717. + IiMustAnyLock(inode);
  10718. + return au_ii(inode)->ii_hinode + bindex;
  10719. +}
  10720. +
  10721. +/* ---------------------------------------------------------------------- */
  10722. +
  10723. +static inline struct dentry *au_pinned_parent(struct au_pin *pin)
  10724. +{
  10725. + if (pin)
  10726. + return pin->parent;
  10727. + return NULL;
  10728. +}
  10729. +
  10730. +static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
  10731. +{
  10732. + if (pin && pin->hdir)
  10733. + return pin->hdir->hi_inode;
  10734. + return NULL;
  10735. +}
  10736. +
  10737. +static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
  10738. +{
  10739. + if (pin)
  10740. + return pin->hdir;
  10741. + return NULL;
  10742. +}
  10743. +
  10744. +static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
  10745. +{
  10746. + if (pin)
  10747. + pin->dentry = dentry;
  10748. +}
  10749. +
  10750. +static inline void au_pin_set_parent_lflag(struct au_pin *pin,
  10751. + unsigned char lflag)
  10752. +{
  10753. + if (pin) {
  10754. + /* dirty macros require brackets */
  10755. + if (lflag) {
  10756. + au_fset_pin(pin->flags, DI_LOCKED);
  10757. + } else {
  10758. + au_fclr_pin(pin->flags, DI_LOCKED);
  10759. + }
  10760. + }
  10761. +}
  10762. +
  10763. +static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
  10764. +{
  10765. + if (pin) {
  10766. + dput(pin->parent);
  10767. + pin->parent = dget(parent);
  10768. + }
  10769. +}
  10770. +
  10771. +/* ---------------------------------------------------------------------- */
  10772. +
  10773. +#ifdef CONFIG_AUFS_HINOTIFY
  10774. +/* hinotify.c */
  10775. +int au_hin_alloc(struct au_hinode *hinode, struct inode *inode,
  10776. + struct inode *h_inode);
  10777. +void au_hin_free(struct au_hinode *hinode);
  10778. +void au_hin_ctl(struct au_hinode *hinode, int do_set);
  10779. +void au_reset_hinotify(struct inode *inode, unsigned int flags);
  10780. +
  10781. +int __init au_hinotify_init(void);
  10782. +void au_hinotify_fin(void);
  10783. +
  10784. +static inline
  10785. +void au_hin_init(struct au_hinode *hinode, struct au_hinotify *val)
  10786. +{
  10787. + hinode->hi_notify = val;
  10788. +}
  10789. +
  10790. +static inline void au_iigen_dec(struct inode *inode)
  10791. +{
  10792. + atomic_dec_return(&au_ii(inode)->ii_generation);
  10793. +}
  10794. +
  10795. +#else
  10796. +static inline
  10797. +int au_hin_alloc(struct au_hinode *hinode __maybe_unused,
  10798. + struct inode *inode __maybe_unused,
  10799. + struct inode *h_inode __maybe_unused)
  10800. +{
  10801. + return -EOPNOTSUPP;
  10802. +}
  10803. +
  10804. +static inline void au_hin_free(struct au_hinode *hinode __maybe_unused)
  10805. +{
  10806. + /* nothing */
  10807. +}
  10808. +
  10809. +static inline void au_hin_ctl(struct au_hinode *hinode __maybe_unused,
  10810. + int do_set __maybe_unused)
  10811. +{
  10812. + /* nothing */
  10813. +}
  10814. +
  10815. +static inline void au_reset_hinotify(struct inode *inode __maybe_unused,
  10816. + unsigned int flags __maybe_unused)
  10817. +{
  10818. + /* nothing */
  10819. +}
  10820. +
  10821. +static inline int au_hinotify_init(void)
  10822. +{
  10823. + return 0;
  10824. +}
  10825. +
  10826. +#define au_hinotify_fin() do {} while (0)
  10827. +
  10828. +static inline
  10829. +void au_hin_init(struct au_hinode *hinode __maybe_unused,
  10830. + struct au_hinotify *val __maybe_unused)
  10831. +{
  10832. + /* empty */
  10833. +}
  10834. +#endif /* CONFIG_AUFS_HINOTIFY */
  10835. +
  10836. +static inline void au_hin_suspend(struct au_hinode *hdir)
  10837. +{
  10838. + au_hin_ctl(hdir, /*do_set*/0);
  10839. +}
  10840. +
  10841. +static inline void au_hin_resume(struct au_hinode *hdir)
  10842. +{
  10843. + au_hin_ctl(hdir, /*do_set*/1);
  10844. +}
  10845. +
  10846. +static inline void au_hin_imtx_lock(struct au_hinode *hdir)
  10847. +{
  10848. + mutex_lock(&hdir->hi_inode->i_mutex);
  10849. + au_hin_suspend(hdir);
  10850. +}
  10851. +
  10852. +static inline void au_hin_imtx_lock_nested(struct au_hinode *hdir,
  10853. + unsigned int sc __maybe_unused)
  10854. +{
  10855. + mutex_lock_nested(&hdir->hi_inode->i_mutex, sc);
  10856. + au_hin_suspend(hdir);
  10857. +}
  10858. +
  10859. +static inline void au_hin_imtx_unlock(struct au_hinode *hdir)
  10860. +{
  10861. + au_hin_resume(hdir);
  10862. + mutex_unlock(&hdir->hi_inode->i_mutex);
  10863. +}
  10864. +
  10865. +#endif /* __KERNEL__ */
  10866. +#endif /* __AUFS_INODE_H__ */
  10867. diff -Nur linux-2.6.34.orig/fs/aufs/ioctl.c linux-2.6.34/fs/aufs/ioctl.c
  10868. --- linux-2.6.34.orig/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100
  10869. +++ linux-2.6.34/fs/aufs/ioctl.c 2010-05-23 23:33:20.443473159 +0200
  10870. @@ -0,0 +1,67 @@
  10871. +/*
  10872. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  10873. + *
  10874. + * This program, aufs is free software; you can redistribute it and/or modify
  10875. + * it under the terms of the GNU General Public License as published by
  10876. + * the Free Software Foundation; either version 2 of the License, or
  10877. + * (at your option) any later version.
  10878. + *
  10879. + * This program is distributed in the hope that it will be useful,
  10880. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10881. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10882. + * GNU General Public License for more details.
  10883. + *
  10884. + * You should have received a copy of the GNU General Public License
  10885. + * along with this program; if not, write to the Free Software
  10886. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  10887. + */
  10888. +
  10889. +/*
  10890. + * ioctl
  10891. + * currently plink-management only.
  10892. + */
  10893. +
  10894. +#include <linux/uaccess.h>
  10895. +#include "aufs.h"
  10896. +
  10897. +long aufs_ioctl_dir(struct file *file, unsigned int cmd,
  10898. + unsigned long arg __maybe_unused)
  10899. +{
  10900. + long err;
  10901. + struct super_block *sb;
  10902. + struct au_sbinfo *sbinfo;
  10903. +
  10904. + err = -EACCES;
  10905. + if (!capable(CAP_SYS_ADMIN))
  10906. + goto out;
  10907. +
  10908. + err = 0;
  10909. + sb = file->f_dentry->d_sb;
  10910. + sbinfo = au_sbi(sb);
  10911. + switch (cmd) {
  10912. + case AUFS_CTL_PLINK_MAINT:
  10913. + /*
  10914. + * pseudo-link maintenance mode,
  10915. + * cleared by aufs_release_dir()
  10916. + */
  10917. + si_write_lock(sb);
  10918. + if (!au_ftest_si(sbinfo, MAINTAIN_PLINK)) {
  10919. + au_fset_si(sbinfo, MAINTAIN_PLINK);
  10920. + au_fi(file)->fi_maintain_plink = 1;
  10921. + } else
  10922. + err = -EBUSY;
  10923. + si_write_unlock(sb);
  10924. + break;
  10925. + case AUFS_CTL_PLINK_CLEAN:
  10926. + aufs_write_lock(sb->s_root);
  10927. + if (au_opt_test(sbinfo->si_mntflags, PLINK))
  10928. + au_plink_put(sb);
  10929. + aufs_write_unlock(sb->s_root);
  10930. + break;
  10931. + default:
  10932. + err = -EINVAL;
  10933. + }
  10934. +
  10935. + out:
  10936. + return err;
  10937. +}
  10938. diff -Nur linux-2.6.34.orig/fs/aufs/i_op_add.c linux-2.6.34/fs/aufs/i_op_add.c
  10939. --- linux-2.6.34.orig/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
  10940. +++ linux-2.6.34/fs/aufs/i_op_add.c 2010-05-23 23:33:20.480978545 +0200
  10941. @@ -0,0 +1,649 @@
  10942. +/*
  10943. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  10944. + *
  10945. + * This program, aufs is free software; you can redistribute it and/or modify
  10946. + * it under the terms of the GNU General Public License as published by
  10947. + * the Free Software Foundation; either version 2 of the License, or
  10948. + * (at your option) any later version.
  10949. + *
  10950. + * This program is distributed in the hope that it will be useful,
  10951. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10952. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10953. + * GNU General Public License for more details.
  10954. + *
  10955. + * You should have received a copy of the GNU General Public License
  10956. + * along with this program; if not, write to the Free Software
  10957. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  10958. + */
  10959. +
  10960. +/*
  10961. + * inode operations (add entry)
  10962. + */
  10963. +
  10964. +#include "aufs.h"
  10965. +
  10966. +/*
  10967. + * final procedure of adding a new entry, except link(2).
  10968. + * remove whiteout, instantiate, copyup the parent dir's times and size
  10969. + * and update version.
  10970. + * if it failed, re-create the removed whiteout.
  10971. + */
  10972. +static int epilog(struct inode *dir, aufs_bindex_t bindex,
  10973. + struct dentry *wh_dentry, struct dentry *dentry)
  10974. +{
  10975. + int err, rerr;
  10976. + aufs_bindex_t bwh;
  10977. + struct path h_path;
  10978. + struct inode *inode, *h_dir;
  10979. + struct dentry *wh;
  10980. +
  10981. + bwh = -1;
  10982. + if (wh_dentry) {
  10983. + h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
  10984. + IMustLock(h_dir);
  10985. + AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
  10986. + bwh = au_dbwh(dentry);
  10987. + h_path.dentry = wh_dentry;
  10988. + h_path.mnt = au_sbr_mnt(dir->i_sb, bindex);
  10989. + err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
  10990. + dentry);
  10991. + if (unlikely(err))
  10992. + goto out;
  10993. + }
  10994. +
  10995. + inode = au_new_inode(dentry, /*must_new*/1);
  10996. + if (!IS_ERR(inode)) {
  10997. + d_instantiate(dentry, inode);
  10998. + dir = dentry->d_parent->d_inode; /* dir inode is locked */
  10999. + IMustLock(dir);
  11000. + if (au_ibstart(dir) == au_dbstart(dentry))
  11001. + au_cpup_attr_timesizes(dir);
  11002. + dir->i_version++;
  11003. + return 0; /* success */
  11004. + }
  11005. +
  11006. + err = PTR_ERR(inode);
  11007. + if (!wh_dentry)
  11008. + goto out;
  11009. +
  11010. + /* revert */
  11011. + /* dir inode is locked */
  11012. + wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
  11013. + rerr = PTR_ERR(wh);
  11014. + if (IS_ERR(wh)) {
  11015. + AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
  11016. + AuDLNPair(dentry), err, rerr);
  11017. + err = -EIO;
  11018. + } else
  11019. + dput(wh);
  11020. +
  11021. + out:
  11022. + return err;
  11023. +}
  11024. +
  11025. +/*
  11026. + * simple tests for the adding inode operations.
  11027. + * following the checks in vfs, plus the parent-child relationship.
  11028. + */
  11029. +int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
  11030. + struct dentry *h_parent, int isdir)
  11031. +{
  11032. + int err;
  11033. + umode_t h_mode;
  11034. + struct dentry *h_dentry;
  11035. + struct inode *h_inode;
  11036. +
  11037. + h_dentry = au_h_dptr(dentry, bindex);
  11038. + h_inode = h_dentry->d_inode;
  11039. + if (!dentry->d_inode) {
  11040. + err = -EEXIST;
  11041. + if (unlikely(h_inode))
  11042. + goto out;
  11043. + } else {
  11044. + /* rename(2) case */
  11045. + err = -EIO;
  11046. + if (unlikely(!h_inode || !h_inode->i_nlink))
  11047. + goto out;
  11048. +
  11049. + h_mode = h_inode->i_mode;
  11050. + if (!isdir) {
  11051. + err = -EISDIR;
  11052. + if (unlikely(S_ISDIR(h_mode)))
  11053. + goto out;
  11054. + } else if (unlikely(!S_ISDIR(h_mode))) {
  11055. + err = -ENOTDIR;
  11056. + goto out;
  11057. + }
  11058. + }
  11059. +
  11060. + err = -EIO;
  11061. + /* expected parent dir is locked */
  11062. + if (unlikely(h_parent != h_dentry->d_parent))
  11063. + goto out;
  11064. + err = 0;
  11065. +
  11066. + out:
  11067. + return err;
  11068. +}
  11069. +
  11070. +/*
  11071. + * initial procedure of adding a new entry.
  11072. + * prepare writable branch and the parent dir, lock it,
  11073. + * and lookup whiteout for the new entry.
  11074. + */
  11075. +static struct dentry*
  11076. +lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
  11077. + struct dentry *src_dentry, struct au_pin *pin,
  11078. + struct au_wr_dir_args *wr_dir_args)
  11079. +{
  11080. + struct dentry *wh_dentry, *h_parent;
  11081. + struct super_block *sb;
  11082. + struct au_branch *br;
  11083. + int err;
  11084. + unsigned int udba;
  11085. + aufs_bindex_t bcpup;
  11086. +
  11087. + err = au_wr_dir(dentry, src_dentry, wr_dir_args);
  11088. + bcpup = err;
  11089. + wh_dentry = ERR_PTR(err);
  11090. + if (unlikely(err < 0))
  11091. + goto out;
  11092. +
  11093. + sb = dentry->d_sb;
  11094. + udba = au_opt_udba(sb);
  11095. + err = au_pin(pin, dentry, bcpup, udba,
  11096. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  11097. + wh_dentry = ERR_PTR(err);
  11098. + if (unlikely(err))
  11099. + goto out;
  11100. +
  11101. + h_parent = au_pinned_h_parent(pin);
  11102. + if (udba != AuOpt_UDBA_NONE
  11103. + && au_dbstart(dentry) == bcpup) {
  11104. + err = au_may_add(dentry, bcpup, h_parent,
  11105. + au_ftest_wrdir(wr_dir_args->flags, ISDIR));
  11106. + wh_dentry = ERR_PTR(err);
  11107. + if (unlikely(err))
  11108. + goto out_unpin;
  11109. + }
  11110. +
  11111. + br = au_sbr(sb, bcpup);
  11112. + if (dt) {
  11113. + struct path tmp = {
  11114. + .dentry = h_parent,
  11115. + .mnt = br->br_mnt
  11116. + };
  11117. + au_dtime_store(dt, au_pinned_parent(pin), &tmp);
  11118. + }
  11119. +
  11120. + wh_dentry = NULL;
  11121. + if (bcpup != au_dbwh(dentry))
  11122. + goto out; /* success */
  11123. +
  11124. + wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
  11125. +
  11126. + out_unpin:
  11127. + if (IS_ERR(wh_dentry))
  11128. + au_unpin(pin);
  11129. + out:
  11130. + return wh_dentry;
  11131. +}
  11132. +
  11133. +/* ---------------------------------------------------------------------- */
  11134. +
  11135. +enum { Mknod, Symlink, Creat };
  11136. +struct simple_arg {
  11137. + int type;
  11138. + union {
  11139. + struct {
  11140. + int mode;
  11141. + struct nameidata *nd;
  11142. + } c;
  11143. + struct {
  11144. + const char *symname;
  11145. + } s;
  11146. + struct {
  11147. + int mode;
  11148. + dev_t dev;
  11149. + } m;
  11150. + } u;
  11151. +};
  11152. +
  11153. +static int add_simple(struct inode *dir, struct dentry *dentry,
  11154. + struct simple_arg *arg)
  11155. +{
  11156. + int err;
  11157. + aufs_bindex_t bstart;
  11158. + unsigned char created;
  11159. + struct au_dtime dt;
  11160. + struct au_pin pin;
  11161. + struct path h_path;
  11162. + struct dentry *wh_dentry, *parent;
  11163. + struct inode *h_dir;
  11164. + struct au_wr_dir_args wr_dir_args = {
  11165. + .force_btgt = -1,
  11166. + .flags = AuWrDir_ADD_ENTRY
  11167. + };
  11168. +
  11169. + IMustLock(dir);
  11170. +
  11171. + parent = dentry->d_parent; /* dir inode is locked */
  11172. + aufs_read_lock(dentry, AuLock_DW);
  11173. + di_write_lock_parent(parent);
  11174. + wh_dentry = lock_hdir_lkup_wh(dentry, &dt, /*src_dentry*/NULL, &pin,
  11175. + &wr_dir_args);
  11176. + err = PTR_ERR(wh_dentry);
  11177. + if (IS_ERR(wh_dentry))
  11178. + goto out;
  11179. +
  11180. + bstart = au_dbstart(dentry);
  11181. + h_path.dentry = au_h_dptr(dentry, bstart);
  11182. + h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
  11183. + h_dir = au_pinned_h_dir(&pin);
  11184. + switch (arg->type) {
  11185. + case Creat:
  11186. + err = vfsub_create(h_dir, &h_path, arg->u.c.mode);
  11187. + break;
  11188. + case Symlink:
  11189. + err = vfsub_symlink(h_dir, &h_path, arg->u.s.symname);
  11190. + break;
  11191. + case Mknod:
  11192. + err = vfsub_mknod(h_dir, &h_path, arg->u.m.mode, arg->u.m.dev);
  11193. + break;
  11194. + default:
  11195. + BUG();
  11196. + }
  11197. + created = !err;
  11198. + if (!err)
  11199. + err = epilog(dir, bstart, wh_dentry, dentry);
  11200. +
  11201. + /* revert */
  11202. + if (unlikely(created && err && h_path.dentry->d_inode)) {
  11203. + int rerr;
  11204. + rerr = vfsub_unlink(h_dir, &h_path, /*force*/0);
  11205. + if (rerr) {
  11206. + AuIOErr("%.*s revert failure(%d, %d)\n",
  11207. + AuDLNPair(dentry), err, rerr);
  11208. + err = -EIO;
  11209. + }
  11210. + au_dtime_revert(&dt);
  11211. + d_drop(dentry);
  11212. + }
  11213. +
  11214. + au_unpin(&pin);
  11215. + dput(wh_dentry);
  11216. +
  11217. + out:
  11218. + if (unlikely(err)) {
  11219. + au_update_dbstart(dentry);
  11220. + d_drop(dentry);
  11221. + }
  11222. + di_write_unlock(parent);
  11223. + aufs_read_unlock(dentry, AuLock_DW);
  11224. + return err;
  11225. +}
  11226. +
  11227. +int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
  11228. +{
  11229. + struct simple_arg arg = {
  11230. + .type = Mknod,
  11231. + .u.m = {
  11232. + .mode = mode,
  11233. + .dev = dev
  11234. + }
  11235. + };
  11236. + return add_simple(dir, dentry, &arg);
  11237. +}
  11238. +
  11239. +int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
  11240. +{
  11241. + struct simple_arg arg = {
  11242. + .type = Symlink,
  11243. + .u.s.symname = symname
  11244. + };
  11245. + return add_simple(dir, dentry, &arg);
  11246. +}
  11247. +
  11248. +int aufs_create(struct inode *dir, struct dentry *dentry, int mode,
  11249. + struct nameidata *nd)
  11250. +{
  11251. + struct simple_arg arg = {
  11252. + .type = Creat,
  11253. + .u.c = {
  11254. + .mode = mode,
  11255. + .nd = nd
  11256. + }
  11257. + };
  11258. + return add_simple(dir, dentry, &arg);
  11259. +}
  11260. +
  11261. +/* ---------------------------------------------------------------------- */
  11262. +
  11263. +struct au_link_args {
  11264. + aufs_bindex_t bdst, bsrc;
  11265. + struct au_pin pin;
  11266. + struct path h_path;
  11267. + struct dentry *src_parent, *parent;
  11268. +};
  11269. +
  11270. +static int au_cpup_before_link(struct dentry *src_dentry,
  11271. + struct au_link_args *a)
  11272. +{
  11273. + int err;
  11274. + struct dentry *h_src_dentry;
  11275. + struct mutex *h_mtx;
  11276. +
  11277. + di_read_lock_parent(a->src_parent, AuLock_IR);
  11278. + err = au_test_and_cpup_dirs(src_dentry, a->bdst);
  11279. + if (unlikely(err))
  11280. + goto out;
  11281. +
  11282. + h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
  11283. + h_mtx = &h_src_dentry->d_inode->i_mutex;
  11284. + err = au_pin(&a->pin, src_dentry, a->bdst,
  11285. + au_opt_udba(src_dentry->d_sb),
  11286. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  11287. + if (unlikely(err))
  11288. + goto out;
  11289. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  11290. + err = au_sio_cpup_simple(src_dentry, a->bdst, -1,
  11291. + AuCpup_DTIME /* | AuCpup_KEEPLINO */);
  11292. + mutex_unlock(h_mtx);
  11293. + au_unpin(&a->pin);
  11294. +
  11295. + out:
  11296. + di_read_unlock(a->src_parent, AuLock_IR);
  11297. + return err;
  11298. +}
  11299. +
  11300. +static int au_cpup_or_link(struct dentry *src_dentry, struct au_link_args *a)
  11301. +{
  11302. + int err;
  11303. + unsigned char plink;
  11304. + struct inode *h_inode, *inode;
  11305. + struct dentry *h_src_dentry;
  11306. + struct super_block *sb;
  11307. +
  11308. + plink = 0;
  11309. + h_inode = NULL;
  11310. + sb = src_dentry->d_sb;
  11311. + inode = src_dentry->d_inode;
  11312. + if (au_ibstart(inode) <= a->bdst)
  11313. + h_inode = au_h_iptr(inode, a->bdst);
  11314. + if (!h_inode || !h_inode->i_nlink) {
  11315. + /* copyup src_dentry as the name of dentry. */
  11316. + au_set_dbstart(src_dentry, a->bdst);
  11317. + au_set_h_dptr(src_dentry, a->bdst, dget(a->h_path.dentry));
  11318. + h_inode = au_h_dptr(src_dentry, a->bsrc)->d_inode;
  11319. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  11320. + err = au_sio_cpup_single(src_dentry, a->bdst, a->bsrc, -1,
  11321. + AuCpup_KEEPLINO, a->parent);
  11322. + mutex_unlock(&h_inode->i_mutex);
  11323. + au_set_h_dptr(src_dentry, a->bdst, NULL);
  11324. + au_set_dbstart(src_dentry, a->bsrc);
  11325. + } else {
  11326. + /* the inode of src_dentry already exists on a.bdst branch */
  11327. + h_src_dentry = d_find_alias(h_inode);
  11328. + if (!h_src_dentry && au_plink_test(inode)) {
  11329. + plink = 1;
  11330. + h_src_dentry = au_plink_lkup(inode, a->bdst);
  11331. + err = PTR_ERR(h_src_dentry);
  11332. + if (IS_ERR(h_src_dentry))
  11333. + goto out;
  11334. +
  11335. + if (unlikely(!h_src_dentry->d_inode)) {
  11336. + dput(h_src_dentry);
  11337. + h_src_dentry = NULL;
  11338. + }
  11339. +
  11340. + }
  11341. + if (h_src_dentry) {
  11342. + err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
  11343. + &a->h_path);
  11344. + dput(h_src_dentry);
  11345. + } else {
  11346. + AuIOErr("no dentry found for hi%lu on b%d\n",
  11347. + h_inode->i_ino, a->bdst);
  11348. + err = -EIO;
  11349. + }
  11350. + }
  11351. +
  11352. + if (!err && !plink)
  11353. + au_plink_append(inode, a->bdst, a->h_path.dentry);
  11354. +
  11355. +out:
  11356. + return err;
  11357. +}
  11358. +
  11359. +int aufs_link(struct dentry *src_dentry, struct inode *dir,
  11360. + struct dentry *dentry)
  11361. +{
  11362. + int err, rerr;
  11363. + struct au_dtime dt;
  11364. + struct au_link_args *a;
  11365. + struct dentry *wh_dentry, *h_src_dentry;
  11366. + struct inode *inode;
  11367. + struct super_block *sb;
  11368. + struct au_wr_dir_args wr_dir_args = {
  11369. + /* .force_btgt = -1, */
  11370. + .flags = AuWrDir_ADD_ENTRY
  11371. + };
  11372. +
  11373. + IMustLock(dir);
  11374. + inode = src_dentry->d_inode;
  11375. + IMustLock(inode);
  11376. +
  11377. + err = -ENOENT;
  11378. + if (unlikely(!inode->i_nlink))
  11379. + goto out;
  11380. +
  11381. + err = -ENOMEM;
  11382. + a = kzalloc(sizeof(*a), GFP_NOFS);
  11383. + if (unlikely(!a))
  11384. + goto out;
  11385. +
  11386. + a->parent = dentry->d_parent; /* dir inode is locked */
  11387. + aufs_read_and_write_lock2(dentry, src_dentry, /*AuLock_FLUSH*/0);
  11388. + a->src_parent = dget_parent(src_dentry);
  11389. + wr_dir_args.force_btgt = au_dbstart(src_dentry);
  11390. +
  11391. + di_write_lock_parent(a->parent);
  11392. + wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
  11393. + wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
  11394. + &wr_dir_args);
  11395. + err = PTR_ERR(wh_dentry);
  11396. + if (IS_ERR(wh_dentry))
  11397. + goto out_unlock;
  11398. +
  11399. + err = 0;
  11400. + sb = dentry->d_sb;
  11401. + a->bdst = au_dbstart(dentry);
  11402. + a->h_path.dentry = au_h_dptr(dentry, a->bdst);
  11403. + a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
  11404. + a->bsrc = au_dbstart(src_dentry);
  11405. + if (au_opt_test(au_mntflags(sb), PLINK)) {
  11406. + if (a->bdst < a->bsrc
  11407. + /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
  11408. + err = au_cpup_or_link(src_dentry, a);
  11409. + else {
  11410. + h_src_dentry = au_h_dptr(src_dentry, a->bdst);
  11411. + err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
  11412. + &a->h_path);
  11413. + }
  11414. + } else {
  11415. + /*
  11416. + * copyup src_dentry to the branch we process,
  11417. + * and then link(2) to it.
  11418. + */
  11419. + if (a->bdst < a->bsrc
  11420. + /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
  11421. + au_unpin(&a->pin);
  11422. + di_write_unlock(a->parent);
  11423. + err = au_cpup_before_link(src_dentry, a);
  11424. + di_write_lock_parent(a->parent);
  11425. + if (!err)
  11426. + err = au_pin(&a->pin, dentry, a->bdst,
  11427. + au_opt_udba(sb),
  11428. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  11429. + if (unlikely(err))
  11430. + goto out_wh;
  11431. + }
  11432. + if (!err) {
  11433. + h_src_dentry = au_h_dptr(src_dentry, a->bdst);
  11434. + err = -ENOENT;
  11435. + if (h_src_dentry && h_src_dentry->d_inode)
  11436. + err = vfsub_link(h_src_dentry,
  11437. + au_pinned_h_dir(&a->pin),
  11438. + &a->h_path);
  11439. + }
  11440. + }
  11441. + if (unlikely(err))
  11442. + goto out_unpin;
  11443. +
  11444. + if (wh_dentry) {
  11445. + a->h_path.dentry = wh_dentry;
  11446. + err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
  11447. + dentry);
  11448. + if (unlikely(err))
  11449. + goto out_revert;
  11450. + }
  11451. +
  11452. + dir->i_version++;
  11453. + if (au_ibstart(dir) == au_dbstart(dentry))
  11454. + au_cpup_attr_timesizes(dir);
  11455. + inc_nlink(inode);
  11456. + inode->i_ctime = dir->i_ctime;
  11457. + if (!d_unhashed(a->h_path.dentry))
  11458. + d_instantiate(dentry, au_igrab(inode));
  11459. + else
  11460. + /* some filesystem calls d_drop() */
  11461. + d_drop(dentry);
  11462. + goto out_unpin; /* success */
  11463. +
  11464. + out_revert:
  11465. + rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path, /*force*/0);
  11466. + if (!rerr)
  11467. + goto out_dt;
  11468. + AuIOErr("%.*s reverting failed(%d, %d)\n",
  11469. + AuDLNPair(dentry), err, rerr);
  11470. + err = -EIO;
  11471. + out_dt:
  11472. + d_drop(dentry);
  11473. + au_dtime_revert(&dt);
  11474. + out_unpin:
  11475. + au_unpin(&a->pin);
  11476. + out_wh:
  11477. + dput(wh_dentry);
  11478. + out_unlock:
  11479. + if (unlikely(err)) {
  11480. + au_update_dbstart(dentry);
  11481. + d_drop(dentry);
  11482. + }
  11483. + di_write_unlock(a->parent);
  11484. + dput(a->src_parent);
  11485. + aufs_read_and_write_unlock2(dentry, src_dentry);
  11486. + kfree(a);
  11487. + out:
  11488. + return err;
  11489. +}
  11490. +
  11491. +int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
  11492. +{
  11493. + int err, rerr;
  11494. + aufs_bindex_t bindex;
  11495. + unsigned char diropq;
  11496. + struct path h_path;
  11497. + struct dentry *wh_dentry, *parent, *opq_dentry;
  11498. + struct mutex *h_mtx;
  11499. + struct super_block *sb;
  11500. + struct {
  11501. + struct au_pin pin;
  11502. + struct au_dtime dt;
  11503. + } *a; /* reduce the stack usage */
  11504. + struct au_wr_dir_args wr_dir_args = {
  11505. + .force_btgt = -1,
  11506. + .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
  11507. + };
  11508. +
  11509. + IMustLock(dir);
  11510. +
  11511. + err = -ENOMEM;
  11512. + a = kmalloc(sizeof(*a), GFP_NOFS);
  11513. + if (unlikely(!a))
  11514. + goto out;
  11515. +
  11516. + aufs_read_lock(dentry, AuLock_DW);
  11517. + parent = dentry->d_parent; /* dir inode is locked */
  11518. + di_write_lock_parent(parent);
  11519. + wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
  11520. + &a->pin, &wr_dir_args);
  11521. + err = PTR_ERR(wh_dentry);
  11522. + if (IS_ERR(wh_dentry))
  11523. + goto out_free;
  11524. +
  11525. + sb = dentry->d_sb;
  11526. + bindex = au_dbstart(dentry);
  11527. + h_path.dentry = au_h_dptr(dentry, bindex);
  11528. + h_path.mnt = au_sbr_mnt(sb, bindex);
  11529. + err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
  11530. + if (unlikely(err))
  11531. + goto out_unlock;
  11532. +
  11533. + /* make the dir opaque */
  11534. + diropq = 0;
  11535. + h_mtx = &h_path.dentry->d_inode->i_mutex;
  11536. + if (wh_dentry
  11537. + || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
  11538. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  11539. + opq_dentry = au_diropq_create(dentry, bindex);
  11540. + mutex_unlock(h_mtx);
  11541. + err = PTR_ERR(opq_dentry);
  11542. + if (IS_ERR(opq_dentry))
  11543. + goto out_dir;
  11544. + dput(opq_dentry);
  11545. + diropq = 1;
  11546. + }
  11547. +
  11548. + err = epilog(dir, bindex, wh_dentry, dentry);
  11549. + if (!err) {
  11550. + inc_nlink(dir);
  11551. + goto out_unlock; /* success */
  11552. + }
  11553. +
  11554. + /* revert */
  11555. + if (diropq) {
  11556. + AuLabel(revert opq);
  11557. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  11558. + rerr = au_diropq_remove(dentry, bindex);
  11559. + mutex_unlock(h_mtx);
  11560. + if (rerr) {
  11561. + AuIOErr("%.*s reverting diropq failed(%d, %d)\n",
  11562. + AuDLNPair(dentry), err, rerr);
  11563. + err = -EIO;
  11564. + }
  11565. + }
  11566. +
  11567. + out_dir:
  11568. + AuLabel(revert dir);
  11569. + rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
  11570. + if (rerr) {
  11571. + AuIOErr("%.*s reverting dir failed(%d, %d)\n",
  11572. + AuDLNPair(dentry), err, rerr);
  11573. + err = -EIO;
  11574. + }
  11575. + d_drop(dentry);
  11576. + au_dtime_revert(&a->dt);
  11577. + out_unlock:
  11578. + au_unpin(&a->pin);
  11579. + dput(wh_dentry);
  11580. + out_free:
  11581. + if (unlikely(err)) {
  11582. + au_update_dbstart(dentry);
  11583. + d_drop(dentry);
  11584. + }
  11585. + di_write_unlock(parent);
  11586. + aufs_read_unlock(dentry, AuLock_DW);
  11587. + kfree(a);
  11588. + out:
  11589. + return err;
  11590. +}
  11591. diff -Nur linux-2.6.34.orig/fs/aufs/i_op.c linux-2.6.34/fs/aufs/i_op.c
  11592. --- linux-2.6.34.orig/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
  11593. +++ linux-2.6.34/fs/aufs/i_op.c 2010-05-23 23:33:20.523473039 +0200
  11594. @@ -0,0 +1,872 @@
  11595. +/*
  11596. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  11597. + *
  11598. + * This program, aufs is free software; you can redistribute it and/or modify
  11599. + * it under the terms of the GNU General Public License as published by
  11600. + * the Free Software Foundation; either version 2 of the License, or
  11601. + * (at your option) any later version.
  11602. + *
  11603. + * This program is distributed in the hope that it will be useful,
  11604. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11605. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11606. + * GNU General Public License for more details.
  11607. + *
  11608. + * You should have received a copy of the GNU General Public License
  11609. + * along with this program; if not, write to the Free Software
  11610. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  11611. + */
  11612. +
  11613. +/*
  11614. + * inode operations (except add/del/rename)
  11615. + */
  11616. +
  11617. +#include <linux/device_cgroup.h>
  11618. +#include <linux/fs_stack.h>
  11619. +#include <linux/mm.h>
  11620. +#include <linux/namei.h>
  11621. +#include <linux/security.h>
  11622. +#include <linux/uaccess.h>
  11623. +#include "aufs.h"
  11624. +
  11625. +static int h_permission(struct inode *h_inode, int mask,
  11626. + struct vfsmount *h_mnt, int brperm)
  11627. +{
  11628. + int err;
  11629. + const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
  11630. +
  11631. + err = -EACCES;
  11632. + if ((write_mask && IS_IMMUTABLE(h_inode))
  11633. + || ((mask & MAY_EXEC)
  11634. + && S_ISREG(h_inode->i_mode)
  11635. + && ((h_mnt->mnt_flags & MNT_NOEXEC)
  11636. + || !(h_inode->i_mode & S_IXUGO))))
  11637. + goto out;
  11638. +
  11639. + /*
  11640. + * - skip the lower fs test in the case of write to ro branch.
  11641. + * - nfs dir permission write check is optimized, but a policy for
  11642. + * link/rename requires a real check.
  11643. + */
  11644. + if ((write_mask && !au_br_writable(brperm))
  11645. + || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
  11646. + && write_mask && !(mask & MAY_READ))
  11647. + || !h_inode->i_op->permission) {
  11648. + /* AuLabel(generic_permission); */
  11649. + err = generic_permission(h_inode, mask, NULL);
  11650. + } else {
  11651. + /* AuLabel(h_inode->permission); */
  11652. + err = h_inode->i_op->permission(h_inode, mask);
  11653. + AuTraceErr(err);
  11654. + }
  11655. +
  11656. + if (!err)
  11657. + err = devcgroup_inode_permission(h_inode, mask);
  11658. + if (!err)
  11659. + err = security_inode_permission
  11660. + (h_inode, mask & (MAY_READ | MAY_WRITE | MAY_EXEC
  11661. + | MAY_APPEND));
  11662. +
  11663. + out:
  11664. + return err;
  11665. +}
  11666. +
  11667. +static int aufs_permission(struct inode *inode, int mask)
  11668. +{
  11669. + int err;
  11670. + aufs_bindex_t bindex, bend;
  11671. + const unsigned char isdir = !!S_ISDIR(inode->i_mode);
  11672. + const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
  11673. + struct inode *h_inode;
  11674. + struct super_block *sb;
  11675. + struct au_branch *br;
  11676. +
  11677. + sb = inode->i_sb;
  11678. + si_read_lock(sb, AuLock_FLUSH);
  11679. + ii_read_lock_child(inode);
  11680. +
  11681. + if (!isdir || write_mask) {
  11682. + h_inode = au_h_iptr(inode, au_ibstart(inode));
  11683. + AuDebugOn(!h_inode
  11684. + || ((h_inode->i_mode & S_IFMT)
  11685. + != (inode->i_mode & S_IFMT)));
  11686. + err = 0;
  11687. + bindex = au_ibstart(inode);
  11688. + br = au_sbr(sb, bindex);
  11689. + err = h_permission(h_inode, mask, br->br_mnt, br->br_perm);
  11690. +
  11691. + if (write_mask && !err) {
  11692. + /* test whether the upper writable branch exists */
  11693. + err = -EROFS;
  11694. + for (; bindex >= 0; bindex--)
  11695. + if (!au_br_rdonly(au_sbr(sb, bindex))) {
  11696. + err = 0;
  11697. + break;
  11698. + }
  11699. + }
  11700. + goto out;
  11701. + }
  11702. +
  11703. + /* non-write to dir */
  11704. + err = 0;
  11705. + bend = au_ibend(inode);
  11706. + for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) {
  11707. + h_inode = au_h_iptr(inode, bindex);
  11708. + if (h_inode) {
  11709. + AuDebugOn(!S_ISDIR(h_inode->i_mode));
  11710. + br = au_sbr(sb, bindex);
  11711. + err = h_permission(h_inode, mask, br->br_mnt,
  11712. + br->br_perm);
  11713. + }
  11714. + }
  11715. +
  11716. + out:
  11717. + ii_read_unlock(inode);
  11718. + si_read_unlock(sb);
  11719. + return err;
  11720. +}
  11721. +
  11722. +/* ---------------------------------------------------------------------- */
  11723. +
  11724. +static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
  11725. + struct nameidata *nd)
  11726. +{
  11727. + struct dentry *ret, *parent;
  11728. + struct inode *inode, *h_inode;
  11729. + struct mutex *mtx;
  11730. + struct super_block *sb;
  11731. + int err, npositive;
  11732. + aufs_bindex_t bstart;
  11733. +
  11734. + /* temporary workaround for a bug in NFSD readdir */
  11735. + if (!au_test_nfsd(current))
  11736. + IMustLock(dir);
  11737. + else
  11738. + WARN_ONCE(!mutex_is_locked(&dir->i_mutex),
  11739. + "a known problem of NFSD readdir since 2.6.28\n");
  11740. +
  11741. + sb = dir->i_sb;
  11742. + si_read_lock(sb, AuLock_FLUSH);
  11743. + err = au_alloc_dinfo(dentry);
  11744. + ret = ERR_PTR(err);
  11745. + if (unlikely(err))
  11746. + goto out;
  11747. +
  11748. + parent = dentry->d_parent; /* dir inode is locked */
  11749. + di_read_lock_parent(parent, AuLock_IR);
  11750. + npositive = au_lkup_dentry(dentry, au_dbstart(parent), /*type*/0, nd);
  11751. + di_read_unlock(parent, AuLock_IR);
  11752. + err = npositive;
  11753. + ret = ERR_PTR(err);
  11754. + if (unlikely(err < 0))
  11755. + goto out_unlock;
  11756. +
  11757. + inode = NULL;
  11758. + if (npositive) {
  11759. + bstart = au_dbstart(dentry);
  11760. + h_inode = au_h_dptr(dentry, bstart)->d_inode;
  11761. + if (!S_ISDIR(h_inode->i_mode)) {
  11762. + /*
  11763. + * stop 'race'-ing between hardlinks under different
  11764. + * parents.
  11765. + */
  11766. + mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;
  11767. + mutex_lock(mtx);
  11768. + inode = au_new_inode(dentry, /*must_new*/0);
  11769. + mutex_unlock(mtx);
  11770. + } else
  11771. + inode = au_new_inode(dentry, /*must_new*/0);
  11772. + ret = (void *)inode;
  11773. + }
  11774. + if (IS_ERR(inode))
  11775. + goto out_unlock;
  11776. +
  11777. + ret = d_splice_alias(inode, dentry);
  11778. + if (unlikely(IS_ERR(ret) && inode))
  11779. + ii_write_unlock(inode);
  11780. + au_store_oflag(nd, inode);
  11781. +
  11782. + out_unlock:
  11783. + di_write_unlock(dentry);
  11784. + out:
  11785. + si_read_unlock(sb);
  11786. + return ret;
  11787. +}
  11788. +
  11789. +/* ---------------------------------------------------------------------- */
  11790. +
  11791. +static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
  11792. + const unsigned char add_entry, aufs_bindex_t bcpup,
  11793. + aufs_bindex_t bstart)
  11794. +{
  11795. + int err;
  11796. + struct dentry *h_parent;
  11797. + struct inode *h_dir;
  11798. +
  11799. + if (add_entry) {
  11800. + au_update_dbstart(dentry);
  11801. + IMustLock(parent->d_inode);
  11802. + } else
  11803. + di_write_lock_parent(parent);
  11804. +
  11805. + err = 0;
  11806. + if (!au_h_dptr(parent, bcpup)) {
  11807. + if (bstart < bcpup)
  11808. + err = au_cpdown_dirs(dentry, bcpup);
  11809. + else
  11810. + err = au_cpup_dirs(dentry, bcpup);
  11811. + }
  11812. + if (!err && add_entry) {
  11813. + h_parent = au_h_dptr(parent, bcpup);
  11814. + h_dir = h_parent->d_inode;
  11815. + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
  11816. + err = au_lkup_neg(dentry, bcpup);
  11817. + /* todo: no unlock here */
  11818. + mutex_unlock(&h_dir->i_mutex);
  11819. + if (bstart < bcpup && au_dbstart(dentry) < 0) {
  11820. + au_set_dbstart(dentry, 0);
  11821. + au_update_dbrange(dentry, /*do_put_zero*/0);
  11822. + }
  11823. + }
  11824. +
  11825. + if (!add_entry)
  11826. + di_write_unlock(parent);
  11827. + if (!err)
  11828. + err = bcpup; /* success */
  11829. +
  11830. + return err;
  11831. +}
  11832. +
  11833. +/*
  11834. + * decide the branch and the parent dir where we will create a new entry.
  11835. + * returns new bindex or an error.
  11836. + * copyup the parent dir if needed.
  11837. + */
  11838. +int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
  11839. + struct au_wr_dir_args *args)
  11840. +{
  11841. + int err;
  11842. + aufs_bindex_t bcpup, bstart, src_bstart;
  11843. + const unsigned char add_entry = !!au_ftest_wrdir(args->flags,
  11844. + ADD_ENTRY);
  11845. + struct super_block *sb;
  11846. + struct dentry *parent;
  11847. + struct au_sbinfo *sbinfo;
  11848. +
  11849. + sb = dentry->d_sb;
  11850. + sbinfo = au_sbi(sb);
  11851. + parent = dget_parent(dentry);
  11852. + bstart = au_dbstart(dentry);
  11853. + bcpup = bstart;
  11854. + if (args->force_btgt < 0) {
  11855. + if (src_dentry) {
  11856. + src_bstart = au_dbstart(src_dentry);
  11857. + if (src_bstart < bstart)
  11858. + bcpup = src_bstart;
  11859. + } else if (add_entry) {
  11860. + err = AuWbrCreate(sbinfo, dentry,
  11861. + au_ftest_wrdir(args->flags, ISDIR));
  11862. + bcpup = err;
  11863. + }
  11864. +
  11865. + if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) {
  11866. + if (add_entry)
  11867. + err = AuWbrCopyup(sbinfo, dentry);
  11868. + else {
  11869. + if (!IS_ROOT(dentry)) {
  11870. + di_read_lock_parent(parent, !AuLock_IR);
  11871. + err = AuWbrCopyup(sbinfo, dentry);
  11872. + di_read_unlock(parent, !AuLock_IR);
  11873. + } else
  11874. + err = AuWbrCopyup(sbinfo, dentry);
  11875. + }
  11876. + bcpup = err;
  11877. + if (unlikely(err < 0))
  11878. + goto out;
  11879. + }
  11880. + } else {
  11881. + bcpup = args->force_btgt;
  11882. + AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode));
  11883. + }
  11884. + AuDbg("bstart %d, bcpup %d\n", bstart, bcpup);
  11885. + if (bstart < bcpup)
  11886. + au_update_dbrange(dentry, /*do_put_zero*/1);
  11887. +
  11888. + err = bcpup;
  11889. + if (bcpup == bstart)
  11890. + goto out; /* success */
  11891. +
  11892. + /* copyup the new parent into the branch we process */
  11893. + err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart);
  11894. +
  11895. + out:
  11896. + dput(parent);
  11897. + return err;
  11898. +}
  11899. +
  11900. +/* ---------------------------------------------------------------------- */
  11901. +
  11902. +struct dentry *au_pinned_h_parent(struct au_pin *pin)
  11903. +{
  11904. + if (pin && pin->parent)
  11905. + return au_h_dptr(pin->parent, pin->bindex);
  11906. + return NULL;
  11907. +}
  11908. +
  11909. +void au_unpin(struct au_pin *p)
  11910. +{
  11911. + if (au_ftest_pin(p->flags, MNT_WRITE))
  11912. + mnt_drop_write(p->h_mnt);
  11913. + if (!p->hdir)
  11914. + return;
  11915. +
  11916. + au_hin_imtx_unlock(p->hdir);
  11917. + if (!au_ftest_pin(p->flags, DI_LOCKED))
  11918. + di_read_unlock(p->parent, AuLock_IR);
  11919. + iput(p->hdir->hi_inode);
  11920. + dput(p->parent);
  11921. + p->parent = NULL;
  11922. + p->hdir = NULL;
  11923. + p->h_mnt = NULL;
  11924. +}
  11925. +
  11926. +int au_do_pin(struct au_pin *p)
  11927. +{
  11928. + int err;
  11929. + struct super_block *sb;
  11930. + struct dentry *h_dentry, *h_parent;
  11931. + struct au_branch *br;
  11932. + struct inode *h_dir;
  11933. +
  11934. + err = 0;
  11935. + sb = p->dentry->d_sb;
  11936. + br = au_sbr(sb, p->bindex);
  11937. + if (IS_ROOT(p->dentry)) {
  11938. + if (au_ftest_pin(p->flags, MNT_WRITE)) {
  11939. + p->h_mnt = br->br_mnt;
  11940. + err = mnt_want_write(p->h_mnt);
  11941. + if (unlikely(err)) {
  11942. + au_fclr_pin(p->flags, MNT_WRITE);
  11943. + goto out_err;
  11944. + }
  11945. + }
  11946. + goto out;
  11947. + }
  11948. +
  11949. + h_dentry = NULL;
  11950. + if (p->bindex <= au_dbend(p->dentry))
  11951. + h_dentry = au_h_dptr(p->dentry, p->bindex);
  11952. +
  11953. + p->parent = dget_parent(p->dentry);
  11954. + if (!au_ftest_pin(p->flags, DI_LOCKED))
  11955. + di_read_lock(p->parent, AuLock_IR, p->lsc_di);
  11956. +
  11957. + h_dir = NULL;
  11958. + h_parent = au_h_dptr(p->parent, p->bindex);
  11959. + p->hdir = au_hi(p->parent->d_inode, p->bindex);
  11960. + if (p->hdir)
  11961. + h_dir = p->hdir->hi_inode;
  11962. +
  11963. + /* udba case */
  11964. + if (unlikely(!p->hdir || !h_dir)) {
  11965. + if (!au_ftest_pin(p->flags, DI_LOCKED))
  11966. + di_read_unlock(p->parent, AuLock_IR);
  11967. + dput(p->parent);
  11968. + p->parent = NULL;
  11969. + goto out_err;
  11970. + }
  11971. +
  11972. + au_igrab(h_dir);
  11973. + au_hin_imtx_lock_nested(p->hdir, p->lsc_hi);
  11974. +
  11975. + if (unlikely(p->hdir->hi_inode != h_parent->d_inode)) {
  11976. + err = -EBUSY;
  11977. + goto out_unpin;
  11978. + }
  11979. + if (h_dentry) {
  11980. + err = au_h_verify(h_dentry, p->udba, h_dir, h_parent, br);
  11981. + if (unlikely(err)) {
  11982. + au_fclr_pin(p->flags, MNT_WRITE);
  11983. + goto out_unpin;
  11984. + }
  11985. + }
  11986. +
  11987. + if (au_ftest_pin(p->flags, MNT_WRITE)) {
  11988. + p->h_mnt = br->br_mnt;
  11989. + err = mnt_want_write(p->h_mnt);
  11990. + if (unlikely(err)) {
  11991. + au_fclr_pin(p->flags, MNT_WRITE);
  11992. + goto out_unpin;
  11993. + }
  11994. + }
  11995. + goto out; /* success */
  11996. +
  11997. + out_unpin:
  11998. + au_unpin(p);
  11999. + out_err:
  12000. + AuErr("err %d\n", err);
  12001. + err = au_busy_or_stale();
  12002. + out:
  12003. + return err;
  12004. +}
  12005. +
  12006. +void au_pin_init(struct au_pin *p, struct dentry *dentry,
  12007. + aufs_bindex_t bindex, int lsc_di, int lsc_hi,
  12008. + unsigned int udba, unsigned char flags)
  12009. +{
  12010. + p->dentry = dentry;
  12011. + p->udba = udba;
  12012. + p->lsc_di = lsc_di;
  12013. + p->lsc_hi = lsc_hi;
  12014. + p->flags = flags;
  12015. + p->bindex = bindex;
  12016. +
  12017. + p->parent = NULL;
  12018. + p->hdir = NULL;
  12019. + p->h_mnt = NULL;
  12020. +}
  12021. +
  12022. +int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
  12023. + unsigned int udba, unsigned char flags)
  12024. +{
  12025. + au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
  12026. + udba, flags);
  12027. + return au_do_pin(pin);
  12028. +}
  12029. +
  12030. +/* ---------------------------------------------------------------------- */
  12031. +
  12032. +#define AuIcpup_DID_CPUP 1
  12033. +#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
  12034. +#define au_fset_icpup(flags, name) { (flags) |= AuIcpup_##name; }
  12035. +#define au_fclr_icpup(flags, name) { (flags) &= ~AuIcpup_##name; }
  12036. +
  12037. +struct au_icpup_args {
  12038. + unsigned char flags;
  12039. + unsigned char pin_flags;
  12040. + aufs_bindex_t btgt;
  12041. + struct au_pin pin;
  12042. + struct path h_path;
  12043. + struct inode *h_inode;
  12044. +};
  12045. +
  12046. +static int au_lock_and_icpup(struct dentry *dentry, struct iattr *ia,
  12047. + struct au_icpup_args *a)
  12048. +{
  12049. + int err;
  12050. + unsigned int udba;
  12051. + loff_t sz;
  12052. + aufs_bindex_t bstart;
  12053. + struct dentry *hi_wh, *parent;
  12054. + struct inode *inode;
  12055. + struct au_wr_dir_args wr_dir_args = {
  12056. + .force_btgt = -1,
  12057. + .flags = 0
  12058. + };
  12059. +
  12060. + di_write_lock_child(dentry);
  12061. + bstart = au_dbstart(dentry);
  12062. + inode = dentry->d_inode;
  12063. + if (S_ISDIR(inode->i_mode))
  12064. + au_fset_wrdir(wr_dir_args.flags, ISDIR);
  12065. + /* plink or hi_wh() case */
  12066. + if (bstart != au_ibstart(inode))
  12067. + wr_dir_args.force_btgt = au_ibstart(inode);
  12068. + err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
  12069. + if (unlikely(err < 0))
  12070. + goto out_dentry;
  12071. + a->btgt = err;
  12072. + if (err != bstart)
  12073. + au_fset_icpup(a->flags, DID_CPUP);
  12074. +
  12075. + err = 0;
  12076. + a->pin_flags = AuPin_MNT_WRITE;
  12077. + parent = NULL;
  12078. + if (!IS_ROOT(dentry)) {
  12079. + au_fset_pin(a->pin_flags, DI_LOCKED);
  12080. + parent = dget_parent(dentry);
  12081. + di_write_lock_parent(parent);
  12082. + }
  12083. +
  12084. + udba = au_opt_udba(dentry->d_sb);
  12085. + if (d_unhashed(dentry) || (ia->ia_valid & ATTR_FILE))
  12086. + udba = AuOpt_UDBA_NONE;
  12087. + err = au_pin(&a->pin, dentry, a->btgt, udba, a->pin_flags);
  12088. + if (unlikely(err)) {
  12089. + if (parent) {
  12090. + di_write_unlock(parent);
  12091. + dput(parent);
  12092. + }
  12093. + goto out_dentry;
  12094. + }
  12095. + a->h_path.dentry = au_h_dptr(dentry, bstart);
  12096. + a->h_inode = a->h_path.dentry->d_inode;
  12097. + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
  12098. + sz = -1;
  12099. + if ((ia->ia_valid & ATTR_SIZE) && ia->ia_size < i_size_read(a->h_inode))
  12100. + sz = ia->ia_size;
  12101. +
  12102. + hi_wh = NULL;
  12103. + if (au_ftest_icpup(a->flags, DID_CPUP) && d_unhashed(dentry)) {
  12104. + hi_wh = au_hi_wh(inode, a->btgt);
  12105. + if (!hi_wh) {
  12106. + err = au_sio_cpup_wh(dentry, a->btgt, sz, /*file*/NULL);
  12107. + if (unlikely(err))
  12108. + goto out_unlock;
  12109. + hi_wh = au_hi_wh(inode, a->btgt);
  12110. + /* todo: revalidate hi_wh? */
  12111. + }
  12112. + }
  12113. +
  12114. + if (parent) {
  12115. + au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
  12116. + di_downgrade_lock(parent, AuLock_IR);
  12117. + dput(parent);
  12118. + }
  12119. + if (!au_ftest_icpup(a->flags, DID_CPUP))
  12120. + goto out; /* success */
  12121. +
  12122. + if (!d_unhashed(dentry)) {
  12123. + err = au_sio_cpup_simple(dentry, a->btgt, sz, AuCpup_DTIME);
  12124. + if (!err)
  12125. + a->h_path.dentry = au_h_dptr(dentry, a->btgt);
  12126. + } else if (!hi_wh)
  12127. + a->h_path.dentry = au_h_dptr(dentry, a->btgt);
  12128. + else
  12129. + a->h_path.dentry = hi_wh; /* do not dget here */
  12130. +
  12131. + out_unlock:
  12132. + mutex_unlock(&a->h_inode->i_mutex);
  12133. + a->h_inode = a->h_path.dentry->d_inode;
  12134. + if (!err) {
  12135. + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
  12136. + goto out; /* success */
  12137. + }
  12138. +
  12139. + au_unpin(&a->pin);
  12140. +
  12141. + out_dentry:
  12142. + di_write_unlock(dentry);
  12143. + out:
  12144. + return err;
  12145. +}
  12146. +
  12147. +static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
  12148. +{
  12149. + int err;
  12150. + struct inode *inode;
  12151. + struct super_block *sb;
  12152. + struct file *file;
  12153. + struct au_icpup_args *a;
  12154. +
  12155. + err = -ENOMEM;
  12156. + a = kzalloc(sizeof(*a), GFP_NOFS);
  12157. + if (unlikely(!a))
  12158. + goto out;
  12159. +
  12160. + inode = dentry->d_inode;
  12161. + IMustLock(inode);
  12162. + sb = dentry->d_sb;
  12163. + si_read_lock(sb, AuLock_FLUSH);
  12164. +
  12165. + file = NULL;
  12166. + if (ia->ia_valid & ATTR_FILE) {
  12167. + /* currently ftruncate(2) only */
  12168. + file = ia->ia_file;
  12169. + fi_write_lock(file);
  12170. + ia->ia_file = au_h_fptr(file, au_fbstart(file));
  12171. + }
  12172. +
  12173. + if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
  12174. + ia->ia_valid &= ~ATTR_MODE;
  12175. +
  12176. + err = au_lock_and_icpup(dentry, ia, a);
  12177. + if (unlikely(err < 0))
  12178. + goto out_si;
  12179. + if (au_ftest_icpup(a->flags, DID_CPUP)) {
  12180. + ia->ia_file = NULL;
  12181. + ia->ia_valid &= ~ATTR_FILE;
  12182. + }
  12183. +
  12184. + a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
  12185. + if (ia->ia_valid & ATTR_SIZE) {
  12186. + struct file *f;
  12187. +
  12188. + if (ia->ia_size < i_size_read(inode)) {
  12189. + /* unmap only */
  12190. + err = vmtruncate(inode, ia->ia_size);
  12191. + if (unlikely(err))
  12192. + goto out_unlock;
  12193. + }
  12194. +
  12195. + f = NULL;
  12196. + if (ia->ia_valid & ATTR_FILE)
  12197. + f = ia->ia_file;
  12198. + mutex_unlock(&a->h_inode->i_mutex);
  12199. + err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
  12200. + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
  12201. + } else
  12202. + err = vfsub_notify_change(&a->h_path, ia);
  12203. + if (!err)
  12204. + au_cpup_attr_changeable(inode);
  12205. +
  12206. + out_unlock:
  12207. + mutex_unlock(&a->h_inode->i_mutex);
  12208. + au_unpin(&a->pin);
  12209. + di_write_unlock(dentry);
  12210. + out_si:
  12211. + if (file) {
  12212. + fi_write_unlock(file);
  12213. + ia->ia_file = file;
  12214. + ia->ia_valid |= ATTR_FILE;
  12215. + }
  12216. + si_read_unlock(sb);
  12217. + kfree(a);
  12218. + out:
  12219. + return err;
  12220. +}
  12221. +
  12222. +static int au_getattr_lock_reval(struct dentry *dentry, unsigned int sigen)
  12223. +{
  12224. + int err;
  12225. + struct inode *inode;
  12226. + struct dentry *parent;
  12227. +
  12228. + err = 0;
  12229. + inode = dentry->d_inode;
  12230. + di_write_lock_child(dentry);
  12231. + if (au_digen(dentry) != sigen || au_iigen(inode) != sigen) {
  12232. + parent = dget_parent(dentry);
  12233. + di_read_lock_parent(parent, AuLock_IR);
  12234. + /* returns a number of positive dentries */
  12235. + err = au_refresh_hdentry(dentry, inode->i_mode & S_IFMT);
  12236. + if (err > 0)
  12237. + err = au_refresh_hinode(inode, dentry);
  12238. + di_read_unlock(parent, AuLock_IR);
  12239. + dput(parent);
  12240. + if (unlikely(!err))
  12241. + err = -EIO;
  12242. + }
  12243. + di_downgrade_lock(dentry, AuLock_IR);
  12244. + if (unlikely(err))
  12245. + di_read_unlock(dentry, AuLock_IR);
  12246. +
  12247. + return err;
  12248. +}
  12249. +
  12250. +static void au_refresh_iattr(struct inode *inode, struct kstat *st,
  12251. + unsigned int nlink)
  12252. +{
  12253. + inode->i_mode = st->mode;
  12254. + inode->i_uid = st->uid;
  12255. + inode->i_gid = st->gid;
  12256. + inode->i_atime = st->atime;
  12257. + inode->i_mtime = st->mtime;
  12258. + inode->i_ctime = st->ctime;
  12259. +
  12260. + au_cpup_attr_nlink(inode, /*force*/0);
  12261. + if (S_ISDIR(inode->i_mode)) {
  12262. + inode->i_nlink -= nlink;
  12263. + inode->i_nlink += st->nlink;
  12264. + }
  12265. +
  12266. + spin_lock(&inode->i_lock);
  12267. + inode->i_blocks = st->blocks;
  12268. + i_size_write(inode, st->size);
  12269. + spin_unlock(&inode->i_lock);
  12270. +}
  12271. +
  12272. +static int aufs_getattr(struct vfsmount *mnt __maybe_unused,
  12273. + struct dentry *dentry, struct kstat *st)
  12274. +{
  12275. + int err;
  12276. + unsigned int mnt_flags;
  12277. + aufs_bindex_t bindex;
  12278. + unsigned char udba_none, positive;
  12279. + struct super_block *sb, *h_sb;
  12280. + struct inode *inode;
  12281. + struct vfsmount *h_mnt;
  12282. + struct dentry *h_dentry;
  12283. +
  12284. + err = 0;
  12285. + sb = dentry->d_sb;
  12286. + inode = dentry->d_inode;
  12287. + si_read_lock(sb, AuLock_FLUSH);
  12288. + mnt_flags = au_mntflags(sb);
  12289. + udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
  12290. +
  12291. + /* support fstat(2) */
  12292. + if (!d_unhashed(dentry) && !udba_none) {
  12293. + unsigned int sigen = au_sigen(sb);
  12294. + if (au_digen(dentry) == sigen && au_iigen(inode) == sigen)
  12295. + di_read_lock_child(dentry, AuLock_IR);
  12296. + else {
  12297. + AuDebugOn(!IS_ROOT(dentry));
  12298. + err = au_getattr_lock_reval(dentry, sigen);
  12299. + if (unlikely(err))
  12300. + goto out;
  12301. + }
  12302. + } else
  12303. + di_read_lock_child(dentry, AuLock_IR);
  12304. +
  12305. + bindex = au_ibstart(inode);
  12306. + h_mnt = au_sbr_mnt(sb, bindex);
  12307. + h_sb = h_mnt->mnt_sb;
  12308. + if (!au_test_fs_bad_iattr(h_sb) && udba_none)
  12309. + goto out_fill; /* success */
  12310. +
  12311. + h_dentry = NULL;
  12312. + if (au_dbstart(dentry) == bindex)
  12313. + h_dentry = dget(au_h_dptr(dentry, bindex));
  12314. + else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
  12315. + h_dentry = au_plink_lkup(inode, bindex);
  12316. + if (IS_ERR(h_dentry))
  12317. + goto out_fill; /* pretending success */
  12318. + }
  12319. + /* illegally overlapped or something */
  12320. + if (unlikely(!h_dentry))
  12321. + goto out_fill; /* pretending success */
  12322. +
  12323. + positive = !!h_dentry->d_inode;
  12324. + if (positive)
  12325. + err = vfs_getattr(h_mnt, h_dentry, st);
  12326. + dput(h_dentry);
  12327. + if (!err) {
  12328. + if (positive)
  12329. + au_refresh_iattr(inode, st, h_dentry->d_inode->i_nlink);
  12330. + goto out_fill; /* success */
  12331. + }
  12332. + goto out_unlock;
  12333. +
  12334. + out_fill:
  12335. + generic_fillattr(inode, st);
  12336. + out_unlock:
  12337. + di_read_unlock(dentry, AuLock_IR);
  12338. + out:
  12339. + si_read_unlock(sb);
  12340. + return err;
  12341. +}
  12342. +
  12343. +/* ---------------------------------------------------------------------- */
  12344. +
  12345. +static int h_readlink(struct dentry *dentry, int bindex, char __user *buf,
  12346. + int bufsiz)
  12347. +{
  12348. + int err;
  12349. + struct super_block *sb;
  12350. + struct dentry *h_dentry;
  12351. +
  12352. + err = -EINVAL;
  12353. + h_dentry = au_h_dptr(dentry, bindex);
  12354. + if (unlikely(/* !h_dentry
  12355. + || !h_dentry->d_inode
  12356. + || !h_dentry->d_inode->i_op
  12357. + || */ !h_dentry->d_inode->i_op->readlink))
  12358. + goto out;
  12359. +
  12360. + err = security_inode_readlink(h_dentry);
  12361. + if (unlikely(err))
  12362. + goto out;
  12363. +
  12364. + sb = dentry->d_sb;
  12365. + if (!au_test_ro(sb, bindex, dentry->d_inode)) {
  12366. + vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry);
  12367. + fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode);
  12368. + }
  12369. + err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz);
  12370. +
  12371. + out:
  12372. + return err;
  12373. +}
  12374. +
  12375. +static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
  12376. +{
  12377. + int err;
  12378. +
  12379. + aufs_read_lock(dentry, AuLock_IR);
  12380. + err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz);
  12381. + aufs_read_unlock(dentry, AuLock_IR);
  12382. +
  12383. + return err;
  12384. +}
  12385. +
  12386. +static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd)
  12387. +{
  12388. + int err;
  12389. + char *buf;
  12390. + mm_segment_t old_fs;
  12391. +
  12392. + err = -ENOMEM;
  12393. + buf = __getname();
  12394. + if (unlikely(!buf))
  12395. + goto out;
  12396. +
  12397. + aufs_read_lock(dentry, AuLock_IR);
  12398. + old_fs = get_fs();
  12399. + set_fs(KERNEL_DS);
  12400. + err = h_readlink(dentry, au_dbstart(dentry), (char __user *)buf,
  12401. + PATH_MAX);
  12402. + set_fs(old_fs);
  12403. + aufs_read_unlock(dentry, AuLock_IR);
  12404. +
  12405. + if (err >= 0) {
  12406. + buf[err] = 0;
  12407. + /* will be freed by put_link */
  12408. + nd_set_link(nd, buf);
  12409. + return NULL; /* success */
  12410. + }
  12411. + __putname(buf);
  12412. +
  12413. + out:
  12414. + path_put(&nd->path);
  12415. + AuTraceErr(err);
  12416. + return ERR_PTR(err);
  12417. +}
  12418. +
  12419. +static void aufs_put_link(struct dentry *dentry __maybe_unused,
  12420. + struct nameidata *nd, void *cookie __maybe_unused)
  12421. +{
  12422. + __putname(nd_get_link(nd));
  12423. +}
  12424. +
  12425. +/* ---------------------------------------------------------------------- */
  12426. +
  12427. +static void aufs_truncate_range(struct inode *inode __maybe_unused,
  12428. + loff_t start __maybe_unused,
  12429. + loff_t end __maybe_unused)
  12430. +{
  12431. + AuUnsupport();
  12432. +}
  12433. +
  12434. +/* ---------------------------------------------------------------------- */
  12435. +
  12436. +struct inode_operations aufs_symlink_iop = {
  12437. + .permission = aufs_permission,
  12438. + .setattr = aufs_setattr,
  12439. + .getattr = aufs_getattr,
  12440. + .readlink = aufs_readlink,
  12441. + .follow_link = aufs_follow_link,
  12442. + .put_link = aufs_put_link
  12443. +};
  12444. +
  12445. +struct inode_operations aufs_dir_iop = {
  12446. + .create = aufs_create,
  12447. + .lookup = aufs_lookup,
  12448. + .link = aufs_link,
  12449. + .unlink = aufs_unlink,
  12450. + .symlink = aufs_symlink,
  12451. + .mkdir = aufs_mkdir,
  12452. + .rmdir = aufs_rmdir,
  12453. + .mknod = aufs_mknod,
  12454. + .rename = aufs_rename,
  12455. +
  12456. + .permission = aufs_permission,
  12457. + .setattr = aufs_setattr,
  12458. + .getattr = aufs_getattr
  12459. +};
  12460. +
  12461. +struct inode_operations aufs_iop = {
  12462. + .permission = aufs_permission,
  12463. + .setattr = aufs_setattr,
  12464. + .getattr = aufs_getattr,
  12465. + .truncate_range = aufs_truncate_range
  12466. +};
  12467. diff -Nur linux-2.6.34.orig/fs/aufs/i_op_del.c linux-2.6.34/fs/aufs/i_op_del.c
  12468. --- linux-2.6.34.orig/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
  12469. +++ linux-2.6.34/fs/aufs/i_op_del.c 2010-05-23 23:33:20.563473113 +0200
  12470. @@ -0,0 +1,468 @@
  12471. +/*
  12472. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  12473. + *
  12474. + * This program, aufs is free software; you can redistribute it and/or modify
  12475. + * it under the terms of the GNU General Public License as published by
  12476. + * the Free Software Foundation; either version 2 of the License, or
  12477. + * (at your option) any later version.
  12478. + *
  12479. + * This program is distributed in the hope that it will be useful,
  12480. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12481. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12482. + * GNU General Public License for more details.
  12483. + *
  12484. + * You should have received a copy of the GNU General Public License
  12485. + * along with this program; if not, write to the Free Software
  12486. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  12487. + */
  12488. +
  12489. +/*
  12490. + * inode operations (del entry)
  12491. + */
  12492. +
  12493. +#include "aufs.h"
  12494. +
  12495. +/*
  12496. + * decide if a new whiteout for @dentry is necessary or not.
  12497. + * when it is necessary, prepare the parent dir for the upper branch whose
  12498. + * branch index is @bcpup for creation. the actual creation of the whiteout will
  12499. + * be done by caller.
  12500. + * return value:
  12501. + * 0: wh is unnecessary
  12502. + * plus: wh is necessary
  12503. + * minus: error
  12504. + */
  12505. +int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
  12506. +{
  12507. + int need_wh, err;
  12508. + aufs_bindex_t bstart;
  12509. + struct super_block *sb;
  12510. +
  12511. + sb = dentry->d_sb;
  12512. + bstart = au_dbstart(dentry);
  12513. + if (*bcpup < 0) {
  12514. + *bcpup = bstart;
  12515. + if (au_test_ro(sb, bstart, dentry->d_inode)) {
  12516. + err = AuWbrCopyup(au_sbi(sb), dentry);
  12517. + *bcpup = err;
  12518. + if (unlikely(err < 0))
  12519. + goto out;
  12520. + }
  12521. + } else
  12522. + AuDebugOn(bstart < *bcpup
  12523. + || au_test_ro(sb, *bcpup, dentry->d_inode));
  12524. + AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
  12525. +
  12526. + if (*bcpup != bstart) {
  12527. + err = au_cpup_dirs(dentry, *bcpup);
  12528. + if (unlikely(err))
  12529. + goto out;
  12530. + need_wh = 1;
  12531. + } else {
  12532. + aufs_bindex_t old_bend, new_bend, bdiropq = -1;
  12533. +
  12534. + old_bend = au_dbend(dentry);
  12535. + if (isdir) {
  12536. + bdiropq = au_dbdiropq(dentry);
  12537. + au_set_dbdiropq(dentry, -1);
  12538. + }
  12539. + need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0,
  12540. + /*nd*/NULL);
  12541. + err = need_wh;
  12542. + if (isdir)
  12543. + au_set_dbdiropq(dentry, bdiropq);
  12544. + if (unlikely(err < 0))
  12545. + goto out;
  12546. + new_bend = au_dbend(dentry);
  12547. + if (!need_wh && old_bend != new_bend) {
  12548. + au_set_h_dptr(dentry, new_bend, NULL);
  12549. + au_set_dbend(dentry, old_bend);
  12550. + }
  12551. + }
  12552. + AuDbg("need_wh %d\n", need_wh);
  12553. + err = need_wh;
  12554. +
  12555. + out:
  12556. + return err;
  12557. +}
  12558. +
  12559. +/*
  12560. + * simple tests for the del-entry operations.
  12561. + * following the checks in vfs, plus the parent-child relationship.
  12562. + */
  12563. +int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
  12564. + struct dentry *h_parent, int isdir)
  12565. +{
  12566. + int err;
  12567. + umode_t h_mode;
  12568. + struct dentry *h_dentry, *h_latest;
  12569. + struct inode *h_inode;
  12570. +
  12571. + h_dentry = au_h_dptr(dentry, bindex);
  12572. + h_inode = h_dentry->d_inode;
  12573. + if (dentry->d_inode) {
  12574. + err = -ENOENT;
  12575. + if (unlikely(!h_inode || !h_inode->i_nlink))
  12576. + goto out;
  12577. +
  12578. + h_mode = h_inode->i_mode;
  12579. + if (!isdir) {
  12580. + err = -EISDIR;
  12581. + if (unlikely(S_ISDIR(h_mode)))
  12582. + goto out;
  12583. + } else if (unlikely(!S_ISDIR(h_mode))) {
  12584. + err = -ENOTDIR;
  12585. + goto out;
  12586. + }
  12587. + } else {
  12588. + /* rename(2) case */
  12589. + err = -EIO;
  12590. + if (unlikely(h_inode))
  12591. + goto out;
  12592. + }
  12593. +
  12594. + err = -ENOENT;
  12595. + /* expected parent dir is locked */
  12596. + if (unlikely(h_parent != h_dentry->d_parent))
  12597. + goto out;
  12598. + err = 0;
  12599. +
  12600. + /*
  12601. + * rmdir a dir may break the consistency on some filesystem.
  12602. + * let's try heavy test.
  12603. + */
  12604. + err = -EACCES;
  12605. + if (unlikely(au_test_h_perm(h_parent->d_inode, MAY_EXEC | MAY_WRITE)))
  12606. + goto out;
  12607. +
  12608. + h_latest = au_sio_lkup_one(&dentry->d_name, h_parent,
  12609. + au_sbr(dentry->d_sb, bindex));
  12610. + err = -EIO;
  12611. + if (IS_ERR(h_latest))
  12612. + goto out;
  12613. + if (h_latest == h_dentry)
  12614. + err = 0;
  12615. + dput(h_latest);
  12616. +
  12617. + out:
  12618. + return err;
  12619. +}
  12620. +
  12621. +/*
  12622. + * decide the branch where we operate for @dentry. the branch index will be set
  12623. + * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
  12624. + * dir for reverting.
  12625. + * when a new whiteout is necessary, create it.
  12626. + */
  12627. +static struct dentry*
  12628. +lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
  12629. + struct au_dtime *dt, struct au_pin *pin)
  12630. +{
  12631. + struct dentry *wh_dentry;
  12632. + struct super_block *sb;
  12633. + struct path h_path;
  12634. + int err, need_wh;
  12635. + unsigned int udba;
  12636. + aufs_bindex_t bcpup;
  12637. +
  12638. + need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
  12639. + wh_dentry = ERR_PTR(need_wh);
  12640. + if (unlikely(need_wh < 0))
  12641. + goto out;
  12642. +
  12643. + sb = dentry->d_sb;
  12644. + udba = au_opt_udba(sb);
  12645. + bcpup = *rbcpup;
  12646. + err = au_pin(pin, dentry, bcpup, udba,
  12647. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  12648. + wh_dentry = ERR_PTR(err);
  12649. + if (unlikely(err))
  12650. + goto out;
  12651. +
  12652. + h_path.dentry = au_pinned_h_parent(pin);
  12653. + if (udba != AuOpt_UDBA_NONE
  12654. + && au_dbstart(dentry) == bcpup) {
  12655. + err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
  12656. + wh_dentry = ERR_PTR(err);
  12657. + if (unlikely(err))
  12658. + goto out_unpin;
  12659. + }
  12660. +
  12661. + h_path.mnt = au_sbr_mnt(sb, bcpup);
  12662. + au_dtime_store(dt, au_pinned_parent(pin), &h_path);
  12663. + wh_dentry = NULL;
  12664. + if (!need_wh)
  12665. + goto out; /* success, no need to create whiteout */
  12666. +
  12667. + wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
  12668. + if (!IS_ERR(wh_dentry))
  12669. + goto out; /* success */
  12670. + /* returns with the parent is locked and wh_dentry is dget-ed */
  12671. +
  12672. + out_unpin:
  12673. + au_unpin(pin);
  12674. + out:
  12675. + return wh_dentry;
  12676. +}
  12677. +
  12678. +/*
  12679. + * when removing a dir, rename it to a unique temporary whiteout-ed name first
  12680. + * in order to be revertible and save time for removing many child whiteouts
  12681. + * under the dir.
  12682. + * returns 1 when there are too many child whiteout and caller should remove
  12683. + * them asynchronously. returns 0 when the number of children is enough small to
  12684. + * remove now or the branch fs is a remote fs.
  12685. + * otherwise return an error.
  12686. + */
  12687. +static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
  12688. + struct au_nhash *whlist, struct inode *dir)
  12689. +{
  12690. + int rmdir_later, err, dirwh;
  12691. + struct dentry *h_dentry;
  12692. + struct super_block *sb;
  12693. +
  12694. + sb = dentry->d_sb;
  12695. + SiMustAnyLock(sb);
  12696. + h_dentry = au_h_dptr(dentry, bindex);
  12697. + err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
  12698. + if (unlikely(err))
  12699. + goto out;
  12700. +
  12701. + /* stop monitoring */
  12702. + au_hin_free(au_hi(dentry->d_inode, bindex));
  12703. +
  12704. + if (!au_test_fs_remote(h_dentry->d_sb)) {
  12705. + dirwh = au_sbi(sb)->si_dirwh;
  12706. + rmdir_later = (dirwh <= 1);
  12707. + if (!rmdir_later)
  12708. + rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
  12709. + dirwh);
  12710. + if (rmdir_later)
  12711. + return rmdir_later;
  12712. + }
  12713. +
  12714. + err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
  12715. + if (unlikely(err)) {
  12716. + AuIOErr("rmdir %.*s, b%d failed, %d. ignored\n",
  12717. + AuDLNPair(h_dentry), bindex, err);
  12718. + err = 0;
  12719. + }
  12720. +
  12721. + out:
  12722. + return err;
  12723. +}
  12724. +
  12725. +/*
  12726. + * final procedure for deleting a entry.
  12727. + * maintain dentry and iattr.
  12728. + */
  12729. +static void epilog(struct inode *dir, struct dentry *dentry,
  12730. + aufs_bindex_t bindex)
  12731. +{
  12732. + struct inode *inode;
  12733. +
  12734. + inode = dentry->d_inode;
  12735. + d_drop(dentry);
  12736. + inode->i_ctime = dir->i_ctime;
  12737. +
  12738. + if (atomic_read(&dentry->d_count) == 1) {
  12739. + au_set_h_dptr(dentry, au_dbstart(dentry), NULL);
  12740. + au_update_dbstart(dentry);
  12741. + }
  12742. + if (au_ibstart(dir) == bindex)
  12743. + au_cpup_attr_timesizes(dir);
  12744. + dir->i_version++;
  12745. +}
  12746. +
  12747. +/*
  12748. + * when an error happened, remove the created whiteout and revert everything.
  12749. + */
  12750. +static int do_revert(int err, struct inode *dir, aufs_bindex_t bwh,
  12751. + struct dentry *wh_dentry, struct dentry *dentry,
  12752. + struct au_dtime *dt)
  12753. +{
  12754. + int rerr;
  12755. + struct path h_path = {
  12756. + .dentry = wh_dentry,
  12757. + .mnt = au_sbr_mnt(dir->i_sb, bwh)
  12758. + };
  12759. +
  12760. + rerr = au_wh_unlink_dentry(au_h_iptr(dir, bwh), &h_path, dentry);
  12761. + if (!rerr) {
  12762. + au_set_dbwh(dentry, bwh);
  12763. + au_dtime_revert(dt);
  12764. + return 0;
  12765. + }
  12766. +
  12767. + AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
  12768. + AuDLNPair(dentry), err, rerr);
  12769. + return -EIO;
  12770. +}
  12771. +
  12772. +/* ---------------------------------------------------------------------- */
  12773. +
  12774. +int aufs_unlink(struct inode *dir, struct dentry *dentry)
  12775. +{
  12776. + int err;
  12777. + aufs_bindex_t bwh, bindex, bstart;
  12778. + struct au_dtime dt;
  12779. + struct au_pin pin;
  12780. + struct path h_path;
  12781. + struct inode *inode, *h_dir;
  12782. + struct dentry *parent, *wh_dentry;
  12783. +
  12784. + IMustLock(dir);
  12785. + inode = dentry->d_inode;
  12786. + if (unlikely(!inode))
  12787. + return -ENOENT; /* possible? */
  12788. + IMustLock(inode);
  12789. +
  12790. + aufs_read_lock(dentry, AuLock_DW);
  12791. + parent = dentry->d_parent; /* dir inode is locked */
  12792. + di_write_lock_parent(parent);
  12793. +
  12794. + bstart = au_dbstart(dentry);
  12795. + bwh = au_dbwh(dentry);
  12796. + bindex = -1;
  12797. + wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt, &pin);
  12798. + err = PTR_ERR(wh_dentry);
  12799. + if (IS_ERR(wh_dentry))
  12800. + goto out;
  12801. +
  12802. + h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
  12803. + h_path.dentry = au_h_dptr(dentry, bstart);
  12804. + dget(h_path.dentry);
  12805. + if (bindex == bstart) {
  12806. + h_dir = au_pinned_h_dir(&pin);
  12807. + err = vfsub_unlink(h_dir, &h_path, /*force*/0);
  12808. + } else {
  12809. + /* dir inode is locked */
  12810. + h_dir = wh_dentry->d_parent->d_inode;
  12811. + IMustLock(h_dir);
  12812. + err = 0;
  12813. + }
  12814. +
  12815. + if (!err) {
  12816. + drop_nlink(inode);
  12817. + epilog(dir, dentry, bindex);
  12818. +
  12819. + /* update target timestamps */
  12820. + if (bindex == bstart) {
  12821. + vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
  12822. + inode->i_ctime = h_path.dentry->d_inode->i_ctime;
  12823. + } else
  12824. + /* todo: this timestamp may be reverted later */
  12825. + inode->i_ctime = h_dir->i_ctime;
  12826. + goto out_unlock; /* success */
  12827. + }
  12828. +
  12829. + /* revert */
  12830. + if (wh_dentry) {
  12831. + int rerr;
  12832. +
  12833. + rerr = do_revert(err, dir, bwh, wh_dentry, dentry, &dt);
  12834. + if (rerr)
  12835. + err = rerr;
  12836. + }
  12837. +
  12838. + out_unlock:
  12839. + au_unpin(&pin);
  12840. + dput(wh_dentry);
  12841. + dput(h_path.dentry);
  12842. + out:
  12843. + di_write_unlock(parent);
  12844. + aufs_read_unlock(dentry, AuLock_DW);
  12845. + return err;
  12846. +}
  12847. +
  12848. +int aufs_rmdir(struct inode *dir, struct dentry *dentry)
  12849. +{
  12850. + int err, rmdir_later;
  12851. + aufs_bindex_t bwh, bindex, bstart;
  12852. + struct au_dtime dt;
  12853. + struct au_pin pin;
  12854. + struct inode *inode;
  12855. + struct dentry *parent, *wh_dentry, *h_dentry;
  12856. + struct au_whtmp_rmdir *args;
  12857. +
  12858. + IMustLock(dir);
  12859. + inode = dentry->d_inode;
  12860. + err = -ENOENT; /* possible? */
  12861. + if (unlikely(!inode))
  12862. + goto out;
  12863. + IMustLock(inode);
  12864. +
  12865. + aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH);
  12866. + err = -ENOMEM;
  12867. + args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
  12868. + if (unlikely(!args))
  12869. + goto out_unlock;
  12870. +
  12871. + parent = dentry->d_parent; /* dir inode is locked */
  12872. + di_write_lock_parent(parent);
  12873. + err = au_test_empty(dentry, &args->whlist);
  12874. + if (unlikely(err))
  12875. + goto out_args;
  12876. +
  12877. + bstart = au_dbstart(dentry);
  12878. + bwh = au_dbwh(dentry);
  12879. + bindex = -1;
  12880. + wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &dt, &pin);
  12881. + err = PTR_ERR(wh_dentry);
  12882. + if (IS_ERR(wh_dentry))
  12883. + goto out_args;
  12884. +
  12885. + h_dentry = au_h_dptr(dentry, bstart);
  12886. + dget(h_dentry);
  12887. + rmdir_later = 0;
  12888. + if (bindex == bstart) {
  12889. + err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir);
  12890. + if (err > 0) {
  12891. + rmdir_later = err;
  12892. + err = 0;
  12893. + }
  12894. + } else {
  12895. + /* stop monitoring */
  12896. + au_hin_free(au_hi(inode, bstart));
  12897. +
  12898. + /* dir inode is locked */
  12899. + IMustLock(wh_dentry->d_parent->d_inode);
  12900. + err = 0;
  12901. + }
  12902. +
  12903. + if (!err) {
  12904. + clear_nlink(inode);
  12905. + au_set_dbdiropq(dentry, -1);
  12906. + epilog(dir, dentry, bindex);
  12907. +
  12908. + if (rmdir_later) {
  12909. + au_whtmp_kick_rmdir(dir, bstart, h_dentry, args);
  12910. + args = NULL;
  12911. + }
  12912. +
  12913. + goto out_unpin; /* success */
  12914. + }
  12915. +
  12916. + /* revert */
  12917. + AuLabel(revert);
  12918. + if (wh_dentry) {
  12919. + int rerr;
  12920. +
  12921. + rerr = do_revert(err, dir, bwh, wh_dentry, dentry, &dt);
  12922. + if (rerr)
  12923. + err = rerr;
  12924. + }
  12925. +
  12926. + out_unpin:
  12927. + au_unpin(&pin);
  12928. + dput(wh_dentry);
  12929. + dput(h_dentry);
  12930. + out_args:
  12931. + di_write_unlock(parent);
  12932. + if (args)
  12933. + au_whtmp_rmdir_free(args);
  12934. + out_unlock:
  12935. + aufs_read_unlock(dentry, AuLock_DW);
  12936. + out:
  12937. + return err;
  12938. +}
  12939. diff -Nur linux-2.6.34.orig/fs/aufs/i_op_ren.c linux-2.6.34/fs/aufs/i_op_ren.c
  12940. --- linux-2.6.34.orig/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
  12941. +++ linux-2.6.34/fs/aufs/i_op_ren.c 2010-05-23 23:33:20.600964691 +0200
  12942. @@ -0,0 +1,948 @@
  12943. +/*
  12944. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  12945. + *
  12946. + * This program, aufs is free software; you can redistribute it and/or modify
  12947. + * it under the terms of the GNU General Public License as published by
  12948. + * the Free Software Foundation; either version 2 of the License, or
  12949. + * (at your option) any later version.
  12950. + *
  12951. + * This program is distributed in the hope that it will be useful,
  12952. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12953. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12954. + * GNU General Public License for more details.
  12955. + *
  12956. + * You should have received a copy of the GNU General Public License
  12957. + * along with this program; if not, write to the Free Software
  12958. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  12959. + */
  12960. +
  12961. +/*
  12962. + * inode operation (rename entry)
  12963. + * todo: this is crazy monster
  12964. + */
  12965. +
  12966. +#include "aufs.h"
  12967. +
  12968. +enum { AuSRC, AuDST, AuSrcDst };
  12969. +enum { AuPARENT, AuCHILD, AuParentChild };
  12970. +
  12971. +#define AuRen_ISDIR 1
  12972. +#define AuRen_ISSAMEDIR (1 << 1)
  12973. +#define AuRen_WHSRC (1 << 2)
  12974. +#define AuRen_WHDST (1 << 3)
  12975. +#define AuRen_MNT_WRITE (1 << 4)
  12976. +#define AuRen_DT_DSTDIR (1 << 5)
  12977. +#define AuRen_DIROPQ (1 << 6)
  12978. +#define AuRen_CPUP (1 << 7)
  12979. +#define au_ftest_ren(flags, name) ((flags) & AuRen_##name)
  12980. +#define au_fset_ren(flags, name) { (flags) |= AuRen_##name; }
  12981. +#define au_fclr_ren(flags, name) { (flags) &= ~AuRen_##name; }
  12982. +
  12983. +struct au_ren_args {
  12984. + struct {
  12985. + struct dentry *dentry, *h_dentry, *parent, *h_parent,
  12986. + *wh_dentry;
  12987. + struct inode *dir, *inode;
  12988. + struct au_hinode *hdir;
  12989. + struct au_dtime dt[AuParentChild];
  12990. + aufs_bindex_t bstart;
  12991. + } sd[AuSrcDst];
  12992. +
  12993. +#define src_dentry sd[AuSRC].dentry
  12994. +#define src_dir sd[AuSRC].dir
  12995. +#define src_inode sd[AuSRC].inode
  12996. +#define src_h_dentry sd[AuSRC].h_dentry
  12997. +#define src_parent sd[AuSRC].parent
  12998. +#define src_h_parent sd[AuSRC].h_parent
  12999. +#define src_wh_dentry sd[AuSRC].wh_dentry
  13000. +#define src_hdir sd[AuSRC].hdir
  13001. +#define src_h_dir sd[AuSRC].hdir->hi_inode
  13002. +#define src_dt sd[AuSRC].dt
  13003. +#define src_bstart sd[AuSRC].bstart
  13004. +
  13005. +#define dst_dentry sd[AuDST].dentry
  13006. +#define dst_dir sd[AuDST].dir
  13007. +#define dst_inode sd[AuDST].inode
  13008. +#define dst_h_dentry sd[AuDST].h_dentry
  13009. +#define dst_parent sd[AuDST].parent
  13010. +#define dst_h_parent sd[AuDST].h_parent
  13011. +#define dst_wh_dentry sd[AuDST].wh_dentry
  13012. +#define dst_hdir sd[AuDST].hdir
  13013. +#define dst_h_dir sd[AuDST].hdir->hi_inode
  13014. +#define dst_dt sd[AuDST].dt
  13015. +#define dst_bstart sd[AuDST].bstart
  13016. +
  13017. + struct dentry *h_trap;
  13018. + struct au_branch *br;
  13019. + struct au_hinode *src_hinode;
  13020. + struct path h_path;
  13021. + struct au_nhash whlist;
  13022. + aufs_bindex_t btgt;
  13023. +
  13024. + unsigned int flags;
  13025. +
  13026. + struct au_whtmp_rmdir *thargs;
  13027. + struct dentry *h_dst;
  13028. +};
  13029. +
  13030. +/* ---------------------------------------------------------------------- */
  13031. +
  13032. +/*
  13033. + * functions for reverting.
  13034. + * when an error happened in a single rename systemcall, we should revert
  13035. + * everything as if nothing happend.
  13036. + * we don't need to revert the copied-up/down the parent dir since they are
  13037. + * harmless.
  13038. + */
  13039. +
  13040. +#define RevertFailure(fmt, args...) do { \
  13041. + AuIOErr("revert failure: " fmt " (%d, %d)\n", \
  13042. + ##args, err, rerr); \
  13043. + err = -EIO; \
  13044. +} while (0)
  13045. +
  13046. +static void au_ren_rev_diropq(int err, struct au_ren_args *a)
  13047. +{
  13048. + int rerr;
  13049. +
  13050. + au_hin_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
  13051. + rerr = au_diropq_remove(a->src_dentry, a->btgt);
  13052. + au_hin_imtx_unlock(a->src_hinode);
  13053. + if (rerr)
  13054. + RevertFailure("remove diropq %.*s", AuDLNPair(a->src_dentry));
  13055. +}
  13056. +
  13057. +
  13058. +static void au_ren_rev_rename(int err, struct au_ren_args *a)
  13059. +{
  13060. + int rerr;
  13061. +
  13062. + a->h_path.dentry = au_lkup_one(&a->src_dentry->d_name, a->src_h_parent,
  13063. + a->br, /*nd*/NULL);
  13064. + rerr = PTR_ERR(a->h_path.dentry);
  13065. + if (IS_ERR(a->h_path.dentry)) {
  13066. + RevertFailure("au_lkup_one %.*s", AuDLNPair(a->src_dentry));
  13067. + return;
  13068. + }
  13069. +
  13070. + rerr = vfsub_rename(a->dst_h_dir,
  13071. + au_h_dptr(a->src_dentry, a->btgt),
  13072. + a->src_h_dir, &a->h_path);
  13073. + d_drop(a->h_path.dentry);
  13074. + dput(a->h_path.dentry);
  13075. + /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
  13076. + if (rerr)
  13077. + RevertFailure("rename %.*s", AuDLNPair(a->src_dentry));
  13078. +}
  13079. +
  13080. +static void au_ren_rev_cpup(int err, struct au_ren_args *a)
  13081. +{
  13082. + int rerr;
  13083. +
  13084. + a->h_path.dentry = a->dst_h_dentry;
  13085. + rerr = vfsub_unlink(a->dst_h_dir, &a->h_path, /*force*/0);
  13086. + au_set_h_dptr(a->src_dentry, a->btgt, NULL);
  13087. + au_set_dbstart(a->src_dentry, a->src_bstart);
  13088. + if (rerr)
  13089. + RevertFailure("unlink %.*s", AuDLNPair(a->dst_h_dentry));
  13090. +}
  13091. +
  13092. +
  13093. +static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
  13094. +{
  13095. + int rerr;
  13096. +
  13097. + a->h_path.dentry = au_lkup_one(&a->dst_dentry->d_name, a->dst_h_parent,
  13098. + a->br, /*nd*/NULL);
  13099. + rerr = PTR_ERR(a->h_path.dentry);
  13100. + if (IS_ERR(a->h_path.dentry)) {
  13101. + RevertFailure("lookup %.*s", AuDLNPair(a->dst_dentry));
  13102. + return;
  13103. + }
  13104. + if (a->h_path.dentry->d_inode) {
  13105. + d_drop(a->h_path.dentry);
  13106. + dput(a->h_path.dentry);
  13107. + return;
  13108. + }
  13109. +
  13110. + rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path);
  13111. + d_drop(a->h_path.dentry);
  13112. + dput(a->h_path.dentry);
  13113. + if (!rerr) {
  13114. + au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
  13115. + au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
  13116. + } else
  13117. + RevertFailure("rename %.*s", AuDLNPair(a->h_dst));
  13118. +}
  13119. +
  13120. +static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
  13121. +{
  13122. + int rerr;
  13123. +
  13124. + a->h_path.dentry = a->src_wh_dentry;
  13125. + rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
  13126. + if (rerr)
  13127. + RevertFailure("unlink %.*s", AuDLNPair(a->src_wh_dentry));
  13128. +}
  13129. +
  13130. +static void au_ren_rev_drop(struct au_ren_args *a)
  13131. +{
  13132. + struct dentry *d, *h_d;
  13133. + int i;
  13134. + aufs_bindex_t bend, bindex;
  13135. +
  13136. + for (i = 0; i < AuSrcDst; i++) {
  13137. + d = a->sd[i].dentry;
  13138. + d_drop(d);
  13139. + bend = au_dbend(d);
  13140. + for (bindex = au_dbstart(d); bindex <= bend; bindex++) {
  13141. + h_d = au_h_dptr(d, bindex);
  13142. + if (h_d)
  13143. + d_drop(h_d);
  13144. + }
  13145. + }
  13146. +
  13147. + au_update_dbstart(a->dst_dentry);
  13148. + if (a->thargs)
  13149. + d_drop(a->h_dst);
  13150. +}
  13151. +#undef RevertFailure
  13152. +
  13153. +/* ---------------------------------------------------------------------- */
  13154. +
  13155. +/*
  13156. + * when we have to copyup the renaming entry, do it with the rename-target name
  13157. + * in order to minimize the cost (the later actual rename is unnecessary).
  13158. + * otherwise rename it on the target branch.
  13159. + */
  13160. +static int au_ren_or_cpup(struct au_ren_args *a)
  13161. +{
  13162. + int err;
  13163. + struct dentry *d;
  13164. +
  13165. + d = a->src_dentry;
  13166. + if (au_dbstart(d) == a->btgt) {
  13167. + a->h_path.dentry = a->dst_h_dentry;
  13168. + if (au_ftest_ren(a->flags, DIROPQ)
  13169. + && au_dbdiropq(d) == a->btgt)
  13170. + au_fclr_ren(a->flags, DIROPQ);
  13171. + AuDebugOn(au_dbstart(d) != a->btgt);
  13172. + err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
  13173. + a->dst_h_dir, &a->h_path);
  13174. + } else {
  13175. + struct mutex *h_mtx = &a->src_h_dentry->d_inode->i_mutex;
  13176. +
  13177. + au_fset_ren(a->flags, CPUP);
  13178. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  13179. + au_set_dbstart(d, a->btgt);
  13180. + au_set_h_dptr(d, a->btgt, dget(a->dst_h_dentry));
  13181. + err = au_sio_cpup_single(d, a->btgt, a->src_bstart, -1,
  13182. + !AuCpup_DTIME, a->dst_parent);
  13183. + if (unlikely(err)) {
  13184. + au_set_h_dptr(d, a->btgt, NULL);
  13185. + au_set_dbstart(d, a->src_bstart);
  13186. + }
  13187. + mutex_unlock(h_mtx);
  13188. + }
  13189. +
  13190. + return err;
  13191. +}
  13192. +
  13193. +/* cf. aufs_rmdir() */
  13194. +static int au_ren_del_whtmp(struct au_ren_args *a)
  13195. +{
  13196. + int err;
  13197. + struct inode *dir;
  13198. +
  13199. + dir = a->dst_dir;
  13200. + SiMustAnyLock(dir->i_sb);
  13201. + if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
  13202. + au_sbi(dir->i_sb)->si_dirwh)
  13203. + || au_test_fs_remote(a->h_dst->d_sb)) {
  13204. + err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
  13205. + if (unlikely(err))
  13206. + AuWarn("failed removing whtmp dir %.*s (%d), "
  13207. + "ignored.\n", AuDLNPair(a->h_dst), err);
  13208. + } else {
  13209. + au_nhash_wh_free(&a->thargs->whlist);
  13210. + a->thargs->whlist = a->whlist;
  13211. + a->whlist.nh_num = 0;
  13212. + au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
  13213. + dput(a->h_dst);
  13214. + a->thargs = NULL;
  13215. + }
  13216. +
  13217. + return 0;
  13218. +}
  13219. +
  13220. +/* make it 'opaque' dir. */
  13221. +static int au_ren_diropq(struct au_ren_args *a)
  13222. +{
  13223. + int err;
  13224. + struct dentry *diropq;
  13225. +
  13226. + err = 0;
  13227. + a->src_hinode = au_hi(a->src_inode, a->btgt);
  13228. + au_hin_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
  13229. + diropq = au_diropq_create(a->src_dentry, a->btgt);
  13230. + au_hin_imtx_unlock(a->src_hinode);
  13231. + if (IS_ERR(diropq))
  13232. + err = PTR_ERR(diropq);
  13233. + dput(diropq);
  13234. +
  13235. + return err;
  13236. +}
  13237. +
  13238. +static int do_rename(struct au_ren_args *a)
  13239. +{
  13240. + int err;
  13241. + struct dentry *d, *h_d;
  13242. +
  13243. + /* prepare workqueue args for asynchronous rmdir */
  13244. + h_d = a->dst_h_dentry;
  13245. + if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) {
  13246. + err = -ENOMEM;
  13247. + a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS);
  13248. + if (unlikely(!a->thargs))
  13249. + goto out;
  13250. + a->h_dst = dget(h_d);
  13251. + }
  13252. +
  13253. + /* create whiteout for src_dentry */
  13254. + if (au_ftest_ren(a->flags, WHSRC)) {
  13255. + a->src_wh_dentry
  13256. + = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent);
  13257. + err = PTR_ERR(a->src_wh_dentry);
  13258. + if (IS_ERR(a->src_wh_dentry))
  13259. + goto out_thargs;
  13260. + }
  13261. +
  13262. + /* lookup whiteout for dentry */
  13263. + if (au_ftest_ren(a->flags, WHDST)) {
  13264. + h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name,
  13265. + a->br);
  13266. + err = PTR_ERR(h_d);
  13267. + if (IS_ERR(h_d))
  13268. + goto out_whsrc;
  13269. + if (!h_d->d_inode)
  13270. + dput(h_d);
  13271. + else
  13272. + a->dst_wh_dentry = h_d;
  13273. + }
  13274. +
  13275. + /* rename dentry to tmpwh */
  13276. + if (a->thargs) {
  13277. + err = au_whtmp_ren(a->dst_h_dentry, a->br);
  13278. + if (unlikely(err))
  13279. + goto out_whdst;
  13280. +
  13281. + d = a->dst_dentry;
  13282. + au_set_h_dptr(d, a->btgt, NULL);
  13283. + err = au_lkup_neg(d, a->btgt);
  13284. + if (unlikely(err))
  13285. + goto out_whtmp;
  13286. + a->dst_h_dentry = au_h_dptr(d, a->btgt);
  13287. + }
  13288. +
  13289. + /* cpup src */
  13290. + if (a->dst_h_dentry->d_inode && a->src_bstart != a->btgt) {
  13291. + struct mutex *h_mtx = &a->src_h_dentry->d_inode->i_mutex;
  13292. +
  13293. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  13294. + err = au_sio_cpup_simple(a->src_dentry, a->btgt, -1,
  13295. + !AuCpup_DTIME);
  13296. + mutex_unlock(h_mtx);
  13297. + if (unlikely(err))
  13298. + goto out_whtmp;
  13299. + }
  13300. +
  13301. + /* rename by vfs_rename or cpup */
  13302. + d = a->dst_dentry;
  13303. + if (au_ftest_ren(a->flags, ISDIR)
  13304. + && (a->dst_wh_dentry
  13305. + || au_dbdiropq(d) == a->btgt
  13306. + /* hide the lower to keep xino */
  13307. + || a->btgt < au_dbend(d)
  13308. + || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ)))
  13309. + au_fset_ren(a->flags, DIROPQ);
  13310. + err = au_ren_or_cpup(a);
  13311. + if (unlikely(err))
  13312. + /* leave the copied-up one */
  13313. + goto out_whtmp;
  13314. +
  13315. + /* make dir opaque */
  13316. + if (au_ftest_ren(a->flags, DIROPQ)) {
  13317. + err = au_ren_diropq(a);
  13318. + if (unlikely(err))
  13319. + goto out_rename;
  13320. + }
  13321. +
  13322. + /* update target timestamps */
  13323. + AuDebugOn(au_dbstart(a->src_dentry) != a->btgt);
  13324. + a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
  13325. + vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
  13326. + a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
  13327. +
  13328. + /* remove whiteout for dentry */
  13329. + if (a->dst_wh_dentry) {
  13330. + a->h_path.dentry = a->dst_wh_dentry;
  13331. + err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
  13332. + a->dst_dentry);
  13333. + if (unlikely(err))
  13334. + goto out_diropq;
  13335. + }
  13336. +
  13337. + /* remove whtmp */
  13338. + if (a->thargs)
  13339. + au_ren_del_whtmp(a); /* ignore this error */
  13340. +
  13341. + err = 0;
  13342. + goto out_success;
  13343. +
  13344. + out_diropq:
  13345. + if (au_ftest_ren(a->flags, DIROPQ))
  13346. + au_ren_rev_diropq(err, a);
  13347. + out_rename:
  13348. + if (!au_ftest_ren(a->flags, CPUP))
  13349. + au_ren_rev_rename(err, a);
  13350. + else
  13351. + au_ren_rev_cpup(err, a);
  13352. + out_whtmp:
  13353. + if (a->thargs)
  13354. + au_ren_rev_whtmp(err, a);
  13355. + out_whdst:
  13356. + dput(a->dst_wh_dentry);
  13357. + a->dst_wh_dentry = NULL;
  13358. + out_whsrc:
  13359. + if (a->src_wh_dentry)
  13360. + au_ren_rev_whsrc(err, a);
  13361. + au_ren_rev_drop(a);
  13362. + out_success:
  13363. + dput(a->src_wh_dentry);
  13364. + dput(a->dst_wh_dentry);
  13365. + out_thargs:
  13366. + if (a->thargs) {
  13367. + dput(a->h_dst);
  13368. + au_whtmp_rmdir_free(a->thargs);
  13369. + a->thargs = NULL;
  13370. + }
  13371. + out:
  13372. + return err;
  13373. +}
  13374. +
  13375. +/* ---------------------------------------------------------------------- */
  13376. +
  13377. +/*
  13378. + * test if @dentry dir can be rename destination or not.
  13379. + * success means, it is a logically empty dir.
  13380. + */
  13381. +static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
  13382. +{
  13383. + return au_test_empty(dentry, whlist);
  13384. +}
  13385. +
  13386. +/*
  13387. + * test if @dentry dir can be rename source or not.
  13388. + * if it can, return 0 and @children is filled.
  13389. + * success means,
  13390. + * - it is a logically empty dir.
  13391. + * - or, it exists on writable branch and has no children including whiteouts
  13392. + * on the lower branch.
  13393. + */
  13394. +static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt)
  13395. +{
  13396. + int err;
  13397. + aufs_bindex_t bstart;
  13398. +
  13399. + bstart = au_dbstart(dentry);
  13400. + if (bstart != btgt) {
  13401. + struct au_nhash whlist;
  13402. +
  13403. + SiMustAnyLock(dentry->d_sb);
  13404. + err = au_nhash_alloc(&whlist, au_sbi(dentry->d_sb)->si_rdhash,
  13405. + GFP_NOFS);
  13406. + if (unlikely(err))
  13407. + goto out;
  13408. + err = au_test_empty(dentry, &whlist);
  13409. + au_nhash_wh_free(&whlist);
  13410. + goto out;
  13411. + }
  13412. +
  13413. + if (bstart == au_dbtaildir(dentry))
  13414. + return 0; /* success */
  13415. +
  13416. + err = au_test_empty_lower(dentry);
  13417. +
  13418. + out:
  13419. + if (err == -ENOTEMPTY) {
  13420. + AuWarn1("renaming dir who has child(ren) on multiple branches,"
  13421. + " is not supported\n");
  13422. + err = -EXDEV;
  13423. + }
  13424. + return err;
  13425. +}
  13426. +
  13427. +/* side effect: sets whlist and h_dentry */
  13428. +static int au_ren_may_dir(struct au_ren_args *a)
  13429. +{
  13430. + int err;
  13431. + struct dentry *d;
  13432. +
  13433. + d = a->dst_dentry;
  13434. + SiMustAnyLock(d->d_sb);
  13435. + err = au_nhash_alloc(&a->whlist, au_sbi(d->d_sb)->si_rdhash, GFP_NOFS);
  13436. + if (unlikely(err))
  13437. + goto out;
  13438. +
  13439. + err = 0;
  13440. + if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) {
  13441. + au_set_dbstart(d, a->dst_bstart);
  13442. + err = may_rename_dstdir(d, &a->whlist);
  13443. + au_set_dbstart(d, a->btgt);
  13444. + }
  13445. + a->dst_h_dentry = au_h_dptr(d, au_dbstart(d));
  13446. + if (unlikely(err))
  13447. + goto out;
  13448. +
  13449. + d = a->src_dentry;
  13450. + a->src_h_dentry = au_h_dptr(d, au_dbstart(d));
  13451. + if (au_ftest_ren(a->flags, ISDIR)) {
  13452. + err = may_rename_srcdir(d, a->btgt);
  13453. + if (unlikely(err)) {
  13454. + au_nhash_wh_free(&a->whlist);
  13455. + a->whlist.nh_num = 0;
  13456. + }
  13457. + }
  13458. + out:
  13459. + return err;
  13460. +}
  13461. +
  13462. +/* ---------------------------------------------------------------------- */
  13463. +
  13464. +/*
  13465. + * simple tests for rename.
  13466. + * following the checks in vfs, plus the parent-child relationship.
  13467. + */
  13468. +static int au_may_ren(struct au_ren_args *a)
  13469. +{
  13470. + int err, isdir;
  13471. + struct inode *h_inode;
  13472. +
  13473. + if (a->src_bstart == a->btgt) {
  13474. + err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
  13475. + au_ftest_ren(a->flags, ISDIR));
  13476. + if (unlikely(err))
  13477. + goto out;
  13478. + err = -EINVAL;
  13479. + if (unlikely(a->src_h_dentry == a->h_trap))
  13480. + goto out;
  13481. + }
  13482. +
  13483. + err = 0;
  13484. + if (a->dst_bstart != a->btgt)
  13485. + goto out;
  13486. +
  13487. + err = -EIO;
  13488. + h_inode = a->dst_h_dentry->d_inode;
  13489. + isdir = !!au_ftest_ren(a->flags, ISDIR);
  13490. + if (!a->dst_dentry->d_inode) {
  13491. + if (unlikely(h_inode))
  13492. + goto out;
  13493. + err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent,
  13494. + isdir);
  13495. + } else {
  13496. + if (unlikely(!h_inode || !h_inode->i_nlink))
  13497. + goto out;
  13498. + err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent,
  13499. + isdir);
  13500. + if (unlikely(err))
  13501. + goto out;
  13502. + err = -ENOTEMPTY;
  13503. + if (unlikely(a->dst_h_dentry == a->h_trap))
  13504. + goto out;
  13505. + err = 0;
  13506. + }
  13507. +
  13508. + out:
  13509. + if (unlikely(err == -ENOENT || err == -EEXIST))
  13510. + err = -EIO;
  13511. + return err;
  13512. +}
  13513. +
  13514. +/* ---------------------------------------------------------------------- */
  13515. +
  13516. +/*
  13517. + * locking order
  13518. + * (VFS)
  13519. + * - src_dir and dir by lock_rename()
  13520. + * - inode if exitsts
  13521. + * (aufs)
  13522. + * - lock all
  13523. + * + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
  13524. + * + si_read_lock
  13525. + * + di_write_lock2_child()
  13526. + * + di_write_lock_child()
  13527. + * + ii_write_lock_child()
  13528. + * + di_write_lock_child2()
  13529. + * + ii_write_lock_child2()
  13530. + * + src_parent and parent
  13531. + * + di_write_lock_parent()
  13532. + * + ii_write_lock_parent()
  13533. + * + di_write_lock_parent2()
  13534. + * + ii_write_lock_parent2()
  13535. + * + lower src_dir and dir by vfsub_lock_rename()
  13536. + * + verify the every relationships between child and parent. if any
  13537. + * of them failed, unlock all and return -EBUSY.
  13538. + */
  13539. +static void au_ren_unlock(struct au_ren_args *a)
  13540. +{
  13541. + struct super_block *sb;
  13542. +
  13543. + sb = a->dst_dentry->d_sb;
  13544. + if (au_ftest_ren(a->flags, MNT_WRITE))
  13545. + mnt_drop_write(a->br->br_mnt);
  13546. + vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
  13547. + a->dst_h_parent, a->dst_hdir);
  13548. +}
  13549. +
  13550. +static int au_ren_lock(struct au_ren_args *a)
  13551. +{
  13552. + int err;
  13553. + unsigned int udba;
  13554. +
  13555. + err = 0;
  13556. + a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
  13557. + a->src_hdir = au_hi(a->src_dir, a->btgt);
  13558. + a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
  13559. + a->dst_hdir = au_hi(a->dst_dir, a->btgt);
  13560. + a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
  13561. + a->dst_h_parent, a->dst_hdir);
  13562. + udba = au_opt_udba(a->src_dentry->d_sb);
  13563. + if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode
  13564. + || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode))
  13565. + err = au_busy_or_stale();
  13566. + if (!err && au_dbstart(a->src_dentry) == a->btgt)
  13567. + err = au_h_verify(a->src_h_dentry, udba,
  13568. + a->src_h_parent->d_inode, a->src_h_parent,
  13569. + a->br);
  13570. + if (!err && au_dbstart(a->dst_dentry) == a->btgt)
  13571. + err = au_h_verify(a->dst_h_dentry, udba,
  13572. + a->dst_h_parent->d_inode, a->dst_h_parent,
  13573. + a->br);
  13574. + if (!err) {
  13575. + err = mnt_want_write(a->br->br_mnt);
  13576. + if (unlikely(err))
  13577. + goto out_unlock;
  13578. + au_fset_ren(a->flags, MNT_WRITE);
  13579. + goto out; /* success */
  13580. + }
  13581. +
  13582. + err = au_busy_or_stale();
  13583. +
  13584. + out_unlock:
  13585. + au_ren_unlock(a);
  13586. + out:
  13587. + return err;
  13588. +}
  13589. +
  13590. +/* ---------------------------------------------------------------------- */
  13591. +
  13592. +static void au_ren_refresh_dir(struct au_ren_args *a)
  13593. +{
  13594. + struct inode *dir;
  13595. +
  13596. + dir = a->dst_dir;
  13597. + dir->i_version++;
  13598. + if (au_ftest_ren(a->flags, ISDIR)) {
  13599. + /* is this updating defined in POSIX? */
  13600. + au_cpup_attr_timesizes(a->src_inode);
  13601. + au_cpup_attr_nlink(dir, /*force*/1);
  13602. + if (a->dst_inode) {
  13603. + clear_nlink(a->dst_inode);
  13604. + au_cpup_attr_timesizes(a->dst_inode);
  13605. + }
  13606. + }
  13607. + if (au_ibstart(dir) == a->btgt)
  13608. + au_cpup_attr_timesizes(dir);
  13609. +
  13610. + if (au_ftest_ren(a->flags, ISSAMEDIR))
  13611. + return;
  13612. +
  13613. + dir = a->src_dir;
  13614. + dir->i_version++;
  13615. + if (au_ftest_ren(a->flags, ISDIR))
  13616. + au_cpup_attr_nlink(dir, /*force*/1);
  13617. + if (au_ibstart(dir) == a->btgt)
  13618. + au_cpup_attr_timesizes(dir);
  13619. +}
  13620. +
  13621. +static void au_ren_refresh(struct au_ren_args *a)
  13622. +{
  13623. + aufs_bindex_t bend, bindex;
  13624. + struct dentry *d, *h_d;
  13625. + struct inode *i, *h_i;
  13626. + struct super_block *sb;
  13627. +
  13628. + d = a->src_dentry;
  13629. + au_set_dbwh(d, -1);
  13630. + bend = au_dbend(d);
  13631. + for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
  13632. + h_d = au_h_dptr(d, bindex);
  13633. + if (h_d)
  13634. + au_set_h_dptr(d, bindex, NULL);
  13635. + }
  13636. + au_set_dbend(d, a->btgt);
  13637. +
  13638. + sb = d->d_sb;
  13639. + i = a->src_inode;
  13640. + if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
  13641. + return; /* success */
  13642. +
  13643. + bend = au_ibend(i);
  13644. + for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
  13645. + h_i = au_h_iptr(i, bindex);
  13646. + if (h_i) {
  13647. + au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
  13648. + /* ignore this error */
  13649. + au_set_h_iptr(i, bindex, NULL, 0);
  13650. + }
  13651. + }
  13652. + au_set_ibend(i, a->btgt);
  13653. +}
  13654. +
  13655. +/* ---------------------------------------------------------------------- */
  13656. +
  13657. +/* mainly for link(2) and rename(2) */
  13658. +int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
  13659. +{
  13660. + aufs_bindex_t bdiropq, bwh;
  13661. + struct dentry *parent;
  13662. + struct au_branch *br;
  13663. +
  13664. + parent = dentry->d_parent;
  13665. + IMustLock(parent->d_inode); /* dir is locked */
  13666. +
  13667. + bdiropq = au_dbdiropq(parent);
  13668. + bwh = au_dbwh(dentry);
  13669. + br = au_sbr(dentry->d_sb, btgt);
  13670. + if (au_br_rdonly(br)
  13671. + || (0 <= bdiropq && bdiropq < btgt)
  13672. + || (0 <= bwh && bwh < btgt))
  13673. + btgt = -1;
  13674. +
  13675. + AuDbg("btgt %d\n", btgt);
  13676. + return btgt;
  13677. +}
  13678. +
  13679. +/* sets src_bstart, dst_bstart and btgt */
  13680. +static int au_ren_wbr(struct au_ren_args *a)
  13681. +{
  13682. + int err;
  13683. + struct au_wr_dir_args wr_dir_args = {
  13684. + /* .force_btgt = -1, */
  13685. + .flags = AuWrDir_ADD_ENTRY
  13686. + };
  13687. +
  13688. + a->src_bstart = au_dbstart(a->src_dentry);
  13689. + a->dst_bstart = au_dbstart(a->dst_dentry);
  13690. + if (au_ftest_ren(a->flags, ISDIR))
  13691. + au_fset_wrdir(wr_dir_args.flags, ISDIR);
  13692. + wr_dir_args.force_btgt = a->src_bstart;
  13693. + if (a->dst_inode && a->dst_bstart < a->src_bstart)
  13694. + wr_dir_args.force_btgt = a->dst_bstart;
  13695. + wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
  13696. + err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
  13697. + a->btgt = err;
  13698. +
  13699. + return err;
  13700. +}
  13701. +
  13702. +static void au_ren_dt(struct au_ren_args *a)
  13703. +{
  13704. + a->h_path.dentry = a->src_h_parent;
  13705. + au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
  13706. + if (!au_ftest_ren(a->flags, ISSAMEDIR)) {
  13707. + a->h_path.dentry = a->dst_h_parent;
  13708. + au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
  13709. + }
  13710. +
  13711. + au_fclr_ren(a->flags, DT_DSTDIR);
  13712. + if (!au_ftest_ren(a->flags, ISDIR))
  13713. + return;
  13714. +
  13715. + a->h_path.dentry = a->src_h_dentry;
  13716. + au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
  13717. + if (a->dst_h_dentry->d_inode) {
  13718. + au_fset_ren(a->flags, DT_DSTDIR);
  13719. + a->h_path.dentry = a->dst_h_dentry;
  13720. + au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
  13721. + }
  13722. +}
  13723. +
  13724. +static void au_ren_rev_dt(int err, struct au_ren_args *a)
  13725. +{
  13726. + struct dentry *h_d;
  13727. + struct mutex *h_mtx;
  13728. +
  13729. + au_dtime_revert(a->src_dt + AuPARENT);
  13730. + if (!au_ftest_ren(a->flags, ISSAMEDIR))
  13731. + au_dtime_revert(a->dst_dt + AuPARENT);
  13732. +
  13733. + if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) {
  13734. + h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
  13735. + h_mtx = &h_d->d_inode->i_mutex;
  13736. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  13737. + au_dtime_revert(a->src_dt + AuCHILD);
  13738. + mutex_unlock(h_mtx);
  13739. +
  13740. + if (au_ftest_ren(a->flags, DT_DSTDIR)) {
  13741. + h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
  13742. + h_mtx = &h_d->d_inode->i_mutex;
  13743. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  13744. + au_dtime_revert(a->dst_dt + AuCHILD);
  13745. + mutex_unlock(h_mtx);
  13746. + }
  13747. + }
  13748. +}
  13749. +
  13750. +/* ---------------------------------------------------------------------- */
  13751. +
  13752. +int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
  13753. + struct inode *_dst_dir, struct dentry *_dst_dentry)
  13754. +{
  13755. + int err;
  13756. + /* reduce stack space */
  13757. + struct au_ren_args *a;
  13758. +
  13759. + IMustLock(_src_dir);
  13760. + IMustLock(_dst_dir);
  13761. +
  13762. + err = -ENOMEM;
  13763. + BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
  13764. + a = kzalloc(sizeof(*a), GFP_NOFS);
  13765. + if (unlikely(!a))
  13766. + goto out;
  13767. +
  13768. + a->src_dir = _src_dir;
  13769. + a->src_dentry = _src_dentry;
  13770. + a->src_inode = a->src_dentry->d_inode;
  13771. + a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
  13772. + a->dst_dir = _dst_dir;
  13773. + a->dst_dentry = _dst_dentry;
  13774. + a->dst_inode = a->dst_dentry->d_inode;
  13775. + a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
  13776. + if (a->dst_inode) {
  13777. + IMustLock(a->dst_inode);
  13778. + au_igrab(a->dst_inode);
  13779. + }
  13780. +
  13781. + err = -ENOTDIR;
  13782. + if (S_ISDIR(a->src_inode->i_mode)) {
  13783. + au_fset_ren(a->flags, ISDIR);
  13784. + if (unlikely(a->dst_inode && !S_ISDIR(a->dst_inode->i_mode)))
  13785. + goto out_free;
  13786. + aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
  13787. + AuLock_DIR | AuLock_FLUSH);
  13788. + } else
  13789. + aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
  13790. + AuLock_FLUSH);
  13791. +
  13792. + au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
  13793. + di_write_lock_parent(a->dst_parent);
  13794. +
  13795. + /* which branch we process */
  13796. + err = au_ren_wbr(a);
  13797. + if (unlikely(err < 0))
  13798. + goto out_unlock;
  13799. + a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
  13800. + a->h_path.mnt = a->br->br_mnt;
  13801. +
  13802. + /* are they available to be renamed */
  13803. + err = au_ren_may_dir(a);
  13804. + if (unlikely(err))
  13805. + goto out_unlock;
  13806. +
  13807. + /* prepare the writable parent dir on the same branch */
  13808. + if (a->dst_bstart == a->btgt) {
  13809. + au_fset_ren(a->flags, WHDST);
  13810. + } else {
  13811. + err = au_cpup_dirs(a->dst_dentry, a->btgt);
  13812. + if (unlikely(err))
  13813. + goto out_children;
  13814. + }
  13815. +
  13816. + if (a->src_dir != a->dst_dir) {
  13817. + /*
  13818. + * this temporary unlock is safe,
  13819. + * because both dir->i_mutex are locked.
  13820. + */
  13821. + di_write_unlock(a->dst_parent);
  13822. + di_write_lock_parent(a->src_parent);
  13823. + err = au_wr_dir_need_wh(a->src_dentry,
  13824. + au_ftest_ren(a->flags, ISDIR),
  13825. + &a->btgt);
  13826. + di_write_unlock(a->src_parent);
  13827. + di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1);
  13828. + au_fclr_ren(a->flags, ISSAMEDIR);
  13829. + } else
  13830. + err = au_wr_dir_need_wh(a->src_dentry,
  13831. + au_ftest_ren(a->flags, ISDIR),
  13832. + &a->btgt);
  13833. + if (unlikely(err < 0))
  13834. + goto out_children;
  13835. + if (err)
  13836. + au_fset_ren(a->flags, WHSRC);
  13837. +
  13838. + /* lock them all */
  13839. + err = au_ren_lock(a);
  13840. + if (unlikely(err))
  13841. + goto out_children;
  13842. +
  13843. + if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE)) {
  13844. + err = au_may_ren(a);
  13845. + if (unlikely(err))
  13846. + goto out_hdir;
  13847. + }
  13848. +
  13849. + /* store timestamps to be revertible */
  13850. + au_ren_dt(a);
  13851. +
  13852. + /* here we go */
  13853. + err = do_rename(a);
  13854. + if (unlikely(err))
  13855. + goto out_dt;
  13856. +
  13857. + /* update dir attributes */
  13858. + au_ren_refresh_dir(a);
  13859. +
  13860. + /* dput/iput all lower dentries */
  13861. + au_ren_refresh(a);
  13862. +
  13863. + goto out_hdir; /* success */
  13864. +
  13865. + out_dt:
  13866. + au_ren_rev_dt(err, a);
  13867. + out_hdir:
  13868. + au_ren_unlock(a);
  13869. + out_children:
  13870. + au_nhash_wh_free(&a->whlist);
  13871. + out_unlock:
  13872. + if (unlikely(err && au_ftest_ren(a->flags, ISDIR))) {
  13873. + au_update_dbstart(a->dst_dentry);
  13874. + d_drop(a->dst_dentry);
  13875. + }
  13876. + if (!err)
  13877. + d_move(a->src_dentry, a->dst_dentry);
  13878. + if (au_ftest_ren(a->flags, ISSAMEDIR))
  13879. + di_write_unlock(a->dst_parent);
  13880. + else
  13881. + di_write_unlock2(a->src_parent, a->dst_parent);
  13882. + aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
  13883. + out_free:
  13884. + iput(a->dst_inode);
  13885. + if (a->thargs)
  13886. + au_whtmp_rmdir_free(a->thargs);
  13887. + kfree(a);
  13888. + out:
  13889. + return err;
  13890. +}
  13891. diff -Nur linux-2.6.34.orig/fs/aufs/Kconfig linux-2.6.34/fs/aufs/Kconfig
  13892. --- linux-2.6.34.orig/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100
  13893. +++ linux-2.6.34/fs/aufs/Kconfig 2010-05-23 23:33:20.653473087 +0200
  13894. @@ -0,0 +1,132 @@
  13895. +config AUFS_FS
  13896. + tristate "Aufs (Advanced multi layered unification filesystem) support"
  13897. + depends on EXPERIMENTAL
  13898. + help
  13899. + Aufs is a stackable unification filesystem such as Unionfs,
  13900. + which unifies several directories and provides a merged single
  13901. + directory.
  13902. + In the early days, aufs was entirely re-designed and
  13903. + re-implemented Unionfs Version 1.x series. Introducing many
  13904. + original ideas, approaches and improvements, it becomes totally
  13905. + different from Unionfs while keeping the basic features.
  13906. +
  13907. +if AUFS_FS
  13908. +choice
  13909. + prompt "Maximum number of branches"
  13910. + default AUFS_BRANCH_MAX_127
  13911. + help
  13912. + Specifies the maximum number of branches (or member directories)
  13913. + in a single aufs. The larger value consumes more system
  13914. + resources and has a minor impact to performance.
  13915. +config AUFS_BRANCH_MAX_127
  13916. + bool "127"
  13917. + help
  13918. + Specifies the maximum number of branches (or member directories)
  13919. + in a single aufs. The larger value consumes more system
  13920. + resources and has a minor impact to performance.
  13921. +config AUFS_BRANCH_MAX_511
  13922. + bool "511"
  13923. + help
  13924. + Specifies the maximum number of branches (or member directories)
  13925. + in a single aufs. The larger value consumes more system
  13926. + resources and has a minor impact to performance.
  13927. +config AUFS_BRANCH_MAX_1023
  13928. + bool "1023"
  13929. + help
  13930. + Specifies the maximum number of branches (or member directories)
  13931. + in a single aufs. The larger value consumes more system
  13932. + resources and has a minor impact to performance.
  13933. +config AUFS_BRANCH_MAX_32767
  13934. + bool "32767"
  13935. + help
  13936. + Specifies the maximum number of branches (or member directories)
  13937. + in a single aufs. The larger value consumes more system
  13938. + resources and has a minor impact to performance.
  13939. +endchoice
  13940. +
  13941. +config AUFS_HINOTIFY
  13942. + bool "Use inotify to detect actions on a branch"
  13943. + depends on INOTIFY
  13944. + help
  13945. + If you want to modify files on branches directly, eg. bypassing aufs,
  13946. + and want aufs to detect the changes of them fully, then enable this
  13947. + option and use 'udba=inotify' mount option.
  13948. + It will have a negative impact to the performance.
  13949. + See detail in aufs.5.
  13950. +
  13951. +config AUFS_EXPORT
  13952. + bool "NFS-exportable aufs"
  13953. + depends on (AUFS_FS = y && EXPORTFS = y) || (AUFS_FS = m && EXPORTFS)
  13954. + help
  13955. + If you want to export your mounted aufs via NFS, then enable this
  13956. + option. There are several requirements for this configuration.
  13957. + See detail in aufs.5.
  13958. +
  13959. +config AUFS_SHWH
  13960. + bool "Show whiteouts"
  13961. + help
  13962. + If you want to make the whiteouts in aufs visible, then enable
  13963. + this option and specify 'shwh' mount option. Although it may
  13964. + sounds like philosophy or something, but in technically it
  13965. + simply shows the name of whiteout with keeping its behaviour.
  13966. +
  13967. +config AUFS_BR_RAMFS
  13968. + bool "Ramfs (initramfs/rootfs) as an aufs branch"
  13969. + help
  13970. + If you want to use ramfs as an aufs branch fs, then enable this
  13971. + option. Generally tmpfs is recommended.
  13972. + Aufs prohibited them to be a branch fs by default, because
  13973. + initramfs becomes unusable after switch_root or something
  13974. + generally. If you sets initramfs as an aufs branch and boot your
  13975. + system by switch_root, you will meet a problem easily since the
  13976. + files in initramfs may be inaccessible.
  13977. + Unless you are going to use ramfs as an aufs branch fs without
  13978. + switch_root or something, leave it N.
  13979. +
  13980. +config AUFS_BR_FUSE
  13981. + bool "Fuse fs as an aufs branch"
  13982. + depends on FUSE_FS
  13983. + select AUFS_POLL
  13984. + help
  13985. + If you want to use fuse-based userspace filesystem as an aufs
  13986. + branch fs, then enable this option.
  13987. + It implements the internal poll(2) operation which is
  13988. + implemented by fuse only (curretnly).
  13989. +
  13990. +config AUFS_DEBUG
  13991. + bool "Debug aufs"
  13992. + help
  13993. + Enable this to compile aufs internal debug code.
  13994. + It will have a negative impact to the performance.
  13995. +
  13996. +config AUFS_MAGIC_SYSRQ
  13997. + bool
  13998. + depends on AUFS_DEBUG && MAGIC_SYSRQ
  13999. + default y
  14000. + help
  14001. + Automatic configuration for internal use.
  14002. + When aufs supports Magic SysRq, enabled automatically.
  14003. +
  14004. +config AUFS_BDEV_LOOP
  14005. + bool
  14006. + depends on BLK_DEV_LOOP
  14007. + default y
  14008. + help
  14009. + Automatic configuration for internal use.
  14010. + Convert =[ym] into =y.
  14011. +
  14012. +config AUFS_INO_T_64
  14013. + bool
  14014. + depends on AUFS_EXPORT
  14015. + depends on 64BIT && !(ALPHA || S390)
  14016. + default y
  14017. + help
  14018. + Automatic configuration for internal use.
  14019. + /* typedef unsigned long/int __kernel_ino_t */
  14020. + /* alpha and s390x are int */
  14021. +
  14022. +config AUFS_POLL
  14023. + bool
  14024. + help
  14025. + Automatic configuration for internal use.
  14026. +endif
  14027. diff -Nur linux-2.6.34.orig/fs/aufs/loop.c linux-2.6.34/fs/aufs/loop.c
  14028. --- linux-2.6.34.orig/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100
  14029. +++ linux-2.6.34/fs/aufs/loop.c 2010-05-23 23:33:20.693473078 +0200
  14030. @@ -0,0 +1,55 @@
  14031. +/*
  14032. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  14033. + *
  14034. + * This program, aufs is free software; you can redistribute it and/or modify
  14035. + * it under the terms of the GNU General Public License as published by
  14036. + * the Free Software Foundation; either version 2 of the License, or
  14037. + * (at your option) any later version.
  14038. + *
  14039. + * This program is distributed in the hope that it will be useful,
  14040. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14041. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14042. + * GNU General Public License for more details.
  14043. + *
  14044. + * You should have received a copy of the GNU General Public License
  14045. + * along with this program; if not, write to the Free Software
  14046. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14047. + */
  14048. +
  14049. +/*
  14050. + * support for loopback block device as a branch
  14051. + */
  14052. +
  14053. +#include <linux/loop.h>
  14054. +#include "aufs.h"
  14055. +
  14056. +/*
  14057. + * test if two lower dentries have overlapping branches.
  14058. + */
  14059. +int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_d1,
  14060. + struct dentry *h_d2)
  14061. +{
  14062. + struct inode *h_inode;
  14063. + struct loop_device *l;
  14064. +
  14065. + h_inode = h_d1->d_inode;
  14066. + if (MAJOR(h_inode->i_sb->s_dev) != LOOP_MAJOR)
  14067. + return 0;
  14068. +
  14069. + l = h_inode->i_sb->s_bdev->bd_disk->private_data;
  14070. + h_d1 = l->lo_backing_file->f_dentry;
  14071. + /* h_d1 can be local NFS. in this case aufs cannot detect the loop */
  14072. + if (unlikely(h_d1->d_sb == sb))
  14073. + return 1;
  14074. + return !!au_test_subdir(h_d1, h_d2);
  14075. +}
  14076. +
  14077. +/* true if a kernel thread named 'loop[0-9].*' accesses a file */
  14078. +int au_test_loopback_kthread(void)
  14079. +{
  14080. + const char c = current->comm[4];
  14081. +
  14082. + return current->mm == NULL
  14083. + && '0' <= c && c <= '9'
  14084. + && strncmp(current->comm, "loop", 4) == 0;
  14085. +}
  14086. diff -Nur linux-2.6.34.orig/fs/aufs/loop.h linux-2.6.34/fs/aufs/loop.h
  14087. --- linux-2.6.34.orig/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
  14088. +++ linux-2.6.34/fs/aufs/loop.h 2010-05-23 23:33:20.732223142 +0200
  14089. @@ -0,0 +1,51 @@
  14090. +/*
  14091. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  14092. + *
  14093. + * This program, aufs is free software; you can redistribute it and/or modify
  14094. + * it under the terms of the GNU General Public License as published by
  14095. + * the Free Software Foundation; either version 2 of the License, or
  14096. + * (at your option) any later version.
  14097. + *
  14098. + * This program is distributed in the hope that it will be useful,
  14099. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14100. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14101. + * GNU General Public License for more details.
  14102. + *
  14103. + * You should have received a copy of the GNU General Public License
  14104. + * along with this program; if not, write to the Free Software
  14105. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14106. + */
  14107. +
  14108. +/*
  14109. + * support for loopback mount as a branch
  14110. + */
  14111. +
  14112. +#ifndef __AUFS_LOOP_H__
  14113. +#define __AUFS_LOOP_H__
  14114. +
  14115. +#ifdef __KERNEL__
  14116. +
  14117. +struct dentry;
  14118. +struct super_block;
  14119. +
  14120. +#ifdef CONFIG_AUFS_BDEV_LOOP
  14121. +/* loop.c */
  14122. +int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_d1,
  14123. + struct dentry *h_d2);
  14124. +int au_test_loopback_kthread(void);
  14125. +#else
  14126. +static inline
  14127. +int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_d1,
  14128. + struct dentry *h_d2)
  14129. +{
  14130. + return 0;
  14131. +}
  14132. +
  14133. +static inline int au_test_loopback_kthread(void)
  14134. +{
  14135. + return 0;
  14136. +}
  14137. +#endif /* BLK_DEV_LOOP */
  14138. +
  14139. +#endif /* __KERNEL__ */
  14140. +#endif /* __AUFS_LOOP_H__ */
  14141. diff -Nur linux-2.6.34.orig/fs/aufs/magic.mk linux-2.6.34/fs/aufs/magic.mk
  14142. --- linux-2.6.34.orig/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100
  14143. +++ linux-2.6.34/fs/aufs/magic.mk 2010-05-23 23:33:20.773473177 +0200
  14144. @@ -0,0 +1,52 @@
  14145. +
  14146. +# defined in ${srctree}/fs/fuse/inode.c
  14147. +# tristate
  14148. +ifdef CONFIG_FUSE_FS
  14149. +ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
  14150. +endif
  14151. +
  14152. +# defined in ${srctree}/fs/ocfs2/ocfs2_fs.h
  14153. +# tristate
  14154. +ifdef CONFIG_OCFS2_FS
  14155. +ccflags-y += -DOCFS2_SUPER_MAGIC=0x7461636f
  14156. +endif
  14157. +
  14158. +# defined in ${srctree}/fs/ocfs2/dlm/userdlm.h
  14159. +# tristate
  14160. +ifdef CONFIG_OCFS2_FS_O2CB
  14161. +ccflags-y += -DDLMFS_MAGIC=0x76a9f425
  14162. +endif
  14163. +
  14164. +# defined in ${srctree}/fs/ramfs/inode.c
  14165. +# always true
  14166. +ccflags-y += -DRAMFS_MAGIC=0x858458f6
  14167. +
  14168. +# defined in ${srctree}/fs/cifs/cifsfs.c
  14169. +# tristate
  14170. +ifdef CONFIG_CIFS_FS
  14171. +ccflags-y += -DCIFS_MAGIC_NUMBER=0xFF534D42
  14172. +endif
  14173. +
  14174. +# defined in ${srctree}/fs/xfs/xfs_sb.h
  14175. +# tristate
  14176. +ifdef CONFIG_XFS_FS
  14177. +ccflags-y += -DXFS_SB_MAGIC=0x58465342
  14178. +endif
  14179. +
  14180. +# defined in ${srctree}/fs/configfs/mount.c
  14181. +# tristate
  14182. +ifdef CONFIG_CONFIGFS_FS
  14183. +ccflags-y += -DCONFIGFS_MAGIC=0x62656570
  14184. +endif
  14185. +
  14186. +# defined in ${srctree}/fs/9p/v9fs.h
  14187. +# tristate
  14188. +ifdef CONFIG_9P_FS
  14189. +ccflags-y += -DV9FS_MAGIC=0x01021997
  14190. +endif
  14191. +
  14192. +# defined in ${srctree}/fs/ubifs/ubifs.h
  14193. +# tristate
  14194. +ifdef CONFIG_UBIFS_FS
  14195. +ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
  14196. +endif
  14197. diff -Nur linux-2.6.34.orig/fs/aufs/Makefile linux-2.6.34/fs/aufs/Makefile
  14198. --- linux-2.6.34.orig/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100
  14199. +++ linux-2.6.34/fs/aufs/Makefile 2010-05-23 23:33:20.810978181 +0200
  14200. @@ -0,0 +1,23 @@
  14201. +
  14202. +include ${src}/magic.mk
  14203. +-include ${src}/priv_def.mk
  14204. +
  14205. +obj-$(CONFIG_AUFS_FS) += aufs.o
  14206. +aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
  14207. + wkq.o vfsub.o dcsub.o \
  14208. + cpup.o whout.o plink.o wbr_policy.o \
  14209. + dinfo.o dentry.o \
  14210. + finfo.o file.o f_op.o \
  14211. + dir.o vdir.o \
  14212. + iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
  14213. + ioctl.o
  14214. +
  14215. +# all are boolean
  14216. +aufs-$(CONFIG_SYSFS) += sysfs.o
  14217. +aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
  14218. +aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
  14219. +aufs-$(CONFIG_AUFS_HINOTIFY) += hinotify.o
  14220. +aufs-$(CONFIG_AUFS_EXPORT) += export.o
  14221. +aufs-$(CONFIG_AUFS_POLL) += poll.o
  14222. +aufs-$(CONFIG_AUFS_DEBUG) += debug.o
  14223. +aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
  14224. diff -Nur linux-2.6.34.orig/fs/aufs/module.c linux-2.6.34/fs/aufs/module.c
  14225. --- linux-2.6.34.orig/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100
  14226. +++ linux-2.6.34/fs/aufs/module.c 2010-05-23 23:33:20.865206461 +0200
  14227. @@ -0,0 +1,173 @@
  14228. +/*
  14229. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  14230. + *
  14231. + * This program, aufs is free software; you can redistribute it and/or modify
  14232. + * it under the terms of the GNU General Public License as published by
  14233. + * the Free Software Foundation; either version 2 of the License, or
  14234. + * (at your option) any later version.
  14235. + *
  14236. + * This program is distributed in the hope that it will be useful,
  14237. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14238. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14239. + * GNU General Public License for more details.
  14240. + *
  14241. + * You should have received a copy of the GNU General Public License
  14242. + * along with this program; if not, write to the Free Software
  14243. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14244. + */
  14245. +
  14246. +/*
  14247. + * module global variables and operations
  14248. + */
  14249. +
  14250. +#include <linux/module.h>
  14251. +#include <linux/seq_file.h>
  14252. +#include "aufs.h"
  14253. +
  14254. +void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp)
  14255. +{
  14256. + if (new_sz <= nused)
  14257. + return p;
  14258. +
  14259. + p = krealloc(p, new_sz, gfp);
  14260. + if (p)
  14261. + memset(p + nused, 0, new_sz - nused);
  14262. + return p;
  14263. +}
  14264. +
  14265. +/* ---------------------------------------------------------------------- */
  14266. +
  14267. +/*
  14268. + * aufs caches
  14269. + */
  14270. +struct kmem_cache *au_cachep[AuCache_Last];
  14271. +static int __init au_cache_init(void)
  14272. +{
  14273. + au_cachep[AuCache_DINFO] = AuCache(au_dinfo);
  14274. + if (au_cachep[AuCache_DINFO])
  14275. + au_cachep[AuCache_ICNTNR] = AuCache(au_icntnr);
  14276. + if (au_cachep[AuCache_ICNTNR])
  14277. + au_cachep[AuCache_FINFO] = AuCache(au_finfo);
  14278. + if (au_cachep[AuCache_FINFO])
  14279. + au_cachep[AuCache_VDIR] = AuCache(au_vdir);
  14280. + if (au_cachep[AuCache_VDIR])
  14281. + au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
  14282. + if (au_cachep[AuCache_DEHSTR])
  14283. + return 0;
  14284. +
  14285. + return -ENOMEM;
  14286. +}
  14287. +
  14288. +static void au_cache_fin(void)
  14289. +{
  14290. + int i;
  14291. + for (i = 0; i < AuCache_Last; i++)
  14292. + if (au_cachep[i]) {
  14293. + kmem_cache_destroy(au_cachep[i]);
  14294. + au_cachep[i] = NULL;
  14295. + }
  14296. +}
  14297. +
  14298. +/* ---------------------------------------------------------------------- */
  14299. +
  14300. +int au_dir_roflags;
  14301. +
  14302. +/*
  14303. + * functions for module interface.
  14304. + */
  14305. +MODULE_LICENSE("GPL");
  14306. +/* MODULE_LICENSE("GPL v2"); */
  14307. +MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
  14308. +MODULE_DESCRIPTION(AUFS_NAME
  14309. + " -- Advanced multi layered unification filesystem");
  14310. +MODULE_VERSION(AUFS_VERSION);
  14311. +
  14312. +/* it should be 'byte', but param_set_byte() prints it by "%c" */
  14313. +short aufs_nwkq = AUFS_NWKQ_DEF;
  14314. +MODULE_PARM_DESC(nwkq, "the number of workqueue thread, " AUFS_WKQ_NAME);
  14315. +module_param_named(nwkq, aufs_nwkq, short, S_IRUGO);
  14316. +
  14317. +/* this module parameter has no meaning when SYSFS is disabled */
  14318. +int sysaufs_brs = 1;
  14319. +MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
  14320. +module_param_named(brs, sysaufs_brs, int, S_IRUGO);
  14321. +
  14322. +/* ---------------------------------------------------------------------- */
  14323. +
  14324. +static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
  14325. +
  14326. +int au_seq_path(struct seq_file *seq, struct path *path)
  14327. +{
  14328. + return seq_path(seq, path, au_esc_chars);
  14329. +}
  14330. +
  14331. +/* ---------------------------------------------------------------------- */
  14332. +
  14333. +static int __init aufs_init(void)
  14334. +{
  14335. + int err, i;
  14336. + char *p;
  14337. +
  14338. + p = au_esc_chars;
  14339. + for (i = 1; i <= ' '; i++)
  14340. + *p++ = i;
  14341. + *p++ = '\\';
  14342. + *p++ = '\x7f';
  14343. + *p = 0;
  14344. +
  14345. + au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
  14346. +
  14347. + sysaufs_brs_init();
  14348. + au_debug_init();
  14349. +
  14350. + err = -EINVAL;
  14351. + if (unlikely(aufs_nwkq <= 0))
  14352. + goto out;
  14353. +
  14354. + err = sysaufs_init();
  14355. + if (unlikely(err))
  14356. + goto out;
  14357. + err = au_wkq_init();
  14358. + if (unlikely(err))
  14359. + goto out_sysaufs;
  14360. + err = au_hinotify_init();
  14361. + if (unlikely(err))
  14362. + goto out_wkq;
  14363. + err = au_sysrq_init();
  14364. + if (unlikely(err))
  14365. + goto out_hin;
  14366. + err = au_cache_init();
  14367. + if (unlikely(err))
  14368. + goto out_sysrq;
  14369. + err = register_filesystem(&aufs_fs_type);
  14370. + if (unlikely(err))
  14371. + goto out_cache;
  14372. + pr_info(AUFS_NAME " " AUFS_VERSION "\n");
  14373. + goto out; /* success */
  14374. +
  14375. + out_cache:
  14376. + au_cache_fin();
  14377. + out_sysrq:
  14378. + au_sysrq_fin();
  14379. + out_hin:
  14380. + au_hinotify_fin();
  14381. + out_wkq:
  14382. + au_wkq_fin();
  14383. + out_sysaufs:
  14384. + sysaufs_fin();
  14385. + out:
  14386. + return err;
  14387. +}
  14388. +
  14389. +static void __exit aufs_exit(void)
  14390. +{
  14391. + unregister_filesystem(&aufs_fs_type);
  14392. + au_cache_fin();
  14393. + au_sysrq_fin();
  14394. + au_hinotify_fin();
  14395. + au_wkq_fin();
  14396. + sysaufs_fin();
  14397. +}
  14398. +
  14399. +module_init(aufs_init);
  14400. +module_exit(aufs_exit);
  14401. diff -Nur linux-2.6.34.orig/fs/aufs/module.h linux-2.6.34/fs/aufs/module.h
  14402. --- linux-2.6.34.orig/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100
  14403. +++ linux-2.6.34/fs/aufs/module.h 2010-05-23 23:33:20.903473083 +0200
  14404. @@ -0,0 +1,78 @@
  14405. +/*
  14406. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  14407. + *
  14408. + * This program, aufs is free software; you can redistribute it and/or modify
  14409. + * it under the terms of the GNU General Public License as published by
  14410. + * the Free Software Foundation; either version 2 of the License, or
  14411. + * (at your option) any later version.
  14412. + *
  14413. + * This program is distributed in the hope that it will be useful,
  14414. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14415. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14416. + * GNU General Public License for more details.
  14417. + *
  14418. + * You should have received a copy of the GNU General Public License
  14419. + * along with this program; if not, write to the Free Software
  14420. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14421. + */
  14422. +
  14423. +/*
  14424. + * module initialization and module-global
  14425. + */
  14426. +
  14427. +#ifndef __AUFS_MODULE_H__
  14428. +#define __AUFS_MODULE_H__
  14429. +
  14430. +#ifdef __KERNEL__
  14431. +
  14432. +#include <linux/slab.h>
  14433. +
  14434. +struct path;
  14435. +struct seq_file;
  14436. +
  14437. +/* module parameters */
  14438. +extern short aufs_nwkq;
  14439. +extern int sysaufs_brs;
  14440. +
  14441. +/* ---------------------------------------------------------------------- */
  14442. +
  14443. +extern int au_dir_roflags;
  14444. +
  14445. +void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp);
  14446. +int au_seq_path(struct seq_file *seq, struct path *path);
  14447. +
  14448. +/* ---------------------------------------------------------------------- */
  14449. +
  14450. +/* kmem cache */
  14451. +enum {
  14452. + AuCache_DINFO,
  14453. + AuCache_ICNTNR,
  14454. + AuCache_FINFO,
  14455. + AuCache_VDIR,
  14456. + AuCache_DEHSTR,
  14457. +#ifdef CONFIG_AUFS_HINOTIFY
  14458. + AuCache_HINOTIFY,
  14459. +#endif
  14460. + AuCache_Last
  14461. +};
  14462. +
  14463. +#define AuCache(type) KMEM_CACHE(type, SLAB_RECLAIM_ACCOUNT)
  14464. +
  14465. +extern struct kmem_cache *au_cachep[];
  14466. +
  14467. +#define AuCacheFuncs(name, index) \
  14468. +static inline void *au_cache_alloc_##name(void) \
  14469. +{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \
  14470. +static inline void au_cache_free_##name(void *p) \
  14471. +{ kmem_cache_free(au_cachep[AuCache_##index], p); }
  14472. +
  14473. +AuCacheFuncs(dinfo, DINFO);
  14474. +AuCacheFuncs(icntnr, ICNTNR);
  14475. +AuCacheFuncs(finfo, FINFO);
  14476. +AuCacheFuncs(vdir, VDIR);
  14477. +AuCacheFuncs(dehstr, DEHSTR);
  14478. +
  14479. +/* ---------------------------------------------------------------------- */
  14480. +
  14481. +#endif /* __KERNEL__ */
  14482. +#endif /* __AUFS_MODULE_H__ */
  14483. diff -Nur linux-2.6.34.orig/fs/aufs/opts.c linux-2.6.34/fs/aufs/opts.c
  14484. --- linux-2.6.34.orig/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100
  14485. +++ linux-2.6.34/fs/aufs/opts.c 2010-05-23 23:33:20.941070510 +0200
  14486. @@ -0,0 +1,1543 @@
  14487. +/*
  14488. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  14489. + *
  14490. + * This program, aufs is free software; you can redistribute it and/or modify
  14491. + * it under the terms of the GNU General Public License as published by
  14492. + * the Free Software Foundation; either version 2 of the License, or
  14493. + * (at your option) any later version.
  14494. + *
  14495. + * This program is distributed in the hope that it will be useful,
  14496. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14497. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14498. + * GNU General Public License for more details.
  14499. + *
  14500. + * You should have received a copy of the GNU General Public License
  14501. + * along with this program; if not, write to the Free Software
  14502. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14503. + */
  14504. +
  14505. +/*
  14506. + * mount options/flags
  14507. + */
  14508. +
  14509. +#include <linux/file.h>
  14510. +#include <linux/namei.h>
  14511. +#include <linux/types.h> /* a distribution requires */
  14512. +#include <linux/parser.h>
  14513. +#include "aufs.h"
  14514. +
  14515. +/* ---------------------------------------------------------------------- */
  14516. +
  14517. +enum {
  14518. + Opt_br,
  14519. + Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend,
  14520. + Opt_idel, Opt_imod, Opt_ireorder,
  14521. + Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, Opt_rendir,
  14522. + Opt_rdblk_def, Opt_rdhash_def,
  14523. + Opt_xino, Opt_zxino, Opt_noxino,
  14524. + Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
  14525. + Opt_trunc_xino_path, Opt_itrunc_xino,
  14526. + Opt_trunc_xib, Opt_notrunc_xib,
  14527. + Opt_shwh, Opt_noshwh,
  14528. + Opt_plink, Opt_noplink, Opt_list_plink,
  14529. + Opt_udba,
  14530. + /* Opt_lock, Opt_unlock, */
  14531. + Opt_cmd, Opt_cmd_args,
  14532. + Opt_diropq_a, Opt_diropq_w,
  14533. + Opt_warn_perm, Opt_nowarn_perm,
  14534. + Opt_wbr_copyup, Opt_wbr_create,
  14535. + Opt_refrof, Opt_norefrof,
  14536. + Opt_verbose, Opt_noverbose,
  14537. + Opt_sum, Opt_nosum, Opt_wsum,
  14538. + Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
  14539. +};
  14540. +
  14541. +static match_table_t options = {
  14542. + {Opt_br, "br=%s"},
  14543. + {Opt_br, "br:%s"},
  14544. +
  14545. + {Opt_add, "add=%d:%s"},
  14546. + {Opt_add, "add:%d:%s"},
  14547. + {Opt_add, "ins=%d:%s"},
  14548. + {Opt_add, "ins:%d:%s"},
  14549. + {Opt_append, "append=%s"},
  14550. + {Opt_append, "append:%s"},
  14551. + {Opt_prepend, "prepend=%s"},
  14552. + {Opt_prepend, "prepend:%s"},
  14553. +
  14554. + {Opt_del, "del=%s"},
  14555. + {Opt_del, "del:%s"},
  14556. + /* {Opt_idel, "idel:%d"}, */
  14557. + {Opt_mod, "mod=%s"},
  14558. + {Opt_mod, "mod:%s"},
  14559. + /* {Opt_imod, "imod:%d:%s"}, */
  14560. +
  14561. + {Opt_dirwh, "dirwh=%d"},
  14562. +
  14563. + {Opt_xino, "xino=%s"},
  14564. + {Opt_noxino, "noxino"},
  14565. + {Opt_trunc_xino, "trunc_xino"},
  14566. + {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
  14567. + {Opt_notrunc_xino, "notrunc_xino"},
  14568. + {Opt_trunc_xino_path, "trunc_xino=%s"},
  14569. + {Opt_itrunc_xino, "itrunc_xino=%d"},
  14570. + /* {Opt_zxino, "zxino=%s"}, */
  14571. + {Opt_trunc_xib, "trunc_xib"},
  14572. + {Opt_notrunc_xib, "notrunc_xib"},
  14573. +
  14574. + {Opt_plink, "plink"},
  14575. + {Opt_noplink, "noplink"},
  14576. +#ifdef CONFIG_AUFS_DEBUG
  14577. + {Opt_list_plink, "list_plink"},
  14578. +#endif
  14579. +
  14580. + {Opt_udba, "udba=%s"},
  14581. +
  14582. + {Opt_diropq_a, "diropq=always"},
  14583. + {Opt_diropq_a, "diropq=a"},
  14584. + {Opt_diropq_w, "diropq=whiteouted"},
  14585. + {Opt_diropq_w, "diropq=w"},
  14586. +
  14587. + {Opt_warn_perm, "warn_perm"},
  14588. + {Opt_nowarn_perm, "nowarn_perm"},
  14589. +
  14590. + /* keep them temporary */
  14591. + {Opt_ignore_silent, "coo=%s"},
  14592. + {Opt_ignore_silent, "nodlgt"},
  14593. + {Opt_ignore_silent, "nodirperm1"},
  14594. + {Opt_ignore_silent, "clean_plink"},
  14595. +
  14596. +#ifdef CONFIG_AUFS_SHWH
  14597. + {Opt_shwh, "shwh"},
  14598. +#endif
  14599. + {Opt_noshwh, "noshwh"},
  14600. +
  14601. + {Opt_rendir, "rendir=%d"},
  14602. +
  14603. + {Opt_refrof, "refrof"},
  14604. + {Opt_norefrof, "norefrof"},
  14605. +
  14606. + {Opt_verbose, "verbose"},
  14607. + {Opt_verbose, "v"},
  14608. + {Opt_noverbose, "noverbose"},
  14609. + {Opt_noverbose, "quiet"},
  14610. + {Opt_noverbose, "q"},
  14611. + {Opt_noverbose, "silent"},
  14612. +
  14613. + {Opt_sum, "sum"},
  14614. + {Opt_nosum, "nosum"},
  14615. + {Opt_wsum, "wsum"},
  14616. +
  14617. + {Opt_rdcache, "rdcache=%d"},
  14618. + {Opt_rdblk, "rdblk=%d"},
  14619. + {Opt_rdblk_def, "rdblk=def"},
  14620. + {Opt_rdhash, "rdhash=%d"},
  14621. + {Opt_rdhash_def, "rdhash=def"},
  14622. +
  14623. + {Opt_wbr_create, "create=%s"},
  14624. + {Opt_wbr_create, "create_policy=%s"},
  14625. + {Opt_wbr_copyup, "cpup=%s"},
  14626. + {Opt_wbr_copyup, "copyup=%s"},
  14627. + {Opt_wbr_copyup, "copyup_policy=%s"},
  14628. +
  14629. + /* internal use for the scripts */
  14630. + {Opt_ignore_silent, "si=%s"},
  14631. +
  14632. + {Opt_br, "dirs=%s"},
  14633. + {Opt_ignore, "debug=%d"},
  14634. + {Opt_ignore, "delete=whiteout"},
  14635. + {Opt_ignore, "delete=all"},
  14636. + {Opt_ignore, "imap=%s"},
  14637. +
  14638. + {Opt_err, NULL}
  14639. +};
  14640. +
  14641. +/* ---------------------------------------------------------------------- */
  14642. +
  14643. +static const char *au_parser_pattern(int val, struct match_token *token)
  14644. +{
  14645. + while (token->pattern) {
  14646. + if (token->token == val)
  14647. + return token->pattern;
  14648. + token++;
  14649. + }
  14650. + BUG();
  14651. + return "??";
  14652. +}
  14653. +
  14654. +/* ---------------------------------------------------------------------- */
  14655. +
  14656. +static match_table_t brperms = {
  14657. + {AuBrPerm_RO, AUFS_BRPERM_RO},
  14658. + {AuBrPerm_RR, AUFS_BRPERM_RR},
  14659. + {AuBrPerm_RW, AUFS_BRPERM_RW},
  14660. +
  14661. + {AuBrPerm_ROWH, AUFS_BRPERM_ROWH},
  14662. + {AuBrPerm_RRWH, AUFS_BRPERM_RRWH},
  14663. + {AuBrPerm_RWNoLinkWH, AUFS_BRPERM_RWNLWH},
  14664. +
  14665. + {AuBrPerm_ROWH, "nfsro"},
  14666. + {AuBrPerm_RO, NULL}
  14667. +};
  14668. +
  14669. +static int br_perm_val(char *perm)
  14670. +{
  14671. + int val;
  14672. + substring_t args[MAX_OPT_ARGS];
  14673. +
  14674. + val = match_token(perm, brperms, args);
  14675. + return val;
  14676. +}
  14677. +
  14678. +const char *au_optstr_br_perm(int brperm)
  14679. +{
  14680. + return au_parser_pattern(brperm, (void *)brperms);
  14681. +}
  14682. +
  14683. +/* ---------------------------------------------------------------------- */
  14684. +
  14685. +static match_table_t udbalevel = {
  14686. + {AuOpt_UDBA_REVAL, "reval"},
  14687. + {AuOpt_UDBA_NONE, "none"},
  14688. +#ifdef CONFIG_AUFS_HINOTIFY
  14689. + {AuOpt_UDBA_HINOTIFY, "inotify"},
  14690. +#endif
  14691. + {-1, NULL}
  14692. +};
  14693. +
  14694. +static int udba_val(char *str)
  14695. +{
  14696. + substring_t args[MAX_OPT_ARGS];
  14697. +
  14698. + return match_token(str, udbalevel, args);
  14699. +}
  14700. +
  14701. +const char *au_optstr_udba(int udba)
  14702. +{
  14703. + return au_parser_pattern(udba, (void *)udbalevel);
  14704. +}
  14705. +
  14706. +/* ---------------------------------------------------------------------- */
  14707. +
  14708. +static match_table_t au_wbr_create_policy = {
  14709. + {AuWbrCreate_TDP, "tdp"},
  14710. + {AuWbrCreate_TDP, "top-down-parent"},
  14711. + {AuWbrCreate_RR, "rr"},
  14712. + {AuWbrCreate_RR, "round-robin"},
  14713. + {AuWbrCreate_MFS, "mfs"},
  14714. + {AuWbrCreate_MFS, "most-free-space"},
  14715. + {AuWbrCreate_MFSV, "mfs:%d"},
  14716. + {AuWbrCreate_MFSV, "most-free-space:%d"},
  14717. +
  14718. + {AuWbrCreate_MFSRR, "mfsrr:%d"},
  14719. + {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
  14720. + {AuWbrCreate_PMFS, "pmfs"},
  14721. + {AuWbrCreate_PMFSV, "pmfs:%d"},
  14722. +
  14723. + {-1, NULL}
  14724. +};
  14725. +
  14726. +/*
  14727. + * cf. linux/lib/parser.c and cmdline.c
  14728. + * gave up calling memparse() since it uses simple_strtoull() instead of
  14729. + * strict_...().
  14730. + */
  14731. +static int au_match_ull(substring_t *s, unsigned long long *result)
  14732. +{
  14733. + int err;
  14734. + unsigned int len;
  14735. + char a[32];
  14736. +
  14737. + err = -ERANGE;
  14738. + len = s->to - s->from;
  14739. + if (len + 1 <= sizeof(a)) {
  14740. + memcpy(a, s->from, len);
  14741. + a[len] = '\0';
  14742. + err = strict_strtoull(a, 0, result);
  14743. + }
  14744. + return err;
  14745. +}
  14746. +
  14747. +static int au_wbr_mfs_wmark(substring_t *arg, char *str,
  14748. + struct au_opt_wbr_create *create)
  14749. +{
  14750. + int err;
  14751. + unsigned long long ull;
  14752. +
  14753. + err = 0;
  14754. + if (!au_match_ull(arg, &ull))
  14755. + create->mfsrr_watermark = ull;
  14756. + else {
  14757. + AuErr("bad integer in %s\n", str);
  14758. + err = -EINVAL;
  14759. + }
  14760. +
  14761. + return err;
  14762. +}
  14763. +
  14764. +static int au_wbr_mfs_sec(substring_t *arg, char *str,
  14765. + struct au_opt_wbr_create *create)
  14766. +{
  14767. + int n, err;
  14768. +
  14769. + err = 0;
  14770. + if (!match_int(arg, &n) && 0 <= n)
  14771. + create->mfs_second = n;
  14772. + else {
  14773. + AuErr("bad integer in %s\n", str);
  14774. + err = -EINVAL;
  14775. + }
  14776. +
  14777. + return err;
  14778. +}
  14779. +
  14780. +static int au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
  14781. +{
  14782. + int err, e;
  14783. + substring_t args[MAX_OPT_ARGS];
  14784. +
  14785. + err = match_token(str, au_wbr_create_policy, args);
  14786. + create->wbr_create = err;
  14787. + switch (err) {
  14788. + case AuWbrCreate_MFSRRV:
  14789. + e = au_wbr_mfs_wmark(&args[0], str, create);
  14790. + if (!e)
  14791. + e = au_wbr_mfs_sec(&args[1], str, create);
  14792. + if (unlikely(e))
  14793. + err = e;
  14794. + break;
  14795. + case AuWbrCreate_MFSRR:
  14796. + e = au_wbr_mfs_wmark(&args[0], str, create);
  14797. + if (unlikely(e)) {
  14798. + err = e;
  14799. + break;
  14800. + }
  14801. + /*FALLTHROUGH*/
  14802. + case AuWbrCreate_MFS:
  14803. + case AuWbrCreate_PMFS:
  14804. + create->mfs_second = AUFS_MFS_SECOND_DEF;
  14805. + break;
  14806. + case AuWbrCreate_MFSV:
  14807. + case AuWbrCreate_PMFSV:
  14808. + e = au_wbr_mfs_sec(&args[0], str, create);
  14809. + if (unlikely(e))
  14810. + err = e;
  14811. + break;
  14812. + }
  14813. +
  14814. + return err;
  14815. +}
  14816. +
  14817. +const char *au_optstr_wbr_create(int wbr_create)
  14818. +{
  14819. + return au_parser_pattern(wbr_create, (void *)au_wbr_create_policy);
  14820. +}
  14821. +
  14822. +static match_table_t au_wbr_copyup_policy = {
  14823. + {AuWbrCopyup_TDP, "tdp"},
  14824. + {AuWbrCopyup_TDP, "top-down-parent"},
  14825. + {AuWbrCopyup_BUP, "bup"},
  14826. + {AuWbrCopyup_BUP, "bottom-up-parent"},
  14827. + {AuWbrCopyup_BU, "bu"},
  14828. + {AuWbrCopyup_BU, "bottom-up"},
  14829. + {-1, NULL}
  14830. +};
  14831. +
  14832. +static int au_wbr_copyup_val(char *str)
  14833. +{
  14834. + substring_t args[MAX_OPT_ARGS];
  14835. +
  14836. + return match_token(str, au_wbr_copyup_policy, args);
  14837. +}
  14838. +
  14839. +const char *au_optstr_wbr_copyup(int wbr_copyup)
  14840. +{
  14841. + return au_parser_pattern(wbr_copyup, (void *)au_wbr_copyup_policy);
  14842. +}
  14843. +
  14844. +/* ---------------------------------------------------------------------- */
  14845. +
  14846. +static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
  14847. +
  14848. +static void dump_opts(struct au_opts *opts)
  14849. +{
  14850. +#ifdef CONFIG_AUFS_DEBUG
  14851. + /* reduce stack space */
  14852. + union {
  14853. + struct au_opt_add *add;
  14854. + struct au_opt_del *del;
  14855. + struct au_opt_mod *mod;
  14856. + struct au_opt_xino *xino;
  14857. + struct au_opt_xino_itrunc *xino_itrunc;
  14858. + struct au_opt_wbr_create *create;
  14859. + } u;
  14860. + struct au_opt *opt;
  14861. +
  14862. + opt = opts->opt;
  14863. + while (opt->type != Opt_tail) {
  14864. + switch (opt->type) {
  14865. + case Opt_add:
  14866. + u.add = &opt->add;
  14867. + AuDbg("add {b%d, %s, 0x%x, %p}\n",
  14868. + u.add->bindex, u.add->pathname, u.add->perm,
  14869. + u.add->path.dentry);
  14870. + break;
  14871. + case Opt_del:
  14872. + case Opt_idel:
  14873. + u.del = &opt->del;
  14874. + AuDbg("del {%s, %p}\n",
  14875. + u.del->pathname, u.del->h_path.dentry);
  14876. + break;
  14877. + case Opt_mod:
  14878. + case Opt_imod:
  14879. + u.mod = &opt->mod;
  14880. + AuDbg("mod {%s, 0x%x, %p}\n",
  14881. + u.mod->path, u.mod->perm, u.mod->h_root);
  14882. + break;
  14883. + case Opt_append:
  14884. + u.add = &opt->add;
  14885. + AuDbg("append {b%d, %s, 0x%x, %p}\n",
  14886. + u.add->bindex, u.add->pathname, u.add->perm,
  14887. + u.add->path.dentry);
  14888. + break;
  14889. + case Opt_prepend:
  14890. + u.add = &opt->add;
  14891. + AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
  14892. + u.add->bindex, u.add->pathname, u.add->perm,
  14893. + u.add->path.dentry);
  14894. + break;
  14895. + case Opt_dirwh:
  14896. + AuDbg("dirwh %d\n", opt->dirwh);
  14897. + break;
  14898. + case Opt_rdcache:
  14899. + AuDbg("rdcache %d\n", opt->rdcache);
  14900. + break;
  14901. + case Opt_rdblk:
  14902. + AuDbg("rdblk %u\n", opt->rdblk);
  14903. + break;
  14904. + case Opt_rdblk_def:
  14905. + AuDbg("rdblk_def\n");
  14906. + break;
  14907. + case Opt_rdhash:
  14908. + AuDbg("rdhash %u\n", opt->rdhash);
  14909. + break;
  14910. + case Opt_rdhash_def:
  14911. + AuDbg("rdhash_def\n");
  14912. + break;
  14913. + case Opt_xino:
  14914. + u.xino = &opt->xino;
  14915. + AuDbg("xino {%s %.*s}\n",
  14916. + u.xino->path,
  14917. + AuDLNPair(u.xino->file->f_dentry));
  14918. + break;
  14919. + case Opt_trunc_xino:
  14920. + AuLabel(trunc_xino);
  14921. + break;
  14922. + case Opt_notrunc_xino:
  14923. + AuLabel(notrunc_xino);
  14924. + break;
  14925. + case Opt_trunc_xino_path:
  14926. + case Opt_itrunc_xino:
  14927. + u.xino_itrunc = &opt->xino_itrunc;
  14928. + AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
  14929. + break;
  14930. +
  14931. + case Opt_noxino:
  14932. + AuLabel(noxino);
  14933. + break;
  14934. + case Opt_trunc_xib:
  14935. + AuLabel(trunc_xib);
  14936. + break;
  14937. + case Opt_notrunc_xib:
  14938. + AuLabel(notrunc_xib);
  14939. + break;
  14940. + case Opt_shwh:
  14941. + AuLabel(shwh);
  14942. + break;
  14943. + case Opt_noshwh:
  14944. + AuLabel(noshwh);
  14945. + break;
  14946. + case Opt_plink:
  14947. + AuLabel(plink);
  14948. + break;
  14949. + case Opt_noplink:
  14950. + AuLabel(noplink);
  14951. + break;
  14952. + case Opt_list_plink:
  14953. + AuLabel(list_plink);
  14954. + break;
  14955. + case Opt_udba:
  14956. + AuDbg("udba %d, %s\n",
  14957. + opt->udba, au_optstr_udba(opt->udba));
  14958. + break;
  14959. + case Opt_diropq_a:
  14960. + AuLabel(diropq_a);
  14961. + break;
  14962. + case Opt_diropq_w:
  14963. + AuLabel(diropq_w);
  14964. + break;
  14965. + case Opt_warn_perm:
  14966. + AuLabel(warn_perm);
  14967. + break;
  14968. + case Opt_nowarn_perm:
  14969. + AuLabel(nowarn_perm);
  14970. + break;
  14971. + case Opt_refrof:
  14972. + AuLabel(refrof);
  14973. + break;
  14974. + case Opt_norefrof:
  14975. + AuLabel(norefrof);
  14976. + break;
  14977. + case Opt_verbose:
  14978. + AuLabel(verbose);
  14979. + break;
  14980. + case Opt_noverbose:
  14981. + AuLabel(noverbose);
  14982. + break;
  14983. + case Opt_sum:
  14984. + AuLabel(sum);
  14985. + break;
  14986. + case Opt_nosum:
  14987. + AuLabel(nosum);
  14988. + break;
  14989. + case Opt_wsum:
  14990. + AuLabel(wsum);
  14991. + break;
  14992. + case Opt_wbr_create:
  14993. + u.create = &opt->wbr_create;
  14994. + AuDbg("create %d, %s\n", u.create->wbr_create,
  14995. + au_optstr_wbr_create(u.create->wbr_create));
  14996. + switch (u.create->wbr_create) {
  14997. + case AuWbrCreate_MFSV:
  14998. + case AuWbrCreate_PMFSV:
  14999. + AuDbg("%d sec\n", u.create->mfs_second);
  15000. + break;
  15001. + case AuWbrCreate_MFSRR:
  15002. + AuDbg("%llu watermark\n",
  15003. + u.create->mfsrr_watermark);
  15004. + break;
  15005. + case AuWbrCreate_MFSRRV:
  15006. + AuDbg("%llu watermark, %d sec\n",
  15007. + u.create->mfsrr_watermark,
  15008. + u.create->mfs_second);
  15009. + break;
  15010. + }
  15011. + break;
  15012. + case Opt_wbr_copyup:
  15013. + AuDbg("copyup %d, %s\n", opt->wbr_copyup,
  15014. + au_optstr_wbr_copyup(opt->wbr_copyup));
  15015. + break;
  15016. + default:
  15017. + BUG();
  15018. + }
  15019. + opt++;
  15020. + }
  15021. +#endif
  15022. +}
  15023. +
  15024. +void au_opts_free(struct au_opts *opts)
  15025. +{
  15026. + struct au_opt *opt;
  15027. +
  15028. + opt = opts->opt;
  15029. + while (opt->type != Opt_tail) {
  15030. + switch (opt->type) {
  15031. + case Opt_add:
  15032. + case Opt_append:
  15033. + case Opt_prepend:
  15034. + path_put(&opt->add.path);
  15035. + break;
  15036. + case Opt_del:
  15037. + case Opt_idel:
  15038. + path_put(&opt->del.h_path);
  15039. + break;
  15040. + case Opt_mod:
  15041. + case Opt_imod:
  15042. + dput(opt->mod.h_root);
  15043. + break;
  15044. + case Opt_xino:
  15045. + fput(opt->xino.file);
  15046. + break;
  15047. + }
  15048. + opt++;
  15049. + }
  15050. +}
  15051. +
  15052. +static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
  15053. + aufs_bindex_t bindex)
  15054. +{
  15055. + int err;
  15056. + struct au_opt_add *add = &opt->add;
  15057. + char *p;
  15058. +
  15059. + add->bindex = bindex;
  15060. + add->perm = AuBrPerm_Last;
  15061. + add->pathname = opt_str;
  15062. + p = strchr(opt_str, '=');
  15063. + if (p) {
  15064. + *p++ = 0;
  15065. + if (*p)
  15066. + add->perm = br_perm_val(p);
  15067. + }
  15068. +
  15069. + err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
  15070. + if (!err) {
  15071. + if (!p) {
  15072. + add->perm = AuBrPerm_RO;
  15073. + if (au_test_fs_rr(add->path.dentry->d_sb))
  15074. + add->perm = AuBrPerm_RR;
  15075. + else if (!bindex && !(sb_flags & MS_RDONLY))
  15076. + add->perm = AuBrPerm_RW;
  15077. + }
  15078. + opt->type = Opt_add;
  15079. + goto out;
  15080. + }
  15081. + AuErr("lookup failed %s (%d)\n", add->pathname, err);
  15082. + err = -EINVAL;
  15083. +
  15084. + out:
  15085. + return err;
  15086. +}
  15087. +
  15088. +static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
  15089. +{
  15090. + int err;
  15091. +
  15092. + del->pathname = args[0].from;
  15093. + AuDbg("del path %s\n", del->pathname);
  15094. +
  15095. + err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
  15096. + if (unlikely(err))
  15097. + AuErr("lookup failed %s (%d)\n", del->pathname, err);
  15098. +
  15099. + return err;
  15100. +}
  15101. +
  15102. +#if 0 /* reserved for future use */
  15103. +static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
  15104. + struct au_opt_del *del, substring_t args[])
  15105. +{
  15106. + int err;
  15107. + struct dentry *root;
  15108. +
  15109. + err = -EINVAL;
  15110. + root = sb->s_root;
  15111. + aufs_read_lock(root, AuLock_FLUSH);
  15112. + if (bindex < 0 || au_sbend(sb) < bindex) {
  15113. + AuErr("out of bounds, %d\n", bindex);
  15114. + goto out;
  15115. + }
  15116. +
  15117. + err = 0;
  15118. + del->h_path.dentry = dget(au_h_dptr(root, bindex));
  15119. + del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
  15120. +
  15121. + out:
  15122. + aufs_read_unlock(root, !AuLock_IR);
  15123. + return err;
  15124. +}
  15125. +#endif
  15126. +
  15127. +static int au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
  15128. +{
  15129. + int err;
  15130. + struct path path;
  15131. + char *p;
  15132. +
  15133. + err = -EINVAL;
  15134. + mod->path = args[0].from;
  15135. + p = strchr(mod->path, '=');
  15136. + if (unlikely(!p)) {
  15137. + AuErr("no permssion %s\n", args[0].from);
  15138. + goto out;
  15139. + }
  15140. +
  15141. + *p++ = 0;
  15142. + err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
  15143. + if (unlikely(err)) {
  15144. + AuErr("lookup failed %s (%d)\n", mod->path, err);
  15145. + goto out;
  15146. + }
  15147. +
  15148. + mod->perm = br_perm_val(p);
  15149. + AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
  15150. + mod->h_root = dget(path.dentry);
  15151. + path_put(&path);
  15152. +
  15153. + out:
  15154. + return err;
  15155. +}
  15156. +
  15157. +#if 0 /* reserved for future use */
  15158. +static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
  15159. + struct au_opt_mod *mod, substring_t args[])
  15160. +{
  15161. + int err;
  15162. + struct dentry *root;
  15163. +
  15164. + err = -EINVAL;
  15165. + root = sb->s_root;
  15166. + aufs_read_lock(root, AuLock_FLUSH);
  15167. + if (bindex < 0 || au_sbend(sb) < bindex) {
  15168. + AuErr("out of bounds, %d\n", bindex);
  15169. + goto out;
  15170. + }
  15171. +
  15172. + err = 0;
  15173. + mod->perm = br_perm_val(args[1].from);
  15174. + AuDbg("mod path %s, perm 0x%x, %s\n",
  15175. + mod->path, mod->perm, args[1].from);
  15176. + mod->h_root = dget(au_h_dptr(root, bindex));
  15177. +
  15178. + out:
  15179. + aufs_read_unlock(root, !AuLock_IR);
  15180. + return err;
  15181. +}
  15182. +#endif
  15183. +
  15184. +static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
  15185. + substring_t args[])
  15186. +{
  15187. + int err;
  15188. + struct file *file;
  15189. +
  15190. + file = au_xino_create(sb, args[0].from, /*silent*/0);
  15191. + err = PTR_ERR(file);
  15192. + if (IS_ERR(file))
  15193. + goto out;
  15194. +
  15195. + err = -EINVAL;
  15196. + if (unlikely(file->f_dentry->d_sb == sb)) {
  15197. + fput(file);
  15198. + AuErr("%s must be outside\n", args[0].from);
  15199. + goto out;
  15200. + }
  15201. +
  15202. + err = 0;
  15203. + xino->file = file;
  15204. + xino->path = args[0].from;
  15205. +
  15206. + out:
  15207. + return err;
  15208. +}
  15209. +
  15210. +static
  15211. +int au_opts_parse_xino_itrunc_path(struct super_block *sb,
  15212. + struct au_opt_xino_itrunc *xino_itrunc,
  15213. + substring_t args[])
  15214. +{
  15215. + int err;
  15216. + aufs_bindex_t bend, bindex;
  15217. + struct path path;
  15218. + struct dentry *root;
  15219. +
  15220. + err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
  15221. + if (unlikely(err)) {
  15222. + AuErr("lookup failed %s (%d)\n", args[0].from, err);
  15223. + goto out;
  15224. + }
  15225. +
  15226. + xino_itrunc->bindex = -1;
  15227. + root = sb->s_root;
  15228. + aufs_read_lock(root, AuLock_FLUSH);
  15229. + bend = au_sbend(sb);
  15230. + for (bindex = 0; bindex <= bend; bindex++) {
  15231. + if (au_h_dptr(root, bindex) == path.dentry) {
  15232. + xino_itrunc->bindex = bindex;
  15233. + break;
  15234. + }
  15235. + }
  15236. + aufs_read_unlock(root, !AuLock_IR);
  15237. + path_put(&path);
  15238. +
  15239. + if (unlikely(xino_itrunc->bindex < 0)) {
  15240. + AuErr("no such branch %s\n", args[0].from);
  15241. + err = -EINVAL;
  15242. + }
  15243. +
  15244. + out:
  15245. + return err;
  15246. +}
  15247. +
  15248. +/* called without aufs lock */
  15249. +int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
  15250. +{
  15251. + int err, n, token;
  15252. + aufs_bindex_t bindex;
  15253. + unsigned char skipped;
  15254. + struct dentry *root;
  15255. + struct au_opt *opt, *opt_tail;
  15256. + char *opt_str;
  15257. + /* reduce the stack space */
  15258. + union {
  15259. + struct au_opt_xino_itrunc *xino_itrunc;
  15260. + struct au_opt_wbr_create *create;
  15261. + } u;
  15262. + struct {
  15263. + substring_t args[MAX_OPT_ARGS];
  15264. + } *a;
  15265. +
  15266. + err = -ENOMEM;
  15267. + a = kmalloc(sizeof(*a), GFP_NOFS);
  15268. + if (unlikely(!a))
  15269. + goto out;
  15270. +
  15271. + root = sb->s_root;
  15272. + err = 0;
  15273. + bindex = 0;
  15274. + opt = opts->opt;
  15275. + opt_tail = opt + opts->max_opt - 1;
  15276. + opt->type = Opt_tail;
  15277. + while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
  15278. + err = -EINVAL;
  15279. + skipped = 0;
  15280. + token = match_token(opt_str, options, a->args);
  15281. + switch (token) {
  15282. + case Opt_br:
  15283. + err = 0;
  15284. + while (!err && (opt_str = strsep(&a->args[0].from, ":"))
  15285. + && *opt_str) {
  15286. + err = opt_add(opt, opt_str, opts->sb_flags,
  15287. + bindex++);
  15288. + if (unlikely(!err && ++opt > opt_tail)) {
  15289. + err = -E2BIG;
  15290. + break;
  15291. + }
  15292. + opt->type = Opt_tail;
  15293. + skipped = 1;
  15294. + }
  15295. + break;
  15296. + case Opt_add:
  15297. + if (unlikely(match_int(&a->args[0], &n))) {
  15298. + AuErr("bad integer in %s\n", opt_str);
  15299. + break;
  15300. + }
  15301. + bindex = n;
  15302. + err = opt_add(opt, a->args[1].from, opts->sb_flags,
  15303. + bindex);
  15304. + if (!err)
  15305. + opt->type = token;
  15306. + break;
  15307. + case Opt_append:
  15308. + err = opt_add(opt, a->args[0].from, opts->sb_flags,
  15309. + /*dummy bindex*/1);
  15310. + if (!err)
  15311. + opt->type = token;
  15312. + break;
  15313. + case Opt_prepend:
  15314. + err = opt_add(opt, a->args[0].from, opts->sb_flags,
  15315. + /*bindex*/0);
  15316. + if (!err)
  15317. + opt->type = token;
  15318. + break;
  15319. + case Opt_del:
  15320. + err = au_opts_parse_del(&opt->del, a->args);
  15321. + if (!err)
  15322. + opt->type = token;
  15323. + break;
  15324. +#if 0 /* reserved for future use */
  15325. + case Opt_idel:
  15326. + del->pathname = "(indexed)";
  15327. + if (unlikely(match_int(&args[0], &n))) {
  15328. + AuErr("bad integer in %s\n", opt_str);
  15329. + break;
  15330. + }
  15331. + err = au_opts_parse_idel(sb, n, &opt->del, a->args);
  15332. + if (!err)
  15333. + opt->type = token;
  15334. + break;
  15335. +#endif
  15336. + case Opt_mod:
  15337. + err = au_opts_parse_mod(&opt->mod, a->args);
  15338. + if (!err)
  15339. + opt->type = token;
  15340. + break;
  15341. +#ifdef IMOD /* reserved for future use */
  15342. + case Opt_imod:
  15343. + u.mod->path = "(indexed)";
  15344. + if (unlikely(match_int(&a->args[0], &n))) {
  15345. + AuErr("bad integer in %s\n", opt_str);
  15346. + break;
  15347. + }
  15348. + err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
  15349. + if (!err)
  15350. + opt->type = token;
  15351. + break;
  15352. +#endif
  15353. + case Opt_xino:
  15354. + err = au_opts_parse_xino(sb, &opt->xino, a->args);
  15355. + if (!err)
  15356. + opt->type = token;
  15357. + break;
  15358. +
  15359. + case Opt_trunc_xino_path:
  15360. + err = au_opts_parse_xino_itrunc_path
  15361. + (sb, &opt->xino_itrunc, a->args);
  15362. + if (!err)
  15363. + opt->type = token;
  15364. + break;
  15365. +
  15366. + case Opt_itrunc_xino:
  15367. + u.xino_itrunc = &opt->xino_itrunc;
  15368. + if (unlikely(match_int(&a->args[0], &n))) {
  15369. + AuErr("bad integer in %s\n", opt_str);
  15370. + break;
  15371. + }
  15372. + u.xino_itrunc->bindex = n;
  15373. + aufs_read_lock(root, AuLock_FLUSH);
  15374. + if (n < 0 || au_sbend(sb) < n) {
  15375. + AuErr("out of bounds, %d\n", n);
  15376. + aufs_read_unlock(root, !AuLock_IR);
  15377. + break;
  15378. + }
  15379. + aufs_read_unlock(root, !AuLock_IR);
  15380. + err = 0;
  15381. + opt->type = token;
  15382. + break;
  15383. +
  15384. + case Opt_dirwh:
  15385. + if (unlikely(match_int(&a->args[0], &opt->dirwh)))
  15386. + break;
  15387. + err = 0;
  15388. + opt->type = token;
  15389. + break;
  15390. +
  15391. + case Opt_rdcache:
  15392. + if (unlikely(match_int(&a->args[0], &opt->rdcache)))
  15393. + break;
  15394. + err = 0;
  15395. + opt->type = token;
  15396. + break;
  15397. + case Opt_rdblk:
  15398. + if (unlikely(match_int(&a->args[0], &n)
  15399. + || n <= 0
  15400. + || n > KMALLOC_MAX_SIZE)) {
  15401. + AuErr("bad integer in %s\n", opt_str);
  15402. + break;
  15403. + }
  15404. + if (unlikely(n < NAME_MAX)) {
  15405. + AuErr("rdblk must be larger than %d\n",
  15406. + NAME_MAX);
  15407. + break;
  15408. + }
  15409. + opt->rdblk = n;
  15410. + err = 0;
  15411. + opt->type = token;
  15412. + break;
  15413. + case Opt_rdhash:
  15414. + if (unlikely(match_int(&a->args[0], &n)
  15415. + || n <= 0
  15416. + || n * sizeof(struct hlist_head)
  15417. + > KMALLOC_MAX_SIZE)) {
  15418. + AuErr("bad integer in %s\n", opt_str);
  15419. + break;
  15420. + }
  15421. + opt->rdhash = n;
  15422. + err = 0;
  15423. + opt->type = token;
  15424. + break;
  15425. +
  15426. + case Opt_trunc_xino:
  15427. + case Opt_notrunc_xino:
  15428. + case Opt_noxino:
  15429. + case Opt_trunc_xib:
  15430. + case Opt_notrunc_xib:
  15431. + case Opt_shwh:
  15432. + case Opt_noshwh:
  15433. + case Opt_plink:
  15434. + case Opt_noplink:
  15435. + case Opt_list_plink:
  15436. + case Opt_diropq_a:
  15437. + case Opt_diropq_w:
  15438. + case Opt_warn_perm:
  15439. + case Opt_nowarn_perm:
  15440. + case Opt_refrof:
  15441. + case Opt_norefrof:
  15442. + case Opt_verbose:
  15443. + case Opt_noverbose:
  15444. + case Opt_sum:
  15445. + case Opt_nosum:
  15446. + case Opt_wsum:
  15447. + case Opt_rdblk_def:
  15448. + case Opt_rdhash_def:
  15449. + err = 0;
  15450. + opt->type = token;
  15451. + break;
  15452. +
  15453. + case Opt_udba:
  15454. + opt->udba = udba_val(a->args[0].from);
  15455. + if (opt->udba >= 0) {
  15456. + err = 0;
  15457. + opt->type = token;
  15458. + } else
  15459. + AuErr("wrong value, %s\n", opt_str);
  15460. + break;
  15461. +
  15462. + case Opt_wbr_create:
  15463. + u.create = &opt->wbr_create;
  15464. + u.create->wbr_create
  15465. + = au_wbr_create_val(a->args[0].from, u.create);
  15466. + if (u.create->wbr_create >= 0) {
  15467. + err = 0;
  15468. + opt->type = token;
  15469. + } else
  15470. + AuErr("wrong value, %s\n", opt_str);
  15471. + break;
  15472. + case Opt_wbr_copyup:
  15473. + opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
  15474. + if (opt->wbr_copyup >= 0) {
  15475. + err = 0;
  15476. + opt->type = token;
  15477. + } else
  15478. + AuErr("wrong value, %s\n", opt_str);
  15479. + break;
  15480. +
  15481. + case Opt_ignore:
  15482. + AuWarn("ignored %s\n", opt_str);
  15483. + /*FALLTHROUGH*/
  15484. + case Opt_ignore_silent:
  15485. + skipped = 1;
  15486. + err = 0;
  15487. + break;
  15488. + case Opt_err:
  15489. + AuErr("unknown option %s\n", opt_str);
  15490. + break;
  15491. + }
  15492. +
  15493. + if (!err && !skipped) {
  15494. + if (unlikely(++opt > opt_tail)) {
  15495. + err = -E2BIG;
  15496. + opt--;
  15497. + opt->type = Opt_tail;
  15498. + break;
  15499. + }
  15500. + opt->type = Opt_tail;
  15501. + }
  15502. + }
  15503. +
  15504. + kfree(a);
  15505. + dump_opts(opts);
  15506. + if (unlikely(err))
  15507. + au_opts_free(opts);
  15508. +
  15509. + out:
  15510. + return err;
  15511. +}
  15512. +
  15513. +static int au_opt_wbr_create(struct super_block *sb,
  15514. + struct au_opt_wbr_create *create)
  15515. +{
  15516. + int err;
  15517. + struct au_sbinfo *sbinfo;
  15518. +
  15519. + SiMustWriteLock(sb);
  15520. +
  15521. + err = 1; /* handled */
  15522. + sbinfo = au_sbi(sb);
  15523. + if (sbinfo->si_wbr_create_ops->fin) {
  15524. + err = sbinfo->si_wbr_create_ops->fin(sb);
  15525. + if (!err)
  15526. + err = 1;
  15527. + }
  15528. +
  15529. + sbinfo->si_wbr_create = create->wbr_create;
  15530. + sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
  15531. + switch (create->wbr_create) {
  15532. + case AuWbrCreate_MFSRRV:
  15533. + case AuWbrCreate_MFSRR:
  15534. + sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
  15535. + /*FALLTHROUGH*/
  15536. + case AuWbrCreate_MFS:
  15537. + case AuWbrCreate_MFSV:
  15538. + case AuWbrCreate_PMFS:
  15539. + case AuWbrCreate_PMFSV:
  15540. + sbinfo->si_wbr_mfs.mfs_expire = create->mfs_second * HZ;
  15541. + break;
  15542. + }
  15543. +
  15544. + if (sbinfo->si_wbr_create_ops->init)
  15545. + sbinfo->si_wbr_create_ops->init(sb); /* ignore */
  15546. +
  15547. + return err;
  15548. +}
  15549. +
  15550. +/*
  15551. + * returns,
  15552. + * plus: processed without an error
  15553. + * zero: unprocessed
  15554. + */
  15555. +static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
  15556. + struct au_opts *opts)
  15557. +{
  15558. + int err;
  15559. + struct au_sbinfo *sbinfo;
  15560. +
  15561. + SiMustWriteLock(sb);
  15562. +
  15563. + err = 1; /* handled */
  15564. + sbinfo = au_sbi(sb);
  15565. + switch (opt->type) {
  15566. + case Opt_udba:
  15567. + sbinfo->si_mntflags &= ~AuOptMask_UDBA;
  15568. + sbinfo->si_mntflags |= opt->udba;
  15569. + opts->given_udba |= opt->udba;
  15570. + break;
  15571. +
  15572. + case Opt_plink:
  15573. + au_opt_set(sbinfo->si_mntflags, PLINK);
  15574. + break;
  15575. + case Opt_noplink:
  15576. + if (au_opt_test(sbinfo->si_mntflags, PLINK))
  15577. + au_plink_put(sb);
  15578. + au_opt_clr(sbinfo->si_mntflags, PLINK);
  15579. + break;
  15580. + case Opt_list_plink:
  15581. + if (au_opt_test(sbinfo->si_mntflags, PLINK))
  15582. + au_plink_list(sb);
  15583. + break;
  15584. +
  15585. + case Opt_diropq_a:
  15586. + au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
  15587. + break;
  15588. + case Opt_diropq_w:
  15589. + au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
  15590. + break;
  15591. +
  15592. + case Opt_warn_perm:
  15593. + au_opt_set(sbinfo->si_mntflags, WARN_PERM);
  15594. + break;
  15595. + case Opt_nowarn_perm:
  15596. + au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
  15597. + break;
  15598. +
  15599. + case Opt_refrof:
  15600. + au_opt_set(sbinfo->si_mntflags, REFROF);
  15601. + break;
  15602. + case Opt_norefrof:
  15603. + au_opt_clr(sbinfo->si_mntflags, REFROF);
  15604. + break;
  15605. +
  15606. + case Opt_verbose:
  15607. + au_opt_set(sbinfo->si_mntflags, VERBOSE);
  15608. + break;
  15609. + case Opt_noverbose:
  15610. + au_opt_clr(sbinfo->si_mntflags, VERBOSE);
  15611. + break;
  15612. +
  15613. + case Opt_sum:
  15614. + au_opt_set(sbinfo->si_mntflags, SUM);
  15615. + break;
  15616. + case Opt_wsum:
  15617. + au_opt_clr(sbinfo->si_mntflags, SUM);
  15618. + au_opt_set(sbinfo->si_mntflags, SUM_W);
  15619. + case Opt_nosum:
  15620. + au_opt_clr(sbinfo->si_mntflags, SUM);
  15621. + au_opt_clr(sbinfo->si_mntflags, SUM_W);
  15622. + break;
  15623. +
  15624. + case Opt_wbr_create:
  15625. + err = au_opt_wbr_create(sb, &opt->wbr_create);
  15626. + break;
  15627. + case Opt_wbr_copyup:
  15628. + sbinfo->si_wbr_copyup = opt->wbr_copyup;
  15629. + sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
  15630. + break;
  15631. +
  15632. + case Opt_dirwh:
  15633. + sbinfo->si_dirwh = opt->dirwh;
  15634. + break;
  15635. +
  15636. + case Opt_rdcache:
  15637. + sbinfo->si_rdcache = opt->rdcache * HZ;
  15638. + break;
  15639. + case Opt_rdblk:
  15640. + sbinfo->si_rdblk = opt->rdblk;
  15641. + break;
  15642. + case Opt_rdblk_def:
  15643. + sbinfo->si_rdblk = AUFS_RDBLK_DEF;
  15644. + break;
  15645. + case Opt_rdhash:
  15646. + sbinfo->si_rdhash = opt->rdhash;
  15647. + break;
  15648. + case Opt_rdhash_def:
  15649. + sbinfo->si_rdhash = AUFS_RDHASH_DEF;
  15650. + break;
  15651. +
  15652. + case Opt_shwh:
  15653. + au_opt_set(sbinfo->si_mntflags, SHWH);
  15654. + break;
  15655. + case Opt_noshwh:
  15656. + au_opt_clr(sbinfo->si_mntflags, SHWH);
  15657. + break;
  15658. +
  15659. + case Opt_trunc_xino:
  15660. + au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
  15661. + break;
  15662. + case Opt_notrunc_xino:
  15663. + au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
  15664. + break;
  15665. +
  15666. + case Opt_trunc_xino_path:
  15667. + case Opt_itrunc_xino:
  15668. + err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
  15669. + if (!err)
  15670. + err = 1;
  15671. + break;
  15672. +
  15673. + case Opt_trunc_xib:
  15674. + au_fset_opts(opts->flags, TRUNC_XIB);
  15675. + break;
  15676. + case Opt_notrunc_xib:
  15677. + au_fclr_opts(opts->flags, TRUNC_XIB);
  15678. + break;
  15679. +
  15680. + default:
  15681. + err = 0;
  15682. + break;
  15683. + }
  15684. +
  15685. + return err;
  15686. +}
  15687. +
  15688. +/*
  15689. + * returns tri-state.
  15690. + * plus: processed without an error
  15691. + * zero: unprocessed
  15692. + * minus: error
  15693. + */
  15694. +static int au_opt_br(struct super_block *sb, struct au_opt *opt,
  15695. + struct au_opts *opts)
  15696. +{
  15697. + int err, do_refresh;
  15698. +
  15699. + err = 0;
  15700. + switch (opt->type) {
  15701. + case Opt_append:
  15702. + opt->add.bindex = au_sbend(sb) + 1;
  15703. + if (opt->add.bindex < 0)
  15704. + opt->add.bindex = 0;
  15705. + goto add;
  15706. + case Opt_prepend:
  15707. + opt->add.bindex = 0;
  15708. + add:
  15709. + case Opt_add:
  15710. + err = au_br_add(sb, &opt->add,
  15711. + au_ftest_opts(opts->flags, REMOUNT));
  15712. + if (!err) {
  15713. + err = 1;
  15714. + au_fset_opts(opts->flags, REFRESH_DIR);
  15715. + if (au_br_whable(opt->add.perm))
  15716. + au_fset_opts(opts->flags, REFRESH_NONDIR);
  15717. + }
  15718. + break;
  15719. +
  15720. + case Opt_del:
  15721. + case Opt_idel:
  15722. + err = au_br_del(sb, &opt->del,
  15723. + au_ftest_opts(opts->flags, REMOUNT));
  15724. + if (!err) {
  15725. + err = 1;
  15726. + au_fset_opts(opts->flags, TRUNC_XIB);
  15727. + au_fset_opts(opts->flags, REFRESH_DIR);
  15728. + au_fset_opts(opts->flags, REFRESH_NONDIR);
  15729. + }
  15730. + break;
  15731. +
  15732. + case Opt_mod:
  15733. + case Opt_imod:
  15734. + err = au_br_mod(sb, &opt->mod,
  15735. + au_ftest_opts(opts->flags, REMOUNT),
  15736. + &do_refresh);
  15737. + if (!err) {
  15738. + err = 1;
  15739. + if (do_refresh) {
  15740. + au_fset_opts(opts->flags, REFRESH_DIR);
  15741. + au_fset_opts(opts->flags, REFRESH_NONDIR);
  15742. + }
  15743. + }
  15744. + break;
  15745. + }
  15746. +
  15747. + return err;
  15748. +}
  15749. +
  15750. +static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
  15751. + struct au_opt_xino **opt_xino,
  15752. + struct au_opts *opts)
  15753. +{
  15754. + int err;
  15755. + aufs_bindex_t bend, bindex;
  15756. + struct dentry *root, *parent, *h_root;
  15757. +
  15758. + err = 0;
  15759. + switch (opt->type) {
  15760. + case Opt_xino:
  15761. + err = au_xino_set(sb, &opt->xino,
  15762. + !!au_ftest_opts(opts->flags, REMOUNT));
  15763. + if (unlikely(err))
  15764. + break;
  15765. +
  15766. + *opt_xino = &opt->xino;
  15767. + au_xino_brid_set(sb, -1);
  15768. +
  15769. + /* safe d_parent access */
  15770. + parent = opt->xino.file->f_dentry->d_parent;
  15771. + root = sb->s_root;
  15772. + bend = au_sbend(sb);
  15773. + for (bindex = 0; bindex <= bend; bindex++) {
  15774. + h_root = au_h_dptr(root, bindex);
  15775. + if (h_root == parent) {
  15776. + au_xino_brid_set(sb, au_sbr_id(sb, bindex));
  15777. + break;
  15778. + }
  15779. + }
  15780. + break;
  15781. +
  15782. + case Opt_noxino:
  15783. + au_xino_clr(sb);
  15784. + au_xino_brid_set(sb, -1);
  15785. + *opt_xino = (void *)-1;
  15786. + break;
  15787. + }
  15788. +
  15789. + return err;
  15790. +}
  15791. +
  15792. +int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
  15793. + unsigned int pending)
  15794. +{
  15795. + int err;
  15796. + aufs_bindex_t bindex, bend;
  15797. + unsigned char do_plink, skip, do_free;
  15798. + struct au_branch *br;
  15799. + struct au_wbr *wbr;
  15800. + struct dentry *root;
  15801. + struct inode *dir, *h_dir;
  15802. + struct au_sbinfo *sbinfo;
  15803. + struct au_hinode *hdir;
  15804. +
  15805. + SiMustAnyLock(sb);
  15806. +
  15807. + sbinfo = au_sbi(sb);
  15808. + AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
  15809. +
  15810. + if (!(sb_flags & MS_RDONLY)) {
  15811. + if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
  15812. + AuWarn("first branch should be rw\n");
  15813. + if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
  15814. + AuWarn("shwh should be used with ro\n");
  15815. + }
  15816. +
  15817. + if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HINOTIFY)
  15818. + && !au_opt_test(sbinfo->si_mntflags, XINO))
  15819. + AuWarn("udba=inotify requires xino\n");
  15820. +
  15821. + err = 0;
  15822. + root = sb->s_root;
  15823. + dir = sb->s_root->d_inode;
  15824. + do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
  15825. + bend = au_sbend(sb);
  15826. + for (bindex = 0; !err && bindex <= bend; bindex++) {
  15827. + skip = 0;
  15828. + h_dir = au_h_iptr(dir, bindex);
  15829. + br = au_sbr(sb, bindex);
  15830. + do_free = 0;
  15831. +
  15832. + wbr = br->br_wbr;
  15833. + if (wbr)
  15834. + wbr_wh_read_lock(wbr);
  15835. +
  15836. + switch (br->br_perm) {
  15837. + case AuBrPerm_RO:
  15838. + case AuBrPerm_ROWH:
  15839. + case AuBrPerm_RR:
  15840. + case AuBrPerm_RRWH:
  15841. + do_free = !!wbr;
  15842. + skip = (!wbr
  15843. + || (!wbr->wbr_whbase
  15844. + && !wbr->wbr_plink
  15845. + && !wbr->wbr_orph));
  15846. + break;
  15847. +
  15848. + case AuBrPerm_RWNoLinkWH:
  15849. + /* skip = (!br->br_whbase && !br->br_orph); */
  15850. + skip = (!wbr || !wbr->wbr_whbase);
  15851. + if (skip && wbr) {
  15852. + if (do_plink)
  15853. + skip = !!wbr->wbr_plink;
  15854. + else
  15855. + skip = !wbr->wbr_plink;
  15856. + }
  15857. + break;
  15858. +
  15859. + case AuBrPerm_RW:
  15860. + /* skip = (br->br_whbase && br->br_ohph); */
  15861. + skip = (wbr && wbr->wbr_whbase);
  15862. + if (skip) {
  15863. + if (do_plink)
  15864. + skip = !!wbr->wbr_plink;
  15865. + else
  15866. + skip = !wbr->wbr_plink;
  15867. + }
  15868. + break;
  15869. +
  15870. + default:
  15871. + BUG();
  15872. + }
  15873. + if (wbr)
  15874. + wbr_wh_read_unlock(wbr);
  15875. +
  15876. + if (skip)
  15877. + continue;
  15878. +
  15879. + hdir = au_hi(dir, bindex);
  15880. + au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT);
  15881. + if (wbr)
  15882. + wbr_wh_write_lock(wbr);
  15883. + err = au_wh_init(au_h_dptr(root, bindex), br, sb);
  15884. + if (wbr)
  15885. + wbr_wh_write_unlock(wbr);
  15886. + au_hin_imtx_unlock(hdir);
  15887. +
  15888. + if (!err && do_free) {
  15889. + kfree(wbr);
  15890. + br->br_wbr = NULL;
  15891. + }
  15892. + }
  15893. +
  15894. + return err;
  15895. +}
  15896. +
  15897. +int au_opts_mount(struct super_block *sb, struct au_opts *opts)
  15898. +{
  15899. + int err;
  15900. + unsigned int tmp;
  15901. + aufs_bindex_t bend;
  15902. + struct au_opt *opt;
  15903. + struct au_opt_xino *opt_xino, xino;
  15904. + struct au_sbinfo *sbinfo;
  15905. +
  15906. + SiMustWriteLock(sb);
  15907. +
  15908. + err = 0;
  15909. + opt_xino = NULL;
  15910. + opt = opts->opt;
  15911. + while (err >= 0 && opt->type != Opt_tail)
  15912. + err = au_opt_simple(sb, opt++, opts);
  15913. + if (err > 0)
  15914. + err = 0;
  15915. + else if (unlikely(err < 0))
  15916. + goto out;
  15917. +
  15918. + /* disable xino and udba temporary */
  15919. + sbinfo = au_sbi(sb);
  15920. + tmp = sbinfo->si_mntflags;
  15921. + au_opt_clr(sbinfo->si_mntflags, XINO);
  15922. + au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
  15923. +
  15924. + opt = opts->opt;
  15925. + while (err >= 0 && opt->type != Opt_tail)
  15926. + err = au_opt_br(sb, opt++, opts);
  15927. + if (err > 0)
  15928. + err = 0;
  15929. + else if (unlikely(err < 0))
  15930. + goto out;
  15931. +
  15932. + bend = au_sbend(sb);
  15933. + if (unlikely(bend < 0)) {
  15934. + err = -EINVAL;
  15935. + AuErr("no branches\n");
  15936. + goto out;
  15937. + }
  15938. +
  15939. + if (au_opt_test(tmp, XINO))
  15940. + au_opt_set(sbinfo->si_mntflags, XINO);
  15941. + opt = opts->opt;
  15942. + while (!err && opt->type != Opt_tail)
  15943. + err = au_opt_xino(sb, opt++, &opt_xino, opts);
  15944. + if (unlikely(err))
  15945. + goto out;
  15946. +
  15947. + err = au_opts_verify(sb, sb->s_flags, tmp);
  15948. + if (unlikely(err))
  15949. + goto out;
  15950. +
  15951. + /* restore xino */
  15952. + if (au_opt_test(tmp, XINO) && !opt_xino) {
  15953. + xino.file = au_xino_def(sb);
  15954. + err = PTR_ERR(xino.file);
  15955. + if (IS_ERR(xino.file))
  15956. + goto out;
  15957. +
  15958. + err = au_xino_set(sb, &xino, /*remount*/0);
  15959. + fput(xino.file);
  15960. + if (unlikely(err))
  15961. + goto out;
  15962. + }
  15963. +
  15964. + /* restore udba */
  15965. + sbinfo->si_mntflags &= ~AuOptMask_UDBA;
  15966. + sbinfo->si_mntflags |= (tmp & AuOptMask_UDBA);
  15967. + if (au_opt_test(tmp, UDBA_HINOTIFY)) {
  15968. + struct inode *dir = sb->s_root->d_inode;
  15969. + au_reset_hinotify(dir,
  15970. + au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
  15971. + }
  15972. +
  15973. + out:
  15974. + return err;
  15975. +}
  15976. +
  15977. +int au_opts_remount(struct super_block *sb, struct au_opts *opts)
  15978. +{
  15979. + int err, rerr;
  15980. + struct inode *dir;
  15981. + struct au_opt_xino *opt_xino;
  15982. + struct au_opt *opt;
  15983. + struct au_sbinfo *sbinfo;
  15984. +
  15985. + SiMustWriteLock(sb);
  15986. +
  15987. + dir = sb->s_root->d_inode;
  15988. + sbinfo = au_sbi(sb);
  15989. + err = 0;
  15990. + opt_xino = NULL;
  15991. + opt = opts->opt;
  15992. + while (err >= 0 && opt->type != Opt_tail) {
  15993. + err = au_opt_simple(sb, opt, opts);
  15994. + if (!err)
  15995. + err = au_opt_br(sb, opt, opts);
  15996. + if (!err)
  15997. + err = au_opt_xino(sb, opt, &opt_xino, opts);
  15998. + opt++;
  15999. + }
  16000. + if (err > 0)
  16001. + err = 0;
  16002. + AuTraceErr(err);
  16003. + /* go on even err */
  16004. +
  16005. + rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
  16006. + if (unlikely(rerr && !err))
  16007. + err = rerr;
  16008. +
  16009. + if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
  16010. + rerr = au_xib_trunc(sb);
  16011. + if (unlikely(rerr && !err))
  16012. + err = rerr;
  16013. + }
  16014. +
  16015. + /* will be handled by the caller */
  16016. + if (!au_ftest_opts(opts->flags, REFRESH_DIR)
  16017. + && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO)))
  16018. + au_fset_opts(opts->flags, REFRESH_DIR);
  16019. +
  16020. + AuDbg("status 0x%x\n", opts->flags);
  16021. + return err;
  16022. +}
  16023. +
  16024. +/* ---------------------------------------------------------------------- */
  16025. +
  16026. +unsigned int au_opt_udba(struct super_block *sb)
  16027. +{
  16028. + return au_mntflags(sb) & AuOptMask_UDBA;
  16029. +}
  16030. diff -Nur linux-2.6.34.orig/fs/aufs/opts.h linux-2.6.34/fs/aufs/opts.h
  16031. --- linux-2.6.34.orig/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100
  16032. +++ linux-2.6.34/fs/aufs/opts.h 2010-05-23 23:33:20.990967055 +0200
  16033. @@ -0,0 +1,196 @@
  16034. +/*
  16035. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  16036. + *
  16037. + * This program, aufs is free software; you can redistribute it and/or modify
  16038. + * it under the terms of the GNU General Public License as published by
  16039. + * the Free Software Foundation; either version 2 of the License, or
  16040. + * (at your option) any later version.
  16041. + *
  16042. + * This program is distributed in the hope that it will be useful,
  16043. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16044. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16045. + * GNU General Public License for more details.
  16046. + *
  16047. + * You should have received a copy of the GNU General Public License
  16048. + * along with this program; if not, write to the Free Software
  16049. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16050. + */
  16051. +
  16052. +/*
  16053. + * mount options/flags
  16054. + */
  16055. +
  16056. +#ifndef __AUFS_OPTS_H__
  16057. +#define __AUFS_OPTS_H__
  16058. +
  16059. +#ifdef __KERNEL__
  16060. +
  16061. +#include <linux/path.h>
  16062. +#include <linux/aufs_type.h>
  16063. +
  16064. +struct file;
  16065. +struct super_block;
  16066. +
  16067. +/* ---------------------------------------------------------------------- */
  16068. +
  16069. +/* mount flags */
  16070. +#define AuOpt_XINO 1 /* external inode number bitmap
  16071. + and translation table */
  16072. +#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */
  16073. +#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */
  16074. +#define AuOpt_UDBA_REVAL (1 << 3)
  16075. +#define AuOpt_UDBA_HINOTIFY (1 << 4)
  16076. +#define AuOpt_SHWH (1 << 5) /* show whiteout */
  16077. +#define AuOpt_PLINK (1 << 6) /* pseudo-link */
  16078. +#define AuOpt_DIRPERM1 (1 << 7) /* unimplemented */
  16079. +#define AuOpt_REFROF (1 << 8) /* unimplemented */
  16080. +#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */
  16081. +#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
  16082. +#define AuOpt_SUM_W (1 << 11) /* unimplemented */
  16083. +#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */
  16084. +#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */
  16085. +
  16086. +#ifndef CONFIG_AUFS_HINOTIFY
  16087. +#undef AuOpt_UDBA_HINOTIFY
  16088. +#define AuOpt_UDBA_HINOTIFY 0
  16089. +#endif
  16090. +#ifndef CONFIG_AUFS_SHWH
  16091. +#undef AuOpt_SHWH
  16092. +#define AuOpt_SHWH 0
  16093. +#endif
  16094. +
  16095. +#define AuOpt_Def (AuOpt_XINO \
  16096. + | AuOpt_UDBA_REVAL \
  16097. + | AuOpt_PLINK \
  16098. + /* | AuOpt_DIRPERM1 */ \
  16099. + | AuOpt_WARN_PERM)
  16100. +#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
  16101. + | AuOpt_UDBA_REVAL \
  16102. + | AuOpt_UDBA_HINOTIFY)
  16103. +
  16104. +#define au_opt_test(flags, name) (flags & AuOpt_##name)
  16105. +#define au_opt_set(flags, name) do { \
  16106. + BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
  16107. + ((flags) |= AuOpt_##name); \
  16108. +} while (0)
  16109. +#define au_opt_set_udba(flags, name) do { \
  16110. + (flags) &= ~AuOptMask_UDBA; \
  16111. + ((flags) |= AuOpt_##name); \
  16112. +} while (0)
  16113. +#define au_opt_clr(flags, name) { ((flags) &= ~AuOpt_##name); }
  16114. +
  16115. +/* ---------------------------------------------------------------------- */
  16116. +
  16117. +/* policies to select one among multiple writable branches */
  16118. +enum {
  16119. + AuWbrCreate_TDP, /* top down parent */
  16120. + AuWbrCreate_RR, /* round robin */
  16121. + AuWbrCreate_MFS, /* most free space */
  16122. + AuWbrCreate_MFSV, /* mfs with seconds */
  16123. + AuWbrCreate_MFSRR, /* mfs then rr */
  16124. + AuWbrCreate_MFSRRV, /* mfs then rr with seconds */
  16125. + AuWbrCreate_PMFS, /* parent and mfs */
  16126. + AuWbrCreate_PMFSV, /* parent and mfs with seconds */
  16127. +
  16128. + AuWbrCreate_Def = AuWbrCreate_TDP
  16129. +};
  16130. +
  16131. +enum {
  16132. + AuWbrCopyup_TDP, /* top down parent */
  16133. + AuWbrCopyup_BUP, /* bottom up parent */
  16134. + AuWbrCopyup_BU, /* bottom up */
  16135. +
  16136. + AuWbrCopyup_Def = AuWbrCopyup_TDP
  16137. +};
  16138. +
  16139. +/* ---------------------------------------------------------------------- */
  16140. +
  16141. +struct au_opt_add {
  16142. + aufs_bindex_t bindex;
  16143. + char *pathname;
  16144. + int perm;
  16145. + struct path path;
  16146. +};
  16147. +
  16148. +struct au_opt_del {
  16149. + char *pathname;
  16150. + struct path h_path;
  16151. +};
  16152. +
  16153. +struct au_opt_mod {
  16154. + char *path;
  16155. + int perm;
  16156. + struct dentry *h_root;
  16157. +};
  16158. +
  16159. +struct au_opt_xino {
  16160. + char *path;
  16161. + struct file *file;
  16162. +};
  16163. +
  16164. +struct au_opt_xino_itrunc {
  16165. + aufs_bindex_t bindex;
  16166. +};
  16167. +
  16168. +struct au_opt_wbr_create {
  16169. + int wbr_create;
  16170. + int mfs_second;
  16171. + unsigned long long mfsrr_watermark;
  16172. +};
  16173. +
  16174. +struct au_opt {
  16175. + int type;
  16176. + union {
  16177. + struct au_opt_xino xino;
  16178. + struct au_opt_xino_itrunc xino_itrunc;
  16179. + struct au_opt_add add;
  16180. + struct au_opt_del del;
  16181. + struct au_opt_mod mod;
  16182. + int dirwh;
  16183. + int rdcache;
  16184. + unsigned int rdblk;
  16185. + unsigned int rdhash;
  16186. + int udba;
  16187. + struct au_opt_wbr_create wbr_create;
  16188. + int wbr_copyup;
  16189. + };
  16190. +};
  16191. +
  16192. +/* opts flags */
  16193. +#define AuOpts_REMOUNT 1
  16194. +#define AuOpts_REFRESH_DIR (1 << 1)
  16195. +#define AuOpts_REFRESH_NONDIR (1 << 2)
  16196. +#define AuOpts_TRUNC_XIB (1 << 3)
  16197. +#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
  16198. +#define au_fset_opts(flags, name) { (flags) |= AuOpts_##name; }
  16199. +#define au_fclr_opts(flags, name) { (flags) &= ~AuOpts_##name; }
  16200. +
  16201. +struct au_opts {
  16202. + struct au_opt *opt;
  16203. + int max_opt;
  16204. +
  16205. + unsigned int given_udba;
  16206. + unsigned int flags;
  16207. + unsigned long sb_flags;
  16208. +};
  16209. +
  16210. +/* ---------------------------------------------------------------------- */
  16211. +
  16212. +const char *au_optstr_br_perm(int brperm);
  16213. +const char *au_optstr_udba(int udba);
  16214. +const char *au_optstr_wbr_copyup(int wbr_copyup);
  16215. +const char *au_optstr_wbr_create(int wbr_create);
  16216. +
  16217. +void au_opts_free(struct au_opts *opts);
  16218. +int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
  16219. +int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
  16220. + unsigned int pending);
  16221. +int au_opts_mount(struct super_block *sb, struct au_opts *opts);
  16222. +int au_opts_remount(struct super_block *sb, struct au_opts *opts);
  16223. +
  16224. +unsigned int au_opt_udba(struct super_block *sb);
  16225. +
  16226. +/* ---------------------------------------------------------------------- */
  16227. +
  16228. +#endif /* __KERNEL__ */
  16229. +#endif /* __AUFS_OPTS_H__ */
  16230. diff -Nur linux-2.6.34.orig/fs/aufs/plink.c linux-2.6.34/fs/aufs/plink.c
  16231. --- linux-2.6.34.orig/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100
  16232. +++ linux-2.6.34/fs/aufs/plink.c 2010-05-23 23:33:21.033473143 +0200
  16233. @@ -0,0 +1,354 @@
  16234. +/*
  16235. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  16236. + *
  16237. + * This program, aufs is free software; you can redistribute it and/or modify
  16238. + * it under the terms of the GNU General Public License as published by
  16239. + * the Free Software Foundation; either version 2 of the License, or
  16240. + * (at your option) any later version.
  16241. + *
  16242. + * This program is distributed in the hope that it will be useful,
  16243. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16244. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16245. + * GNU General Public License for more details.
  16246. + *
  16247. + * You should have received a copy of the GNU General Public License
  16248. + * along with this program; if not, write to the Free Software
  16249. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16250. + */
  16251. +
  16252. +/*
  16253. + * pseudo-link
  16254. + */
  16255. +
  16256. +#include "aufs.h"
  16257. +
  16258. +/*
  16259. + * during a user process maintains the pseudo-links,
  16260. + * prohibit adding a new plink and branch manipulation.
  16261. + */
  16262. +void au_plink_block_maintain(struct super_block *sb)
  16263. +{
  16264. + struct au_sbinfo *sbi = au_sbi(sb);
  16265. +
  16266. + SiMustAnyLock(sb);
  16267. +
  16268. + /* gave up wake_up_bit() */
  16269. + wait_event(sbi->si_plink_wq, !au_ftest_si(sbi, MAINTAIN_PLINK));
  16270. +}
  16271. +
  16272. +/* ---------------------------------------------------------------------- */
  16273. +
  16274. +struct pseudo_link {
  16275. + struct list_head list;
  16276. + struct inode *inode;
  16277. +};
  16278. +
  16279. +#ifdef CONFIG_AUFS_DEBUG
  16280. +void au_plink_list(struct super_block *sb)
  16281. +{
  16282. + struct au_sbinfo *sbinfo;
  16283. + struct list_head *plink_list;
  16284. + struct pseudo_link *plink;
  16285. +
  16286. + SiMustAnyLock(sb);
  16287. +
  16288. + sbinfo = au_sbi(sb);
  16289. + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
  16290. +
  16291. + plink_list = &sbinfo->si_plink.head;
  16292. + spin_lock(&sbinfo->si_plink.spin);
  16293. + list_for_each_entry(plink, plink_list, list)
  16294. + AuDbg("%lu\n", plink->inode->i_ino);
  16295. + spin_unlock(&sbinfo->si_plink.spin);
  16296. +}
  16297. +#endif
  16298. +
  16299. +/* is the inode pseudo-linked? */
  16300. +int au_plink_test(struct inode *inode)
  16301. +{
  16302. + int found;
  16303. + struct au_sbinfo *sbinfo;
  16304. + struct list_head *plink_list;
  16305. + struct pseudo_link *plink;
  16306. +
  16307. + sbinfo = au_sbi(inode->i_sb);
  16308. + AuRwMustAnyLock(&sbinfo->si_rwsem);
  16309. + AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
  16310. +
  16311. + found = 0;
  16312. + plink_list = &sbinfo->si_plink.head;
  16313. + spin_lock(&sbinfo->si_plink.spin);
  16314. + list_for_each_entry(plink, plink_list, list)
  16315. + if (plink->inode == inode) {
  16316. + found = 1;
  16317. + break;
  16318. + }
  16319. + spin_unlock(&sbinfo->si_plink.spin);
  16320. + return found;
  16321. +}
  16322. +
  16323. +/* ---------------------------------------------------------------------- */
  16324. +
  16325. +/*
  16326. + * generate a name for plink.
  16327. + * the file will be stored under AUFS_WH_PLINKDIR.
  16328. + */
  16329. +/* 20 is max digits length of ulong 64 */
  16330. +#define PLINK_NAME_LEN ((20 + 1) * 2)
  16331. +
  16332. +static int plink_name(char *name, int len, struct inode *inode,
  16333. + aufs_bindex_t bindex)
  16334. +{
  16335. + int rlen;
  16336. + struct inode *h_inode;
  16337. +
  16338. + h_inode = au_h_iptr(inode, bindex);
  16339. + rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
  16340. + return rlen;
  16341. +}
  16342. +
  16343. +/* lookup the plink-ed @inode under the branch at @bindex */
  16344. +struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
  16345. +{
  16346. + struct dentry *h_dentry, *h_parent;
  16347. + struct au_branch *br;
  16348. + struct inode *h_dir;
  16349. + char a[PLINK_NAME_LEN];
  16350. + struct qstr tgtname = {
  16351. + .name = a
  16352. + };
  16353. +
  16354. + br = au_sbr(inode->i_sb, bindex);
  16355. + h_parent = br->br_wbr->wbr_plink;
  16356. + h_dir = h_parent->d_inode;
  16357. + tgtname.len = plink_name(a, sizeof(a), inode, bindex);
  16358. +
  16359. + /* always superio. */
  16360. + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
  16361. + h_dentry = au_sio_lkup_one(&tgtname, h_parent, br);
  16362. + mutex_unlock(&h_dir->i_mutex);
  16363. + return h_dentry;
  16364. +}
  16365. +
  16366. +/* create a pseudo-link */
  16367. +static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
  16368. + struct dentry *h_dentry, struct au_branch *br)
  16369. +{
  16370. + int err;
  16371. + struct path h_path = {
  16372. + .mnt = br->br_mnt
  16373. + };
  16374. + struct inode *h_dir;
  16375. +
  16376. + h_dir = h_parent->d_inode;
  16377. + again:
  16378. + h_path.dentry = au_lkup_one(tgt, h_parent, br, /*nd*/NULL);
  16379. + err = PTR_ERR(h_path.dentry);
  16380. + if (IS_ERR(h_path.dentry))
  16381. + goto out;
  16382. +
  16383. + err = 0;
  16384. + /* wh.plink dir is not monitored */
  16385. + if (h_path.dentry->d_inode
  16386. + && h_path.dentry->d_inode != h_dentry->d_inode) {
  16387. + err = vfsub_unlink(h_dir, &h_path, /*force*/0);
  16388. + dput(h_path.dentry);
  16389. + h_path.dentry = NULL;
  16390. + if (!err)
  16391. + goto again;
  16392. + }
  16393. + if (!err && !h_path.dentry->d_inode)
  16394. + err = vfsub_link(h_dentry, h_dir, &h_path);
  16395. + dput(h_path.dentry);
  16396. +
  16397. + out:
  16398. + return err;
  16399. +}
  16400. +
  16401. +struct do_whplink_args {
  16402. + int *errp;
  16403. + struct qstr *tgt;
  16404. + struct dentry *h_parent;
  16405. + struct dentry *h_dentry;
  16406. + struct au_branch *br;
  16407. +};
  16408. +
  16409. +static void call_do_whplink(void *args)
  16410. +{
  16411. + struct do_whplink_args *a = args;
  16412. + *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
  16413. +}
  16414. +
  16415. +static int whplink(struct dentry *h_dentry, struct inode *inode,
  16416. + aufs_bindex_t bindex, struct au_branch *br)
  16417. +{
  16418. + int err, wkq_err;
  16419. + struct au_wbr *wbr;
  16420. + struct dentry *h_parent;
  16421. + struct inode *h_dir;
  16422. + char a[PLINK_NAME_LEN];
  16423. + struct qstr tgtname = {
  16424. + .name = a
  16425. + };
  16426. +
  16427. + wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
  16428. + h_parent = wbr->wbr_plink;
  16429. + h_dir = h_parent->d_inode;
  16430. + tgtname.len = plink_name(a, sizeof(a), inode, bindex);
  16431. +
  16432. + /* always superio. */
  16433. + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
  16434. + if (!au_test_wkq(current)) {
  16435. + struct do_whplink_args args = {
  16436. + .errp = &err,
  16437. + .tgt = &tgtname,
  16438. + .h_parent = h_parent,
  16439. + .h_dentry = h_dentry,
  16440. + .br = br
  16441. + };
  16442. + wkq_err = au_wkq_wait(call_do_whplink, &args);
  16443. + if (unlikely(wkq_err))
  16444. + err = wkq_err;
  16445. + } else
  16446. + err = do_whplink(&tgtname, h_parent, h_dentry, br);
  16447. + mutex_unlock(&h_dir->i_mutex);
  16448. +
  16449. + return err;
  16450. +}
  16451. +
  16452. +/* free a single plink */
  16453. +static void do_put_plink(struct pseudo_link *plink, int do_del)
  16454. +{
  16455. + iput(plink->inode);
  16456. + if (do_del)
  16457. + list_del(&plink->list);
  16458. + kfree(plink);
  16459. +}
  16460. +
  16461. +/*
  16462. + * create a new pseudo-link for @h_dentry on @bindex.
  16463. + * the linked inode is held in aufs @inode.
  16464. + */
  16465. +void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
  16466. + struct dentry *h_dentry)
  16467. +{
  16468. + struct super_block *sb;
  16469. + struct au_sbinfo *sbinfo;
  16470. + struct list_head *plink_list;
  16471. + struct pseudo_link *plink;
  16472. + int found, err, cnt;
  16473. +
  16474. + sb = inode->i_sb;
  16475. + sbinfo = au_sbi(sb);
  16476. + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
  16477. +
  16478. + err = 0;
  16479. + cnt = 0;
  16480. + found = 0;
  16481. + plink_list = &sbinfo->si_plink.head;
  16482. + spin_lock(&sbinfo->si_plink.spin);
  16483. + list_for_each_entry(plink, plink_list, list) {
  16484. + cnt++;
  16485. + if (plink->inode == inode) {
  16486. + found = 1;
  16487. + break;
  16488. + }
  16489. + }
  16490. + if (found) {
  16491. + spin_unlock(&sbinfo->si_plink.spin);
  16492. + return;
  16493. + }
  16494. +
  16495. + plink = NULL;
  16496. + if (!found) {
  16497. + plink = kmalloc(sizeof(*plink), GFP_ATOMIC);
  16498. + if (plink) {
  16499. + plink->inode = au_igrab(inode);
  16500. + list_add(&plink->list, plink_list);
  16501. + cnt++;
  16502. + } else
  16503. + err = -ENOMEM;
  16504. + }
  16505. + spin_unlock(&sbinfo->si_plink.spin);
  16506. +
  16507. + if (!err) {
  16508. + au_plink_block_maintain(sb);
  16509. + err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
  16510. + }
  16511. +
  16512. + if (unlikely(cnt > AUFS_PLINK_WARN))
  16513. + AuWarn1("unexpectedly many pseudo links, %d\n", cnt);
  16514. + if (unlikely(err)) {
  16515. + AuWarn("err %d, damaged pseudo link.\n", err);
  16516. + if (!found && plink)
  16517. + do_put_plink(plink, /*do_del*/1);
  16518. + }
  16519. +}
  16520. +
  16521. +/* free all plinks */
  16522. +void au_plink_put(struct super_block *sb)
  16523. +{
  16524. + struct au_sbinfo *sbinfo;
  16525. + struct list_head *plink_list;
  16526. + struct pseudo_link *plink, *tmp;
  16527. +
  16528. + SiMustWriteLock(sb);
  16529. +
  16530. + sbinfo = au_sbi(sb);
  16531. + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
  16532. +
  16533. + plink_list = &sbinfo->si_plink.head;
  16534. + /* no spin_lock since sbinfo is write-locked */
  16535. + list_for_each_entry_safe(plink, tmp, plink_list, list)
  16536. + do_put_plink(plink, 0);
  16537. + INIT_LIST_HEAD(plink_list);
  16538. +}
  16539. +
  16540. +/* free the plinks on a branch specified by @br_id */
  16541. +void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
  16542. +{
  16543. + struct au_sbinfo *sbinfo;
  16544. + struct list_head *plink_list;
  16545. + struct pseudo_link *plink, *tmp;
  16546. + struct inode *inode;
  16547. + aufs_bindex_t bstart, bend, bindex;
  16548. + unsigned char do_put;
  16549. +
  16550. + SiMustWriteLock(sb);
  16551. +
  16552. + sbinfo = au_sbi(sb);
  16553. + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
  16554. +
  16555. + plink_list = &sbinfo->si_plink.head;
  16556. + /* no spin_lock since sbinfo is write-locked */
  16557. + list_for_each_entry_safe(plink, tmp, plink_list, list) {
  16558. + do_put = 0;
  16559. + inode = au_igrab(plink->inode);
  16560. + ii_write_lock_child(inode);
  16561. + bstart = au_ibstart(inode);
  16562. + bend = au_ibend(inode);
  16563. + if (bstart >= 0) {
  16564. + for (bindex = bstart; bindex <= bend; bindex++) {
  16565. + if (!au_h_iptr(inode, bindex)
  16566. + || au_ii_br_id(inode, bindex) != br_id)
  16567. + continue;
  16568. + au_set_h_iptr(inode, bindex, NULL, 0);
  16569. + do_put = 1;
  16570. + break;
  16571. + }
  16572. + } else
  16573. + do_put_plink(plink, 1);
  16574. +
  16575. + if (do_put) {
  16576. + for (bindex = bstart; bindex <= bend; bindex++)
  16577. + if (au_h_iptr(inode, bindex)) {
  16578. + do_put = 0;
  16579. + break;
  16580. + }
  16581. + if (do_put)
  16582. + do_put_plink(plink, 1);
  16583. + }
  16584. + ii_write_unlock(inode);
  16585. + iput(inode);
  16586. + }
  16587. +}
  16588. diff -Nur linux-2.6.34.orig/fs/aufs/poll.c linux-2.6.34/fs/aufs/poll.c
  16589. --- linux-2.6.34.orig/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100
  16590. +++ linux-2.6.34/fs/aufs/poll.c 2010-05-23 23:33:21.073473127 +0200
  16591. @@ -0,0 +1,56 @@
  16592. +/*
  16593. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  16594. + *
  16595. + * This program, aufs is free software; you can redistribute it and/or modify
  16596. + * it under the terms of the GNU General Public License as published by
  16597. + * the Free Software Foundation; either version 2 of the License, or
  16598. + * (at your option) any later version.
  16599. + *
  16600. + * This program is distributed in the hope that it will be useful,
  16601. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16602. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16603. + * GNU General Public License for more details.
  16604. + *
  16605. + * You should have received a copy of the GNU General Public License
  16606. + * along with this program; if not, write to the Free Software
  16607. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16608. + */
  16609. +
  16610. +/*
  16611. + * poll operation
  16612. + * There is only one filesystem which implements ->poll operation, currently.
  16613. + */
  16614. +
  16615. +#include "aufs.h"
  16616. +
  16617. +unsigned int aufs_poll(struct file *file, poll_table *wait)
  16618. +{
  16619. + unsigned int mask;
  16620. + int err;
  16621. + struct file *h_file;
  16622. + struct dentry *dentry;
  16623. + struct super_block *sb;
  16624. +
  16625. + /* We should pretend an error happened. */
  16626. + mask = POLLERR /* | POLLIN | POLLOUT */;
  16627. + dentry = file->f_dentry;
  16628. + sb = dentry->d_sb;
  16629. + si_read_lock(sb, AuLock_FLUSH);
  16630. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
  16631. + if (unlikely(err))
  16632. + goto out;
  16633. +
  16634. + /* it is not an error if h_file has no operation */
  16635. + mask = DEFAULT_POLLMASK;
  16636. + h_file = au_h_fptr(file, au_fbstart(file));
  16637. + if (h_file->f_op && h_file->f_op->poll)
  16638. + mask = h_file->f_op->poll(h_file, wait);
  16639. +
  16640. + di_read_unlock(dentry, AuLock_IR);
  16641. + fi_read_unlock(file);
  16642. +
  16643. + out:
  16644. + si_read_unlock(sb);
  16645. + AuTraceErr((int)mask);
  16646. + return mask;
  16647. +}
  16648. diff -Nur linux-2.6.34.orig/fs/aufs/rwsem.h linux-2.6.34/fs/aufs/rwsem.h
  16649. --- linux-2.6.34.orig/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100
  16650. +++ linux-2.6.34/fs/aufs/rwsem.h 2010-05-23 23:33:21.141617129 +0200
  16651. @@ -0,0 +1,186 @@
  16652. +/*
  16653. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  16654. + *
  16655. + * This program, aufs is free software; you can redistribute it and/or modify
  16656. + * it under the terms of the GNU General Public License as published by
  16657. + * the Free Software Foundation; either version 2 of the License, or
  16658. + * (at your option) any later version.
  16659. + *
  16660. + * This program is distributed in the hope that it will be useful,
  16661. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16662. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16663. + * GNU General Public License for more details.
  16664. + *
  16665. + * You should have received a copy of the GNU General Public License
  16666. + * along with this program; if not, write to the Free Software
  16667. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16668. + */
  16669. +
  16670. +/*
  16671. + * simple read-write semaphore wrappers
  16672. + */
  16673. +
  16674. +#ifndef __AUFS_RWSEM_H__
  16675. +#define __AUFS_RWSEM_H__
  16676. +
  16677. +#ifdef __KERNEL__
  16678. +
  16679. +#include <linux/rwsem.h>
  16680. +
  16681. +struct au_rwsem {
  16682. + struct rw_semaphore rwsem;
  16683. +#ifdef CONFIG_AUFS_DEBUG
  16684. + /* just for debugging, not almighty counter */
  16685. + atomic_t rcnt, wcnt;
  16686. +#endif
  16687. +};
  16688. +
  16689. +#ifdef CONFIG_AUFS_DEBUG
  16690. +#define AuDbgCntInit(rw) do { \
  16691. + atomic_set(&(rw)->rcnt, 0); \
  16692. + atomic_set(&(rw)->wcnt, 0); \
  16693. + smp_mb(); /* atomic set */ \
  16694. +} while (0)
  16695. +
  16696. +#define AuDbgRcntInc(rw) atomic_inc_return(&(rw)->rcnt)
  16697. +#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0)
  16698. +#define AuDbgWcntInc(rw) WARN_ON(atomic_inc_return(&(rw)->wcnt) > 1)
  16699. +#define AuDbgWcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->wcnt) < 0)
  16700. +#else
  16701. +#define AuDbgCntInit(rw) do {} while (0)
  16702. +#define AuDbgRcntInc(rw) do {} while (0)
  16703. +#define AuDbgRcntDec(rw) do {} while (0)
  16704. +#define AuDbgWcntInc(rw) do {} while (0)
  16705. +#define AuDbgWcntDec(rw) do {} while (0)
  16706. +#endif /* CONFIG_AUFS_DEBUG */
  16707. +
  16708. +/* to debug easier, do not make them inlined functions */
  16709. +#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->rwsem.wait_list))
  16710. +/* rwsem_is_locked() is unusable */
  16711. +#define AuRwMustReadLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0)
  16712. +#define AuRwMustWriteLock(rw) AuDebugOn(atomic_read(&(rw)->wcnt) <= 0)
  16713. +#define AuRwMustAnyLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0 \
  16714. + && atomic_read(&(rw)->wcnt) <= 0)
  16715. +#define AuRwDestroy(rw) AuDebugOn(atomic_read(&(rw)->rcnt) \
  16716. + || atomic_read(&(rw)->wcnt))
  16717. +
  16718. +static inline void au_rw_init(struct au_rwsem *rw)
  16719. +{
  16720. + AuDbgCntInit(rw);
  16721. + init_rwsem(&rw->rwsem);
  16722. +}
  16723. +
  16724. +static inline void au_rw_init_wlock(struct au_rwsem *rw)
  16725. +{
  16726. + au_rw_init(rw);
  16727. + down_write(&rw->rwsem);
  16728. + AuDbgWcntInc(rw);
  16729. +}
  16730. +
  16731. +static inline void au_rw_init_wlock_nested(struct au_rwsem *rw,
  16732. + unsigned int lsc)
  16733. +{
  16734. + au_rw_init(rw);
  16735. + down_write_nested(&rw->rwsem, lsc);
  16736. + AuDbgWcntInc(rw);
  16737. +}
  16738. +
  16739. +static inline void au_rw_read_lock(struct au_rwsem *rw)
  16740. +{
  16741. + down_read(&rw->rwsem);
  16742. + AuDbgRcntInc(rw);
  16743. +}
  16744. +
  16745. +static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc)
  16746. +{
  16747. + down_read_nested(&rw->rwsem, lsc);
  16748. + AuDbgRcntInc(rw);
  16749. +}
  16750. +
  16751. +static inline void au_rw_read_unlock(struct au_rwsem *rw)
  16752. +{
  16753. + AuRwMustReadLock(rw);
  16754. + AuDbgRcntDec(rw);
  16755. + up_read(&rw->rwsem);
  16756. +}
  16757. +
  16758. +static inline void au_rw_dgrade_lock(struct au_rwsem *rw)
  16759. +{
  16760. + AuRwMustWriteLock(rw);
  16761. + AuDbgRcntInc(rw);
  16762. + AuDbgWcntDec(rw);
  16763. + downgrade_write(&rw->rwsem);
  16764. +}
  16765. +
  16766. +static inline void au_rw_write_lock(struct au_rwsem *rw)
  16767. +{
  16768. + down_write(&rw->rwsem);
  16769. + AuDbgWcntInc(rw);
  16770. +}
  16771. +
  16772. +static inline void au_rw_write_lock_nested(struct au_rwsem *rw,
  16773. + unsigned int lsc)
  16774. +{
  16775. + down_write_nested(&rw->rwsem, lsc);
  16776. + AuDbgWcntInc(rw);
  16777. +}
  16778. +
  16779. +static inline void au_rw_write_unlock(struct au_rwsem *rw)
  16780. +{
  16781. + AuRwMustWriteLock(rw);
  16782. + AuDbgWcntDec(rw);
  16783. + up_write(&rw->rwsem);
  16784. +}
  16785. +
  16786. +/* why is not _nested version defined */
  16787. +static inline int au_rw_read_trylock(struct au_rwsem *rw)
  16788. +{
  16789. + int ret = down_read_trylock(&rw->rwsem);
  16790. + if (ret)
  16791. + AuDbgRcntInc(rw);
  16792. + return ret;
  16793. +}
  16794. +
  16795. +static inline int au_rw_write_trylock(struct au_rwsem *rw)
  16796. +{
  16797. + int ret = down_write_trylock(&rw->rwsem);
  16798. + if (ret)
  16799. + AuDbgWcntInc(rw);
  16800. + return ret;
  16801. +}
  16802. +
  16803. +#undef AuDbgCntInit
  16804. +#undef AuDbgRcntInc
  16805. +#undef AuDbgRcntDec
  16806. +#undef AuDbgWcntInc
  16807. +#undef AuDbgWcntDec
  16808. +
  16809. +#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
  16810. +static inline void prefix##_read_lock(param) \
  16811. +{ au_rw_read_lock(rwsem); } \
  16812. +static inline void prefix##_write_lock(param) \
  16813. +{ au_rw_write_lock(rwsem); } \
  16814. +static inline int prefix##_read_trylock(param) \
  16815. +{ return au_rw_read_trylock(rwsem); } \
  16816. +static inline int prefix##_write_trylock(param) \
  16817. +{ return au_rw_write_trylock(rwsem); }
  16818. +/* why is not _nested version defined */
  16819. +/* static inline void prefix##_read_trylock_nested(param, lsc)
  16820. +{ au_rw_read_trylock_nested(rwsem, lsc)); }
  16821. +static inline void prefix##_write_trylock_nestd(param, lsc)
  16822. +{ au_rw_write_trylock_nested(rwsem, lsc); } */
  16823. +
  16824. +#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
  16825. +static inline void prefix##_read_unlock(param) \
  16826. +{ au_rw_read_unlock(rwsem); } \
  16827. +static inline void prefix##_write_unlock(param) \
  16828. +{ au_rw_write_unlock(rwsem); } \
  16829. +static inline void prefix##_downgrade_lock(param) \
  16830. +{ au_rw_dgrade_lock(rwsem); }
  16831. +
  16832. +#define AuSimpleRwsemFuncs(prefix, param, rwsem) \
  16833. + AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
  16834. + AuSimpleUnlockRwsemFuncs(prefix, param, rwsem)
  16835. +
  16836. +#endif /* __KERNEL__ */
  16837. +#endif /* __AUFS_RWSEM_H__ */
  16838. diff -Nur linux-2.6.34.orig/fs/aufs/sbinfo.c linux-2.6.34/fs/aufs/sbinfo.c
  16839. --- linux-2.6.34.orig/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100
  16840. +++ linux-2.6.34/fs/aufs/sbinfo.c 2010-05-23 23:33:21.183473099 +0200
  16841. @@ -0,0 +1,208 @@
  16842. +/*
  16843. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  16844. + *
  16845. + * This program, aufs is free software; you can redistribute it and/or modify
  16846. + * it under the terms of the GNU General Public License as published by
  16847. + * the Free Software Foundation; either version 2 of the License, or
  16848. + * (at your option) any later version.
  16849. + *
  16850. + * This program is distributed in the hope that it will be useful,
  16851. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16852. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16853. + * GNU General Public License for more details.
  16854. + *
  16855. + * You should have received a copy of the GNU General Public License
  16856. + * along with this program; if not, write to the Free Software
  16857. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16858. + */
  16859. +
  16860. +/*
  16861. + * superblock private data
  16862. + */
  16863. +
  16864. +#include "aufs.h"
  16865. +
  16866. +/*
  16867. + * they are necessary regardless sysfs is disabled.
  16868. + */
  16869. +void au_si_free(struct kobject *kobj)
  16870. +{
  16871. + struct au_sbinfo *sbinfo;
  16872. + struct super_block *sb;
  16873. +
  16874. + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
  16875. + AuDebugOn(!list_empty(&sbinfo->si_plink.head));
  16876. +
  16877. + sb = sbinfo->si_sb;
  16878. + si_write_lock(sb);
  16879. + au_xino_clr(sb);
  16880. + au_br_free(sbinfo);
  16881. + kfree(sbinfo->si_branch);
  16882. + mutex_destroy(&sbinfo->si_xib_mtx);
  16883. + si_write_unlock(sb);
  16884. + AuRwDestroy(&sbinfo->si_rwsem);
  16885. +
  16886. + kfree(sbinfo);
  16887. +}
  16888. +
  16889. +int au_si_alloc(struct super_block *sb)
  16890. +{
  16891. + int err;
  16892. + struct au_sbinfo *sbinfo;
  16893. +
  16894. + err = -ENOMEM;
  16895. + sbinfo = kmalloc(sizeof(*sbinfo), GFP_NOFS);
  16896. + if (unlikely(!sbinfo))
  16897. + goto out;
  16898. +
  16899. + /* will be reallocated separately */
  16900. + sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
  16901. + if (unlikely(!sbinfo->si_branch))
  16902. + goto out_sbinfo;
  16903. +
  16904. + memset(&sbinfo->si_kobj, 0, sizeof(sbinfo->si_kobj));
  16905. + err = sysaufs_si_init(sbinfo);
  16906. + if (unlikely(err))
  16907. + goto out_br;
  16908. +
  16909. + au_nwt_init(&sbinfo->si_nowait);
  16910. + au_rw_init_wlock(&sbinfo->si_rwsem);
  16911. + sbinfo->si_generation = 0;
  16912. + sbinfo->au_si_status = 0;
  16913. + sbinfo->si_bend = -1;
  16914. + sbinfo->si_last_br_id = 0;
  16915. +
  16916. + sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
  16917. + sbinfo->si_wbr_create = AuWbrCreate_Def;
  16918. + sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + AuWbrCopyup_Def;
  16919. + sbinfo->si_wbr_create_ops = au_wbr_create_ops + AuWbrCreate_Def;
  16920. +
  16921. + sbinfo->si_mntflags = AuOpt_Def;
  16922. +
  16923. + sbinfo->si_xread = NULL;
  16924. + sbinfo->si_xwrite = NULL;
  16925. + sbinfo->si_xib = NULL;
  16926. + mutex_init(&sbinfo->si_xib_mtx);
  16927. + sbinfo->si_xib_buf = NULL;
  16928. + sbinfo->si_xino_brid = -1;
  16929. + /* leave si_xib_last_pindex and si_xib_next_bit */
  16930. +
  16931. + sbinfo->si_rdcache = AUFS_RDCACHE_DEF * HZ;
  16932. + sbinfo->si_rdblk = AUFS_RDBLK_DEF;
  16933. + sbinfo->si_rdhash = AUFS_RDHASH_DEF;
  16934. + sbinfo->si_dirwh = AUFS_DIRWH_DEF;
  16935. +
  16936. + au_spl_init(&sbinfo->si_plink);
  16937. + init_waitqueue_head(&sbinfo->si_plink_wq);
  16938. +
  16939. + /* leave other members for sysaufs and si_mnt. */
  16940. + sbinfo->si_sb = sb;
  16941. + sb->s_fs_info = sbinfo;
  16942. + au_debug_sbinfo_init(sbinfo);
  16943. + return 0; /* success */
  16944. +
  16945. + out_br:
  16946. + kfree(sbinfo->si_branch);
  16947. + out_sbinfo:
  16948. + kfree(sbinfo);
  16949. + out:
  16950. + return err;
  16951. +}
  16952. +
  16953. +int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr)
  16954. +{
  16955. + int err, sz;
  16956. + struct au_branch **brp;
  16957. +
  16958. + AuRwMustWriteLock(&sbinfo->si_rwsem);
  16959. +
  16960. + err = -ENOMEM;
  16961. + sz = sizeof(*brp) * (sbinfo->si_bend + 1);
  16962. + if (unlikely(!sz))
  16963. + sz = sizeof(*brp);
  16964. + brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS);
  16965. + if (brp) {
  16966. + sbinfo->si_branch = brp;
  16967. + err = 0;
  16968. + }
  16969. +
  16970. + return err;
  16971. +}
  16972. +
  16973. +/* ---------------------------------------------------------------------- */
  16974. +
  16975. +unsigned int au_sigen_inc(struct super_block *sb)
  16976. +{
  16977. + unsigned int gen;
  16978. +
  16979. + SiMustWriteLock(sb);
  16980. +
  16981. + gen = ++au_sbi(sb)->si_generation;
  16982. + au_update_digen(sb->s_root);
  16983. + au_update_iigen(sb->s_root->d_inode);
  16984. + sb->s_root->d_inode->i_version++;
  16985. + return gen;
  16986. +}
  16987. +
  16988. +aufs_bindex_t au_new_br_id(struct super_block *sb)
  16989. +{
  16990. + aufs_bindex_t br_id;
  16991. + int i;
  16992. + struct au_sbinfo *sbinfo;
  16993. +
  16994. + SiMustWriteLock(sb);
  16995. +
  16996. + sbinfo = au_sbi(sb);
  16997. + for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
  16998. + br_id = ++sbinfo->si_last_br_id;
  16999. + if (br_id && au_br_index(sb, br_id) < 0)
  17000. + return br_id;
  17001. + }
  17002. +
  17003. + return -1;
  17004. +}
  17005. +
  17006. +/* ---------------------------------------------------------------------- */
  17007. +
  17008. +/* dentry and super_block lock. call at entry point */
  17009. +void aufs_read_lock(struct dentry *dentry, int flags)
  17010. +{
  17011. + si_read_lock(dentry->d_sb, flags);
  17012. + if (au_ftest_lock(flags, DW))
  17013. + di_write_lock_child(dentry);
  17014. + else
  17015. + di_read_lock_child(dentry, flags);
  17016. +}
  17017. +
  17018. +void aufs_read_unlock(struct dentry *dentry, int flags)
  17019. +{
  17020. + if (au_ftest_lock(flags, DW))
  17021. + di_write_unlock(dentry);
  17022. + else
  17023. + di_read_unlock(dentry, flags);
  17024. + si_read_unlock(dentry->d_sb);
  17025. +}
  17026. +
  17027. +void aufs_write_lock(struct dentry *dentry)
  17028. +{
  17029. + si_write_lock(dentry->d_sb);
  17030. + di_write_lock_child(dentry);
  17031. +}
  17032. +
  17033. +void aufs_write_unlock(struct dentry *dentry)
  17034. +{
  17035. + di_write_unlock(dentry);
  17036. + si_write_unlock(dentry->d_sb);
  17037. +}
  17038. +
  17039. +void aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
  17040. +{
  17041. + si_read_lock(d1->d_sb, flags);
  17042. + di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR));
  17043. +}
  17044. +
  17045. +void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
  17046. +{
  17047. + di_write_unlock2(d1, d2);
  17048. + si_read_unlock(d1->d_sb);
  17049. +}
  17050. diff -Nur linux-2.6.34.orig/fs/aufs/spl.h linux-2.6.34/fs/aufs/spl.h
  17051. --- linux-2.6.34.orig/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100
  17052. +++ linux-2.6.34/fs/aufs/spl.h 2010-05-23 23:33:21.256309595 +0200
  17053. @@ -0,0 +1,57 @@
  17054. +/*
  17055. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  17056. + *
  17057. + * This program, aufs is free software; you can redistribute it and/or modify
  17058. + * it under the terms of the GNU General Public License as published by
  17059. + * the Free Software Foundation; either version 2 of the License, or
  17060. + * (at your option) any later version.
  17061. + *
  17062. + * This program is distributed in the hope that it will be useful,
  17063. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17064. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17065. + * GNU General Public License for more details.
  17066. + *
  17067. + * You should have received a copy of the GNU General Public License
  17068. + * along with this program; if not, write to the Free Software
  17069. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17070. + */
  17071. +
  17072. +/*
  17073. + * simple list protected by a spinlock
  17074. + */
  17075. +
  17076. +#ifndef __AUFS_SPL_H__
  17077. +#define __AUFS_SPL_H__
  17078. +
  17079. +#ifdef __KERNEL__
  17080. +
  17081. +#include <linux/spinlock.h>
  17082. +#include <linux/list.h>
  17083. +
  17084. +struct au_splhead {
  17085. + spinlock_t spin;
  17086. + struct list_head head;
  17087. +};
  17088. +
  17089. +static inline void au_spl_init(struct au_splhead *spl)
  17090. +{
  17091. + spin_lock_init(&spl->spin);
  17092. + INIT_LIST_HEAD(&spl->head);
  17093. +}
  17094. +
  17095. +static inline void au_spl_add(struct list_head *list, struct au_splhead *spl)
  17096. +{
  17097. + spin_lock(&spl->spin);
  17098. + list_add(list, &spl->head);
  17099. + spin_unlock(&spl->spin);
  17100. +}
  17101. +
  17102. +static inline void au_spl_del(struct list_head *list, struct au_splhead *spl)
  17103. +{
  17104. + spin_lock(&spl->spin);
  17105. + list_del(list);
  17106. + spin_unlock(&spl->spin);
  17107. +}
  17108. +
  17109. +#endif /* __KERNEL__ */
  17110. +#endif /* __AUFS_SPL_H__ */
  17111. diff -Nur linux-2.6.34.orig/fs/aufs/super.c linux-2.6.34/fs/aufs/super.c
  17112. --- linux-2.6.34.orig/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
  17113. +++ linux-2.6.34/fs/aufs/super.c 2010-05-23 23:33:21.290963488 +0200
  17114. @@ -0,0 +1,874 @@
  17115. +/*
  17116. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  17117. + *
  17118. + * This program, aufs is free software; you can redistribute it and/or modify
  17119. + * it under the terms of the GNU General Public License as published by
  17120. + * the Free Software Foundation; either version 2 of the License, or
  17121. + * (at your option) any later version.
  17122. + *
  17123. + * This program is distributed in the hope that it will be useful,
  17124. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17125. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17126. + * GNU General Public License for more details.
  17127. + *
  17128. + * You should have received a copy of the GNU General Public License
  17129. + * along with this program; if not, write to the Free Software
  17130. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17131. + */
  17132. +
  17133. +/*
  17134. + * mount and super_block operations
  17135. + */
  17136. +
  17137. +#include <linux/buffer_head.h>
  17138. +#include <linux/module.h>
  17139. +#include <linux/seq_file.h>
  17140. +#include <linux/statfs.h>
  17141. +#include "aufs.h"
  17142. +
  17143. +/*
  17144. + * super_operations
  17145. + */
  17146. +static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
  17147. +{
  17148. + struct au_icntnr *c;
  17149. +
  17150. + c = au_cache_alloc_icntnr();
  17151. + if (c) {
  17152. + inode_init_once(&c->vfs_inode);
  17153. + c->vfs_inode.i_version = 1; /* sigen(sb); */
  17154. + c->iinfo.ii_hinode = NULL;
  17155. + return &c->vfs_inode;
  17156. + }
  17157. + return NULL;
  17158. +}
  17159. +
  17160. +static void aufs_destroy_inode(struct inode *inode)
  17161. +{
  17162. + au_iinfo_fin(inode);
  17163. + au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
  17164. +}
  17165. +
  17166. +struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
  17167. +{
  17168. + struct inode *inode;
  17169. + int err;
  17170. +
  17171. + inode = iget_locked(sb, ino);
  17172. + if (unlikely(!inode)) {
  17173. + inode = ERR_PTR(-ENOMEM);
  17174. + goto out;
  17175. + }
  17176. + if (!(inode->i_state & I_NEW))
  17177. + goto out;
  17178. +
  17179. + err = au_xigen_new(inode);
  17180. + if (!err)
  17181. + err = au_iinfo_init(inode);
  17182. + if (!err)
  17183. + inode->i_version++;
  17184. + else {
  17185. + iget_failed(inode);
  17186. + inode = ERR_PTR(err);
  17187. + }
  17188. +
  17189. + out:
  17190. + /* never return NULL */
  17191. + AuDebugOn(!inode);
  17192. + AuTraceErrPtr(inode);
  17193. + return inode;
  17194. +}
  17195. +
  17196. +/* lock free root dinfo */
  17197. +static int au_show_brs(struct seq_file *seq, struct super_block *sb)
  17198. +{
  17199. + int err;
  17200. + aufs_bindex_t bindex, bend;
  17201. + struct path path;
  17202. + struct au_hdentry *hd;
  17203. + struct au_branch *br;
  17204. +
  17205. + err = 0;
  17206. + bend = au_sbend(sb);
  17207. + hd = au_di(sb->s_root)->di_hdentry;
  17208. + for (bindex = 0; !err && bindex <= bend; bindex++) {
  17209. + br = au_sbr(sb, bindex);
  17210. + path.mnt = br->br_mnt;
  17211. + path.dentry = hd[bindex].hd_dentry;
  17212. + err = au_seq_path(seq, &path);
  17213. + if (err > 0)
  17214. + err = seq_printf(seq, "=%s",
  17215. + au_optstr_br_perm(br->br_perm));
  17216. + if (!err && bindex != bend)
  17217. + err = seq_putc(seq, ':');
  17218. + }
  17219. +
  17220. + return err;
  17221. +}
  17222. +
  17223. +static void au_show_wbr_create(struct seq_file *m, int v,
  17224. + struct au_sbinfo *sbinfo)
  17225. +{
  17226. + const char *pat;
  17227. +
  17228. + AuRwMustAnyLock(&sbinfo->si_rwsem);
  17229. +
  17230. + seq_printf(m, ",create=");
  17231. + pat = au_optstr_wbr_create(v);
  17232. + switch (v) {
  17233. + case AuWbrCreate_TDP:
  17234. + case AuWbrCreate_RR:
  17235. + case AuWbrCreate_MFS:
  17236. + case AuWbrCreate_PMFS:
  17237. + seq_printf(m, pat);
  17238. + break;
  17239. + case AuWbrCreate_MFSV:
  17240. + seq_printf(m, /*pat*/"mfs:%lu",
  17241. + sbinfo->si_wbr_mfs.mfs_expire / HZ);
  17242. + break;
  17243. + case AuWbrCreate_PMFSV:
  17244. + seq_printf(m, /*pat*/"pmfs:%lu",
  17245. + sbinfo->si_wbr_mfs.mfs_expire / HZ);
  17246. + break;
  17247. + case AuWbrCreate_MFSRR:
  17248. + seq_printf(m, /*pat*/"mfsrr:%llu",
  17249. + sbinfo->si_wbr_mfs.mfsrr_watermark);
  17250. + break;
  17251. + case AuWbrCreate_MFSRRV:
  17252. + seq_printf(m, /*pat*/"mfsrr:%llu:%lu",
  17253. + sbinfo->si_wbr_mfs.mfsrr_watermark,
  17254. + sbinfo->si_wbr_mfs.mfs_expire / HZ);
  17255. + break;
  17256. + }
  17257. +}
  17258. +
  17259. +static int au_show_xino(struct seq_file *seq, struct vfsmount *mnt)
  17260. +{
  17261. +#ifdef CONFIG_SYSFS
  17262. + return 0;
  17263. +#else
  17264. + int err;
  17265. + const int len = sizeof(AUFS_XINO_FNAME) - 1;
  17266. + aufs_bindex_t bindex, brid;
  17267. + struct super_block *sb;
  17268. + struct qstr *name;
  17269. + struct file *f;
  17270. + struct dentry *d, *h_root;
  17271. +
  17272. + AuRwMustAnyLock(&sbinfo->si_rwsem);
  17273. +
  17274. + err = 0;
  17275. + sb = mnt->mnt_sb;
  17276. + f = au_sbi(sb)->si_xib;
  17277. + if (!f)
  17278. + goto out;
  17279. +
  17280. + /* stop printing the default xino path on the first writable branch */
  17281. + h_root = NULL;
  17282. + brid = au_xino_brid(sb);
  17283. + if (brid >= 0) {
  17284. + bindex = au_br_index(sb, brid);
  17285. + h_root = au_di(sb->s_root)->di_hdentry[0 + bindex].hd_dentry;
  17286. + }
  17287. + d = f->f_dentry;
  17288. + name = &d->d_name;
  17289. + /* safe ->d_parent because the file is unlinked */
  17290. + if (d->d_parent == h_root
  17291. + && name->len == len
  17292. + && !memcmp(name->name, AUFS_XINO_FNAME, len))
  17293. + goto out;
  17294. +
  17295. + seq_puts(seq, ",xino=");
  17296. + err = au_xino_path(seq, f);
  17297. +
  17298. + out:
  17299. + return err;
  17300. +#endif
  17301. +}
  17302. +
  17303. +/* seq_file will re-call me in case of too long string */
  17304. +static int aufs_show_options(struct seq_file *m, struct vfsmount *mnt)
  17305. +{
  17306. + int err, n;
  17307. + unsigned int mnt_flags, v;
  17308. + struct super_block *sb;
  17309. + struct au_sbinfo *sbinfo;
  17310. +
  17311. +#define AuBool(name, str) do { \
  17312. + v = au_opt_test(mnt_flags, name); \
  17313. + if (v != au_opt_test(AuOpt_Def, name)) \
  17314. + seq_printf(m, ",%s" #str, v ? "" : "no"); \
  17315. +} while (0)
  17316. +
  17317. +#define AuStr(name, str) do { \
  17318. + v = mnt_flags & AuOptMask_##name; \
  17319. + if (v != (AuOpt_Def & AuOptMask_##name)) \
  17320. + seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
  17321. +} while (0)
  17322. +
  17323. +#define AuUInt(name, str, val) do { \
  17324. + if (val != AUFS_##name##_DEF) \
  17325. + seq_printf(m, "," #str "=%u", val); \
  17326. +} while (0)
  17327. +
  17328. + /* lock free root dinfo */
  17329. + sb = mnt->mnt_sb;
  17330. + si_noflush_read_lock(sb);
  17331. + sbinfo = au_sbi(sb);
  17332. + seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
  17333. +
  17334. + mnt_flags = au_mntflags(sb);
  17335. + if (au_opt_test(mnt_flags, XINO)) {
  17336. + err = au_show_xino(m, mnt);
  17337. + if (unlikely(err))
  17338. + goto out;
  17339. + } else
  17340. + seq_puts(m, ",noxino");
  17341. +
  17342. + AuBool(TRUNC_XINO, trunc_xino);
  17343. + AuStr(UDBA, udba);
  17344. + AuBool(SHWH, shwh);
  17345. + AuBool(PLINK, plink);
  17346. + /* AuBool(DIRPERM1, dirperm1); */
  17347. + /* AuBool(REFROF, refrof); */
  17348. +
  17349. + v = sbinfo->si_wbr_create;
  17350. + if (v != AuWbrCreate_Def)
  17351. + au_show_wbr_create(m, v, sbinfo);
  17352. +
  17353. + v = sbinfo->si_wbr_copyup;
  17354. + if (v != AuWbrCopyup_Def)
  17355. + seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
  17356. +
  17357. + v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
  17358. + if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
  17359. + seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
  17360. +
  17361. + AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
  17362. +
  17363. + n = sbinfo->si_rdcache / HZ;
  17364. + AuUInt(RDCACHE, rdcache, n);
  17365. +
  17366. + AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
  17367. + AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
  17368. +
  17369. + AuBool(SUM, sum);
  17370. + /* AuBool(SUM_W, wsum); */
  17371. + AuBool(WARN_PERM, warn_perm);
  17372. + AuBool(VERBOSE, verbose);
  17373. +
  17374. + out:
  17375. + /* be sure to print "br:" last */
  17376. + if (!sysaufs_brs) {
  17377. + seq_puts(m, ",br:");
  17378. + au_show_brs(m, sb);
  17379. + }
  17380. + si_read_unlock(sb);
  17381. + return 0;
  17382. +
  17383. +#undef Deleted
  17384. +#undef AuBool
  17385. +#undef AuStr
  17386. +}
  17387. +
  17388. +/* ---------------------------------------------------------------------- */
  17389. +
  17390. +/* sum mode which returns the summation for statfs(2) */
  17391. +
  17392. +static u64 au_add_till_max(u64 a, u64 b)
  17393. +{
  17394. + u64 old;
  17395. +
  17396. + old = a;
  17397. + a += b;
  17398. + if (old < a)
  17399. + return a;
  17400. + return ULLONG_MAX;
  17401. +}
  17402. +
  17403. +static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
  17404. +{
  17405. + int err;
  17406. + u64 blocks, bfree, bavail, files, ffree;
  17407. + aufs_bindex_t bend, bindex, i;
  17408. + unsigned char shared;
  17409. + struct vfsmount *h_mnt;
  17410. + struct super_block *h_sb;
  17411. +
  17412. + blocks = 0;
  17413. + bfree = 0;
  17414. + bavail = 0;
  17415. + files = 0;
  17416. + ffree = 0;
  17417. +
  17418. + err = 0;
  17419. + bend = au_sbend(sb);
  17420. + for (bindex = bend; bindex >= 0; bindex--) {
  17421. + h_mnt = au_sbr_mnt(sb, bindex);
  17422. + h_sb = h_mnt->mnt_sb;
  17423. + shared = 0;
  17424. + for (i = bindex + 1; !shared && i <= bend; i++)
  17425. + shared = (au_sbr_sb(sb, i) == h_sb);
  17426. + if (shared)
  17427. + continue;
  17428. +
  17429. + /* sb->s_root for NFS is unreliable */
  17430. + err = vfs_statfs(h_mnt->mnt_root, buf);
  17431. + if (unlikely(err))
  17432. + goto out;
  17433. +
  17434. + blocks = au_add_till_max(blocks, buf->f_blocks);
  17435. + bfree = au_add_till_max(bfree, buf->f_bfree);
  17436. + bavail = au_add_till_max(bavail, buf->f_bavail);
  17437. + files = au_add_till_max(files, buf->f_files);
  17438. + ffree = au_add_till_max(ffree, buf->f_ffree);
  17439. + }
  17440. +
  17441. + buf->f_blocks = blocks;
  17442. + buf->f_bfree = bfree;
  17443. + buf->f_bavail = bavail;
  17444. + buf->f_files = files;
  17445. + buf->f_ffree = ffree;
  17446. +
  17447. + out:
  17448. + return err;
  17449. +}
  17450. +
  17451. +static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
  17452. +{
  17453. + int err;
  17454. + struct super_block *sb;
  17455. +
  17456. + /* lock free root dinfo */
  17457. + sb = dentry->d_sb;
  17458. + si_noflush_read_lock(sb);
  17459. + if (!au_opt_test(au_mntflags(sb), SUM))
  17460. + /* sb->s_root for NFS is unreliable */
  17461. + err = vfs_statfs(au_sbr_mnt(sb, 0)->mnt_root, buf);
  17462. + else
  17463. + err = au_statfs_sum(sb, buf);
  17464. + si_read_unlock(sb);
  17465. +
  17466. + if (!err) {
  17467. + buf->f_type = AUFS_SUPER_MAGIC;
  17468. + buf->f_namelen -= AUFS_WH_PFX_LEN;
  17469. + memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
  17470. + }
  17471. + /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
  17472. +
  17473. + return err;
  17474. +}
  17475. +
  17476. +/* ---------------------------------------------------------------------- */
  17477. +
  17478. +/* try flushing the lower fs at aufs remount/unmount time */
  17479. +
  17480. +static void au_fsync_br(struct super_block *sb)
  17481. +{
  17482. + aufs_bindex_t bend, bindex;
  17483. + int brperm;
  17484. + struct au_branch *br;
  17485. + struct super_block *h_sb;
  17486. +
  17487. + bend = au_sbend(sb);
  17488. + for (bindex = 0; bindex < bend; bindex++) {
  17489. + br = au_sbr(sb, bindex);
  17490. + brperm = br->br_perm;
  17491. + if (brperm == AuBrPerm_RR || brperm == AuBrPerm_RRWH)
  17492. + continue;
  17493. + h_sb = br->br_mnt->mnt_sb;
  17494. + if (bdev_read_only(h_sb->s_bdev))
  17495. + continue;
  17496. +
  17497. + lockdep_off();
  17498. + down_write(&h_sb->s_umount);
  17499. + shrink_dcache_sb(h_sb);
  17500. + sync_filesystem(h_sb);
  17501. + up_write(&h_sb->s_umount);
  17502. + lockdep_on();
  17503. + }
  17504. +}
  17505. +
  17506. +/*
  17507. + * this IS NOT for super_operations.
  17508. + * I guess it will be reverted someday.
  17509. + */
  17510. +static void aufs_umount_begin(struct super_block *sb)
  17511. +{
  17512. + struct au_sbinfo *sbinfo;
  17513. +
  17514. + sbinfo = au_sbi(sb);
  17515. + if (!sbinfo)
  17516. + return;
  17517. +
  17518. + si_write_lock(sb);
  17519. + au_fsync_br(sb);
  17520. + if (au_opt_test(au_mntflags(sb), PLINK))
  17521. + au_plink_put(sb);
  17522. + if (sbinfo->si_wbr_create_ops->fin)
  17523. + sbinfo->si_wbr_create_ops->fin(sb);
  17524. + si_write_unlock(sb);
  17525. +}
  17526. +
  17527. +/* final actions when unmounting a file system */
  17528. +static void aufs_put_super(struct super_block *sb)
  17529. +{
  17530. + struct au_sbinfo *sbinfo;
  17531. +
  17532. + sbinfo = au_sbi(sb);
  17533. + if (!sbinfo)
  17534. + return;
  17535. +
  17536. + aufs_umount_begin(sb);
  17537. + dbgaufs_si_fin(sbinfo);
  17538. + kobject_put(&sbinfo->si_kobj);
  17539. +}
  17540. +
  17541. +/* ---------------------------------------------------------------------- */
  17542. +
  17543. +/*
  17544. + * refresh dentry and inode at remount time.
  17545. + */
  17546. +static int do_refresh(struct dentry *dentry, mode_t type,
  17547. + unsigned int dir_flags)
  17548. +{
  17549. + int err;
  17550. + struct dentry *parent;
  17551. +
  17552. + di_write_lock_child(dentry);
  17553. + parent = dget_parent(dentry);
  17554. + di_read_lock_parent(parent, AuLock_IR);
  17555. +
  17556. + /* returns the number of positive dentries */
  17557. + err = au_refresh_hdentry(dentry, type);
  17558. + if (err >= 0) {
  17559. + struct inode *inode = dentry->d_inode;
  17560. + err = au_refresh_hinode(inode, dentry);
  17561. + if (!err && type == S_IFDIR)
  17562. + au_reset_hinotify(inode, dir_flags);
  17563. + }
  17564. + if (unlikely(err))
  17565. + AuErr("unrecoverable error %d, %.*s\n", err, AuDLNPair(dentry));
  17566. +
  17567. + di_read_unlock(parent, AuLock_IR);
  17568. + dput(parent);
  17569. + di_write_unlock(dentry);
  17570. +
  17571. + return err;
  17572. +}
  17573. +
  17574. +static int test_dir(struct dentry *dentry, void *arg __maybe_unused)
  17575. +{
  17576. + return S_ISDIR(dentry->d_inode->i_mode);
  17577. +}
  17578. +
  17579. +/* gave up consolidating with refresh_nondir() */
  17580. +static int refresh_dir(struct dentry *root, unsigned int sigen)
  17581. +{
  17582. + int err, i, j, ndentry, e;
  17583. + struct au_dcsub_pages dpages;
  17584. + struct au_dpage *dpage;
  17585. + struct dentry **dentries;
  17586. + struct inode *inode;
  17587. + const unsigned int flags = au_hi_flags(root->d_inode, /*isdir*/1);
  17588. +
  17589. + err = 0;
  17590. + list_for_each_entry(inode, &root->d_sb->s_inodes, i_sb_list)
  17591. + if (S_ISDIR(inode->i_mode) && au_iigen(inode) != sigen) {
  17592. + ii_write_lock_child(inode);
  17593. + e = au_refresh_hinode_self(inode, /*do_attr*/1);
  17594. + ii_write_unlock(inode);
  17595. + if (unlikely(e)) {
  17596. + AuDbg("e %d, i%lu\n", e, inode->i_ino);
  17597. + if (!err)
  17598. + err = e;
  17599. + /* go on even if err */
  17600. + }
  17601. + }
  17602. +
  17603. + e = au_dpages_init(&dpages, GFP_NOFS);
  17604. + if (unlikely(e)) {
  17605. + if (!err)
  17606. + err = e;
  17607. + goto out;
  17608. + }
  17609. + e = au_dcsub_pages(&dpages, root, test_dir, NULL);
  17610. + if (unlikely(e)) {
  17611. + if (!err)
  17612. + err = e;
  17613. + goto out_dpages;
  17614. + }
  17615. +
  17616. + for (i = 0; !e && i < dpages.ndpage; i++) {
  17617. + dpage = dpages.dpages + i;
  17618. + dentries = dpage->dentries;
  17619. + ndentry = dpage->ndentry;
  17620. + for (j = 0; !e && j < ndentry; j++) {
  17621. + struct dentry *d;
  17622. +
  17623. + d = dentries[j];
  17624. + au_dbg_verify_dir_parent(d, sigen);
  17625. + if (au_digen(d) != sigen) {
  17626. + e = do_refresh(d, S_IFDIR, flags);
  17627. + if (unlikely(e && !err))
  17628. + err = e;
  17629. + /* break on err */
  17630. + }
  17631. + }
  17632. + }
  17633. +
  17634. + out_dpages:
  17635. + au_dpages_free(&dpages);
  17636. + out:
  17637. + return err;
  17638. +}
  17639. +
  17640. +static int test_nondir(struct dentry *dentry, void *arg __maybe_unused)
  17641. +{
  17642. + return !S_ISDIR(dentry->d_inode->i_mode);
  17643. +}
  17644. +
  17645. +static int refresh_nondir(struct dentry *root, unsigned int sigen,
  17646. + int do_dentry)
  17647. +{
  17648. + int err, i, j, ndentry, e;
  17649. + struct au_dcsub_pages dpages;
  17650. + struct au_dpage *dpage;
  17651. + struct dentry **dentries;
  17652. + struct inode *inode;
  17653. +
  17654. + err = 0;
  17655. + list_for_each_entry(inode, &root->d_sb->s_inodes, i_sb_list)
  17656. + if (!S_ISDIR(inode->i_mode) && au_iigen(inode) != sigen) {
  17657. + ii_write_lock_child(inode);
  17658. + e = au_refresh_hinode_self(inode, /*do_attr*/1);
  17659. + ii_write_unlock(inode);
  17660. + if (unlikely(e)) {
  17661. + AuDbg("e %d, i%lu\n", e, inode->i_ino);
  17662. + if (!err)
  17663. + err = e;
  17664. + /* go on even if err */
  17665. + }
  17666. + }
  17667. +
  17668. + if (!do_dentry)
  17669. + goto out;
  17670. +
  17671. + e = au_dpages_init(&dpages, GFP_NOFS);
  17672. + if (unlikely(e)) {
  17673. + if (!err)
  17674. + err = e;
  17675. + goto out;
  17676. + }
  17677. + e = au_dcsub_pages(&dpages, root, test_nondir, NULL);
  17678. + if (unlikely(e)) {
  17679. + if (!err)
  17680. + err = e;
  17681. + goto out_dpages;
  17682. + }
  17683. +
  17684. + for (i = 0; i < dpages.ndpage; i++) {
  17685. + dpage = dpages.dpages + i;
  17686. + dentries = dpage->dentries;
  17687. + ndentry = dpage->ndentry;
  17688. + for (j = 0; j < ndentry; j++) {
  17689. + struct dentry *d;
  17690. +
  17691. + d = dentries[j];
  17692. + au_dbg_verify_nondir_parent(d, sigen);
  17693. + inode = d->d_inode;
  17694. + if (inode && au_digen(d) != sigen) {
  17695. + e = do_refresh(d, inode->i_mode & S_IFMT,
  17696. + /*dir_flags*/0);
  17697. + if (unlikely(e && !err))
  17698. + err = e;
  17699. + /* go on even err */
  17700. + }
  17701. + }
  17702. + }
  17703. +
  17704. + out_dpages:
  17705. + au_dpages_free(&dpages);
  17706. + out:
  17707. + return err;
  17708. +}
  17709. +
  17710. +static void au_remount_refresh(struct super_block *sb, unsigned int flags)
  17711. +{
  17712. + int err;
  17713. + unsigned int sigen;
  17714. + struct au_sbinfo *sbinfo;
  17715. + struct dentry *root;
  17716. + struct inode *inode;
  17717. +
  17718. + au_sigen_inc(sb);
  17719. + sigen = au_sigen(sb);
  17720. + sbinfo = au_sbi(sb);
  17721. + au_fclr_si(sbinfo, FAILED_REFRESH_DIRS);
  17722. +
  17723. + root = sb->s_root;
  17724. + DiMustNoWaiters(root);
  17725. + inode = root->d_inode;
  17726. + IiMustNoWaiters(inode);
  17727. + au_reset_hinotify(inode, au_hi_flags(inode, /*isdir*/1));
  17728. + di_write_unlock(root);
  17729. +
  17730. + err = refresh_dir(root, sigen);
  17731. + if (unlikely(err)) {
  17732. + au_fset_si(sbinfo, FAILED_REFRESH_DIRS);
  17733. + AuWarn("Refreshing directories failed, ignored (%d)\n", err);
  17734. + }
  17735. +
  17736. + if (au_ftest_opts(flags, REFRESH_NONDIR)) {
  17737. + err = refresh_nondir(root, sigen, !err);
  17738. + if (unlikely(err))
  17739. + AuWarn("Refreshing non-directories failed, ignored"
  17740. + "(%d)\n", err);
  17741. + }
  17742. +
  17743. + /* aufs_write_lock() calls ..._child() */
  17744. + di_write_lock_child(root);
  17745. + au_cpup_attr_all(root->d_inode, /*force*/1);
  17746. +}
  17747. +
  17748. +/* stop extra interpretation of errno in mount(8), and strange error messages */
  17749. +static int cvt_err(int err)
  17750. +{
  17751. + AuTraceErr(err);
  17752. +
  17753. + switch (err) {
  17754. + case -ENOENT:
  17755. + case -ENOTDIR:
  17756. + case -EEXIST:
  17757. + case -EIO:
  17758. + err = -EINVAL;
  17759. + }
  17760. + return err;
  17761. +}
  17762. +
  17763. +static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
  17764. +{
  17765. + int err;
  17766. + struct au_opts opts;
  17767. + struct dentry *root;
  17768. + struct inode *inode;
  17769. + struct au_sbinfo *sbinfo;
  17770. +
  17771. + err = 0;
  17772. + root = sb->s_root;
  17773. + if (!data || !*data) {
  17774. + aufs_write_lock(root);
  17775. + err = au_opts_verify(sb, *flags, /*pending*/0);
  17776. + if (!err)
  17777. + au_fsync_br(sb);
  17778. + aufs_write_unlock(root);
  17779. + goto out;
  17780. + }
  17781. +
  17782. + err = -ENOMEM;
  17783. + memset(&opts, 0, sizeof(opts));
  17784. + opts.opt = (void *)__get_free_page(GFP_NOFS);
  17785. + if (unlikely(!opts.opt))
  17786. + goto out;
  17787. + opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
  17788. + opts.flags = AuOpts_REMOUNT;
  17789. + opts.sb_flags = *flags;
  17790. +
  17791. + /* parse it before aufs lock */
  17792. + err = au_opts_parse(sb, data, &opts);
  17793. + if (unlikely(err))
  17794. + goto out_opts;
  17795. +
  17796. + sbinfo = au_sbi(sb);
  17797. + inode = root->d_inode;
  17798. + mutex_lock(&inode->i_mutex);
  17799. + aufs_write_lock(root);
  17800. + au_fsync_br(sb);
  17801. +
  17802. + /* au_opts_remount() may return an error */
  17803. + err = au_opts_remount(sb, &opts);
  17804. + au_opts_free(&opts);
  17805. +
  17806. + if (au_ftest_opts(opts.flags, REFRESH_DIR)
  17807. + || au_ftest_opts(opts.flags, REFRESH_NONDIR))
  17808. + au_remount_refresh(sb, opts.flags);
  17809. +
  17810. + aufs_write_unlock(root);
  17811. + mutex_unlock(&inode->i_mutex);
  17812. +
  17813. + out_opts:
  17814. + free_page((unsigned long)opts.opt);
  17815. + out:
  17816. + err = cvt_err(err);
  17817. + AuTraceErr(err);
  17818. + return err;
  17819. +}
  17820. +
  17821. +static struct super_operations aufs_sop = {
  17822. + .alloc_inode = aufs_alloc_inode,
  17823. + .destroy_inode = aufs_destroy_inode,
  17824. + .drop_inode = generic_delete_inode,
  17825. + .show_options = aufs_show_options,
  17826. + .statfs = aufs_statfs,
  17827. + .put_super = aufs_put_super,
  17828. + .remount_fs = aufs_remount_fs
  17829. +};
  17830. +
  17831. +/* ---------------------------------------------------------------------- */
  17832. +
  17833. +static int alloc_root(struct super_block *sb)
  17834. +{
  17835. + int err;
  17836. + struct inode *inode;
  17837. + struct dentry *root;
  17838. +
  17839. + err = -ENOMEM;
  17840. + inode = au_iget_locked(sb, AUFS_ROOT_INO);
  17841. + err = PTR_ERR(inode);
  17842. + if (IS_ERR(inode))
  17843. + goto out;
  17844. +
  17845. + inode->i_op = &aufs_dir_iop;
  17846. + inode->i_fop = &aufs_dir_fop;
  17847. + inode->i_mode = S_IFDIR;
  17848. + inode->i_nlink = 2;
  17849. + unlock_new_inode(inode);
  17850. +
  17851. + root = d_alloc_root(inode);
  17852. + if (unlikely(!root))
  17853. + goto out_iput;
  17854. + err = PTR_ERR(root);
  17855. + if (IS_ERR(root))
  17856. + goto out_iput;
  17857. +
  17858. + err = au_alloc_dinfo(root);
  17859. + if (!err) {
  17860. + sb->s_root = root;
  17861. + return 0; /* success */
  17862. + }
  17863. + dput(root);
  17864. + goto out; /* do not iput */
  17865. +
  17866. + out_iput:
  17867. + iget_failed(inode);
  17868. + iput(inode);
  17869. + out:
  17870. + return err;
  17871. +
  17872. +}
  17873. +
  17874. +static int aufs_fill_super(struct super_block *sb, void *raw_data,
  17875. + int silent __maybe_unused)
  17876. +{
  17877. + int err;
  17878. + struct au_opts opts;
  17879. + struct dentry *root;
  17880. + struct inode *inode;
  17881. + char *arg = raw_data;
  17882. +
  17883. + if (unlikely(!arg || !*arg)) {
  17884. + err = -EINVAL;
  17885. + AuErr("no arg\n");
  17886. + goto out;
  17887. + }
  17888. +
  17889. + err = -ENOMEM;
  17890. + memset(&opts, 0, sizeof(opts));
  17891. + opts.opt = (void *)__get_free_page(GFP_NOFS);
  17892. + if (unlikely(!opts.opt))
  17893. + goto out;
  17894. + opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
  17895. + opts.sb_flags = sb->s_flags;
  17896. +
  17897. + err = au_si_alloc(sb);
  17898. + if (unlikely(err))
  17899. + goto out_opts;
  17900. +
  17901. + /* all timestamps always follow the ones on the branch */
  17902. + sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
  17903. + sb->s_op = &aufs_sop;
  17904. + sb->s_magic = AUFS_SUPER_MAGIC;
  17905. + sb->s_maxbytes = 0;
  17906. + au_export_init(sb);
  17907. +
  17908. + err = alloc_root(sb);
  17909. + if (unlikely(err)) {
  17910. + si_write_unlock(sb);
  17911. + goto out_info;
  17912. + }
  17913. + root = sb->s_root;
  17914. + inode = root->d_inode;
  17915. +
  17916. + /*
  17917. + * actually we can parse options regardless aufs lock here.
  17918. + * but at remount time, parsing must be done before aufs lock.
  17919. + * so we follow the same rule.
  17920. + */
  17921. + ii_write_lock_parent(inode);
  17922. + aufs_write_unlock(root);
  17923. + err = au_opts_parse(sb, arg, &opts);
  17924. + if (unlikely(err))
  17925. + goto out_root;
  17926. +
  17927. + /* lock vfs_inode first, then aufs. */
  17928. + mutex_lock(&inode->i_mutex);
  17929. + inode->i_op = &aufs_dir_iop;
  17930. + inode->i_fop = &aufs_dir_fop;
  17931. + aufs_write_lock(root);
  17932. + err = au_opts_mount(sb, &opts);
  17933. + au_opts_free(&opts);
  17934. + if (unlikely(err))
  17935. + goto out_unlock;
  17936. + aufs_write_unlock(root);
  17937. + mutex_unlock(&inode->i_mutex);
  17938. + goto out_opts; /* success */
  17939. +
  17940. + out_unlock:
  17941. + aufs_write_unlock(root);
  17942. + mutex_unlock(&inode->i_mutex);
  17943. + out_root:
  17944. + dput(root);
  17945. + sb->s_root = NULL;
  17946. + out_info:
  17947. + kobject_put(&au_sbi(sb)->si_kobj);
  17948. + sb->s_fs_info = NULL;
  17949. + out_opts:
  17950. + free_page((unsigned long)opts.opt);
  17951. + out:
  17952. + AuTraceErr(err);
  17953. + err = cvt_err(err);
  17954. + AuTraceErr(err);
  17955. + return err;
  17956. +}
  17957. +
  17958. +/* ---------------------------------------------------------------------- */
  17959. +
  17960. +static int aufs_get_sb(struct file_system_type *fs_type, int flags,
  17961. + const char *dev_name __maybe_unused, void *raw_data,
  17962. + struct vfsmount *mnt)
  17963. +{
  17964. + int err;
  17965. + struct super_block *sb;
  17966. +
  17967. + /* all timestamps always follow the ones on the branch */
  17968. + /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
  17969. + err = get_sb_nodev(fs_type, flags, raw_data, aufs_fill_super, mnt);
  17970. + if (!err) {
  17971. + sb = mnt->mnt_sb;
  17972. + si_write_lock(sb);
  17973. + sysaufs_brs_add(sb, 0);
  17974. + si_write_unlock(sb);
  17975. + }
  17976. + return err;
  17977. +}
  17978. +
  17979. +struct file_system_type aufs_fs_type = {
  17980. + .name = AUFS_FSTYPE,
  17981. + .fs_flags =
  17982. + FS_RENAME_DOES_D_MOVE /* a race between rename and others */
  17983. + | FS_REVAL_DOT, /* for NFS branch and udba */
  17984. + .get_sb = aufs_get_sb,
  17985. + .kill_sb = generic_shutdown_super,
  17986. + /* no need to __module_get() and module_put(). */
  17987. + .owner = THIS_MODULE,
  17988. +};
  17989. diff -Nur linux-2.6.34.orig/fs/aufs/super.h linux-2.6.34/fs/aufs/super.h
  17990. --- linux-2.6.34.orig/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100
  17991. +++ linux-2.6.34/fs/aufs/super.h 2010-05-23 23:33:21.333473217 +0200
  17992. @@ -0,0 +1,384 @@
  17993. +/*
  17994. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  17995. + *
  17996. + * This program, aufs is free software; you can redistribute it and/or modify
  17997. + * it under the terms of the GNU General Public License as published by
  17998. + * the Free Software Foundation; either version 2 of the License, or
  17999. + * (at your option) any later version.
  18000. + *
  18001. + * This program is distributed in the hope that it will be useful,
  18002. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18003. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18004. + * GNU General Public License for more details.
  18005. + *
  18006. + * You should have received a copy of the GNU General Public License
  18007. + * along with this program; if not, write to the Free Software
  18008. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18009. + */
  18010. +
  18011. +/*
  18012. + * super_block operations
  18013. + */
  18014. +
  18015. +#ifndef __AUFS_SUPER_H__
  18016. +#define __AUFS_SUPER_H__
  18017. +
  18018. +#ifdef __KERNEL__
  18019. +
  18020. +#include <linux/fs.h>
  18021. +#include <linux/aufs_type.h>
  18022. +#include "rwsem.h"
  18023. +#include "spl.h"
  18024. +#include "wkq.h"
  18025. +
  18026. +typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *);
  18027. +typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t,
  18028. + loff_t *);
  18029. +
  18030. +/* policies to select one among multiple writable branches */
  18031. +struct au_wbr_copyup_operations {
  18032. + int (*copyup)(struct dentry *dentry);
  18033. +};
  18034. +
  18035. +struct au_wbr_create_operations {
  18036. + int (*create)(struct dentry *dentry, int isdir);
  18037. + int (*init)(struct super_block *sb);
  18038. + int (*fin)(struct super_block *sb);
  18039. +};
  18040. +
  18041. +struct au_wbr_mfs {
  18042. + struct mutex mfs_lock; /* protect this structure */
  18043. + unsigned long mfs_jiffy;
  18044. + unsigned long mfs_expire;
  18045. + aufs_bindex_t mfs_bindex;
  18046. +
  18047. + unsigned long long mfsrr_bytes;
  18048. + unsigned long long mfsrr_watermark;
  18049. +};
  18050. +
  18051. +struct au_branch;
  18052. +struct au_sbinfo {
  18053. + /* nowait tasks in the system-wide workqueue */
  18054. + struct au_nowait_tasks si_nowait;
  18055. +
  18056. + struct au_rwsem si_rwsem;
  18057. +
  18058. + /* branch management */
  18059. + unsigned int si_generation;
  18060. +
  18061. + /* see above flags */
  18062. + unsigned char au_si_status;
  18063. +
  18064. + aufs_bindex_t si_bend;
  18065. + aufs_bindex_t si_last_br_id;
  18066. + struct au_branch **si_branch;
  18067. +
  18068. + /* policy to select a writable branch */
  18069. + unsigned char si_wbr_copyup;
  18070. + unsigned char si_wbr_create;
  18071. + struct au_wbr_copyup_operations *si_wbr_copyup_ops;
  18072. + struct au_wbr_create_operations *si_wbr_create_ops;
  18073. +
  18074. + /* round robin */
  18075. + atomic_t si_wbr_rr_next;
  18076. +
  18077. + /* most free space */
  18078. + struct au_wbr_mfs si_wbr_mfs;
  18079. +
  18080. + /* mount flags */
  18081. + /* include/asm-ia64/siginfo.h defines a macro named si_flags */
  18082. + unsigned int si_mntflags;
  18083. +
  18084. + /* external inode number (bitmap and translation table) */
  18085. + au_readf_t si_xread;
  18086. + au_writef_t si_xwrite;
  18087. + struct file *si_xib;
  18088. + struct mutex si_xib_mtx; /* protect xib members */
  18089. + unsigned long *si_xib_buf;
  18090. + unsigned long si_xib_last_pindex;
  18091. + int si_xib_next_bit;
  18092. + aufs_bindex_t si_xino_brid;
  18093. + /* reserved for future use */
  18094. + /* unsigned long long si_xib_limit; */ /* Max xib file size */
  18095. +
  18096. +#ifdef CONFIG_AUFS_EXPORT
  18097. + /* i_generation */
  18098. + struct file *si_xigen;
  18099. + atomic_t si_xigen_next;
  18100. +#endif
  18101. +
  18102. + /* vdir parameters */
  18103. + unsigned long si_rdcache; /* max cache time in HZ */
  18104. + unsigned int si_rdblk; /* deblk size */
  18105. + unsigned int si_rdhash; /* hash size */
  18106. +
  18107. + /*
  18108. + * If the number of whiteouts are larger than si_dirwh, leave all of
  18109. + * them after au_whtmp_ren to reduce the cost of rmdir(2).
  18110. + * future fsck.aufs or kernel thread will remove them later.
  18111. + * Otherwise, remove all whiteouts and the dir in rmdir(2).
  18112. + */
  18113. + unsigned int si_dirwh;
  18114. +
  18115. + /*
  18116. + * rename(2) a directory with all children.
  18117. + */
  18118. + /* reserved for future use */
  18119. + /* int si_rendir; */
  18120. +
  18121. + /* pseudo_link list */
  18122. + struct au_splhead si_plink;
  18123. + wait_queue_head_t si_plink_wq;
  18124. +
  18125. + /*
  18126. + * sysfs and lifetime management.
  18127. + * this is not a small structure and it may be a waste of memory in case
  18128. + * of sysfs is disabled, particulary when many aufs-es are mounted.
  18129. + * but using sysfs is majority.
  18130. + */
  18131. + struct kobject si_kobj;
  18132. +#ifdef CONFIG_DEBUG_FS
  18133. + struct dentry *si_dbgaufs, *si_dbgaufs_xib;
  18134. +#ifdef CONFIG_AUFS_EXPORT
  18135. + struct dentry *si_dbgaufs_xigen;
  18136. +#endif
  18137. +#endif
  18138. +
  18139. + /* dirty, necessary for unmounting, sysfs and sysrq */
  18140. + struct super_block *si_sb;
  18141. +};
  18142. +
  18143. +/* sbinfo status flags */
  18144. +/*
  18145. + * set true when refresh_dirs() failed at remount time.
  18146. + * then try refreshing dirs at access time again.
  18147. + * if it is false, refreshing dirs at access time is unnecesary
  18148. + */
  18149. +#define AuSi_FAILED_REFRESH_DIRS 1
  18150. +#define AuSi_MAINTAIN_PLINK (1 << 1) /* ioctl */
  18151. +static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
  18152. + unsigned int flag)
  18153. +{
  18154. + AuRwMustAnyLock(&sbi->si_rwsem);
  18155. + return sbi->au_si_status & flag;
  18156. +}
  18157. +#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name)
  18158. +#define au_fset_si(sbinfo, name) do { \
  18159. + AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
  18160. + (sbinfo)->au_si_status |= AuSi_##name; \
  18161. +} while (0)
  18162. +#define au_fclr_si(sbinfo, name) do { \
  18163. + AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
  18164. + (sbinfo)->au_si_status &= ~AuSi_##name; \
  18165. +} while (0)
  18166. +
  18167. +/* ---------------------------------------------------------------------- */
  18168. +
  18169. +/* policy to select one among writable branches */
  18170. +#define AuWbrCopyup(sbinfo, args...) \
  18171. + ((sbinfo)->si_wbr_copyup_ops->copyup(args))
  18172. +#define AuWbrCreate(sbinfo, args...) \
  18173. + ((sbinfo)->si_wbr_create_ops->create(args))
  18174. +
  18175. +/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
  18176. +#define AuLock_DW 1 /* write-lock dentry */
  18177. +#define AuLock_IR (1 << 1) /* read-lock inode */
  18178. +#define AuLock_IW (1 << 2) /* write-lock inode */
  18179. +#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
  18180. +#define AuLock_DIR (1 << 4) /* target is a dir */
  18181. +#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
  18182. +#define au_fset_lock(flags, name) { (flags) |= AuLock_##name; }
  18183. +#define au_fclr_lock(flags, name) { (flags) &= ~AuLock_##name; }
  18184. +
  18185. +/* ---------------------------------------------------------------------- */
  18186. +
  18187. +/* super.c */
  18188. +extern struct file_system_type aufs_fs_type;
  18189. +struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
  18190. +
  18191. +/* sbinfo.c */
  18192. +void au_si_free(struct kobject *kobj);
  18193. +int au_si_alloc(struct super_block *sb);
  18194. +int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr);
  18195. +
  18196. +unsigned int au_sigen_inc(struct super_block *sb);
  18197. +aufs_bindex_t au_new_br_id(struct super_block *sb);
  18198. +
  18199. +void aufs_read_lock(struct dentry *dentry, int flags);
  18200. +void aufs_read_unlock(struct dentry *dentry, int flags);
  18201. +void aufs_write_lock(struct dentry *dentry);
  18202. +void aufs_write_unlock(struct dentry *dentry);
  18203. +void aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int isdir);
  18204. +void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
  18205. +
  18206. +/* wbr_policy.c */
  18207. +extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
  18208. +extern struct au_wbr_create_operations au_wbr_create_ops[];
  18209. +int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
  18210. +
  18211. +/* ---------------------------------------------------------------------- */
  18212. +
  18213. +static inline struct au_sbinfo *au_sbi(struct super_block *sb)
  18214. +{
  18215. + return sb->s_fs_info;
  18216. +}
  18217. +
  18218. +/* ---------------------------------------------------------------------- */
  18219. +
  18220. +#ifdef CONFIG_AUFS_EXPORT
  18221. +void au_export_init(struct super_block *sb);
  18222. +
  18223. +static inline int au_test_nfsd(struct task_struct *tsk)
  18224. +{
  18225. + return !tsk->mm && !strcmp(tsk->comm, "nfsd");
  18226. +}
  18227. +
  18228. +int au_xigen_inc(struct inode *inode);
  18229. +int au_xigen_new(struct inode *inode);
  18230. +int au_xigen_set(struct super_block *sb, struct file *base);
  18231. +void au_xigen_clr(struct super_block *sb);
  18232. +
  18233. +static inline int au_busy_or_stale(void)
  18234. +{
  18235. + if (!au_test_nfsd(current))
  18236. + return -EBUSY;
  18237. + return -ESTALE;
  18238. +}
  18239. +#else
  18240. +static inline void au_export_init(struct super_block *sb)
  18241. +{
  18242. + /* nothing */
  18243. +}
  18244. +
  18245. +static inline int au_test_nfsd(struct task_struct *tsk)
  18246. +{
  18247. + return 0;
  18248. +}
  18249. +
  18250. +static inline int au_xigen_inc(struct inode *inode)
  18251. +{
  18252. + return 0;
  18253. +}
  18254. +
  18255. +static inline int au_xigen_new(struct inode *inode)
  18256. +{
  18257. + return 0;
  18258. +}
  18259. +
  18260. +static inline int au_xigen_set(struct super_block *sb, struct file *base)
  18261. +{
  18262. + return 0;
  18263. +}
  18264. +
  18265. +static inline void au_xigen_clr(struct super_block *sb)
  18266. +{
  18267. + /* empty */
  18268. +}
  18269. +
  18270. +static inline int au_busy_or_stale(void)
  18271. +{
  18272. + return -EBUSY;
  18273. +}
  18274. +#endif /* CONFIG_AUFS_EXPORT */
  18275. +
  18276. +/* ---------------------------------------------------------------------- */
  18277. +
  18278. +static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
  18279. +{
  18280. + /*
  18281. + * This function is a dynamic '__init' fucntion actually,
  18282. + * so the tiny check for si_rwsem is unnecessary.
  18283. + */
  18284. + /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
  18285. +#ifdef CONFIG_DEBUG_FS
  18286. + sbinfo->si_dbgaufs = NULL;
  18287. + sbinfo->si_dbgaufs_xib = NULL;
  18288. +#ifdef CONFIG_AUFS_EXPORT
  18289. + sbinfo->si_dbgaufs_xigen = NULL;
  18290. +#endif
  18291. +#endif
  18292. +}
  18293. +
  18294. +/* ---------------------------------------------------------------------- */
  18295. +
  18296. +/* lock superblock. mainly for entry point functions */
  18297. +/*
  18298. + * si_noflush_read_lock, si_noflush_write_lock,
  18299. + * si_read_unlock, si_write_unlock, si_downgrade_lock
  18300. + */
  18301. +AuSimpleLockRwsemFuncs(si_noflush, struct super_block *sb,
  18302. + &au_sbi(sb)->si_rwsem);
  18303. +AuSimpleUnlockRwsemFuncs(si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
  18304. +
  18305. +#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
  18306. +#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
  18307. +#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
  18308. +
  18309. +static inline void si_read_lock(struct super_block *sb, int flags)
  18310. +{
  18311. + if (au_ftest_lock(flags, FLUSH))
  18312. + au_nwt_flush(&au_sbi(sb)->si_nowait);
  18313. + si_noflush_read_lock(sb);
  18314. +}
  18315. +
  18316. +static inline void si_write_lock(struct super_block *sb)
  18317. +{
  18318. + au_nwt_flush(&au_sbi(sb)->si_nowait);
  18319. + si_noflush_write_lock(sb);
  18320. +}
  18321. +
  18322. +static inline int si_read_trylock(struct super_block *sb, int flags)
  18323. +{
  18324. + if (au_ftest_lock(flags, FLUSH))
  18325. + au_nwt_flush(&au_sbi(sb)->si_nowait);
  18326. + return si_noflush_read_trylock(sb);
  18327. +}
  18328. +
  18329. +static inline int si_write_trylock(struct super_block *sb, int flags)
  18330. +{
  18331. + if (au_ftest_lock(flags, FLUSH))
  18332. + au_nwt_flush(&au_sbi(sb)->si_nowait);
  18333. + return si_noflush_write_trylock(sb);
  18334. +}
  18335. +
  18336. +/* ---------------------------------------------------------------------- */
  18337. +
  18338. +static inline aufs_bindex_t au_sbend(struct super_block *sb)
  18339. +{
  18340. + SiMustAnyLock(sb);
  18341. + return au_sbi(sb)->si_bend;
  18342. +}
  18343. +
  18344. +static inline unsigned int au_mntflags(struct super_block *sb)
  18345. +{
  18346. + SiMustAnyLock(sb);
  18347. + return au_sbi(sb)->si_mntflags;
  18348. +}
  18349. +
  18350. +static inline unsigned int au_sigen(struct super_block *sb)
  18351. +{
  18352. + SiMustAnyLock(sb);
  18353. + return au_sbi(sb)->si_generation;
  18354. +}
  18355. +
  18356. +static inline struct au_branch *au_sbr(struct super_block *sb,
  18357. + aufs_bindex_t bindex)
  18358. +{
  18359. + SiMustAnyLock(sb);
  18360. + return au_sbi(sb)->si_branch[0 + bindex];
  18361. +}
  18362. +
  18363. +static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid)
  18364. +{
  18365. + SiMustWriteLock(sb);
  18366. + au_sbi(sb)->si_xino_brid = brid;
  18367. +}
  18368. +
  18369. +static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
  18370. +{
  18371. + SiMustAnyLock(sb);
  18372. + return au_sbi(sb)->si_xino_brid;
  18373. +}
  18374. +
  18375. +#endif /* __KERNEL__ */
  18376. +#endif /* __AUFS_SUPER_H__ */
  18377. diff -Nur linux-2.6.34.orig/fs/aufs/sysaufs.c linux-2.6.34/fs/aufs/sysaufs.c
  18378. --- linux-2.6.34.orig/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
  18379. +++ linux-2.6.34/fs/aufs/sysaufs.c 2010-05-23 23:33:21.373473051 +0200
  18380. @@ -0,0 +1,104 @@
  18381. +/*
  18382. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  18383. + *
  18384. + * This program, aufs is free software; you can redistribute it and/or modify
  18385. + * it under the terms of the GNU General Public License as published by
  18386. + * the Free Software Foundation; either version 2 of the License, or
  18387. + * (at your option) any later version.
  18388. + *
  18389. + * This program is distributed in the hope that it will be useful,
  18390. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18391. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18392. + * GNU General Public License for more details.
  18393. + *
  18394. + * You should have received a copy of the GNU General Public License
  18395. + * along with this program; if not, write to the Free Software
  18396. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18397. + */
  18398. +
  18399. +/*
  18400. + * sysfs interface and lifetime management
  18401. + * they are necessary regardless sysfs is disabled.
  18402. + */
  18403. +
  18404. +#include <linux/fs.h>
  18405. +#include <linux/random.h>
  18406. +#include <linux/sysfs.h>
  18407. +#include "aufs.h"
  18408. +
  18409. +unsigned long sysaufs_si_mask;
  18410. +struct kset *sysaufs_ket;
  18411. +
  18412. +#define AuSiAttr(_name) { \
  18413. + .attr = { .name = __stringify(_name), .mode = 0444 }, \
  18414. + .show = sysaufs_si_##_name, \
  18415. +}
  18416. +
  18417. +static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
  18418. +struct attribute *sysaufs_si_attrs[] = {
  18419. + &sysaufs_si_attr_xi_path.attr,
  18420. + NULL,
  18421. +};
  18422. +
  18423. +static struct sysfs_ops au_sbi_ops = {
  18424. + .show = sysaufs_si_show
  18425. +};
  18426. +
  18427. +static struct kobj_type au_sbi_ktype = {
  18428. + .release = au_si_free,
  18429. + .sysfs_ops = &au_sbi_ops,
  18430. + .default_attrs = sysaufs_si_attrs
  18431. +};
  18432. +
  18433. +/* ---------------------------------------------------------------------- */
  18434. +
  18435. +int sysaufs_si_init(struct au_sbinfo *sbinfo)
  18436. +{
  18437. + int err;
  18438. +
  18439. + sbinfo->si_kobj.kset = sysaufs_ket;
  18440. + /* cf. sysaufs_name() */
  18441. + err = kobject_init_and_add
  18442. + (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_ket->kobj*/NULL,
  18443. + SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
  18444. +
  18445. + dbgaufs_si_null(sbinfo);
  18446. + if (!err) {
  18447. + err = dbgaufs_si_init(sbinfo);
  18448. + if (unlikely(err))
  18449. + kobject_put(&sbinfo->si_kobj);
  18450. + }
  18451. + return err;
  18452. +}
  18453. +
  18454. +void sysaufs_fin(void)
  18455. +{
  18456. + dbgaufs_fin();
  18457. + sysfs_remove_group(&sysaufs_ket->kobj, sysaufs_attr_group);
  18458. + kset_unregister(sysaufs_ket);
  18459. +}
  18460. +
  18461. +int __init sysaufs_init(void)
  18462. +{
  18463. + int err;
  18464. +
  18465. + do {
  18466. + get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
  18467. + } while (!sysaufs_si_mask);
  18468. +
  18469. + sysaufs_ket = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
  18470. + err = PTR_ERR(sysaufs_ket);
  18471. + if (IS_ERR(sysaufs_ket))
  18472. + goto out;
  18473. + err = sysfs_create_group(&sysaufs_ket->kobj, sysaufs_attr_group);
  18474. + if (unlikely(err)) {
  18475. + kset_unregister(sysaufs_ket);
  18476. + goto out;
  18477. + }
  18478. +
  18479. + err = dbgaufs_init();
  18480. + if (unlikely(err))
  18481. + sysaufs_fin();
  18482. + out:
  18483. + return err;
  18484. +}
  18485. diff -Nur linux-2.6.34.orig/fs/aufs/sysaufs.h linux-2.6.34/fs/aufs/sysaufs.h
  18486. --- linux-2.6.34.orig/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
  18487. +++ linux-2.6.34/fs/aufs/sysaufs.h 2010-05-23 23:33:21.410978037 +0200
  18488. @@ -0,0 +1,120 @@
  18489. +/*
  18490. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  18491. + *
  18492. + * This program, aufs is free software; you can redistribute it and/or modify
  18493. + * it under the terms of the GNU General Public License as published by
  18494. + * the Free Software Foundation; either version 2 of the License, or
  18495. + * (at your option) any later version.
  18496. + *
  18497. + * This program is distributed in the hope that it will be useful,
  18498. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18499. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18500. + * GNU General Public License for more details.
  18501. + *
  18502. + * You should have received a copy of the GNU General Public License
  18503. + * along with this program; if not, write to the Free Software
  18504. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18505. + */
  18506. +
  18507. +/*
  18508. + * sysfs interface and mount lifetime management
  18509. + */
  18510. +
  18511. +#ifndef __SYSAUFS_H__
  18512. +#define __SYSAUFS_H__
  18513. +
  18514. +#ifdef __KERNEL__
  18515. +
  18516. +#include <linux/sysfs.h>
  18517. +#include <linux/aufs_type.h>
  18518. +#include "module.h"
  18519. +
  18520. +struct super_block;
  18521. +struct au_sbinfo;
  18522. +
  18523. +struct sysaufs_si_attr {
  18524. + struct attribute attr;
  18525. + int (*show)(struct seq_file *seq, struct super_block *sb);
  18526. +};
  18527. +
  18528. +/* ---------------------------------------------------------------------- */
  18529. +
  18530. +/* sysaufs.c */
  18531. +extern unsigned long sysaufs_si_mask;
  18532. +extern struct kset *sysaufs_ket;
  18533. +extern struct attribute *sysaufs_si_attrs[];
  18534. +int sysaufs_si_init(struct au_sbinfo *sbinfo);
  18535. +int __init sysaufs_init(void);
  18536. +void sysaufs_fin(void);
  18537. +
  18538. +/* ---------------------------------------------------------------------- */
  18539. +
  18540. +/* some people doesn't like to show a pointer in kernel */
  18541. +static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
  18542. +{
  18543. + return sysaufs_si_mask ^ (unsigned long)sbinfo;
  18544. +}
  18545. +
  18546. +#define SysaufsSiNamePrefix "si_"
  18547. +#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16)
  18548. +static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
  18549. +{
  18550. + snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
  18551. + sysaufs_si_id(sbinfo));
  18552. +}
  18553. +
  18554. +struct au_branch;
  18555. +#ifdef CONFIG_SYSFS
  18556. +/* sysfs.c */
  18557. +extern struct attribute_group *sysaufs_attr_group;
  18558. +
  18559. +int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
  18560. +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
  18561. + char *buf);
  18562. +
  18563. +void sysaufs_br_init(struct au_branch *br);
  18564. +void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
  18565. +void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
  18566. +
  18567. +#define sysaufs_brs_init() do {} while (0)
  18568. +
  18569. +#else
  18570. +#define sysaufs_attr_group NULL
  18571. +
  18572. +static inline
  18573. +int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
  18574. +{
  18575. + return 0;
  18576. +}
  18577. +
  18578. +static inline
  18579. +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
  18580. + char *buf)
  18581. +{
  18582. + return 0;
  18583. +}
  18584. +
  18585. +static inline void sysaufs_br_init(struct au_branch *br)
  18586. +{
  18587. + /* empty */
  18588. +}
  18589. +
  18590. +static inline void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
  18591. +{
  18592. + /* nothing */
  18593. +}
  18594. +
  18595. +static inline void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
  18596. +{
  18597. + /* nothing */
  18598. +}
  18599. +
  18600. +static inline void sysaufs_brs_init(void)
  18601. +{
  18602. + sysaufs_brs = 0;
  18603. +}
  18604. +
  18605. +#endif /* CONFIG_SYSFS */
  18606. +
  18607. +#endif /* __KERNEL__ */
  18608. +#endif /* __SYSAUFS_H__ */
  18609. diff -Nur linux-2.6.34.orig/fs/aufs/sysfs.c linux-2.6.34/fs/aufs/sysfs.c
  18610. --- linux-2.6.34.orig/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100
  18611. +++ linux-2.6.34/fs/aufs/sysfs.c 2010-05-23 23:33:21.472224620 +0200
  18612. @@ -0,0 +1,210 @@
  18613. +/*
  18614. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  18615. + *
  18616. + * This program, aufs is free software; you can redistribute it and/or modify
  18617. + * it under the terms of the GNU General Public License as published by
  18618. + * the Free Software Foundation; either version 2 of the License, or
  18619. + * (at your option) any later version.
  18620. + *
  18621. + * This program is distributed in the hope that it will be useful,
  18622. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18623. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18624. + * GNU General Public License for more details.
  18625. + *
  18626. + * You should have received a copy of the GNU General Public License
  18627. + * along with this program; if not, write to the Free Software
  18628. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18629. + */
  18630. +
  18631. +/*
  18632. + * sysfs interface
  18633. + */
  18634. +
  18635. +#include <linux/fs.h>
  18636. +#include <linux/module.h>
  18637. +#include <linux/seq_file.h>
  18638. +#include <linux/sysfs.h>
  18639. +#include "aufs.h"
  18640. +
  18641. +static struct attribute *au_attr[] = {
  18642. + NULL, /* need to NULL terminate the list of attributes */
  18643. +};
  18644. +
  18645. +static struct attribute_group sysaufs_attr_group_body = {
  18646. + .attrs = au_attr
  18647. +};
  18648. +
  18649. +struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
  18650. +
  18651. +/* ---------------------------------------------------------------------- */
  18652. +
  18653. +int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
  18654. +{
  18655. + int err;
  18656. +
  18657. + SiMustAnyLock(sb);
  18658. +
  18659. + err = 0;
  18660. + if (au_opt_test(au_mntflags(sb), XINO)) {
  18661. + err = au_xino_path(seq, au_sbi(sb)->si_xib);
  18662. + seq_putc(seq, '\n');
  18663. + }
  18664. + return err;
  18665. +}
  18666. +
  18667. +/*
  18668. + * the lifetime of branch is independent from the entry under sysfs.
  18669. + * sysfs handles the lifetime of the entry, and never call ->show() after it is
  18670. + * unlinked.
  18671. + */
  18672. +static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
  18673. + aufs_bindex_t bindex)
  18674. +{
  18675. + struct path path;
  18676. + struct dentry *root;
  18677. + struct au_branch *br;
  18678. +
  18679. + AuDbg("b%d\n", bindex);
  18680. +
  18681. + root = sb->s_root;
  18682. + di_read_lock_parent(root, !AuLock_IR);
  18683. + br = au_sbr(sb, bindex);
  18684. + path.mnt = br->br_mnt;
  18685. + path.dentry = au_h_dptr(root, bindex);
  18686. + au_seq_path(seq, &path);
  18687. + di_read_unlock(root, !AuLock_IR);
  18688. + seq_printf(seq, "=%s\n", au_optstr_br_perm(br->br_perm));
  18689. + return 0;
  18690. +}
  18691. +
  18692. +/* ---------------------------------------------------------------------- */
  18693. +
  18694. +static struct seq_file *au_seq(char *p, ssize_t len)
  18695. +{
  18696. + struct seq_file *seq;
  18697. +
  18698. + seq = kzalloc(sizeof(*seq), GFP_NOFS);
  18699. + if (seq) {
  18700. + /* mutex_init(&seq.lock); */
  18701. + seq->buf = p;
  18702. + seq->size = len;
  18703. + return seq; /* success */
  18704. + }
  18705. +
  18706. + seq = ERR_PTR(-ENOMEM);
  18707. + return seq;
  18708. +}
  18709. +
  18710. +#define SysaufsBr_PREFIX "br"
  18711. +
  18712. +/* todo: file size may exceed PAGE_SIZE */
  18713. +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
  18714. + char *buf)
  18715. +{
  18716. + ssize_t err;
  18717. + long l;
  18718. + aufs_bindex_t bend;
  18719. + struct au_sbinfo *sbinfo;
  18720. + struct super_block *sb;
  18721. + struct seq_file *seq;
  18722. + char *name;
  18723. + struct attribute **cattr;
  18724. +
  18725. + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
  18726. + sb = sbinfo->si_sb;
  18727. + si_noflush_read_lock(sb);
  18728. +
  18729. + seq = au_seq(buf, PAGE_SIZE);
  18730. + err = PTR_ERR(seq);
  18731. + if (IS_ERR(seq))
  18732. + goto out;
  18733. +
  18734. + name = (void *)attr->name;
  18735. + cattr = sysaufs_si_attrs;
  18736. + while (*cattr) {
  18737. + if (!strcmp(name, (*cattr)->name)) {
  18738. + err = container_of(*cattr, struct sysaufs_si_attr, attr)
  18739. + ->show(seq, sb);
  18740. + goto out_seq;
  18741. + }
  18742. + cattr++;
  18743. + }
  18744. +
  18745. + bend = au_sbend(sb);
  18746. + if (!strncmp(name, SysaufsBr_PREFIX, sizeof(SysaufsBr_PREFIX) - 1)) {
  18747. + name += sizeof(SysaufsBr_PREFIX) - 1;
  18748. + err = strict_strtol(name, 10, &l);
  18749. + if (!err) {
  18750. + if (l <= bend)
  18751. + err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l);
  18752. + else
  18753. + err = -ENOENT;
  18754. + }
  18755. + goto out_seq;
  18756. + }
  18757. + BUG();
  18758. +
  18759. + out_seq:
  18760. + if (!err) {
  18761. + err = seq->count;
  18762. + /* sysfs limit */
  18763. + if (unlikely(err == PAGE_SIZE))
  18764. + err = -EFBIG;
  18765. + }
  18766. + kfree(seq);
  18767. + out:
  18768. + si_read_unlock(sb);
  18769. + return err;
  18770. +}
  18771. +
  18772. +/* ---------------------------------------------------------------------- */
  18773. +
  18774. +void sysaufs_br_init(struct au_branch *br)
  18775. +{
  18776. + br->br_attr.name = br->br_name;
  18777. + br->br_attr.mode = S_IRUGO;
  18778. + br->br_attr.owner = THIS_MODULE;
  18779. +}
  18780. +
  18781. +void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
  18782. +{
  18783. + struct au_branch *br;
  18784. + struct kobject *kobj;
  18785. + aufs_bindex_t bend;
  18786. +
  18787. + dbgaufs_brs_del(sb, bindex);
  18788. +
  18789. + if (!sysaufs_brs)
  18790. + return;
  18791. +
  18792. + kobj = &au_sbi(sb)->si_kobj;
  18793. + bend = au_sbend(sb);
  18794. + for (; bindex <= bend; bindex++) {
  18795. + br = au_sbr(sb, bindex);
  18796. + sysfs_remove_file(kobj, &br->br_attr);
  18797. + }
  18798. +}
  18799. +
  18800. +void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
  18801. +{
  18802. + int err;
  18803. + aufs_bindex_t bend;
  18804. + struct kobject *kobj;
  18805. + struct au_branch *br;
  18806. +
  18807. + dbgaufs_brs_add(sb, bindex);
  18808. +
  18809. + if (!sysaufs_brs)
  18810. + return;
  18811. +
  18812. + kobj = &au_sbi(sb)->si_kobj;
  18813. + bend = au_sbend(sb);
  18814. + for (; bindex <= bend; bindex++) {
  18815. + br = au_sbr(sb, bindex);
  18816. + snprintf(br->br_name, sizeof(br->br_name), SysaufsBr_PREFIX
  18817. + "%d", bindex);
  18818. + err = sysfs_create_file(kobj, &br->br_attr);
  18819. + if (unlikely(err))
  18820. + AuWarn("failed %s under sysfs(%d)\n", br->br_name, err);
  18821. + }
  18822. +}
  18823. diff -Nur linux-2.6.34.orig/fs/aufs/sysrq.c linux-2.6.34/fs/aufs/sysrq.c
  18824. --- linux-2.6.34.orig/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100
  18825. +++ linux-2.6.34/fs/aufs/sysrq.c 2010-05-23 23:33:21.520978408 +0200
  18826. @@ -0,0 +1,115 @@
  18827. +/*
  18828. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  18829. + *
  18830. + * This program, aufs is free software; you can redistribute it and/or modify
  18831. + * it under the terms of the GNU General Public License as published by
  18832. + * the Free Software Foundation; either version 2 of the License, or
  18833. + * (at your option) any later version.
  18834. + *
  18835. + * This program is distributed in the hope that it will be useful,
  18836. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18837. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18838. + * GNU General Public License for more details.
  18839. + *
  18840. + * You should have received a copy of the GNU General Public License
  18841. + * along with this program; if not, write to the Free Software
  18842. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18843. + */
  18844. +
  18845. +/*
  18846. + * magic sysrq hanlder
  18847. + */
  18848. +
  18849. +#include <linux/fs.h>
  18850. +#include <linux/module.h>
  18851. +#include <linux/moduleparam.h>
  18852. +/* #include <linux/sysrq.h> */
  18853. +#include "aufs.h"
  18854. +
  18855. +/* ---------------------------------------------------------------------- */
  18856. +
  18857. +static void sysrq_sb(struct super_block *sb)
  18858. +{
  18859. + char *plevel;
  18860. + struct au_sbinfo *sbinfo;
  18861. + struct file *file;
  18862. +
  18863. + plevel = au_plevel;
  18864. + au_plevel = KERN_WARNING;
  18865. + au_debug(1);
  18866. +
  18867. + sbinfo = au_sbi(sb);
  18868. + pr_warning("si=%lx\n", sysaufs_si_id(sbinfo));
  18869. + pr_warning(AUFS_NAME ": superblock\n");
  18870. + au_dpri_sb(sb);
  18871. + pr_warning(AUFS_NAME ": root dentry\n");
  18872. + au_dpri_dentry(sb->s_root);
  18873. + pr_warning(AUFS_NAME ": root inode\n");
  18874. + au_dpri_inode(sb->s_root->d_inode);
  18875. +#if 0
  18876. + struct inode *i;
  18877. + pr_warning(AUFS_NAME ": isolated inode\n");
  18878. + list_for_each_entry(i, &sb->s_inodes, i_sb_list)
  18879. + if (list_empty(&i->i_dentry))
  18880. + au_dpri_inode(i);
  18881. +#endif
  18882. + pr_warning(AUFS_NAME ": files\n");
  18883. + list_for_each_entry(file, &sb->s_files, f_u.fu_list)
  18884. + if (!special_file(file->f_dentry->d_inode->i_mode))
  18885. + au_dpri_file(file);
  18886. +
  18887. + au_plevel = plevel;
  18888. + au_debug(0);
  18889. +}
  18890. +
  18891. +/* ---------------------------------------------------------------------- */
  18892. +
  18893. +/* module parameter */
  18894. +static char *aufs_sysrq_key = "a";
  18895. +module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO);
  18896. +MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
  18897. +
  18898. +static void au_sysrq(int key __maybe_unused,
  18899. + struct tty_struct *tty __maybe_unused)
  18900. +{
  18901. + struct kobject *kobj;
  18902. + struct au_sbinfo *sbinfo;
  18903. +
  18904. + /* spin_lock(&sysaufs_ket->list_lock); */
  18905. + list_for_each_entry(kobj, &sysaufs_ket->list, entry) {
  18906. + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
  18907. + sysrq_sb(sbinfo->si_sb);
  18908. + }
  18909. + /* spin_unlock(&sysaufs_ket->list_lock); */
  18910. +}
  18911. +
  18912. +static struct sysrq_key_op au_sysrq_op = {
  18913. + .handler = au_sysrq,
  18914. + .help_msg = "Aufs",
  18915. + .action_msg = "Aufs",
  18916. + .enable_mask = SYSRQ_ENABLE_DUMP
  18917. +};
  18918. +
  18919. +/* ---------------------------------------------------------------------- */
  18920. +
  18921. +int __init au_sysrq_init(void)
  18922. +{
  18923. + int err;
  18924. + char key;
  18925. +
  18926. + err = -1;
  18927. + key = *aufs_sysrq_key;
  18928. + if ('a' <= key && key <= 'z')
  18929. + err = register_sysrq_key(key, &au_sysrq_op);
  18930. + if (unlikely(err))
  18931. + AuErr("err %d, sysrq=%c\n", err, key);
  18932. + return err;
  18933. +}
  18934. +
  18935. +void au_sysrq_fin(void)
  18936. +{
  18937. + int err;
  18938. + err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
  18939. + if (unlikely(err))
  18940. + AuErr("err %d (ignored)\n", err);
  18941. +}
  18942. diff -Nur linux-2.6.34.orig/fs/aufs/vdir.c linux-2.6.34/fs/aufs/vdir.c
  18943. --- linux-2.6.34.orig/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100
  18944. +++ linux-2.6.34/fs/aufs/vdir.c 2010-05-23 23:33:21.571845413 +0200
  18945. @@ -0,0 +1,882 @@
  18946. +/*
  18947. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  18948. + *
  18949. + * This program, aufs is free software; you can redistribute it and/or modify
  18950. + * it under the terms of the GNU General Public License as published by
  18951. + * the Free Software Foundation; either version 2 of the License, or
  18952. + * (at your option) any later version.
  18953. + *
  18954. + * This program is distributed in the hope that it will be useful,
  18955. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18956. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18957. + * GNU General Public License for more details.
  18958. + *
  18959. + * You should have received a copy of the GNU General Public License
  18960. + * along with this program; if not, write to the Free Software
  18961. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18962. + */
  18963. +
  18964. +/*
  18965. + * virtual or vertical directory
  18966. + */
  18967. +
  18968. +#include <linux/hash.h>
  18969. +#include "aufs.h"
  18970. +
  18971. +static unsigned int calc_size(int nlen)
  18972. +{
  18973. + BUILD_BUG_ON(sizeof(ino_t) != sizeof(long));
  18974. + return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
  18975. +}
  18976. +
  18977. +static int set_deblk_end(union au_vdir_deblk_p *p,
  18978. + union au_vdir_deblk_p *deblk_end)
  18979. +{
  18980. + if (calc_size(0) <= deblk_end->deblk - p->deblk) {
  18981. + p->de->de_str.len = 0;
  18982. + /* smp_mb(); */
  18983. + return 0;
  18984. + }
  18985. + return -1; /* error */
  18986. +}
  18987. +
  18988. +/* returns true or false */
  18989. +static int is_deblk_end(union au_vdir_deblk_p *p,
  18990. + union au_vdir_deblk_p *deblk_end)
  18991. +{
  18992. + if (calc_size(0) <= deblk_end->deblk - p->deblk)
  18993. + return !p->de->de_str.len;
  18994. + return 1;
  18995. +}
  18996. +
  18997. +static unsigned char *last_deblk(struct au_vdir *vdir)
  18998. +{
  18999. + return vdir->vd_deblk[vdir->vd_nblk - 1];
  19000. +}
  19001. +
  19002. +/* ---------------------------------------------------------------------- */
  19003. +
  19004. +/*
  19005. + * the allocated memory has to be freed by
  19006. + * au_nhash_wh_free() or au_nhash_de_free().
  19007. + */
  19008. +int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
  19009. +{
  19010. + struct hlist_head *head;
  19011. + unsigned int u;
  19012. +
  19013. + head = kmalloc(sizeof(*nhash->nh_head) * num_hash, gfp);
  19014. + if (head) {
  19015. + nhash->nh_num = num_hash;
  19016. + nhash->nh_head = head;
  19017. + for (u = 0; u < num_hash; u++)
  19018. + INIT_HLIST_HEAD(head++);
  19019. + return 0; /* success */
  19020. + }
  19021. +
  19022. + return -ENOMEM;
  19023. +}
  19024. +
  19025. +static void nhash_count(struct hlist_head *head)
  19026. +{
  19027. +#if 0
  19028. + unsigned long n;
  19029. + struct hlist_node *pos;
  19030. +
  19031. + n = 0;
  19032. + hlist_for_each(pos, head)
  19033. + n++;
  19034. + AuInfo("%lu\n", n);
  19035. +#endif
  19036. +}
  19037. +
  19038. +static void au_nhash_wh_do_free(struct hlist_head *head)
  19039. +{
  19040. + struct au_vdir_wh *tpos;
  19041. + struct hlist_node *pos, *node;
  19042. +
  19043. + hlist_for_each_entry_safe(tpos, pos, node, head, wh_hash) {
  19044. + /* hlist_del(pos); */
  19045. + kfree(tpos);
  19046. + }
  19047. +}
  19048. +
  19049. +static void au_nhash_de_do_free(struct hlist_head *head)
  19050. +{
  19051. + struct au_vdir_dehstr *tpos;
  19052. + struct hlist_node *pos, *node;
  19053. +
  19054. + hlist_for_each_entry_safe(tpos, pos, node, head, hash) {
  19055. + /* hlist_del(pos); */
  19056. + au_cache_free_dehstr(tpos);
  19057. + }
  19058. +}
  19059. +
  19060. +static void au_nhash_do_free(struct au_nhash *nhash,
  19061. + void (*free)(struct hlist_head *head))
  19062. +{
  19063. + unsigned int u, n;
  19064. + struct hlist_head *head;
  19065. +
  19066. + n = nhash->nh_num;
  19067. + head = nhash->nh_head;
  19068. + for (u = 0; u < n; u++) {
  19069. + nhash_count(head);
  19070. + free(head++);
  19071. + }
  19072. + kfree(nhash->nh_head);
  19073. +}
  19074. +
  19075. +void au_nhash_wh_free(struct au_nhash *whlist)
  19076. +{
  19077. + au_nhash_do_free(whlist, au_nhash_wh_do_free);
  19078. +}
  19079. +
  19080. +static void au_nhash_de_free(struct au_nhash *delist)
  19081. +{
  19082. + au_nhash_do_free(delist, au_nhash_de_do_free);
  19083. +}
  19084. +
  19085. +/* ---------------------------------------------------------------------- */
  19086. +
  19087. +int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
  19088. + int limit)
  19089. +{
  19090. + int num;
  19091. + unsigned int u, n;
  19092. + struct hlist_head *head;
  19093. + struct au_vdir_wh *tpos;
  19094. + struct hlist_node *pos;
  19095. +
  19096. + num = 0;
  19097. + n = whlist->nh_num;
  19098. + head = whlist->nh_head;
  19099. + for (u = 0; u < n; u++) {
  19100. + hlist_for_each_entry(tpos, pos, head, wh_hash)
  19101. + if (tpos->wh_bindex == btgt && ++num > limit)
  19102. + return 1;
  19103. + head++;
  19104. + }
  19105. + return 0;
  19106. +}
  19107. +
  19108. +static struct hlist_head *au_name_hash(struct au_nhash *nhash,
  19109. + unsigned char *name,
  19110. + unsigned int len)
  19111. +{
  19112. + unsigned int v;
  19113. + /* const unsigned int magic_bit = 12; */
  19114. +
  19115. + v = 0;
  19116. + while (len--)
  19117. + v += *name++;
  19118. + /* v = hash_long(v, magic_bit); */
  19119. + v %= nhash->nh_num;
  19120. + return nhash->nh_head + v;
  19121. +}
  19122. +
  19123. +static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
  19124. + int nlen)
  19125. +{
  19126. + return str->len == nlen && !memcmp(str->name, name, nlen);
  19127. +}
  19128. +
  19129. +/* returns found or not */
  19130. +int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
  19131. +{
  19132. + struct hlist_head *head;
  19133. + struct au_vdir_wh *tpos;
  19134. + struct hlist_node *pos;
  19135. + struct au_vdir_destr *str;
  19136. +
  19137. + head = au_name_hash(whlist, name, nlen);
  19138. + hlist_for_each_entry(tpos, pos, head, wh_hash) {
  19139. + str = &tpos->wh_str;
  19140. + AuDbg("%.*s\n", str->len, str->name);
  19141. + if (au_nhash_test_name(str, name, nlen))
  19142. + return 1;
  19143. + }
  19144. + return 0;
  19145. +}
  19146. +
  19147. +/* returns found(true) or not */
  19148. +static int test_known(struct au_nhash *delist, char *name, int nlen)
  19149. +{
  19150. + struct hlist_head *head;
  19151. + struct au_vdir_dehstr *tpos;
  19152. + struct hlist_node *pos;
  19153. + struct au_vdir_destr *str;
  19154. +
  19155. + head = au_name_hash(delist, name, nlen);
  19156. + hlist_for_each_entry(tpos, pos, head, hash) {
  19157. + str = tpos->str;
  19158. + AuDbg("%.*s\n", str->len, str->name);
  19159. + if (au_nhash_test_name(str, name, nlen))
  19160. + return 1;
  19161. + }
  19162. + return 0;
  19163. +}
  19164. +
  19165. +static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
  19166. + unsigned char d_type)
  19167. +{
  19168. +#ifdef CONFIG_AUFS_SHWH
  19169. + wh->wh_ino = ino;
  19170. + wh->wh_type = d_type;
  19171. +#endif
  19172. +}
  19173. +
  19174. +/* ---------------------------------------------------------------------- */
  19175. +
  19176. +int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
  19177. + unsigned int d_type, aufs_bindex_t bindex,
  19178. + unsigned char shwh)
  19179. +{
  19180. + int err;
  19181. + struct au_vdir_destr *str;
  19182. + struct au_vdir_wh *wh;
  19183. +
  19184. + AuDbg("%.*s\n", nlen, name);
  19185. + err = -ENOMEM;
  19186. + wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
  19187. + if (unlikely(!wh))
  19188. + goto out;
  19189. +
  19190. + err = 0;
  19191. + wh->wh_bindex = bindex;
  19192. + if (shwh)
  19193. + au_shwh_init_wh(wh, ino, d_type);
  19194. + str = &wh->wh_str;
  19195. + str->len = nlen;
  19196. + memcpy(str->name, name, nlen);
  19197. + hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
  19198. + /* smp_mb(); */
  19199. +
  19200. + out:
  19201. + return err;
  19202. +}
  19203. +
  19204. +static int append_deblk(struct au_vdir *vdir)
  19205. +{
  19206. + int err;
  19207. + unsigned long ul;
  19208. + const unsigned int deblk_sz = vdir->vd_deblk_sz;
  19209. + union au_vdir_deblk_p p, deblk_end;
  19210. + unsigned char **o;
  19211. +
  19212. + err = -ENOMEM;
  19213. + o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
  19214. + GFP_NOFS);
  19215. + if (unlikely(!o))
  19216. + goto out;
  19217. +
  19218. + vdir->vd_deblk = o;
  19219. + p.deblk = kmalloc(deblk_sz, GFP_NOFS);
  19220. + if (p.deblk) {
  19221. + ul = vdir->vd_nblk++;
  19222. + vdir->vd_deblk[ul] = p.deblk;
  19223. + vdir->vd_last.ul = ul;
  19224. + vdir->vd_last.p.deblk = p.deblk;
  19225. + deblk_end.deblk = p.deblk + deblk_sz;
  19226. + err = set_deblk_end(&p, &deblk_end);
  19227. + }
  19228. +
  19229. + out:
  19230. + return err;
  19231. +}
  19232. +
  19233. +static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
  19234. + unsigned int d_type, struct au_nhash *delist)
  19235. +{
  19236. + int err;
  19237. + unsigned int sz;
  19238. + const unsigned int deblk_sz = vdir->vd_deblk_sz;
  19239. + union au_vdir_deblk_p p, *room, deblk_end;
  19240. + struct au_vdir_dehstr *dehstr;
  19241. +
  19242. + p.deblk = last_deblk(vdir);
  19243. + deblk_end.deblk = p.deblk + deblk_sz;
  19244. + room = &vdir->vd_last.p;
  19245. + AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
  19246. + || !is_deblk_end(room, &deblk_end));
  19247. +
  19248. + sz = calc_size(nlen);
  19249. + if (unlikely(sz > deblk_end.deblk - room->deblk)) {
  19250. + err = append_deblk(vdir);
  19251. + if (unlikely(err))
  19252. + goto out;
  19253. +
  19254. + p.deblk = last_deblk(vdir);
  19255. + deblk_end.deblk = p.deblk + deblk_sz;
  19256. + /* smp_mb(); */
  19257. + AuDebugOn(room->deblk != p.deblk);
  19258. + }
  19259. +
  19260. + err = -ENOMEM;
  19261. + dehstr = au_cache_alloc_dehstr();
  19262. + if (unlikely(!dehstr))
  19263. + goto out;
  19264. +
  19265. + dehstr->str = &room->de->de_str;
  19266. + hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
  19267. + room->de->de_ino = ino;
  19268. + room->de->de_type = d_type;
  19269. + room->de->de_str.len = nlen;
  19270. + memcpy(room->de->de_str.name, name, nlen);
  19271. +
  19272. + err = 0;
  19273. + room->deblk += sz;
  19274. + if (unlikely(set_deblk_end(room, &deblk_end)))
  19275. + err = append_deblk(vdir);
  19276. + /* smp_mb(); */
  19277. +
  19278. + out:
  19279. + return err;
  19280. +}
  19281. +
  19282. +/* ---------------------------------------------------------------------- */
  19283. +
  19284. +void au_vdir_free(struct au_vdir *vdir)
  19285. +{
  19286. + unsigned char **deblk;
  19287. +
  19288. + deblk = vdir->vd_deblk;
  19289. + while (vdir->vd_nblk--)
  19290. + kfree(*deblk++);
  19291. + kfree(vdir->vd_deblk);
  19292. + au_cache_free_vdir(vdir);
  19293. +}
  19294. +
  19295. +static struct au_vdir *alloc_vdir(struct super_block *sb)
  19296. +{
  19297. + struct au_vdir *vdir;
  19298. + int err;
  19299. +
  19300. + SiMustAnyLock(sb);
  19301. +
  19302. + err = -ENOMEM;
  19303. + vdir = au_cache_alloc_vdir();
  19304. + if (unlikely(!vdir))
  19305. + goto out;
  19306. +
  19307. + vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
  19308. + if (unlikely(!vdir->vd_deblk))
  19309. + goto out_free;
  19310. +
  19311. + vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
  19312. + vdir->vd_nblk = 0;
  19313. + vdir->vd_version = 0;
  19314. + vdir->vd_jiffy = 0;
  19315. + err = append_deblk(vdir);
  19316. + if (!err)
  19317. + return vdir; /* success */
  19318. +
  19319. + kfree(vdir->vd_deblk);
  19320. +
  19321. + out_free:
  19322. + au_cache_free_vdir(vdir);
  19323. + out:
  19324. + vdir = ERR_PTR(err);
  19325. + return vdir;
  19326. +}
  19327. +
  19328. +static int reinit_vdir(struct au_vdir *vdir)
  19329. +{
  19330. + int err;
  19331. + union au_vdir_deblk_p p, deblk_end;
  19332. +
  19333. + while (vdir->vd_nblk > 1) {
  19334. + kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
  19335. + /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
  19336. + vdir->vd_nblk--;
  19337. + }
  19338. + p.deblk = vdir->vd_deblk[0];
  19339. + deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
  19340. + err = set_deblk_end(&p, &deblk_end);
  19341. + /* keep vd_dblk_sz */
  19342. + vdir->vd_last.ul = 0;
  19343. + vdir->vd_last.p.deblk = vdir->vd_deblk[0];
  19344. + vdir->vd_version = 0;
  19345. + vdir->vd_jiffy = 0;
  19346. + /* smp_mb(); */
  19347. + return err;
  19348. +}
  19349. +
  19350. +/* ---------------------------------------------------------------------- */
  19351. +
  19352. +static int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  19353. + unsigned int d_type, ino_t *ino)
  19354. +{
  19355. + int err;
  19356. + struct mutex *mtx;
  19357. + const int isdir = (d_type == DT_DIR);
  19358. +
  19359. + /* prevent hardlinks from race condition */
  19360. + mtx = NULL;
  19361. + if (!isdir) {
  19362. + mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx;
  19363. + mutex_lock(mtx);
  19364. + }
  19365. + err = au_xino_read(sb, bindex, h_ino, ino);
  19366. + if (unlikely(err))
  19367. + goto out;
  19368. +
  19369. + if (!*ino) {
  19370. + err = -EIO;
  19371. + *ino = au_xino_new_ino(sb);
  19372. + if (unlikely(!*ino))
  19373. + goto out;
  19374. + err = au_xino_write(sb, bindex, h_ino, *ino);
  19375. + if (unlikely(err))
  19376. + goto out;
  19377. + }
  19378. +
  19379. + out:
  19380. + if (!isdir)
  19381. + mutex_unlock(mtx);
  19382. + return err;
  19383. +}
  19384. +
  19385. +static int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  19386. + unsigned int d_type, ino_t *ino)
  19387. +{
  19388. +#ifdef CONFIG_AUFS_SHWH
  19389. + return au_ino(sb, bindex, h_ino, d_type, ino);
  19390. +#else
  19391. + return 0;
  19392. +#endif
  19393. +}
  19394. +
  19395. +#define AuFillVdir_CALLED 1
  19396. +#define AuFillVdir_WHABLE (1 << 1)
  19397. +#define AuFillVdir_SHWH (1 << 2)
  19398. +#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
  19399. +#define au_fset_fillvdir(flags, name) { (flags) |= AuFillVdir_##name; }
  19400. +#define au_fclr_fillvdir(flags, name) { (flags) &= ~AuFillVdir_##name; }
  19401. +
  19402. +#ifndef CONFIG_AUFS_SHWH
  19403. +#undef AuFillVdir_SHWH
  19404. +#define AuFillVdir_SHWH 0
  19405. +#endif
  19406. +
  19407. +struct fillvdir_arg {
  19408. + struct file *file;
  19409. + struct au_vdir *vdir;
  19410. + struct au_nhash delist;
  19411. + struct au_nhash whlist;
  19412. + aufs_bindex_t bindex;
  19413. + unsigned int flags;
  19414. + int err;
  19415. +};
  19416. +
  19417. +static int fillvdir(void *__arg, const char *__name, int nlen,
  19418. + loff_t offset __maybe_unused, u64 h_ino,
  19419. + unsigned int d_type)
  19420. +{
  19421. + struct fillvdir_arg *arg = __arg;
  19422. + char *name = (void *)__name;
  19423. + struct super_block *sb;
  19424. + ino_t ino;
  19425. + const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
  19426. +
  19427. + arg->err = 0;
  19428. + sb = arg->file->f_dentry->d_sb;
  19429. + au_fset_fillvdir(arg->flags, CALLED);
  19430. + /* smp_mb(); */
  19431. + if (nlen <= AUFS_WH_PFX_LEN
  19432. + || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
  19433. + if (test_known(&arg->delist, name, nlen)
  19434. + || au_nhash_test_known_wh(&arg->whlist, name, nlen))
  19435. + goto out; /* already exists or whiteouted */
  19436. +
  19437. + sb = arg->file->f_dentry->d_sb;
  19438. + arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
  19439. + if (!arg->err)
  19440. + arg->err = append_de(arg->vdir, name, nlen, ino,
  19441. + d_type, &arg->delist);
  19442. + } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
  19443. + name += AUFS_WH_PFX_LEN;
  19444. + nlen -= AUFS_WH_PFX_LEN;
  19445. + if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
  19446. + goto out; /* already whiteouted */
  19447. +
  19448. + if (shwh)
  19449. + arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
  19450. + &ino);
  19451. + if (!arg->err)
  19452. + arg->err = au_nhash_append_wh
  19453. + (&arg->whlist, name, nlen, ino, d_type,
  19454. + arg->bindex, shwh);
  19455. + }
  19456. +
  19457. + out:
  19458. + if (!arg->err)
  19459. + arg->vdir->vd_jiffy = jiffies;
  19460. + /* smp_mb(); */
  19461. + AuTraceErr(arg->err);
  19462. + return arg->err;
  19463. +}
  19464. +
  19465. +static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
  19466. + struct au_nhash *whlist, struct au_nhash *delist)
  19467. +{
  19468. +#ifdef CONFIG_AUFS_SHWH
  19469. + int err;
  19470. + unsigned int nh, u;
  19471. + struct hlist_head *head;
  19472. + struct au_vdir_wh *tpos;
  19473. + struct hlist_node *pos, *n;
  19474. + char *p, *o;
  19475. + struct au_vdir_destr *destr;
  19476. +
  19477. + AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
  19478. +
  19479. + err = -ENOMEM;
  19480. + o = p = __getname();
  19481. + if (unlikely(!p))
  19482. + goto out;
  19483. +
  19484. + err = 0;
  19485. + nh = whlist->nh_num;
  19486. + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
  19487. + p += AUFS_WH_PFX_LEN;
  19488. + for (u = 0; u < nh; u++) {
  19489. + head = whlist->nh_head + u;
  19490. + hlist_for_each_entry_safe(tpos, pos, n, head, wh_hash) {
  19491. + destr = &tpos->wh_str;
  19492. + memcpy(p, destr->name, destr->len);
  19493. + err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
  19494. + tpos->wh_ino, tpos->wh_type, delist);
  19495. + if (unlikely(err))
  19496. + break;
  19497. + }
  19498. + }
  19499. +
  19500. + __putname(o);
  19501. +
  19502. + out:
  19503. + AuTraceErr(err);
  19504. + return err;
  19505. +#else
  19506. + return 0;
  19507. +#endif
  19508. +}
  19509. +
  19510. +static int au_do_read_vdir(struct fillvdir_arg *arg)
  19511. +{
  19512. + int err;
  19513. + unsigned int rdhash;
  19514. + loff_t offset;
  19515. + aufs_bindex_t bend, bindex, bstart;
  19516. + unsigned char shwh;
  19517. + struct file *hf, *file;
  19518. + struct super_block *sb;
  19519. +
  19520. + file = arg->file;
  19521. + sb = file->f_dentry->d_sb;
  19522. + SiMustAnyLock(sb);
  19523. +
  19524. + rdhash = au_sbi(sb)->si_rdhash;
  19525. + err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
  19526. + if (unlikely(err))
  19527. + goto out;
  19528. + err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
  19529. + if (unlikely(err))
  19530. + goto out_delist;
  19531. +
  19532. + err = 0;
  19533. + arg->flags = 0;
  19534. + shwh = 0;
  19535. + if (au_opt_test(au_mntflags(sb), SHWH)) {
  19536. + shwh = 1;
  19537. + au_fset_fillvdir(arg->flags, SHWH);
  19538. + }
  19539. + bstart = au_fbstart(file);
  19540. + bend = au_fbend(file);
  19541. + for (bindex = bstart; !err && bindex <= bend; bindex++) {
  19542. + hf = au_h_fptr(file, bindex);
  19543. + if (!hf)
  19544. + continue;
  19545. +
  19546. + offset = vfsub_llseek(hf, 0, SEEK_SET);
  19547. + err = offset;
  19548. + if (unlikely(offset))
  19549. + break;
  19550. +
  19551. + arg->bindex = bindex;
  19552. + au_fclr_fillvdir(arg->flags, WHABLE);
  19553. + if (shwh
  19554. + || (bindex != bend
  19555. + && au_br_whable(au_sbr_perm(sb, bindex))))
  19556. + au_fset_fillvdir(arg->flags, WHABLE);
  19557. + do {
  19558. + arg->err = 0;
  19559. + au_fclr_fillvdir(arg->flags, CALLED);
  19560. + /* smp_mb(); */
  19561. + err = vfsub_readdir(hf, fillvdir, arg);
  19562. + if (err >= 0)
  19563. + err = arg->err;
  19564. + } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
  19565. + }
  19566. +
  19567. + if (!err && shwh)
  19568. + err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
  19569. +
  19570. + au_nhash_wh_free(&arg->whlist);
  19571. +
  19572. + out_delist:
  19573. + au_nhash_de_free(&arg->delist);
  19574. + out:
  19575. + return err;
  19576. +}
  19577. +
  19578. +static int read_vdir(struct file *file, int may_read)
  19579. +{
  19580. + int err;
  19581. + unsigned long expire;
  19582. + unsigned char do_read;
  19583. + struct fillvdir_arg arg;
  19584. + struct inode *inode;
  19585. + struct au_vdir *vdir, *allocated;
  19586. +
  19587. + err = 0;
  19588. + inode = file->f_dentry->d_inode;
  19589. + IMustLock(inode);
  19590. + SiMustAnyLock(inode->i_sb);
  19591. +
  19592. + allocated = NULL;
  19593. + do_read = 0;
  19594. + expire = au_sbi(inode->i_sb)->si_rdcache;
  19595. + vdir = au_ivdir(inode);
  19596. + if (!vdir) {
  19597. + do_read = 1;
  19598. + vdir = alloc_vdir(inode->i_sb);
  19599. + err = PTR_ERR(vdir);
  19600. + if (IS_ERR(vdir))
  19601. + goto out;
  19602. + err = 0;
  19603. + allocated = vdir;
  19604. + } else if (may_read
  19605. + && (inode->i_version != vdir->vd_version
  19606. + || time_after(jiffies, vdir->vd_jiffy + expire))) {
  19607. + do_read = 1;
  19608. + err = reinit_vdir(vdir);
  19609. + if (unlikely(err))
  19610. + goto out;
  19611. + }
  19612. +
  19613. + if (!do_read)
  19614. + return 0; /* success */
  19615. +
  19616. + arg.file = file;
  19617. + arg.vdir = vdir;
  19618. + err = au_do_read_vdir(&arg);
  19619. + if (!err) {
  19620. + /* file->f_pos = 0; */
  19621. + vdir->vd_version = inode->i_version;
  19622. + vdir->vd_last.ul = 0;
  19623. + vdir->vd_last.p.deblk = vdir->vd_deblk[0];
  19624. + if (allocated)
  19625. + au_set_ivdir(inode, allocated);
  19626. + } else if (allocated)
  19627. + au_vdir_free(allocated);
  19628. +
  19629. + out:
  19630. + return err;
  19631. +}
  19632. +
  19633. +static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
  19634. +{
  19635. + int err, rerr;
  19636. + unsigned long ul, n;
  19637. + const unsigned int deblk_sz = src->vd_deblk_sz;
  19638. +
  19639. + AuDebugOn(tgt->vd_nblk != 1);
  19640. +
  19641. + err = -ENOMEM;
  19642. + if (tgt->vd_nblk < src->vd_nblk) {
  19643. + unsigned char **p;
  19644. +
  19645. + p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
  19646. + GFP_NOFS);
  19647. + if (unlikely(!p))
  19648. + goto out;
  19649. + tgt->vd_deblk = p;
  19650. + }
  19651. +
  19652. + tgt->vd_nblk = src->vd_nblk;
  19653. + tgt->vd_deblk_sz = deblk_sz;
  19654. + memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
  19655. + /* tgt->vd_last.i = 0; */
  19656. + /* tgt->vd_last.p.deblk = tgt->vd_deblk[0]; */
  19657. + tgt->vd_version = src->vd_version;
  19658. + tgt->vd_jiffy = src->vd_jiffy;
  19659. +
  19660. + n = src->vd_nblk;
  19661. + for (ul = 1; ul < n; ul++) {
  19662. + tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
  19663. + GFP_NOFS);
  19664. + if (unlikely(!tgt->vd_deblk[ul]))
  19665. + goto out;
  19666. + }
  19667. + /* smp_mb(); */
  19668. + return 0; /* success */
  19669. +
  19670. + out:
  19671. + rerr = reinit_vdir(tgt);
  19672. + BUG_ON(rerr);
  19673. + return err;
  19674. +}
  19675. +
  19676. +int au_vdir_init(struct file *file)
  19677. +{
  19678. + int err;
  19679. + struct inode *inode;
  19680. + struct au_vdir *vdir_cache, *allocated;
  19681. +
  19682. + err = read_vdir(file, !file->f_pos);
  19683. + if (unlikely(err))
  19684. + goto out;
  19685. +
  19686. + allocated = NULL;
  19687. + vdir_cache = au_fvdir_cache(file);
  19688. + if (!vdir_cache) {
  19689. + vdir_cache = alloc_vdir(file->f_dentry->d_sb);
  19690. + err = PTR_ERR(vdir_cache);
  19691. + if (IS_ERR(vdir_cache))
  19692. + goto out;
  19693. + allocated = vdir_cache;
  19694. + } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
  19695. + err = reinit_vdir(vdir_cache);
  19696. + if (unlikely(err))
  19697. + goto out;
  19698. + } else
  19699. + return 0; /* success */
  19700. +
  19701. + inode = file->f_dentry->d_inode;
  19702. + err = copy_vdir(vdir_cache, au_ivdir(inode));
  19703. + if (!err) {
  19704. + file->f_version = inode->i_version;
  19705. + if (allocated)
  19706. + au_set_fvdir_cache(file, allocated);
  19707. + } else if (allocated)
  19708. + au_vdir_free(allocated);
  19709. +
  19710. + out:
  19711. + return err;
  19712. +}
  19713. +
  19714. +static loff_t calc_offset(struct au_vdir *vdir)
  19715. +{
  19716. + loff_t offset;
  19717. + union au_vdir_deblk_p p;
  19718. +
  19719. + p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
  19720. + offset = vdir->vd_last.p.deblk - p.deblk;
  19721. + offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
  19722. + return offset;
  19723. +}
  19724. +
  19725. +/* returns true or false */
  19726. +static int seek_vdir(struct file *file)
  19727. +{
  19728. + int valid;
  19729. + unsigned int deblk_sz;
  19730. + unsigned long ul, n;
  19731. + loff_t offset;
  19732. + union au_vdir_deblk_p p, deblk_end;
  19733. + struct au_vdir *vdir_cache;
  19734. +
  19735. + valid = 1;
  19736. + vdir_cache = au_fvdir_cache(file);
  19737. + offset = calc_offset(vdir_cache);
  19738. + AuDbg("offset %lld\n", offset);
  19739. + if (file->f_pos == offset)
  19740. + goto out;
  19741. +
  19742. + vdir_cache->vd_last.ul = 0;
  19743. + vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
  19744. + if (!file->f_pos)
  19745. + goto out;
  19746. +
  19747. + valid = 0;
  19748. + deblk_sz = vdir_cache->vd_deblk_sz;
  19749. + ul = div64_u64(file->f_pos, deblk_sz);
  19750. + AuDbg("ul %lu\n", ul);
  19751. + if (ul >= vdir_cache->vd_nblk)
  19752. + goto out;
  19753. +
  19754. + n = vdir_cache->vd_nblk;
  19755. + for (; ul < n; ul++) {
  19756. + p.deblk = vdir_cache->vd_deblk[ul];
  19757. + deblk_end.deblk = p.deblk + deblk_sz;
  19758. + offset = ul;
  19759. + offset *= deblk_sz;
  19760. + while (!is_deblk_end(&p, &deblk_end) && offset < file->f_pos) {
  19761. + unsigned int l;
  19762. +
  19763. + l = calc_size(p.de->de_str.len);
  19764. + offset += l;
  19765. + p.deblk += l;
  19766. + }
  19767. + if (!is_deblk_end(&p, &deblk_end)) {
  19768. + valid = 1;
  19769. + vdir_cache->vd_last.ul = ul;
  19770. + vdir_cache->vd_last.p = p;
  19771. + break;
  19772. + }
  19773. + }
  19774. +
  19775. + out:
  19776. + /* smp_mb(); */
  19777. + AuTraceErr(!valid);
  19778. + return valid;
  19779. +}
  19780. +
  19781. +int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir)
  19782. +{
  19783. + int err;
  19784. + unsigned int l, deblk_sz;
  19785. + union au_vdir_deblk_p deblk_end;
  19786. + struct au_vdir *vdir_cache;
  19787. + struct au_vdir_de *de;
  19788. +
  19789. + vdir_cache = au_fvdir_cache(file);
  19790. + if (!seek_vdir(file))
  19791. + return 0;
  19792. +
  19793. + deblk_sz = vdir_cache->vd_deblk_sz;
  19794. + while (1) {
  19795. + deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
  19796. + deblk_end.deblk += deblk_sz;
  19797. + while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
  19798. + de = vdir_cache->vd_last.p.de;
  19799. + AuDbg("%.*s, off%lld, i%lu, dt%d\n",
  19800. + de->de_str.len, de->de_str.name, file->f_pos,
  19801. + (unsigned long)de->de_ino, de->de_type);
  19802. + err = filldir(dirent, de->de_str.name, de->de_str.len,
  19803. + file->f_pos, de->de_ino, de->de_type);
  19804. + if (unlikely(err)) {
  19805. + AuTraceErr(err);
  19806. + /* todo: ignore the error caused by udba? */
  19807. + /* return err; */
  19808. + return 0;
  19809. + }
  19810. +
  19811. + l = calc_size(de->de_str.len);
  19812. + vdir_cache->vd_last.p.deblk += l;
  19813. + file->f_pos += l;
  19814. + }
  19815. + if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
  19816. + vdir_cache->vd_last.ul++;
  19817. + vdir_cache->vd_last.p.deblk
  19818. + = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
  19819. + file->f_pos = deblk_sz * vdir_cache->vd_last.ul;
  19820. + continue;
  19821. + }
  19822. + break;
  19823. + }
  19824. +
  19825. + /* smp_mb(); */
  19826. + return 0;
  19827. +}
  19828. diff -Nur linux-2.6.34.orig/fs/aufs/vfsub.c linux-2.6.34/fs/aufs/vfsub.c
  19829. --- linux-2.6.34.orig/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100
  19830. +++ linux-2.6.34/fs/aufs/vfsub.c 2010-05-23 23:33:21.621650481 +0200
  19831. @@ -0,0 +1,740 @@
  19832. +/*
  19833. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  19834. + *
  19835. + * This program, aufs is free software; you can redistribute it and/or modify
  19836. + * it under the terms of the GNU General Public License as published by
  19837. + * the Free Software Foundation; either version 2 of the License, or
  19838. + * (at your option) any later version.
  19839. + *
  19840. + * This program is distributed in the hope that it will be useful,
  19841. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19842. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19843. + * GNU General Public License for more details.
  19844. + *
  19845. + * You should have received a copy of the GNU General Public License
  19846. + * along with this program; if not, write to the Free Software
  19847. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  19848. + */
  19849. +
  19850. +/*
  19851. + * sub-routines for VFS
  19852. + */
  19853. +
  19854. +#include <linux/namei.h>
  19855. +#include <linux/security.h>
  19856. +#include <linux/splice.h>
  19857. +#include <linux/uaccess.h>
  19858. +#include "aufs.h"
  19859. +
  19860. +int vfsub_update_h_iattr(struct path *h_path, int *did)
  19861. +{
  19862. + int err;
  19863. + struct kstat st;
  19864. + struct super_block *h_sb;
  19865. +
  19866. + /* for remote fs, leave work for its getattr or d_revalidate */
  19867. + /* for bad i_attr fs, handle them in aufs_getattr() */
  19868. + /* still some fs may acquire i_mutex. we need to skip them */
  19869. + err = 0;
  19870. + if (!did)
  19871. + did = &err;
  19872. + h_sb = h_path->dentry->d_sb;
  19873. + *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
  19874. + if (*did)
  19875. + err = vfs_getattr(h_path->mnt, h_path->dentry, &st);
  19876. +
  19877. + return err;
  19878. +}
  19879. +
  19880. +/* ---------------------------------------------------------------------- */
  19881. +
  19882. +#ifdef CONFIG_IMA
  19883. +#error IMA is not supported since it does not work well. Wait for their fixing.
  19884. +#endif
  19885. +
  19886. +struct file *vfsub_filp_open(const char *path, int oflags, int mode)
  19887. +{
  19888. + struct file *file;
  19889. +
  19890. + lockdep_off();
  19891. + file = filp_open(path, oflags, mode);
  19892. + lockdep_on();
  19893. + if (IS_ERR(file))
  19894. + goto out;
  19895. + vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
  19896. +
  19897. + out:
  19898. + return file;
  19899. +}
  19900. +
  19901. +int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
  19902. +{
  19903. + int err;
  19904. +
  19905. + /* lockdep_off(); */
  19906. + err = kern_path(name, flags, path);
  19907. + /* lockdep_on(); */
  19908. + if (!err && path->dentry->d_inode)
  19909. + vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
  19910. + return err;
  19911. +}
  19912. +
  19913. +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
  19914. + int len)
  19915. +{
  19916. + struct path path = {
  19917. + .mnt = NULL
  19918. + };
  19919. +
  19920. + IMustLock(parent->d_inode);
  19921. +
  19922. + path.dentry = lookup_one_len(name, parent, len);
  19923. + if (IS_ERR(path.dentry))
  19924. + goto out;
  19925. + if (path.dentry->d_inode)
  19926. + vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
  19927. +
  19928. + out:
  19929. + return path.dentry;
  19930. +}
  19931. +
  19932. +struct dentry *vfsub_lookup_hash(struct nameidata *nd)
  19933. +{
  19934. + struct path path = {
  19935. + .mnt = nd->path.mnt
  19936. + };
  19937. +
  19938. + IMustLock(nd->path.dentry->d_inode);
  19939. +
  19940. + path.dentry = lookup_hash(nd);
  19941. + if (!IS_ERR(path.dentry) && path.dentry->d_inode)
  19942. + vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
  19943. +
  19944. + return path.dentry;
  19945. +}
  19946. +
  19947. +/* ---------------------------------------------------------------------- */
  19948. +
  19949. +struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
  19950. + struct dentry *d2, struct au_hinode *hdir2)
  19951. +{
  19952. + struct dentry *d;
  19953. +
  19954. + lockdep_off();
  19955. + d = lock_rename(d1, d2);
  19956. + lockdep_on();
  19957. + au_hin_suspend(hdir1);
  19958. + if (hdir1 != hdir2)
  19959. + au_hin_suspend(hdir2);
  19960. +
  19961. + return d;
  19962. +}
  19963. +
  19964. +void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
  19965. + struct dentry *d2, struct au_hinode *hdir2)
  19966. +{
  19967. + au_hin_resume(hdir1);
  19968. + if (hdir1 != hdir2)
  19969. + au_hin_resume(hdir2);
  19970. + lockdep_off();
  19971. + unlock_rename(d1, d2);
  19972. + lockdep_on();
  19973. +}
  19974. +
  19975. +/* ---------------------------------------------------------------------- */
  19976. +
  19977. +int vfsub_create(struct inode *dir, struct path *path, int mode)
  19978. +{
  19979. + int err;
  19980. + struct dentry *d;
  19981. +
  19982. + IMustLock(dir);
  19983. +
  19984. + d = path->dentry;
  19985. + path->dentry = d->d_parent;
  19986. + err = security_path_mknod(path, path->dentry, mode, 0);
  19987. + path->dentry = d;
  19988. + if (unlikely(err))
  19989. + goto out;
  19990. +
  19991. + if (au_test_fs_null_nd(dir->i_sb))
  19992. + err = vfs_create(dir, path->dentry, mode, NULL);
  19993. + else {
  19994. + struct nameidata h_nd;
  19995. +
  19996. + memset(&h_nd, 0, sizeof(h_nd));
  19997. + h_nd.flags = LOOKUP_CREATE;
  19998. + h_nd.intent.open.flags = O_CREAT
  19999. + | vfsub_fmode_to_uint(FMODE_READ);
  20000. + h_nd.intent.open.create_mode = mode;
  20001. + h_nd.path.dentry = path->dentry->d_parent;
  20002. + h_nd.path.mnt = path->mnt;
  20003. + path_get(&h_nd.path);
  20004. + err = vfs_create(dir, path->dentry, mode, &h_nd);
  20005. + path_put(&h_nd.path);
  20006. + }
  20007. +
  20008. + if (!err) {
  20009. + struct path tmp = *path;
  20010. + int did;
  20011. +
  20012. + vfsub_update_h_iattr(&tmp, &did);
  20013. + if (did) {
  20014. + tmp.dentry = path->dentry->d_parent;
  20015. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20016. + }
  20017. + /*ignore*/
  20018. + }
  20019. +
  20020. + out:
  20021. + return err;
  20022. +}
  20023. +
  20024. +int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
  20025. +{
  20026. + int err;
  20027. + struct dentry *d;
  20028. +
  20029. + IMustLock(dir);
  20030. +
  20031. + d = path->dentry;
  20032. + path->dentry = d->d_parent;
  20033. + err = security_path_symlink(path, path->dentry, symname);
  20034. + path->dentry = d;
  20035. + if (unlikely(err))
  20036. + goto out;
  20037. +
  20038. + err = vfs_symlink(dir, path->dentry, symname);
  20039. + if (!err) {
  20040. + struct path tmp = *path;
  20041. + int did;
  20042. +
  20043. + vfsub_update_h_iattr(&tmp, &did);
  20044. + if (did) {
  20045. + tmp.dentry = path->dentry->d_parent;
  20046. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20047. + }
  20048. + /*ignore*/
  20049. + }
  20050. +
  20051. + out:
  20052. + return err;
  20053. +}
  20054. +
  20055. +int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
  20056. +{
  20057. + int err;
  20058. + struct dentry *d;
  20059. +
  20060. + IMustLock(dir);
  20061. +
  20062. + d = path->dentry;
  20063. + path->dentry = d->d_parent;
  20064. + err = security_path_mknod(path, path->dentry, mode, dev);
  20065. + path->dentry = d;
  20066. + if (unlikely(err))
  20067. + goto out;
  20068. +
  20069. + err = vfs_mknod(dir, path->dentry, mode, dev);
  20070. + if (!err) {
  20071. + struct path tmp = *path;
  20072. + int did;
  20073. +
  20074. + vfsub_update_h_iattr(&tmp, &did);
  20075. + if (did) {
  20076. + tmp.dentry = path->dentry->d_parent;
  20077. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20078. + }
  20079. + /*ignore*/
  20080. + }
  20081. +
  20082. + out:
  20083. + return err;
  20084. +}
  20085. +
  20086. +static int au_test_nlink(struct inode *inode)
  20087. +{
  20088. + const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
  20089. +
  20090. + if (!au_test_fs_no_limit_nlink(inode->i_sb)
  20091. + || inode->i_nlink < link_max)
  20092. + return 0;
  20093. + return -EMLINK;
  20094. +}
  20095. +
  20096. +int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path)
  20097. +{
  20098. + int err;
  20099. + struct dentry *d;
  20100. +
  20101. + IMustLock(dir);
  20102. +
  20103. + err = au_test_nlink(src_dentry->d_inode);
  20104. + if (unlikely(err))
  20105. + return err;
  20106. +
  20107. + d = path->dentry;
  20108. + path->dentry = d->d_parent;
  20109. + err = security_path_link(src_dentry, path, path->dentry);
  20110. + path->dentry = d;
  20111. + if (unlikely(err))
  20112. + goto out;
  20113. +
  20114. + lockdep_off();
  20115. + err = vfs_link(src_dentry, dir, path->dentry);
  20116. + lockdep_on();
  20117. + if (!err) {
  20118. + struct path tmp = *path;
  20119. + int did;
  20120. +
  20121. + /* fuse has different memory inode for the same inumber */
  20122. + vfsub_update_h_iattr(&tmp, &did);
  20123. + if (did) {
  20124. + tmp.dentry = path->dentry->d_parent;
  20125. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20126. + tmp.dentry = src_dentry;
  20127. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20128. + }
  20129. + /*ignore*/
  20130. + }
  20131. +
  20132. + out:
  20133. + return err;
  20134. +}
  20135. +
  20136. +int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
  20137. + struct inode *dir, struct path *path)
  20138. +{
  20139. + int err;
  20140. + struct path tmp = {
  20141. + .mnt = path->mnt
  20142. + };
  20143. + struct dentry *d;
  20144. +
  20145. + IMustLock(dir);
  20146. + IMustLock(src_dir);
  20147. +
  20148. + d = path->dentry;
  20149. + path->dentry = d->d_parent;
  20150. + tmp.dentry = src_dentry->d_parent;
  20151. + err = security_path_rename(&tmp, src_dentry, path, path->dentry);
  20152. + path->dentry = d;
  20153. + if (unlikely(err))
  20154. + goto out;
  20155. +
  20156. + lockdep_off();
  20157. + err = vfs_rename(src_dir, src_dentry, dir, path->dentry);
  20158. + lockdep_on();
  20159. + if (!err) {
  20160. + int did;
  20161. +
  20162. + tmp.dentry = d->d_parent;
  20163. + vfsub_update_h_iattr(&tmp, &did);
  20164. + if (did) {
  20165. + tmp.dentry = src_dentry;
  20166. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20167. + tmp.dentry = src_dentry->d_parent;
  20168. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20169. + }
  20170. + /*ignore*/
  20171. + }
  20172. +
  20173. + out:
  20174. + return err;
  20175. +}
  20176. +
  20177. +int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
  20178. +{
  20179. + int err;
  20180. + struct dentry *d;
  20181. +
  20182. + IMustLock(dir);
  20183. +
  20184. + d = path->dentry;
  20185. + path->dentry = d->d_parent;
  20186. + err = security_path_mkdir(path, path->dentry, mode);
  20187. + path->dentry = d;
  20188. + if (unlikely(err))
  20189. + goto out;
  20190. +
  20191. + err = vfs_mkdir(dir, path->dentry, mode);
  20192. + if (!err) {
  20193. + struct path tmp = *path;
  20194. + int did;
  20195. +
  20196. + vfsub_update_h_iattr(&tmp, &did);
  20197. + if (did) {
  20198. + tmp.dentry = path->dentry->d_parent;
  20199. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20200. + }
  20201. + /*ignore*/
  20202. + }
  20203. +
  20204. + out:
  20205. + return err;
  20206. +}
  20207. +
  20208. +int vfsub_rmdir(struct inode *dir, struct path *path)
  20209. +{
  20210. + int err;
  20211. + struct dentry *d;
  20212. +
  20213. + IMustLock(dir);
  20214. +
  20215. + d = path->dentry;
  20216. + path->dentry = d->d_parent;
  20217. + err = security_path_rmdir(path, path->dentry);
  20218. + path->dentry = d;
  20219. + if (unlikely(err))
  20220. + goto out;
  20221. +
  20222. + lockdep_off();
  20223. + err = vfs_rmdir(dir, path->dentry);
  20224. + lockdep_on();
  20225. + if (!err) {
  20226. + struct path tmp = {
  20227. + .dentry = path->dentry->d_parent,
  20228. + .mnt = path->mnt
  20229. + };
  20230. +
  20231. + vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
  20232. + }
  20233. +
  20234. + out:
  20235. + return err;
  20236. +}
  20237. +
  20238. +/* ---------------------------------------------------------------------- */
  20239. +
  20240. +ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
  20241. + loff_t *ppos)
  20242. +{
  20243. + ssize_t err;
  20244. +
  20245. + err = vfs_read(file, ubuf, count, ppos);
  20246. + if (err >= 0)
  20247. + vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
  20248. + return err;
  20249. +}
  20250. +
  20251. +/* todo: kernel_read()? */
  20252. +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
  20253. + loff_t *ppos)
  20254. +{
  20255. + ssize_t err;
  20256. + mm_segment_t oldfs;
  20257. +
  20258. + oldfs = get_fs();
  20259. + set_fs(KERNEL_DS);
  20260. + err = vfsub_read_u(file, (char __user *)kbuf, count, ppos);
  20261. + set_fs(oldfs);
  20262. + return err;
  20263. +}
  20264. +
  20265. +ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
  20266. + loff_t *ppos)
  20267. +{
  20268. + ssize_t err;
  20269. +
  20270. + lockdep_off();
  20271. + err = vfs_write(file, ubuf, count, ppos);
  20272. + lockdep_on();
  20273. + if (err >= 0)
  20274. + vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
  20275. + return err;
  20276. +}
  20277. +
  20278. +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
  20279. +{
  20280. + ssize_t err;
  20281. + mm_segment_t oldfs;
  20282. +
  20283. + oldfs = get_fs();
  20284. + set_fs(KERNEL_DS);
  20285. + err = vfsub_write_u(file, (const char __user *)kbuf, count, ppos);
  20286. + set_fs(oldfs);
  20287. + return err;
  20288. +}
  20289. +
  20290. +int vfsub_readdir(struct file *file, filldir_t filldir, void *arg)
  20291. +{
  20292. + int err;
  20293. +
  20294. + lockdep_off();
  20295. + err = vfs_readdir(file, filldir, arg);
  20296. + lockdep_on();
  20297. + if (err >= 0)
  20298. + vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
  20299. + return err;
  20300. +}
  20301. +
  20302. +long vfsub_splice_to(struct file *in, loff_t *ppos,
  20303. + struct pipe_inode_info *pipe, size_t len,
  20304. + unsigned int flags)
  20305. +{
  20306. + long err;
  20307. +
  20308. + lockdep_off();
  20309. + err = do_splice_to(in, ppos, pipe, len, flags);
  20310. + lockdep_on();
  20311. + if (err >= 0)
  20312. + vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
  20313. + return err;
  20314. +}
  20315. +
  20316. +long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
  20317. + loff_t *ppos, size_t len, unsigned int flags)
  20318. +{
  20319. + long err;
  20320. +
  20321. + lockdep_off();
  20322. + err = do_splice_from(pipe, out, ppos, len, flags);
  20323. + lockdep_on();
  20324. + if (err >= 0)
  20325. + vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
  20326. + return err;
  20327. +}
  20328. +
  20329. +/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
  20330. +int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
  20331. + struct file *h_file)
  20332. +{
  20333. + int err;
  20334. + struct inode *h_inode;
  20335. +
  20336. + h_inode = h_path->dentry->d_inode;
  20337. + if (!h_file) {
  20338. + err = mnt_want_write(h_path->mnt);
  20339. + if (err)
  20340. + goto out;
  20341. + err = inode_permission(h_inode, MAY_WRITE);
  20342. + if (err)
  20343. + goto out_mnt;
  20344. + err = get_write_access(h_inode);
  20345. + if (err)
  20346. + goto out_mnt;
  20347. + err = break_lease(h_inode, vfsub_fmode_to_uint(FMODE_WRITE));
  20348. + if (err)
  20349. + goto out_inode;
  20350. + }
  20351. +
  20352. + err = locks_verify_truncate(h_inode, h_file, length);
  20353. + if (!err)
  20354. + err = security_path_truncate(h_path, length, attr);
  20355. + if (!err) {
  20356. + lockdep_off();
  20357. + err = do_truncate(h_path->dentry, length, attr, h_file);
  20358. + lockdep_on();
  20359. + }
  20360. +
  20361. + out_inode:
  20362. + if (!h_file)
  20363. + put_write_access(h_inode);
  20364. + out_mnt:
  20365. + if (!h_file)
  20366. + mnt_drop_write(h_path->mnt);
  20367. + out:
  20368. + return err;
  20369. +}
  20370. +
  20371. +/* ---------------------------------------------------------------------- */
  20372. +
  20373. +struct au_vfsub_mkdir_args {
  20374. + int *errp;
  20375. + struct inode *dir;
  20376. + struct path *path;
  20377. + int mode;
  20378. +};
  20379. +
  20380. +static void au_call_vfsub_mkdir(void *args)
  20381. +{
  20382. + struct au_vfsub_mkdir_args *a = args;
  20383. + *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
  20384. +}
  20385. +
  20386. +int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
  20387. +{
  20388. + int err, do_sio, wkq_err;
  20389. +
  20390. + do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
  20391. + if (!do_sio)
  20392. + err = vfsub_mkdir(dir, path, mode);
  20393. + else {
  20394. + struct au_vfsub_mkdir_args args = {
  20395. + .errp = &err,
  20396. + .dir = dir,
  20397. + .path = path,
  20398. + .mode = mode
  20399. + };
  20400. + wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
  20401. + if (unlikely(wkq_err))
  20402. + err = wkq_err;
  20403. + }
  20404. +
  20405. + return err;
  20406. +}
  20407. +
  20408. +struct au_vfsub_rmdir_args {
  20409. + int *errp;
  20410. + struct inode *dir;
  20411. + struct path *path;
  20412. +};
  20413. +
  20414. +static void au_call_vfsub_rmdir(void *args)
  20415. +{
  20416. + struct au_vfsub_rmdir_args *a = args;
  20417. + *a->errp = vfsub_rmdir(a->dir, a->path);
  20418. +}
  20419. +
  20420. +int vfsub_sio_rmdir(struct inode *dir, struct path *path)
  20421. +{
  20422. + int err, do_sio, wkq_err;
  20423. +
  20424. + do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
  20425. + if (!do_sio)
  20426. + err = vfsub_rmdir(dir, path);
  20427. + else {
  20428. + struct au_vfsub_rmdir_args args = {
  20429. + .errp = &err,
  20430. + .dir = dir,
  20431. + .path = path
  20432. + };
  20433. + wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
  20434. + if (unlikely(wkq_err))
  20435. + err = wkq_err;
  20436. + }
  20437. +
  20438. + return err;
  20439. +}
  20440. +
  20441. +/* ---------------------------------------------------------------------- */
  20442. +
  20443. +struct notify_change_args {
  20444. + int *errp;
  20445. + struct path *path;
  20446. + struct iattr *ia;
  20447. +};
  20448. +
  20449. +static void call_notify_change(void *args)
  20450. +{
  20451. + struct notify_change_args *a = args;
  20452. + struct inode *h_inode;
  20453. +
  20454. + h_inode = a->path->dentry->d_inode;
  20455. + IMustLock(h_inode);
  20456. +
  20457. + *a->errp = -EPERM;
  20458. + if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
  20459. + lockdep_off();
  20460. + *a->errp = notify_change(a->path->dentry, a->ia);
  20461. + lockdep_on();
  20462. + if (!*a->errp)
  20463. + vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
  20464. + }
  20465. + AuTraceErr(*a->errp);
  20466. +}
  20467. +
  20468. +int vfsub_notify_change(struct path *path, struct iattr *ia)
  20469. +{
  20470. + int err;
  20471. + struct notify_change_args args = {
  20472. + .errp = &err,
  20473. + .path = path,
  20474. + .ia = ia
  20475. + };
  20476. +
  20477. + call_notify_change(&args);
  20478. +
  20479. + return err;
  20480. +}
  20481. +
  20482. +int vfsub_sio_notify_change(struct path *path, struct iattr *ia)
  20483. +{
  20484. + int err, wkq_err;
  20485. + struct notify_change_args args = {
  20486. + .errp = &err,
  20487. + .path = path,
  20488. + .ia = ia
  20489. + };
  20490. +
  20491. + wkq_err = au_wkq_wait(call_notify_change, &args);
  20492. + if (unlikely(wkq_err))
  20493. + err = wkq_err;
  20494. +
  20495. + return err;
  20496. +}
  20497. +
  20498. +/* ---------------------------------------------------------------------- */
  20499. +
  20500. +struct unlink_args {
  20501. + int *errp;
  20502. + struct inode *dir;
  20503. + struct path *path;
  20504. +};
  20505. +
  20506. +static void call_unlink(void *args)
  20507. +{
  20508. + struct unlink_args *a = args;
  20509. + struct dentry *d = a->path->dentry;
  20510. + struct inode *h_inode;
  20511. + const int stop_sillyrename = (au_test_nfs(d->d_sb)
  20512. + && atomic_read(&d->d_count) == 1);
  20513. +
  20514. + IMustLock(a->dir);
  20515. +
  20516. + a->path->dentry = d->d_parent;
  20517. + *a->errp = security_path_unlink(a->path, d);
  20518. + a->path->dentry = d;
  20519. + if (unlikely(*a->errp))
  20520. + return;
  20521. +
  20522. + if (!stop_sillyrename)
  20523. + dget(d);
  20524. + h_inode = d->d_inode;
  20525. + if (h_inode)
  20526. + atomic_inc(&h_inode->i_count);
  20527. +
  20528. + lockdep_off();
  20529. + *a->errp = vfs_unlink(a->dir, d);
  20530. + lockdep_on();
  20531. + if (!*a->errp) {
  20532. + struct path tmp = {
  20533. + .dentry = d->d_parent,
  20534. + .mnt = a->path->mnt
  20535. + };
  20536. + vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
  20537. + }
  20538. +
  20539. + if (!stop_sillyrename)
  20540. + dput(d);
  20541. + if (h_inode)
  20542. + iput(h_inode);
  20543. +
  20544. + AuTraceErr(*a->errp);
  20545. +}
  20546. +
  20547. +/*
  20548. + * @dir: must be locked.
  20549. + * @dentry: target dentry.
  20550. + */
  20551. +int vfsub_unlink(struct inode *dir, struct path *path, int force)
  20552. +{
  20553. + int err;
  20554. + struct unlink_args args = {
  20555. + .errp = &err,
  20556. + .dir = dir,
  20557. + .path = path
  20558. + };
  20559. +
  20560. + if (!force)
  20561. + call_unlink(&args);
  20562. + else {
  20563. + int wkq_err;
  20564. +
  20565. + wkq_err = au_wkq_wait(call_unlink, &args);
  20566. + if (unlikely(wkq_err))
  20567. + err = wkq_err;
  20568. + }
  20569. +
  20570. + return err;
  20571. +}
  20572. diff -Nur linux-2.6.34.orig/fs/aufs/vfsub.h linux-2.6.34/fs/aufs/vfsub.h
  20573. --- linux-2.6.34.orig/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
  20574. +++ linux-2.6.34/fs/aufs/vfsub.h 2010-05-23 23:33:21.663473060 +0200
  20575. @@ -0,0 +1,172 @@
  20576. +/*
  20577. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  20578. + *
  20579. + * This program, aufs is free software; you can redistribute it and/or modify
  20580. + * it under the terms of the GNU General Public License as published by
  20581. + * the Free Software Foundation; either version 2 of the License, or
  20582. + * (at your option) any later version.
  20583. + *
  20584. + * This program is distributed in the hope that it will be useful,
  20585. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20586. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20587. + * GNU General Public License for more details.
  20588. + *
  20589. + * You should have received a copy of the GNU General Public License
  20590. + * along with this program; if not, write to the Free Software
  20591. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20592. + */
  20593. +
  20594. +/*
  20595. + * sub-routines for VFS
  20596. + */
  20597. +
  20598. +#ifndef __AUFS_VFSUB_H__
  20599. +#define __AUFS_VFSUB_H__
  20600. +
  20601. +#ifdef __KERNEL__
  20602. +
  20603. +#include <linux/fs.h>
  20604. +#include <linux/fs_stack.h>
  20605. +
  20606. +/* ---------------------------------------------------------------------- */
  20607. +
  20608. +/* lock subclass for lower inode */
  20609. +/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
  20610. +/* reduce? gave up. */
  20611. +enum {
  20612. + AuLsc_I_Begin = I_MUTEX_QUOTA, /* 4 */
  20613. + AuLsc_I_PARENT, /* lower inode, parent first */
  20614. + AuLsc_I_PARENT2, /* copyup dirs */
  20615. + AuLsc_I_PARENT3, /* copyup wh */
  20616. + AuLsc_I_CHILD,
  20617. + AuLsc_I_CHILD2,
  20618. + AuLsc_I_End
  20619. +};
  20620. +
  20621. +/* to debug easier, do not make them inlined functions */
  20622. +#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
  20623. +#define IMustLock(i) MtxMustLock(&(i)->i_mutex)
  20624. +
  20625. +/* ---------------------------------------------------------------------- */
  20626. +
  20627. +static inline void vfsub_copy_inode_size(struct inode *inode,
  20628. + struct inode *h_inode)
  20629. +{
  20630. + spin_lock(&inode->i_lock);
  20631. + fsstack_copy_inode_size(inode, h_inode);
  20632. + spin_unlock(&inode->i_lock);
  20633. +}
  20634. +
  20635. +int vfsub_update_h_iattr(struct path *h_path, int *did);
  20636. +struct file *vfsub_filp_open(const char *path, int oflags, int mode);
  20637. +int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
  20638. +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
  20639. + int len);
  20640. +struct dentry *vfsub_lookup_hash(struct nameidata *nd);
  20641. +
  20642. +/* ---------------------------------------------------------------------- */
  20643. +
  20644. +struct au_hinode;
  20645. +struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
  20646. + struct dentry *d2, struct au_hinode *hdir2);
  20647. +void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
  20648. + struct dentry *d2, struct au_hinode *hdir2);
  20649. +
  20650. +int vfsub_create(struct inode *dir, struct path *path, int mode);
  20651. +int vfsub_symlink(struct inode *dir, struct path *path,
  20652. + const char *symname);
  20653. +int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
  20654. +int vfsub_link(struct dentry *src_dentry, struct inode *dir,
  20655. + struct path *path);
  20656. +int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
  20657. + struct inode *hdir, struct path *path);
  20658. +int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
  20659. +int vfsub_rmdir(struct inode *dir, struct path *path);
  20660. +
  20661. +/* ---------------------------------------------------------------------- */
  20662. +
  20663. +ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
  20664. + loff_t *ppos);
  20665. +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
  20666. + loff_t *ppos);
  20667. +ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
  20668. + loff_t *ppos);
  20669. +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
  20670. + loff_t *ppos);
  20671. +int vfsub_readdir(struct file *file, filldir_t filldir, void *arg);
  20672. +
  20673. +static inline void vfsub_file_accessed(struct file *h_file)
  20674. +{
  20675. + file_accessed(h_file);
  20676. + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
  20677. +}
  20678. +
  20679. +static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
  20680. + struct dentry *h_dentry)
  20681. +{
  20682. + struct path h_path = {
  20683. + .dentry = h_dentry,
  20684. + .mnt = h_mnt
  20685. + };
  20686. + touch_atime(h_mnt, h_dentry);
  20687. + vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
  20688. +}
  20689. +
  20690. +long vfsub_splice_to(struct file *in, loff_t *ppos,
  20691. + struct pipe_inode_info *pipe, size_t len,
  20692. + unsigned int flags);
  20693. +long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
  20694. + loff_t *ppos, size_t len, unsigned int flags);
  20695. +int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
  20696. + struct file *h_file);
  20697. +
  20698. +/* ---------------------------------------------------------------------- */
  20699. +
  20700. +static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
  20701. +{
  20702. + loff_t err;
  20703. +
  20704. + lockdep_off();
  20705. + err = vfs_llseek(file, offset, origin);
  20706. + lockdep_on();
  20707. + return err;
  20708. +}
  20709. +
  20710. +/* ---------------------------------------------------------------------- */
  20711. +
  20712. +/* dirty workaround for strict type of fmode_t */
  20713. +union vfsub_fmu {
  20714. + fmode_t fm;
  20715. + unsigned int ui;
  20716. +};
  20717. +
  20718. +static inline unsigned int vfsub_fmode_to_uint(fmode_t fm)
  20719. +{
  20720. + union vfsub_fmu u = {
  20721. + .fm = fm
  20722. + };
  20723. +
  20724. + BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui));
  20725. +
  20726. + return u.ui;
  20727. +}
  20728. +
  20729. +static inline fmode_t vfsub_uint_to_fmode(unsigned int ui)
  20730. +{
  20731. + union vfsub_fmu u = {
  20732. + .ui = ui
  20733. + };
  20734. +
  20735. + return u.fm;
  20736. +}
  20737. +
  20738. +/* ---------------------------------------------------------------------- */
  20739. +
  20740. +int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
  20741. +int vfsub_sio_rmdir(struct inode *dir, struct path *path);
  20742. +int vfsub_sio_notify_change(struct path *path, struct iattr *ia);
  20743. +int vfsub_notify_change(struct path *path, struct iattr *ia);
  20744. +int vfsub_unlink(struct inode *dir, struct path *path, int force);
  20745. +
  20746. +#endif /* __KERNEL__ */
  20747. +#endif /* __AUFS_VFSUB_H__ */
  20748. diff -Nur linux-2.6.34.orig/fs/aufs/wbr_policy.c linux-2.6.34/fs/aufs/wbr_policy.c
  20749. --- linux-2.6.34.orig/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100
  20750. +++ linux-2.6.34/fs/aufs/wbr_policy.c 2010-05-23 23:33:21.703473113 +0200
  20751. @@ -0,0 +1,641 @@
  20752. +/*
  20753. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  20754. + *
  20755. + * This program, aufs is free software; you can redistribute it and/or modify
  20756. + * it under the terms of the GNU General Public License as published by
  20757. + * the Free Software Foundation; either version 2 of the License, or
  20758. + * (at your option) any later version.
  20759. + *
  20760. + * This program is distributed in the hope that it will be useful,
  20761. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20762. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20763. + * GNU General Public License for more details.
  20764. + *
  20765. + * You should have received a copy of the GNU General Public License
  20766. + * along with this program; if not, write to the Free Software
  20767. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20768. + */
  20769. +
  20770. +/*
  20771. + * policies for selecting one among multiple writable branches
  20772. + */
  20773. +
  20774. +#include <linux/statfs.h>
  20775. +#include "aufs.h"
  20776. +
  20777. +/* subset of cpup_attr() */
  20778. +static noinline_for_stack
  20779. +int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
  20780. +{
  20781. + int err, sbits;
  20782. + struct iattr ia;
  20783. + struct inode *h_isrc;
  20784. +
  20785. + h_isrc = h_src->d_inode;
  20786. + ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
  20787. + ia.ia_mode = h_isrc->i_mode;
  20788. + ia.ia_uid = h_isrc->i_uid;
  20789. + ia.ia_gid = h_isrc->i_gid;
  20790. + sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
  20791. + au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc);
  20792. + err = vfsub_sio_notify_change(h_path, &ia);
  20793. +
  20794. + /* is this nfs only? */
  20795. + if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
  20796. + ia.ia_valid = ATTR_FORCE | ATTR_MODE;
  20797. + ia.ia_mode = h_isrc->i_mode;
  20798. + err = vfsub_sio_notify_change(h_path, &ia);
  20799. + }
  20800. +
  20801. + return err;
  20802. +}
  20803. +
  20804. +#define AuCpdown_PARENT_OPQ 1
  20805. +#define AuCpdown_WHED (1 << 1)
  20806. +#define AuCpdown_MADE_DIR (1 << 2)
  20807. +#define AuCpdown_DIROPQ (1 << 3)
  20808. +#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name)
  20809. +#define au_fset_cpdown(flags, name) { (flags) |= AuCpdown_##name; }
  20810. +#define au_fclr_cpdown(flags, name) { (flags) &= ~AuCpdown_##name; }
  20811. +
  20812. +struct au_cpdown_dir_args {
  20813. + struct dentry *parent;
  20814. + unsigned int flags;
  20815. +};
  20816. +
  20817. +static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
  20818. + struct au_cpdown_dir_args *a)
  20819. +{
  20820. + int err;
  20821. + struct dentry *opq_dentry;
  20822. +
  20823. + opq_dentry = au_diropq_create(dentry, bdst);
  20824. + err = PTR_ERR(opq_dentry);
  20825. + if (IS_ERR(opq_dentry))
  20826. + goto out;
  20827. + dput(opq_dentry);
  20828. + au_fset_cpdown(a->flags, DIROPQ);
  20829. +
  20830. + out:
  20831. + return err;
  20832. +}
  20833. +
  20834. +static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
  20835. + struct inode *dir, aufs_bindex_t bdst)
  20836. +{
  20837. + int err;
  20838. + struct path h_path;
  20839. + struct au_branch *br;
  20840. +
  20841. + br = au_sbr(dentry->d_sb, bdst);
  20842. + h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
  20843. + err = PTR_ERR(h_path.dentry);
  20844. + if (IS_ERR(h_path.dentry))
  20845. + goto out;
  20846. +
  20847. + err = 0;
  20848. + if (h_path.dentry->d_inode) {
  20849. + h_path.mnt = br->br_mnt;
  20850. + err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
  20851. + dentry);
  20852. + }
  20853. + dput(h_path.dentry);
  20854. +
  20855. + out:
  20856. + return err;
  20857. +}
  20858. +
  20859. +static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
  20860. + struct dentry *h_parent, void *arg)
  20861. +{
  20862. + int err, rerr;
  20863. + aufs_bindex_t bend, bopq, bstart;
  20864. + unsigned char parent_opq;
  20865. + struct path h_path;
  20866. + struct dentry *parent;
  20867. + struct inode *h_dir, *h_inode, *inode, *dir;
  20868. + struct au_cpdown_dir_args *args = arg;
  20869. +
  20870. + bstart = au_dbstart(dentry);
  20871. + /* dentry is di-locked */
  20872. + parent = dget_parent(dentry);
  20873. + dir = parent->d_inode;
  20874. + h_dir = h_parent->d_inode;
  20875. + AuDebugOn(h_dir != au_h_iptr(dir, bdst));
  20876. + IMustLock(h_dir);
  20877. +
  20878. + err = au_lkup_neg(dentry, bdst);
  20879. + if (unlikely(err < 0))
  20880. + goto out;
  20881. + h_path.dentry = au_h_dptr(dentry, bdst);
  20882. + h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
  20883. + err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path,
  20884. + S_IRWXU | S_IRUGO | S_IXUGO);
  20885. + if (unlikely(err))
  20886. + goto out_put;
  20887. + au_fset_cpdown(args->flags, MADE_DIR);
  20888. +
  20889. + bend = au_dbend(dentry);
  20890. + bopq = au_dbdiropq(dentry);
  20891. + au_fclr_cpdown(args->flags, WHED);
  20892. + au_fclr_cpdown(args->flags, DIROPQ);
  20893. + if (au_dbwh(dentry) == bdst)
  20894. + au_fset_cpdown(args->flags, WHED);
  20895. + if (!au_ftest_cpdown(args->flags, PARENT_OPQ) && bopq <= bdst)
  20896. + au_fset_cpdown(args->flags, PARENT_OPQ);
  20897. + parent_opq = (au_ftest_cpdown(args->flags, PARENT_OPQ)
  20898. + && args->parent == dentry);
  20899. + h_inode = h_path.dentry->d_inode;
  20900. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  20901. + if (au_ftest_cpdown(args->flags, WHED)) {
  20902. + err = au_cpdown_dir_opq(dentry, bdst, args);
  20903. + if (unlikely(err)) {
  20904. + mutex_unlock(&h_inode->i_mutex);
  20905. + goto out_dir;
  20906. + }
  20907. + }
  20908. +
  20909. + err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart));
  20910. + mutex_unlock(&h_inode->i_mutex);
  20911. + if (unlikely(err))
  20912. + goto out_opq;
  20913. +
  20914. + if (au_ftest_cpdown(args->flags, WHED)) {
  20915. + err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
  20916. + if (unlikely(err))
  20917. + goto out_opq;
  20918. + }
  20919. +
  20920. + inode = dentry->d_inode;
  20921. + if (au_ibend(inode) < bdst)
  20922. + au_set_ibend(inode, bdst);
  20923. + au_set_h_iptr(inode, bdst, au_igrab(h_inode),
  20924. + au_hi_flags(inode, /*isdir*/1));
  20925. + goto out; /* success */
  20926. +
  20927. + /* revert */
  20928. + out_opq:
  20929. + if (au_ftest_cpdown(args->flags, DIROPQ)) {
  20930. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  20931. + rerr = au_diropq_remove(dentry, bdst);
  20932. + mutex_unlock(&h_inode->i_mutex);
  20933. + if (unlikely(rerr)) {
  20934. + AuIOErr("failed removing diropq for %.*s b%d (%d)\n",
  20935. + AuDLNPair(dentry), bdst, rerr);
  20936. + err = -EIO;
  20937. + goto out;
  20938. + }
  20939. + }
  20940. + out_dir:
  20941. + if (au_ftest_cpdown(args->flags, MADE_DIR)) {
  20942. + rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
  20943. + if (unlikely(rerr)) {
  20944. + AuIOErr("failed removing %.*s b%d (%d)\n",
  20945. + AuDLNPair(dentry), bdst, rerr);
  20946. + err = -EIO;
  20947. + }
  20948. + }
  20949. + out_put:
  20950. + au_set_h_dptr(dentry, bdst, NULL);
  20951. + if (au_dbend(dentry) == bdst)
  20952. + au_update_dbend(dentry);
  20953. + out:
  20954. + dput(parent);
  20955. + return err;
  20956. +}
  20957. +
  20958. +int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
  20959. +{
  20960. + int err;
  20961. + struct au_cpdown_dir_args args = {
  20962. + .parent = dget_parent(dentry),
  20963. + .flags = 0
  20964. + };
  20965. +
  20966. + err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &args);
  20967. + dput(args.parent);
  20968. +
  20969. + return err;
  20970. +}
  20971. +
  20972. +/* ---------------------------------------------------------------------- */
  20973. +
  20974. +/* policies for create */
  20975. +
  20976. +static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
  20977. +{
  20978. + for (; bindex >= 0; bindex--)
  20979. + if (!au_br_rdonly(au_sbr(sb, bindex)))
  20980. + return bindex;
  20981. + return -EROFS;
  20982. +}
  20983. +
  20984. +/* top down parent */
  20985. +static int au_wbr_create_tdp(struct dentry *dentry, int isdir __maybe_unused)
  20986. +{
  20987. + int err;
  20988. + aufs_bindex_t bstart, bindex;
  20989. + struct super_block *sb;
  20990. + struct dentry *parent, *h_parent;
  20991. +
  20992. + sb = dentry->d_sb;
  20993. + bstart = au_dbstart(dentry);
  20994. + err = bstart;
  20995. + if (!au_br_rdonly(au_sbr(sb, bstart)))
  20996. + goto out;
  20997. +
  20998. + err = -EROFS;
  20999. + parent = dget_parent(dentry);
  21000. + for (bindex = au_dbstart(parent); bindex < bstart; bindex++) {
  21001. + h_parent = au_h_dptr(parent, bindex);
  21002. + if (!h_parent || !h_parent->d_inode)
  21003. + continue;
  21004. +
  21005. + if (!au_br_rdonly(au_sbr(sb, bindex))) {
  21006. + err = bindex;
  21007. + break;
  21008. + }
  21009. + }
  21010. + dput(parent);
  21011. +
  21012. + /* bottom up here */
  21013. + if (unlikely(err < 0))
  21014. + err = au_wbr_bu(sb, bstart - 1);
  21015. +
  21016. + out:
  21017. + AuDbg("b%d\n", err);
  21018. + return err;
  21019. +}
  21020. +
  21021. +/* ---------------------------------------------------------------------- */
  21022. +
  21023. +/* an exception for the policy other than tdp */
  21024. +static int au_wbr_create_exp(struct dentry *dentry)
  21025. +{
  21026. + int err;
  21027. + aufs_bindex_t bwh, bdiropq;
  21028. + struct dentry *parent;
  21029. +
  21030. + err = -1;
  21031. + bwh = au_dbwh(dentry);
  21032. + parent = dget_parent(dentry);
  21033. + bdiropq = au_dbdiropq(parent);
  21034. + if (bwh >= 0) {
  21035. + if (bdiropq >= 0)
  21036. + err = min(bdiropq, bwh);
  21037. + else
  21038. + err = bwh;
  21039. + AuDbg("%d\n", err);
  21040. + } else if (bdiropq >= 0) {
  21041. + err = bdiropq;
  21042. + AuDbg("%d\n", err);
  21043. + }
  21044. + dput(parent);
  21045. +
  21046. + if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
  21047. + err = -1;
  21048. +
  21049. + AuDbg("%d\n", err);
  21050. + return err;
  21051. +}
  21052. +
  21053. +/* ---------------------------------------------------------------------- */
  21054. +
  21055. +/* round robin */
  21056. +static int au_wbr_create_init_rr(struct super_block *sb)
  21057. +{
  21058. + int err;
  21059. +
  21060. + err = au_wbr_bu(sb, au_sbend(sb));
  21061. + atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
  21062. + /* smp_mb(); */
  21063. +
  21064. + AuDbg("b%d\n", err);
  21065. + return err;
  21066. +}
  21067. +
  21068. +static int au_wbr_create_rr(struct dentry *dentry, int isdir)
  21069. +{
  21070. + int err, nbr;
  21071. + unsigned int u;
  21072. + aufs_bindex_t bindex, bend;
  21073. + struct super_block *sb;
  21074. + atomic_t *next;
  21075. +
  21076. + err = au_wbr_create_exp(dentry);
  21077. + if (err >= 0)
  21078. + goto out;
  21079. +
  21080. + sb = dentry->d_sb;
  21081. + next = &au_sbi(sb)->si_wbr_rr_next;
  21082. + bend = au_sbend(sb);
  21083. + nbr = bend + 1;
  21084. + for (bindex = 0; bindex <= bend; bindex++) {
  21085. + if (!isdir) {
  21086. + err = atomic_dec_return(next) + 1;
  21087. + /* modulo for 0 is meaningless */
  21088. + if (unlikely(!err))
  21089. + err = atomic_dec_return(next) + 1;
  21090. + } else
  21091. + err = atomic_read(next);
  21092. + AuDbg("%d\n", err);
  21093. + u = err;
  21094. + err = u % nbr;
  21095. + AuDbg("%d\n", err);
  21096. + if (!au_br_rdonly(au_sbr(sb, err)))
  21097. + break;
  21098. + err = -EROFS;
  21099. + }
  21100. +
  21101. + out:
  21102. + AuDbg("%d\n", err);
  21103. + return err;
  21104. +}
  21105. +
  21106. +/* ---------------------------------------------------------------------- */
  21107. +
  21108. +/* most free space */
  21109. +static void au_mfs(struct dentry *dentry)
  21110. +{
  21111. + struct super_block *sb;
  21112. + struct au_branch *br;
  21113. + struct au_wbr_mfs *mfs;
  21114. + aufs_bindex_t bindex, bend;
  21115. + int err;
  21116. + unsigned long long b, bavail;
  21117. + /* reduce the stack usage */
  21118. + struct kstatfs *st;
  21119. +
  21120. + st = kmalloc(sizeof(*st), GFP_NOFS);
  21121. + if (unlikely(!st)) {
  21122. + AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
  21123. + return;
  21124. + }
  21125. +
  21126. + bavail = 0;
  21127. + sb = dentry->d_sb;
  21128. + mfs = &au_sbi(sb)->si_wbr_mfs;
  21129. + MtxMustLock(&mfs->mfs_lock);
  21130. + mfs->mfs_bindex = -EROFS;
  21131. + mfs->mfsrr_bytes = 0;
  21132. + bend = au_sbend(sb);
  21133. + for (bindex = 0; bindex <= bend; bindex++) {
  21134. + br = au_sbr(sb, bindex);
  21135. + if (au_br_rdonly(br))
  21136. + continue;
  21137. +
  21138. + /* sb->s_root for NFS is unreliable */
  21139. + err = vfs_statfs(br->br_mnt->mnt_root, st);
  21140. + if (unlikely(err)) {
  21141. + AuWarn1("failed statfs, b%d, %d\n", bindex, err);
  21142. + continue;
  21143. + }
  21144. +
  21145. + /* when the available size is equal, select the lower one */
  21146. + BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
  21147. + || sizeof(b) < sizeof(st->f_bsize));
  21148. + b = st->f_bavail * st->f_bsize;
  21149. + br->br_wbr->wbr_bytes = b;
  21150. + if (b >= bavail) {
  21151. + bavail = b;
  21152. + mfs->mfs_bindex = bindex;
  21153. + mfs->mfs_jiffy = jiffies;
  21154. + }
  21155. + }
  21156. +
  21157. + mfs->mfsrr_bytes = bavail;
  21158. + AuDbg("b%d\n", mfs->mfs_bindex);
  21159. + kfree(st);
  21160. +}
  21161. +
  21162. +static int au_wbr_create_mfs(struct dentry *dentry, int isdir __maybe_unused)
  21163. +{
  21164. + int err;
  21165. + struct super_block *sb;
  21166. + struct au_wbr_mfs *mfs;
  21167. +
  21168. + err = au_wbr_create_exp(dentry);
  21169. + if (err >= 0)
  21170. + goto out;
  21171. +
  21172. + sb = dentry->d_sb;
  21173. + mfs = &au_sbi(sb)->si_wbr_mfs;
  21174. + mutex_lock(&mfs->mfs_lock);
  21175. + if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
  21176. + || mfs->mfs_bindex < 0
  21177. + || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
  21178. + au_mfs(dentry);
  21179. + mutex_unlock(&mfs->mfs_lock);
  21180. + err = mfs->mfs_bindex;
  21181. +
  21182. + out:
  21183. + AuDbg("b%d\n", err);
  21184. + return err;
  21185. +}
  21186. +
  21187. +static int au_wbr_create_init_mfs(struct super_block *sb)
  21188. +{
  21189. + struct au_wbr_mfs *mfs;
  21190. +
  21191. + mfs = &au_sbi(sb)->si_wbr_mfs;
  21192. + mutex_init(&mfs->mfs_lock);
  21193. + mfs->mfs_jiffy = 0;
  21194. + mfs->mfs_bindex = -EROFS;
  21195. +
  21196. + return 0;
  21197. +}
  21198. +
  21199. +static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
  21200. +{
  21201. + mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
  21202. + return 0;
  21203. +}
  21204. +
  21205. +/* ---------------------------------------------------------------------- */
  21206. +
  21207. +/* most free space and then round robin */
  21208. +static int au_wbr_create_mfsrr(struct dentry *dentry, int isdir)
  21209. +{
  21210. + int err;
  21211. + struct au_wbr_mfs *mfs;
  21212. +
  21213. + err = au_wbr_create_mfs(dentry, isdir);
  21214. + if (err >= 0) {
  21215. + mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
  21216. + mutex_lock(&mfs->mfs_lock);
  21217. + if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
  21218. + err = au_wbr_create_rr(dentry, isdir);
  21219. + mutex_unlock(&mfs->mfs_lock);
  21220. + }
  21221. +
  21222. + AuDbg("b%d\n", err);
  21223. + return err;
  21224. +}
  21225. +
  21226. +static int au_wbr_create_init_mfsrr(struct super_block *sb)
  21227. +{
  21228. + int err;
  21229. +
  21230. + au_wbr_create_init_mfs(sb); /* ignore */
  21231. + err = au_wbr_create_init_rr(sb);
  21232. +
  21233. + return err;
  21234. +}
  21235. +
  21236. +/* ---------------------------------------------------------------------- */
  21237. +
  21238. +/* top down parent and most free space */
  21239. +static int au_wbr_create_pmfs(struct dentry *dentry, int isdir)
  21240. +{
  21241. + int err, e2;
  21242. + unsigned long long b;
  21243. + aufs_bindex_t bindex, bstart, bend;
  21244. + struct super_block *sb;
  21245. + struct dentry *parent, *h_parent;
  21246. + struct au_branch *br;
  21247. +
  21248. + err = au_wbr_create_tdp(dentry, isdir);
  21249. + if (unlikely(err < 0))
  21250. + goto out;
  21251. + parent = dget_parent(dentry);
  21252. + bstart = au_dbstart(parent);
  21253. + bend = au_dbtaildir(parent);
  21254. + if (bstart == bend)
  21255. + goto out_parent; /* success */
  21256. +
  21257. + e2 = au_wbr_create_mfs(dentry, isdir);
  21258. + if (e2 < 0)
  21259. + goto out_parent; /* success */
  21260. +
  21261. + /* when the available size is equal, select upper one */
  21262. + sb = dentry->d_sb;
  21263. + br = au_sbr(sb, err);
  21264. + b = br->br_wbr->wbr_bytes;
  21265. + AuDbg("b%d, %llu\n", err, b);
  21266. +
  21267. + for (bindex = bstart; bindex <= bend; bindex++) {
  21268. + h_parent = au_h_dptr(parent, bindex);
  21269. + if (!h_parent || !h_parent->d_inode)
  21270. + continue;
  21271. +
  21272. + br = au_sbr(sb, bindex);
  21273. + if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
  21274. + b = br->br_wbr->wbr_bytes;
  21275. + err = bindex;
  21276. + AuDbg("b%d, %llu\n", err, b);
  21277. + }
  21278. + }
  21279. +
  21280. + out_parent:
  21281. + dput(parent);
  21282. + out:
  21283. + AuDbg("b%d\n", err);
  21284. + return err;
  21285. +}
  21286. +
  21287. +/* ---------------------------------------------------------------------- */
  21288. +
  21289. +/* policies for copyup */
  21290. +
  21291. +/* top down parent */
  21292. +static int au_wbr_copyup_tdp(struct dentry *dentry)
  21293. +{
  21294. + return au_wbr_create_tdp(dentry, /*isdir, anything is ok*/0);
  21295. +}
  21296. +
  21297. +/* bottom up parent */
  21298. +static int au_wbr_copyup_bup(struct dentry *dentry)
  21299. +{
  21300. + int err;
  21301. + aufs_bindex_t bindex, bstart;
  21302. + struct dentry *parent, *h_parent;
  21303. + struct super_block *sb;
  21304. +
  21305. + err = -EROFS;
  21306. + sb = dentry->d_sb;
  21307. + parent = dget_parent(dentry);
  21308. + bstart = au_dbstart(parent);
  21309. + for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) {
  21310. + h_parent = au_h_dptr(parent, bindex);
  21311. + if (!h_parent || !h_parent->d_inode)
  21312. + continue;
  21313. +
  21314. + if (!au_br_rdonly(au_sbr(sb, bindex))) {
  21315. + err = bindex;
  21316. + break;
  21317. + }
  21318. + }
  21319. + dput(parent);
  21320. +
  21321. + /* bottom up here */
  21322. + if (unlikely(err < 0))
  21323. + err = au_wbr_bu(sb, bstart - 1);
  21324. +
  21325. + AuDbg("b%d\n", err);
  21326. + return err;
  21327. +}
  21328. +
  21329. +/* bottom up */
  21330. +static int au_wbr_copyup_bu(struct dentry *dentry)
  21331. +{
  21332. + int err;
  21333. +
  21334. + err = au_wbr_bu(dentry->d_sb, au_dbstart(dentry));
  21335. +
  21336. + AuDbg("b%d\n", err);
  21337. + return err;
  21338. +}
  21339. +
  21340. +/* ---------------------------------------------------------------------- */
  21341. +
  21342. +struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
  21343. + [AuWbrCopyup_TDP] = {
  21344. + .copyup = au_wbr_copyup_tdp
  21345. + },
  21346. + [AuWbrCopyup_BUP] = {
  21347. + .copyup = au_wbr_copyup_bup
  21348. + },
  21349. + [AuWbrCopyup_BU] = {
  21350. + .copyup = au_wbr_copyup_bu
  21351. + }
  21352. +};
  21353. +
  21354. +struct au_wbr_create_operations au_wbr_create_ops[] = {
  21355. + [AuWbrCreate_TDP] = {
  21356. + .create = au_wbr_create_tdp
  21357. + },
  21358. + [AuWbrCreate_RR] = {
  21359. + .create = au_wbr_create_rr,
  21360. + .init = au_wbr_create_init_rr
  21361. + },
  21362. + [AuWbrCreate_MFS] = {
  21363. + .create = au_wbr_create_mfs,
  21364. + .init = au_wbr_create_init_mfs,
  21365. + .fin = au_wbr_create_fin_mfs
  21366. + },
  21367. + [AuWbrCreate_MFSV] = {
  21368. + .create = au_wbr_create_mfs,
  21369. + .init = au_wbr_create_init_mfs,
  21370. + .fin = au_wbr_create_fin_mfs
  21371. + },
  21372. + [AuWbrCreate_MFSRR] = {
  21373. + .create = au_wbr_create_mfsrr,
  21374. + .init = au_wbr_create_init_mfsrr,
  21375. + .fin = au_wbr_create_fin_mfs
  21376. + },
  21377. + [AuWbrCreate_MFSRRV] = {
  21378. + .create = au_wbr_create_mfsrr,
  21379. + .init = au_wbr_create_init_mfsrr,
  21380. + .fin = au_wbr_create_fin_mfs
  21381. + },
  21382. + [AuWbrCreate_PMFS] = {
  21383. + .create = au_wbr_create_pmfs,
  21384. + .init = au_wbr_create_init_mfs,
  21385. + .fin = au_wbr_create_fin_mfs
  21386. + },
  21387. + [AuWbrCreate_PMFSV] = {
  21388. + .create = au_wbr_create_pmfs,
  21389. + .init = au_wbr_create_init_mfs,
  21390. + .fin = au_wbr_create_fin_mfs
  21391. + }
  21392. +};
  21393. diff -Nur linux-2.6.34.orig/fs/aufs/whout.c linux-2.6.34/fs/aufs/whout.c
  21394. --- linux-2.6.34.orig/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100
  21395. +++ linux-2.6.34/fs/aufs/whout.c 2010-05-23 23:33:21.740969899 +0200
  21396. @@ -0,0 +1,1048 @@
  21397. +/*
  21398. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  21399. + *
  21400. + * This program, aufs is free software; you can redistribute it and/or modify
  21401. + * it under the terms of the GNU General Public License as published by
  21402. + * the Free Software Foundation; either version 2 of the License, or
  21403. + * (at your option) any later version.
  21404. + *
  21405. + * This program is distributed in the hope that it will be useful,
  21406. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21407. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21408. + * GNU General Public License for more details.
  21409. + *
  21410. + * You should have received a copy of the GNU General Public License
  21411. + * along with this program; if not, write to the Free Software
  21412. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  21413. + */
  21414. +
  21415. +/*
  21416. + * whiteout for logical deletion and opaque directory
  21417. + */
  21418. +
  21419. +#include <linux/fs.h>
  21420. +#include "aufs.h"
  21421. +
  21422. +#define WH_MASK S_IRUGO
  21423. +
  21424. +/*
  21425. + * If a directory contains this file, then it is opaque. We start with the
  21426. + * .wh. flag so that it is blocked by lookup.
  21427. + */
  21428. +static struct qstr diropq_name = {
  21429. + .name = AUFS_WH_DIROPQ,
  21430. + .len = sizeof(AUFS_WH_DIROPQ) - 1
  21431. +};
  21432. +
  21433. +/*
  21434. + * generate whiteout name, which is NOT terminated by NULL.
  21435. + * @name: original d_name.name
  21436. + * @len: original d_name.len
  21437. + * @wh: whiteout qstr
  21438. + * returns zero when succeeds, otherwise error.
  21439. + * succeeded value as wh->name should be freed by kfree().
  21440. + */
  21441. +int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
  21442. +{
  21443. + char *p;
  21444. +
  21445. + if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
  21446. + return -ENAMETOOLONG;
  21447. +
  21448. + wh->len = name->len + AUFS_WH_PFX_LEN;
  21449. + p = kmalloc(wh->len, GFP_NOFS);
  21450. + wh->name = p;
  21451. + if (p) {
  21452. + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
  21453. + memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
  21454. + /* smp_mb(); */
  21455. + return 0;
  21456. + }
  21457. + return -ENOMEM;
  21458. +}
  21459. +
  21460. +/* ---------------------------------------------------------------------- */
  21461. +
  21462. +/*
  21463. + * test if the @wh_name exists under @h_parent.
  21464. + * @try_sio specifies the necessary of super-io.
  21465. + */
  21466. +int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
  21467. + struct au_branch *br, int try_sio)
  21468. +{
  21469. + int err;
  21470. + struct dentry *wh_dentry;
  21471. + struct inode *h_dir;
  21472. +
  21473. + h_dir = h_parent->d_inode;
  21474. + if (!try_sio)
  21475. + wh_dentry = au_lkup_one(wh_name, h_parent, br, /*nd*/NULL);
  21476. + else
  21477. + wh_dentry = au_sio_lkup_one(wh_name, h_parent, br);
  21478. + err = PTR_ERR(wh_dentry);
  21479. + if (IS_ERR(wh_dentry))
  21480. + goto out;
  21481. +
  21482. + err = 0;
  21483. + if (!wh_dentry->d_inode)
  21484. + goto out_wh; /* success */
  21485. +
  21486. + err = 1;
  21487. + if (S_ISREG(wh_dentry->d_inode->i_mode))
  21488. + goto out_wh; /* success */
  21489. +
  21490. + err = -EIO;
  21491. + AuIOErr("%.*s Invalid whiteout entry type 0%o.\n",
  21492. + AuDLNPair(wh_dentry), wh_dentry->d_inode->i_mode);
  21493. +
  21494. + out_wh:
  21495. + dput(wh_dentry);
  21496. + out:
  21497. + return err;
  21498. +}
  21499. +
  21500. +/*
  21501. + * test if the @h_dentry sets opaque or not.
  21502. + */
  21503. +int au_diropq_test(struct dentry *h_dentry, struct au_branch *br)
  21504. +{
  21505. + int err;
  21506. + struct inode *h_dir;
  21507. +
  21508. + h_dir = h_dentry->d_inode;
  21509. + err = au_wh_test(h_dentry, &diropq_name, br,
  21510. + au_test_h_perm_sio(h_dir, MAY_EXEC));
  21511. + return err;
  21512. +}
  21513. +
  21514. +/*
  21515. + * returns a negative dentry whose name is unique and temporary.
  21516. + */
  21517. +struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
  21518. + struct qstr *prefix)
  21519. +{
  21520. +#define HEX_LEN 4
  21521. + struct dentry *dentry;
  21522. + int i;
  21523. + char defname[AUFS_WH_PFX_LEN * 2 + DNAME_INLINE_LEN_MIN + 1
  21524. + + HEX_LEN + 1], *name, *p;
  21525. + static unsigned short cnt;
  21526. + struct qstr qs;
  21527. +
  21528. + name = defname;
  21529. + qs.len = sizeof(defname) - DNAME_INLINE_LEN_MIN + prefix->len - 1;
  21530. + if (unlikely(prefix->len > DNAME_INLINE_LEN_MIN)) {
  21531. + dentry = ERR_PTR(-ENAMETOOLONG);
  21532. + if (unlikely(qs.len >= PATH_MAX))
  21533. + goto out;
  21534. + dentry = ERR_PTR(-ENOMEM);
  21535. + name = kmalloc(qs.len + 1, GFP_NOFS);
  21536. + if (unlikely(!name))
  21537. + goto out;
  21538. + }
  21539. +
  21540. + /* doubly whiteout-ed */
  21541. + memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
  21542. + p = name + AUFS_WH_PFX_LEN * 2;
  21543. + memcpy(p, prefix->name, prefix->len);
  21544. + p += prefix->len;
  21545. + *p++ = '.';
  21546. + AuDebugOn(name + qs.len + 1 - p <= HEX_LEN);
  21547. +
  21548. + qs.name = name;
  21549. + for (i = 0; i < 3; i++) {
  21550. + sprintf(p, "%.*d", HEX_LEN, cnt++);
  21551. + dentry = au_sio_lkup_one(&qs, h_parent, br);
  21552. + if (IS_ERR(dentry) || !dentry->d_inode)
  21553. + goto out_name;
  21554. + dput(dentry);
  21555. + }
  21556. + /* AuWarn("could not get random name\n"); */
  21557. + dentry = ERR_PTR(-EEXIST);
  21558. + AuDbg("%.*s\n", AuLNPair(&qs));
  21559. + BUG();
  21560. +
  21561. + out_name:
  21562. + if (name != defname)
  21563. + kfree(name);
  21564. + out:
  21565. + return dentry;
  21566. +#undef HEX_LEN
  21567. +}
  21568. +
  21569. +/*
  21570. + * rename the @h_dentry on @br to the whiteouted temporary name.
  21571. + */
  21572. +int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
  21573. +{
  21574. + int err;
  21575. + struct path h_path = {
  21576. + .mnt = br->br_mnt
  21577. + };
  21578. + struct inode *h_dir;
  21579. + struct dentry *h_parent;
  21580. +
  21581. + h_parent = h_dentry->d_parent; /* dir inode is locked */
  21582. + h_dir = h_parent->d_inode;
  21583. + IMustLock(h_dir);
  21584. +
  21585. + h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
  21586. + err = PTR_ERR(h_path.dentry);
  21587. + if (IS_ERR(h_path.dentry))
  21588. + goto out;
  21589. +
  21590. + /* under the same dir, no need to lock_rename() */
  21591. + err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path);
  21592. + AuTraceErr(err);
  21593. + dput(h_path.dentry);
  21594. +
  21595. + out:
  21596. + return err;
  21597. +}
  21598. +
  21599. +/* ---------------------------------------------------------------------- */
  21600. +/*
  21601. + * functions for removing a whiteout
  21602. + */
  21603. +
  21604. +static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
  21605. +{
  21606. + int force;
  21607. +
  21608. + /*
  21609. + * forces superio when the dir has a sticky bit.
  21610. + * this may be a violation of unix fs semantics.
  21611. + */
  21612. + force = (h_dir->i_mode & S_ISVTX)
  21613. + && h_path->dentry->d_inode->i_uid != current_fsuid();
  21614. + return vfsub_unlink(h_dir, h_path, force);
  21615. +}
  21616. +
  21617. +int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
  21618. + struct dentry *dentry)
  21619. +{
  21620. + int err;
  21621. +
  21622. + err = do_unlink_wh(h_dir, h_path);
  21623. + if (!err && dentry)
  21624. + au_set_dbwh(dentry, -1);
  21625. +
  21626. + return err;
  21627. +}
  21628. +
  21629. +static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
  21630. + struct au_branch *br)
  21631. +{
  21632. + int err;
  21633. + struct path h_path = {
  21634. + .mnt = br->br_mnt
  21635. + };
  21636. +
  21637. + err = 0;
  21638. + h_path.dentry = au_lkup_one(wh, h_parent, br, /*nd*/NULL);
  21639. + if (IS_ERR(h_path.dentry))
  21640. + err = PTR_ERR(h_path.dentry);
  21641. + else {
  21642. + if (h_path.dentry->d_inode
  21643. + && S_ISREG(h_path.dentry->d_inode->i_mode))
  21644. + err = do_unlink_wh(h_parent->d_inode, &h_path);
  21645. + dput(h_path.dentry);
  21646. + }
  21647. +
  21648. + return err;
  21649. +}
  21650. +
  21651. +/* ---------------------------------------------------------------------- */
  21652. +/*
  21653. + * initialize/clean whiteout for a branch
  21654. + */
  21655. +
  21656. +static void au_wh_clean(struct inode *h_dir, struct path *whpath,
  21657. + const int isdir)
  21658. +{
  21659. + int err;
  21660. +
  21661. + if (!whpath->dentry->d_inode)
  21662. + return;
  21663. +
  21664. + err = mnt_want_write(whpath->mnt);
  21665. + if (!err) {
  21666. + if (isdir)
  21667. + err = vfsub_rmdir(h_dir, whpath);
  21668. + else
  21669. + err = vfsub_unlink(h_dir, whpath, /*force*/0);
  21670. + mnt_drop_write(whpath->mnt);
  21671. + }
  21672. + if (unlikely(err))
  21673. + AuWarn("failed removing %.*s (%d), ignored.\n",
  21674. + AuDLNPair(whpath->dentry), err);
  21675. +}
  21676. +
  21677. +static int test_linkable(struct dentry *h_root)
  21678. +{
  21679. + struct inode *h_dir = h_root->d_inode;
  21680. +
  21681. + if (h_dir->i_op->link)
  21682. + return 0;
  21683. +
  21684. + AuErr("%.*s (%s) doesn't support link(2), use noplink and rw+nolwh\n",
  21685. + AuDLNPair(h_root), au_sbtype(h_root->d_sb));
  21686. + return -ENOSYS;
  21687. +}
  21688. +
  21689. +/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
  21690. +static int au_whdir(struct inode *h_dir, struct path *path)
  21691. +{
  21692. + int err;
  21693. +
  21694. + err = -EEXIST;
  21695. + if (!path->dentry->d_inode) {
  21696. + int mode = S_IRWXU;
  21697. +
  21698. + if (au_test_nfs(path->dentry->d_sb))
  21699. + mode |= S_IXUGO;
  21700. + err = mnt_want_write(path->mnt);
  21701. + if (!err) {
  21702. + err = vfsub_mkdir(h_dir, path, mode);
  21703. + mnt_drop_write(path->mnt);
  21704. + }
  21705. + } else if (S_ISDIR(path->dentry->d_inode->i_mode))
  21706. + err = 0;
  21707. + else
  21708. + AuErr("unknown %.*s exists\n", AuDLNPair(path->dentry));
  21709. +
  21710. + return err;
  21711. +}
  21712. +
  21713. +struct au_wh_base {
  21714. + const struct qstr *name;
  21715. + struct dentry *dentry;
  21716. +};
  21717. +
  21718. +static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
  21719. + struct path *h_path)
  21720. +{
  21721. + h_path->dentry = base[AuBrWh_BASE].dentry;
  21722. + au_wh_clean(h_dir, h_path, /*isdir*/0);
  21723. + h_path->dentry = base[AuBrWh_PLINK].dentry;
  21724. + au_wh_clean(h_dir, h_path, /*isdir*/1);
  21725. + h_path->dentry = base[AuBrWh_ORPH].dentry;
  21726. + au_wh_clean(h_dir, h_path, /*isdir*/1);
  21727. +}
  21728. +
  21729. +/*
  21730. + * returns tri-state,
  21731. + * minus: error, caller should print the mesage
  21732. + * zero: succuess
  21733. + * plus: error, caller should NOT print the mesage
  21734. + */
  21735. +static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
  21736. + int do_plink, struct au_wh_base base[],
  21737. + struct path *h_path)
  21738. +{
  21739. + int err;
  21740. + struct inode *h_dir;
  21741. +
  21742. + h_dir = h_root->d_inode;
  21743. + h_path->dentry = base[AuBrWh_BASE].dentry;
  21744. + au_wh_clean(h_dir, h_path, /*isdir*/0);
  21745. + h_path->dentry = base[AuBrWh_PLINK].dentry;
  21746. + if (do_plink) {
  21747. + err = test_linkable(h_root);
  21748. + if (unlikely(err)) {
  21749. + err = 1;
  21750. + goto out;
  21751. + }
  21752. +
  21753. + err = au_whdir(h_dir, h_path);
  21754. + if (unlikely(err))
  21755. + goto out;
  21756. + wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
  21757. + } else
  21758. + au_wh_clean(h_dir, h_path, /*isdir*/1);
  21759. + h_path->dentry = base[AuBrWh_ORPH].dentry;
  21760. + err = au_whdir(h_dir, h_path);
  21761. + if (unlikely(err))
  21762. + goto out;
  21763. + wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
  21764. +
  21765. + out:
  21766. + return err;
  21767. +}
  21768. +
  21769. +/*
  21770. + * for the moment, aufs supports the branch filesystem which does not support
  21771. + * link(2). testing on FAT which does not support i_op->setattr() fully either,
  21772. + * copyup failed. finally, such filesystem will not be used as the writable
  21773. + * branch.
  21774. + *
  21775. + * returns tri-state, see above.
  21776. + */
  21777. +static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
  21778. + int do_plink, struct au_wh_base base[],
  21779. + struct path *h_path)
  21780. +{
  21781. + int err;
  21782. + struct inode *h_dir;
  21783. +
  21784. + WbrWhMustWriteLock(wbr);
  21785. +
  21786. + err = test_linkable(h_root);
  21787. + if (unlikely(err)) {
  21788. + err = 1;
  21789. + goto out;
  21790. + }
  21791. +
  21792. + /*
  21793. + * todo: should this create be done in /sbin/mount.aufs helper?
  21794. + */
  21795. + err = -EEXIST;
  21796. + h_dir = h_root->d_inode;
  21797. + if (!base[AuBrWh_BASE].dentry->d_inode) {
  21798. + err = mnt_want_write(h_path->mnt);
  21799. + if (!err) {
  21800. + h_path->dentry = base[AuBrWh_BASE].dentry;
  21801. + err = vfsub_create(h_dir, h_path, WH_MASK);
  21802. + mnt_drop_write(h_path->mnt);
  21803. + }
  21804. + } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode))
  21805. + err = 0;
  21806. + else
  21807. + AuErr("unknown %.*s/%.*s exists\n",
  21808. + AuDLNPair(h_root), AuDLNPair(base[AuBrWh_BASE].dentry));
  21809. + if (unlikely(err))
  21810. + goto out;
  21811. +
  21812. + h_path->dentry = base[AuBrWh_PLINK].dentry;
  21813. + if (do_plink) {
  21814. + err = au_whdir(h_dir, h_path);
  21815. + if (unlikely(err))
  21816. + goto out;
  21817. + wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
  21818. + } else
  21819. + au_wh_clean(h_dir, h_path, /*isdir*/1);
  21820. + wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
  21821. +
  21822. + h_path->dentry = base[AuBrWh_ORPH].dentry;
  21823. + err = au_whdir(h_dir, h_path);
  21824. + if (unlikely(err))
  21825. + goto out;
  21826. + wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
  21827. +
  21828. + out:
  21829. + return err;
  21830. +}
  21831. +
  21832. +/*
  21833. + * initialize the whiteout base file/dir for @br.
  21834. + */
  21835. +int au_wh_init(struct dentry *h_root, struct au_branch *br,
  21836. + struct super_block *sb)
  21837. +{
  21838. + int err, i;
  21839. + const unsigned char do_plink
  21840. + = !!au_opt_test(au_mntflags(sb), PLINK);
  21841. + struct path path = {
  21842. + .mnt = br->br_mnt
  21843. + };
  21844. + struct inode *h_dir;
  21845. + struct au_wbr *wbr = br->br_wbr;
  21846. + static const struct qstr base_name[] = {
  21847. + [AuBrWh_BASE] = {
  21848. + .name = AUFS_BASE_NAME,
  21849. + .len = sizeof(AUFS_BASE_NAME) - 1
  21850. + },
  21851. + [AuBrWh_PLINK] = {
  21852. + .name = AUFS_PLINKDIR_NAME,
  21853. + .len = sizeof(AUFS_PLINKDIR_NAME) - 1
  21854. + },
  21855. + [AuBrWh_ORPH] = {
  21856. + .name = AUFS_ORPHDIR_NAME,
  21857. + .len = sizeof(AUFS_ORPHDIR_NAME) - 1
  21858. + }
  21859. + };
  21860. + struct au_wh_base base[] = {
  21861. + [AuBrWh_BASE] = {
  21862. + .name = base_name + AuBrWh_BASE,
  21863. + .dentry = NULL
  21864. + },
  21865. + [AuBrWh_PLINK] = {
  21866. + .name = base_name + AuBrWh_PLINK,
  21867. + .dentry = NULL
  21868. + },
  21869. + [AuBrWh_ORPH] = {
  21870. + .name = base_name + AuBrWh_ORPH,
  21871. + .dentry = NULL
  21872. + }
  21873. + };
  21874. +
  21875. + if (wbr)
  21876. + WbrWhMustWriteLock(wbr);
  21877. +
  21878. + h_dir = h_root->d_inode;
  21879. + for (i = 0; i < AuBrWh_Last; i++) {
  21880. + /* doubly whiteouted */
  21881. + struct dentry *d;
  21882. +
  21883. + d = au_wh_lkup(h_root, (void *)base[i].name, br);
  21884. + err = PTR_ERR(d);
  21885. + if (IS_ERR(d))
  21886. + goto out;
  21887. +
  21888. + base[i].dentry = d;
  21889. + AuDebugOn(wbr
  21890. + && wbr->wbr_wh[i]
  21891. + && wbr->wbr_wh[i] != base[i].dentry);
  21892. + }
  21893. +
  21894. + if (wbr)
  21895. + for (i = 0; i < AuBrWh_Last; i++) {
  21896. + dput(wbr->wbr_wh[i]);
  21897. + wbr->wbr_wh[i] = NULL;
  21898. + }
  21899. +
  21900. + err = 0;
  21901. +
  21902. + switch (br->br_perm) {
  21903. + case AuBrPerm_RO:
  21904. + case AuBrPerm_ROWH:
  21905. + case AuBrPerm_RR:
  21906. + case AuBrPerm_RRWH:
  21907. + au_wh_init_ro(h_dir, base, &path);
  21908. + break;
  21909. +
  21910. + case AuBrPerm_RWNoLinkWH:
  21911. + err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
  21912. + if (err > 0)
  21913. + goto out;
  21914. + else if (err)
  21915. + goto out_err;
  21916. + break;
  21917. +
  21918. + case AuBrPerm_RW:
  21919. + err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
  21920. + if (err > 0)
  21921. + goto out;
  21922. + else if (err)
  21923. + goto out_err;
  21924. + break;
  21925. +
  21926. + default:
  21927. + BUG();
  21928. + }
  21929. + goto out; /* success */
  21930. +
  21931. + out_err:
  21932. + AuErr("an error(%d) on the writable branch %.*s(%s)\n",
  21933. + err, AuDLNPair(h_root), au_sbtype(h_root->d_sb));
  21934. + out:
  21935. + for (i = 0; i < AuBrWh_Last; i++)
  21936. + dput(base[i].dentry);
  21937. + return err;
  21938. +}
  21939. +
  21940. +/* ---------------------------------------------------------------------- */
  21941. +/*
  21942. + * whiteouts are all hard-linked usually.
  21943. + * when its link count reaches a ceiling, we create a new whiteout base
  21944. + * asynchronously.
  21945. + */
  21946. +
  21947. +struct reinit_br_wh {
  21948. + struct super_block *sb;
  21949. + struct au_branch *br;
  21950. +};
  21951. +
  21952. +static void reinit_br_wh(void *arg)
  21953. +{
  21954. + int err;
  21955. + aufs_bindex_t bindex;
  21956. + struct path h_path;
  21957. + struct reinit_br_wh *a = arg;
  21958. + struct au_wbr *wbr;
  21959. + struct inode *dir;
  21960. + struct dentry *h_root;
  21961. + struct au_hinode *hdir;
  21962. +
  21963. + err = 0;
  21964. + wbr = a->br->br_wbr;
  21965. + /* big aufs lock */
  21966. + si_noflush_write_lock(a->sb);
  21967. + if (!au_br_writable(a->br->br_perm))
  21968. + goto out;
  21969. + bindex = au_br_index(a->sb, a->br->br_id);
  21970. + if (unlikely(bindex < 0))
  21971. + goto out;
  21972. +
  21973. + di_read_lock_parent(a->sb->s_root, AuLock_IR);
  21974. + dir = a->sb->s_root->d_inode;
  21975. + hdir = au_hi(dir, bindex);
  21976. + h_root = au_h_dptr(a->sb->s_root, bindex);
  21977. +
  21978. + au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT);
  21979. + wbr_wh_write_lock(wbr);
  21980. + err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
  21981. + h_root, a->br);
  21982. + if (!err) {
  21983. + err = mnt_want_write(a->br->br_mnt);
  21984. + if (!err) {
  21985. + h_path.dentry = wbr->wbr_whbase;
  21986. + h_path.mnt = a->br->br_mnt;
  21987. + err = vfsub_unlink(hdir->hi_inode, &h_path, /*force*/0);
  21988. + mnt_drop_write(a->br->br_mnt);
  21989. + }
  21990. + } else {
  21991. + AuWarn("%.*s is moved, ignored\n", AuDLNPair(wbr->wbr_whbase));
  21992. + err = 0;
  21993. + }
  21994. + dput(wbr->wbr_whbase);
  21995. + wbr->wbr_whbase = NULL;
  21996. + if (!err)
  21997. + err = au_wh_init(h_root, a->br, a->sb);
  21998. + wbr_wh_write_unlock(wbr);
  21999. + au_hin_imtx_unlock(hdir);
  22000. + di_read_unlock(a->sb->s_root, AuLock_IR);
  22001. +
  22002. + out:
  22003. + if (wbr)
  22004. + atomic_dec(&wbr->wbr_wh_running);
  22005. + atomic_dec(&a->br->br_count);
  22006. + au_nwt_done(&au_sbi(a->sb)->si_nowait);
  22007. + si_write_unlock(a->sb);
  22008. + kfree(arg);
  22009. + if (unlikely(err))
  22010. + AuIOErr("err %d\n", err);
  22011. +}
  22012. +
  22013. +static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
  22014. +{
  22015. + int do_dec, wkq_err;
  22016. + struct reinit_br_wh *arg;
  22017. +
  22018. + do_dec = 1;
  22019. + if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
  22020. + goto out;
  22021. +
  22022. + /* ignore ENOMEM */
  22023. + arg = kmalloc(sizeof(*arg), GFP_NOFS);
  22024. + if (arg) {
  22025. + /*
  22026. + * dec(wh_running), kfree(arg) and dec(br_count)
  22027. + * in reinit function
  22028. + */
  22029. + arg->sb = sb;
  22030. + arg->br = br;
  22031. + atomic_inc(&br->br_count);
  22032. + wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb);
  22033. + if (unlikely(wkq_err)) {
  22034. + atomic_dec(&br->br_wbr->wbr_wh_running);
  22035. + atomic_dec(&br->br_count);
  22036. + kfree(arg);
  22037. + }
  22038. + do_dec = 0;
  22039. + }
  22040. +
  22041. + out:
  22042. + if (do_dec)
  22043. + atomic_dec(&br->br_wbr->wbr_wh_running);
  22044. +}
  22045. +
  22046. +/* ---------------------------------------------------------------------- */
  22047. +
  22048. +/*
  22049. + * create the whiteout @wh.
  22050. + */
  22051. +static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
  22052. + struct dentry *wh)
  22053. +{
  22054. + int err;
  22055. + struct path h_path = {
  22056. + .dentry = wh
  22057. + };
  22058. + struct au_branch *br;
  22059. + struct au_wbr *wbr;
  22060. + struct dentry *h_parent;
  22061. + struct inode *h_dir;
  22062. +
  22063. + h_parent = wh->d_parent; /* dir inode is locked */
  22064. + h_dir = h_parent->d_inode;
  22065. + IMustLock(h_dir);
  22066. +
  22067. + br = au_sbr(sb, bindex);
  22068. + h_path.mnt = br->br_mnt;
  22069. + wbr = br->br_wbr;
  22070. + wbr_wh_read_lock(wbr);
  22071. + if (wbr->wbr_whbase) {
  22072. + err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path);
  22073. + if (!err || err != -EMLINK)
  22074. + goto out;
  22075. +
  22076. + /* link count full. re-initialize br_whbase. */
  22077. + kick_reinit_br_wh(sb, br);
  22078. + }
  22079. +
  22080. + /* return this error in this context */
  22081. + err = vfsub_create(h_dir, &h_path, WH_MASK);
  22082. +
  22083. + out:
  22084. + wbr_wh_read_unlock(wbr);
  22085. + return err;
  22086. +}
  22087. +
  22088. +/* ---------------------------------------------------------------------- */
  22089. +
  22090. +/*
  22091. + * create or remove the diropq.
  22092. + */
  22093. +static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
  22094. + unsigned int flags)
  22095. +{
  22096. + struct dentry *opq_dentry, *h_dentry;
  22097. + struct super_block *sb;
  22098. + struct au_branch *br;
  22099. + int err;
  22100. +
  22101. + sb = dentry->d_sb;
  22102. + br = au_sbr(sb, bindex);
  22103. + h_dentry = au_h_dptr(dentry, bindex);
  22104. + opq_dentry = au_lkup_one(&diropq_name, h_dentry, br, /*nd*/NULL);
  22105. + if (IS_ERR(opq_dentry))
  22106. + goto out;
  22107. +
  22108. + if (au_ftest_diropq(flags, CREATE)) {
  22109. + err = link_or_create_wh(sb, bindex, opq_dentry);
  22110. + if (!err) {
  22111. + au_set_dbdiropq(dentry, bindex);
  22112. + goto out; /* success */
  22113. + }
  22114. + } else {
  22115. + struct path tmp = {
  22116. + .dentry = opq_dentry,
  22117. + .mnt = br->br_mnt
  22118. + };
  22119. + err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp);
  22120. + if (!err)
  22121. + au_set_dbdiropq(dentry, -1);
  22122. + }
  22123. + dput(opq_dentry);
  22124. + opq_dentry = ERR_PTR(err);
  22125. +
  22126. + out:
  22127. + return opq_dentry;
  22128. +}
  22129. +
  22130. +struct do_diropq_args {
  22131. + struct dentry **errp;
  22132. + struct dentry *dentry;
  22133. + aufs_bindex_t bindex;
  22134. + unsigned int flags;
  22135. +};
  22136. +
  22137. +static void call_do_diropq(void *args)
  22138. +{
  22139. + struct do_diropq_args *a = args;
  22140. + *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
  22141. +}
  22142. +
  22143. +struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
  22144. + unsigned int flags)
  22145. +{
  22146. + struct dentry *diropq, *h_dentry;
  22147. +
  22148. + h_dentry = au_h_dptr(dentry, bindex);
  22149. + if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE))
  22150. + diropq = do_diropq(dentry, bindex, flags);
  22151. + else {
  22152. + int wkq_err;
  22153. + struct do_diropq_args args = {
  22154. + .errp = &diropq,
  22155. + .dentry = dentry,
  22156. + .bindex = bindex,
  22157. + .flags = flags
  22158. + };
  22159. +
  22160. + wkq_err = au_wkq_wait(call_do_diropq, &args);
  22161. + if (unlikely(wkq_err))
  22162. + diropq = ERR_PTR(wkq_err);
  22163. + }
  22164. +
  22165. + return diropq;
  22166. +}
  22167. +
  22168. +/* ---------------------------------------------------------------------- */
  22169. +
  22170. +/*
  22171. + * lookup whiteout dentry.
  22172. + * @h_parent: lower parent dentry which must exist and be locked
  22173. + * @base_name: name of dentry which will be whiteouted
  22174. + * returns dentry for whiteout.
  22175. + */
  22176. +struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
  22177. + struct au_branch *br)
  22178. +{
  22179. + int err;
  22180. + struct qstr wh_name;
  22181. + struct dentry *wh_dentry;
  22182. +
  22183. + err = au_wh_name_alloc(&wh_name, base_name);
  22184. + wh_dentry = ERR_PTR(err);
  22185. + if (!err) {
  22186. + wh_dentry = au_lkup_one(&wh_name, h_parent, br, /*nd*/NULL);
  22187. + kfree(wh_name.name);
  22188. + }
  22189. + return wh_dentry;
  22190. +}
  22191. +
  22192. +/*
  22193. + * link/create a whiteout for @dentry on @bindex.
  22194. + */
  22195. +struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
  22196. + struct dentry *h_parent)
  22197. +{
  22198. + struct dentry *wh_dentry;
  22199. + struct super_block *sb;
  22200. + int err;
  22201. +
  22202. + sb = dentry->d_sb;
  22203. + wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
  22204. + if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) {
  22205. + err = link_or_create_wh(sb, bindex, wh_dentry);
  22206. + if (!err)
  22207. + au_set_dbwh(dentry, bindex);
  22208. + else {
  22209. + dput(wh_dentry);
  22210. + wh_dentry = ERR_PTR(err);
  22211. + }
  22212. + }
  22213. +
  22214. + return wh_dentry;
  22215. +}
  22216. +
  22217. +/* ---------------------------------------------------------------------- */
  22218. +
  22219. +/* Delete all whiteouts in this directory on branch bindex. */
  22220. +static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
  22221. + aufs_bindex_t bindex, struct au_branch *br)
  22222. +{
  22223. + int err;
  22224. + unsigned long ul, n;
  22225. + struct qstr wh_name;
  22226. + char *p;
  22227. + struct hlist_head *head;
  22228. + struct au_vdir_wh *tpos;
  22229. + struct hlist_node *pos;
  22230. + struct au_vdir_destr *str;
  22231. +
  22232. + err = -ENOMEM;
  22233. + p = __getname();
  22234. + wh_name.name = p;
  22235. + if (unlikely(!wh_name.name))
  22236. + goto out;
  22237. +
  22238. + err = 0;
  22239. + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
  22240. + p += AUFS_WH_PFX_LEN;
  22241. + n = whlist->nh_num;
  22242. + head = whlist->nh_head;
  22243. + for (ul = 0; !err && ul < n; ul++, head++) {
  22244. + hlist_for_each_entry(tpos, pos, head, wh_hash) {
  22245. + if (tpos->wh_bindex != bindex)
  22246. + continue;
  22247. +
  22248. + str = &tpos->wh_str;
  22249. + if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
  22250. + memcpy(p, str->name, str->len);
  22251. + wh_name.len = AUFS_WH_PFX_LEN + str->len;
  22252. + err = unlink_wh_name(h_dentry, &wh_name, br);
  22253. + if (!err)
  22254. + continue;
  22255. + break;
  22256. + }
  22257. + AuIOErr("whiteout name too long %.*s\n",
  22258. + str->len, str->name);
  22259. + err = -EIO;
  22260. + break;
  22261. + }
  22262. + }
  22263. + __putname(wh_name.name);
  22264. +
  22265. + out:
  22266. + return err;
  22267. +}
  22268. +
  22269. +struct del_wh_children_args {
  22270. + int *errp;
  22271. + struct dentry *h_dentry;
  22272. + struct au_nhash whlist;
  22273. + aufs_bindex_t bindex;
  22274. + struct au_branch *br;
  22275. +};
  22276. +
  22277. +static void call_del_wh_children(void *args)
  22278. +{
  22279. + struct del_wh_children_args *a = args;
  22280. + *a->errp = del_wh_children(a->h_dentry, &a->whlist, a->bindex, a->br);
  22281. +}
  22282. +
  22283. +/* ---------------------------------------------------------------------- */
  22284. +
  22285. +struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
  22286. +{
  22287. + struct au_whtmp_rmdir *whtmp;
  22288. + int err;
  22289. +
  22290. + SiMustAnyLock(sb);
  22291. +
  22292. + whtmp = kmalloc(sizeof(*whtmp), gfp);
  22293. + if (unlikely(!whtmp)) {
  22294. + whtmp = ERR_PTR(-ENOMEM);
  22295. + goto out;
  22296. + }
  22297. +
  22298. + whtmp->dir = NULL;
  22299. + whtmp->wh_dentry = NULL;
  22300. + err = au_nhash_alloc(&whtmp->whlist, au_sbi(sb)->si_rdhash, gfp);
  22301. + if (!err)
  22302. + return whtmp; /* success */
  22303. +
  22304. + kfree(whtmp);
  22305. + whtmp = ERR_PTR(err);
  22306. +
  22307. + out:
  22308. + return whtmp;
  22309. +}
  22310. +
  22311. +void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
  22312. +{
  22313. + dput(whtmp->wh_dentry);
  22314. + iput(whtmp->dir);
  22315. + au_nhash_wh_free(&whtmp->whlist);
  22316. + kfree(whtmp);
  22317. +}
  22318. +
  22319. +/*
  22320. + * rmdir the whiteouted temporary named dir @h_dentry.
  22321. + * @whlist: whiteouted children.
  22322. + */
  22323. +int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
  22324. + struct dentry *wh_dentry, struct au_nhash *whlist)
  22325. +{
  22326. + int err;
  22327. + struct path h_tmp;
  22328. + struct inode *wh_inode, *h_dir;
  22329. + struct au_branch *br;
  22330. +
  22331. + h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
  22332. + IMustLock(h_dir);
  22333. +
  22334. + br = au_sbr(dir->i_sb, bindex);
  22335. + wh_inode = wh_dentry->d_inode;
  22336. + mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
  22337. +
  22338. + /*
  22339. + * someone else might change some whiteouts while we were sleeping.
  22340. + * it means this whlist may have an obsoleted entry.
  22341. + */
  22342. + if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
  22343. + err = del_wh_children(wh_dentry, whlist, bindex, br);
  22344. + else {
  22345. + int wkq_err;
  22346. + struct del_wh_children_args args = {
  22347. + .errp = &err,
  22348. + .h_dentry = wh_dentry,
  22349. + .whlist = *whlist,
  22350. + .bindex = bindex,
  22351. + .br = br
  22352. + };
  22353. +
  22354. + wkq_err = au_wkq_wait(call_del_wh_children, &args);
  22355. + if (unlikely(wkq_err))
  22356. + err = wkq_err;
  22357. + }
  22358. + mutex_unlock(&wh_inode->i_mutex);
  22359. +
  22360. + if (!err) {
  22361. + h_tmp.dentry = wh_dentry;
  22362. + h_tmp.mnt = br->br_mnt;
  22363. + err = vfsub_rmdir(h_dir, &h_tmp);
  22364. + /* d_drop(h_dentry); */
  22365. + }
  22366. +
  22367. + if (!err) {
  22368. + if (au_ibstart(dir) == bindex) {
  22369. + au_cpup_attr_timesizes(dir);
  22370. + drop_nlink(dir);
  22371. + }
  22372. + return 0; /* success */
  22373. + }
  22374. +
  22375. + AuWarn("failed removing %.*s(%d), ignored\n",
  22376. + AuDLNPair(wh_dentry), err);
  22377. + return err;
  22378. +}
  22379. +
  22380. +static void call_rmdir_whtmp(void *args)
  22381. +{
  22382. + int err;
  22383. + struct au_whtmp_rmdir *a = args;
  22384. + struct super_block *sb;
  22385. + struct dentry *h_parent;
  22386. + struct inode *h_dir;
  22387. + struct au_branch *br;
  22388. + struct au_hinode *hdir;
  22389. +
  22390. + /* rmdir by nfsd may cause deadlock with this i_mutex */
  22391. + /* mutex_lock(&a->dir->i_mutex); */
  22392. + sb = a->dir->i_sb;
  22393. + si_noflush_read_lock(sb);
  22394. + err = au_test_ro(sb, a->bindex, NULL);
  22395. + if (unlikely(err))
  22396. + goto out;
  22397. +
  22398. + err = -EIO;
  22399. + br = au_sbr(sb, a->bindex);
  22400. + ii_write_lock_parent(a->dir);
  22401. + h_parent = dget_parent(a->wh_dentry);
  22402. + h_dir = h_parent->d_inode;
  22403. + hdir = au_hi(a->dir, a->bindex);
  22404. + au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT);
  22405. + err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent, br);
  22406. + if (!err) {
  22407. + err = mnt_want_write(br->br_mnt);
  22408. + if (!err) {
  22409. + err = au_whtmp_rmdir(a->dir, a->bindex, a->wh_dentry,
  22410. + &a->whlist);
  22411. + mnt_drop_write(br->br_mnt);
  22412. + }
  22413. + }
  22414. + au_hin_imtx_unlock(hdir);
  22415. + dput(h_parent);
  22416. + ii_write_unlock(a->dir);
  22417. +
  22418. + out:
  22419. + /* mutex_unlock(&a->dir->i_mutex); */
  22420. + au_nwt_done(&au_sbi(sb)->si_nowait);
  22421. + si_read_unlock(sb);
  22422. + au_whtmp_rmdir_free(a);
  22423. + if (unlikely(err))
  22424. + AuIOErr("err %d\n", err);
  22425. +}
  22426. +
  22427. +void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
  22428. + struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
  22429. +{
  22430. + int wkq_err;
  22431. +
  22432. + IMustLock(dir);
  22433. +
  22434. + /* all post-process will be done in do_rmdir_whtmp(). */
  22435. + args->dir = au_igrab(dir);
  22436. + args->bindex = bindex;
  22437. + args->wh_dentry = dget(wh_dentry);
  22438. + wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, dir->i_sb);
  22439. + if (unlikely(wkq_err)) {
  22440. + AuWarn("rmdir error %.*s (%d), ignored\n",
  22441. + AuDLNPair(wh_dentry), wkq_err);
  22442. + au_whtmp_rmdir_free(args);
  22443. + }
  22444. +}
  22445. diff -Nur linux-2.6.34.orig/fs/aufs/whout.h linux-2.6.34/fs/aufs/whout.h
  22446. --- linux-2.6.34.orig/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100
  22447. +++ linux-2.6.34/fs/aufs/whout.h 2010-05-23 23:33:21.783473084 +0200
  22448. @@ -0,0 +1,87 @@
  22449. +/*
  22450. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  22451. + *
  22452. + * This program, aufs is free software; you can redistribute it and/or modify
  22453. + * it under the terms of the GNU General Public License as published by
  22454. + * the Free Software Foundation; either version 2 of the License, or
  22455. + * (at your option) any later version.
  22456. + *
  22457. + * This program is distributed in the hope that it will be useful,
  22458. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22459. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22460. + * GNU General Public License for more details.
  22461. + *
  22462. + * You should have received a copy of the GNU General Public License
  22463. + * along with this program; if not, write to the Free Software
  22464. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22465. + */
  22466. +
  22467. +/*
  22468. + * whiteout for logical deletion and opaque directory
  22469. + */
  22470. +
  22471. +#ifndef __AUFS_WHOUT_H__
  22472. +#define __AUFS_WHOUT_H__
  22473. +
  22474. +#ifdef __KERNEL__
  22475. +
  22476. +#include <linux/aufs_type.h>
  22477. +#include "dir.h"
  22478. +
  22479. +/* whout.c */
  22480. +int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
  22481. +struct au_branch;
  22482. +int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
  22483. + struct au_branch *br, int try_sio);
  22484. +int au_diropq_test(struct dentry *h_dentry, struct au_branch *br);
  22485. +struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
  22486. + struct qstr *prefix);
  22487. +int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
  22488. +int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
  22489. + struct dentry *dentry);
  22490. +int au_wh_init(struct dentry *h_parent, struct au_branch *br,
  22491. + struct super_block *sb);
  22492. +
  22493. +/* diropq flags */
  22494. +#define AuDiropq_CREATE 1
  22495. +#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name)
  22496. +#define au_fset_diropq(flags, name) { (flags) |= AuDiropq_##name; }
  22497. +#define au_fclr_diropq(flags, name) { (flags) &= ~AuDiropq_##name; }
  22498. +
  22499. +struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
  22500. + unsigned int flags);
  22501. +struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
  22502. + struct au_branch *br);
  22503. +struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
  22504. + struct dentry *h_parent);
  22505. +
  22506. +/* real rmdir for the whiteout-ed dir */
  22507. +struct au_whtmp_rmdir {
  22508. + struct inode *dir;
  22509. + aufs_bindex_t bindex;
  22510. + struct dentry *wh_dentry;
  22511. + struct au_nhash whlist;
  22512. +};
  22513. +
  22514. +struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
  22515. +void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
  22516. +int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
  22517. + struct dentry *wh_dentry, struct au_nhash *whlist);
  22518. +void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
  22519. + struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
  22520. +
  22521. +/* ---------------------------------------------------------------------- */
  22522. +
  22523. +static inline struct dentry *au_diropq_create(struct dentry *dentry,
  22524. + aufs_bindex_t bindex)
  22525. +{
  22526. + return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
  22527. +}
  22528. +
  22529. +static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
  22530. +{
  22531. + return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
  22532. +}
  22533. +
  22534. +#endif /* __KERNEL__ */
  22535. +#endif /* __AUFS_WHOUT_H__ */
  22536. diff -Nur linux-2.6.34.orig/fs/aufs/wkq.c linux-2.6.34/fs/aufs/wkq.c
  22537. --- linux-2.6.34.orig/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100
  22538. +++ linux-2.6.34/fs/aufs/wkq.c 2010-05-23 23:33:21.820978231 +0200
  22539. @@ -0,0 +1,259 @@
  22540. +/*
  22541. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  22542. + *
  22543. + * This program, aufs is free software; you can redistribute it and/or modify
  22544. + * it under the terms of the GNU General Public License as published by
  22545. + * the Free Software Foundation; either version 2 of the License, or
  22546. + * (at your option) any later version.
  22547. + *
  22548. + * This program is distributed in the hope that it will be useful,
  22549. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22550. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22551. + * GNU General Public License for more details.
  22552. + *
  22553. + * You should have received a copy of the GNU General Public License
  22554. + * along with this program; if not, write to the Free Software
  22555. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22556. + */
  22557. +
  22558. +/*
  22559. + * workqueue for asynchronous/super-io operations
  22560. + * todo: try new dredential scheme
  22561. + */
  22562. +
  22563. +#include <linux/module.h>
  22564. +#include "aufs.h"
  22565. +
  22566. +/* internal workqueue named AUFS_WKQ_NAME */
  22567. +static struct au_wkq {
  22568. + struct workqueue_struct *q;
  22569. +
  22570. + /* balancing */
  22571. + atomic_t busy;
  22572. +} *au_wkq;
  22573. +
  22574. +struct au_wkinfo {
  22575. + struct work_struct wk;
  22576. + struct super_block *sb;
  22577. +
  22578. + unsigned int flags; /* see wkq.h */
  22579. +
  22580. + au_wkq_func_t func;
  22581. + void *args;
  22582. +
  22583. + atomic_t *busyp;
  22584. + struct completion *comp;
  22585. +};
  22586. +
  22587. +/* ---------------------------------------------------------------------- */
  22588. +
  22589. +static int enqueue(struct au_wkq *wkq, struct au_wkinfo *wkinfo)
  22590. +{
  22591. + wkinfo->busyp = &wkq->busy;
  22592. + if (au_ftest_wkq(wkinfo->flags, WAIT))
  22593. + return !queue_work(wkq->q, &wkinfo->wk);
  22594. + else
  22595. + return !schedule_work(&wkinfo->wk);
  22596. +}
  22597. +
  22598. +static void do_wkq(struct au_wkinfo *wkinfo)
  22599. +{
  22600. + unsigned int idle, n;
  22601. + int i, idle_idx;
  22602. +
  22603. + while (1) {
  22604. + if (au_ftest_wkq(wkinfo->flags, WAIT)) {
  22605. + idle_idx = 0;
  22606. + idle = UINT_MAX;
  22607. + for (i = 0; i < aufs_nwkq; i++) {
  22608. + n = atomic_inc_return(&au_wkq[i].busy);
  22609. + if (n == 1 && !enqueue(au_wkq + i, wkinfo))
  22610. + return; /* success */
  22611. +
  22612. + if (n < idle) {
  22613. + idle_idx = i;
  22614. + idle = n;
  22615. + }
  22616. + atomic_dec(&au_wkq[i].busy);
  22617. + }
  22618. + } else
  22619. + idle_idx = aufs_nwkq;
  22620. +
  22621. + atomic_inc(&au_wkq[idle_idx].busy);
  22622. + if (!enqueue(au_wkq + idle_idx, wkinfo))
  22623. + return; /* success */
  22624. +
  22625. + /* impossible? */
  22626. + AuWarn1("failed to queue_work()\n");
  22627. + yield();
  22628. + }
  22629. +}
  22630. +
  22631. +static void wkq_func(struct work_struct *wk)
  22632. +{
  22633. + struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
  22634. +
  22635. + wkinfo->func(wkinfo->args);
  22636. + atomic_dec_return(wkinfo->busyp);
  22637. + if (au_ftest_wkq(wkinfo->flags, WAIT))
  22638. + complete(wkinfo->comp);
  22639. + else {
  22640. + kobject_put(&au_sbi(wkinfo->sb)->si_kobj);
  22641. + module_put(THIS_MODULE);
  22642. + kfree(wkinfo);
  22643. + }
  22644. +}
  22645. +
  22646. +/*
  22647. + * Since struct completion is large, try allocating it dynamically.
  22648. + */
  22649. +#if defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS)
  22650. +#define AuWkqCompDeclare(name) struct completion *comp = NULL
  22651. +
  22652. +static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
  22653. +{
  22654. + *comp = kmalloc(sizeof(**comp), GFP_NOFS);
  22655. + if (*comp) {
  22656. + init_completion(*comp);
  22657. + wkinfo->comp = *comp;
  22658. + return 0;
  22659. + }
  22660. + return -ENOMEM;
  22661. +}
  22662. +
  22663. +static void au_wkq_comp_free(struct completion *comp)
  22664. +{
  22665. + kfree(comp);
  22666. +}
  22667. +
  22668. +#else
  22669. +
  22670. +/* no braces */
  22671. +#define AuWkqCompDeclare(name) \
  22672. + DECLARE_COMPLETION_ONSTACK(_ ## name); \
  22673. + struct completion *comp = &_ ## name
  22674. +
  22675. +static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
  22676. +{
  22677. + wkinfo->comp = *comp;
  22678. + return 0;
  22679. +}
  22680. +
  22681. +static void au_wkq_comp_free(struct completion *comp __maybe_unused)
  22682. +{
  22683. + /* empty */
  22684. +}
  22685. +#endif /* 4KSTACKS */
  22686. +
  22687. +static void au_wkq_run(struct au_wkinfo *wkinfo)
  22688. +{
  22689. + au_dbg_verify_kthread();
  22690. + INIT_WORK(&wkinfo->wk, wkq_func);
  22691. + do_wkq(wkinfo);
  22692. +}
  22693. +
  22694. +int au_wkq_wait(au_wkq_func_t func, void *args)
  22695. +{
  22696. + int err;
  22697. + AuWkqCompDeclare(comp);
  22698. + struct au_wkinfo wkinfo = {
  22699. + .flags = AuWkq_WAIT,
  22700. + .func = func,
  22701. + .args = args
  22702. + };
  22703. +
  22704. + err = au_wkq_comp_alloc(&wkinfo, &comp);
  22705. + if (!err) {
  22706. + au_wkq_run(&wkinfo);
  22707. + /* no timeout, no interrupt */
  22708. + wait_for_completion(wkinfo.comp);
  22709. + au_wkq_comp_free(comp);
  22710. + }
  22711. +
  22712. + return err;
  22713. +
  22714. +}
  22715. +
  22716. +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb)
  22717. +{
  22718. + int err;
  22719. + struct au_wkinfo *wkinfo;
  22720. +
  22721. + atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
  22722. +
  22723. + /*
  22724. + * wkq_func() must free this wkinfo.
  22725. + * it highly depends upon the implementation of workqueue.
  22726. + */
  22727. + err = 0;
  22728. + wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
  22729. + if (wkinfo) {
  22730. + wkinfo->sb = sb;
  22731. + wkinfo->flags = !AuWkq_WAIT;
  22732. + wkinfo->func = func;
  22733. + wkinfo->args = args;
  22734. + wkinfo->comp = NULL;
  22735. + kobject_get(&au_sbi(sb)->si_kobj);
  22736. + __module_get(THIS_MODULE);
  22737. +
  22738. + au_wkq_run(wkinfo);
  22739. + } else {
  22740. + err = -ENOMEM;
  22741. + atomic_dec(&au_sbi(sb)->si_nowait.nw_len);
  22742. + }
  22743. +
  22744. + return err;
  22745. +}
  22746. +
  22747. +/* ---------------------------------------------------------------------- */
  22748. +
  22749. +void au_nwt_init(struct au_nowait_tasks *nwt)
  22750. +{
  22751. + atomic_set(&nwt->nw_len, 0);
  22752. + /* smp_mb();*/ /* atomic_set */
  22753. + init_waitqueue_head(&nwt->nw_wq);
  22754. +}
  22755. +
  22756. +void au_wkq_fin(void)
  22757. +{
  22758. + int i;
  22759. +
  22760. + for (i = 0; i < aufs_nwkq; i++)
  22761. + if (au_wkq[i].q && !IS_ERR(au_wkq[i].q))
  22762. + destroy_workqueue(au_wkq[i].q);
  22763. + kfree(au_wkq);
  22764. +}
  22765. +
  22766. +int __init au_wkq_init(void)
  22767. +{
  22768. + int err, i;
  22769. + struct au_wkq *nowaitq;
  22770. +
  22771. + /* '+1' is for accounting of nowait queue */
  22772. + err = -ENOMEM;
  22773. + au_wkq = kcalloc(aufs_nwkq + 1, sizeof(*au_wkq), GFP_NOFS);
  22774. + if (unlikely(!au_wkq))
  22775. + goto out;
  22776. +
  22777. + err = 0;
  22778. + for (i = 0; i < aufs_nwkq; i++) {
  22779. + au_wkq[i].q = create_singlethread_workqueue(AUFS_WKQ_NAME);
  22780. + if (au_wkq[i].q && !IS_ERR(au_wkq[i].q)) {
  22781. + atomic_set(&au_wkq[i].busy, 0);
  22782. + continue;
  22783. + }
  22784. +
  22785. + err = PTR_ERR(au_wkq[i].q);
  22786. + au_wkq_fin();
  22787. + goto out;
  22788. + }
  22789. +
  22790. + /* nowait accounting */
  22791. + nowaitq = au_wkq + aufs_nwkq;
  22792. + atomic_set(&nowaitq->busy, 0);
  22793. + nowaitq->q = NULL;
  22794. + /* smp_mb(); */ /* atomic_set */
  22795. +
  22796. + out:
  22797. + return err;
  22798. +}
  22799. diff -Nur linux-2.6.34.orig/fs/aufs/wkq.h linux-2.6.34/fs/aufs/wkq.h
  22800. --- linux-2.6.34.orig/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100
  22801. +++ linux-2.6.34/fs/aufs/wkq.h 2010-05-23 23:33:21.863473117 +0200
  22802. @@ -0,0 +1,82 @@
  22803. +/*
  22804. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  22805. + *
  22806. + * This program, aufs is free software; you can redistribute it and/or modify
  22807. + * it under the terms of the GNU General Public License as published by
  22808. + * the Free Software Foundation; either version 2 of the License, or
  22809. + * (at your option) any later version.
  22810. + *
  22811. + * This program is distributed in the hope that it will be useful,
  22812. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22813. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22814. + * GNU General Public License for more details.
  22815. + *
  22816. + * You should have received a copy of the GNU General Public License
  22817. + * along with this program; if not, write to the Free Software
  22818. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22819. + */
  22820. +
  22821. +/*
  22822. + * workqueue for asynchronous/super-io operations
  22823. + * todo: try new credentials management scheme
  22824. + */
  22825. +
  22826. +#ifndef __AUFS_WKQ_H__
  22827. +#define __AUFS_WKQ_H__
  22828. +
  22829. +#ifdef __KERNEL__
  22830. +
  22831. +#include <linux/sched.h>
  22832. +#include <linux/wait.h>
  22833. +#include <linux/aufs_type.h>
  22834. +
  22835. +struct super_block;
  22836. +
  22837. +/* ---------------------------------------------------------------------- */
  22838. +
  22839. +/*
  22840. + * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
  22841. + */
  22842. +struct au_nowait_tasks {
  22843. + atomic_t nw_len;
  22844. + wait_queue_head_t nw_wq;
  22845. +};
  22846. +
  22847. +/* ---------------------------------------------------------------------- */
  22848. +
  22849. +typedef void (*au_wkq_func_t)(void *args);
  22850. +
  22851. +/* wkq flags */
  22852. +#define AuWkq_WAIT 1
  22853. +#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name)
  22854. +#define au_fset_wkq(flags, name) { (flags) |= AuWkq_##name; }
  22855. +#define au_fclr_wkq(flags, name) { (flags) &= ~AuWkq_##name; }
  22856. +
  22857. +/* wkq.c */
  22858. +int au_wkq_wait(au_wkq_func_t func, void *args);
  22859. +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb);
  22860. +void au_nwt_init(struct au_nowait_tasks *nwt);
  22861. +int __init au_wkq_init(void);
  22862. +void au_wkq_fin(void);
  22863. +
  22864. +/* ---------------------------------------------------------------------- */
  22865. +
  22866. +static inline int au_test_wkq(struct task_struct *tsk)
  22867. +{
  22868. + return !tsk->mm && !strcmp(tsk->comm, AUFS_WKQ_NAME);
  22869. +}
  22870. +
  22871. +static inline void au_nwt_done(struct au_nowait_tasks *nwt)
  22872. +{
  22873. + if (!atomic_dec_return(&nwt->nw_len))
  22874. + wake_up_all(&nwt->nw_wq);
  22875. +}
  22876. +
  22877. +static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
  22878. +{
  22879. + wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
  22880. + return 0;
  22881. +}
  22882. +
  22883. +#endif /* __KERNEL__ */
  22884. +#endif /* __AUFS_WKQ_H__ */
  22885. diff -Nur linux-2.6.34.orig/fs/aufs/xino.c linux-2.6.34/fs/aufs/xino.c
  22886. --- linux-2.6.34.orig/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100
  22887. +++ linux-2.6.34/fs/aufs/xino.c 2010-05-23 23:33:21.912293851 +0200
  22888. @@ -0,0 +1,1200 @@
  22889. +/*
  22890. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  22891. + *
  22892. + * This program, aufs is free software; you can redistribute it and/or modify
  22893. + * it under the terms of the GNU General Public License as published by
  22894. + * the Free Software Foundation; either version 2 of the License, or
  22895. + * (at your option) any later version.
  22896. + *
  22897. + * This program is distributed in the hope that it will be useful,
  22898. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22899. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22900. + * GNU General Public License for more details.
  22901. + *
  22902. + * You should have received a copy of the GNU General Public License
  22903. + * along with this program; if not, write to the Free Software
  22904. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22905. + */
  22906. +
  22907. +/*
  22908. + * external inode number translation table and bitmap
  22909. + */
  22910. +
  22911. +#include <linux/file.h>
  22912. +#include <linux/seq_file.h>
  22913. +#include <linux/uaccess.h>
  22914. +#include "aufs.h"
  22915. +
  22916. +ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size,
  22917. + loff_t *pos)
  22918. +{
  22919. + ssize_t err;
  22920. + mm_segment_t oldfs;
  22921. +
  22922. + oldfs = get_fs();
  22923. + set_fs(KERNEL_DS);
  22924. + do {
  22925. + /* todo: signal_pending? */
  22926. + err = func(file, (char __user *)buf, size, pos);
  22927. + } while (err == -EAGAIN || err == -EINTR);
  22928. + set_fs(oldfs);
  22929. +
  22930. +#if 0 /* reserved for future use */
  22931. + if (err > 0)
  22932. + fsnotify_access(file->f_dentry);
  22933. +#endif
  22934. +
  22935. + return err;
  22936. +}
  22937. +
  22938. +/* ---------------------------------------------------------------------- */
  22939. +
  22940. +static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *buf,
  22941. + size_t size, loff_t *pos)
  22942. +{
  22943. + ssize_t err;
  22944. + mm_segment_t oldfs;
  22945. +
  22946. + oldfs = get_fs();
  22947. + set_fs(KERNEL_DS);
  22948. + lockdep_off();
  22949. + do {
  22950. + /* todo: signal_pending? */
  22951. + err = func(file, (const char __user *)buf, size, pos);
  22952. + } while (err == -EAGAIN || err == -EINTR);
  22953. + lockdep_on();
  22954. + set_fs(oldfs);
  22955. +
  22956. +#if 0 /* reserved for future use */
  22957. + if (err > 0)
  22958. + fsnotify_modify(file->f_dentry);
  22959. +#endif
  22960. +
  22961. + return err;
  22962. +}
  22963. +
  22964. +struct do_xino_fwrite_args {
  22965. + ssize_t *errp;
  22966. + au_writef_t func;
  22967. + struct file *file;
  22968. + void *buf;
  22969. + size_t size;
  22970. + loff_t *pos;
  22971. +};
  22972. +
  22973. +static void call_do_xino_fwrite(void *args)
  22974. +{
  22975. + struct do_xino_fwrite_args *a = args;
  22976. + *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
  22977. +}
  22978. +
  22979. +ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
  22980. + loff_t *pos)
  22981. +{
  22982. + ssize_t err;
  22983. +
  22984. + /* todo: signal block and no wkq? */
  22985. + /* todo: new credential scheme */
  22986. + /*
  22987. + * it breaks RLIMIT_FSIZE and normal user's limit,
  22988. + * users should care about quota and real 'filesystem full.'
  22989. + */
  22990. + if (!au_test_wkq(current)) {
  22991. + int wkq_err;
  22992. + struct do_xino_fwrite_args args = {
  22993. + .errp = &err,
  22994. + .func = func,
  22995. + .file = file,
  22996. + .buf = buf,
  22997. + .size = size,
  22998. + .pos = pos
  22999. + };
  23000. +
  23001. + wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
  23002. + if (unlikely(wkq_err))
  23003. + err = wkq_err;
  23004. + } else
  23005. + err = do_xino_fwrite(func, file, buf, size, pos);
  23006. +
  23007. + return err;
  23008. +}
  23009. +
  23010. +/* ---------------------------------------------------------------------- */
  23011. +
  23012. +/*
  23013. + * create a new xinofile at the same place/path as @base_file.
  23014. + */
  23015. +struct file *au_xino_create2(struct file *base_file, struct file *copy_src)
  23016. +{
  23017. + struct file *file;
  23018. + struct dentry *base, *dentry, *parent;
  23019. + struct inode *dir;
  23020. + struct qstr *name;
  23021. + int err;
  23022. +
  23023. + base = base_file->f_dentry;
  23024. + parent = base->d_parent; /* dir inode is locked */
  23025. + dir = parent->d_inode;
  23026. + IMustLock(dir);
  23027. +
  23028. + file = ERR_PTR(-EINVAL);
  23029. + name = &base->d_name;
  23030. + dentry = vfsub_lookup_one_len(name->name, parent, name->len);
  23031. + if (IS_ERR(dentry)) {
  23032. + file = (void *)dentry;
  23033. + AuErr("%.*s lookup err %ld\n", AuLNPair(name), PTR_ERR(dentry));
  23034. + goto out;
  23035. + }
  23036. +
  23037. + /* no need to mnt_want_write() since we call dentry_open() later */
  23038. + err = vfs_create(dir, dentry, S_IRUGO | S_IWUGO, NULL);
  23039. + if (unlikely(err)) {
  23040. + file = ERR_PTR(err);
  23041. + AuErr("%.*s create err %d\n", AuLNPair(name), err);
  23042. + goto out_dput;
  23043. + }
  23044. +
  23045. + file = dentry_open(dget(dentry), mntget(base_file->f_vfsmnt),
  23046. + O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE,
  23047. + current_cred());
  23048. + if (IS_ERR(file)) {
  23049. + AuErr("%.*s open err %ld\n", AuLNPair(name), PTR_ERR(file));
  23050. + goto out_dput;
  23051. + }
  23052. +
  23053. + err = vfsub_unlink(dir, &file->f_path, /*force*/0);
  23054. + if (unlikely(err)) {
  23055. + AuErr("%.*s unlink err %d\n", AuLNPair(name), err);
  23056. + goto out_fput;
  23057. + }
  23058. +
  23059. + if (copy_src) {
  23060. + /* no one can touch copy_src xino */
  23061. + err = au_copy_file(file, copy_src,
  23062. + i_size_read(copy_src->f_dentry->d_inode));
  23063. + if (unlikely(err)) {
  23064. + AuErr("%.*s copy err %d\n", AuLNPair(name), err);
  23065. + goto out_fput;
  23066. + }
  23067. + }
  23068. + goto out_dput; /* success */
  23069. +
  23070. + out_fput:
  23071. + fput(file);
  23072. + file = ERR_PTR(err);
  23073. + out_dput:
  23074. + dput(dentry);
  23075. + out:
  23076. + return file;
  23077. +}
  23078. +
  23079. +struct au_xino_lock_dir {
  23080. + struct au_hinode *hdir;
  23081. + struct dentry *parent;
  23082. + struct mutex *mtx;
  23083. +};
  23084. +
  23085. +static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
  23086. + struct au_xino_lock_dir *ldir)
  23087. +{
  23088. + aufs_bindex_t brid, bindex;
  23089. +
  23090. + ldir->hdir = NULL;
  23091. + bindex = -1;
  23092. + brid = au_xino_brid(sb);
  23093. + if (brid >= 0)
  23094. + bindex = au_br_index(sb, brid);
  23095. + if (bindex >= 0) {
  23096. + ldir->hdir = au_hi(sb->s_root->d_inode, bindex);
  23097. + au_hin_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
  23098. + } else {
  23099. + ldir->parent = dget_parent(xino->f_dentry);
  23100. + ldir->mtx = &ldir->parent->d_inode->i_mutex;
  23101. + mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT);
  23102. + }
  23103. +}
  23104. +
  23105. +static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
  23106. +{
  23107. + if (ldir->hdir)
  23108. + au_hin_imtx_unlock(ldir->hdir);
  23109. + else {
  23110. + mutex_unlock(ldir->mtx);
  23111. + dput(ldir->parent);
  23112. + }
  23113. +}
  23114. +
  23115. +/* ---------------------------------------------------------------------- */
  23116. +
  23117. +/* trucate xino files asynchronously */
  23118. +
  23119. +int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex)
  23120. +{
  23121. + int err;
  23122. + aufs_bindex_t bi, bend;
  23123. + struct au_branch *br;
  23124. + struct file *new_xino, *file;
  23125. + struct super_block *h_sb;
  23126. + struct au_xino_lock_dir ldir;
  23127. +
  23128. + err = -EINVAL;
  23129. + bend = au_sbend(sb);
  23130. + if (unlikely(bindex < 0 || bend < bindex))
  23131. + goto out;
  23132. + br = au_sbr(sb, bindex);
  23133. + file = br->br_xino.xi_file;
  23134. + if (!file)
  23135. + goto out;
  23136. +
  23137. + au_xino_lock_dir(sb, file, &ldir);
  23138. + /* mnt_want_write() is unnecessary here */
  23139. + new_xino = au_xino_create2(file, file);
  23140. + au_xino_unlock_dir(&ldir);
  23141. + err = PTR_ERR(new_xino);
  23142. + if (IS_ERR(new_xino))
  23143. + goto out;
  23144. + err = 0;
  23145. + fput(file);
  23146. + br->br_xino.xi_file = new_xino;
  23147. +
  23148. + h_sb = br->br_mnt->mnt_sb;
  23149. + for (bi = 0; bi <= bend; bi++) {
  23150. + if (unlikely(bi == bindex))
  23151. + continue;
  23152. + br = au_sbr(sb, bi);
  23153. + if (br->br_mnt->mnt_sb != h_sb)
  23154. + continue;
  23155. +
  23156. + fput(br->br_xino.xi_file);
  23157. + br->br_xino.xi_file = new_xino;
  23158. + get_file(new_xino);
  23159. + }
  23160. +
  23161. + out:
  23162. + return err;
  23163. +}
  23164. +
  23165. +struct xino_do_trunc_args {
  23166. + struct super_block *sb;
  23167. + struct au_branch *br;
  23168. +};
  23169. +
  23170. +static void xino_do_trunc(void *_args)
  23171. +{
  23172. + struct xino_do_trunc_args *args = _args;
  23173. + struct super_block *sb;
  23174. + struct au_branch *br;
  23175. + struct inode *dir;
  23176. + int err;
  23177. + aufs_bindex_t bindex;
  23178. +
  23179. + err = 0;
  23180. + sb = args->sb;
  23181. + dir = sb->s_root->d_inode;
  23182. + br = args->br;
  23183. +
  23184. + si_noflush_write_lock(sb);
  23185. + ii_read_lock_parent(dir);
  23186. + bindex = au_br_index(sb, br->br_id);
  23187. + err = au_xino_trunc(sb, bindex);
  23188. + if (!err
  23189. + && br->br_xino.xi_file->f_dentry->d_inode->i_blocks
  23190. + >= br->br_xino_upper)
  23191. + br->br_xino_upper += AUFS_XINO_TRUNC_STEP;
  23192. +
  23193. + ii_read_unlock(dir);
  23194. + if (unlikely(err))
  23195. + AuWarn("err b%d, (%d)\n", bindex, err);
  23196. + atomic_dec(&br->br_xino_running);
  23197. + atomic_dec(&br->br_count);
  23198. + au_nwt_done(&au_sbi(sb)->si_nowait);
  23199. + si_write_unlock(sb);
  23200. + kfree(args);
  23201. +}
  23202. +
  23203. +static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
  23204. +{
  23205. + struct xino_do_trunc_args *args;
  23206. + int wkq_err;
  23207. +
  23208. + if (br->br_xino.xi_file->f_dentry->d_inode->i_blocks
  23209. + < br->br_xino_upper)
  23210. + return;
  23211. +
  23212. + if (atomic_inc_return(&br->br_xino_running) > 1)
  23213. + goto out;
  23214. +
  23215. + /* lock and kfree() will be called in trunc_xino() */
  23216. + args = kmalloc(sizeof(*args), GFP_NOFS);
  23217. + if (unlikely(!args)) {
  23218. + AuErr1("no memory\n");
  23219. + goto out_args;
  23220. + }
  23221. +
  23222. + atomic_inc_return(&br->br_count);
  23223. + args->sb = sb;
  23224. + args->br = br;
  23225. + wkq_err = au_wkq_nowait(xino_do_trunc, args, sb);
  23226. + if (!wkq_err)
  23227. + return; /* success */
  23228. +
  23229. + AuErr("wkq %d\n", wkq_err);
  23230. + atomic_dec_return(&br->br_count);
  23231. +
  23232. + out_args:
  23233. + kfree(args);
  23234. + out:
  23235. + atomic_dec_return(&br->br_xino_running);
  23236. +}
  23237. +
  23238. +/* ---------------------------------------------------------------------- */
  23239. +
  23240. +static int au_xino_do_write(au_writef_t write, struct file *file,
  23241. + ino_t h_ino, ino_t ino)
  23242. +{
  23243. + loff_t pos;
  23244. + ssize_t sz;
  23245. +
  23246. + pos = h_ino;
  23247. + if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) {
  23248. + AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
  23249. + return -EFBIG;
  23250. + }
  23251. + pos *= sizeof(ino);
  23252. + sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos);
  23253. + if (sz == sizeof(ino))
  23254. + return 0; /* success */
  23255. +
  23256. + AuIOErr("write failed (%zd)\n", sz);
  23257. + return -EIO;
  23258. +}
  23259. +
  23260. +/*
  23261. + * write @ino to the xinofile for the specified branch{@sb, @bindex}
  23262. + * at the position of @h_ino.
  23263. + * even if @ino is zero, it is written to the xinofile and means no entry.
  23264. + * if the size of the xino file on a specific filesystem exceeds the watermark,
  23265. + * try truncating it.
  23266. + */
  23267. +int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  23268. + ino_t ino)
  23269. +{
  23270. + int err;
  23271. + unsigned int mnt_flags;
  23272. + struct au_branch *br;
  23273. +
  23274. + BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max)
  23275. + || ((loff_t)-1) > 0);
  23276. + SiMustAnyLock(sb);
  23277. +
  23278. + mnt_flags = au_mntflags(sb);
  23279. + if (!au_opt_test(mnt_flags, XINO))
  23280. + return 0;
  23281. +
  23282. + br = au_sbr(sb, bindex);
  23283. + err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
  23284. + h_ino, ino);
  23285. + if (!err) {
  23286. + if (au_opt_test(mnt_flags, TRUNC_XINO)
  23287. + && au_test_fs_trunc_xino(br->br_mnt->mnt_sb))
  23288. + xino_try_trunc(sb, br);
  23289. + return 0; /* success */
  23290. + }
  23291. +
  23292. + AuIOErr("write failed (%d)\n", err);
  23293. + return -EIO;
  23294. +}
  23295. +
  23296. +/* ---------------------------------------------------------------------- */
  23297. +
  23298. +/* aufs inode number bitmap */
  23299. +
  23300. +static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
  23301. +static ino_t xib_calc_ino(unsigned long pindex, int bit)
  23302. +{
  23303. + ino_t ino;
  23304. +
  23305. + AuDebugOn(bit < 0 || page_bits <= bit);
  23306. + ino = AUFS_FIRST_INO + pindex * page_bits + bit;
  23307. + return ino;
  23308. +}
  23309. +
  23310. +static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
  23311. +{
  23312. + AuDebugOn(ino < AUFS_FIRST_INO);
  23313. + ino -= AUFS_FIRST_INO;
  23314. + *pindex = ino / page_bits;
  23315. + *bit = ino % page_bits;
  23316. +}
  23317. +
  23318. +static int xib_pindex(struct super_block *sb, unsigned long pindex)
  23319. +{
  23320. + int err;
  23321. + loff_t pos;
  23322. + ssize_t sz;
  23323. + struct au_sbinfo *sbinfo;
  23324. + struct file *xib;
  23325. + unsigned long *p;
  23326. +
  23327. + sbinfo = au_sbi(sb);
  23328. + MtxMustLock(&sbinfo->si_xib_mtx);
  23329. + AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
  23330. + || !au_opt_test(sbinfo->si_mntflags, XINO));
  23331. +
  23332. + if (pindex == sbinfo->si_xib_last_pindex)
  23333. + return 0;
  23334. +
  23335. + xib = sbinfo->si_xib;
  23336. + p = sbinfo->si_xib_buf;
  23337. + pos = sbinfo->si_xib_last_pindex;
  23338. + pos *= PAGE_SIZE;
  23339. + sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
  23340. + if (unlikely(sz != PAGE_SIZE))
  23341. + goto out;
  23342. +
  23343. + pos = pindex;
  23344. + pos *= PAGE_SIZE;
  23345. + if (i_size_read(xib->f_dentry->d_inode) >= pos + PAGE_SIZE)
  23346. + sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
  23347. + else {
  23348. + memset(p, 0, PAGE_SIZE);
  23349. + sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
  23350. + }
  23351. + if (sz == PAGE_SIZE) {
  23352. + sbinfo->si_xib_last_pindex = pindex;
  23353. + return 0; /* success */
  23354. + }
  23355. +
  23356. + out:
  23357. + AuIOErr1("write failed (%zd)\n", sz);
  23358. + err = sz;
  23359. + if (sz >= 0)
  23360. + err = -EIO;
  23361. + return err;
  23362. +}
  23363. +
  23364. +/* ---------------------------------------------------------------------- */
  23365. +
  23366. +int au_xino_write0(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  23367. + ino_t ino)
  23368. +{
  23369. + int err, bit;
  23370. + unsigned long pindex;
  23371. + struct au_sbinfo *sbinfo;
  23372. +
  23373. + if (!au_opt_test(au_mntflags(sb), XINO))
  23374. + return 0;
  23375. +
  23376. + err = 0;
  23377. + if (ino) {
  23378. + sbinfo = au_sbi(sb);
  23379. + xib_calc_bit(ino, &pindex, &bit);
  23380. + AuDebugOn(page_bits <= bit);
  23381. + mutex_lock(&sbinfo->si_xib_mtx);
  23382. + err = xib_pindex(sb, pindex);
  23383. + if (!err) {
  23384. + clear_bit(bit, sbinfo->si_xib_buf);
  23385. + sbinfo->si_xib_next_bit = bit;
  23386. + }
  23387. + mutex_unlock(&sbinfo->si_xib_mtx);
  23388. + }
  23389. +
  23390. + if (!err)
  23391. + err = au_xino_write(sb, bindex, h_ino, 0);
  23392. + return err;
  23393. +}
  23394. +
  23395. +/* get an unused inode number from bitmap */
  23396. +ino_t au_xino_new_ino(struct super_block *sb)
  23397. +{
  23398. + ino_t ino;
  23399. + unsigned long *p, pindex, ul, pend;
  23400. + struct au_sbinfo *sbinfo;
  23401. + struct file *file;
  23402. + int free_bit, err;
  23403. +
  23404. + if (!au_opt_test(au_mntflags(sb), XINO))
  23405. + return iunique(sb, AUFS_FIRST_INO);
  23406. +
  23407. + sbinfo = au_sbi(sb);
  23408. + mutex_lock(&sbinfo->si_xib_mtx);
  23409. + p = sbinfo->si_xib_buf;
  23410. + free_bit = sbinfo->si_xib_next_bit;
  23411. + if (free_bit < page_bits && !test_bit(free_bit, p))
  23412. + goto out; /* success */
  23413. + free_bit = find_first_zero_bit(p, page_bits);
  23414. + if (free_bit < page_bits)
  23415. + goto out; /* success */
  23416. +
  23417. + pindex = sbinfo->si_xib_last_pindex;
  23418. + for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
  23419. + err = xib_pindex(sb, ul);
  23420. + if (unlikely(err))
  23421. + goto out_err;
  23422. + free_bit = find_first_zero_bit(p, page_bits);
  23423. + if (free_bit < page_bits)
  23424. + goto out; /* success */
  23425. + }
  23426. +
  23427. + file = sbinfo->si_xib;
  23428. + pend = i_size_read(file->f_dentry->d_inode) / PAGE_SIZE;
  23429. + for (ul = pindex + 1; ul <= pend; ul++) {
  23430. + err = xib_pindex(sb, ul);
  23431. + if (unlikely(err))
  23432. + goto out_err;
  23433. + free_bit = find_first_zero_bit(p, page_bits);
  23434. + if (free_bit < page_bits)
  23435. + goto out; /* success */
  23436. + }
  23437. + BUG();
  23438. +
  23439. + out:
  23440. + set_bit(free_bit, p);
  23441. + sbinfo->si_xib_next_bit++;
  23442. + pindex = sbinfo->si_xib_last_pindex;
  23443. + mutex_unlock(&sbinfo->si_xib_mtx);
  23444. + ino = xib_calc_ino(pindex, free_bit);
  23445. + AuDbg("i%lu\n", (unsigned long)ino);
  23446. + return ino;
  23447. + out_err:
  23448. + mutex_unlock(&sbinfo->si_xib_mtx);
  23449. + AuDbg("i0\n");
  23450. + return 0;
  23451. +}
  23452. +
  23453. +/*
  23454. + * read @ino from xinofile for the specified branch{@sb, @bindex}
  23455. + * at the position of @h_ino.
  23456. + * if @ino does not exist and @do_new is true, get new one.
  23457. + */
  23458. +int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  23459. + ino_t *ino)
  23460. +{
  23461. + int err;
  23462. + ssize_t sz;
  23463. + loff_t pos;
  23464. + struct file *file;
  23465. + struct au_sbinfo *sbinfo;
  23466. +
  23467. + *ino = 0;
  23468. + if (!au_opt_test(au_mntflags(sb), XINO))
  23469. + return 0; /* no xino */
  23470. +
  23471. + err = 0;
  23472. + sbinfo = au_sbi(sb);
  23473. + pos = h_ino;
  23474. + if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) {
  23475. + AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
  23476. + return -EFBIG;
  23477. + }
  23478. + pos *= sizeof(*ino);
  23479. +
  23480. + file = au_sbr(sb, bindex)->br_xino.xi_file;
  23481. + if (i_size_read(file->f_dentry->d_inode) < pos + sizeof(*ino))
  23482. + return 0; /* no ino */
  23483. +
  23484. + sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos);
  23485. + if (sz == sizeof(*ino))
  23486. + return 0; /* success */
  23487. +
  23488. + err = sz;
  23489. + if (unlikely(sz >= 0)) {
  23490. + err = -EIO;
  23491. + AuIOErr("xino read error (%zd)\n", sz);
  23492. + }
  23493. +
  23494. + return err;
  23495. +}
  23496. +
  23497. +/* ---------------------------------------------------------------------- */
  23498. +
  23499. +/* create and set a new xino file */
  23500. +
  23501. +struct file *au_xino_create(struct super_block *sb, char *fname, int silent)
  23502. +{
  23503. + struct file *file;
  23504. + struct dentry *h_parent, *d;
  23505. + struct inode *h_dir;
  23506. + int err;
  23507. +
  23508. + /*
  23509. + * at mount-time, and the xino file is the default path,
  23510. + * hinotify is disabled so we have no inotify events to ignore.
  23511. + * when a user specified the xino, we cannot get au_hdir to be ignored.
  23512. + */
  23513. + file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE,
  23514. + S_IRUGO | S_IWUGO);
  23515. + if (IS_ERR(file)) {
  23516. + if (!silent)
  23517. + AuErr("open %s(%ld)\n", fname, PTR_ERR(file));
  23518. + return file;
  23519. + }
  23520. +
  23521. + /* keep file count */
  23522. + h_parent = dget_parent(file->f_dentry);
  23523. + h_dir = h_parent->d_inode;
  23524. + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
  23525. + /* mnt_want_write() is unnecessary here */
  23526. + err = vfsub_unlink(h_dir, &file->f_path, /*force*/0);
  23527. + mutex_unlock(&h_dir->i_mutex);
  23528. + dput(h_parent);
  23529. + if (unlikely(err)) {
  23530. + if (!silent)
  23531. + AuErr("unlink %s(%d)\n", fname, err);
  23532. + goto out;
  23533. + }
  23534. +
  23535. + err = -EINVAL;
  23536. + d = file->f_dentry;
  23537. + if (unlikely(sb == d->d_sb)) {
  23538. + if (!silent)
  23539. + AuErr("%s must be outside\n", fname);
  23540. + goto out;
  23541. + }
  23542. + if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
  23543. + if (!silent)
  23544. + AuErr("xino doesn't support %s(%s)\n",
  23545. + fname, au_sbtype(d->d_sb));
  23546. + goto out;
  23547. + }
  23548. + return file; /* success */
  23549. +
  23550. + out:
  23551. + fput(file);
  23552. + file = ERR_PTR(err);
  23553. + return file;
  23554. +}
  23555. +
  23556. +/*
  23557. + * find another branch who is on the same filesystem of the specified
  23558. + * branch{@btgt}. search until @bend.
  23559. + */
  23560. +static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
  23561. + aufs_bindex_t bend)
  23562. +{
  23563. + aufs_bindex_t bindex;
  23564. + struct super_block *tgt_sb = au_sbr_sb(sb, btgt);
  23565. +
  23566. + for (bindex = 0; bindex < btgt; bindex++)
  23567. + if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
  23568. + return bindex;
  23569. + for (bindex++; bindex <= bend; bindex++)
  23570. + if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
  23571. + return bindex;
  23572. + return -1;
  23573. +}
  23574. +
  23575. +/* ---------------------------------------------------------------------- */
  23576. +
  23577. +/*
  23578. + * initialize the xinofile for the specified branch @br
  23579. + * at the place/path where @base_file indicates.
  23580. + * test whether another branch is on the same filesystem or not,
  23581. + * if @do_test is true.
  23582. + */
  23583. +int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
  23584. + struct file *base_file, int do_test)
  23585. +{
  23586. + int err;
  23587. + ino_t ino;
  23588. + aufs_bindex_t bend, bindex;
  23589. + struct au_branch *shared_br, *b;
  23590. + struct file *file;
  23591. + struct super_block *tgt_sb;
  23592. +
  23593. + shared_br = NULL;
  23594. + bend = au_sbend(sb);
  23595. + if (do_test) {
  23596. + tgt_sb = br->br_mnt->mnt_sb;
  23597. + for (bindex = 0; bindex <= bend; bindex++) {
  23598. + b = au_sbr(sb, bindex);
  23599. + if (tgt_sb == b->br_mnt->mnt_sb) {
  23600. + shared_br = b;
  23601. + break;
  23602. + }
  23603. + }
  23604. + }
  23605. +
  23606. + if (!shared_br || !shared_br->br_xino.xi_file) {
  23607. + struct au_xino_lock_dir ldir;
  23608. +
  23609. + au_xino_lock_dir(sb, base_file, &ldir);
  23610. + /* mnt_want_write() is unnecessary here */
  23611. + file = au_xino_create2(base_file, NULL);
  23612. + au_xino_unlock_dir(&ldir);
  23613. + err = PTR_ERR(file);
  23614. + if (IS_ERR(file))
  23615. + goto out;
  23616. + br->br_xino.xi_file = file;
  23617. + } else {
  23618. + br->br_xino.xi_file = shared_br->br_xino.xi_file;
  23619. + get_file(br->br_xino.xi_file);
  23620. + }
  23621. +
  23622. + ino = AUFS_ROOT_INO;
  23623. + err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
  23624. + h_ino, ino);
  23625. + if (!err)
  23626. + return 0; /* success */
  23627. +
  23628. +
  23629. + out:
  23630. + return err;
  23631. +}
  23632. +
  23633. +/* ---------------------------------------------------------------------- */
  23634. +
  23635. +/* trucate a xino bitmap file */
  23636. +
  23637. +/* todo: slow */
  23638. +static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
  23639. +{
  23640. + int err, bit;
  23641. + ssize_t sz;
  23642. + unsigned long pindex;
  23643. + loff_t pos, pend;
  23644. + struct au_sbinfo *sbinfo;
  23645. + au_readf_t func;
  23646. + ino_t *ino;
  23647. + unsigned long *p;
  23648. +
  23649. + err = 0;
  23650. + sbinfo = au_sbi(sb);
  23651. + MtxMustLock(&sbinfo->si_xib_mtx);
  23652. + p = sbinfo->si_xib_buf;
  23653. + func = sbinfo->si_xread;
  23654. + pend = i_size_read(file->f_dentry->d_inode);
  23655. + pos = 0;
  23656. + while (pos < pend) {
  23657. + sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
  23658. + err = sz;
  23659. + if (unlikely(sz <= 0))
  23660. + goto out;
  23661. +
  23662. + err = 0;
  23663. + for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
  23664. + if (unlikely(*ino < AUFS_FIRST_INO))
  23665. + continue;
  23666. +
  23667. + xib_calc_bit(*ino, &pindex, &bit);
  23668. + AuDebugOn(page_bits <= bit);
  23669. + err = xib_pindex(sb, pindex);
  23670. + if (!err)
  23671. + set_bit(bit, p);
  23672. + else
  23673. + goto out;
  23674. + }
  23675. + }
  23676. +
  23677. + out:
  23678. + return err;
  23679. +}
  23680. +
  23681. +static int xib_restore(struct super_block *sb)
  23682. +{
  23683. + int err;
  23684. + aufs_bindex_t bindex, bend;
  23685. + void *page;
  23686. +
  23687. + err = -ENOMEM;
  23688. + page = (void *)__get_free_page(GFP_NOFS);
  23689. + if (unlikely(!page))
  23690. + goto out;
  23691. +
  23692. + err = 0;
  23693. + bend = au_sbend(sb);
  23694. + for (bindex = 0; !err && bindex <= bend; bindex++)
  23695. + if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0)
  23696. + err = do_xib_restore
  23697. + (sb, au_sbr(sb, bindex)->br_xino.xi_file, page);
  23698. + else
  23699. + AuDbg("b%d\n", bindex);
  23700. + free_page((unsigned long)page);
  23701. +
  23702. + out:
  23703. + return err;
  23704. +}
  23705. +
  23706. +int au_xib_trunc(struct super_block *sb)
  23707. +{
  23708. + int err;
  23709. + ssize_t sz;
  23710. + loff_t pos;
  23711. + struct au_xino_lock_dir ldir;
  23712. + struct au_sbinfo *sbinfo;
  23713. + unsigned long *p;
  23714. + struct file *file;
  23715. +
  23716. + SiMustWriteLock(sb);
  23717. +
  23718. + err = 0;
  23719. + sbinfo = au_sbi(sb);
  23720. + if (!au_opt_test(sbinfo->si_mntflags, XINO))
  23721. + goto out;
  23722. +
  23723. + file = sbinfo->si_xib;
  23724. + if (i_size_read(file->f_dentry->d_inode) <= PAGE_SIZE)
  23725. + goto out;
  23726. +
  23727. + au_xino_lock_dir(sb, file, &ldir);
  23728. + /* mnt_want_write() is unnecessary here */
  23729. + file = au_xino_create2(sbinfo->si_xib, NULL);
  23730. + au_xino_unlock_dir(&ldir);
  23731. + err = PTR_ERR(file);
  23732. + if (IS_ERR(file))
  23733. + goto out;
  23734. + fput(sbinfo->si_xib);
  23735. + sbinfo->si_xib = file;
  23736. +
  23737. + p = sbinfo->si_xib_buf;
  23738. + memset(p, 0, PAGE_SIZE);
  23739. + pos = 0;
  23740. + sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
  23741. + if (unlikely(sz != PAGE_SIZE)) {
  23742. + err = sz;
  23743. + AuIOErr("err %d\n", err);
  23744. + if (sz >= 0)
  23745. + err = -EIO;
  23746. + goto out;
  23747. + }
  23748. +
  23749. + mutex_lock(&sbinfo->si_xib_mtx);
  23750. + /* mnt_want_write() is unnecessary here */
  23751. + err = xib_restore(sb);
  23752. + mutex_unlock(&sbinfo->si_xib_mtx);
  23753. +
  23754. +out:
  23755. + return err;
  23756. +}
  23757. +
  23758. +/* ---------------------------------------------------------------------- */
  23759. +
  23760. +/*
  23761. + * xino mount option handlers
  23762. + */
  23763. +static au_readf_t find_readf(struct file *h_file)
  23764. +{
  23765. + const struct file_operations *fop = h_file->f_op;
  23766. +
  23767. + if (fop) {
  23768. + if (fop->read)
  23769. + return fop->read;
  23770. + if (fop->aio_read)
  23771. + return do_sync_read;
  23772. + }
  23773. + return ERR_PTR(-ENOSYS);
  23774. +}
  23775. +
  23776. +static au_writef_t find_writef(struct file *h_file)
  23777. +{
  23778. + const struct file_operations *fop = h_file->f_op;
  23779. +
  23780. + if (fop) {
  23781. + if (fop->write)
  23782. + return fop->write;
  23783. + if (fop->aio_write)
  23784. + return do_sync_write;
  23785. + }
  23786. + return ERR_PTR(-ENOSYS);
  23787. +}
  23788. +
  23789. +/* xino bitmap */
  23790. +static void xino_clear_xib(struct super_block *sb)
  23791. +{
  23792. + struct au_sbinfo *sbinfo;
  23793. +
  23794. + SiMustWriteLock(sb);
  23795. +
  23796. + sbinfo = au_sbi(sb);
  23797. + sbinfo->si_xread = NULL;
  23798. + sbinfo->si_xwrite = NULL;
  23799. + if (sbinfo->si_xib)
  23800. + fput(sbinfo->si_xib);
  23801. + sbinfo->si_xib = NULL;
  23802. + free_page((unsigned long)sbinfo->si_xib_buf);
  23803. + sbinfo->si_xib_buf = NULL;
  23804. +}
  23805. +
  23806. +static int au_xino_set_xib(struct super_block *sb, struct file *base)
  23807. +{
  23808. + int err;
  23809. + loff_t pos;
  23810. + struct au_sbinfo *sbinfo;
  23811. + struct file *file;
  23812. +
  23813. + SiMustWriteLock(sb);
  23814. +
  23815. + sbinfo = au_sbi(sb);
  23816. + file = au_xino_create2(base, sbinfo->si_xib);
  23817. + err = PTR_ERR(file);
  23818. + if (IS_ERR(file))
  23819. + goto out;
  23820. + if (sbinfo->si_xib)
  23821. + fput(sbinfo->si_xib);
  23822. + sbinfo->si_xib = file;
  23823. + sbinfo->si_xread = find_readf(file);
  23824. + sbinfo->si_xwrite = find_writef(file);
  23825. +
  23826. + err = -ENOMEM;
  23827. + if (!sbinfo->si_xib_buf)
  23828. + sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
  23829. + if (unlikely(!sbinfo->si_xib_buf))
  23830. + goto out_unset;
  23831. +
  23832. + sbinfo->si_xib_last_pindex = 0;
  23833. + sbinfo->si_xib_next_bit = 0;
  23834. + if (i_size_read(file->f_dentry->d_inode) < PAGE_SIZE) {
  23835. + pos = 0;
  23836. + err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
  23837. + PAGE_SIZE, &pos);
  23838. + if (unlikely(err != PAGE_SIZE))
  23839. + goto out_free;
  23840. + }
  23841. + err = 0;
  23842. + goto out; /* success */
  23843. +
  23844. + out_free:
  23845. + free_page((unsigned long)sbinfo->si_xib_buf);
  23846. + sbinfo->si_xib_buf = NULL;
  23847. + if (err >= 0)
  23848. + err = -EIO;
  23849. + out_unset:
  23850. + fput(sbinfo->si_xib);
  23851. + sbinfo->si_xib = NULL;
  23852. + sbinfo->si_xread = NULL;
  23853. + sbinfo->si_xwrite = NULL;
  23854. + out:
  23855. + return err;
  23856. +}
  23857. +
  23858. +/* xino for each branch */
  23859. +static void xino_clear_br(struct super_block *sb)
  23860. +{
  23861. + aufs_bindex_t bindex, bend;
  23862. + struct au_branch *br;
  23863. +
  23864. + bend = au_sbend(sb);
  23865. + for (bindex = 0; bindex <= bend; bindex++) {
  23866. + br = au_sbr(sb, bindex);
  23867. + if (!br || !br->br_xino.xi_file)
  23868. + continue;
  23869. +
  23870. + fput(br->br_xino.xi_file);
  23871. + br->br_xino.xi_file = NULL;
  23872. + }
  23873. +}
  23874. +
  23875. +static int au_xino_set_br(struct super_block *sb, struct file *base)
  23876. +{
  23877. + int err;
  23878. + ino_t ino;
  23879. + aufs_bindex_t bindex, bend, bshared;
  23880. + struct {
  23881. + struct file *old, *new;
  23882. + } *fpair, *p;
  23883. + struct au_branch *br;
  23884. + struct inode *inode;
  23885. + au_writef_t writef;
  23886. +
  23887. + SiMustWriteLock(sb);
  23888. +
  23889. + err = -ENOMEM;
  23890. + bend = au_sbend(sb);
  23891. + fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS);
  23892. + if (unlikely(!fpair))
  23893. + goto out;
  23894. +
  23895. + inode = sb->s_root->d_inode;
  23896. + ino = AUFS_ROOT_INO;
  23897. + writef = au_sbi(sb)->si_xwrite;
  23898. + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
  23899. + br = au_sbr(sb, bindex);
  23900. + bshared = is_sb_shared(sb, bindex, bindex - 1);
  23901. + if (bshared >= 0) {
  23902. + /* shared xino */
  23903. + *p = fpair[bshared];
  23904. + get_file(p->new);
  23905. + }
  23906. +
  23907. + if (!p->new) {
  23908. + /* new xino */
  23909. + p->old = br->br_xino.xi_file;
  23910. + p->new = au_xino_create2(base, br->br_xino.xi_file);
  23911. + err = PTR_ERR(p->new);
  23912. + if (IS_ERR(p->new)) {
  23913. + p->new = NULL;
  23914. + goto out_pair;
  23915. + }
  23916. + }
  23917. +
  23918. + err = au_xino_do_write(writef, p->new,
  23919. + au_h_iptr(inode, bindex)->i_ino, ino);
  23920. + if (unlikely(err))
  23921. + goto out_pair;
  23922. + }
  23923. +
  23924. + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
  23925. + br = au_sbr(sb, bindex);
  23926. + if (br->br_xino.xi_file)
  23927. + fput(br->br_xino.xi_file);
  23928. + get_file(p->new);
  23929. + br->br_xino.xi_file = p->new;
  23930. + }
  23931. +
  23932. + out_pair:
  23933. + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++)
  23934. + if (p->new)
  23935. + fput(p->new);
  23936. + else
  23937. + break;
  23938. + kfree(fpair);
  23939. + out:
  23940. + return err;
  23941. +}
  23942. +
  23943. +void au_xino_clr(struct super_block *sb)
  23944. +{
  23945. + struct au_sbinfo *sbinfo;
  23946. +
  23947. + au_xigen_clr(sb);
  23948. + xino_clear_xib(sb);
  23949. + xino_clear_br(sb);
  23950. + sbinfo = au_sbi(sb);
  23951. + /* lvalue, do not call au_mntflags() */
  23952. + au_opt_clr(sbinfo->si_mntflags, XINO);
  23953. +}
  23954. +
  23955. +int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount)
  23956. +{
  23957. + int err, skip;
  23958. + struct dentry *parent, *cur_parent;
  23959. + struct qstr *dname, *cur_name;
  23960. + struct file *cur_xino;
  23961. + struct inode *dir;
  23962. + struct au_sbinfo *sbinfo;
  23963. +
  23964. + SiMustWriteLock(sb);
  23965. +
  23966. + err = 0;
  23967. + sbinfo = au_sbi(sb);
  23968. + parent = dget_parent(xino->file->f_dentry);
  23969. + if (remount) {
  23970. + skip = 0;
  23971. + dname = &xino->file->f_dentry->d_name;
  23972. + cur_xino = sbinfo->si_xib;
  23973. + if (cur_xino) {
  23974. + cur_parent = dget_parent(cur_xino->f_dentry);
  23975. + cur_name = &cur_xino->f_dentry->d_name;
  23976. + skip = (cur_parent == parent
  23977. + && dname->len == cur_name->len
  23978. + && !memcmp(dname->name, cur_name->name,
  23979. + dname->len));
  23980. + dput(cur_parent);
  23981. + }
  23982. + if (skip)
  23983. + goto out;
  23984. + }
  23985. +
  23986. + au_opt_set(sbinfo->si_mntflags, XINO);
  23987. + dir = parent->d_inode;
  23988. + mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT);
  23989. + /* mnt_want_write() is unnecessary here */
  23990. + err = au_xino_set_xib(sb, xino->file);
  23991. + if (!err)
  23992. + err = au_xigen_set(sb, xino->file);
  23993. + if (!err)
  23994. + err = au_xino_set_br(sb, xino->file);
  23995. + mutex_unlock(&dir->i_mutex);
  23996. + if (!err)
  23997. + goto out; /* success */
  23998. +
  23999. + /* reset all */
  24000. + AuIOErr("failed creating xino(%d).\n", err);
  24001. +
  24002. + out:
  24003. + dput(parent);
  24004. + return err;
  24005. +}
  24006. +
  24007. +/* ---------------------------------------------------------------------- */
  24008. +
  24009. +/*
  24010. + * create a xinofile at the default place/path.
  24011. + */
  24012. +struct file *au_xino_def(struct super_block *sb)
  24013. +{
  24014. + struct file *file;
  24015. + char *page, *p;
  24016. + struct au_branch *br;
  24017. + struct super_block *h_sb;
  24018. + struct path path;
  24019. + aufs_bindex_t bend, bindex, bwr;
  24020. +
  24021. + br = NULL;
  24022. + bend = au_sbend(sb);
  24023. + bwr = -1;
  24024. + for (bindex = 0; bindex <= bend; bindex++) {
  24025. + br = au_sbr(sb, bindex);
  24026. + if (au_br_writable(br->br_perm)
  24027. + && !au_test_fs_bad_xino(br->br_mnt->mnt_sb)) {
  24028. + bwr = bindex;
  24029. + break;
  24030. + }
  24031. + }
  24032. +
  24033. + if (bwr >= 0) {
  24034. + file = ERR_PTR(-ENOMEM);
  24035. + page = __getname();
  24036. + if (unlikely(!page))
  24037. + goto out;
  24038. + path.mnt = br->br_mnt;
  24039. + path.dentry = au_h_dptr(sb->s_root, bwr);
  24040. + p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
  24041. + file = (void *)p;
  24042. + if (!IS_ERR(p)) {
  24043. + strcat(p, "/" AUFS_XINO_FNAME);
  24044. + AuDbg("%s\n", p);
  24045. + file = au_xino_create(sb, p, /*silent*/0);
  24046. + if (!IS_ERR(file))
  24047. + au_xino_brid_set(sb, br->br_id);
  24048. + }
  24049. + __putname(page);
  24050. + } else {
  24051. + file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
  24052. + if (IS_ERR(file))
  24053. + goto out;
  24054. + h_sb = file->f_dentry->d_sb;
  24055. + if (unlikely(au_test_fs_bad_xino(h_sb))) {
  24056. + AuErr("xino doesn't support %s(%s)\n",
  24057. + AUFS_XINO_DEFPATH, au_sbtype(h_sb));
  24058. + fput(file);
  24059. + file = ERR_PTR(-EINVAL);
  24060. + }
  24061. + if (!IS_ERR(file))
  24062. + au_xino_brid_set(sb, -1);
  24063. + }
  24064. +
  24065. + out:
  24066. + return file;
  24067. +}
  24068. +
  24069. +/* ---------------------------------------------------------------------- */
  24070. +
  24071. +int au_xino_path(struct seq_file *seq, struct file *file)
  24072. +{
  24073. + int err;
  24074. +
  24075. + err = au_seq_path(seq, &file->f_path);
  24076. + if (unlikely(err < 0))
  24077. + goto out;
  24078. +
  24079. + err = 0;
  24080. +#define Deleted "\\040(deleted)"
  24081. + seq->count -= sizeof(Deleted) - 1;
  24082. + AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
  24083. + sizeof(Deleted) - 1));
  24084. +#undef Deleted
  24085. +
  24086. + out:
  24087. + return err;
  24088. +}
  24089. diff -Nur linux-2.6.34.orig/fs/Kconfig linux-2.6.34/fs/Kconfig
  24090. --- linux-2.6.34.orig/fs/Kconfig 2010-05-16 23:17:36.000000000 +0200
  24091. +++ linux-2.6.34/fs/Kconfig 2010-05-23 23:33:21.962123255 +0200
  24092. @@ -44,6 +44,7 @@
  24093. source "fs/ocfs2/Kconfig"
  24094. source "fs/btrfs/Kconfig"
  24095. source "fs/nilfs2/Kconfig"
  24096. +source "fs/aufs/Kconfig"
  24097. endif # BLOCK
  24098. diff -Nur linux-2.6.34.orig/fs/Makefile linux-2.6.34/fs/Makefile
  24099. --- linux-2.6.34.orig/fs/Makefile 2010-05-16 23:17:36.000000000 +0200
  24100. +++ linux-2.6.34/fs/Makefile 2010-05-23 23:33:22.023473125 +0200
  24101. @@ -85,6 +85,7 @@
  24102. obj-$(CONFIG_HFS_FS) += hfs/
  24103. obj-$(CONFIG_ECRYPT_FS) += ecryptfs/
  24104. obj-$(CONFIG_VXFS_FS) += freevxfs/
  24105. +obj-$(CONFIG_AUFS_FS) += aufs/
  24106. obj-$(CONFIG_NFS_FS) += nfs/
  24107. obj-$(CONFIG_EXPORTFS) += exportfs/
  24108. obj-$(CONFIG_NFSD) += nfsd/
  24109. diff -Nur linux-2.6.34.orig/fs/namei.c linux-2.6.34/fs/namei.c
  24110. --- linux-2.6.34.orig/fs/namei.c 2010-05-16 23:17:36.000000000 +0200
  24111. +++ linux-2.6.34/fs/namei.c 2010-05-23 23:33:22.061750745 +0200
  24112. @@ -348,6 +348,7 @@
  24113. return 0;
  24114. }
  24115. +EXPORT_SYMBOL(deny_write_access);
  24116. /**
  24117. * path_get - get a reference to a path
  24118. @@ -1177,7 +1178,7 @@
  24119. * needs parent already locked. Doesn't follow mounts.
  24120. * SMP-safe.
  24121. */
  24122. -static struct dentry *lookup_hash(struct nameidata *nd)
  24123. +struct dentry *lookup_hash(struct nameidata *nd)
  24124. {
  24125. int err;
  24126. @@ -1186,8 +1187,9 @@
  24127. return ERR_PTR(err);
  24128. return __lookup_hash(&nd->last, nd->path.dentry, nd);
  24129. }
  24130. +EXPORT_SYMBOL(lookup_hash);
  24131. -static int __lookup_one_len(const char *name, struct qstr *this,
  24132. +int __lookup_one_len(const char *name, struct qstr *this,
  24133. struct dentry *base, int len)
  24134. {
  24135. unsigned long hash;
  24136. @@ -1208,6 +1210,7 @@
  24137. this->hash = end_name_hash(hash);
  24138. return 0;
  24139. }
  24140. +EXPORT_SYMBOL(__lookup_one_len);
  24141. /**
  24142. * lookup_one_len - filesystem helper to lookup single pathname component
  24143. diff -Nur linux-2.6.34.orig/fs/namespace.c linux-2.6.34/fs/namespace.c
  24144. --- linux-2.6.34.orig/fs/namespace.c 2010-05-16 23:17:36.000000000 +0200
  24145. +++ linux-2.6.34/fs/namespace.c 2010-05-23 23:33:22.113473124 +0200
  24146. @@ -39,6 +39,7 @@
  24147. /* spinlock for vfsmount related operations, inplace of dcache_lock */
  24148. __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock);
  24149. +EXPORT_SYMBOL(vfsmount_lock);
  24150. static int event;
  24151. static DEFINE_IDA(mnt_id_ida);
  24152. diff -Nur linux-2.6.34.orig/fs/open.c linux-2.6.34/fs/open.c
  24153. --- linux-2.6.34.orig/fs/open.c 2010-05-16 23:17:36.000000000 +0200
  24154. +++ linux-2.6.34/fs/open.c 2010-05-23 23:33:22.193472989 +0200
  24155. @@ -225,6 +225,7 @@
  24156. mutex_unlock(&dentry->d_inode->i_mutex);
  24157. return ret;
  24158. }
  24159. +EXPORT_SYMBOL(do_truncate);
  24160. static long do_sys_truncate(const char __user *pathname, loff_t length)
  24161. {
  24162. diff -Nur linux-2.6.34.orig/fs/splice.c linux-2.6.34/fs/splice.c
  24163. --- linux-2.6.34.orig/fs/splice.c 2010-05-16 23:17:36.000000000 +0200
  24164. +++ linux-2.6.34/fs/splice.c 2010-05-23 23:33:22.223464538 +0200
  24165. @@ -1054,8 +1054,8 @@
  24166. /*
  24167. * Attempt to initiate a splice from pipe to file.
  24168. */
  24169. -static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  24170. - loff_t *ppos, size_t len, unsigned int flags)
  24171. +long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  24172. + loff_t *ppos, size_t len, unsigned int flags)
  24173. {
  24174. ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
  24175. loff_t *, size_t, unsigned int);
  24176. @@ -1078,13 +1078,14 @@
  24177. return splice_write(pipe, out, ppos, len, flags);
  24178. }
  24179. +EXPORT_SYMBOL(do_splice_from);
  24180. /*
  24181. * Attempt to initiate a splice from a file to a pipe.
  24182. */
  24183. -static long do_splice_to(struct file *in, loff_t *ppos,
  24184. - struct pipe_inode_info *pipe, size_t len,
  24185. - unsigned int flags)
  24186. +long do_splice_to(struct file *in, loff_t *ppos,
  24187. + struct pipe_inode_info *pipe, size_t len,
  24188. + unsigned int flags)
  24189. {
  24190. ssize_t (*splice_read)(struct file *, loff_t *,
  24191. struct pipe_inode_info *, size_t, unsigned int);
  24192. @@ -1104,6 +1105,7 @@
  24193. return splice_read(in, ppos, pipe, len, flags);
  24194. }
  24195. +EXPORT_SYMBOL(do_splice_to);
  24196. /**
  24197. * splice_direct_to_actor - splices data directly between two non-pipes
  24198. diff -Nur linux-2.6.34.orig/include/linux/aufs_type.h linux-2.6.34/include/linux/aufs_type.h
  24199. --- linux-2.6.34.orig/include/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
  24200. +++ linux-2.6.34/include/linux/aufs_type.h 2010-05-23 23:33:22.311715313 +0200
  24201. @@ -0,0 +1,109 @@
  24202. +/*
  24203. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  24204. + *
  24205. + * This program, aufs is free software; you can redistribute it and/or modify
  24206. + * it under the terms of the GNU General Public License as published by
  24207. + * the Free Software Foundation; either version 2 of the License, or
  24208. + * (at your option) any later version.
  24209. + *
  24210. + * This program is distributed in the hope that it will be useful,
  24211. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24212. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24213. + * GNU General Public License for more details.
  24214. + *
  24215. + * You should have received a copy of the GNU General Public License
  24216. + * along with this program; if not, write to the Free Software
  24217. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  24218. + */
  24219. +
  24220. +#ifndef __AUFS_TYPE_H__
  24221. +#define __AUFS_TYPE_H__
  24222. +
  24223. +#include <linux/ioctl.h>
  24224. +
  24225. +#define AUFS_VERSION "2-standalone.tree-30-20090803"
  24226. +
  24227. +/* todo? move this to linux-2.6.19/include/magic.h */
  24228. +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
  24229. +
  24230. +/* ---------------------------------------------------------------------- */
  24231. +
  24232. +#ifdef CONFIG_AUFS_BRANCH_MAX_127
  24233. +/* some environments treat 'char' as 'unsigned char' by default */
  24234. +typedef signed char aufs_bindex_t;
  24235. +#define AUFS_BRANCH_MAX 127
  24236. +#else
  24237. +typedef short aufs_bindex_t;
  24238. +#ifdef CONFIG_AUFS_BRANCH_MAX_511
  24239. +#define AUFS_BRANCH_MAX 511
  24240. +#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
  24241. +#define AUFS_BRANCH_MAX 1023
  24242. +#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
  24243. +#define AUFS_BRANCH_MAX 32767
  24244. +#endif
  24245. +#endif
  24246. +
  24247. +#ifdef __KERNEL__
  24248. +#ifndef AUFS_BRANCH_MAX
  24249. +#error unknown CONFIG_AUFS_BRANCH_MAX value
  24250. +#endif
  24251. +#endif /* __KERNEL__ */
  24252. +
  24253. +/* ---------------------------------------------------------------------- */
  24254. +
  24255. +#define AUFS_NAME "aufs"
  24256. +#define AUFS_FSTYPE AUFS_NAME
  24257. +
  24258. +#define AUFS_ROOT_INO 2
  24259. +#define AUFS_FIRST_INO 11
  24260. +
  24261. +#define AUFS_WH_PFX ".wh."
  24262. +#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1)
  24263. +#define AUFS_XINO_FNAME "." AUFS_NAME ".xino"
  24264. +#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME
  24265. +#define AUFS_XINO_TRUNC_INIT 64 /* blocks */
  24266. +#define AUFS_XINO_TRUNC_STEP 4 /* blocks */
  24267. +#define AUFS_DIRWH_DEF 3
  24268. +#define AUFS_RDCACHE_DEF 10 /* seconds */
  24269. +#define AUFS_RDBLK_DEF 512 /* bytes */
  24270. +#define AUFS_RDHASH_DEF 32
  24271. +#define AUFS_WKQ_NAME AUFS_NAME "d"
  24272. +#define AUFS_NWKQ_DEF 4
  24273. +#define AUFS_MFS_SECOND_DEF 30 /* seconds */
  24274. +#define AUFS_PLINK_WARN 100 /* number of plinks */
  24275. +
  24276. +#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */
  24277. +#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME
  24278. +
  24279. +#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME
  24280. +#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk"
  24281. +#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph"
  24282. +
  24283. +/* doubly whiteouted */
  24284. +#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME
  24285. +#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME
  24286. +#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME
  24287. +
  24288. +/* branch permission */
  24289. +#define AUFS_BRPERM_RW "rw"
  24290. +#define AUFS_BRPERM_RO "ro"
  24291. +#define AUFS_BRPERM_RR "rr"
  24292. +#define AUFS_BRPERM_WH "wh"
  24293. +#define AUFS_BRPERM_NLWH "nolwh"
  24294. +#define AUFS_BRPERM_ROWH AUFS_BRPERM_RO "+" AUFS_BRPERM_WH
  24295. +#define AUFS_BRPERM_RRWH AUFS_BRPERM_RR "+" AUFS_BRPERM_WH
  24296. +#define AUFS_BRPERM_RWNLWH AUFS_BRPERM_RW "+" AUFS_BRPERM_NLWH
  24297. +
  24298. +/* ---------------------------------------------------------------------- */
  24299. +
  24300. +/* ioctl */
  24301. +enum {
  24302. + AuCtl_PLINK_MAINT,
  24303. + AuCtl_PLINK_CLEAN
  24304. +};
  24305. +
  24306. +#define AuCtlType 'A'
  24307. +#define AUFS_CTL_PLINK_MAINT _IO(AuCtlType, AuCtl_PLINK_MAINT)
  24308. +#define AUFS_CTL_PLINK_CLEAN _IO(AuCtlType, AuCtl_PLINK_CLEAN)
  24309. +
  24310. +#endif /* __AUFS_TYPE_H__ */
  24311. diff -Nur linux-2.6.34.orig/include/linux/Kbuild linux-2.6.34/include/linux/Kbuild
  24312. --- linux-2.6.34.orig/include/linux/Kbuild 2010-05-16 23:17:36.000000000 +0200
  24313. +++ linux-2.6.34/include/linux/Kbuild 2010-05-23 23:33:22.351651089 +0200
  24314. @@ -34,6 +34,7 @@
  24315. header-y += atmsap.h
  24316. header-y += atmsvc.h
  24317. header-y += atm_zatm.h
  24318. +header-y += aufs_type.h
  24319. header-y += auto_fs4.h
  24320. header-y += ax25.h
  24321. header-y += b1lli.h
  24322. diff -Nur linux-2.6.34.orig/include/linux/namei.h linux-2.6.34/include/linux/namei.h
  24323. --- linux-2.6.34.orig/include/linux/namei.h 2010-05-16 23:17:36.000000000 +0200
  24324. +++ linux-2.6.34/include/linux/namei.h 2010-05-23 23:33:22.402167374 +0200
  24325. @@ -73,6 +73,9 @@
  24326. extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
  24327. int (*open)(struct inode *, struct file *));
  24328. +extern struct dentry *lookup_hash(struct nameidata *nd);
  24329. +extern int __lookup_one_len(const char *name, struct qstr *this,
  24330. + struct dentry *base, int len);
  24331. extern struct dentry *lookup_one_len(const char *, struct dentry *, int);
  24332. extern int follow_down(struct path *);
  24333. diff -Nur linux-2.6.34.orig/include/linux/splice.h linux-2.6.34/include/linux/splice.h
  24334. --- linux-2.6.34.orig/include/linux/splice.h 2010-05-16 23:17:36.000000000 +0200
  24335. +++ linux-2.6.34/include/linux/splice.h 2010-05-23 23:33:22.443475345 +0200
  24336. @@ -82,4 +82,10 @@
  24337. extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *,
  24338. splice_direct_actor *);
  24339. +extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  24340. + loff_t *ppos, size_t len, unsigned int flags);
  24341. +extern long do_splice_to(struct file *in, loff_t *ppos,
  24342. + struct pipe_inode_info *pipe, size_t len,
  24343. + unsigned int flags);
  24344. +
  24345. #endif
  24346. diff -Nur linux-2.6.34.orig/security/device_cgroup.c linux-2.6.34/security/device_cgroup.c
  24347. --- linux-2.6.34.orig/security/device_cgroup.c 2010-05-16 23:17:36.000000000 +0200
  24348. +++ linux-2.6.34/security/device_cgroup.c 2010-05-23 23:33:22.523473073 +0200
  24349. @@ -515,6 +515,7 @@
  24350. return -EPERM;
  24351. }
  24352. +EXPORT_SYMBOL(devcgroup_inode_permission);
  24353. int devcgroup_inode_mknod(int mode, dev_t dev)
  24354. {
  24355. diff -Nur linux-2.6.34.orig/security/security.c linux-2.6.34/security/security.c
  24356. --- linux-2.6.34.orig/security/security.c 2010-05-16 23:17:36.000000000 +0200
  24357. +++ linux-2.6.34/security/security.c 2010-05-23 23:33:22.553464163 +0200
  24358. @@ -385,6 +385,7 @@
  24359. ima_inode_free(inode);
  24360. security_ops->inode_free_security(inode);
  24361. }
  24362. +EXPORT_SYMBOL(security_path_mkdir);
  24363. int security_inode_init_security(struct inode *inode, struct inode *dir,
  24364. char **name, void **value, size_t *len)
  24365. @@ -411,6 +412,7 @@
  24366. return 0;
  24367. return security_ops->path_mkdir(dir, dentry, mode);
  24368. }
  24369. +EXPORT_SYMBOL(security_path_rmdir);
  24370. int security_path_rmdir(struct path *dir, struct dentry *dentry)
  24371. {
  24372. @@ -418,6 +420,7 @@
  24373. return 0;
  24374. return security_ops->path_rmdir(dir, dentry);
  24375. }
  24376. +EXPORT_SYMBOL(security_path_unlink);
  24377. int security_path_unlink(struct path *dir, struct dentry *dentry)
  24378. {
  24379. @@ -425,6 +428,7 @@
  24380. return 0;
  24381. return security_ops->path_unlink(dir, dentry);
  24382. }
  24383. +EXPORT_SYMBOL(security_path_symlink);
  24384. int security_path_symlink(struct path *dir, struct dentry *dentry,
  24385. const char *old_name)
  24386. @@ -441,6 +445,7 @@
  24387. return 0;
  24388. return security_ops->path_link(old_dentry, new_dir, new_dentry);
  24389. }
  24390. +EXPORT_SYMBOL(security_path_link);
  24391. int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
  24392. struct path *new_dir, struct dentry *new_dentry)
  24393. @@ -451,6 +456,7 @@
  24394. return security_ops->path_rename(old_dir, old_dentry, new_dir,
  24395. new_dentry);
  24396. }
  24397. +EXPORT_SYMBOL(security_path_rename);
  24398. int security_path_truncate(struct path *path, loff_t length,
  24399. unsigned int time_attrs)
  24400. @@ -479,6 +485,7 @@
  24401. {
  24402. return security_ops->path_chroot(path);
  24403. }
  24404. +EXPORT_SYMBOL(security_path_truncate);
  24405. #endif
  24406. int security_inode_create(struct inode *dir, struct dentry *dentry, int mode)
  24407. @@ -550,6 +557,7 @@
  24408. return 0;
  24409. return security_ops->inode_readlink(dentry);
  24410. }
  24411. +EXPORT_SYMBOL(security_inode_readlink);
  24412. int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
  24413. {
  24414. @@ -564,6 +572,7 @@
  24415. return 0;
  24416. return security_ops->inode_permission(inode, mask);
  24417. }
  24418. +EXPORT_SYMBOL(security_inode_permission);
  24419. int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
  24420. {
  24421. @@ -664,6 +673,7 @@
  24422. {
  24423. return security_ops->file_permission(file, mask);
  24424. }
  24425. +EXPORT_SYMBOL(security_file_permission);
  24426. int security_file_alloc(struct file *file)
  24427. {