aufs2.patch 610 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455
  1. diff -Nur linux-2.6.31.5.orig/Documentation/ABI/testing/debugfs-aufs linux-2.6.31.5/Documentation/ABI/testing/debugfs-aufs
  2. --- linux-2.6.31.5.orig/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100
  3. +++ linux-2.6.31.5/Documentation/ABI/testing/debugfs-aufs 2009-11-15 22:02:37.000000000 +0100
  4. @@ -0,0 +1,40 @@
  5. +What: /debug/aufs/si_<id>/
  6. +Date: March 2009
  7. +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
  8. +Description:
  9. + Under /debug/aufs, a directory named si_<id> is created
  10. + per aufs mount, where <id> is a unique id generated
  11. + internally.
  12. +
  13. +What: /debug/aufs/si_<id>/xib
  14. +Date: March 2009
  15. +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
  16. +Description:
  17. + It shows the consumed blocks by xib (External Inode Number
  18. + Bitmap), its block size and file size.
  19. + When the aufs mount option 'noxino' is specified, it
  20. + will be empty. About XINO files, see
  21. + Documentation/filesystems/aufs/aufs.5 in detail.
  22. +
  23. +What: /debug/aufs/si_<id>/xino0, xino1 ... xinoN
  24. +Date: March 2009
  25. +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
  26. +Description:
  27. + It shows the consumed blocks by xino (External Inode Number
  28. + Translation Table), its link count, block size and file
  29. + size.
  30. + When the aufs mount option 'noxino' is specified, it
  31. + will be empty. About XINO files, see
  32. + Documentation/filesystems/aufs/aufs.5 in detail.
  33. +
  34. +What: /debug/aufs/si_<id>/xigen
  35. +Date: March 2009
  36. +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
  37. +Description:
  38. + It shows the consumed blocks by xigen (External Inode
  39. + Generation Table), its block size and file size.
  40. + If CONFIG_AUFS_EXPORT is disabled, this entry will not
  41. + be created.
  42. + When the aufs mount option 'noxino' is specified, it
  43. + will be empty. About XINO files, see
  44. + Documentation/filesystems/aufs/aufs.5 in detail.
  45. diff -Nur linux-2.6.31.5.orig/Documentation/ABI/testing/sysfs-aufs linux-2.6.31.5/Documentation/ABI/testing/sysfs-aufs
  46. --- linux-2.6.31.5.orig/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100
  47. +++ linux-2.6.31.5/Documentation/ABI/testing/sysfs-aufs 2009-11-15 22:02:37.000000000 +0100
  48. @@ -0,0 +1,25 @@
  49. +What: /sys/fs/aufs/si_<id>/
  50. +Date: March 2009
  51. +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
  52. +Description:
  53. + Under /sys/fs/aufs, a directory named si_<id> is created
  54. + per aufs mount, where <id> is a unique id generated
  55. + internally.
  56. +
  57. +What: /sys/fs/aufs/si_<id>/br0, br1 ... brN
  58. +Date: March 2009
  59. +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
  60. +Description:
  61. + It shows the abolute path of a member directory (which
  62. + is called branch) in aufs, and its permission.
  63. +
  64. +What: /sys/fs/aufs/si_<id>/xi_path
  65. +Date: March 2009
  66. +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
  67. +Description:
  68. + It shows the abolute path of XINO (External Inode Number
  69. + Bitmap, Translation Table and Generation Table) file
  70. + even if it is the default path.
  71. + When the aufs mount option 'noxino' is specified, it
  72. + will be empty. About XINO files, see
  73. + Documentation/filesystems/aufs/aufs.5 in detail.
  74. diff -Nur linux-2.6.31.5.orig/fs/aufs/aufs.h linux-2.6.31.5/fs/aufs/aufs.h
  75. --- linux-2.6.31.5.orig/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100
  76. +++ linux-2.6.31.5/fs/aufs/aufs.h 2009-11-15 22:02:37.000000000 +0100
  77. @@ -0,0 +1,51 @@
  78. +/*
  79. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  80. + *
  81. + * This program, aufs is free software; you can redistribute it and/or modify
  82. + * it under the terms of the GNU General Public License as published by
  83. + * the Free Software Foundation; either version 2 of the License, or
  84. + * (at your option) any later version.
  85. + *
  86. + * This program is distributed in the hope that it will be useful,
  87. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  88. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  89. + * GNU General Public License for more details.
  90. + *
  91. + * You should have received a copy of the GNU General Public License
  92. + * along with this program; if not, write to the Free Software
  93. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  94. + */
  95. +
  96. +/*
  97. + * all header files
  98. + */
  99. +
  100. +#ifndef __AUFS_H__
  101. +#define __AUFS_H__
  102. +
  103. +#ifdef __KERNEL__
  104. +
  105. +#include "debug.h"
  106. +
  107. +#include "branch.h"
  108. +#include "cpup.h"
  109. +#include "dcsub.h"
  110. +#include "dbgaufs.h"
  111. +#include "dentry.h"
  112. +#include "dir.h"
  113. +#include "file.h"
  114. +#include "fstype.h"
  115. +#include "inode.h"
  116. +#include "loop.h"
  117. +#include "module.h"
  118. +#include "opts.h"
  119. +#include "rwsem.h"
  120. +#include "spl.h"
  121. +#include "super.h"
  122. +#include "sysaufs.h"
  123. +#include "vfsub.h"
  124. +#include "whout.h"
  125. +#include "wkq.h"
  126. +
  127. +#endif /* __KERNEL__ */
  128. +#endif /* __AUFS_H__ */
  129. diff -Nur linux-2.6.31.5.orig/fs/aufs/branch.c linux-2.6.31.5/fs/aufs/branch.c
  130. --- linux-2.6.31.5.orig/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100
  131. +++ linux-2.6.31.5/fs/aufs/branch.c 2009-11-15 22:02:37.000000000 +0100
  132. @@ -0,0 +1,974 @@
  133. +/*
  134. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  135. + *
  136. + * This program, aufs is free software; you can redistribute it and/or modify
  137. + * it under the terms of the GNU General Public License as published by
  138. + * the Free Software Foundation; either version 2 of the License, or
  139. + * (at your option) any later version.
  140. + *
  141. + * This program is distributed in the hope that it will be useful,
  142. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  143. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  144. + * GNU General Public License for more details.
  145. + *
  146. + * You should have received a copy of the GNU General Public License
  147. + * along with this program; if not, write to the Free Software
  148. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  149. + */
  150. +
  151. +/*
  152. + * branch management
  153. + */
  154. +
  155. +#include <linux/file.h>
  156. +#include "aufs.h"
  157. +
  158. +/*
  159. + * free a single branch
  160. + */
  161. +static void au_br_do_free(struct au_branch *br)
  162. +{
  163. + int i;
  164. + struct au_wbr *wbr;
  165. +
  166. + if (br->br_xino.xi_file)
  167. + fput(br->br_xino.xi_file);
  168. + mutex_destroy(&br->br_xino.xi_nondir_mtx);
  169. +
  170. + AuDebugOn(atomic_read(&br->br_count));
  171. +
  172. + wbr = br->br_wbr;
  173. + if (wbr) {
  174. + for (i = 0; i < AuBrWh_Last; i++)
  175. + dput(wbr->wbr_wh[i]);
  176. + AuDebugOn(atomic_read(&wbr->wbr_wh_running));
  177. + AuRwDestroy(&wbr->wbr_wh_rwsem);
  178. + }
  179. +
  180. + /* some filesystems acquire extra lock */
  181. + lockdep_off();
  182. + mntput(br->br_mnt);
  183. + lockdep_on();
  184. +
  185. + kfree(wbr);
  186. + kfree(br);
  187. +}
  188. +
  189. +/*
  190. + * frees all branches
  191. + */
  192. +void au_br_free(struct au_sbinfo *sbinfo)
  193. +{
  194. + aufs_bindex_t bmax;
  195. + struct au_branch **br;
  196. +
  197. + AuRwMustWriteLock(&sbinfo->si_rwsem);
  198. +
  199. + bmax = sbinfo->si_bend + 1;
  200. + br = sbinfo->si_branch;
  201. + while (bmax--)
  202. + au_br_do_free(*br++);
  203. +}
  204. +
  205. +/*
  206. + * find the index of a branch which is specified by @br_id.
  207. + */
  208. +int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
  209. +{
  210. + aufs_bindex_t bindex, bend;
  211. +
  212. + bend = au_sbend(sb);
  213. + for (bindex = 0; bindex <= bend; bindex++)
  214. + if (au_sbr_id(sb, bindex) == br_id)
  215. + return bindex;
  216. + return -1;
  217. +}
  218. +
  219. +/* ---------------------------------------------------------------------- */
  220. +
  221. +/*
  222. + * add a branch
  223. + */
  224. +
  225. +static int test_overlap(struct super_block *sb, struct dentry *h_d1,
  226. + struct dentry *h_d2)
  227. +{
  228. + if (unlikely(h_d1 == h_d2))
  229. + return 1;
  230. + return !!au_test_subdir(h_d1, h_d2)
  231. + || !!au_test_subdir(h_d2, h_d1)
  232. + || au_test_loopback_overlap(sb, h_d1, h_d2)
  233. + || au_test_loopback_overlap(sb, h_d2, h_d1);
  234. +}
  235. +
  236. +/*
  237. + * returns a newly allocated branch. @new_nbranch is a number of branches
  238. + * after adding a branch.
  239. + */
  240. +static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
  241. + int perm)
  242. +{
  243. + struct au_branch *add_branch;
  244. + struct dentry *root;
  245. +
  246. + root = sb->s_root;
  247. + add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS);
  248. + if (unlikely(!add_branch))
  249. + goto out;
  250. +
  251. + add_branch->br_wbr = NULL;
  252. + if (au_br_writable(perm)) {
  253. + /* may be freed separately at changing the branch permission */
  254. + add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr),
  255. + GFP_NOFS);
  256. + if (unlikely(!add_branch->br_wbr))
  257. + goto out_br;
  258. + }
  259. +
  260. + if (unlikely(au_sbr_realloc(au_sbi(sb), new_nbranch)
  261. + || au_di_realloc(au_di(root), new_nbranch)
  262. + || au_ii_realloc(au_ii(root->d_inode), new_nbranch)))
  263. + goto out_wbr;
  264. + return add_branch; /* success */
  265. +
  266. + out_wbr:
  267. + kfree(add_branch->br_wbr);
  268. + out_br:
  269. + kfree(add_branch);
  270. + out:
  271. + return ERR_PTR(-ENOMEM);
  272. +}
  273. +
  274. +/*
  275. + * test if the branch permission is legal or not.
  276. + */
  277. +static int test_br(struct inode *inode, int brperm, char *path)
  278. +{
  279. + int err;
  280. +
  281. + err = 0;
  282. + if (unlikely(au_br_writable(brperm) && IS_RDONLY(inode))) {
  283. + AuErr("write permission for readonly mount or inode, %s\n",
  284. + path);
  285. + err = -EINVAL;
  286. + }
  287. +
  288. + return err;
  289. +}
  290. +
  291. +/*
  292. + * returns:
  293. + * 0: success, the caller will add it
  294. + * plus: success, it is already unified, the caller should ignore it
  295. + * minus: error
  296. + */
  297. +static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
  298. +{
  299. + int err;
  300. + aufs_bindex_t bend, bindex;
  301. + struct dentry *root;
  302. + struct inode *inode, *h_inode;
  303. +
  304. + root = sb->s_root;
  305. + bend = au_sbend(sb);
  306. + if (unlikely(bend >= 0
  307. + && au_find_dbindex(root, add->path.dentry) >= 0)) {
  308. + err = 1;
  309. + if (!remount) {
  310. + err = -EINVAL;
  311. + AuErr("%s duplicated\n", add->pathname);
  312. + }
  313. + goto out;
  314. + }
  315. +
  316. + err = -ENOSPC; /* -E2BIG; */
  317. + if (unlikely(AUFS_BRANCH_MAX <= add->bindex
  318. + || AUFS_BRANCH_MAX - 1 <= bend)) {
  319. + AuErr("number of branches exceeded %s\n", add->pathname);
  320. + goto out;
  321. + }
  322. +
  323. + err = -EDOM;
  324. + if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) {
  325. + AuErr("bad index %d\n", add->bindex);
  326. + goto out;
  327. + }
  328. +
  329. + inode = add->path.dentry->d_inode;
  330. + err = -ENOENT;
  331. + if (unlikely(!inode->i_nlink)) {
  332. + AuErr("no existence %s\n", add->pathname);
  333. + goto out;
  334. + }
  335. +
  336. + err = -EINVAL;
  337. + if (unlikely(inode->i_sb == sb)) {
  338. + AuErr("%s must be outside\n", add->pathname);
  339. + goto out;
  340. + }
  341. +
  342. + if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
  343. + AuErr("unsupported filesystem, %s (%s)\n",
  344. + add->pathname, au_sbtype(inode->i_sb));
  345. + goto out;
  346. + }
  347. +
  348. + err = test_br(add->path.dentry->d_inode, add->perm, add->pathname);
  349. + if (unlikely(err))
  350. + goto out;
  351. +
  352. + if (bend < 0)
  353. + return 0; /* success */
  354. +
  355. + err = -EINVAL;
  356. + for (bindex = 0; bindex <= bend; bindex++)
  357. + if (unlikely(test_overlap(sb, add->path.dentry,
  358. + au_h_dptr(root, bindex)))) {
  359. + AuErr("%s is overlapped\n", add->pathname);
  360. + goto out;
  361. + }
  362. +
  363. + err = 0;
  364. + if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
  365. + h_inode = au_h_dptr(root, 0)->d_inode;
  366. + if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
  367. + || h_inode->i_uid != inode->i_uid
  368. + || h_inode->i_gid != inode->i_gid)
  369. + AuWarn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
  370. + add->pathname,
  371. + inode->i_uid, inode->i_gid,
  372. + (inode->i_mode & S_IALLUGO),
  373. + h_inode->i_uid, h_inode->i_gid,
  374. + (h_inode->i_mode & S_IALLUGO));
  375. + }
  376. +
  377. + out:
  378. + return err;
  379. +}
  380. +
  381. +/*
  382. + * initialize or clean the whiteouts for an adding branch
  383. + */
  384. +static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
  385. + int new_perm, struct dentry *h_root)
  386. +{
  387. + int err, old_perm;
  388. + aufs_bindex_t bindex;
  389. + struct mutex *h_mtx;
  390. + struct au_wbr *wbr;
  391. + struct au_hinode *hdir;
  392. +
  393. + wbr = br->br_wbr;
  394. + old_perm = br->br_perm;
  395. + br->br_perm = new_perm;
  396. + hdir = NULL;
  397. + h_mtx = NULL;
  398. + bindex = au_br_index(sb, br->br_id);
  399. + if (0 <= bindex) {
  400. + hdir = au_hi(sb->s_root->d_inode, bindex);
  401. + au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT);
  402. + } else {
  403. + h_mtx = &h_root->d_inode->i_mutex;
  404. + mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
  405. + }
  406. + if (!wbr)
  407. + err = au_wh_init(h_root, br, sb);
  408. + else {
  409. + wbr_wh_write_lock(wbr);
  410. + err = au_wh_init(h_root, br, sb);
  411. + wbr_wh_write_unlock(wbr);
  412. + }
  413. + if (hdir)
  414. + au_hin_imtx_unlock(hdir);
  415. + else
  416. + mutex_unlock(h_mtx);
  417. + br->br_perm = old_perm;
  418. +
  419. + if (!err && wbr && !au_br_writable(new_perm)) {
  420. + kfree(wbr);
  421. + br->br_wbr = NULL;
  422. + }
  423. +
  424. + return err;
  425. +}
  426. +
  427. +static int au_wbr_init(struct au_branch *br, struct super_block *sb,
  428. + int perm, struct path *path)
  429. +{
  430. + int err;
  431. + struct au_wbr *wbr;
  432. +
  433. + wbr = br->br_wbr;
  434. + au_rw_init(&wbr->wbr_wh_rwsem);
  435. + memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh));
  436. + atomic_set(&wbr->wbr_wh_running, 0);
  437. + wbr->wbr_bytes = 0;
  438. +
  439. + err = au_br_init_wh(sb, br, perm, path->dentry);
  440. +
  441. + return err;
  442. +}
  443. +
  444. +/* intialize a new branch */
  445. +static int au_br_init(struct au_branch *br, struct super_block *sb,
  446. + struct au_opt_add *add)
  447. +{
  448. + int err;
  449. +
  450. + err = 0;
  451. + memset(&br->br_xino, 0, sizeof(br->br_xino));
  452. + mutex_init(&br->br_xino.xi_nondir_mtx);
  453. + br->br_perm = add->perm;
  454. + br->br_mnt = add->path.mnt; /* set first, mntget() later */
  455. + atomic_set(&br->br_count, 0);
  456. + br->br_xino_upper = AUFS_XINO_TRUNC_INIT;
  457. + atomic_set(&br->br_xino_running, 0);
  458. + br->br_id = au_new_br_id(sb);
  459. +
  460. + if (au_br_writable(add->perm)) {
  461. + err = au_wbr_init(br, sb, add->perm, &add->path);
  462. + if (unlikely(err))
  463. + goto out;
  464. + }
  465. +
  466. + if (au_opt_test(au_mntflags(sb), XINO)) {
  467. + err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino,
  468. + au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
  469. + if (unlikely(err)) {
  470. + AuDebugOn(br->br_xino.xi_file);
  471. + goto out;
  472. + }
  473. + }
  474. +
  475. + sysaufs_br_init(br);
  476. + mntget(add->path.mnt);
  477. +
  478. + out:
  479. + return err;
  480. +}
  481. +
  482. +static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
  483. + struct au_branch *br, aufs_bindex_t bend,
  484. + aufs_bindex_t amount)
  485. +{
  486. + struct au_branch **brp;
  487. +
  488. + AuRwMustWriteLock(&sbinfo->si_rwsem);
  489. +
  490. + brp = sbinfo->si_branch + bindex;
  491. + memmove(brp + 1, brp, sizeof(*brp) * amount);
  492. + *brp = br;
  493. + sbinfo->si_bend++;
  494. + if (unlikely(bend < 0))
  495. + sbinfo->si_bend = 0;
  496. +}
  497. +
  498. +static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
  499. + aufs_bindex_t bend, aufs_bindex_t amount)
  500. +{
  501. + struct au_hdentry *hdp;
  502. +
  503. + AuRwMustWriteLock(&dinfo->di_rwsem);
  504. +
  505. + hdp = dinfo->di_hdentry + bindex;
  506. + memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
  507. + au_h_dentry_init(hdp);
  508. + dinfo->di_bend++;
  509. + if (unlikely(bend < 0))
  510. + dinfo->di_bstart = 0;
  511. +}
  512. +
  513. +static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
  514. + aufs_bindex_t bend, aufs_bindex_t amount)
  515. +{
  516. + struct au_hinode *hip;
  517. +
  518. + AuRwMustWriteLock(&iinfo->ii_rwsem);
  519. +
  520. + hip = iinfo->ii_hinode + bindex;
  521. + memmove(hip + 1, hip, sizeof(*hip) * amount);
  522. + hip->hi_inode = NULL;
  523. + au_hin_init(hip, NULL);
  524. + iinfo->ii_bend++;
  525. + if (unlikely(bend < 0))
  526. + iinfo->ii_bstart = 0;
  527. +}
  528. +
  529. +static void au_br_do_add(struct super_block *sb, struct dentry *h_dentry,
  530. + struct au_branch *br, aufs_bindex_t bindex)
  531. +{
  532. + struct dentry *root;
  533. + struct inode *root_inode;
  534. + aufs_bindex_t bend, amount;
  535. +
  536. + root = sb->s_root;
  537. + root_inode = root->d_inode;
  538. + au_plink_block_maintain(sb);
  539. + bend = au_sbend(sb);
  540. + amount = bend + 1 - bindex;
  541. + au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount);
  542. + au_br_do_add_hdp(au_di(root), bindex, bend, amount);
  543. + au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount);
  544. + au_set_h_dptr(root, bindex, dget(h_dentry));
  545. + au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode),
  546. + /*flags*/0);
  547. +}
  548. +
  549. +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
  550. +{
  551. + int err;
  552. + unsigned long long maxb;
  553. + aufs_bindex_t bend, add_bindex;
  554. + struct dentry *root, *h_dentry;
  555. + struct inode *root_inode;
  556. + struct au_branch *add_branch;
  557. +
  558. + root = sb->s_root;
  559. + root_inode = root->d_inode;
  560. + IMustLock(root_inode);
  561. + err = test_add(sb, add, remount);
  562. + if (unlikely(err < 0))
  563. + goto out;
  564. + if (err) {
  565. + err = 0;
  566. + goto out; /* success */
  567. + }
  568. +
  569. + bend = au_sbend(sb);
  570. + add_branch = au_br_alloc(sb, bend + 2, add->perm);
  571. + err = PTR_ERR(add_branch);
  572. + if (IS_ERR(add_branch))
  573. + goto out;
  574. +
  575. + err = au_br_init(add_branch, sb, add);
  576. + if (unlikely(err)) {
  577. + au_br_do_free(add_branch);
  578. + goto out;
  579. + }
  580. +
  581. + add_bindex = add->bindex;
  582. + h_dentry = add->path.dentry;
  583. + if (!remount)
  584. + au_br_do_add(sb, h_dentry, add_branch, add_bindex);
  585. + else {
  586. + sysaufs_brs_del(sb, add_bindex);
  587. + au_br_do_add(sb, h_dentry, add_branch, add_bindex);
  588. + sysaufs_brs_add(sb, add_bindex);
  589. + }
  590. +
  591. + if (!add_bindex)
  592. + au_cpup_attr_all(root_inode, /*force*/1);
  593. + else
  594. + au_add_nlink(root_inode, h_dentry->d_inode);
  595. + maxb = h_dentry->d_sb->s_maxbytes;
  596. + if (sb->s_maxbytes < maxb)
  597. + sb->s_maxbytes = maxb;
  598. +
  599. + /*
  600. + * this test/set prevents aufs from handling unnecesary inotify events
  601. + * of xino files, in a case of re-adding a writable branch which was
  602. + * once detached from aufs.
  603. + */
  604. + if (au_xino_brid(sb) < 0
  605. + && au_br_writable(add_branch->br_perm)
  606. + && !au_test_fs_bad_xino(h_dentry->d_sb)
  607. + && add_branch->br_xino.xi_file
  608. + && add_branch->br_xino.xi_file->f_dentry->d_parent == h_dentry)
  609. + au_xino_brid_set(sb, add_branch->br_id);
  610. +
  611. + out:
  612. + return err;
  613. +}
  614. +
  615. +/* ---------------------------------------------------------------------- */
  616. +
  617. +/*
  618. + * delete a branch
  619. + */
  620. +
  621. +/* to show the line number, do not make it inlined function */
  622. +#define AuVerbose(do_info, fmt, args...) do { \
  623. + if (do_info) \
  624. + AuInfo(fmt, ##args); \
  625. +} while (0)
  626. +
  627. +/*
  628. + * test if the branch is deletable or not.
  629. + */
  630. +static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
  631. + unsigned int sigen)
  632. +{
  633. + int err, i, j, ndentry;
  634. + aufs_bindex_t bstart, bend;
  635. + unsigned char verbose;
  636. + struct au_dcsub_pages dpages;
  637. + struct au_dpage *dpage;
  638. + struct dentry *d;
  639. + struct inode *inode;
  640. +
  641. + err = au_dpages_init(&dpages, GFP_NOFS);
  642. + if (unlikely(err))
  643. + goto out;
  644. + err = au_dcsub_pages(&dpages, root, NULL, NULL);
  645. + if (unlikely(err))
  646. + goto out_dpages;
  647. +
  648. + verbose = !!au_opt_test(au_mntflags(root->d_sb), VERBOSE);
  649. + for (i = 0; !err && i < dpages.ndpage; i++) {
  650. + dpage = dpages.dpages + i;
  651. + ndentry = dpage->ndentry;
  652. + for (j = 0; !err && j < ndentry; j++) {
  653. + d = dpage->dentries[j];
  654. + AuDebugOn(!atomic_read(&d->d_count));
  655. + inode = d->d_inode;
  656. + if (au_digen(d) == sigen && au_iigen(inode) == sigen)
  657. + di_read_lock_child(d, AuLock_IR);
  658. + else {
  659. + di_write_lock_child(d);
  660. + err = au_reval_dpath(d, sigen);
  661. + if (!err)
  662. + di_downgrade_lock(d, AuLock_IR);
  663. + else {
  664. + di_write_unlock(d);
  665. + break;
  666. + }
  667. + }
  668. +
  669. + bstart = au_dbstart(d);
  670. + bend = au_dbend(d);
  671. + if (bstart <= bindex
  672. + && bindex <= bend
  673. + && au_h_dptr(d, bindex)
  674. + && (!S_ISDIR(inode->i_mode) || bstart == bend)) {
  675. + err = -EBUSY;
  676. + AuVerbose(verbose, "busy %.*s\n", AuDLNPair(d));
  677. + }
  678. + di_read_unlock(d, AuLock_IR);
  679. + }
  680. + }
  681. +
  682. + out_dpages:
  683. + au_dpages_free(&dpages);
  684. + out:
  685. + return err;
  686. +}
  687. +
  688. +static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
  689. + unsigned int sigen)
  690. +{
  691. + int err;
  692. + struct inode *i;
  693. + aufs_bindex_t bstart, bend;
  694. + unsigned char verbose;
  695. +
  696. + err = 0;
  697. + verbose = !!au_opt_test(au_mntflags(sb), VERBOSE);
  698. + list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
  699. + AuDebugOn(!atomic_read(&i->i_count));
  700. + if (!list_empty(&i->i_dentry))
  701. + continue;
  702. +
  703. + if (au_iigen(i) == sigen)
  704. + ii_read_lock_child(i);
  705. + else {
  706. + ii_write_lock_child(i);
  707. + err = au_refresh_hinode_self(i, /*do_attr*/1);
  708. + if (!err)
  709. + ii_downgrade_lock(i);
  710. + else {
  711. + ii_write_unlock(i);
  712. + break;
  713. + }
  714. + }
  715. +
  716. + bstart = au_ibstart(i);
  717. + bend = au_ibend(i);
  718. + if (bstart <= bindex
  719. + && bindex <= bend
  720. + && au_h_iptr(i, bindex)
  721. + && (!S_ISDIR(i->i_mode) || bstart == bend)) {
  722. + err = -EBUSY;
  723. + AuVerbose(verbose, "busy i%lu\n", i->i_ino);
  724. + ii_read_unlock(i);
  725. + break;
  726. + }
  727. + ii_read_unlock(i);
  728. + }
  729. +
  730. + return err;
  731. +}
  732. +
  733. +static int test_children_busy(struct dentry *root, aufs_bindex_t bindex)
  734. +{
  735. + int err;
  736. + unsigned int sigen;
  737. +
  738. + sigen = au_sigen(root->d_sb);
  739. + DiMustNoWaiters(root);
  740. + IiMustNoWaiters(root->d_inode);
  741. + di_write_unlock(root);
  742. + err = test_dentry_busy(root, bindex, sigen);
  743. + if (!err)
  744. + err = test_inode_busy(root->d_sb, bindex, sigen);
  745. + di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
  746. +
  747. + return err;
  748. +}
  749. +
  750. +static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
  751. + const aufs_bindex_t bindex,
  752. + const aufs_bindex_t bend)
  753. +{
  754. + struct au_branch **brp, **p;
  755. +
  756. + AuRwMustWriteLock(&sbinfo->si_rwsem);
  757. +
  758. + brp = sbinfo->si_branch + bindex;
  759. + if (bindex < bend)
  760. + memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex));
  761. + sbinfo->si_branch[0 + bend] = NULL;
  762. + sbinfo->si_bend--;
  763. +
  764. + p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, GFP_NOFS);
  765. + if (p)
  766. + sbinfo->si_branch = p;
  767. +}
  768. +
  769. +static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
  770. + const aufs_bindex_t bend)
  771. +{
  772. + struct au_hdentry *hdp, *p;
  773. +
  774. + AuRwMustWriteLock(&dinfo->di_rwsem);
  775. +
  776. + hdp = dinfo->di_hdentry + bindex;
  777. + if (bindex < bend)
  778. + memmove(hdp, hdp + 1, sizeof(*hdp) * (bend - bindex));
  779. + dinfo->di_hdentry[0 + bend].hd_dentry = NULL;
  780. + dinfo->di_bend--;
  781. +
  782. + p = krealloc(dinfo->di_hdentry, sizeof(*p) * bend, GFP_NOFS);
  783. + if (p)
  784. + dinfo->di_hdentry = p;
  785. +}
  786. +
  787. +static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
  788. + const aufs_bindex_t bend)
  789. +{
  790. + struct au_hinode *hip, *p;
  791. +
  792. + AuRwMustWriteLock(&iinfo->ii_rwsem);
  793. +
  794. + hip = iinfo->ii_hinode + bindex;
  795. + if (bindex < bend)
  796. + memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex));
  797. + iinfo->ii_hinode[0 + bend].hi_inode = NULL;
  798. + au_hin_init(iinfo->ii_hinode + bend, NULL);
  799. + iinfo->ii_bend--;
  800. +
  801. + p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, GFP_NOFS);
  802. + if (p)
  803. + iinfo->ii_hinode = p;
  804. +}
  805. +
  806. +static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
  807. + struct au_branch *br)
  808. +{
  809. + aufs_bindex_t bend;
  810. + struct au_sbinfo *sbinfo;
  811. + struct dentry *root;
  812. + struct inode *inode;
  813. +
  814. + SiMustWriteLock(sb);
  815. +
  816. + root = sb->s_root;
  817. + inode = root->d_inode;
  818. + au_plink_block_maintain(sb);
  819. + sbinfo = au_sbi(sb);
  820. + bend = sbinfo->si_bend;
  821. +
  822. + dput(au_h_dptr(root, bindex));
  823. + au_hiput(au_hi(inode, bindex));
  824. + au_br_do_free(br);
  825. +
  826. + au_br_do_del_brp(sbinfo, bindex, bend);
  827. + au_br_do_del_hdp(au_di(root), bindex, bend);
  828. + au_br_do_del_hip(au_ii(inode), bindex, bend);
  829. +}
  830. +
  831. +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
  832. +{
  833. + int err, rerr, i;
  834. + unsigned int mnt_flags;
  835. + aufs_bindex_t bindex, bend, br_id;
  836. + unsigned char do_wh, verbose;
  837. + struct au_branch *br;
  838. + struct au_wbr *wbr;
  839. +
  840. + err = 0;
  841. + bindex = au_find_dbindex(sb->s_root, del->h_path.dentry);
  842. + if (bindex < 0) {
  843. + if (remount)
  844. + goto out; /* success */
  845. + err = -ENOENT;
  846. + AuErr("%s no such branch\n", del->pathname);
  847. + goto out;
  848. + }
  849. + AuDbg("bindex b%d\n", bindex);
  850. +
  851. + err = -EBUSY;
  852. + mnt_flags = au_mntflags(sb);
  853. + verbose = !!au_opt_test(mnt_flags, VERBOSE);
  854. + bend = au_sbend(sb);
  855. + if (unlikely(!bend)) {
  856. + AuVerbose(verbose, "no more branches left\n");
  857. + goto out;
  858. + }
  859. + br = au_sbr(sb, bindex);
  860. + i = atomic_read(&br->br_count);
  861. + if (unlikely(i)) {
  862. + AuVerbose(verbose, "%d file(s) opened\n", i);
  863. + goto out;
  864. + }
  865. +
  866. + wbr = br->br_wbr;
  867. + do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
  868. + if (do_wh) {
  869. + /* instead of WbrWhMustWriteLock(wbr) */
  870. + SiMustWriteLock(sb);
  871. + for (i = 0; i < AuBrWh_Last; i++) {
  872. + dput(wbr->wbr_wh[i]);
  873. + wbr->wbr_wh[i] = NULL;
  874. + }
  875. + }
  876. +
  877. + err = test_children_busy(sb->s_root, bindex);
  878. + if (unlikely(err)) {
  879. + if (do_wh)
  880. + goto out_wh;
  881. + goto out;
  882. + }
  883. +
  884. + err = 0;
  885. + br_id = br->br_id;
  886. + if (!remount)
  887. + au_br_do_del(sb, bindex, br);
  888. + else {
  889. + sysaufs_brs_del(sb, bindex);
  890. + au_br_do_del(sb, bindex, br);
  891. + sysaufs_brs_add(sb, bindex);
  892. + }
  893. +
  894. + if (!bindex)
  895. + au_cpup_attr_all(sb->s_root->d_inode, /*force*/1);
  896. + else
  897. + au_sub_nlink(sb->s_root->d_inode, del->h_path.dentry->d_inode);
  898. + if (au_opt_test(mnt_flags, PLINK))
  899. + au_plink_half_refresh(sb, br_id);
  900. +
  901. + if (sb->s_maxbytes == del->h_path.dentry->d_sb->s_maxbytes) {
  902. + bend--;
  903. + sb->s_maxbytes = 0;
  904. + for (bindex = 0; bindex <= bend; bindex++) {
  905. + unsigned long long maxb;
  906. +
  907. + maxb = au_sbr_sb(sb, bindex)->s_maxbytes;
  908. + if (sb->s_maxbytes < maxb)
  909. + sb->s_maxbytes = maxb;
  910. + }
  911. + }
  912. +
  913. + if (au_xino_brid(sb) == br->br_id)
  914. + au_xino_brid_set(sb, -1);
  915. + goto out; /* success */
  916. +
  917. + out_wh:
  918. + /* revert */
  919. + rerr = au_br_init_wh(sb, br, br->br_perm, del->h_path.dentry);
  920. + if (rerr)
  921. + AuWarn("failed re-creating base whiteout, %s. (%d)\n",
  922. + del->pathname, rerr);
  923. + out:
  924. + return err;
  925. +}
  926. +
  927. +/* ---------------------------------------------------------------------- */
  928. +
  929. +/*
  930. + * change a branch permission
  931. + */
  932. +
  933. +static int do_need_sigen_inc(int a, int b)
  934. +{
  935. + return au_br_whable(a) && !au_br_whable(b);
  936. +}
  937. +
  938. +static int need_sigen_inc(int old, int new)
  939. +{
  940. + return do_need_sigen_inc(old, new)
  941. + || do_need_sigen_inc(new, old);
  942. +}
  943. +
  944. +static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
  945. +{
  946. + int err;
  947. + unsigned long n, ul, bytes, files;
  948. + aufs_bindex_t bstart;
  949. + struct file *file, *hf, **a;
  950. + const int step_bytes = 1024, /* memory allocation unit */
  951. + step_files = step_bytes / sizeof(*a);
  952. +
  953. + err = -ENOMEM;
  954. + n = 0;
  955. + bytes = step_bytes;
  956. + files = step_files;
  957. + a = kmalloc(bytes, GFP_NOFS);
  958. + if (unlikely(!a))
  959. + goto out;
  960. +
  961. + /* no need file_list_lock() since sbinfo is locked? defered? */
  962. + list_for_each_entry(file, &sb->s_files, f_u.fu_list) {
  963. + if (special_file(file->f_dentry->d_inode->i_mode))
  964. + continue;
  965. +
  966. + AuDbg("%.*s\n", AuDLNPair(file->f_dentry));
  967. + fi_read_lock(file);
  968. + if (unlikely(au_test_mmapped(file))) {
  969. + err = -EBUSY;
  970. + FiMustNoWaiters(file);
  971. + fi_read_unlock(file);
  972. + goto out_free;
  973. + }
  974. +
  975. + bstart = au_fbstart(file);
  976. + if (!S_ISREG(file->f_dentry->d_inode->i_mode)
  977. + || !(file->f_mode & FMODE_WRITE)
  978. + || bstart != bindex) {
  979. + FiMustNoWaiters(file);
  980. + fi_read_unlock(file);
  981. + continue;
  982. + }
  983. +
  984. + hf = au_h_fptr(file, bstart);
  985. + FiMustNoWaiters(file);
  986. + fi_read_unlock(file);
  987. +
  988. + if (n < files)
  989. + a[n++] = hf;
  990. + else {
  991. + void *p;
  992. +
  993. + err = -ENOMEM;
  994. + bytes += step_bytes;
  995. + files += step_files;
  996. + p = krealloc(a, bytes, GFP_NOFS);
  997. + if (p) {
  998. + a = p;
  999. + a[n++] = hf;
  1000. + } else
  1001. + goto out_free;
  1002. + }
  1003. + }
  1004. +
  1005. + err = 0;
  1006. + for (ul = 0; ul < n; ul++) {
  1007. + /* todo: already flushed? */
  1008. + /* cf. fs/super.c:mark_files_ro() */
  1009. + hf = a[ul];
  1010. + hf->f_mode &= ~FMODE_WRITE;
  1011. + if (!file_check_writeable(hf)) {
  1012. + file_release_write(hf);
  1013. + mnt_drop_write(hf->f_vfsmnt);
  1014. + }
  1015. + }
  1016. +
  1017. + out_free:
  1018. + kfree(a);
  1019. + out:
  1020. + return err;
  1021. +}
  1022. +
  1023. +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
  1024. + int *do_update)
  1025. +{
  1026. + int err, rerr;
  1027. + aufs_bindex_t bindex;
  1028. + struct dentry *root;
  1029. + struct au_branch *br;
  1030. +
  1031. + root = sb->s_root;
  1032. + au_plink_block_maintain(sb);
  1033. + bindex = au_find_dbindex(root, mod->h_root);
  1034. + if (bindex < 0) {
  1035. + if (remount)
  1036. + return 0; /* success */
  1037. + err = -ENOENT;
  1038. + AuErr("%s no such branch\n", mod->path);
  1039. + goto out;
  1040. + }
  1041. + AuDbg("bindex b%d\n", bindex);
  1042. +
  1043. + err = test_br(mod->h_root->d_inode, mod->perm, mod->path);
  1044. + if (unlikely(err))
  1045. + goto out;
  1046. +
  1047. + br = au_sbr(sb, bindex);
  1048. + if (br->br_perm == mod->perm)
  1049. + return 0; /* success */
  1050. +
  1051. + if (au_br_writable(br->br_perm)) {
  1052. + /* remove whiteout base */
  1053. + err = au_br_init_wh(sb, br, mod->perm, mod->h_root);
  1054. + if (unlikely(err))
  1055. + goto out;
  1056. +
  1057. + if (!au_br_writable(mod->perm)) {
  1058. + /* rw --> ro, file might be mmapped */
  1059. + DiMustNoWaiters(root);
  1060. + IiMustNoWaiters(root->d_inode);
  1061. + di_write_unlock(root);
  1062. + err = au_br_mod_files_ro(sb, bindex);
  1063. + /* aufs_write_lock() calls ..._child() */
  1064. + di_write_lock_child(root);
  1065. +
  1066. + if (unlikely(err)) {
  1067. + rerr = -ENOMEM;
  1068. + br->br_wbr = kmalloc(sizeof(*br->br_wbr),
  1069. + GFP_NOFS);
  1070. + if (br->br_wbr)
  1071. + rerr = au_br_init_wh
  1072. + (sb, br, br->br_perm,
  1073. + mod->h_root);
  1074. + if (unlikely(rerr)) {
  1075. + AuIOErr("nested error %d (%d)\n",
  1076. + rerr, err);
  1077. + br->br_perm = mod->perm;
  1078. + }
  1079. + }
  1080. + }
  1081. + } else if (au_br_writable(mod->perm)) {
  1082. + /* ro --> rw */
  1083. + err = -ENOMEM;
  1084. + br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS);
  1085. + if (br->br_wbr) {
  1086. + struct path path = {
  1087. + .mnt = br->br_mnt,
  1088. + .dentry = mod->h_root
  1089. + };
  1090. +
  1091. + err = au_wbr_init(br, sb, mod->perm, &path);
  1092. + if (unlikely(err)) {
  1093. + kfree(br->br_wbr);
  1094. + br->br_wbr = NULL;
  1095. + }
  1096. + }
  1097. + }
  1098. +
  1099. + if (!err) {
  1100. + *do_update |= need_sigen_inc(br->br_perm, mod->perm);
  1101. + br->br_perm = mod->perm;
  1102. + }
  1103. +
  1104. + out:
  1105. + return err;
  1106. +}
  1107. diff -Nur linux-2.6.31.5.orig/fs/aufs/branch.h linux-2.6.31.5/fs/aufs/branch.h
  1108. --- linux-2.6.31.5.orig/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100
  1109. +++ linux-2.6.31.5/fs/aufs/branch.h 2009-11-15 22:02:37.000000000 +0100
  1110. @@ -0,0 +1,219 @@
  1111. +/*
  1112. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  1113. + *
  1114. + * This program, aufs is free software; you can redistribute it and/or modify
  1115. + * it under the terms of the GNU General Public License as published by
  1116. + * the Free Software Foundation; either version 2 of the License, or
  1117. + * (at your option) any later version.
  1118. + *
  1119. + * This program is distributed in the hope that it will be useful,
  1120. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1121. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1122. + * GNU General Public License for more details.
  1123. + *
  1124. + * You should have received a copy of the GNU General Public License
  1125. + * along with this program; if not, write to the Free Software
  1126. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  1127. + */
  1128. +
  1129. +/*
  1130. + * branch filesystems and xino for them
  1131. + */
  1132. +
  1133. +#ifndef __AUFS_BRANCH_H__
  1134. +#define __AUFS_BRANCH_H__
  1135. +
  1136. +#ifdef __KERNEL__
  1137. +
  1138. +#include <linux/fs.h>
  1139. +#include <linux/mount.h>
  1140. +#include <linux/aufs_type.h>
  1141. +#include "rwsem.h"
  1142. +#include "super.h"
  1143. +
  1144. +/* ---------------------------------------------------------------------- */
  1145. +
  1146. +/* a xino file */
  1147. +struct au_xino_file {
  1148. + struct file *xi_file;
  1149. + struct mutex xi_nondir_mtx;
  1150. +
  1151. + /* todo: make xino files an array to support huge inode number */
  1152. +
  1153. +#ifdef CONFIG_DEBUG_FS
  1154. + struct dentry *xi_dbgaufs;
  1155. +#endif
  1156. +};
  1157. +
  1158. +/* members for writable branch only */
  1159. +enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
  1160. +struct au_wbr {
  1161. + struct au_rwsem wbr_wh_rwsem;
  1162. + struct dentry *wbr_wh[AuBrWh_Last];
  1163. + atomic_t wbr_wh_running;
  1164. +#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
  1165. +#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
  1166. +#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
  1167. +
  1168. + /* mfs mode */
  1169. + unsigned long long wbr_bytes;
  1170. +};
  1171. +
  1172. +/* protected by superblock rwsem */
  1173. +struct au_branch {
  1174. + struct au_xino_file br_xino;
  1175. +
  1176. + aufs_bindex_t br_id;
  1177. +
  1178. + int br_perm;
  1179. + struct vfsmount *br_mnt;
  1180. + atomic_t br_count;
  1181. +
  1182. + struct au_wbr *br_wbr;
  1183. +
  1184. + /* xino truncation */
  1185. + blkcnt_t br_xino_upper; /* watermark in blocks */
  1186. + atomic_t br_xino_running;
  1187. +
  1188. +#ifdef CONFIG_SYSFS
  1189. + /* an entry under sysfs per mount-point */
  1190. + char br_name[8];
  1191. + struct attribute br_attr;
  1192. +#endif
  1193. +};
  1194. +
  1195. +/* ---------------------------------------------------------------------- */
  1196. +
  1197. +/* branch permission and attribute */
  1198. +enum {
  1199. + AuBrPerm_RW, /* writable, linkable wh */
  1200. + AuBrPerm_RO, /* readonly, no wh */
  1201. + AuBrPerm_RR, /* natively readonly, no wh */
  1202. +
  1203. + AuBrPerm_RWNoLinkWH, /* un-linkable whiteouts */
  1204. +
  1205. + AuBrPerm_ROWH, /* whiteout-able */
  1206. + AuBrPerm_RRWH, /* whiteout-able */
  1207. +
  1208. + AuBrPerm_Last
  1209. +};
  1210. +
  1211. +static inline int au_br_writable(int brperm)
  1212. +{
  1213. + return brperm == AuBrPerm_RW || brperm == AuBrPerm_RWNoLinkWH;
  1214. +}
  1215. +
  1216. +static inline int au_br_whable(int brperm)
  1217. +{
  1218. + return brperm == AuBrPerm_RW
  1219. + || brperm == AuBrPerm_ROWH
  1220. + || brperm == AuBrPerm_RRWH;
  1221. +}
  1222. +
  1223. +static inline int au_br_rdonly(struct au_branch *br)
  1224. +{
  1225. + return ((br->br_mnt->mnt_sb->s_flags & MS_RDONLY)
  1226. + || !au_br_writable(br->br_perm))
  1227. + ? -EROFS : 0;
  1228. +}
  1229. +
  1230. +static inline int au_br_hinotifyable(int brperm __maybe_unused)
  1231. +{
  1232. +#ifdef CONFIG_AUFS_HINOTIFY
  1233. + return brperm != AuBrPerm_RR && brperm != AuBrPerm_RRWH;
  1234. +#else
  1235. + return 0;
  1236. +#endif
  1237. +}
  1238. +
  1239. +/* ---------------------------------------------------------------------- */
  1240. +
  1241. +/* branch.c */
  1242. +struct au_sbinfo;
  1243. +void au_br_free(struct au_sbinfo *sinfo);
  1244. +int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
  1245. +struct au_opt_add;
  1246. +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
  1247. +struct au_opt_del;
  1248. +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
  1249. +struct au_opt_mod;
  1250. +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
  1251. + int *do_update);
  1252. +
  1253. +/* xino.c */
  1254. +static const loff_t au_loff_max = LLONG_MAX;
  1255. +
  1256. +int au_xib_trunc(struct super_block *sb);
  1257. +ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size,
  1258. + loff_t *pos);
  1259. +ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
  1260. + loff_t *pos);
  1261. +struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
  1262. +struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
  1263. +ino_t au_xino_new_ino(struct super_block *sb);
  1264. +int au_xino_write0(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  1265. + ino_t ino);
  1266. +int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  1267. + ino_t ino);
  1268. +int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  1269. + ino_t *ino);
  1270. +int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
  1271. + struct file *base_file, int do_test);
  1272. +int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
  1273. +
  1274. +struct au_opt_xino;
  1275. +int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
  1276. +void au_xino_clr(struct super_block *sb);
  1277. +struct file *au_xino_def(struct super_block *sb);
  1278. +int au_xino_path(struct seq_file *seq, struct file *file);
  1279. +
  1280. +/* ---------------------------------------------------------------------- */
  1281. +
  1282. +/* Superblock to branch */
  1283. +static inline
  1284. +aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
  1285. +{
  1286. + return au_sbr(sb, bindex)->br_id;
  1287. +}
  1288. +
  1289. +static inline
  1290. +struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
  1291. +{
  1292. + return au_sbr(sb, bindex)->br_mnt;
  1293. +}
  1294. +
  1295. +static inline
  1296. +struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
  1297. +{
  1298. + return au_sbr_mnt(sb, bindex)->mnt_sb;
  1299. +}
  1300. +
  1301. +static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
  1302. +{
  1303. + atomic_dec_return(&au_sbr(sb, bindex)->br_count);
  1304. +}
  1305. +
  1306. +static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
  1307. +{
  1308. + return au_sbr(sb, bindex)->br_perm;
  1309. +}
  1310. +
  1311. +static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
  1312. +{
  1313. + return au_br_whable(au_sbr_perm(sb, bindex));
  1314. +}
  1315. +
  1316. +/* ---------------------------------------------------------------------- */
  1317. +
  1318. +/*
  1319. + * wbr_wh_read_lock, wbr_wh_write_lock
  1320. + * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
  1321. + */
  1322. +AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
  1323. +
  1324. +#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
  1325. +#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
  1326. +#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
  1327. +
  1328. +#endif /* __KERNEL__ */
  1329. +#endif /* __AUFS_BRANCH_H__ */
  1330. diff -Nur linux-2.6.31.5.orig/fs/aufs/cpup.c linux-2.6.31.5/fs/aufs/cpup.c
  1331. --- linux-2.6.31.5.orig/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
  1332. +++ linux-2.6.31.5/fs/aufs/cpup.c 2009-11-15 22:02:37.000000000 +0100
  1333. @@ -0,0 +1,1048 @@
  1334. +/*
  1335. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  1336. + *
  1337. + * This program, aufs is free software; you can redistribute it and/or modify
  1338. + * it under the terms of the GNU General Public License as published by
  1339. + * the Free Software Foundation; either version 2 of the License, or
  1340. + * (at your option) any later version.
  1341. + *
  1342. + * This program is distributed in the hope that it will be useful,
  1343. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1344. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1345. + * GNU General Public License for more details.
  1346. + *
  1347. + * You should have received a copy of the GNU General Public License
  1348. + * along with this program; if not, write to the Free Software
  1349. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  1350. + */
  1351. +
  1352. +/*
  1353. + * copy-up functions, see wbr_policy.c for copy-down
  1354. + */
  1355. +
  1356. +#include <linux/file.h>
  1357. +#include <linux/fs_stack.h>
  1358. +#include <linux/mm.h>
  1359. +#include <linux/uaccess.h>
  1360. +#include "aufs.h"
  1361. +
  1362. +void au_cpup_attr_flags(struct inode *dst, struct inode *src)
  1363. +{
  1364. + const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
  1365. + | S_NOATIME | S_NOCMTIME;
  1366. +
  1367. + dst->i_flags |= src->i_flags & ~mask;
  1368. + if (au_test_fs_notime(dst->i_sb))
  1369. + dst->i_flags |= S_NOATIME | S_NOCMTIME;
  1370. +}
  1371. +
  1372. +void au_cpup_attr_timesizes(struct inode *inode)
  1373. +{
  1374. + struct inode *h_inode;
  1375. +
  1376. + h_inode = au_h_iptr(inode, au_ibstart(inode));
  1377. + fsstack_copy_attr_times(inode, h_inode);
  1378. + vfsub_copy_inode_size(inode, h_inode);
  1379. +}
  1380. +
  1381. +void au_cpup_attr_nlink(struct inode *inode, int force)
  1382. +{
  1383. + struct inode *h_inode;
  1384. + struct super_block *sb;
  1385. + aufs_bindex_t bindex, bend;
  1386. +
  1387. + sb = inode->i_sb;
  1388. + bindex = au_ibstart(inode);
  1389. + h_inode = au_h_iptr(inode, bindex);
  1390. + if (!force
  1391. + && !S_ISDIR(h_inode->i_mode)
  1392. + && au_opt_test(au_mntflags(sb), PLINK)
  1393. + && au_plink_test(inode))
  1394. + return;
  1395. +
  1396. + inode->i_nlink = h_inode->i_nlink;
  1397. +
  1398. + /*
  1399. + * fewer nlink makes find(1) noisy, but larger nlink doesn't.
  1400. + * it may includes whplink directory.
  1401. + */
  1402. + if (S_ISDIR(h_inode->i_mode)) {
  1403. + bend = au_ibend(inode);
  1404. + for (bindex++; bindex <= bend; bindex++) {
  1405. + h_inode = au_h_iptr(inode, bindex);
  1406. + if (h_inode)
  1407. + au_add_nlink(inode, h_inode);
  1408. + }
  1409. + }
  1410. +}
  1411. +
  1412. +void au_cpup_attr_changeable(struct inode *inode)
  1413. +{
  1414. + struct inode *h_inode;
  1415. +
  1416. + h_inode = au_h_iptr(inode, au_ibstart(inode));
  1417. + inode->i_mode = h_inode->i_mode;
  1418. + inode->i_uid = h_inode->i_uid;
  1419. + inode->i_gid = h_inode->i_gid;
  1420. + au_cpup_attr_timesizes(inode);
  1421. + au_cpup_attr_flags(inode, h_inode);
  1422. +}
  1423. +
  1424. +void au_cpup_igen(struct inode *inode, struct inode *h_inode)
  1425. +{
  1426. + struct au_iinfo *iinfo = au_ii(inode);
  1427. +
  1428. + IiMustWriteLock(inode);
  1429. +
  1430. + iinfo->ii_higen = h_inode->i_generation;
  1431. + iinfo->ii_hsb1 = h_inode->i_sb;
  1432. +}
  1433. +
  1434. +void au_cpup_attr_all(struct inode *inode, int force)
  1435. +{
  1436. + struct inode *h_inode;
  1437. +
  1438. + h_inode = au_h_iptr(inode, au_ibstart(inode));
  1439. + au_cpup_attr_changeable(inode);
  1440. + if (inode->i_nlink > 0)
  1441. + au_cpup_attr_nlink(inode, force);
  1442. + inode->i_rdev = h_inode->i_rdev;
  1443. + inode->i_blkbits = h_inode->i_blkbits;
  1444. + au_cpup_igen(inode, h_inode);
  1445. +}
  1446. +
  1447. +/* ---------------------------------------------------------------------- */
  1448. +
  1449. +/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
  1450. +
  1451. +/* keep the timestamps of the parent dir when cpup */
  1452. +void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
  1453. + struct path *h_path)
  1454. +{
  1455. + struct inode *h_inode;
  1456. +
  1457. + dt->dt_dentry = dentry;
  1458. + dt->dt_h_path = *h_path;
  1459. + h_inode = h_path->dentry->d_inode;
  1460. + dt->dt_atime = h_inode->i_atime;
  1461. + dt->dt_mtime = h_inode->i_mtime;
  1462. + /* smp_mb(); */
  1463. +}
  1464. +
  1465. +void au_dtime_revert(struct au_dtime *dt)
  1466. +{
  1467. + struct iattr attr;
  1468. + int err;
  1469. +
  1470. + attr.ia_atime = dt->dt_atime;
  1471. + attr.ia_mtime = dt->dt_mtime;
  1472. + attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
  1473. + | ATTR_ATIME | ATTR_ATIME_SET;
  1474. +
  1475. + err = vfsub_notify_change(&dt->dt_h_path, &attr);
  1476. + if (unlikely(err))
  1477. + AuWarn("restoring timestamps failed(%d). ignored\n", err);
  1478. +}
  1479. +
  1480. +/* ---------------------------------------------------------------------- */
  1481. +
  1482. +static noinline_for_stack
  1483. +int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src)
  1484. +{
  1485. + int err, sbits;
  1486. + struct iattr ia;
  1487. + struct path h_path;
  1488. + struct inode *h_isrc, *h_idst;
  1489. +
  1490. + h_path.dentry = au_h_dptr(dst, bindex);
  1491. + h_idst = h_path.dentry->d_inode;
  1492. + h_path.mnt = au_sbr_mnt(dst->d_sb, bindex);
  1493. + h_isrc = h_src->d_inode;
  1494. + ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
  1495. + | ATTR_ATIME | ATTR_MTIME
  1496. + | ATTR_ATIME_SET | ATTR_MTIME_SET;
  1497. + ia.ia_uid = h_isrc->i_uid;
  1498. + ia.ia_gid = h_isrc->i_gid;
  1499. + ia.ia_atime = h_isrc->i_atime;
  1500. + ia.ia_mtime = h_isrc->i_mtime;
  1501. + if (h_idst->i_mode != h_isrc->i_mode
  1502. + && !S_ISLNK(h_idst->i_mode)) {
  1503. + ia.ia_valid |= ATTR_MODE;
  1504. + ia.ia_mode = h_isrc->i_mode;
  1505. + }
  1506. + sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
  1507. + au_cpup_attr_flags(h_idst, h_isrc);
  1508. + err = vfsub_notify_change(&h_path, &ia);
  1509. +
  1510. + /* is this nfs only? */
  1511. + if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
  1512. + ia.ia_valid = ATTR_FORCE | ATTR_MODE;
  1513. + ia.ia_mode = h_isrc->i_mode;
  1514. + err = vfsub_notify_change(&h_path, &ia);
  1515. + }
  1516. +
  1517. + return err;
  1518. +}
  1519. +
  1520. +/* ---------------------------------------------------------------------- */
  1521. +
  1522. +static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
  1523. + char *buf, unsigned long blksize)
  1524. +{
  1525. + int err;
  1526. + size_t sz, rbytes, wbytes;
  1527. + unsigned char all_zero;
  1528. + char *p, *zp;
  1529. + struct mutex *h_mtx;
  1530. + /* reduce stack usage */
  1531. + struct iattr *ia;
  1532. +
  1533. + zp = page_address(ZERO_PAGE(0));
  1534. + if (unlikely(!zp))
  1535. + return -ENOMEM; /* possible? */
  1536. +
  1537. + err = 0;
  1538. + all_zero = 0;
  1539. + while (len) {
  1540. + AuDbg("len %lld\n", len);
  1541. + sz = blksize;
  1542. + if (len < blksize)
  1543. + sz = len;
  1544. +
  1545. + rbytes = 0;
  1546. + /* todo: signal_pending? */
  1547. + while (!rbytes || err == -EAGAIN || err == -EINTR) {
  1548. + rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
  1549. + err = rbytes;
  1550. + }
  1551. + if (unlikely(err < 0))
  1552. + break;
  1553. +
  1554. + all_zero = 0;
  1555. + if (len >= rbytes && rbytes == blksize)
  1556. + all_zero = !memcmp(buf, zp, rbytes);
  1557. + if (!all_zero) {
  1558. + wbytes = rbytes;
  1559. + p = buf;
  1560. + while (wbytes) {
  1561. + size_t b;
  1562. +
  1563. + b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
  1564. + err = b;
  1565. + /* todo: signal_pending? */
  1566. + if (unlikely(err == -EAGAIN || err == -EINTR))
  1567. + continue;
  1568. + if (unlikely(err < 0))
  1569. + break;
  1570. + wbytes -= b;
  1571. + p += b;
  1572. + }
  1573. + } else {
  1574. + loff_t res;
  1575. +
  1576. + AuLabel(hole);
  1577. + res = vfsub_llseek(dst, rbytes, SEEK_CUR);
  1578. + err = res;
  1579. + if (unlikely(res < 0))
  1580. + break;
  1581. + }
  1582. + len -= rbytes;
  1583. + err = 0;
  1584. + }
  1585. +
  1586. + /* the last block may be a hole */
  1587. + if (!err && all_zero) {
  1588. + AuLabel(last hole);
  1589. +
  1590. + err = 1;
  1591. + if (au_test_nfs(dst->f_dentry->d_sb)) {
  1592. + /* nfs requires this step to make last hole */
  1593. + /* is this only nfs? */
  1594. + do {
  1595. + /* todo: signal_pending? */
  1596. + err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
  1597. + } while (err == -EAGAIN || err == -EINTR);
  1598. + if (err == 1)
  1599. + dst->f_pos--;
  1600. + }
  1601. +
  1602. + if (err == 1) {
  1603. + ia = (void *)buf;
  1604. + ia->ia_size = dst->f_pos;
  1605. + ia->ia_valid = ATTR_SIZE | ATTR_FILE;
  1606. + ia->ia_file = dst;
  1607. + h_mtx = &dst->f_dentry->d_inode->i_mutex;
  1608. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
  1609. + err = vfsub_notify_change(&dst->f_path, ia);
  1610. + mutex_unlock(h_mtx);
  1611. + }
  1612. + }
  1613. +
  1614. + return err;
  1615. +}
  1616. +
  1617. +int au_copy_file(struct file *dst, struct file *src, loff_t len)
  1618. +{
  1619. + int err;
  1620. + unsigned long blksize;
  1621. + unsigned char do_kfree;
  1622. + char *buf;
  1623. +
  1624. + err = -ENOMEM;
  1625. + blksize = dst->f_dentry->d_sb->s_blocksize;
  1626. + if (!blksize || PAGE_SIZE < blksize)
  1627. + blksize = PAGE_SIZE;
  1628. + AuDbg("blksize %lu\n", blksize);
  1629. + do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
  1630. + if (do_kfree)
  1631. + buf = kmalloc(blksize, GFP_NOFS);
  1632. + else
  1633. + buf = (void *)__get_free_page(GFP_NOFS);
  1634. + if (unlikely(!buf))
  1635. + goto out;
  1636. +
  1637. + if (len > (1 << 22))
  1638. + AuDbg("copying a large file %lld\n", (long long)len);
  1639. +
  1640. + src->f_pos = 0;
  1641. + dst->f_pos = 0;
  1642. + err = au_do_copy_file(dst, src, len, buf, blksize);
  1643. + if (do_kfree)
  1644. + kfree(buf);
  1645. + else
  1646. + free_page((unsigned long)buf);
  1647. +
  1648. + out:
  1649. + return err;
  1650. +}
  1651. +
  1652. +/*
  1653. + * to support a sparse file which is opened with O_APPEND,
  1654. + * we need to close the file.
  1655. + */
  1656. +static int au_cp_regular(struct dentry *dentry, aufs_bindex_t bdst,
  1657. + aufs_bindex_t bsrc, loff_t len)
  1658. +{
  1659. + int err, i;
  1660. + enum { SRC, DST };
  1661. + struct {
  1662. + aufs_bindex_t bindex;
  1663. + unsigned int flags;
  1664. + struct dentry *dentry;
  1665. + struct file *file;
  1666. + void *label, *label_file;
  1667. + } *f, file[] = {
  1668. + {
  1669. + .bindex = bsrc,
  1670. + .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
  1671. + .file = NULL,
  1672. + .label = &&out,
  1673. + .label_file = &&out_src
  1674. + },
  1675. + {
  1676. + .bindex = bdst,
  1677. + .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
  1678. + .file = NULL,
  1679. + .label = &&out_src,
  1680. + .label_file = &&out_dst
  1681. + }
  1682. + };
  1683. + struct super_block *sb;
  1684. +
  1685. + /* bsrc branch can be ro/rw. */
  1686. + sb = dentry->d_sb;
  1687. + f = file;
  1688. + for (i = 0; i < 2; i++, f++) {
  1689. + f->dentry = au_h_dptr(dentry, f->bindex);
  1690. + f->file = au_h_open(dentry, f->bindex, f->flags, /*file*/NULL);
  1691. + err = PTR_ERR(f->file);
  1692. + if (IS_ERR(f->file))
  1693. + goto *f->label;
  1694. + err = -EINVAL;
  1695. + if (unlikely(!f->file->f_op))
  1696. + goto *f->label_file;
  1697. + }
  1698. +
  1699. + /* try stopping to update while we copyup */
  1700. + IMustLock(file[SRC].dentry->d_inode);
  1701. + err = au_copy_file(file[DST].file, file[SRC].file, len);
  1702. +
  1703. + out_dst:
  1704. + fput(file[DST].file);
  1705. + au_sbr_put(sb, file[DST].bindex);
  1706. + out_src:
  1707. + fput(file[SRC].file);
  1708. + au_sbr_put(sb, file[SRC].bindex);
  1709. + out:
  1710. + return err;
  1711. +}
  1712. +
  1713. +static int au_do_cpup_regular(struct dentry *dentry, aufs_bindex_t bdst,
  1714. + aufs_bindex_t bsrc, loff_t len,
  1715. + struct inode *h_dir, struct path *h_path)
  1716. +{
  1717. + int err, rerr;
  1718. + loff_t l;
  1719. +
  1720. + err = 0;
  1721. + l = i_size_read(au_h_iptr(dentry->d_inode, bsrc));
  1722. + if (len == -1 || l < len)
  1723. + len = l;
  1724. + if (len)
  1725. + err = au_cp_regular(dentry, bdst, bsrc, len);
  1726. + if (!err)
  1727. + goto out; /* success */
  1728. +
  1729. + rerr = vfsub_unlink(h_dir, h_path, /*force*/0);
  1730. + if (rerr) {
  1731. + AuIOErr("failed unlinking cpup-ed %.*s(%d, %d)\n",
  1732. + AuDLNPair(h_path->dentry), err, rerr);
  1733. + err = -EIO;
  1734. + }
  1735. +
  1736. + out:
  1737. + return err;
  1738. +}
  1739. +
  1740. +static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
  1741. + struct inode *h_dir)
  1742. +{
  1743. + int err, symlen;
  1744. + mm_segment_t old_fs;
  1745. + char *sym;
  1746. +
  1747. + err = -ENOSYS;
  1748. + if (unlikely(!h_src->d_inode->i_op->readlink))
  1749. + goto out;
  1750. +
  1751. + err = -ENOMEM;
  1752. + sym = __getname();
  1753. + if (unlikely(!sym))
  1754. + goto out;
  1755. +
  1756. + old_fs = get_fs();
  1757. + set_fs(KERNEL_DS);
  1758. + symlen = h_src->d_inode->i_op->readlink(h_src, (char __user *)sym,
  1759. + PATH_MAX);
  1760. + err = symlen;
  1761. + set_fs(old_fs);
  1762. +
  1763. + if (symlen > 0) {
  1764. + sym[symlen] = 0;
  1765. + err = vfsub_symlink(h_dir, h_path, sym);
  1766. + }
  1767. + __putname(sym);
  1768. +
  1769. + out:
  1770. + return err;
  1771. +}
  1772. +
  1773. +/* return with the lower dst inode is locked */
  1774. +static noinline_for_stack
  1775. +int cpup_entry(struct dentry *dentry, aufs_bindex_t bdst,
  1776. + aufs_bindex_t bsrc, loff_t len, unsigned int flags,
  1777. + struct dentry *dst_parent)
  1778. +{
  1779. + int err;
  1780. + umode_t mode;
  1781. + unsigned int mnt_flags;
  1782. + unsigned char isdir;
  1783. + const unsigned char do_dt = !!au_ftest_cpup(flags, DTIME);
  1784. + struct au_dtime dt;
  1785. + struct path h_path;
  1786. + struct dentry *h_src, *h_dst, *h_parent;
  1787. + struct inode *h_inode, *h_dir;
  1788. + struct super_block *sb;
  1789. +
  1790. + /* bsrc branch can be ro/rw. */
  1791. + h_src = au_h_dptr(dentry, bsrc);
  1792. + h_inode = h_src->d_inode;
  1793. + AuDebugOn(h_inode != au_h_iptr(dentry->d_inode, bsrc));
  1794. +
  1795. + /* try stopping to be referenced while we are creating */
  1796. + h_dst = au_h_dptr(dentry, bdst);
  1797. + h_parent = h_dst->d_parent; /* dir inode is locked */
  1798. + h_dir = h_parent->d_inode;
  1799. + IMustLock(h_dir);
  1800. + AuDebugOn(h_parent != h_dst->d_parent);
  1801. +
  1802. + sb = dentry->d_sb;
  1803. + h_path.mnt = au_sbr_mnt(sb, bdst);
  1804. + if (do_dt) {
  1805. + h_path.dentry = h_parent;
  1806. + au_dtime_store(&dt, dst_parent, &h_path);
  1807. + }
  1808. + h_path.dentry = h_dst;
  1809. +
  1810. + isdir = 0;
  1811. + mode = h_inode->i_mode;
  1812. + switch (mode & S_IFMT) {
  1813. + case S_IFREG:
  1814. + /* try stopping to update while we are referencing */
  1815. + IMustLock(h_inode);
  1816. + err = vfsub_create(h_dir, &h_path, mode | S_IWUSR);
  1817. + if (!err)
  1818. + err = au_do_cpup_regular
  1819. + (dentry, bdst, bsrc, len,
  1820. + au_h_iptr(dst_parent->d_inode, bdst), &h_path);
  1821. + break;
  1822. + case S_IFDIR:
  1823. + isdir = 1;
  1824. + err = vfsub_mkdir(h_dir, &h_path, mode);
  1825. + if (!err) {
  1826. + /*
  1827. + * strange behaviour from the users view,
  1828. + * particularry setattr case
  1829. + */
  1830. + if (au_ibstart(dst_parent->d_inode) == bdst)
  1831. + au_cpup_attr_nlink(dst_parent->d_inode,
  1832. + /*force*/1);
  1833. + au_cpup_attr_nlink(dentry->d_inode, /*force*/1);
  1834. + }
  1835. + break;
  1836. + case S_IFLNK:
  1837. + err = au_do_cpup_symlink(&h_path, h_src, h_dir);
  1838. + break;
  1839. + case S_IFCHR:
  1840. + case S_IFBLK:
  1841. + AuDebugOn(!capable(CAP_MKNOD));
  1842. + /*FALLTHROUGH*/
  1843. + case S_IFIFO:
  1844. + case S_IFSOCK:
  1845. + err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
  1846. + break;
  1847. + default:
  1848. + AuIOErr("Unknown inode type 0%o\n", mode);
  1849. + err = -EIO;
  1850. + }
  1851. +
  1852. + mnt_flags = au_mntflags(sb);
  1853. + if (!au_opt_test(mnt_flags, UDBA_NONE)
  1854. + && !isdir
  1855. + && au_opt_test(mnt_flags, XINO)
  1856. + && h_inode->i_nlink == 1
  1857. + /* todo: unnecessary? */
  1858. + /* && dentry->d_inode->i_nlink == 1 */
  1859. + && bdst < bsrc
  1860. + && !au_ftest_cpup(flags, KEEPLINO))
  1861. + au_xino_write(sb, bsrc, h_inode->i_ino, /*ino*/0);
  1862. + /* ignore this error */
  1863. +
  1864. + if (do_dt)
  1865. + au_dtime_revert(&dt);
  1866. + return err;
  1867. +}
  1868. +
  1869. +/*
  1870. + * copyup the @dentry from @bsrc to @bdst.
  1871. + * the caller must set the both of lower dentries.
  1872. + * @len is for truncating when it is -1 copyup the entire file.
  1873. + * in link/rename cases, @dst_parent may be different from the real one.
  1874. + */
  1875. +static int au_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
  1876. + aufs_bindex_t bsrc, loff_t len, unsigned int flags,
  1877. + struct dentry *dst_parent)
  1878. +{
  1879. + int err, rerr;
  1880. + aufs_bindex_t old_ibstart;
  1881. + unsigned char isdir, plink;
  1882. + struct au_dtime dt;
  1883. + struct path h_path;
  1884. + struct dentry *h_src, *h_dst, *h_parent;
  1885. + struct inode *dst_inode, *h_dir, *inode;
  1886. + struct super_block *sb;
  1887. +
  1888. + AuDebugOn(bsrc <= bdst);
  1889. +
  1890. + sb = dentry->d_sb;
  1891. + h_path.mnt = au_sbr_mnt(sb, bdst);
  1892. + h_dst = au_h_dptr(dentry, bdst);
  1893. + h_parent = h_dst->d_parent; /* dir inode is locked */
  1894. + h_dir = h_parent->d_inode;
  1895. + IMustLock(h_dir);
  1896. +
  1897. + h_src = au_h_dptr(dentry, bsrc);
  1898. + inode = dentry->d_inode;
  1899. +
  1900. + if (!dst_parent)
  1901. + dst_parent = dget_parent(dentry);
  1902. + else
  1903. + dget(dst_parent);
  1904. +
  1905. + plink = !!au_opt_test(au_mntflags(sb), PLINK);
  1906. + dst_inode = au_h_iptr(inode, bdst);
  1907. + if (dst_inode) {
  1908. + if (unlikely(!plink)) {
  1909. + err = -EIO;
  1910. + AuIOErr("i%lu exists on a upper branch "
  1911. + "but plink is disabled\n", inode->i_ino);
  1912. + goto out;
  1913. + }
  1914. +
  1915. + if (dst_inode->i_nlink) {
  1916. + const int do_dt = au_ftest_cpup(flags, DTIME);
  1917. +
  1918. + h_src = au_plink_lkup(inode, bdst);
  1919. + err = PTR_ERR(h_src);
  1920. + if (IS_ERR(h_src))
  1921. + goto out;
  1922. + if (unlikely(!h_src->d_inode)) {
  1923. + err = -EIO;
  1924. + AuIOErr("i%lu exists on a upper branch "
  1925. + "but plink is broken\n", inode->i_ino);
  1926. + dput(h_src);
  1927. + goto out;
  1928. + }
  1929. +
  1930. + if (do_dt) {
  1931. + h_path.dentry = h_parent;
  1932. + au_dtime_store(&dt, dst_parent, &h_path);
  1933. + }
  1934. + h_path.dentry = h_dst;
  1935. + err = vfsub_link(h_src, h_dir, &h_path);
  1936. + if (do_dt)
  1937. + au_dtime_revert(&dt);
  1938. + dput(h_src);
  1939. + goto out;
  1940. + } else
  1941. + /* todo: cpup_wh_file? */
  1942. + /* udba work */
  1943. + au_update_brange(inode, 1);
  1944. + }
  1945. +
  1946. + old_ibstart = au_ibstart(inode);
  1947. + err = cpup_entry(dentry, bdst, bsrc, len, flags, dst_parent);
  1948. + if (unlikely(err))
  1949. + goto out;
  1950. + dst_inode = h_dst->d_inode;
  1951. + mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
  1952. +
  1953. + err = cpup_iattr(dentry, bdst, h_src);
  1954. + isdir = S_ISDIR(dst_inode->i_mode);
  1955. + if (!err) {
  1956. + if (bdst < old_ibstart)
  1957. + au_set_ibstart(inode, bdst);
  1958. + au_set_h_iptr(inode, bdst, au_igrab(dst_inode),
  1959. + au_hi_flags(inode, isdir));
  1960. + mutex_unlock(&dst_inode->i_mutex);
  1961. + if (!isdir
  1962. + && h_src->d_inode->i_nlink > 1
  1963. + && plink)
  1964. + au_plink_append(inode, bdst, h_dst);
  1965. + goto out; /* success */
  1966. + }
  1967. +
  1968. + /* revert */
  1969. + h_path.dentry = h_parent;
  1970. + mutex_unlock(&dst_inode->i_mutex);
  1971. + au_dtime_store(&dt, dst_parent, &h_path);
  1972. + h_path.dentry = h_dst;
  1973. + if (!isdir)
  1974. + rerr = vfsub_unlink(h_dir, &h_path, /*force*/0);
  1975. + else
  1976. + rerr = vfsub_rmdir(h_dir, &h_path);
  1977. + au_dtime_revert(&dt);
  1978. + if (rerr) {
  1979. + AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
  1980. + err = -EIO;
  1981. + }
  1982. +
  1983. + out:
  1984. + dput(dst_parent);
  1985. + return err;
  1986. +}
  1987. +
  1988. +struct au_cpup_single_args {
  1989. + int *errp;
  1990. + struct dentry *dentry;
  1991. + aufs_bindex_t bdst, bsrc;
  1992. + loff_t len;
  1993. + unsigned int flags;
  1994. + struct dentry *dst_parent;
  1995. +};
  1996. +
  1997. +static void au_call_cpup_single(void *args)
  1998. +{
  1999. + struct au_cpup_single_args *a = args;
  2000. + *a->errp = au_cpup_single(a->dentry, a->bdst, a->bsrc, a->len,
  2001. + a->flags, a->dst_parent);
  2002. +}
  2003. +
  2004. +int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
  2005. + aufs_bindex_t bsrc, loff_t len, unsigned int flags,
  2006. + struct dentry *dst_parent)
  2007. +{
  2008. + int err, wkq_err;
  2009. + umode_t mode;
  2010. + struct dentry *h_dentry;
  2011. +
  2012. + h_dentry = au_h_dptr(dentry, bsrc);
  2013. + mode = h_dentry->d_inode->i_mode & S_IFMT;
  2014. + if ((mode != S_IFCHR && mode != S_IFBLK)
  2015. + || capable(CAP_MKNOD))
  2016. + err = au_cpup_single(dentry, bdst, bsrc, len, flags,
  2017. + dst_parent);
  2018. + else {
  2019. + struct au_cpup_single_args args = {
  2020. + .errp = &err,
  2021. + .dentry = dentry,
  2022. + .bdst = bdst,
  2023. + .bsrc = bsrc,
  2024. + .len = len,
  2025. + .flags = flags,
  2026. + .dst_parent = dst_parent
  2027. + };
  2028. + wkq_err = au_wkq_wait(au_call_cpup_single, &args);
  2029. + if (unlikely(wkq_err))
  2030. + err = wkq_err;
  2031. + }
  2032. +
  2033. + return err;
  2034. +}
  2035. +
  2036. +/*
  2037. + * copyup the @dentry from the first active lower branch to @bdst,
  2038. + * using au_cpup_single().
  2039. + */
  2040. +static int au_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
  2041. + unsigned int flags)
  2042. +{
  2043. + int err;
  2044. + aufs_bindex_t bsrc, bend;
  2045. +
  2046. + bend = au_dbend(dentry);
  2047. + for (bsrc = bdst + 1; bsrc <= bend; bsrc++)
  2048. + if (au_h_dptr(dentry, bsrc))
  2049. + break;
  2050. +
  2051. + err = au_lkup_neg(dentry, bdst);
  2052. + if (!err) {
  2053. + err = au_cpup_single(dentry, bdst, bsrc, len, flags, NULL);
  2054. + if (!err)
  2055. + return 0; /* success */
  2056. +
  2057. + /* revert */
  2058. + au_set_h_dptr(dentry, bdst, NULL);
  2059. + au_set_dbstart(dentry, bsrc);
  2060. + }
  2061. +
  2062. + return err;
  2063. +}
  2064. +
  2065. +struct au_cpup_simple_args {
  2066. + int *errp;
  2067. + struct dentry *dentry;
  2068. + aufs_bindex_t bdst;
  2069. + loff_t len;
  2070. + unsigned int flags;
  2071. +};
  2072. +
  2073. +static void au_call_cpup_simple(void *args)
  2074. +{
  2075. + struct au_cpup_simple_args *a = args;
  2076. + *a->errp = au_cpup_simple(a->dentry, a->bdst, a->len, a->flags);
  2077. +}
  2078. +
  2079. +int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
  2080. + unsigned int flags)
  2081. +{
  2082. + int err, wkq_err;
  2083. + unsigned char do_sio;
  2084. + struct dentry *parent;
  2085. + struct inode *h_dir;
  2086. +
  2087. + parent = dget_parent(dentry);
  2088. + h_dir = au_h_iptr(parent->d_inode, bdst);
  2089. + do_sio = !!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE);
  2090. + if (!do_sio) {
  2091. + /*
  2092. + * testing CAP_MKNOD is for generic fs,
  2093. + * but CAP_FSETID is for xfs only, currently.
  2094. + */
  2095. + umode_t mode = dentry->d_inode->i_mode;
  2096. + do_sio = (((mode & (S_IFCHR | S_IFBLK))
  2097. + && !capable(CAP_MKNOD))
  2098. + || ((mode & (S_ISUID | S_ISGID))
  2099. + && !capable(CAP_FSETID)));
  2100. + }
  2101. + if (!do_sio)
  2102. + err = au_cpup_simple(dentry, bdst, len, flags);
  2103. + else {
  2104. + struct au_cpup_simple_args args = {
  2105. + .errp = &err,
  2106. + .dentry = dentry,
  2107. + .bdst = bdst,
  2108. + .len = len,
  2109. + .flags = flags
  2110. + };
  2111. + wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
  2112. + if (unlikely(wkq_err))
  2113. + err = wkq_err;
  2114. + }
  2115. +
  2116. + dput(parent);
  2117. + return err;
  2118. +}
  2119. +
  2120. +/* ---------------------------------------------------------------------- */
  2121. +
  2122. +/*
  2123. + * copyup the deleted file for writing.
  2124. + */
  2125. +static int au_do_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst,
  2126. + struct dentry *wh_dentry, struct file *file,
  2127. + loff_t len)
  2128. +{
  2129. + int err;
  2130. + aufs_bindex_t bstart;
  2131. + struct au_dinfo *dinfo;
  2132. + struct dentry *h_d_dst, *h_d_start;
  2133. +
  2134. + dinfo = au_di(dentry);
  2135. + AuRwMustWriteLock(&dinfo->di_rwsem);
  2136. +
  2137. + bstart = dinfo->di_bstart;
  2138. + h_d_dst = dinfo->di_hdentry[0 + bdst].hd_dentry;
  2139. + dinfo->di_bstart = bdst;
  2140. + dinfo->di_hdentry[0 + bdst].hd_dentry = wh_dentry;
  2141. + h_d_start = dinfo->di_hdentry[0 + bstart].hd_dentry;
  2142. + if (file)
  2143. + dinfo->di_hdentry[0 + bstart].hd_dentry
  2144. + = au_h_fptr(file, au_fbstart(file))->f_dentry;
  2145. + err = au_cpup_single(dentry, bdst, bstart, len, !AuCpup_DTIME,
  2146. + /*h_parent*/NULL);
  2147. + if (!err && file) {
  2148. + err = au_reopen_nondir(file);
  2149. + dinfo->di_hdentry[0 + bstart].hd_dentry = h_d_start;
  2150. + }
  2151. + dinfo->di_hdentry[0 + bdst].hd_dentry = h_d_dst;
  2152. + dinfo->di_bstart = bstart;
  2153. +
  2154. + return err;
  2155. +}
  2156. +
  2157. +static int au_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
  2158. + struct file *file)
  2159. +{
  2160. + int err;
  2161. + struct au_dtime dt;
  2162. + struct dentry *parent, *h_parent, *wh_dentry;
  2163. + struct au_branch *br;
  2164. + struct path h_path;
  2165. +
  2166. + br = au_sbr(dentry->d_sb, bdst);
  2167. + parent = dget_parent(dentry);
  2168. + h_parent = au_h_dptr(parent, bdst);
  2169. + wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
  2170. + err = PTR_ERR(wh_dentry);
  2171. + if (IS_ERR(wh_dentry))
  2172. + goto out;
  2173. +
  2174. + h_path.dentry = h_parent;
  2175. + h_path.mnt = br->br_mnt;
  2176. + au_dtime_store(&dt, parent, &h_path);
  2177. + err = au_do_cpup_wh(dentry, bdst, wh_dentry, file, len);
  2178. + if (unlikely(err))
  2179. + goto out_wh;
  2180. +
  2181. + dget(wh_dentry);
  2182. + h_path.dentry = wh_dentry;
  2183. + err = vfsub_unlink(h_parent->d_inode, &h_path, /*force*/0);
  2184. + if (unlikely(err)) {
  2185. + AuIOErr("failed remove copied-up tmp file %.*s(%d)\n",
  2186. + AuDLNPair(wh_dentry), err);
  2187. + err = -EIO;
  2188. + }
  2189. + au_dtime_revert(&dt);
  2190. + au_set_hi_wh(dentry->d_inode, bdst, wh_dentry);
  2191. +
  2192. + out_wh:
  2193. + dput(wh_dentry);
  2194. + out:
  2195. + dput(parent);
  2196. + return err;
  2197. +}
  2198. +
  2199. +struct au_cpup_wh_args {
  2200. + int *errp;
  2201. + struct dentry *dentry;
  2202. + aufs_bindex_t bdst;
  2203. + loff_t len;
  2204. + struct file *file;
  2205. +};
  2206. +
  2207. +static void au_call_cpup_wh(void *args)
  2208. +{
  2209. + struct au_cpup_wh_args *a = args;
  2210. + *a->errp = au_cpup_wh(a->dentry, a->bdst, a->len, a->file);
  2211. +}
  2212. +
  2213. +int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
  2214. + struct file *file)
  2215. +{
  2216. + int err, wkq_err;
  2217. + struct dentry *parent, *h_orph, *h_parent, *h_dentry;
  2218. + struct inode *dir, *h_dir, *h_tmpdir, *h_inode;
  2219. + struct au_wbr *wbr;
  2220. +
  2221. + parent = dget_parent(dentry);
  2222. + dir = parent->d_inode;
  2223. + h_orph = NULL;
  2224. + h_parent = NULL;
  2225. + h_dir = au_igrab(au_h_iptr(dir, bdst));
  2226. + h_tmpdir = h_dir;
  2227. + if (!h_dir->i_nlink) {
  2228. + wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
  2229. + h_orph = wbr->wbr_orph;
  2230. +
  2231. + h_parent = dget(au_h_dptr(parent, bdst));
  2232. + au_set_h_dptr(parent, bdst, NULL);
  2233. + au_set_h_dptr(parent, bdst, dget(h_orph));
  2234. + h_tmpdir = h_orph->d_inode;
  2235. + au_set_h_iptr(dir, bdst, NULL, 0);
  2236. + au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
  2237. +
  2238. + /* this temporary unlock is safe */
  2239. + if (file)
  2240. + h_dentry = au_h_fptr(file, au_fbstart(file))->f_dentry;
  2241. + else
  2242. + h_dentry = au_h_dptr(dentry, au_dbstart(dentry));
  2243. + h_inode = h_dentry->d_inode;
  2244. + IMustLock(h_inode);
  2245. + mutex_unlock(&h_inode->i_mutex);
  2246. + mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
  2247. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  2248. + }
  2249. +
  2250. + if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE))
  2251. + err = au_cpup_wh(dentry, bdst, len, file);
  2252. + else {
  2253. + struct au_cpup_wh_args args = {
  2254. + .errp = &err,
  2255. + .dentry = dentry,
  2256. + .bdst = bdst,
  2257. + .len = len,
  2258. + .file = file
  2259. + };
  2260. + wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
  2261. + if (unlikely(wkq_err))
  2262. + err = wkq_err;
  2263. + }
  2264. +
  2265. + if (h_orph) {
  2266. + mutex_unlock(&h_tmpdir->i_mutex);
  2267. + au_set_h_iptr(dir, bdst, NULL, 0);
  2268. + au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
  2269. + au_set_h_dptr(parent, bdst, NULL);
  2270. + au_set_h_dptr(parent, bdst, h_parent);
  2271. + }
  2272. + iput(h_dir);
  2273. + dput(parent);
  2274. +
  2275. + return err;
  2276. +}
  2277. +
  2278. +/* ---------------------------------------------------------------------- */
  2279. +
  2280. +/*
  2281. + * generic routine for both of copy-up and copy-down.
  2282. + */
  2283. +/* cf. revalidate function in file.c */
  2284. +int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
  2285. + int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
  2286. + struct dentry *h_parent, void *arg),
  2287. + void *arg)
  2288. +{
  2289. + int err;
  2290. + struct au_pin pin;
  2291. + struct dentry *d, *parent, *h_parent, *real_parent;
  2292. +
  2293. + err = 0;
  2294. + parent = dget_parent(dentry);
  2295. + if (IS_ROOT(parent))
  2296. + goto out;
  2297. +
  2298. + au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
  2299. + au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
  2300. +
  2301. + /* do not use au_dpage */
  2302. + real_parent = parent;
  2303. + while (1) {
  2304. + dput(parent);
  2305. + parent = dget_parent(dentry);
  2306. + h_parent = au_h_dptr(parent, bdst);
  2307. + if (h_parent)
  2308. + goto out; /* success */
  2309. +
  2310. + /* find top dir which is necessary to cpup */
  2311. + do {
  2312. + d = parent;
  2313. + dput(parent);
  2314. + parent = dget_parent(d);
  2315. + di_read_lock_parent3(parent, !AuLock_IR);
  2316. + h_parent = au_h_dptr(parent, bdst);
  2317. + di_read_unlock(parent, !AuLock_IR);
  2318. + } while (!h_parent);
  2319. +
  2320. + if (d != real_parent)
  2321. + di_write_lock_child3(d);
  2322. +
  2323. + /* somebody else might create while we were sleeping */
  2324. + if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) {
  2325. + if (au_h_dptr(d, bdst))
  2326. + au_update_dbstart(d);
  2327. +
  2328. + au_pin_set_dentry(&pin, d);
  2329. + err = au_do_pin(&pin);
  2330. + if (!err) {
  2331. + err = cp(d, bdst, h_parent, arg);
  2332. + au_unpin(&pin);
  2333. + }
  2334. + }
  2335. +
  2336. + if (d != real_parent)
  2337. + di_write_unlock(d);
  2338. + if (unlikely(err))
  2339. + break;
  2340. + }
  2341. +
  2342. + out:
  2343. + dput(parent);
  2344. + return err;
  2345. +}
  2346. +
  2347. +static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
  2348. + struct dentry *h_parent __maybe_unused ,
  2349. + void *arg __maybe_unused)
  2350. +{
  2351. + return au_sio_cpup_simple(dentry, bdst, -1, AuCpup_DTIME);
  2352. +}
  2353. +
  2354. +int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
  2355. +{
  2356. + return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
  2357. +}
  2358. +
  2359. +int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
  2360. +{
  2361. + int err;
  2362. + struct dentry *parent;
  2363. + struct inode *dir;
  2364. +
  2365. + parent = dget_parent(dentry);
  2366. + dir = parent->d_inode;
  2367. + err = 0;
  2368. + if (au_h_iptr(dir, bdst))
  2369. + goto out;
  2370. +
  2371. + di_read_unlock(parent, AuLock_IR);
  2372. + di_write_lock_parent(parent);
  2373. + /* someone else might change our inode while we were sleeping */
  2374. + if (!au_h_iptr(dir, bdst))
  2375. + err = au_cpup_dirs(dentry, bdst);
  2376. + di_downgrade_lock(parent, AuLock_IR);
  2377. +
  2378. + out:
  2379. + dput(parent);
  2380. + return err;
  2381. +}
  2382. diff -Nur linux-2.6.31.5.orig/fs/aufs/cpup.h linux-2.6.31.5/fs/aufs/cpup.h
  2383. --- linux-2.6.31.5.orig/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100
  2384. +++ linux-2.6.31.5/fs/aufs/cpup.h 2009-11-15 22:02:37.000000000 +0100
  2385. @@ -0,0 +1,81 @@
  2386. +/*
  2387. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  2388. + *
  2389. + * This program, aufs is free software; you can redistribute it and/or modify
  2390. + * it under the terms of the GNU General Public License as published by
  2391. + * the Free Software Foundation; either version 2 of the License, or
  2392. + * (at your option) any later version.
  2393. + *
  2394. + * This program is distributed in the hope that it will be useful,
  2395. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2396. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2397. + * GNU General Public License for more details.
  2398. + *
  2399. + * You should have received a copy of the GNU General Public License
  2400. + * along with this program; if not, write to the Free Software
  2401. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  2402. + */
  2403. +
  2404. +/*
  2405. + * copy-up/down functions
  2406. + */
  2407. +
  2408. +#ifndef __AUFS_CPUP_H__
  2409. +#define __AUFS_CPUP_H__
  2410. +
  2411. +#ifdef __KERNEL__
  2412. +
  2413. +#include <linux/path.h>
  2414. +#include <linux/time.h>
  2415. +#include <linux/aufs_type.h>
  2416. +
  2417. +struct inode;
  2418. +struct file;
  2419. +
  2420. +void au_cpup_attr_flags(struct inode *dst, struct inode *src);
  2421. +void au_cpup_attr_timesizes(struct inode *inode);
  2422. +void au_cpup_attr_nlink(struct inode *inode, int force);
  2423. +void au_cpup_attr_changeable(struct inode *inode);
  2424. +void au_cpup_igen(struct inode *inode, struct inode *h_inode);
  2425. +void au_cpup_attr_all(struct inode *inode, int force);
  2426. +
  2427. +/* ---------------------------------------------------------------------- */
  2428. +
  2429. +/* cpup flags */
  2430. +#define AuCpup_DTIME 1 /* do dtime_store/revert */
  2431. +#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino,
  2432. + for link(2) */
  2433. +#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name)
  2434. +#define au_fset_cpup(flags, name) { (flags) |= AuCpup_##name; }
  2435. +#define au_fclr_cpup(flags, name) { (flags) &= ~AuCpup_##name; }
  2436. +
  2437. +int au_copy_file(struct file *dst, struct file *src, loff_t len);
  2438. +int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
  2439. + aufs_bindex_t bsrc, loff_t len, unsigned int flags,
  2440. + struct dentry *dst_parent);
  2441. +int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
  2442. + unsigned int flags);
  2443. +int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
  2444. + struct file *file);
  2445. +
  2446. +int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
  2447. + int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
  2448. + struct dentry *h_parent, void *arg),
  2449. + void *arg);
  2450. +int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
  2451. +int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
  2452. +
  2453. +/* ---------------------------------------------------------------------- */
  2454. +
  2455. +/* keep timestamps when copyup */
  2456. +struct au_dtime {
  2457. + struct dentry *dt_dentry;
  2458. + struct path dt_h_path;
  2459. + struct timespec dt_atime, dt_mtime;
  2460. +};
  2461. +void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
  2462. + struct path *h_path);
  2463. +void au_dtime_revert(struct au_dtime *dt);
  2464. +
  2465. +#endif /* __KERNEL__ */
  2466. +#endif /* __AUFS_CPUP_H__ */
  2467. diff -Nur linux-2.6.31.5.orig/fs/aufs/dbgaufs.c linux-2.6.31.5/fs/aufs/dbgaufs.c
  2468. --- linux-2.6.31.5.orig/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
  2469. +++ linux-2.6.31.5/fs/aufs/dbgaufs.c 2009-11-15 22:02:37.000000000 +0100
  2470. @@ -0,0 +1,331 @@
  2471. +/*
  2472. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  2473. + *
  2474. + * This program, aufs is free software; you can redistribute it and/or modify
  2475. + * it under the terms of the GNU General Public License as published by
  2476. + * the Free Software Foundation; either version 2 of the License, or
  2477. + * (at your option) any later version.
  2478. + *
  2479. + * This program is distributed in the hope that it will be useful,
  2480. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2481. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2482. + * GNU General Public License for more details.
  2483. + *
  2484. + * You should have received a copy of the GNU General Public License
  2485. + * along with this program; if not, write to the Free Software
  2486. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  2487. + */
  2488. +
  2489. +/*
  2490. + * debugfs interface
  2491. + */
  2492. +
  2493. +#include <linux/debugfs.h>
  2494. +#include "aufs.h"
  2495. +
  2496. +#ifndef CONFIG_SYSFS
  2497. +#error DEBUG_FS depends upon SYSFS
  2498. +#endif
  2499. +
  2500. +static struct dentry *dbgaufs;
  2501. +static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
  2502. +
  2503. +/* 20 is max digits length of ulong 64 */
  2504. +struct dbgaufs_arg {
  2505. + int n;
  2506. + char a[20 * 4];
  2507. +};
  2508. +
  2509. +/*
  2510. + * common function for all XINO files
  2511. + */
  2512. +static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
  2513. + struct file *file)
  2514. +{
  2515. + kfree(file->private_data);
  2516. + return 0;
  2517. +}
  2518. +
  2519. +static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
  2520. +{
  2521. + int err;
  2522. + struct kstat st;
  2523. + struct dbgaufs_arg *p;
  2524. +
  2525. + err = -ENOMEM;
  2526. + p = kmalloc(sizeof(*p), GFP_NOFS);
  2527. + if (unlikely(!p))
  2528. + goto out;
  2529. +
  2530. + err = 0;
  2531. + p->n = 0;
  2532. + file->private_data = p;
  2533. + if (!xf)
  2534. + goto out;
  2535. +
  2536. + err = vfs_getattr(xf->f_vfsmnt, xf->f_dentry, &st);
  2537. + if (!err) {
  2538. + if (do_fcnt)
  2539. + p->n = snprintf
  2540. + (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n",
  2541. + (long)file_count(xf), st.blocks, st.blksize,
  2542. + (long long)st.size);
  2543. + else
  2544. + p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n",
  2545. + st.blocks, st.blksize,
  2546. + (long long)st.size);
  2547. + AuDebugOn(p->n >= sizeof(p->a));
  2548. + } else {
  2549. + p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
  2550. + err = 0;
  2551. + }
  2552. +
  2553. + out:
  2554. + return err;
  2555. +
  2556. +}
  2557. +
  2558. +static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
  2559. + size_t count, loff_t *ppos)
  2560. +{
  2561. + struct dbgaufs_arg *p;
  2562. +
  2563. + p = file->private_data;
  2564. + return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
  2565. +}
  2566. +
  2567. +/* ---------------------------------------------------------------------- */
  2568. +
  2569. +static int dbgaufs_xib_open(struct inode *inode, struct file *file)
  2570. +{
  2571. + int err;
  2572. + struct au_sbinfo *sbinfo;
  2573. + struct super_block *sb;
  2574. +
  2575. + sbinfo = inode->i_private;
  2576. + sb = sbinfo->si_sb;
  2577. + si_noflush_read_lock(sb);
  2578. + err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0);
  2579. + si_read_unlock(sb);
  2580. + return err;
  2581. +}
  2582. +
  2583. +static const struct file_operations dbgaufs_xib_fop = {
  2584. + .open = dbgaufs_xib_open,
  2585. + .release = dbgaufs_xi_release,
  2586. + .read = dbgaufs_xi_read
  2587. +};
  2588. +
  2589. +/* ---------------------------------------------------------------------- */
  2590. +
  2591. +#define DbgaufsXi_PREFIX "xi"
  2592. +
  2593. +static int dbgaufs_xino_open(struct inode *inode, struct file *file)
  2594. +{
  2595. + int err;
  2596. + long l;
  2597. + struct au_sbinfo *sbinfo;
  2598. + struct super_block *sb;
  2599. + struct file *xf;
  2600. + struct qstr *name;
  2601. +
  2602. + err = -ENOENT;
  2603. + xf = NULL;
  2604. + name = &file->f_dentry->d_name;
  2605. + if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
  2606. + || memcmp(name->name, DbgaufsXi_PREFIX,
  2607. + sizeof(DbgaufsXi_PREFIX) - 1)))
  2608. + goto out;
  2609. + err = strict_strtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
  2610. + if (unlikely(err))
  2611. + goto out;
  2612. +
  2613. + sbinfo = inode->i_private;
  2614. + sb = sbinfo->si_sb;
  2615. + si_noflush_read_lock(sb);
  2616. + if (l <= au_sbend(sb)) {
  2617. + xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file;
  2618. + err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1);
  2619. + } else
  2620. + err = -ENOENT;
  2621. + si_read_unlock(sb);
  2622. +
  2623. + out:
  2624. + return err;
  2625. +}
  2626. +
  2627. +static const struct file_operations dbgaufs_xino_fop = {
  2628. + .open = dbgaufs_xino_open,
  2629. + .release = dbgaufs_xi_release,
  2630. + .read = dbgaufs_xi_read
  2631. +};
  2632. +
  2633. +void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
  2634. +{
  2635. + aufs_bindex_t bend;
  2636. + struct au_branch *br;
  2637. + struct au_xino_file *xi;
  2638. +
  2639. + if (!au_sbi(sb)->si_dbgaufs)
  2640. + return;
  2641. +
  2642. + bend = au_sbend(sb);
  2643. + for (; bindex <= bend; bindex++) {
  2644. + br = au_sbr(sb, bindex);
  2645. + xi = &br->br_xino;
  2646. + if (xi->xi_dbgaufs) {
  2647. + debugfs_remove(xi->xi_dbgaufs);
  2648. + xi->xi_dbgaufs = NULL;
  2649. + }
  2650. + }
  2651. +}
  2652. +
  2653. +void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
  2654. +{
  2655. + struct au_sbinfo *sbinfo;
  2656. + struct dentry *parent;
  2657. + struct au_branch *br;
  2658. + struct au_xino_file *xi;
  2659. + aufs_bindex_t bend;
  2660. + char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */
  2661. +
  2662. + sbinfo = au_sbi(sb);
  2663. + parent = sbinfo->si_dbgaufs;
  2664. + if (!parent)
  2665. + return;
  2666. +
  2667. + bend = au_sbend(sb);
  2668. + for (; bindex <= bend; bindex++) {
  2669. + snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
  2670. + br = au_sbr(sb, bindex);
  2671. + xi = &br->br_xino;
  2672. + AuDebugOn(xi->xi_dbgaufs);
  2673. + xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
  2674. + sbinfo, &dbgaufs_xino_fop);
  2675. + /* ignore an error */
  2676. + if (unlikely(!xi->xi_dbgaufs))
  2677. + AuWarn1("failed %s under debugfs\n", name);
  2678. + }
  2679. +}
  2680. +
  2681. +/* ---------------------------------------------------------------------- */
  2682. +
  2683. +#ifdef CONFIG_AUFS_EXPORT
  2684. +static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
  2685. +{
  2686. + int err;
  2687. + struct au_sbinfo *sbinfo;
  2688. + struct super_block *sb;
  2689. +
  2690. + sbinfo = inode->i_private;
  2691. + sb = sbinfo->si_sb;
  2692. + si_noflush_read_lock(sb);
  2693. + err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0);
  2694. + si_read_unlock(sb);
  2695. + return err;
  2696. +}
  2697. +
  2698. +static const struct file_operations dbgaufs_xigen_fop = {
  2699. + .open = dbgaufs_xigen_open,
  2700. + .release = dbgaufs_xi_release,
  2701. + .read = dbgaufs_xi_read
  2702. +};
  2703. +
  2704. +static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
  2705. +{
  2706. + int err;
  2707. +
  2708. + /*
  2709. + * This function is a dynamic '__init' fucntion actually,
  2710. + * so the tiny check for si_rwsem is unnecessary.
  2711. + */
  2712. + /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
  2713. +
  2714. + err = -EIO;
  2715. + sbinfo->si_dbgaufs_xigen = debugfs_create_file
  2716. + ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
  2717. + &dbgaufs_xigen_fop);
  2718. + if (sbinfo->si_dbgaufs_xigen)
  2719. + err = 0;
  2720. +
  2721. + return err;
  2722. +}
  2723. +#else
  2724. +static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
  2725. +{
  2726. + return 0;
  2727. +}
  2728. +#endif /* CONFIG_AUFS_EXPORT */
  2729. +
  2730. +/* ---------------------------------------------------------------------- */
  2731. +
  2732. +void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
  2733. +{
  2734. + /*
  2735. + * This function is a dynamic '__init' fucntion actually,
  2736. + * so the tiny check for si_rwsem is unnecessary.
  2737. + */
  2738. + /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
  2739. +
  2740. + debugfs_remove_recursive(sbinfo->si_dbgaufs);
  2741. + sbinfo->si_dbgaufs = NULL;
  2742. + kobject_put(&sbinfo->si_kobj);
  2743. +}
  2744. +
  2745. +int dbgaufs_si_init(struct au_sbinfo *sbinfo)
  2746. +{
  2747. + int err;
  2748. + char name[SysaufsSiNameLen];
  2749. +
  2750. + /*
  2751. + * This function is a dynamic '__init' fucntion actually,
  2752. + * so the tiny check for si_rwsem is unnecessary.
  2753. + */
  2754. + /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
  2755. +
  2756. + err = -ENOENT;
  2757. + if (!dbgaufs) {
  2758. + AuErr1("/debug/aufs is uninitialized\n");
  2759. + goto out;
  2760. + }
  2761. +
  2762. + err = -EIO;
  2763. + sysaufs_name(sbinfo, name);
  2764. + sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
  2765. + if (unlikely(!sbinfo->si_dbgaufs))
  2766. + goto out;
  2767. + kobject_get(&sbinfo->si_kobj);
  2768. +
  2769. + sbinfo->si_dbgaufs_xib = debugfs_create_file
  2770. + ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
  2771. + &dbgaufs_xib_fop);
  2772. + if (unlikely(!sbinfo->si_dbgaufs_xib))
  2773. + goto out_dir;
  2774. +
  2775. + err = dbgaufs_xigen_init(sbinfo);
  2776. + if (!err)
  2777. + goto out; /* success */
  2778. +
  2779. + out_dir:
  2780. + dbgaufs_si_fin(sbinfo);
  2781. + out:
  2782. + return err;
  2783. +}
  2784. +
  2785. +/* ---------------------------------------------------------------------- */
  2786. +
  2787. +void dbgaufs_fin(void)
  2788. +{
  2789. + debugfs_remove(dbgaufs);
  2790. +}
  2791. +
  2792. +int __init dbgaufs_init(void)
  2793. +{
  2794. + int err;
  2795. +
  2796. + err = -EIO;
  2797. + dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
  2798. + if (dbgaufs)
  2799. + err = 0;
  2800. + return err;
  2801. +}
  2802. diff -Nur linux-2.6.31.5.orig/fs/aufs/dbgaufs.h linux-2.6.31.5/fs/aufs/dbgaufs.h
  2803. --- linux-2.6.31.5.orig/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
  2804. +++ linux-2.6.31.5/fs/aufs/dbgaufs.h 2009-11-15 22:02:37.000000000 +0100
  2805. @@ -0,0 +1,79 @@
  2806. +/*
  2807. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  2808. + *
  2809. + * This program, aufs is free software; you can redistribute it and/or modify
  2810. + * it under the terms of the GNU General Public License as published by
  2811. + * the Free Software Foundation; either version 2 of the License, or
  2812. + * (at your option) any later version.
  2813. + *
  2814. + * This program is distributed in the hope that it will be useful,
  2815. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2816. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2817. + * GNU General Public License for more details.
  2818. + *
  2819. + * You should have received a copy of the GNU General Public License
  2820. + * along with this program; if not, write to the Free Software
  2821. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  2822. + */
  2823. +
  2824. +/*
  2825. + * debugfs interface
  2826. + */
  2827. +
  2828. +#ifndef __DBGAUFS_H__
  2829. +#define __DBGAUFS_H__
  2830. +
  2831. +#ifdef __KERNEL__
  2832. +
  2833. +#include <linux/init.h>
  2834. +#include <linux/aufs_type.h>
  2835. +
  2836. +struct super_block;
  2837. +struct au_sbinfo;
  2838. +
  2839. +#ifdef CONFIG_DEBUG_FS
  2840. +/* dbgaufs.c */
  2841. +void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
  2842. +void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
  2843. +void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
  2844. +int dbgaufs_si_init(struct au_sbinfo *sbinfo);
  2845. +void dbgaufs_fin(void);
  2846. +int __init dbgaufs_init(void);
  2847. +
  2848. +#else
  2849. +
  2850. +static inline
  2851. +void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
  2852. +{
  2853. + /* empty */
  2854. +}
  2855. +
  2856. +static inline
  2857. +void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
  2858. +{
  2859. + /* empty */
  2860. +}
  2861. +
  2862. +static inline
  2863. +void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
  2864. +{
  2865. + /* empty */
  2866. +}
  2867. +
  2868. +static inline
  2869. +int dbgaufs_si_init(struct au_sbinfo *sbinfo)
  2870. +{
  2871. + return 0;
  2872. +}
  2873. +
  2874. +#define dbgaufs_fin() do {} while (0)
  2875. +
  2876. +static inline
  2877. +int __init dbgaufs_init(void)
  2878. +{
  2879. + return 0;
  2880. +}
  2881. +#endif /* CONFIG_DEBUG_FS */
  2882. +
  2883. +#endif /* __KERNEL__ */
  2884. +#endif /* __DBGAUFS_H__ */
  2885. diff -Nur linux-2.6.31.5.orig/fs/aufs/dcsub.c linux-2.6.31.5/fs/aufs/dcsub.c
  2886. --- linux-2.6.31.5.orig/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100
  2887. +++ linux-2.6.31.5/fs/aufs/dcsub.c 2009-11-15 22:02:37.000000000 +0100
  2888. @@ -0,0 +1,223 @@
  2889. +/*
  2890. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  2891. + *
  2892. + * This program, aufs is free software; you can redistribute it and/or modify
  2893. + * it under the terms of the GNU General Public License as published by
  2894. + * the Free Software Foundation; either version 2 of the License, or
  2895. + * (at your option) any later version.
  2896. + *
  2897. + * This program is distributed in the hope that it will be useful,
  2898. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2899. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2900. + * GNU General Public License for more details.
  2901. + *
  2902. + * You should have received a copy of the GNU General Public License
  2903. + * along with this program; if not, write to the Free Software
  2904. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  2905. + */
  2906. +
  2907. +/*
  2908. + * sub-routines for dentry cache
  2909. + */
  2910. +
  2911. +#include "aufs.h"
  2912. +
  2913. +static void au_dpage_free(struct au_dpage *dpage)
  2914. +{
  2915. + int i;
  2916. + struct dentry **p;
  2917. +
  2918. + p = dpage->dentries;
  2919. + for (i = 0; i < dpage->ndentry; i++)
  2920. + dput(*p++);
  2921. + free_page((unsigned long)dpage->dentries);
  2922. +}
  2923. +
  2924. +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
  2925. +{
  2926. + int err;
  2927. + void *p;
  2928. +
  2929. + err = -ENOMEM;
  2930. + dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
  2931. + if (unlikely(!dpages->dpages))
  2932. + goto out;
  2933. +
  2934. + p = (void *)__get_free_page(gfp);
  2935. + if (unlikely(!p))
  2936. + goto out_dpages;
  2937. +
  2938. + dpages->dpages[0].ndentry = 0;
  2939. + dpages->dpages[0].dentries = p;
  2940. + dpages->ndpage = 1;
  2941. + return 0; /* success */
  2942. +
  2943. + out_dpages:
  2944. + kfree(dpages->dpages);
  2945. + out:
  2946. + return err;
  2947. +}
  2948. +
  2949. +void au_dpages_free(struct au_dcsub_pages *dpages)
  2950. +{
  2951. + int i;
  2952. + struct au_dpage *p;
  2953. +
  2954. + p = dpages->dpages;
  2955. + for (i = 0; i < dpages->ndpage; i++)
  2956. + au_dpage_free(p++);
  2957. + kfree(dpages->dpages);
  2958. +}
  2959. +
  2960. +static int au_dpages_append(struct au_dcsub_pages *dpages,
  2961. + struct dentry *dentry, gfp_t gfp)
  2962. +{
  2963. + int err, sz;
  2964. + struct au_dpage *dpage;
  2965. + void *p;
  2966. +
  2967. + dpage = dpages->dpages + dpages->ndpage - 1;
  2968. + sz = PAGE_SIZE / sizeof(dentry);
  2969. + if (unlikely(dpage->ndentry >= sz)) {
  2970. + AuLabel(new dpage);
  2971. + err = -ENOMEM;
  2972. + sz = dpages->ndpage * sizeof(*dpages->dpages);
  2973. + p = au_kzrealloc(dpages->dpages, sz,
  2974. + sz + sizeof(*dpages->dpages), gfp);
  2975. + if (unlikely(!p))
  2976. + goto out;
  2977. +
  2978. + dpages->dpages = p;
  2979. + dpage = dpages->dpages + dpages->ndpage;
  2980. + p = (void *)__get_free_page(gfp);
  2981. + if (unlikely(!p))
  2982. + goto out;
  2983. +
  2984. + dpage->ndentry = 0;
  2985. + dpage->dentries = p;
  2986. + dpages->ndpage++;
  2987. + }
  2988. +
  2989. + dpage->dentries[dpage->ndentry++] = dget(dentry);
  2990. + return 0; /* success */
  2991. +
  2992. + out:
  2993. + return err;
  2994. +}
  2995. +
  2996. +int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
  2997. + au_dpages_test test, void *arg)
  2998. +{
  2999. + int err;
  3000. + struct dentry *this_parent = root;
  3001. + struct list_head *next;
  3002. + struct super_block *sb = root->d_sb;
  3003. +
  3004. + err = 0;
  3005. + spin_lock(&dcache_lock);
  3006. + repeat:
  3007. + next = this_parent->d_subdirs.next;
  3008. + resume:
  3009. + if (this_parent->d_sb == sb
  3010. + && !IS_ROOT(this_parent)
  3011. + && atomic_read(&this_parent->d_count)
  3012. + && this_parent->d_inode
  3013. + && (!test || test(this_parent, arg))) {
  3014. + err = au_dpages_append(dpages, this_parent, GFP_ATOMIC);
  3015. + if (unlikely(err))
  3016. + goto out;
  3017. + }
  3018. +
  3019. + while (next != &this_parent->d_subdirs) {
  3020. + struct list_head *tmp = next;
  3021. + struct dentry *dentry = list_entry(tmp, struct dentry,
  3022. + d_u.d_child);
  3023. + next = tmp->next;
  3024. + if (/*d_unhashed(dentry) || */!dentry->d_inode)
  3025. + continue;
  3026. + if (!list_empty(&dentry->d_subdirs)) {
  3027. + this_parent = dentry;
  3028. + goto repeat;
  3029. + }
  3030. + if (dentry->d_sb == sb
  3031. + && atomic_read(&dentry->d_count)
  3032. + && (!test || test(dentry, arg))) {
  3033. + err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
  3034. + if (unlikely(err))
  3035. + goto out;
  3036. + }
  3037. + }
  3038. +
  3039. + if (this_parent != root) {
  3040. + next = this_parent->d_u.d_child.next;
  3041. + this_parent = this_parent->d_parent; /* dcache_lock is locked */
  3042. + goto resume;
  3043. + }
  3044. + out:
  3045. + spin_unlock(&dcache_lock);
  3046. + return err;
  3047. +}
  3048. +
  3049. +int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
  3050. + int do_include, au_dpages_test test, void *arg)
  3051. +{
  3052. + int err;
  3053. +
  3054. + err = 0;
  3055. + spin_lock(&dcache_lock);
  3056. + if (do_include && (!test || test(dentry, arg))) {
  3057. + err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
  3058. + if (unlikely(err))
  3059. + goto out;
  3060. + }
  3061. + while (!IS_ROOT(dentry)) {
  3062. + dentry = dentry->d_parent; /* dcache_lock is locked */
  3063. + if (!test || test(dentry, arg)) {
  3064. + err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
  3065. + if (unlikely(err))
  3066. + break;
  3067. + }
  3068. + }
  3069. +
  3070. + out:
  3071. + spin_unlock(&dcache_lock);
  3072. +
  3073. + return err;
  3074. +}
  3075. +
  3076. +struct dentry *au_test_subdir(struct dentry *d1, struct dentry *d2)
  3077. +{
  3078. + struct dentry *trap, **dentries;
  3079. + int err, i, j;
  3080. + struct au_dcsub_pages dpages;
  3081. + struct au_dpage *dpage;
  3082. +
  3083. + trap = ERR_PTR(-ENOMEM);
  3084. + err = au_dpages_init(&dpages, GFP_NOFS);
  3085. + if (unlikely(err))
  3086. + goto out;
  3087. + err = au_dcsub_pages_rev(&dpages, d1, /*do_include*/1, NULL, NULL);
  3088. + if (unlikely(err))
  3089. + goto out_dpages;
  3090. +
  3091. + trap = d1;
  3092. + for (i = 0; !err && i < dpages.ndpage; i++) {
  3093. + dpage = dpages.dpages + i;
  3094. + dentries = dpage->dentries;
  3095. + for (j = 0; !err && j < dpage->ndentry; j++) {
  3096. + struct dentry *d;
  3097. +
  3098. + d = dentries[j];
  3099. + err = (d == d2);
  3100. + if (!err)
  3101. + trap = d;
  3102. + }
  3103. + }
  3104. + if (!err)
  3105. + trap = NULL;
  3106. +
  3107. + out_dpages:
  3108. + au_dpages_free(&dpages);
  3109. + out:
  3110. + return trap;
  3111. +}
  3112. diff -Nur linux-2.6.31.5.orig/fs/aufs/dcsub.h linux-2.6.31.5/fs/aufs/dcsub.h
  3113. --- linux-2.6.31.5.orig/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100
  3114. +++ linux-2.6.31.5/fs/aufs/dcsub.h 2009-11-15 22:02:37.000000000 +0100
  3115. @@ -0,0 +1,54 @@
  3116. +/*
  3117. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  3118. + *
  3119. + * This program, aufs is free software; you can redistribute it and/or modify
  3120. + * it under the terms of the GNU General Public License as published by
  3121. + * the Free Software Foundation; either version 2 of the License, or
  3122. + * (at your option) any later version.
  3123. + *
  3124. + * This program is distributed in the hope that it will be useful,
  3125. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3126. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3127. + * GNU General Public License for more details.
  3128. + *
  3129. + * You should have received a copy of the GNU General Public License
  3130. + * along with this program; if not, write to the Free Software
  3131. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  3132. + */
  3133. +
  3134. +/*
  3135. + * sub-routines for dentry cache
  3136. + */
  3137. +
  3138. +#ifndef __AUFS_DCSUB_H__
  3139. +#define __AUFS_DCSUB_H__
  3140. +
  3141. +#ifdef __KERNEL__
  3142. +
  3143. +#include <linux/types.h>
  3144. +
  3145. +struct dentry;
  3146. +
  3147. +struct au_dpage {
  3148. + int ndentry;
  3149. + struct dentry **dentries;
  3150. +};
  3151. +
  3152. +struct au_dcsub_pages {
  3153. + int ndpage;
  3154. + struct au_dpage *dpages;
  3155. +};
  3156. +
  3157. +/* ---------------------------------------------------------------------- */
  3158. +
  3159. +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
  3160. +void au_dpages_free(struct au_dcsub_pages *dpages);
  3161. +typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
  3162. +int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
  3163. + au_dpages_test test, void *arg);
  3164. +int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
  3165. + int do_include, au_dpages_test test, void *arg);
  3166. +struct dentry *au_test_subdir(struct dentry *d1, struct dentry *d2);
  3167. +
  3168. +#endif /* __KERNEL__ */
  3169. +#endif /* __AUFS_DCSUB_H__ */
  3170. diff -Nur linux-2.6.31.5.orig/fs/aufs/debug.c linux-2.6.31.5/fs/aufs/debug.c
  3171. --- linux-2.6.31.5.orig/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
  3172. +++ linux-2.6.31.5/fs/aufs/debug.c 2009-11-15 22:02:37.000000000 +0100
  3173. @@ -0,0 +1,427 @@
  3174. +/*
  3175. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  3176. + *
  3177. + * This program, aufs is free software; you can redistribute it and/or modify
  3178. + * it under the terms of the GNU General Public License as published by
  3179. + * the Free Software Foundation; either version 2 of the License, or
  3180. + * (at your option) any later version.
  3181. + *
  3182. + * This program is distributed in the hope that it will be useful,
  3183. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3184. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3185. + * GNU General Public License for more details.
  3186. + *
  3187. + * You should have received a copy of the GNU General Public License
  3188. + * along with this program; if not, write to the Free Software
  3189. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  3190. + */
  3191. +
  3192. +/*
  3193. + * debug print functions
  3194. + */
  3195. +
  3196. +#include <linux/module.h>
  3197. +#include <linux/vt_kern.h>
  3198. +#include "aufs.h"
  3199. +
  3200. +int aufs_debug;
  3201. +MODULE_PARM_DESC(debug, "debug print");
  3202. +module_param_named(debug, aufs_debug, int, S_IRUGO | S_IWUSR | S_IWGRP);
  3203. +
  3204. +char *au_plevel = KERN_DEBUG;
  3205. +#define dpri(fmt, arg...) do { \
  3206. + if (au_debug_test()) \
  3207. + printk("%s" fmt, au_plevel, ##arg); \
  3208. +} while (0)
  3209. +
  3210. +/* ---------------------------------------------------------------------- */
  3211. +
  3212. +void au_dpri_whlist(struct au_nhash *whlist)
  3213. +{
  3214. + unsigned long ul, n;
  3215. + struct hlist_head *head;
  3216. + struct au_vdir_wh *tpos;
  3217. + struct hlist_node *pos;
  3218. +
  3219. + n = whlist->nh_num;
  3220. + head = whlist->nh_head;
  3221. + for (ul = 0; ul < n; ul++) {
  3222. + hlist_for_each_entry(tpos, pos, head, wh_hash)
  3223. + dpri("b%d, %.*s, %d\n",
  3224. + tpos->wh_bindex,
  3225. + tpos->wh_str.len, tpos->wh_str.name,
  3226. + tpos->wh_str.len);
  3227. + head++;
  3228. + }
  3229. +}
  3230. +
  3231. +void au_dpri_vdir(struct au_vdir *vdir)
  3232. +{
  3233. + unsigned long ul;
  3234. + union au_vdir_deblk_p p;
  3235. + unsigned char *o;
  3236. +
  3237. + if (!vdir || IS_ERR(vdir)) {
  3238. + dpri("err %ld\n", PTR_ERR(vdir));
  3239. + return;
  3240. + }
  3241. +
  3242. + dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n",
  3243. + vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
  3244. + vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
  3245. + for (ul = 0; ul < vdir->vd_nblk; ul++) {
  3246. + p.deblk = vdir->vd_deblk[ul];
  3247. + o = p.deblk;
  3248. + dpri("[%lu]: %p\n", ul, o);
  3249. + }
  3250. +}
  3251. +
  3252. +static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode,
  3253. + struct dentry *wh)
  3254. +{
  3255. + char *n = NULL;
  3256. + int l = 0;
  3257. +
  3258. + if (!inode || IS_ERR(inode)) {
  3259. + dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
  3260. + return -1;
  3261. + }
  3262. +
  3263. + /* the type of i_blocks depends upon CONFIG_LSF */
  3264. + BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
  3265. + && sizeof(inode->i_blocks) != sizeof(u64));
  3266. + if (wh) {
  3267. + n = (void *)wh->d_name.name;
  3268. + l = wh->d_name.len;
  3269. + }
  3270. +
  3271. + dpri("i%d: i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
  3272. + " ct %lld, np %lu, st 0x%lx, f 0x%x, g %x%s%.*s\n",
  3273. + bindex,
  3274. + inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
  3275. + atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
  3276. + i_size_read(inode), (unsigned long long)inode->i_blocks,
  3277. + (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
  3278. + inode->i_mapping ? inode->i_mapping->nrpages : 0,
  3279. + inode->i_state, inode->i_flags, inode->i_generation,
  3280. + l ? ", wh " : "", l, n);
  3281. + return 0;
  3282. +}
  3283. +
  3284. +void au_dpri_inode(struct inode *inode)
  3285. +{
  3286. + struct au_iinfo *iinfo;
  3287. + aufs_bindex_t bindex;
  3288. + int err;
  3289. +
  3290. + err = do_pri_inode(-1, inode, NULL);
  3291. + if (err || !au_test_aufs(inode->i_sb))
  3292. + return;
  3293. +
  3294. + iinfo = au_ii(inode);
  3295. + if (!iinfo)
  3296. + return;
  3297. + dpri("i-1: bstart %d, bend %d, gen %d\n",
  3298. + iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode));
  3299. + if (iinfo->ii_bstart < 0)
  3300. + return;
  3301. + for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++)
  3302. + do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode,
  3303. + iinfo->ii_hinode[0 + bindex].hi_whdentry);
  3304. +}
  3305. +
  3306. +static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
  3307. +{
  3308. + struct dentry *wh = NULL;
  3309. +
  3310. + if (!dentry || IS_ERR(dentry)) {
  3311. + dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
  3312. + return -1;
  3313. + }
  3314. + /* do not call dget_parent() here */
  3315. + dpri("d%d: %.*s?/%.*s, %s, cnt %d, flags 0x%x\n",
  3316. + bindex,
  3317. + AuDLNPair(dentry->d_parent), AuDLNPair(dentry),
  3318. + dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
  3319. + atomic_read(&dentry->d_count), dentry->d_flags);
  3320. + if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) {
  3321. + struct au_iinfo *iinfo = au_ii(dentry->d_inode);
  3322. + if (iinfo)
  3323. + wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
  3324. + }
  3325. + do_pri_inode(bindex, dentry->d_inode, wh);
  3326. + return 0;
  3327. +}
  3328. +
  3329. +void au_dpri_dentry(struct dentry *dentry)
  3330. +{
  3331. + struct au_dinfo *dinfo;
  3332. + aufs_bindex_t bindex;
  3333. + int err;
  3334. +
  3335. + err = do_pri_dentry(-1, dentry);
  3336. + if (err || !au_test_aufs(dentry->d_sb))
  3337. + return;
  3338. +
  3339. + dinfo = au_di(dentry);
  3340. + if (!dinfo)
  3341. + return;
  3342. + dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d\n",
  3343. + dinfo->di_bstart, dinfo->di_bend,
  3344. + dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry));
  3345. + if (dinfo->di_bstart < 0)
  3346. + return;
  3347. + for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++)
  3348. + do_pri_dentry(bindex, dinfo->di_hdentry[0 + bindex].hd_dentry);
  3349. +}
  3350. +
  3351. +static int do_pri_file(aufs_bindex_t bindex, struct file *file)
  3352. +{
  3353. + char a[32];
  3354. +
  3355. + if (!file || IS_ERR(file)) {
  3356. + dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
  3357. + return -1;
  3358. + }
  3359. + a[0] = 0;
  3360. + if (bindex < 0
  3361. + && file->f_dentry
  3362. + && au_test_aufs(file->f_dentry->d_sb)
  3363. + && au_fi(file))
  3364. + snprintf(a, sizeof(a), ", mmapped %d", au_test_mmapped(file));
  3365. + dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, pos %llu%s\n",
  3366. + bindex, file->f_mode, file->f_flags, (long)file_count(file),
  3367. + file->f_pos, a);
  3368. + if (file->f_dentry)
  3369. + do_pri_dentry(bindex, file->f_dentry);
  3370. + return 0;
  3371. +}
  3372. +
  3373. +void au_dpri_file(struct file *file)
  3374. +{
  3375. + struct au_finfo *finfo;
  3376. + aufs_bindex_t bindex;
  3377. + int err;
  3378. +
  3379. + err = do_pri_file(-1, file);
  3380. + if (err || !file->f_dentry || !au_test_aufs(file->f_dentry->d_sb))
  3381. + return;
  3382. +
  3383. + finfo = au_fi(file);
  3384. + if (!finfo)
  3385. + return;
  3386. + if (finfo->fi_bstart < 0)
  3387. + return;
  3388. + for (bindex = finfo->fi_bstart; bindex <= finfo->fi_bend; bindex++) {
  3389. + struct au_hfile *hf;
  3390. +
  3391. + hf = finfo->fi_hfile + bindex;
  3392. + do_pri_file(bindex, hf ? hf->hf_file : NULL);
  3393. + }
  3394. +}
  3395. +
  3396. +static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
  3397. +{
  3398. + struct vfsmount *mnt;
  3399. + struct super_block *sb;
  3400. +
  3401. + if (!br || IS_ERR(br))
  3402. + goto out;
  3403. + mnt = br->br_mnt;
  3404. + if (!mnt || IS_ERR(mnt))
  3405. + goto out;
  3406. + sb = mnt->mnt_sb;
  3407. + if (!sb || IS_ERR(sb))
  3408. + goto out;
  3409. +
  3410. + dpri("s%d: {perm 0x%x, cnt %d, wbr %p}, "
  3411. + "%s, dev 0x%02x%02x, flags 0x%lx, cnt(BIAS) %d, active %d, "
  3412. + "xino %d\n",
  3413. + bindex, br->br_perm, atomic_read(&br->br_count), br->br_wbr,
  3414. + au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
  3415. + sb->s_flags, sb->s_count - S_BIAS,
  3416. + atomic_read(&sb->s_active), !!br->br_xino.xi_file);
  3417. + return 0;
  3418. +
  3419. + out:
  3420. + dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
  3421. + return -1;
  3422. +}
  3423. +
  3424. +void au_dpri_sb(struct super_block *sb)
  3425. +{
  3426. + struct au_sbinfo *sbinfo;
  3427. + aufs_bindex_t bindex;
  3428. + int err;
  3429. + /* to reuduce stack size */
  3430. + struct {
  3431. + struct vfsmount mnt;
  3432. + struct au_branch fake;
  3433. + } *a;
  3434. +
  3435. + /* this function can be called from magic sysrq */
  3436. + a = kzalloc(sizeof(*a), GFP_ATOMIC);
  3437. + if (unlikely(!a)) {
  3438. + dpri("no memory\n");
  3439. + return;
  3440. + }
  3441. +
  3442. + a->mnt.mnt_sb = sb;
  3443. + a->fake.br_perm = 0;
  3444. + a->fake.br_mnt = &a->mnt;
  3445. + a->fake.br_xino.xi_file = NULL;
  3446. + atomic_set(&a->fake.br_count, 0);
  3447. + smp_mb(); /* atomic_set */
  3448. + err = do_pri_br(-1, &a->fake);
  3449. + kfree(a);
  3450. + dpri("dev 0x%x\n", sb->s_dev);
  3451. + if (err || !au_test_aufs(sb))
  3452. + return;
  3453. +
  3454. + sbinfo = au_sbi(sb);
  3455. + if (!sbinfo)
  3456. + return;
  3457. + dpri("nw %d, gen %u, kobj %d\n",
  3458. + atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
  3459. + atomic_read(&sbinfo->si_kobj.kref.refcount));
  3460. + for (bindex = 0; bindex <= sbinfo->si_bend; bindex++)
  3461. + do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
  3462. +}
  3463. +
  3464. +/* ---------------------------------------------------------------------- */
  3465. +
  3466. +void au_dbg_sleep_jiffy(int jiffy)
  3467. +{
  3468. + while (jiffy)
  3469. + jiffy = schedule_timeout_uninterruptible(jiffy);
  3470. +}
  3471. +
  3472. +void au_dbg_iattr(struct iattr *ia)
  3473. +{
  3474. +#define AuBit(name) if (ia->ia_valid & ATTR_ ## name) \
  3475. + dpri(#name "\n")
  3476. + AuBit(MODE);
  3477. + AuBit(UID);
  3478. + AuBit(GID);
  3479. + AuBit(SIZE);
  3480. + AuBit(ATIME);
  3481. + AuBit(MTIME);
  3482. + AuBit(CTIME);
  3483. + AuBit(ATIME_SET);
  3484. + AuBit(MTIME_SET);
  3485. + AuBit(FORCE);
  3486. + AuBit(ATTR_FLAG);
  3487. + AuBit(KILL_SUID);
  3488. + AuBit(KILL_SGID);
  3489. + AuBit(FILE);
  3490. + AuBit(KILL_PRIV);
  3491. + AuBit(OPEN);
  3492. + AuBit(TIMES_SET);
  3493. +#undef AuBit
  3494. + dpri("ia_file %p\n", ia->ia_file);
  3495. +}
  3496. +
  3497. +/* ---------------------------------------------------------------------- */
  3498. +
  3499. +void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen)
  3500. +{
  3501. + struct dentry *parent;
  3502. +
  3503. + parent = dget_parent(dentry);
  3504. + AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode)
  3505. + || IS_ROOT(dentry)
  3506. + || au_digen(parent) != sigen);
  3507. + dput(parent);
  3508. +}
  3509. +
  3510. +void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen)
  3511. +{
  3512. + struct dentry *parent;
  3513. +
  3514. + parent = dget_parent(dentry);
  3515. + AuDebugOn(S_ISDIR(dentry->d_inode->i_mode)
  3516. + || au_digen(parent) != sigen);
  3517. + dput(parent);
  3518. +}
  3519. +
  3520. +void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
  3521. +{
  3522. + int err, i, j;
  3523. + struct au_dcsub_pages dpages;
  3524. + struct au_dpage *dpage;
  3525. + struct dentry **dentries;
  3526. +
  3527. + err = au_dpages_init(&dpages, GFP_NOFS);
  3528. + AuDebugOn(err);
  3529. + err = au_dcsub_pages_rev(&dpages, parent, /*do_include*/1, NULL, NULL);
  3530. + AuDebugOn(err);
  3531. + for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
  3532. + dpage = dpages.dpages + i;
  3533. + dentries = dpage->dentries;
  3534. + for (j = dpage->ndentry - 1; !err && j >= 0; j--)
  3535. + AuDebugOn(au_digen(dentries[j]) != sigen);
  3536. + }
  3537. + au_dpages_free(&dpages);
  3538. +}
  3539. +
  3540. +void au_dbg_verify_hf(struct au_finfo *finfo)
  3541. +{
  3542. + struct au_hfile *hf;
  3543. + aufs_bindex_t bend, bindex;
  3544. +
  3545. + if (finfo->fi_bstart >= 0) {
  3546. + bend = finfo->fi_bend;
  3547. + for (bindex = finfo->fi_bstart; bindex <= bend; bindex++) {
  3548. + hf = finfo->fi_hfile + bindex;
  3549. + AuDebugOn(hf->hf_file || hf->hf_br);
  3550. + }
  3551. + }
  3552. +}
  3553. +
  3554. +void au_dbg_verify_kthread(void)
  3555. +{
  3556. + if (au_test_wkq(current)) {
  3557. + au_dbg_blocked();
  3558. + BUG();
  3559. + }
  3560. +}
  3561. +
  3562. +/* ---------------------------------------------------------------------- */
  3563. +
  3564. +void au_debug_sbinfo_init(struct au_sbinfo *sbinfo __maybe_unused)
  3565. +{
  3566. +#ifdef AuForceNoPlink
  3567. + au_opt_clr(sbinfo->si_mntflags, PLINK);
  3568. +#endif
  3569. +#ifdef AuForceNoXino
  3570. + au_opt_clr(sbinfo->si_mntflags, XINO);
  3571. +#endif
  3572. +#ifdef AuForceNoRefrof
  3573. + au_opt_clr(sbinfo->si_mntflags, REFROF);
  3574. +#endif
  3575. +#ifdef AuForceHinotify
  3576. + au_opt_set_udba(sbinfo->si_mntflags, UDBA_HINOTIFY);
  3577. +#endif
  3578. +}
  3579. +
  3580. +int __init au_debug_init(void)
  3581. +{
  3582. + aufs_bindex_t bindex;
  3583. + struct au_vdir_destr destr;
  3584. +
  3585. + bindex = -1;
  3586. + AuDebugOn(bindex >= 0);
  3587. +
  3588. + destr.len = -1;
  3589. + AuDebugOn(destr.len < NAME_MAX);
  3590. +
  3591. +#ifdef CONFIG_4KSTACKS
  3592. + AuWarn("CONFIG_4KSTACKS is defined.\n");
  3593. +#endif
  3594. +
  3595. +#ifdef AuForceNoBrs
  3596. + sysaufs_brs = 0;
  3597. +#endif
  3598. +
  3599. + return 0;
  3600. +}
  3601. diff -Nur linux-2.6.31.5.orig/fs/aufs/debug.h linux-2.6.31.5/fs/aufs/debug.h
  3602. --- linux-2.6.31.5.orig/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100
  3603. +++ linux-2.6.31.5/fs/aufs/debug.h 2009-11-15 22:16:14.000000000 +0100
  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.31.5.orig/fs/aufs/dentry.c linux-2.6.31.5/fs/aufs/dentry.c
  3867. --- linux-2.6.31.5.orig/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100
  3868. +++ linux-2.6.31.5/fs/aufs/dentry.c 2009-11-15 22:02:37.000000000 +0100
  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.31.5.orig/fs/aufs/dentry.h linux-2.6.31.5/fs/aufs/dentry.h
  4751. --- linux-2.6.31.5.orig/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
  4752. +++ linux-2.6.31.5/fs/aufs/dentry.h 2009-11-15 22:02:37.000000000 +0100
  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.31.5.orig/fs/aufs/dinfo.c linux-2.6.31.5/fs/aufs/dinfo.c
  4986. --- linux-2.6.31.5.orig/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100
  4987. +++ linux-2.6.31.5/fs/aufs/dinfo.c 2009-11-15 22:02:37.000000000 +0100
  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.31.5.orig/fs/aufs/dir.c linux-2.6.31.5/fs/aufs/dir.c
  5357. --- linux-2.6.31.5.orig/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
  5358. +++ linux-2.6.31.5/fs/aufs/dir.c 2009-11-15 22:02:37.000000000 +0100
  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.31.5.orig/fs/aufs/dir.h linux-2.6.31.5/fs/aufs/dir.h
  5899. --- linux-2.6.31.5.orig/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100
  5900. +++ linux-2.6.31.5/fs/aufs/dir.h 2009-11-15 22:02:37.000000000 +0100
  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.31.5.orig/fs/aufs/export.c linux-2.6.31.5/fs/aufs/export.c
  6017. --- linux-2.6.31.5.orig/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
  6018. +++ linux-2.6.31.5/fs/aufs/export.c 2009-11-15 22:27:33.000000000 +0100
  6019. @@ -0,0 +1,746 @@
  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 "aufs.h"
  6049. +
  6050. +union conv {
  6051. +#ifdef CONFIG_AUFS_INO_T_64
  6052. + __u32 a[2];
  6053. +#else
  6054. + __u32 a[1];
  6055. +#endif
  6056. + ino_t ino;
  6057. +};
  6058. +
  6059. +static ino_t decode_ino(__u32 *a)
  6060. +{
  6061. + union conv u;
  6062. +
  6063. + BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
  6064. + u.a[0] = a[0];
  6065. +#ifdef CONFIG_AUFS_INO_T_64
  6066. + u.a[1] = a[1];
  6067. +#endif
  6068. + return u.ino;
  6069. +}
  6070. +
  6071. +static void encode_ino(__u32 *a, ino_t ino)
  6072. +{
  6073. + union conv u;
  6074. +
  6075. + u.ino = ino;
  6076. + a[0] = u.a[0];
  6077. +#ifdef CONFIG_AUFS_INO_T_64
  6078. + a[1] = u.a[1];
  6079. +#endif
  6080. +}
  6081. +
  6082. +/* NFS file handle */
  6083. +enum {
  6084. + Fh_br_id,
  6085. + Fh_sigen,
  6086. +#ifdef CONFIG_AUFS_INO_T_64
  6087. + /* support 64bit inode number */
  6088. + Fh_ino1,
  6089. + Fh_ino2,
  6090. + Fh_dir_ino1,
  6091. + Fh_dir_ino2,
  6092. +#else
  6093. + Fh_ino1,
  6094. + Fh_dir_ino1,
  6095. +#endif
  6096. + Fh_igen,
  6097. + Fh_h_type,
  6098. + Fh_tail,
  6099. +
  6100. + Fh_ino = Fh_ino1,
  6101. + Fh_dir_ino = Fh_dir_ino1
  6102. +};
  6103. +
  6104. +static int au_test_anon(struct dentry *dentry)
  6105. +{
  6106. + return !!(dentry->d_flags & DCACHE_DISCONNECTED);
  6107. +}
  6108. +
  6109. +/* ---------------------------------------------------------------------- */
  6110. +/* inode generation external table */
  6111. +
  6112. +int au_xigen_inc(struct inode *inode)
  6113. +{
  6114. + int err;
  6115. + loff_t pos;
  6116. + ssize_t sz;
  6117. + __u32 igen;
  6118. + struct super_block *sb;
  6119. + struct au_sbinfo *sbinfo;
  6120. +
  6121. + err = 0;
  6122. + sb = inode->i_sb;
  6123. + sbinfo = au_sbi(sb);
  6124. + /*
  6125. + * temporary workaround for escaping from SiMustAnyLock() in
  6126. + * au_mntflags(), since this function is called from au_iinfo_fin().
  6127. + */
  6128. + if (unlikely(!au_opt_test(sbinfo->si_mntflags, XINO)))
  6129. + goto out;
  6130. +
  6131. + pos = inode->i_ino;
  6132. + pos *= sizeof(igen);
  6133. + igen = inode->i_generation + 1;
  6134. + sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
  6135. + sizeof(igen), &pos);
  6136. + if (sz == sizeof(igen))
  6137. + goto out; /* success */
  6138. +
  6139. + err = sz;
  6140. + if (unlikely(sz >= 0)) {
  6141. + err = -EIO;
  6142. + AuIOErr("xigen error (%zd)\n", sz);
  6143. + }
  6144. +
  6145. + out:
  6146. + return err;
  6147. +}
  6148. +
  6149. +int au_xigen_new(struct inode *inode)
  6150. +{
  6151. + int err;
  6152. + loff_t pos;
  6153. + ssize_t sz;
  6154. + struct super_block *sb;
  6155. + struct au_sbinfo *sbinfo;
  6156. + struct file *file;
  6157. +
  6158. + err = 0;
  6159. + /* todo: dirty, at mount time */
  6160. + if (inode->i_ino == AUFS_ROOT_INO)
  6161. + goto out;
  6162. + sb = inode->i_sb;
  6163. + SiMustAnyLock(sb);
  6164. + if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
  6165. + goto out;
  6166. +
  6167. + err = -EFBIG;
  6168. + pos = inode->i_ino;
  6169. + if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
  6170. + AuIOErr1("too large i%lld\n", pos);
  6171. + goto out;
  6172. + }
  6173. + pos *= sizeof(inode->i_generation);
  6174. +
  6175. + err = 0;
  6176. + sbinfo = au_sbi(sb);
  6177. + file = sbinfo->si_xigen;
  6178. + BUG_ON(!file);
  6179. +
  6180. + if (i_size_read(file->f_dentry->d_inode)
  6181. + < pos + sizeof(inode->i_generation)) {
  6182. + inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
  6183. + sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
  6184. + sizeof(inode->i_generation), &pos);
  6185. + } else
  6186. + sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
  6187. + sizeof(inode->i_generation), &pos);
  6188. + if (sz == sizeof(inode->i_generation))
  6189. + goto out; /* success */
  6190. +
  6191. + err = sz;
  6192. + if (unlikely(sz >= 0)) {
  6193. + err = -EIO;
  6194. + AuIOErr("xigen error (%zd)\n", sz);
  6195. + }
  6196. +
  6197. + out:
  6198. + return err;
  6199. +}
  6200. +
  6201. +int au_xigen_set(struct super_block *sb, struct file *base)
  6202. +{
  6203. + int err;
  6204. + struct au_sbinfo *sbinfo;
  6205. + struct file *file;
  6206. +
  6207. + SiMustWriteLock(sb);
  6208. +
  6209. + sbinfo = au_sbi(sb);
  6210. + file = au_xino_create2(base, sbinfo->si_xigen);
  6211. + err = PTR_ERR(file);
  6212. + if (IS_ERR(file))
  6213. + goto out;
  6214. + err = 0;
  6215. + if (sbinfo->si_xigen)
  6216. + fput(sbinfo->si_xigen);
  6217. + sbinfo->si_xigen = file;
  6218. +
  6219. + out:
  6220. + return err;
  6221. +}
  6222. +
  6223. +void au_xigen_clr(struct super_block *sb)
  6224. +{
  6225. + struct au_sbinfo *sbinfo;
  6226. +
  6227. + SiMustWriteLock(sb);
  6228. +
  6229. + sbinfo = au_sbi(sb);
  6230. + if (sbinfo->si_xigen) {
  6231. + fput(sbinfo->si_xigen);
  6232. + sbinfo->si_xigen = NULL;
  6233. + }
  6234. +}
  6235. +
  6236. +/* ---------------------------------------------------------------------- */
  6237. +
  6238. +static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
  6239. + ino_t dir_ino)
  6240. +{
  6241. + struct dentry *dentry, *d;
  6242. + struct inode *inode;
  6243. + unsigned int sigen;
  6244. +
  6245. + dentry = NULL;
  6246. + inode = ilookup(sb, ino);
  6247. + if (!inode)
  6248. + goto out;
  6249. +
  6250. + dentry = ERR_PTR(-ESTALE);
  6251. + sigen = au_sigen(sb);
  6252. + if (unlikely(is_bad_inode(inode)
  6253. + || IS_DEADDIR(inode)
  6254. + || sigen != au_iigen(inode)))
  6255. + goto out_iput;
  6256. +
  6257. + dentry = NULL;
  6258. + if (!dir_ino || S_ISDIR(inode->i_mode))
  6259. + dentry = d_find_alias(inode);
  6260. + else {
  6261. + spin_lock(&dcache_lock);
  6262. + list_for_each_entry(d, &inode->i_dentry, d_alias)
  6263. + if (!au_test_anon(d)
  6264. + && d->d_parent->d_inode->i_ino == dir_ino) {
  6265. + dentry = dget_locked(d);
  6266. + break;
  6267. + }
  6268. + spin_unlock(&dcache_lock);
  6269. + }
  6270. + if (unlikely(dentry && sigen != au_digen(dentry))) {
  6271. + dput(dentry);
  6272. + dentry = ERR_PTR(-ESTALE);
  6273. + }
  6274. +
  6275. + out_iput:
  6276. + iput(inode);
  6277. + out:
  6278. + return dentry;
  6279. +}
  6280. +
  6281. +/* ---------------------------------------------------------------------- */
  6282. +
  6283. +/* todo: dirty? */
  6284. +/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
  6285. +static struct vfsmount *au_mnt_get(struct super_block *sb)
  6286. +{
  6287. + struct mnt_namespace *ns;
  6288. + struct vfsmount *pos, *mnt;
  6289. +
  6290. + spin_lock(&vfsmount_lock);
  6291. + /* no get/put ?? */
  6292. + AuDebugOn(!current->nsproxy);
  6293. + ns = current->nsproxy->mnt_ns;
  6294. + AuDebugOn(!ns);
  6295. + mnt = NULL;
  6296. + /* the order (reverse) will not be a problem */
  6297. + list_for_each_entry(pos, &ns->list, mnt_list)
  6298. + if (pos->mnt_sb == sb) {
  6299. + mnt = mntget(pos);
  6300. + break;
  6301. + }
  6302. + spin_unlock(&vfsmount_lock);
  6303. + AuDebugOn(!mnt);
  6304. +
  6305. + return mnt;
  6306. +}
  6307. +
  6308. +struct au_nfsd_si_lock {
  6309. + const unsigned int sigen;
  6310. + const aufs_bindex_t br_id;
  6311. + unsigned char force_lock;
  6312. +};
  6313. +
  6314. +static aufs_bindex_t si_nfsd_read_lock(struct super_block *sb,
  6315. + struct au_nfsd_si_lock *nsi_lock)
  6316. +{
  6317. + aufs_bindex_t bindex;
  6318. +
  6319. + si_read_lock(sb, AuLock_FLUSH);
  6320. +
  6321. + /* branch id may be wrapped around */
  6322. + bindex = au_br_index(sb, nsi_lock->br_id);
  6323. + if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
  6324. + goto out; /* success */
  6325. +
  6326. + if (!nsi_lock->force_lock)
  6327. + si_read_unlock(sb);
  6328. + bindex = -1;
  6329. +
  6330. + out:
  6331. + return bindex;
  6332. +}
  6333. +
  6334. +struct find_name_by_ino {
  6335. + int called, found;
  6336. + ino_t ino;
  6337. + char *name;
  6338. + int namelen;
  6339. +};
  6340. +
  6341. +static int
  6342. +find_name_by_ino(void *arg, const char *name, int namelen, loff_t offset,
  6343. + u64 ino, unsigned int d_type)
  6344. +{
  6345. + struct find_name_by_ino *a = arg;
  6346. +
  6347. + a->called++;
  6348. + if (a->ino != ino)
  6349. + return 0;
  6350. +
  6351. + memcpy(a->name, name, namelen);
  6352. + a->namelen = namelen;
  6353. + a->found = 1;
  6354. + return 1;
  6355. +}
  6356. +
  6357. +static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
  6358. + struct au_nfsd_si_lock *nsi_lock)
  6359. +{
  6360. + struct dentry *dentry, *parent;
  6361. + struct file *file;
  6362. + struct inode *dir;
  6363. + struct find_name_by_ino arg;
  6364. + int err;
  6365. +
  6366. + parent = path->dentry;
  6367. + if (nsi_lock)
  6368. + si_read_unlock(parent->d_sb);
  6369. + path_get(path);
  6370. + file = dentry_open(parent, path->mnt, au_dir_roflags, current_cred());
  6371. + dentry = (void *)file;
  6372. + if (IS_ERR(file))
  6373. + goto out;
  6374. +
  6375. + dentry = ERR_PTR(-ENOMEM);
  6376. + arg.name = __getname();
  6377. + if (unlikely(!arg.name))
  6378. + goto out_file;
  6379. + arg.ino = ino;
  6380. + arg.found = 0;
  6381. + do {
  6382. + arg.called = 0;
  6383. + /* smp_mb(); */
  6384. + err = vfsub_readdir(file, find_name_by_ino, &arg);
  6385. + } while (!err && !arg.found && arg.called);
  6386. + dentry = ERR_PTR(err);
  6387. + if (unlikely(err))
  6388. + goto out_name;
  6389. + dentry = ERR_PTR(-ENOENT);
  6390. + if (!arg.found)
  6391. + goto out_name;
  6392. +
  6393. + /* do not call au_lkup_one() */
  6394. + dir = parent->d_inode;
  6395. + mutex_lock(&dir->i_mutex);
  6396. + dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
  6397. + mutex_unlock(&dir->i_mutex);
  6398. + AuTraceErrPtr(dentry);
  6399. + if (IS_ERR(dentry))
  6400. + goto out_name;
  6401. + AuDebugOn(au_test_anon(dentry));
  6402. + if (unlikely(!dentry->d_inode)) {
  6403. + dput(dentry);
  6404. + dentry = ERR_PTR(-ENOENT);
  6405. + }
  6406. +
  6407. + out_name:
  6408. + __putname(arg.name);
  6409. + out_file:
  6410. + fput(file);
  6411. + out:
  6412. + if (unlikely(nsi_lock
  6413. + && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
  6414. + if (!IS_ERR(dentry)) {
  6415. + dput(dentry);
  6416. + dentry = ERR_PTR(-ESTALE);
  6417. + }
  6418. + AuTraceErrPtr(dentry);
  6419. + return dentry;
  6420. +}
  6421. +
  6422. +static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
  6423. + ino_t dir_ino,
  6424. + struct au_nfsd_si_lock *nsi_lock)
  6425. +{
  6426. + struct dentry *dentry;
  6427. + struct path path;
  6428. +
  6429. + if (dir_ino != AUFS_ROOT_INO) {
  6430. + path.dentry = decode_by_ino(sb, dir_ino, 0);
  6431. + dentry = path.dentry;
  6432. + if (!path.dentry || IS_ERR(path.dentry))
  6433. + goto out;
  6434. + AuDebugOn(au_test_anon(path.dentry));
  6435. + } else
  6436. + path.dentry = dget(sb->s_root);
  6437. +
  6438. + path.mnt = au_mnt_get(sb);
  6439. + dentry = au_lkup_by_ino(&path, ino, nsi_lock);
  6440. + path_put(&path);
  6441. +
  6442. + out:
  6443. + AuTraceErrPtr(dentry);
  6444. + return dentry;
  6445. +}
  6446. +
  6447. +/* ---------------------------------------------------------------------- */
  6448. +
  6449. +static int h_acceptable(void *expv, struct dentry *dentry)
  6450. +{
  6451. + return 1;
  6452. +}
  6453. +
  6454. +static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
  6455. + char *buf, int len, struct super_block *sb)
  6456. +{
  6457. + char *p;
  6458. + int n;
  6459. + struct path path;
  6460. +
  6461. + p = d_path(h_rootpath, buf, len);
  6462. + if (IS_ERR(p))
  6463. + goto out;
  6464. + n = strlen(p);
  6465. +
  6466. + path.mnt = h_rootpath->mnt;
  6467. + path.dentry = h_parent;
  6468. + p = d_path(&path, buf, len);
  6469. + if (IS_ERR(p))
  6470. + goto out;
  6471. + if (n != 1)
  6472. + p += n;
  6473. +
  6474. + path.mnt = au_mnt_get(sb);
  6475. + path.dentry = sb->s_root;
  6476. + p = d_path(&path, buf, len - strlen(p));
  6477. + mntput(path.mnt);
  6478. + if (IS_ERR(p))
  6479. + goto out;
  6480. + if (n != 1)
  6481. + p[strlen(p)] = '/';
  6482. +
  6483. + out:
  6484. + AuTraceErrPtr(p);
  6485. + return p;
  6486. +}
  6487. +
  6488. +static
  6489. +struct dentry *decode_by_path(struct super_block *sb, aufs_bindex_t bindex,
  6490. + ino_t ino, __u32 *fh, int fh_len,
  6491. + struct au_nfsd_si_lock *nsi_lock)
  6492. +{
  6493. + struct dentry *dentry, *h_parent, *root;
  6494. + struct super_block *h_sb;
  6495. + char *pathname, *p;
  6496. + struct vfsmount *h_mnt;
  6497. + struct au_branch *br;
  6498. + int err;
  6499. + struct path path;
  6500. +
  6501. + br = au_sbr(sb, bindex);
  6502. + /* au_br_get(br); */
  6503. + h_mnt = br->br_mnt;
  6504. + h_sb = h_mnt->mnt_sb;
  6505. + /* todo: call lower fh_to_dentry()? fh_to_parent()? */
  6506. + h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
  6507. + fh_len - Fh_tail, fh[Fh_h_type],
  6508. + h_acceptable, /*context*/NULL);
  6509. + dentry = h_parent;
  6510. + if (unlikely(!h_parent || IS_ERR(h_parent))) {
  6511. + AuWarn1("%s decode_fh failed, %ld\n",
  6512. + au_sbtype(h_sb), PTR_ERR(h_parent));
  6513. + goto out;
  6514. + }
  6515. + dentry = NULL;
  6516. + if (unlikely(au_test_anon(h_parent))) {
  6517. + AuWarn1("%s decode_fh returned a disconnected dentry\n",
  6518. + au_sbtype(h_sb));
  6519. + goto out_h_parent;
  6520. + }
  6521. +
  6522. + dentry = ERR_PTR(-ENOMEM);
  6523. + pathname = (void *)__get_free_page(GFP_NOFS);
  6524. + if (unlikely(!pathname))
  6525. + goto out_h_parent;
  6526. +
  6527. + root = sb->s_root;
  6528. + path.mnt = h_mnt;
  6529. + di_read_lock_parent(root, !AuLock_IR);
  6530. + path.dentry = au_h_dptr(root, bindex);
  6531. + di_read_unlock(root, !AuLock_IR);
  6532. + p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
  6533. + dentry = (void *)p;
  6534. + if (IS_ERR(p))
  6535. + goto out_pathname;
  6536. +
  6537. + si_read_unlock(sb);
  6538. + err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
  6539. + dentry = ERR_PTR(err);
  6540. + if (unlikely(err))
  6541. + goto out_relock;
  6542. +
  6543. + dentry = ERR_PTR(-ENOENT);
  6544. + AuDebugOn(au_test_anon(path.dentry));
  6545. + if (unlikely(!path.dentry->d_inode))
  6546. + goto out_path;
  6547. +
  6548. + if (ino != path.dentry->d_inode->i_ino)
  6549. + dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
  6550. + else
  6551. + dentry = dget(path.dentry);
  6552. +
  6553. + out_path:
  6554. + path_put(&path);
  6555. + out_relock:
  6556. + if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
  6557. + if (!IS_ERR(dentry)) {
  6558. + dput(dentry);
  6559. + dentry = ERR_PTR(-ESTALE);
  6560. + }
  6561. + out_pathname:
  6562. + free_page((unsigned long)pathname);
  6563. + out_h_parent:
  6564. + dput(h_parent);
  6565. + out:
  6566. + /* au_br_put(br); */
  6567. + AuTraceErrPtr(dentry);
  6568. + return dentry;
  6569. +}
  6570. +
  6571. +/* ---------------------------------------------------------------------- */
  6572. +
  6573. +static struct dentry *
  6574. +aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
  6575. + int fh_type)
  6576. +{
  6577. + struct dentry *dentry;
  6578. + __u32 *fh = fid->raw;
  6579. + ino_t ino, dir_ino;
  6580. + aufs_bindex_t bindex;
  6581. + struct au_nfsd_si_lock nsi_lock = {
  6582. + .sigen = fh[Fh_sigen],
  6583. + .br_id = fh[Fh_br_id],
  6584. + .force_lock = 0
  6585. + };
  6586. +
  6587. + AuDebugOn(fh_len < Fh_tail);
  6588. +
  6589. + dentry = ERR_PTR(-ESTALE);
  6590. + /* branch id may be wrapped around */
  6591. + bindex = si_nfsd_read_lock(sb, &nsi_lock);
  6592. + if (unlikely(bindex < 0))
  6593. + goto out;
  6594. + nsi_lock.force_lock = 1;
  6595. +
  6596. + /* is this inode still cached? */
  6597. + ino = decode_ino(fh + Fh_ino);
  6598. + AuDebugOn(ino == AUFS_ROOT_INO);
  6599. + dir_ino = decode_ino(fh + Fh_dir_ino);
  6600. + dentry = decode_by_ino(sb, ino, dir_ino);
  6601. + if (IS_ERR(dentry))
  6602. + goto out_unlock;
  6603. + if (dentry)
  6604. + goto accept;
  6605. +
  6606. + /* is the parent dir cached? */
  6607. + dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
  6608. + if (IS_ERR(dentry))
  6609. + goto out_unlock;
  6610. + if (dentry)
  6611. + goto accept;
  6612. +
  6613. + /* lookup path */
  6614. + dentry = decode_by_path(sb, bindex, ino, fh, fh_len, &nsi_lock);
  6615. + if (IS_ERR(dentry))
  6616. + goto out_unlock;
  6617. + if (unlikely(!dentry))
  6618. + /* todo?: make it ESTALE */
  6619. + goto out_unlock;
  6620. +
  6621. + accept:
  6622. + if (dentry->d_inode->i_generation == fh[Fh_igen])
  6623. + goto out_unlock; /* success */
  6624. +
  6625. + dput(dentry);
  6626. + dentry = ERR_PTR(-ESTALE);
  6627. + out_unlock:
  6628. + si_read_unlock(sb);
  6629. + out:
  6630. + AuTraceErrPtr(dentry);
  6631. + return dentry;
  6632. +}
  6633. +
  6634. +#if 0 /* reserved for future use */
  6635. +/* support subtreecheck option */
  6636. +static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
  6637. + int fh_len, int fh_type)
  6638. +{
  6639. + struct dentry *parent;
  6640. + __u32 *fh = fid->raw;
  6641. + ino_t dir_ino;
  6642. +
  6643. + dir_ino = decode_ino(fh + Fh_dir_ino);
  6644. + parent = decode_by_ino(sb, dir_ino, 0);
  6645. + if (IS_ERR(parent))
  6646. + goto out;
  6647. + if (!parent)
  6648. + parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
  6649. + dir_ino, fh, fh_len);
  6650. +
  6651. + out:
  6652. + AuTraceErrPtr(parent);
  6653. + return parent;
  6654. +}
  6655. +#endif
  6656. +
  6657. +/* ---------------------------------------------------------------------- */
  6658. +
  6659. +static int aufs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
  6660. + int connectable)
  6661. +{
  6662. + int err;
  6663. + aufs_bindex_t bindex, bend;
  6664. + struct super_block *sb, *h_sb;
  6665. + struct inode *inode;
  6666. + struct dentry *parent, *h_parent;
  6667. + struct au_branch *br;
  6668. +
  6669. + AuDebugOn(au_test_anon(dentry));
  6670. +
  6671. + parent = NULL;
  6672. + err = -ENOSPC;
  6673. + if (unlikely(*max_len <= Fh_tail)) {
  6674. + AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
  6675. + goto out;
  6676. + }
  6677. +
  6678. + err = FILEID_ROOT;
  6679. + if (IS_ROOT(dentry)) {
  6680. + AuDebugOn(dentry->d_inode->i_ino != AUFS_ROOT_INO);
  6681. + goto out;
  6682. + }
  6683. +
  6684. + err = -EIO;
  6685. + h_parent = NULL;
  6686. + sb = dentry->d_sb;
  6687. + aufs_read_lock(dentry, AuLock_FLUSH | AuLock_IR);
  6688. + parent = dget_parent(dentry);
  6689. + di_read_lock_parent(parent, !AuLock_IR);
  6690. + inode = dentry->d_inode;
  6691. + AuDebugOn(!inode);
  6692. +#ifdef CONFIG_AUFS_DEBUG
  6693. + if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
  6694. + AuWarn1("NFS-exporting requires xino\n");
  6695. +#endif
  6696. +
  6697. + bend = au_dbtaildir(parent);
  6698. + for (bindex = au_dbstart(parent); bindex <= bend; bindex++) {
  6699. + h_parent = au_h_dptr(parent, bindex);
  6700. + if (h_parent) {
  6701. + dget(h_parent);
  6702. + break;
  6703. + }
  6704. + }
  6705. + if (unlikely(!h_parent))
  6706. + goto out_unlock;
  6707. +
  6708. + err = -EPERM;
  6709. + br = au_sbr(sb, bindex);
  6710. + h_sb = br->br_mnt->mnt_sb;
  6711. + if (unlikely(!h_sb->s_export_op)) {
  6712. + AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
  6713. + goto out_dput;
  6714. + }
  6715. +
  6716. + fh[Fh_br_id] = br->br_id;
  6717. + fh[Fh_sigen] = au_sigen(sb);
  6718. + encode_ino(fh + Fh_ino, inode->i_ino);
  6719. + encode_ino(fh + Fh_dir_ino, parent->d_inode->i_ino);
  6720. + fh[Fh_igen] = inode->i_generation;
  6721. +
  6722. + *max_len -= Fh_tail;
  6723. + fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
  6724. + max_len,
  6725. + /*connectable or subtreecheck*/0);
  6726. + err = fh[Fh_h_type];
  6727. + *max_len += Fh_tail;
  6728. + /* todo: macros? */
  6729. + if (err != 255)
  6730. + err = 99;
  6731. + else
  6732. + AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
  6733. +
  6734. + out_dput:
  6735. + dput(h_parent);
  6736. + out_unlock:
  6737. + di_read_unlock(parent, !AuLock_IR);
  6738. + dput(parent);
  6739. + aufs_read_unlock(dentry, AuLock_IR);
  6740. + out:
  6741. + if (unlikely(err < 0))
  6742. + err = 255;
  6743. + return err;
  6744. +}
  6745. +
  6746. +/* ---------------------------------------------------------------------- */
  6747. +
  6748. +static struct export_operations aufs_export_op = {
  6749. + .fh_to_dentry = aufs_fh_to_dentry,
  6750. + /* .fh_to_parent = aufs_fh_to_parent, */
  6751. + .encode_fh = aufs_encode_fh
  6752. +};
  6753. +
  6754. +void au_export_init(struct super_block *sb)
  6755. +{
  6756. + struct au_sbinfo *sbinfo;
  6757. + __u32 u;
  6758. +
  6759. + sb->s_export_op = &aufs_export_op;
  6760. + sbinfo = au_sbi(sb);
  6761. + sbinfo->si_xigen = NULL;
  6762. + get_random_bytes(&u, sizeof(u));
  6763. + BUILD_BUG_ON(sizeof(u) != sizeof(int));
  6764. + atomic_set(&sbinfo->si_xigen_next, u);
  6765. +}
  6766. diff -Nur linux-2.6.31.5.orig/fs/aufs/file.c linux-2.6.31.5/fs/aufs/file.c
  6767. --- linux-2.6.31.5.orig/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
  6768. +++ linux-2.6.31.5/fs/aufs/file.c 2009-11-15 22:02:37.000000000 +0100
  6769. @@ -0,0 +1,578 @@
  6770. +/*
  6771. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  6772. + *
  6773. + * This program, aufs is free software; you can redistribute it and/or modify
  6774. + * it under the terms of the GNU General Public License as published by
  6775. + * the Free Software Foundation; either version 2 of the License, or
  6776. + * (at your option) any later version.
  6777. + *
  6778. + * This program is distributed in the hope that it will be useful,
  6779. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  6780. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  6781. + * GNU General Public License for more details.
  6782. + *
  6783. + * You should have received a copy of the GNU General Public License
  6784. + * along with this program; if not, write to the Free Software
  6785. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  6786. + */
  6787. +
  6788. +/*
  6789. + * handling file/dir, and address_space operation
  6790. + */
  6791. +
  6792. +#include <linux/file.h>
  6793. +#include <linux/fsnotify.h>
  6794. +#include <linux/namei.h>
  6795. +#include <linux/pagemap.h>
  6796. +#include "aufs.h"
  6797. +
  6798. +/*
  6799. + * a dirty trick for handling deny_write_access().
  6800. + * because FMODE_EXEC flag is not passed to f_op->open(),
  6801. + * set it to file->private_data temporary.
  6802. + */
  6803. +void au_store_oflag(struct nameidata *nd, struct inode *inode)
  6804. +{
  6805. + if (nd
  6806. + /* && !(nd->flags & LOOKUP_CONTINUE) */
  6807. + && (nd->flags & LOOKUP_OPEN)
  6808. + && (nd->intent.open.flags & vfsub_fmode_to_uint(FMODE_EXEC))
  6809. + && inode
  6810. + && S_ISREG(inode->i_mode)) {
  6811. + /* suppress a warning in lp64 */
  6812. + unsigned long flags = nd->intent.open.flags;
  6813. + nd->intent.open.file->private_data = (void *)flags;
  6814. + /* smp_mb(); */
  6815. + }
  6816. +}
  6817. +
  6818. +/* drop flags for writing */
  6819. +unsigned int au_file_roflags(unsigned int flags)
  6820. +{
  6821. + flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
  6822. + flags |= O_RDONLY | O_NOATIME;
  6823. + return flags;
  6824. +}
  6825. +
  6826. +/* common functions to regular file and dir */
  6827. +struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
  6828. + struct file *file)
  6829. +{
  6830. + struct file *h_file;
  6831. + struct dentry *h_dentry;
  6832. + struct inode *h_inode;
  6833. + struct super_block *sb;
  6834. + struct au_branch *br;
  6835. + int err;
  6836. +
  6837. + /* a race condition can happen between open and unlink/rmdir */
  6838. + h_file = ERR_PTR(-ENOENT);
  6839. + h_dentry = au_h_dptr(dentry, bindex);
  6840. + if (au_test_nfsd(current) && !h_dentry)
  6841. + goto out;
  6842. + h_inode = h_dentry->d_inode;
  6843. + if (au_test_nfsd(current) && !h_inode)
  6844. + goto out;
  6845. + if (unlikely((!d_unhashed(dentry) && d_unhashed(h_dentry))
  6846. + || !h_inode))
  6847. + goto out;
  6848. +
  6849. + sb = dentry->d_sb;
  6850. + br = au_sbr(sb, bindex);
  6851. + h_file = ERR_PTR(-EACCES);
  6852. + if (file && (file->f_mode & FMODE_EXEC)
  6853. + && (br->br_mnt->mnt_flags & MNT_NOEXEC))
  6854. + goto out;
  6855. +
  6856. + /* drop flags for writing */
  6857. + if (au_test_ro(sb, bindex, dentry->d_inode))
  6858. + flags = au_file_roflags(flags);
  6859. + flags &= ~O_CREAT;
  6860. + atomic_inc(&br->br_count);
  6861. + h_file = dentry_open(dget(h_dentry), mntget(br->br_mnt), flags,
  6862. + current_cred());
  6863. + if (IS_ERR(h_file))
  6864. + goto out_br;
  6865. +
  6866. + if (file && (file->f_mode & FMODE_EXEC)) {
  6867. + h_file->f_mode |= FMODE_EXEC;
  6868. + err = deny_write_access(h_file);
  6869. + if (unlikely(err)) {
  6870. + fput(h_file);
  6871. + h_file = ERR_PTR(err);
  6872. + goto out_br;
  6873. + }
  6874. + }
  6875. + fsnotify_open(h_dentry);
  6876. + goto out; /* success */
  6877. +
  6878. + out_br:
  6879. + atomic_dec(&br->br_count);
  6880. + out:
  6881. + return h_file;
  6882. +}
  6883. +
  6884. +int au_do_open(struct file *file, int (*open)(struct file *file, int flags))
  6885. +{
  6886. + int err;
  6887. + struct dentry *dentry;
  6888. + struct super_block *sb;
  6889. +
  6890. + dentry = file->f_dentry;
  6891. + sb = dentry->d_sb;
  6892. + si_read_lock(sb, AuLock_FLUSH);
  6893. + err = au_finfo_init(file);
  6894. + if (unlikely(err))
  6895. + goto out;
  6896. +
  6897. + di_read_lock_child(dentry, AuLock_IR);
  6898. + err = open(file, file->f_flags);
  6899. + di_read_unlock(dentry, AuLock_IR);
  6900. +
  6901. + fi_write_unlock(file);
  6902. + if (unlikely(err))
  6903. + au_finfo_fin(file);
  6904. + out:
  6905. + si_read_unlock(sb);
  6906. + return err;
  6907. +}
  6908. +
  6909. +int au_reopen_nondir(struct file *file)
  6910. +{
  6911. + int err;
  6912. + aufs_bindex_t bstart, bindex, bend;
  6913. + struct dentry *dentry;
  6914. + struct file *h_file, *h_file_tmp;
  6915. +
  6916. + dentry = file->f_dentry;
  6917. + bstart = au_dbstart(dentry);
  6918. + h_file_tmp = NULL;
  6919. + if (au_fbstart(file) == bstart) {
  6920. + h_file = au_h_fptr(file, bstart);
  6921. + if (file->f_mode == h_file->f_mode)
  6922. + return 0; /* success */
  6923. + h_file_tmp = h_file;
  6924. + get_file(h_file_tmp);
  6925. + au_set_h_fptr(file, bstart, NULL);
  6926. + }
  6927. + AuDebugOn(au_fbstart(file) < bstart
  6928. + || au_fi(file)->fi_hfile[0 + bstart].hf_file);
  6929. +
  6930. + h_file = au_h_open(dentry, bstart, file->f_flags & ~O_TRUNC, file);
  6931. + err = PTR_ERR(h_file);
  6932. + if (IS_ERR(h_file))
  6933. + goto out; /* todo: close all? */
  6934. +
  6935. + err = 0;
  6936. + au_set_fbstart(file, bstart);
  6937. + au_set_h_fptr(file, bstart, h_file);
  6938. + au_update_figen(file);
  6939. + /* todo: necessary? */
  6940. + /* file->f_ra = h_file->f_ra; */
  6941. +
  6942. + /* close lower files */
  6943. + bend = au_fbend(file);
  6944. + for (bindex = bstart + 1; bindex <= bend; bindex++)
  6945. + au_set_h_fptr(file, bindex, NULL);
  6946. + au_set_fbend(file, bstart);
  6947. +
  6948. + out:
  6949. + if (h_file_tmp)
  6950. + fput(h_file_tmp);
  6951. + return err;
  6952. +}
  6953. +
  6954. +/* ---------------------------------------------------------------------- */
  6955. +
  6956. +static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
  6957. + struct dentry *hi_wh)
  6958. +{
  6959. + int err;
  6960. + aufs_bindex_t bstart;
  6961. + struct au_dinfo *dinfo;
  6962. + struct dentry *h_dentry;
  6963. +
  6964. + dinfo = au_di(file->f_dentry);
  6965. + AuRwMustWriteLock(&dinfo->di_rwsem);
  6966. +
  6967. + bstart = dinfo->di_bstart;
  6968. + dinfo->di_bstart = btgt;
  6969. + h_dentry = dinfo->di_hdentry[0 + btgt].hd_dentry;
  6970. + dinfo->di_hdentry[0 + btgt].hd_dentry = hi_wh;
  6971. + err = au_reopen_nondir(file);
  6972. + dinfo->di_hdentry[0 + btgt].hd_dentry = h_dentry;
  6973. + dinfo->di_bstart = bstart;
  6974. +
  6975. + return err;
  6976. +}
  6977. +
  6978. +static int au_ready_to_write_wh(struct file *file, loff_t len,
  6979. + aufs_bindex_t bcpup)
  6980. +{
  6981. + int err;
  6982. + struct inode *inode;
  6983. + struct dentry *dentry, *hi_wh;
  6984. + struct super_block *sb;
  6985. +
  6986. + dentry = file->f_dentry;
  6987. + inode = dentry->d_inode;
  6988. + hi_wh = au_hi_wh(inode, bcpup);
  6989. + if (!hi_wh)
  6990. + err = au_sio_cpup_wh(dentry, bcpup, len, file);
  6991. + else
  6992. + /* already copied-up after unlink */
  6993. + err = au_reopen_wh(file, bcpup, hi_wh);
  6994. +
  6995. + sb = dentry->d_sb;
  6996. + if (!err && inode->i_nlink > 1 && au_opt_test(au_mntflags(sb), PLINK))
  6997. + au_plink_append(inode, bcpup, au_h_dptr(dentry, bcpup));
  6998. +
  6999. + return err;
  7000. +}
  7001. +
  7002. +/*
  7003. + * prepare the @file for writing.
  7004. + */
  7005. +int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
  7006. +{
  7007. + int err;
  7008. + aufs_bindex_t bstart, bcpup;
  7009. + struct dentry *dentry, *parent, *h_dentry;
  7010. + struct inode *h_inode, *inode;
  7011. + struct super_block *sb;
  7012. +
  7013. + dentry = file->f_dentry;
  7014. + sb = dentry->d_sb;
  7015. + bstart = au_fbstart(file);
  7016. + inode = dentry->d_inode;
  7017. + err = au_test_ro(sb, bstart, inode);
  7018. + if (!err && (au_h_fptr(file, bstart)->f_mode & FMODE_WRITE)) {
  7019. + err = au_pin(pin, dentry, bstart, AuOpt_UDBA_NONE, /*flags*/0);
  7020. + goto out;
  7021. + }
  7022. +
  7023. + /* need to cpup */
  7024. + parent = dget_parent(dentry);
  7025. + di_write_lock_parent(parent);
  7026. + err = AuWbrCopyup(au_sbi(sb), dentry);
  7027. + bcpup = err;
  7028. + if (unlikely(err < 0))
  7029. + goto out_dgrade;
  7030. + err = 0;
  7031. +
  7032. + if (!au_h_dptr(parent, bcpup)) {
  7033. + err = au_cpup_dirs(dentry, bcpup);
  7034. + if (unlikely(err))
  7035. + goto out_dgrade;
  7036. + }
  7037. +
  7038. + err = au_pin(pin, dentry, bcpup, AuOpt_UDBA_NONE,
  7039. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  7040. + if (unlikely(err))
  7041. + goto out_dgrade;
  7042. +
  7043. + h_dentry = au_h_fptr(file, bstart)->f_dentry;
  7044. + h_inode = h_dentry->d_inode;
  7045. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  7046. + if (d_unhashed(dentry) /* || d_unhashed(h_dentry) */
  7047. + /* || !h_inode->i_nlink */) {
  7048. + err = au_ready_to_write_wh(file, len, bcpup);
  7049. + di_downgrade_lock(parent, AuLock_IR);
  7050. + } else {
  7051. + di_downgrade_lock(parent, AuLock_IR);
  7052. + if (!au_h_dptr(dentry, bcpup))
  7053. + err = au_sio_cpup_simple(dentry, bcpup, len,
  7054. + AuCpup_DTIME);
  7055. + if (!err)
  7056. + err = au_reopen_nondir(file);
  7057. + }
  7058. + mutex_unlock(&h_inode->i_mutex);
  7059. +
  7060. + if (!err) {
  7061. + au_pin_set_parent_lflag(pin, /*lflag*/0);
  7062. + goto out_dput; /* success */
  7063. + }
  7064. + au_unpin(pin);
  7065. + goto out_unlock;
  7066. +
  7067. + out_dgrade:
  7068. + di_downgrade_lock(parent, AuLock_IR);
  7069. + out_unlock:
  7070. + di_read_unlock(parent, AuLock_IR);
  7071. + out_dput:
  7072. + dput(parent);
  7073. + out:
  7074. + return err;
  7075. +}
  7076. +
  7077. +/* ---------------------------------------------------------------------- */
  7078. +
  7079. +static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
  7080. +{
  7081. + int err;
  7082. + aufs_bindex_t bstart;
  7083. + struct au_pin pin;
  7084. + struct au_finfo *finfo;
  7085. + struct dentry *dentry, *parent, *hi_wh;
  7086. + struct inode *inode;
  7087. + struct super_block *sb;
  7088. +
  7089. + FiMustWriteLock(file);
  7090. +
  7091. + err = 0;
  7092. + finfo = au_fi(file);
  7093. + dentry = file->f_dentry;
  7094. + sb = dentry->d_sb;
  7095. + inode = dentry->d_inode;
  7096. + bstart = au_ibstart(inode);
  7097. + if (bstart == finfo->fi_bstart)
  7098. + goto out;
  7099. +
  7100. + parent = dget_parent(dentry);
  7101. + if (au_test_ro(sb, bstart, inode)) {
  7102. + di_read_lock_parent(parent, !AuLock_IR);
  7103. + err = AuWbrCopyup(au_sbi(sb), dentry);
  7104. + bstart = err;
  7105. + di_read_unlock(parent, !AuLock_IR);
  7106. + if (unlikely(err < 0))
  7107. + goto out_parent;
  7108. + err = 0;
  7109. + }
  7110. +
  7111. + di_read_lock_parent(parent, AuLock_IR);
  7112. + hi_wh = au_hi_wh(inode, bstart);
  7113. + if (au_opt_test(au_mntflags(sb), PLINK)
  7114. + && au_plink_test(inode)
  7115. + && !d_unhashed(dentry)) {
  7116. + err = au_test_and_cpup_dirs(dentry, bstart);
  7117. + if (unlikely(err))
  7118. + goto out_unlock;
  7119. +
  7120. + /* always superio. */
  7121. + err = au_pin(&pin, dentry, bstart, AuOpt_UDBA_NONE,
  7122. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  7123. + if (!err)
  7124. + err = au_sio_cpup_simple(dentry, bstart, -1,
  7125. + AuCpup_DTIME);
  7126. + au_unpin(&pin);
  7127. + } else if (hi_wh) {
  7128. + /* already copied-up after unlink */
  7129. + err = au_reopen_wh(file, bstart, hi_wh);
  7130. + *need_reopen = 0;
  7131. + }
  7132. +
  7133. + out_unlock:
  7134. + di_read_unlock(parent, AuLock_IR);
  7135. + out_parent:
  7136. + dput(parent);
  7137. + out:
  7138. + return err;
  7139. +}
  7140. +
  7141. +static void au_do_refresh_file(struct file *file)
  7142. +{
  7143. + aufs_bindex_t bindex, bend, new_bindex, brid;
  7144. + struct au_hfile *p, tmp, *q;
  7145. + struct au_finfo *finfo;
  7146. + struct super_block *sb;
  7147. +
  7148. + FiMustWriteLock(file);
  7149. +
  7150. + sb = file->f_dentry->d_sb;
  7151. + finfo = au_fi(file);
  7152. + p = finfo->fi_hfile + finfo->fi_bstart;
  7153. + brid = p->hf_br->br_id;
  7154. + bend = finfo->fi_bend;
  7155. + for (bindex = finfo->fi_bstart; bindex <= bend; bindex++, p++) {
  7156. + if (!p->hf_file)
  7157. + continue;
  7158. +
  7159. + new_bindex = au_br_index(sb, p->hf_br->br_id);
  7160. + if (new_bindex == bindex)
  7161. + continue;
  7162. + if (new_bindex < 0) {
  7163. + au_set_h_fptr(file, bindex, NULL);
  7164. + continue;
  7165. + }
  7166. +
  7167. + /* swap two lower inode, and loop again */
  7168. + q = finfo->fi_hfile + new_bindex;
  7169. + tmp = *q;
  7170. + *q = *p;
  7171. + *p = tmp;
  7172. + if (tmp.hf_file) {
  7173. + bindex--;
  7174. + p--;
  7175. + }
  7176. + }
  7177. +
  7178. + p = finfo->fi_hfile;
  7179. + if (!au_test_mmapped(file) && !d_unhashed(file->f_dentry)) {
  7180. + bend = au_sbend(sb);
  7181. + for (finfo->fi_bstart = 0; finfo->fi_bstart <= bend;
  7182. + finfo->fi_bstart++, p++)
  7183. + if (p->hf_file) {
  7184. + if (p->hf_file->f_dentry
  7185. + && p->hf_file->f_dentry->d_inode)
  7186. + break;
  7187. + else
  7188. + au_hfput(p, file);
  7189. + }
  7190. + } else {
  7191. + bend = au_br_index(sb, brid);
  7192. + for (finfo->fi_bstart = 0; finfo->fi_bstart < bend;
  7193. + finfo->fi_bstart++, p++)
  7194. + if (p->hf_file)
  7195. + au_hfput(p, file);
  7196. + bend = au_sbend(sb);
  7197. + }
  7198. +
  7199. + p = finfo->fi_hfile + bend;
  7200. + for (finfo->fi_bend = bend; finfo->fi_bend >= finfo->fi_bstart;
  7201. + finfo->fi_bend--, p--)
  7202. + if (p->hf_file) {
  7203. + if (p->hf_file->f_dentry
  7204. + && p->hf_file->f_dentry->d_inode)
  7205. + break;
  7206. + else
  7207. + au_hfput(p, file);
  7208. + }
  7209. + AuDebugOn(finfo->fi_bend < finfo->fi_bstart);
  7210. +}
  7211. +
  7212. +/*
  7213. + * after branch manipulating, refresh the file.
  7214. + */
  7215. +static int refresh_file(struct file *file, int (*reopen)(struct file *file))
  7216. +{
  7217. + int err, need_reopen;
  7218. + struct dentry *dentry;
  7219. + aufs_bindex_t bend, bindex;
  7220. +
  7221. + dentry = file->f_dentry;
  7222. + err = au_fi_realloc(au_fi(file), au_sbend(dentry->d_sb) + 1);
  7223. + if (unlikely(err))
  7224. + goto out;
  7225. + au_do_refresh_file(file);
  7226. +
  7227. + err = 0;
  7228. + need_reopen = 1;
  7229. + if (!au_test_mmapped(file))
  7230. + err = au_file_refresh_by_inode(file, &need_reopen);
  7231. + if (!err && need_reopen && !d_unhashed(dentry))
  7232. + err = reopen(file);
  7233. + if (!err) {
  7234. + au_update_figen(file);
  7235. + return 0; /* success */
  7236. + }
  7237. +
  7238. + /* error, close all lower files */
  7239. + bend = au_fbend(file);
  7240. + for (bindex = au_fbstart(file); bindex <= bend; bindex++)
  7241. + au_set_h_fptr(file, bindex, NULL);
  7242. +
  7243. + out:
  7244. + return err;
  7245. +}
  7246. +
  7247. +/* common function to regular file and dir */
  7248. +int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
  7249. + int wlock)
  7250. +{
  7251. + int err;
  7252. + unsigned int sigen, figen;
  7253. + aufs_bindex_t bstart;
  7254. + unsigned char pseudo_link;
  7255. + struct dentry *dentry;
  7256. +
  7257. + err = 0;
  7258. + dentry = file->f_dentry;
  7259. + sigen = au_sigen(dentry->d_sb);
  7260. + fi_write_lock(file);
  7261. + figen = au_figen(file);
  7262. + di_write_lock_child(dentry);
  7263. + bstart = au_dbstart(dentry);
  7264. + pseudo_link = (bstart != au_ibstart(dentry->d_inode));
  7265. + if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) {
  7266. + if (!wlock) {
  7267. + di_downgrade_lock(dentry, AuLock_IR);
  7268. + fi_downgrade_lock(file);
  7269. + }
  7270. + goto out; /* success */
  7271. + }
  7272. +
  7273. + AuDbg("sigen %d, figen %d\n", sigen, figen);
  7274. + if (sigen != au_digen(dentry)
  7275. + || sigen != au_iigen(dentry->d_inode)) {
  7276. + err = au_reval_dpath(dentry, sigen);
  7277. + if (unlikely(err < 0))
  7278. + goto out;
  7279. + AuDebugOn(au_digen(dentry) != sigen
  7280. + || au_iigen(dentry->d_inode) != sigen);
  7281. + }
  7282. +
  7283. + err = refresh_file(file, reopen);
  7284. + if (!err) {
  7285. + if (!wlock) {
  7286. + di_downgrade_lock(dentry, AuLock_IR);
  7287. + fi_downgrade_lock(file);
  7288. + }
  7289. + } else {
  7290. + di_write_unlock(dentry);
  7291. + fi_write_unlock(file);
  7292. + }
  7293. +
  7294. + out:
  7295. + return err;
  7296. +}
  7297. +
  7298. +/* ---------------------------------------------------------------------- */
  7299. +
  7300. +/* cf. aufs_nopage() */
  7301. +/* for madvise(2) */
  7302. +static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
  7303. +{
  7304. + unlock_page(page);
  7305. + return 0;
  7306. +}
  7307. +
  7308. +/* they will never be called. */
  7309. +#ifdef CONFIG_AUFS_DEBUG
  7310. +static int aufs_write_begin(struct file *file, struct address_space *mapping,
  7311. + loff_t pos, unsigned len, unsigned flags,
  7312. + struct page **pagep, void **fsdata)
  7313. +{ AuUnsupport(); return 0; }
  7314. +static int aufs_write_end(struct file *file, struct address_space *mapping,
  7315. + loff_t pos, unsigned len, unsigned copied,
  7316. + struct page *page, void *fsdata)
  7317. +{ AuUnsupport(); return 0; }
  7318. +static int aufs_writepage(struct page *page, struct writeback_control *wbc)
  7319. +{ AuUnsupport(); return 0; }
  7320. +static void aufs_sync_page(struct page *page)
  7321. +{ AuUnsupport(); }
  7322. +
  7323. +static int aufs_set_page_dirty(struct page *page)
  7324. +{ AuUnsupport(); return 0; }
  7325. +static void aufs_invalidatepage(struct page *page, unsigned long offset)
  7326. +{ AuUnsupport(); }
  7327. +static int aufs_releasepage(struct page *page, gfp_t gfp)
  7328. +{ AuUnsupport(); return 0; }
  7329. +static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb,
  7330. + const struct iovec *iov, loff_t offset,
  7331. + unsigned long nr_segs)
  7332. +{ AuUnsupport(); return 0; }
  7333. +#endif /* CONFIG_AUFS_DEBUG */
  7334. +
  7335. +struct address_space_operations aufs_aop = {
  7336. + .readpage = aufs_readpage,
  7337. +#ifdef CONFIG_AUFS_DEBUG
  7338. + .writepage = aufs_writepage,
  7339. + .sync_page = aufs_sync_page,
  7340. + .set_page_dirty = aufs_set_page_dirty,
  7341. + .write_begin = aufs_write_begin,
  7342. + .write_end = aufs_write_end,
  7343. + .invalidatepage = aufs_invalidatepage,
  7344. + .releasepage = aufs_releasepage,
  7345. + .direct_IO = aufs_direct_IO,
  7346. +#endif /* CONFIG_AUFS_DEBUG */
  7347. +};
  7348. diff -Nur linux-2.6.31.5.orig/fs/aufs/file.h linux-2.6.31.5/fs/aufs/file.h
  7349. --- linux-2.6.31.5.orig/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100
  7350. +++ linux-2.6.31.5/fs/aufs/file.h 2009-11-15 22:02:37.000000000 +0100
  7351. @@ -0,0 +1,175 @@
  7352. +/*
  7353. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  7354. + *
  7355. + * This program, aufs is free software; you can redistribute it and/or modify
  7356. + * it under the terms of the GNU General Public License as published by
  7357. + * the Free Software Foundation; either version 2 of the License, or
  7358. + * (at your option) any later version.
  7359. + *
  7360. + * This program is distributed in the hope that it will be useful,
  7361. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7362. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  7363. + * GNU General Public License for more details.
  7364. + *
  7365. + * You should have received a copy of the GNU General Public License
  7366. + * along with this program; if not, write to the Free Software
  7367. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  7368. + */
  7369. +
  7370. +/*
  7371. + * file operations
  7372. + */
  7373. +
  7374. +#ifndef __AUFS_FILE_H__
  7375. +#define __AUFS_FILE_H__
  7376. +
  7377. +#ifdef __KERNEL__
  7378. +
  7379. +#include <linux/fs.h>
  7380. +#include <linux/poll.h>
  7381. +#include <linux/aufs_type.h>
  7382. +#include "rwsem.h"
  7383. +
  7384. +struct au_branch;
  7385. +struct au_hfile {
  7386. + struct file *hf_file;
  7387. + struct au_branch *hf_br;
  7388. +};
  7389. +
  7390. +struct au_vdir;
  7391. +struct au_finfo {
  7392. + atomic_t fi_generation;
  7393. +
  7394. + struct au_rwsem fi_rwsem;
  7395. + struct au_hfile *fi_hfile;
  7396. + aufs_bindex_t fi_bstart, fi_bend;
  7397. +
  7398. + union {
  7399. + /* non-dir only */
  7400. + struct {
  7401. + struct vm_operations_struct *fi_h_vm_ops;
  7402. + struct vm_operations_struct *fi_vm_ops;
  7403. + };
  7404. +
  7405. + /* dir only */
  7406. + struct {
  7407. + struct au_vdir *fi_vdir_cache;
  7408. + int fi_maintain_plink;
  7409. + };
  7410. + };
  7411. +};
  7412. +
  7413. +/* ---------------------------------------------------------------------- */
  7414. +
  7415. +/* file.c */
  7416. +extern struct address_space_operations aufs_aop;
  7417. +void au_store_oflag(struct nameidata *nd, struct inode *inode);
  7418. +unsigned int au_file_roflags(unsigned int flags);
  7419. +struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
  7420. + struct file *file);
  7421. +int au_do_open(struct file *file, int (*open)(struct file *file, int flags));
  7422. +int au_reopen_nondir(struct file *file);
  7423. +struct au_pin;
  7424. +int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
  7425. +int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
  7426. + int wlock);
  7427. +
  7428. +/* poll.c */
  7429. +#ifdef CONFIG_AUFS_POLL
  7430. +unsigned int aufs_poll(struct file *file, poll_table *wait);
  7431. +#endif
  7432. +
  7433. +/* f_op.c */
  7434. +extern const struct file_operations aufs_file_fop;
  7435. +int aufs_flush(struct file *file, fl_owner_t id);
  7436. +
  7437. +/* finfo.c */
  7438. +void au_hfput(struct au_hfile *hf, struct file *file);
  7439. +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
  7440. + struct file *h_file);
  7441. +
  7442. +void au_update_figen(struct file *file);
  7443. +
  7444. +void au_finfo_fin(struct file *file);
  7445. +int au_finfo_init(struct file *file);
  7446. +int au_fi_realloc(struct au_finfo *finfo, int nbr);
  7447. +
  7448. +/* ---------------------------------------------------------------------- */
  7449. +
  7450. +static inline struct au_finfo *au_fi(struct file *file)
  7451. +{
  7452. + return file->private_data;
  7453. +}
  7454. +
  7455. +/* ---------------------------------------------------------------------- */
  7456. +
  7457. +/*
  7458. + * fi_read_lock, fi_write_lock,
  7459. + * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
  7460. + */
  7461. +AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
  7462. +
  7463. +#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
  7464. +#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
  7465. +#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
  7466. +
  7467. +/* ---------------------------------------------------------------------- */
  7468. +
  7469. +/* todo: hard/soft set? */
  7470. +static inline aufs_bindex_t au_fbstart(struct file *file)
  7471. +{
  7472. + FiMustAnyLock(file);
  7473. + return au_fi(file)->fi_bstart;
  7474. +}
  7475. +
  7476. +static inline aufs_bindex_t au_fbend(struct file *file)
  7477. +{
  7478. + FiMustAnyLock(file);
  7479. + return au_fi(file)->fi_bend;
  7480. +}
  7481. +
  7482. +static inline struct au_vdir *au_fvdir_cache(struct file *file)
  7483. +{
  7484. + FiMustAnyLock(file);
  7485. + return au_fi(file)->fi_vdir_cache;
  7486. +}
  7487. +
  7488. +static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex)
  7489. +{
  7490. + FiMustWriteLock(file);
  7491. + au_fi(file)->fi_bstart = bindex;
  7492. +}
  7493. +
  7494. +static inline void au_set_fbend(struct file *file, aufs_bindex_t bindex)
  7495. +{
  7496. + FiMustWriteLock(file);
  7497. + au_fi(file)->fi_bend = bindex;
  7498. +}
  7499. +
  7500. +static inline void au_set_fvdir_cache(struct file *file,
  7501. + struct au_vdir *vdir_cache)
  7502. +{
  7503. + FiMustWriteLock(file);
  7504. + au_fi(file)->fi_vdir_cache = vdir_cache;
  7505. +}
  7506. +
  7507. +static inline struct file *au_h_fptr(struct file *file, aufs_bindex_t bindex)
  7508. +{
  7509. + FiMustAnyLock(file);
  7510. + return au_fi(file)->fi_hfile[0 + bindex].hf_file;
  7511. +}
  7512. +
  7513. +/* todo: memory barrier? */
  7514. +static inline unsigned int au_figen(struct file *f)
  7515. +{
  7516. + return atomic_read(&au_fi(f)->fi_generation);
  7517. +}
  7518. +
  7519. +static inline int au_test_mmapped(struct file *f)
  7520. +{
  7521. + FiMustAnyLock(f);
  7522. + return !!(au_fi(f)->fi_h_vm_ops);
  7523. +}
  7524. +
  7525. +#endif /* __KERNEL__ */
  7526. +#endif /* __AUFS_FILE_H__ */
  7527. diff -Nur linux-2.6.31.5.orig/fs/aufs/finfo.c linux-2.6.31.5/fs/aufs/finfo.c
  7528. --- linux-2.6.31.5.orig/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100
  7529. +++ linux-2.6.31.5/fs/aufs/finfo.c 2009-11-15 22:02:37.000000000 +0100
  7530. @@ -0,0 +1,133 @@
  7531. +/*
  7532. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  7533. + *
  7534. + * This program, aufs is free software; you can redistribute it and/or modify
  7535. + * it under the terms of the GNU General Public License as published by
  7536. + * the Free Software Foundation; either version 2 of the License, or
  7537. + * (at your option) any later version.
  7538. + *
  7539. + * This program is distributed in the hope that it will be useful,
  7540. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7541. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  7542. + * GNU General Public License for more details.
  7543. + *
  7544. + * You should have received a copy of the GNU General Public License
  7545. + * along with this program; if not, write to the Free Software
  7546. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  7547. + */
  7548. +
  7549. +/*
  7550. + * file private data
  7551. + */
  7552. +
  7553. +#include <linux/file.h>
  7554. +#include "aufs.h"
  7555. +
  7556. +void au_hfput(struct au_hfile *hf, struct file *file)
  7557. +{
  7558. + if (file->f_mode & FMODE_EXEC)
  7559. + allow_write_access(hf->hf_file);
  7560. + fput(hf->hf_file);
  7561. + hf->hf_file = NULL;
  7562. + atomic_dec_return(&hf->hf_br->br_count);
  7563. + hf->hf_br = NULL;
  7564. +}
  7565. +
  7566. +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
  7567. +{
  7568. + struct au_finfo *finfo = au_fi(file);
  7569. + struct au_hfile *hf;
  7570. +
  7571. + hf = finfo->fi_hfile + bindex;
  7572. + if (hf->hf_file)
  7573. + au_hfput(hf, file);
  7574. + if (val) {
  7575. + hf->hf_file = val;
  7576. + hf->hf_br = au_sbr(file->f_dentry->d_sb, bindex);
  7577. + }
  7578. +}
  7579. +
  7580. +void au_update_figen(struct file *file)
  7581. +{
  7582. + atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_dentry));
  7583. + /* smp_mb(); */ /* atomic_set */
  7584. +}
  7585. +
  7586. +/* ---------------------------------------------------------------------- */
  7587. +
  7588. +void au_finfo_fin(struct file *file)
  7589. +{
  7590. + struct au_finfo *finfo;
  7591. + aufs_bindex_t bindex, bend;
  7592. +
  7593. + fi_write_lock(file);
  7594. + bend = au_fbend(file);
  7595. + bindex = au_fbstart(file);
  7596. + if (bindex >= 0)
  7597. + /*
  7598. + * calls fput() instead of filp_close(),
  7599. + * since no dnotify or lock for the lower file.
  7600. + */
  7601. + for (; bindex <= bend; bindex++)
  7602. + au_set_h_fptr(file, bindex, NULL);
  7603. +
  7604. + finfo = au_fi(file);
  7605. + au_dbg_verify_hf(finfo);
  7606. + kfree(finfo->fi_hfile);
  7607. + fi_write_unlock(file);
  7608. + AuRwDestroy(&finfo->fi_rwsem);
  7609. + au_cache_free_finfo(finfo);
  7610. +}
  7611. +
  7612. +int au_finfo_init(struct file *file)
  7613. +{
  7614. + struct au_finfo *finfo;
  7615. + struct dentry *dentry;
  7616. + unsigned long ul;
  7617. +
  7618. + dentry = file->f_dentry;
  7619. + finfo = au_cache_alloc_finfo();
  7620. + if (unlikely(!finfo))
  7621. + goto out;
  7622. +
  7623. + finfo->fi_hfile = kcalloc(au_sbend(dentry->d_sb) + 1,
  7624. + sizeof(*finfo->fi_hfile), GFP_NOFS);
  7625. + if (unlikely(!finfo->fi_hfile))
  7626. + goto out_finfo;
  7627. +
  7628. + au_rw_init_wlock(&finfo->fi_rwsem);
  7629. + finfo->fi_bstart = -1;
  7630. + finfo->fi_bend = -1;
  7631. + atomic_set(&finfo->fi_generation, au_digen(dentry));
  7632. + /* smp_mb(); */ /* atomic_set */
  7633. +
  7634. + /* cf. au_store_oflag() */
  7635. + /* suppress a warning in lp64 */
  7636. + ul = (unsigned long)file->private_data;
  7637. + file->f_mode |= (vfsub_uint_to_fmode(ul) & FMODE_EXEC);
  7638. + file->private_data = finfo;
  7639. + return 0; /* success */
  7640. +
  7641. + out_finfo:
  7642. + au_cache_free_finfo(finfo);
  7643. + out:
  7644. + return -ENOMEM;
  7645. +}
  7646. +
  7647. +int au_fi_realloc(struct au_finfo *finfo, int nbr)
  7648. +{
  7649. + int err, sz;
  7650. + struct au_hfile *hfp;
  7651. +
  7652. + err = -ENOMEM;
  7653. + sz = sizeof(*hfp) * (finfo->fi_bend + 1);
  7654. + if (!sz)
  7655. + sz = sizeof(*hfp);
  7656. + hfp = au_kzrealloc(finfo->fi_hfile, sz, sizeof(*hfp) * nbr, GFP_NOFS);
  7657. + if (hfp) {
  7658. + finfo->fi_hfile = hfp;
  7659. + err = 0;
  7660. + }
  7661. +
  7662. + return err;
  7663. +}
  7664. diff -Nur linux-2.6.31.5.orig/fs/aufs/f_op.c linux-2.6.31.5/fs/aufs/f_op.c
  7665. --- linux-2.6.31.5.orig/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100
  7666. +++ linux-2.6.31.5/fs/aufs/f_op.c 2009-11-15 22:02:37.000000000 +0100
  7667. @@ -0,0 +1,802 @@
  7668. +/*
  7669. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  7670. + *
  7671. + * This program, aufs is free software; you can redistribute it and/or modify
  7672. + * it under the terms of the GNU General Public License as published by
  7673. + * the Free Software Foundation; either version 2 of the License, or
  7674. + * (at your option) any later version.
  7675. + *
  7676. + * This program is distributed in the hope that it will be useful,
  7677. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7678. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  7679. + * GNU General Public License for more details.
  7680. + *
  7681. + * You should have received a copy of the GNU General Public License
  7682. + * along with this program; if not, write to the Free Software
  7683. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  7684. + */
  7685. +
  7686. +/*
  7687. + * file and vm operations
  7688. + */
  7689. +
  7690. +#include <linux/file.h>
  7691. +#include <linux/fs_stack.h>
  7692. +#include <linux/mm.h>
  7693. +#include <linux/security.h>
  7694. +#include "aufs.h"
  7695. +
  7696. +/* common function to regular file and dir */
  7697. +int aufs_flush(struct file *file, fl_owner_t id)
  7698. +{
  7699. + int err;
  7700. + aufs_bindex_t bindex, bend;
  7701. + struct dentry *dentry;
  7702. + struct file *h_file;
  7703. +
  7704. + dentry = file->f_dentry;
  7705. + si_noflush_read_lock(dentry->d_sb);
  7706. + fi_read_lock(file);
  7707. + di_read_lock_child(dentry, AuLock_IW);
  7708. +
  7709. + err = 0;
  7710. + bend = au_fbend(file);
  7711. + for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
  7712. + h_file = au_h_fptr(file, bindex);
  7713. + if (!h_file || !h_file->f_op || !h_file->f_op->flush)
  7714. + continue;
  7715. +
  7716. + err = h_file->f_op->flush(h_file, id);
  7717. + if (!err)
  7718. + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
  7719. + /*ignore*/
  7720. + }
  7721. + au_cpup_attr_timesizes(dentry->d_inode);
  7722. +
  7723. + di_read_unlock(dentry, AuLock_IW);
  7724. + fi_read_unlock(file);
  7725. + si_read_unlock(dentry->d_sb);
  7726. + return err;
  7727. +}
  7728. +
  7729. +/* ---------------------------------------------------------------------- */
  7730. +
  7731. +static int do_open_nondir(struct file *file, int flags)
  7732. +{
  7733. + int err;
  7734. + aufs_bindex_t bindex;
  7735. + struct file *h_file;
  7736. + struct dentry *dentry;
  7737. + struct au_finfo *finfo;
  7738. +
  7739. + FiMustWriteLock(file);
  7740. +
  7741. + err = 0;
  7742. + dentry = file->f_dentry;
  7743. + finfo = au_fi(file);
  7744. + finfo->fi_h_vm_ops = NULL;
  7745. + finfo->fi_vm_ops = NULL;
  7746. + bindex = au_dbstart(dentry);
  7747. + /* O_TRUNC is processed already */
  7748. + BUG_ON(au_test_ro(dentry->d_sb, bindex, dentry->d_inode)
  7749. + && (flags & O_TRUNC));
  7750. +
  7751. + h_file = au_h_open(dentry, bindex, flags, file);
  7752. + if (IS_ERR(h_file))
  7753. + err = PTR_ERR(h_file);
  7754. + else {
  7755. + au_set_fbstart(file, bindex);
  7756. + au_set_fbend(file, bindex);
  7757. + au_set_h_fptr(file, bindex, h_file);
  7758. + au_update_figen(file);
  7759. + /* todo: necessary? */
  7760. + /* file->f_ra = h_file->f_ra; */
  7761. + }
  7762. + return err;
  7763. +}
  7764. +
  7765. +static int aufs_open_nondir(struct inode *inode __maybe_unused,
  7766. + struct file *file)
  7767. +{
  7768. + return au_do_open(file, do_open_nondir);
  7769. +}
  7770. +
  7771. +static int aufs_release_nondir(struct inode *inode __maybe_unused,
  7772. + struct file *file)
  7773. +{
  7774. + struct super_block *sb = file->f_dentry->d_sb;
  7775. +
  7776. + si_noflush_read_lock(sb);
  7777. + kfree(au_fi(file)->fi_vm_ops);
  7778. + au_finfo_fin(file);
  7779. + si_read_unlock(sb);
  7780. + return 0;
  7781. +}
  7782. +
  7783. +/* ---------------------------------------------------------------------- */
  7784. +
  7785. +static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
  7786. + loff_t *ppos)
  7787. +{
  7788. + ssize_t err;
  7789. + struct dentry *dentry;
  7790. + struct file *h_file;
  7791. + struct super_block *sb;
  7792. +
  7793. + dentry = file->f_dentry;
  7794. + sb = dentry->d_sb;
  7795. + si_read_lock(sb, AuLock_FLUSH);
  7796. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
  7797. + if (unlikely(err))
  7798. + goto out;
  7799. +
  7800. + h_file = au_h_fptr(file, au_fbstart(file));
  7801. + err = vfsub_read_u(h_file, buf, count, ppos);
  7802. + /* todo: necessary? */
  7803. + /* file->f_ra = h_file->f_ra; */
  7804. + fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
  7805. +
  7806. + di_read_unlock(dentry, AuLock_IR);
  7807. + fi_read_unlock(file);
  7808. + out:
  7809. + si_read_unlock(sb);
  7810. + return err;
  7811. +}
  7812. +
  7813. +static ssize_t aufs_write(struct file *file, const char __user *ubuf,
  7814. + size_t count, loff_t *ppos)
  7815. +{
  7816. + ssize_t err;
  7817. + aufs_bindex_t bstart;
  7818. + struct au_pin pin;
  7819. + struct dentry *dentry;
  7820. + struct inode *inode;
  7821. + struct super_block *sb;
  7822. + struct file *h_file;
  7823. + char __user *buf = (char __user *)ubuf;
  7824. +
  7825. + dentry = file->f_dentry;
  7826. + sb = dentry->d_sb;
  7827. + inode = dentry->d_inode;
  7828. + mutex_lock(&inode->i_mutex);
  7829. + si_read_lock(sb, AuLock_FLUSH);
  7830. +
  7831. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  7832. + if (unlikely(err))
  7833. + goto out;
  7834. +
  7835. + err = au_ready_to_write(file, -1, &pin);
  7836. + di_downgrade_lock(dentry, AuLock_IR);
  7837. + if (unlikely(err))
  7838. + goto out_unlock;
  7839. +
  7840. + bstart = au_fbstart(file);
  7841. + h_file = au_h_fptr(file, bstart);
  7842. + au_unpin(&pin);
  7843. + err = vfsub_write_u(h_file, buf, count, ppos);
  7844. + au_cpup_attr_timesizes(inode);
  7845. + inode->i_mode = h_file->f_dentry->d_inode->i_mode;
  7846. +
  7847. + out_unlock:
  7848. + di_read_unlock(dentry, AuLock_IR);
  7849. + fi_write_unlock(file);
  7850. + out:
  7851. + si_read_unlock(sb);
  7852. + mutex_unlock(&inode->i_mutex);
  7853. + return err;
  7854. +}
  7855. +
  7856. +static ssize_t aufs_aio_read(struct kiocb *kio, const struct iovec *iov,
  7857. + unsigned long nv, loff_t pos)
  7858. +{
  7859. + ssize_t err;
  7860. + struct file *file, *h_file;
  7861. + struct dentry *dentry;
  7862. + struct super_block *sb;
  7863. +
  7864. + file = kio->ki_filp;
  7865. + dentry = file->f_dentry;
  7866. + sb = dentry->d_sb;
  7867. + si_read_lock(sb, AuLock_FLUSH);
  7868. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
  7869. + if (unlikely(err))
  7870. + goto out;
  7871. +
  7872. + err = -ENOSYS;
  7873. + h_file = au_h_fptr(file, au_fbstart(file));
  7874. + if (h_file->f_op && h_file->f_op->aio_read) {
  7875. + err = security_file_permission(h_file, MAY_READ);
  7876. + if (unlikely(err))
  7877. + goto out_unlock;
  7878. + if (!is_sync_kiocb(kio)) {
  7879. + get_file(h_file);
  7880. + fput(file);
  7881. + }
  7882. + kio->ki_filp = h_file;
  7883. + err = h_file->f_op->aio_read(kio, iov, nv, pos);
  7884. + /* todo: necessary? */
  7885. + /* file->f_ra = h_file->f_ra; */
  7886. + fsstack_copy_attr_atime(dentry->d_inode,
  7887. + h_file->f_dentry->d_inode);
  7888. + } else
  7889. + /* currently there is no such fs */
  7890. + WARN_ON_ONCE(h_file->f_op && h_file->f_op->read);
  7891. +
  7892. + out_unlock:
  7893. + di_read_unlock(dentry, AuLock_IR);
  7894. + fi_read_unlock(file);
  7895. + out:
  7896. + si_read_unlock(sb);
  7897. + return err;
  7898. +}
  7899. +
  7900. +static ssize_t aufs_aio_write(struct kiocb *kio, const struct iovec *iov,
  7901. + unsigned long nv, loff_t pos)
  7902. +{
  7903. + ssize_t err;
  7904. + aufs_bindex_t bstart;
  7905. + struct au_pin pin;
  7906. + struct dentry *dentry;
  7907. + struct inode *inode;
  7908. + struct super_block *sb;
  7909. + struct file *file, *h_file;
  7910. +
  7911. + file = kio->ki_filp;
  7912. + dentry = file->f_dentry;
  7913. + sb = dentry->d_sb;
  7914. + inode = dentry->d_inode;
  7915. + mutex_lock(&inode->i_mutex);
  7916. + si_read_lock(sb, AuLock_FLUSH);
  7917. +
  7918. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  7919. + if (unlikely(err))
  7920. + goto out;
  7921. +
  7922. + err = au_ready_to_write(file, -1, &pin);
  7923. + di_downgrade_lock(dentry, AuLock_IR);
  7924. + if (unlikely(err))
  7925. + goto out_unlock;
  7926. +
  7927. + err = -ENOSYS;
  7928. + bstart = au_fbstart(file);
  7929. + h_file = au_h_fptr(file, bstart);
  7930. + au_unpin(&pin);
  7931. + if (h_file->f_op && h_file->f_op->aio_write) {
  7932. + err = security_file_permission(h_file, MAY_WRITE);
  7933. + if (unlikely(err))
  7934. + goto out_unlock;
  7935. + if (!is_sync_kiocb(kio)) {
  7936. + get_file(h_file);
  7937. + fput(file);
  7938. + }
  7939. + kio->ki_filp = h_file;
  7940. + err = h_file->f_op->aio_write(kio, iov, nv, pos);
  7941. + au_cpup_attr_timesizes(inode);
  7942. + inode->i_mode = h_file->f_dentry->d_inode->i_mode;
  7943. + } else
  7944. + /* currently there is no such fs */
  7945. + WARN_ON_ONCE(h_file->f_op && h_file->f_op->write);
  7946. +
  7947. + out_unlock:
  7948. + di_read_unlock(dentry, AuLock_IR);
  7949. + fi_write_unlock(file);
  7950. + out:
  7951. + si_read_unlock(sb);
  7952. + mutex_unlock(&inode->i_mutex);
  7953. + return err;
  7954. +}
  7955. +
  7956. +static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
  7957. + struct pipe_inode_info *pipe, size_t len,
  7958. + unsigned int flags)
  7959. +{
  7960. + ssize_t err;
  7961. + struct file *h_file;
  7962. + struct dentry *dentry;
  7963. + struct super_block *sb;
  7964. +
  7965. + dentry = file->f_dentry;
  7966. + sb = dentry->d_sb;
  7967. + si_read_lock(sb, AuLock_FLUSH);
  7968. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
  7969. + if (unlikely(err))
  7970. + goto out;
  7971. +
  7972. + err = -EINVAL;
  7973. + h_file = au_h_fptr(file, au_fbstart(file));
  7974. + if (au_test_loopback_kthread()) {
  7975. + file->f_mapping = h_file->f_mapping;
  7976. + smp_mb(); /* unnecessary? */
  7977. + }
  7978. + err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
  7979. + /* todo: necessasry? */
  7980. + /* file->f_ra = h_file->f_ra; */
  7981. + fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
  7982. +
  7983. + di_read_unlock(dentry, AuLock_IR);
  7984. + fi_read_unlock(file);
  7985. +
  7986. + out:
  7987. + si_read_unlock(sb);
  7988. + return err;
  7989. +}
  7990. +
  7991. +static ssize_t
  7992. +aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
  7993. + size_t len, unsigned int flags)
  7994. +{
  7995. + ssize_t err;
  7996. + struct au_pin pin;
  7997. + struct dentry *dentry;
  7998. + struct inode *inode;
  7999. + struct super_block *sb;
  8000. + struct file *h_file;
  8001. +
  8002. + dentry = file->f_dentry;
  8003. + inode = dentry->d_inode;
  8004. + mutex_lock(&inode->i_mutex);
  8005. + sb = dentry->d_sb;
  8006. + si_read_lock(sb, AuLock_FLUSH);
  8007. +
  8008. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  8009. + if (unlikely(err))
  8010. + goto out;
  8011. +
  8012. + err = au_ready_to_write(file, -1, &pin);
  8013. + di_downgrade_lock(dentry, AuLock_IR);
  8014. + if (unlikely(err))
  8015. + goto out_unlock;
  8016. +
  8017. + h_file = au_h_fptr(file, au_fbstart(file));
  8018. + au_unpin(&pin);
  8019. + err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
  8020. + au_cpup_attr_timesizes(inode);
  8021. + inode->i_mode = h_file->f_dentry->d_inode->i_mode;
  8022. +
  8023. + out_unlock:
  8024. + di_read_unlock(dentry, AuLock_IR);
  8025. + fi_write_unlock(file);
  8026. + out:
  8027. + si_read_unlock(sb);
  8028. + mutex_unlock(&inode->i_mutex);
  8029. + return err;
  8030. +}
  8031. +
  8032. +/* ---------------------------------------------------------------------- */
  8033. +
  8034. +static struct file *au_safe_file(struct vm_area_struct *vma)
  8035. +{
  8036. + struct file *file;
  8037. +
  8038. + file = vma->vm_file;
  8039. + if (file->private_data && au_test_aufs(file->f_dentry->d_sb))
  8040. + return file;
  8041. + return NULL;
  8042. +}
  8043. +
  8044. +static void au_reset_file(struct vm_area_struct *vma, struct file *file)
  8045. +{
  8046. + vma->vm_file = file;
  8047. + /* smp_mb(); */ /* flush vm_file */
  8048. +}
  8049. +
  8050. +static int aufs_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
  8051. +{
  8052. + int err;
  8053. + static DECLARE_WAIT_QUEUE_HEAD(wq);
  8054. + struct file *file, *h_file;
  8055. + struct au_finfo *finfo;
  8056. +
  8057. + /* todo: non-robr mode, user vm_file as it is? */
  8058. + wait_event(wq, (file = au_safe_file(vma)));
  8059. +
  8060. + /* do not revalidate, no si lock */
  8061. + finfo = au_fi(file);
  8062. + h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file;
  8063. + AuDebugOn(!h_file || !finfo->fi_h_vm_ops);
  8064. +
  8065. + fi_write_lock(file);
  8066. + vma->vm_file = h_file;
  8067. + err = finfo->fi_h_vm_ops->fault(vma, vmf);
  8068. + /* todo: necessary? */
  8069. + /* file->f_ra = h_file->f_ra; */
  8070. + au_reset_file(vma, file);
  8071. + fi_write_unlock(file);
  8072. +#if 0 /* def CONFIG_SMP */
  8073. + /* wake_up_nr(&wq, online_cpu - 1); */
  8074. + wake_up_all(&wq);
  8075. +#else
  8076. + wake_up(&wq);
  8077. +#endif
  8078. +
  8079. + return err;
  8080. +}
  8081. +
  8082. +static int aufs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
  8083. +{
  8084. + int err;
  8085. + static DECLARE_WAIT_QUEUE_HEAD(wq);
  8086. + struct file *file, *h_file;
  8087. + struct au_finfo *finfo;
  8088. +
  8089. + wait_event(wq, (file = au_safe_file(vma)));
  8090. +
  8091. + finfo = au_fi(file);
  8092. + h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file;
  8093. + AuDebugOn(!h_file || !finfo->fi_h_vm_ops);
  8094. +
  8095. + fi_write_lock(file);
  8096. + vma->vm_file = h_file;
  8097. + err = finfo->fi_h_vm_ops->page_mkwrite(vma, vmf);
  8098. + au_reset_file(vma, file);
  8099. + fi_write_unlock(file);
  8100. + wake_up(&wq);
  8101. +
  8102. + return err;
  8103. +}
  8104. +
  8105. +static void aufs_vm_close(struct vm_area_struct *vma)
  8106. +{
  8107. + static DECLARE_WAIT_QUEUE_HEAD(wq);
  8108. + struct file *file, *h_file;
  8109. + struct au_finfo *finfo;
  8110. +
  8111. + wait_event(wq, (file = au_safe_file(vma)));
  8112. +
  8113. + finfo = au_fi(file);
  8114. + h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file;
  8115. + AuDebugOn(!h_file || !finfo->fi_h_vm_ops);
  8116. +
  8117. + fi_write_lock(file);
  8118. + vma->vm_file = h_file;
  8119. + finfo->fi_h_vm_ops->close(vma);
  8120. + au_reset_file(vma, file);
  8121. + fi_write_unlock(file);
  8122. + wake_up(&wq);
  8123. +}
  8124. +
  8125. +static struct vm_operations_struct aufs_vm_ops = {
  8126. + /* .close and .page_mkwrite are not set by default */
  8127. + .fault = aufs_fault,
  8128. +};
  8129. +
  8130. +/* ---------------------------------------------------------------------- */
  8131. +
  8132. +static struct vm_operations_struct *au_vm_ops(struct file *h_file,
  8133. + struct vm_area_struct *vma)
  8134. +{
  8135. + struct vm_operations_struct *vm_ops;
  8136. + int err;
  8137. +
  8138. + vm_ops = ERR_PTR(-ENODEV);
  8139. + if (!h_file->f_op || !h_file->f_op->mmap)
  8140. + goto out;
  8141. +
  8142. + err = h_file->f_op->mmap(h_file, vma);
  8143. + vm_ops = ERR_PTR(err);
  8144. + if (unlikely(err))
  8145. + goto out;
  8146. +
  8147. + vm_ops = vma->vm_ops;
  8148. + err = do_munmap(current->mm, vma->vm_start,
  8149. + vma->vm_end - vma->vm_start);
  8150. + if (unlikely(err)) {
  8151. + AuIOErr("failed internal unmapping %.*s, %d\n",
  8152. + AuDLNPair(h_file->f_dentry), err);
  8153. + vm_ops = ERR_PTR(-EIO);
  8154. + }
  8155. +
  8156. + out:
  8157. + return vm_ops;
  8158. +}
  8159. +
  8160. +static int au_custom_vm_ops(struct au_finfo *finfo, struct vm_area_struct *vma)
  8161. +{
  8162. + int err;
  8163. + struct vm_operations_struct *h_ops;
  8164. +
  8165. + AuRwMustAnyLock(&finfo->fi_rwsem);
  8166. +
  8167. + err = 0;
  8168. + h_ops = finfo->fi_h_vm_ops;
  8169. + AuDebugOn(!h_ops);
  8170. + if ((!h_ops->page_mkwrite && !h_ops->close)
  8171. + || finfo->fi_vm_ops)
  8172. + goto out;
  8173. +
  8174. + err = -ENOMEM;
  8175. + finfo->fi_vm_ops = kmemdup(&aufs_vm_ops, sizeof(aufs_vm_ops), GFP_NOFS);
  8176. + if (unlikely(!finfo->fi_vm_ops))
  8177. + goto out;
  8178. +
  8179. + err = 0;
  8180. + if (h_ops->page_mkwrite)
  8181. + finfo->fi_vm_ops->page_mkwrite = aufs_page_mkwrite;
  8182. + if (h_ops->close)
  8183. + finfo->fi_vm_ops->close = aufs_vm_close;
  8184. +
  8185. + vma->vm_ops = finfo->fi_vm_ops;
  8186. +
  8187. + out:
  8188. + return err;
  8189. +}
  8190. +
  8191. +static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
  8192. +{
  8193. + int err;
  8194. + unsigned char wlock, mmapped;
  8195. + struct dentry *dentry;
  8196. + struct super_block *sb;
  8197. + struct file *h_file;
  8198. + struct vm_operations_struct *vm_ops;
  8199. +
  8200. + dentry = file->f_dentry;
  8201. + wlock = !!(file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
  8202. + sb = dentry->d_sb;
  8203. + si_read_lock(sb, AuLock_FLUSH);
  8204. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  8205. + if (unlikely(err))
  8206. + goto out;
  8207. +
  8208. + mmapped = !!au_test_mmapped(file);
  8209. + if (wlock) {
  8210. + struct au_pin pin;
  8211. +
  8212. + err = au_ready_to_write(file, -1, &pin);
  8213. + di_downgrade_lock(dentry, AuLock_IR);
  8214. + if (unlikely(err))
  8215. + goto out_unlock;
  8216. + au_unpin(&pin);
  8217. + } else
  8218. + di_downgrade_lock(dentry, AuLock_IR);
  8219. +
  8220. + h_file = au_h_fptr(file, au_fbstart(file));
  8221. + if (!mmapped && au_test_fs_bad_mapping(h_file->f_dentry->d_sb)) {
  8222. + /*
  8223. + * by this assignment, f_mapping will differs from aufs inode
  8224. + * i_mapping.
  8225. + * if someone else mixes the use of f_dentry->d_inode and
  8226. + * f_mapping->host, then a problem may arise.
  8227. + */
  8228. + file->f_mapping = h_file->f_mapping;
  8229. + }
  8230. +
  8231. + vm_ops = NULL;
  8232. + if (!mmapped) {
  8233. + vm_ops = au_vm_ops(h_file, vma);
  8234. + err = PTR_ERR(vm_ops);
  8235. + if (IS_ERR(vm_ops))
  8236. + goto out_unlock;
  8237. + }
  8238. +
  8239. + /*
  8240. + * unnecessary to handle MAP_DENYWRITE and deny_write_access()?
  8241. + * currently MAP_DENYWRITE from userspace is ignored, but elf loader
  8242. + * sets it. when FMODE_EXEC is set (by open_exec() or sys_uselib()),
  8243. + * both of the aufs file and the lower file is deny_write_access()-ed.
  8244. + * finally I hope we can skip handlling MAP_DENYWRITE here.
  8245. + */
  8246. + err = generic_file_mmap(file, vma);
  8247. + if (unlikely(err))
  8248. + goto out_unlock;
  8249. +
  8250. + vma->vm_ops = &aufs_vm_ops;
  8251. + /* test again */
  8252. + if (!au_test_mmapped(file))
  8253. + au_fi(file)->fi_h_vm_ops = vm_ops;
  8254. +
  8255. + err = au_custom_vm_ops(au_fi(file), vma);
  8256. + if (unlikely(err))
  8257. + goto out_unlock;
  8258. +
  8259. + vfsub_file_accessed(h_file);
  8260. + fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
  8261. +
  8262. + out_unlock:
  8263. + di_read_unlock(dentry, AuLock_IR);
  8264. + fi_write_unlock(file);
  8265. + out:
  8266. + si_read_unlock(sb);
  8267. + return err;
  8268. +}
  8269. +
  8270. +/* ---------------------------------------------------------------------- */
  8271. +
  8272. +static int aufs_fsync_nondir(struct file *file, struct dentry *dentry,
  8273. + int datasync)
  8274. +{
  8275. + int err;
  8276. + struct au_pin pin;
  8277. + struct inode *inode;
  8278. + struct file *h_file;
  8279. + struct super_block *sb;
  8280. +
  8281. + inode = dentry->d_inode;
  8282. + IMustLock(file->f_mapping->host);
  8283. + if (inode != file->f_mapping->host) {
  8284. + mutex_unlock(&file->f_mapping->host->i_mutex);
  8285. + mutex_lock(&inode->i_mutex);
  8286. + }
  8287. + IMustLock(inode);
  8288. +
  8289. + sb = dentry->d_sb;
  8290. + si_read_lock(sb, AuLock_FLUSH);
  8291. +
  8292. + err = 0; /* -EBADF; */ /* posix? */
  8293. + if (unlikely(!(file->f_mode & FMODE_WRITE)))
  8294. + goto out;
  8295. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  8296. + if (unlikely(err))
  8297. + goto out;
  8298. +
  8299. + err = au_ready_to_write(file, -1, &pin);
  8300. + di_downgrade_lock(dentry, AuLock_IR);
  8301. + if (unlikely(err))
  8302. + goto out_unlock;
  8303. + au_unpin(&pin);
  8304. +
  8305. + err = -EINVAL;
  8306. + h_file = au_h_fptr(file, au_fbstart(file));
  8307. + if (h_file->f_op && h_file->f_op->fsync) {
  8308. + struct dentry *h_d;
  8309. + struct mutex *h_mtx;
  8310. +
  8311. + /*
  8312. + * no filemap_fdatawrite() since aufs file has no its own
  8313. + * mapping, but dir.
  8314. + */
  8315. + h_d = h_file->f_dentry;
  8316. + h_mtx = &h_d->d_inode->i_mutex;
  8317. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  8318. + err = h_file->f_op->fsync(h_file, h_d, datasync);
  8319. + if (!err)
  8320. + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
  8321. + /*ignore*/
  8322. + au_cpup_attr_timesizes(inode);
  8323. + mutex_unlock(h_mtx);
  8324. + }
  8325. +
  8326. + out_unlock:
  8327. + di_read_unlock(dentry, AuLock_IR);
  8328. + fi_write_unlock(file);
  8329. + out:
  8330. + si_read_unlock(sb);
  8331. + if (inode != file->f_mapping->host) {
  8332. + mutex_unlock(&inode->i_mutex);
  8333. + mutex_lock(&file->f_mapping->host->i_mutex);
  8334. + }
  8335. + return err;
  8336. +}
  8337. +
  8338. +/* no one supports this operation, currently */
  8339. +#if 0
  8340. +static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync)
  8341. +{
  8342. + int err;
  8343. + struct au_pin pin;
  8344. + struct dentry *dentry;
  8345. + struct inode *inode;
  8346. + struct file *file, *h_file;
  8347. + struct super_block *sb;
  8348. +
  8349. + file = kio->ki_filp;
  8350. + dentry = file->f_dentry;
  8351. + inode = dentry->d_inode;
  8352. + mutex_lock(&inode->i_mutex);
  8353. +
  8354. + sb = dentry->d_sb;
  8355. + si_read_lock(sb, AuLock_FLUSH);
  8356. +
  8357. + err = 0; /* -EBADF; */ /* posix? */
  8358. + if (unlikely(!(file->f_mode & FMODE_WRITE)))
  8359. + goto out;
  8360. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  8361. + if (unlikely(err))
  8362. + goto out;
  8363. +
  8364. + err = au_ready_to_write(file, -1, &pin);
  8365. + di_downgrade_lock(dentry, AuLock_IR);
  8366. + if (unlikely(err))
  8367. + goto out_unlock;
  8368. + au_unpin(&pin);
  8369. +
  8370. + err = -ENOSYS;
  8371. + h_file = au_h_fptr(file, au_fbstart(file));
  8372. + if (h_file->f_op && h_file->f_op->aio_fsync) {
  8373. + struct dentry *h_d;
  8374. + struct mutex *h_mtx;
  8375. +
  8376. + h_d = h_file->f_dentry;
  8377. + h_mtx = &h_d->d_inode->i_mutex;
  8378. + if (!is_sync_kiocb(kio)) {
  8379. + get_file(h_file);
  8380. + fput(file);
  8381. + }
  8382. + kio->ki_filp = h_file;
  8383. + err = h_file->f_op->aio_fsync(kio, datasync);
  8384. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  8385. + if (!err)
  8386. + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
  8387. + /*ignore*/
  8388. + au_cpup_attr_timesizes(inode);
  8389. + mutex_unlock(h_mtx);
  8390. + }
  8391. +
  8392. + out_unlock:
  8393. + di_read_unlock(dentry, AuLock_IR);
  8394. + fi_write_unlock(file);
  8395. + out:
  8396. + si_read_unlock(sb);
  8397. + mutex_unlock(&inode->i_mutex);
  8398. + return err;
  8399. +}
  8400. +#endif
  8401. +
  8402. +static int aufs_fasync(int fd, struct file *file, int flag)
  8403. +{
  8404. + int err;
  8405. + struct file *h_file;
  8406. + struct dentry *dentry;
  8407. + struct super_block *sb;
  8408. +
  8409. + dentry = file->f_dentry;
  8410. + sb = dentry->d_sb;
  8411. + si_read_lock(sb, AuLock_FLUSH);
  8412. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
  8413. + if (unlikely(err))
  8414. + goto out;
  8415. +
  8416. + h_file = au_h_fptr(file, au_fbstart(file));
  8417. + if (h_file->f_op && h_file->f_op->fasync)
  8418. + err = h_file->f_op->fasync(fd, h_file, flag);
  8419. +
  8420. + di_read_unlock(dentry, AuLock_IR);
  8421. + fi_read_unlock(file);
  8422. +
  8423. + out:
  8424. + si_read_unlock(sb);
  8425. + return err;
  8426. +}
  8427. +
  8428. +/* ---------------------------------------------------------------------- */
  8429. +
  8430. +/* no one supports this operation, currently */
  8431. +#if 0
  8432. +static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
  8433. + size_t len, loff_t *pos , int more)
  8434. +{
  8435. +}
  8436. +#endif
  8437. +
  8438. +/* ---------------------------------------------------------------------- */
  8439. +
  8440. +const struct file_operations aufs_file_fop = {
  8441. + /*
  8442. + * while generic_file_llseek/_unlocked() don't use BKL,
  8443. + * don't use it since it operates file->f_mapping->host.
  8444. + * in aufs, it may be a real file and may confuse users by UDBA.
  8445. + */
  8446. + /* .llseek = generic_file_llseek, */
  8447. +
  8448. + .read = aufs_read,
  8449. + .write = aufs_write,
  8450. + .aio_read = aufs_aio_read,
  8451. + .aio_write = aufs_aio_write,
  8452. +#ifdef CONFIG_AUFS_POLL
  8453. + .poll = aufs_poll,
  8454. +#endif
  8455. + .mmap = aufs_mmap,
  8456. + .open = aufs_open_nondir,
  8457. + .flush = aufs_flush,
  8458. + .release = aufs_release_nondir,
  8459. + .fsync = aufs_fsync_nondir,
  8460. + /* .aio_fsync = aufs_aio_fsync_nondir, */
  8461. + .fasync = aufs_fasync,
  8462. + /* .sendpage = aufs_sendpage, */
  8463. + .splice_write = aufs_splice_write,
  8464. + .splice_read = aufs_splice_read,
  8465. +#if 0
  8466. + .aio_splice_write = aufs_aio_splice_write,
  8467. + .aio_splice_read = aufs_aio_splice_read
  8468. +#endif
  8469. +};
  8470. diff -Nur linux-2.6.31.5.orig/fs/aufs/fstype.h linux-2.6.31.5/fs/aufs/fstype.h
  8471. --- linux-2.6.31.5.orig/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100
  8472. +++ linux-2.6.31.5/fs/aufs/fstype.h 2009-11-15 22:02:37.000000000 +0100
  8473. @@ -0,0 +1,474 @@
  8474. +/*
  8475. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  8476. + *
  8477. + * This program, aufs is free software; you can redistribute it and/or modify
  8478. + * it under the terms of the GNU General Public License as published by
  8479. + * the Free Software Foundation; either version 2 of the License, or
  8480. + * (at your option) any later version.
  8481. + *
  8482. + * This program is distributed in the hope that it will be useful,
  8483. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  8484. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8485. + * GNU General Public License for more details.
  8486. + *
  8487. + * You should have received a copy of the GNU General Public License
  8488. + * along with this program; if not, write to the Free Software
  8489. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  8490. + */
  8491. +
  8492. +/*
  8493. + * judging filesystem type
  8494. + */
  8495. +
  8496. +#ifndef __AUFS_FSTYPE_H__
  8497. +#define __AUFS_FSTYPE_H__
  8498. +
  8499. +#ifdef __KERNEL__
  8500. +
  8501. +#include <linux/cramfs_fs.h>
  8502. +#include <linux/fs.h>
  8503. +#include <linux/magic.h>
  8504. +#include <linux/romfs_fs.h>
  8505. +#include <linux/aufs_type.h>
  8506. +
  8507. +static inline int au_test_aufs(struct super_block *sb)
  8508. +{
  8509. + return sb->s_magic == AUFS_SUPER_MAGIC;
  8510. +}
  8511. +
  8512. +static inline const char *au_sbtype(struct super_block *sb)
  8513. +{
  8514. + return sb->s_type->name;
  8515. +}
  8516. +
  8517. +static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
  8518. +{
  8519. +#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE)
  8520. + return sb->s_magic == ROMFS_MAGIC;
  8521. +#else
  8522. + return 0;
  8523. +#endif
  8524. +}
  8525. +
  8526. +static inline int au_test_romfs(struct super_block *sb __maybe_unused)
  8527. +{
  8528. +#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE)
  8529. + return sb->s_magic == ISOFS_SUPER_MAGIC;
  8530. +#else
  8531. + return 0;
  8532. +#endif
  8533. +}
  8534. +
  8535. +static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
  8536. +{
  8537. +#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE)
  8538. + return sb->s_magic == CRAMFS_MAGIC;
  8539. +#endif
  8540. + return 0;
  8541. +}
  8542. +
  8543. +static inline int au_test_nfs(struct super_block *sb __maybe_unused)
  8544. +{
  8545. +#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE)
  8546. + return sb->s_magic == NFS_SUPER_MAGIC;
  8547. +#else
  8548. + return 0;
  8549. +#endif
  8550. +}
  8551. +
  8552. +static inline int au_test_fuse(struct super_block *sb __maybe_unused)
  8553. +{
  8554. +#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE)
  8555. + return sb->s_magic == FUSE_SUPER_MAGIC;
  8556. +#else
  8557. + return 0;
  8558. +#endif
  8559. +}
  8560. +
  8561. +static inline int au_test_xfs(struct super_block *sb __maybe_unused)
  8562. +{
  8563. +#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE)
  8564. + return sb->s_magic == XFS_SB_MAGIC;
  8565. +#else
  8566. + return 0;
  8567. +#endif
  8568. +}
  8569. +
  8570. +static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
  8571. +{
  8572. +#ifdef CONFIG_TMPFS
  8573. + return sb->s_magic == TMPFS_MAGIC;
  8574. +#else
  8575. + return 0;
  8576. +#endif
  8577. +}
  8578. +
  8579. +static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
  8580. +{
  8581. +#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE)
  8582. + return !strcmp(au_sbtype(sb), "ecryptfs");
  8583. +#else
  8584. + return 0;
  8585. +#endif
  8586. +}
  8587. +
  8588. +static inline int au_test_smbfs(struct super_block *sb __maybe_unused)
  8589. +{
  8590. +#if defined(CONFIG_SMB_FS) || defined(CONFIG_SMB_FS_MODULE)
  8591. + return sb->s_magic == SMB_SUPER_MAGIC;
  8592. +#else
  8593. + return 0;
  8594. +#endif
  8595. +}
  8596. +
  8597. +static inline int au_test_ocfs2(struct super_block *sb __maybe_unused)
  8598. +{
  8599. +#if defined(CONFIG_OCFS2_FS) || defined(CONFIG_OCFS2_FS_MODULE)
  8600. + return sb->s_magic == OCFS2_SUPER_MAGIC;
  8601. +#else
  8602. + return 0;
  8603. +#endif
  8604. +}
  8605. +
  8606. +static inline int au_test_ocfs2_dlmfs(struct super_block *sb __maybe_unused)
  8607. +{
  8608. +#if defined(CONFIG_OCFS2_FS_O2CB) || defined(CONFIG_OCFS2_FS_O2CB_MODULE)
  8609. + return sb->s_magic == DLMFS_MAGIC;
  8610. +#else
  8611. + return 0;
  8612. +#endif
  8613. +}
  8614. +
  8615. +static inline int au_test_coda(struct super_block *sb __maybe_unused)
  8616. +{
  8617. +#if defined(CONFIG_CODA_FS) || defined(CONFIG_CODA_FS_MODULE)
  8618. + return sb->s_magic == CODA_SUPER_MAGIC;
  8619. +#else
  8620. + return 0;
  8621. +#endif
  8622. +}
  8623. +
  8624. +static inline int au_test_v9fs(struct super_block *sb __maybe_unused)
  8625. +{
  8626. +#if defined(CONFIG_9P_FS) || defined(CONFIG_9P_FS_MODULE)
  8627. + return sb->s_magic == V9FS_MAGIC;
  8628. +#else
  8629. + return 0;
  8630. +#endif
  8631. +}
  8632. +
  8633. +static inline int au_test_ext4(struct super_block *sb __maybe_unused)
  8634. +{
  8635. +#if defined(CONFIG_EXT4DEV_FS) || defined(CONFIG_EXT4DEV_FS_MODULE)
  8636. + return sb->s_magic == EXT4_SUPER_MAGIC;
  8637. +#else
  8638. + return 0;
  8639. +#endif
  8640. +}
  8641. +
  8642. +static inline int au_test_sysv(struct super_block *sb __maybe_unused)
  8643. +{
  8644. +#if defined(CONFIG_SYSV_FS) || defined(CONFIG_SYSV_FS_MODULE)
  8645. + return !strcmp(au_sbtype(sb), "sysv");
  8646. +#else
  8647. + return 0;
  8648. +#endif
  8649. +}
  8650. +
  8651. +static inline int au_test_ramfs(struct super_block *sb)
  8652. +{
  8653. + return sb->s_magic == RAMFS_MAGIC;
  8654. +}
  8655. +
  8656. +static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
  8657. +{
  8658. +#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE)
  8659. + return sb->s_magic == UBIFS_SUPER_MAGIC;
  8660. +#else
  8661. + return 0;
  8662. +#endif
  8663. +}
  8664. +
  8665. +static inline int au_test_procfs(struct super_block *sb __maybe_unused)
  8666. +{
  8667. +#ifdef CONFIG_PROC_FS
  8668. + return sb->s_magic == PROC_SUPER_MAGIC;
  8669. +#else
  8670. + return 0;
  8671. +#endif
  8672. +}
  8673. +
  8674. +static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
  8675. +{
  8676. +#ifdef CONFIG_SYSFS
  8677. + return sb->s_magic == SYSFS_MAGIC;
  8678. +#else
  8679. + return 0;
  8680. +#endif
  8681. +}
  8682. +
  8683. +static inline int au_test_configfs(struct super_block *sb __maybe_unused)
  8684. +{
  8685. +#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE)
  8686. + return sb->s_magic == CONFIGFS_MAGIC;
  8687. +#else
  8688. + return 0;
  8689. +#endif
  8690. +}
  8691. +
  8692. +static inline int au_test_minix(struct super_block *sb __maybe_unused)
  8693. +{
  8694. +#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE)
  8695. + return sb->s_magic == MINIX3_SUPER_MAGIC
  8696. + || sb->s_magic == MINIX2_SUPER_MAGIC
  8697. + || sb->s_magic == MINIX2_SUPER_MAGIC2
  8698. + || sb->s_magic == MINIX_SUPER_MAGIC
  8699. + || sb->s_magic == MINIX_SUPER_MAGIC2;
  8700. +#else
  8701. + return 0;
  8702. +#endif
  8703. +}
  8704. +
  8705. +static inline int au_test_cifs(struct super_block *sb __maybe_unused)
  8706. +{
  8707. +#if defined(CONFIG_CIFS_FS) || defined(CONFIGCIFS_FS_MODULE)
  8708. + return sb->s_magic == CIFS_MAGIC_NUMBER;
  8709. +#else
  8710. + return 0;
  8711. +#endif
  8712. +}
  8713. +
  8714. +static inline int au_test_fat(struct super_block *sb __maybe_unused)
  8715. +{
  8716. +#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE)
  8717. + return sb->s_magic == MSDOS_SUPER_MAGIC;
  8718. +#else
  8719. + return 0;
  8720. +#endif
  8721. +}
  8722. +
  8723. +static inline int au_test_msdos(struct super_block *sb)
  8724. +{
  8725. + return au_test_fat(sb);
  8726. +}
  8727. +
  8728. +static inline int au_test_vfat(struct super_block *sb)
  8729. +{
  8730. + return au_test_fat(sb);
  8731. +}
  8732. +
  8733. +static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
  8734. +{
  8735. +#ifdef CONFIG_SECURITYFS
  8736. + return sb->s_magic == SECURITYFS_MAGIC;
  8737. +#else
  8738. + return 0;
  8739. +#endif
  8740. +}
  8741. +
  8742. +static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
  8743. +{
  8744. +#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE)
  8745. + return sb->s_magic == SQUASHFS_MAGIC;
  8746. +#else
  8747. + return 0;
  8748. +#endif
  8749. +}
  8750. +
  8751. +static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
  8752. +{
  8753. +#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE)
  8754. + return sb->s_magic == BTRFS_SUPER_MAGIC;
  8755. +#else
  8756. + return 0;
  8757. +#endif
  8758. +}
  8759. +
  8760. +static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
  8761. +{
  8762. +#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE)
  8763. + return sb->s_magic == XENFS_SUPER_MAGIC;
  8764. +#else
  8765. + return 0;
  8766. +#endif
  8767. +}
  8768. +
  8769. +static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
  8770. +{
  8771. +#ifdef CONFIG_DEBUG_FS
  8772. + return sb->s_magic == DEBUGFS_MAGIC;
  8773. +#else
  8774. + return 0;
  8775. +#endif
  8776. +}
  8777. +
  8778. +/* ---------------------------------------------------------------------- */
  8779. +/*
  8780. + * they can't be an aufs branch.
  8781. + */
  8782. +static inline int au_test_fs_unsuppoted(struct super_block *sb)
  8783. +{
  8784. + return
  8785. +#ifndef CONFIG_AUFS_BR_RAMFS
  8786. + au_test_ramfs(sb) ||
  8787. +#endif
  8788. + au_test_procfs(sb)
  8789. + || au_test_sysfs(sb)
  8790. + || au_test_configfs(sb)
  8791. + || au_test_debugfs(sb)
  8792. + || au_test_securityfs(sb)
  8793. + || au_test_xenfs(sb)
  8794. + /* || !strcmp(au_sbtype(sb), "unionfs") */
  8795. + || au_test_aufs(sb); /* will be supported in next version */
  8796. +}
  8797. +
  8798. +/*
  8799. + * If the filesystem supports NFS-export, then it has to support NULL as
  8800. + * a nameidata parameter for ->create(), ->lookup() and ->d_revalidate().
  8801. + * We can apply this principle when we handle a lower filesystem.
  8802. + */
  8803. +static inline int au_test_fs_null_nd(struct super_block *sb)
  8804. +{
  8805. + return !!sb->s_export_op;
  8806. +}
  8807. +
  8808. +static inline int au_test_fs_remote(struct super_block *sb)
  8809. +{
  8810. + return !au_test_tmpfs(sb)
  8811. +#ifdef CONFIG_AUFS_BR_RAMFS
  8812. + && !au_test_ramfs(sb)
  8813. +#endif
  8814. + && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
  8815. +}
  8816. +
  8817. +/* ---------------------------------------------------------------------- */
  8818. +
  8819. +/*
  8820. + * Note: these functions (below) are created after reading ->getattr() in all
  8821. + * filesystems under linux/fs. it means we have to do so in every update...
  8822. + */
  8823. +
  8824. +/*
  8825. + * some filesystems require getattr to refresh the inode attributes before
  8826. + * referencing.
  8827. + * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
  8828. + * and leave the work for d_revalidate()
  8829. + */
  8830. +static inline int au_test_fs_refresh_iattr(struct super_block *sb)
  8831. +{
  8832. + return au_test_nfs(sb)
  8833. + || au_test_fuse(sb)
  8834. + /* || au_test_smbfs(sb) */ /* untested */
  8835. + /* || au_test_ocfs2(sb) */ /* untested */
  8836. + /* || au_test_btrfs(sb) */ /* untested */
  8837. + /* || au_test_coda(sb) */ /* untested */
  8838. + /* || au_test_v9fs(sb) */ /* untested */
  8839. + ;
  8840. +}
  8841. +
  8842. +/*
  8843. + * filesystems which don't maintain i_size or i_blocks.
  8844. + */
  8845. +static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
  8846. +{
  8847. + return au_test_xfs(sb)
  8848. + /* || au_test_ext4(sb) */ /* untested */
  8849. + /* || au_test_ocfs2(sb) */ /* untested */
  8850. + /* || au_test_ocfs2_dlmfs(sb) */ /* untested */
  8851. + /* || au_test_sysv(sb) */ /* untested */
  8852. + /* || au_test_ubifs(sb) */ /* untested */
  8853. + /* || au_test_minix(sb) */ /* untested */
  8854. + ;
  8855. +}
  8856. +
  8857. +/*
  8858. + * filesystems which don't store the correct value in some of their inode
  8859. + * attributes.
  8860. + */
  8861. +static inline int au_test_fs_bad_iattr(struct super_block *sb)
  8862. +{
  8863. + return au_test_fs_bad_iattr_size(sb)
  8864. + /* || au_test_cifs(sb) */ /* untested */
  8865. + || au_test_fat(sb)
  8866. + || au_test_msdos(sb)
  8867. + || au_test_vfat(sb);
  8868. +}
  8869. +
  8870. +/* they don't check i_nlink in link(2) */
  8871. +static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
  8872. +{
  8873. + return au_test_tmpfs(sb)
  8874. +#ifdef CONFIG_AUFS_BR_RAMFS
  8875. + || au_test_ramfs(sb)
  8876. +#endif
  8877. + || au_test_ubifs(sb);
  8878. +}
  8879. +
  8880. +/*
  8881. + * filesystems which sets S_NOATIME and S_NOCMTIME.
  8882. + */
  8883. +static inline int au_test_fs_notime(struct super_block *sb)
  8884. +{
  8885. + return au_test_nfs(sb)
  8886. + || au_test_fuse(sb)
  8887. + || au_test_ubifs(sb)
  8888. + /* || au_test_cifs(sb) */ /* untested */
  8889. + ;
  8890. +}
  8891. +
  8892. +/*
  8893. + * filesystems which requires replacing i_mapping.
  8894. + */
  8895. +static inline int au_test_fs_bad_mapping(struct super_block *sb)
  8896. +{
  8897. + return au_test_fuse(sb)
  8898. + || au_test_ubifs(sb);
  8899. +}
  8900. +
  8901. +/* temporary support for i#1 in cramfs */
  8902. +static inline int au_test_fs_unique_ino(struct inode *inode)
  8903. +{
  8904. + if (au_test_cramfs(inode->i_sb))
  8905. + return inode->i_ino != 1;
  8906. + return 1;
  8907. +}
  8908. +
  8909. +/* ---------------------------------------------------------------------- */
  8910. +
  8911. +/*
  8912. + * the filesystem where the xino files placed must support i/o after unlink and
  8913. + * maintain i_size and i_blocks.
  8914. + */
  8915. +static inline int au_test_fs_bad_xino(struct super_block *sb)
  8916. +{
  8917. + return au_test_fs_remote(sb)
  8918. + || au_test_fs_bad_iattr_size(sb)
  8919. +#ifdef CONFIG_AUFS_BR_RAMFS
  8920. + || !(au_test_ramfs(sb) || au_test_fs_null_nd(sb))
  8921. +#else
  8922. + || !au_test_fs_null_nd(sb) /* to keep xino code simple */
  8923. +#endif
  8924. + /* don't want unnecessary work for xino */
  8925. + || au_test_aufs(sb)
  8926. + || au_test_ecryptfs(sb);
  8927. +}
  8928. +
  8929. +static inline int au_test_fs_trunc_xino(struct super_block *sb)
  8930. +{
  8931. + return au_test_tmpfs(sb)
  8932. + || au_test_ramfs(sb);
  8933. +}
  8934. +
  8935. +/*
  8936. + * test if the @sb is real-readonly.
  8937. + */
  8938. +static inline int au_test_fs_rr(struct super_block *sb)
  8939. +{
  8940. + return au_test_squashfs(sb)
  8941. + || au_test_iso9660(sb)
  8942. + || au_test_cramfs(sb)
  8943. + || au_test_romfs(sb);
  8944. +}
  8945. +
  8946. +#endif /* __KERNEL__ */
  8947. +#endif /* __AUFS_FSTYPE_H__ */
  8948. diff -Nur linux-2.6.31.5.orig/fs/aufs/hinotify.c linux-2.6.31.5/fs/aufs/hinotify.c
  8949. --- linux-2.6.31.5.orig/fs/aufs/hinotify.c 1970-01-01 01:00:00.000000000 +0100
  8950. +++ linux-2.6.31.5/fs/aufs/hinotify.c 2009-11-15 22:02:37.000000000 +0100
  8951. @@ -0,0 +1,755 @@
  8952. +/*
  8953. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  8954. + *
  8955. + * This program, aufs is free software; you can redistribute it and/or modify
  8956. + * it under the terms of the GNU General Public License as published by
  8957. + * the Free Software Foundation; either version 2 of the License, or
  8958. + * (at your option) any later version.
  8959. + *
  8960. + * This program is distributed in the hope that it will be useful,
  8961. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  8962. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8963. + * GNU General Public License for more details.
  8964. + *
  8965. + * You should have received a copy of the GNU General Public License
  8966. + * along with this program; if not, write to the Free Software
  8967. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  8968. + */
  8969. +
  8970. +/*
  8971. + * inotify for the lower directories
  8972. + */
  8973. +
  8974. +#include "aufs.h"
  8975. +
  8976. +static const __u32 AuHinMask = (IN_MOVE | IN_DELETE | IN_CREATE);
  8977. +static struct inotify_handle *au_hin_handle;
  8978. +
  8979. +AuCacheFuncs(hinotify, HINOTIFY);
  8980. +
  8981. +int au_hin_alloc(struct au_hinode *hinode, struct inode *inode,
  8982. + struct inode *h_inode)
  8983. +{
  8984. + int err;
  8985. + struct au_hinotify *hin;
  8986. + s32 wd;
  8987. +
  8988. + err = -ENOMEM;
  8989. + hin = au_cache_alloc_hinotify();
  8990. + if (hin) {
  8991. + AuDebugOn(hinode->hi_notify);
  8992. + hinode->hi_notify = hin;
  8993. + hin->hin_aufs_inode = inode;
  8994. +
  8995. + inotify_init_watch(&hin->hin_watch);
  8996. + wd = inotify_add_watch(au_hin_handle, &hin->hin_watch, h_inode,
  8997. + AuHinMask);
  8998. + if (wd >= 0)
  8999. + return 0; /* success */
  9000. +
  9001. + err = wd;
  9002. + put_inotify_watch(&hin->hin_watch);
  9003. + au_cache_free_hinotify(hin);
  9004. + hinode->hi_notify = NULL;
  9005. + }
  9006. +
  9007. + return err;
  9008. +}
  9009. +
  9010. +void au_hin_free(struct au_hinode *hinode)
  9011. +{
  9012. + int err;
  9013. + struct au_hinotify *hin;
  9014. +
  9015. + hin = hinode->hi_notify;
  9016. + if (hin) {
  9017. + err = 0;
  9018. + if (atomic_read(&hin->hin_watch.count))
  9019. + err = inotify_rm_watch(au_hin_handle, &hin->hin_watch);
  9020. + if (unlikely(err))
  9021. + /* it means the watch is already removed */
  9022. + AuWarn("failed inotify_rm_watch() %d\n", err);
  9023. + au_cache_free_hinotify(hin);
  9024. + hinode->hi_notify = NULL;
  9025. + }
  9026. +}
  9027. +
  9028. +/* ---------------------------------------------------------------------- */
  9029. +
  9030. +void au_hin_ctl(struct au_hinode *hinode, int do_set)
  9031. +{
  9032. + struct inode *h_inode;
  9033. + struct inotify_watch *watch;
  9034. +
  9035. + if (!hinode->hi_notify)
  9036. + return;
  9037. +
  9038. + h_inode = hinode->hi_inode;
  9039. + IMustLock(h_inode);
  9040. +
  9041. + /* todo: try inotify_find_update_watch()? */
  9042. + watch = &hinode->hi_notify->hin_watch;
  9043. + mutex_lock(&h_inode->inotify_mutex);
  9044. + /* mutex_lock(&watch->ih->mutex); */
  9045. + if (do_set) {
  9046. + AuDebugOn(watch->mask & AuHinMask);
  9047. + watch->mask |= AuHinMask;
  9048. + } else {
  9049. + AuDebugOn(!(watch->mask & AuHinMask));
  9050. + watch->mask &= ~AuHinMask;
  9051. + }
  9052. + /* mutex_unlock(&watch->ih->mutex); */
  9053. + mutex_unlock(&h_inode->inotify_mutex);
  9054. +}
  9055. +
  9056. +void au_reset_hinotify(struct inode *inode, unsigned int flags)
  9057. +{
  9058. + aufs_bindex_t bindex, bend;
  9059. + struct inode *hi;
  9060. + struct dentry *iwhdentry;
  9061. +
  9062. + bend = au_ibend(inode);
  9063. + for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
  9064. + hi = au_h_iptr(inode, bindex);
  9065. + if (!hi)
  9066. + continue;
  9067. +
  9068. + /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */
  9069. + iwhdentry = au_hi_wh(inode, bindex);
  9070. + if (iwhdentry)
  9071. + dget(iwhdentry);
  9072. + au_igrab(hi);
  9073. + au_set_h_iptr(inode, bindex, NULL, 0);
  9074. + au_set_h_iptr(inode, bindex, au_igrab(hi),
  9075. + flags & ~AuHi_XINO);
  9076. + iput(hi);
  9077. + dput(iwhdentry);
  9078. + /* mutex_unlock(&hi->i_mutex); */
  9079. + }
  9080. +}
  9081. +
  9082. +/* ---------------------------------------------------------------------- */
  9083. +
  9084. +static int hin_xino(struct inode *inode, struct inode *h_inode)
  9085. +{
  9086. + int err;
  9087. + aufs_bindex_t bindex, bend, bfound, bstart;
  9088. + struct inode *h_i;
  9089. +
  9090. + err = 0;
  9091. + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
  9092. + AuWarn("branch root dir was changed\n");
  9093. + goto out;
  9094. + }
  9095. +
  9096. + bfound = -1;
  9097. + bend = au_ibend(inode);
  9098. + bstart = au_ibstart(inode);
  9099. +#if 0 /* reserved for future use */
  9100. + if (bindex == bend) {
  9101. + /* keep this ino in rename case */
  9102. + goto out;
  9103. + }
  9104. +#endif
  9105. + for (bindex = bstart; bindex <= bend; bindex++) {
  9106. + if (au_h_iptr(inode, bindex) == h_inode) {
  9107. + bfound = bindex;
  9108. + break;
  9109. + }
  9110. + }
  9111. + if (bfound < 0)
  9112. + goto out;
  9113. +
  9114. + for (bindex = bstart; bindex <= bend; bindex++) {
  9115. + h_i = au_h_iptr(inode, bindex);
  9116. + if (!h_i)
  9117. + continue;
  9118. +
  9119. + err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
  9120. + /* ignore this error */
  9121. + /* bad action? */
  9122. + }
  9123. +
  9124. + /* children inode number will be broken */
  9125. +
  9126. + out:
  9127. + AuTraceErr(err);
  9128. + return err;
  9129. +}
  9130. +
  9131. +static int hin_gen_tree(struct dentry *dentry)
  9132. +{
  9133. + int err, i, j, ndentry;
  9134. + struct au_dcsub_pages dpages;
  9135. + struct au_dpage *dpage;
  9136. + struct dentry **dentries;
  9137. +
  9138. + err = au_dpages_init(&dpages, GFP_NOFS);
  9139. + if (unlikely(err))
  9140. + goto out;
  9141. + err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
  9142. + if (unlikely(err))
  9143. + goto out_dpages;
  9144. +
  9145. + for (i = 0; i < dpages.ndpage; i++) {
  9146. + dpage = dpages.dpages + i;
  9147. + dentries = dpage->dentries;
  9148. + ndentry = dpage->ndentry;
  9149. + for (j = 0; j < ndentry; j++) {
  9150. + struct dentry *d;
  9151. +
  9152. + d = dentries[j];
  9153. + if (IS_ROOT(d))
  9154. + continue;
  9155. +
  9156. + d_drop(d);
  9157. + au_digen_dec(d);
  9158. + if (d->d_inode)
  9159. + /* todo: reset children xino?
  9160. + cached children only? */
  9161. + au_iigen_dec(d->d_inode);
  9162. + }
  9163. + }
  9164. +
  9165. + out_dpages:
  9166. + au_dpages_free(&dpages);
  9167. +
  9168. + /* discard children */
  9169. + dentry_unhash(dentry);
  9170. + dput(dentry);
  9171. + out:
  9172. + return err;
  9173. +}
  9174. +
  9175. +/*
  9176. + * return 0 if processed.
  9177. + */
  9178. +static int hin_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
  9179. + const unsigned int isdir)
  9180. +{
  9181. + int err;
  9182. + struct dentry *d;
  9183. + struct qstr *dname;
  9184. +
  9185. + err = 1;
  9186. + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
  9187. + AuWarn("branch root dir was changed\n");
  9188. + err = 0;
  9189. + goto out;
  9190. + }
  9191. +
  9192. + if (!isdir) {
  9193. + AuDebugOn(!name);
  9194. + au_iigen_dec(inode);
  9195. + spin_lock(&dcache_lock);
  9196. + list_for_each_entry(d, &inode->i_dentry, d_alias) {
  9197. + dname = &d->d_name;
  9198. + if (dname->len != nlen
  9199. + && memcmp(dname->name, name, nlen))
  9200. + continue;
  9201. + err = 0;
  9202. + spin_lock(&d->d_lock);
  9203. + __d_drop(d);
  9204. + au_digen_dec(d);
  9205. + spin_unlock(&d->d_lock);
  9206. + break;
  9207. + }
  9208. + spin_unlock(&dcache_lock);
  9209. + } else {
  9210. + au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIRS);
  9211. + d = d_find_alias(inode);
  9212. + if (!d) {
  9213. + au_iigen_dec(inode);
  9214. + goto out;
  9215. + }
  9216. +
  9217. + dname = &d->d_name;
  9218. + if (dname->len == nlen && !memcmp(dname->name, name, nlen))
  9219. + err = hin_gen_tree(d);
  9220. + dput(d);
  9221. + }
  9222. +
  9223. + out:
  9224. + AuTraceErr(err);
  9225. + return err;
  9226. +}
  9227. +
  9228. +static int hin_gen_by_name(struct dentry *dentry, const unsigned int isdir)
  9229. +{
  9230. + int err;
  9231. + struct inode *inode;
  9232. +
  9233. + inode = dentry->d_inode;
  9234. + if (IS_ROOT(dentry)
  9235. + /* || (inode && inode->i_ino == AUFS_ROOT_INO) */
  9236. + ) {
  9237. + AuWarn("branch root dir was changed\n");
  9238. + return 0;
  9239. + }
  9240. +
  9241. + err = 0;
  9242. + if (!isdir) {
  9243. + d_drop(dentry);
  9244. + au_digen_dec(dentry);
  9245. + if (inode)
  9246. + au_iigen_dec(inode);
  9247. + } else {
  9248. + au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS);
  9249. + if (inode)
  9250. + err = hin_gen_tree(dentry);
  9251. + }
  9252. +
  9253. + AuTraceErr(err);
  9254. + return err;
  9255. +}
  9256. +
  9257. +/* ---------------------------------------------------------------------- */
  9258. +
  9259. +/* hinotify job flags */
  9260. +#define AuHinJob_XINO0 1
  9261. +#define AuHinJob_GEN (1 << 1)
  9262. +#define AuHinJob_DIRENT (1 << 2)
  9263. +#define AuHinJob_ISDIR (1 << 3)
  9264. +#define AuHinJob_TRYXINO0 (1 << 4)
  9265. +#define AuHinJob_MNTPNT (1 << 5)
  9266. +#define au_ftest_hinjob(flags, name) ((flags) & AuHinJob_##name)
  9267. +#define au_fset_hinjob(flags, name) { (flags) |= AuHinJob_##name; }
  9268. +#define au_fclr_hinjob(flags, name) { (flags) &= ~AuHinJob_##name; }
  9269. +
  9270. +struct hin_job_args {
  9271. + unsigned int flags;
  9272. + struct inode *inode, *h_inode, *dir, *h_dir;
  9273. + struct dentry *dentry;
  9274. + char *h_name;
  9275. + int h_nlen;
  9276. +};
  9277. +
  9278. +static int hin_job(struct hin_job_args *a)
  9279. +{
  9280. + const unsigned int isdir = au_ftest_hinjob(a->flags, ISDIR);
  9281. +
  9282. + /* reset xino */
  9283. + if (au_ftest_hinjob(a->flags, XINO0) && a->inode)
  9284. + hin_xino(a->inode, a->h_inode); /* ignore this error */
  9285. +
  9286. + if (au_ftest_hinjob(a->flags, TRYXINO0)
  9287. + && a->inode
  9288. + && a->h_inode) {
  9289. + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
  9290. + if (!a->h_inode->i_nlink)
  9291. + hin_xino(a->inode, a->h_inode); /* ignore this error */
  9292. + mutex_unlock(&a->h_inode->i_mutex);
  9293. + }
  9294. +
  9295. + /* make the generation obsolete */
  9296. + if (au_ftest_hinjob(a->flags, GEN)) {
  9297. + int err = -1;
  9298. + if (a->inode)
  9299. + err = hin_gen_by_inode(a->h_name, a->h_nlen, a->inode,
  9300. + isdir);
  9301. + if (err && a->dentry)
  9302. + hin_gen_by_name(a->dentry, isdir);
  9303. + /* ignore this error */
  9304. + }
  9305. +
  9306. + /* make dir entries obsolete */
  9307. + if (au_ftest_hinjob(a->flags, DIRENT) && a->inode) {
  9308. + struct au_vdir *vdir;
  9309. +
  9310. + vdir = au_ivdir(a->inode);
  9311. + if (vdir)
  9312. + vdir->vd_jiffy = 0;
  9313. + /* IMustLock(a->inode); */
  9314. + /* a->inode->i_version++; */
  9315. + }
  9316. +
  9317. + /* can do nothing but warn */
  9318. + if (au_ftest_hinjob(a->flags, MNTPNT)
  9319. + && a->dentry
  9320. + && d_mountpoint(a->dentry))
  9321. + AuWarn("mount-point %.*s is removed or renamed\n",
  9322. + AuDLNPair(a->dentry));
  9323. +
  9324. + return 0;
  9325. +}
  9326. +
  9327. +/* ---------------------------------------------------------------------- */
  9328. +
  9329. +static char *in_name(u32 mask)
  9330. +{
  9331. +#ifdef CONFIG_AUFS_DEBUG
  9332. +#define test_ret(flag) if (mask & flag) \
  9333. + return #flag;
  9334. + test_ret(IN_ACCESS);
  9335. + test_ret(IN_MODIFY);
  9336. + test_ret(IN_ATTRIB);
  9337. + test_ret(IN_CLOSE_WRITE);
  9338. + test_ret(IN_CLOSE_NOWRITE);
  9339. + test_ret(IN_OPEN);
  9340. + test_ret(IN_MOVED_FROM);
  9341. + test_ret(IN_MOVED_TO);
  9342. + test_ret(IN_CREATE);
  9343. + test_ret(IN_DELETE);
  9344. + test_ret(IN_DELETE_SELF);
  9345. + test_ret(IN_MOVE_SELF);
  9346. + test_ret(IN_UNMOUNT);
  9347. + test_ret(IN_Q_OVERFLOW);
  9348. + test_ret(IN_IGNORED);
  9349. + return "";
  9350. +#undef test_ret
  9351. +#else
  9352. + return "??";
  9353. +#endif
  9354. +}
  9355. +
  9356. +static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
  9357. + struct inode *dir)
  9358. +{
  9359. + struct dentry *dentry, *d, *parent;
  9360. + struct qstr *dname;
  9361. +
  9362. + parent = d_find_alias(dir);
  9363. + if (!parent)
  9364. + return NULL;
  9365. +
  9366. + dentry = NULL;
  9367. + spin_lock(&dcache_lock);
  9368. + list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) {
  9369. + /* AuDbg("%.*s\n", AuDLNPair(d)); */
  9370. + dname = &d->d_name;
  9371. + if (dname->len != nlen || memcmp(dname->name, name, nlen))
  9372. + continue;
  9373. + if (!atomic_read(&d->d_count) || !d->d_fsdata) {
  9374. + spin_lock(&d->d_lock);
  9375. + __d_drop(d);
  9376. + spin_unlock(&d->d_lock);
  9377. + continue;
  9378. + }
  9379. +
  9380. + dentry = dget(d);
  9381. + break;
  9382. + }
  9383. + spin_unlock(&dcache_lock);
  9384. + dput(parent);
  9385. +
  9386. + if (dentry)
  9387. + di_write_lock_child(dentry);
  9388. +
  9389. + return dentry;
  9390. +}
  9391. +
  9392. +static struct inode *lookup_wlock_by_ino(struct super_block *sb,
  9393. + aufs_bindex_t bindex, ino_t h_ino)
  9394. +{
  9395. + struct inode *inode;
  9396. + ino_t ino;
  9397. + int err;
  9398. +
  9399. + inode = NULL;
  9400. + err = au_xino_read(sb, bindex, h_ino, &ino);
  9401. + if (!err && ino)
  9402. + inode = ilookup(sb, ino);
  9403. + if (!inode)
  9404. + goto out;
  9405. +
  9406. + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
  9407. + AuWarn("wrong root branch\n");
  9408. + iput(inode);
  9409. + inode = NULL;
  9410. + goto out;
  9411. + }
  9412. +
  9413. + ii_write_lock_child(inode);
  9414. +
  9415. + out:
  9416. + return inode;
  9417. +}
  9418. +
  9419. +enum { CHILD, PARENT };
  9420. +struct postproc_args {
  9421. + struct inode *h_dir, *dir, *h_child_inode;
  9422. + u32 mask;
  9423. + unsigned int flags[2];
  9424. + unsigned int h_child_nlen;
  9425. + char h_child_name[];
  9426. +};
  9427. +
  9428. +static void postproc(void *_args)
  9429. +{
  9430. + struct postproc_args *a = _args;
  9431. + struct super_block *sb;
  9432. + aufs_bindex_t bindex, bend, bfound;
  9433. + unsigned char xino, try_iput;
  9434. + int err;
  9435. + struct inode *inode;
  9436. + ino_t h_ino;
  9437. + struct hin_job_args args;
  9438. + struct dentry *dentry;
  9439. + struct au_sbinfo *sbinfo;
  9440. +
  9441. + AuDebugOn(!_args);
  9442. + AuDebugOn(!a->h_dir);
  9443. + AuDebugOn(!a->dir);
  9444. + AuDebugOn(!a->mask);
  9445. + AuDbg("mask 0x%x %s, i%lu, hi%lu, hci%lu\n",
  9446. + a->mask, in_name(a->mask), a->dir->i_ino, a->h_dir->i_ino,
  9447. + a->h_child_inode ? a->h_child_inode->i_ino : 0);
  9448. +
  9449. + inode = NULL;
  9450. + dentry = NULL;
  9451. + /*
  9452. + * do not lock a->dir->i_mutex here
  9453. + * because of d_revalidate() may cause a deadlock.
  9454. + */
  9455. + sb = a->dir->i_sb;
  9456. + AuDebugOn(!sb);
  9457. + sbinfo = au_sbi(sb);
  9458. + AuDebugOn(!sbinfo);
  9459. + /* big aufs lock */
  9460. + si_noflush_write_lock(sb);
  9461. +
  9462. + ii_read_lock_parent(a->dir);
  9463. + bfound = -1;
  9464. + bend = au_ibend(a->dir);
  9465. + for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
  9466. + if (au_h_iptr(a->dir, bindex) == a->h_dir) {
  9467. + bfound = bindex;
  9468. + break;
  9469. + }
  9470. + ii_read_unlock(a->dir);
  9471. + if (unlikely(bfound < 0))
  9472. + goto out;
  9473. +
  9474. + xino = !!au_opt_test(au_mntflags(sb), XINO);
  9475. + h_ino = 0;
  9476. + if (a->h_child_inode)
  9477. + h_ino = a->h_child_inode->i_ino;
  9478. +
  9479. + if (a->h_child_nlen
  9480. + && (au_ftest_hinjob(a->flags[CHILD], GEN)
  9481. + || au_ftest_hinjob(a->flags[CHILD], MNTPNT)))
  9482. + dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
  9483. + a->dir);
  9484. + try_iput = 0;
  9485. + if (dentry)
  9486. + inode = dentry->d_inode;
  9487. + if (xino && !inode && h_ino
  9488. + && (au_ftest_hinjob(a->flags[CHILD], XINO0)
  9489. + || au_ftest_hinjob(a->flags[CHILD], TRYXINO0)
  9490. + || au_ftest_hinjob(a->flags[CHILD], GEN))) {
  9491. + inode = lookup_wlock_by_ino(sb, bfound, h_ino);
  9492. + try_iput = 1;
  9493. + }
  9494. +
  9495. + args.flags = a->flags[CHILD];
  9496. + args.dentry = dentry;
  9497. + args.inode = inode;
  9498. + args.h_inode = a->h_child_inode;
  9499. + args.dir = a->dir;
  9500. + args.h_dir = a->h_dir;
  9501. + args.h_name = a->h_child_name;
  9502. + args.h_nlen = a->h_child_nlen;
  9503. + err = hin_job(&args);
  9504. + if (dentry) {
  9505. + if (dentry->d_fsdata)
  9506. + di_write_unlock(dentry);
  9507. + dput(dentry);
  9508. + }
  9509. + if (inode && try_iput) {
  9510. + ii_write_unlock(inode);
  9511. + iput(inode);
  9512. + }
  9513. +
  9514. + ii_write_lock_parent(a->dir);
  9515. + args.flags = a->flags[PARENT];
  9516. + args.dentry = NULL;
  9517. + args.inode = a->dir;
  9518. + args.h_inode = a->h_dir;
  9519. + args.dir = NULL;
  9520. + args.h_dir = NULL;
  9521. + args.h_name = NULL;
  9522. + args.h_nlen = 0;
  9523. + err = hin_job(&args);
  9524. + ii_write_unlock(a->dir);
  9525. +
  9526. + out:
  9527. + au_nwt_done(&sbinfo->si_nowait);
  9528. + si_write_unlock(sb);
  9529. +
  9530. + iput(a->h_child_inode);
  9531. + iput(a->h_dir);
  9532. + iput(a->dir);
  9533. + kfree(a);
  9534. +}
  9535. +
  9536. +/* ---------------------------------------------------------------------- */
  9537. +
  9538. +static void aufs_inotify(struct inotify_watch *watch, u32 wd __maybe_unused,
  9539. + u32 mask, u32 cookie __maybe_unused,
  9540. + const char *h_child_name, struct inode *h_child_inode)
  9541. +{
  9542. + struct au_hinotify *hinotify;
  9543. + struct postproc_args *args;
  9544. + int len, wkq_err;
  9545. + unsigned char isdir, isroot, wh;
  9546. + char *p;
  9547. + struct inode *dir;
  9548. + unsigned int flags[2];
  9549. +
  9550. + /* if IN_UNMOUNT happens, there must be another bug */
  9551. + AuDebugOn(mask & IN_UNMOUNT);
  9552. + if (mask & (IN_IGNORED | IN_UNMOUNT)) {
  9553. + put_inotify_watch(watch);
  9554. + return;
  9555. + }
  9556. +#ifdef AuDbgHinotify
  9557. + au_debug(1);
  9558. + if (1 || !h_child_name || strcmp(h_child_name, AUFS_XINO_FNAME)) {
  9559. + AuDbg("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s,"
  9560. + " hi%lu\n",
  9561. + watch->inode->i_ino, wd, mask, in_name(mask), cookie,
  9562. + h_child_name ? h_child_name : "",
  9563. + h_child_inode ? h_child_inode->i_ino : 0);
  9564. + WARN_ON(1);
  9565. + }
  9566. + au_debug(0);
  9567. +#endif
  9568. +
  9569. + hinotify = container_of(watch, struct au_hinotify, hin_watch);
  9570. + AuDebugOn(!hinotify || !hinotify->hin_aufs_inode);
  9571. + dir = igrab(hinotify->hin_aufs_inode);
  9572. + if (!dir)
  9573. + return;
  9574. +
  9575. + isroot = (dir->i_ino == AUFS_ROOT_INO);
  9576. + len = 0;
  9577. + wh = 0;
  9578. + if (h_child_name) {
  9579. + len = strlen(h_child_name);
  9580. + if (!memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
  9581. + h_child_name += AUFS_WH_PFX_LEN;
  9582. + len -= AUFS_WH_PFX_LEN;
  9583. + wh = 1;
  9584. + }
  9585. + }
  9586. +
  9587. + isdir = 0;
  9588. + if (h_child_inode)
  9589. + isdir = !!S_ISDIR(h_child_inode->i_mode);
  9590. + flags[PARENT] = AuHinJob_ISDIR;
  9591. + flags[CHILD] = 0;
  9592. + if (isdir)
  9593. + flags[CHILD] = AuHinJob_ISDIR;
  9594. + switch (mask & IN_ALL_EVENTS) {
  9595. + case IN_MOVED_FROM:
  9596. + case IN_MOVED_TO:
  9597. + AuDebugOn(!h_child_name || !h_child_inode);
  9598. + au_fset_hinjob(flags[CHILD], GEN);
  9599. + au_fset_hinjob(flags[CHILD], XINO0);
  9600. + au_fset_hinjob(flags[CHILD], MNTPNT);
  9601. + au_fset_hinjob(flags[PARENT], DIRENT);
  9602. + break;
  9603. +
  9604. + case IN_CREATE:
  9605. + AuDebugOn(!h_child_name || !h_child_inode);
  9606. + au_fset_hinjob(flags[PARENT], DIRENT);
  9607. + au_fset_hinjob(flags[CHILD], GEN);
  9608. + break;
  9609. +
  9610. + case IN_DELETE:
  9611. + /*
  9612. + * aufs never be able to get this child inode.
  9613. + * revalidation should be in d_revalidate()
  9614. + * by checking i_nlink, i_generation or d_unhashed().
  9615. + */
  9616. + AuDebugOn(!h_child_name);
  9617. + au_fset_hinjob(flags[PARENT], DIRENT);
  9618. + au_fset_hinjob(flags[CHILD], GEN);
  9619. + au_fset_hinjob(flags[CHILD], TRYXINO0);
  9620. + au_fset_hinjob(flags[CHILD], MNTPNT);
  9621. + break;
  9622. +
  9623. + default:
  9624. + AuDebugOn(1);
  9625. + }
  9626. +
  9627. + if (wh)
  9628. + h_child_inode = NULL;
  9629. +
  9630. + /* iput() and kfree() will be called in postproc() */
  9631. + /*
  9632. + * inotify_mutex is already acquired and kmalloc/prune_icache may lock
  9633. + * iprune_mutex. strange.
  9634. + */
  9635. + lockdep_off();
  9636. + args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
  9637. + lockdep_on();
  9638. + if (unlikely(!args)) {
  9639. + AuErr1("no memory\n");
  9640. + iput(dir);
  9641. + return;
  9642. + }
  9643. + args->flags[PARENT] = flags[PARENT];
  9644. + args->flags[CHILD] = flags[CHILD];
  9645. + args->mask = mask;
  9646. + args->dir = dir;
  9647. + args->h_dir = igrab(watch->inode);
  9648. + if (h_child_inode)
  9649. + h_child_inode = igrab(h_child_inode); /* can be NULL */
  9650. + args->h_child_inode = h_child_inode;
  9651. + args->h_child_nlen = len;
  9652. + if (len) {
  9653. + p = (void *)args;
  9654. + p += sizeof(*args);
  9655. + memcpy(p, h_child_name, len + 1);
  9656. + }
  9657. +
  9658. + lockdep_off();
  9659. + wkq_err = au_wkq_nowait(postproc, args, dir->i_sb);
  9660. + lockdep_on();
  9661. + if (unlikely(wkq_err))
  9662. + AuErr("wkq %d\n", wkq_err);
  9663. +}
  9664. +
  9665. +static void aufs_inotify_destroy(struct inotify_watch *watch __maybe_unused)
  9666. +{
  9667. + return;
  9668. +}
  9669. +
  9670. +static struct inotify_operations aufs_inotify_ops = {
  9671. + .handle_event = aufs_inotify,
  9672. + .destroy_watch = aufs_inotify_destroy
  9673. +};
  9674. +
  9675. +/* ---------------------------------------------------------------------- */
  9676. +
  9677. +static void au_hin_destroy_cache(void)
  9678. +{
  9679. + kmem_cache_destroy(au_cachep[AuCache_HINOTIFY]);
  9680. + au_cachep[AuCache_HINOTIFY] = NULL;
  9681. +}
  9682. +
  9683. +int __init au_hinotify_init(void)
  9684. +{
  9685. + int err;
  9686. +
  9687. + err = -ENOMEM;
  9688. + au_cachep[AuCache_HINOTIFY] = AuCache(au_hinotify);
  9689. + if (au_cachep[AuCache_HINOTIFY]) {
  9690. + err = 0;
  9691. + au_hin_handle = inotify_init(&aufs_inotify_ops);
  9692. + if (IS_ERR(au_hin_handle)) {
  9693. + err = PTR_ERR(au_hin_handle);
  9694. + au_hin_destroy_cache();
  9695. + }
  9696. + }
  9697. + AuTraceErr(err);
  9698. + return err;
  9699. +}
  9700. +
  9701. +void au_hinotify_fin(void)
  9702. +{
  9703. + inotify_destroy(au_hin_handle);
  9704. + if (au_cachep[AuCache_HINOTIFY])
  9705. + au_hin_destroy_cache();
  9706. +}
  9707. diff -Nur linux-2.6.31.5.orig/fs/aufs/iinfo.c linux-2.6.31.5/fs/aufs/iinfo.c
  9708. --- linux-2.6.31.5.orig/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100
  9709. +++ linux-2.6.31.5/fs/aufs/iinfo.c 2009-11-15 22:02:37.000000000 +0100
  9710. @@ -0,0 +1,283 @@
  9711. +/*
  9712. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  9713. + *
  9714. + * This program, aufs is free software; you can redistribute it and/or modify
  9715. + * it under the terms of the GNU General Public License as published by
  9716. + * the Free Software Foundation; either version 2 of the License, or
  9717. + * (at your option) any later version.
  9718. + *
  9719. + * This program is distributed in the hope that it will be useful,
  9720. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9721. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9722. + * GNU General Public License for more details.
  9723. + *
  9724. + * You should have received a copy of the GNU General Public License
  9725. + * along with this program; if not, write to the Free Software
  9726. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  9727. + */
  9728. +
  9729. +/*
  9730. + * inode private data
  9731. + */
  9732. +
  9733. +#include "aufs.h"
  9734. +
  9735. +struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
  9736. +{
  9737. + struct inode *h_inode;
  9738. +
  9739. + IiMustAnyLock(inode);
  9740. +
  9741. + h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode;
  9742. + AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
  9743. + return h_inode;
  9744. +}
  9745. +
  9746. +/* todo: hard/soft set? */
  9747. +void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex)
  9748. +{
  9749. + struct au_iinfo *iinfo = au_ii(inode);
  9750. + struct inode *h_inode;
  9751. +
  9752. + IiMustWriteLock(inode);
  9753. +
  9754. + iinfo->ii_bstart = bindex;
  9755. + h_inode = iinfo->ii_hinode[bindex + 0].hi_inode;
  9756. + if (h_inode)
  9757. + au_cpup_igen(inode, h_inode);
  9758. +}
  9759. +
  9760. +void au_hiput(struct au_hinode *hinode)
  9761. +{
  9762. + au_hin_free(hinode);
  9763. + dput(hinode->hi_whdentry);
  9764. + iput(hinode->hi_inode);
  9765. +}
  9766. +
  9767. +unsigned int au_hi_flags(struct inode *inode, int isdir)
  9768. +{
  9769. + unsigned int flags;
  9770. + const unsigned int mnt_flags = au_mntflags(inode->i_sb);
  9771. +
  9772. + flags = 0;
  9773. + if (au_opt_test(mnt_flags, XINO))
  9774. + au_fset_hi(flags, XINO);
  9775. + if (isdir && au_opt_test(mnt_flags, UDBA_HINOTIFY))
  9776. + au_fset_hi(flags, HINOTIFY);
  9777. + return flags;
  9778. +}
  9779. +
  9780. +void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
  9781. + struct inode *h_inode, unsigned int flags)
  9782. +{
  9783. + struct au_hinode *hinode;
  9784. + struct inode *hi;
  9785. + struct au_iinfo *iinfo = au_ii(inode);
  9786. +
  9787. + IiMustWriteLock(inode);
  9788. +
  9789. + hinode = iinfo->ii_hinode + bindex;
  9790. + hi = hinode->hi_inode;
  9791. + AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
  9792. + AuDebugOn(h_inode && hi);
  9793. +
  9794. + if (hi)
  9795. + au_hiput(hinode);
  9796. + hinode->hi_inode = h_inode;
  9797. + if (h_inode) {
  9798. + int err;
  9799. + struct super_block *sb = inode->i_sb;
  9800. + struct au_branch *br;
  9801. +
  9802. + if (bindex == iinfo->ii_bstart)
  9803. + au_cpup_igen(inode, h_inode);
  9804. + br = au_sbr(sb, bindex);
  9805. + hinode->hi_id = br->br_id;
  9806. + if (au_ftest_hi(flags, XINO)) {
  9807. + err = au_xino_write(sb, bindex, h_inode->i_ino,
  9808. + inode->i_ino);
  9809. + if (unlikely(err))
  9810. + AuIOErr1("failed au_xino_write() %d\n", err);
  9811. + }
  9812. +
  9813. + if (au_ftest_hi(flags, HINOTIFY)
  9814. + && au_br_hinotifyable(br->br_perm)) {
  9815. + err = au_hin_alloc(hinode, inode, h_inode);
  9816. + if (unlikely(err))
  9817. + AuIOErr1("au_hin_alloc() %d\n", err);
  9818. + }
  9819. + }
  9820. +}
  9821. +
  9822. +void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
  9823. + struct dentry *h_wh)
  9824. +{
  9825. + struct au_hinode *hinode;
  9826. +
  9827. + IiMustWriteLock(inode);
  9828. +
  9829. + hinode = au_ii(inode)->ii_hinode + bindex;
  9830. + AuDebugOn(hinode->hi_whdentry);
  9831. + hinode->hi_whdentry = h_wh;
  9832. +}
  9833. +
  9834. +void au_update_iigen(struct inode *inode)
  9835. +{
  9836. + atomic_set(&au_ii(inode)->ii_generation, au_sigen(inode->i_sb));
  9837. + /* smp_mb(); */ /* atomic_set */
  9838. +}
  9839. +
  9840. +/* it may be called at remount time, too */
  9841. +void au_update_brange(struct inode *inode, int do_put_zero)
  9842. +{
  9843. + struct au_iinfo *iinfo;
  9844. +
  9845. + iinfo = au_ii(inode);
  9846. + if (!iinfo || iinfo->ii_bstart < 0)
  9847. + return;
  9848. +
  9849. + IiMustWriteLock(inode);
  9850. +
  9851. + if (do_put_zero) {
  9852. + aufs_bindex_t bindex;
  9853. +
  9854. + for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
  9855. + bindex++) {
  9856. + struct inode *h_i;
  9857. +
  9858. + h_i = iinfo->ii_hinode[0 + bindex].hi_inode;
  9859. + if (h_i && !h_i->i_nlink)
  9860. + au_set_h_iptr(inode, bindex, NULL, 0);
  9861. + }
  9862. + }
  9863. +
  9864. + iinfo->ii_bstart = -1;
  9865. + while (++iinfo->ii_bstart <= iinfo->ii_bend)
  9866. + if (iinfo->ii_hinode[0 + iinfo->ii_bstart].hi_inode)
  9867. + break;
  9868. + if (iinfo->ii_bstart > iinfo->ii_bend) {
  9869. + iinfo->ii_bstart = -1;
  9870. + iinfo->ii_bend = -1;
  9871. + return;
  9872. + }
  9873. +
  9874. + iinfo->ii_bend++;
  9875. + while (0 <= --iinfo->ii_bend)
  9876. + if (iinfo->ii_hinode[0 + iinfo->ii_bend].hi_inode)
  9877. + break;
  9878. + AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend || iinfo->ii_bend < 0);
  9879. +}
  9880. +
  9881. +/* ---------------------------------------------------------------------- */
  9882. +
  9883. +int au_iinfo_init(struct inode *inode)
  9884. +{
  9885. + struct au_iinfo *iinfo;
  9886. + struct super_block *sb;
  9887. + int nbr, i;
  9888. +
  9889. + sb = inode->i_sb;
  9890. + iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
  9891. + nbr = au_sbend(sb) + 1;
  9892. + if (unlikely(nbr <= 0))
  9893. + nbr = 1;
  9894. + iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
  9895. + if (iinfo->ii_hinode) {
  9896. + for (i = 0; i < nbr; i++)
  9897. + iinfo->ii_hinode[i].hi_id = -1;
  9898. +
  9899. + atomic_set(&iinfo->ii_generation, au_sigen(sb));
  9900. + /* smp_mb(); */ /* atomic_set */
  9901. + au_rw_init(&iinfo->ii_rwsem);
  9902. + iinfo->ii_bstart = -1;
  9903. + iinfo->ii_bend = -1;
  9904. + iinfo->ii_vdir = NULL;
  9905. + return 0;
  9906. + }
  9907. + return -ENOMEM;
  9908. +}
  9909. +
  9910. +int au_ii_realloc(struct au_iinfo *iinfo, int nbr)
  9911. +{
  9912. + int err, sz;
  9913. + struct au_hinode *hip;
  9914. +
  9915. + AuRwMustWriteLock(&iinfo->ii_rwsem);
  9916. +
  9917. + err = -ENOMEM;
  9918. + sz = sizeof(*hip) * (iinfo->ii_bend + 1);
  9919. + if (!sz)
  9920. + sz = sizeof(*hip);
  9921. + hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS);
  9922. + if (hip) {
  9923. + iinfo->ii_hinode = hip;
  9924. + err = 0;
  9925. + }
  9926. +
  9927. + return err;
  9928. +}
  9929. +
  9930. +static int au_iinfo_write0(struct super_block *sb, struct au_hinode *hinode,
  9931. + ino_t ino)
  9932. +{
  9933. + int err;
  9934. + aufs_bindex_t bindex;
  9935. + unsigned char locked;
  9936. +
  9937. + err = 0;
  9938. + locked = !!si_noflush_read_trylock(sb);
  9939. + bindex = au_br_index(sb, hinode->hi_id);
  9940. + if (bindex >= 0)
  9941. + err = au_xino_write0(sb, bindex, hinode->hi_inode->i_ino, ino);
  9942. + /* error action? */
  9943. + if (locked)
  9944. + si_read_unlock(sb);
  9945. + return err;
  9946. +}
  9947. +
  9948. +void au_iinfo_fin(struct inode *inode)
  9949. +{
  9950. + ino_t ino;
  9951. + aufs_bindex_t bend;
  9952. + unsigned char unlinked = !inode->i_nlink;
  9953. + struct au_iinfo *iinfo;
  9954. + struct au_hinode *hi;
  9955. + struct super_block *sb;
  9956. +
  9957. + if (unlinked) {
  9958. + int err = au_xigen_inc(inode);
  9959. + if (unlikely(err))
  9960. + AuWarn1("failed resetting i_generation, %d\n", err);
  9961. + }
  9962. +
  9963. + iinfo = au_ii(inode);
  9964. + /* bad_inode case */
  9965. + if (!iinfo)
  9966. + return;
  9967. +
  9968. + if (iinfo->ii_vdir)
  9969. + au_vdir_free(iinfo->ii_vdir);
  9970. +
  9971. + if (iinfo->ii_bstart >= 0) {
  9972. + sb = inode->i_sb;
  9973. + ino = 0;
  9974. + if (unlinked)
  9975. + ino = inode->i_ino;
  9976. + hi = iinfo->ii_hinode + iinfo->ii_bstart;
  9977. + bend = iinfo->ii_bend;
  9978. + while (iinfo->ii_bstart++ <= bend) {
  9979. + if (hi->hi_inode) {
  9980. + if (unlinked || !hi->hi_inode->i_nlink) {
  9981. + au_iinfo_write0(sb, hi, ino);
  9982. + /* ignore this error */
  9983. + ino = 0;
  9984. + }
  9985. + au_hiput(hi);
  9986. + }
  9987. + hi++;
  9988. + }
  9989. + }
  9990. +
  9991. + kfree(iinfo->ii_hinode);
  9992. + AuRwDestroy(&iinfo->ii_rwsem);
  9993. +}
  9994. diff -Nur linux-2.6.31.5.orig/fs/aufs/inode.c linux-2.6.31.5/fs/aufs/inode.c
  9995. --- linux-2.6.31.5.orig/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100
  9996. +++ linux-2.6.31.5/fs/aufs/inode.c 2009-11-15 22:02:37.000000000 +0100
  9997. @@ -0,0 +1,380 @@
  9998. +/*
  9999. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  10000. + *
  10001. + * This program, aufs is free software; you can redistribute it and/or modify
  10002. + * it under the terms of the GNU General Public License as published by
  10003. + * the Free Software Foundation; either version 2 of the License, or
  10004. + * (at your option) any later version.
  10005. + *
  10006. + * This program is distributed in the hope that it will be useful,
  10007. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10008. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10009. + * GNU General Public License for more details.
  10010. + *
  10011. + * You should have received a copy of the GNU General Public License
  10012. + * along with this program; if not, write to the Free Software
  10013. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  10014. + */
  10015. +
  10016. +/*
  10017. + * inode functions
  10018. + */
  10019. +
  10020. +#include "aufs.h"
  10021. +
  10022. +struct inode *au_igrab(struct inode *inode)
  10023. +{
  10024. + if (inode) {
  10025. + AuDebugOn(!atomic_read(&inode->i_count));
  10026. + atomic_inc_return(&inode->i_count);
  10027. + }
  10028. + return inode;
  10029. +}
  10030. +
  10031. +static void au_refresh_hinode_attr(struct inode *inode, int do_version)
  10032. +{
  10033. + au_cpup_attr_all(inode, /*force*/0);
  10034. + au_update_iigen(inode);
  10035. + if (do_version)
  10036. + inode->i_version++;
  10037. +}
  10038. +
  10039. +int au_refresh_hinode_self(struct inode *inode, int do_attr)
  10040. +{
  10041. + int err;
  10042. + aufs_bindex_t bindex, new_bindex;
  10043. + unsigned char update;
  10044. + struct inode *first;
  10045. + struct au_hinode *p, *q, tmp;
  10046. + struct super_block *sb;
  10047. + struct au_iinfo *iinfo;
  10048. +
  10049. + IiMustWriteLock(inode);
  10050. +
  10051. + update = 0;
  10052. + sb = inode->i_sb;
  10053. + iinfo = au_ii(inode);
  10054. + err = au_ii_realloc(iinfo, au_sbend(sb) + 1);
  10055. + if (unlikely(err))
  10056. + goto out;
  10057. +
  10058. + p = iinfo->ii_hinode + iinfo->ii_bstart;
  10059. + first = p->hi_inode;
  10060. + err = 0;
  10061. + for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
  10062. + bindex++, p++) {
  10063. + if (!p->hi_inode)
  10064. + continue;
  10065. +
  10066. + new_bindex = au_br_index(sb, p->hi_id);
  10067. + if (new_bindex == bindex)
  10068. + continue;
  10069. +
  10070. + if (new_bindex < 0) {
  10071. + update++;
  10072. + au_hiput(p);
  10073. + p->hi_inode = NULL;
  10074. + continue;
  10075. + }
  10076. +
  10077. + if (new_bindex < iinfo->ii_bstart)
  10078. + iinfo->ii_bstart = new_bindex;
  10079. + if (iinfo->ii_bend < new_bindex)
  10080. + iinfo->ii_bend = new_bindex;
  10081. + /* swap two lower inode, and loop again */
  10082. + q = iinfo->ii_hinode + new_bindex;
  10083. + tmp = *q;
  10084. + *q = *p;
  10085. + *p = tmp;
  10086. + if (tmp.hi_inode) {
  10087. + bindex--;
  10088. + p--;
  10089. + }
  10090. + }
  10091. + au_update_brange(inode, /*do_put_zero*/0);
  10092. + if (do_attr)
  10093. + au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
  10094. +
  10095. + out:
  10096. + return err;
  10097. +}
  10098. +
  10099. +int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
  10100. +{
  10101. + int err, update;
  10102. + unsigned int flags;
  10103. + aufs_bindex_t bindex, bend;
  10104. + unsigned char isdir;
  10105. + struct inode *first;
  10106. + struct au_hinode *p;
  10107. + struct au_iinfo *iinfo;
  10108. +
  10109. + err = au_refresh_hinode_self(inode, /*do_attr*/0);
  10110. + if (unlikely(err))
  10111. + goto out;
  10112. +
  10113. + update = 0;
  10114. + iinfo = au_ii(inode);
  10115. + p = iinfo->ii_hinode + iinfo->ii_bstart;
  10116. + first = p->hi_inode;
  10117. + isdir = S_ISDIR(inode->i_mode);
  10118. + flags = au_hi_flags(inode, isdir);
  10119. + bend = au_dbend(dentry);
  10120. + for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
  10121. + struct inode *h_i;
  10122. + struct dentry *h_d;
  10123. +
  10124. + h_d = au_h_dptr(dentry, bindex);
  10125. + if (!h_d || !h_d->d_inode)
  10126. + continue;
  10127. +
  10128. + if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) {
  10129. + h_i = au_h_iptr(inode, bindex);
  10130. + if (h_i) {
  10131. + if (h_i == h_d->d_inode)
  10132. + continue;
  10133. + err = -EIO;
  10134. + break;
  10135. + }
  10136. + }
  10137. + if (bindex < iinfo->ii_bstart)
  10138. + iinfo->ii_bstart = bindex;
  10139. + if (iinfo->ii_bend < bindex)
  10140. + iinfo->ii_bend = bindex;
  10141. + au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags);
  10142. + update = 1;
  10143. + }
  10144. + au_update_brange(inode, /*do_put_zero*/0);
  10145. +
  10146. + if (unlikely(err))
  10147. + goto out;
  10148. +
  10149. + au_refresh_hinode_attr(inode, update && isdir);
  10150. +
  10151. + out:
  10152. + return err;
  10153. +}
  10154. +
  10155. +static int set_inode(struct inode *inode, struct dentry *dentry)
  10156. +{
  10157. + int err;
  10158. + unsigned int flags;
  10159. + umode_t mode;
  10160. + aufs_bindex_t bindex, bstart, btail;
  10161. + unsigned char isdir;
  10162. + struct dentry *h_dentry;
  10163. + struct inode *h_inode;
  10164. + struct au_iinfo *iinfo;
  10165. +
  10166. + IiMustWriteLock(inode);
  10167. +
  10168. + err = 0;
  10169. + isdir = 0;
  10170. + bstart = au_dbstart(dentry);
  10171. + h_inode = au_h_dptr(dentry, bstart)->d_inode;
  10172. + mode = h_inode->i_mode;
  10173. + switch (mode & S_IFMT) {
  10174. + case S_IFREG:
  10175. + btail = au_dbtail(dentry);
  10176. + inode->i_op = &aufs_iop;
  10177. + inode->i_fop = &aufs_file_fop;
  10178. + inode->i_mapping->a_ops = &aufs_aop;
  10179. + break;
  10180. + case S_IFDIR:
  10181. + isdir = 1;
  10182. + btail = au_dbtaildir(dentry);
  10183. + inode->i_op = &aufs_dir_iop;
  10184. + inode->i_fop = &aufs_dir_fop;
  10185. + break;
  10186. + case S_IFLNK:
  10187. + btail = au_dbtail(dentry);
  10188. + inode->i_op = &aufs_symlink_iop;
  10189. + break;
  10190. + case S_IFBLK:
  10191. + case S_IFCHR:
  10192. + case S_IFIFO:
  10193. + case S_IFSOCK:
  10194. + btail = au_dbtail(dentry);
  10195. + inode->i_op = &aufs_iop;
  10196. + init_special_inode(inode, mode, h_inode->i_rdev);
  10197. + break;
  10198. + default:
  10199. + AuIOErr("Unknown file type 0%o\n", mode);
  10200. + err = -EIO;
  10201. + goto out;
  10202. + }
  10203. +
  10204. + /* do not set inotify for whiteouted dirs (SHWH mode) */
  10205. + flags = au_hi_flags(inode, isdir);
  10206. + if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
  10207. + && au_ftest_hi(flags, HINOTIFY)
  10208. + && dentry->d_name.len > AUFS_WH_PFX_LEN
  10209. + && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
  10210. + au_fclr_hi(flags, HINOTIFY);
  10211. + iinfo = au_ii(inode);
  10212. + iinfo->ii_bstart = bstart;
  10213. + iinfo->ii_bend = btail;
  10214. + for (bindex = bstart; bindex <= btail; bindex++) {
  10215. + h_dentry = au_h_dptr(dentry, bindex);
  10216. + if (h_dentry)
  10217. + au_set_h_iptr(inode, bindex,
  10218. + au_igrab(h_dentry->d_inode), flags);
  10219. + }
  10220. + au_cpup_attr_all(inode, /*force*/1);
  10221. +
  10222. + out:
  10223. + return err;
  10224. +}
  10225. +
  10226. +/* successful returns with iinfo write_locked */
  10227. +static int reval_inode(struct inode *inode, struct dentry *dentry, int *matched)
  10228. +{
  10229. + int err;
  10230. + aufs_bindex_t bindex, bend;
  10231. + struct inode *h_inode, *h_dinode;
  10232. +
  10233. + *matched = 0;
  10234. +
  10235. + /*
  10236. + * before this function, if aufs got any iinfo lock, it must be only
  10237. + * one, the parent dir.
  10238. + * it can happen by UDBA and the obsoleted inode number.
  10239. + */
  10240. + err = -EIO;
  10241. + if (unlikely(inode->i_ino == parent_ino(dentry)))
  10242. + goto out;
  10243. +
  10244. + err = 0;
  10245. + ii_write_lock_new_child(inode);
  10246. + h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode;
  10247. + bend = au_ibend(inode);
  10248. + for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
  10249. + h_inode = au_h_iptr(inode, bindex);
  10250. + if (h_inode && h_inode == h_dinode) {
  10251. + *matched = 1;
  10252. + err = 0;
  10253. + if (au_iigen(inode) != au_digen(dentry))
  10254. + err = au_refresh_hinode(inode, dentry);
  10255. + break;
  10256. + }
  10257. + }
  10258. +
  10259. + if (unlikely(err))
  10260. + ii_write_unlock(inode);
  10261. + out:
  10262. + return err;
  10263. +}
  10264. +
  10265. +/* successful returns with iinfo write_locked */
  10266. +/* todo: return with unlocked? */
  10267. +struct inode *au_new_inode(struct dentry *dentry, int must_new)
  10268. +{
  10269. + struct inode *inode;
  10270. + struct dentry *h_dentry;
  10271. + struct super_block *sb;
  10272. + ino_t h_ino, ino;
  10273. + int err, match;
  10274. + aufs_bindex_t bstart;
  10275. +
  10276. + sb = dentry->d_sb;
  10277. + bstart = au_dbstart(dentry);
  10278. + h_dentry = au_h_dptr(dentry, bstart);
  10279. + h_ino = h_dentry->d_inode->i_ino;
  10280. + err = au_xino_read(sb, bstart, h_ino, &ino);
  10281. + inode = ERR_PTR(err);
  10282. + if (unlikely(err))
  10283. + goto out;
  10284. + new_ino:
  10285. + if (!ino) {
  10286. + ino = au_xino_new_ino(sb);
  10287. + if (unlikely(!ino)) {
  10288. + inode = ERR_PTR(-EIO);
  10289. + goto out;
  10290. + }
  10291. + }
  10292. +
  10293. + AuDbg("i%lu\n", (unsigned long)ino);
  10294. + inode = au_iget_locked(sb, ino);
  10295. + err = PTR_ERR(inode);
  10296. + if (IS_ERR(inode))
  10297. + goto out;
  10298. +
  10299. + AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
  10300. + if (inode->i_state & I_NEW) {
  10301. + ii_write_lock_new_child(inode);
  10302. + err = set_inode(inode, dentry);
  10303. + unlock_new_inode(inode);
  10304. + if (!err)
  10305. + goto out; /* success */
  10306. +
  10307. + iget_failed(inode);
  10308. + ii_write_unlock(inode);
  10309. + goto out_iput;
  10310. + } else if (!must_new) {
  10311. + err = reval_inode(inode, dentry, &match);
  10312. + if (!err)
  10313. + goto out; /* success */
  10314. + else if (match)
  10315. + goto out_iput;
  10316. + }
  10317. +
  10318. + if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode)))
  10319. + AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
  10320. + " b%d, %s, %.*s, hi%lu, i%lu.\n",
  10321. + bstart, au_sbtype(h_dentry->d_sb), AuDLNPair(dentry),
  10322. + (unsigned long)h_ino, (unsigned long)ino);
  10323. + ino = 0;
  10324. + err = au_xino_write(sb, bstart, h_ino, /*ino*/0);
  10325. + if (!err) {
  10326. + iput(inode);
  10327. + goto new_ino;
  10328. + }
  10329. +
  10330. + out_iput:
  10331. + iput(inode);
  10332. + inode = ERR_PTR(err);
  10333. + out:
  10334. + return inode;
  10335. +}
  10336. +
  10337. +/* ---------------------------------------------------------------------- */
  10338. +
  10339. +int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
  10340. + struct inode *inode)
  10341. +{
  10342. + int err;
  10343. +
  10344. + err = au_br_rdonly(au_sbr(sb, bindex));
  10345. +
  10346. + /* pseudo-link after flushed may happen out of bounds */
  10347. + if (!err
  10348. + && inode
  10349. + && au_ibstart(inode) <= bindex
  10350. + && bindex <= au_ibend(inode)) {
  10351. + /*
  10352. + * permission check is unnecessary since vfsub routine
  10353. + * will be called later
  10354. + */
  10355. + struct inode *hi = au_h_iptr(inode, bindex);
  10356. + if (hi)
  10357. + err = IS_IMMUTABLE(hi) ? -EROFS : 0;
  10358. + }
  10359. +
  10360. + return err;
  10361. +}
  10362. +
  10363. +int au_test_h_perm(struct inode *h_inode, int mask)
  10364. +{
  10365. + if (!current_fsuid())
  10366. + return 0;
  10367. + return inode_permission(h_inode, mask);
  10368. +}
  10369. +
  10370. +int au_test_h_perm_sio(struct inode *h_inode, int mask)
  10371. +{
  10372. + if (au_test_nfs(h_inode->i_sb)
  10373. + && (mask & MAY_WRITE)
  10374. + && S_ISDIR(h_inode->i_mode))
  10375. + mask |= MAY_READ; /* force permission check */
  10376. + return au_test_h_perm(h_inode, mask);
  10377. +}
  10378. diff -Nur linux-2.6.31.5.orig/fs/aufs/inode.h linux-2.6.31.5/fs/aufs/inode.h
  10379. --- linux-2.6.31.5.orig/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
  10380. +++ linux-2.6.31.5/fs/aufs/inode.h 2009-11-15 22:02:37.000000000 +0100
  10381. @@ -0,0 +1,484 @@
  10382. +/*
  10383. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  10384. + *
  10385. + * This program, aufs is free software; you can redistribute it and/or modify
  10386. + * it under the terms of the GNU General Public License as published by
  10387. + * the Free Software Foundation; either version 2 of the License, or
  10388. + * (at your option) any later version.
  10389. + *
  10390. + * This program is distributed in the hope that it will be useful,
  10391. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10392. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10393. + * GNU General Public License for more details.
  10394. + *
  10395. + * You should have received a copy of the GNU General Public License
  10396. + * along with this program; if not, write to the Free Software
  10397. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  10398. + */
  10399. +
  10400. +/*
  10401. + * inode operations
  10402. + */
  10403. +
  10404. +#ifndef __AUFS_INODE_H__
  10405. +#define __AUFS_INODE_H__
  10406. +
  10407. +#ifdef __KERNEL__
  10408. +
  10409. +#include <linux/fs.h>
  10410. +#include <linux/inotify.h>
  10411. +#include <linux/aufs_type.h>
  10412. +#include "rwsem.h"
  10413. +
  10414. +struct vfsmount;
  10415. +
  10416. +struct au_hinotify {
  10417. +#ifdef CONFIG_AUFS_HINOTIFY
  10418. + struct inotify_watch hin_watch;
  10419. + struct inode *hin_aufs_inode; /* no get/put */
  10420. +#endif
  10421. +};
  10422. +
  10423. +struct au_hinode {
  10424. + struct inode *hi_inode;
  10425. + aufs_bindex_t hi_id;
  10426. +#ifdef CONFIG_AUFS_HINOTIFY
  10427. + struct au_hinotify *hi_notify;
  10428. +#endif
  10429. +
  10430. + /* reference to the copied-up whiteout with get/put */
  10431. + struct dentry *hi_whdentry;
  10432. +};
  10433. +
  10434. +struct au_vdir;
  10435. +struct au_iinfo {
  10436. + atomic_t ii_generation;
  10437. + struct super_block *ii_hsb1; /* no get/put */
  10438. +
  10439. + struct au_rwsem ii_rwsem;
  10440. + aufs_bindex_t ii_bstart, ii_bend;
  10441. + __u32 ii_higen;
  10442. + struct au_hinode *ii_hinode;
  10443. + struct au_vdir *ii_vdir;
  10444. +};
  10445. +
  10446. +struct au_icntnr {
  10447. + struct au_iinfo iinfo;
  10448. + struct inode vfs_inode;
  10449. +};
  10450. +
  10451. +/* au_pin flags */
  10452. +#define AuPin_DI_LOCKED 1
  10453. +#define AuPin_MNT_WRITE (1 << 1)
  10454. +#define au_ftest_pin(flags, name) ((flags) & AuPin_##name)
  10455. +#define au_fset_pin(flags, name) { (flags) |= AuPin_##name; }
  10456. +#define au_fclr_pin(flags, name) { (flags) &= ~AuPin_##name; }
  10457. +
  10458. +struct au_pin {
  10459. + /* input */
  10460. + struct dentry *dentry;
  10461. + unsigned int udba;
  10462. + unsigned char lsc_di, lsc_hi, flags;
  10463. + aufs_bindex_t bindex;
  10464. +
  10465. + /* output */
  10466. + struct dentry *parent;
  10467. + struct au_hinode *hdir;
  10468. + struct vfsmount *h_mnt;
  10469. +};
  10470. +
  10471. +/* ---------------------------------------------------------------------- */
  10472. +
  10473. +static inline struct au_iinfo *au_ii(struct inode *inode)
  10474. +{
  10475. + struct au_iinfo *iinfo;
  10476. +
  10477. + iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
  10478. + if (iinfo->ii_hinode)
  10479. + return iinfo;
  10480. + return NULL; /* debugging bad_inode case */
  10481. +}
  10482. +
  10483. +/* ---------------------------------------------------------------------- */
  10484. +
  10485. +/* inode.c */
  10486. +struct inode *au_igrab(struct inode *inode);
  10487. +int au_refresh_hinode_self(struct inode *inode, int do_attr);
  10488. +int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
  10489. +struct inode *au_new_inode(struct dentry *dentry, int must_new);
  10490. +int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
  10491. + struct inode *inode);
  10492. +int au_test_h_perm(struct inode *h_inode, int mask);
  10493. +int au_test_h_perm_sio(struct inode *h_inode, int mask);
  10494. +
  10495. +/* i_op.c */
  10496. +extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
  10497. +
  10498. +/* au_wr_dir flags */
  10499. +#define AuWrDir_ADD_ENTRY 1
  10500. +#define AuWrDir_ISDIR (1 << 1)
  10501. +#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
  10502. +#define au_fset_wrdir(flags, name) { (flags) |= AuWrDir_##name; }
  10503. +#define au_fclr_wrdir(flags, name) { (flags) &= ~AuWrDir_##name; }
  10504. +
  10505. +struct au_wr_dir_args {
  10506. + aufs_bindex_t force_btgt;
  10507. + unsigned char flags;
  10508. +};
  10509. +int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
  10510. + struct au_wr_dir_args *args);
  10511. +
  10512. +struct dentry *au_pinned_h_parent(struct au_pin *pin);
  10513. +void au_pin_init(struct au_pin *pin, struct dentry *dentry,
  10514. + aufs_bindex_t bindex, int lsc_di, int lsc_hi,
  10515. + unsigned int udba, unsigned char flags);
  10516. +int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
  10517. + unsigned int udba, unsigned char flags) __must_check;
  10518. +int au_do_pin(struct au_pin *pin) __must_check;
  10519. +void au_unpin(struct au_pin *pin);
  10520. +
  10521. +/* i_op_add.c */
  10522. +int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
  10523. + struct dentry *h_parent, int isdir);
  10524. +int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev);
  10525. +int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
  10526. +int aufs_create(struct inode *dir, struct dentry *dentry, int mode,
  10527. + struct nameidata *nd);
  10528. +int aufs_link(struct dentry *src_dentry, struct inode *dir,
  10529. + struct dentry *dentry);
  10530. +int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
  10531. +
  10532. +/* i_op_del.c */
  10533. +int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
  10534. +int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
  10535. + struct dentry *h_parent, int isdir);
  10536. +int aufs_unlink(struct inode *dir, struct dentry *dentry);
  10537. +int aufs_rmdir(struct inode *dir, struct dentry *dentry);
  10538. +
  10539. +/* i_op_ren.c */
  10540. +int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
  10541. +int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
  10542. + struct inode *dir, struct dentry *dentry);
  10543. +
  10544. +/* iinfo.c */
  10545. +struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
  10546. +void au_hiput(struct au_hinode *hinode);
  10547. +void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex);
  10548. +void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
  10549. + struct dentry *h_wh);
  10550. +unsigned int au_hi_flags(struct inode *inode, int isdir);
  10551. +
  10552. +/* hinode flags */
  10553. +#define AuHi_XINO 1
  10554. +#define AuHi_HINOTIFY (1 << 1)
  10555. +#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
  10556. +#define au_fset_hi(flags, name) { (flags) |= AuHi_##name; }
  10557. +#define au_fclr_hi(flags, name) { (flags) &= ~AuHi_##name; }
  10558. +
  10559. +#ifndef CONFIG_AUFS_HINOTIFY
  10560. +#undef AuHi_HINOTIFY
  10561. +#define AuHi_HINOTIFY 0
  10562. +#endif
  10563. +
  10564. +void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
  10565. + struct inode *h_inode, unsigned int flags);
  10566. +
  10567. +void au_update_iigen(struct inode *inode);
  10568. +void au_update_brange(struct inode *inode, int do_put_zero);
  10569. +
  10570. +int au_iinfo_init(struct inode *inode);
  10571. +void au_iinfo_fin(struct inode *inode);
  10572. +int au_ii_realloc(struct au_iinfo *iinfo, int nbr);
  10573. +
  10574. +/* plink.c */
  10575. +void au_plink_block_maintain(struct super_block *sb);
  10576. +#ifdef CONFIG_AUFS_DEBUG
  10577. +void au_plink_list(struct super_block *sb);
  10578. +#else
  10579. +static inline void au_plink_list(struct super_block *sb)
  10580. +{
  10581. + /* nothing */
  10582. +}
  10583. +#endif
  10584. +int au_plink_test(struct inode *inode);
  10585. +struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
  10586. +void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
  10587. + struct dentry *h_dentry);
  10588. +void au_plink_put(struct super_block *sb);
  10589. +void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
  10590. +
  10591. +/* ---------------------------------------------------------------------- */
  10592. +
  10593. +/* lock subclass for iinfo */
  10594. +enum {
  10595. + AuLsc_II_CHILD, /* child first */
  10596. + AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hinotify */
  10597. + AuLsc_II_CHILD3, /* copyup dirs */
  10598. + AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
  10599. + AuLsc_II_PARENT2,
  10600. + AuLsc_II_PARENT3, /* copyup dirs */
  10601. + AuLsc_II_NEW_CHILD
  10602. +};
  10603. +
  10604. +/*
  10605. + * ii_read_lock_child, ii_write_lock_child,
  10606. + * ii_read_lock_child2, ii_write_lock_child2,
  10607. + * ii_read_lock_child3, ii_write_lock_child3,
  10608. + * ii_read_lock_parent, ii_write_lock_parent,
  10609. + * ii_read_lock_parent2, ii_write_lock_parent2,
  10610. + * ii_read_lock_parent3, ii_write_lock_parent3,
  10611. + * ii_read_lock_new_child, ii_write_lock_new_child,
  10612. + */
  10613. +#define AuReadLockFunc(name, lsc) \
  10614. +static inline void ii_read_lock_##name(struct inode *i) \
  10615. +{ \
  10616. + au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
  10617. +}
  10618. +
  10619. +#define AuWriteLockFunc(name, lsc) \
  10620. +static inline void ii_write_lock_##name(struct inode *i) \
  10621. +{ \
  10622. + au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
  10623. +}
  10624. +
  10625. +#define AuRWLockFuncs(name, lsc) \
  10626. + AuReadLockFunc(name, lsc) \
  10627. + AuWriteLockFunc(name, lsc)
  10628. +
  10629. +AuRWLockFuncs(child, CHILD);
  10630. +AuRWLockFuncs(child2, CHILD2);
  10631. +AuRWLockFuncs(child3, CHILD3);
  10632. +AuRWLockFuncs(parent, PARENT);
  10633. +AuRWLockFuncs(parent2, PARENT2);
  10634. +AuRWLockFuncs(parent3, PARENT3);
  10635. +AuRWLockFuncs(new_child, NEW_CHILD);
  10636. +
  10637. +#undef AuReadLockFunc
  10638. +#undef AuWriteLockFunc
  10639. +#undef AuRWLockFuncs
  10640. +
  10641. +/*
  10642. + * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
  10643. + */
  10644. +AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
  10645. +
  10646. +#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
  10647. +#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
  10648. +#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
  10649. +
  10650. +/* ---------------------------------------------------------------------- */
  10651. +
  10652. +static inline unsigned int au_iigen(struct inode *inode)
  10653. +{
  10654. + return atomic_read(&au_ii(inode)->ii_generation);
  10655. +}
  10656. +
  10657. +/* tiny test for inode number */
  10658. +/* tmpfs generation is too rough */
  10659. +static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
  10660. +{
  10661. + struct au_iinfo *iinfo;
  10662. +
  10663. + iinfo = au_ii(inode);
  10664. + AuRwMustAnyLock(&iinfo->ii_rwsem);
  10665. + return !(iinfo->ii_hsb1 == h_inode->i_sb
  10666. + && iinfo->ii_higen == h_inode->i_generation);
  10667. +}
  10668. +
  10669. +/* ---------------------------------------------------------------------- */
  10670. +
  10671. +static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
  10672. + aufs_bindex_t bindex)
  10673. +{
  10674. + IiMustAnyLock(inode);
  10675. + return au_ii(inode)->ii_hinode[0 + bindex].hi_id;
  10676. +}
  10677. +
  10678. +static inline aufs_bindex_t au_ibstart(struct inode *inode)
  10679. +{
  10680. + IiMustAnyLock(inode);
  10681. + return au_ii(inode)->ii_bstart;
  10682. +}
  10683. +
  10684. +static inline aufs_bindex_t au_ibend(struct inode *inode)
  10685. +{
  10686. + IiMustAnyLock(inode);
  10687. + return au_ii(inode)->ii_bend;
  10688. +}
  10689. +
  10690. +static inline struct au_vdir *au_ivdir(struct inode *inode)
  10691. +{
  10692. + IiMustAnyLock(inode);
  10693. + return au_ii(inode)->ii_vdir;
  10694. +}
  10695. +
  10696. +static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
  10697. +{
  10698. + IiMustAnyLock(inode);
  10699. + return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry;
  10700. +}
  10701. +
  10702. +static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex)
  10703. +{
  10704. + IiMustWriteLock(inode);
  10705. + au_ii(inode)->ii_bend = bindex;
  10706. +}
  10707. +
  10708. +static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
  10709. +{
  10710. + IiMustWriteLock(inode);
  10711. + au_ii(inode)->ii_vdir = vdir;
  10712. +}
  10713. +
  10714. +static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
  10715. +{
  10716. + IiMustAnyLock(inode);
  10717. + return au_ii(inode)->ii_hinode + bindex;
  10718. +}
  10719. +
  10720. +/* ---------------------------------------------------------------------- */
  10721. +
  10722. +static inline struct dentry *au_pinned_parent(struct au_pin *pin)
  10723. +{
  10724. + if (pin)
  10725. + return pin->parent;
  10726. + return NULL;
  10727. +}
  10728. +
  10729. +static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
  10730. +{
  10731. + if (pin && pin->hdir)
  10732. + return pin->hdir->hi_inode;
  10733. + return NULL;
  10734. +}
  10735. +
  10736. +static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
  10737. +{
  10738. + if (pin)
  10739. + return pin->hdir;
  10740. + return NULL;
  10741. +}
  10742. +
  10743. +static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
  10744. +{
  10745. + if (pin)
  10746. + pin->dentry = dentry;
  10747. +}
  10748. +
  10749. +static inline void au_pin_set_parent_lflag(struct au_pin *pin,
  10750. + unsigned char lflag)
  10751. +{
  10752. + if (pin) {
  10753. + /* dirty macros require brackets */
  10754. + if (lflag) {
  10755. + au_fset_pin(pin->flags, DI_LOCKED);
  10756. + } else {
  10757. + au_fclr_pin(pin->flags, DI_LOCKED);
  10758. + }
  10759. + }
  10760. +}
  10761. +
  10762. +static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
  10763. +{
  10764. + if (pin) {
  10765. + dput(pin->parent);
  10766. + pin->parent = dget(parent);
  10767. + }
  10768. +}
  10769. +
  10770. +/* ---------------------------------------------------------------------- */
  10771. +
  10772. +#ifdef CONFIG_AUFS_HINOTIFY
  10773. +/* hinotify.c */
  10774. +int au_hin_alloc(struct au_hinode *hinode, struct inode *inode,
  10775. + struct inode *h_inode);
  10776. +void au_hin_free(struct au_hinode *hinode);
  10777. +void au_hin_ctl(struct au_hinode *hinode, int do_set);
  10778. +void au_reset_hinotify(struct inode *inode, unsigned int flags);
  10779. +
  10780. +int __init au_hinotify_init(void);
  10781. +void au_hinotify_fin(void);
  10782. +
  10783. +static inline
  10784. +void au_hin_init(struct au_hinode *hinode, struct au_hinotify *val)
  10785. +{
  10786. + hinode->hi_notify = val;
  10787. +}
  10788. +
  10789. +static inline void au_iigen_dec(struct inode *inode)
  10790. +{
  10791. + atomic_dec_return(&au_ii(inode)->ii_generation);
  10792. +}
  10793. +
  10794. +#else
  10795. +static inline
  10796. +int au_hin_alloc(struct au_hinode *hinode __maybe_unused,
  10797. + struct inode *inode __maybe_unused,
  10798. + struct inode *h_inode __maybe_unused)
  10799. +{
  10800. + return -EOPNOTSUPP;
  10801. +}
  10802. +
  10803. +static inline void au_hin_free(struct au_hinode *hinode __maybe_unused)
  10804. +{
  10805. + /* nothing */
  10806. +}
  10807. +
  10808. +static inline void au_hin_ctl(struct au_hinode *hinode __maybe_unused,
  10809. + int do_set __maybe_unused)
  10810. +{
  10811. + /* nothing */
  10812. +}
  10813. +
  10814. +static inline void au_reset_hinotify(struct inode *inode __maybe_unused,
  10815. + unsigned int flags __maybe_unused)
  10816. +{
  10817. + /* nothing */
  10818. +}
  10819. +
  10820. +static inline int au_hinotify_init(void)
  10821. +{
  10822. + return 0;
  10823. +}
  10824. +
  10825. +#define au_hinotify_fin() do {} while (0)
  10826. +
  10827. +static inline
  10828. +void au_hin_init(struct au_hinode *hinode __maybe_unused,
  10829. + struct au_hinotify *val __maybe_unused)
  10830. +{
  10831. + /* empty */
  10832. +}
  10833. +#endif /* CONFIG_AUFS_HINOTIFY */
  10834. +
  10835. +static inline void au_hin_suspend(struct au_hinode *hdir)
  10836. +{
  10837. + au_hin_ctl(hdir, /*do_set*/0);
  10838. +}
  10839. +
  10840. +static inline void au_hin_resume(struct au_hinode *hdir)
  10841. +{
  10842. + au_hin_ctl(hdir, /*do_set*/1);
  10843. +}
  10844. +
  10845. +static inline void au_hin_imtx_lock(struct au_hinode *hdir)
  10846. +{
  10847. + mutex_lock(&hdir->hi_inode->i_mutex);
  10848. + au_hin_suspend(hdir);
  10849. +}
  10850. +
  10851. +static inline void au_hin_imtx_lock_nested(struct au_hinode *hdir,
  10852. + unsigned int sc __maybe_unused)
  10853. +{
  10854. + mutex_lock_nested(&hdir->hi_inode->i_mutex, sc);
  10855. + au_hin_suspend(hdir);
  10856. +}
  10857. +
  10858. +static inline void au_hin_imtx_unlock(struct au_hinode *hdir)
  10859. +{
  10860. + au_hin_resume(hdir);
  10861. + mutex_unlock(&hdir->hi_inode->i_mutex);
  10862. +}
  10863. +
  10864. +#endif /* __KERNEL__ */
  10865. +#endif /* __AUFS_INODE_H__ */
  10866. diff -Nur linux-2.6.31.5.orig/fs/aufs/ioctl.c linux-2.6.31.5/fs/aufs/ioctl.c
  10867. --- linux-2.6.31.5.orig/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100
  10868. +++ linux-2.6.31.5/fs/aufs/ioctl.c 2009-11-15 22:02:37.000000000 +0100
  10869. @@ -0,0 +1,67 @@
  10870. +/*
  10871. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  10872. + *
  10873. + * This program, aufs is free software; you can redistribute it and/or modify
  10874. + * it under the terms of the GNU General Public License as published by
  10875. + * the Free Software Foundation; either version 2 of the License, or
  10876. + * (at your option) any later version.
  10877. + *
  10878. + * This program is distributed in the hope that it will be useful,
  10879. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10880. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10881. + * GNU General Public License for more details.
  10882. + *
  10883. + * You should have received a copy of the GNU General Public License
  10884. + * along with this program; if not, write to the Free Software
  10885. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  10886. + */
  10887. +
  10888. +/*
  10889. + * ioctl
  10890. + * currently plink-management only.
  10891. + */
  10892. +
  10893. +#include <linux/uaccess.h>
  10894. +#include "aufs.h"
  10895. +
  10896. +long aufs_ioctl_dir(struct file *file, unsigned int cmd,
  10897. + unsigned long arg __maybe_unused)
  10898. +{
  10899. + long err;
  10900. + struct super_block *sb;
  10901. + struct au_sbinfo *sbinfo;
  10902. +
  10903. + err = -EACCES;
  10904. + if (!capable(CAP_SYS_ADMIN))
  10905. + goto out;
  10906. +
  10907. + err = 0;
  10908. + sb = file->f_dentry->d_sb;
  10909. + sbinfo = au_sbi(sb);
  10910. + switch (cmd) {
  10911. + case AUFS_CTL_PLINK_MAINT:
  10912. + /*
  10913. + * pseudo-link maintenance mode,
  10914. + * cleared by aufs_release_dir()
  10915. + */
  10916. + si_write_lock(sb);
  10917. + if (!au_ftest_si(sbinfo, MAINTAIN_PLINK)) {
  10918. + au_fset_si(sbinfo, MAINTAIN_PLINK);
  10919. + au_fi(file)->fi_maintain_plink = 1;
  10920. + } else
  10921. + err = -EBUSY;
  10922. + si_write_unlock(sb);
  10923. + break;
  10924. + case AUFS_CTL_PLINK_CLEAN:
  10925. + aufs_write_lock(sb->s_root);
  10926. + if (au_opt_test(sbinfo->si_mntflags, PLINK))
  10927. + au_plink_put(sb);
  10928. + aufs_write_unlock(sb->s_root);
  10929. + break;
  10930. + default:
  10931. + err = -EINVAL;
  10932. + }
  10933. +
  10934. + out:
  10935. + return err;
  10936. +}
  10937. diff -Nur linux-2.6.31.5.orig/fs/aufs/i_op_add.c linux-2.6.31.5/fs/aufs/i_op_add.c
  10938. --- linux-2.6.31.5.orig/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
  10939. +++ linux-2.6.31.5/fs/aufs/i_op_add.c 2009-11-15 22:02:37.000000000 +0100
  10940. @@ -0,0 +1,649 @@
  10941. +/*
  10942. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  10943. + *
  10944. + * This program, aufs is free software; you can redistribute it and/or modify
  10945. + * it under the terms of the GNU General Public License as published by
  10946. + * the Free Software Foundation; either version 2 of the License, or
  10947. + * (at your option) any later version.
  10948. + *
  10949. + * This program is distributed in the hope that it will be useful,
  10950. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10951. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10952. + * GNU General Public License for more details.
  10953. + *
  10954. + * You should have received a copy of the GNU General Public License
  10955. + * along with this program; if not, write to the Free Software
  10956. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  10957. + */
  10958. +
  10959. +/*
  10960. + * inode operations (add entry)
  10961. + */
  10962. +
  10963. +#include "aufs.h"
  10964. +
  10965. +/*
  10966. + * final procedure of adding a new entry, except link(2).
  10967. + * remove whiteout, instantiate, copyup the parent dir's times and size
  10968. + * and update version.
  10969. + * if it failed, re-create the removed whiteout.
  10970. + */
  10971. +static int epilog(struct inode *dir, aufs_bindex_t bindex,
  10972. + struct dentry *wh_dentry, struct dentry *dentry)
  10973. +{
  10974. + int err, rerr;
  10975. + aufs_bindex_t bwh;
  10976. + struct path h_path;
  10977. + struct inode *inode, *h_dir;
  10978. + struct dentry *wh;
  10979. +
  10980. + bwh = -1;
  10981. + if (wh_dentry) {
  10982. + h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
  10983. + IMustLock(h_dir);
  10984. + AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
  10985. + bwh = au_dbwh(dentry);
  10986. + h_path.dentry = wh_dentry;
  10987. + h_path.mnt = au_sbr_mnt(dir->i_sb, bindex);
  10988. + err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
  10989. + dentry);
  10990. + if (unlikely(err))
  10991. + goto out;
  10992. + }
  10993. +
  10994. + inode = au_new_inode(dentry, /*must_new*/1);
  10995. + if (!IS_ERR(inode)) {
  10996. + d_instantiate(dentry, inode);
  10997. + dir = dentry->d_parent->d_inode; /* dir inode is locked */
  10998. + IMustLock(dir);
  10999. + if (au_ibstart(dir) == au_dbstart(dentry))
  11000. + au_cpup_attr_timesizes(dir);
  11001. + dir->i_version++;
  11002. + return 0; /* success */
  11003. + }
  11004. +
  11005. + err = PTR_ERR(inode);
  11006. + if (!wh_dentry)
  11007. + goto out;
  11008. +
  11009. + /* revert */
  11010. + /* dir inode is locked */
  11011. + wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
  11012. + rerr = PTR_ERR(wh);
  11013. + if (IS_ERR(wh)) {
  11014. + AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
  11015. + AuDLNPair(dentry), err, rerr);
  11016. + err = -EIO;
  11017. + } else
  11018. + dput(wh);
  11019. +
  11020. + out:
  11021. + return err;
  11022. +}
  11023. +
  11024. +/*
  11025. + * simple tests for the adding inode operations.
  11026. + * following the checks in vfs, plus the parent-child relationship.
  11027. + */
  11028. +int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
  11029. + struct dentry *h_parent, int isdir)
  11030. +{
  11031. + int err;
  11032. + umode_t h_mode;
  11033. + struct dentry *h_dentry;
  11034. + struct inode *h_inode;
  11035. +
  11036. + h_dentry = au_h_dptr(dentry, bindex);
  11037. + h_inode = h_dentry->d_inode;
  11038. + if (!dentry->d_inode) {
  11039. + err = -EEXIST;
  11040. + if (unlikely(h_inode))
  11041. + goto out;
  11042. + } else {
  11043. + /* rename(2) case */
  11044. + err = -EIO;
  11045. + if (unlikely(!h_inode || !h_inode->i_nlink))
  11046. + goto out;
  11047. +
  11048. + h_mode = h_inode->i_mode;
  11049. + if (!isdir) {
  11050. + err = -EISDIR;
  11051. + if (unlikely(S_ISDIR(h_mode)))
  11052. + goto out;
  11053. + } else if (unlikely(!S_ISDIR(h_mode))) {
  11054. + err = -ENOTDIR;
  11055. + goto out;
  11056. + }
  11057. + }
  11058. +
  11059. + err = -EIO;
  11060. + /* expected parent dir is locked */
  11061. + if (unlikely(h_parent != h_dentry->d_parent))
  11062. + goto out;
  11063. + err = 0;
  11064. +
  11065. + out:
  11066. + return err;
  11067. +}
  11068. +
  11069. +/*
  11070. + * initial procedure of adding a new entry.
  11071. + * prepare writable branch and the parent dir, lock it,
  11072. + * and lookup whiteout for the new entry.
  11073. + */
  11074. +static struct dentry*
  11075. +lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
  11076. + struct dentry *src_dentry, struct au_pin *pin,
  11077. + struct au_wr_dir_args *wr_dir_args)
  11078. +{
  11079. + struct dentry *wh_dentry, *h_parent;
  11080. + struct super_block *sb;
  11081. + struct au_branch *br;
  11082. + int err;
  11083. + unsigned int udba;
  11084. + aufs_bindex_t bcpup;
  11085. +
  11086. + err = au_wr_dir(dentry, src_dentry, wr_dir_args);
  11087. + bcpup = err;
  11088. + wh_dentry = ERR_PTR(err);
  11089. + if (unlikely(err < 0))
  11090. + goto out;
  11091. +
  11092. + sb = dentry->d_sb;
  11093. + udba = au_opt_udba(sb);
  11094. + err = au_pin(pin, dentry, bcpup, udba,
  11095. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  11096. + wh_dentry = ERR_PTR(err);
  11097. + if (unlikely(err))
  11098. + goto out;
  11099. +
  11100. + h_parent = au_pinned_h_parent(pin);
  11101. + if (udba != AuOpt_UDBA_NONE
  11102. + && au_dbstart(dentry) == bcpup) {
  11103. + err = au_may_add(dentry, bcpup, h_parent,
  11104. + au_ftest_wrdir(wr_dir_args->flags, ISDIR));
  11105. + wh_dentry = ERR_PTR(err);
  11106. + if (unlikely(err))
  11107. + goto out_unpin;
  11108. + }
  11109. +
  11110. + br = au_sbr(sb, bcpup);
  11111. + if (dt) {
  11112. + struct path tmp = {
  11113. + .dentry = h_parent,
  11114. + .mnt = br->br_mnt
  11115. + };
  11116. + au_dtime_store(dt, au_pinned_parent(pin), &tmp);
  11117. + }
  11118. +
  11119. + wh_dentry = NULL;
  11120. + if (bcpup != au_dbwh(dentry))
  11121. + goto out; /* success */
  11122. +
  11123. + wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
  11124. +
  11125. + out_unpin:
  11126. + if (IS_ERR(wh_dentry))
  11127. + au_unpin(pin);
  11128. + out:
  11129. + return wh_dentry;
  11130. +}
  11131. +
  11132. +/* ---------------------------------------------------------------------- */
  11133. +
  11134. +enum { Mknod, Symlink, Creat };
  11135. +struct simple_arg {
  11136. + int type;
  11137. + union {
  11138. + struct {
  11139. + int mode;
  11140. + struct nameidata *nd;
  11141. + } c;
  11142. + struct {
  11143. + const char *symname;
  11144. + } s;
  11145. + struct {
  11146. + int mode;
  11147. + dev_t dev;
  11148. + } m;
  11149. + } u;
  11150. +};
  11151. +
  11152. +static int add_simple(struct inode *dir, struct dentry *dentry,
  11153. + struct simple_arg *arg)
  11154. +{
  11155. + int err;
  11156. + aufs_bindex_t bstart;
  11157. + unsigned char created;
  11158. + struct au_dtime dt;
  11159. + struct au_pin pin;
  11160. + struct path h_path;
  11161. + struct dentry *wh_dentry, *parent;
  11162. + struct inode *h_dir;
  11163. + struct au_wr_dir_args wr_dir_args = {
  11164. + .force_btgt = -1,
  11165. + .flags = AuWrDir_ADD_ENTRY
  11166. + };
  11167. +
  11168. + IMustLock(dir);
  11169. +
  11170. + parent = dentry->d_parent; /* dir inode is locked */
  11171. + aufs_read_lock(dentry, AuLock_DW);
  11172. + di_write_lock_parent(parent);
  11173. + wh_dentry = lock_hdir_lkup_wh(dentry, &dt, /*src_dentry*/NULL, &pin,
  11174. + &wr_dir_args);
  11175. + err = PTR_ERR(wh_dentry);
  11176. + if (IS_ERR(wh_dentry))
  11177. + goto out;
  11178. +
  11179. + bstart = au_dbstart(dentry);
  11180. + h_path.dentry = au_h_dptr(dentry, bstart);
  11181. + h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
  11182. + h_dir = au_pinned_h_dir(&pin);
  11183. + switch (arg->type) {
  11184. + case Creat:
  11185. + err = vfsub_create(h_dir, &h_path, arg->u.c.mode);
  11186. + break;
  11187. + case Symlink:
  11188. + err = vfsub_symlink(h_dir, &h_path, arg->u.s.symname);
  11189. + break;
  11190. + case Mknod:
  11191. + err = vfsub_mknod(h_dir, &h_path, arg->u.m.mode, arg->u.m.dev);
  11192. + break;
  11193. + default:
  11194. + BUG();
  11195. + }
  11196. + created = !err;
  11197. + if (!err)
  11198. + err = epilog(dir, bstart, wh_dentry, dentry);
  11199. +
  11200. + /* revert */
  11201. + if (unlikely(created && err && h_path.dentry->d_inode)) {
  11202. + int rerr;
  11203. + rerr = vfsub_unlink(h_dir, &h_path, /*force*/0);
  11204. + if (rerr) {
  11205. + AuIOErr("%.*s revert failure(%d, %d)\n",
  11206. + AuDLNPair(dentry), err, rerr);
  11207. + err = -EIO;
  11208. + }
  11209. + au_dtime_revert(&dt);
  11210. + d_drop(dentry);
  11211. + }
  11212. +
  11213. + au_unpin(&pin);
  11214. + dput(wh_dentry);
  11215. +
  11216. + out:
  11217. + if (unlikely(err)) {
  11218. + au_update_dbstart(dentry);
  11219. + d_drop(dentry);
  11220. + }
  11221. + di_write_unlock(parent);
  11222. + aufs_read_unlock(dentry, AuLock_DW);
  11223. + return err;
  11224. +}
  11225. +
  11226. +int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
  11227. +{
  11228. + struct simple_arg arg = {
  11229. + .type = Mknod,
  11230. + .u.m = {
  11231. + .mode = mode,
  11232. + .dev = dev
  11233. + }
  11234. + };
  11235. + return add_simple(dir, dentry, &arg);
  11236. +}
  11237. +
  11238. +int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
  11239. +{
  11240. + struct simple_arg arg = {
  11241. + .type = Symlink,
  11242. + .u.s.symname = symname
  11243. + };
  11244. + return add_simple(dir, dentry, &arg);
  11245. +}
  11246. +
  11247. +int aufs_create(struct inode *dir, struct dentry *dentry, int mode,
  11248. + struct nameidata *nd)
  11249. +{
  11250. + struct simple_arg arg = {
  11251. + .type = Creat,
  11252. + .u.c = {
  11253. + .mode = mode,
  11254. + .nd = nd
  11255. + }
  11256. + };
  11257. + return add_simple(dir, dentry, &arg);
  11258. +}
  11259. +
  11260. +/* ---------------------------------------------------------------------- */
  11261. +
  11262. +struct au_link_args {
  11263. + aufs_bindex_t bdst, bsrc;
  11264. + struct au_pin pin;
  11265. + struct path h_path;
  11266. + struct dentry *src_parent, *parent;
  11267. +};
  11268. +
  11269. +static int au_cpup_before_link(struct dentry *src_dentry,
  11270. + struct au_link_args *a)
  11271. +{
  11272. + int err;
  11273. + struct dentry *h_src_dentry;
  11274. + struct mutex *h_mtx;
  11275. +
  11276. + di_read_lock_parent(a->src_parent, AuLock_IR);
  11277. + err = au_test_and_cpup_dirs(src_dentry, a->bdst);
  11278. + if (unlikely(err))
  11279. + goto out;
  11280. +
  11281. + h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
  11282. + h_mtx = &h_src_dentry->d_inode->i_mutex;
  11283. + err = au_pin(&a->pin, src_dentry, a->bdst,
  11284. + au_opt_udba(src_dentry->d_sb),
  11285. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  11286. + if (unlikely(err))
  11287. + goto out;
  11288. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  11289. + err = au_sio_cpup_simple(src_dentry, a->bdst, -1,
  11290. + AuCpup_DTIME /* | AuCpup_KEEPLINO */);
  11291. + mutex_unlock(h_mtx);
  11292. + au_unpin(&a->pin);
  11293. +
  11294. + out:
  11295. + di_read_unlock(a->src_parent, AuLock_IR);
  11296. + return err;
  11297. +}
  11298. +
  11299. +static int au_cpup_or_link(struct dentry *src_dentry, struct au_link_args *a)
  11300. +{
  11301. + int err;
  11302. + unsigned char plink;
  11303. + struct inode *h_inode, *inode;
  11304. + struct dentry *h_src_dentry;
  11305. + struct super_block *sb;
  11306. +
  11307. + plink = 0;
  11308. + h_inode = NULL;
  11309. + sb = src_dentry->d_sb;
  11310. + inode = src_dentry->d_inode;
  11311. + if (au_ibstart(inode) <= a->bdst)
  11312. + h_inode = au_h_iptr(inode, a->bdst);
  11313. + if (!h_inode || !h_inode->i_nlink) {
  11314. + /* copyup src_dentry as the name of dentry. */
  11315. + au_set_dbstart(src_dentry, a->bdst);
  11316. + au_set_h_dptr(src_dentry, a->bdst, dget(a->h_path.dentry));
  11317. + h_inode = au_h_dptr(src_dentry, a->bsrc)->d_inode;
  11318. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  11319. + err = au_sio_cpup_single(src_dentry, a->bdst, a->bsrc, -1,
  11320. + AuCpup_KEEPLINO, a->parent);
  11321. + mutex_unlock(&h_inode->i_mutex);
  11322. + au_set_h_dptr(src_dentry, a->bdst, NULL);
  11323. + au_set_dbstart(src_dentry, a->bsrc);
  11324. + } else {
  11325. + /* the inode of src_dentry already exists on a.bdst branch */
  11326. + h_src_dentry = d_find_alias(h_inode);
  11327. + if (!h_src_dentry && au_plink_test(inode)) {
  11328. + plink = 1;
  11329. + h_src_dentry = au_plink_lkup(inode, a->bdst);
  11330. + err = PTR_ERR(h_src_dentry);
  11331. + if (IS_ERR(h_src_dentry))
  11332. + goto out;
  11333. +
  11334. + if (unlikely(!h_src_dentry->d_inode)) {
  11335. + dput(h_src_dentry);
  11336. + h_src_dentry = NULL;
  11337. + }
  11338. +
  11339. + }
  11340. + if (h_src_dentry) {
  11341. + err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
  11342. + &a->h_path);
  11343. + dput(h_src_dentry);
  11344. + } else {
  11345. + AuIOErr("no dentry found for hi%lu on b%d\n",
  11346. + h_inode->i_ino, a->bdst);
  11347. + err = -EIO;
  11348. + }
  11349. + }
  11350. +
  11351. + if (!err && !plink)
  11352. + au_plink_append(inode, a->bdst, a->h_path.dentry);
  11353. +
  11354. +out:
  11355. + return err;
  11356. +}
  11357. +
  11358. +int aufs_link(struct dentry *src_dentry, struct inode *dir,
  11359. + struct dentry *dentry)
  11360. +{
  11361. + int err, rerr;
  11362. + struct au_dtime dt;
  11363. + struct au_link_args *a;
  11364. + struct dentry *wh_dentry, *h_src_dentry;
  11365. + struct inode *inode;
  11366. + struct super_block *sb;
  11367. + struct au_wr_dir_args wr_dir_args = {
  11368. + /* .force_btgt = -1, */
  11369. + .flags = AuWrDir_ADD_ENTRY
  11370. + };
  11371. +
  11372. + IMustLock(dir);
  11373. + inode = src_dentry->d_inode;
  11374. + IMustLock(inode);
  11375. +
  11376. + err = -ENOENT;
  11377. + if (unlikely(!inode->i_nlink))
  11378. + goto out;
  11379. +
  11380. + err = -ENOMEM;
  11381. + a = kzalloc(sizeof(*a), GFP_NOFS);
  11382. + if (unlikely(!a))
  11383. + goto out;
  11384. +
  11385. + a->parent = dentry->d_parent; /* dir inode is locked */
  11386. + aufs_read_and_write_lock2(dentry, src_dentry, /*AuLock_FLUSH*/0);
  11387. + a->src_parent = dget_parent(src_dentry);
  11388. + wr_dir_args.force_btgt = au_dbstart(src_dentry);
  11389. +
  11390. + di_write_lock_parent(a->parent);
  11391. + wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
  11392. + wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
  11393. + &wr_dir_args);
  11394. + err = PTR_ERR(wh_dentry);
  11395. + if (IS_ERR(wh_dentry))
  11396. + goto out_unlock;
  11397. +
  11398. + err = 0;
  11399. + sb = dentry->d_sb;
  11400. + a->bdst = au_dbstart(dentry);
  11401. + a->h_path.dentry = au_h_dptr(dentry, a->bdst);
  11402. + a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
  11403. + a->bsrc = au_dbstart(src_dentry);
  11404. + if (au_opt_test(au_mntflags(sb), PLINK)) {
  11405. + if (a->bdst < a->bsrc
  11406. + /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
  11407. + err = au_cpup_or_link(src_dentry, a);
  11408. + else {
  11409. + h_src_dentry = au_h_dptr(src_dentry, a->bdst);
  11410. + err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
  11411. + &a->h_path);
  11412. + }
  11413. + } else {
  11414. + /*
  11415. + * copyup src_dentry to the branch we process,
  11416. + * and then link(2) to it.
  11417. + */
  11418. + if (a->bdst < a->bsrc
  11419. + /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
  11420. + au_unpin(&a->pin);
  11421. + di_write_unlock(a->parent);
  11422. + err = au_cpup_before_link(src_dentry, a);
  11423. + di_write_lock_parent(a->parent);
  11424. + if (!err)
  11425. + err = au_pin(&a->pin, dentry, a->bdst,
  11426. + au_opt_udba(sb),
  11427. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  11428. + if (unlikely(err))
  11429. + goto out_wh;
  11430. + }
  11431. + if (!err) {
  11432. + h_src_dentry = au_h_dptr(src_dentry, a->bdst);
  11433. + err = -ENOENT;
  11434. + if (h_src_dentry && h_src_dentry->d_inode)
  11435. + err = vfsub_link(h_src_dentry,
  11436. + au_pinned_h_dir(&a->pin),
  11437. + &a->h_path);
  11438. + }
  11439. + }
  11440. + if (unlikely(err))
  11441. + goto out_unpin;
  11442. +
  11443. + if (wh_dentry) {
  11444. + a->h_path.dentry = wh_dentry;
  11445. + err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
  11446. + dentry);
  11447. + if (unlikely(err))
  11448. + goto out_revert;
  11449. + }
  11450. +
  11451. + dir->i_version++;
  11452. + if (au_ibstart(dir) == au_dbstart(dentry))
  11453. + au_cpup_attr_timesizes(dir);
  11454. + inc_nlink(inode);
  11455. + inode->i_ctime = dir->i_ctime;
  11456. + if (!d_unhashed(a->h_path.dentry))
  11457. + d_instantiate(dentry, au_igrab(inode));
  11458. + else
  11459. + /* some filesystem calls d_drop() */
  11460. + d_drop(dentry);
  11461. + goto out_unpin; /* success */
  11462. +
  11463. + out_revert:
  11464. + rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path, /*force*/0);
  11465. + if (!rerr)
  11466. + goto out_dt;
  11467. + AuIOErr("%.*s reverting failed(%d, %d)\n",
  11468. + AuDLNPair(dentry), err, rerr);
  11469. + err = -EIO;
  11470. + out_dt:
  11471. + d_drop(dentry);
  11472. + au_dtime_revert(&dt);
  11473. + out_unpin:
  11474. + au_unpin(&a->pin);
  11475. + out_wh:
  11476. + dput(wh_dentry);
  11477. + out_unlock:
  11478. + if (unlikely(err)) {
  11479. + au_update_dbstart(dentry);
  11480. + d_drop(dentry);
  11481. + }
  11482. + di_write_unlock(a->parent);
  11483. + dput(a->src_parent);
  11484. + aufs_read_and_write_unlock2(dentry, src_dentry);
  11485. + kfree(a);
  11486. + out:
  11487. + return err;
  11488. +}
  11489. +
  11490. +int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
  11491. +{
  11492. + int err, rerr;
  11493. + aufs_bindex_t bindex;
  11494. + unsigned char diropq;
  11495. + struct path h_path;
  11496. + struct dentry *wh_dentry, *parent, *opq_dentry;
  11497. + struct mutex *h_mtx;
  11498. + struct super_block *sb;
  11499. + struct {
  11500. + struct au_pin pin;
  11501. + struct au_dtime dt;
  11502. + } *a; /* reduce the stack usage */
  11503. + struct au_wr_dir_args wr_dir_args = {
  11504. + .force_btgt = -1,
  11505. + .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
  11506. + };
  11507. +
  11508. + IMustLock(dir);
  11509. +
  11510. + err = -ENOMEM;
  11511. + a = kmalloc(sizeof(*a), GFP_NOFS);
  11512. + if (unlikely(!a))
  11513. + goto out;
  11514. +
  11515. + aufs_read_lock(dentry, AuLock_DW);
  11516. + parent = dentry->d_parent; /* dir inode is locked */
  11517. + di_write_lock_parent(parent);
  11518. + wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
  11519. + &a->pin, &wr_dir_args);
  11520. + err = PTR_ERR(wh_dentry);
  11521. + if (IS_ERR(wh_dentry))
  11522. + goto out_free;
  11523. +
  11524. + sb = dentry->d_sb;
  11525. + bindex = au_dbstart(dentry);
  11526. + h_path.dentry = au_h_dptr(dentry, bindex);
  11527. + h_path.mnt = au_sbr_mnt(sb, bindex);
  11528. + err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
  11529. + if (unlikely(err))
  11530. + goto out_unlock;
  11531. +
  11532. + /* make the dir opaque */
  11533. + diropq = 0;
  11534. + h_mtx = &h_path.dentry->d_inode->i_mutex;
  11535. + if (wh_dentry
  11536. + || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
  11537. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  11538. + opq_dentry = au_diropq_create(dentry, bindex);
  11539. + mutex_unlock(h_mtx);
  11540. + err = PTR_ERR(opq_dentry);
  11541. + if (IS_ERR(opq_dentry))
  11542. + goto out_dir;
  11543. + dput(opq_dentry);
  11544. + diropq = 1;
  11545. + }
  11546. +
  11547. + err = epilog(dir, bindex, wh_dentry, dentry);
  11548. + if (!err) {
  11549. + inc_nlink(dir);
  11550. + goto out_unlock; /* success */
  11551. + }
  11552. +
  11553. + /* revert */
  11554. + if (diropq) {
  11555. + AuLabel(revert opq);
  11556. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  11557. + rerr = au_diropq_remove(dentry, bindex);
  11558. + mutex_unlock(h_mtx);
  11559. + if (rerr) {
  11560. + AuIOErr("%.*s reverting diropq failed(%d, %d)\n",
  11561. + AuDLNPair(dentry), err, rerr);
  11562. + err = -EIO;
  11563. + }
  11564. + }
  11565. +
  11566. + out_dir:
  11567. + AuLabel(revert dir);
  11568. + rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
  11569. + if (rerr) {
  11570. + AuIOErr("%.*s reverting dir failed(%d, %d)\n",
  11571. + AuDLNPair(dentry), err, rerr);
  11572. + err = -EIO;
  11573. + }
  11574. + d_drop(dentry);
  11575. + au_dtime_revert(&a->dt);
  11576. + out_unlock:
  11577. + au_unpin(&a->pin);
  11578. + dput(wh_dentry);
  11579. + out_free:
  11580. + if (unlikely(err)) {
  11581. + au_update_dbstart(dentry);
  11582. + d_drop(dentry);
  11583. + }
  11584. + di_write_unlock(parent);
  11585. + aufs_read_unlock(dentry, AuLock_DW);
  11586. + kfree(a);
  11587. + out:
  11588. + return err;
  11589. +}
  11590. diff -Nur linux-2.6.31.5.orig/fs/aufs/i_op.c linux-2.6.31.5/fs/aufs/i_op.c
  11591. --- linux-2.6.31.5.orig/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
  11592. +++ linux-2.6.31.5/fs/aufs/i_op.c 2009-11-15 22:02:37.000000000 +0100
  11593. @@ -0,0 +1,872 @@
  11594. +/*
  11595. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  11596. + *
  11597. + * This program, aufs is free software; you can redistribute it and/or modify
  11598. + * it under the terms of the GNU General Public License as published by
  11599. + * the Free Software Foundation; either version 2 of the License, or
  11600. + * (at your option) any later version.
  11601. + *
  11602. + * This program is distributed in the hope that it will be useful,
  11603. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11604. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11605. + * GNU General Public License for more details.
  11606. + *
  11607. + * You should have received a copy of the GNU General Public License
  11608. + * along with this program; if not, write to the Free Software
  11609. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  11610. + */
  11611. +
  11612. +/*
  11613. + * inode operations (except add/del/rename)
  11614. + */
  11615. +
  11616. +#include <linux/device_cgroup.h>
  11617. +#include <linux/fs_stack.h>
  11618. +#include <linux/mm.h>
  11619. +#include <linux/namei.h>
  11620. +#include <linux/security.h>
  11621. +#include <linux/uaccess.h>
  11622. +#include "aufs.h"
  11623. +
  11624. +static int h_permission(struct inode *h_inode, int mask,
  11625. + struct vfsmount *h_mnt, int brperm)
  11626. +{
  11627. + int err;
  11628. + const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
  11629. +
  11630. + err = -EACCES;
  11631. + if ((write_mask && IS_IMMUTABLE(h_inode))
  11632. + || ((mask & MAY_EXEC)
  11633. + && S_ISREG(h_inode->i_mode)
  11634. + && ((h_mnt->mnt_flags & MNT_NOEXEC)
  11635. + || !(h_inode->i_mode & S_IXUGO))))
  11636. + goto out;
  11637. +
  11638. + /*
  11639. + * - skip the lower fs test in the case of write to ro branch.
  11640. + * - nfs dir permission write check is optimized, but a policy for
  11641. + * link/rename requires a real check.
  11642. + */
  11643. + if ((write_mask && !au_br_writable(brperm))
  11644. + || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
  11645. + && write_mask && !(mask & MAY_READ))
  11646. + || !h_inode->i_op->permission) {
  11647. + /* AuLabel(generic_permission); */
  11648. + err = generic_permission(h_inode, mask, NULL);
  11649. + } else {
  11650. + /* AuLabel(h_inode->permission); */
  11651. + err = h_inode->i_op->permission(h_inode, mask);
  11652. + AuTraceErr(err);
  11653. + }
  11654. +
  11655. + if (!err)
  11656. + err = devcgroup_inode_permission(h_inode, mask);
  11657. + if (!err)
  11658. + err = security_inode_permission
  11659. + (h_inode, mask & (MAY_READ | MAY_WRITE | MAY_EXEC
  11660. + | MAY_APPEND));
  11661. +
  11662. + out:
  11663. + return err;
  11664. +}
  11665. +
  11666. +static int aufs_permission(struct inode *inode, int mask)
  11667. +{
  11668. + int err;
  11669. + aufs_bindex_t bindex, bend;
  11670. + const unsigned char isdir = !!S_ISDIR(inode->i_mode);
  11671. + const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
  11672. + struct inode *h_inode;
  11673. + struct super_block *sb;
  11674. + struct au_branch *br;
  11675. +
  11676. + sb = inode->i_sb;
  11677. + si_read_lock(sb, AuLock_FLUSH);
  11678. + ii_read_lock_child(inode);
  11679. +
  11680. + if (!isdir || write_mask) {
  11681. + h_inode = au_h_iptr(inode, au_ibstart(inode));
  11682. + AuDebugOn(!h_inode
  11683. + || ((h_inode->i_mode & S_IFMT)
  11684. + != (inode->i_mode & S_IFMT)));
  11685. + err = 0;
  11686. + bindex = au_ibstart(inode);
  11687. + br = au_sbr(sb, bindex);
  11688. + err = h_permission(h_inode, mask, br->br_mnt, br->br_perm);
  11689. +
  11690. + if (write_mask && !err) {
  11691. + /* test whether the upper writable branch exists */
  11692. + err = -EROFS;
  11693. + for (; bindex >= 0; bindex--)
  11694. + if (!au_br_rdonly(au_sbr(sb, bindex))) {
  11695. + err = 0;
  11696. + break;
  11697. + }
  11698. + }
  11699. + goto out;
  11700. + }
  11701. +
  11702. + /* non-write to dir */
  11703. + err = 0;
  11704. + bend = au_ibend(inode);
  11705. + for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) {
  11706. + h_inode = au_h_iptr(inode, bindex);
  11707. + if (h_inode) {
  11708. + AuDebugOn(!S_ISDIR(h_inode->i_mode));
  11709. + br = au_sbr(sb, bindex);
  11710. + err = h_permission(h_inode, mask, br->br_mnt,
  11711. + br->br_perm);
  11712. + }
  11713. + }
  11714. +
  11715. + out:
  11716. + ii_read_unlock(inode);
  11717. + si_read_unlock(sb);
  11718. + return err;
  11719. +}
  11720. +
  11721. +/* ---------------------------------------------------------------------- */
  11722. +
  11723. +static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
  11724. + struct nameidata *nd)
  11725. +{
  11726. + struct dentry *ret, *parent;
  11727. + struct inode *inode, *h_inode;
  11728. + struct mutex *mtx;
  11729. + struct super_block *sb;
  11730. + int err, npositive;
  11731. + aufs_bindex_t bstart;
  11732. +
  11733. + /* temporary workaround for a bug in NFSD readdir */
  11734. + if (!au_test_nfsd(current))
  11735. + IMustLock(dir);
  11736. + else
  11737. + WARN_ONCE(!mutex_is_locked(&dir->i_mutex),
  11738. + "a known problem of NFSD readdir since 2.6.28\n");
  11739. +
  11740. + sb = dir->i_sb;
  11741. + si_read_lock(sb, AuLock_FLUSH);
  11742. + err = au_alloc_dinfo(dentry);
  11743. + ret = ERR_PTR(err);
  11744. + if (unlikely(err))
  11745. + goto out;
  11746. +
  11747. + parent = dentry->d_parent; /* dir inode is locked */
  11748. + di_read_lock_parent(parent, AuLock_IR);
  11749. + npositive = au_lkup_dentry(dentry, au_dbstart(parent), /*type*/0, nd);
  11750. + di_read_unlock(parent, AuLock_IR);
  11751. + err = npositive;
  11752. + ret = ERR_PTR(err);
  11753. + if (unlikely(err < 0))
  11754. + goto out_unlock;
  11755. +
  11756. + inode = NULL;
  11757. + if (npositive) {
  11758. + bstart = au_dbstart(dentry);
  11759. + h_inode = au_h_dptr(dentry, bstart)->d_inode;
  11760. + if (!S_ISDIR(h_inode->i_mode)) {
  11761. + /*
  11762. + * stop 'race'-ing between hardlinks under different
  11763. + * parents.
  11764. + */
  11765. + mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;
  11766. + mutex_lock(mtx);
  11767. + inode = au_new_inode(dentry, /*must_new*/0);
  11768. + mutex_unlock(mtx);
  11769. + } else
  11770. + inode = au_new_inode(dentry, /*must_new*/0);
  11771. + ret = (void *)inode;
  11772. + }
  11773. + if (IS_ERR(inode))
  11774. + goto out_unlock;
  11775. +
  11776. + ret = d_splice_alias(inode, dentry);
  11777. + if (unlikely(IS_ERR(ret) && inode))
  11778. + ii_write_unlock(inode);
  11779. + au_store_oflag(nd, inode);
  11780. +
  11781. + out_unlock:
  11782. + di_write_unlock(dentry);
  11783. + out:
  11784. + si_read_unlock(sb);
  11785. + return ret;
  11786. +}
  11787. +
  11788. +/* ---------------------------------------------------------------------- */
  11789. +
  11790. +static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
  11791. + const unsigned char add_entry, aufs_bindex_t bcpup,
  11792. + aufs_bindex_t bstart)
  11793. +{
  11794. + int err;
  11795. + struct dentry *h_parent;
  11796. + struct inode *h_dir;
  11797. +
  11798. + if (add_entry) {
  11799. + au_update_dbstart(dentry);
  11800. + IMustLock(parent->d_inode);
  11801. + } else
  11802. + di_write_lock_parent(parent);
  11803. +
  11804. + err = 0;
  11805. + if (!au_h_dptr(parent, bcpup)) {
  11806. + if (bstart < bcpup)
  11807. + err = au_cpdown_dirs(dentry, bcpup);
  11808. + else
  11809. + err = au_cpup_dirs(dentry, bcpup);
  11810. + }
  11811. + if (!err && add_entry) {
  11812. + h_parent = au_h_dptr(parent, bcpup);
  11813. + h_dir = h_parent->d_inode;
  11814. + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
  11815. + err = au_lkup_neg(dentry, bcpup);
  11816. + /* todo: no unlock here */
  11817. + mutex_unlock(&h_dir->i_mutex);
  11818. + if (bstart < bcpup && au_dbstart(dentry) < 0) {
  11819. + au_set_dbstart(dentry, 0);
  11820. + au_update_dbrange(dentry, /*do_put_zero*/0);
  11821. + }
  11822. + }
  11823. +
  11824. + if (!add_entry)
  11825. + di_write_unlock(parent);
  11826. + if (!err)
  11827. + err = bcpup; /* success */
  11828. +
  11829. + return err;
  11830. +}
  11831. +
  11832. +/*
  11833. + * decide the branch and the parent dir where we will create a new entry.
  11834. + * returns new bindex or an error.
  11835. + * copyup the parent dir if needed.
  11836. + */
  11837. +int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
  11838. + struct au_wr_dir_args *args)
  11839. +{
  11840. + int err;
  11841. + aufs_bindex_t bcpup, bstart, src_bstart;
  11842. + const unsigned char add_entry = !!au_ftest_wrdir(args->flags,
  11843. + ADD_ENTRY);
  11844. + struct super_block *sb;
  11845. + struct dentry *parent;
  11846. + struct au_sbinfo *sbinfo;
  11847. +
  11848. + sb = dentry->d_sb;
  11849. + sbinfo = au_sbi(sb);
  11850. + parent = dget_parent(dentry);
  11851. + bstart = au_dbstart(dentry);
  11852. + bcpup = bstart;
  11853. + if (args->force_btgt < 0) {
  11854. + if (src_dentry) {
  11855. + src_bstart = au_dbstart(src_dentry);
  11856. + if (src_bstart < bstart)
  11857. + bcpup = src_bstart;
  11858. + } else if (add_entry) {
  11859. + err = AuWbrCreate(sbinfo, dentry,
  11860. + au_ftest_wrdir(args->flags, ISDIR));
  11861. + bcpup = err;
  11862. + }
  11863. +
  11864. + if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) {
  11865. + if (add_entry)
  11866. + err = AuWbrCopyup(sbinfo, dentry);
  11867. + else {
  11868. + if (!IS_ROOT(dentry)) {
  11869. + di_read_lock_parent(parent, !AuLock_IR);
  11870. + err = AuWbrCopyup(sbinfo, dentry);
  11871. + di_read_unlock(parent, !AuLock_IR);
  11872. + } else
  11873. + err = AuWbrCopyup(sbinfo, dentry);
  11874. + }
  11875. + bcpup = err;
  11876. + if (unlikely(err < 0))
  11877. + goto out;
  11878. + }
  11879. + } else {
  11880. + bcpup = args->force_btgt;
  11881. + AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode));
  11882. + }
  11883. + AuDbg("bstart %d, bcpup %d\n", bstart, bcpup);
  11884. + if (bstart < bcpup)
  11885. + au_update_dbrange(dentry, /*do_put_zero*/1);
  11886. +
  11887. + err = bcpup;
  11888. + if (bcpup == bstart)
  11889. + goto out; /* success */
  11890. +
  11891. + /* copyup the new parent into the branch we process */
  11892. + err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart);
  11893. +
  11894. + out:
  11895. + dput(parent);
  11896. + return err;
  11897. +}
  11898. +
  11899. +/* ---------------------------------------------------------------------- */
  11900. +
  11901. +struct dentry *au_pinned_h_parent(struct au_pin *pin)
  11902. +{
  11903. + if (pin && pin->parent)
  11904. + return au_h_dptr(pin->parent, pin->bindex);
  11905. + return NULL;
  11906. +}
  11907. +
  11908. +void au_unpin(struct au_pin *p)
  11909. +{
  11910. + if (au_ftest_pin(p->flags, MNT_WRITE))
  11911. + mnt_drop_write(p->h_mnt);
  11912. + if (!p->hdir)
  11913. + return;
  11914. +
  11915. + au_hin_imtx_unlock(p->hdir);
  11916. + if (!au_ftest_pin(p->flags, DI_LOCKED))
  11917. + di_read_unlock(p->parent, AuLock_IR);
  11918. + iput(p->hdir->hi_inode);
  11919. + dput(p->parent);
  11920. + p->parent = NULL;
  11921. + p->hdir = NULL;
  11922. + p->h_mnt = NULL;
  11923. +}
  11924. +
  11925. +int au_do_pin(struct au_pin *p)
  11926. +{
  11927. + int err;
  11928. + struct super_block *sb;
  11929. + struct dentry *h_dentry, *h_parent;
  11930. + struct au_branch *br;
  11931. + struct inode *h_dir;
  11932. +
  11933. + err = 0;
  11934. + sb = p->dentry->d_sb;
  11935. + br = au_sbr(sb, p->bindex);
  11936. + if (IS_ROOT(p->dentry)) {
  11937. + if (au_ftest_pin(p->flags, MNT_WRITE)) {
  11938. + p->h_mnt = br->br_mnt;
  11939. + err = mnt_want_write(p->h_mnt);
  11940. + if (unlikely(err)) {
  11941. + au_fclr_pin(p->flags, MNT_WRITE);
  11942. + goto out_err;
  11943. + }
  11944. + }
  11945. + goto out;
  11946. + }
  11947. +
  11948. + h_dentry = NULL;
  11949. + if (p->bindex <= au_dbend(p->dentry))
  11950. + h_dentry = au_h_dptr(p->dentry, p->bindex);
  11951. +
  11952. + p->parent = dget_parent(p->dentry);
  11953. + if (!au_ftest_pin(p->flags, DI_LOCKED))
  11954. + di_read_lock(p->parent, AuLock_IR, p->lsc_di);
  11955. +
  11956. + h_dir = NULL;
  11957. + h_parent = au_h_dptr(p->parent, p->bindex);
  11958. + p->hdir = au_hi(p->parent->d_inode, p->bindex);
  11959. + if (p->hdir)
  11960. + h_dir = p->hdir->hi_inode;
  11961. +
  11962. + /* udba case */
  11963. + if (unlikely(!p->hdir || !h_dir)) {
  11964. + if (!au_ftest_pin(p->flags, DI_LOCKED))
  11965. + di_read_unlock(p->parent, AuLock_IR);
  11966. + dput(p->parent);
  11967. + p->parent = NULL;
  11968. + goto out_err;
  11969. + }
  11970. +
  11971. + au_igrab(h_dir);
  11972. + au_hin_imtx_lock_nested(p->hdir, p->lsc_hi);
  11973. +
  11974. + if (unlikely(p->hdir->hi_inode != h_parent->d_inode)) {
  11975. + err = -EBUSY;
  11976. + goto out_unpin;
  11977. + }
  11978. + if (h_dentry) {
  11979. + err = au_h_verify(h_dentry, p->udba, h_dir, h_parent, br);
  11980. + if (unlikely(err)) {
  11981. + au_fclr_pin(p->flags, MNT_WRITE);
  11982. + goto out_unpin;
  11983. + }
  11984. + }
  11985. +
  11986. + if (au_ftest_pin(p->flags, MNT_WRITE)) {
  11987. + p->h_mnt = br->br_mnt;
  11988. + err = mnt_want_write(p->h_mnt);
  11989. + if (unlikely(err)) {
  11990. + au_fclr_pin(p->flags, MNT_WRITE);
  11991. + goto out_unpin;
  11992. + }
  11993. + }
  11994. + goto out; /* success */
  11995. +
  11996. + out_unpin:
  11997. + au_unpin(p);
  11998. + out_err:
  11999. + AuErr("err %d\n", err);
  12000. + err = au_busy_or_stale();
  12001. + out:
  12002. + return err;
  12003. +}
  12004. +
  12005. +void au_pin_init(struct au_pin *p, struct dentry *dentry,
  12006. + aufs_bindex_t bindex, int lsc_di, int lsc_hi,
  12007. + unsigned int udba, unsigned char flags)
  12008. +{
  12009. + p->dentry = dentry;
  12010. + p->udba = udba;
  12011. + p->lsc_di = lsc_di;
  12012. + p->lsc_hi = lsc_hi;
  12013. + p->flags = flags;
  12014. + p->bindex = bindex;
  12015. +
  12016. + p->parent = NULL;
  12017. + p->hdir = NULL;
  12018. + p->h_mnt = NULL;
  12019. +}
  12020. +
  12021. +int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
  12022. + unsigned int udba, unsigned char flags)
  12023. +{
  12024. + au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
  12025. + udba, flags);
  12026. + return au_do_pin(pin);
  12027. +}
  12028. +
  12029. +/* ---------------------------------------------------------------------- */
  12030. +
  12031. +#define AuIcpup_DID_CPUP 1
  12032. +#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
  12033. +#define au_fset_icpup(flags, name) { (flags) |= AuIcpup_##name; }
  12034. +#define au_fclr_icpup(flags, name) { (flags) &= ~AuIcpup_##name; }
  12035. +
  12036. +struct au_icpup_args {
  12037. + unsigned char flags;
  12038. + unsigned char pin_flags;
  12039. + aufs_bindex_t btgt;
  12040. + struct au_pin pin;
  12041. + struct path h_path;
  12042. + struct inode *h_inode;
  12043. +};
  12044. +
  12045. +static int au_lock_and_icpup(struct dentry *dentry, struct iattr *ia,
  12046. + struct au_icpup_args *a)
  12047. +{
  12048. + int err;
  12049. + unsigned int udba;
  12050. + loff_t sz;
  12051. + aufs_bindex_t bstart;
  12052. + struct dentry *hi_wh, *parent;
  12053. + struct inode *inode;
  12054. + struct au_wr_dir_args wr_dir_args = {
  12055. + .force_btgt = -1,
  12056. + .flags = 0
  12057. + };
  12058. +
  12059. + di_write_lock_child(dentry);
  12060. + bstart = au_dbstart(dentry);
  12061. + inode = dentry->d_inode;
  12062. + if (S_ISDIR(inode->i_mode))
  12063. + au_fset_wrdir(wr_dir_args.flags, ISDIR);
  12064. + /* plink or hi_wh() case */
  12065. + if (bstart != au_ibstart(inode))
  12066. + wr_dir_args.force_btgt = au_ibstart(inode);
  12067. + err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
  12068. + if (unlikely(err < 0))
  12069. + goto out_dentry;
  12070. + a->btgt = err;
  12071. + if (err != bstart)
  12072. + au_fset_icpup(a->flags, DID_CPUP);
  12073. +
  12074. + err = 0;
  12075. + a->pin_flags = AuPin_MNT_WRITE;
  12076. + parent = NULL;
  12077. + if (!IS_ROOT(dentry)) {
  12078. + au_fset_pin(a->pin_flags, DI_LOCKED);
  12079. + parent = dget_parent(dentry);
  12080. + di_write_lock_parent(parent);
  12081. + }
  12082. +
  12083. + udba = au_opt_udba(dentry->d_sb);
  12084. + if (d_unhashed(dentry) || (ia->ia_valid & ATTR_FILE))
  12085. + udba = AuOpt_UDBA_NONE;
  12086. + err = au_pin(&a->pin, dentry, a->btgt, udba, a->pin_flags);
  12087. + if (unlikely(err)) {
  12088. + if (parent) {
  12089. + di_write_unlock(parent);
  12090. + dput(parent);
  12091. + }
  12092. + goto out_dentry;
  12093. + }
  12094. + a->h_path.dentry = au_h_dptr(dentry, bstart);
  12095. + a->h_inode = a->h_path.dentry->d_inode;
  12096. + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
  12097. + sz = -1;
  12098. + if ((ia->ia_valid & ATTR_SIZE) && ia->ia_size < i_size_read(a->h_inode))
  12099. + sz = ia->ia_size;
  12100. +
  12101. + hi_wh = NULL;
  12102. + if (au_ftest_icpup(a->flags, DID_CPUP) && d_unhashed(dentry)) {
  12103. + hi_wh = au_hi_wh(inode, a->btgt);
  12104. + if (!hi_wh) {
  12105. + err = au_sio_cpup_wh(dentry, a->btgt, sz, /*file*/NULL);
  12106. + if (unlikely(err))
  12107. + goto out_unlock;
  12108. + hi_wh = au_hi_wh(inode, a->btgt);
  12109. + /* todo: revalidate hi_wh? */
  12110. + }
  12111. + }
  12112. +
  12113. + if (parent) {
  12114. + au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
  12115. + di_downgrade_lock(parent, AuLock_IR);
  12116. + dput(parent);
  12117. + }
  12118. + if (!au_ftest_icpup(a->flags, DID_CPUP))
  12119. + goto out; /* success */
  12120. +
  12121. + if (!d_unhashed(dentry)) {
  12122. + err = au_sio_cpup_simple(dentry, a->btgt, sz, AuCpup_DTIME);
  12123. + if (!err)
  12124. + a->h_path.dentry = au_h_dptr(dentry, a->btgt);
  12125. + } else if (!hi_wh)
  12126. + a->h_path.dentry = au_h_dptr(dentry, a->btgt);
  12127. + else
  12128. + a->h_path.dentry = hi_wh; /* do not dget here */
  12129. +
  12130. + out_unlock:
  12131. + mutex_unlock(&a->h_inode->i_mutex);
  12132. + a->h_inode = a->h_path.dentry->d_inode;
  12133. + if (!err) {
  12134. + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
  12135. + goto out; /* success */
  12136. + }
  12137. +
  12138. + au_unpin(&a->pin);
  12139. +
  12140. + out_dentry:
  12141. + di_write_unlock(dentry);
  12142. + out:
  12143. + return err;
  12144. +}
  12145. +
  12146. +static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
  12147. +{
  12148. + int err;
  12149. + struct inode *inode;
  12150. + struct super_block *sb;
  12151. + struct file *file;
  12152. + struct au_icpup_args *a;
  12153. +
  12154. + err = -ENOMEM;
  12155. + a = kzalloc(sizeof(*a), GFP_NOFS);
  12156. + if (unlikely(!a))
  12157. + goto out;
  12158. +
  12159. + inode = dentry->d_inode;
  12160. + IMustLock(inode);
  12161. + sb = dentry->d_sb;
  12162. + si_read_lock(sb, AuLock_FLUSH);
  12163. +
  12164. + file = NULL;
  12165. + if (ia->ia_valid & ATTR_FILE) {
  12166. + /* currently ftruncate(2) only */
  12167. + file = ia->ia_file;
  12168. + fi_write_lock(file);
  12169. + ia->ia_file = au_h_fptr(file, au_fbstart(file));
  12170. + }
  12171. +
  12172. + if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
  12173. + ia->ia_valid &= ~ATTR_MODE;
  12174. +
  12175. + err = au_lock_and_icpup(dentry, ia, a);
  12176. + if (unlikely(err < 0))
  12177. + goto out_si;
  12178. + if (au_ftest_icpup(a->flags, DID_CPUP)) {
  12179. + ia->ia_file = NULL;
  12180. + ia->ia_valid &= ~ATTR_FILE;
  12181. + }
  12182. +
  12183. + a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
  12184. + if (ia->ia_valid & ATTR_SIZE) {
  12185. + struct file *f;
  12186. +
  12187. + if (ia->ia_size < i_size_read(inode)) {
  12188. + /* unmap only */
  12189. + err = vmtruncate(inode, ia->ia_size);
  12190. + if (unlikely(err))
  12191. + goto out_unlock;
  12192. + }
  12193. +
  12194. + f = NULL;
  12195. + if (ia->ia_valid & ATTR_FILE)
  12196. + f = ia->ia_file;
  12197. + mutex_unlock(&a->h_inode->i_mutex);
  12198. + err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
  12199. + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
  12200. + } else
  12201. + err = vfsub_notify_change(&a->h_path, ia);
  12202. + if (!err)
  12203. + au_cpup_attr_changeable(inode);
  12204. +
  12205. + out_unlock:
  12206. + mutex_unlock(&a->h_inode->i_mutex);
  12207. + au_unpin(&a->pin);
  12208. + di_write_unlock(dentry);
  12209. + out_si:
  12210. + if (file) {
  12211. + fi_write_unlock(file);
  12212. + ia->ia_file = file;
  12213. + ia->ia_valid |= ATTR_FILE;
  12214. + }
  12215. + si_read_unlock(sb);
  12216. + kfree(a);
  12217. + out:
  12218. + return err;
  12219. +}
  12220. +
  12221. +static int au_getattr_lock_reval(struct dentry *dentry, unsigned int sigen)
  12222. +{
  12223. + int err;
  12224. + struct inode *inode;
  12225. + struct dentry *parent;
  12226. +
  12227. + err = 0;
  12228. + inode = dentry->d_inode;
  12229. + di_write_lock_child(dentry);
  12230. + if (au_digen(dentry) != sigen || au_iigen(inode) != sigen) {
  12231. + parent = dget_parent(dentry);
  12232. + di_read_lock_parent(parent, AuLock_IR);
  12233. + /* returns a number of positive dentries */
  12234. + err = au_refresh_hdentry(dentry, inode->i_mode & S_IFMT);
  12235. + if (err > 0)
  12236. + err = au_refresh_hinode(inode, dentry);
  12237. + di_read_unlock(parent, AuLock_IR);
  12238. + dput(parent);
  12239. + if (unlikely(!err))
  12240. + err = -EIO;
  12241. + }
  12242. + di_downgrade_lock(dentry, AuLock_IR);
  12243. + if (unlikely(err))
  12244. + di_read_unlock(dentry, AuLock_IR);
  12245. +
  12246. + return err;
  12247. +}
  12248. +
  12249. +static void au_refresh_iattr(struct inode *inode, struct kstat *st,
  12250. + unsigned int nlink)
  12251. +{
  12252. + inode->i_mode = st->mode;
  12253. + inode->i_uid = st->uid;
  12254. + inode->i_gid = st->gid;
  12255. + inode->i_atime = st->atime;
  12256. + inode->i_mtime = st->mtime;
  12257. + inode->i_ctime = st->ctime;
  12258. +
  12259. + au_cpup_attr_nlink(inode, /*force*/0);
  12260. + if (S_ISDIR(inode->i_mode)) {
  12261. + inode->i_nlink -= nlink;
  12262. + inode->i_nlink += st->nlink;
  12263. + }
  12264. +
  12265. + spin_lock(&inode->i_lock);
  12266. + inode->i_blocks = st->blocks;
  12267. + i_size_write(inode, st->size);
  12268. + spin_unlock(&inode->i_lock);
  12269. +}
  12270. +
  12271. +static int aufs_getattr(struct vfsmount *mnt __maybe_unused,
  12272. + struct dentry *dentry, struct kstat *st)
  12273. +{
  12274. + int err;
  12275. + unsigned int mnt_flags;
  12276. + aufs_bindex_t bindex;
  12277. + unsigned char udba_none, positive;
  12278. + struct super_block *sb, *h_sb;
  12279. + struct inode *inode;
  12280. + struct vfsmount *h_mnt;
  12281. + struct dentry *h_dentry;
  12282. +
  12283. + err = 0;
  12284. + sb = dentry->d_sb;
  12285. + inode = dentry->d_inode;
  12286. + si_read_lock(sb, AuLock_FLUSH);
  12287. + mnt_flags = au_mntflags(sb);
  12288. + udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
  12289. +
  12290. + /* support fstat(2) */
  12291. + if (!d_unhashed(dentry) && !udba_none) {
  12292. + unsigned int sigen = au_sigen(sb);
  12293. + if (au_digen(dentry) == sigen && au_iigen(inode) == sigen)
  12294. + di_read_lock_child(dentry, AuLock_IR);
  12295. + else {
  12296. + AuDebugOn(!IS_ROOT(dentry));
  12297. + err = au_getattr_lock_reval(dentry, sigen);
  12298. + if (unlikely(err))
  12299. + goto out;
  12300. + }
  12301. + } else
  12302. + di_read_lock_child(dentry, AuLock_IR);
  12303. +
  12304. + bindex = au_ibstart(inode);
  12305. + h_mnt = au_sbr_mnt(sb, bindex);
  12306. + h_sb = h_mnt->mnt_sb;
  12307. + if (!au_test_fs_bad_iattr(h_sb) && udba_none)
  12308. + goto out_fill; /* success */
  12309. +
  12310. + h_dentry = NULL;
  12311. + if (au_dbstart(dentry) == bindex)
  12312. + h_dentry = dget(au_h_dptr(dentry, bindex));
  12313. + else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
  12314. + h_dentry = au_plink_lkup(inode, bindex);
  12315. + if (IS_ERR(h_dentry))
  12316. + goto out_fill; /* pretending success */
  12317. + }
  12318. + /* illegally overlapped or something */
  12319. + if (unlikely(!h_dentry))
  12320. + goto out_fill; /* pretending success */
  12321. +
  12322. + positive = !!h_dentry->d_inode;
  12323. + if (positive)
  12324. + err = vfs_getattr(h_mnt, h_dentry, st);
  12325. + dput(h_dentry);
  12326. + if (!err) {
  12327. + if (positive)
  12328. + au_refresh_iattr(inode, st, h_dentry->d_inode->i_nlink);
  12329. + goto out_fill; /* success */
  12330. + }
  12331. + goto out_unlock;
  12332. +
  12333. + out_fill:
  12334. + generic_fillattr(inode, st);
  12335. + out_unlock:
  12336. + di_read_unlock(dentry, AuLock_IR);
  12337. + out:
  12338. + si_read_unlock(sb);
  12339. + return err;
  12340. +}
  12341. +
  12342. +/* ---------------------------------------------------------------------- */
  12343. +
  12344. +static int h_readlink(struct dentry *dentry, int bindex, char __user *buf,
  12345. + int bufsiz)
  12346. +{
  12347. + int err;
  12348. + struct super_block *sb;
  12349. + struct dentry *h_dentry;
  12350. +
  12351. + err = -EINVAL;
  12352. + h_dentry = au_h_dptr(dentry, bindex);
  12353. + if (unlikely(/* !h_dentry
  12354. + || !h_dentry->d_inode
  12355. + || !h_dentry->d_inode->i_op
  12356. + || */ !h_dentry->d_inode->i_op->readlink))
  12357. + goto out;
  12358. +
  12359. + err = security_inode_readlink(h_dentry);
  12360. + if (unlikely(err))
  12361. + goto out;
  12362. +
  12363. + sb = dentry->d_sb;
  12364. + if (!au_test_ro(sb, bindex, dentry->d_inode)) {
  12365. + vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry);
  12366. + fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode);
  12367. + }
  12368. + err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz);
  12369. +
  12370. + out:
  12371. + return err;
  12372. +}
  12373. +
  12374. +static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
  12375. +{
  12376. + int err;
  12377. +
  12378. + aufs_read_lock(dentry, AuLock_IR);
  12379. + err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz);
  12380. + aufs_read_unlock(dentry, AuLock_IR);
  12381. +
  12382. + return err;
  12383. +}
  12384. +
  12385. +static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd)
  12386. +{
  12387. + int err;
  12388. + char *buf;
  12389. + mm_segment_t old_fs;
  12390. +
  12391. + err = -ENOMEM;
  12392. + buf = __getname();
  12393. + if (unlikely(!buf))
  12394. + goto out;
  12395. +
  12396. + aufs_read_lock(dentry, AuLock_IR);
  12397. + old_fs = get_fs();
  12398. + set_fs(KERNEL_DS);
  12399. + err = h_readlink(dentry, au_dbstart(dentry), (char __user *)buf,
  12400. + PATH_MAX);
  12401. + set_fs(old_fs);
  12402. + aufs_read_unlock(dentry, AuLock_IR);
  12403. +
  12404. + if (err >= 0) {
  12405. + buf[err] = 0;
  12406. + /* will be freed by put_link */
  12407. + nd_set_link(nd, buf);
  12408. + return NULL; /* success */
  12409. + }
  12410. + __putname(buf);
  12411. +
  12412. + out:
  12413. + path_put(&nd->path);
  12414. + AuTraceErr(err);
  12415. + return ERR_PTR(err);
  12416. +}
  12417. +
  12418. +static void aufs_put_link(struct dentry *dentry __maybe_unused,
  12419. + struct nameidata *nd, void *cookie __maybe_unused)
  12420. +{
  12421. + __putname(nd_get_link(nd));
  12422. +}
  12423. +
  12424. +/* ---------------------------------------------------------------------- */
  12425. +
  12426. +static void aufs_truncate_range(struct inode *inode __maybe_unused,
  12427. + loff_t start __maybe_unused,
  12428. + loff_t end __maybe_unused)
  12429. +{
  12430. + AuUnsupport();
  12431. +}
  12432. +
  12433. +/* ---------------------------------------------------------------------- */
  12434. +
  12435. +struct inode_operations aufs_symlink_iop = {
  12436. + .permission = aufs_permission,
  12437. + .setattr = aufs_setattr,
  12438. + .getattr = aufs_getattr,
  12439. + .readlink = aufs_readlink,
  12440. + .follow_link = aufs_follow_link,
  12441. + .put_link = aufs_put_link
  12442. +};
  12443. +
  12444. +struct inode_operations aufs_dir_iop = {
  12445. + .create = aufs_create,
  12446. + .lookup = aufs_lookup,
  12447. + .link = aufs_link,
  12448. + .unlink = aufs_unlink,
  12449. + .symlink = aufs_symlink,
  12450. + .mkdir = aufs_mkdir,
  12451. + .rmdir = aufs_rmdir,
  12452. + .mknod = aufs_mknod,
  12453. + .rename = aufs_rename,
  12454. +
  12455. + .permission = aufs_permission,
  12456. + .setattr = aufs_setattr,
  12457. + .getattr = aufs_getattr
  12458. +};
  12459. +
  12460. +struct inode_operations aufs_iop = {
  12461. + .permission = aufs_permission,
  12462. + .setattr = aufs_setattr,
  12463. + .getattr = aufs_getattr,
  12464. + .truncate_range = aufs_truncate_range
  12465. +};
  12466. diff -Nur linux-2.6.31.5.orig/fs/aufs/i_op_del.c linux-2.6.31.5/fs/aufs/i_op_del.c
  12467. --- linux-2.6.31.5.orig/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
  12468. +++ linux-2.6.31.5/fs/aufs/i_op_del.c 2009-11-15 22:02:37.000000000 +0100
  12469. @@ -0,0 +1,468 @@
  12470. +/*
  12471. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  12472. + *
  12473. + * This program, aufs is free software; you can redistribute it and/or modify
  12474. + * it under the terms of the GNU General Public License as published by
  12475. + * the Free Software Foundation; either version 2 of the License, or
  12476. + * (at your option) any later version.
  12477. + *
  12478. + * This program is distributed in the hope that it will be useful,
  12479. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12480. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12481. + * GNU General Public License for more details.
  12482. + *
  12483. + * You should have received a copy of the GNU General Public License
  12484. + * along with this program; if not, write to the Free Software
  12485. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  12486. + */
  12487. +
  12488. +/*
  12489. + * inode operations (del entry)
  12490. + */
  12491. +
  12492. +#include "aufs.h"
  12493. +
  12494. +/*
  12495. + * decide if a new whiteout for @dentry is necessary or not.
  12496. + * when it is necessary, prepare the parent dir for the upper branch whose
  12497. + * branch index is @bcpup for creation. the actual creation of the whiteout will
  12498. + * be done by caller.
  12499. + * return value:
  12500. + * 0: wh is unnecessary
  12501. + * plus: wh is necessary
  12502. + * minus: error
  12503. + */
  12504. +int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
  12505. +{
  12506. + int need_wh, err;
  12507. + aufs_bindex_t bstart;
  12508. + struct super_block *sb;
  12509. +
  12510. + sb = dentry->d_sb;
  12511. + bstart = au_dbstart(dentry);
  12512. + if (*bcpup < 0) {
  12513. + *bcpup = bstart;
  12514. + if (au_test_ro(sb, bstart, dentry->d_inode)) {
  12515. + err = AuWbrCopyup(au_sbi(sb), dentry);
  12516. + *bcpup = err;
  12517. + if (unlikely(err < 0))
  12518. + goto out;
  12519. + }
  12520. + } else
  12521. + AuDebugOn(bstart < *bcpup
  12522. + || au_test_ro(sb, *bcpup, dentry->d_inode));
  12523. + AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
  12524. +
  12525. + if (*bcpup != bstart) {
  12526. + err = au_cpup_dirs(dentry, *bcpup);
  12527. + if (unlikely(err))
  12528. + goto out;
  12529. + need_wh = 1;
  12530. + } else {
  12531. + aufs_bindex_t old_bend, new_bend, bdiropq = -1;
  12532. +
  12533. + old_bend = au_dbend(dentry);
  12534. + if (isdir) {
  12535. + bdiropq = au_dbdiropq(dentry);
  12536. + au_set_dbdiropq(dentry, -1);
  12537. + }
  12538. + need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0,
  12539. + /*nd*/NULL);
  12540. + err = need_wh;
  12541. + if (isdir)
  12542. + au_set_dbdiropq(dentry, bdiropq);
  12543. + if (unlikely(err < 0))
  12544. + goto out;
  12545. + new_bend = au_dbend(dentry);
  12546. + if (!need_wh && old_bend != new_bend) {
  12547. + au_set_h_dptr(dentry, new_bend, NULL);
  12548. + au_set_dbend(dentry, old_bend);
  12549. + }
  12550. + }
  12551. + AuDbg("need_wh %d\n", need_wh);
  12552. + err = need_wh;
  12553. +
  12554. + out:
  12555. + return err;
  12556. +}
  12557. +
  12558. +/*
  12559. + * simple tests for the del-entry operations.
  12560. + * following the checks in vfs, plus the parent-child relationship.
  12561. + */
  12562. +int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
  12563. + struct dentry *h_parent, int isdir)
  12564. +{
  12565. + int err;
  12566. + umode_t h_mode;
  12567. + struct dentry *h_dentry, *h_latest;
  12568. + struct inode *h_inode;
  12569. +
  12570. + h_dentry = au_h_dptr(dentry, bindex);
  12571. + h_inode = h_dentry->d_inode;
  12572. + if (dentry->d_inode) {
  12573. + err = -ENOENT;
  12574. + if (unlikely(!h_inode || !h_inode->i_nlink))
  12575. + goto out;
  12576. +
  12577. + h_mode = h_inode->i_mode;
  12578. + if (!isdir) {
  12579. + err = -EISDIR;
  12580. + if (unlikely(S_ISDIR(h_mode)))
  12581. + goto out;
  12582. + } else if (unlikely(!S_ISDIR(h_mode))) {
  12583. + err = -ENOTDIR;
  12584. + goto out;
  12585. + }
  12586. + } else {
  12587. + /* rename(2) case */
  12588. + err = -EIO;
  12589. + if (unlikely(h_inode))
  12590. + goto out;
  12591. + }
  12592. +
  12593. + err = -ENOENT;
  12594. + /* expected parent dir is locked */
  12595. + if (unlikely(h_parent != h_dentry->d_parent))
  12596. + goto out;
  12597. + err = 0;
  12598. +
  12599. + /*
  12600. + * rmdir a dir may break the consistency on some filesystem.
  12601. + * let's try heavy test.
  12602. + */
  12603. + err = -EACCES;
  12604. + if (unlikely(au_test_h_perm(h_parent->d_inode, MAY_EXEC | MAY_WRITE)))
  12605. + goto out;
  12606. +
  12607. + h_latest = au_sio_lkup_one(&dentry->d_name, h_parent,
  12608. + au_sbr(dentry->d_sb, bindex));
  12609. + err = -EIO;
  12610. + if (IS_ERR(h_latest))
  12611. + goto out;
  12612. + if (h_latest == h_dentry)
  12613. + err = 0;
  12614. + dput(h_latest);
  12615. +
  12616. + out:
  12617. + return err;
  12618. +}
  12619. +
  12620. +/*
  12621. + * decide the branch where we operate for @dentry. the branch index will be set
  12622. + * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
  12623. + * dir for reverting.
  12624. + * when a new whiteout is necessary, create it.
  12625. + */
  12626. +static struct dentry*
  12627. +lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
  12628. + struct au_dtime *dt, struct au_pin *pin)
  12629. +{
  12630. + struct dentry *wh_dentry;
  12631. + struct super_block *sb;
  12632. + struct path h_path;
  12633. + int err, need_wh;
  12634. + unsigned int udba;
  12635. + aufs_bindex_t bcpup;
  12636. +
  12637. + need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
  12638. + wh_dentry = ERR_PTR(need_wh);
  12639. + if (unlikely(need_wh < 0))
  12640. + goto out;
  12641. +
  12642. + sb = dentry->d_sb;
  12643. + udba = au_opt_udba(sb);
  12644. + bcpup = *rbcpup;
  12645. + err = au_pin(pin, dentry, bcpup, udba,
  12646. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  12647. + wh_dentry = ERR_PTR(err);
  12648. + if (unlikely(err))
  12649. + goto out;
  12650. +
  12651. + h_path.dentry = au_pinned_h_parent(pin);
  12652. + if (udba != AuOpt_UDBA_NONE
  12653. + && au_dbstart(dentry) == bcpup) {
  12654. + err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
  12655. + wh_dentry = ERR_PTR(err);
  12656. + if (unlikely(err))
  12657. + goto out_unpin;
  12658. + }
  12659. +
  12660. + h_path.mnt = au_sbr_mnt(sb, bcpup);
  12661. + au_dtime_store(dt, au_pinned_parent(pin), &h_path);
  12662. + wh_dentry = NULL;
  12663. + if (!need_wh)
  12664. + goto out; /* success, no need to create whiteout */
  12665. +
  12666. + wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
  12667. + if (!IS_ERR(wh_dentry))
  12668. + goto out; /* success */
  12669. + /* returns with the parent is locked and wh_dentry is dget-ed */
  12670. +
  12671. + out_unpin:
  12672. + au_unpin(pin);
  12673. + out:
  12674. + return wh_dentry;
  12675. +}
  12676. +
  12677. +/*
  12678. + * when removing a dir, rename it to a unique temporary whiteout-ed name first
  12679. + * in order to be revertible and save time for removing many child whiteouts
  12680. + * under the dir.
  12681. + * returns 1 when there are too many child whiteout and caller should remove
  12682. + * them asynchronously. returns 0 when the number of children is enough small to
  12683. + * remove now or the branch fs is a remote fs.
  12684. + * otherwise return an error.
  12685. + */
  12686. +static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
  12687. + struct au_nhash *whlist, struct inode *dir)
  12688. +{
  12689. + int rmdir_later, err, dirwh;
  12690. + struct dentry *h_dentry;
  12691. + struct super_block *sb;
  12692. +
  12693. + sb = dentry->d_sb;
  12694. + SiMustAnyLock(sb);
  12695. + h_dentry = au_h_dptr(dentry, bindex);
  12696. + err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
  12697. + if (unlikely(err))
  12698. + goto out;
  12699. +
  12700. + /* stop monitoring */
  12701. + au_hin_free(au_hi(dentry->d_inode, bindex));
  12702. +
  12703. + if (!au_test_fs_remote(h_dentry->d_sb)) {
  12704. + dirwh = au_sbi(sb)->si_dirwh;
  12705. + rmdir_later = (dirwh <= 1);
  12706. + if (!rmdir_later)
  12707. + rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
  12708. + dirwh);
  12709. + if (rmdir_later)
  12710. + return rmdir_later;
  12711. + }
  12712. +
  12713. + err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
  12714. + if (unlikely(err)) {
  12715. + AuIOErr("rmdir %.*s, b%d failed, %d. ignored\n",
  12716. + AuDLNPair(h_dentry), bindex, err);
  12717. + err = 0;
  12718. + }
  12719. +
  12720. + out:
  12721. + return err;
  12722. +}
  12723. +
  12724. +/*
  12725. + * final procedure for deleting a entry.
  12726. + * maintain dentry and iattr.
  12727. + */
  12728. +static void epilog(struct inode *dir, struct dentry *dentry,
  12729. + aufs_bindex_t bindex)
  12730. +{
  12731. + struct inode *inode;
  12732. +
  12733. + inode = dentry->d_inode;
  12734. + d_drop(dentry);
  12735. + inode->i_ctime = dir->i_ctime;
  12736. +
  12737. + if (atomic_read(&dentry->d_count) == 1) {
  12738. + au_set_h_dptr(dentry, au_dbstart(dentry), NULL);
  12739. + au_update_dbstart(dentry);
  12740. + }
  12741. + if (au_ibstart(dir) == bindex)
  12742. + au_cpup_attr_timesizes(dir);
  12743. + dir->i_version++;
  12744. +}
  12745. +
  12746. +/*
  12747. + * when an error happened, remove the created whiteout and revert everything.
  12748. + */
  12749. +static int do_revert(int err, struct inode *dir, aufs_bindex_t bwh,
  12750. + struct dentry *wh_dentry, struct dentry *dentry,
  12751. + struct au_dtime *dt)
  12752. +{
  12753. + int rerr;
  12754. + struct path h_path = {
  12755. + .dentry = wh_dentry,
  12756. + .mnt = au_sbr_mnt(dir->i_sb, bwh)
  12757. + };
  12758. +
  12759. + rerr = au_wh_unlink_dentry(au_h_iptr(dir, bwh), &h_path, dentry);
  12760. + if (!rerr) {
  12761. + au_set_dbwh(dentry, bwh);
  12762. + au_dtime_revert(dt);
  12763. + return 0;
  12764. + }
  12765. +
  12766. + AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
  12767. + AuDLNPair(dentry), err, rerr);
  12768. + return -EIO;
  12769. +}
  12770. +
  12771. +/* ---------------------------------------------------------------------- */
  12772. +
  12773. +int aufs_unlink(struct inode *dir, struct dentry *dentry)
  12774. +{
  12775. + int err;
  12776. + aufs_bindex_t bwh, bindex, bstart;
  12777. + struct au_dtime dt;
  12778. + struct au_pin pin;
  12779. + struct path h_path;
  12780. + struct inode *inode, *h_dir;
  12781. + struct dentry *parent, *wh_dentry;
  12782. +
  12783. + IMustLock(dir);
  12784. + inode = dentry->d_inode;
  12785. + if (unlikely(!inode))
  12786. + return -ENOENT; /* possible? */
  12787. + IMustLock(inode);
  12788. +
  12789. + aufs_read_lock(dentry, AuLock_DW);
  12790. + parent = dentry->d_parent; /* dir inode is locked */
  12791. + di_write_lock_parent(parent);
  12792. +
  12793. + bstart = au_dbstart(dentry);
  12794. + bwh = au_dbwh(dentry);
  12795. + bindex = -1;
  12796. + wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt, &pin);
  12797. + err = PTR_ERR(wh_dentry);
  12798. + if (IS_ERR(wh_dentry))
  12799. + goto out;
  12800. +
  12801. + h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
  12802. + h_path.dentry = au_h_dptr(dentry, bstart);
  12803. + dget(h_path.dentry);
  12804. + if (bindex == bstart) {
  12805. + h_dir = au_pinned_h_dir(&pin);
  12806. + err = vfsub_unlink(h_dir, &h_path, /*force*/0);
  12807. + } else {
  12808. + /* dir inode is locked */
  12809. + h_dir = wh_dentry->d_parent->d_inode;
  12810. + IMustLock(h_dir);
  12811. + err = 0;
  12812. + }
  12813. +
  12814. + if (!err) {
  12815. + drop_nlink(inode);
  12816. + epilog(dir, dentry, bindex);
  12817. +
  12818. + /* update target timestamps */
  12819. + if (bindex == bstart) {
  12820. + vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
  12821. + inode->i_ctime = h_path.dentry->d_inode->i_ctime;
  12822. + } else
  12823. + /* todo: this timestamp may be reverted later */
  12824. + inode->i_ctime = h_dir->i_ctime;
  12825. + goto out_unlock; /* success */
  12826. + }
  12827. +
  12828. + /* revert */
  12829. + if (wh_dentry) {
  12830. + int rerr;
  12831. +
  12832. + rerr = do_revert(err, dir, bwh, wh_dentry, dentry, &dt);
  12833. + if (rerr)
  12834. + err = rerr;
  12835. + }
  12836. +
  12837. + out_unlock:
  12838. + au_unpin(&pin);
  12839. + dput(wh_dentry);
  12840. + dput(h_path.dentry);
  12841. + out:
  12842. + di_write_unlock(parent);
  12843. + aufs_read_unlock(dentry, AuLock_DW);
  12844. + return err;
  12845. +}
  12846. +
  12847. +int aufs_rmdir(struct inode *dir, struct dentry *dentry)
  12848. +{
  12849. + int err, rmdir_later;
  12850. + aufs_bindex_t bwh, bindex, bstart;
  12851. + struct au_dtime dt;
  12852. + struct au_pin pin;
  12853. + struct inode *inode;
  12854. + struct dentry *parent, *wh_dentry, *h_dentry;
  12855. + struct au_whtmp_rmdir *args;
  12856. +
  12857. + IMustLock(dir);
  12858. + inode = dentry->d_inode;
  12859. + err = -ENOENT; /* possible? */
  12860. + if (unlikely(!inode))
  12861. + goto out;
  12862. + IMustLock(inode);
  12863. +
  12864. + aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH);
  12865. + err = -ENOMEM;
  12866. + args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
  12867. + if (unlikely(!args))
  12868. + goto out_unlock;
  12869. +
  12870. + parent = dentry->d_parent; /* dir inode is locked */
  12871. + di_write_lock_parent(parent);
  12872. + err = au_test_empty(dentry, &args->whlist);
  12873. + if (unlikely(err))
  12874. + goto out_args;
  12875. +
  12876. + bstart = au_dbstart(dentry);
  12877. + bwh = au_dbwh(dentry);
  12878. + bindex = -1;
  12879. + wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &dt, &pin);
  12880. + err = PTR_ERR(wh_dentry);
  12881. + if (IS_ERR(wh_dentry))
  12882. + goto out_args;
  12883. +
  12884. + h_dentry = au_h_dptr(dentry, bstart);
  12885. + dget(h_dentry);
  12886. + rmdir_later = 0;
  12887. + if (bindex == bstart) {
  12888. + err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir);
  12889. + if (err > 0) {
  12890. + rmdir_later = err;
  12891. + err = 0;
  12892. + }
  12893. + } else {
  12894. + /* stop monitoring */
  12895. + au_hin_free(au_hi(inode, bstart));
  12896. +
  12897. + /* dir inode is locked */
  12898. + IMustLock(wh_dentry->d_parent->d_inode);
  12899. + err = 0;
  12900. + }
  12901. +
  12902. + if (!err) {
  12903. + clear_nlink(inode);
  12904. + au_set_dbdiropq(dentry, -1);
  12905. + epilog(dir, dentry, bindex);
  12906. +
  12907. + if (rmdir_later) {
  12908. + au_whtmp_kick_rmdir(dir, bstart, h_dentry, args);
  12909. + args = NULL;
  12910. + }
  12911. +
  12912. + goto out_unpin; /* success */
  12913. + }
  12914. +
  12915. + /* revert */
  12916. + AuLabel(revert);
  12917. + if (wh_dentry) {
  12918. + int rerr;
  12919. +
  12920. + rerr = do_revert(err, dir, bwh, wh_dentry, dentry, &dt);
  12921. + if (rerr)
  12922. + err = rerr;
  12923. + }
  12924. +
  12925. + out_unpin:
  12926. + au_unpin(&pin);
  12927. + dput(wh_dentry);
  12928. + dput(h_dentry);
  12929. + out_args:
  12930. + di_write_unlock(parent);
  12931. + if (args)
  12932. + au_whtmp_rmdir_free(args);
  12933. + out_unlock:
  12934. + aufs_read_unlock(dentry, AuLock_DW);
  12935. + out:
  12936. + return err;
  12937. +}
  12938. diff -Nur linux-2.6.31.5.orig/fs/aufs/i_op_ren.c linux-2.6.31.5/fs/aufs/i_op_ren.c
  12939. --- linux-2.6.31.5.orig/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
  12940. +++ linux-2.6.31.5/fs/aufs/i_op_ren.c 2009-11-15 22:02:37.000000000 +0100
  12941. @@ -0,0 +1,948 @@
  12942. +/*
  12943. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  12944. + *
  12945. + * This program, aufs is free software; you can redistribute it and/or modify
  12946. + * it under the terms of the GNU General Public License as published by
  12947. + * the Free Software Foundation; either version 2 of the License, or
  12948. + * (at your option) any later version.
  12949. + *
  12950. + * This program is distributed in the hope that it will be useful,
  12951. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12952. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12953. + * GNU General Public License for more details.
  12954. + *
  12955. + * You should have received a copy of the GNU General Public License
  12956. + * along with this program; if not, write to the Free Software
  12957. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  12958. + */
  12959. +
  12960. +/*
  12961. + * inode operation (rename entry)
  12962. + * todo: this is crazy monster
  12963. + */
  12964. +
  12965. +#include "aufs.h"
  12966. +
  12967. +enum { AuSRC, AuDST, AuSrcDst };
  12968. +enum { AuPARENT, AuCHILD, AuParentChild };
  12969. +
  12970. +#define AuRen_ISDIR 1
  12971. +#define AuRen_ISSAMEDIR (1 << 1)
  12972. +#define AuRen_WHSRC (1 << 2)
  12973. +#define AuRen_WHDST (1 << 3)
  12974. +#define AuRen_MNT_WRITE (1 << 4)
  12975. +#define AuRen_DT_DSTDIR (1 << 5)
  12976. +#define AuRen_DIROPQ (1 << 6)
  12977. +#define AuRen_CPUP (1 << 7)
  12978. +#define au_ftest_ren(flags, name) ((flags) & AuRen_##name)
  12979. +#define au_fset_ren(flags, name) { (flags) |= AuRen_##name; }
  12980. +#define au_fclr_ren(flags, name) { (flags) &= ~AuRen_##name; }
  12981. +
  12982. +struct au_ren_args {
  12983. + struct {
  12984. + struct dentry *dentry, *h_dentry, *parent, *h_parent,
  12985. + *wh_dentry;
  12986. + struct inode *dir, *inode;
  12987. + struct au_hinode *hdir;
  12988. + struct au_dtime dt[AuParentChild];
  12989. + aufs_bindex_t bstart;
  12990. + } sd[AuSrcDst];
  12991. +
  12992. +#define src_dentry sd[AuSRC].dentry
  12993. +#define src_dir sd[AuSRC].dir
  12994. +#define src_inode sd[AuSRC].inode
  12995. +#define src_h_dentry sd[AuSRC].h_dentry
  12996. +#define src_parent sd[AuSRC].parent
  12997. +#define src_h_parent sd[AuSRC].h_parent
  12998. +#define src_wh_dentry sd[AuSRC].wh_dentry
  12999. +#define src_hdir sd[AuSRC].hdir
  13000. +#define src_h_dir sd[AuSRC].hdir->hi_inode
  13001. +#define src_dt sd[AuSRC].dt
  13002. +#define src_bstart sd[AuSRC].bstart
  13003. +
  13004. +#define dst_dentry sd[AuDST].dentry
  13005. +#define dst_dir sd[AuDST].dir
  13006. +#define dst_inode sd[AuDST].inode
  13007. +#define dst_h_dentry sd[AuDST].h_dentry
  13008. +#define dst_parent sd[AuDST].parent
  13009. +#define dst_h_parent sd[AuDST].h_parent
  13010. +#define dst_wh_dentry sd[AuDST].wh_dentry
  13011. +#define dst_hdir sd[AuDST].hdir
  13012. +#define dst_h_dir sd[AuDST].hdir->hi_inode
  13013. +#define dst_dt sd[AuDST].dt
  13014. +#define dst_bstart sd[AuDST].bstart
  13015. +
  13016. + struct dentry *h_trap;
  13017. + struct au_branch *br;
  13018. + struct au_hinode *src_hinode;
  13019. + struct path h_path;
  13020. + struct au_nhash whlist;
  13021. + aufs_bindex_t btgt;
  13022. +
  13023. + unsigned int flags;
  13024. +
  13025. + struct au_whtmp_rmdir *thargs;
  13026. + struct dentry *h_dst;
  13027. +};
  13028. +
  13029. +/* ---------------------------------------------------------------------- */
  13030. +
  13031. +/*
  13032. + * functions for reverting.
  13033. + * when an error happened in a single rename systemcall, we should revert
  13034. + * everything as if nothing happend.
  13035. + * we don't need to revert the copied-up/down the parent dir since they are
  13036. + * harmless.
  13037. + */
  13038. +
  13039. +#define RevertFailure(fmt, args...) do { \
  13040. + AuIOErr("revert failure: " fmt " (%d, %d)\n", \
  13041. + ##args, err, rerr); \
  13042. + err = -EIO; \
  13043. +} while (0)
  13044. +
  13045. +static void au_ren_rev_diropq(int err, struct au_ren_args *a)
  13046. +{
  13047. + int rerr;
  13048. +
  13049. + au_hin_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
  13050. + rerr = au_diropq_remove(a->src_dentry, a->btgt);
  13051. + au_hin_imtx_unlock(a->src_hinode);
  13052. + if (rerr)
  13053. + RevertFailure("remove diropq %.*s", AuDLNPair(a->src_dentry));
  13054. +}
  13055. +
  13056. +
  13057. +static void au_ren_rev_rename(int err, struct au_ren_args *a)
  13058. +{
  13059. + int rerr;
  13060. +
  13061. + a->h_path.dentry = au_lkup_one(&a->src_dentry->d_name, a->src_h_parent,
  13062. + a->br, /*nd*/NULL);
  13063. + rerr = PTR_ERR(a->h_path.dentry);
  13064. + if (IS_ERR(a->h_path.dentry)) {
  13065. + RevertFailure("au_lkup_one %.*s", AuDLNPair(a->src_dentry));
  13066. + return;
  13067. + }
  13068. +
  13069. + rerr = vfsub_rename(a->dst_h_dir,
  13070. + au_h_dptr(a->src_dentry, a->btgt),
  13071. + a->src_h_dir, &a->h_path);
  13072. + d_drop(a->h_path.dentry);
  13073. + dput(a->h_path.dentry);
  13074. + /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
  13075. + if (rerr)
  13076. + RevertFailure("rename %.*s", AuDLNPair(a->src_dentry));
  13077. +}
  13078. +
  13079. +static void au_ren_rev_cpup(int err, struct au_ren_args *a)
  13080. +{
  13081. + int rerr;
  13082. +
  13083. + a->h_path.dentry = a->dst_h_dentry;
  13084. + rerr = vfsub_unlink(a->dst_h_dir, &a->h_path, /*force*/0);
  13085. + au_set_h_dptr(a->src_dentry, a->btgt, NULL);
  13086. + au_set_dbstart(a->src_dentry, a->src_bstart);
  13087. + if (rerr)
  13088. + RevertFailure("unlink %.*s", AuDLNPair(a->dst_h_dentry));
  13089. +}
  13090. +
  13091. +
  13092. +static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
  13093. +{
  13094. + int rerr;
  13095. +
  13096. + a->h_path.dentry = au_lkup_one(&a->dst_dentry->d_name, a->dst_h_parent,
  13097. + a->br, /*nd*/NULL);
  13098. + rerr = PTR_ERR(a->h_path.dentry);
  13099. + if (IS_ERR(a->h_path.dentry)) {
  13100. + RevertFailure("lookup %.*s", AuDLNPair(a->dst_dentry));
  13101. + return;
  13102. + }
  13103. + if (a->h_path.dentry->d_inode) {
  13104. + d_drop(a->h_path.dentry);
  13105. + dput(a->h_path.dentry);
  13106. + return;
  13107. + }
  13108. +
  13109. + rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path);
  13110. + d_drop(a->h_path.dentry);
  13111. + dput(a->h_path.dentry);
  13112. + if (!rerr) {
  13113. + au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
  13114. + au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
  13115. + } else
  13116. + RevertFailure("rename %.*s", AuDLNPair(a->h_dst));
  13117. +}
  13118. +
  13119. +static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
  13120. +{
  13121. + int rerr;
  13122. +
  13123. + a->h_path.dentry = a->src_wh_dentry;
  13124. + rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
  13125. + if (rerr)
  13126. + RevertFailure("unlink %.*s", AuDLNPair(a->src_wh_dentry));
  13127. +}
  13128. +
  13129. +static void au_ren_rev_drop(struct au_ren_args *a)
  13130. +{
  13131. + struct dentry *d, *h_d;
  13132. + int i;
  13133. + aufs_bindex_t bend, bindex;
  13134. +
  13135. + for (i = 0; i < AuSrcDst; i++) {
  13136. + d = a->sd[i].dentry;
  13137. + d_drop(d);
  13138. + bend = au_dbend(d);
  13139. + for (bindex = au_dbstart(d); bindex <= bend; bindex++) {
  13140. + h_d = au_h_dptr(d, bindex);
  13141. + if (h_d)
  13142. + d_drop(h_d);
  13143. + }
  13144. + }
  13145. +
  13146. + au_update_dbstart(a->dst_dentry);
  13147. + if (a->thargs)
  13148. + d_drop(a->h_dst);
  13149. +}
  13150. +#undef RevertFailure
  13151. +
  13152. +/* ---------------------------------------------------------------------- */
  13153. +
  13154. +/*
  13155. + * when we have to copyup the renaming entry, do it with the rename-target name
  13156. + * in order to minimize the cost (the later actual rename is unnecessary).
  13157. + * otherwise rename it on the target branch.
  13158. + */
  13159. +static int au_ren_or_cpup(struct au_ren_args *a)
  13160. +{
  13161. + int err;
  13162. + struct dentry *d;
  13163. +
  13164. + d = a->src_dentry;
  13165. + if (au_dbstart(d) == a->btgt) {
  13166. + a->h_path.dentry = a->dst_h_dentry;
  13167. + if (au_ftest_ren(a->flags, DIROPQ)
  13168. + && au_dbdiropq(d) == a->btgt)
  13169. + au_fclr_ren(a->flags, DIROPQ);
  13170. + AuDebugOn(au_dbstart(d) != a->btgt);
  13171. + err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
  13172. + a->dst_h_dir, &a->h_path);
  13173. + } else {
  13174. + struct mutex *h_mtx = &a->src_h_dentry->d_inode->i_mutex;
  13175. +
  13176. + au_fset_ren(a->flags, CPUP);
  13177. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  13178. + au_set_dbstart(d, a->btgt);
  13179. + au_set_h_dptr(d, a->btgt, dget(a->dst_h_dentry));
  13180. + err = au_sio_cpup_single(d, a->btgt, a->src_bstart, -1,
  13181. + !AuCpup_DTIME, a->dst_parent);
  13182. + if (unlikely(err)) {
  13183. + au_set_h_dptr(d, a->btgt, NULL);
  13184. + au_set_dbstart(d, a->src_bstart);
  13185. + }
  13186. + mutex_unlock(h_mtx);
  13187. + }
  13188. +
  13189. + return err;
  13190. +}
  13191. +
  13192. +/* cf. aufs_rmdir() */
  13193. +static int au_ren_del_whtmp(struct au_ren_args *a)
  13194. +{
  13195. + int err;
  13196. + struct inode *dir;
  13197. +
  13198. + dir = a->dst_dir;
  13199. + SiMustAnyLock(dir->i_sb);
  13200. + if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
  13201. + au_sbi(dir->i_sb)->si_dirwh)
  13202. + || au_test_fs_remote(a->h_dst->d_sb)) {
  13203. + err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
  13204. + if (unlikely(err))
  13205. + AuWarn("failed removing whtmp dir %.*s (%d), "
  13206. + "ignored.\n", AuDLNPair(a->h_dst), err);
  13207. + } else {
  13208. + au_nhash_wh_free(&a->thargs->whlist);
  13209. + a->thargs->whlist = a->whlist;
  13210. + a->whlist.nh_num = 0;
  13211. + au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
  13212. + dput(a->h_dst);
  13213. + a->thargs = NULL;
  13214. + }
  13215. +
  13216. + return 0;
  13217. +}
  13218. +
  13219. +/* make it 'opaque' dir. */
  13220. +static int au_ren_diropq(struct au_ren_args *a)
  13221. +{
  13222. + int err;
  13223. + struct dentry *diropq;
  13224. +
  13225. + err = 0;
  13226. + a->src_hinode = au_hi(a->src_inode, a->btgt);
  13227. + au_hin_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
  13228. + diropq = au_diropq_create(a->src_dentry, a->btgt);
  13229. + au_hin_imtx_unlock(a->src_hinode);
  13230. + if (IS_ERR(diropq))
  13231. + err = PTR_ERR(diropq);
  13232. + dput(diropq);
  13233. +
  13234. + return err;
  13235. +}
  13236. +
  13237. +static int do_rename(struct au_ren_args *a)
  13238. +{
  13239. + int err;
  13240. + struct dentry *d, *h_d;
  13241. +
  13242. + /* prepare workqueue args for asynchronous rmdir */
  13243. + h_d = a->dst_h_dentry;
  13244. + if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) {
  13245. + err = -ENOMEM;
  13246. + a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS);
  13247. + if (unlikely(!a->thargs))
  13248. + goto out;
  13249. + a->h_dst = dget(h_d);
  13250. + }
  13251. +
  13252. + /* create whiteout for src_dentry */
  13253. + if (au_ftest_ren(a->flags, WHSRC)) {
  13254. + a->src_wh_dentry
  13255. + = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent);
  13256. + err = PTR_ERR(a->src_wh_dentry);
  13257. + if (IS_ERR(a->src_wh_dentry))
  13258. + goto out_thargs;
  13259. + }
  13260. +
  13261. + /* lookup whiteout for dentry */
  13262. + if (au_ftest_ren(a->flags, WHDST)) {
  13263. + h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name,
  13264. + a->br);
  13265. + err = PTR_ERR(h_d);
  13266. + if (IS_ERR(h_d))
  13267. + goto out_whsrc;
  13268. + if (!h_d->d_inode)
  13269. + dput(h_d);
  13270. + else
  13271. + a->dst_wh_dentry = h_d;
  13272. + }
  13273. +
  13274. + /* rename dentry to tmpwh */
  13275. + if (a->thargs) {
  13276. + err = au_whtmp_ren(a->dst_h_dentry, a->br);
  13277. + if (unlikely(err))
  13278. + goto out_whdst;
  13279. +
  13280. + d = a->dst_dentry;
  13281. + au_set_h_dptr(d, a->btgt, NULL);
  13282. + err = au_lkup_neg(d, a->btgt);
  13283. + if (unlikely(err))
  13284. + goto out_whtmp;
  13285. + a->dst_h_dentry = au_h_dptr(d, a->btgt);
  13286. + }
  13287. +
  13288. + /* cpup src */
  13289. + if (a->dst_h_dentry->d_inode && a->src_bstart != a->btgt) {
  13290. + struct mutex *h_mtx = &a->src_h_dentry->d_inode->i_mutex;
  13291. +
  13292. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  13293. + err = au_sio_cpup_simple(a->src_dentry, a->btgt, -1,
  13294. + !AuCpup_DTIME);
  13295. + mutex_unlock(h_mtx);
  13296. + if (unlikely(err))
  13297. + goto out_whtmp;
  13298. + }
  13299. +
  13300. + /* rename by vfs_rename or cpup */
  13301. + d = a->dst_dentry;
  13302. + if (au_ftest_ren(a->flags, ISDIR)
  13303. + && (a->dst_wh_dentry
  13304. + || au_dbdiropq(d) == a->btgt
  13305. + /* hide the lower to keep xino */
  13306. + || a->btgt < au_dbend(d)
  13307. + || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ)))
  13308. + au_fset_ren(a->flags, DIROPQ);
  13309. + err = au_ren_or_cpup(a);
  13310. + if (unlikely(err))
  13311. + /* leave the copied-up one */
  13312. + goto out_whtmp;
  13313. +
  13314. + /* make dir opaque */
  13315. + if (au_ftest_ren(a->flags, DIROPQ)) {
  13316. + err = au_ren_diropq(a);
  13317. + if (unlikely(err))
  13318. + goto out_rename;
  13319. + }
  13320. +
  13321. + /* update target timestamps */
  13322. + AuDebugOn(au_dbstart(a->src_dentry) != a->btgt);
  13323. + a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
  13324. + vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
  13325. + a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
  13326. +
  13327. + /* remove whiteout for dentry */
  13328. + if (a->dst_wh_dentry) {
  13329. + a->h_path.dentry = a->dst_wh_dentry;
  13330. + err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
  13331. + a->dst_dentry);
  13332. + if (unlikely(err))
  13333. + goto out_diropq;
  13334. + }
  13335. +
  13336. + /* remove whtmp */
  13337. + if (a->thargs)
  13338. + au_ren_del_whtmp(a); /* ignore this error */
  13339. +
  13340. + err = 0;
  13341. + goto out_success;
  13342. +
  13343. + out_diropq:
  13344. + if (au_ftest_ren(a->flags, DIROPQ))
  13345. + au_ren_rev_diropq(err, a);
  13346. + out_rename:
  13347. + if (!au_ftest_ren(a->flags, CPUP))
  13348. + au_ren_rev_rename(err, a);
  13349. + else
  13350. + au_ren_rev_cpup(err, a);
  13351. + out_whtmp:
  13352. + if (a->thargs)
  13353. + au_ren_rev_whtmp(err, a);
  13354. + out_whdst:
  13355. + dput(a->dst_wh_dentry);
  13356. + a->dst_wh_dentry = NULL;
  13357. + out_whsrc:
  13358. + if (a->src_wh_dentry)
  13359. + au_ren_rev_whsrc(err, a);
  13360. + au_ren_rev_drop(a);
  13361. + out_success:
  13362. + dput(a->src_wh_dentry);
  13363. + dput(a->dst_wh_dentry);
  13364. + out_thargs:
  13365. + if (a->thargs) {
  13366. + dput(a->h_dst);
  13367. + au_whtmp_rmdir_free(a->thargs);
  13368. + a->thargs = NULL;
  13369. + }
  13370. + out:
  13371. + return err;
  13372. +}
  13373. +
  13374. +/* ---------------------------------------------------------------------- */
  13375. +
  13376. +/*
  13377. + * test if @dentry dir can be rename destination or not.
  13378. + * success means, it is a logically empty dir.
  13379. + */
  13380. +static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
  13381. +{
  13382. + return au_test_empty(dentry, whlist);
  13383. +}
  13384. +
  13385. +/*
  13386. + * test if @dentry dir can be rename source or not.
  13387. + * if it can, return 0 and @children is filled.
  13388. + * success means,
  13389. + * - it is a logically empty dir.
  13390. + * - or, it exists on writable branch and has no children including whiteouts
  13391. + * on the lower branch.
  13392. + */
  13393. +static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt)
  13394. +{
  13395. + int err;
  13396. + aufs_bindex_t bstart;
  13397. +
  13398. + bstart = au_dbstart(dentry);
  13399. + if (bstart != btgt) {
  13400. + struct au_nhash whlist;
  13401. +
  13402. + SiMustAnyLock(dentry->d_sb);
  13403. + err = au_nhash_alloc(&whlist, au_sbi(dentry->d_sb)->si_rdhash,
  13404. + GFP_NOFS);
  13405. + if (unlikely(err))
  13406. + goto out;
  13407. + err = au_test_empty(dentry, &whlist);
  13408. + au_nhash_wh_free(&whlist);
  13409. + goto out;
  13410. + }
  13411. +
  13412. + if (bstart == au_dbtaildir(dentry))
  13413. + return 0; /* success */
  13414. +
  13415. + err = au_test_empty_lower(dentry);
  13416. +
  13417. + out:
  13418. + if (err == -ENOTEMPTY) {
  13419. + AuWarn1("renaming dir who has child(ren) on multiple branches,"
  13420. + " is not supported\n");
  13421. + err = -EXDEV;
  13422. + }
  13423. + return err;
  13424. +}
  13425. +
  13426. +/* side effect: sets whlist and h_dentry */
  13427. +static int au_ren_may_dir(struct au_ren_args *a)
  13428. +{
  13429. + int err;
  13430. + struct dentry *d;
  13431. +
  13432. + d = a->dst_dentry;
  13433. + SiMustAnyLock(d->d_sb);
  13434. + err = au_nhash_alloc(&a->whlist, au_sbi(d->d_sb)->si_rdhash, GFP_NOFS);
  13435. + if (unlikely(err))
  13436. + goto out;
  13437. +
  13438. + err = 0;
  13439. + if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) {
  13440. + au_set_dbstart(d, a->dst_bstart);
  13441. + err = may_rename_dstdir(d, &a->whlist);
  13442. + au_set_dbstart(d, a->btgt);
  13443. + }
  13444. + a->dst_h_dentry = au_h_dptr(d, au_dbstart(d));
  13445. + if (unlikely(err))
  13446. + goto out;
  13447. +
  13448. + d = a->src_dentry;
  13449. + a->src_h_dentry = au_h_dptr(d, au_dbstart(d));
  13450. + if (au_ftest_ren(a->flags, ISDIR)) {
  13451. + err = may_rename_srcdir(d, a->btgt);
  13452. + if (unlikely(err)) {
  13453. + au_nhash_wh_free(&a->whlist);
  13454. + a->whlist.nh_num = 0;
  13455. + }
  13456. + }
  13457. + out:
  13458. + return err;
  13459. +}
  13460. +
  13461. +/* ---------------------------------------------------------------------- */
  13462. +
  13463. +/*
  13464. + * simple tests for rename.
  13465. + * following the checks in vfs, plus the parent-child relationship.
  13466. + */
  13467. +static int au_may_ren(struct au_ren_args *a)
  13468. +{
  13469. + int err, isdir;
  13470. + struct inode *h_inode;
  13471. +
  13472. + if (a->src_bstart == a->btgt) {
  13473. + err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
  13474. + au_ftest_ren(a->flags, ISDIR));
  13475. + if (unlikely(err))
  13476. + goto out;
  13477. + err = -EINVAL;
  13478. + if (unlikely(a->src_h_dentry == a->h_trap))
  13479. + goto out;
  13480. + }
  13481. +
  13482. + err = 0;
  13483. + if (a->dst_bstart != a->btgt)
  13484. + goto out;
  13485. +
  13486. + err = -EIO;
  13487. + h_inode = a->dst_h_dentry->d_inode;
  13488. + isdir = !!au_ftest_ren(a->flags, ISDIR);
  13489. + if (!a->dst_dentry->d_inode) {
  13490. + if (unlikely(h_inode))
  13491. + goto out;
  13492. + err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent,
  13493. + isdir);
  13494. + } else {
  13495. + if (unlikely(!h_inode || !h_inode->i_nlink))
  13496. + goto out;
  13497. + err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent,
  13498. + isdir);
  13499. + if (unlikely(err))
  13500. + goto out;
  13501. + err = -ENOTEMPTY;
  13502. + if (unlikely(a->dst_h_dentry == a->h_trap))
  13503. + goto out;
  13504. + err = 0;
  13505. + }
  13506. +
  13507. + out:
  13508. + if (unlikely(err == -ENOENT || err == -EEXIST))
  13509. + err = -EIO;
  13510. + return err;
  13511. +}
  13512. +
  13513. +/* ---------------------------------------------------------------------- */
  13514. +
  13515. +/*
  13516. + * locking order
  13517. + * (VFS)
  13518. + * - src_dir and dir by lock_rename()
  13519. + * - inode if exitsts
  13520. + * (aufs)
  13521. + * - lock all
  13522. + * + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
  13523. + * + si_read_lock
  13524. + * + di_write_lock2_child()
  13525. + * + di_write_lock_child()
  13526. + * + ii_write_lock_child()
  13527. + * + di_write_lock_child2()
  13528. + * + ii_write_lock_child2()
  13529. + * + src_parent and parent
  13530. + * + di_write_lock_parent()
  13531. + * + ii_write_lock_parent()
  13532. + * + di_write_lock_parent2()
  13533. + * + ii_write_lock_parent2()
  13534. + * + lower src_dir and dir by vfsub_lock_rename()
  13535. + * + verify the every relationships between child and parent. if any
  13536. + * of them failed, unlock all and return -EBUSY.
  13537. + */
  13538. +static void au_ren_unlock(struct au_ren_args *a)
  13539. +{
  13540. + struct super_block *sb;
  13541. +
  13542. + sb = a->dst_dentry->d_sb;
  13543. + if (au_ftest_ren(a->flags, MNT_WRITE))
  13544. + mnt_drop_write(a->br->br_mnt);
  13545. + vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
  13546. + a->dst_h_parent, a->dst_hdir);
  13547. +}
  13548. +
  13549. +static int au_ren_lock(struct au_ren_args *a)
  13550. +{
  13551. + int err;
  13552. + unsigned int udba;
  13553. +
  13554. + err = 0;
  13555. + a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
  13556. + a->src_hdir = au_hi(a->src_dir, a->btgt);
  13557. + a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
  13558. + a->dst_hdir = au_hi(a->dst_dir, a->btgt);
  13559. + a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
  13560. + a->dst_h_parent, a->dst_hdir);
  13561. + udba = au_opt_udba(a->src_dentry->d_sb);
  13562. + if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode
  13563. + || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode))
  13564. + err = au_busy_or_stale();
  13565. + if (!err && au_dbstart(a->src_dentry) == a->btgt)
  13566. + err = au_h_verify(a->src_h_dentry, udba,
  13567. + a->src_h_parent->d_inode, a->src_h_parent,
  13568. + a->br);
  13569. + if (!err && au_dbstart(a->dst_dentry) == a->btgt)
  13570. + err = au_h_verify(a->dst_h_dentry, udba,
  13571. + a->dst_h_parent->d_inode, a->dst_h_parent,
  13572. + a->br);
  13573. + if (!err) {
  13574. + err = mnt_want_write(a->br->br_mnt);
  13575. + if (unlikely(err))
  13576. + goto out_unlock;
  13577. + au_fset_ren(a->flags, MNT_WRITE);
  13578. + goto out; /* success */
  13579. + }
  13580. +
  13581. + err = au_busy_or_stale();
  13582. +
  13583. + out_unlock:
  13584. + au_ren_unlock(a);
  13585. + out:
  13586. + return err;
  13587. +}
  13588. +
  13589. +/* ---------------------------------------------------------------------- */
  13590. +
  13591. +static void au_ren_refresh_dir(struct au_ren_args *a)
  13592. +{
  13593. + struct inode *dir;
  13594. +
  13595. + dir = a->dst_dir;
  13596. + dir->i_version++;
  13597. + if (au_ftest_ren(a->flags, ISDIR)) {
  13598. + /* is this updating defined in POSIX? */
  13599. + au_cpup_attr_timesizes(a->src_inode);
  13600. + au_cpup_attr_nlink(dir, /*force*/1);
  13601. + if (a->dst_inode) {
  13602. + clear_nlink(a->dst_inode);
  13603. + au_cpup_attr_timesizes(a->dst_inode);
  13604. + }
  13605. + }
  13606. + if (au_ibstart(dir) == a->btgt)
  13607. + au_cpup_attr_timesizes(dir);
  13608. +
  13609. + if (au_ftest_ren(a->flags, ISSAMEDIR))
  13610. + return;
  13611. +
  13612. + dir = a->src_dir;
  13613. + dir->i_version++;
  13614. + if (au_ftest_ren(a->flags, ISDIR))
  13615. + au_cpup_attr_nlink(dir, /*force*/1);
  13616. + if (au_ibstart(dir) == a->btgt)
  13617. + au_cpup_attr_timesizes(dir);
  13618. +}
  13619. +
  13620. +static void au_ren_refresh(struct au_ren_args *a)
  13621. +{
  13622. + aufs_bindex_t bend, bindex;
  13623. + struct dentry *d, *h_d;
  13624. + struct inode *i, *h_i;
  13625. + struct super_block *sb;
  13626. +
  13627. + d = a->src_dentry;
  13628. + au_set_dbwh(d, -1);
  13629. + bend = au_dbend(d);
  13630. + for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
  13631. + h_d = au_h_dptr(d, bindex);
  13632. + if (h_d)
  13633. + au_set_h_dptr(d, bindex, NULL);
  13634. + }
  13635. + au_set_dbend(d, a->btgt);
  13636. +
  13637. + sb = d->d_sb;
  13638. + i = a->src_inode;
  13639. + if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
  13640. + return; /* success */
  13641. +
  13642. + bend = au_ibend(i);
  13643. + for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
  13644. + h_i = au_h_iptr(i, bindex);
  13645. + if (h_i) {
  13646. + au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
  13647. + /* ignore this error */
  13648. + au_set_h_iptr(i, bindex, NULL, 0);
  13649. + }
  13650. + }
  13651. + au_set_ibend(i, a->btgt);
  13652. +}
  13653. +
  13654. +/* ---------------------------------------------------------------------- */
  13655. +
  13656. +/* mainly for link(2) and rename(2) */
  13657. +int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
  13658. +{
  13659. + aufs_bindex_t bdiropq, bwh;
  13660. + struct dentry *parent;
  13661. + struct au_branch *br;
  13662. +
  13663. + parent = dentry->d_parent;
  13664. + IMustLock(parent->d_inode); /* dir is locked */
  13665. +
  13666. + bdiropq = au_dbdiropq(parent);
  13667. + bwh = au_dbwh(dentry);
  13668. + br = au_sbr(dentry->d_sb, btgt);
  13669. + if (au_br_rdonly(br)
  13670. + || (0 <= bdiropq && bdiropq < btgt)
  13671. + || (0 <= bwh && bwh < btgt))
  13672. + btgt = -1;
  13673. +
  13674. + AuDbg("btgt %d\n", btgt);
  13675. + return btgt;
  13676. +}
  13677. +
  13678. +/* sets src_bstart, dst_bstart and btgt */
  13679. +static int au_ren_wbr(struct au_ren_args *a)
  13680. +{
  13681. + int err;
  13682. + struct au_wr_dir_args wr_dir_args = {
  13683. + /* .force_btgt = -1, */
  13684. + .flags = AuWrDir_ADD_ENTRY
  13685. + };
  13686. +
  13687. + a->src_bstart = au_dbstart(a->src_dentry);
  13688. + a->dst_bstart = au_dbstart(a->dst_dentry);
  13689. + if (au_ftest_ren(a->flags, ISDIR))
  13690. + au_fset_wrdir(wr_dir_args.flags, ISDIR);
  13691. + wr_dir_args.force_btgt = a->src_bstart;
  13692. + if (a->dst_inode && a->dst_bstart < a->src_bstart)
  13693. + wr_dir_args.force_btgt = a->dst_bstart;
  13694. + wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
  13695. + err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
  13696. + a->btgt = err;
  13697. +
  13698. + return err;
  13699. +}
  13700. +
  13701. +static void au_ren_dt(struct au_ren_args *a)
  13702. +{
  13703. + a->h_path.dentry = a->src_h_parent;
  13704. + au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
  13705. + if (!au_ftest_ren(a->flags, ISSAMEDIR)) {
  13706. + a->h_path.dentry = a->dst_h_parent;
  13707. + au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
  13708. + }
  13709. +
  13710. + au_fclr_ren(a->flags, DT_DSTDIR);
  13711. + if (!au_ftest_ren(a->flags, ISDIR))
  13712. + return;
  13713. +
  13714. + a->h_path.dentry = a->src_h_dentry;
  13715. + au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
  13716. + if (a->dst_h_dentry->d_inode) {
  13717. + au_fset_ren(a->flags, DT_DSTDIR);
  13718. + a->h_path.dentry = a->dst_h_dentry;
  13719. + au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
  13720. + }
  13721. +}
  13722. +
  13723. +static void au_ren_rev_dt(int err, struct au_ren_args *a)
  13724. +{
  13725. + struct dentry *h_d;
  13726. + struct mutex *h_mtx;
  13727. +
  13728. + au_dtime_revert(a->src_dt + AuPARENT);
  13729. + if (!au_ftest_ren(a->flags, ISSAMEDIR))
  13730. + au_dtime_revert(a->dst_dt + AuPARENT);
  13731. +
  13732. + if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) {
  13733. + h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
  13734. + h_mtx = &h_d->d_inode->i_mutex;
  13735. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  13736. + au_dtime_revert(a->src_dt + AuCHILD);
  13737. + mutex_unlock(h_mtx);
  13738. +
  13739. + if (au_ftest_ren(a->flags, DT_DSTDIR)) {
  13740. + h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
  13741. + h_mtx = &h_d->d_inode->i_mutex;
  13742. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  13743. + au_dtime_revert(a->dst_dt + AuCHILD);
  13744. + mutex_unlock(h_mtx);
  13745. + }
  13746. + }
  13747. +}
  13748. +
  13749. +/* ---------------------------------------------------------------------- */
  13750. +
  13751. +int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
  13752. + struct inode *_dst_dir, struct dentry *_dst_dentry)
  13753. +{
  13754. + int err;
  13755. + /* reduce stack space */
  13756. + struct au_ren_args *a;
  13757. +
  13758. + IMustLock(_src_dir);
  13759. + IMustLock(_dst_dir);
  13760. +
  13761. + err = -ENOMEM;
  13762. + BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
  13763. + a = kzalloc(sizeof(*a), GFP_NOFS);
  13764. + if (unlikely(!a))
  13765. + goto out;
  13766. +
  13767. + a->src_dir = _src_dir;
  13768. + a->src_dentry = _src_dentry;
  13769. + a->src_inode = a->src_dentry->d_inode;
  13770. + a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
  13771. + a->dst_dir = _dst_dir;
  13772. + a->dst_dentry = _dst_dentry;
  13773. + a->dst_inode = a->dst_dentry->d_inode;
  13774. + a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
  13775. + if (a->dst_inode) {
  13776. + IMustLock(a->dst_inode);
  13777. + au_igrab(a->dst_inode);
  13778. + }
  13779. +
  13780. + err = -ENOTDIR;
  13781. + if (S_ISDIR(a->src_inode->i_mode)) {
  13782. + au_fset_ren(a->flags, ISDIR);
  13783. + if (unlikely(a->dst_inode && !S_ISDIR(a->dst_inode->i_mode)))
  13784. + goto out_free;
  13785. + aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
  13786. + AuLock_DIR | AuLock_FLUSH);
  13787. + } else
  13788. + aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
  13789. + AuLock_FLUSH);
  13790. +
  13791. + au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
  13792. + di_write_lock_parent(a->dst_parent);
  13793. +
  13794. + /* which branch we process */
  13795. + err = au_ren_wbr(a);
  13796. + if (unlikely(err < 0))
  13797. + goto out_unlock;
  13798. + a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
  13799. + a->h_path.mnt = a->br->br_mnt;
  13800. +
  13801. + /* are they available to be renamed */
  13802. + err = au_ren_may_dir(a);
  13803. + if (unlikely(err))
  13804. + goto out_unlock;
  13805. +
  13806. + /* prepare the writable parent dir on the same branch */
  13807. + if (a->dst_bstart == a->btgt) {
  13808. + au_fset_ren(a->flags, WHDST);
  13809. + } else {
  13810. + err = au_cpup_dirs(a->dst_dentry, a->btgt);
  13811. + if (unlikely(err))
  13812. + goto out_children;
  13813. + }
  13814. +
  13815. + if (a->src_dir != a->dst_dir) {
  13816. + /*
  13817. + * this temporary unlock is safe,
  13818. + * because both dir->i_mutex are locked.
  13819. + */
  13820. + di_write_unlock(a->dst_parent);
  13821. + di_write_lock_parent(a->src_parent);
  13822. + err = au_wr_dir_need_wh(a->src_dentry,
  13823. + au_ftest_ren(a->flags, ISDIR),
  13824. + &a->btgt);
  13825. + di_write_unlock(a->src_parent);
  13826. + di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1);
  13827. + au_fclr_ren(a->flags, ISSAMEDIR);
  13828. + } else
  13829. + err = au_wr_dir_need_wh(a->src_dentry,
  13830. + au_ftest_ren(a->flags, ISDIR),
  13831. + &a->btgt);
  13832. + if (unlikely(err < 0))
  13833. + goto out_children;
  13834. + if (err)
  13835. + au_fset_ren(a->flags, WHSRC);
  13836. +
  13837. + /* lock them all */
  13838. + err = au_ren_lock(a);
  13839. + if (unlikely(err))
  13840. + goto out_children;
  13841. +
  13842. + if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE)) {
  13843. + err = au_may_ren(a);
  13844. + if (unlikely(err))
  13845. + goto out_hdir;
  13846. + }
  13847. +
  13848. + /* store timestamps to be revertible */
  13849. + au_ren_dt(a);
  13850. +
  13851. + /* here we go */
  13852. + err = do_rename(a);
  13853. + if (unlikely(err))
  13854. + goto out_dt;
  13855. +
  13856. + /* update dir attributes */
  13857. + au_ren_refresh_dir(a);
  13858. +
  13859. + /* dput/iput all lower dentries */
  13860. + au_ren_refresh(a);
  13861. +
  13862. + goto out_hdir; /* success */
  13863. +
  13864. + out_dt:
  13865. + au_ren_rev_dt(err, a);
  13866. + out_hdir:
  13867. + au_ren_unlock(a);
  13868. + out_children:
  13869. + au_nhash_wh_free(&a->whlist);
  13870. + out_unlock:
  13871. + if (unlikely(err && au_ftest_ren(a->flags, ISDIR))) {
  13872. + au_update_dbstart(a->dst_dentry);
  13873. + d_drop(a->dst_dentry);
  13874. + }
  13875. + if (!err)
  13876. + d_move(a->src_dentry, a->dst_dentry);
  13877. + if (au_ftest_ren(a->flags, ISSAMEDIR))
  13878. + di_write_unlock(a->dst_parent);
  13879. + else
  13880. + di_write_unlock2(a->src_parent, a->dst_parent);
  13881. + aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
  13882. + out_free:
  13883. + iput(a->dst_inode);
  13884. + if (a->thargs)
  13885. + au_whtmp_rmdir_free(a->thargs);
  13886. + kfree(a);
  13887. + out:
  13888. + return err;
  13889. +}
  13890. diff -Nur linux-2.6.31.5.orig/fs/aufs/Kconfig linux-2.6.31.5/fs/aufs/Kconfig
  13891. --- linux-2.6.31.5.orig/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100
  13892. +++ linux-2.6.31.5/fs/aufs/Kconfig 2009-11-15 22:02:37.000000000 +0100
  13893. @@ -0,0 +1,132 @@
  13894. +config AUFS_FS
  13895. + tristate "Aufs (Advanced multi layered unification filesystem) support"
  13896. + depends on EXPERIMENTAL
  13897. + help
  13898. + Aufs is a stackable unification filesystem such as Unionfs,
  13899. + which unifies several directories and provides a merged single
  13900. + directory.
  13901. + In the early days, aufs was entirely re-designed and
  13902. + re-implemented Unionfs Version 1.x series. Introducing many
  13903. + original ideas, approaches and improvements, it becomes totally
  13904. + different from Unionfs while keeping the basic features.
  13905. +
  13906. +if AUFS_FS
  13907. +choice
  13908. + prompt "Maximum number of branches"
  13909. + default AUFS_BRANCH_MAX_127
  13910. + help
  13911. + Specifies the maximum number of branches (or member directories)
  13912. + in a single aufs. The larger value consumes more system
  13913. + resources and has a minor impact to performance.
  13914. +config AUFS_BRANCH_MAX_127
  13915. + bool "127"
  13916. + help
  13917. + Specifies the maximum number of branches (or member directories)
  13918. + in a single aufs. The larger value consumes more system
  13919. + resources and has a minor impact to performance.
  13920. +config AUFS_BRANCH_MAX_511
  13921. + bool "511"
  13922. + help
  13923. + Specifies the maximum number of branches (or member directories)
  13924. + in a single aufs. The larger value consumes more system
  13925. + resources and has a minor impact to performance.
  13926. +config AUFS_BRANCH_MAX_1023
  13927. + bool "1023"
  13928. + help
  13929. + Specifies the maximum number of branches (or member directories)
  13930. + in a single aufs. The larger value consumes more system
  13931. + resources and has a minor impact to performance.
  13932. +config AUFS_BRANCH_MAX_32767
  13933. + bool "32767"
  13934. + help
  13935. + Specifies the maximum number of branches (or member directories)
  13936. + in a single aufs. The larger value consumes more system
  13937. + resources and has a minor impact to performance.
  13938. +endchoice
  13939. +
  13940. +config AUFS_HINOTIFY
  13941. + bool "Use inotify to detect actions on a branch"
  13942. + depends on INOTIFY
  13943. + help
  13944. + If you want to modify files on branches directly, eg. bypassing aufs,
  13945. + and want aufs to detect the changes of them fully, then enable this
  13946. + option and use 'udba=inotify' mount option.
  13947. + It will have a negative impact to the performance.
  13948. + See detail in aufs.5.
  13949. +
  13950. +config AUFS_EXPORT
  13951. + bool "NFS-exportable aufs"
  13952. + depends on (AUFS_FS = y && EXPORTFS = y) || (AUFS_FS = m && EXPORTFS)
  13953. + help
  13954. + If you want to export your mounted aufs via NFS, then enable this
  13955. + option. There are several requirements for this configuration.
  13956. + See detail in aufs.5.
  13957. +
  13958. +config AUFS_SHWH
  13959. + bool "Show whiteouts"
  13960. + help
  13961. + If you want to make the whiteouts in aufs visible, then enable
  13962. + this option and specify 'shwh' mount option. Although it may
  13963. + sounds like philosophy or something, but in technically it
  13964. + simply shows the name of whiteout with keeping its behaviour.
  13965. +
  13966. +config AUFS_BR_RAMFS
  13967. + bool "Ramfs (initramfs/rootfs) as an aufs branch"
  13968. + help
  13969. + If you want to use ramfs as an aufs branch fs, then enable this
  13970. + option. Generally tmpfs is recommended.
  13971. + Aufs prohibited them to be a branch fs by default, because
  13972. + initramfs becomes unusable after switch_root or something
  13973. + generally. If you sets initramfs as an aufs branch and boot your
  13974. + system by switch_root, you will meet a problem easily since the
  13975. + files in initramfs may be inaccessible.
  13976. + Unless you are going to use ramfs as an aufs branch fs without
  13977. + switch_root or something, leave it N.
  13978. +
  13979. +config AUFS_BR_FUSE
  13980. + bool "Fuse fs as an aufs branch"
  13981. + depends on FUSE_FS
  13982. + select AUFS_POLL
  13983. + help
  13984. + If you want to use fuse-based userspace filesystem as an aufs
  13985. + branch fs, then enable this option.
  13986. + It implements the internal poll(2) operation which is
  13987. + implemented by fuse only (curretnly).
  13988. +
  13989. +config AUFS_DEBUG
  13990. + bool "Debug aufs"
  13991. + help
  13992. + Enable this to compile aufs internal debug code.
  13993. + It will have a negative impact to the performance.
  13994. +
  13995. +config AUFS_MAGIC_SYSRQ
  13996. + bool
  13997. + depends on AUFS_DEBUG && MAGIC_SYSRQ
  13998. + default y
  13999. + help
  14000. + Automatic configuration for internal use.
  14001. + When aufs supports Magic SysRq, enabled automatically.
  14002. +
  14003. +config AUFS_BDEV_LOOP
  14004. + bool
  14005. + depends on BLK_DEV_LOOP
  14006. + default y
  14007. + help
  14008. + Automatic configuration for internal use.
  14009. + Convert =[ym] into =y.
  14010. +
  14011. +config AUFS_INO_T_64
  14012. + bool
  14013. + depends on AUFS_EXPORT
  14014. + depends on 64BIT && !(ALPHA || S390)
  14015. + default y
  14016. + help
  14017. + Automatic configuration for internal use.
  14018. + /* typedef unsigned long/int __kernel_ino_t */
  14019. + /* alpha and s390x are int */
  14020. +
  14021. +config AUFS_POLL
  14022. + bool
  14023. + help
  14024. + Automatic configuration for internal use.
  14025. +endif
  14026. diff -Nur linux-2.6.31.5.orig/fs/aufs/loop.c linux-2.6.31.5/fs/aufs/loop.c
  14027. --- linux-2.6.31.5.orig/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100
  14028. +++ linux-2.6.31.5/fs/aufs/loop.c 2009-11-15 22:02:37.000000000 +0100
  14029. @@ -0,0 +1,55 @@
  14030. +/*
  14031. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  14032. + *
  14033. + * This program, aufs is free software; you can redistribute it and/or modify
  14034. + * it under the terms of the GNU General Public License as published by
  14035. + * the Free Software Foundation; either version 2 of the License, or
  14036. + * (at your option) any later version.
  14037. + *
  14038. + * This program is distributed in the hope that it will be useful,
  14039. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14040. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14041. + * GNU General Public License for more details.
  14042. + *
  14043. + * You should have received a copy of the GNU General Public License
  14044. + * along with this program; if not, write to the Free Software
  14045. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14046. + */
  14047. +
  14048. +/*
  14049. + * support for loopback block device as a branch
  14050. + */
  14051. +
  14052. +#include <linux/loop.h>
  14053. +#include "aufs.h"
  14054. +
  14055. +/*
  14056. + * test if two lower dentries have overlapping branches.
  14057. + */
  14058. +int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_d1,
  14059. + struct dentry *h_d2)
  14060. +{
  14061. + struct inode *h_inode;
  14062. + struct loop_device *l;
  14063. +
  14064. + h_inode = h_d1->d_inode;
  14065. + if (MAJOR(h_inode->i_sb->s_dev) != LOOP_MAJOR)
  14066. + return 0;
  14067. +
  14068. + l = h_inode->i_sb->s_bdev->bd_disk->private_data;
  14069. + h_d1 = l->lo_backing_file->f_dentry;
  14070. + /* h_d1 can be local NFS. in this case aufs cannot detect the loop */
  14071. + if (unlikely(h_d1->d_sb == sb))
  14072. + return 1;
  14073. + return !!au_test_subdir(h_d1, h_d2);
  14074. +}
  14075. +
  14076. +/* true if a kernel thread named 'loop[0-9].*' accesses a file */
  14077. +int au_test_loopback_kthread(void)
  14078. +{
  14079. + const char c = current->comm[4];
  14080. +
  14081. + return current->mm == NULL
  14082. + && '0' <= c && c <= '9'
  14083. + && strncmp(current->comm, "loop", 4) == 0;
  14084. +}
  14085. diff -Nur linux-2.6.31.5.orig/fs/aufs/loop.h linux-2.6.31.5/fs/aufs/loop.h
  14086. --- linux-2.6.31.5.orig/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
  14087. +++ linux-2.6.31.5/fs/aufs/loop.h 2009-11-15 22:02:37.000000000 +0100
  14088. @@ -0,0 +1,51 @@
  14089. +/*
  14090. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  14091. + *
  14092. + * This program, aufs is free software; you can redistribute it and/or modify
  14093. + * it under the terms of the GNU General Public License as published by
  14094. + * the Free Software Foundation; either version 2 of the License, or
  14095. + * (at your option) any later version.
  14096. + *
  14097. + * This program is distributed in the hope that it will be useful,
  14098. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14099. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14100. + * GNU General Public License for more details.
  14101. + *
  14102. + * You should have received a copy of the GNU General Public License
  14103. + * along with this program; if not, write to the Free Software
  14104. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14105. + */
  14106. +
  14107. +/*
  14108. + * support for loopback mount as a branch
  14109. + */
  14110. +
  14111. +#ifndef __AUFS_LOOP_H__
  14112. +#define __AUFS_LOOP_H__
  14113. +
  14114. +#ifdef __KERNEL__
  14115. +
  14116. +struct dentry;
  14117. +struct super_block;
  14118. +
  14119. +#ifdef CONFIG_AUFS_BDEV_LOOP
  14120. +/* loop.c */
  14121. +int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_d1,
  14122. + struct dentry *h_d2);
  14123. +int au_test_loopback_kthread(void);
  14124. +#else
  14125. +static inline
  14126. +int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_d1,
  14127. + struct dentry *h_d2)
  14128. +{
  14129. + return 0;
  14130. +}
  14131. +
  14132. +static inline int au_test_loopback_kthread(void)
  14133. +{
  14134. + return 0;
  14135. +}
  14136. +#endif /* BLK_DEV_LOOP */
  14137. +
  14138. +#endif /* __KERNEL__ */
  14139. +#endif /* __AUFS_LOOP_H__ */
  14140. diff -Nur linux-2.6.31.5.orig/fs/aufs/magic.mk linux-2.6.31.5/fs/aufs/magic.mk
  14141. --- linux-2.6.31.5.orig/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100
  14142. +++ linux-2.6.31.5/fs/aufs/magic.mk 2009-11-15 22:02:37.000000000 +0100
  14143. @@ -0,0 +1,52 @@
  14144. +
  14145. +# defined in ${srctree}/fs/fuse/inode.c
  14146. +# tristate
  14147. +ifdef CONFIG_FUSE_FS
  14148. +ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
  14149. +endif
  14150. +
  14151. +# defined in ${srctree}/fs/ocfs2/ocfs2_fs.h
  14152. +# tristate
  14153. +ifdef CONFIG_OCFS2_FS
  14154. +ccflags-y += -DOCFS2_SUPER_MAGIC=0x7461636f
  14155. +endif
  14156. +
  14157. +# defined in ${srctree}/fs/ocfs2/dlm/userdlm.h
  14158. +# tristate
  14159. +ifdef CONFIG_OCFS2_FS_O2CB
  14160. +ccflags-y += -DDLMFS_MAGIC=0x76a9f425
  14161. +endif
  14162. +
  14163. +# defined in ${srctree}/fs/ramfs/inode.c
  14164. +# always true
  14165. +ccflags-y += -DRAMFS_MAGIC=0x858458f6
  14166. +
  14167. +# defined in ${srctree}/fs/cifs/cifsfs.c
  14168. +# tristate
  14169. +ifdef CONFIG_CIFS_FS
  14170. +ccflags-y += -DCIFS_MAGIC_NUMBER=0xFF534D42
  14171. +endif
  14172. +
  14173. +# defined in ${srctree}/fs/xfs/xfs_sb.h
  14174. +# tristate
  14175. +ifdef CONFIG_XFS_FS
  14176. +ccflags-y += -DXFS_SB_MAGIC=0x58465342
  14177. +endif
  14178. +
  14179. +# defined in ${srctree}/fs/configfs/mount.c
  14180. +# tristate
  14181. +ifdef CONFIG_CONFIGFS_FS
  14182. +ccflags-y += -DCONFIGFS_MAGIC=0x62656570
  14183. +endif
  14184. +
  14185. +# defined in ${srctree}/fs/9p/v9fs.h
  14186. +# tristate
  14187. +ifdef CONFIG_9P_FS
  14188. +ccflags-y += -DV9FS_MAGIC=0x01021997
  14189. +endif
  14190. +
  14191. +# defined in ${srctree}/fs/ubifs/ubifs.h
  14192. +# tristate
  14193. +ifdef CONFIG_UBIFS_FS
  14194. +ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
  14195. +endif
  14196. diff -Nur linux-2.6.31.5.orig/fs/aufs/Makefile linux-2.6.31.5/fs/aufs/Makefile
  14197. --- linux-2.6.31.5.orig/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100
  14198. +++ linux-2.6.31.5/fs/aufs/Makefile 2009-11-15 22:02:37.000000000 +0100
  14199. @@ -0,0 +1,23 @@
  14200. +
  14201. +include ${src}/magic.mk
  14202. +-include ${src}/priv_def.mk
  14203. +
  14204. +obj-$(CONFIG_AUFS_FS) += aufs.o
  14205. +aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
  14206. + wkq.o vfsub.o dcsub.o \
  14207. + cpup.o whout.o plink.o wbr_policy.o \
  14208. + dinfo.o dentry.o \
  14209. + finfo.o file.o f_op.o \
  14210. + dir.o vdir.o \
  14211. + iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
  14212. + ioctl.o
  14213. +
  14214. +# all are boolean
  14215. +aufs-$(CONFIG_SYSFS) += sysfs.o
  14216. +aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
  14217. +aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
  14218. +aufs-$(CONFIG_AUFS_HINOTIFY) += hinotify.o
  14219. +aufs-$(CONFIG_AUFS_EXPORT) += export.o
  14220. +aufs-$(CONFIG_AUFS_POLL) += poll.o
  14221. +aufs-$(CONFIG_AUFS_DEBUG) += debug.o
  14222. +aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
  14223. diff -Nur linux-2.6.31.5.orig/fs/aufs/module.c linux-2.6.31.5/fs/aufs/module.c
  14224. --- linux-2.6.31.5.orig/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100
  14225. +++ linux-2.6.31.5/fs/aufs/module.c 2009-11-15 22:02:37.000000000 +0100
  14226. @@ -0,0 +1,173 @@
  14227. +/*
  14228. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  14229. + *
  14230. + * This program, aufs is free software; you can redistribute it and/or modify
  14231. + * it under the terms of the GNU General Public License as published by
  14232. + * the Free Software Foundation; either version 2 of the License, or
  14233. + * (at your option) any later version.
  14234. + *
  14235. + * This program is distributed in the hope that it will be useful,
  14236. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14237. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14238. + * GNU General Public License for more details.
  14239. + *
  14240. + * You should have received a copy of the GNU General Public License
  14241. + * along with this program; if not, write to the Free Software
  14242. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14243. + */
  14244. +
  14245. +/*
  14246. + * module global variables and operations
  14247. + */
  14248. +
  14249. +#include <linux/module.h>
  14250. +#include <linux/seq_file.h>
  14251. +#include "aufs.h"
  14252. +
  14253. +void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp)
  14254. +{
  14255. + if (new_sz <= nused)
  14256. + return p;
  14257. +
  14258. + p = krealloc(p, new_sz, gfp);
  14259. + if (p)
  14260. + memset(p + nused, 0, new_sz - nused);
  14261. + return p;
  14262. +}
  14263. +
  14264. +/* ---------------------------------------------------------------------- */
  14265. +
  14266. +/*
  14267. + * aufs caches
  14268. + */
  14269. +struct kmem_cache *au_cachep[AuCache_Last];
  14270. +static int __init au_cache_init(void)
  14271. +{
  14272. + au_cachep[AuCache_DINFO] = AuCache(au_dinfo);
  14273. + if (au_cachep[AuCache_DINFO])
  14274. + au_cachep[AuCache_ICNTNR] = AuCache(au_icntnr);
  14275. + if (au_cachep[AuCache_ICNTNR])
  14276. + au_cachep[AuCache_FINFO] = AuCache(au_finfo);
  14277. + if (au_cachep[AuCache_FINFO])
  14278. + au_cachep[AuCache_VDIR] = AuCache(au_vdir);
  14279. + if (au_cachep[AuCache_VDIR])
  14280. + au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
  14281. + if (au_cachep[AuCache_DEHSTR])
  14282. + return 0;
  14283. +
  14284. + return -ENOMEM;
  14285. +}
  14286. +
  14287. +static void au_cache_fin(void)
  14288. +{
  14289. + int i;
  14290. + for (i = 0; i < AuCache_Last; i++)
  14291. + if (au_cachep[i]) {
  14292. + kmem_cache_destroy(au_cachep[i]);
  14293. + au_cachep[i] = NULL;
  14294. + }
  14295. +}
  14296. +
  14297. +/* ---------------------------------------------------------------------- */
  14298. +
  14299. +int au_dir_roflags;
  14300. +
  14301. +/*
  14302. + * functions for module interface.
  14303. + */
  14304. +MODULE_LICENSE("GPL");
  14305. +/* MODULE_LICENSE("GPL v2"); */
  14306. +MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
  14307. +MODULE_DESCRIPTION(AUFS_NAME
  14308. + " -- Advanced multi layered unification filesystem");
  14309. +MODULE_VERSION(AUFS_VERSION);
  14310. +
  14311. +/* it should be 'byte', but param_set_byte() prints it by "%c" */
  14312. +short aufs_nwkq = AUFS_NWKQ_DEF;
  14313. +MODULE_PARM_DESC(nwkq, "the number of workqueue thread, " AUFS_WKQ_NAME);
  14314. +module_param_named(nwkq, aufs_nwkq, short, S_IRUGO);
  14315. +
  14316. +/* this module parameter has no meaning when SYSFS is disabled */
  14317. +int sysaufs_brs = 1;
  14318. +MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
  14319. +module_param_named(brs, sysaufs_brs, int, S_IRUGO);
  14320. +
  14321. +/* ---------------------------------------------------------------------- */
  14322. +
  14323. +static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
  14324. +
  14325. +int au_seq_path(struct seq_file *seq, struct path *path)
  14326. +{
  14327. + return seq_path(seq, path, au_esc_chars);
  14328. +}
  14329. +
  14330. +/* ---------------------------------------------------------------------- */
  14331. +
  14332. +static int __init aufs_init(void)
  14333. +{
  14334. + int err, i;
  14335. + char *p;
  14336. +
  14337. + p = au_esc_chars;
  14338. + for (i = 1; i <= ' '; i++)
  14339. + *p++ = i;
  14340. + *p++ = '\\';
  14341. + *p++ = '\x7f';
  14342. + *p = 0;
  14343. +
  14344. + au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
  14345. +
  14346. + sysaufs_brs_init();
  14347. + au_debug_init();
  14348. +
  14349. + err = -EINVAL;
  14350. + if (unlikely(aufs_nwkq <= 0))
  14351. + goto out;
  14352. +
  14353. + err = sysaufs_init();
  14354. + if (unlikely(err))
  14355. + goto out;
  14356. + err = au_wkq_init();
  14357. + if (unlikely(err))
  14358. + goto out_sysaufs;
  14359. + err = au_hinotify_init();
  14360. + if (unlikely(err))
  14361. + goto out_wkq;
  14362. + err = au_sysrq_init();
  14363. + if (unlikely(err))
  14364. + goto out_hin;
  14365. + err = au_cache_init();
  14366. + if (unlikely(err))
  14367. + goto out_sysrq;
  14368. + err = register_filesystem(&aufs_fs_type);
  14369. + if (unlikely(err))
  14370. + goto out_cache;
  14371. + pr_info(AUFS_NAME " " AUFS_VERSION "\n");
  14372. + goto out; /* success */
  14373. +
  14374. + out_cache:
  14375. + au_cache_fin();
  14376. + out_sysrq:
  14377. + au_sysrq_fin();
  14378. + out_hin:
  14379. + au_hinotify_fin();
  14380. + out_wkq:
  14381. + au_wkq_fin();
  14382. + out_sysaufs:
  14383. + sysaufs_fin();
  14384. + out:
  14385. + return err;
  14386. +}
  14387. +
  14388. +static void __exit aufs_exit(void)
  14389. +{
  14390. + unregister_filesystem(&aufs_fs_type);
  14391. + au_cache_fin();
  14392. + au_sysrq_fin();
  14393. + au_hinotify_fin();
  14394. + au_wkq_fin();
  14395. + sysaufs_fin();
  14396. +}
  14397. +
  14398. +module_init(aufs_init);
  14399. +module_exit(aufs_exit);
  14400. diff -Nur linux-2.6.31.5.orig/fs/aufs/module.h linux-2.6.31.5/fs/aufs/module.h
  14401. --- linux-2.6.31.5.orig/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100
  14402. +++ linux-2.6.31.5/fs/aufs/module.h 2009-11-15 22:02:37.000000000 +0100
  14403. @@ -0,0 +1,78 @@
  14404. +/*
  14405. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  14406. + *
  14407. + * This program, aufs is free software; you can redistribute it and/or modify
  14408. + * it under the terms of the GNU General Public License as published by
  14409. + * the Free Software Foundation; either version 2 of the License, or
  14410. + * (at your option) any later version.
  14411. + *
  14412. + * This program is distributed in the hope that it will be useful,
  14413. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14414. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14415. + * GNU General Public License for more details.
  14416. + *
  14417. + * You should have received a copy of the GNU General Public License
  14418. + * along with this program; if not, write to the Free Software
  14419. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14420. + */
  14421. +
  14422. +/*
  14423. + * module initialization and module-global
  14424. + */
  14425. +
  14426. +#ifndef __AUFS_MODULE_H__
  14427. +#define __AUFS_MODULE_H__
  14428. +
  14429. +#ifdef __KERNEL__
  14430. +
  14431. +#include <linux/slab.h>
  14432. +
  14433. +struct path;
  14434. +struct seq_file;
  14435. +
  14436. +/* module parameters */
  14437. +extern short aufs_nwkq;
  14438. +extern int sysaufs_brs;
  14439. +
  14440. +/* ---------------------------------------------------------------------- */
  14441. +
  14442. +extern int au_dir_roflags;
  14443. +
  14444. +void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp);
  14445. +int au_seq_path(struct seq_file *seq, struct path *path);
  14446. +
  14447. +/* ---------------------------------------------------------------------- */
  14448. +
  14449. +/* kmem cache */
  14450. +enum {
  14451. + AuCache_DINFO,
  14452. + AuCache_ICNTNR,
  14453. + AuCache_FINFO,
  14454. + AuCache_VDIR,
  14455. + AuCache_DEHSTR,
  14456. +#ifdef CONFIG_AUFS_HINOTIFY
  14457. + AuCache_HINOTIFY,
  14458. +#endif
  14459. + AuCache_Last
  14460. +};
  14461. +
  14462. +#define AuCache(type) KMEM_CACHE(type, SLAB_RECLAIM_ACCOUNT)
  14463. +
  14464. +extern struct kmem_cache *au_cachep[];
  14465. +
  14466. +#define AuCacheFuncs(name, index) \
  14467. +static inline void *au_cache_alloc_##name(void) \
  14468. +{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \
  14469. +static inline void au_cache_free_##name(void *p) \
  14470. +{ kmem_cache_free(au_cachep[AuCache_##index], p); }
  14471. +
  14472. +AuCacheFuncs(dinfo, DINFO);
  14473. +AuCacheFuncs(icntnr, ICNTNR);
  14474. +AuCacheFuncs(finfo, FINFO);
  14475. +AuCacheFuncs(vdir, VDIR);
  14476. +AuCacheFuncs(dehstr, DEHSTR);
  14477. +
  14478. +/* ---------------------------------------------------------------------- */
  14479. +
  14480. +#endif /* __KERNEL__ */
  14481. +#endif /* __AUFS_MODULE_H__ */
  14482. diff -Nur linux-2.6.31.5.orig/fs/aufs/opts.c linux-2.6.31.5/fs/aufs/opts.c
  14483. --- linux-2.6.31.5.orig/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100
  14484. +++ linux-2.6.31.5/fs/aufs/opts.c 2009-11-15 22:02:37.000000000 +0100
  14485. @@ -0,0 +1,1543 @@
  14486. +/*
  14487. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  14488. + *
  14489. + * This program, aufs is free software; you can redistribute it and/or modify
  14490. + * it under the terms of the GNU General Public License as published by
  14491. + * the Free Software Foundation; either version 2 of the License, or
  14492. + * (at your option) any later version.
  14493. + *
  14494. + * This program is distributed in the hope that it will be useful,
  14495. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14496. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14497. + * GNU General Public License for more details.
  14498. + *
  14499. + * You should have received a copy of the GNU General Public License
  14500. + * along with this program; if not, write to the Free Software
  14501. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14502. + */
  14503. +
  14504. +/*
  14505. + * mount options/flags
  14506. + */
  14507. +
  14508. +#include <linux/file.h>
  14509. +#include <linux/namei.h>
  14510. +#include <linux/types.h> /* a distribution requires */
  14511. +#include <linux/parser.h>
  14512. +#include "aufs.h"
  14513. +
  14514. +/* ---------------------------------------------------------------------- */
  14515. +
  14516. +enum {
  14517. + Opt_br,
  14518. + Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend,
  14519. + Opt_idel, Opt_imod, Opt_ireorder,
  14520. + Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, Opt_rendir,
  14521. + Opt_rdblk_def, Opt_rdhash_def,
  14522. + Opt_xino, Opt_zxino, Opt_noxino,
  14523. + Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
  14524. + Opt_trunc_xino_path, Opt_itrunc_xino,
  14525. + Opt_trunc_xib, Opt_notrunc_xib,
  14526. + Opt_shwh, Opt_noshwh,
  14527. + Opt_plink, Opt_noplink, Opt_list_plink,
  14528. + Opt_udba,
  14529. + /* Opt_lock, Opt_unlock, */
  14530. + Opt_cmd, Opt_cmd_args,
  14531. + Opt_diropq_a, Opt_diropq_w,
  14532. + Opt_warn_perm, Opt_nowarn_perm,
  14533. + Opt_wbr_copyup, Opt_wbr_create,
  14534. + Opt_refrof, Opt_norefrof,
  14535. + Opt_verbose, Opt_noverbose,
  14536. + Opt_sum, Opt_nosum, Opt_wsum,
  14537. + Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
  14538. +};
  14539. +
  14540. +static match_table_t options = {
  14541. + {Opt_br, "br=%s"},
  14542. + {Opt_br, "br:%s"},
  14543. +
  14544. + {Opt_add, "add=%d:%s"},
  14545. + {Opt_add, "add:%d:%s"},
  14546. + {Opt_add, "ins=%d:%s"},
  14547. + {Opt_add, "ins:%d:%s"},
  14548. + {Opt_append, "append=%s"},
  14549. + {Opt_append, "append:%s"},
  14550. + {Opt_prepend, "prepend=%s"},
  14551. + {Opt_prepend, "prepend:%s"},
  14552. +
  14553. + {Opt_del, "del=%s"},
  14554. + {Opt_del, "del:%s"},
  14555. + /* {Opt_idel, "idel:%d"}, */
  14556. + {Opt_mod, "mod=%s"},
  14557. + {Opt_mod, "mod:%s"},
  14558. + /* {Opt_imod, "imod:%d:%s"}, */
  14559. +
  14560. + {Opt_dirwh, "dirwh=%d"},
  14561. +
  14562. + {Opt_xino, "xino=%s"},
  14563. + {Opt_noxino, "noxino"},
  14564. + {Opt_trunc_xino, "trunc_xino"},
  14565. + {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
  14566. + {Opt_notrunc_xino, "notrunc_xino"},
  14567. + {Opt_trunc_xino_path, "trunc_xino=%s"},
  14568. + {Opt_itrunc_xino, "itrunc_xino=%d"},
  14569. + /* {Opt_zxino, "zxino=%s"}, */
  14570. + {Opt_trunc_xib, "trunc_xib"},
  14571. + {Opt_notrunc_xib, "notrunc_xib"},
  14572. +
  14573. + {Opt_plink, "plink"},
  14574. + {Opt_noplink, "noplink"},
  14575. +#ifdef CONFIG_AUFS_DEBUG
  14576. + {Opt_list_plink, "list_plink"},
  14577. +#endif
  14578. +
  14579. + {Opt_udba, "udba=%s"},
  14580. +
  14581. + {Opt_diropq_a, "diropq=always"},
  14582. + {Opt_diropq_a, "diropq=a"},
  14583. + {Opt_diropq_w, "diropq=whiteouted"},
  14584. + {Opt_diropq_w, "diropq=w"},
  14585. +
  14586. + {Opt_warn_perm, "warn_perm"},
  14587. + {Opt_nowarn_perm, "nowarn_perm"},
  14588. +
  14589. + /* keep them temporary */
  14590. + {Opt_ignore_silent, "coo=%s"},
  14591. + {Opt_ignore_silent, "nodlgt"},
  14592. + {Opt_ignore_silent, "nodirperm1"},
  14593. + {Opt_ignore_silent, "clean_plink"},
  14594. +
  14595. +#ifdef CONFIG_AUFS_SHWH
  14596. + {Opt_shwh, "shwh"},
  14597. +#endif
  14598. + {Opt_noshwh, "noshwh"},
  14599. +
  14600. + {Opt_rendir, "rendir=%d"},
  14601. +
  14602. + {Opt_refrof, "refrof"},
  14603. + {Opt_norefrof, "norefrof"},
  14604. +
  14605. + {Opt_verbose, "verbose"},
  14606. + {Opt_verbose, "v"},
  14607. + {Opt_noverbose, "noverbose"},
  14608. + {Opt_noverbose, "quiet"},
  14609. + {Opt_noverbose, "q"},
  14610. + {Opt_noverbose, "silent"},
  14611. +
  14612. + {Opt_sum, "sum"},
  14613. + {Opt_nosum, "nosum"},
  14614. + {Opt_wsum, "wsum"},
  14615. +
  14616. + {Opt_rdcache, "rdcache=%d"},
  14617. + {Opt_rdblk, "rdblk=%d"},
  14618. + {Opt_rdblk_def, "rdblk=def"},
  14619. + {Opt_rdhash, "rdhash=%d"},
  14620. + {Opt_rdhash_def, "rdhash=def"},
  14621. +
  14622. + {Opt_wbr_create, "create=%s"},
  14623. + {Opt_wbr_create, "create_policy=%s"},
  14624. + {Opt_wbr_copyup, "cpup=%s"},
  14625. + {Opt_wbr_copyup, "copyup=%s"},
  14626. + {Opt_wbr_copyup, "copyup_policy=%s"},
  14627. +
  14628. + /* internal use for the scripts */
  14629. + {Opt_ignore_silent, "si=%s"},
  14630. +
  14631. + {Opt_br, "dirs=%s"},
  14632. + {Opt_ignore, "debug=%d"},
  14633. + {Opt_ignore, "delete=whiteout"},
  14634. + {Opt_ignore, "delete=all"},
  14635. + {Opt_ignore, "imap=%s"},
  14636. +
  14637. + {Opt_err, NULL}
  14638. +};
  14639. +
  14640. +/* ---------------------------------------------------------------------- */
  14641. +
  14642. +static const char *au_parser_pattern(int val, struct match_token *token)
  14643. +{
  14644. + while (token->pattern) {
  14645. + if (token->token == val)
  14646. + return token->pattern;
  14647. + token++;
  14648. + }
  14649. + BUG();
  14650. + return "??";
  14651. +}
  14652. +
  14653. +/* ---------------------------------------------------------------------- */
  14654. +
  14655. +static match_table_t brperms = {
  14656. + {AuBrPerm_RO, AUFS_BRPERM_RO},
  14657. + {AuBrPerm_RR, AUFS_BRPERM_RR},
  14658. + {AuBrPerm_RW, AUFS_BRPERM_RW},
  14659. +
  14660. + {AuBrPerm_ROWH, AUFS_BRPERM_ROWH},
  14661. + {AuBrPerm_RRWH, AUFS_BRPERM_RRWH},
  14662. + {AuBrPerm_RWNoLinkWH, AUFS_BRPERM_RWNLWH},
  14663. +
  14664. + {AuBrPerm_ROWH, "nfsro"},
  14665. + {AuBrPerm_RO, NULL}
  14666. +};
  14667. +
  14668. +static int br_perm_val(char *perm)
  14669. +{
  14670. + int val;
  14671. + substring_t args[MAX_OPT_ARGS];
  14672. +
  14673. + val = match_token(perm, brperms, args);
  14674. + return val;
  14675. +}
  14676. +
  14677. +const char *au_optstr_br_perm(int brperm)
  14678. +{
  14679. + return au_parser_pattern(brperm, (void *)brperms);
  14680. +}
  14681. +
  14682. +/* ---------------------------------------------------------------------- */
  14683. +
  14684. +static match_table_t udbalevel = {
  14685. + {AuOpt_UDBA_REVAL, "reval"},
  14686. + {AuOpt_UDBA_NONE, "none"},
  14687. +#ifdef CONFIG_AUFS_HINOTIFY
  14688. + {AuOpt_UDBA_HINOTIFY, "inotify"},
  14689. +#endif
  14690. + {-1, NULL}
  14691. +};
  14692. +
  14693. +static int udba_val(char *str)
  14694. +{
  14695. + substring_t args[MAX_OPT_ARGS];
  14696. +
  14697. + return match_token(str, udbalevel, args);
  14698. +}
  14699. +
  14700. +const char *au_optstr_udba(int udba)
  14701. +{
  14702. + return au_parser_pattern(udba, (void *)udbalevel);
  14703. +}
  14704. +
  14705. +/* ---------------------------------------------------------------------- */
  14706. +
  14707. +static match_table_t au_wbr_create_policy = {
  14708. + {AuWbrCreate_TDP, "tdp"},
  14709. + {AuWbrCreate_TDP, "top-down-parent"},
  14710. + {AuWbrCreate_RR, "rr"},
  14711. + {AuWbrCreate_RR, "round-robin"},
  14712. + {AuWbrCreate_MFS, "mfs"},
  14713. + {AuWbrCreate_MFS, "most-free-space"},
  14714. + {AuWbrCreate_MFSV, "mfs:%d"},
  14715. + {AuWbrCreate_MFSV, "most-free-space:%d"},
  14716. +
  14717. + {AuWbrCreate_MFSRR, "mfsrr:%d"},
  14718. + {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
  14719. + {AuWbrCreate_PMFS, "pmfs"},
  14720. + {AuWbrCreate_PMFSV, "pmfs:%d"},
  14721. +
  14722. + {-1, NULL}
  14723. +};
  14724. +
  14725. +/*
  14726. + * cf. linux/lib/parser.c and cmdline.c
  14727. + * gave up calling memparse() since it uses simple_strtoull() instead of
  14728. + * strict_...().
  14729. + */
  14730. +static int au_match_ull(substring_t *s, unsigned long long *result)
  14731. +{
  14732. + int err;
  14733. + unsigned int len;
  14734. + char a[32];
  14735. +
  14736. + err = -ERANGE;
  14737. + len = s->to - s->from;
  14738. + if (len + 1 <= sizeof(a)) {
  14739. + memcpy(a, s->from, len);
  14740. + a[len] = '\0';
  14741. + err = strict_strtoull(a, 0, result);
  14742. + }
  14743. + return err;
  14744. +}
  14745. +
  14746. +static int au_wbr_mfs_wmark(substring_t *arg, char *str,
  14747. + struct au_opt_wbr_create *create)
  14748. +{
  14749. + int err;
  14750. + unsigned long long ull;
  14751. +
  14752. + err = 0;
  14753. + if (!au_match_ull(arg, &ull))
  14754. + create->mfsrr_watermark = ull;
  14755. + else {
  14756. + AuErr("bad integer in %s\n", str);
  14757. + err = -EINVAL;
  14758. + }
  14759. +
  14760. + return err;
  14761. +}
  14762. +
  14763. +static int au_wbr_mfs_sec(substring_t *arg, char *str,
  14764. + struct au_opt_wbr_create *create)
  14765. +{
  14766. + int n, err;
  14767. +
  14768. + err = 0;
  14769. + if (!match_int(arg, &n) && 0 <= n)
  14770. + create->mfs_second = n;
  14771. + else {
  14772. + AuErr("bad integer in %s\n", str);
  14773. + err = -EINVAL;
  14774. + }
  14775. +
  14776. + return err;
  14777. +}
  14778. +
  14779. +static int au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
  14780. +{
  14781. + int err, e;
  14782. + substring_t args[MAX_OPT_ARGS];
  14783. +
  14784. + err = match_token(str, au_wbr_create_policy, args);
  14785. + create->wbr_create = err;
  14786. + switch (err) {
  14787. + case AuWbrCreate_MFSRRV:
  14788. + e = au_wbr_mfs_wmark(&args[0], str, create);
  14789. + if (!e)
  14790. + e = au_wbr_mfs_sec(&args[1], str, create);
  14791. + if (unlikely(e))
  14792. + err = e;
  14793. + break;
  14794. + case AuWbrCreate_MFSRR:
  14795. + e = au_wbr_mfs_wmark(&args[0], str, create);
  14796. + if (unlikely(e)) {
  14797. + err = e;
  14798. + break;
  14799. + }
  14800. + /*FALLTHROUGH*/
  14801. + case AuWbrCreate_MFS:
  14802. + case AuWbrCreate_PMFS:
  14803. + create->mfs_second = AUFS_MFS_SECOND_DEF;
  14804. + break;
  14805. + case AuWbrCreate_MFSV:
  14806. + case AuWbrCreate_PMFSV:
  14807. + e = au_wbr_mfs_sec(&args[0], str, create);
  14808. + if (unlikely(e))
  14809. + err = e;
  14810. + break;
  14811. + }
  14812. +
  14813. + return err;
  14814. +}
  14815. +
  14816. +const char *au_optstr_wbr_create(int wbr_create)
  14817. +{
  14818. + return au_parser_pattern(wbr_create, (void *)au_wbr_create_policy);
  14819. +}
  14820. +
  14821. +static match_table_t au_wbr_copyup_policy = {
  14822. + {AuWbrCopyup_TDP, "tdp"},
  14823. + {AuWbrCopyup_TDP, "top-down-parent"},
  14824. + {AuWbrCopyup_BUP, "bup"},
  14825. + {AuWbrCopyup_BUP, "bottom-up-parent"},
  14826. + {AuWbrCopyup_BU, "bu"},
  14827. + {AuWbrCopyup_BU, "bottom-up"},
  14828. + {-1, NULL}
  14829. +};
  14830. +
  14831. +static int au_wbr_copyup_val(char *str)
  14832. +{
  14833. + substring_t args[MAX_OPT_ARGS];
  14834. +
  14835. + return match_token(str, au_wbr_copyup_policy, args);
  14836. +}
  14837. +
  14838. +const char *au_optstr_wbr_copyup(int wbr_copyup)
  14839. +{
  14840. + return au_parser_pattern(wbr_copyup, (void *)au_wbr_copyup_policy);
  14841. +}
  14842. +
  14843. +/* ---------------------------------------------------------------------- */
  14844. +
  14845. +static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
  14846. +
  14847. +static void dump_opts(struct au_opts *opts)
  14848. +{
  14849. +#ifdef CONFIG_AUFS_DEBUG
  14850. + /* reduce stack space */
  14851. + union {
  14852. + struct au_opt_add *add;
  14853. + struct au_opt_del *del;
  14854. + struct au_opt_mod *mod;
  14855. + struct au_opt_xino *xino;
  14856. + struct au_opt_xino_itrunc *xino_itrunc;
  14857. + struct au_opt_wbr_create *create;
  14858. + } u;
  14859. + struct au_opt *opt;
  14860. +
  14861. + opt = opts->opt;
  14862. + while (opt->type != Opt_tail) {
  14863. + switch (opt->type) {
  14864. + case Opt_add:
  14865. + u.add = &opt->add;
  14866. + AuDbg("add {b%d, %s, 0x%x, %p}\n",
  14867. + u.add->bindex, u.add->pathname, u.add->perm,
  14868. + u.add->path.dentry);
  14869. + break;
  14870. + case Opt_del:
  14871. + case Opt_idel:
  14872. + u.del = &opt->del;
  14873. + AuDbg("del {%s, %p}\n",
  14874. + u.del->pathname, u.del->h_path.dentry);
  14875. + break;
  14876. + case Opt_mod:
  14877. + case Opt_imod:
  14878. + u.mod = &opt->mod;
  14879. + AuDbg("mod {%s, 0x%x, %p}\n",
  14880. + u.mod->path, u.mod->perm, u.mod->h_root);
  14881. + break;
  14882. + case Opt_append:
  14883. + u.add = &opt->add;
  14884. + AuDbg("append {b%d, %s, 0x%x, %p}\n",
  14885. + u.add->bindex, u.add->pathname, u.add->perm,
  14886. + u.add->path.dentry);
  14887. + break;
  14888. + case Opt_prepend:
  14889. + u.add = &opt->add;
  14890. + AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
  14891. + u.add->bindex, u.add->pathname, u.add->perm,
  14892. + u.add->path.dentry);
  14893. + break;
  14894. + case Opt_dirwh:
  14895. + AuDbg("dirwh %d\n", opt->dirwh);
  14896. + break;
  14897. + case Opt_rdcache:
  14898. + AuDbg("rdcache %d\n", opt->rdcache);
  14899. + break;
  14900. + case Opt_rdblk:
  14901. + AuDbg("rdblk %u\n", opt->rdblk);
  14902. + break;
  14903. + case Opt_rdblk_def:
  14904. + AuDbg("rdblk_def\n");
  14905. + break;
  14906. + case Opt_rdhash:
  14907. + AuDbg("rdhash %u\n", opt->rdhash);
  14908. + break;
  14909. + case Opt_rdhash_def:
  14910. + AuDbg("rdhash_def\n");
  14911. + break;
  14912. + case Opt_xino:
  14913. + u.xino = &opt->xino;
  14914. + AuDbg("xino {%s %.*s}\n",
  14915. + u.xino->path,
  14916. + AuDLNPair(u.xino->file->f_dentry));
  14917. + break;
  14918. + case Opt_trunc_xino:
  14919. + AuLabel(trunc_xino);
  14920. + break;
  14921. + case Opt_notrunc_xino:
  14922. + AuLabel(notrunc_xino);
  14923. + break;
  14924. + case Opt_trunc_xino_path:
  14925. + case Opt_itrunc_xino:
  14926. + u.xino_itrunc = &opt->xino_itrunc;
  14927. + AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
  14928. + break;
  14929. +
  14930. + case Opt_noxino:
  14931. + AuLabel(noxino);
  14932. + break;
  14933. + case Opt_trunc_xib:
  14934. + AuLabel(trunc_xib);
  14935. + break;
  14936. + case Opt_notrunc_xib:
  14937. + AuLabel(notrunc_xib);
  14938. + break;
  14939. + case Opt_shwh:
  14940. + AuLabel(shwh);
  14941. + break;
  14942. + case Opt_noshwh:
  14943. + AuLabel(noshwh);
  14944. + break;
  14945. + case Opt_plink:
  14946. + AuLabel(plink);
  14947. + break;
  14948. + case Opt_noplink:
  14949. + AuLabel(noplink);
  14950. + break;
  14951. + case Opt_list_plink:
  14952. + AuLabel(list_plink);
  14953. + break;
  14954. + case Opt_udba:
  14955. + AuDbg("udba %d, %s\n",
  14956. + opt->udba, au_optstr_udba(opt->udba));
  14957. + break;
  14958. + case Opt_diropq_a:
  14959. + AuLabel(diropq_a);
  14960. + break;
  14961. + case Opt_diropq_w:
  14962. + AuLabel(diropq_w);
  14963. + break;
  14964. + case Opt_warn_perm:
  14965. + AuLabel(warn_perm);
  14966. + break;
  14967. + case Opt_nowarn_perm:
  14968. + AuLabel(nowarn_perm);
  14969. + break;
  14970. + case Opt_refrof:
  14971. + AuLabel(refrof);
  14972. + break;
  14973. + case Opt_norefrof:
  14974. + AuLabel(norefrof);
  14975. + break;
  14976. + case Opt_verbose:
  14977. + AuLabel(verbose);
  14978. + break;
  14979. + case Opt_noverbose:
  14980. + AuLabel(noverbose);
  14981. + break;
  14982. + case Opt_sum:
  14983. + AuLabel(sum);
  14984. + break;
  14985. + case Opt_nosum:
  14986. + AuLabel(nosum);
  14987. + break;
  14988. + case Opt_wsum:
  14989. + AuLabel(wsum);
  14990. + break;
  14991. + case Opt_wbr_create:
  14992. + u.create = &opt->wbr_create;
  14993. + AuDbg("create %d, %s\n", u.create->wbr_create,
  14994. + au_optstr_wbr_create(u.create->wbr_create));
  14995. + switch (u.create->wbr_create) {
  14996. + case AuWbrCreate_MFSV:
  14997. + case AuWbrCreate_PMFSV:
  14998. + AuDbg("%d sec\n", u.create->mfs_second);
  14999. + break;
  15000. + case AuWbrCreate_MFSRR:
  15001. + AuDbg("%llu watermark\n",
  15002. + u.create->mfsrr_watermark);
  15003. + break;
  15004. + case AuWbrCreate_MFSRRV:
  15005. + AuDbg("%llu watermark, %d sec\n",
  15006. + u.create->mfsrr_watermark,
  15007. + u.create->mfs_second);
  15008. + break;
  15009. + }
  15010. + break;
  15011. + case Opt_wbr_copyup:
  15012. + AuDbg("copyup %d, %s\n", opt->wbr_copyup,
  15013. + au_optstr_wbr_copyup(opt->wbr_copyup));
  15014. + break;
  15015. + default:
  15016. + BUG();
  15017. + }
  15018. + opt++;
  15019. + }
  15020. +#endif
  15021. +}
  15022. +
  15023. +void au_opts_free(struct au_opts *opts)
  15024. +{
  15025. + struct au_opt *opt;
  15026. +
  15027. + opt = opts->opt;
  15028. + while (opt->type != Opt_tail) {
  15029. + switch (opt->type) {
  15030. + case Opt_add:
  15031. + case Opt_append:
  15032. + case Opt_prepend:
  15033. + path_put(&opt->add.path);
  15034. + break;
  15035. + case Opt_del:
  15036. + case Opt_idel:
  15037. + path_put(&opt->del.h_path);
  15038. + break;
  15039. + case Opt_mod:
  15040. + case Opt_imod:
  15041. + dput(opt->mod.h_root);
  15042. + break;
  15043. + case Opt_xino:
  15044. + fput(opt->xino.file);
  15045. + break;
  15046. + }
  15047. + opt++;
  15048. + }
  15049. +}
  15050. +
  15051. +static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
  15052. + aufs_bindex_t bindex)
  15053. +{
  15054. + int err;
  15055. + struct au_opt_add *add = &opt->add;
  15056. + char *p;
  15057. +
  15058. + add->bindex = bindex;
  15059. + add->perm = AuBrPerm_Last;
  15060. + add->pathname = opt_str;
  15061. + p = strchr(opt_str, '=');
  15062. + if (p) {
  15063. + *p++ = 0;
  15064. + if (*p)
  15065. + add->perm = br_perm_val(p);
  15066. + }
  15067. +
  15068. + err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
  15069. + if (!err) {
  15070. + if (!p) {
  15071. + add->perm = AuBrPerm_RO;
  15072. + if (au_test_fs_rr(add->path.dentry->d_sb))
  15073. + add->perm = AuBrPerm_RR;
  15074. + else if (!bindex && !(sb_flags & MS_RDONLY))
  15075. + add->perm = AuBrPerm_RW;
  15076. + }
  15077. + opt->type = Opt_add;
  15078. + goto out;
  15079. + }
  15080. + AuErr("lookup failed %s (%d)\n", add->pathname, err);
  15081. + err = -EINVAL;
  15082. +
  15083. + out:
  15084. + return err;
  15085. +}
  15086. +
  15087. +static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
  15088. +{
  15089. + int err;
  15090. +
  15091. + del->pathname = args[0].from;
  15092. + AuDbg("del path %s\n", del->pathname);
  15093. +
  15094. + err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
  15095. + if (unlikely(err))
  15096. + AuErr("lookup failed %s (%d)\n", del->pathname, err);
  15097. +
  15098. + return err;
  15099. +}
  15100. +
  15101. +#if 0 /* reserved for future use */
  15102. +static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
  15103. + struct au_opt_del *del, substring_t args[])
  15104. +{
  15105. + int err;
  15106. + struct dentry *root;
  15107. +
  15108. + err = -EINVAL;
  15109. + root = sb->s_root;
  15110. + aufs_read_lock(root, AuLock_FLUSH);
  15111. + if (bindex < 0 || au_sbend(sb) < bindex) {
  15112. + AuErr("out of bounds, %d\n", bindex);
  15113. + goto out;
  15114. + }
  15115. +
  15116. + err = 0;
  15117. + del->h_path.dentry = dget(au_h_dptr(root, bindex));
  15118. + del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
  15119. +
  15120. + out:
  15121. + aufs_read_unlock(root, !AuLock_IR);
  15122. + return err;
  15123. +}
  15124. +#endif
  15125. +
  15126. +static int au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
  15127. +{
  15128. + int err;
  15129. + struct path path;
  15130. + char *p;
  15131. +
  15132. + err = -EINVAL;
  15133. + mod->path = args[0].from;
  15134. + p = strchr(mod->path, '=');
  15135. + if (unlikely(!p)) {
  15136. + AuErr("no permssion %s\n", args[0].from);
  15137. + goto out;
  15138. + }
  15139. +
  15140. + *p++ = 0;
  15141. + err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
  15142. + if (unlikely(err)) {
  15143. + AuErr("lookup failed %s (%d)\n", mod->path, err);
  15144. + goto out;
  15145. + }
  15146. +
  15147. + mod->perm = br_perm_val(p);
  15148. + AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
  15149. + mod->h_root = dget(path.dentry);
  15150. + path_put(&path);
  15151. +
  15152. + out:
  15153. + return err;
  15154. +}
  15155. +
  15156. +#if 0 /* reserved for future use */
  15157. +static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
  15158. + struct au_opt_mod *mod, substring_t args[])
  15159. +{
  15160. + int err;
  15161. + struct dentry *root;
  15162. +
  15163. + err = -EINVAL;
  15164. + root = sb->s_root;
  15165. + aufs_read_lock(root, AuLock_FLUSH);
  15166. + if (bindex < 0 || au_sbend(sb) < bindex) {
  15167. + AuErr("out of bounds, %d\n", bindex);
  15168. + goto out;
  15169. + }
  15170. +
  15171. + err = 0;
  15172. + mod->perm = br_perm_val(args[1].from);
  15173. + AuDbg("mod path %s, perm 0x%x, %s\n",
  15174. + mod->path, mod->perm, args[1].from);
  15175. + mod->h_root = dget(au_h_dptr(root, bindex));
  15176. +
  15177. + out:
  15178. + aufs_read_unlock(root, !AuLock_IR);
  15179. + return err;
  15180. +}
  15181. +#endif
  15182. +
  15183. +static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
  15184. + substring_t args[])
  15185. +{
  15186. + int err;
  15187. + struct file *file;
  15188. +
  15189. + file = au_xino_create(sb, args[0].from, /*silent*/0);
  15190. + err = PTR_ERR(file);
  15191. + if (IS_ERR(file))
  15192. + goto out;
  15193. +
  15194. + err = -EINVAL;
  15195. + if (unlikely(file->f_dentry->d_sb == sb)) {
  15196. + fput(file);
  15197. + AuErr("%s must be outside\n", args[0].from);
  15198. + goto out;
  15199. + }
  15200. +
  15201. + err = 0;
  15202. + xino->file = file;
  15203. + xino->path = args[0].from;
  15204. +
  15205. + out:
  15206. + return err;
  15207. +}
  15208. +
  15209. +static
  15210. +int au_opts_parse_xino_itrunc_path(struct super_block *sb,
  15211. + struct au_opt_xino_itrunc *xino_itrunc,
  15212. + substring_t args[])
  15213. +{
  15214. + int err;
  15215. + aufs_bindex_t bend, bindex;
  15216. + struct path path;
  15217. + struct dentry *root;
  15218. +
  15219. + err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
  15220. + if (unlikely(err)) {
  15221. + AuErr("lookup failed %s (%d)\n", args[0].from, err);
  15222. + goto out;
  15223. + }
  15224. +
  15225. + xino_itrunc->bindex = -1;
  15226. + root = sb->s_root;
  15227. + aufs_read_lock(root, AuLock_FLUSH);
  15228. + bend = au_sbend(sb);
  15229. + for (bindex = 0; bindex <= bend; bindex++) {
  15230. + if (au_h_dptr(root, bindex) == path.dentry) {
  15231. + xino_itrunc->bindex = bindex;
  15232. + break;
  15233. + }
  15234. + }
  15235. + aufs_read_unlock(root, !AuLock_IR);
  15236. + path_put(&path);
  15237. +
  15238. + if (unlikely(xino_itrunc->bindex < 0)) {
  15239. + AuErr("no such branch %s\n", args[0].from);
  15240. + err = -EINVAL;
  15241. + }
  15242. +
  15243. + out:
  15244. + return err;
  15245. +}
  15246. +
  15247. +/* called without aufs lock */
  15248. +int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
  15249. +{
  15250. + int err, n, token;
  15251. + aufs_bindex_t bindex;
  15252. + unsigned char skipped;
  15253. + struct dentry *root;
  15254. + struct au_opt *opt, *opt_tail;
  15255. + char *opt_str;
  15256. + /* reduce the stack space */
  15257. + union {
  15258. + struct au_opt_xino_itrunc *xino_itrunc;
  15259. + struct au_opt_wbr_create *create;
  15260. + } u;
  15261. + struct {
  15262. + substring_t args[MAX_OPT_ARGS];
  15263. + } *a;
  15264. +
  15265. + err = -ENOMEM;
  15266. + a = kmalloc(sizeof(*a), GFP_NOFS);
  15267. + if (unlikely(!a))
  15268. + goto out;
  15269. +
  15270. + root = sb->s_root;
  15271. + err = 0;
  15272. + bindex = 0;
  15273. + opt = opts->opt;
  15274. + opt_tail = opt + opts->max_opt - 1;
  15275. + opt->type = Opt_tail;
  15276. + while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
  15277. + err = -EINVAL;
  15278. + skipped = 0;
  15279. + token = match_token(opt_str, options, a->args);
  15280. + switch (token) {
  15281. + case Opt_br:
  15282. + err = 0;
  15283. + while (!err && (opt_str = strsep(&a->args[0].from, ":"))
  15284. + && *opt_str) {
  15285. + err = opt_add(opt, opt_str, opts->sb_flags,
  15286. + bindex++);
  15287. + if (unlikely(!err && ++opt > opt_tail)) {
  15288. + err = -E2BIG;
  15289. + break;
  15290. + }
  15291. + opt->type = Opt_tail;
  15292. + skipped = 1;
  15293. + }
  15294. + break;
  15295. + case Opt_add:
  15296. + if (unlikely(match_int(&a->args[0], &n))) {
  15297. + AuErr("bad integer in %s\n", opt_str);
  15298. + break;
  15299. + }
  15300. + bindex = n;
  15301. + err = opt_add(opt, a->args[1].from, opts->sb_flags,
  15302. + bindex);
  15303. + if (!err)
  15304. + opt->type = token;
  15305. + break;
  15306. + case Opt_append:
  15307. + err = opt_add(opt, a->args[0].from, opts->sb_flags,
  15308. + /*dummy bindex*/1);
  15309. + if (!err)
  15310. + opt->type = token;
  15311. + break;
  15312. + case Opt_prepend:
  15313. + err = opt_add(opt, a->args[0].from, opts->sb_flags,
  15314. + /*bindex*/0);
  15315. + if (!err)
  15316. + opt->type = token;
  15317. + break;
  15318. + case Opt_del:
  15319. + err = au_opts_parse_del(&opt->del, a->args);
  15320. + if (!err)
  15321. + opt->type = token;
  15322. + break;
  15323. +#if 0 /* reserved for future use */
  15324. + case Opt_idel:
  15325. + del->pathname = "(indexed)";
  15326. + if (unlikely(match_int(&args[0], &n))) {
  15327. + AuErr("bad integer in %s\n", opt_str);
  15328. + break;
  15329. + }
  15330. + err = au_opts_parse_idel(sb, n, &opt->del, a->args);
  15331. + if (!err)
  15332. + opt->type = token;
  15333. + break;
  15334. +#endif
  15335. + case Opt_mod:
  15336. + err = au_opts_parse_mod(&opt->mod, a->args);
  15337. + if (!err)
  15338. + opt->type = token;
  15339. + break;
  15340. +#ifdef IMOD /* reserved for future use */
  15341. + case Opt_imod:
  15342. + u.mod->path = "(indexed)";
  15343. + if (unlikely(match_int(&a->args[0], &n))) {
  15344. + AuErr("bad integer in %s\n", opt_str);
  15345. + break;
  15346. + }
  15347. + err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
  15348. + if (!err)
  15349. + opt->type = token;
  15350. + break;
  15351. +#endif
  15352. + case Opt_xino:
  15353. + err = au_opts_parse_xino(sb, &opt->xino, a->args);
  15354. + if (!err)
  15355. + opt->type = token;
  15356. + break;
  15357. +
  15358. + case Opt_trunc_xino_path:
  15359. + err = au_opts_parse_xino_itrunc_path
  15360. + (sb, &opt->xino_itrunc, a->args);
  15361. + if (!err)
  15362. + opt->type = token;
  15363. + break;
  15364. +
  15365. + case Opt_itrunc_xino:
  15366. + u.xino_itrunc = &opt->xino_itrunc;
  15367. + if (unlikely(match_int(&a->args[0], &n))) {
  15368. + AuErr("bad integer in %s\n", opt_str);
  15369. + break;
  15370. + }
  15371. + u.xino_itrunc->bindex = n;
  15372. + aufs_read_lock(root, AuLock_FLUSH);
  15373. + if (n < 0 || au_sbend(sb) < n) {
  15374. + AuErr("out of bounds, %d\n", n);
  15375. + aufs_read_unlock(root, !AuLock_IR);
  15376. + break;
  15377. + }
  15378. + aufs_read_unlock(root, !AuLock_IR);
  15379. + err = 0;
  15380. + opt->type = token;
  15381. + break;
  15382. +
  15383. + case Opt_dirwh:
  15384. + if (unlikely(match_int(&a->args[0], &opt->dirwh)))
  15385. + break;
  15386. + err = 0;
  15387. + opt->type = token;
  15388. + break;
  15389. +
  15390. + case Opt_rdcache:
  15391. + if (unlikely(match_int(&a->args[0], &opt->rdcache)))
  15392. + break;
  15393. + err = 0;
  15394. + opt->type = token;
  15395. + break;
  15396. + case Opt_rdblk:
  15397. + if (unlikely(match_int(&a->args[0], &n)
  15398. + || n <= 0
  15399. + || n > KMALLOC_MAX_SIZE)) {
  15400. + AuErr("bad integer in %s\n", opt_str);
  15401. + break;
  15402. + }
  15403. + if (unlikely(n < NAME_MAX)) {
  15404. + AuErr("rdblk must be larger than %d\n",
  15405. + NAME_MAX);
  15406. + break;
  15407. + }
  15408. + opt->rdblk = n;
  15409. + err = 0;
  15410. + opt->type = token;
  15411. + break;
  15412. + case Opt_rdhash:
  15413. + if (unlikely(match_int(&a->args[0], &n)
  15414. + || n <= 0
  15415. + || n * sizeof(struct hlist_head)
  15416. + > KMALLOC_MAX_SIZE)) {
  15417. + AuErr("bad integer in %s\n", opt_str);
  15418. + break;
  15419. + }
  15420. + opt->rdhash = n;
  15421. + err = 0;
  15422. + opt->type = token;
  15423. + break;
  15424. +
  15425. + case Opt_trunc_xino:
  15426. + case Opt_notrunc_xino:
  15427. + case Opt_noxino:
  15428. + case Opt_trunc_xib:
  15429. + case Opt_notrunc_xib:
  15430. + case Opt_shwh:
  15431. + case Opt_noshwh:
  15432. + case Opt_plink:
  15433. + case Opt_noplink:
  15434. + case Opt_list_plink:
  15435. + case Opt_diropq_a:
  15436. + case Opt_diropq_w:
  15437. + case Opt_warn_perm:
  15438. + case Opt_nowarn_perm:
  15439. + case Opt_refrof:
  15440. + case Opt_norefrof:
  15441. + case Opt_verbose:
  15442. + case Opt_noverbose:
  15443. + case Opt_sum:
  15444. + case Opt_nosum:
  15445. + case Opt_wsum:
  15446. + case Opt_rdblk_def:
  15447. + case Opt_rdhash_def:
  15448. + err = 0;
  15449. + opt->type = token;
  15450. + break;
  15451. +
  15452. + case Opt_udba:
  15453. + opt->udba = udba_val(a->args[0].from);
  15454. + if (opt->udba >= 0) {
  15455. + err = 0;
  15456. + opt->type = token;
  15457. + } else
  15458. + AuErr("wrong value, %s\n", opt_str);
  15459. + break;
  15460. +
  15461. + case Opt_wbr_create:
  15462. + u.create = &opt->wbr_create;
  15463. + u.create->wbr_create
  15464. + = au_wbr_create_val(a->args[0].from, u.create);
  15465. + if (u.create->wbr_create >= 0) {
  15466. + err = 0;
  15467. + opt->type = token;
  15468. + } else
  15469. + AuErr("wrong value, %s\n", opt_str);
  15470. + break;
  15471. + case Opt_wbr_copyup:
  15472. + opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
  15473. + if (opt->wbr_copyup >= 0) {
  15474. + err = 0;
  15475. + opt->type = token;
  15476. + } else
  15477. + AuErr("wrong value, %s\n", opt_str);
  15478. + break;
  15479. +
  15480. + case Opt_ignore:
  15481. + AuWarn("ignored %s\n", opt_str);
  15482. + /*FALLTHROUGH*/
  15483. + case Opt_ignore_silent:
  15484. + skipped = 1;
  15485. + err = 0;
  15486. + break;
  15487. + case Opt_err:
  15488. + AuErr("unknown option %s\n", opt_str);
  15489. + break;
  15490. + }
  15491. +
  15492. + if (!err && !skipped) {
  15493. + if (unlikely(++opt > opt_tail)) {
  15494. + err = -E2BIG;
  15495. + opt--;
  15496. + opt->type = Opt_tail;
  15497. + break;
  15498. + }
  15499. + opt->type = Opt_tail;
  15500. + }
  15501. + }
  15502. +
  15503. + kfree(a);
  15504. + dump_opts(opts);
  15505. + if (unlikely(err))
  15506. + au_opts_free(opts);
  15507. +
  15508. + out:
  15509. + return err;
  15510. +}
  15511. +
  15512. +static int au_opt_wbr_create(struct super_block *sb,
  15513. + struct au_opt_wbr_create *create)
  15514. +{
  15515. + int err;
  15516. + struct au_sbinfo *sbinfo;
  15517. +
  15518. + SiMustWriteLock(sb);
  15519. +
  15520. + err = 1; /* handled */
  15521. + sbinfo = au_sbi(sb);
  15522. + if (sbinfo->si_wbr_create_ops->fin) {
  15523. + err = sbinfo->si_wbr_create_ops->fin(sb);
  15524. + if (!err)
  15525. + err = 1;
  15526. + }
  15527. +
  15528. + sbinfo->si_wbr_create = create->wbr_create;
  15529. + sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
  15530. + switch (create->wbr_create) {
  15531. + case AuWbrCreate_MFSRRV:
  15532. + case AuWbrCreate_MFSRR:
  15533. + sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
  15534. + /*FALLTHROUGH*/
  15535. + case AuWbrCreate_MFS:
  15536. + case AuWbrCreate_MFSV:
  15537. + case AuWbrCreate_PMFS:
  15538. + case AuWbrCreate_PMFSV:
  15539. + sbinfo->si_wbr_mfs.mfs_expire = create->mfs_second * HZ;
  15540. + break;
  15541. + }
  15542. +
  15543. + if (sbinfo->si_wbr_create_ops->init)
  15544. + sbinfo->si_wbr_create_ops->init(sb); /* ignore */
  15545. +
  15546. + return err;
  15547. +}
  15548. +
  15549. +/*
  15550. + * returns,
  15551. + * plus: processed without an error
  15552. + * zero: unprocessed
  15553. + */
  15554. +static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
  15555. + struct au_opts *opts)
  15556. +{
  15557. + int err;
  15558. + struct au_sbinfo *sbinfo;
  15559. +
  15560. + SiMustWriteLock(sb);
  15561. +
  15562. + err = 1; /* handled */
  15563. + sbinfo = au_sbi(sb);
  15564. + switch (opt->type) {
  15565. + case Opt_udba:
  15566. + sbinfo->si_mntflags &= ~AuOptMask_UDBA;
  15567. + sbinfo->si_mntflags |= opt->udba;
  15568. + opts->given_udba |= opt->udba;
  15569. + break;
  15570. +
  15571. + case Opt_plink:
  15572. + au_opt_set(sbinfo->si_mntflags, PLINK);
  15573. + break;
  15574. + case Opt_noplink:
  15575. + if (au_opt_test(sbinfo->si_mntflags, PLINK))
  15576. + au_plink_put(sb);
  15577. + au_opt_clr(sbinfo->si_mntflags, PLINK);
  15578. + break;
  15579. + case Opt_list_plink:
  15580. + if (au_opt_test(sbinfo->si_mntflags, PLINK))
  15581. + au_plink_list(sb);
  15582. + break;
  15583. +
  15584. + case Opt_diropq_a:
  15585. + au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
  15586. + break;
  15587. + case Opt_diropq_w:
  15588. + au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
  15589. + break;
  15590. +
  15591. + case Opt_warn_perm:
  15592. + au_opt_set(sbinfo->si_mntflags, WARN_PERM);
  15593. + break;
  15594. + case Opt_nowarn_perm:
  15595. + au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
  15596. + break;
  15597. +
  15598. + case Opt_refrof:
  15599. + au_opt_set(sbinfo->si_mntflags, REFROF);
  15600. + break;
  15601. + case Opt_norefrof:
  15602. + au_opt_clr(sbinfo->si_mntflags, REFROF);
  15603. + break;
  15604. +
  15605. + case Opt_verbose:
  15606. + au_opt_set(sbinfo->si_mntflags, VERBOSE);
  15607. + break;
  15608. + case Opt_noverbose:
  15609. + au_opt_clr(sbinfo->si_mntflags, VERBOSE);
  15610. + break;
  15611. +
  15612. + case Opt_sum:
  15613. + au_opt_set(sbinfo->si_mntflags, SUM);
  15614. + break;
  15615. + case Opt_wsum:
  15616. + au_opt_clr(sbinfo->si_mntflags, SUM);
  15617. + au_opt_set(sbinfo->si_mntflags, SUM_W);
  15618. + case Opt_nosum:
  15619. + au_opt_clr(sbinfo->si_mntflags, SUM);
  15620. + au_opt_clr(sbinfo->si_mntflags, SUM_W);
  15621. + break;
  15622. +
  15623. + case Opt_wbr_create:
  15624. + err = au_opt_wbr_create(sb, &opt->wbr_create);
  15625. + break;
  15626. + case Opt_wbr_copyup:
  15627. + sbinfo->si_wbr_copyup = opt->wbr_copyup;
  15628. + sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
  15629. + break;
  15630. +
  15631. + case Opt_dirwh:
  15632. + sbinfo->si_dirwh = opt->dirwh;
  15633. + break;
  15634. +
  15635. + case Opt_rdcache:
  15636. + sbinfo->si_rdcache = opt->rdcache * HZ;
  15637. + break;
  15638. + case Opt_rdblk:
  15639. + sbinfo->si_rdblk = opt->rdblk;
  15640. + break;
  15641. + case Opt_rdblk_def:
  15642. + sbinfo->si_rdblk = AUFS_RDBLK_DEF;
  15643. + break;
  15644. + case Opt_rdhash:
  15645. + sbinfo->si_rdhash = opt->rdhash;
  15646. + break;
  15647. + case Opt_rdhash_def:
  15648. + sbinfo->si_rdhash = AUFS_RDHASH_DEF;
  15649. + break;
  15650. +
  15651. + case Opt_shwh:
  15652. + au_opt_set(sbinfo->si_mntflags, SHWH);
  15653. + break;
  15654. + case Opt_noshwh:
  15655. + au_opt_clr(sbinfo->si_mntflags, SHWH);
  15656. + break;
  15657. +
  15658. + case Opt_trunc_xino:
  15659. + au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
  15660. + break;
  15661. + case Opt_notrunc_xino:
  15662. + au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
  15663. + break;
  15664. +
  15665. + case Opt_trunc_xino_path:
  15666. + case Opt_itrunc_xino:
  15667. + err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
  15668. + if (!err)
  15669. + err = 1;
  15670. + break;
  15671. +
  15672. + case Opt_trunc_xib:
  15673. + au_fset_opts(opts->flags, TRUNC_XIB);
  15674. + break;
  15675. + case Opt_notrunc_xib:
  15676. + au_fclr_opts(opts->flags, TRUNC_XIB);
  15677. + break;
  15678. +
  15679. + default:
  15680. + err = 0;
  15681. + break;
  15682. + }
  15683. +
  15684. + return err;
  15685. +}
  15686. +
  15687. +/*
  15688. + * returns tri-state.
  15689. + * plus: processed without an error
  15690. + * zero: unprocessed
  15691. + * minus: error
  15692. + */
  15693. +static int au_opt_br(struct super_block *sb, struct au_opt *opt,
  15694. + struct au_opts *opts)
  15695. +{
  15696. + int err, do_refresh;
  15697. +
  15698. + err = 0;
  15699. + switch (opt->type) {
  15700. + case Opt_append:
  15701. + opt->add.bindex = au_sbend(sb) + 1;
  15702. + if (opt->add.bindex < 0)
  15703. + opt->add.bindex = 0;
  15704. + goto add;
  15705. + case Opt_prepend:
  15706. + opt->add.bindex = 0;
  15707. + add:
  15708. + case Opt_add:
  15709. + err = au_br_add(sb, &opt->add,
  15710. + au_ftest_opts(opts->flags, REMOUNT));
  15711. + if (!err) {
  15712. + err = 1;
  15713. + au_fset_opts(opts->flags, REFRESH_DIR);
  15714. + if (au_br_whable(opt->add.perm))
  15715. + au_fset_opts(opts->flags, REFRESH_NONDIR);
  15716. + }
  15717. + break;
  15718. +
  15719. + case Opt_del:
  15720. + case Opt_idel:
  15721. + err = au_br_del(sb, &opt->del,
  15722. + au_ftest_opts(opts->flags, REMOUNT));
  15723. + if (!err) {
  15724. + err = 1;
  15725. + au_fset_opts(opts->flags, TRUNC_XIB);
  15726. + au_fset_opts(opts->flags, REFRESH_DIR);
  15727. + au_fset_opts(opts->flags, REFRESH_NONDIR);
  15728. + }
  15729. + break;
  15730. +
  15731. + case Opt_mod:
  15732. + case Opt_imod:
  15733. + err = au_br_mod(sb, &opt->mod,
  15734. + au_ftest_opts(opts->flags, REMOUNT),
  15735. + &do_refresh);
  15736. + if (!err) {
  15737. + err = 1;
  15738. + if (do_refresh) {
  15739. + au_fset_opts(opts->flags, REFRESH_DIR);
  15740. + au_fset_opts(opts->flags, REFRESH_NONDIR);
  15741. + }
  15742. + }
  15743. + break;
  15744. + }
  15745. +
  15746. + return err;
  15747. +}
  15748. +
  15749. +static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
  15750. + struct au_opt_xino **opt_xino,
  15751. + struct au_opts *opts)
  15752. +{
  15753. + int err;
  15754. + aufs_bindex_t bend, bindex;
  15755. + struct dentry *root, *parent, *h_root;
  15756. +
  15757. + err = 0;
  15758. + switch (opt->type) {
  15759. + case Opt_xino:
  15760. + err = au_xino_set(sb, &opt->xino,
  15761. + !!au_ftest_opts(opts->flags, REMOUNT));
  15762. + if (unlikely(err))
  15763. + break;
  15764. +
  15765. + *opt_xino = &opt->xino;
  15766. + au_xino_brid_set(sb, -1);
  15767. +
  15768. + /* safe d_parent access */
  15769. + parent = opt->xino.file->f_dentry->d_parent;
  15770. + root = sb->s_root;
  15771. + bend = au_sbend(sb);
  15772. + for (bindex = 0; bindex <= bend; bindex++) {
  15773. + h_root = au_h_dptr(root, bindex);
  15774. + if (h_root == parent) {
  15775. + au_xino_brid_set(sb, au_sbr_id(sb, bindex));
  15776. + break;
  15777. + }
  15778. + }
  15779. + break;
  15780. +
  15781. + case Opt_noxino:
  15782. + au_xino_clr(sb);
  15783. + au_xino_brid_set(sb, -1);
  15784. + *opt_xino = (void *)-1;
  15785. + break;
  15786. + }
  15787. +
  15788. + return err;
  15789. +}
  15790. +
  15791. +int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
  15792. + unsigned int pending)
  15793. +{
  15794. + int err;
  15795. + aufs_bindex_t bindex, bend;
  15796. + unsigned char do_plink, skip, do_free;
  15797. + struct au_branch *br;
  15798. + struct au_wbr *wbr;
  15799. + struct dentry *root;
  15800. + struct inode *dir, *h_dir;
  15801. + struct au_sbinfo *sbinfo;
  15802. + struct au_hinode *hdir;
  15803. +
  15804. + SiMustAnyLock(sb);
  15805. +
  15806. + sbinfo = au_sbi(sb);
  15807. + AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
  15808. +
  15809. + if (!(sb_flags & MS_RDONLY)) {
  15810. + if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
  15811. + AuWarn("first branch should be rw\n");
  15812. + if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
  15813. + AuWarn("shwh should be used with ro\n");
  15814. + }
  15815. +
  15816. + if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HINOTIFY)
  15817. + && !au_opt_test(sbinfo->si_mntflags, XINO))
  15818. + AuWarn("udba=inotify requires xino\n");
  15819. +
  15820. + err = 0;
  15821. + root = sb->s_root;
  15822. + dir = sb->s_root->d_inode;
  15823. + do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
  15824. + bend = au_sbend(sb);
  15825. + for (bindex = 0; !err && bindex <= bend; bindex++) {
  15826. + skip = 0;
  15827. + h_dir = au_h_iptr(dir, bindex);
  15828. + br = au_sbr(sb, bindex);
  15829. + do_free = 0;
  15830. +
  15831. + wbr = br->br_wbr;
  15832. + if (wbr)
  15833. + wbr_wh_read_lock(wbr);
  15834. +
  15835. + switch (br->br_perm) {
  15836. + case AuBrPerm_RO:
  15837. + case AuBrPerm_ROWH:
  15838. + case AuBrPerm_RR:
  15839. + case AuBrPerm_RRWH:
  15840. + do_free = !!wbr;
  15841. + skip = (!wbr
  15842. + || (!wbr->wbr_whbase
  15843. + && !wbr->wbr_plink
  15844. + && !wbr->wbr_orph));
  15845. + break;
  15846. +
  15847. + case AuBrPerm_RWNoLinkWH:
  15848. + /* skip = (!br->br_whbase && !br->br_orph); */
  15849. + skip = (!wbr || !wbr->wbr_whbase);
  15850. + if (skip && wbr) {
  15851. + if (do_plink)
  15852. + skip = !!wbr->wbr_plink;
  15853. + else
  15854. + skip = !wbr->wbr_plink;
  15855. + }
  15856. + break;
  15857. +
  15858. + case AuBrPerm_RW:
  15859. + /* skip = (br->br_whbase && br->br_ohph); */
  15860. + skip = (wbr && wbr->wbr_whbase);
  15861. + if (skip) {
  15862. + if (do_plink)
  15863. + skip = !!wbr->wbr_plink;
  15864. + else
  15865. + skip = !wbr->wbr_plink;
  15866. + }
  15867. + break;
  15868. +
  15869. + default:
  15870. + BUG();
  15871. + }
  15872. + if (wbr)
  15873. + wbr_wh_read_unlock(wbr);
  15874. +
  15875. + if (skip)
  15876. + continue;
  15877. +
  15878. + hdir = au_hi(dir, bindex);
  15879. + au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT);
  15880. + if (wbr)
  15881. + wbr_wh_write_lock(wbr);
  15882. + err = au_wh_init(au_h_dptr(root, bindex), br, sb);
  15883. + if (wbr)
  15884. + wbr_wh_write_unlock(wbr);
  15885. + au_hin_imtx_unlock(hdir);
  15886. +
  15887. + if (!err && do_free) {
  15888. + kfree(wbr);
  15889. + br->br_wbr = NULL;
  15890. + }
  15891. + }
  15892. +
  15893. + return err;
  15894. +}
  15895. +
  15896. +int au_opts_mount(struct super_block *sb, struct au_opts *opts)
  15897. +{
  15898. + int err;
  15899. + unsigned int tmp;
  15900. + aufs_bindex_t bend;
  15901. + struct au_opt *opt;
  15902. + struct au_opt_xino *opt_xino, xino;
  15903. + struct au_sbinfo *sbinfo;
  15904. +
  15905. + SiMustWriteLock(sb);
  15906. +
  15907. + err = 0;
  15908. + opt_xino = NULL;
  15909. + opt = opts->opt;
  15910. + while (err >= 0 && opt->type != Opt_tail)
  15911. + err = au_opt_simple(sb, opt++, opts);
  15912. + if (err > 0)
  15913. + err = 0;
  15914. + else if (unlikely(err < 0))
  15915. + goto out;
  15916. +
  15917. + /* disable xino and udba temporary */
  15918. + sbinfo = au_sbi(sb);
  15919. + tmp = sbinfo->si_mntflags;
  15920. + au_opt_clr(sbinfo->si_mntflags, XINO);
  15921. + au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
  15922. +
  15923. + opt = opts->opt;
  15924. + while (err >= 0 && opt->type != Opt_tail)
  15925. + err = au_opt_br(sb, opt++, opts);
  15926. + if (err > 0)
  15927. + err = 0;
  15928. + else if (unlikely(err < 0))
  15929. + goto out;
  15930. +
  15931. + bend = au_sbend(sb);
  15932. + if (unlikely(bend < 0)) {
  15933. + err = -EINVAL;
  15934. + AuErr("no branches\n");
  15935. + goto out;
  15936. + }
  15937. +
  15938. + if (au_opt_test(tmp, XINO))
  15939. + au_opt_set(sbinfo->si_mntflags, XINO);
  15940. + opt = opts->opt;
  15941. + while (!err && opt->type != Opt_tail)
  15942. + err = au_opt_xino(sb, opt++, &opt_xino, opts);
  15943. + if (unlikely(err))
  15944. + goto out;
  15945. +
  15946. + err = au_opts_verify(sb, sb->s_flags, tmp);
  15947. + if (unlikely(err))
  15948. + goto out;
  15949. +
  15950. + /* restore xino */
  15951. + if (au_opt_test(tmp, XINO) && !opt_xino) {
  15952. + xino.file = au_xino_def(sb);
  15953. + err = PTR_ERR(xino.file);
  15954. + if (IS_ERR(xino.file))
  15955. + goto out;
  15956. +
  15957. + err = au_xino_set(sb, &xino, /*remount*/0);
  15958. + fput(xino.file);
  15959. + if (unlikely(err))
  15960. + goto out;
  15961. + }
  15962. +
  15963. + /* restore udba */
  15964. + sbinfo->si_mntflags &= ~AuOptMask_UDBA;
  15965. + sbinfo->si_mntflags |= (tmp & AuOptMask_UDBA);
  15966. + if (au_opt_test(tmp, UDBA_HINOTIFY)) {
  15967. + struct inode *dir = sb->s_root->d_inode;
  15968. + au_reset_hinotify(dir,
  15969. + au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
  15970. + }
  15971. +
  15972. + out:
  15973. + return err;
  15974. +}
  15975. +
  15976. +int au_opts_remount(struct super_block *sb, struct au_opts *opts)
  15977. +{
  15978. + int err, rerr;
  15979. + struct inode *dir;
  15980. + struct au_opt_xino *opt_xino;
  15981. + struct au_opt *opt;
  15982. + struct au_sbinfo *sbinfo;
  15983. +
  15984. + SiMustWriteLock(sb);
  15985. +
  15986. + dir = sb->s_root->d_inode;
  15987. + sbinfo = au_sbi(sb);
  15988. + err = 0;
  15989. + opt_xino = NULL;
  15990. + opt = opts->opt;
  15991. + while (err >= 0 && opt->type != Opt_tail) {
  15992. + err = au_opt_simple(sb, opt, opts);
  15993. + if (!err)
  15994. + err = au_opt_br(sb, opt, opts);
  15995. + if (!err)
  15996. + err = au_opt_xino(sb, opt, &opt_xino, opts);
  15997. + opt++;
  15998. + }
  15999. + if (err > 0)
  16000. + err = 0;
  16001. + AuTraceErr(err);
  16002. + /* go on even err */
  16003. +
  16004. + rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
  16005. + if (unlikely(rerr && !err))
  16006. + err = rerr;
  16007. +
  16008. + if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
  16009. + rerr = au_xib_trunc(sb);
  16010. + if (unlikely(rerr && !err))
  16011. + err = rerr;
  16012. + }
  16013. +
  16014. + /* will be handled by the caller */
  16015. + if (!au_ftest_opts(opts->flags, REFRESH_DIR)
  16016. + && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO)))
  16017. + au_fset_opts(opts->flags, REFRESH_DIR);
  16018. +
  16019. + AuDbg("status 0x%x\n", opts->flags);
  16020. + return err;
  16021. +}
  16022. +
  16023. +/* ---------------------------------------------------------------------- */
  16024. +
  16025. +unsigned int au_opt_udba(struct super_block *sb)
  16026. +{
  16027. + return au_mntflags(sb) & AuOptMask_UDBA;
  16028. +}
  16029. diff -Nur linux-2.6.31.5.orig/fs/aufs/opts.h linux-2.6.31.5/fs/aufs/opts.h
  16030. --- linux-2.6.31.5.orig/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100
  16031. +++ linux-2.6.31.5/fs/aufs/opts.h 2009-11-15 22:02:37.000000000 +0100
  16032. @@ -0,0 +1,196 @@
  16033. +/*
  16034. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  16035. + *
  16036. + * This program, aufs is free software; you can redistribute it and/or modify
  16037. + * it under the terms of the GNU General Public License as published by
  16038. + * the Free Software Foundation; either version 2 of the License, or
  16039. + * (at your option) any later version.
  16040. + *
  16041. + * This program is distributed in the hope that it will be useful,
  16042. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16043. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16044. + * GNU General Public License for more details.
  16045. + *
  16046. + * You should have received a copy of the GNU General Public License
  16047. + * along with this program; if not, write to the Free Software
  16048. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16049. + */
  16050. +
  16051. +/*
  16052. + * mount options/flags
  16053. + */
  16054. +
  16055. +#ifndef __AUFS_OPTS_H__
  16056. +#define __AUFS_OPTS_H__
  16057. +
  16058. +#ifdef __KERNEL__
  16059. +
  16060. +#include <linux/path.h>
  16061. +#include <linux/aufs_type.h>
  16062. +
  16063. +struct file;
  16064. +struct super_block;
  16065. +
  16066. +/* ---------------------------------------------------------------------- */
  16067. +
  16068. +/* mount flags */
  16069. +#define AuOpt_XINO 1 /* external inode number bitmap
  16070. + and translation table */
  16071. +#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */
  16072. +#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */
  16073. +#define AuOpt_UDBA_REVAL (1 << 3)
  16074. +#define AuOpt_UDBA_HINOTIFY (1 << 4)
  16075. +#define AuOpt_SHWH (1 << 5) /* show whiteout */
  16076. +#define AuOpt_PLINK (1 << 6) /* pseudo-link */
  16077. +#define AuOpt_DIRPERM1 (1 << 7) /* unimplemented */
  16078. +#define AuOpt_REFROF (1 << 8) /* unimplemented */
  16079. +#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */
  16080. +#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
  16081. +#define AuOpt_SUM_W (1 << 11) /* unimplemented */
  16082. +#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */
  16083. +#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */
  16084. +
  16085. +#ifndef CONFIG_AUFS_HINOTIFY
  16086. +#undef AuOpt_UDBA_HINOTIFY
  16087. +#define AuOpt_UDBA_HINOTIFY 0
  16088. +#endif
  16089. +#ifndef CONFIG_AUFS_SHWH
  16090. +#undef AuOpt_SHWH
  16091. +#define AuOpt_SHWH 0
  16092. +#endif
  16093. +
  16094. +#define AuOpt_Def (AuOpt_XINO \
  16095. + | AuOpt_UDBA_REVAL \
  16096. + | AuOpt_PLINK \
  16097. + /* | AuOpt_DIRPERM1 */ \
  16098. + | AuOpt_WARN_PERM)
  16099. +#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
  16100. + | AuOpt_UDBA_REVAL \
  16101. + | AuOpt_UDBA_HINOTIFY)
  16102. +
  16103. +#define au_opt_test(flags, name) (flags & AuOpt_##name)
  16104. +#define au_opt_set(flags, name) do { \
  16105. + BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
  16106. + ((flags) |= AuOpt_##name); \
  16107. +} while (0)
  16108. +#define au_opt_set_udba(flags, name) do { \
  16109. + (flags) &= ~AuOptMask_UDBA; \
  16110. + ((flags) |= AuOpt_##name); \
  16111. +} while (0)
  16112. +#define au_opt_clr(flags, name) { ((flags) &= ~AuOpt_##name); }
  16113. +
  16114. +/* ---------------------------------------------------------------------- */
  16115. +
  16116. +/* policies to select one among multiple writable branches */
  16117. +enum {
  16118. + AuWbrCreate_TDP, /* top down parent */
  16119. + AuWbrCreate_RR, /* round robin */
  16120. + AuWbrCreate_MFS, /* most free space */
  16121. + AuWbrCreate_MFSV, /* mfs with seconds */
  16122. + AuWbrCreate_MFSRR, /* mfs then rr */
  16123. + AuWbrCreate_MFSRRV, /* mfs then rr with seconds */
  16124. + AuWbrCreate_PMFS, /* parent and mfs */
  16125. + AuWbrCreate_PMFSV, /* parent and mfs with seconds */
  16126. +
  16127. + AuWbrCreate_Def = AuWbrCreate_TDP
  16128. +};
  16129. +
  16130. +enum {
  16131. + AuWbrCopyup_TDP, /* top down parent */
  16132. + AuWbrCopyup_BUP, /* bottom up parent */
  16133. + AuWbrCopyup_BU, /* bottom up */
  16134. +
  16135. + AuWbrCopyup_Def = AuWbrCopyup_TDP
  16136. +};
  16137. +
  16138. +/* ---------------------------------------------------------------------- */
  16139. +
  16140. +struct au_opt_add {
  16141. + aufs_bindex_t bindex;
  16142. + char *pathname;
  16143. + int perm;
  16144. + struct path path;
  16145. +};
  16146. +
  16147. +struct au_opt_del {
  16148. + char *pathname;
  16149. + struct path h_path;
  16150. +};
  16151. +
  16152. +struct au_opt_mod {
  16153. + char *path;
  16154. + int perm;
  16155. + struct dentry *h_root;
  16156. +};
  16157. +
  16158. +struct au_opt_xino {
  16159. + char *path;
  16160. + struct file *file;
  16161. +};
  16162. +
  16163. +struct au_opt_xino_itrunc {
  16164. + aufs_bindex_t bindex;
  16165. +};
  16166. +
  16167. +struct au_opt_wbr_create {
  16168. + int wbr_create;
  16169. + int mfs_second;
  16170. + unsigned long long mfsrr_watermark;
  16171. +};
  16172. +
  16173. +struct au_opt {
  16174. + int type;
  16175. + union {
  16176. + struct au_opt_xino xino;
  16177. + struct au_opt_xino_itrunc xino_itrunc;
  16178. + struct au_opt_add add;
  16179. + struct au_opt_del del;
  16180. + struct au_opt_mod mod;
  16181. + int dirwh;
  16182. + int rdcache;
  16183. + unsigned int rdblk;
  16184. + unsigned int rdhash;
  16185. + int udba;
  16186. + struct au_opt_wbr_create wbr_create;
  16187. + int wbr_copyup;
  16188. + };
  16189. +};
  16190. +
  16191. +/* opts flags */
  16192. +#define AuOpts_REMOUNT 1
  16193. +#define AuOpts_REFRESH_DIR (1 << 1)
  16194. +#define AuOpts_REFRESH_NONDIR (1 << 2)
  16195. +#define AuOpts_TRUNC_XIB (1 << 3)
  16196. +#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
  16197. +#define au_fset_opts(flags, name) { (flags) |= AuOpts_##name; }
  16198. +#define au_fclr_opts(flags, name) { (flags) &= ~AuOpts_##name; }
  16199. +
  16200. +struct au_opts {
  16201. + struct au_opt *opt;
  16202. + int max_opt;
  16203. +
  16204. + unsigned int given_udba;
  16205. + unsigned int flags;
  16206. + unsigned long sb_flags;
  16207. +};
  16208. +
  16209. +/* ---------------------------------------------------------------------- */
  16210. +
  16211. +const char *au_optstr_br_perm(int brperm);
  16212. +const char *au_optstr_udba(int udba);
  16213. +const char *au_optstr_wbr_copyup(int wbr_copyup);
  16214. +const char *au_optstr_wbr_create(int wbr_create);
  16215. +
  16216. +void au_opts_free(struct au_opts *opts);
  16217. +int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
  16218. +int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
  16219. + unsigned int pending);
  16220. +int au_opts_mount(struct super_block *sb, struct au_opts *opts);
  16221. +int au_opts_remount(struct super_block *sb, struct au_opts *opts);
  16222. +
  16223. +unsigned int au_opt_udba(struct super_block *sb);
  16224. +
  16225. +/* ---------------------------------------------------------------------- */
  16226. +
  16227. +#endif /* __KERNEL__ */
  16228. +#endif /* __AUFS_OPTS_H__ */
  16229. diff -Nur linux-2.6.31.5.orig/fs/aufs/plink.c linux-2.6.31.5/fs/aufs/plink.c
  16230. --- linux-2.6.31.5.orig/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100
  16231. +++ linux-2.6.31.5/fs/aufs/plink.c 2009-11-15 22:02:37.000000000 +0100
  16232. @@ -0,0 +1,354 @@
  16233. +/*
  16234. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  16235. + *
  16236. + * This program, aufs is free software; you can redistribute it and/or modify
  16237. + * it under the terms of the GNU General Public License as published by
  16238. + * the Free Software Foundation; either version 2 of the License, or
  16239. + * (at your option) any later version.
  16240. + *
  16241. + * This program is distributed in the hope that it will be useful,
  16242. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16243. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16244. + * GNU General Public License for more details.
  16245. + *
  16246. + * You should have received a copy of the GNU General Public License
  16247. + * along with this program; if not, write to the Free Software
  16248. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16249. + */
  16250. +
  16251. +/*
  16252. + * pseudo-link
  16253. + */
  16254. +
  16255. +#include "aufs.h"
  16256. +
  16257. +/*
  16258. + * during a user process maintains the pseudo-links,
  16259. + * prohibit adding a new plink and branch manipulation.
  16260. + */
  16261. +void au_plink_block_maintain(struct super_block *sb)
  16262. +{
  16263. + struct au_sbinfo *sbi = au_sbi(sb);
  16264. +
  16265. + SiMustAnyLock(sb);
  16266. +
  16267. + /* gave up wake_up_bit() */
  16268. + wait_event(sbi->si_plink_wq, !au_ftest_si(sbi, MAINTAIN_PLINK));
  16269. +}
  16270. +
  16271. +/* ---------------------------------------------------------------------- */
  16272. +
  16273. +struct pseudo_link {
  16274. + struct list_head list;
  16275. + struct inode *inode;
  16276. +};
  16277. +
  16278. +#ifdef CONFIG_AUFS_DEBUG
  16279. +void au_plink_list(struct super_block *sb)
  16280. +{
  16281. + struct au_sbinfo *sbinfo;
  16282. + struct list_head *plink_list;
  16283. + struct pseudo_link *plink;
  16284. +
  16285. + SiMustAnyLock(sb);
  16286. +
  16287. + sbinfo = au_sbi(sb);
  16288. + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
  16289. +
  16290. + plink_list = &sbinfo->si_plink.head;
  16291. + spin_lock(&sbinfo->si_plink.spin);
  16292. + list_for_each_entry(plink, plink_list, list)
  16293. + AuDbg("%lu\n", plink->inode->i_ino);
  16294. + spin_unlock(&sbinfo->si_plink.spin);
  16295. +}
  16296. +#endif
  16297. +
  16298. +/* is the inode pseudo-linked? */
  16299. +int au_plink_test(struct inode *inode)
  16300. +{
  16301. + int found;
  16302. + struct au_sbinfo *sbinfo;
  16303. + struct list_head *plink_list;
  16304. + struct pseudo_link *plink;
  16305. +
  16306. + sbinfo = au_sbi(inode->i_sb);
  16307. + AuRwMustAnyLock(&sbinfo->si_rwsem);
  16308. + AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
  16309. +
  16310. + found = 0;
  16311. + plink_list = &sbinfo->si_plink.head;
  16312. + spin_lock(&sbinfo->si_plink.spin);
  16313. + list_for_each_entry(plink, plink_list, list)
  16314. + if (plink->inode == inode) {
  16315. + found = 1;
  16316. + break;
  16317. + }
  16318. + spin_unlock(&sbinfo->si_plink.spin);
  16319. + return found;
  16320. +}
  16321. +
  16322. +/* ---------------------------------------------------------------------- */
  16323. +
  16324. +/*
  16325. + * generate a name for plink.
  16326. + * the file will be stored under AUFS_WH_PLINKDIR.
  16327. + */
  16328. +/* 20 is max digits length of ulong 64 */
  16329. +#define PLINK_NAME_LEN ((20 + 1) * 2)
  16330. +
  16331. +static int plink_name(char *name, int len, struct inode *inode,
  16332. + aufs_bindex_t bindex)
  16333. +{
  16334. + int rlen;
  16335. + struct inode *h_inode;
  16336. +
  16337. + h_inode = au_h_iptr(inode, bindex);
  16338. + rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
  16339. + return rlen;
  16340. +}
  16341. +
  16342. +/* lookup the plink-ed @inode under the branch at @bindex */
  16343. +struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
  16344. +{
  16345. + struct dentry *h_dentry, *h_parent;
  16346. + struct au_branch *br;
  16347. + struct inode *h_dir;
  16348. + char a[PLINK_NAME_LEN];
  16349. + struct qstr tgtname = {
  16350. + .name = a
  16351. + };
  16352. +
  16353. + br = au_sbr(inode->i_sb, bindex);
  16354. + h_parent = br->br_wbr->wbr_plink;
  16355. + h_dir = h_parent->d_inode;
  16356. + tgtname.len = plink_name(a, sizeof(a), inode, bindex);
  16357. +
  16358. + /* always superio. */
  16359. + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
  16360. + h_dentry = au_sio_lkup_one(&tgtname, h_parent, br);
  16361. + mutex_unlock(&h_dir->i_mutex);
  16362. + return h_dentry;
  16363. +}
  16364. +
  16365. +/* create a pseudo-link */
  16366. +static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
  16367. + struct dentry *h_dentry, struct au_branch *br)
  16368. +{
  16369. + int err;
  16370. + struct path h_path = {
  16371. + .mnt = br->br_mnt
  16372. + };
  16373. + struct inode *h_dir;
  16374. +
  16375. + h_dir = h_parent->d_inode;
  16376. + again:
  16377. + h_path.dentry = au_lkup_one(tgt, h_parent, br, /*nd*/NULL);
  16378. + err = PTR_ERR(h_path.dentry);
  16379. + if (IS_ERR(h_path.dentry))
  16380. + goto out;
  16381. +
  16382. + err = 0;
  16383. + /* wh.plink dir is not monitored */
  16384. + if (h_path.dentry->d_inode
  16385. + && h_path.dentry->d_inode != h_dentry->d_inode) {
  16386. + err = vfsub_unlink(h_dir, &h_path, /*force*/0);
  16387. + dput(h_path.dentry);
  16388. + h_path.dentry = NULL;
  16389. + if (!err)
  16390. + goto again;
  16391. + }
  16392. + if (!err && !h_path.dentry->d_inode)
  16393. + err = vfsub_link(h_dentry, h_dir, &h_path);
  16394. + dput(h_path.dentry);
  16395. +
  16396. + out:
  16397. + return err;
  16398. +}
  16399. +
  16400. +struct do_whplink_args {
  16401. + int *errp;
  16402. + struct qstr *tgt;
  16403. + struct dentry *h_parent;
  16404. + struct dentry *h_dentry;
  16405. + struct au_branch *br;
  16406. +};
  16407. +
  16408. +static void call_do_whplink(void *args)
  16409. +{
  16410. + struct do_whplink_args *a = args;
  16411. + *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
  16412. +}
  16413. +
  16414. +static int whplink(struct dentry *h_dentry, struct inode *inode,
  16415. + aufs_bindex_t bindex, struct au_branch *br)
  16416. +{
  16417. + int err, wkq_err;
  16418. + struct au_wbr *wbr;
  16419. + struct dentry *h_parent;
  16420. + struct inode *h_dir;
  16421. + char a[PLINK_NAME_LEN];
  16422. + struct qstr tgtname = {
  16423. + .name = a
  16424. + };
  16425. +
  16426. + wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
  16427. + h_parent = wbr->wbr_plink;
  16428. + h_dir = h_parent->d_inode;
  16429. + tgtname.len = plink_name(a, sizeof(a), inode, bindex);
  16430. +
  16431. + /* always superio. */
  16432. + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
  16433. + if (!au_test_wkq(current)) {
  16434. + struct do_whplink_args args = {
  16435. + .errp = &err,
  16436. + .tgt = &tgtname,
  16437. + .h_parent = h_parent,
  16438. + .h_dentry = h_dentry,
  16439. + .br = br
  16440. + };
  16441. + wkq_err = au_wkq_wait(call_do_whplink, &args);
  16442. + if (unlikely(wkq_err))
  16443. + err = wkq_err;
  16444. + } else
  16445. + err = do_whplink(&tgtname, h_parent, h_dentry, br);
  16446. + mutex_unlock(&h_dir->i_mutex);
  16447. +
  16448. + return err;
  16449. +}
  16450. +
  16451. +/* free a single plink */
  16452. +static void do_put_plink(struct pseudo_link *plink, int do_del)
  16453. +{
  16454. + iput(plink->inode);
  16455. + if (do_del)
  16456. + list_del(&plink->list);
  16457. + kfree(plink);
  16458. +}
  16459. +
  16460. +/*
  16461. + * create a new pseudo-link for @h_dentry on @bindex.
  16462. + * the linked inode is held in aufs @inode.
  16463. + */
  16464. +void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
  16465. + struct dentry *h_dentry)
  16466. +{
  16467. + struct super_block *sb;
  16468. + struct au_sbinfo *sbinfo;
  16469. + struct list_head *plink_list;
  16470. + struct pseudo_link *plink;
  16471. + int found, err, cnt;
  16472. +
  16473. + sb = inode->i_sb;
  16474. + sbinfo = au_sbi(sb);
  16475. + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
  16476. +
  16477. + err = 0;
  16478. + cnt = 0;
  16479. + found = 0;
  16480. + plink_list = &sbinfo->si_plink.head;
  16481. + spin_lock(&sbinfo->si_plink.spin);
  16482. + list_for_each_entry(plink, plink_list, list) {
  16483. + cnt++;
  16484. + if (plink->inode == inode) {
  16485. + found = 1;
  16486. + break;
  16487. + }
  16488. + }
  16489. + if (found) {
  16490. + spin_unlock(&sbinfo->si_plink.spin);
  16491. + return;
  16492. + }
  16493. +
  16494. + plink = NULL;
  16495. + if (!found) {
  16496. + plink = kmalloc(sizeof(*plink), GFP_ATOMIC);
  16497. + if (plink) {
  16498. + plink->inode = au_igrab(inode);
  16499. + list_add(&plink->list, plink_list);
  16500. + cnt++;
  16501. + } else
  16502. + err = -ENOMEM;
  16503. + }
  16504. + spin_unlock(&sbinfo->si_plink.spin);
  16505. +
  16506. + if (!err) {
  16507. + au_plink_block_maintain(sb);
  16508. + err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
  16509. + }
  16510. +
  16511. + if (unlikely(cnt > AUFS_PLINK_WARN))
  16512. + AuWarn1("unexpectedly many pseudo links, %d\n", cnt);
  16513. + if (unlikely(err)) {
  16514. + AuWarn("err %d, damaged pseudo link.\n", err);
  16515. + if (!found && plink)
  16516. + do_put_plink(plink, /*do_del*/1);
  16517. + }
  16518. +}
  16519. +
  16520. +/* free all plinks */
  16521. +void au_plink_put(struct super_block *sb)
  16522. +{
  16523. + struct au_sbinfo *sbinfo;
  16524. + struct list_head *plink_list;
  16525. + struct pseudo_link *plink, *tmp;
  16526. +
  16527. + SiMustWriteLock(sb);
  16528. +
  16529. + sbinfo = au_sbi(sb);
  16530. + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
  16531. +
  16532. + plink_list = &sbinfo->si_plink.head;
  16533. + /* no spin_lock since sbinfo is write-locked */
  16534. + list_for_each_entry_safe(plink, tmp, plink_list, list)
  16535. + do_put_plink(plink, 0);
  16536. + INIT_LIST_HEAD(plink_list);
  16537. +}
  16538. +
  16539. +/* free the plinks on a branch specified by @br_id */
  16540. +void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
  16541. +{
  16542. + struct au_sbinfo *sbinfo;
  16543. + struct list_head *plink_list;
  16544. + struct pseudo_link *plink, *tmp;
  16545. + struct inode *inode;
  16546. + aufs_bindex_t bstart, bend, bindex;
  16547. + unsigned char do_put;
  16548. +
  16549. + SiMustWriteLock(sb);
  16550. +
  16551. + sbinfo = au_sbi(sb);
  16552. + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
  16553. +
  16554. + plink_list = &sbinfo->si_plink.head;
  16555. + /* no spin_lock since sbinfo is write-locked */
  16556. + list_for_each_entry_safe(plink, tmp, plink_list, list) {
  16557. + do_put = 0;
  16558. + inode = au_igrab(plink->inode);
  16559. + ii_write_lock_child(inode);
  16560. + bstart = au_ibstart(inode);
  16561. + bend = au_ibend(inode);
  16562. + if (bstart >= 0) {
  16563. + for (bindex = bstart; bindex <= bend; bindex++) {
  16564. + if (!au_h_iptr(inode, bindex)
  16565. + || au_ii_br_id(inode, bindex) != br_id)
  16566. + continue;
  16567. + au_set_h_iptr(inode, bindex, NULL, 0);
  16568. + do_put = 1;
  16569. + break;
  16570. + }
  16571. + } else
  16572. + do_put_plink(plink, 1);
  16573. +
  16574. + if (do_put) {
  16575. + for (bindex = bstart; bindex <= bend; bindex++)
  16576. + if (au_h_iptr(inode, bindex)) {
  16577. + do_put = 0;
  16578. + break;
  16579. + }
  16580. + if (do_put)
  16581. + do_put_plink(plink, 1);
  16582. + }
  16583. + ii_write_unlock(inode);
  16584. + iput(inode);
  16585. + }
  16586. +}
  16587. diff -Nur linux-2.6.31.5.orig/fs/aufs/poll.c linux-2.6.31.5/fs/aufs/poll.c
  16588. --- linux-2.6.31.5.orig/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100
  16589. +++ linux-2.6.31.5/fs/aufs/poll.c 2009-11-15 22:02:37.000000000 +0100
  16590. @@ -0,0 +1,56 @@
  16591. +/*
  16592. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  16593. + *
  16594. + * This program, aufs is free software; you can redistribute it and/or modify
  16595. + * it under the terms of the GNU General Public License as published by
  16596. + * the Free Software Foundation; either version 2 of the License, or
  16597. + * (at your option) any later version.
  16598. + *
  16599. + * This program is distributed in the hope that it will be useful,
  16600. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16601. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16602. + * GNU General Public License for more details.
  16603. + *
  16604. + * You should have received a copy of the GNU General Public License
  16605. + * along with this program; if not, write to the Free Software
  16606. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16607. + */
  16608. +
  16609. +/*
  16610. + * poll operation
  16611. + * There is only one filesystem which implements ->poll operation, currently.
  16612. + */
  16613. +
  16614. +#include "aufs.h"
  16615. +
  16616. +unsigned int aufs_poll(struct file *file, poll_table *wait)
  16617. +{
  16618. + unsigned int mask;
  16619. + int err;
  16620. + struct file *h_file;
  16621. + struct dentry *dentry;
  16622. + struct super_block *sb;
  16623. +
  16624. + /* We should pretend an error happened. */
  16625. + mask = POLLERR /* | POLLIN | POLLOUT */;
  16626. + dentry = file->f_dentry;
  16627. + sb = dentry->d_sb;
  16628. + si_read_lock(sb, AuLock_FLUSH);
  16629. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
  16630. + if (unlikely(err))
  16631. + goto out;
  16632. +
  16633. + /* it is not an error if h_file has no operation */
  16634. + mask = DEFAULT_POLLMASK;
  16635. + h_file = au_h_fptr(file, au_fbstart(file));
  16636. + if (h_file->f_op && h_file->f_op->poll)
  16637. + mask = h_file->f_op->poll(h_file, wait);
  16638. +
  16639. + di_read_unlock(dentry, AuLock_IR);
  16640. + fi_read_unlock(file);
  16641. +
  16642. + out:
  16643. + si_read_unlock(sb);
  16644. + AuTraceErr((int)mask);
  16645. + return mask;
  16646. +}
  16647. diff -Nur linux-2.6.31.5.orig/fs/aufs/rwsem.h linux-2.6.31.5/fs/aufs/rwsem.h
  16648. --- linux-2.6.31.5.orig/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100
  16649. +++ linux-2.6.31.5/fs/aufs/rwsem.h 2009-11-15 22:02:37.000000000 +0100
  16650. @@ -0,0 +1,186 @@
  16651. +/*
  16652. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  16653. + *
  16654. + * This program, aufs is free software; you can redistribute it and/or modify
  16655. + * it under the terms of the GNU General Public License as published by
  16656. + * the Free Software Foundation; either version 2 of the License, or
  16657. + * (at your option) any later version.
  16658. + *
  16659. + * This program is distributed in the hope that it will be useful,
  16660. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16661. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16662. + * GNU General Public License for more details.
  16663. + *
  16664. + * You should have received a copy of the GNU General Public License
  16665. + * along with this program; if not, write to the Free Software
  16666. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16667. + */
  16668. +
  16669. +/*
  16670. + * simple read-write semaphore wrappers
  16671. + */
  16672. +
  16673. +#ifndef __AUFS_RWSEM_H__
  16674. +#define __AUFS_RWSEM_H__
  16675. +
  16676. +#ifdef __KERNEL__
  16677. +
  16678. +#include <linux/rwsem.h>
  16679. +
  16680. +struct au_rwsem {
  16681. + struct rw_semaphore rwsem;
  16682. +#ifdef CONFIG_AUFS_DEBUG
  16683. + /* just for debugging, not almighty counter */
  16684. + atomic_t rcnt, wcnt;
  16685. +#endif
  16686. +};
  16687. +
  16688. +#ifdef CONFIG_AUFS_DEBUG
  16689. +#define AuDbgCntInit(rw) do { \
  16690. + atomic_set(&(rw)->rcnt, 0); \
  16691. + atomic_set(&(rw)->wcnt, 0); \
  16692. + smp_mb(); /* atomic set */ \
  16693. +} while (0)
  16694. +
  16695. +#define AuDbgRcntInc(rw) atomic_inc_return(&(rw)->rcnt)
  16696. +#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0)
  16697. +#define AuDbgWcntInc(rw) WARN_ON(atomic_inc_return(&(rw)->wcnt) > 1)
  16698. +#define AuDbgWcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->wcnt) < 0)
  16699. +#else
  16700. +#define AuDbgCntInit(rw) do {} while (0)
  16701. +#define AuDbgRcntInc(rw) do {} while (0)
  16702. +#define AuDbgRcntDec(rw) do {} while (0)
  16703. +#define AuDbgWcntInc(rw) do {} while (0)
  16704. +#define AuDbgWcntDec(rw) do {} while (0)
  16705. +#endif /* CONFIG_AUFS_DEBUG */
  16706. +
  16707. +/* to debug easier, do not make them inlined functions */
  16708. +#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->rwsem.wait_list))
  16709. +/* rwsem_is_locked() is unusable */
  16710. +#define AuRwMustReadLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0)
  16711. +#define AuRwMustWriteLock(rw) AuDebugOn(atomic_read(&(rw)->wcnt) <= 0)
  16712. +#define AuRwMustAnyLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0 \
  16713. + && atomic_read(&(rw)->wcnt) <= 0)
  16714. +#define AuRwDestroy(rw) AuDebugOn(atomic_read(&(rw)->rcnt) \
  16715. + || atomic_read(&(rw)->wcnt))
  16716. +
  16717. +static inline void au_rw_init(struct au_rwsem *rw)
  16718. +{
  16719. + AuDbgCntInit(rw);
  16720. + init_rwsem(&rw->rwsem);
  16721. +}
  16722. +
  16723. +static inline void au_rw_init_wlock(struct au_rwsem *rw)
  16724. +{
  16725. + au_rw_init(rw);
  16726. + down_write(&rw->rwsem);
  16727. + AuDbgWcntInc(rw);
  16728. +}
  16729. +
  16730. +static inline void au_rw_init_wlock_nested(struct au_rwsem *rw,
  16731. + unsigned int lsc)
  16732. +{
  16733. + au_rw_init(rw);
  16734. + down_write_nested(&rw->rwsem, lsc);
  16735. + AuDbgWcntInc(rw);
  16736. +}
  16737. +
  16738. +static inline void au_rw_read_lock(struct au_rwsem *rw)
  16739. +{
  16740. + down_read(&rw->rwsem);
  16741. + AuDbgRcntInc(rw);
  16742. +}
  16743. +
  16744. +static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc)
  16745. +{
  16746. + down_read_nested(&rw->rwsem, lsc);
  16747. + AuDbgRcntInc(rw);
  16748. +}
  16749. +
  16750. +static inline void au_rw_read_unlock(struct au_rwsem *rw)
  16751. +{
  16752. + AuRwMustReadLock(rw);
  16753. + AuDbgRcntDec(rw);
  16754. + up_read(&rw->rwsem);
  16755. +}
  16756. +
  16757. +static inline void au_rw_dgrade_lock(struct au_rwsem *rw)
  16758. +{
  16759. + AuRwMustWriteLock(rw);
  16760. + AuDbgRcntInc(rw);
  16761. + AuDbgWcntDec(rw);
  16762. + downgrade_write(&rw->rwsem);
  16763. +}
  16764. +
  16765. +static inline void au_rw_write_lock(struct au_rwsem *rw)
  16766. +{
  16767. + down_write(&rw->rwsem);
  16768. + AuDbgWcntInc(rw);
  16769. +}
  16770. +
  16771. +static inline void au_rw_write_lock_nested(struct au_rwsem *rw,
  16772. + unsigned int lsc)
  16773. +{
  16774. + down_write_nested(&rw->rwsem, lsc);
  16775. + AuDbgWcntInc(rw);
  16776. +}
  16777. +
  16778. +static inline void au_rw_write_unlock(struct au_rwsem *rw)
  16779. +{
  16780. + AuRwMustWriteLock(rw);
  16781. + AuDbgWcntDec(rw);
  16782. + up_write(&rw->rwsem);
  16783. +}
  16784. +
  16785. +/* why is not _nested version defined */
  16786. +static inline int au_rw_read_trylock(struct au_rwsem *rw)
  16787. +{
  16788. + int ret = down_read_trylock(&rw->rwsem);
  16789. + if (ret)
  16790. + AuDbgRcntInc(rw);
  16791. + return ret;
  16792. +}
  16793. +
  16794. +static inline int au_rw_write_trylock(struct au_rwsem *rw)
  16795. +{
  16796. + int ret = down_write_trylock(&rw->rwsem);
  16797. + if (ret)
  16798. + AuDbgWcntInc(rw);
  16799. + return ret;
  16800. +}
  16801. +
  16802. +#undef AuDbgCntInit
  16803. +#undef AuDbgRcntInc
  16804. +#undef AuDbgRcntDec
  16805. +#undef AuDbgWcntInc
  16806. +#undef AuDbgWcntDec
  16807. +
  16808. +#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
  16809. +static inline void prefix##_read_lock(param) \
  16810. +{ au_rw_read_lock(rwsem); } \
  16811. +static inline void prefix##_write_lock(param) \
  16812. +{ au_rw_write_lock(rwsem); } \
  16813. +static inline int prefix##_read_trylock(param) \
  16814. +{ return au_rw_read_trylock(rwsem); } \
  16815. +static inline int prefix##_write_trylock(param) \
  16816. +{ return au_rw_write_trylock(rwsem); }
  16817. +/* why is not _nested version defined */
  16818. +/* static inline void prefix##_read_trylock_nested(param, lsc)
  16819. +{ au_rw_read_trylock_nested(rwsem, lsc)); }
  16820. +static inline void prefix##_write_trylock_nestd(param, lsc)
  16821. +{ au_rw_write_trylock_nested(rwsem, lsc); } */
  16822. +
  16823. +#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
  16824. +static inline void prefix##_read_unlock(param) \
  16825. +{ au_rw_read_unlock(rwsem); } \
  16826. +static inline void prefix##_write_unlock(param) \
  16827. +{ au_rw_write_unlock(rwsem); } \
  16828. +static inline void prefix##_downgrade_lock(param) \
  16829. +{ au_rw_dgrade_lock(rwsem); }
  16830. +
  16831. +#define AuSimpleRwsemFuncs(prefix, param, rwsem) \
  16832. + AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
  16833. + AuSimpleUnlockRwsemFuncs(prefix, param, rwsem)
  16834. +
  16835. +#endif /* __KERNEL__ */
  16836. +#endif /* __AUFS_RWSEM_H__ */
  16837. diff -Nur linux-2.6.31.5.orig/fs/aufs/sbinfo.c linux-2.6.31.5/fs/aufs/sbinfo.c
  16838. --- linux-2.6.31.5.orig/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100
  16839. +++ linux-2.6.31.5/fs/aufs/sbinfo.c 2009-11-15 22:02:37.000000000 +0100
  16840. @@ -0,0 +1,208 @@
  16841. +/*
  16842. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  16843. + *
  16844. + * This program, aufs is free software; you can redistribute it and/or modify
  16845. + * it under the terms of the GNU General Public License as published by
  16846. + * the Free Software Foundation; either version 2 of the License, or
  16847. + * (at your option) any later version.
  16848. + *
  16849. + * This program is distributed in the hope that it will be useful,
  16850. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16851. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16852. + * GNU General Public License for more details.
  16853. + *
  16854. + * You should have received a copy of the GNU General Public License
  16855. + * along with this program; if not, write to the Free Software
  16856. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16857. + */
  16858. +
  16859. +/*
  16860. + * superblock private data
  16861. + */
  16862. +
  16863. +#include "aufs.h"
  16864. +
  16865. +/*
  16866. + * they are necessary regardless sysfs is disabled.
  16867. + */
  16868. +void au_si_free(struct kobject *kobj)
  16869. +{
  16870. + struct au_sbinfo *sbinfo;
  16871. + struct super_block *sb;
  16872. +
  16873. + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
  16874. + AuDebugOn(!list_empty(&sbinfo->si_plink.head));
  16875. +
  16876. + sb = sbinfo->si_sb;
  16877. + si_write_lock(sb);
  16878. + au_xino_clr(sb);
  16879. + au_br_free(sbinfo);
  16880. + kfree(sbinfo->si_branch);
  16881. + mutex_destroy(&sbinfo->si_xib_mtx);
  16882. + si_write_unlock(sb);
  16883. + AuRwDestroy(&sbinfo->si_rwsem);
  16884. +
  16885. + kfree(sbinfo);
  16886. +}
  16887. +
  16888. +int au_si_alloc(struct super_block *sb)
  16889. +{
  16890. + int err;
  16891. + struct au_sbinfo *sbinfo;
  16892. +
  16893. + err = -ENOMEM;
  16894. + sbinfo = kmalloc(sizeof(*sbinfo), GFP_NOFS);
  16895. + if (unlikely(!sbinfo))
  16896. + goto out;
  16897. +
  16898. + /* will be reallocated separately */
  16899. + sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
  16900. + if (unlikely(!sbinfo->si_branch))
  16901. + goto out_sbinfo;
  16902. +
  16903. + memset(&sbinfo->si_kobj, 0, sizeof(sbinfo->si_kobj));
  16904. + err = sysaufs_si_init(sbinfo);
  16905. + if (unlikely(err))
  16906. + goto out_br;
  16907. +
  16908. + au_nwt_init(&sbinfo->si_nowait);
  16909. + au_rw_init_wlock(&sbinfo->si_rwsem);
  16910. + sbinfo->si_generation = 0;
  16911. + sbinfo->au_si_status = 0;
  16912. + sbinfo->si_bend = -1;
  16913. + sbinfo->si_last_br_id = 0;
  16914. +
  16915. + sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
  16916. + sbinfo->si_wbr_create = AuWbrCreate_Def;
  16917. + sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + AuWbrCopyup_Def;
  16918. + sbinfo->si_wbr_create_ops = au_wbr_create_ops + AuWbrCreate_Def;
  16919. +
  16920. + sbinfo->si_mntflags = AuOpt_Def;
  16921. +
  16922. + sbinfo->si_xread = NULL;
  16923. + sbinfo->si_xwrite = NULL;
  16924. + sbinfo->si_xib = NULL;
  16925. + mutex_init(&sbinfo->si_xib_mtx);
  16926. + sbinfo->si_xib_buf = NULL;
  16927. + sbinfo->si_xino_brid = -1;
  16928. + /* leave si_xib_last_pindex and si_xib_next_bit */
  16929. +
  16930. + sbinfo->si_rdcache = AUFS_RDCACHE_DEF * HZ;
  16931. + sbinfo->si_rdblk = AUFS_RDBLK_DEF;
  16932. + sbinfo->si_rdhash = AUFS_RDHASH_DEF;
  16933. + sbinfo->si_dirwh = AUFS_DIRWH_DEF;
  16934. +
  16935. + au_spl_init(&sbinfo->si_plink);
  16936. + init_waitqueue_head(&sbinfo->si_plink_wq);
  16937. +
  16938. + /* leave other members for sysaufs and si_mnt. */
  16939. + sbinfo->si_sb = sb;
  16940. + sb->s_fs_info = sbinfo;
  16941. + au_debug_sbinfo_init(sbinfo);
  16942. + return 0; /* success */
  16943. +
  16944. + out_br:
  16945. + kfree(sbinfo->si_branch);
  16946. + out_sbinfo:
  16947. + kfree(sbinfo);
  16948. + out:
  16949. + return err;
  16950. +}
  16951. +
  16952. +int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr)
  16953. +{
  16954. + int err, sz;
  16955. + struct au_branch **brp;
  16956. +
  16957. + AuRwMustWriteLock(&sbinfo->si_rwsem);
  16958. +
  16959. + err = -ENOMEM;
  16960. + sz = sizeof(*brp) * (sbinfo->si_bend + 1);
  16961. + if (unlikely(!sz))
  16962. + sz = sizeof(*brp);
  16963. + brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS);
  16964. + if (brp) {
  16965. + sbinfo->si_branch = brp;
  16966. + err = 0;
  16967. + }
  16968. +
  16969. + return err;
  16970. +}
  16971. +
  16972. +/* ---------------------------------------------------------------------- */
  16973. +
  16974. +unsigned int au_sigen_inc(struct super_block *sb)
  16975. +{
  16976. + unsigned int gen;
  16977. +
  16978. + SiMustWriteLock(sb);
  16979. +
  16980. + gen = ++au_sbi(sb)->si_generation;
  16981. + au_update_digen(sb->s_root);
  16982. + au_update_iigen(sb->s_root->d_inode);
  16983. + sb->s_root->d_inode->i_version++;
  16984. + return gen;
  16985. +}
  16986. +
  16987. +aufs_bindex_t au_new_br_id(struct super_block *sb)
  16988. +{
  16989. + aufs_bindex_t br_id;
  16990. + int i;
  16991. + struct au_sbinfo *sbinfo;
  16992. +
  16993. + SiMustWriteLock(sb);
  16994. +
  16995. + sbinfo = au_sbi(sb);
  16996. + for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
  16997. + br_id = ++sbinfo->si_last_br_id;
  16998. + if (br_id && au_br_index(sb, br_id) < 0)
  16999. + return br_id;
  17000. + }
  17001. +
  17002. + return -1;
  17003. +}
  17004. +
  17005. +/* ---------------------------------------------------------------------- */
  17006. +
  17007. +/* dentry and super_block lock. call at entry point */
  17008. +void aufs_read_lock(struct dentry *dentry, int flags)
  17009. +{
  17010. + si_read_lock(dentry->d_sb, flags);
  17011. + if (au_ftest_lock(flags, DW))
  17012. + di_write_lock_child(dentry);
  17013. + else
  17014. + di_read_lock_child(dentry, flags);
  17015. +}
  17016. +
  17017. +void aufs_read_unlock(struct dentry *dentry, int flags)
  17018. +{
  17019. + if (au_ftest_lock(flags, DW))
  17020. + di_write_unlock(dentry);
  17021. + else
  17022. + di_read_unlock(dentry, flags);
  17023. + si_read_unlock(dentry->d_sb);
  17024. +}
  17025. +
  17026. +void aufs_write_lock(struct dentry *dentry)
  17027. +{
  17028. + si_write_lock(dentry->d_sb);
  17029. + di_write_lock_child(dentry);
  17030. +}
  17031. +
  17032. +void aufs_write_unlock(struct dentry *dentry)
  17033. +{
  17034. + di_write_unlock(dentry);
  17035. + si_write_unlock(dentry->d_sb);
  17036. +}
  17037. +
  17038. +void aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
  17039. +{
  17040. + si_read_lock(d1->d_sb, flags);
  17041. + di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR));
  17042. +}
  17043. +
  17044. +void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
  17045. +{
  17046. + di_write_unlock2(d1, d2);
  17047. + si_read_unlock(d1->d_sb);
  17048. +}
  17049. diff -Nur linux-2.6.31.5.orig/fs/aufs/spl.h linux-2.6.31.5/fs/aufs/spl.h
  17050. --- linux-2.6.31.5.orig/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100
  17051. +++ linux-2.6.31.5/fs/aufs/spl.h 2009-11-15 22:02:37.000000000 +0100
  17052. @@ -0,0 +1,57 @@
  17053. +/*
  17054. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  17055. + *
  17056. + * This program, aufs is free software; you can redistribute it and/or modify
  17057. + * it under the terms of the GNU General Public License as published by
  17058. + * the Free Software Foundation; either version 2 of the License, or
  17059. + * (at your option) any later version.
  17060. + *
  17061. + * This program is distributed in the hope that it will be useful,
  17062. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17063. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17064. + * GNU General Public License for more details.
  17065. + *
  17066. + * You should have received a copy of the GNU General Public License
  17067. + * along with this program; if not, write to the Free Software
  17068. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17069. + */
  17070. +
  17071. +/*
  17072. + * simple list protected by a spinlock
  17073. + */
  17074. +
  17075. +#ifndef __AUFS_SPL_H__
  17076. +#define __AUFS_SPL_H__
  17077. +
  17078. +#ifdef __KERNEL__
  17079. +
  17080. +#include <linux/spinlock.h>
  17081. +#include <linux/list.h>
  17082. +
  17083. +struct au_splhead {
  17084. + spinlock_t spin;
  17085. + struct list_head head;
  17086. +};
  17087. +
  17088. +static inline void au_spl_init(struct au_splhead *spl)
  17089. +{
  17090. + spin_lock_init(&spl->spin);
  17091. + INIT_LIST_HEAD(&spl->head);
  17092. +}
  17093. +
  17094. +static inline void au_spl_add(struct list_head *list, struct au_splhead *spl)
  17095. +{
  17096. + spin_lock(&spl->spin);
  17097. + list_add(list, &spl->head);
  17098. + spin_unlock(&spl->spin);
  17099. +}
  17100. +
  17101. +static inline void au_spl_del(struct list_head *list, struct au_splhead *spl)
  17102. +{
  17103. + spin_lock(&spl->spin);
  17104. + list_del(list);
  17105. + spin_unlock(&spl->spin);
  17106. +}
  17107. +
  17108. +#endif /* __KERNEL__ */
  17109. +#endif /* __AUFS_SPL_H__ */
  17110. diff -Nur linux-2.6.31.5.orig/fs/aufs/super.c linux-2.6.31.5/fs/aufs/super.c
  17111. --- linux-2.6.31.5.orig/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
  17112. +++ linux-2.6.31.5/fs/aufs/super.c 2009-11-15 22:20:26.000000000 +0100
  17113. @@ -0,0 +1,874 @@
  17114. +/*
  17115. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  17116. + *
  17117. + * This program, aufs is free software; you can redistribute it and/or modify
  17118. + * it under the terms of the GNU General Public License as published by
  17119. + * the Free Software Foundation; either version 2 of the License, or
  17120. + * (at your option) any later version.
  17121. + *
  17122. + * This program is distributed in the hope that it will be useful,
  17123. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17124. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17125. + * GNU General Public License for more details.
  17126. + *
  17127. + * You should have received a copy of the GNU General Public License
  17128. + * along with this program; if not, write to the Free Software
  17129. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17130. + */
  17131. +
  17132. +/*
  17133. + * mount and super_block operations
  17134. + */
  17135. +
  17136. +#include <linux/buffer_head.h>
  17137. +#include <linux/module.h>
  17138. +#include <linux/seq_file.h>
  17139. +#include <linux/statfs.h>
  17140. +#include "aufs.h"
  17141. +
  17142. +/*
  17143. + * super_operations
  17144. + */
  17145. +static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
  17146. +{
  17147. + struct au_icntnr *c;
  17148. +
  17149. + c = au_cache_alloc_icntnr();
  17150. + if (c) {
  17151. + inode_init_once(&c->vfs_inode);
  17152. + c->vfs_inode.i_version = 1; /* sigen(sb); */
  17153. + c->iinfo.ii_hinode = NULL;
  17154. + return &c->vfs_inode;
  17155. + }
  17156. + return NULL;
  17157. +}
  17158. +
  17159. +static void aufs_destroy_inode(struct inode *inode)
  17160. +{
  17161. + au_iinfo_fin(inode);
  17162. + au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
  17163. +}
  17164. +
  17165. +struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
  17166. +{
  17167. + struct inode *inode;
  17168. + int err;
  17169. +
  17170. + inode = iget_locked(sb, ino);
  17171. + if (unlikely(!inode)) {
  17172. + inode = ERR_PTR(-ENOMEM);
  17173. + goto out;
  17174. + }
  17175. + if (!(inode->i_state & I_NEW))
  17176. + goto out;
  17177. +
  17178. + err = au_xigen_new(inode);
  17179. + if (!err)
  17180. + err = au_iinfo_init(inode);
  17181. + if (!err)
  17182. + inode->i_version++;
  17183. + else {
  17184. + iget_failed(inode);
  17185. + inode = ERR_PTR(err);
  17186. + }
  17187. +
  17188. + out:
  17189. + /* never return NULL */
  17190. + AuDebugOn(!inode);
  17191. + AuTraceErrPtr(inode);
  17192. + return inode;
  17193. +}
  17194. +
  17195. +/* lock free root dinfo */
  17196. +static int au_show_brs(struct seq_file *seq, struct super_block *sb)
  17197. +{
  17198. + int err;
  17199. + aufs_bindex_t bindex, bend;
  17200. + struct path path;
  17201. + struct au_hdentry *hd;
  17202. + struct au_branch *br;
  17203. +
  17204. + err = 0;
  17205. + bend = au_sbend(sb);
  17206. + hd = au_di(sb->s_root)->di_hdentry;
  17207. + for (bindex = 0; !err && bindex <= bend; bindex++) {
  17208. + br = au_sbr(sb, bindex);
  17209. + path.mnt = br->br_mnt;
  17210. + path.dentry = hd[bindex].hd_dentry;
  17211. + err = au_seq_path(seq, &path);
  17212. + if (err > 0)
  17213. + err = seq_printf(seq, "=%s",
  17214. + au_optstr_br_perm(br->br_perm));
  17215. + if (!err && bindex != bend)
  17216. + err = seq_putc(seq, ':');
  17217. + }
  17218. +
  17219. + return err;
  17220. +}
  17221. +
  17222. +static void au_show_wbr_create(struct seq_file *m, int v,
  17223. + struct au_sbinfo *sbinfo)
  17224. +{
  17225. + const char *pat;
  17226. +
  17227. + AuRwMustAnyLock(&sbinfo->si_rwsem);
  17228. +
  17229. + seq_printf(m, ",create=");
  17230. + pat = au_optstr_wbr_create(v);
  17231. + switch (v) {
  17232. + case AuWbrCreate_TDP:
  17233. + case AuWbrCreate_RR:
  17234. + case AuWbrCreate_MFS:
  17235. + case AuWbrCreate_PMFS:
  17236. + seq_printf(m, pat);
  17237. + break;
  17238. + case AuWbrCreate_MFSV:
  17239. + seq_printf(m, /*pat*/"mfs:%lu",
  17240. + sbinfo->si_wbr_mfs.mfs_expire / HZ);
  17241. + break;
  17242. + case AuWbrCreate_PMFSV:
  17243. + seq_printf(m, /*pat*/"pmfs:%lu",
  17244. + sbinfo->si_wbr_mfs.mfs_expire / HZ);
  17245. + break;
  17246. + case AuWbrCreate_MFSRR:
  17247. + seq_printf(m, /*pat*/"mfsrr:%llu",
  17248. + sbinfo->si_wbr_mfs.mfsrr_watermark);
  17249. + break;
  17250. + case AuWbrCreate_MFSRRV:
  17251. + seq_printf(m, /*pat*/"mfsrr:%llu:%lu",
  17252. + sbinfo->si_wbr_mfs.mfsrr_watermark,
  17253. + sbinfo->si_wbr_mfs.mfs_expire / HZ);
  17254. + break;
  17255. + }
  17256. +}
  17257. +
  17258. +static int au_show_xino(struct seq_file *seq, struct vfsmount *mnt)
  17259. +{
  17260. +#ifdef CONFIG_SYSFS
  17261. + return 0;
  17262. +#else
  17263. + int err;
  17264. + const int len = sizeof(AUFS_XINO_FNAME) - 1;
  17265. + aufs_bindex_t bindex, brid;
  17266. + struct super_block *sb;
  17267. + struct qstr *name;
  17268. + struct file *f;
  17269. + struct dentry *d, *h_root;
  17270. +
  17271. + AuRwMustAnyLock(&sbinfo->si_rwsem);
  17272. +
  17273. + err = 0;
  17274. + sb = mnt->mnt_sb;
  17275. + f = au_sbi(sb)->si_xib;
  17276. + if (!f)
  17277. + goto out;
  17278. +
  17279. + /* stop printing the default xino path on the first writable branch */
  17280. + h_root = NULL;
  17281. + brid = au_xino_brid(sb);
  17282. + if (brid >= 0) {
  17283. + bindex = au_br_index(sb, brid);
  17284. + h_root = au_di(sb->s_root)->di_hdentry[0 + bindex].hd_dentry;
  17285. + }
  17286. + d = f->f_dentry;
  17287. + name = &d->d_name;
  17288. + /* safe ->d_parent because the file is unlinked */
  17289. + if (d->d_parent == h_root
  17290. + && name->len == len
  17291. + && !memcmp(name->name, AUFS_XINO_FNAME, len))
  17292. + goto out;
  17293. +
  17294. + seq_puts(seq, ",xino=");
  17295. + err = au_xino_path(seq, f);
  17296. +
  17297. + out:
  17298. + return err;
  17299. +#endif
  17300. +}
  17301. +
  17302. +/* seq_file will re-call me in case of too long string */
  17303. +static int aufs_show_options(struct seq_file *m, struct vfsmount *mnt)
  17304. +{
  17305. + int err, n;
  17306. + unsigned int mnt_flags, v;
  17307. + struct super_block *sb;
  17308. + struct au_sbinfo *sbinfo;
  17309. +
  17310. +#define AuBool(name, str) do { \
  17311. + v = au_opt_test(mnt_flags, name); \
  17312. + if (v != au_opt_test(AuOpt_Def, name)) \
  17313. + seq_printf(m, ",%s" #str, v ? "" : "no"); \
  17314. +} while (0)
  17315. +
  17316. +#define AuStr(name, str) do { \
  17317. + v = mnt_flags & AuOptMask_##name; \
  17318. + if (v != (AuOpt_Def & AuOptMask_##name)) \
  17319. + seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
  17320. +} while (0)
  17321. +
  17322. +#define AuUInt(name, str, val) do { \
  17323. + if (val != AUFS_##name##_DEF) \
  17324. + seq_printf(m, "," #str "=%u", val); \
  17325. +} while (0)
  17326. +
  17327. + /* lock free root dinfo */
  17328. + sb = mnt->mnt_sb;
  17329. + si_noflush_read_lock(sb);
  17330. + sbinfo = au_sbi(sb);
  17331. + seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
  17332. +
  17333. + mnt_flags = au_mntflags(sb);
  17334. + if (au_opt_test(mnt_flags, XINO)) {
  17335. + err = au_show_xino(m, mnt);
  17336. + if (unlikely(err))
  17337. + goto out;
  17338. + } else
  17339. + seq_puts(m, ",noxino");
  17340. +
  17341. + AuBool(TRUNC_XINO, trunc_xino);
  17342. + AuStr(UDBA, udba);
  17343. + AuBool(SHWH, shwh);
  17344. + AuBool(PLINK, plink);
  17345. + /* AuBool(DIRPERM1, dirperm1); */
  17346. + /* AuBool(REFROF, refrof); */
  17347. +
  17348. + v = sbinfo->si_wbr_create;
  17349. + if (v != AuWbrCreate_Def)
  17350. + au_show_wbr_create(m, v, sbinfo);
  17351. +
  17352. + v = sbinfo->si_wbr_copyup;
  17353. + if (v != AuWbrCopyup_Def)
  17354. + seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
  17355. +
  17356. + v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
  17357. + if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
  17358. + seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
  17359. +
  17360. + AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
  17361. +
  17362. + n = sbinfo->si_rdcache / HZ;
  17363. + AuUInt(RDCACHE, rdcache, n);
  17364. +
  17365. + AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
  17366. + AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
  17367. +
  17368. + AuBool(SUM, sum);
  17369. + /* AuBool(SUM_W, wsum); */
  17370. + AuBool(WARN_PERM, warn_perm);
  17371. + AuBool(VERBOSE, verbose);
  17372. +
  17373. + out:
  17374. + /* be sure to print "br:" last */
  17375. + if (!sysaufs_brs) {
  17376. + seq_puts(m, ",br:");
  17377. + au_show_brs(m, sb);
  17378. + }
  17379. + si_read_unlock(sb);
  17380. + return 0;
  17381. +
  17382. +#undef Deleted
  17383. +#undef AuBool
  17384. +#undef AuStr
  17385. +}
  17386. +
  17387. +/* ---------------------------------------------------------------------- */
  17388. +
  17389. +/* sum mode which returns the summation for statfs(2) */
  17390. +
  17391. +static u64 au_add_till_max(u64 a, u64 b)
  17392. +{
  17393. + u64 old;
  17394. +
  17395. + old = a;
  17396. + a += b;
  17397. + if (old < a)
  17398. + return a;
  17399. + return ULLONG_MAX;
  17400. +}
  17401. +
  17402. +static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
  17403. +{
  17404. + int err;
  17405. + u64 blocks, bfree, bavail, files, ffree;
  17406. + aufs_bindex_t bend, bindex, i;
  17407. + unsigned char shared;
  17408. + struct vfsmount *h_mnt;
  17409. + struct super_block *h_sb;
  17410. +
  17411. + blocks = 0;
  17412. + bfree = 0;
  17413. + bavail = 0;
  17414. + files = 0;
  17415. + ffree = 0;
  17416. +
  17417. + err = 0;
  17418. + bend = au_sbend(sb);
  17419. + for (bindex = bend; bindex >= 0; bindex--) {
  17420. + h_mnt = au_sbr_mnt(sb, bindex);
  17421. + h_sb = h_mnt->mnt_sb;
  17422. + shared = 0;
  17423. + for (i = bindex + 1; !shared && i <= bend; i++)
  17424. + shared = (au_sbr_sb(sb, i) == h_sb);
  17425. + if (shared)
  17426. + continue;
  17427. +
  17428. + /* sb->s_root for NFS is unreliable */
  17429. + err = vfs_statfs(h_mnt->mnt_root, buf);
  17430. + if (unlikely(err))
  17431. + goto out;
  17432. +
  17433. + blocks = au_add_till_max(blocks, buf->f_blocks);
  17434. + bfree = au_add_till_max(bfree, buf->f_bfree);
  17435. + bavail = au_add_till_max(bavail, buf->f_bavail);
  17436. + files = au_add_till_max(files, buf->f_files);
  17437. + ffree = au_add_till_max(ffree, buf->f_ffree);
  17438. + }
  17439. +
  17440. + buf->f_blocks = blocks;
  17441. + buf->f_bfree = bfree;
  17442. + buf->f_bavail = bavail;
  17443. + buf->f_files = files;
  17444. + buf->f_ffree = ffree;
  17445. +
  17446. + out:
  17447. + return err;
  17448. +}
  17449. +
  17450. +static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
  17451. +{
  17452. + int err;
  17453. + struct super_block *sb;
  17454. +
  17455. + /* lock free root dinfo */
  17456. + sb = dentry->d_sb;
  17457. + si_noflush_read_lock(sb);
  17458. + if (!au_opt_test(au_mntflags(sb), SUM))
  17459. + /* sb->s_root for NFS is unreliable */
  17460. + err = vfs_statfs(au_sbr_mnt(sb, 0)->mnt_root, buf);
  17461. + else
  17462. + err = au_statfs_sum(sb, buf);
  17463. + si_read_unlock(sb);
  17464. +
  17465. + if (!err) {
  17466. + buf->f_type = AUFS_SUPER_MAGIC;
  17467. + buf->f_namelen -= AUFS_WH_PFX_LEN;
  17468. + memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
  17469. + }
  17470. + /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
  17471. +
  17472. + return err;
  17473. +}
  17474. +
  17475. +/* ---------------------------------------------------------------------- */
  17476. +
  17477. +/* try flushing the lower fs at aufs remount/unmount time */
  17478. +
  17479. +static void au_fsync_br(struct super_block *sb)
  17480. +{
  17481. + aufs_bindex_t bend, bindex;
  17482. + int brperm;
  17483. + struct au_branch *br;
  17484. + struct super_block *h_sb;
  17485. +
  17486. + bend = au_sbend(sb);
  17487. + for (bindex = 0; bindex < bend; bindex++) {
  17488. + br = au_sbr(sb, bindex);
  17489. + brperm = br->br_perm;
  17490. + if (brperm == AuBrPerm_RR || brperm == AuBrPerm_RRWH)
  17491. + continue;
  17492. + h_sb = br->br_mnt->mnt_sb;
  17493. + if (bdev_read_only(h_sb->s_bdev))
  17494. + continue;
  17495. +
  17496. + lockdep_off();
  17497. + down_write(&h_sb->s_umount);
  17498. + shrink_dcache_sb(h_sb);
  17499. + sync_filesystem(h_sb);
  17500. + up_write(&h_sb->s_umount);
  17501. + lockdep_on();
  17502. + }
  17503. +}
  17504. +
  17505. +/*
  17506. + * this IS NOT for super_operations.
  17507. + * I guess it will be reverted someday.
  17508. + */
  17509. +static void aufs_umount_begin(struct super_block *sb)
  17510. +{
  17511. + struct au_sbinfo *sbinfo;
  17512. +
  17513. + sbinfo = au_sbi(sb);
  17514. + if (!sbinfo)
  17515. + return;
  17516. +
  17517. + si_write_lock(sb);
  17518. + au_fsync_br(sb);
  17519. + if (au_opt_test(au_mntflags(sb), PLINK))
  17520. + au_plink_put(sb);
  17521. + if (sbinfo->si_wbr_create_ops->fin)
  17522. + sbinfo->si_wbr_create_ops->fin(sb);
  17523. + si_write_unlock(sb);
  17524. +}
  17525. +
  17526. +/* final actions when unmounting a file system */
  17527. +static void aufs_put_super(struct super_block *sb)
  17528. +{
  17529. + struct au_sbinfo *sbinfo;
  17530. +
  17531. + sbinfo = au_sbi(sb);
  17532. + if (!sbinfo)
  17533. + return;
  17534. +
  17535. + aufs_umount_begin(sb);
  17536. + dbgaufs_si_fin(sbinfo);
  17537. + kobject_put(&sbinfo->si_kobj);
  17538. +}
  17539. +
  17540. +/* ---------------------------------------------------------------------- */
  17541. +
  17542. +/*
  17543. + * refresh dentry and inode at remount time.
  17544. + */
  17545. +static int do_refresh(struct dentry *dentry, mode_t type,
  17546. + unsigned int dir_flags)
  17547. +{
  17548. + int err;
  17549. + struct dentry *parent;
  17550. +
  17551. + di_write_lock_child(dentry);
  17552. + parent = dget_parent(dentry);
  17553. + di_read_lock_parent(parent, AuLock_IR);
  17554. +
  17555. + /* returns the number of positive dentries */
  17556. + err = au_refresh_hdentry(dentry, type);
  17557. + if (err >= 0) {
  17558. + struct inode *inode = dentry->d_inode;
  17559. + err = au_refresh_hinode(inode, dentry);
  17560. + if (!err && type == S_IFDIR)
  17561. + au_reset_hinotify(inode, dir_flags);
  17562. + }
  17563. + if (unlikely(err))
  17564. + AuErr("unrecoverable error %d, %.*s\n", err, AuDLNPair(dentry));
  17565. +
  17566. + di_read_unlock(parent, AuLock_IR);
  17567. + dput(parent);
  17568. + di_write_unlock(dentry);
  17569. +
  17570. + return err;
  17571. +}
  17572. +
  17573. +static int test_dir(struct dentry *dentry, void *arg __maybe_unused)
  17574. +{
  17575. + return S_ISDIR(dentry->d_inode->i_mode);
  17576. +}
  17577. +
  17578. +/* gave up consolidating with refresh_nondir() */
  17579. +static int refresh_dir(struct dentry *root, unsigned int sigen)
  17580. +{
  17581. + int err, i, j, ndentry, e;
  17582. + struct au_dcsub_pages dpages;
  17583. + struct au_dpage *dpage;
  17584. + struct dentry **dentries;
  17585. + struct inode *inode;
  17586. + const unsigned int flags = au_hi_flags(root->d_inode, /*isdir*/1);
  17587. +
  17588. + err = 0;
  17589. + list_for_each_entry(inode, &root->d_sb->s_inodes, i_sb_list)
  17590. + if (S_ISDIR(inode->i_mode) && au_iigen(inode) != sigen) {
  17591. + ii_write_lock_child(inode);
  17592. + e = au_refresh_hinode_self(inode, /*do_attr*/1);
  17593. + ii_write_unlock(inode);
  17594. + if (unlikely(e)) {
  17595. + AuDbg("e %d, i%lu\n", e, inode->i_ino);
  17596. + if (!err)
  17597. + err = e;
  17598. + /* go on even if err */
  17599. + }
  17600. + }
  17601. +
  17602. + e = au_dpages_init(&dpages, GFP_NOFS);
  17603. + if (unlikely(e)) {
  17604. + if (!err)
  17605. + err = e;
  17606. + goto out;
  17607. + }
  17608. + e = au_dcsub_pages(&dpages, root, test_dir, NULL);
  17609. + if (unlikely(e)) {
  17610. + if (!err)
  17611. + err = e;
  17612. + goto out_dpages;
  17613. + }
  17614. +
  17615. + for (i = 0; !e && i < dpages.ndpage; i++) {
  17616. + dpage = dpages.dpages + i;
  17617. + dentries = dpage->dentries;
  17618. + ndentry = dpage->ndentry;
  17619. + for (j = 0; !e && j < ndentry; j++) {
  17620. + struct dentry *d;
  17621. +
  17622. + d = dentries[j];
  17623. + au_dbg_verify_dir_parent(d, sigen);
  17624. + if (au_digen(d) != sigen) {
  17625. + e = do_refresh(d, S_IFDIR, flags);
  17626. + if (unlikely(e && !err))
  17627. + err = e;
  17628. + /* break on err */
  17629. + }
  17630. + }
  17631. + }
  17632. +
  17633. + out_dpages:
  17634. + au_dpages_free(&dpages);
  17635. + out:
  17636. + return err;
  17637. +}
  17638. +
  17639. +static int test_nondir(struct dentry *dentry, void *arg __maybe_unused)
  17640. +{
  17641. + return !S_ISDIR(dentry->d_inode->i_mode);
  17642. +}
  17643. +
  17644. +static int refresh_nondir(struct dentry *root, unsigned int sigen,
  17645. + int do_dentry)
  17646. +{
  17647. + int err, i, j, ndentry, e;
  17648. + struct au_dcsub_pages dpages;
  17649. + struct au_dpage *dpage;
  17650. + struct dentry **dentries;
  17651. + struct inode *inode;
  17652. +
  17653. + err = 0;
  17654. + list_for_each_entry(inode, &root->d_sb->s_inodes, i_sb_list)
  17655. + if (!S_ISDIR(inode->i_mode) && au_iigen(inode) != sigen) {
  17656. + ii_write_lock_child(inode);
  17657. + e = au_refresh_hinode_self(inode, /*do_attr*/1);
  17658. + ii_write_unlock(inode);
  17659. + if (unlikely(e)) {
  17660. + AuDbg("e %d, i%lu\n", e, inode->i_ino);
  17661. + if (!err)
  17662. + err = e;
  17663. + /* go on even if err */
  17664. + }
  17665. + }
  17666. +
  17667. + if (!do_dentry)
  17668. + goto out;
  17669. +
  17670. + e = au_dpages_init(&dpages, GFP_NOFS);
  17671. + if (unlikely(e)) {
  17672. + if (!err)
  17673. + err = e;
  17674. + goto out;
  17675. + }
  17676. + e = au_dcsub_pages(&dpages, root, test_nondir, NULL);
  17677. + if (unlikely(e)) {
  17678. + if (!err)
  17679. + err = e;
  17680. + goto out_dpages;
  17681. + }
  17682. +
  17683. + for (i = 0; i < dpages.ndpage; i++) {
  17684. + dpage = dpages.dpages + i;
  17685. + dentries = dpage->dentries;
  17686. + ndentry = dpage->ndentry;
  17687. + for (j = 0; j < ndentry; j++) {
  17688. + struct dentry *d;
  17689. +
  17690. + d = dentries[j];
  17691. + au_dbg_verify_nondir_parent(d, sigen);
  17692. + inode = d->d_inode;
  17693. + if (inode && au_digen(d) != sigen) {
  17694. + e = do_refresh(d, inode->i_mode & S_IFMT,
  17695. + /*dir_flags*/0);
  17696. + if (unlikely(e && !err))
  17697. + err = e;
  17698. + /* go on even err */
  17699. + }
  17700. + }
  17701. + }
  17702. +
  17703. + out_dpages:
  17704. + au_dpages_free(&dpages);
  17705. + out:
  17706. + return err;
  17707. +}
  17708. +
  17709. +static void au_remount_refresh(struct super_block *sb, unsigned int flags)
  17710. +{
  17711. + int err;
  17712. + unsigned int sigen;
  17713. + struct au_sbinfo *sbinfo;
  17714. + struct dentry *root;
  17715. + struct inode *inode;
  17716. +
  17717. + au_sigen_inc(sb);
  17718. + sigen = au_sigen(sb);
  17719. + sbinfo = au_sbi(sb);
  17720. + au_fclr_si(sbinfo, FAILED_REFRESH_DIRS);
  17721. +
  17722. + root = sb->s_root;
  17723. + DiMustNoWaiters(root);
  17724. + inode = root->d_inode;
  17725. + IiMustNoWaiters(inode);
  17726. + au_reset_hinotify(inode, au_hi_flags(inode, /*isdir*/1));
  17727. + di_write_unlock(root);
  17728. +
  17729. + err = refresh_dir(root, sigen);
  17730. + if (unlikely(err)) {
  17731. + au_fset_si(sbinfo, FAILED_REFRESH_DIRS);
  17732. + AuWarn("Refreshing directories failed, ignored (%d)\n", err);
  17733. + }
  17734. +
  17735. + if (au_ftest_opts(flags, REFRESH_NONDIR)) {
  17736. + err = refresh_nondir(root, sigen, !err);
  17737. + if (unlikely(err))
  17738. + AuWarn("Refreshing non-directories failed, ignored"
  17739. + "(%d)\n", err);
  17740. + }
  17741. +
  17742. + /* aufs_write_lock() calls ..._child() */
  17743. + di_write_lock_child(root);
  17744. + au_cpup_attr_all(root->d_inode, /*force*/1);
  17745. +}
  17746. +
  17747. +/* stop extra interpretation of errno in mount(8), and strange error messages */
  17748. +static int cvt_err(int err)
  17749. +{
  17750. + AuTraceErr(err);
  17751. +
  17752. + switch (err) {
  17753. + case -ENOENT:
  17754. + case -ENOTDIR:
  17755. + case -EEXIST:
  17756. + case -EIO:
  17757. + err = -EINVAL;
  17758. + }
  17759. + return err;
  17760. +}
  17761. +
  17762. +static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
  17763. +{
  17764. + int err;
  17765. + struct au_opts opts;
  17766. + struct dentry *root;
  17767. + struct inode *inode;
  17768. + struct au_sbinfo *sbinfo;
  17769. +
  17770. + err = 0;
  17771. + root = sb->s_root;
  17772. + if (!data || !*data) {
  17773. + aufs_write_lock(root);
  17774. + err = au_opts_verify(sb, *flags, /*pending*/0);
  17775. + if (!err)
  17776. + au_fsync_br(sb);
  17777. + aufs_write_unlock(root);
  17778. + goto out;
  17779. + }
  17780. +
  17781. + err = -ENOMEM;
  17782. + memset(&opts, 0, sizeof(opts));
  17783. + opts.opt = (void *)__get_free_page(GFP_NOFS);
  17784. + if (unlikely(!opts.opt))
  17785. + goto out;
  17786. + opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
  17787. + opts.flags = AuOpts_REMOUNT;
  17788. + opts.sb_flags = *flags;
  17789. +
  17790. + /* parse it before aufs lock */
  17791. + err = au_opts_parse(sb, data, &opts);
  17792. + if (unlikely(err))
  17793. + goto out_opts;
  17794. +
  17795. + sbinfo = au_sbi(sb);
  17796. + inode = root->d_inode;
  17797. + mutex_lock(&inode->i_mutex);
  17798. + aufs_write_lock(root);
  17799. + au_fsync_br(sb);
  17800. +
  17801. + /* au_opts_remount() may return an error */
  17802. + err = au_opts_remount(sb, &opts);
  17803. + au_opts_free(&opts);
  17804. +
  17805. + if (au_ftest_opts(opts.flags, REFRESH_DIR)
  17806. + || au_ftest_opts(opts.flags, REFRESH_NONDIR))
  17807. + au_remount_refresh(sb, opts.flags);
  17808. +
  17809. + aufs_write_unlock(root);
  17810. + mutex_unlock(&inode->i_mutex);
  17811. +
  17812. + out_opts:
  17813. + free_page((unsigned long)opts.opt);
  17814. + out:
  17815. + err = cvt_err(err);
  17816. + AuTraceErr(err);
  17817. + return err;
  17818. +}
  17819. +
  17820. +static struct super_operations aufs_sop = {
  17821. + .alloc_inode = aufs_alloc_inode,
  17822. + .destroy_inode = aufs_destroy_inode,
  17823. + .drop_inode = generic_delete_inode,
  17824. + .show_options = aufs_show_options,
  17825. + .statfs = aufs_statfs,
  17826. + .put_super = aufs_put_super,
  17827. + .remount_fs = aufs_remount_fs
  17828. +};
  17829. +
  17830. +/* ---------------------------------------------------------------------- */
  17831. +
  17832. +static int alloc_root(struct super_block *sb)
  17833. +{
  17834. + int err;
  17835. + struct inode *inode;
  17836. + struct dentry *root;
  17837. +
  17838. + err = -ENOMEM;
  17839. + inode = au_iget_locked(sb, AUFS_ROOT_INO);
  17840. + err = PTR_ERR(inode);
  17841. + if (IS_ERR(inode))
  17842. + goto out;
  17843. +
  17844. + inode->i_op = &aufs_dir_iop;
  17845. + inode->i_fop = &aufs_dir_fop;
  17846. + inode->i_mode = S_IFDIR;
  17847. + inode->i_nlink = 2;
  17848. + unlock_new_inode(inode);
  17849. +
  17850. + root = d_alloc_root(inode);
  17851. + if (unlikely(!root))
  17852. + goto out_iput;
  17853. + err = PTR_ERR(root);
  17854. + if (IS_ERR(root))
  17855. + goto out_iput;
  17856. +
  17857. + err = au_alloc_dinfo(root);
  17858. + if (!err) {
  17859. + sb->s_root = root;
  17860. + return 0; /* success */
  17861. + }
  17862. + dput(root);
  17863. + goto out; /* do not iput */
  17864. +
  17865. + out_iput:
  17866. + iget_failed(inode);
  17867. + iput(inode);
  17868. + out:
  17869. + return err;
  17870. +
  17871. +}
  17872. +
  17873. +static int aufs_fill_super(struct super_block *sb, void *raw_data,
  17874. + int silent __maybe_unused)
  17875. +{
  17876. + int err;
  17877. + struct au_opts opts;
  17878. + struct dentry *root;
  17879. + struct inode *inode;
  17880. + char *arg = raw_data;
  17881. +
  17882. + if (unlikely(!arg || !*arg)) {
  17883. + err = -EINVAL;
  17884. + AuErr("no arg\n");
  17885. + goto out;
  17886. + }
  17887. +
  17888. + err = -ENOMEM;
  17889. + memset(&opts, 0, sizeof(opts));
  17890. + opts.opt = (void *)__get_free_page(GFP_NOFS);
  17891. + if (unlikely(!opts.opt))
  17892. + goto out;
  17893. + opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
  17894. + opts.sb_flags = sb->s_flags;
  17895. +
  17896. + err = au_si_alloc(sb);
  17897. + if (unlikely(err))
  17898. + goto out_opts;
  17899. +
  17900. + /* all timestamps always follow the ones on the branch */
  17901. + sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
  17902. + sb->s_op = &aufs_sop;
  17903. + sb->s_magic = AUFS_SUPER_MAGIC;
  17904. + sb->s_maxbytes = 0;
  17905. + au_export_init(sb);
  17906. +
  17907. + err = alloc_root(sb);
  17908. + if (unlikely(err)) {
  17909. + si_write_unlock(sb);
  17910. + goto out_info;
  17911. + }
  17912. + root = sb->s_root;
  17913. + inode = root->d_inode;
  17914. +
  17915. + /*
  17916. + * actually we can parse options regardless aufs lock here.
  17917. + * but at remount time, parsing must be done before aufs lock.
  17918. + * so we follow the same rule.
  17919. + */
  17920. + ii_write_lock_parent(inode);
  17921. + aufs_write_unlock(root);
  17922. + err = au_opts_parse(sb, arg, &opts);
  17923. + if (unlikely(err))
  17924. + goto out_root;
  17925. +
  17926. + /* lock vfs_inode first, then aufs. */
  17927. + mutex_lock(&inode->i_mutex);
  17928. + inode->i_op = &aufs_dir_iop;
  17929. + inode->i_fop = &aufs_dir_fop;
  17930. + aufs_write_lock(root);
  17931. + err = au_opts_mount(sb, &opts);
  17932. + au_opts_free(&opts);
  17933. + if (unlikely(err))
  17934. + goto out_unlock;
  17935. + aufs_write_unlock(root);
  17936. + mutex_unlock(&inode->i_mutex);
  17937. + goto out_opts; /* success */
  17938. +
  17939. + out_unlock:
  17940. + aufs_write_unlock(root);
  17941. + mutex_unlock(&inode->i_mutex);
  17942. + out_root:
  17943. + dput(root);
  17944. + sb->s_root = NULL;
  17945. + out_info:
  17946. + kobject_put(&au_sbi(sb)->si_kobj);
  17947. + sb->s_fs_info = NULL;
  17948. + out_opts:
  17949. + free_page((unsigned long)opts.opt);
  17950. + out:
  17951. + AuTraceErr(err);
  17952. + err = cvt_err(err);
  17953. + AuTraceErr(err);
  17954. + return err;
  17955. +}
  17956. +
  17957. +/* ---------------------------------------------------------------------- */
  17958. +
  17959. +static int aufs_get_sb(struct file_system_type *fs_type, int flags,
  17960. + const char *dev_name __maybe_unused, void *raw_data,
  17961. + struct vfsmount *mnt)
  17962. +{
  17963. + int err;
  17964. + struct super_block *sb;
  17965. +
  17966. + /* all timestamps always follow the ones on the branch */
  17967. + /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
  17968. + err = get_sb_nodev(fs_type, flags, raw_data, aufs_fill_super, mnt);
  17969. + if (!err) {
  17970. + sb = mnt->mnt_sb;
  17971. + si_write_lock(sb);
  17972. + sysaufs_brs_add(sb, 0);
  17973. + si_write_unlock(sb);
  17974. + }
  17975. + return err;
  17976. +}
  17977. +
  17978. +struct file_system_type aufs_fs_type = {
  17979. + .name = AUFS_FSTYPE,
  17980. + .fs_flags =
  17981. + FS_RENAME_DOES_D_MOVE /* a race between rename and others */
  17982. + | FS_REVAL_DOT, /* for NFS branch and udba */
  17983. + .get_sb = aufs_get_sb,
  17984. + .kill_sb = generic_shutdown_super,
  17985. + /* no need to __module_get() and module_put(). */
  17986. + .owner = THIS_MODULE,
  17987. +};
  17988. diff -Nur linux-2.6.31.5.orig/fs/aufs/super.h linux-2.6.31.5/fs/aufs/super.h
  17989. --- linux-2.6.31.5.orig/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100
  17990. +++ linux-2.6.31.5/fs/aufs/super.h 2009-11-15 22:02:37.000000000 +0100
  17991. @@ -0,0 +1,384 @@
  17992. +/*
  17993. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  17994. + *
  17995. + * This program, aufs is free software; you can redistribute it and/or modify
  17996. + * it under the terms of the GNU General Public License as published by
  17997. + * the Free Software Foundation; either version 2 of the License, or
  17998. + * (at your option) any later version.
  17999. + *
  18000. + * This program is distributed in the hope that it will be useful,
  18001. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18002. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18003. + * GNU General Public License for more details.
  18004. + *
  18005. + * You should have received a copy of the GNU General Public License
  18006. + * along with this program; if not, write to the Free Software
  18007. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18008. + */
  18009. +
  18010. +/*
  18011. + * super_block operations
  18012. + */
  18013. +
  18014. +#ifndef __AUFS_SUPER_H__
  18015. +#define __AUFS_SUPER_H__
  18016. +
  18017. +#ifdef __KERNEL__
  18018. +
  18019. +#include <linux/fs.h>
  18020. +#include <linux/aufs_type.h>
  18021. +#include "rwsem.h"
  18022. +#include "spl.h"
  18023. +#include "wkq.h"
  18024. +
  18025. +typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *);
  18026. +typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t,
  18027. + loff_t *);
  18028. +
  18029. +/* policies to select one among multiple writable branches */
  18030. +struct au_wbr_copyup_operations {
  18031. + int (*copyup)(struct dentry *dentry);
  18032. +};
  18033. +
  18034. +struct au_wbr_create_operations {
  18035. + int (*create)(struct dentry *dentry, int isdir);
  18036. + int (*init)(struct super_block *sb);
  18037. + int (*fin)(struct super_block *sb);
  18038. +};
  18039. +
  18040. +struct au_wbr_mfs {
  18041. + struct mutex mfs_lock; /* protect this structure */
  18042. + unsigned long mfs_jiffy;
  18043. + unsigned long mfs_expire;
  18044. + aufs_bindex_t mfs_bindex;
  18045. +
  18046. + unsigned long long mfsrr_bytes;
  18047. + unsigned long long mfsrr_watermark;
  18048. +};
  18049. +
  18050. +struct au_branch;
  18051. +struct au_sbinfo {
  18052. + /* nowait tasks in the system-wide workqueue */
  18053. + struct au_nowait_tasks si_nowait;
  18054. +
  18055. + struct au_rwsem si_rwsem;
  18056. +
  18057. + /* branch management */
  18058. + unsigned int si_generation;
  18059. +
  18060. + /* see above flags */
  18061. + unsigned char au_si_status;
  18062. +
  18063. + aufs_bindex_t si_bend;
  18064. + aufs_bindex_t si_last_br_id;
  18065. + struct au_branch **si_branch;
  18066. +
  18067. + /* policy to select a writable branch */
  18068. + unsigned char si_wbr_copyup;
  18069. + unsigned char si_wbr_create;
  18070. + struct au_wbr_copyup_operations *si_wbr_copyup_ops;
  18071. + struct au_wbr_create_operations *si_wbr_create_ops;
  18072. +
  18073. + /* round robin */
  18074. + atomic_t si_wbr_rr_next;
  18075. +
  18076. + /* most free space */
  18077. + struct au_wbr_mfs si_wbr_mfs;
  18078. +
  18079. + /* mount flags */
  18080. + /* include/asm-ia64/siginfo.h defines a macro named si_flags */
  18081. + unsigned int si_mntflags;
  18082. +
  18083. + /* external inode number (bitmap and translation table) */
  18084. + au_readf_t si_xread;
  18085. + au_writef_t si_xwrite;
  18086. + struct file *si_xib;
  18087. + struct mutex si_xib_mtx; /* protect xib members */
  18088. + unsigned long *si_xib_buf;
  18089. + unsigned long si_xib_last_pindex;
  18090. + int si_xib_next_bit;
  18091. + aufs_bindex_t si_xino_brid;
  18092. + /* reserved for future use */
  18093. + /* unsigned long long si_xib_limit; */ /* Max xib file size */
  18094. +
  18095. +#ifdef CONFIG_AUFS_EXPORT
  18096. + /* i_generation */
  18097. + struct file *si_xigen;
  18098. + atomic_t si_xigen_next;
  18099. +#endif
  18100. +
  18101. + /* vdir parameters */
  18102. + unsigned long si_rdcache; /* max cache time in HZ */
  18103. + unsigned int si_rdblk; /* deblk size */
  18104. + unsigned int si_rdhash; /* hash size */
  18105. +
  18106. + /*
  18107. + * If the number of whiteouts are larger than si_dirwh, leave all of
  18108. + * them after au_whtmp_ren to reduce the cost of rmdir(2).
  18109. + * future fsck.aufs or kernel thread will remove them later.
  18110. + * Otherwise, remove all whiteouts and the dir in rmdir(2).
  18111. + */
  18112. + unsigned int si_dirwh;
  18113. +
  18114. + /*
  18115. + * rename(2) a directory with all children.
  18116. + */
  18117. + /* reserved for future use */
  18118. + /* int si_rendir; */
  18119. +
  18120. + /* pseudo_link list */
  18121. + struct au_splhead si_plink;
  18122. + wait_queue_head_t si_plink_wq;
  18123. +
  18124. + /*
  18125. + * sysfs and lifetime management.
  18126. + * this is not a small structure and it may be a waste of memory in case
  18127. + * of sysfs is disabled, particulary when many aufs-es are mounted.
  18128. + * but using sysfs is majority.
  18129. + */
  18130. + struct kobject si_kobj;
  18131. +#ifdef CONFIG_DEBUG_FS
  18132. + struct dentry *si_dbgaufs, *si_dbgaufs_xib;
  18133. +#ifdef CONFIG_AUFS_EXPORT
  18134. + struct dentry *si_dbgaufs_xigen;
  18135. +#endif
  18136. +#endif
  18137. +
  18138. + /* dirty, necessary for unmounting, sysfs and sysrq */
  18139. + struct super_block *si_sb;
  18140. +};
  18141. +
  18142. +/* sbinfo status flags */
  18143. +/*
  18144. + * set true when refresh_dirs() failed at remount time.
  18145. + * then try refreshing dirs at access time again.
  18146. + * if it is false, refreshing dirs at access time is unnecesary
  18147. + */
  18148. +#define AuSi_FAILED_REFRESH_DIRS 1
  18149. +#define AuSi_MAINTAIN_PLINK (1 << 1) /* ioctl */
  18150. +static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
  18151. + unsigned int flag)
  18152. +{
  18153. + AuRwMustAnyLock(&sbi->si_rwsem);
  18154. + return sbi->au_si_status & flag;
  18155. +}
  18156. +#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name)
  18157. +#define au_fset_si(sbinfo, name) do { \
  18158. + AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
  18159. + (sbinfo)->au_si_status |= AuSi_##name; \
  18160. +} while (0)
  18161. +#define au_fclr_si(sbinfo, name) do { \
  18162. + AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
  18163. + (sbinfo)->au_si_status &= ~AuSi_##name; \
  18164. +} while (0)
  18165. +
  18166. +/* ---------------------------------------------------------------------- */
  18167. +
  18168. +/* policy to select one among writable branches */
  18169. +#define AuWbrCopyup(sbinfo, args...) \
  18170. + ((sbinfo)->si_wbr_copyup_ops->copyup(args))
  18171. +#define AuWbrCreate(sbinfo, args...) \
  18172. + ((sbinfo)->si_wbr_create_ops->create(args))
  18173. +
  18174. +/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
  18175. +#define AuLock_DW 1 /* write-lock dentry */
  18176. +#define AuLock_IR (1 << 1) /* read-lock inode */
  18177. +#define AuLock_IW (1 << 2) /* write-lock inode */
  18178. +#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
  18179. +#define AuLock_DIR (1 << 4) /* target is a dir */
  18180. +#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
  18181. +#define au_fset_lock(flags, name) { (flags) |= AuLock_##name; }
  18182. +#define au_fclr_lock(flags, name) { (flags) &= ~AuLock_##name; }
  18183. +
  18184. +/* ---------------------------------------------------------------------- */
  18185. +
  18186. +/* super.c */
  18187. +extern struct file_system_type aufs_fs_type;
  18188. +struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
  18189. +
  18190. +/* sbinfo.c */
  18191. +void au_si_free(struct kobject *kobj);
  18192. +int au_si_alloc(struct super_block *sb);
  18193. +int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr);
  18194. +
  18195. +unsigned int au_sigen_inc(struct super_block *sb);
  18196. +aufs_bindex_t au_new_br_id(struct super_block *sb);
  18197. +
  18198. +void aufs_read_lock(struct dentry *dentry, int flags);
  18199. +void aufs_read_unlock(struct dentry *dentry, int flags);
  18200. +void aufs_write_lock(struct dentry *dentry);
  18201. +void aufs_write_unlock(struct dentry *dentry);
  18202. +void aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int isdir);
  18203. +void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
  18204. +
  18205. +/* wbr_policy.c */
  18206. +extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
  18207. +extern struct au_wbr_create_operations au_wbr_create_ops[];
  18208. +int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
  18209. +
  18210. +/* ---------------------------------------------------------------------- */
  18211. +
  18212. +static inline struct au_sbinfo *au_sbi(struct super_block *sb)
  18213. +{
  18214. + return sb->s_fs_info;
  18215. +}
  18216. +
  18217. +/* ---------------------------------------------------------------------- */
  18218. +
  18219. +#ifdef CONFIG_AUFS_EXPORT
  18220. +void au_export_init(struct super_block *sb);
  18221. +
  18222. +static inline int au_test_nfsd(struct task_struct *tsk)
  18223. +{
  18224. + return !tsk->mm && !strcmp(tsk->comm, "nfsd");
  18225. +}
  18226. +
  18227. +int au_xigen_inc(struct inode *inode);
  18228. +int au_xigen_new(struct inode *inode);
  18229. +int au_xigen_set(struct super_block *sb, struct file *base);
  18230. +void au_xigen_clr(struct super_block *sb);
  18231. +
  18232. +static inline int au_busy_or_stale(void)
  18233. +{
  18234. + if (!au_test_nfsd(current))
  18235. + return -EBUSY;
  18236. + return -ESTALE;
  18237. +}
  18238. +#else
  18239. +static inline void au_export_init(struct super_block *sb)
  18240. +{
  18241. + /* nothing */
  18242. +}
  18243. +
  18244. +static inline int au_test_nfsd(struct task_struct *tsk)
  18245. +{
  18246. + return 0;
  18247. +}
  18248. +
  18249. +static inline int au_xigen_inc(struct inode *inode)
  18250. +{
  18251. + return 0;
  18252. +}
  18253. +
  18254. +static inline int au_xigen_new(struct inode *inode)
  18255. +{
  18256. + return 0;
  18257. +}
  18258. +
  18259. +static inline int au_xigen_set(struct super_block *sb, struct file *base)
  18260. +{
  18261. + return 0;
  18262. +}
  18263. +
  18264. +static inline void au_xigen_clr(struct super_block *sb)
  18265. +{
  18266. + /* empty */
  18267. +}
  18268. +
  18269. +static inline int au_busy_or_stale(void)
  18270. +{
  18271. + return -EBUSY;
  18272. +}
  18273. +#endif /* CONFIG_AUFS_EXPORT */
  18274. +
  18275. +/* ---------------------------------------------------------------------- */
  18276. +
  18277. +static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
  18278. +{
  18279. + /*
  18280. + * This function is a dynamic '__init' fucntion actually,
  18281. + * so the tiny check for si_rwsem is unnecessary.
  18282. + */
  18283. + /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
  18284. +#ifdef CONFIG_DEBUG_FS
  18285. + sbinfo->si_dbgaufs = NULL;
  18286. + sbinfo->si_dbgaufs_xib = NULL;
  18287. +#ifdef CONFIG_AUFS_EXPORT
  18288. + sbinfo->si_dbgaufs_xigen = NULL;
  18289. +#endif
  18290. +#endif
  18291. +}
  18292. +
  18293. +/* ---------------------------------------------------------------------- */
  18294. +
  18295. +/* lock superblock. mainly for entry point functions */
  18296. +/*
  18297. + * si_noflush_read_lock, si_noflush_write_lock,
  18298. + * si_read_unlock, si_write_unlock, si_downgrade_lock
  18299. + */
  18300. +AuSimpleLockRwsemFuncs(si_noflush, struct super_block *sb,
  18301. + &au_sbi(sb)->si_rwsem);
  18302. +AuSimpleUnlockRwsemFuncs(si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
  18303. +
  18304. +#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
  18305. +#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
  18306. +#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
  18307. +
  18308. +static inline void si_read_lock(struct super_block *sb, int flags)
  18309. +{
  18310. + if (au_ftest_lock(flags, FLUSH))
  18311. + au_nwt_flush(&au_sbi(sb)->si_nowait);
  18312. + si_noflush_read_lock(sb);
  18313. +}
  18314. +
  18315. +static inline void si_write_lock(struct super_block *sb)
  18316. +{
  18317. + au_nwt_flush(&au_sbi(sb)->si_nowait);
  18318. + si_noflush_write_lock(sb);
  18319. +}
  18320. +
  18321. +static inline int si_read_trylock(struct super_block *sb, int flags)
  18322. +{
  18323. + if (au_ftest_lock(flags, FLUSH))
  18324. + au_nwt_flush(&au_sbi(sb)->si_nowait);
  18325. + return si_noflush_read_trylock(sb);
  18326. +}
  18327. +
  18328. +static inline int si_write_trylock(struct super_block *sb, int flags)
  18329. +{
  18330. + if (au_ftest_lock(flags, FLUSH))
  18331. + au_nwt_flush(&au_sbi(sb)->si_nowait);
  18332. + return si_noflush_write_trylock(sb);
  18333. +}
  18334. +
  18335. +/* ---------------------------------------------------------------------- */
  18336. +
  18337. +static inline aufs_bindex_t au_sbend(struct super_block *sb)
  18338. +{
  18339. + SiMustAnyLock(sb);
  18340. + return au_sbi(sb)->si_bend;
  18341. +}
  18342. +
  18343. +static inline unsigned int au_mntflags(struct super_block *sb)
  18344. +{
  18345. + SiMustAnyLock(sb);
  18346. + return au_sbi(sb)->si_mntflags;
  18347. +}
  18348. +
  18349. +static inline unsigned int au_sigen(struct super_block *sb)
  18350. +{
  18351. + SiMustAnyLock(sb);
  18352. + return au_sbi(sb)->si_generation;
  18353. +}
  18354. +
  18355. +static inline struct au_branch *au_sbr(struct super_block *sb,
  18356. + aufs_bindex_t bindex)
  18357. +{
  18358. + SiMustAnyLock(sb);
  18359. + return au_sbi(sb)->si_branch[0 + bindex];
  18360. +}
  18361. +
  18362. +static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid)
  18363. +{
  18364. + SiMustWriteLock(sb);
  18365. + au_sbi(sb)->si_xino_brid = brid;
  18366. +}
  18367. +
  18368. +static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
  18369. +{
  18370. + SiMustAnyLock(sb);
  18371. + return au_sbi(sb)->si_xino_brid;
  18372. +}
  18373. +
  18374. +#endif /* __KERNEL__ */
  18375. +#endif /* __AUFS_SUPER_H__ */
  18376. diff -Nur linux-2.6.31.5.orig/fs/aufs/sysaufs.c linux-2.6.31.5/fs/aufs/sysaufs.c
  18377. --- linux-2.6.31.5.orig/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
  18378. +++ linux-2.6.31.5/fs/aufs/sysaufs.c 2009-11-15 22:02:37.000000000 +0100
  18379. @@ -0,0 +1,104 @@
  18380. +/*
  18381. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  18382. + *
  18383. + * This program, aufs is free software; you can redistribute it and/or modify
  18384. + * it under the terms of the GNU General Public License as published by
  18385. + * the Free Software Foundation; either version 2 of the License, or
  18386. + * (at your option) any later version.
  18387. + *
  18388. + * This program is distributed in the hope that it will be useful,
  18389. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18390. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18391. + * GNU General Public License for more details.
  18392. + *
  18393. + * You should have received a copy of the GNU General Public License
  18394. + * along with this program; if not, write to the Free Software
  18395. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18396. + */
  18397. +
  18398. +/*
  18399. + * sysfs interface and lifetime management
  18400. + * they are necessary regardless sysfs is disabled.
  18401. + */
  18402. +
  18403. +#include <linux/fs.h>
  18404. +#include <linux/random.h>
  18405. +#include <linux/sysfs.h>
  18406. +#include "aufs.h"
  18407. +
  18408. +unsigned long sysaufs_si_mask;
  18409. +struct kset *sysaufs_ket;
  18410. +
  18411. +#define AuSiAttr(_name) { \
  18412. + .attr = { .name = __stringify(_name), .mode = 0444 }, \
  18413. + .show = sysaufs_si_##_name, \
  18414. +}
  18415. +
  18416. +static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
  18417. +struct attribute *sysaufs_si_attrs[] = {
  18418. + &sysaufs_si_attr_xi_path.attr,
  18419. + NULL,
  18420. +};
  18421. +
  18422. +static struct sysfs_ops au_sbi_ops = {
  18423. + .show = sysaufs_si_show
  18424. +};
  18425. +
  18426. +static struct kobj_type au_sbi_ktype = {
  18427. + .release = au_si_free,
  18428. + .sysfs_ops = &au_sbi_ops,
  18429. + .default_attrs = sysaufs_si_attrs
  18430. +};
  18431. +
  18432. +/* ---------------------------------------------------------------------- */
  18433. +
  18434. +int sysaufs_si_init(struct au_sbinfo *sbinfo)
  18435. +{
  18436. + int err;
  18437. +
  18438. + sbinfo->si_kobj.kset = sysaufs_ket;
  18439. + /* cf. sysaufs_name() */
  18440. + err = kobject_init_and_add
  18441. + (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_ket->kobj*/NULL,
  18442. + SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
  18443. +
  18444. + dbgaufs_si_null(sbinfo);
  18445. + if (!err) {
  18446. + err = dbgaufs_si_init(sbinfo);
  18447. + if (unlikely(err))
  18448. + kobject_put(&sbinfo->si_kobj);
  18449. + }
  18450. + return err;
  18451. +}
  18452. +
  18453. +void sysaufs_fin(void)
  18454. +{
  18455. + dbgaufs_fin();
  18456. + sysfs_remove_group(&sysaufs_ket->kobj, sysaufs_attr_group);
  18457. + kset_unregister(sysaufs_ket);
  18458. +}
  18459. +
  18460. +int __init sysaufs_init(void)
  18461. +{
  18462. + int err;
  18463. +
  18464. + do {
  18465. + get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
  18466. + } while (!sysaufs_si_mask);
  18467. +
  18468. + sysaufs_ket = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
  18469. + err = PTR_ERR(sysaufs_ket);
  18470. + if (IS_ERR(sysaufs_ket))
  18471. + goto out;
  18472. + err = sysfs_create_group(&sysaufs_ket->kobj, sysaufs_attr_group);
  18473. + if (unlikely(err)) {
  18474. + kset_unregister(sysaufs_ket);
  18475. + goto out;
  18476. + }
  18477. +
  18478. + err = dbgaufs_init();
  18479. + if (unlikely(err))
  18480. + sysaufs_fin();
  18481. + out:
  18482. + return err;
  18483. +}
  18484. diff -Nur linux-2.6.31.5.orig/fs/aufs/sysaufs.h linux-2.6.31.5/fs/aufs/sysaufs.h
  18485. --- linux-2.6.31.5.orig/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
  18486. +++ linux-2.6.31.5/fs/aufs/sysaufs.h 2009-11-15 22:02:37.000000000 +0100
  18487. @@ -0,0 +1,120 @@
  18488. +/*
  18489. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  18490. + *
  18491. + * This program, aufs is free software; you can redistribute it and/or modify
  18492. + * it under the terms of the GNU General Public License as published by
  18493. + * the Free Software Foundation; either version 2 of the License, or
  18494. + * (at your option) any later version.
  18495. + *
  18496. + * This program is distributed in the hope that it will be useful,
  18497. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18498. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18499. + * GNU General Public License for more details.
  18500. + *
  18501. + * You should have received a copy of the GNU General Public License
  18502. + * along with this program; if not, write to the Free Software
  18503. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18504. + */
  18505. +
  18506. +/*
  18507. + * sysfs interface and mount lifetime management
  18508. + */
  18509. +
  18510. +#ifndef __SYSAUFS_H__
  18511. +#define __SYSAUFS_H__
  18512. +
  18513. +#ifdef __KERNEL__
  18514. +
  18515. +#include <linux/sysfs.h>
  18516. +#include <linux/aufs_type.h>
  18517. +#include "module.h"
  18518. +
  18519. +struct super_block;
  18520. +struct au_sbinfo;
  18521. +
  18522. +struct sysaufs_si_attr {
  18523. + struct attribute attr;
  18524. + int (*show)(struct seq_file *seq, struct super_block *sb);
  18525. +};
  18526. +
  18527. +/* ---------------------------------------------------------------------- */
  18528. +
  18529. +/* sysaufs.c */
  18530. +extern unsigned long sysaufs_si_mask;
  18531. +extern struct kset *sysaufs_ket;
  18532. +extern struct attribute *sysaufs_si_attrs[];
  18533. +int sysaufs_si_init(struct au_sbinfo *sbinfo);
  18534. +int __init sysaufs_init(void);
  18535. +void sysaufs_fin(void);
  18536. +
  18537. +/* ---------------------------------------------------------------------- */
  18538. +
  18539. +/* some people doesn't like to show a pointer in kernel */
  18540. +static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
  18541. +{
  18542. + return sysaufs_si_mask ^ (unsigned long)sbinfo;
  18543. +}
  18544. +
  18545. +#define SysaufsSiNamePrefix "si_"
  18546. +#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16)
  18547. +static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
  18548. +{
  18549. + snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
  18550. + sysaufs_si_id(sbinfo));
  18551. +}
  18552. +
  18553. +struct au_branch;
  18554. +#ifdef CONFIG_SYSFS
  18555. +/* sysfs.c */
  18556. +extern struct attribute_group *sysaufs_attr_group;
  18557. +
  18558. +int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
  18559. +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
  18560. + char *buf);
  18561. +
  18562. +void sysaufs_br_init(struct au_branch *br);
  18563. +void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
  18564. +void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
  18565. +
  18566. +#define sysaufs_brs_init() do {} while (0)
  18567. +
  18568. +#else
  18569. +#define sysaufs_attr_group NULL
  18570. +
  18571. +static inline
  18572. +int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
  18573. +{
  18574. + return 0;
  18575. +}
  18576. +
  18577. +static inline
  18578. +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
  18579. + char *buf)
  18580. +{
  18581. + return 0;
  18582. +}
  18583. +
  18584. +static inline void sysaufs_br_init(struct au_branch *br)
  18585. +{
  18586. + /* empty */
  18587. +}
  18588. +
  18589. +static inline void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
  18590. +{
  18591. + /* nothing */
  18592. +}
  18593. +
  18594. +static inline void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
  18595. +{
  18596. + /* nothing */
  18597. +}
  18598. +
  18599. +static inline void sysaufs_brs_init(void)
  18600. +{
  18601. + sysaufs_brs = 0;
  18602. +}
  18603. +
  18604. +#endif /* CONFIG_SYSFS */
  18605. +
  18606. +#endif /* __KERNEL__ */
  18607. +#endif /* __SYSAUFS_H__ */
  18608. diff -Nur linux-2.6.31.5.orig/fs/aufs/sysfs.c linux-2.6.31.5/fs/aufs/sysfs.c
  18609. --- linux-2.6.31.5.orig/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100
  18610. +++ linux-2.6.31.5/fs/aufs/sysfs.c 2009-11-15 22:02:37.000000000 +0100
  18611. @@ -0,0 +1,210 @@
  18612. +/*
  18613. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  18614. + *
  18615. + * This program, aufs is free software; you can redistribute it and/or modify
  18616. + * it under the terms of the GNU General Public License as published by
  18617. + * the Free Software Foundation; either version 2 of the License, or
  18618. + * (at your option) any later version.
  18619. + *
  18620. + * This program is distributed in the hope that it will be useful,
  18621. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18622. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18623. + * GNU General Public License for more details.
  18624. + *
  18625. + * You should have received a copy of the GNU General Public License
  18626. + * along with this program; if not, write to the Free Software
  18627. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18628. + */
  18629. +
  18630. +/*
  18631. + * sysfs interface
  18632. + */
  18633. +
  18634. +#include <linux/fs.h>
  18635. +#include <linux/module.h>
  18636. +#include <linux/seq_file.h>
  18637. +#include <linux/sysfs.h>
  18638. +#include "aufs.h"
  18639. +
  18640. +static struct attribute *au_attr[] = {
  18641. + NULL, /* need to NULL terminate the list of attributes */
  18642. +};
  18643. +
  18644. +static struct attribute_group sysaufs_attr_group_body = {
  18645. + .attrs = au_attr
  18646. +};
  18647. +
  18648. +struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
  18649. +
  18650. +/* ---------------------------------------------------------------------- */
  18651. +
  18652. +int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
  18653. +{
  18654. + int err;
  18655. +
  18656. + SiMustAnyLock(sb);
  18657. +
  18658. + err = 0;
  18659. + if (au_opt_test(au_mntflags(sb), XINO)) {
  18660. + err = au_xino_path(seq, au_sbi(sb)->si_xib);
  18661. + seq_putc(seq, '\n');
  18662. + }
  18663. + return err;
  18664. +}
  18665. +
  18666. +/*
  18667. + * the lifetime of branch is independent from the entry under sysfs.
  18668. + * sysfs handles the lifetime of the entry, and never call ->show() after it is
  18669. + * unlinked.
  18670. + */
  18671. +static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
  18672. + aufs_bindex_t bindex)
  18673. +{
  18674. + struct path path;
  18675. + struct dentry *root;
  18676. + struct au_branch *br;
  18677. +
  18678. + AuDbg("b%d\n", bindex);
  18679. +
  18680. + root = sb->s_root;
  18681. + di_read_lock_parent(root, !AuLock_IR);
  18682. + br = au_sbr(sb, bindex);
  18683. + path.mnt = br->br_mnt;
  18684. + path.dentry = au_h_dptr(root, bindex);
  18685. + au_seq_path(seq, &path);
  18686. + di_read_unlock(root, !AuLock_IR);
  18687. + seq_printf(seq, "=%s\n", au_optstr_br_perm(br->br_perm));
  18688. + return 0;
  18689. +}
  18690. +
  18691. +/* ---------------------------------------------------------------------- */
  18692. +
  18693. +static struct seq_file *au_seq(char *p, ssize_t len)
  18694. +{
  18695. + struct seq_file *seq;
  18696. +
  18697. + seq = kzalloc(sizeof(*seq), GFP_NOFS);
  18698. + if (seq) {
  18699. + /* mutex_init(&seq.lock); */
  18700. + seq->buf = p;
  18701. + seq->size = len;
  18702. + return seq; /* success */
  18703. + }
  18704. +
  18705. + seq = ERR_PTR(-ENOMEM);
  18706. + return seq;
  18707. +}
  18708. +
  18709. +#define SysaufsBr_PREFIX "br"
  18710. +
  18711. +/* todo: file size may exceed PAGE_SIZE */
  18712. +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
  18713. + char *buf)
  18714. +{
  18715. + ssize_t err;
  18716. + long l;
  18717. + aufs_bindex_t bend;
  18718. + struct au_sbinfo *sbinfo;
  18719. + struct super_block *sb;
  18720. + struct seq_file *seq;
  18721. + char *name;
  18722. + struct attribute **cattr;
  18723. +
  18724. + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
  18725. + sb = sbinfo->si_sb;
  18726. + si_noflush_read_lock(sb);
  18727. +
  18728. + seq = au_seq(buf, PAGE_SIZE);
  18729. + err = PTR_ERR(seq);
  18730. + if (IS_ERR(seq))
  18731. + goto out;
  18732. +
  18733. + name = (void *)attr->name;
  18734. + cattr = sysaufs_si_attrs;
  18735. + while (*cattr) {
  18736. + if (!strcmp(name, (*cattr)->name)) {
  18737. + err = container_of(*cattr, struct sysaufs_si_attr, attr)
  18738. + ->show(seq, sb);
  18739. + goto out_seq;
  18740. + }
  18741. + cattr++;
  18742. + }
  18743. +
  18744. + bend = au_sbend(sb);
  18745. + if (!strncmp(name, SysaufsBr_PREFIX, sizeof(SysaufsBr_PREFIX) - 1)) {
  18746. + name += sizeof(SysaufsBr_PREFIX) - 1;
  18747. + err = strict_strtol(name, 10, &l);
  18748. + if (!err) {
  18749. + if (l <= bend)
  18750. + err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l);
  18751. + else
  18752. + err = -ENOENT;
  18753. + }
  18754. + goto out_seq;
  18755. + }
  18756. + BUG();
  18757. +
  18758. + out_seq:
  18759. + if (!err) {
  18760. + err = seq->count;
  18761. + /* sysfs limit */
  18762. + if (unlikely(err == PAGE_SIZE))
  18763. + err = -EFBIG;
  18764. + }
  18765. + kfree(seq);
  18766. + out:
  18767. + si_read_unlock(sb);
  18768. + return err;
  18769. +}
  18770. +
  18771. +/* ---------------------------------------------------------------------- */
  18772. +
  18773. +void sysaufs_br_init(struct au_branch *br)
  18774. +{
  18775. + br->br_attr.name = br->br_name;
  18776. + br->br_attr.mode = S_IRUGO;
  18777. + br->br_attr.owner = THIS_MODULE;
  18778. +}
  18779. +
  18780. +void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
  18781. +{
  18782. + struct au_branch *br;
  18783. + struct kobject *kobj;
  18784. + aufs_bindex_t bend;
  18785. +
  18786. + dbgaufs_brs_del(sb, bindex);
  18787. +
  18788. + if (!sysaufs_brs)
  18789. + return;
  18790. +
  18791. + kobj = &au_sbi(sb)->si_kobj;
  18792. + bend = au_sbend(sb);
  18793. + for (; bindex <= bend; bindex++) {
  18794. + br = au_sbr(sb, bindex);
  18795. + sysfs_remove_file(kobj, &br->br_attr);
  18796. + }
  18797. +}
  18798. +
  18799. +void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
  18800. +{
  18801. + int err;
  18802. + aufs_bindex_t bend;
  18803. + struct kobject *kobj;
  18804. + struct au_branch *br;
  18805. +
  18806. + dbgaufs_brs_add(sb, bindex);
  18807. +
  18808. + if (!sysaufs_brs)
  18809. + return;
  18810. +
  18811. + kobj = &au_sbi(sb)->si_kobj;
  18812. + bend = au_sbend(sb);
  18813. + for (; bindex <= bend; bindex++) {
  18814. + br = au_sbr(sb, bindex);
  18815. + snprintf(br->br_name, sizeof(br->br_name), SysaufsBr_PREFIX
  18816. + "%d", bindex);
  18817. + err = sysfs_create_file(kobj, &br->br_attr);
  18818. + if (unlikely(err))
  18819. + AuWarn("failed %s under sysfs(%d)\n", br->br_name, err);
  18820. + }
  18821. +}
  18822. diff -Nur linux-2.6.31.5.orig/fs/aufs/sysrq.c linux-2.6.31.5/fs/aufs/sysrq.c
  18823. --- linux-2.6.31.5.orig/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100
  18824. +++ linux-2.6.31.5/fs/aufs/sysrq.c 2009-11-15 22:02:37.000000000 +0100
  18825. @@ -0,0 +1,115 @@
  18826. +/*
  18827. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  18828. + *
  18829. + * This program, aufs is free software; you can redistribute it and/or modify
  18830. + * it under the terms of the GNU General Public License as published by
  18831. + * the Free Software Foundation; either version 2 of the License, or
  18832. + * (at your option) any later version.
  18833. + *
  18834. + * This program is distributed in the hope that it will be useful,
  18835. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18836. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18837. + * GNU General Public License for more details.
  18838. + *
  18839. + * You should have received a copy of the GNU General Public License
  18840. + * along with this program; if not, write to the Free Software
  18841. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18842. + */
  18843. +
  18844. +/*
  18845. + * magic sysrq hanlder
  18846. + */
  18847. +
  18848. +#include <linux/fs.h>
  18849. +#include <linux/module.h>
  18850. +#include <linux/moduleparam.h>
  18851. +/* #include <linux/sysrq.h> */
  18852. +#include "aufs.h"
  18853. +
  18854. +/* ---------------------------------------------------------------------- */
  18855. +
  18856. +static void sysrq_sb(struct super_block *sb)
  18857. +{
  18858. + char *plevel;
  18859. + struct au_sbinfo *sbinfo;
  18860. + struct file *file;
  18861. +
  18862. + plevel = au_plevel;
  18863. + au_plevel = KERN_WARNING;
  18864. + au_debug(1);
  18865. +
  18866. + sbinfo = au_sbi(sb);
  18867. + pr_warning("si=%lx\n", sysaufs_si_id(sbinfo));
  18868. + pr_warning(AUFS_NAME ": superblock\n");
  18869. + au_dpri_sb(sb);
  18870. + pr_warning(AUFS_NAME ": root dentry\n");
  18871. + au_dpri_dentry(sb->s_root);
  18872. + pr_warning(AUFS_NAME ": root inode\n");
  18873. + au_dpri_inode(sb->s_root->d_inode);
  18874. +#if 0
  18875. + struct inode *i;
  18876. + pr_warning(AUFS_NAME ": isolated inode\n");
  18877. + list_for_each_entry(i, &sb->s_inodes, i_sb_list)
  18878. + if (list_empty(&i->i_dentry))
  18879. + au_dpri_inode(i);
  18880. +#endif
  18881. + pr_warning(AUFS_NAME ": files\n");
  18882. + list_for_each_entry(file, &sb->s_files, f_u.fu_list)
  18883. + if (!special_file(file->f_dentry->d_inode->i_mode))
  18884. + au_dpri_file(file);
  18885. +
  18886. + au_plevel = plevel;
  18887. + au_debug(0);
  18888. +}
  18889. +
  18890. +/* ---------------------------------------------------------------------- */
  18891. +
  18892. +/* module parameter */
  18893. +static char *aufs_sysrq_key = "a";
  18894. +module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO);
  18895. +MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
  18896. +
  18897. +static void au_sysrq(int key __maybe_unused,
  18898. + struct tty_struct *tty __maybe_unused)
  18899. +{
  18900. + struct kobject *kobj;
  18901. + struct au_sbinfo *sbinfo;
  18902. +
  18903. + /* spin_lock(&sysaufs_ket->list_lock); */
  18904. + list_for_each_entry(kobj, &sysaufs_ket->list, entry) {
  18905. + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
  18906. + sysrq_sb(sbinfo->si_sb);
  18907. + }
  18908. + /* spin_unlock(&sysaufs_ket->list_lock); */
  18909. +}
  18910. +
  18911. +static struct sysrq_key_op au_sysrq_op = {
  18912. + .handler = au_sysrq,
  18913. + .help_msg = "Aufs",
  18914. + .action_msg = "Aufs",
  18915. + .enable_mask = SYSRQ_ENABLE_DUMP
  18916. +};
  18917. +
  18918. +/* ---------------------------------------------------------------------- */
  18919. +
  18920. +int __init au_sysrq_init(void)
  18921. +{
  18922. + int err;
  18923. + char key;
  18924. +
  18925. + err = -1;
  18926. + key = *aufs_sysrq_key;
  18927. + if ('a' <= key && key <= 'z')
  18928. + err = register_sysrq_key(key, &au_sysrq_op);
  18929. + if (unlikely(err))
  18930. + AuErr("err %d, sysrq=%c\n", err, key);
  18931. + return err;
  18932. +}
  18933. +
  18934. +void au_sysrq_fin(void)
  18935. +{
  18936. + int err;
  18937. + err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
  18938. + if (unlikely(err))
  18939. + AuErr("err %d (ignored)\n", err);
  18940. +}
  18941. diff -Nur linux-2.6.31.5.orig/fs/aufs/vdir.c linux-2.6.31.5/fs/aufs/vdir.c
  18942. --- linux-2.6.31.5.orig/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100
  18943. +++ linux-2.6.31.5/fs/aufs/vdir.c 2009-11-15 22:02:37.000000000 +0100
  18944. @@ -0,0 +1,882 @@
  18945. +/*
  18946. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  18947. + *
  18948. + * This program, aufs is free software; you can redistribute it and/or modify
  18949. + * it under the terms of the GNU General Public License as published by
  18950. + * the Free Software Foundation; either version 2 of the License, or
  18951. + * (at your option) any later version.
  18952. + *
  18953. + * This program is distributed in the hope that it will be useful,
  18954. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18955. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18956. + * GNU General Public License for more details.
  18957. + *
  18958. + * You should have received a copy of the GNU General Public License
  18959. + * along with this program; if not, write to the Free Software
  18960. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18961. + */
  18962. +
  18963. +/*
  18964. + * virtual or vertical directory
  18965. + */
  18966. +
  18967. +#include <linux/hash.h>
  18968. +#include "aufs.h"
  18969. +
  18970. +static unsigned int calc_size(int nlen)
  18971. +{
  18972. + BUILD_BUG_ON(sizeof(ino_t) != sizeof(long));
  18973. + return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
  18974. +}
  18975. +
  18976. +static int set_deblk_end(union au_vdir_deblk_p *p,
  18977. + union au_vdir_deblk_p *deblk_end)
  18978. +{
  18979. + if (calc_size(0) <= deblk_end->deblk - p->deblk) {
  18980. + p->de->de_str.len = 0;
  18981. + /* smp_mb(); */
  18982. + return 0;
  18983. + }
  18984. + return -1; /* error */
  18985. +}
  18986. +
  18987. +/* returns true or false */
  18988. +static int is_deblk_end(union au_vdir_deblk_p *p,
  18989. + union au_vdir_deblk_p *deblk_end)
  18990. +{
  18991. + if (calc_size(0) <= deblk_end->deblk - p->deblk)
  18992. + return !p->de->de_str.len;
  18993. + return 1;
  18994. +}
  18995. +
  18996. +static unsigned char *last_deblk(struct au_vdir *vdir)
  18997. +{
  18998. + return vdir->vd_deblk[vdir->vd_nblk - 1];
  18999. +}
  19000. +
  19001. +/* ---------------------------------------------------------------------- */
  19002. +
  19003. +/*
  19004. + * the allocated memory has to be freed by
  19005. + * au_nhash_wh_free() or au_nhash_de_free().
  19006. + */
  19007. +int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
  19008. +{
  19009. + struct hlist_head *head;
  19010. + unsigned int u;
  19011. +
  19012. + head = kmalloc(sizeof(*nhash->nh_head) * num_hash, gfp);
  19013. + if (head) {
  19014. + nhash->nh_num = num_hash;
  19015. + nhash->nh_head = head;
  19016. + for (u = 0; u < num_hash; u++)
  19017. + INIT_HLIST_HEAD(head++);
  19018. + return 0; /* success */
  19019. + }
  19020. +
  19021. + return -ENOMEM;
  19022. +}
  19023. +
  19024. +static void nhash_count(struct hlist_head *head)
  19025. +{
  19026. +#if 0
  19027. + unsigned long n;
  19028. + struct hlist_node *pos;
  19029. +
  19030. + n = 0;
  19031. + hlist_for_each(pos, head)
  19032. + n++;
  19033. + AuInfo("%lu\n", n);
  19034. +#endif
  19035. +}
  19036. +
  19037. +static void au_nhash_wh_do_free(struct hlist_head *head)
  19038. +{
  19039. + struct au_vdir_wh *tpos;
  19040. + struct hlist_node *pos, *node;
  19041. +
  19042. + hlist_for_each_entry_safe(tpos, pos, node, head, wh_hash) {
  19043. + /* hlist_del(pos); */
  19044. + kfree(tpos);
  19045. + }
  19046. +}
  19047. +
  19048. +static void au_nhash_de_do_free(struct hlist_head *head)
  19049. +{
  19050. + struct au_vdir_dehstr *tpos;
  19051. + struct hlist_node *pos, *node;
  19052. +
  19053. + hlist_for_each_entry_safe(tpos, pos, node, head, hash) {
  19054. + /* hlist_del(pos); */
  19055. + au_cache_free_dehstr(tpos);
  19056. + }
  19057. +}
  19058. +
  19059. +static void au_nhash_do_free(struct au_nhash *nhash,
  19060. + void (*free)(struct hlist_head *head))
  19061. +{
  19062. + unsigned int u, n;
  19063. + struct hlist_head *head;
  19064. +
  19065. + n = nhash->nh_num;
  19066. + head = nhash->nh_head;
  19067. + for (u = 0; u < n; u++) {
  19068. + nhash_count(head);
  19069. + free(head++);
  19070. + }
  19071. + kfree(nhash->nh_head);
  19072. +}
  19073. +
  19074. +void au_nhash_wh_free(struct au_nhash *whlist)
  19075. +{
  19076. + au_nhash_do_free(whlist, au_nhash_wh_do_free);
  19077. +}
  19078. +
  19079. +static void au_nhash_de_free(struct au_nhash *delist)
  19080. +{
  19081. + au_nhash_do_free(delist, au_nhash_de_do_free);
  19082. +}
  19083. +
  19084. +/* ---------------------------------------------------------------------- */
  19085. +
  19086. +int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
  19087. + int limit)
  19088. +{
  19089. + int num;
  19090. + unsigned int u, n;
  19091. + struct hlist_head *head;
  19092. + struct au_vdir_wh *tpos;
  19093. + struct hlist_node *pos;
  19094. +
  19095. + num = 0;
  19096. + n = whlist->nh_num;
  19097. + head = whlist->nh_head;
  19098. + for (u = 0; u < n; u++) {
  19099. + hlist_for_each_entry(tpos, pos, head, wh_hash)
  19100. + if (tpos->wh_bindex == btgt && ++num > limit)
  19101. + return 1;
  19102. + head++;
  19103. + }
  19104. + return 0;
  19105. +}
  19106. +
  19107. +static struct hlist_head *au_name_hash(struct au_nhash *nhash,
  19108. + unsigned char *name,
  19109. + unsigned int len)
  19110. +{
  19111. + unsigned int v;
  19112. + /* const unsigned int magic_bit = 12; */
  19113. +
  19114. + v = 0;
  19115. + while (len--)
  19116. + v += *name++;
  19117. + /* v = hash_long(v, magic_bit); */
  19118. + v %= nhash->nh_num;
  19119. + return nhash->nh_head + v;
  19120. +}
  19121. +
  19122. +static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
  19123. + int nlen)
  19124. +{
  19125. + return str->len == nlen && !memcmp(str->name, name, nlen);
  19126. +}
  19127. +
  19128. +/* returns found or not */
  19129. +int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
  19130. +{
  19131. + struct hlist_head *head;
  19132. + struct au_vdir_wh *tpos;
  19133. + struct hlist_node *pos;
  19134. + struct au_vdir_destr *str;
  19135. +
  19136. + head = au_name_hash(whlist, name, nlen);
  19137. + hlist_for_each_entry(tpos, pos, head, wh_hash) {
  19138. + str = &tpos->wh_str;
  19139. + AuDbg("%.*s\n", str->len, str->name);
  19140. + if (au_nhash_test_name(str, name, nlen))
  19141. + return 1;
  19142. + }
  19143. + return 0;
  19144. +}
  19145. +
  19146. +/* returns found(true) or not */
  19147. +static int test_known(struct au_nhash *delist, char *name, int nlen)
  19148. +{
  19149. + struct hlist_head *head;
  19150. + struct au_vdir_dehstr *tpos;
  19151. + struct hlist_node *pos;
  19152. + struct au_vdir_destr *str;
  19153. +
  19154. + head = au_name_hash(delist, name, nlen);
  19155. + hlist_for_each_entry(tpos, pos, head, hash) {
  19156. + str = tpos->str;
  19157. + AuDbg("%.*s\n", str->len, str->name);
  19158. + if (au_nhash_test_name(str, name, nlen))
  19159. + return 1;
  19160. + }
  19161. + return 0;
  19162. +}
  19163. +
  19164. +static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
  19165. + unsigned char d_type)
  19166. +{
  19167. +#ifdef CONFIG_AUFS_SHWH
  19168. + wh->wh_ino = ino;
  19169. + wh->wh_type = d_type;
  19170. +#endif
  19171. +}
  19172. +
  19173. +/* ---------------------------------------------------------------------- */
  19174. +
  19175. +int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
  19176. + unsigned int d_type, aufs_bindex_t bindex,
  19177. + unsigned char shwh)
  19178. +{
  19179. + int err;
  19180. + struct au_vdir_destr *str;
  19181. + struct au_vdir_wh *wh;
  19182. +
  19183. + AuDbg("%.*s\n", nlen, name);
  19184. + err = -ENOMEM;
  19185. + wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
  19186. + if (unlikely(!wh))
  19187. + goto out;
  19188. +
  19189. + err = 0;
  19190. + wh->wh_bindex = bindex;
  19191. + if (shwh)
  19192. + au_shwh_init_wh(wh, ino, d_type);
  19193. + str = &wh->wh_str;
  19194. + str->len = nlen;
  19195. + memcpy(str->name, name, nlen);
  19196. + hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
  19197. + /* smp_mb(); */
  19198. +
  19199. + out:
  19200. + return err;
  19201. +}
  19202. +
  19203. +static int append_deblk(struct au_vdir *vdir)
  19204. +{
  19205. + int err;
  19206. + unsigned long ul;
  19207. + const unsigned int deblk_sz = vdir->vd_deblk_sz;
  19208. + union au_vdir_deblk_p p, deblk_end;
  19209. + unsigned char **o;
  19210. +
  19211. + err = -ENOMEM;
  19212. + o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
  19213. + GFP_NOFS);
  19214. + if (unlikely(!o))
  19215. + goto out;
  19216. +
  19217. + vdir->vd_deblk = o;
  19218. + p.deblk = kmalloc(deblk_sz, GFP_NOFS);
  19219. + if (p.deblk) {
  19220. + ul = vdir->vd_nblk++;
  19221. + vdir->vd_deblk[ul] = p.deblk;
  19222. + vdir->vd_last.ul = ul;
  19223. + vdir->vd_last.p.deblk = p.deblk;
  19224. + deblk_end.deblk = p.deblk + deblk_sz;
  19225. + err = set_deblk_end(&p, &deblk_end);
  19226. + }
  19227. +
  19228. + out:
  19229. + return err;
  19230. +}
  19231. +
  19232. +static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
  19233. + unsigned int d_type, struct au_nhash *delist)
  19234. +{
  19235. + int err;
  19236. + unsigned int sz;
  19237. + const unsigned int deblk_sz = vdir->vd_deblk_sz;
  19238. + union au_vdir_deblk_p p, *room, deblk_end;
  19239. + struct au_vdir_dehstr *dehstr;
  19240. +
  19241. + p.deblk = last_deblk(vdir);
  19242. + deblk_end.deblk = p.deblk + deblk_sz;
  19243. + room = &vdir->vd_last.p;
  19244. + AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
  19245. + || !is_deblk_end(room, &deblk_end));
  19246. +
  19247. + sz = calc_size(nlen);
  19248. + if (unlikely(sz > deblk_end.deblk - room->deblk)) {
  19249. + err = append_deblk(vdir);
  19250. + if (unlikely(err))
  19251. + goto out;
  19252. +
  19253. + p.deblk = last_deblk(vdir);
  19254. + deblk_end.deblk = p.deblk + deblk_sz;
  19255. + /* smp_mb(); */
  19256. + AuDebugOn(room->deblk != p.deblk);
  19257. + }
  19258. +
  19259. + err = -ENOMEM;
  19260. + dehstr = au_cache_alloc_dehstr();
  19261. + if (unlikely(!dehstr))
  19262. + goto out;
  19263. +
  19264. + dehstr->str = &room->de->de_str;
  19265. + hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
  19266. + room->de->de_ino = ino;
  19267. + room->de->de_type = d_type;
  19268. + room->de->de_str.len = nlen;
  19269. + memcpy(room->de->de_str.name, name, nlen);
  19270. +
  19271. + err = 0;
  19272. + room->deblk += sz;
  19273. + if (unlikely(set_deblk_end(room, &deblk_end)))
  19274. + err = append_deblk(vdir);
  19275. + /* smp_mb(); */
  19276. +
  19277. + out:
  19278. + return err;
  19279. +}
  19280. +
  19281. +/* ---------------------------------------------------------------------- */
  19282. +
  19283. +void au_vdir_free(struct au_vdir *vdir)
  19284. +{
  19285. + unsigned char **deblk;
  19286. +
  19287. + deblk = vdir->vd_deblk;
  19288. + while (vdir->vd_nblk--)
  19289. + kfree(*deblk++);
  19290. + kfree(vdir->vd_deblk);
  19291. + au_cache_free_vdir(vdir);
  19292. +}
  19293. +
  19294. +static struct au_vdir *alloc_vdir(struct super_block *sb)
  19295. +{
  19296. + struct au_vdir *vdir;
  19297. + int err;
  19298. +
  19299. + SiMustAnyLock(sb);
  19300. +
  19301. + err = -ENOMEM;
  19302. + vdir = au_cache_alloc_vdir();
  19303. + if (unlikely(!vdir))
  19304. + goto out;
  19305. +
  19306. + vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
  19307. + if (unlikely(!vdir->vd_deblk))
  19308. + goto out_free;
  19309. +
  19310. + vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
  19311. + vdir->vd_nblk = 0;
  19312. + vdir->vd_version = 0;
  19313. + vdir->vd_jiffy = 0;
  19314. + err = append_deblk(vdir);
  19315. + if (!err)
  19316. + return vdir; /* success */
  19317. +
  19318. + kfree(vdir->vd_deblk);
  19319. +
  19320. + out_free:
  19321. + au_cache_free_vdir(vdir);
  19322. + out:
  19323. + vdir = ERR_PTR(err);
  19324. + return vdir;
  19325. +}
  19326. +
  19327. +static int reinit_vdir(struct au_vdir *vdir)
  19328. +{
  19329. + int err;
  19330. + union au_vdir_deblk_p p, deblk_end;
  19331. +
  19332. + while (vdir->vd_nblk > 1) {
  19333. + kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
  19334. + /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
  19335. + vdir->vd_nblk--;
  19336. + }
  19337. + p.deblk = vdir->vd_deblk[0];
  19338. + deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
  19339. + err = set_deblk_end(&p, &deblk_end);
  19340. + /* keep vd_dblk_sz */
  19341. + vdir->vd_last.ul = 0;
  19342. + vdir->vd_last.p.deblk = vdir->vd_deblk[0];
  19343. + vdir->vd_version = 0;
  19344. + vdir->vd_jiffy = 0;
  19345. + /* smp_mb(); */
  19346. + return err;
  19347. +}
  19348. +
  19349. +/* ---------------------------------------------------------------------- */
  19350. +
  19351. +static int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  19352. + unsigned int d_type, ino_t *ino)
  19353. +{
  19354. + int err;
  19355. + struct mutex *mtx;
  19356. + const int isdir = (d_type == DT_DIR);
  19357. +
  19358. + /* prevent hardlinks from race condition */
  19359. + mtx = NULL;
  19360. + if (!isdir) {
  19361. + mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx;
  19362. + mutex_lock(mtx);
  19363. + }
  19364. + err = au_xino_read(sb, bindex, h_ino, ino);
  19365. + if (unlikely(err))
  19366. + goto out;
  19367. +
  19368. + if (!*ino) {
  19369. + err = -EIO;
  19370. + *ino = au_xino_new_ino(sb);
  19371. + if (unlikely(!*ino))
  19372. + goto out;
  19373. + err = au_xino_write(sb, bindex, h_ino, *ino);
  19374. + if (unlikely(err))
  19375. + goto out;
  19376. + }
  19377. +
  19378. + out:
  19379. + if (!isdir)
  19380. + mutex_unlock(mtx);
  19381. + return err;
  19382. +}
  19383. +
  19384. +static int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  19385. + unsigned int d_type, ino_t *ino)
  19386. +{
  19387. +#ifdef CONFIG_AUFS_SHWH
  19388. + return au_ino(sb, bindex, h_ino, d_type, ino);
  19389. +#else
  19390. + return 0;
  19391. +#endif
  19392. +}
  19393. +
  19394. +#define AuFillVdir_CALLED 1
  19395. +#define AuFillVdir_WHABLE (1 << 1)
  19396. +#define AuFillVdir_SHWH (1 << 2)
  19397. +#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
  19398. +#define au_fset_fillvdir(flags, name) { (flags) |= AuFillVdir_##name; }
  19399. +#define au_fclr_fillvdir(flags, name) { (flags) &= ~AuFillVdir_##name; }
  19400. +
  19401. +#ifndef CONFIG_AUFS_SHWH
  19402. +#undef AuFillVdir_SHWH
  19403. +#define AuFillVdir_SHWH 0
  19404. +#endif
  19405. +
  19406. +struct fillvdir_arg {
  19407. + struct file *file;
  19408. + struct au_vdir *vdir;
  19409. + struct au_nhash delist;
  19410. + struct au_nhash whlist;
  19411. + aufs_bindex_t bindex;
  19412. + unsigned int flags;
  19413. + int err;
  19414. +};
  19415. +
  19416. +static int fillvdir(void *__arg, const char *__name, int nlen,
  19417. + loff_t offset __maybe_unused, u64 h_ino,
  19418. + unsigned int d_type)
  19419. +{
  19420. + struct fillvdir_arg *arg = __arg;
  19421. + char *name = (void *)__name;
  19422. + struct super_block *sb;
  19423. + ino_t ino;
  19424. + const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
  19425. +
  19426. + arg->err = 0;
  19427. + sb = arg->file->f_dentry->d_sb;
  19428. + au_fset_fillvdir(arg->flags, CALLED);
  19429. + /* smp_mb(); */
  19430. + if (nlen <= AUFS_WH_PFX_LEN
  19431. + || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
  19432. + if (test_known(&arg->delist, name, nlen)
  19433. + || au_nhash_test_known_wh(&arg->whlist, name, nlen))
  19434. + goto out; /* already exists or whiteouted */
  19435. +
  19436. + sb = arg->file->f_dentry->d_sb;
  19437. + arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
  19438. + if (!arg->err)
  19439. + arg->err = append_de(arg->vdir, name, nlen, ino,
  19440. + d_type, &arg->delist);
  19441. + } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
  19442. + name += AUFS_WH_PFX_LEN;
  19443. + nlen -= AUFS_WH_PFX_LEN;
  19444. + if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
  19445. + goto out; /* already whiteouted */
  19446. +
  19447. + if (shwh)
  19448. + arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
  19449. + &ino);
  19450. + if (!arg->err)
  19451. + arg->err = au_nhash_append_wh
  19452. + (&arg->whlist, name, nlen, ino, d_type,
  19453. + arg->bindex, shwh);
  19454. + }
  19455. +
  19456. + out:
  19457. + if (!arg->err)
  19458. + arg->vdir->vd_jiffy = jiffies;
  19459. + /* smp_mb(); */
  19460. + AuTraceErr(arg->err);
  19461. + return arg->err;
  19462. +}
  19463. +
  19464. +static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
  19465. + struct au_nhash *whlist, struct au_nhash *delist)
  19466. +{
  19467. +#ifdef CONFIG_AUFS_SHWH
  19468. + int err;
  19469. + unsigned int nh, u;
  19470. + struct hlist_head *head;
  19471. + struct au_vdir_wh *tpos;
  19472. + struct hlist_node *pos, *n;
  19473. + char *p, *o;
  19474. + struct au_vdir_destr *destr;
  19475. +
  19476. + AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
  19477. +
  19478. + err = -ENOMEM;
  19479. + o = p = __getname();
  19480. + if (unlikely(!p))
  19481. + goto out;
  19482. +
  19483. + err = 0;
  19484. + nh = whlist->nh_num;
  19485. + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
  19486. + p += AUFS_WH_PFX_LEN;
  19487. + for (u = 0; u < nh; u++) {
  19488. + head = whlist->nh_head + u;
  19489. + hlist_for_each_entry_safe(tpos, pos, n, head, wh_hash) {
  19490. + destr = &tpos->wh_str;
  19491. + memcpy(p, destr->name, destr->len);
  19492. + err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
  19493. + tpos->wh_ino, tpos->wh_type, delist);
  19494. + if (unlikely(err))
  19495. + break;
  19496. + }
  19497. + }
  19498. +
  19499. + __putname(o);
  19500. +
  19501. + out:
  19502. + AuTraceErr(err);
  19503. + return err;
  19504. +#else
  19505. + return 0;
  19506. +#endif
  19507. +}
  19508. +
  19509. +static int au_do_read_vdir(struct fillvdir_arg *arg)
  19510. +{
  19511. + int err;
  19512. + unsigned int rdhash;
  19513. + loff_t offset;
  19514. + aufs_bindex_t bend, bindex, bstart;
  19515. + unsigned char shwh;
  19516. + struct file *hf, *file;
  19517. + struct super_block *sb;
  19518. +
  19519. + file = arg->file;
  19520. + sb = file->f_dentry->d_sb;
  19521. + SiMustAnyLock(sb);
  19522. +
  19523. + rdhash = au_sbi(sb)->si_rdhash;
  19524. + err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
  19525. + if (unlikely(err))
  19526. + goto out;
  19527. + err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
  19528. + if (unlikely(err))
  19529. + goto out_delist;
  19530. +
  19531. + err = 0;
  19532. + arg->flags = 0;
  19533. + shwh = 0;
  19534. + if (au_opt_test(au_mntflags(sb), SHWH)) {
  19535. + shwh = 1;
  19536. + au_fset_fillvdir(arg->flags, SHWH);
  19537. + }
  19538. + bstart = au_fbstart(file);
  19539. + bend = au_fbend(file);
  19540. + for (bindex = bstart; !err && bindex <= bend; bindex++) {
  19541. + hf = au_h_fptr(file, bindex);
  19542. + if (!hf)
  19543. + continue;
  19544. +
  19545. + offset = vfsub_llseek(hf, 0, SEEK_SET);
  19546. + err = offset;
  19547. + if (unlikely(offset))
  19548. + break;
  19549. +
  19550. + arg->bindex = bindex;
  19551. + au_fclr_fillvdir(arg->flags, WHABLE);
  19552. + if (shwh
  19553. + || (bindex != bend
  19554. + && au_br_whable(au_sbr_perm(sb, bindex))))
  19555. + au_fset_fillvdir(arg->flags, WHABLE);
  19556. + do {
  19557. + arg->err = 0;
  19558. + au_fclr_fillvdir(arg->flags, CALLED);
  19559. + /* smp_mb(); */
  19560. + err = vfsub_readdir(hf, fillvdir, arg);
  19561. + if (err >= 0)
  19562. + err = arg->err;
  19563. + } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
  19564. + }
  19565. +
  19566. + if (!err && shwh)
  19567. + err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
  19568. +
  19569. + au_nhash_wh_free(&arg->whlist);
  19570. +
  19571. + out_delist:
  19572. + au_nhash_de_free(&arg->delist);
  19573. + out:
  19574. + return err;
  19575. +}
  19576. +
  19577. +static int read_vdir(struct file *file, int may_read)
  19578. +{
  19579. + int err;
  19580. + unsigned long expire;
  19581. + unsigned char do_read;
  19582. + struct fillvdir_arg arg;
  19583. + struct inode *inode;
  19584. + struct au_vdir *vdir, *allocated;
  19585. +
  19586. + err = 0;
  19587. + inode = file->f_dentry->d_inode;
  19588. + IMustLock(inode);
  19589. + SiMustAnyLock(inode->i_sb);
  19590. +
  19591. + allocated = NULL;
  19592. + do_read = 0;
  19593. + expire = au_sbi(inode->i_sb)->si_rdcache;
  19594. + vdir = au_ivdir(inode);
  19595. + if (!vdir) {
  19596. + do_read = 1;
  19597. + vdir = alloc_vdir(inode->i_sb);
  19598. + err = PTR_ERR(vdir);
  19599. + if (IS_ERR(vdir))
  19600. + goto out;
  19601. + err = 0;
  19602. + allocated = vdir;
  19603. + } else if (may_read
  19604. + && (inode->i_version != vdir->vd_version
  19605. + || time_after(jiffies, vdir->vd_jiffy + expire))) {
  19606. + do_read = 1;
  19607. + err = reinit_vdir(vdir);
  19608. + if (unlikely(err))
  19609. + goto out;
  19610. + }
  19611. +
  19612. + if (!do_read)
  19613. + return 0; /* success */
  19614. +
  19615. + arg.file = file;
  19616. + arg.vdir = vdir;
  19617. + err = au_do_read_vdir(&arg);
  19618. + if (!err) {
  19619. + /* file->f_pos = 0; */
  19620. + vdir->vd_version = inode->i_version;
  19621. + vdir->vd_last.ul = 0;
  19622. + vdir->vd_last.p.deblk = vdir->vd_deblk[0];
  19623. + if (allocated)
  19624. + au_set_ivdir(inode, allocated);
  19625. + } else if (allocated)
  19626. + au_vdir_free(allocated);
  19627. +
  19628. + out:
  19629. + return err;
  19630. +}
  19631. +
  19632. +static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
  19633. +{
  19634. + int err, rerr;
  19635. + unsigned long ul, n;
  19636. + const unsigned int deblk_sz = src->vd_deblk_sz;
  19637. +
  19638. + AuDebugOn(tgt->vd_nblk != 1);
  19639. +
  19640. + err = -ENOMEM;
  19641. + if (tgt->vd_nblk < src->vd_nblk) {
  19642. + unsigned char **p;
  19643. +
  19644. + p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
  19645. + GFP_NOFS);
  19646. + if (unlikely(!p))
  19647. + goto out;
  19648. + tgt->vd_deblk = p;
  19649. + }
  19650. +
  19651. + tgt->vd_nblk = src->vd_nblk;
  19652. + tgt->vd_deblk_sz = deblk_sz;
  19653. + memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
  19654. + /* tgt->vd_last.i = 0; */
  19655. + /* tgt->vd_last.p.deblk = tgt->vd_deblk[0]; */
  19656. + tgt->vd_version = src->vd_version;
  19657. + tgt->vd_jiffy = src->vd_jiffy;
  19658. +
  19659. + n = src->vd_nblk;
  19660. + for (ul = 1; ul < n; ul++) {
  19661. + tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
  19662. + GFP_NOFS);
  19663. + if (unlikely(!tgt->vd_deblk[ul]))
  19664. + goto out;
  19665. + }
  19666. + /* smp_mb(); */
  19667. + return 0; /* success */
  19668. +
  19669. + out:
  19670. + rerr = reinit_vdir(tgt);
  19671. + BUG_ON(rerr);
  19672. + return err;
  19673. +}
  19674. +
  19675. +int au_vdir_init(struct file *file)
  19676. +{
  19677. + int err;
  19678. + struct inode *inode;
  19679. + struct au_vdir *vdir_cache, *allocated;
  19680. +
  19681. + err = read_vdir(file, !file->f_pos);
  19682. + if (unlikely(err))
  19683. + goto out;
  19684. +
  19685. + allocated = NULL;
  19686. + vdir_cache = au_fvdir_cache(file);
  19687. + if (!vdir_cache) {
  19688. + vdir_cache = alloc_vdir(file->f_dentry->d_sb);
  19689. + err = PTR_ERR(vdir_cache);
  19690. + if (IS_ERR(vdir_cache))
  19691. + goto out;
  19692. + allocated = vdir_cache;
  19693. + } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
  19694. + err = reinit_vdir(vdir_cache);
  19695. + if (unlikely(err))
  19696. + goto out;
  19697. + } else
  19698. + return 0; /* success */
  19699. +
  19700. + inode = file->f_dentry->d_inode;
  19701. + err = copy_vdir(vdir_cache, au_ivdir(inode));
  19702. + if (!err) {
  19703. + file->f_version = inode->i_version;
  19704. + if (allocated)
  19705. + au_set_fvdir_cache(file, allocated);
  19706. + } else if (allocated)
  19707. + au_vdir_free(allocated);
  19708. +
  19709. + out:
  19710. + return err;
  19711. +}
  19712. +
  19713. +static loff_t calc_offset(struct au_vdir *vdir)
  19714. +{
  19715. + loff_t offset;
  19716. + union au_vdir_deblk_p p;
  19717. +
  19718. + p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
  19719. + offset = vdir->vd_last.p.deblk - p.deblk;
  19720. + offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
  19721. + return offset;
  19722. +}
  19723. +
  19724. +/* returns true or false */
  19725. +static int seek_vdir(struct file *file)
  19726. +{
  19727. + int valid;
  19728. + unsigned int deblk_sz;
  19729. + unsigned long ul, n;
  19730. + loff_t offset;
  19731. + union au_vdir_deblk_p p, deblk_end;
  19732. + struct au_vdir *vdir_cache;
  19733. +
  19734. + valid = 1;
  19735. + vdir_cache = au_fvdir_cache(file);
  19736. + offset = calc_offset(vdir_cache);
  19737. + AuDbg("offset %lld\n", offset);
  19738. + if (file->f_pos == offset)
  19739. + goto out;
  19740. +
  19741. + vdir_cache->vd_last.ul = 0;
  19742. + vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
  19743. + if (!file->f_pos)
  19744. + goto out;
  19745. +
  19746. + valid = 0;
  19747. + deblk_sz = vdir_cache->vd_deblk_sz;
  19748. + ul = div64_u64(file->f_pos, deblk_sz);
  19749. + AuDbg("ul %lu\n", ul);
  19750. + if (ul >= vdir_cache->vd_nblk)
  19751. + goto out;
  19752. +
  19753. + n = vdir_cache->vd_nblk;
  19754. + for (; ul < n; ul++) {
  19755. + p.deblk = vdir_cache->vd_deblk[ul];
  19756. + deblk_end.deblk = p.deblk + deblk_sz;
  19757. + offset = ul;
  19758. + offset *= deblk_sz;
  19759. + while (!is_deblk_end(&p, &deblk_end) && offset < file->f_pos) {
  19760. + unsigned int l;
  19761. +
  19762. + l = calc_size(p.de->de_str.len);
  19763. + offset += l;
  19764. + p.deblk += l;
  19765. + }
  19766. + if (!is_deblk_end(&p, &deblk_end)) {
  19767. + valid = 1;
  19768. + vdir_cache->vd_last.ul = ul;
  19769. + vdir_cache->vd_last.p = p;
  19770. + break;
  19771. + }
  19772. + }
  19773. +
  19774. + out:
  19775. + /* smp_mb(); */
  19776. + AuTraceErr(!valid);
  19777. + return valid;
  19778. +}
  19779. +
  19780. +int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir)
  19781. +{
  19782. + int err;
  19783. + unsigned int l, deblk_sz;
  19784. + union au_vdir_deblk_p deblk_end;
  19785. + struct au_vdir *vdir_cache;
  19786. + struct au_vdir_de *de;
  19787. +
  19788. + vdir_cache = au_fvdir_cache(file);
  19789. + if (!seek_vdir(file))
  19790. + return 0;
  19791. +
  19792. + deblk_sz = vdir_cache->vd_deblk_sz;
  19793. + while (1) {
  19794. + deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
  19795. + deblk_end.deblk += deblk_sz;
  19796. + while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
  19797. + de = vdir_cache->vd_last.p.de;
  19798. + AuDbg("%.*s, off%lld, i%lu, dt%d\n",
  19799. + de->de_str.len, de->de_str.name, file->f_pos,
  19800. + (unsigned long)de->de_ino, de->de_type);
  19801. + err = filldir(dirent, de->de_str.name, de->de_str.len,
  19802. + file->f_pos, de->de_ino, de->de_type);
  19803. + if (unlikely(err)) {
  19804. + AuTraceErr(err);
  19805. + /* todo: ignore the error caused by udba? */
  19806. + /* return err; */
  19807. + return 0;
  19808. + }
  19809. +
  19810. + l = calc_size(de->de_str.len);
  19811. + vdir_cache->vd_last.p.deblk += l;
  19812. + file->f_pos += l;
  19813. + }
  19814. + if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
  19815. + vdir_cache->vd_last.ul++;
  19816. + vdir_cache->vd_last.p.deblk
  19817. + = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
  19818. + file->f_pos = deblk_sz * vdir_cache->vd_last.ul;
  19819. + continue;
  19820. + }
  19821. + break;
  19822. + }
  19823. +
  19824. + /* smp_mb(); */
  19825. + return 0;
  19826. +}
  19827. diff -Nur linux-2.6.31.5.orig/fs/aufs/vfsub.c linux-2.6.31.5/fs/aufs/vfsub.c
  19828. --- linux-2.6.31.5.orig/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100
  19829. +++ linux-2.6.31.5/fs/aufs/vfsub.c 2009-11-15 22:02:37.000000000 +0100
  19830. @@ -0,0 +1,740 @@
  19831. +/*
  19832. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  19833. + *
  19834. + * This program, aufs is free software; you can redistribute it and/or modify
  19835. + * it under the terms of the GNU General Public License as published by
  19836. + * the Free Software Foundation; either version 2 of the License, or
  19837. + * (at your option) any later version.
  19838. + *
  19839. + * This program is distributed in the hope that it will be useful,
  19840. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19841. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19842. + * GNU General Public License for more details.
  19843. + *
  19844. + * You should have received a copy of the GNU General Public License
  19845. + * along with this program; if not, write to the Free Software
  19846. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  19847. + */
  19848. +
  19849. +/*
  19850. + * sub-routines for VFS
  19851. + */
  19852. +
  19853. +#include <linux/namei.h>
  19854. +#include <linux/security.h>
  19855. +#include <linux/splice.h>
  19856. +#include <linux/uaccess.h>
  19857. +#include "aufs.h"
  19858. +
  19859. +int vfsub_update_h_iattr(struct path *h_path, int *did)
  19860. +{
  19861. + int err;
  19862. + struct kstat st;
  19863. + struct super_block *h_sb;
  19864. +
  19865. + /* for remote fs, leave work for its getattr or d_revalidate */
  19866. + /* for bad i_attr fs, handle them in aufs_getattr() */
  19867. + /* still some fs may acquire i_mutex. we need to skip them */
  19868. + err = 0;
  19869. + if (!did)
  19870. + did = &err;
  19871. + h_sb = h_path->dentry->d_sb;
  19872. + *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
  19873. + if (*did)
  19874. + err = vfs_getattr(h_path->mnt, h_path->dentry, &st);
  19875. +
  19876. + return err;
  19877. +}
  19878. +
  19879. +/* ---------------------------------------------------------------------- */
  19880. +
  19881. +#ifdef CONFIG_IMA
  19882. +#error IMA is not supported since it does not work well. Wait for their fixing.
  19883. +#endif
  19884. +
  19885. +struct file *vfsub_filp_open(const char *path, int oflags, int mode)
  19886. +{
  19887. + struct file *file;
  19888. +
  19889. + lockdep_off();
  19890. + file = filp_open(path, oflags, mode);
  19891. + lockdep_on();
  19892. + if (IS_ERR(file))
  19893. + goto out;
  19894. + vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
  19895. +
  19896. + out:
  19897. + return file;
  19898. +}
  19899. +
  19900. +int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
  19901. +{
  19902. + int err;
  19903. +
  19904. + /* lockdep_off(); */
  19905. + err = kern_path(name, flags, path);
  19906. + /* lockdep_on(); */
  19907. + if (!err && path->dentry->d_inode)
  19908. + vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
  19909. + return err;
  19910. +}
  19911. +
  19912. +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
  19913. + int len)
  19914. +{
  19915. + struct path path = {
  19916. + .mnt = NULL
  19917. + };
  19918. +
  19919. + IMustLock(parent->d_inode);
  19920. +
  19921. + path.dentry = lookup_one_len(name, parent, len);
  19922. + if (IS_ERR(path.dentry))
  19923. + goto out;
  19924. + if (path.dentry->d_inode)
  19925. + vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
  19926. +
  19927. + out:
  19928. + return path.dentry;
  19929. +}
  19930. +
  19931. +struct dentry *vfsub_lookup_hash(struct nameidata *nd)
  19932. +{
  19933. + struct path path = {
  19934. + .mnt = nd->path.mnt
  19935. + };
  19936. +
  19937. + IMustLock(nd->path.dentry->d_inode);
  19938. +
  19939. + path.dentry = lookup_hash(nd);
  19940. + if (!IS_ERR(path.dentry) && path.dentry->d_inode)
  19941. + vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
  19942. +
  19943. + return path.dentry;
  19944. +}
  19945. +
  19946. +/* ---------------------------------------------------------------------- */
  19947. +
  19948. +struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
  19949. + struct dentry *d2, struct au_hinode *hdir2)
  19950. +{
  19951. + struct dentry *d;
  19952. +
  19953. + lockdep_off();
  19954. + d = lock_rename(d1, d2);
  19955. + lockdep_on();
  19956. + au_hin_suspend(hdir1);
  19957. + if (hdir1 != hdir2)
  19958. + au_hin_suspend(hdir2);
  19959. +
  19960. + return d;
  19961. +}
  19962. +
  19963. +void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
  19964. + struct dentry *d2, struct au_hinode *hdir2)
  19965. +{
  19966. + au_hin_resume(hdir1);
  19967. + if (hdir1 != hdir2)
  19968. + au_hin_resume(hdir2);
  19969. + lockdep_off();
  19970. + unlock_rename(d1, d2);
  19971. + lockdep_on();
  19972. +}
  19973. +
  19974. +/* ---------------------------------------------------------------------- */
  19975. +
  19976. +int vfsub_create(struct inode *dir, struct path *path, int mode)
  19977. +{
  19978. + int err;
  19979. + struct dentry *d;
  19980. +
  19981. + IMustLock(dir);
  19982. +
  19983. + d = path->dentry;
  19984. + path->dentry = d->d_parent;
  19985. + err = security_path_mknod(path, path->dentry, mode, 0);
  19986. + path->dentry = d;
  19987. + if (unlikely(err))
  19988. + goto out;
  19989. +
  19990. + if (au_test_fs_null_nd(dir->i_sb))
  19991. + err = vfs_create(dir, path->dentry, mode, NULL);
  19992. + else {
  19993. + struct nameidata h_nd;
  19994. +
  19995. + memset(&h_nd, 0, sizeof(h_nd));
  19996. + h_nd.flags = LOOKUP_CREATE;
  19997. + h_nd.intent.open.flags = O_CREAT
  19998. + | vfsub_fmode_to_uint(FMODE_READ);
  19999. + h_nd.intent.open.create_mode = mode;
  20000. + h_nd.path.dentry = path->dentry->d_parent;
  20001. + h_nd.path.mnt = path->mnt;
  20002. + path_get(&h_nd.path);
  20003. + err = vfs_create(dir, path->dentry, mode, &h_nd);
  20004. + path_put(&h_nd.path);
  20005. + }
  20006. +
  20007. + if (!err) {
  20008. + struct path tmp = *path;
  20009. + int did;
  20010. +
  20011. + vfsub_update_h_iattr(&tmp, &did);
  20012. + if (did) {
  20013. + tmp.dentry = path->dentry->d_parent;
  20014. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20015. + }
  20016. + /*ignore*/
  20017. + }
  20018. +
  20019. + out:
  20020. + return err;
  20021. +}
  20022. +
  20023. +int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
  20024. +{
  20025. + int err;
  20026. + struct dentry *d;
  20027. +
  20028. + IMustLock(dir);
  20029. +
  20030. + d = path->dentry;
  20031. + path->dentry = d->d_parent;
  20032. + err = security_path_symlink(path, path->dentry, symname);
  20033. + path->dentry = d;
  20034. + if (unlikely(err))
  20035. + goto out;
  20036. +
  20037. + err = vfs_symlink(dir, path->dentry, symname);
  20038. + if (!err) {
  20039. + struct path tmp = *path;
  20040. + int did;
  20041. +
  20042. + vfsub_update_h_iattr(&tmp, &did);
  20043. + if (did) {
  20044. + tmp.dentry = path->dentry->d_parent;
  20045. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20046. + }
  20047. + /*ignore*/
  20048. + }
  20049. +
  20050. + out:
  20051. + return err;
  20052. +}
  20053. +
  20054. +int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
  20055. +{
  20056. + int err;
  20057. + struct dentry *d;
  20058. +
  20059. + IMustLock(dir);
  20060. +
  20061. + d = path->dentry;
  20062. + path->dentry = d->d_parent;
  20063. + err = security_path_mknod(path, path->dentry, mode, dev);
  20064. + path->dentry = d;
  20065. + if (unlikely(err))
  20066. + goto out;
  20067. +
  20068. + err = vfs_mknod(dir, path->dentry, mode, dev);
  20069. + if (!err) {
  20070. + struct path tmp = *path;
  20071. + int did;
  20072. +
  20073. + vfsub_update_h_iattr(&tmp, &did);
  20074. + if (did) {
  20075. + tmp.dentry = path->dentry->d_parent;
  20076. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20077. + }
  20078. + /*ignore*/
  20079. + }
  20080. +
  20081. + out:
  20082. + return err;
  20083. +}
  20084. +
  20085. +static int au_test_nlink(struct inode *inode)
  20086. +{
  20087. + const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
  20088. +
  20089. + if (!au_test_fs_no_limit_nlink(inode->i_sb)
  20090. + || inode->i_nlink < link_max)
  20091. + return 0;
  20092. + return -EMLINK;
  20093. +}
  20094. +
  20095. +int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path)
  20096. +{
  20097. + int err;
  20098. + struct dentry *d;
  20099. +
  20100. + IMustLock(dir);
  20101. +
  20102. + err = au_test_nlink(src_dentry->d_inode);
  20103. + if (unlikely(err))
  20104. + return err;
  20105. +
  20106. + d = path->dentry;
  20107. + path->dentry = d->d_parent;
  20108. + err = security_path_link(src_dentry, path, path->dentry);
  20109. + path->dentry = d;
  20110. + if (unlikely(err))
  20111. + goto out;
  20112. +
  20113. + lockdep_off();
  20114. + err = vfs_link(src_dentry, dir, path->dentry);
  20115. + lockdep_on();
  20116. + if (!err) {
  20117. + struct path tmp = *path;
  20118. + int did;
  20119. +
  20120. + /* fuse has different memory inode for the same inumber */
  20121. + vfsub_update_h_iattr(&tmp, &did);
  20122. + if (did) {
  20123. + tmp.dentry = path->dentry->d_parent;
  20124. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20125. + tmp.dentry = src_dentry;
  20126. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20127. + }
  20128. + /*ignore*/
  20129. + }
  20130. +
  20131. + out:
  20132. + return err;
  20133. +}
  20134. +
  20135. +int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
  20136. + struct inode *dir, struct path *path)
  20137. +{
  20138. + int err;
  20139. + struct path tmp = {
  20140. + .mnt = path->mnt
  20141. + };
  20142. + struct dentry *d;
  20143. +
  20144. + IMustLock(dir);
  20145. + IMustLock(src_dir);
  20146. +
  20147. + d = path->dentry;
  20148. + path->dentry = d->d_parent;
  20149. + tmp.dentry = src_dentry->d_parent;
  20150. + err = security_path_rename(&tmp, src_dentry, path, path->dentry);
  20151. + path->dentry = d;
  20152. + if (unlikely(err))
  20153. + goto out;
  20154. +
  20155. + lockdep_off();
  20156. + err = vfs_rename(src_dir, src_dentry, dir, path->dentry);
  20157. + lockdep_on();
  20158. + if (!err) {
  20159. + int did;
  20160. +
  20161. + tmp.dentry = d->d_parent;
  20162. + vfsub_update_h_iattr(&tmp, &did);
  20163. + if (did) {
  20164. + tmp.dentry = src_dentry;
  20165. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20166. + tmp.dentry = src_dentry->d_parent;
  20167. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20168. + }
  20169. + /*ignore*/
  20170. + }
  20171. +
  20172. + out:
  20173. + return err;
  20174. +}
  20175. +
  20176. +int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
  20177. +{
  20178. + int err;
  20179. + struct dentry *d;
  20180. +
  20181. + IMustLock(dir);
  20182. +
  20183. + d = path->dentry;
  20184. + path->dentry = d->d_parent;
  20185. + err = security_path_mkdir(path, path->dentry, mode);
  20186. + path->dentry = d;
  20187. + if (unlikely(err))
  20188. + goto out;
  20189. +
  20190. + err = vfs_mkdir(dir, path->dentry, mode);
  20191. + if (!err) {
  20192. + struct path tmp = *path;
  20193. + int did;
  20194. +
  20195. + vfsub_update_h_iattr(&tmp, &did);
  20196. + if (did) {
  20197. + tmp.dentry = path->dentry->d_parent;
  20198. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  20199. + }
  20200. + /*ignore*/
  20201. + }
  20202. +
  20203. + out:
  20204. + return err;
  20205. +}
  20206. +
  20207. +int vfsub_rmdir(struct inode *dir, struct path *path)
  20208. +{
  20209. + int err;
  20210. + struct dentry *d;
  20211. +
  20212. + IMustLock(dir);
  20213. +
  20214. + d = path->dentry;
  20215. + path->dentry = d->d_parent;
  20216. + err = security_path_rmdir(path, path->dentry);
  20217. + path->dentry = d;
  20218. + if (unlikely(err))
  20219. + goto out;
  20220. +
  20221. + lockdep_off();
  20222. + err = vfs_rmdir(dir, path->dentry);
  20223. + lockdep_on();
  20224. + if (!err) {
  20225. + struct path tmp = {
  20226. + .dentry = path->dentry->d_parent,
  20227. + .mnt = path->mnt
  20228. + };
  20229. +
  20230. + vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
  20231. + }
  20232. +
  20233. + out:
  20234. + return err;
  20235. +}
  20236. +
  20237. +/* ---------------------------------------------------------------------- */
  20238. +
  20239. +ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
  20240. + loff_t *ppos)
  20241. +{
  20242. + ssize_t err;
  20243. +
  20244. + err = vfs_read(file, ubuf, count, ppos);
  20245. + if (err >= 0)
  20246. + vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
  20247. + return err;
  20248. +}
  20249. +
  20250. +/* todo: kernel_read()? */
  20251. +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
  20252. + loff_t *ppos)
  20253. +{
  20254. + ssize_t err;
  20255. + mm_segment_t oldfs;
  20256. +
  20257. + oldfs = get_fs();
  20258. + set_fs(KERNEL_DS);
  20259. + err = vfsub_read_u(file, (char __user *)kbuf, count, ppos);
  20260. + set_fs(oldfs);
  20261. + return err;
  20262. +}
  20263. +
  20264. +ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
  20265. + loff_t *ppos)
  20266. +{
  20267. + ssize_t err;
  20268. +
  20269. + lockdep_off();
  20270. + err = vfs_write(file, ubuf, count, ppos);
  20271. + lockdep_on();
  20272. + if (err >= 0)
  20273. + vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
  20274. + return err;
  20275. +}
  20276. +
  20277. +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
  20278. +{
  20279. + ssize_t err;
  20280. + mm_segment_t oldfs;
  20281. +
  20282. + oldfs = get_fs();
  20283. + set_fs(KERNEL_DS);
  20284. + err = vfsub_write_u(file, (const char __user *)kbuf, count, ppos);
  20285. + set_fs(oldfs);
  20286. + return err;
  20287. +}
  20288. +
  20289. +int vfsub_readdir(struct file *file, filldir_t filldir, void *arg)
  20290. +{
  20291. + int err;
  20292. +
  20293. + lockdep_off();
  20294. + err = vfs_readdir(file, filldir, arg);
  20295. + lockdep_on();
  20296. + if (err >= 0)
  20297. + vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
  20298. + return err;
  20299. +}
  20300. +
  20301. +long vfsub_splice_to(struct file *in, loff_t *ppos,
  20302. + struct pipe_inode_info *pipe, size_t len,
  20303. + unsigned int flags)
  20304. +{
  20305. + long err;
  20306. +
  20307. + lockdep_off();
  20308. + err = do_splice_to(in, ppos, pipe, len, flags);
  20309. + lockdep_on();
  20310. + if (err >= 0)
  20311. + vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
  20312. + return err;
  20313. +}
  20314. +
  20315. +long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
  20316. + loff_t *ppos, size_t len, unsigned int flags)
  20317. +{
  20318. + long err;
  20319. +
  20320. + lockdep_off();
  20321. + err = do_splice_from(pipe, out, ppos, len, flags);
  20322. + lockdep_on();
  20323. + if (err >= 0)
  20324. + vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
  20325. + return err;
  20326. +}
  20327. +
  20328. +/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
  20329. +int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
  20330. + struct file *h_file)
  20331. +{
  20332. + int err;
  20333. + struct inode *h_inode;
  20334. +
  20335. + h_inode = h_path->dentry->d_inode;
  20336. + if (!h_file) {
  20337. + err = mnt_want_write(h_path->mnt);
  20338. + if (err)
  20339. + goto out;
  20340. + err = inode_permission(h_inode, MAY_WRITE);
  20341. + if (err)
  20342. + goto out_mnt;
  20343. + err = get_write_access(h_inode);
  20344. + if (err)
  20345. + goto out_mnt;
  20346. + err = break_lease(h_inode, vfsub_fmode_to_uint(FMODE_WRITE));
  20347. + if (err)
  20348. + goto out_inode;
  20349. + }
  20350. +
  20351. + err = locks_verify_truncate(h_inode, h_file, length);
  20352. + if (!err)
  20353. + err = security_path_truncate(h_path, length, attr);
  20354. + if (!err) {
  20355. + lockdep_off();
  20356. + err = do_truncate(h_path->dentry, length, attr, h_file);
  20357. + lockdep_on();
  20358. + }
  20359. +
  20360. + out_inode:
  20361. + if (!h_file)
  20362. + put_write_access(h_inode);
  20363. + out_mnt:
  20364. + if (!h_file)
  20365. + mnt_drop_write(h_path->mnt);
  20366. + out:
  20367. + return err;
  20368. +}
  20369. +
  20370. +/* ---------------------------------------------------------------------- */
  20371. +
  20372. +struct au_vfsub_mkdir_args {
  20373. + int *errp;
  20374. + struct inode *dir;
  20375. + struct path *path;
  20376. + int mode;
  20377. +};
  20378. +
  20379. +static void au_call_vfsub_mkdir(void *args)
  20380. +{
  20381. + struct au_vfsub_mkdir_args *a = args;
  20382. + *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
  20383. +}
  20384. +
  20385. +int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
  20386. +{
  20387. + int err, do_sio, wkq_err;
  20388. +
  20389. + do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
  20390. + if (!do_sio)
  20391. + err = vfsub_mkdir(dir, path, mode);
  20392. + else {
  20393. + struct au_vfsub_mkdir_args args = {
  20394. + .errp = &err,
  20395. + .dir = dir,
  20396. + .path = path,
  20397. + .mode = mode
  20398. + };
  20399. + wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
  20400. + if (unlikely(wkq_err))
  20401. + err = wkq_err;
  20402. + }
  20403. +
  20404. + return err;
  20405. +}
  20406. +
  20407. +struct au_vfsub_rmdir_args {
  20408. + int *errp;
  20409. + struct inode *dir;
  20410. + struct path *path;
  20411. +};
  20412. +
  20413. +static void au_call_vfsub_rmdir(void *args)
  20414. +{
  20415. + struct au_vfsub_rmdir_args *a = args;
  20416. + *a->errp = vfsub_rmdir(a->dir, a->path);
  20417. +}
  20418. +
  20419. +int vfsub_sio_rmdir(struct inode *dir, struct path *path)
  20420. +{
  20421. + int err, do_sio, wkq_err;
  20422. +
  20423. + do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
  20424. + if (!do_sio)
  20425. + err = vfsub_rmdir(dir, path);
  20426. + else {
  20427. + struct au_vfsub_rmdir_args args = {
  20428. + .errp = &err,
  20429. + .dir = dir,
  20430. + .path = path
  20431. + };
  20432. + wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
  20433. + if (unlikely(wkq_err))
  20434. + err = wkq_err;
  20435. + }
  20436. +
  20437. + return err;
  20438. +}
  20439. +
  20440. +/* ---------------------------------------------------------------------- */
  20441. +
  20442. +struct notify_change_args {
  20443. + int *errp;
  20444. + struct path *path;
  20445. + struct iattr *ia;
  20446. +};
  20447. +
  20448. +static void call_notify_change(void *args)
  20449. +{
  20450. + struct notify_change_args *a = args;
  20451. + struct inode *h_inode;
  20452. +
  20453. + h_inode = a->path->dentry->d_inode;
  20454. + IMustLock(h_inode);
  20455. +
  20456. + *a->errp = -EPERM;
  20457. + if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
  20458. + lockdep_off();
  20459. + *a->errp = notify_change(a->path->dentry, a->ia);
  20460. + lockdep_on();
  20461. + if (!*a->errp)
  20462. + vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
  20463. + }
  20464. + AuTraceErr(*a->errp);
  20465. +}
  20466. +
  20467. +int vfsub_notify_change(struct path *path, struct iattr *ia)
  20468. +{
  20469. + int err;
  20470. + struct notify_change_args args = {
  20471. + .errp = &err,
  20472. + .path = path,
  20473. + .ia = ia
  20474. + };
  20475. +
  20476. + call_notify_change(&args);
  20477. +
  20478. + return err;
  20479. +}
  20480. +
  20481. +int vfsub_sio_notify_change(struct path *path, struct iattr *ia)
  20482. +{
  20483. + int err, wkq_err;
  20484. + struct notify_change_args args = {
  20485. + .errp = &err,
  20486. + .path = path,
  20487. + .ia = ia
  20488. + };
  20489. +
  20490. + wkq_err = au_wkq_wait(call_notify_change, &args);
  20491. + if (unlikely(wkq_err))
  20492. + err = wkq_err;
  20493. +
  20494. + return err;
  20495. +}
  20496. +
  20497. +/* ---------------------------------------------------------------------- */
  20498. +
  20499. +struct unlink_args {
  20500. + int *errp;
  20501. + struct inode *dir;
  20502. + struct path *path;
  20503. +};
  20504. +
  20505. +static void call_unlink(void *args)
  20506. +{
  20507. + struct unlink_args *a = args;
  20508. + struct dentry *d = a->path->dentry;
  20509. + struct inode *h_inode;
  20510. + const int stop_sillyrename = (au_test_nfs(d->d_sb)
  20511. + && atomic_read(&d->d_count) == 1);
  20512. +
  20513. + IMustLock(a->dir);
  20514. +
  20515. + a->path->dentry = d->d_parent;
  20516. + *a->errp = security_path_unlink(a->path, d);
  20517. + a->path->dentry = d;
  20518. + if (unlikely(*a->errp))
  20519. + return;
  20520. +
  20521. + if (!stop_sillyrename)
  20522. + dget(d);
  20523. + h_inode = d->d_inode;
  20524. + if (h_inode)
  20525. + atomic_inc(&h_inode->i_count);
  20526. +
  20527. + lockdep_off();
  20528. + *a->errp = vfs_unlink(a->dir, d);
  20529. + lockdep_on();
  20530. + if (!*a->errp) {
  20531. + struct path tmp = {
  20532. + .dentry = d->d_parent,
  20533. + .mnt = a->path->mnt
  20534. + };
  20535. + vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
  20536. + }
  20537. +
  20538. + if (!stop_sillyrename)
  20539. + dput(d);
  20540. + if (h_inode)
  20541. + iput(h_inode);
  20542. +
  20543. + AuTraceErr(*a->errp);
  20544. +}
  20545. +
  20546. +/*
  20547. + * @dir: must be locked.
  20548. + * @dentry: target dentry.
  20549. + */
  20550. +int vfsub_unlink(struct inode *dir, struct path *path, int force)
  20551. +{
  20552. + int err;
  20553. + struct unlink_args args = {
  20554. + .errp = &err,
  20555. + .dir = dir,
  20556. + .path = path
  20557. + };
  20558. +
  20559. + if (!force)
  20560. + call_unlink(&args);
  20561. + else {
  20562. + int wkq_err;
  20563. +
  20564. + wkq_err = au_wkq_wait(call_unlink, &args);
  20565. + if (unlikely(wkq_err))
  20566. + err = wkq_err;
  20567. + }
  20568. +
  20569. + return err;
  20570. +}
  20571. diff -Nur linux-2.6.31.5.orig/fs/aufs/vfsub.h linux-2.6.31.5/fs/aufs/vfsub.h
  20572. --- linux-2.6.31.5.orig/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
  20573. +++ linux-2.6.31.5/fs/aufs/vfsub.h 2009-11-15 22:02:37.000000000 +0100
  20574. @@ -0,0 +1,172 @@
  20575. +/*
  20576. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  20577. + *
  20578. + * This program, aufs is free software; you can redistribute it and/or modify
  20579. + * it under the terms of the GNU General Public License as published by
  20580. + * the Free Software Foundation; either version 2 of the License, or
  20581. + * (at your option) any later version.
  20582. + *
  20583. + * This program is distributed in the hope that it will be useful,
  20584. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20585. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20586. + * GNU General Public License for more details.
  20587. + *
  20588. + * You should have received a copy of the GNU General Public License
  20589. + * along with this program; if not, write to the Free Software
  20590. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20591. + */
  20592. +
  20593. +/*
  20594. + * sub-routines for VFS
  20595. + */
  20596. +
  20597. +#ifndef __AUFS_VFSUB_H__
  20598. +#define __AUFS_VFSUB_H__
  20599. +
  20600. +#ifdef __KERNEL__
  20601. +
  20602. +#include <linux/fs.h>
  20603. +#include <linux/fs_stack.h>
  20604. +
  20605. +/* ---------------------------------------------------------------------- */
  20606. +
  20607. +/* lock subclass for lower inode */
  20608. +/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
  20609. +/* reduce? gave up. */
  20610. +enum {
  20611. + AuLsc_I_Begin = I_MUTEX_QUOTA, /* 4 */
  20612. + AuLsc_I_PARENT, /* lower inode, parent first */
  20613. + AuLsc_I_PARENT2, /* copyup dirs */
  20614. + AuLsc_I_PARENT3, /* copyup wh */
  20615. + AuLsc_I_CHILD,
  20616. + AuLsc_I_CHILD2,
  20617. + AuLsc_I_End
  20618. +};
  20619. +
  20620. +/* to debug easier, do not make them inlined functions */
  20621. +#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
  20622. +#define IMustLock(i) MtxMustLock(&(i)->i_mutex)
  20623. +
  20624. +/* ---------------------------------------------------------------------- */
  20625. +
  20626. +static inline void vfsub_copy_inode_size(struct inode *inode,
  20627. + struct inode *h_inode)
  20628. +{
  20629. + spin_lock(&inode->i_lock);
  20630. + fsstack_copy_inode_size(inode, h_inode);
  20631. + spin_unlock(&inode->i_lock);
  20632. +}
  20633. +
  20634. +int vfsub_update_h_iattr(struct path *h_path, int *did);
  20635. +struct file *vfsub_filp_open(const char *path, int oflags, int mode);
  20636. +int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
  20637. +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
  20638. + int len);
  20639. +struct dentry *vfsub_lookup_hash(struct nameidata *nd);
  20640. +
  20641. +/* ---------------------------------------------------------------------- */
  20642. +
  20643. +struct au_hinode;
  20644. +struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
  20645. + struct dentry *d2, struct au_hinode *hdir2);
  20646. +void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
  20647. + struct dentry *d2, struct au_hinode *hdir2);
  20648. +
  20649. +int vfsub_create(struct inode *dir, struct path *path, int mode);
  20650. +int vfsub_symlink(struct inode *dir, struct path *path,
  20651. + const char *symname);
  20652. +int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
  20653. +int vfsub_link(struct dentry *src_dentry, struct inode *dir,
  20654. + struct path *path);
  20655. +int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
  20656. + struct inode *hdir, struct path *path);
  20657. +int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
  20658. +int vfsub_rmdir(struct inode *dir, struct path *path);
  20659. +
  20660. +/* ---------------------------------------------------------------------- */
  20661. +
  20662. +ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
  20663. + loff_t *ppos);
  20664. +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
  20665. + loff_t *ppos);
  20666. +ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
  20667. + loff_t *ppos);
  20668. +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
  20669. + loff_t *ppos);
  20670. +int vfsub_readdir(struct file *file, filldir_t filldir, void *arg);
  20671. +
  20672. +static inline void vfsub_file_accessed(struct file *h_file)
  20673. +{
  20674. + file_accessed(h_file);
  20675. + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
  20676. +}
  20677. +
  20678. +static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
  20679. + struct dentry *h_dentry)
  20680. +{
  20681. + struct path h_path = {
  20682. + .dentry = h_dentry,
  20683. + .mnt = h_mnt
  20684. + };
  20685. + touch_atime(h_mnt, h_dentry);
  20686. + vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
  20687. +}
  20688. +
  20689. +long vfsub_splice_to(struct file *in, loff_t *ppos,
  20690. + struct pipe_inode_info *pipe, size_t len,
  20691. + unsigned int flags);
  20692. +long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
  20693. + loff_t *ppos, size_t len, unsigned int flags);
  20694. +int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
  20695. + struct file *h_file);
  20696. +
  20697. +/* ---------------------------------------------------------------------- */
  20698. +
  20699. +static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
  20700. +{
  20701. + loff_t err;
  20702. +
  20703. + lockdep_off();
  20704. + err = vfs_llseek(file, offset, origin);
  20705. + lockdep_on();
  20706. + return err;
  20707. +}
  20708. +
  20709. +/* ---------------------------------------------------------------------- */
  20710. +
  20711. +/* dirty workaround for strict type of fmode_t */
  20712. +union vfsub_fmu {
  20713. + fmode_t fm;
  20714. + unsigned int ui;
  20715. +};
  20716. +
  20717. +static inline unsigned int vfsub_fmode_to_uint(fmode_t fm)
  20718. +{
  20719. + union vfsub_fmu u = {
  20720. + .fm = fm
  20721. + };
  20722. +
  20723. + BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui));
  20724. +
  20725. + return u.ui;
  20726. +}
  20727. +
  20728. +static inline fmode_t vfsub_uint_to_fmode(unsigned int ui)
  20729. +{
  20730. + union vfsub_fmu u = {
  20731. + .ui = ui
  20732. + };
  20733. +
  20734. + return u.fm;
  20735. +}
  20736. +
  20737. +/* ---------------------------------------------------------------------- */
  20738. +
  20739. +int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
  20740. +int vfsub_sio_rmdir(struct inode *dir, struct path *path);
  20741. +int vfsub_sio_notify_change(struct path *path, struct iattr *ia);
  20742. +int vfsub_notify_change(struct path *path, struct iattr *ia);
  20743. +int vfsub_unlink(struct inode *dir, struct path *path, int force);
  20744. +
  20745. +#endif /* __KERNEL__ */
  20746. +#endif /* __AUFS_VFSUB_H__ */
  20747. diff -Nur linux-2.6.31.5.orig/fs/aufs/wbr_policy.c linux-2.6.31.5/fs/aufs/wbr_policy.c
  20748. --- linux-2.6.31.5.orig/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100
  20749. +++ linux-2.6.31.5/fs/aufs/wbr_policy.c 2009-11-15 22:02:37.000000000 +0100
  20750. @@ -0,0 +1,641 @@
  20751. +/*
  20752. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  20753. + *
  20754. + * This program, aufs is free software; you can redistribute it and/or modify
  20755. + * it under the terms of the GNU General Public License as published by
  20756. + * the Free Software Foundation; either version 2 of the License, or
  20757. + * (at your option) any later version.
  20758. + *
  20759. + * This program is distributed in the hope that it will be useful,
  20760. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20761. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20762. + * GNU General Public License for more details.
  20763. + *
  20764. + * You should have received a copy of the GNU General Public License
  20765. + * along with this program; if not, write to the Free Software
  20766. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20767. + */
  20768. +
  20769. +/*
  20770. + * policies for selecting one among multiple writable branches
  20771. + */
  20772. +
  20773. +#include <linux/statfs.h>
  20774. +#include "aufs.h"
  20775. +
  20776. +/* subset of cpup_attr() */
  20777. +static noinline_for_stack
  20778. +int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
  20779. +{
  20780. + int err, sbits;
  20781. + struct iattr ia;
  20782. + struct inode *h_isrc;
  20783. +
  20784. + h_isrc = h_src->d_inode;
  20785. + ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
  20786. + ia.ia_mode = h_isrc->i_mode;
  20787. + ia.ia_uid = h_isrc->i_uid;
  20788. + ia.ia_gid = h_isrc->i_gid;
  20789. + sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
  20790. + au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc);
  20791. + err = vfsub_sio_notify_change(h_path, &ia);
  20792. +
  20793. + /* is this nfs only? */
  20794. + if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
  20795. + ia.ia_valid = ATTR_FORCE | ATTR_MODE;
  20796. + ia.ia_mode = h_isrc->i_mode;
  20797. + err = vfsub_sio_notify_change(h_path, &ia);
  20798. + }
  20799. +
  20800. + return err;
  20801. +}
  20802. +
  20803. +#define AuCpdown_PARENT_OPQ 1
  20804. +#define AuCpdown_WHED (1 << 1)
  20805. +#define AuCpdown_MADE_DIR (1 << 2)
  20806. +#define AuCpdown_DIROPQ (1 << 3)
  20807. +#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name)
  20808. +#define au_fset_cpdown(flags, name) { (flags) |= AuCpdown_##name; }
  20809. +#define au_fclr_cpdown(flags, name) { (flags) &= ~AuCpdown_##name; }
  20810. +
  20811. +struct au_cpdown_dir_args {
  20812. + struct dentry *parent;
  20813. + unsigned int flags;
  20814. +};
  20815. +
  20816. +static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
  20817. + struct au_cpdown_dir_args *a)
  20818. +{
  20819. + int err;
  20820. + struct dentry *opq_dentry;
  20821. +
  20822. + opq_dentry = au_diropq_create(dentry, bdst);
  20823. + err = PTR_ERR(opq_dentry);
  20824. + if (IS_ERR(opq_dentry))
  20825. + goto out;
  20826. + dput(opq_dentry);
  20827. + au_fset_cpdown(a->flags, DIROPQ);
  20828. +
  20829. + out:
  20830. + return err;
  20831. +}
  20832. +
  20833. +static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
  20834. + struct inode *dir, aufs_bindex_t bdst)
  20835. +{
  20836. + int err;
  20837. + struct path h_path;
  20838. + struct au_branch *br;
  20839. +
  20840. + br = au_sbr(dentry->d_sb, bdst);
  20841. + h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
  20842. + err = PTR_ERR(h_path.dentry);
  20843. + if (IS_ERR(h_path.dentry))
  20844. + goto out;
  20845. +
  20846. + err = 0;
  20847. + if (h_path.dentry->d_inode) {
  20848. + h_path.mnt = br->br_mnt;
  20849. + err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
  20850. + dentry);
  20851. + }
  20852. + dput(h_path.dentry);
  20853. +
  20854. + out:
  20855. + return err;
  20856. +}
  20857. +
  20858. +static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
  20859. + struct dentry *h_parent, void *arg)
  20860. +{
  20861. + int err, rerr;
  20862. + aufs_bindex_t bend, bopq, bstart;
  20863. + unsigned char parent_opq;
  20864. + struct path h_path;
  20865. + struct dentry *parent;
  20866. + struct inode *h_dir, *h_inode, *inode, *dir;
  20867. + struct au_cpdown_dir_args *args = arg;
  20868. +
  20869. + bstart = au_dbstart(dentry);
  20870. + /* dentry is di-locked */
  20871. + parent = dget_parent(dentry);
  20872. + dir = parent->d_inode;
  20873. + h_dir = h_parent->d_inode;
  20874. + AuDebugOn(h_dir != au_h_iptr(dir, bdst));
  20875. + IMustLock(h_dir);
  20876. +
  20877. + err = au_lkup_neg(dentry, bdst);
  20878. + if (unlikely(err < 0))
  20879. + goto out;
  20880. + h_path.dentry = au_h_dptr(dentry, bdst);
  20881. + h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
  20882. + err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path,
  20883. + S_IRWXU | S_IRUGO | S_IXUGO);
  20884. + if (unlikely(err))
  20885. + goto out_put;
  20886. + au_fset_cpdown(args->flags, MADE_DIR);
  20887. +
  20888. + bend = au_dbend(dentry);
  20889. + bopq = au_dbdiropq(dentry);
  20890. + au_fclr_cpdown(args->flags, WHED);
  20891. + au_fclr_cpdown(args->flags, DIROPQ);
  20892. + if (au_dbwh(dentry) == bdst)
  20893. + au_fset_cpdown(args->flags, WHED);
  20894. + if (!au_ftest_cpdown(args->flags, PARENT_OPQ) && bopq <= bdst)
  20895. + au_fset_cpdown(args->flags, PARENT_OPQ);
  20896. + parent_opq = (au_ftest_cpdown(args->flags, PARENT_OPQ)
  20897. + && args->parent == dentry);
  20898. + h_inode = h_path.dentry->d_inode;
  20899. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  20900. + if (au_ftest_cpdown(args->flags, WHED)) {
  20901. + err = au_cpdown_dir_opq(dentry, bdst, args);
  20902. + if (unlikely(err)) {
  20903. + mutex_unlock(&h_inode->i_mutex);
  20904. + goto out_dir;
  20905. + }
  20906. + }
  20907. +
  20908. + err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart));
  20909. + mutex_unlock(&h_inode->i_mutex);
  20910. + if (unlikely(err))
  20911. + goto out_opq;
  20912. +
  20913. + if (au_ftest_cpdown(args->flags, WHED)) {
  20914. + err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
  20915. + if (unlikely(err))
  20916. + goto out_opq;
  20917. + }
  20918. +
  20919. + inode = dentry->d_inode;
  20920. + if (au_ibend(inode) < bdst)
  20921. + au_set_ibend(inode, bdst);
  20922. + au_set_h_iptr(inode, bdst, au_igrab(h_inode),
  20923. + au_hi_flags(inode, /*isdir*/1));
  20924. + goto out; /* success */
  20925. +
  20926. + /* revert */
  20927. + out_opq:
  20928. + if (au_ftest_cpdown(args->flags, DIROPQ)) {
  20929. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  20930. + rerr = au_diropq_remove(dentry, bdst);
  20931. + mutex_unlock(&h_inode->i_mutex);
  20932. + if (unlikely(rerr)) {
  20933. + AuIOErr("failed removing diropq for %.*s b%d (%d)\n",
  20934. + AuDLNPair(dentry), bdst, rerr);
  20935. + err = -EIO;
  20936. + goto out;
  20937. + }
  20938. + }
  20939. + out_dir:
  20940. + if (au_ftest_cpdown(args->flags, MADE_DIR)) {
  20941. + rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
  20942. + if (unlikely(rerr)) {
  20943. + AuIOErr("failed removing %.*s b%d (%d)\n",
  20944. + AuDLNPair(dentry), bdst, rerr);
  20945. + err = -EIO;
  20946. + }
  20947. + }
  20948. + out_put:
  20949. + au_set_h_dptr(dentry, bdst, NULL);
  20950. + if (au_dbend(dentry) == bdst)
  20951. + au_update_dbend(dentry);
  20952. + out:
  20953. + dput(parent);
  20954. + return err;
  20955. +}
  20956. +
  20957. +int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
  20958. +{
  20959. + int err;
  20960. + struct au_cpdown_dir_args args = {
  20961. + .parent = dget_parent(dentry),
  20962. + .flags = 0
  20963. + };
  20964. +
  20965. + err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &args);
  20966. + dput(args.parent);
  20967. +
  20968. + return err;
  20969. +}
  20970. +
  20971. +/* ---------------------------------------------------------------------- */
  20972. +
  20973. +/* policies for create */
  20974. +
  20975. +static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
  20976. +{
  20977. + for (; bindex >= 0; bindex--)
  20978. + if (!au_br_rdonly(au_sbr(sb, bindex)))
  20979. + return bindex;
  20980. + return -EROFS;
  20981. +}
  20982. +
  20983. +/* top down parent */
  20984. +static int au_wbr_create_tdp(struct dentry *dentry, int isdir __maybe_unused)
  20985. +{
  20986. + int err;
  20987. + aufs_bindex_t bstart, bindex;
  20988. + struct super_block *sb;
  20989. + struct dentry *parent, *h_parent;
  20990. +
  20991. + sb = dentry->d_sb;
  20992. + bstart = au_dbstart(dentry);
  20993. + err = bstart;
  20994. + if (!au_br_rdonly(au_sbr(sb, bstart)))
  20995. + goto out;
  20996. +
  20997. + err = -EROFS;
  20998. + parent = dget_parent(dentry);
  20999. + for (bindex = au_dbstart(parent); bindex < bstart; bindex++) {
  21000. + h_parent = au_h_dptr(parent, bindex);
  21001. + if (!h_parent || !h_parent->d_inode)
  21002. + continue;
  21003. +
  21004. + if (!au_br_rdonly(au_sbr(sb, bindex))) {
  21005. + err = bindex;
  21006. + break;
  21007. + }
  21008. + }
  21009. + dput(parent);
  21010. +
  21011. + /* bottom up here */
  21012. + if (unlikely(err < 0))
  21013. + err = au_wbr_bu(sb, bstart - 1);
  21014. +
  21015. + out:
  21016. + AuDbg("b%d\n", err);
  21017. + return err;
  21018. +}
  21019. +
  21020. +/* ---------------------------------------------------------------------- */
  21021. +
  21022. +/* an exception for the policy other than tdp */
  21023. +static int au_wbr_create_exp(struct dentry *dentry)
  21024. +{
  21025. + int err;
  21026. + aufs_bindex_t bwh, bdiropq;
  21027. + struct dentry *parent;
  21028. +
  21029. + err = -1;
  21030. + bwh = au_dbwh(dentry);
  21031. + parent = dget_parent(dentry);
  21032. + bdiropq = au_dbdiropq(parent);
  21033. + if (bwh >= 0) {
  21034. + if (bdiropq >= 0)
  21035. + err = min(bdiropq, bwh);
  21036. + else
  21037. + err = bwh;
  21038. + AuDbg("%d\n", err);
  21039. + } else if (bdiropq >= 0) {
  21040. + err = bdiropq;
  21041. + AuDbg("%d\n", err);
  21042. + }
  21043. + dput(parent);
  21044. +
  21045. + if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
  21046. + err = -1;
  21047. +
  21048. + AuDbg("%d\n", err);
  21049. + return err;
  21050. +}
  21051. +
  21052. +/* ---------------------------------------------------------------------- */
  21053. +
  21054. +/* round robin */
  21055. +static int au_wbr_create_init_rr(struct super_block *sb)
  21056. +{
  21057. + int err;
  21058. +
  21059. + err = au_wbr_bu(sb, au_sbend(sb));
  21060. + atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
  21061. + /* smp_mb(); */
  21062. +
  21063. + AuDbg("b%d\n", err);
  21064. + return err;
  21065. +}
  21066. +
  21067. +static int au_wbr_create_rr(struct dentry *dentry, int isdir)
  21068. +{
  21069. + int err, nbr;
  21070. + unsigned int u;
  21071. + aufs_bindex_t bindex, bend;
  21072. + struct super_block *sb;
  21073. + atomic_t *next;
  21074. +
  21075. + err = au_wbr_create_exp(dentry);
  21076. + if (err >= 0)
  21077. + goto out;
  21078. +
  21079. + sb = dentry->d_sb;
  21080. + next = &au_sbi(sb)->si_wbr_rr_next;
  21081. + bend = au_sbend(sb);
  21082. + nbr = bend + 1;
  21083. + for (bindex = 0; bindex <= bend; bindex++) {
  21084. + if (!isdir) {
  21085. + err = atomic_dec_return(next) + 1;
  21086. + /* modulo for 0 is meaningless */
  21087. + if (unlikely(!err))
  21088. + err = atomic_dec_return(next) + 1;
  21089. + } else
  21090. + err = atomic_read(next);
  21091. + AuDbg("%d\n", err);
  21092. + u = err;
  21093. + err = u % nbr;
  21094. + AuDbg("%d\n", err);
  21095. + if (!au_br_rdonly(au_sbr(sb, err)))
  21096. + break;
  21097. + err = -EROFS;
  21098. + }
  21099. +
  21100. + out:
  21101. + AuDbg("%d\n", err);
  21102. + return err;
  21103. +}
  21104. +
  21105. +/* ---------------------------------------------------------------------- */
  21106. +
  21107. +/* most free space */
  21108. +static void au_mfs(struct dentry *dentry)
  21109. +{
  21110. + struct super_block *sb;
  21111. + struct au_branch *br;
  21112. + struct au_wbr_mfs *mfs;
  21113. + aufs_bindex_t bindex, bend;
  21114. + int err;
  21115. + unsigned long long b, bavail;
  21116. + /* reduce the stack usage */
  21117. + struct kstatfs *st;
  21118. +
  21119. + st = kmalloc(sizeof(*st), GFP_NOFS);
  21120. + if (unlikely(!st)) {
  21121. + AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
  21122. + return;
  21123. + }
  21124. +
  21125. + bavail = 0;
  21126. + sb = dentry->d_sb;
  21127. + mfs = &au_sbi(sb)->si_wbr_mfs;
  21128. + MtxMustLock(&mfs->mfs_lock);
  21129. + mfs->mfs_bindex = -EROFS;
  21130. + mfs->mfsrr_bytes = 0;
  21131. + bend = au_sbend(sb);
  21132. + for (bindex = 0; bindex <= bend; bindex++) {
  21133. + br = au_sbr(sb, bindex);
  21134. + if (au_br_rdonly(br))
  21135. + continue;
  21136. +
  21137. + /* sb->s_root for NFS is unreliable */
  21138. + err = vfs_statfs(br->br_mnt->mnt_root, st);
  21139. + if (unlikely(err)) {
  21140. + AuWarn1("failed statfs, b%d, %d\n", bindex, err);
  21141. + continue;
  21142. + }
  21143. +
  21144. + /* when the available size is equal, select the lower one */
  21145. + BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
  21146. + || sizeof(b) < sizeof(st->f_bsize));
  21147. + b = st->f_bavail * st->f_bsize;
  21148. + br->br_wbr->wbr_bytes = b;
  21149. + if (b >= bavail) {
  21150. + bavail = b;
  21151. + mfs->mfs_bindex = bindex;
  21152. + mfs->mfs_jiffy = jiffies;
  21153. + }
  21154. + }
  21155. +
  21156. + mfs->mfsrr_bytes = bavail;
  21157. + AuDbg("b%d\n", mfs->mfs_bindex);
  21158. + kfree(st);
  21159. +}
  21160. +
  21161. +static int au_wbr_create_mfs(struct dentry *dentry, int isdir __maybe_unused)
  21162. +{
  21163. + int err;
  21164. + struct super_block *sb;
  21165. + struct au_wbr_mfs *mfs;
  21166. +
  21167. + err = au_wbr_create_exp(dentry);
  21168. + if (err >= 0)
  21169. + goto out;
  21170. +
  21171. + sb = dentry->d_sb;
  21172. + mfs = &au_sbi(sb)->si_wbr_mfs;
  21173. + mutex_lock(&mfs->mfs_lock);
  21174. + if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
  21175. + || mfs->mfs_bindex < 0
  21176. + || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
  21177. + au_mfs(dentry);
  21178. + mutex_unlock(&mfs->mfs_lock);
  21179. + err = mfs->mfs_bindex;
  21180. +
  21181. + out:
  21182. + AuDbg("b%d\n", err);
  21183. + return err;
  21184. +}
  21185. +
  21186. +static int au_wbr_create_init_mfs(struct super_block *sb)
  21187. +{
  21188. + struct au_wbr_mfs *mfs;
  21189. +
  21190. + mfs = &au_sbi(sb)->si_wbr_mfs;
  21191. + mutex_init(&mfs->mfs_lock);
  21192. + mfs->mfs_jiffy = 0;
  21193. + mfs->mfs_bindex = -EROFS;
  21194. +
  21195. + return 0;
  21196. +}
  21197. +
  21198. +static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
  21199. +{
  21200. + mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
  21201. + return 0;
  21202. +}
  21203. +
  21204. +/* ---------------------------------------------------------------------- */
  21205. +
  21206. +/* most free space and then round robin */
  21207. +static int au_wbr_create_mfsrr(struct dentry *dentry, int isdir)
  21208. +{
  21209. + int err;
  21210. + struct au_wbr_mfs *mfs;
  21211. +
  21212. + err = au_wbr_create_mfs(dentry, isdir);
  21213. + if (err >= 0) {
  21214. + mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
  21215. + mutex_lock(&mfs->mfs_lock);
  21216. + if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
  21217. + err = au_wbr_create_rr(dentry, isdir);
  21218. + mutex_unlock(&mfs->mfs_lock);
  21219. + }
  21220. +
  21221. + AuDbg("b%d\n", err);
  21222. + return err;
  21223. +}
  21224. +
  21225. +static int au_wbr_create_init_mfsrr(struct super_block *sb)
  21226. +{
  21227. + int err;
  21228. +
  21229. + au_wbr_create_init_mfs(sb); /* ignore */
  21230. + err = au_wbr_create_init_rr(sb);
  21231. +
  21232. + return err;
  21233. +}
  21234. +
  21235. +/* ---------------------------------------------------------------------- */
  21236. +
  21237. +/* top down parent and most free space */
  21238. +static int au_wbr_create_pmfs(struct dentry *dentry, int isdir)
  21239. +{
  21240. + int err, e2;
  21241. + unsigned long long b;
  21242. + aufs_bindex_t bindex, bstart, bend;
  21243. + struct super_block *sb;
  21244. + struct dentry *parent, *h_parent;
  21245. + struct au_branch *br;
  21246. +
  21247. + err = au_wbr_create_tdp(dentry, isdir);
  21248. + if (unlikely(err < 0))
  21249. + goto out;
  21250. + parent = dget_parent(dentry);
  21251. + bstart = au_dbstart(parent);
  21252. + bend = au_dbtaildir(parent);
  21253. + if (bstart == bend)
  21254. + goto out_parent; /* success */
  21255. +
  21256. + e2 = au_wbr_create_mfs(dentry, isdir);
  21257. + if (e2 < 0)
  21258. + goto out_parent; /* success */
  21259. +
  21260. + /* when the available size is equal, select upper one */
  21261. + sb = dentry->d_sb;
  21262. + br = au_sbr(sb, err);
  21263. + b = br->br_wbr->wbr_bytes;
  21264. + AuDbg("b%d, %llu\n", err, b);
  21265. +
  21266. + for (bindex = bstart; bindex <= bend; bindex++) {
  21267. + h_parent = au_h_dptr(parent, bindex);
  21268. + if (!h_parent || !h_parent->d_inode)
  21269. + continue;
  21270. +
  21271. + br = au_sbr(sb, bindex);
  21272. + if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
  21273. + b = br->br_wbr->wbr_bytes;
  21274. + err = bindex;
  21275. + AuDbg("b%d, %llu\n", err, b);
  21276. + }
  21277. + }
  21278. +
  21279. + out_parent:
  21280. + dput(parent);
  21281. + out:
  21282. + AuDbg("b%d\n", err);
  21283. + return err;
  21284. +}
  21285. +
  21286. +/* ---------------------------------------------------------------------- */
  21287. +
  21288. +/* policies for copyup */
  21289. +
  21290. +/* top down parent */
  21291. +static int au_wbr_copyup_tdp(struct dentry *dentry)
  21292. +{
  21293. + return au_wbr_create_tdp(dentry, /*isdir, anything is ok*/0);
  21294. +}
  21295. +
  21296. +/* bottom up parent */
  21297. +static int au_wbr_copyup_bup(struct dentry *dentry)
  21298. +{
  21299. + int err;
  21300. + aufs_bindex_t bindex, bstart;
  21301. + struct dentry *parent, *h_parent;
  21302. + struct super_block *sb;
  21303. +
  21304. + err = -EROFS;
  21305. + sb = dentry->d_sb;
  21306. + parent = dget_parent(dentry);
  21307. + bstart = au_dbstart(parent);
  21308. + for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) {
  21309. + h_parent = au_h_dptr(parent, bindex);
  21310. + if (!h_parent || !h_parent->d_inode)
  21311. + continue;
  21312. +
  21313. + if (!au_br_rdonly(au_sbr(sb, bindex))) {
  21314. + err = bindex;
  21315. + break;
  21316. + }
  21317. + }
  21318. + dput(parent);
  21319. +
  21320. + /* bottom up here */
  21321. + if (unlikely(err < 0))
  21322. + err = au_wbr_bu(sb, bstart - 1);
  21323. +
  21324. + AuDbg("b%d\n", err);
  21325. + return err;
  21326. +}
  21327. +
  21328. +/* bottom up */
  21329. +static int au_wbr_copyup_bu(struct dentry *dentry)
  21330. +{
  21331. + int err;
  21332. +
  21333. + err = au_wbr_bu(dentry->d_sb, au_dbstart(dentry));
  21334. +
  21335. + AuDbg("b%d\n", err);
  21336. + return err;
  21337. +}
  21338. +
  21339. +/* ---------------------------------------------------------------------- */
  21340. +
  21341. +struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
  21342. + [AuWbrCopyup_TDP] = {
  21343. + .copyup = au_wbr_copyup_tdp
  21344. + },
  21345. + [AuWbrCopyup_BUP] = {
  21346. + .copyup = au_wbr_copyup_bup
  21347. + },
  21348. + [AuWbrCopyup_BU] = {
  21349. + .copyup = au_wbr_copyup_bu
  21350. + }
  21351. +};
  21352. +
  21353. +struct au_wbr_create_operations au_wbr_create_ops[] = {
  21354. + [AuWbrCreate_TDP] = {
  21355. + .create = au_wbr_create_tdp
  21356. + },
  21357. + [AuWbrCreate_RR] = {
  21358. + .create = au_wbr_create_rr,
  21359. + .init = au_wbr_create_init_rr
  21360. + },
  21361. + [AuWbrCreate_MFS] = {
  21362. + .create = au_wbr_create_mfs,
  21363. + .init = au_wbr_create_init_mfs,
  21364. + .fin = au_wbr_create_fin_mfs
  21365. + },
  21366. + [AuWbrCreate_MFSV] = {
  21367. + .create = au_wbr_create_mfs,
  21368. + .init = au_wbr_create_init_mfs,
  21369. + .fin = au_wbr_create_fin_mfs
  21370. + },
  21371. + [AuWbrCreate_MFSRR] = {
  21372. + .create = au_wbr_create_mfsrr,
  21373. + .init = au_wbr_create_init_mfsrr,
  21374. + .fin = au_wbr_create_fin_mfs
  21375. + },
  21376. + [AuWbrCreate_MFSRRV] = {
  21377. + .create = au_wbr_create_mfsrr,
  21378. + .init = au_wbr_create_init_mfsrr,
  21379. + .fin = au_wbr_create_fin_mfs
  21380. + },
  21381. + [AuWbrCreate_PMFS] = {
  21382. + .create = au_wbr_create_pmfs,
  21383. + .init = au_wbr_create_init_mfs,
  21384. + .fin = au_wbr_create_fin_mfs
  21385. + },
  21386. + [AuWbrCreate_PMFSV] = {
  21387. + .create = au_wbr_create_pmfs,
  21388. + .init = au_wbr_create_init_mfs,
  21389. + .fin = au_wbr_create_fin_mfs
  21390. + }
  21391. +};
  21392. diff -Nur linux-2.6.31.5.orig/fs/aufs/whout.c linux-2.6.31.5/fs/aufs/whout.c
  21393. --- linux-2.6.31.5.orig/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100
  21394. +++ linux-2.6.31.5/fs/aufs/whout.c 2009-11-15 22:02:37.000000000 +0100
  21395. @@ -0,0 +1,1048 @@
  21396. +/*
  21397. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  21398. + *
  21399. + * This program, aufs is free software; you can redistribute it and/or modify
  21400. + * it under the terms of the GNU General Public License as published by
  21401. + * the Free Software Foundation; either version 2 of the License, or
  21402. + * (at your option) any later version.
  21403. + *
  21404. + * This program is distributed in the hope that it will be useful,
  21405. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21406. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21407. + * GNU General Public License for more details.
  21408. + *
  21409. + * You should have received a copy of the GNU General Public License
  21410. + * along with this program; if not, write to the Free Software
  21411. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  21412. + */
  21413. +
  21414. +/*
  21415. + * whiteout for logical deletion and opaque directory
  21416. + */
  21417. +
  21418. +#include <linux/fs.h>
  21419. +#include "aufs.h"
  21420. +
  21421. +#define WH_MASK S_IRUGO
  21422. +
  21423. +/*
  21424. + * If a directory contains this file, then it is opaque. We start with the
  21425. + * .wh. flag so that it is blocked by lookup.
  21426. + */
  21427. +static struct qstr diropq_name = {
  21428. + .name = AUFS_WH_DIROPQ,
  21429. + .len = sizeof(AUFS_WH_DIROPQ) - 1
  21430. +};
  21431. +
  21432. +/*
  21433. + * generate whiteout name, which is NOT terminated by NULL.
  21434. + * @name: original d_name.name
  21435. + * @len: original d_name.len
  21436. + * @wh: whiteout qstr
  21437. + * returns zero when succeeds, otherwise error.
  21438. + * succeeded value as wh->name should be freed by kfree().
  21439. + */
  21440. +int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
  21441. +{
  21442. + char *p;
  21443. +
  21444. + if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
  21445. + return -ENAMETOOLONG;
  21446. +
  21447. + wh->len = name->len + AUFS_WH_PFX_LEN;
  21448. + p = kmalloc(wh->len, GFP_NOFS);
  21449. + wh->name = p;
  21450. + if (p) {
  21451. + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
  21452. + memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
  21453. + /* smp_mb(); */
  21454. + return 0;
  21455. + }
  21456. + return -ENOMEM;
  21457. +}
  21458. +
  21459. +/* ---------------------------------------------------------------------- */
  21460. +
  21461. +/*
  21462. + * test if the @wh_name exists under @h_parent.
  21463. + * @try_sio specifies the necessary of super-io.
  21464. + */
  21465. +int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
  21466. + struct au_branch *br, int try_sio)
  21467. +{
  21468. + int err;
  21469. + struct dentry *wh_dentry;
  21470. + struct inode *h_dir;
  21471. +
  21472. + h_dir = h_parent->d_inode;
  21473. + if (!try_sio)
  21474. + wh_dentry = au_lkup_one(wh_name, h_parent, br, /*nd*/NULL);
  21475. + else
  21476. + wh_dentry = au_sio_lkup_one(wh_name, h_parent, br);
  21477. + err = PTR_ERR(wh_dentry);
  21478. + if (IS_ERR(wh_dentry))
  21479. + goto out;
  21480. +
  21481. + err = 0;
  21482. + if (!wh_dentry->d_inode)
  21483. + goto out_wh; /* success */
  21484. +
  21485. + err = 1;
  21486. + if (S_ISREG(wh_dentry->d_inode->i_mode))
  21487. + goto out_wh; /* success */
  21488. +
  21489. + err = -EIO;
  21490. + AuIOErr("%.*s Invalid whiteout entry type 0%o.\n",
  21491. + AuDLNPair(wh_dentry), wh_dentry->d_inode->i_mode);
  21492. +
  21493. + out_wh:
  21494. + dput(wh_dentry);
  21495. + out:
  21496. + return err;
  21497. +}
  21498. +
  21499. +/*
  21500. + * test if the @h_dentry sets opaque or not.
  21501. + */
  21502. +int au_diropq_test(struct dentry *h_dentry, struct au_branch *br)
  21503. +{
  21504. + int err;
  21505. + struct inode *h_dir;
  21506. +
  21507. + h_dir = h_dentry->d_inode;
  21508. + err = au_wh_test(h_dentry, &diropq_name, br,
  21509. + au_test_h_perm_sio(h_dir, MAY_EXEC));
  21510. + return err;
  21511. +}
  21512. +
  21513. +/*
  21514. + * returns a negative dentry whose name is unique and temporary.
  21515. + */
  21516. +struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
  21517. + struct qstr *prefix)
  21518. +{
  21519. +#define HEX_LEN 4
  21520. + struct dentry *dentry;
  21521. + int i;
  21522. + char defname[AUFS_WH_PFX_LEN * 2 + DNAME_INLINE_LEN_MIN + 1
  21523. + + HEX_LEN + 1], *name, *p;
  21524. + static unsigned short cnt;
  21525. + struct qstr qs;
  21526. +
  21527. + name = defname;
  21528. + qs.len = sizeof(defname) - DNAME_INLINE_LEN_MIN + prefix->len - 1;
  21529. + if (unlikely(prefix->len > DNAME_INLINE_LEN_MIN)) {
  21530. + dentry = ERR_PTR(-ENAMETOOLONG);
  21531. + if (unlikely(qs.len >= PATH_MAX))
  21532. + goto out;
  21533. + dentry = ERR_PTR(-ENOMEM);
  21534. + name = kmalloc(qs.len + 1, GFP_NOFS);
  21535. + if (unlikely(!name))
  21536. + goto out;
  21537. + }
  21538. +
  21539. + /* doubly whiteout-ed */
  21540. + memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
  21541. + p = name + AUFS_WH_PFX_LEN * 2;
  21542. + memcpy(p, prefix->name, prefix->len);
  21543. + p += prefix->len;
  21544. + *p++ = '.';
  21545. + AuDebugOn(name + qs.len + 1 - p <= HEX_LEN);
  21546. +
  21547. + qs.name = name;
  21548. + for (i = 0; i < 3; i++) {
  21549. + sprintf(p, "%.*d", HEX_LEN, cnt++);
  21550. + dentry = au_sio_lkup_one(&qs, h_parent, br);
  21551. + if (IS_ERR(dentry) || !dentry->d_inode)
  21552. + goto out_name;
  21553. + dput(dentry);
  21554. + }
  21555. + /* AuWarn("could not get random name\n"); */
  21556. + dentry = ERR_PTR(-EEXIST);
  21557. + AuDbg("%.*s\n", AuLNPair(&qs));
  21558. + BUG();
  21559. +
  21560. + out_name:
  21561. + if (name != defname)
  21562. + kfree(name);
  21563. + out:
  21564. + return dentry;
  21565. +#undef HEX_LEN
  21566. +}
  21567. +
  21568. +/*
  21569. + * rename the @h_dentry on @br to the whiteouted temporary name.
  21570. + */
  21571. +int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
  21572. +{
  21573. + int err;
  21574. + struct path h_path = {
  21575. + .mnt = br->br_mnt
  21576. + };
  21577. + struct inode *h_dir;
  21578. + struct dentry *h_parent;
  21579. +
  21580. + h_parent = h_dentry->d_parent; /* dir inode is locked */
  21581. + h_dir = h_parent->d_inode;
  21582. + IMustLock(h_dir);
  21583. +
  21584. + h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
  21585. + err = PTR_ERR(h_path.dentry);
  21586. + if (IS_ERR(h_path.dentry))
  21587. + goto out;
  21588. +
  21589. + /* under the same dir, no need to lock_rename() */
  21590. + err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path);
  21591. + AuTraceErr(err);
  21592. + dput(h_path.dentry);
  21593. +
  21594. + out:
  21595. + return err;
  21596. +}
  21597. +
  21598. +/* ---------------------------------------------------------------------- */
  21599. +/*
  21600. + * functions for removing a whiteout
  21601. + */
  21602. +
  21603. +static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
  21604. +{
  21605. + int force;
  21606. +
  21607. + /*
  21608. + * forces superio when the dir has a sticky bit.
  21609. + * this may be a violation of unix fs semantics.
  21610. + */
  21611. + force = (h_dir->i_mode & S_ISVTX)
  21612. + && h_path->dentry->d_inode->i_uid != current_fsuid();
  21613. + return vfsub_unlink(h_dir, h_path, force);
  21614. +}
  21615. +
  21616. +int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
  21617. + struct dentry *dentry)
  21618. +{
  21619. + int err;
  21620. +
  21621. + err = do_unlink_wh(h_dir, h_path);
  21622. + if (!err && dentry)
  21623. + au_set_dbwh(dentry, -1);
  21624. +
  21625. + return err;
  21626. +}
  21627. +
  21628. +static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
  21629. + struct au_branch *br)
  21630. +{
  21631. + int err;
  21632. + struct path h_path = {
  21633. + .mnt = br->br_mnt
  21634. + };
  21635. +
  21636. + err = 0;
  21637. + h_path.dentry = au_lkup_one(wh, h_parent, br, /*nd*/NULL);
  21638. + if (IS_ERR(h_path.dentry))
  21639. + err = PTR_ERR(h_path.dentry);
  21640. + else {
  21641. + if (h_path.dentry->d_inode
  21642. + && S_ISREG(h_path.dentry->d_inode->i_mode))
  21643. + err = do_unlink_wh(h_parent->d_inode, &h_path);
  21644. + dput(h_path.dentry);
  21645. + }
  21646. +
  21647. + return err;
  21648. +}
  21649. +
  21650. +/* ---------------------------------------------------------------------- */
  21651. +/*
  21652. + * initialize/clean whiteout for a branch
  21653. + */
  21654. +
  21655. +static void au_wh_clean(struct inode *h_dir, struct path *whpath,
  21656. + const int isdir)
  21657. +{
  21658. + int err;
  21659. +
  21660. + if (!whpath->dentry->d_inode)
  21661. + return;
  21662. +
  21663. + err = mnt_want_write(whpath->mnt);
  21664. + if (!err) {
  21665. + if (isdir)
  21666. + err = vfsub_rmdir(h_dir, whpath);
  21667. + else
  21668. + err = vfsub_unlink(h_dir, whpath, /*force*/0);
  21669. + mnt_drop_write(whpath->mnt);
  21670. + }
  21671. + if (unlikely(err))
  21672. + AuWarn("failed removing %.*s (%d), ignored.\n",
  21673. + AuDLNPair(whpath->dentry), err);
  21674. +}
  21675. +
  21676. +static int test_linkable(struct dentry *h_root)
  21677. +{
  21678. + struct inode *h_dir = h_root->d_inode;
  21679. +
  21680. + if (h_dir->i_op->link)
  21681. + return 0;
  21682. +
  21683. + AuErr("%.*s (%s) doesn't support link(2), use noplink and rw+nolwh\n",
  21684. + AuDLNPair(h_root), au_sbtype(h_root->d_sb));
  21685. + return -ENOSYS;
  21686. +}
  21687. +
  21688. +/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
  21689. +static int au_whdir(struct inode *h_dir, struct path *path)
  21690. +{
  21691. + int err;
  21692. +
  21693. + err = -EEXIST;
  21694. + if (!path->dentry->d_inode) {
  21695. + int mode = S_IRWXU;
  21696. +
  21697. + if (au_test_nfs(path->dentry->d_sb))
  21698. + mode |= S_IXUGO;
  21699. + err = mnt_want_write(path->mnt);
  21700. + if (!err) {
  21701. + err = vfsub_mkdir(h_dir, path, mode);
  21702. + mnt_drop_write(path->mnt);
  21703. + }
  21704. + } else if (S_ISDIR(path->dentry->d_inode->i_mode))
  21705. + err = 0;
  21706. + else
  21707. + AuErr("unknown %.*s exists\n", AuDLNPair(path->dentry));
  21708. +
  21709. + return err;
  21710. +}
  21711. +
  21712. +struct au_wh_base {
  21713. + const struct qstr *name;
  21714. + struct dentry *dentry;
  21715. +};
  21716. +
  21717. +static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
  21718. + struct path *h_path)
  21719. +{
  21720. + h_path->dentry = base[AuBrWh_BASE].dentry;
  21721. + au_wh_clean(h_dir, h_path, /*isdir*/0);
  21722. + h_path->dentry = base[AuBrWh_PLINK].dentry;
  21723. + au_wh_clean(h_dir, h_path, /*isdir*/1);
  21724. + h_path->dentry = base[AuBrWh_ORPH].dentry;
  21725. + au_wh_clean(h_dir, h_path, /*isdir*/1);
  21726. +}
  21727. +
  21728. +/*
  21729. + * returns tri-state,
  21730. + * minus: error, caller should print the mesage
  21731. + * zero: succuess
  21732. + * plus: error, caller should NOT print the mesage
  21733. + */
  21734. +static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
  21735. + int do_plink, struct au_wh_base base[],
  21736. + struct path *h_path)
  21737. +{
  21738. + int err;
  21739. + struct inode *h_dir;
  21740. +
  21741. + h_dir = h_root->d_inode;
  21742. + h_path->dentry = base[AuBrWh_BASE].dentry;
  21743. + au_wh_clean(h_dir, h_path, /*isdir*/0);
  21744. + h_path->dentry = base[AuBrWh_PLINK].dentry;
  21745. + if (do_plink) {
  21746. + err = test_linkable(h_root);
  21747. + if (unlikely(err)) {
  21748. + err = 1;
  21749. + goto out;
  21750. + }
  21751. +
  21752. + err = au_whdir(h_dir, h_path);
  21753. + if (unlikely(err))
  21754. + goto out;
  21755. + wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
  21756. + } else
  21757. + au_wh_clean(h_dir, h_path, /*isdir*/1);
  21758. + h_path->dentry = base[AuBrWh_ORPH].dentry;
  21759. + err = au_whdir(h_dir, h_path);
  21760. + if (unlikely(err))
  21761. + goto out;
  21762. + wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
  21763. +
  21764. + out:
  21765. + return err;
  21766. +}
  21767. +
  21768. +/*
  21769. + * for the moment, aufs supports the branch filesystem which does not support
  21770. + * link(2). testing on FAT which does not support i_op->setattr() fully either,
  21771. + * copyup failed. finally, such filesystem will not be used as the writable
  21772. + * branch.
  21773. + *
  21774. + * returns tri-state, see above.
  21775. + */
  21776. +static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
  21777. + int do_plink, struct au_wh_base base[],
  21778. + struct path *h_path)
  21779. +{
  21780. + int err;
  21781. + struct inode *h_dir;
  21782. +
  21783. + WbrWhMustWriteLock(wbr);
  21784. +
  21785. + err = test_linkable(h_root);
  21786. + if (unlikely(err)) {
  21787. + err = 1;
  21788. + goto out;
  21789. + }
  21790. +
  21791. + /*
  21792. + * todo: should this create be done in /sbin/mount.aufs helper?
  21793. + */
  21794. + err = -EEXIST;
  21795. + h_dir = h_root->d_inode;
  21796. + if (!base[AuBrWh_BASE].dentry->d_inode) {
  21797. + err = mnt_want_write(h_path->mnt);
  21798. + if (!err) {
  21799. + h_path->dentry = base[AuBrWh_BASE].dentry;
  21800. + err = vfsub_create(h_dir, h_path, WH_MASK);
  21801. + mnt_drop_write(h_path->mnt);
  21802. + }
  21803. + } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode))
  21804. + err = 0;
  21805. + else
  21806. + AuErr("unknown %.*s/%.*s exists\n",
  21807. + AuDLNPair(h_root), AuDLNPair(base[AuBrWh_BASE].dentry));
  21808. + if (unlikely(err))
  21809. + goto out;
  21810. +
  21811. + h_path->dentry = base[AuBrWh_PLINK].dentry;
  21812. + if (do_plink) {
  21813. + err = au_whdir(h_dir, h_path);
  21814. + if (unlikely(err))
  21815. + goto out;
  21816. + wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
  21817. + } else
  21818. + au_wh_clean(h_dir, h_path, /*isdir*/1);
  21819. + wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
  21820. +
  21821. + h_path->dentry = base[AuBrWh_ORPH].dentry;
  21822. + err = au_whdir(h_dir, h_path);
  21823. + if (unlikely(err))
  21824. + goto out;
  21825. + wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
  21826. +
  21827. + out:
  21828. + return err;
  21829. +}
  21830. +
  21831. +/*
  21832. + * initialize the whiteout base file/dir for @br.
  21833. + */
  21834. +int au_wh_init(struct dentry *h_root, struct au_branch *br,
  21835. + struct super_block *sb)
  21836. +{
  21837. + int err, i;
  21838. + const unsigned char do_plink
  21839. + = !!au_opt_test(au_mntflags(sb), PLINK);
  21840. + struct path path = {
  21841. + .mnt = br->br_mnt
  21842. + };
  21843. + struct inode *h_dir;
  21844. + struct au_wbr *wbr = br->br_wbr;
  21845. + static const struct qstr base_name[] = {
  21846. + [AuBrWh_BASE] = {
  21847. + .name = AUFS_BASE_NAME,
  21848. + .len = sizeof(AUFS_BASE_NAME) - 1
  21849. + },
  21850. + [AuBrWh_PLINK] = {
  21851. + .name = AUFS_PLINKDIR_NAME,
  21852. + .len = sizeof(AUFS_PLINKDIR_NAME) - 1
  21853. + },
  21854. + [AuBrWh_ORPH] = {
  21855. + .name = AUFS_ORPHDIR_NAME,
  21856. + .len = sizeof(AUFS_ORPHDIR_NAME) - 1
  21857. + }
  21858. + };
  21859. + struct au_wh_base base[] = {
  21860. + [AuBrWh_BASE] = {
  21861. + .name = base_name + AuBrWh_BASE,
  21862. + .dentry = NULL
  21863. + },
  21864. + [AuBrWh_PLINK] = {
  21865. + .name = base_name + AuBrWh_PLINK,
  21866. + .dentry = NULL
  21867. + },
  21868. + [AuBrWh_ORPH] = {
  21869. + .name = base_name + AuBrWh_ORPH,
  21870. + .dentry = NULL
  21871. + }
  21872. + };
  21873. +
  21874. + if (wbr)
  21875. + WbrWhMustWriteLock(wbr);
  21876. +
  21877. + h_dir = h_root->d_inode;
  21878. + for (i = 0; i < AuBrWh_Last; i++) {
  21879. + /* doubly whiteouted */
  21880. + struct dentry *d;
  21881. +
  21882. + d = au_wh_lkup(h_root, (void *)base[i].name, br);
  21883. + err = PTR_ERR(d);
  21884. + if (IS_ERR(d))
  21885. + goto out;
  21886. +
  21887. + base[i].dentry = d;
  21888. + AuDebugOn(wbr
  21889. + && wbr->wbr_wh[i]
  21890. + && wbr->wbr_wh[i] != base[i].dentry);
  21891. + }
  21892. +
  21893. + if (wbr)
  21894. + for (i = 0; i < AuBrWh_Last; i++) {
  21895. + dput(wbr->wbr_wh[i]);
  21896. + wbr->wbr_wh[i] = NULL;
  21897. + }
  21898. +
  21899. + err = 0;
  21900. +
  21901. + switch (br->br_perm) {
  21902. + case AuBrPerm_RO:
  21903. + case AuBrPerm_ROWH:
  21904. + case AuBrPerm_RR:
  21905. + case AuBrPerm_RRWH:
  21906. + au_wh_init_ro(h_dir, base, &path);
  21907. + break;
  21908. +
  21909. + case AuBrPerm_RWNoLinkWH:
  21910. + err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
  21911. + if (err > 0)
  21912. + goto out;
  21913. + else if (err)
  21914. + goto out_err;
  21915. + break;
  21916. +
  21917. + case AuBrPerm_RW:
  21918. + err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
  21919. + if (err > 0)
  21920. + goto out;
  21921. + else if (err)
  21922. + goto out_err;
  21923. + break;
  21924. +
  21925. + default:
  21926. + BUG();
  21927. + }
  21928. + goto out; /* success */
  21929. +
  21930. + out_err:
  21931. + AuErr("an error(%d) on the writable branch %.*s(%s)\n",
  21932. + err, AuDLNPair(h_root), au_sbtype(h_root->d_sb));
  21933. + out:
  21934. + for (i = 0; i < AuBrWh_Last; i++)
  21935. + dput(base[i].dentry);
  21936. + return err;
  21937. +}
  21938. +
  21939. +/* ---------------------------------------------------------------------- */
  21940. +/*
  21941. + * whiteouts are all hard-linked usually.
  21942. + * when its link count reaches a ceiling, we create a new whiteout base
  21943. + * asynchronously.
  21944. + */
  21945. +
  21946. +struct reinit_br_wh {
  21947. + struct super_block *sb;
  21948. + struct au_branch *br;
  21949. +};
  21950. +
  21951. +static void reinit_br_wh(void *arg)
  21952. +{
  21953. + int err;
  21954. + aufs_bindex_t bindex;
  21955. + struct path h_path;
  21956. + struct reinit_br_wh *a = arg;
  21957. + struct au_wbr *wbr;
  21958. + struct inode *dir;
  21959. + struct dentry *h_root;
  21960. + struct au_hinode *hdir;
  21961. +
  21962. + err = 0;
  21963. + wbr = a->br->br_wbr;
  21964. + /* big aufs lock */
  21965. + si_noflush_write_lock(a->sb);
  21966. + if (!au_br_writable(a->br->br_perm))
  21967. + goto out;
  21968. + bindex = au_br_index(a->sb, a->br->br_id);
  21969. + if (unlikely(bindex < 0))
  21970. + goto out;
  21971. +
  21972. + di_read_lock_parent(a->sb->s_root, AuLock_IR);
  21973. + dir = a->sb->s_root->d_inode;
  21974. + hdir = au_hi(dir, bindex);
  21975. + h_root = au_h_dptr(a->sb->s_root, bindex);
  21976. +
  21977. + au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT);
  21978. + wbr_wh_write_lock(wbr);
  21979. + err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
  21980. + h_root, a->br);
  21981. + if (!err) {
  21982. + err = mnt_want_write(a->br->br_mnt);
  21983. + if (!err) {
  21984. + h_path.dentry = wbr->wbr_whbase;
  21985. + h_path.mnt = a->br->br_mnt;
  21986. + err = vfsub_unlink(hdir->hi_inode, &h_path, /*force*/0);
  21987. + mnt_drop_write(a->br->br_mnt);
  21988. + }
  21989. + } else {
  21990. + AuWarn("%.*s is moved, ignored\n", AuDLNPair(wbr->wbr_whbase));
  21991. + err = 0;
  21992. + }
  21993. + dput(wbr->wbr_whbase);
  21994. + wbr->wbr_whbase = NULL;
  21995. + if (!err)
  21996. + err = au_wh_init(h_root, a->br, a->sb);
  21997. + wbr_wh_write_unlock(wbr);
  21998. + au_hin_imtx_unlock(hdir);
  21999. + di_read_unlock(a->sb->s_root, AuLock_IR);
  22000. +
  22001. + out:
  22002. + if (wbr)
  22003. + atomic_dec(&wbr->wbr_wh_running);
  22004. + atomic_dec(&a->br->br_count);
  22005. + au_nwt_done(&au_sbi(a->sb)->si_nowait);
  22006. + si_write_unlock(a->sb);
  22007. + kfree(arg);
  22008. + if (unlikely(err))
  22009. + AuIOErr("err %d\n", err);
  22010. +}
  22011. +
  22012. +static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
  22013. +{
  22014. + int do_dec, wkq_err;
  22015. + struct reinit_br_wh *arg;
  22016. +
  22017. + do_dec = 1;
  22018. + if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
  22019. + goto out;
  22020. +
  22021. + /* ignore ENOMEM */
  22022. + arg = kmalloc(sizeof(*arg), GFP_NOFS);
  22023. + if (arg) {
  22024. + /*
  22025. + * dec(wh_running), kfree(arg) and dec(br_count)
  22026. + * in reinit function
  22027. + */
  22028. + arg->sb = sb;
  22029. + arg->br = br;
  22030. + atomic_inc(&br->br_count);
  22031. + wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb);
  22032. + if (unlikely(wkq_err)) {
  22033. + atomic_dec(&br->br_wbr->wbr_wh_running);
  22034. + atomic_dec(&br->br_count);
  22035. + kfree(arg);
  22036. + }
  22037. + do_dec = 0;
  22038. + }
  22039. +
  22040. + out:
  22041. + if (do_dec)
  22042. + atomic_dec(&br->br_wbr->wbr_wh_running);
  22043. +}
  22044. +
  22045. +/* ---------------------------------------------------------------------- */
  22046. +
  22047. +/*
  22048. + * create the whiteout @wh.
  22049. + */
  22050. +static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
  22051. + struct dentry *wh)
  22052. +{
  22053. + int err;
  22054. + struct path h_path = {
  22055. + .dentry = wh
  22056. + };
  22057. + struct au_branch *br;
  22058. + struct au_wbr *wbr;
  22059. + struct dentry *h_parent;
  22060. + struct inode *h_dir;
  22061. +
  22062. + h_parent = wh->d_parent; /* dir inode is locked */
  22063. + h_dir = h_parent->d_inode;
  22064. + IMustLock(h_dir);
  22065. +
  22066. + br = au_sbr(sb, bindex);
  22067. + h_path.mnt = br->br_mnt;
  22068. + wbr = br->br_wbr;
  22069. + wbr_wh_read_lock(wbr);
  22070. + if (wbr->wbr_whbase) {
  22071. + err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path);
  22072. + if (!err || err != -EMLINK)
  22073. + goto out;
  22074. +
  22075. + /* link count full. re-initialize br_whbase. */
  22076. + kick_reinit_br_wh(sb, br);
  22077. + }
  22078. +
  22079. + /* return this error in this context */
  22080. + err = vfsub_create(h_dir, &h_path, WH_MASK);
  22081. +
  22082. + out:
  22083. + wbr_wh_read_unlock(wbr);
  22084. + return err;
  22085. +}
  22086. +
  22087. +/* ---------------------------------------------------------------------- */
  22088. +
  22089. +/*
  22090. + * create or remove the diropq.
  22091. + */
  22092. +static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
  22093. + unsigned int flags)
  22094. +{
  22095. + struct dentry *opq_dentry, *h_dentry;
  22096. + struct super_block *sb;
  22097. + struct au_branch *br;
  22098. + int err;
  22099. +
  22100. + sb = dentry->d_sb;
  22101. + br = au_sbr(sb, bindex);
  22102. + h_dentry = au_h_dptr(dentry, bindex);
  22103. + opq_dentry = au_lkup_one(&diropq_name, h_dentry, br, /*nd*/NULL);
  22104. + if (IS_ERR(opq_dentry))
  22105. + goto out;
  22106. +
  22107. + if (au_ftest_diropq(flags, CREATE)) {
  22108. + err = link_or_create_wh(sb, bindex, opq_dentry);
  22109. + if (!err) {
  22110. + au_set_dbdiropq(dentry, bindex);
  22111. + goto out; /* success */
  22112. + }
  22113. + } else {
  22114. + struct path tmp = {
  22115. + .dentry = opq_dentry,
  22116. + .mnt = br->br_mnt
  22117. + };
  22118. + err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp);
  22119. + if (!err)
  22120. + au_set_dbdiropq(dentry, -1);
  22121. + }
  22122. + dput(opq_dentry);
  22123. + opq_dentry = ERR_PTR(err);
  22124. +
  22125. + out:
  22126. + return opq_dentry;
  22127. +}
  22128. +
  22129. +struct do_diropq_args {
  22130. + struct dentry **errp;
  22131. + struct dentry *dentry;
  22132. + aufs_bindex_t bindex;
  22133. + unsigned int flags;
  22134. +};
  22135. +
  22136. +static void call_do_diropq(void *args)
  22137. +{
  22138. + struct do_diropq_args *a = args;
  22139. + *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
  22140. +}
  22141. +
  22142. +struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
  22143. + unsigned int flags)
  22144. +{
  22145. + struct dentry *diropq, *h_dentry;
  22146. +
  22147. + h_dentry = au_h_dptr(dentry, bindex);
  22148. + if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE))
  22149. + diropq = do_diropq(dentry, bindex, flags);
  22150. + else {
  22151. + int wkq_err;
  22152. + struct do_diropq_args args = {
  22153. + .errp = &diropq,
  22154. + .dentry = dentry,
  22155. + .bindex = bindex,
  22156. + .flags = flags
  22157. + };
  22158. +
  22159. + wkq_err = au_wkq_wait(call_do_diropq, &args);
  22160. + if (unlikely(wkq_err))
  22161. + diropq = ERR_PTR(wkq_err);
  22162. + }
  22163. +
  22164. + return diropq;
  22165. +}
  22166. +
  22167. +/* ---------------------------------------------------------------------- */
  22168. +
  22169. +/*
  22170. + * lookup whiteout dentry.
  22171. + * @h_parent: lower parent dentry which must exist and be locked
  22172. + * @base_name: name of dentry which will be whiteouted
  22173. + * returns dentry for whiteout.
  22174. + */
  22175. +struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
  22176. + struct au_branch *br)
  22177. +{
  22178. + int err;
  22179. + struct qstr wh_name;
  22180. + struct dentry *wh_dentry;
  22181. +
  22182. + err = au_wh_name_alloc(&wh_name, base_name);
  22183. + wh_dentry = ERR_PTR(err);
  22184. + if (!err) {
  22185. + wh_dentry = au_lkup_one(&wh_name, h_parent, br, /*nd*/NULL);
  22186. + kfree(wh_name.name);
  22187. + }
  22188. + return wh_dentry;
  22189. +}
  22190. +
  22191. +/*
  22192. + * link/create a whiteout for @dentry on @bindex.
  22193. + */
  22194. +struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
  22195. + struct dentry *h_parent)
  22196. +{
  22197. + struct dentry *wh_dentry;
  22198. + struct super_block *sb;
  22199. + int err;
  22200. +
  22201. + sb = dentry->d_sb;
  22202. + wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
  22203. + if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) {
  22204. + err = link_or_create_wh(sb, bindex, wh_dentry);
  22205. + if (!err)
  22206. + au_set_dbwh(dentry, bindex);
  22207. + else {
  22208. + dput(wh_dentry);
  22209. + wh_dentry = ERR_PTR(err);
  22210. + }
  22211. + }
  22212. +
  22213. + return wh_dentry;
  22214. +}
  22215. +
  22216. +/* ---------------------------------------------------------------------- */
  22217. +
  22218. +/* Delete all whiteouts in this directory on branch bindex. */
  22219. +static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
  22220. + aufs_bindex_t bindex, struct au_branch *br)
  22221. +{
  22222. + int err;
  22223. + unsigned long ul, n;
  22224. + struct qstr wh_name;
  22225. + char *p;
  22226. + struct hlist_head *head;
  22227. + struct au_vdir_wh *tpos;
  22228. + struct hlist_node *pos;
  22229. + struct au_vdir_destr *str;
  22230. +
  22231. + err = -ENOMEM;
  22232. + p = __getname();
  22233. + wh_name.name = p;
  22234. + if (unlikely(!wh_name.name))
  22235. + goto out;
  22236. +
  22237. + err = 0;
  22238. + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
  22239. + p += AUFS_WH_PFX_LEN;
  22240. + n = whlist->nh_num;
  22241. + head = whlist->nh_head;
  22242. + for (ul = 0; !err && ul < n; ul++, head++) {
  22243. + hlist_for_each_entry(tpos, pos, head, wh_hash) {
  22244. + if (tpos->wh_bindex != bindex)
  22245. + continue;
  22246. +
  22247. + str = &tpos->wh_str;
  22248. + if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
  22249. + memcpy(p, str->name, str->len);
  22250. + wh_name.len = AUFS_WH_PFX_LEN + str->len;
  22251. + err = unlink_wh_name(h_dentry, &wh_name, br);
  22252. + if (!err)
  22253. + continue;
  22254. + break;
  22255. + }
  22256. + AuIOErr("whiteout name too long %.*s\n",
  22257. + str->len, str->name);
  22258. + err = -EIO;
  22259. + break;
  22260. + }
  22261. + }
  22262. + __putname(wh_name.name);
  22263. +
  22264. + out:
  22265. + return err;
  22266. +}
  22267. +
  22268. +struct del_wh_children_args {
  22269. + int *errp;
  22270. + struct dentry *h_dentry;
  22271. + struct au_nhash whlist;
  22272. + aufs_bindex_t bindex;
  22273. + struct au_branch *br;
  22274. +};
  22275. +
  22276. +static void call_del_wh_children(void *args)
  22277. +{
  22278. + struct del_wh_children_args *a = args;
  22279. + *a->errp = del_wh_children(a->h_dentry, &a->whlist, a->bindex, a->br);
  22280. +}
  22281. +
  22282. +/* ---------------------------------------------------------------------- */
  22283. +
  22284. +struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
  22285. +{
  22286. + struct au_whtmp_rmdir *whtmp;
  22287. + int err;
  22288. +
  22289. + SiMustAnyLock(sb);
  22290. +
  22291. + whtmp = kmalloc(sizeof(*whtmp), gfp);
  22292. + if (unlikely(!whtmp)) {
  22293. + whtmp = ERR_PTR(-ENOMEM);
  22294. + goto out;
  22295. + }
  22296. +
  22297. + whtmp->dir = NULL;
  22298. + whtmp->wh_dentry = NULL;
  22299. + err = au_nhash_alloc(&whtmp->whlist, au_sbi(sb)->si_rdhash, gfp);
  22300. + if (!err)
  22301. + return whtmp; /* success */
  22302. +
  22303. + kfree(whtmp);
  22304. + whtmp = ERR_PTR(err);
  22305. +
  22306. + out:
  22307. + return whtmp;
  22308. +}
  22309. +
  22310. +void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
  22311. +{
  22312. + dput(whtmp->wh_dentry);
  22313. + iput(whtmp->dir);
  22314. + au_nhash_wh_free(&whtmp->whlist);
  22315. + kfree(whtmp);
  22316. +}
  22317. +
  22318. +/*
  22319. + * rmdir the whiteouted temporary named dir @h_dentry.
  22320. + * @whlist: whiteouted children.
  22321. + */
  22322. +int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
  22323. + struct dentry *wh_dentry, struct au_nhash *whlist)
  22324. +{
  22325. + int err;
  22326. + struct path h_tmp;
  22327. + struct inode *wh_inode, *h_dir;
  22328. + struct au_branch *br;
  22329. +
  22330. + h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
  22331. + IMustLock(h_dir);
  22332. +
  22333. + br = au_sbr(dir->i_sb, bindex);
  22334. + wh_inode = wh_dentry->d_inode;
  22335. + mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
  22336. +
  22337. + /*
  22338. + * someone else might change some whiteouts while we were sleeping.
  22339. + * it means this whlist may have an obsoleted entry.
  22340. + */
  22341. + if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
  22342. + err = del_wh_children(wh_dentry, whlist, bindex, br);
  22343. + else {
  22344. + int wkq_err;
  22345. + struct del_wh_children_args args = {
  22346. + .errp = &err,
  22347. + .h_dentry = wh_dentry,
  22348. + .whlist = *whlist,
  22349. + .bindex = bindex,
  22350. + .br = br
  22351. + };
  22352. +
  22353. + wkq_err = au_wkq_wait(call_del_wh_children, &args);
  22354. + if (unlikely(wkq_err))
  22355. + err = wkq_err;
  22356. + }
  22357. + mutex_unlock(&wh_inode->i_mutex);
  22358. +
  22359. + if (!err) {
  22360. + h_tmp.dentry = wh_dentry;
  22361. + h_tmp.mnt = br->br_mnt;
  22362. + err = vfsub_rmdir(h_dir, &h_tmp);
  22363. + /* d_drop(h_dentry); */
  22364. + }
  22365. +
  22366. + if (!err) {
  22367. + if (au_ibstart(dir) == bindex) {
  22368. + au_cpup_attr_timesizes(dir);
  22369. + drop_nlink(dir);
  22370. + }
  22371. + return 0; /* success */
  22372. + }
  22373. +
  22374. + AuWarn("failed removing %.*s(%d), ignored\n",
  22375. + AuDLNPair(wh_dentry), err);
  22376. + return err;
  22377. +}
  22378. +
  22379. +static void call_rmdir_whtmp(void *args)
  22380. +{
  22381. + int err;
  22382. + struct au_whtmp_rmdir *a = args;
  22383. + struct super_block *sb;
  22384. + struct dentry *h_parent;
  22385. + struct inode *h_dir;
  22386. + struct au_branch *br;
  22387. + struct au_hinode *hdir;
  22388. +
  22389. + /* rmdir by nfsd may cause deadlock with this i_mutex */
  22390. + /* mutex_lock(&a->dir->i_mutex); */
  22391. + sb = a->dir->i_sb;
  22392. + si_noflush_read_lock(sb);
  22393. + err = au_test_ro(sb, a->bindex, NULL);
  22394. + if (unlikely(err))
  22395. + goto out;
  22396. +
  22397. + err = -EIO;
  22398. + br = au_sbr(sb, a->bindex);
  22399. + ii_write_lock_parent(a->dir);
  22400. + h_parent = dget_parent(a->wh_dentry);
  22401. + h_dir = h_parent->d_inode;
  22402. + hdir = au_hi(a->dir, a->bindex);
  22403. + au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT);
  22404. + err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent, br);
  22405. + if (!err) {
  22406. + err = mnt_want_write(br->br_mnt);
  22407. + if (!err) {
  22408. + err = au_whtmp_rmdir(a->dir, a->bindex, a->wh_dentry,
  22409. + &a->whlist);
  22410. + mnt_drop_write(br->br_mnt);
  22411. + }
  22412. + }
  22413. + au_hin_imtx_unlock(hdir);
  22414. + dput(h_parent);
  22415. + ii_write_unlock(a->dir);
  22416. +
  22417. + out:
  22418. + /* mutex_unlock(&a->dir->i_mutex); */
  22419. + au_nwt_done(&au_sbi(sb)->si_nowait);
  22420. + si_read_unlock(sb);
  22421. + au_whtmp_rmdir_free(a);
  22422. + if (unlikely(err))
  22423. + AuIOErr("err %d\n", err);
  22424. +}
  22425. +
  22426. +void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
  22427. + struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
  22428. +{
  22429. + int wkq_err;
  22430. +
  22431. + IMustLock(dir);
  22432. +
  22433. + /* all post-process will be done in do_rmdir_whtmp(). */
  22434. + args->dir = au_igrab(dir);
  22435. + args->bindex = bindex;
  22436. + args->wh_dentry = dget(wh_dentry);
  22437. + wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, dir->i_sb);
  22438. + if (unlikely(wkq_err)) {
  22439. + AuWarn("rmdir error %.*s (%d), ignored\n",
  22440. + AuDLNPair(wh_dentry), wkq_err);
  22441. + au_whtmp_rmdir_free(args);
  22442. + }
  22443. +}
  22444. diff -Nur linux-2.6.31.5.orig/fs/aufs/whout.h linux-2.6.31.5/fs/aufs/whout.h
  22445. --- linux-2.6.31.5.orig/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100
  22446. +++ linux-2.6.31.5/fs/aufs/whout.h 2009-11-15 22:02:37.000000000 +0100
  22447. @@ -0,0 +1,87 @@
  22448. +/*
  22449. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  22450. + *
  22451. + * This program, aufs is free software; you can redistribute it and/or modify
  22452. + * it under the terms of the GNU General Public License as published by
  22453. + * the Free Software Foundation; either version 2 of the License, or
  22454. + * (at your option) any later version.
  22455. + *
  22456. + * This program is distributed in the hope that it will be useful,
  22457. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22458. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22459. + * GNU General Public License for more details.
  22460. + *
  22461. + * You should have received a copy of the GNU General Public License
  22462. + * along with this program; if not, write to the Free Software
  22463. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22464. + */
  22465. +
  22466. +/*
  22467. + * whiteout for logical deletion and opaque directory
  22468. + */
  22469. +
  22470. +#ifndef __AUFS_WHOUT_H__
  22471. +#define __AUFS_WHOUT_H__
  22472. +
  22473. +#ifdef __KERNEL__
  22474. +
  22475. +#include <linux/aufs_type.h>
  22476. +#include "dir.h"
  22477. +
  22478. +/* whout.c */
  22479. +int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
  22480. +struct au_branch;
  22481. +int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
  22482. + struct au_branch *br, int try_sio);
  22483. +int au_diropq_test(struct dentry *h_dentry, struct au_branch *br);
  22484. +struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
  22485. + struct qstr *prefix);
  22486. +int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
  22487. +int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
  22488. + struct dentry *dentry);
  22489. +int au_wh_init(struct dentry *h_parent, struct au_branch *br,
  22490. + struct super_block *sb);
  22491. +
  22492. +/* diropq flags */
  22493. +#define AuDiropq_CREATE 1
  22494. +#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name)
  22495. +#define au_fset_diropq(flags, name) { (flags) |= AuDiropq_##name; }
  22496. +#define au_fclr_diropq(flags, name) { (flags) &= ~AuDiropq_##name; }
  22497. +
  22498. +struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
  22499. + unsigned int flags);
  22500. +struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
  22501. + struct au_branch *br);
  22502. +struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
  22503. + struct dentry *h_parent);
  22504. +
  22505. +/* real rmdir for the whiteout-ed dir */
  22506. +struct au_whtmp_rmdir {
  22507. + struct inode *dir;
  22508. + aufs_bindex_t bindex;
  22509. + struct dentry *wh_dentry;
  22510. + struct au_nhash whlist;
  22511. +};
  22512. +
  22513. +struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
  22514. +void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
  22515. +int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
  22516. + struct dentry *wh_dentry, struct au_nhash *whlist);
  22517. +void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
  22518. + struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
  22519. +
  22520. +/* ---------------------------------------------------------------------- */
  22521. +
  22522. +static inline struct dentry *au_diropq_create(struct dentry *dentry,
  22523. + aufs_bindex_t bindex)
  22524. +{
  22525. + return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
  22526. +}
  22527. +
  22528. +static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
  22529. +{
  22530. + return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
  22531. +}
  22532. +
  22533. +#endif /* __KERNEL__ */
  22534. +#endif /* __AUFS_WHOUT_H__ */
  22535. diff -Nur linux-2.6.31.5.orig/fs/aufs/wkq.c linux-2.6.31.5/fs/aufs/wkq.c
  22536. --- linux-2.6.31.5.orig/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100
  22537. +++ linux-2.6.31.5/fs/aufs/wkq.c 2009-11-15 22:02:37.000000000 +0100
  22538. @@ -0,0 +1,259 @@
  22539. +/*
  22540. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  22541. + *
  22542. + * This program, aufs is free software; you can redistribute it and/or modify
  22543. + * it under the terms of the GNU General Public License as published by
  22544. + * the Free Software Foundation; either version 2 of the License, or
  22545. + * (at your option) any later version.
  22546. + *
  22547. + * This program is distributed in the hope that it will be useful,
  22548. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22549. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22550. + * GNU General Public License for more details.
  22551. + *
  22552. + * You should have received a copy of the GNU General Public License
  22553. + * along with this program; if not, write to the Free Software
  22554. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22555. + */
  22556. +
  22557. +/*
  22558. + * workqueue for asynchronous/super-io operations
  22559. + * todo: try new dredential scheme
  22560. + */
  22561. +
  22562. +#include <linux/module.h>
  22563. +#include "aufs.h"
  22564. +
  22565. +/* internal workqueue named AUFS_WKQ_NAME */
  22566. +static struct au_wkq {
  22567. + struct workqueue_struct *q;
  22568. +
  22569. + /* balancing */
  22570. + atomic_t busy;
  22571. +} *au_wkq;
  22572. +
  22573. +struct au_wkinfo {
  22574. + struct work_struct wk;
  22575. + struct super_block *sb;
  22576. +
  22577. + unsigned int flags; /* see wkq.h */
  22578. +
  22579. + au_wkq_func_t func;
  22580. + void *args;
  22581. +
  22582. + atomic_t *busyp;
  22583. + struct completion *comp;
  22584. +};
  22585. +
  22586. +/* ---------------------------------------------------------------------- */
  22587. +
  22588. +static int enqueue(struct au_wkq *wkq, struct au_wkinfo *wkinfo)
  22589. +{
  22590. + wkinfo->busyp = &wkq->busy;
  22591. + if (au_ftest_wkq(wkinfo->flags, WAIT))
  22592. + return !queue_work(wkq->q, &wkinfo->wk);
  22593. + else
  22594. + return !schedule_work(&wkinfo->wk);
  22595. +}
  22596. +
  22597. +static void do_wkq(struct au_wkinfo *wkinfo)
  22598. +{
  22599. + unsigned int idle, n;
  22600. + int i, idle_idx;
  22601. +
  22602. + while (1) {
  22603. + if (au_ftest_wkq(wkinfo->flags, WAIT)) {
  22604. + idle_idx = 0;
  22605. + idle = UINT_MAX;
  22606. + for (i = 0; i < aufs_nwkq; i++) {
  22607. + n = atomic_inc_return(&au_wkq[i].busy);
  22608. + if (n == 1 && !enqueue(au_wkq + i, wkinfo))
  22609. + return; /* success */
  22610. +
  22611. + if (n < idle) {
  22612. + idle_idx = i;
  22613. + idle = n;
  22614. + }
  22615. + atomic_dec(&au_wkq[i].busy);
  22616. + }
  22617. + } else
  22618. + idle_idx = aufs_nwkq;
  22619. +
  22620. + atomic_inc(&au_wkq[idle_idx].busy);
  22621. + if (!enqueue(au_wkq + idle_idx, wkinfo))
  22622. + return; /* success */
  22623. +
  22624. + /* impossible? */
  22625. + AuWarn1("failed to queue_work()\n");
  22626. + yield();
  22627. + }
  22628. +}
  22629. +
  22630. +static void wkq_func(struct work_struct *wk)
  22631. +{
  22632. + struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
  22633. +
  22634. + wkinfo->func(wkinfo->args);
  22635. + atomic_dec_return(wkinfo->busyp);
  22636. + if (au_ftest_wkq(wkinfo->flags, WAIT))
  22637. + complete(wkinfo->comp);
  22638. + else {
  22639. + kobject_put(&au_sbi(wkinfo->sb)->si_kobj);
  22640. + module_put(THIS_MODULE);
  22641. + kfree(wkinfo);
  22642. + }
  22643. +}
  22644. +
  22645. +/*
  22646. + * Since struct completion is large, try allocating it dynamically.
  22647. + */
  22648. +#if defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS)
  22649. +#define AuWkqCompDeclare(name) struct completion *comp = NULL
  22650. +
  22651. +static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
  22652. +{
  22653. + *comp = kmalloc(sizeof(**comp), GFP_NOFS);
  22654. + if (*comp) {
  22655. + init_completion(*comp);
  22656. + wkinfo->comp = *comp;
  22657. + return 0;
  22658. + }
  22659. + return -ENOMEM;
  22660. +}
  22661. +
  22662. +static void au_wkq_comp_free(struct completion *comp)
  22663. +{
  22664. + kfree(comp);
  22665. +}
  22666. +
  22667. +#else
  22668. +
  22669. +/* no braces */
  22670. +#define AuWkqCompDeclare(name) \
  22671. + DECLARE_COMPLETION_ONSTACK(_ ## name); \
  22672. + struct completion *comp = &_ ## name
  22673. +
  22674. +static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
  22675. +{
  22676. + wkinfo->comp = *comp;
  22677. + return 0;
  22678. +}
  22679. +
  22680. +static void au_wkq_comp_free(struct completion *comp __maybe_unused)
  22681. +{
  22682. + /* empty */
  22683. +}
  22684. +#endif /* 4KSTACKS */
  22685. +
  22686. +static void au_wkq_run(struct au_wkinfo *wkinfo)
  22687. +{
  22688. + au_dbg_verify_kthread();
  22689. + INIT_WORK(&wkinfo->wk, wkq_func);
  22690. + do_wkq(wkinfo);
  22691. +}
  22692. +
  22693. +int au_wkq_wait(au_wkq_func_t func, void *args)
  22694. +{
  22695. + int err;
  22696. + AuWkqCompDeclare(comp);
  22697. + struct au_wkinfo wkinfo = {
  22698. + .flags = AuWkq_WAIT,
  22699. + .func = func,
  22700. + .args = args
  22701. + };
  22702. +
  22703. + err = au_wkq_comp_alloc(&wkinfo, &comp);
  22704. + if (!err) {
  22705. + au_wkq_run(&wkinfo);
  22706. + /* no timeout, no interrupt */
  22707. + wait_for_completion(wkinfo.comp);
  22708. + au_wkq_comp_free(comp);
  22709. + }
  22710. +
  22711. + return err;
  22712. +
  22713. +}
  22714. +
  22715. +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb)
  22716. +{
  22717. + int err;
  22718. + struct au_wkinfo *wkinfo;
  22719. +
  22720. + atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
  22721. +
  22722. + /*
  22723. + * wkq_func() must free this wkinfo.
  22724. + * it highly depends upon the implementation of workqueue.
  22725. + */
  22726. + err = 0;
  22727. + wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
  22728. + if (wkinfo) {
  22729. + wkinfo->sb = sb;
  22730. + wkinfo->flags = !AuWkq_WAIT;
  22731. + wkinfo->func = func;
  22732. + wkinfo->args = args;
  22733. + wkinfo->comp = NULL;
  22734. + kobject_get(&au_sbi(sb)->si_kobj);
  22735. + __module_get(THIS_MODULE);
  22736. +
  22737. + au_wkq_run(wkinfo);
  22738. + } else {
  22739. + err = -ENOMEM;
  22740. + atomic_dec(&au_sbi(sb)->si_nowait.nw_len);
  22741. + }
  22742. +
  22743. + return err;
  22744. +}
  22745. +
  22746. +/* ---------------------------------------------------------------------- */
  22747. +
  22748. +void au_nwt_init(struct au_nowait_tasks *nwt)
  22749. +{
  22750. + atomic_set(&nwt->nw_len, 0);
  22751. + /* smp_mb();*/ /* atomic_set */
  22752. + init_waitqueue_head(&nwt->nw_wq);
  22753. +}
  22754. +
  22755. +void au_wkq_fin(void)
  22756. +{
  22757. + int i;
  22758. +
  22759. + for (i = 0; i < aufs_nwkq; i++)
  22760. + if (au_wkq[i].q && !IS_ERR(au_wkq[i].q))
  22761. + destroy_workqueue(au_wkq[i].q);
  22762. + kfree(au_wkq);
  22763. +}
  22764. +
  22765. +int __init au_wkq_init(void)
  22766. +{
  22767. + int err, i;
  22768. + struct au_wkq *nowaitq;
  22769. +
  22770. + /* '+1' is for accounting of nowait queue */
  22771. + err = -ENOMEM;
  22772. + au_wkq = kcalloc(aufs_nwkq + 1, sizeof(*au_wkq), GFP_NOFS);
  22773. + if (unlikely(!au_wkq))
  22774. + goto out;
  22775. +
  22776. + err = 0;
  22777. + for (i = 0; i < aufs_nwkq; i++) {
  22778. + au_wkq[i].q = create_singlethread_workqueue(AUFS_WKQ_NAME);
  22779. + if (au_wkq[i].q && !IS_ERR(au_wkq[i].q)) {
  22780. + atomic_set(&au_wkq[i].busy, 0);
  22781. + continue;
  22782. + }
  22783. +
  22784. + err = PTR_ERR(au_wkq[i].q);
  22785. + au_wkq_fin();
  22786. + goto out;
  22787. + }
  22788. +
  22789. + /* nowait accounting */
  22790. + nowaitq = au_wkq + aufs_nwkq;
  22791. + atomic_set(&nowaitq->busy, 0);
  22792. + nowaitq->q = NULL;
  22793. + /* smp_mb(); */ /* atomic_set */
  22794. +
  22795. + out:
  22796. + return err;
  22797. +}
  22798. diff -Nur linux-2.6.31.5.orig/fs/aufs/wkq.h linux-2.6.31.5/fs/aufs/wkq.h
  22799. --- linux-2.6.31.5.orig/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100
  22800. +++ linux-2.6.31.5/fs/aufs/wkq.h 2009-11-15 22:02:37.000000000 +0100
  22801. @@ -0,0 +1,82 @@
  22802. +/*
  22803. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  22804. + *
  22805. + * This program, aufs is free software; you can redistribute it and/or modify
  22806. + * it under the terms of the GNU General Public License as published by
  22807. + * the Free Software Foundation; either version 2 of the License, or
  22808. + * (at your option) any later version.
  22809. + *
  22810. + * This program is distributed in the hope that it will be useful,
  22811. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22812. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22813. + * GNU General Public License for more details.
  22814. + *
  22815. + * You should have received a copy of the GNU General Public License
  22816. + * along with this program; if not, write to the Free Software
  22817. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22818. + */
  22819. +
  22820. +/*
  22821. + * workqueue for asynchronous/super-io operations
  22822. + * todo: try new credentials management scheme
  22823. + */
  22824. +
  22825. +#ifndef __AUFS_WKQ_H__
  22826. +#define __AUFS_WKQ_H__
  22827. +
  22828. +#ifdef __KERNEL__
  22829. +
  22830. +#include <linux/sched.h>
  22831. +#include <linux/wait.h>
  22832. +#include <linux/aufs_type.h>
  22833. +
  22834. +struct super_block;
  22835. +
  22836. +/* ---------------------------------------------------------------------- */
  22837. +
  22838. +/*
  22839. + * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
  22840. + */
  22841. +struct au_nowait_tasks {
  22842. + atomic_t nw_len;
  22843. + wait_queue_head_t nw_wq;
  22844. +};
  22845. +
  22846. +/* ---------------------------------------------------------------------- */
  22847. +
  22848. +typedef void (*au_wkq_func_t)(void *args);
  22849. +
  22850. +/* wkq flags */
  22851. +#define AuWkq_WAIT 1
  22852. +#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name)
  22853. +#define au_fset_wkq(flags, name) { (flags) |= AuWkq_##name; }
  22854. +#define au_fclr_wkq(flags, name) { (flags) &= ~AuWkq_##name; }
  22855. +
  22856. +/* wkq.c */
  22857. +int au_wkq_wait(au_wkq_func_t func, void *args);
  22858. +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb);
  22859. +void au_nwt_init(struct au_nowait_tasks *nwt);
  22860. +int __init au_wkq_init(void);
  22861. +void au_wkq_fin(void);
  22862. +
  22863. +/* ---------------------------------------------------------------------- */
  22864. +
  22865. +static inline int au_test_wkq(struct task_struct *tsk)
  22866. +{
  22867. + return !tsk->mm && !strcmp(tsk->comm, AUFS_WKQ_NAME);
  22868. +}
  22869. +
  22870. +static inline void au_nwt_done(struct au_nowait_tasks *nwt)
  22871. +{
  22872. + if (!atomic_dec_return(&nwt->nw_len))
  22873. + wake_up_all(&nwt->nw_wq);
  22874. +}
  22875. +
  22876. +static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
  22877. +{
  22878. + wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
  22879. + return 0;
  22880. +}
  22881. +
  22882. +#endif /* __KERNEL__ */
  22883. +#endif /* __AUFS_WKQ_H__ */
  22884. diff -Nur linux-2.6.31.5.orig/fs/aufs/xino.c linux-2.6.31.5/fs/aufs/xino.c
  22885. --- linux-2.6.31.5.orig/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100
  22886. +++ linux-2.6.31.5/fs/aufs/xino.c 2009-11-15 22:02:37.000000000 +0100
  22887. @@ -0,0 +1,1200 @@
  22888. +/*
  22889. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  22890. + *
  22891. + * This program, aufs is free software; you can redistribute it and/or modify
  22892. + * it under the terms of the GNU General Public License as published by
  22893. + * the Free Software Foundation; either version 2 of the License, or
  22894. + * (at your option) any later version.
  22895. + *
  22896. + * This program is distributed in the hope that it will be useful,
  22897. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22898. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22899. + * GNU General Public License for more details.
  22900. + *
  22901. + * You should have received a copy of the GNU General Public License
  22902. + * along with this program; if not, write to the Free Software
  22903. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22904. + */
  22905. +
  22906. +/*
  22907. + * external inode number translation table and bitmap
  22908. + */
  22909. +
  22910. +#include <linux/file.h>
  22911. +#include <linux/seq_file.h>
  22912. +#include <linux/uaccess.h>
  22913. +#include "aufs.h"
  22914. +
  22915. +ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size,
  22916. + loff_t *pos)
  22917. +{
  22918. + ssize_t err;
  22919. + mm_segment_t oldfs;
  22920. +
  22921. + oldfs = get_fs();
  22922. + set_fs(KERNEL_DS);
  22923. + do {
  22924. + /* todo: signal_pending? */
  22925. + err = func(file, (char __user *)buf, size, pos);
  22926. + } while (err == -EAGAIN || err == -EINTR);
  22927. + set_fs(oldfs);
  22928. +
  22929. +#if 0 /* reserved for future use */
  22930. + if (err > 0)
  22931. + fsnotify_access(file->f_dentry);
  22932. +#endif
  22933. +
  22934. + return err;
  22935. +}
  22936. +
  22937. +/* ---------------------------------------------------------------------- */
  22938. +
  22939. +static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *buf,
  22940. + size_t size, loff_t *pos)
  22941. +{
  22942. + ssize_t err;
  22943. + mm_segment_t oldfs;
  22944. +
  22945. + oldfs = get_fs();
  22946. + set_fs(KERNEL_DS);
  22947. + lockdep_off();
  22948. + do {
  22949. + /* todo: signal_pending? */
  22950. + err = func(file, (const char __user *)buf, size, pos);
  22951. + } while (err == -EAGAIN || err == -EINTR);
  22952. + lockdep_on();
  22953. + set_fs(oldfs);
  22954. +
  22955. +#if 0 /* reserved for future use */
  22956. + if (err > 0)
  22957. + fsnotify_modify(file->f_dentry);
  22958. +#endif
  22959. +
  22960. + return err;
  22961. +}
  22962. +
  22963. +struct do_xino_fwrite_args {
  22964. + ssize_t *errp;
  22965. + au_writef_t func;
  22966. + struct file *file;
  22967. + void *buf;
  22968. + size_t size;
  22969. + loff_t *pos;
  22970. +};
  22971. +
  22972. +static void call_do_xino_fwrite(void *args)
  22973. +{
  22974. + struct do_xino_fwrite_args *a = args;
  22975. + *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
  22976. +}
  22977. +
  22978. +ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
  22979. + loff_t *pos)
  22980. +{
  22981. + ssize_t err;
  22982. +
  22983. + /* todo: signal block and no wkq? */
  22984. + /* todo: new credential scheme */
  22985. + /*
  22986. + * it breaks RLIMIT_FSIZE and normal user's limit,
  22987. + * users should care about quota and real 'filesystem full.'
  22988. + */
  22989. + if (!au_test_wkq(current)) {
  22990. + int wkq_err;
  22991. + struct do_xino_fwrite_args args = {
  22992. + .errp = &err,
  22993. + .func = func,
  22994. + .file = file,
  22995. + .buf = buf,
  22996. + .size = size,
  22997. + .pos = pos
  22998. + };
  22999. +
  23000. + wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
  23001. + if (unlikely(wkq_err))
  23002. + err = wkq_err;
  23003. + } else
  23004. + err = do_xino_fwrite(func, file, buf, size, pos);
  23005. +
  23006. + return err;
  23007. +}
  23008. +
  23009. +/* ---------------------------------------------------------------------- */
  23010. +
  23011. +/*
  23012. + * create a new xinofile at the same place/path as @base_file.
  23013. + */
  23014. +struct file *au_xino_create2(struct file *base_file, struct file *copy_src)
  23015. +{
  23016. + struct file *file;
  23017. + struct dentry *base, *dentry, *parent;
  23018. + struct inode *dir;
  23019. + struct qstr *name;
  23020. + int err;
  23021. +
  23022. + base = base_file->f_dentry;
  23023. + parent = base->d_parent; /* dir inode is locked */
  23024. + dir = parent->d_inode;
  23025. + IMustLock(dir);
  23026. +
  23027. + file = ERR_PTR(-EINVAL);
  23028. + name = &base->d_name;
  23029. + dentry = vfsub_lookup_one_len(name->name, parent, name->len);
  23030. + if (IS_ERR(dentry)) {
  23031. + file = (void *)dentry;
  23032. + AuErr("%.*s lookup err %ld\n", AuLNPair(name), PTR_ERR(dentry));
  23033. + goto out;
  23034. + }
  23035. +
  23036. + /* no need to mnt_want_write() since we call dentry_open() later */
  23037. + err = vfs_create(dir, dentry, S_IRUGO | S_IWUGO, NULL);
  23038. + if (unlikely(err)) {
  23039. + file = ERR_PTR(err);
  23040. + AuErr("%.*s create err %d\n", AuLNPair(name), err);
  23041. + goto out_dput;
  23042. + }
  23043. +
  23044. + file = dentry_open(dget(dentry), mntget(base_file->f_vfsmnt),
  23045. + O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE,
  23046. + current_cred());
  23047. + if (IS_ERR(file)) {
  23048. + AuErr("%.*s open err %ld\n", AuLNPair(name), PTR_ERR(file));
  23049. + goto out_dput;
  23050. + }
  23051. +
  23052. + err = vfsub_unlink(dir, &file->f_path, /*force*/0);
  23053. + if (unlikely(err)) {
  23054. + AuErr("%.*s unlink err %d\n", AuLNPair(name), err);
  23055. + goto out_fput;
  23056. + }
  23057. +
  23058. + if (copy_src) {
  23059. + /* no one can touch copy_src xino */
  23060. + err = au_copy_file(file, copy_src,
  23061. + i_size_read(copy_src->f_dentry->d_inode));
  23062. + if (unlikely(err)) {
  23063. + AuErr("%.*s copy err %d\n", AuLNPair(name), err);
  23064. + goto out_fput;
  23065. + }
  23066. + }
  23067. + goto out_dput; /* success */
  23068. +
  23069. + out_fput:
  23070. + fput(file);
  23071. + file = ERR_PTR(err);
  23072. + out_dput:
  23073. + dput(dentry);
  23074. + out:
  23075. + return file;
  23076. +}
  23077. +
  23078. +struct au_xino_lock_dir {
  23079. + struct au_hinode *hdir;
  23080. + struct dentry *parent;
  23081. + struct mutex *mtx;
  23082. +};
  23083. +
  23084. +static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
  23085. + struct au_xino_lock_dir *ldir)
  23086. +{
  23087. + aufs_bindex_t brid, bindex;
  23088. +
  23089. + ldir->hdir = NULL;
  23090. + bindex = -1;
  23091. + brid = au_xino_brid(sb);
  23092. + if (brid >= 0)
  23093. + bindex = au_br_index(sb, brid);
  23094. + if (bindex >= 0) {
  23095. + ldir->hdir = au_hi(sb->s_root->d_inode, bindex);
  23096. + au_hin_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
  23097. + } else {
  23098. + ldir->parent = dget_parent(xino->f_dentry);
  23099. + ldir->mtx = &ldir->parent->d_inode->i_mutex;
  23100. + mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT);
  23101. + }
  23102. +}
  23103. +
  23104. +static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
  23105. +{
  23106. + if (ldir->hdir)
  23107. + au_hin_imtx_unlock(ldir->hdir);
  23108. + else {
  23109. + mutex_unlock(ldir->mtx);
  23110. + dput(ldir->parent);
  23111. + }
  23112. +}
  23113. +
  23114. +/* ---------------------------------------------------------------------- */
  23115. +
  23116. +/* trucate xino files asynchronously */
  23117. +
  23118. +int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex)
  23119. +{
  23120. + int err;
  23121. + aufs_bindex_t bi, bend;
  23122. + struct au_branch *br;
  23123. + struct file *new_xino, *file;
  23124. + struct super_block *h_sb;
  23125. + struct au_xino_lock_dir ldir;
  23126. +
  23127. + err = -EINVAL;
  23128. + bend = au_sbend(sb);
  23129. + if (unlikely(bindex < 0 || bend < bindex))
  23130. + goto out;
  23131. + br = au_sbr(sb, bindex);
  23132. + file = br->br_xino.xi_file;
  23133. + if (!file)
  23134. + goto out;
  23135. +
  23136. + au_xino_lock_dir(sb, file, &ldir);
  23137. + /* mnt_want_write() is unnecessary here */
  23138. + new_xino = au_xino_create2(file, file);
  23139. + au_xino_unlock_dir(&ldir);
  23140. + err = PTR_ERR(new_xino);
  23141. + if (IS_ERR(new_xino))
  23142. + goto out;
  23143. + err = 0;
  23144. + fput(file);
  23145. + br->br_xino.xi_file = new_xino;
  23146. +
  23147. + h_sb = br->br_mnt->mnt_sb;
  23148. + for (bi = 0; bi <= bend; bi++) {
  23149. + if (unlikely(bi == bindex))
  23150. + continue;
  23151. + br = au_sbr(sb, bi);
  23152. + if (br->br_mnt->mnt_sb != h_sb)
  23153. + continue;
  23154. +
  23155. + fput(br->br_xino.xi_file);
  23156. + br->br_xino.xi_file = new_xino;
  23157. + get_file(new_xino);
  23158. + }
  23159. +
  23160. + out:
  23161. + return err;
  23162. +}
  23163. +
  23164. +struct xino_do_trunc_args {
  23165. + struct super_block *sb;
  23166. + struct au_branch *br;
  23167. +};
  23168. +
  23169. +static void xino_do_trunc(void *_args)
  23170. +{
  23171. + struct xino_do_trunc_args *args = _args;
  23172. + struct super_block *sb;
  23173. + struct au_branch *br;
  23174. + struct inode *dir;
  23175. + int err;
  23176. + aufs_bindex_t bindex;
  23177. +
  23178. + err = 0;
  23179. + sb = args->sb;
  23180. + dir = sb->s_root->d_inode;
  23181. + br = args->br;
  23182. +
  23183. + si_noflush_write_lock(sb);
  23184. + ii_read_lock_parent(dir);
  23185. + bindex = au_br_index(sb, br->br_id);
  23186. + err = au_xino_trunc(sb, bindex);
  23187. + if (!err
  23188. + && br->br_xino.xi_file->f_dentry->d_inode->i_blocks
  23189. + >= br->br_xino_upper)
  23190. + br->br_xino_upper += AUFS_XINO_TRUNC_STEP;
  23191. +
  23192. + ii_read_unlock(dir);
  23193. + if (unlikely(err))
  23194. + AuWarn("err b%d, (%d)\n", bindex, err);
  23195. + atomic_dec(&br->br_xino_running);
  23196. + atomic_dec(&br->br_count);
  23197. + au_nwt_done(&au_sbi(sb)->si_nowait);
  23198. + si_write_unlock(sb);
  23199. + kfree(args);
  23200. +}
  23201. +
  23202. +static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
  23203. +{
  23204. + struct xino_do_trunc_args *args;
  23205. + int wkq_err;
  23206. +
  23207. + if (br->br_xino.xi_file->f_dentry->d_inode->i_blocks
  23208. + < br->br_xino_upper)
  23209. + return;
  23210. +
  23211. + if (atomic_inc_return(&br->br_xino_running) > 1)
  23212. + goto out;
  23213. +
  23214. + /* lock and kfree() will be called in trunc_xino() */
  23215. + args = kmalloc(sizeof(*args), GFP_NOFS);
  23216. + if (unlikely(!args)) {
  23217. + AuErr1("no memory\n");
  23218. + goto out_args;
  23219. + }
  23220. +
  23221. + atomic_inc_return(&br->br_count);
  23222. + args->sb = sb;
  23223. + args->br = br;
  23224. + wkq_err = au_wkq_nowait(xino_do_trunc, args, sb);
  23225. + if (!wkq_err)
  23226. + return; /* success */
  23227. +
  23228. + AuErr("wkq %d\n", wkq_err);
  23229. + atomic_dec_return(&br->br_count);
  23230. +
  23231. + out_args:
  23232. + kfree(args);
  23233. + out:
  23234. + atomic_dec_return(&br->br_xino_running);
  23235. +}
  23236. +
  23237. +/* ---------------------------------------------------------------------- */
  23238. +
  23239. +static int au_xino_do_write(au_writef_t write, struct file *file,
  23240. + ino_t h_ino, ino_t ino)
  23241. +{
  23242. + loff_t pos;
  23243. + ssize_t sz;
  23244. +
  23245. + pos = h_ino;
  23246. + if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) {
  23247. + AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
  23248. + return -EFBIG;
  23249. + }
  23250. + pos *= sizeof(ino);
  23251. + sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos);
  23252. + if (sz == sizeof(ino))
  23253. + return 0; /* success */
  23254. +
  23255. + AuIOErr("write failed (%zd)\n", sz);
  23256. + return -EIO;
  23257. +}
  23258. +
  23259. +/*
  23260. + * write @ino to the xinofile for the specified branch{@sb, @bindex}
  23261. + * at the position of @h_ino.
  23262. + * even if @ino is zero, it is written to the xinofile and means no entry.
  23263. + * if the size of the xino file on a specific filesystem exceeds the watermark,
  23264. + * try truncating it.
  23265. + */
  23266. +int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  23267. + ino_t ino)
  23268. +{
  23269. + int err;
  23270. + unsigned int mnt_flags;
  23271. + struct au_branch *br;
  23272. +
  23273. + BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max)
  23274. + || ((loff_t)-1) > 0);
  23275. + SiMustAnyLock(sb);
  23276. +
  23277. + mnt_flags = au_mntflags(sb);
  23278. + if (!au_opt_test(mnt_flags, XINO))
  23279. + return 0;
  23280. +
  23281. + br = au_sbr(sb, bindex);
  23282. + err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
  23283. + h_ino, ino);
  23284. + if (!err) {
  23285. + if (au_opt_test(mnt_flags, TRUNC_XINO)
  23286. + && au_test_fs_trunc_xino(br->br_mnt->mnt_sb))
  23287. + xino_try_trunc(sb, br);
  23288. + return 0; /* success */
  23289. + }
  23290. +
  23291. + AuIOErr("write failed (%d)\n", err);
  23292. + return -EIO;
  23293. +}
  23294. +
  23295. +/* ---------------------------------------------------------------------- */
  23296. +
  23297. +/* aufs inode number bitmap */
  23298. +
  23299. +static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
  23300. +static ino_t xib_calc_ino(unsigned long pindex, int bit)
  23301. +{
  23302. + ino_t ino;
  23303. +
  23304. + AuDebugOn(bit < 0 || page_bits <= bit);
  23305. + ino = AUFS_FIRST_INO + pindex * page_bits + bit;
  23306. + return ino;
  23307. +}
  23308. +
  23309. +static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
  23310. +{
  23311. + AuDebugOn(ino < AUFS_FIRST_INO);
  23312. + ino -= AUFS_FIRST_INO;
  23313. + *pindex = ino / page_bits;
  23314. + *bit = ino % page_bits;
  23315. +}
  23316. +
  23317. +static int xib_pindex(struct super_block *sb, unsigned long pindex)
  23318. +{
  23319. + int err;
  23320. + loff_t pos;
  23321. + ssize_t sz;
  23322. + struct au_sbinfo *sbinfo;
  23323. + struct file *xib;
  23324. + unsigned long *p;
  23325. +
  23326. + sbinfo = au_sbi(sb);
  23327. + MtxMustLock(&sbinfo->si_xib_mtx);
  23328. + AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
  23329. + || !au_opt_test(sbinfo->si_mntflags, XINO));
  23330. +
  23331. + if (pindex == sbinfo->si_xib_last_pindex)
  23332. + return 0;
  23333. +
  23334. + xib = sbinfo->si_xib;
  23335. + p = sbinfo->si_xib_buf;
  23336. + pos = sbinfo->si_xib_last_pindex;
  23337. + pos *= PAGE_SIZE;
  23338. + sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
  23339. + if (unlikely(sz != PAGE_SIZE))
  23340. + goto out;
  23341. +
  23342. + pos = pindex;
  23343. + pos *= PAGE_SIZE;
  23344. + if (i_size_read(xib->f_dentry->d_inode) >= pos + PAGE_SIZE)
  23345. + sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
  23346. + else {
  23347. + memset(p, 0, PAGE_SIZE);
  23348. + sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
  23349. + }
  23350. + if (sz == PAGE_SIZE) {
  23351. + sbinfo->si_xib_last_pindex = pindex;
  23352. + return 0; /* success */
  23353. + }
  23354. +
  23355. + out:
  23356. + AuIOErr1("write failed (%zd)\n", sz);
  23357. + err = sz;
  23358. + if (sz >= 0)
  23359. + err = -EIO;
  23360. + return err;
  23361. +}
  23362. +
  23363. +/* ---------------------------------------------------------------------- */
  23364. +
  23365. +int au_xino_write0(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  23366. + ino_t ino)
  23367. +{
  23368. + int err, bit;
  23369. + unsigned long pindex;
  23370. + struct au_sbinfo *sbinfo;
  23371. +
  23372. + if (!au_opt_test(au_mntflags(sb), XINO))
  23373. + return 0;
  23374. +
  23375. + err = 0;
  23376. + if (ino) {
  23377. + sbinfo = au_sbi(sb);
  23378. + xib_calc_bit(ino, &pindex, &bit);
  23379. + AuDebugOn(page_bits <= bit);
  23380. + mutex_lock(&sbinfo->si_xib_mtx);
  23381. + err = xib_pindex(sb, pindex);
  23382. + if (!err) {
  23383. + clear_bit(bit, sbinfo->si_xib_buf);
  23384. + sbinfo->si_xib_next_bit = bit;
  23385. + }
  23386. + mutex_unlock(&sbinfo->si_xib_mtx);
  23387. + }
  23388. +
  23389. + if (!err)
  23390. + err = au_xino_write(sb, bindex, h_ino, 0);
  23391. + return err;
  23392. +}
  23393. +
  23394. +/* get an unused inode number from bitmap */
  23395. +ino_t au_xino_new_ino(struct super_block *sb)
  23396. +{
  23397. + ino_t ino;
  23398. + unsigned long *p, pindex, ul, pend;
  23399. + struct au_sbinfo *sbinfo;
  23400. + struct file *file;
  23401. + int free_bit, err;
  23402. +
  23403. + if (!au_opt_test(au_mntflags(sb), XINO))
  23404. + return iunique(sb, AUFS_FIRST_INO);
  23405. +
  23406. + sbinfo = au_sbi(sb);
  23407. + mutex_lock(&sbinfo->si_xib_mtx);
  23408. + p = sbinfo->si_xib_buf;
  23409. + free_bit = sbinfo->si_xib_next_bit;
  23410. + if (free_bit < page_bits && !test_bit(free_bit, p))
  23411. + goto out; /* success */
  23412. + free_bit = find_first_zero_bit(p, page_bits);
  23413. + if (free_bit < page_bits)
  23414. + goto out; /* success */
  23415. +
  23416. + pindex = sbinfo->si_xib_last_pindex;
  23417. + for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
  23418. + err = xib_pindex(sb, ul);
  23419. + if (unlikely(err))
  23420. + goto out_err;
  23421. + free_bit = find_first_zero_bit(p, page_bits);
  23422. + if (free_bit < page_bits)
  23423. + goto out; /* success */
  23424. + }
  23425. +
  23426. + file = sbinfo->si_xib;
  23427. + pend = i_size_read(file->f_dentry->d_inode) / PAGE_SIZE;
  23428. + for (ul = pindex + 1; ul <= pend; ul++) {
  23429. + err = xib_pindex(sb, ul);
  23430. + if (unlikely(err))
  23431. + goto out_err;
  23432. + free_bit = find_first_zero_bit(p, page_bits);
  23433. + if (free_bit < page_bits)
  23434. + goto out; /* success */
  23435. + }
  23436. + BUG();
  23437. +
  23438. + out:
  23439. + set_bit(free_bit, p);
  23440. + sbinfo->si_xib_next_bit++;
  23441. + pindex = sbinfo->si_xib_last_pindex;
  23442. + mutex_unlock(&sbinfo->si_xib_mtx);
  23443. + ino = xib_calc_ino(pindex, free_bit);
  23444. + AuDbg("i%lu\n", (unsigned long)ino);
  23445. + return ino;
  23446. + out_err:
  23447. + mutex_unlock(&sbinfo->si_xib_mtx);
  23448. + AuDbg("i0\n");
  23449. + return 0;
  23450. +}
  23451. +
  23452. +/*
  23453. + * read @ino from xinofile for the specified branch{@sb, @bindex}
  23454. + * at the position of @h_ino.
  23455. + * if @ino does not exist and @do_new is true, get new one.
  23456. + */
  23457. +int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  23458. + ino_t *ino)
  23459. +{
  23460. + int err;
  23461. + ssize_t sz;
  23462. + loff_t pos;
  23463. + struct file *file;
  23464. + struct au_sbinfo *sbinfo;
  23465. +
  23466. + *ino = 0;
  23467. + if (!au_opt_test(au_mntflags(sb), XINO))
  23468. + return 0; /* no xino */
  23469. +
  23470. + err = 0;
  23471. + sbinfo = au_sbi(sb);
  23472. + pos = h_ino;
  23473. + if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) {
  23474. + AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
  23475. + return -EFBIG;
  23476. + }
  23477. + pos *= sizeof(*ino);
  23478. +
  23479. + file = au_sbr(sb, bindex)->br_xino.xi_file;
  23480. + if (i_size_read(file->f_dentry->d_inode) < pos + sizeof(*ino))
  23481. + return 0; /* no ino */
  23482. +
  23483. + sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos);
  23484. + if (sz == sizeof(*ino))
  23485. + return 0; /* success */
  23486. +
  23487. + err = sz;
  23488. + if (unlikely(sz >= 0)) {
  23489. + err = -EIO;
  23490. + AuIOErr("xino read error (%zd)\n", sz);
  23491. + }
  23492. +
  23493. + return err;
  23494. +}
  23495. +
  23496. +/* ---------------------------------------------------------------------- */
  23497. +
  23498. +/* create and set a new xino file */
  23499. +
  23500. +struct file *au_xino_create(struct super_block *sb, char *fname, int silent)
  23501. +{
  23502. + struct file *file;
  23503. + struct dentry *h_parent, *d;
  23504. + struct inode *h_dir;
  23505. + int err;
  23506. +
  23507. + /*
  23508. + * at mount-time, and the xino file is the default path,
  23509. + * hinotify is disabled so we have no inotify events to ignore.
  23510. + * when a user specified the xino, we cannot get au_hdir to be ignored.
  23511. + */
  23512. + file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE,
  23513. + S_IRUGO | S_IWUGO);
  23514. + if (IS_ERR(file)) {
  23515. + if (!silent)
  23516. + AuErr("open %s(%ld)\n", fname, PTR_ERR(file));
  23517. + return file;
  23518. + }
  23519. +
  23520. + /* keep file count */
  23521. + h_parent = dget_parent(file->f_dentry);
  23522. + h_dir = h_parent->d_inode;
  23523. + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
  23524. + /* mnt_want_write() is unnecessary here */
  23525. + err = vfsub_unlink(h_dir, &file->f_path, /*force*/0);
  23526. + mutex_unlock(&h_dir->i_mutex);
  23527. + dput(h_parent);
  23528. + if (unlikely(err)) {
  23529. + if (!silent)
  23530. + AuErr("unlink %s(%d)\n", fname, err);
  23531. + goto out;
  23532. + }
  23533. +
  23534. + err = -EINVAL;
  23535. + d = file->f_dentry;
  23536. + if (unlikely(sb == d->d_sb)) {
  23537. + if (!silent)
  23538. + AuErr("%s must be outside\n", fname);
  23539. + goto out;
  23540. + }
  23541. + if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
  23542. + if (!silent)
  23543. + AuErr("xino doesn't support %s(%s)\n",
  23544. + fname, au_sbtype(d->d_sb));
  23545. + goto out;
  23546. + }
  23547. + return file; /* success */
  23548. +
  23549. + out:
  23550. + fput(file);
  23551. + file = ERR_PTR(err);
  23552. + return file;
  23553. +}
  23554. +
  23555. +/*
  23556. + * find another branch who is on the same filesystem of the specified
  23557. + * branch{@btgt}. search until @bend.
  23558. + */
  23559. +static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
  23560. + aufs_bindex_t bend)
  23561. +{
  23562. + aufs_bindex_t bindex;
  23563. + struct super_block *tgt_sb = au_sbr_sb(sb, btgt);
  23564. +
  23565. + for (bindex = 0; bindex < btgt; bindex++)
  23566. + if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
  23567. + return bindex;
  23568. + for (bindex++; bindex <= bend; bindex++)
  23569. + if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
  23570. + return bindex;
  23571. + return -1;
  23572. +}
  23573. +
  23574. +/* ---------------------------------------------------------------------- */
  23575. +
  23576. +/*
  23577. + * initialize the xinofile for the specified branch @br
  23578. + * at the place/path where @base_file indicates.
  23579. + * test whether another branch is on the same filesystem or not,
  23580. + * if @do_test is true.
  23581. + */
  23582. +int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
  23583. + struct file *base_file, int do_test)
  23584. +{
  23585. + int err;
  23586. + ino_t ino;
  23587. + aufs_bindex_t bend, bindex;
  23588. + struct au_branch *shared_br, *b;
  23589. + struct file *file;
  23590. + struct super_block *tgt_sb;
  23591. +
  23592. + shared_br = NULL;
  23593. + bend = au_sbend(sb);
  23594. + if (do_test) {
  23595. + tgt_sb = br->br_mnt->mnt_sb;
  23596. + for (bindex = 0; bindex <= bend; bindex++) {
  23597. + b = au_sbr(sb, bindex);
  23598. + if (tgt_sb == b->br_mnt->mnt_sb) {
  23599. + shared_br = b;
  23600. + break;
  23601. + }
  23602. + }
  23603. + }
  23604. +
  23605. + if (!shared_br || !shared_br->br_xino.xi_file) {
  23606. + struct au_xino_lock_dir ldir;
  23607. +
  23608. + au_xino_lock_dir(sb, base_file, &ldir);
  23609. + /* mnt_want_write() is unnecessary here */
  23610. + file = au_xino_create2(base_file, NULL);
  23611. + au_xino_unlock_dir(&ldir);
  23612. + err = PTR_ERR(file);
  23613. + if (IS_ERR(file))
  23614. + goto out;
  23615. + br->br_xino.xi_file = file;
  23616. + } else {
  23617. + br->br_xino.xi_file = shared_br->br_xino.xi_file;
  23618. + get_file(br->br_xino.xi_file);
  23619. + }
  23620. +
  23621. + ino = AUFS_ROOT_INO;
  23622. + err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
  23623. + h_ino, ino);
  23624. + if (!err)
  23625. + return 0; /* success */
  23626. +
  23627. +
  23628. + out:
  23629. + return err;
  23630. +}
  23631. +
  23632. +/* ---------------------------------------------------------------------- */
  23633. +
  23634. +/* trucate a xino bitmap file */
  23635. +
  23636. +/* todo: slow */
  23637. +static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
  23638. +{
  23639. + int err, bit;
  23640. + ssize_t sz;
  23641. + unsigned long pindex;
  23642. + loff_t pos, pend;
  23643. + struct au_sbinfo *sbinfo;
  23644. + au_readf_t func;
  23645. + ino_t *ino;
  23646. + unsigned long *p;
  23647. +
  23648. + err = 0;
  23649. + sbinfo = au_sbi(sb);
  23650. + MtxMustLock(&sbinfo->si_xib_mtx);
  23651. + p = sbinfo->si_xib_buf;
  23652. + func = sbinfo->si_xread;
  23653. + pend = i_size_read(file->f_dentry->d_inode);
  23654. + pos = 0;
  23655. + while (pos < pend) {
  23656. + sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
  23657. + err = sz;
  23658. + if (unlikely(sz <= 0))
  23659. + goto out;
  23660. +
  23661. + err = 0;
  23662. + for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
  23663. + if (unlikely(*ino < AUFS_FIRST_INO))
  23664. + continue;
  23665. +
  23666. + xib_calc_bit(*ino, &pindex, &bit);
  23667. + AuDebugOn(page_bits <= bit);
  23668. + err = xib_pindex(sb, pindex);
  23669. + if (!err)
  23670. + set_bit(bit, p);
  23671. + else
  23672. + goto out;
  23673. + }
  23674. + }
  23675. +
  23676. + out:
  23677. + return err;
  23678. +}
  23679. +
  23680. +static int xib_restore(struct super_block *sb)
  23681. +{
  23682. + int err;
  23683. + aufs_bindex_t bindex, bend;
  23684. + void *page;
  23685. +
  23686. + err = -ENOMEM;
  23687. + page = (void *)__get_free_page(GFP_NOFS);
  23688. + if (unlikely(!page))
  23689. + goto out;
  23690. +
  23691. + err = 0;
  23692. + bend = au_sbend(sb);
  23693. + for (bindex = 0; !err && bindex <= bend; bindex++)
  23694. + if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0)
  23695. + err = do_xib_restore
  23696. + (sb, au_sbr(sb, bindex)->br_xino.xi_file, page);
  23697. + else
  23698. + AuDbg("b%d\n", bindex);
  23699. + free_page((unsigned long)page);
  23700. +
  23701. + out:
  23702. + return err;
  23703. +}
  23704. +
  23705. +int au_xib_trunc(struct super_block *sb)
  23706. +{
  23707. + int err;
  23708. + ssize_t sz;
  23709. + loff_t pos;
  23710. + struct au_xino_lock_dir ldir;
  23711. + struct au_sbinfo *sbinfo;
  23712. + unsigned long *p;
  23713. + struct file *file;
  23714. +
  23715. + SiMustWriteLock(sb);
  23716. +
  23717. + err = 0;
  23718. + sbinfo = au_sbi(sb);
  23719. + if (!au_opt_test(sbinfo->si_mntflags, XINO))
  23720. + goto out;
  23721. +
  23722. + file = sbinfo->si_xib;
  23723. + if (i_size_read(file->f_dentry->d_inode) <= PAGE_SIZE)
  23724. + goto out;
  23725. +
  23726. + au_xino_lock_dir(sb, file, &ldir);
  23727. + /* mnt_want_write() is unnecessary here */
  23728. + file = au_xino_create2(sbinfo->si_xib, NULL);
  23729. + au_xino_unlock_dir(&ldir);
  23730. + err = PTR_ERR(file);
  23731. + if (IS_ERR(file))
  23732. + goto out;
  23733. + fput(sbinfo->si_xib);
  23734. + sbinfo->si_xib = file;
  23735. +
  23736. + p = sbinfo->si_xib_buf;
  23737. + memset(p, 0, PAGE_SIZE);
  23738. + pos = 0;
  23739. + sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
  23740. + if (unlikely(sz != PAGE_SIZE)) {
  23741. + err = sz;
  23742. + AuIOErr("err %d\n", err);
  23743. + if (sz >= 0)
  23744. + err = -EIO;
  23745. + goto out;
  23746. + }
  23747. +
  23748. + mutex_lock(&sbinfo->si_xib_mtx);
  23749. + /* mnt_want_write() is unnecessary here */
  23750. + err = xib_restore(sb);
  23751. + mutex_unlock(&sbinfo->si_xib_mtx);
  23752. +
  23753. +out:
  23754. + return err;
  23755. +}
  23756. +
  23757. +/* ---------------------------------------------------------------------- */
  23758. +
  23759. +/*
  23760. + * xino mount option handlers
  23761. + */
  23762. +static au_readf_t find_readf(struct file *h_file)
  23763. +{
  23764. + const struct file_operations *fop = h_file->f_op;
  23765. +
  23766. + if (fop) {
  23767. + if (fop->read)
  23768. + return fop->read;
  23769. + if (fop->aio_read)
  23770. + return do_sync_read;
  23771. + }
  23772. + return ERR_PTR(-ENOSYS);
  23773. +}
  23774. +
  23775. +static au_writef_t find_writef(struct file *h_file)
  23776. +{
  23777. + const struct file_operations *fop = h_file->f_op;
  23778. +
  23779. + if (fop) {
  23780. + if (fop->write)
  23781. + return fop->write;
  23782. + if (fop->aio_write)
  23783. + return do_sync_write;
  23784. + }
  23785. + return ERR_PTR(-ENOSYS);
  23786. +}
  23787. +
  23788. +/* xino bitmap */
  23789. +static void xino_clear_xib(struct super_block *sb)
  23790. +{
  23791. + struct au_sbinfo *sbinfo;
  23792. +
  23793. + SiMustWriteLock(sb);
  23794. +
  23795. + sbinfo = au_sbi(sb);
  23796. + sbinfo->si_xread = NULL;
  23797. + sbinfo->si_xwrite = NULL;
  23798. + if (sbinfo->si_xib)
  23799. + fput(sbinfo->si_xib);
  23800. + sbinfo->si_xib = NULL;
  23801. + free_page((unsigned long)sbinfo->si_xib_buf);
  23802. + sbinfo->si_xib_buf = NULL;
  23803. +}
  23804. +
  23805. +static int au_xino_set_xib(struct super_block *sb, struct file *base)
  23806. +{
  23807. + int err;
  23808. + loff_t pos;
  23809. + struct au_sbinfo *sbinfo;
  23810. + struct file *file;
  23811. +
  23812. + SiMustWriteLock(sb);
  23813. +
  23814. + sbinfo = au_sbi(sb);
  23815. + file = au_xino_create2(base, sbinfo->si_xib);
  23816. + err = PTR_ERR(file);
  23817. + if (IS_ERR(file))
  23818. + goto out;
  23819. + if (sbinfo->si_xib)
  23820. + fput(sbinfo->si_xib);
  23821. + sbinfo->si_xib = file;
  23822. + sbinfo->si_xread = find_readf(file);
  23823. + sbinfo->si_xwrite = find_writef(file);
  23824. +
  23825. + err = -ENOMEM;
  23826. + if (!sbinfo->si_xib_buf)
  23827. + sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
  23828. + if (unlikely(!sbinfo->si_xib_buf))
  23829. + goto out_unset;
  23830. +
  23831. + sbinfo->si_xib_last_pindex = 0;
  23832. + sbinfo->si_xib_next_bit = 0;
  23833. + if (i_size_read(file->f_dentry->d_inode) < PAGE_SIZE) {
  23834. + pos = 0;
  23835. + err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
  23836. + PAGE_SIZE, &pos);
  23837. + if (unlikely(err != PAGE_SIZE))
  23838. + goto out_free;
  23839. + }
  23840. + err = 0;
  23841. + goto out; /* success */
  23842. +
  23843. + out_free:
  23844. + free_page((unsigned long)sbinfo->si_xib_buf);
  23845. + sbinfo->si_xib_buf = NULL;
  23846. + if (err >= 0)
  23847. + err = -EIO;
  23848. + out_unset:
  23849. + fput(sbinfo->si_xib);
  23850. + sbinfo->si_xib = NULL;
  23851. + sbinfo->si_xread = NULL;
  23852. + sbinfo->si_xwrite = NULL;
  23853. + out:
  23854. + return err;
  23855. +}
  23856. +
  23857. +/* xino for each branch */
  23858. +static void xino_clear_br(struct super_block *sb)
  23859. +{
  23860. + aufs_bindex_t bindex, bend;
  23861. + struct au_branch *br;
  23862. +
  23863. + bend = au_sbend(sb);
  23864. + for (bindex = 0; bindex <= bend; bindex++) {
  23865. + br = au_sbr(sb, bindex);
  23866. + if (!br || !br->br_xino.xi_file)
  23867. + continue;
  23868. +
  23869. + fput(br->br_xino.xi_file);
  23870. + br->br_xino.xi_file = NULL;
  23871. + }
  23872. +}
  23873. +
  23874. +static int au_xino_set_br(struct super_block *sb, struct file *base)
  23875. +{
  23876. + int err;
  23877. + ino_t ino;
  23878. + aufs_bindex_t bindex, bend, bshared;
  23879. + struct {
  23880. + struct file *old, *new;
  23881. + } *fpair, *p;
  23882. + struct au_branch *br;
  23883. + struct inode *inode;
  23884. + au_writef_t writef;
  23885. +
  23886. + SiMustWriteLock(sb);
  23887. +
  23888. + err = -ENOMEM;
  23889. + bend = au_sbend(sb);
  23890. + fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS);
  23891. + if (unlikely(!fpair))
  23892. + goto out;
  23893. +
  23894. + inode = sb->s_root->d_inode;
  23895. + ino = AUFS_ROOT_INO;
  23896. + writef = au_sbi(sb)->si_xwrite;
  23897. + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
  23898. + br = au_sbr(sb, bindex);
  23899. + bshared = is_sb_shared(sb, bindex, bindex - 1);
  23900. + if (bshared >= 0) {
  23901. + /* shared xino */
  23902. + *p = fpair[bshared];
  23903. + get_file(p->new);
  23904. + }
  23905. +
  23906. + if (!p->new) {
  23907. + /* new xino */
  23908. + p->old = br->br_xino.xi_file;
  23909. + p->new = au_xino_create2(base, br->br_xino.xi_file);
  23910. + err = PTR_ERR(p->new);
  23911. + if (IS_ERR(p->new)) {
  23912. + p->new = NULL;
  23913. + goto out_pair;
  23914. + }
  23915. + }
  23916. +
  23917. + err = au_xino_do_write(writef, p->new,
  23918. + au_h_iptr(inode, bindex)->i_ino, ino);
  23919. + if (unlikely(err))
  23920. + goto out_pair;
  23921. + }
  23922. +
  23923. + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
  23924. + br = au_sbr(sb, bindex);
  23925. + if (br->br_xino.xi_file)
  23926. + fput(br->br_xino.xi_file);
  23927. + get_file(p->new);
  23928. + br->br_xino.xi_file = p->new;
  23929. + }
  23930. +
  23931. + out_pair:
  23932. + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++)
  23933. + if (p->new)
  23934. + fput(p->new);
  23935. + else
  23936. + break;
  23937. + kfree(fpair);
  23938. + out:
  23939. + return err;
  23940. +}
  23941. +
  23942. +void au_xino_clr(struct super_block *sb)
  23943. +{
  23944. + struct au_sbinfo *sbinfo;
  23945. +
  23946. + au_xigen_clr(sb);
  23947. + xino_clear_xib(sb);
  23948. + xino_clear_br(sb);
  23949. + sbinfo = au_sbi(sb);
  23950. + /* lvalue, do not call au_mntflags() */
  23951. + au_opt_clr(sbinfo->si_mntflags, XINO);
  23952. +}
  23953. +
  23954. +int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount)
  23955. +{
  23956. + int err, skip;
  23957. + struct dentry *parent, *cur_parent;
  23958. + struct qstr *dname, *cur_name;
  23959. + struct file *cur_xino;
  23960. + struct inode *dir;
  23961. + struct au_sbinfo *sbinfo;
  23962. +
  23963. + SiMustWriteLock(sb);
  23964. +
  23965. + err = 0;
  23966. + sbinfo = au_sbi(sb);
  23967. + parent = dget_parent(xino->file->f_dentry);
  23968. + if (remount) {
  23969. + skip = 0;
  23970. + dname = &xino->file->f_dentry->d_name;
  23971. + cur_xino = sbinfo->si_xib;
  23972. + if (cur_xino) {
  23973. + cur_parent = dget_parent(cur_xino->f_dentry);
  23974. + cur_name = &cur_xino->f_dentry->d_name;
  23975. + skip = (cur_parent == parent
  23976. + && dname->len == cur_name->len
  23977. + && !memcmp(dname->name, cur_name->name,
  23978. + dname->len));
  23979. + dput(cur_parent);
  23980. + }
  23981. + if (skip)
  23982. + goto out;
  23983. + }
  23984. +
  23985. + au_opt_set(sbinfo->si_mntflags, XINO);
  23986. + dir = parent->d_inode;
  23987. + mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT);
  23988. + /* mnt_want_write() is unnecessary here */
  23989. + err = au_xino_set_xib(sb, xino->file);
  23990. + if (!err)
  23991. + err = au_xigen_set(sb, xino->file);
  23992. + if (!err)
  23993. + err = au_xino_set_br(sb, xino->file);
  23994. + mutex_unlock(&dir->i_mutex);
  23995. + if (!err)
  23996. + goto out; /* success */
  23997. +
  23998. + /* reset all */
  23999. + AuIOErr("failed creating xino(%d).\n", err);
  24000. +
  24001. + out:
  24002. + dput(parent);
  24003. + return err;
  24004. +}
  24005. +
  24006. +/* ---------------------------------------------------------------------- */
  24007. +
  24008. +/*
  24009. + * create a xinofile at the default place/path.
  24010. + */
  24011. +struct file *au_xino_def(struct super_block *sb)
  24012. +{
  24013. + struct file *file;
  24014. + char *page, *p;
  24015. + struct au_branch *br;
  24016. + struct super_block *h_sb;
  24017. + struct path path;
  24018. + aufs_bindex_t bend, bindex, bwr;
  24019. +
  24020. + br = NULL;
  24021. + bend = au_sbend(sb);
  24022. + bwr = -1;
  24023. + for (bindex = 0; bindex <= bend; bindex++) {
  24024. + br = au_sbr(sb, bindex);
  24025. + if (au_br_writable(br->br_perm)
  24026. + && !au_test_fs_bad_xino(br->br_mnt->mnt_sb)) {
  24027. + bwr = bindex;
  24028. + break;
  24029. + }
  24030. + }
  24031. +
  24032. + if (bwr >= 0) {
  24033. + file = ERR_PTR(-ENOMEM);
  24034. + page = __getname();
  24035. + if (unlikely(!page))
  24036. + goto out;
  24037. + path.mnt = br->br_mnt;
  24038. + path.dentry = au_h_dptr(sb->s_root, bwr);
  24039. + p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
  24040. + file = (void *)p;
  24041. + if (!IS_ERR(p)) {
  24042. + strcat(p, "/" AUFS_XINO_FNAME);
  24043. + AuDbg("%s\n", p);
  24044. + file = au_xino_create(sb, p, /*silent*/0);
  24045. + if (!IS_ERR(file))
  24046. + au_xino_brid_set(sb, br->br_id);
  24047. + }
  24048. + __putname(page);
  24049. + } else {
  24050. + file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
  24051. + if (IS_ERR(file))
  24052. + goto out;
  24053. + h_sb = file->f_dentry->d_sb;
  24054. + if (unlikely(au_test_fs_bad_xino(h_sb))) {
  24055. + AuErr("xino doesn't support %s(%s)\n",
  24056. + AUFS_XINO_DEFPATH, au_sbtype(h_sb));
  24057. + fput(file);
  24058. + file = ERR_PTR(-EINVAL);
  24059. + }
  24060. + if (!IS_ERR(file))
  24061. + au_xino_brid_set(sb, -1);
  24062. + }
  24063. +
  24064. + out:
  24065. + return file;
  24066. +}
  24067. +
  24068. +/* ---------------------------------------------------------------------- */
  24069. +
  24070. +int au_xino_path(struct seq_file *seq, struct file *file)
  24071. +{
  24072. + int err;
  24073. +
  24074. + err = au_seq_path(seq, &file->f_path);
  24075. + if (unlikely(err < 0))
  24076. + goto out;
  24077. +
  24078. + err = 0;
  24079. +#define Deleted "\\040(deleted)"
  24080. + seq->count -= sizeof(Deleted) - 1;
  24081. + AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
  24082. + sizeof(Deleted) - 1));
  24083. +#undef Deleted
  24084. +
  24085. + out:
  24086. + return err;
  24087. +}
  24088. diff -Nur linux-2.6.31.5.orig/fs/Kconfig linux-2.6.31.5/fs/Kconfig
  24089. --- linux-2.6.31.5.orig/fs/Kconfig 2009-10-23 00:57:56.000000000 +0200
  24090. +++ linux-2.6.31.5/fs/Kconfig 2009-11-15 22:02:37.000000000 +0100
  24091. @@ -187,6 +187,7 @@
  24092. source "fs/ufs/Kconfig"
  24093. source "fs/exofs/Kconfig"
  24094. source "fs/nilfs2/Kconfig"
  24095. +source "fs/aufs/Kconfig"
  24096. endif # MISC_FILESYSTEMS
  24097. diff -Nur linux-2.6.31.5.orig/fs/Makefile linux-2.6.31.5/fs/Makefile
  24098. --- linux-2.6.31.5.orig/fs/Makefile 2009-10-23 00:57:56.000000000 +0200
  24099. +++ linux-2.6.31.5/fs/Makefile 2009-11-15 22:02:37.000000000 +0100
  24100. @@ -85,6 +85,7 @@
  24101. obj-$(CONFIG_HFS_FS) += hfs/
  24102. obj-$(CONFIG_ECRYPT_FS) += ecryptfs/
  24103. obj-$(CONFIG_VXFS_FS) += freevxfs/
  24104. +obj-$(CONFIG_AUFS_FS) += aufs/
  24105. obj-$(CONFIG_NFS_FS) += nfs/
  24106. obj-$(CONFIG_EXPORTFS) += exportfs/
  24107. obj-$(CONFIG_NFSD) += nfsd/
  24108. diff -Nur linux-2.6.31.5.orig/fs/namei.c linux-2.6.31.5/fs/namei.c
  24109. --- linux-2.6.31.5.orig/fs/namei.c 2009-10-23 00:57:56.000000000 +0200
  24110. +++ linux-2.6.31.5/fs/namei.c 2009-11-15 22:02:37.000000000 +0100
  24111. @@ -337,6 +337,7 @@
  24112. return 0;
  24113. }
  24114. +EXPORT_SYMBOL(deny_write_access);
  24115. /**
  24116. * path_get - get a reference to a path
  24117. @@ -1219,7 +1220,7 @@
  24118. * needs parent already locked. Doesn't follow mounts.
  24119. * SMP-safe.
  24120. */
  24121. -static struct dentry *lookup_hash(struct nameidata *nd)
  24122. +struct dentry *lookup_hash(struct nameidata *nd)
  24123. {
  24124. int err;
  24125. @@ -1228,8 +1229,9 @@
  24126. return ERR_PTR(err);
  24127. return __lookup_hash(&nd->last, nd->path.dentry, nd);
  24128. }
  24129. +EXPORT_SYMBOL(lookup_hash);
  24130. -static int __lookup_one_len(const char *name, struct qstr *this,
  24131. +int __lookup_one_len(const char *name, struct qstr *this,
  24132. struct dentry *base, int len)
  24133. {
  24134. unsigned long hash;
  24135. @@ -1250,6 +1252,7 @@
  24136. this->hash = end_name_hash(hash);
  24137. return 0;
  24138. }
  24139. +EXPORT_SYMBOL(__lookup_one_len);
  24140. /**
  24141. * lookup_one_len - filesystem helper to lookup single pathname component
  24142. diff -Nur linux-2.6.31.5.orig/fs/namespace.c linux-2.6.31.5/fs/namespace.c
  24143. --- linux-2.6.31.5.orig/fs/namespace.c 2009-10-23 00:57:56.000000000 +0200
  24144. +++ linux-2.6.31.5/fs/namespace.c 2009-11-15 22:02:37.000000000 +0100
  24145. @@ -39,6 +39,7 @@
  24146. /* spinlock for vfsmount related operations, inplace of dcache_lock */
  24147. __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock);
  24148. +EXPORT_SYMBOL(vfsmount_lock);
  24149. static int event;
  24150. static DEFINE_IDA(mnt_id_ida);
  24151. diff -Nur linux-2.6.31.5.orig/fs/open.c linux-2.6.31.5/fs/open.c
  24152. --- linux-2.6.31.5.orig/fs/open.c 2009-10-23 00:57:56.000000000 +0200
  24153. +++ linux-2.6.31.5/fs/open.c 2009-11-15 22:02:37.000000000 +0100
  24154. @@ -221,6 +221,7 @@
  24155. mutex_unlock(&dentry->d_inode->i_mutex);
  24156. return err;
  24157. }
  24158. +EXPORT_SYMBOL(do_truncate);
  24159. static long do_sys_truncate(const char __user *pathname, loff_t length)
  24160. {
  24161. diff -Nur linux-2.6.31.5.orig/fs/splice.c linux-2.6.31.5/fs/splice.c
  24162. --- linux-2.6.31.5.orig/fs/splice.c 2009-10-23 00:57:56.000000000 +0200
  24163. +++ linux-2.6.31.5/fs/splice.c 2009-11-15 22:02:37.000000000 +0100
  24164. @@ -1057,8 +1057,8 @@
  24165. /*
  24166. * Attempt to initiate a splice from pipe to file.
  24167. */
  24168. -static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  24169. - loff_t *ppos, size_t len, unsigned int flags)
  24170. +long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  24171. + loff_t *ppos, size_t len, unsigned int flags)
  24172. {
  24173. ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
  24174. loff_t *, size_t, unsigned int);
  24175. @@ -1080,13 +1080,14 @@
  24176. return splice_write(pipe, out, ppos, len, flags);
  24177. }
  24178. +EXPORT_SYMBOL(do_splice_from);
  24179. /*
  24180. * Attempt to initiate a splice from a file to a pipe.
  24181. */
  24182. -static long do_splice_to(struct file *in, loff_t *ppos,
  24183. - struct pipe_inode_info *pipe, size_t len,
  24184. - unsigned int flags)
  24185. +long do_splice_to(struct file *in, loff_t *ppos,
  24186. + struct pipe_inode_info *pipe, size_t len,
  24187. + unsigned int flags)
  24188. {
  24189. ssize_t (*splice_read)(struct file *, loff_t *,
  24190. struct pipe_inode_info *, size_t, unsigned int);
  24191. @@ -1105,6 +1106,7 @@
  24192. return splice_read(in, ppos, pipe, len, flags);
  24193. }
  24194. +EXPORT_SYMBOL(do_splice_to);
  24195. /**
  24196. * splice_direct_to_actor - splices data directly between two non-pipes
  24197. diff -Nur linux-2.6.31.5.orig/include/linux/aufs_type.h linux-2.6.31.5/include/linux/aufs_type.h
  24198. --- linux-2.6.31.5.orig/include/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
  24199. +++ linux-2.6.31.5/include/linux/aufs_type.h 2009-11-15 22:02:37.000000000 +0100
  24200. @@ -0,0 +1,109 @@
  24201. +/*
  24202. + * Copyright (C) 2005-2009 Junjiro R. Okajima
  24203. + *
  24204. + * This program, aufs is free software; you can redistribute it and/or modify
  24205. + * it under the terms of the GNU General Public License as published by
  24206. + * the Free Software Foundation; either version 2 of the License, or
  24207. + * (at your option) any later version.
  24208. + *
  24209. + * This program is distributed in the hope that it will be useful,
  24210. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24211. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24212. + * GNU General Public License for more details.
  24213. + *
  24214. + * You should have received a copy of the GNU General Public License
  24215. + * along with this program; if not, write to the Free Software
  24216. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  24217. + */
  24218. +
  24219. +#ifndef __AUFS_TYPE_H__
  24220. +#define __AUFS_TYPE_H__
  24221. +
  24222. +#include <linux/ioctl.h>
  24223. +
  24224. +#define AUFS_VERSION "2-standalone.tree-30-20090803"
  24225. +
  24226. +/* todo? move this to linux-2.6.19/include/magic.h */
  24227. +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
  24228. +
  24229. +/* ---------------------------------------------------------------------- */
  24230. +
  24231. +#ifdef CONFIG_AUFS_BRANCH_MAX_127
  24232. +/* some environments treat 'char' as 'unsigned char' by default */
  24233. +typedef signed char aufs_bindex_t;
  24234. +#define AUFS_BRANCH_MAX 127
  24235. +#else
  24236. +typedef short aufs_bindex_t;
  24237. +#ifdef CONFIG_AUFS_BRANCH_MAX_511
  24238. +#define AUFS_BRANCH_MAX 511
  24239. +#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
  24240. +#define AUFS_BRANCH_MAX 1023
  24241. +#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
  24242. +#define AUFS_BRANCH_MAX 32767
  24243. +#endif
  24244. +#endif
  24245. +
  24246. +#ifdef __KERNEL__
  24247. +#ifndef AUFS_BRANCH_MAX
  24248. +#error unknown CONFIG_AUFS_BRANCH_MAX value
  24249. +#endif
  24250. +#endif /* __KERNEL__ */
  24251. +
  24252. +/* ---------------------------------------------------------------------- */
  24253. +
  24254. +#define AUFS_NAME "aufs"
  24255. +#define AUFS_FSTYPE AUFS_NAME
  24256. +
  24257. +#define AUFS_ROOT_INO 2
  24258. +#define AUFS_FIRST_INO 11
  24259. +
  24260. +#define AUFS_WH_PFX ".wh."
  24261. +#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1)
  24262. +#define AUFS_XINO_FNAME "." AUFS_NAME ".xino"
  24263. +#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME
  24264. +#define AUFS_XINO_TRUNC_INIT 64 /* blocks */
  24265. +#define AUFS_XINO_TRUNC_STEP 4 /* blocks */
  24266. +#define AUFS_DIRWH_DEF 3
  24267. +#define AUFS_RDCACHE_DEF 10 /* seconds */
  24268. +#define AUFS_RDBLK_DEF 512 /* bytes */
  24269. +#define AUFS_RDHASH_DEF 32
  24270. +#define AUFS_WKQ_NAME AUFS_NAME "d"
  24271. +#define AUFS_NWKQ_DEF 4
  24272. +#define AUFS_MFS_SECOND_DEF 30 /* seconds */
  24273. +#define AUFS_PLINK_WARN 100 /* number of plinks */
  24274. +
  24275. +#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */
  24276. +#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME
  24277. +
  24278. +#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME
  24279. +#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk"
  24280. +#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph"
  24281. +
  24282. +/* doubly whiteouted */
  24283. +#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME
  24284. +#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME
  24285. +#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME
  24286. +
  24287. +/* branch permission */
  24288. +#define AUFS_BRPERM_RW "rw"
  24289. +#define AUFS_BRPERM_RO "ro"
  24290. +#define AUFS_BRPERM_RR "rr"
  24291. +#define AUFS_BRPERM_WH "wh"
  24292. +#define AUFS_BRPERM_NLWH "nolwh"
  24293. +#define AUFS_BRPERM_ROWH AUFS_BRPERM_RO "+" AUFS_BRPERM_WH
  24294. +#define AUFS_BRPERM_RRWH AUFS_BRPERM_RR "+" AUFS_BRPERM_WH
  24295. +#define AUFS_BRPERM_RWNLWH AUFS_BRPERM_RW "+" AUFS_BRPERM_NLWH
  24296. +
  24297. +/* ---------------------------------------------------------------------- */
  24298. +
  24299. +/* ioctl */
  24300. +enum {
  24301. + AuCtl_PLINK_MAINT,
  24302. + AuCtl_PLINK_CLEAN
  24303. +};
  24304. +
  24305. +#define AuCtlType 'A'
  24306. +#define AUFS_CTL_PLINK_MAINT _IO(AuCtlType, AuCtl_PLINK_MAINT)
  24307. +#define AUFS_CTL_PLINK_CLEAN _IO(AuCtlType, AuCtl_PLINK_CLEAN)
  24308. +
  24309. +#endif /* __AUFS_TYPE_H__ */
  24310. diff -Nur linux-2.6.31.5.orig/include/linux/Kbuild linux-2.6.31.5/include/linux/Kbuild
  24311. --- linux-2.6.31.5.orig/include/linux/Kbuild 2009-10-23 00:57:56.000000000 +0200
  24312. +++ linux-2.6.31.5/include/linux/Kbuild 2009-11-15 22:02:38.000000000 +0100
  24313. @@ -34,6 +34,7 @@
  24314. header-y += atmsap.h
  24315. header-y += atmsvc.h
  24316. header-y += atm_zatm.h
  24317. +header-y += aufs_type.h
  24318. header-y += auto_fs4.h
  24319. header-y += ax25.h
  24320. header-y += b1lli.h
  24321. diff -Nur linux-2.6.31.5.orig/include/linux/namei.h linux-2.6.31.5/include/linux/namei.h
  24322. --- linux-2.6.31.5.orig/include/linux/namei.h 2009-10-23 00:57:56.000000000 +0200
  24323. +++ linux-2.6.31.5/include/linux/namei.h 2009-11-15 22:02:38.000000000 +0100
  24324. @@ -75,6 +75,9 @@
  24325. extern struct file *nameidata_to_filp(struct nameidata *nd, int flags);
  24326. extern void release_open_intent(struct nameidata *);
  24327. +extern struct dentry *lookup_hash(struct nameidata *nd);
  24328. +extern int __lookup_one_len(const char *name, struct qstr *this,
  24329. + struct dentry *base, int len);
  24330. extern struct dentry *lookup_one_len(const char *, struct dentry *, int);
  24331. extern struct dentry *lookup_one_noperm(const char *, struct dentry *);
  24332. diff -Nur linux-2.6.31.5.orig/include/linux/splice.h linux-2.6.31.5/include/linux/splice.h
  24333. --- linux-2.6.31.5.orig/include/linux/splice.h 2009-10-23 00:57:56.000000000 +0200
  24334. +++ linux-2.6.31.5/include/linux/splice.h 2009-11-15 22:02:38.000000000 +0100
  24335. @@ -82,4 +82,10 @@
  24336. extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *,
  24337. splice_direct_actor *);
  24338. +extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  24339. + loff_t *ppos, size_t len, unsigned int flags);
  24340. +extern long do_splice_to(struct file *in, loff_t *ppos,
  24341. + struct pipe_inode_info *pipe, size_t len,
  24342. + unsigned int flags);
  24343. +
  24344. #endif
  24345. diff -Nur linux-2.6.31.5.orig/security/device_cgroup.c linux-2.6.31.5/security/device_cgroup.c
  24346. --- linux-2.6.31.5.orig/security/device_cgroup.c 2009-10-23 00:57:56.000000000 +0200
  24347. +++ linux-2.6.31.5/security/device_cgroup.c 2009-11-15 22:02:38.000000000 +0100
  24348. @@ -513,6 +513,7 @@
  24349. return -EPERM;
  24350. }
  24351. +EXPORT_SYMBOL(devcgroup_inode_permission);
  24352. int devcgroup_inode_mknod(int mode, dev_t dev)
  24353. {
  24354. diff -Nur linux-2.6.31.5.orig/security/security.c linux-2.6.31.5/security/security.c
  24355. --- linux-2.6.31.5.orig/security/security.c 2009-10-23 00:57:56.000000000 +0200
  24356. +++ linux-2.6.31.5/security/security.c 2009-11-15 22:02:38.000000000 +0100
  24357. @@ -386,6 +386,7 @@
  24358. return 0;
  24359. return security_ops->path_mkdir(path, dentry, mode);
  24360. }
  24361. +EXPORT_SYMBOL(security_path_mkdir);
  24362. int security_path_rmdir(struct path *path, struct dentry *dentry)
  24363. {
  24364. @@ -393,6 +394,7 @@
  24365. return 0;
  24366. return security_ops->path_rmdir(path, dentry);
  24367. }
  24368. +EXPORT_SYMBOL(security_path_rmdir);
  24369. int security_path_unlink(struct path *path, struct dentry *dentry)
  24370. {
  24371. @@ -400,6 +402,7 @@
  24372. return 0;
  24373. return security_ops->path_unlink(path, dentry);
  24374. }
  24375. +EXPORT_SYMBOL(security_path_unlink);
  24376. int security_path_symlink(struct path *path, struct dentry *dentry,
  24377. const char *old_name)
  24378. @@ -408,6 +411,7 @@
  24379. return 0;
  24380. return security_ops->path_symlink(path, dentry, old_name);
  24381. }
  24382. +EXPORT_SYMBOL(security_path_symlink);
  24383. int security_path_link(struct dentry *old_dentry, struct path *new_dir,
  24384. struct dentry *new_dentry)
  24385. @@ -416,6 +420,7 @@
  24386. return 0;
  24387. return security_ops->path_link(old_dentry, new_dir, new_dentry);
  24388. }
  24389. +EXPORT_SYMBOL(security_path_link);
  24390. int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
  24391. struct path *new_dir, struct dentry *new_dentry)
  24392. @@ -426,6 +431,7 @@
  24393. return security_ops->path_rename(old_dir, old_dentry, new_dir,
  24394. new_dentry);
  24395. }
  24396. +EXPORT_SYMBOL(security_path_rename);
  24397. int security_path_truncate(struct path *path, loff_t length,
  24398. unsigned int time_attrs)
  24399. @@ -434,6 +440,7 @@
  24400. return 0;
  24401. return security_ops->path_truncate(path, length, time_attrs);
  24402. }
  24403. +EXPORT_SYMBOL(security_path_truncate);
  24404. #endif
  24405. int security_inode_create(struct inode *dir, struct dentry *dentry, int mode)
  24406. @@ -505,6 +512,7 @@
  24407. return 0;
  24408. return security_ops->inode_readlink(dentry);
  24409. }
  24410. +EXPORT_SYMBOL(security_inode_readlink);
  24411. int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
  24412. {
  24413. @@ -519,6 +527,7 @@
  24414. return 0;
  24415. return security_ops->inode_permission(inode, mask);
  24416. }
  24417. +EXPORT_SYMBOL(security_inode_permission);
  24418. int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
  24419. {
  24420. @@ -619,6 +628,7 @@
  24421. {
  24422. return security_ops->file_permission(file, mask);
  24423. }
  24424. +EXPORT_SYMBOL(security_file_permission);
  24425. int security_file_alloc(struct file *file)
  24426. {