aufs2.patch 707 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523
  1. diff -Nur linux-2.6.37.orig/fs/Kconfig linux-2.6.37/fs/Kconfig
  2. --- linux-2.6.37.orig/fs/Kconfig 2011-01-05 01:50:19.000000000 +0100
  3. +++ linux-2.6.37/fs/Kconfig 2011-01-11 20:15:11.000000000 +0100
  4. @@ -191,6 +191,7 @@
  5. source "fs/sysv/Kconfig"
  6. source "fs/ufs/Kconfig"
  7. source "fs/exofs/Kconfig"
  8. +source "fs/aufs/Kconfig"
  9. endif # MISC_FILESYSTEMS
  10. diff -Nur linux-2.6.37.orig/fs/Makefile linux-2.6.37/fs/Makefile
  11. --- linux-2.6.37.orig/fs/Makefile 2011-01-05 01:50:19.000000000 +0100
  12. +++ linux-2.6.37/fs/Makefile 2011-01-11 20:15:11.000000000 +0100
  13. @@ -121,3 +121,4 @@
  14. obj-$(CONFIG_GFS2_FS) += gfs2/
  15. obj-$(CONFIG_EXOFS_FS) += exofs/
  16. obj-$(CONFIG_CEPH_FS) += ceph/
  17. +obj-$(CONFIG_AUFS_FS) += aufs/
  18. diff -Nur linux-2.6.37.orig/fs/aufs/Kconfig linux-2.6.37/fs/aufs/Kconfig
  19. --- linux-2.6.37.orig/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100
  20. +++ linux-2.6.37/fs/aufs/Kconfig 2011-01-11 20:15:11.000000000 +0100
  21. @@ -0,0 +1,180 @@
  22. +config AUFS_FS
  23. + tristate "Aufs (Advanced multi layered unification filesystem) support"
  24. + depends on EXPERIMENTAL
  25. + help
  26. + Aufs is a stackable unification filesystem such as Unionfs,
  27. + which unifies several directories and provides a merged single
  28. + directory.
  29. + In the early days, aufs was entirely re-designed and
  30. + re-implemented Unionfs Version 1.x series. Introducing many
  31. + original ideas, approaches and improvements, it becomes totally
  32. + different from Unionfs while keeping the basic features.
  33. +
  34. +if AUFS_FS
  35. +choice
  36. + prompt "Maximum number of branches"
  37. + default AUFS_BRANCH_MAX_127
  38. + help
  39. + Specifies the maximum number of branches (or member directories)
  40. + in a single aufs. The larger value consumes more system
  41. + resources and has a minor impact to performance.
  42. +config AUFS_BRANCH_MAX_127
  43. + bool "127"
  44. + help
  45. + Specifies the maximum number of branches (or member directories)
  46. + in a single aufs. The larger value consumes more system
  47. + resources and has a minor impact to performance.
  48. +config AUFS_BRANCH_MAX_511
  49. + bool "511"
  50. + help
  51. + Specifies the maximum number of branches (or member directories)
  52. + in a single aufs. The larger value consumes more system
  53. + resources and has a minor impact to performance.
  54. +config AUFS_BRANCH_MAX_1023
  55. + bool "1023"
  56. + help
  57. + Specifies the maximum number of branches (or member directories)
  58. + in a single aufs. The larger value consumes more system
  59. + resources and has a minor impact to performance.
  60. +config AUFS_BRANCH_MAX_32767
  61. + bool "32767"
  62. + help
  63. + Specifies the maximum number of branches (or member directories)
  64. + in a single aufs. The larger value consumes more system
  65. + resources and has a minor impact to performance.
  66. +endchoice
  67. +
  68. +config AUFS_SBILIST
  69. + bool
  70. + depends on AUFS_MAGIC_SYSRQ || PROC_FS
  71. + default y
  72. + help
  73. + Automatic configuration for internal use.
  74. + When aufs supports Magic SysRq or /proc, enabled automatically.
  75. +
  76. +config AUFS_HNOTIFY
  77. + bool "Detect direct branch access (bypassing aufs)"
  78. + help
  79. + If you want to modify files on branches directly, eg. bypassing aufs,
  80. + and want aufs to detect the changes of them fully, then enable this
  81. + option and use 'udba=notify' mount option.
  82. + Currently there is only one available configuration, "fsnotify".
  83. + It will have a negative impact to the performance.
  84. + See detail in aufs.5.
  85. +
  86. +choice
  87. + prompt "method" if AUFS_HNOTIFY
  88. + default AUFS_HFSNOTIFY
  89. +config AUFS_HFSNOTIFY
  90. + bool "fsnotify"
  91. + select FSNOTIFY
  92. +endchoice
  93. +
  94. +config AUFS_EXPORT
  95. + bool "NFS-exportable aufs"
  96. + depends on (AUFS_FS = y && EXPORTFS = y) || (AUFS_FS = m && EXPORTFS)
  97. + help
  98. + If you want to export your mounted aufs via NFS, then enable this
  99. + option. There are several requirements for this configuration.
  100. + See detail in aufs.5.
  101. +
  102. +config AUFS_INO_T_64
  103. + bool
  104. + depends on AUFS_EXPORT
  105. + depends on 64BIT && !(ALPHA || S390)
  106. + default y
  107. + help
  108. + Automatic configuration for internal use.
  109. + /* typedef unsigned long/int __kernel_ino_t */
  110. + /* alpha and s390x are int */
  111. +
  112. +config AUFS_RDU
  113. + bool "Readdir in userspace"
  114. + help
  115. + Aufs has two methods to provide a merged view for a directory,
  116. + by a user-space library and by kernel-space natively. The latter
  117. + is always enabled but sometimes large and slow.
  118. + If you enable this option, install the library in aufs2-util
  119. + package, and set some environment variables for your readdir(3),
  120. + then the work will be handled in user-space which generally
  121. + shows better performance in most cases.
  122. + See detail in aufs.5.
  123. +
  124. +config AUFS_SP_IATTR
  125. + bool "Respect the attributes (mtime/ctime mainly) of special files"
  126. + help
  127. + When you write something to a special file, some attributes of it
  128. + (mtime/ctime mainly) may be updated. Generally such updates are
  129. + less important (actually some device drivers and NFS ignore
  130. + it). But some applications (such like test program) requires
  131. + such updates. If you need these updates, then enable this
  132. + configuration which introduces some overhead.
  133. + Currently this configuration handles FIFO only.
  134. +
  135. +config AUFS_SHWH
  136. + bool "Show whiteouts"
  137. + help
  138. + If you want to make the whiteouts in aufs visible, then enable
  139. + this option and specify 'shwh' mount option. Although it may
  140. + sounds like philosophy or something, but in technically it
  141. + simply shows the name of whiteout with keeping its behaviour.
  142. +
  143. +config AUFS_BR_RAMFS
  144. + bool "Ramfs (initramfs/rootfs) as an aufs branch"
  145. + help
  146. + If you want to use ramfs as an aufs branch fs, then enable this
  147. + option. Generally tmpfs is recommended.
  148. + Aufs prohibited them to be a branch fs by default, because
  149. + initramfs becomes unusable after switch_root or something
  150. + generally. If you sets initramfs as an aufs branch and boot your
  151. + system by switch_root, you will meet a problem easily since the
  152. + files in initramfs may be inaccessible.
  153. + Unless you are going to use ramfs as an aufs branch fs without
  154. + switch_root or something, leave it N.
  155. +
  156. +config AUFS_BR_FUSE
  157. + bool "Fuse fs as an aufs branch"
  158. + depends on FUSE_FS
  159. + select AUFS_POLL
  160. + help
  161. + If you want to use fuse-based userspace filesystem as an aufs
  162. + branch fs, then enable this option.
  163. + It implements the internal poll(2) operation which is
  164. + implemented by fuse only (curretnly).
  165. +
  166. +config AUFS_POLL
  167. + bool
  168. + help
  169. + Automatic configuration for internal use.
  170. +
  171. +config AUFS_BR_HFSPLUS
  172. + bool "Hfsplus as an aufs branch"
  173. + depends on HFSPLUS_FS
  174. + default y
  175. + help
  176. + If you want to use hfsplus fs as an aufs branch fs, then enable
  177. + this option. This option introduces a small overhead at
  178. + copying-up a file on hfsplus.
  179. +
  180. +config AUFS_BDEV_LOOP
  181. + bool
  182. + depends on BLK_DEV_LOOP
  183. + default y
  184. + help
  185. + Automatic configuration for internal use.
  186. + Convert =[ym] into =y.
  187. +
  188. +config AUFS_DEBUG
  189. + bool "Debug aufs"
  190. + help
  191. + Enable this to compile aufs internal debug code.
  192. + It will have a negative impact to the performance.
  193. +
  194. +config AUFS_MAGIC_SYSRQ
  195. + bool
  196. + depends on AUFS_DEBUG && MAGIC_SYSRQ
  197. + default y
  198. + help
  199. + Automatic configuration for internal use.
  200. + When aufs supports Magic SysRq, enabled automatically.
  201. +endif
  202. diff -Nur linux-2.6.37.orig/fs/aufs/Makefile linux-2.6.37/fs/aufs/Makefile
  203. --- linux-2.6.37.orig/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100
  204. +++ linux-2.6.37/fs/aufs/Makefile 2011-01-11 20:15:11.000000000 +0100
  205. @@ -0,0 +1,38 @@
  206. +
  207. +include ${src}/magic.mk
  208. +ifeq (${CONFIG_AUFS_FS},m)
  209. +include ${src}/conf.mk
  210. +endif
  211. +-include ${src}/priv_def.mk
  212. +
  213. +# cf. include/linux/kernel.h
  214. +# enable pr_debug
  215. +ccflags-y += -DDEBUG
  216. +# sparse doesn't allow spaces
  217. +ccflags-y += -D'pr_fmt(fmt)=AUFS_NAME"\040%s:%d:%s[%d]:\040"fmt,__func__,__LINE__,current->comm,current->pid'
  218. +
  219. +obj-$(CONFIG_AUFS_FS) += aufs.o
  220. +aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
  221. + wkq.o vfsub.o dcsub.o \
  222. + cpup.o whout.o wbr_policy.o \
  223. + dinfo.o dentry.o \
  224. + dynop.o \
  225. + finfo.o file.o f_op.o \
  226. + dir.o vdir.o \
  227. + iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
  228. + ioctl.o
  229. +
  230. +# all are boolean
  231. +aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
  232. +aufs-$(CONFIG_SYSFS) += sysfs.o
  233. +aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
  234. +aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
  235. +aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
  236. +aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
  237. +aufs-$(CONFIG_AUFS_EXPORT) += export.o
  238. +aufs-$(CONFIG_AUFS_POLL) += poll.o
  239. +aufs-$(CONFIG_AUFS_RDU) += rdu.o
  240. +aufs-$(CONFIG_AUFS_SP_IATTR) += f_op_sp.o
  241. +aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
  242. +aufs-$(CONFIG_AUFS_DEBUG) += debug.o
  243. +aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
  244. diff -Nur linux-2.6.37.orig/fs/aufs/aufs.h linux-2.6.37/fs/aufs/aufs.h
  245. --- linux-2.6.37.orig/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100
  246. +++ linux-2.6.37/fs/aufs/aufs.h 2011-01-11 20:15:11.000000000 +0100
  247. @@ -0,0 +1,61 @@
  248. +/*
  249. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  250. + *
  251. + * This program, aufs is free software; you can redistribute it and/or modify
  252. + * it under the terms of the GNU General Public License as published by
  253. + * the Free Software Foundation; either version 2 of the License, or
  254. + * (at your option) any later version.
  255. + *
  256. + * This program is distributed in the hope that it will be useful,
  257. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  258. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  259. + * GNU General Public License for more details.
  260. + *
  261. + * You should have received a copy of the GNU General Public License
  262. + * along with this program; if not, write to the Free Software
  263. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  264. + */
  265. +
  266. +/*
  267. + * all header files
  268. + */
  269. +
  270. +#ifndef __AUFS_H__
  271. +#define __AUFS_H__
  272. +
  273. +#ifdef __KERNEL__
  274. +
  275. +#define AuStub(type, name, body, ...) \
  276. + static inline type name(__VA_ARGS__) { body; }
  277. +
  278. +#define AuStubVoid(name, ...) \
  279. + AuStub(void, name, , __VA_ARGS__)
  280. +#define AuStubInt0(name, ...) \
  281. + AuStub(int, name, return 0, __VA_ARGS__)
  282. +
  283. +#include "debug.h"
  284. +
  285. +#include "branch.h"
  286. +#include "cpup.h"
  287. +#include "dcsub.h"
  288. +#include "dbgaufs.h"
  289. +#include "dentry.h"
  290. +#include "dir.h"
  291. +#include "dynop.h"
  292. +#include "file.h"
  293. +#include "fstype.h"
  294. +#include "inode.h"
  295. +#include "loop.h"
  296. +#include "module.h"
  297. +/* never include ./mtx.h */
  298. +#include "opts.h"
  299. +#include "rwsem.h"
  300. +#include "spl.h"
  301. +#include "super.h"
  302. +#include "sysaufs.h"
  303. +#include "vfsub.h"
  304. +#include "whout.h"
  305. +#include "wkq.h"
  306. +
  307. +#endif /* __KERNEL__ */
  308. +#endif /* __AUFS_H__ */
  309. diff -Nur linux-2.6.37.orig/fs/aufs/branch.c linux-2.6.37/fs/aufs/branch.c
  310. --- linux-2.6.37.orig/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100
  311. +++ linux-2.6.37/fs/aufs/branch.c 2011-01-11 20:15:11.000000000 +0100
  312. @@ -0,0 +1,1071 @@
  313. +/*
  314. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  315. + *
  316. + * This program, aufs is free software; you can redistribute it and/or modify
  317. + * it under the terms of the GNU General Public License as published by
  318. + * the Free Software Foundation; either version 2 of the License, or
  319. + * (at your option) any later version.
  320. + *
  321. + * This program is distributed in the hope that it will be useful,
  322. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  323. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  324. + * GNU General Public License for more details.
  325. + *
  326. + * You should have received a copy of the GNU General Public License
  327. + * along with this program; if not, write to the Free Software
  328. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  329. + */
  330. +
  331. +/*
  332. + * branch management
  333. + */
  334. +
  335. +#include <linux/file.h>
  336. +#include <linux/statfs.h>
  337. +#include "aufs.h"
  338. +
  339. +/*
  340. + * free a single branch
  341. + */
  342. +static void au_br_do_free(struct au_branch *br)
  343. +{
  344. + int i;
  345. + struct au_wbr *wbr;
  346. + struct au_dykey **key;
  347. +
  348. + au_hnotify_fin_br(br);
  349. +
  350. + if (br->br_xino.xi_file)
  351. + fput(br->br_xino.xi_file);
  352. + mutex_destroy(&br->br_xino.xi_nondir_mtx);
  353. +
  354. + AuDebugOn(atomic_read(&br->br_count));
  355. +
  356. + wbr = br->br_wbr;
  357. + if (wbr) {
  358. + for (i = 0; i < AuBrWh_Last; i++)
  359. + dput(wbr->wbr_wh[i]);
  360. + AuDebugOn(atomic_read(&wbr->wbr_wh_running));
  361. + AuRwDestroy(&wbr->wbr_wh_rwsem);
  362. + }
  363. +
  364. + key = br->br_dykey;
  365. + for (i = 0; i < AuBrDynOp; i++, key++)
  366. + if (*key)
  367. + au_dy_put(*key);
  368. + else
  369. + break;
  370. +
  371. + mntput(br->br_mnt);
  372. + kfree(wbr);
  373. + kfree(br);
  374. +}
  375. +
  376. +/*
  377. + * frees all branches
  378. + */
  379. +void au_br_free(struct au_sbinfo *sbinfo)
  380. +{
  381. + aufs_bindex_t bmax;
  382. + struct au_branch **br;
  383. +
  384. + AuRwMustWriteLock(&sbinfo->si_rwsem);
  385. +
  386. + bmax = sbinfo->si_bend + 1;
  387. + br = sbinfo->si_branch;
  388. + while (bmax--)
  389. + au_br_do_free(*br++);
  390. +}
  391. +
  392. +/*
  393. + * find the index of a branch which is specified by @br_id.
  394. + */
  395. +int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
  396. +{
  397. + aufs_bindex_t bindex, bend;
  398. +
  399. + bend = au_sbend(sb);
  400. + for (bindex = 0; bindex <= bend; bindex++)
  401. + if (au_sbr_id(sb, bindex) == br_id)
  402. + return bindex;
  403. + return -1;
  404. +}
  405. +
  406. +/* ---------------------------------------------------------------------- */
  407. +
  408. +/*
  409. + * add a branch
  410. + */
  411. +
  412. +static int test_overlap(struct super_block *sb, struct dentry *h_adding,
  413. + struct dentry *h_root)
  414. +{
  415. + if (unlikely(h_adding == h_root
  416. + || au_test_loopback_overlap(sb, h_adding)))
  417. + return 1;
  418. + if (h_adding->d_sb != h_root->d_sb)
  419. + return 0;
  420. + return au_test_subdir(h_adding, h_root)
  421. + || au_test_subdir(h_root, h_adding);
  422. +}
  423. +
  424. +/*
  425. + * returns a newly allocated branch. @new_nbranch is a number of branches
  426. + * after adding a branch.
  427. + */
  428. +static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
  429. + int perm)
  430. +{
  431. + struct au_branch *add_branch;
  432. + struct dentry *root;
  433. + int err;
  434. +
  435. + err = -ENOMEM;
  436. + root = sb->s_root;
  437. + add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS);
  438. + if (unlikely(!add_branch))
  439. + goto out;
  440. +
  441. + err = au_hnotify_init_br(add_branch, perm);
  442. + if (unlikely(err))
  443. + goto out_br;
  444. +
  445. + add_branch->br_wbr = NULL;
  446. + if (au_br_writable(perm)) {
  447. + /* may be freed separately at changing the branch permission */
  448. + add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr),
  449. + GFP_NOFS);
  450. + if (unlikely(!add_branch->br_wbr))
  451. + goto out_hnotify;
  452. + }
  453. +
  454. + err = au_sbr_realloc(au_sbi(sb), new_nbranch);
  455. + if (!err)
  456. + err = au_di_realloc(au_di(root), new_nbranch);
  457. + if (!err)
  458. + err = au_ii_realloc(au_ii(root->d_inode), new_nbranch);
  459. + if (!err)
  460. + return add_branch; /* success */
  461. +
  462. + kfree(add_branch->br_wbr);
  463. +
  464. +out_hnotify:
  465. + au_hnotify_fin_br(add_branch);
  466. +out_br:
  467. + kfree(add_branch);
  468. +out:
  469. + return ERR_PTR(err);
  470. +}
  471. +
  472. +/*
  473. + * test if the branch permission is legal or not.
  474. + */
  475. +static int test_br(struct inode *inode, int brperm, char *path)
  476. +{
  477. + int err;
  478. +
  479. + err = (au_br_writable(brperm) && IS_RDONLY(inode));
  480. + if (!err)
  481. + goto out;
  482. +
  483. + err = -EINVAL;
  484. + pr_err("write permission for readonly mount or inode, %s\n", path);
  485. +
  486. +out:
  487. + return err;
  488. +}
  489. +
  490. +/*
  491. + * returns:
  492. + * 0: success, the caller will add it
  493. + * plus: success, it is already unified, the caller should ignore it
  494. + * minus: error
  495. + */
  496. +static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
  497. +{
  498. + int err;
  499. + aufs_bindex_t bend, bindex;
  500. + struct dentry *root;
  501. + struct inode *inode, *h_inode;
  502. +
  503. + root = sb->s_root;
  504. + bend = au_sbend(sb);
  505. + if (unlikely(bend >= 0
  506. + && au_find_dbindex(root, add->path.dentry) >= 0)) {
  507. + err = 1;
  508. + if (!remount) {
  509. + err = -EINVAL;
  510. + pr_err("%s duplicated\n", add->pathname);
  511. + }
  512. + goto out;
  513. + }
  514. +
  515. + err = -ENOSPC; /* -E2BIG; */
  516. + if (unlikely(AUFS_BRANCH_MAX <= add->bindex
  517. + || AUFS_BRANCH_MAX - 1 <= bend)) {
  518. + pr_err("number of branches exceeded %s\n", add->pathname);
  519. + goto out;
  520. + }
  521. +
  522. + err = -EDOM;
  523. + if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) {
  524. + pr_err("bad index %d\n", add->bindex);
  525. + goto out;
  526. + }
  527. +
  528. + inode = add->path.dentry->d_inode;
  529. + err = -ENOENT;
  530. + if (unlikely(!inode->i_nlink)) {
  531. + pr_err("no existence %s\n", add->pathname);
  532. + goto out;
  533. + }
  534. +
  535. + err = -EINVAL;
  536. + if (unlikely(inode->i_sb == sb)) {
  537. + pr_err("%s must be outside\n", add->pathname);
  538. + goto out;
  539. + }
  540. +
  541. + if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
  542. + pr_err("unsupported filesystem, %s (%s)\n",
  543. + add->pathname, au_sbtype(inode->i_sb));
  544. + goto out;
  545. + }
  546. +
  547. + err = test_br(add->path.dentry->d_inode, add->perm, add->pathname);
  548. + if (unlikely(err))
  549. + goto out;
  550. +
  551. + if (bend < 0)
  552. + return 0; /* success */
  553. +
  554. + err = -EINVAL;
  555. + for (bindex = 0; bindex <= bend; bindex++)
  556. + if (unlikely(test_overlap(sb, add->path.dentry,
  557. + au_h_dptr(root, bindex)))) {
  558. + pr_err("%s is overlapped\n", add->pathname);
  559. + goto out;
  560. + }
  561. +
  562. + err = 0;
  563. + if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
  564. + h_inode = au_h_dptr(root, 0)->d_inode;
  565. + if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
  566. + || h_inode->i_uid != inode->i_uid
  567. + || h_inode->i_gid != inode->i_gid)
  568. + pr_warning("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
  569. + add->pathname,
  570. + inode->i_uid, inode->i_gid,
  571. + (inode->i_mode & S_IALLUGO),
  572. + h_inode->i_uid, h_inode->i_gid,
  573. + (h_inode->i_mode & S_IALLUGO));
  574. + }
  575. +
  576. +out:
  577. + return err;
  578. +}
  579. +
  580. +/*
  581. + * initialize or clean the whiteouts for an adding branch
  582. + */
  583. +static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
  584. + int new_perm, struct dentry *h_root)
  585. +{
  586. + int err, old_perm;
  587. + aufs_bindex_t bindex;
  588. + struct mutex *h_mtx;
  589. + struct au_wbr *wbr;
  590. + struct au_hinode *hdir;
  591. +
  592. + wbr = br->br_wbr;
  593. + old_perm = br->br_perm;
  594. + br->br_perm = new_perm;
  595. + hdir = NULL;
  596. + h_mtx = NULL;
  597. + bindex = au_br_index(sb, br->br_id);
  598. + if (0 <= bindex) {
  599. + hdir = au_hi(sb->s_root->d_inode, bindex);
  600. + au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
  601. + } else {
  602. + h_mtx = &h_root->d_inode->i_mutex;
  603. + mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
  604. + }
  605. + if (!wbr)
  606. + err = au_wh_init(h_root, br, sb);
  607. + else {
  608. + wbr_wh_write_lock(wbr);
  609. + err = au_wh_init(h_root, br, sb);
  610. + wbr_wh_write_unlock(wbr);
  611. + }
  612. + if (hdir)
  613. + au_hn_imtx_unlock(hdir);
  614. + else
  615. + mutex_unlock(h_mtx);
  616. + br->br_perm = old_perm;
  617. +
  618. + if (!err && wbr && !au_br_writable(new_perm)) {
  619. + kfree(wbr);
  620. + br->br_wbr = NULL;
  621. + }
  622. +
  623. + return err;
  624. +}
  625. +
  626. +static int au_wbr_init(struct au_branch *br, struct super_block *sb,
  627. + int perm, struct path *path)
  628. +{
  629. + int err;
  630. + struct kstatfs kst;
  631. + struct au_wbr *wbr;
  632. + struct dentry *h_dentry;
  633. +
  634. + wbr = br->br_wbr;
  635. + au_rw_init(&wbr->wbr_wh_rwsem);
  636. + memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh));
  637. + atomic_set(&wbr->wbr_wh_running, 0);
  638. + wbr->wbr_bytes = 0;
  639. +
  640. + /*
  641. + * a limit for rmdir/rename a dir
  642. + * cf. AUFS_MAX_NAMELEN in include/linux/aufs_type.h
  643. + */
  644. + err = vfs_statfs(path, &kst);
  645. + if (unlikely(err))
  646. + goto out;
  647. + err = -EINVAL;
  648. + h_dentry = path->dentry;
  649. + if (kst.f_namelen >= NAME_MAX)
  650. + err = au_br_init_wh(sb, br, perm, h_dentry);
  651. + else
  652. + pr_err("%.*s(%s), unsupported namelen %ld\n",
  653. + AuDLNPair(h_dentry), au_sbtype(h_dentry->d_sb),
  654. + kst.f_namelen);
  655. +
  656. +out:
  657. + return err;
  658. +}
  659. +
  660. +/* intialize a new branch */
  661. +static int au_br_init(struct au_branch *br, struct super_block *sb,
  662. + struct au_opt_add *add)
  663. +{
  664. + int err;
  665. +
  666. + err = 0;
  667. + memset(&br->br_xino, 0, sizeof(br->br_xino));
  668. + mutex_init(&br->br_xino.xi_nondir_mtx);
  669. + br->br_perm = add->perm;
  670. + br->br_mnt = add->path.mnt; /* set first, mntget() later */
  671. + spin_lock_init(&br->br_dykey_lock);
  672. + memset(br->br_dykey, 0, sizeof(br->br_dykey));
  673. + atomic_set(&br->br_count, 0);
  674. + br->br_xino_upper = AUFS_XINO_TRUNC_INIT;
  675. + atomic_set(&br->br_xino_running, 0);
  676. + br->br_id = au_new_br_id(sb);
  677. + AuDebugOn(br->br_id < 0);
  678. +
  679. + if (au_br_writable(add->perm)) {
  680. + err = au_wbr_init(br, sb, add->perm, &add->path);
  681. + if (unlikely(err))
  682. + goto out_err;
  683. + }
  684. +
  685. + if (au_opt_test(au_mntflags(sb), XINO)) {
  686. + err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino,
  687. + au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
  688. + if (unlikely(err)) {
  689. + AuDebugOn(br->br_xino.xi_file);
  690. + goto out_err;
  691. + }
  692. + }
  693. +
  694. + sysaufs_br_init(br);
  695. + mntget(add->path.mnt);
  696. + goto out; /* success */
  697. +
  698. +out_err:
  699. + br->br_mnt = NULL;
  700. +out:
  701. + return err;
  702. +}
  703. +
  704. +static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
  705. + struct au_branch *br, aufs_bindex_t bend,
  706. + aufs_bindex_t amount)
  707. +{
  708. + struct au_branch **brp;
  709. +
  710. + AuRwMustWriteLock(&sbinfo->si_rwsem);
  711. +
  712. + brp = sbinfo->si_branch + bindex;
  713. + memmove(brp + 1, brp, sizeof(*brp) * amount);
  714. + *brp = br;
  715. + sbinfo->si_bend++;
  716. + if (unlikely(bend < 0))
  717. + sbinfo->si_bend = 0;
  718. +}
  719. +
  720. +static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
  721. + aufs_bindex_t bend, aufs_bindex_t amount)
  722. +{
  723. + struct au_hdentry *hdp;
  724. +
  725. + AuRwMustWriteLock(&dinfo->di_rwsem);
  726. +
  727. + hdp = dinfo->di_hdentry + bindex;
  728. + memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
  729. + au_h_dentry_init(hdp);
  730. + dinfo->di_bend++;
  731. + if (unlikely(bend < 0))
  732. + dinfo->di_bstart = 0;
  733. +}
  734. +
  735. +static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
  736. + aufs_bindex_t bend, aufs_bindex_t amount)
  737. +{
  738. + struct au_hinode *hip;
  739. +
  740. + AuRwMustWriteLock(&iinfo->ii_rwsem);
  741. +
  742. + hip = iinfo->ii_hinode + bindex;
  743. + memmove(hip + 1, hip, sizeof(*hip) * amount);
  744. + hip->hi_inode = NULL;
  745. + au_hn_init(hip);
  746. + iinfo->ii_bend++;
  747. + if (unlikely(bend < 0))
  748. + iinfo->ii_bstart = 0;
  749. +}
  750. +
  751. +static void au_br_do_add(struct super_block *sb, struct dentry *h_dentry,
  752. + struct au_branch *br, aufs_bindex_t bindex)
  753. +{
  754. + struct dentry *root;
  755. + struct inode *root_inode;
  756. + aufs_bindex_t bend, amount;
  757. +
  758. + root = sb->s_root;
  759. + root_inode = root->d_inode;
  760. + bend = au_sbend(sb);
  761. + amount = bend + 1 - bindex;
  762. + au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount);
  763. + au_br_do_add_hdp(au_di(root), bindex, bend, amount);
  764. + au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount);
  765. + au_set_h_dptr(root, bindex, dget(h_dentry));
  766. + au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode),
  767. + /*flags*/0);
  768. +}
  769. +
  770. +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
  771. +{
  772. + int err;
  773. + aufs_bindex_t bend, add_bindex;
  774. + struct dentry *root, *h_dentry;
  775. + struct inode *root_inode;
  776. + struct au_branch *add_branch;
  777. +
  778. + root = sb->s_root;
  779. + root_inode = root->d_inode;
  780. + IMustLock(root_inode);
  781. + err = test_add(sb, add, remount);
  782. + if (unlikely(err < 0))
  783. + goto out;
  784. + if (err) {
  785. + err = 0;
  786. + goto out; /* success */
  787. + }
  788. +
  789. + bend = au_sbend(sb);
  790. + add_branch = au_br_alloc(sb, bend + 2, add->perm);
  791. + err = PTR_ERR(add_branch);
  792. + if (IS_ERR(add_branch))
  793. + goto out;
  794. +
  795. + err = au_br_init(add_branch, sb, add);
  796. + if (unlikely(err)) {
  797. + au_br_do_free(add_branch);
  798. + goto out;
  799. + }
  800. +
  801. + add_bindex = add->bindex;
  802. + h_dentry = add->path.dentry;
  803. + if (!remount)
  804. + au_br_do_add(sb, h_dentry, add_branch, add_bindex);
  805. + else {
  806. + sysaufs_brs_del(sb, add_bindex);
  807. + au_br_do_add(sb, h_dentry, add_branch, add_bindex);
  808. + sysaufs_brs_add(sb, add_bindex);
  809. + }
  810. +
  811. + if (!add_bindex) {
  812. + au_cpup_attr_all(root_inode, /*force*/1);
  813. + sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
  814. + } else
  815. + au_add_nlink(root_inode, h_dentry->d_inode);
  816. +
  817. + /*
  818. + * this test/set prevents aufs from handling unnecesary notify events
  819. + * of xino files, in a case of re-adding a writable branch which was
  820. + * once detached from aufs.
  821. + */
  822. + if (au_xino_brid(sb) < 0
  823. + && au_br_writable(add_branch->br_perm)
  824. + && !au_test_fs_bad_xino(h_dentry->d_sb)
  825. + && add_branch->br_xino.xi_file
  826. + && add_branch->br_xino.xi_file->f_dentry->d_parent == h_dentry)
  827. + au_xino_brid_set(sb, add_branch->br_id);
  828. +
  829. +out:
  830. + return err;
  831. +}
  832. +
  833. +/* ---------------------------------------------------------------------- */
  834. +
  835. +/*
  836. + * delete a branch
  837. + */
  838. +
  839. +/* to show the line number, do not make it inlined function */
  840. +#define AuVerbose(do_info, fmt, ...) do { \
  841. + if (do_info) \
  842. + pr_info(fmt, ##__VA_ARGS__); \
  843. +} while (0)
  844. +
  845. +/*
  846. + * test if the branch is deletable or not.
  847. + */
  848. +static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
  849. + unsigned int sigen, const unsigned int verbose)
  850. +{
  851. + int err, i, j, ndentry;
  852. + aufs_bindex_t bstart, bend;
  853. + struct au_dcsub_pages dpages;
  854. + struct au_dpage *dpage;
  855. + struct dentry *d;
  856. + struct inode *inode;
  857. +
  858. + err = au_dpages_init(&dpages, GFP_NOFS);
  859. + if (unlikely(err))
  860. + goto out;
  861. + err = au_dcsub_pages(&dpages, root, NULL, NULL);
  862. + if (unlikely(err))
  863. + goto out_dpages;
  864. +
  865. + for (i = 0; !err && i < dpages.ndpage; i++) {
  866. + dpage = dpages.dpages + i;
  867. + ndentry = dpage->ndentry;
  868. + for (j = 0; !err && j < ndentry; j++) {
  869. + d = dpage->dentries[j];
  870. + AuDebugOn(!atomic_read(&d->d_count));
  871. + if (!au_digen_test(d, sigen)) {
  872. + di_read_lock_child(d, AuLock_IR);
  873. + if (unlikely(au_dbrange_test(d))) {
  874. + di_read_unlock(d, AuLock_IR);
  875. + continue;
  876. + }
  877. + } else {
  878. + di_write_lock_child(d);
  879. + if (unlikely(au_dbrange_test(d))) {
  880. + di_write_unlock(d);
  881. + continue;
  882. + }
  883. + err = au_reval_dpath(d, sigen);
  884. + if (!err)
  885. + di_downgrade_lock(d, AuLock_IR);
  886. + else {
  887. + di_write_unlock(d);
  888. + break;
  889. + }
  890. + }
  891. +
  892. + /* AuDbgDentry(d); */
  893. + inode = d->d_inode;
  894. + bstart = au_dbstart(d);
  895. + bend = au_dbend(d);
  896. + if (bstart <= bindex
  897. + && bindex <= bend
  898. + && au_h_dptr(d, bindex)
  899. + && ((inode && !S_ISDIR(inode->i_mode))
  900. + || bstart == bend)) {
  901. + err = -EBUSY;
  902. + AuVerbose(verbose, "busy %.*s\n", AuDLNPair(d));
  903. + AuDbgDentry(d);
  904. + }
  905. + di_read_unlock(d, AuLock_IR);
  906. + }
  907. + }
  908. +
  909. +out_dpages:
  910. + au_dpages_free(&dpages);
  911. +out:
  912. + return err;
  913. +}
  914. +
  915. +static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
  916. + unsigned int sigen, const unsigned int verbose)
  917. +{
  918. + int err;
  919. + unsigned long long max, ull;
  920. + struct inode *i, **array;
  921. + aufs_bindex_t bstart, bend;
  922. +
  923. + array = au_iarray_alloc(sb, &max);
  924. + err = PTR_ERR(array);
  925. + if (IS_ERR(array))
  926. + goto out;
  927. +
  928. + err = 0;
  929. + AuDbg("b%d\n", bindex);
  930. + for (ull = 0; !err && ull < max; ull++) {
  931. + i = array[ull];
  932. + if (i->i_ino == AUFS_ROOT_INO)
  933. + continue;
  934. +
  935. + /* AuDbgInode(i); */
  936. + if (au_iigen(i) == sigen)
  937. + ii_read_lock_child(i);
  938. + else {
  939. + ii_write_lock_child(i);
  940. + err = au_refresh_hinode_self(i);
  941. + au_iigen_dec(i);
  942. + if (!err)
  943. + ii_downgrade_lock(i);
  944. + else {
  945. + ii_write_unlock(i);
  946. + break;
  947. + }
  948. + }
  949. +
  950. + bstart = au_ibstart(i);
  951. + bend = au_ibend(i);
  952. + if (bstart <= bindex
  953. + && bindex <= bend
  954. + && au_h_iptr(i, bindex)
  955. + && (!S_ISDIR(i->i_mode) || bstart == bend)) {
  956. + err = -EBUSY;
  957. + AuVerbose(verbose, "busy i%lu\n", i->i_ino);
  958. + AuDbgInode(i);
  959. + }
  960. + ii_read_unlock(i);
  961. + }
  962. + au_iarray_free(array, max);
  963. +
  964. +out:
  965. + return err;
  966. +}
  967. +
  968. +static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
  969. + const unsigned int verbose)
  970. +{
  971. + int err;
  972. + unsigned int sigen;
  973. +
  974. + sigen = au_sigen(root->d_sb);
  975. + DiMustNoWaiters(root);
  976. + IiMustNoWaiters(root->d_inode);
  977. + di_write_unlock(root);
  978. + err = test_dentry_busy(root, bindex, sigen, verbose);
  979. + if (!err)
  980. + err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
  981. + di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
  982. +
  983. + return err;
  984. +}
  985. +
  986. +static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
  987. + const aufs_bindex_t bindex,
  988. + const aufs_bindex_t bend)
  989. +{
  990. + struct au_branch **brp, **p;
  991. +
  992. + AuRwMustWriteLock(&sbinfo->si_rwsem);
  993. +
  994. + brp = sbinfo->si_branch + bindex;
  995. + if (bindex < bend)
  996. + memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex));
  997. + sbinfo->si_branch[0 + bend] = NULL;
  998. + sbinfo->si_bend--;
  999. +
  1000. + p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, GFP_NOFS);
  1001. + if (p)
  1002. + sbinfo->si_branch = p;
  1003. + /* harmless error */
  1004. +}
  1005. +
  1006. +static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
  1007. + const aufs_bindex_t bend)
  1008. +{
  1009. + struct au_hdentry *hdp, *p;
  1010. +
  1011. + AuRwMustWriteLock(&dinfo->di_rwsem);
  1012. +
  1013. + hdp = dinfo->di_hdentry;
  1014. + if (bindex < bend)
  1015. + memmove(hdp + bindex, hdp + bindex + 1,
  1016. + sizeof(*hdp) * (bend - bindex));
  1017. + hdp[0 + bend].hd_dentry = NULL;
  1018. + dinfo->di_bend--;
  1019. +
  1020. + p = krealloc(hdp, sizeof(*p) * bend, GFP_NOFS);
  1021. + if (p)
  1022. + dinfo->di_hdentry = p;
  1023. + /* harmless error */
  1024. +}
  1025. +
  1026. +static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
  1027. + const aufs_bindex_t bend)
  1028. +{
  1029. + struct au_hinode *hip, *p;
  1030. +
  1031. + AuRwMustWriteLock(&iinfo->ii_rwsem);
  1032. +
  1033. + hip = iinfo->ii_hinode + bindex;
  1034. + if (bindex < bend)
  1035. + memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex));
  1036. + iinfo->ii_hinode[0 + bend].hi_inode = NULL;
  1037. + au_hn_init(iinfo->ii_hinode + bend);
  1038. + iinfo->ii_bend--;
  1039. +
  1040. + p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, GFP_NOFS);
  1041. + if (p)
  1042. + iinfo->ii_hinode = p;
  1043. + /* harmless error */
  1044. +}
  1045. +
  1046. +static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
  1047. + struct au_branch *br)
  1048. +{
  1049. + aufs_bindex_t bend;
  1050. + struct au_sbinfo *sbinfo;
  1051. + struct dentry *root;
  1052. + struct inode *inode;
  1053. +
  1054. + SiMustWriteLock(sb);
  1055. +
  1056. + root = sb->s_root;
  1057. + inode = root->d_inode;
  1058. + sbinfo = au_sbi(sb);
  1059. + bend = sbinfo->si_bend;
  1060. +
  1061. + dput(au_h_dptr(root, bindex));
  1062. + au_hiput(au_hi(inode, bindex));
  1063. + au_br_do_free(br);
  1064. +
  1065. + au_br_do_del_brp(sbinfo, bindex, bend);
  1066. + au_br_do_del_hdp(au_di(root), bindex, bend);
  1067. + au_br_do_del_hip(au_ii(inode), bindex, bend);
  1068. +}
  1069. +
  1070. +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
  1071. +{
  1072. + int err, rerr, i;
  1073. + unsigned int mnt_flags;
  1074. + aufs_bindex_t bindex, bend, br_id;
  1075. + unsigned char do_wh, verbose;
  1076. + struct au_branch *br;
  1077. + struct au_wbr *wbr;
  1078. +
  1079. + err = 0;
  1080. + bindex = au_find_dbindex(sb->s_root, del->h_path.dentry);
  1081. + if (bindex < 0) {
  1082. + if (remount)
  1083. + goto out; /* success */
  1084. + err = -ENOENT;
  1085. + pr_err("%s no such branch\n", del->pathname);
  1086. + goto out;
  1087. + }
  1088. + AuDbg("bindex b%d\n", bindex);
  1089. +
  1090. + err = -EBUSY;
  1091. + mnt_flags = au_mntflags(sb);
  1092. + verbose = !!au_opt_test(mnt_flags, VERBOSE);
  1093. + bend = au_sbend(sb);
  1094. + if (unlikely(!bend)) {
  1095. + AuVerbose(verbose, "no more branches left\n");
  1096. + goto out;
  1097. + }
  1098. + br = au_sbr(sb, bindex);
  1099. + i = atomic_read(&br->br_count);
  1100. + if (unlikely(i)) {
  1101. + AuVerbose(verbose, "%d file(s) opened\n", i);
  1102. + goto out;
  1103. + }
  1104. +
  1105. + wbr = br->br_wbr;
  1106. + do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
  1107. + if (do_wh) {
  1108. + /* instead of WbrWhMustWriteLock(wbr) */
  1109. + SiMustWriteLock(sb);
  1110. + for (i = 0; i < AuBrWh_Last; i++) {
  1111. + dput(wbr->wbr_wh[i]);
  1112. + wbr->wbr_wh[i] = NULL;
  1113. + }
  1114. + }
  1115. +
  1116. + err = test_children_busy(sb->s_root, bindex, verbose);
  1117. + if (unlikely(err)) {
  1118. + if (do_wh)
  1119. + goto out_wh;
  1120. + goto out;
  1121. + }
  1122. +
  1123. + err = 0;
  1124. + br_id = br->br_id;
  1125. + if (!remount)
  1126. + au_br_do_del(sb, bindex, br);
  1127. + else {
  1128. + sysaufs_brs_del(sb, bindex);
  1129. + au_br_do_del(sb, bindex, br);
  1130. + sysaufs_brs_add(sb, bindex);
  1131. + }
  1132. +
  1133. + if (!bindex) {
  1134. + au_cpup_attr_all(sb->s_root->d_inode, /*force*/1);
  1135. + sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
  1136. + } else
  1137. + au_sub_nlink(sb->s_root->d_inode, del->h_path.dentry->d_inode);
  1138. + if (au_opt_test(mnt_flags, PLINK))
  1139. + au_plink_half_refresh(sb, br_id);
  1140. +
  1141. + if (au_xino_brid(sb) == br_id)
  1142. + au_xino_brid_set(sb, -1);
  1143. + goto out; /* success */
  1144. +
  1145. +out_wh:
  1146. + /* revert */
  1147. + rerr = au_br_init_wh(sb, br, br->br_perm, del->h_path.dentry);
  1148. + if (rerr)
  1149. + pr_warning("failed re-creating base whiteout, %s. (%d)\n",
  1150. + del->pathname, rerr);
  1151. +out:
  1152. + return err;
  1153. +}
  1154. +
  1155. +/* ---------------------------------------------------------------------- */
  1156. +
  1157. +/*
  1158. + * change a branch permission
  1159. + */
  1160. +
  1161. +static void au_warn_ima(void)
  1162. +{
  1163. +#ifdef CONFIG_IMA
  1164. + /* since it doesn't support mark_files_ro() */
  1165. + AuWarn1("RW -> RO makes IMA to produce wrong message\n");
  1166. +#endif
  1167. +}
  1168. +
  1169. +static int do_need_sigen_inc(int a, int b)
  1170. +{
  1171. + return au_br_whable(a) && !au_br_whable(b);
  1172. +}
  1173. +
  1174. +static int need_sigen_inc(int old, int new)
  1175. +{
  1176. + return do_need_sigen_inc(old, new)
  1177. + || do_need_sigen_inc(new, old);
  1178. +}
  1179. +
  1180. +static unsigned long long au_farray_cb(void *a,
  1181. + unsigned long long max __maybe_unused,
  1182. + void *arg)
  1183. +{
  1184. + unsigned long long n;
  1185. + struct file **p, *f;
  1186. + struct super_block *sb = arg;
  1187. +
  1188. + n = 0;
  1189. + p = a;
  1190. + lg_global_lock(files_lglock);
  1191. + do_file_list_for_each_entry(sb, f) {
  1192. + if (au_fi(f)
  1193. + && !special_file(f->f_dentry->d_inode->i_mode)) {
  1194. + get_file(f);
  1195. + *p++ = f;
  1196. + n++;
  1197. + AuDebugOn(n > max);
  1198. + }
  1199. + } while_file_list_for_each_entry;
  1200. + lg_global_unlock(files_lglock);
  1201. +
  1202. + return n;
  1203. +}
  1204. +
  1205. +static struct file **au_farray_alloc(struct super_block *sb,
  1206. + unsigned long long *max)
  1207. +{
  1208. + *max = atomic_long_read(&au_sbi(sb)->si_nfiles);
  1209. + return au_array_alloc(max, au_farray_cb, sb);
  1210. +}
  1211. +
  1212. +static void au_farray_free(struct file **a, unsigned long long max)
  1213. +{
  1214. + unsigned long long ull;
  1215. +
  1216. + for (ull = 0; ull < max; ull++)
  1217. + if (a[ull])
  1218. + fput(a[ull]);
  1219. + au_array_free(a);
  1220. +}
  1221. +
  1222. +static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
  1223. +{
  1224. + int err, do_warn;
  1225. + unsigned long long ull, max;
  1226. + aufs_bindex_t br_id;
  1227. + struct file *file, *hf, **array;
  1228. + struct inode *inode;
  1229. + struct au_hfile *hfile;
  1230. +
  1231. + array = au_farray_alloc(sb, &max);
  1232. + err = PTR_ERR(array);
  1233. + if (IS_ERR(array))
  1234. + goto out;
  1235. +
  1236. + do_warn = 0;
  1237. + br_id = au_sbr_id(sb, bindex);
  1238. + for (ull = 0; ull < max; ull++) {
  1239. + file = array[ull];
  1240. +
  1241. + /* AuDbg("%.*s\n", AuDLNPair(file->f_dentry)); */
  1242. + fi_read_lock(file);
  1243. + if (unlikely(au_test_mmapped(file))) {
  1244. + err = -EBUSY;
  1245. + AuDbgFile(file);
  1246. + FiMustNoWaiters(file);
  1247. + fi_read_unlock(file);
  1248. + goto out_array;
  1249. + }
  1250. +
  1251. + inode = file->f_dentry->d_inode;
  1252. + hfile = &au_fi(file)->fi_htop;
  1253. + hf = hfile->hf_file;
  1254. + if (!S_ISREG(inode->i_mode)
  1255. + || !(file->f_mode & FMODE_WRITE)
  1256. + || hfile->hf_br->br_id != br_id
  1257. + || !(hf->f_mode & FMODE_WRITE))
  1258. + array[ull] = NULL;
  1259. + else {
  1260. + do_warn = 1;
  1261. + get_file(file);
  1262. + }
  1263. +
  1264. + FiMustNoWaiters(file);
  1265. + fi_read_unlock(file);
  1266. + fput(file);
  1267. + }
  1268. +
  1269. + err = 0;
  1270. + if (do_warn)
  1271. + au_warn_ima();
  1272. +
  1273. + for (ull = 0; ull < max; ull++) {
  1274. + file = array[ull];
  1275. + if (!file)
  1276. + continue;
  1277. +
  1278. + /* todo: already flushed? */
  1279. + /* cf. fs/super.c:mark_files_ro() */
  1280. + /* fi_read_lock(file); */
  1281. + hfile = &au_fi(file)->fi_htop;
  1282. + hf = hfile->hf_file;
  1283. + /* fi_read_unlock(file); */
  1284. + spin_lock(&hf->f_lock);
  1285. + hf->f_mode &= ~FMODE_WRITE;
  1286. + spin_unlock(&hf->f_lock);
  1287. + if (!file_check_writeable(hf)) {
  1288. + file_release_write(hf);
  1289. + mnt_drop_write(hf->f_vfsmnt);
  1290. + }
  1291. + }
  1292. +
  1293. +out_array:
  1294. + au_farray_free(array, max);
  1295. +out:
  1296. + AuTraceErr(err);
  1297. + return err;
  1298. +}
  1299. +
  1300. +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
  1301. + int *do_refresh)
  1302. +{
  1303. + int err, rerr;
  1304. + aufs_bindex_t bindex;
  1305. + struct path path;
  1306. + struct dentry *root;
  1307. + struct au_branch *br;
  1308. +
  1309. + root = sb->s_root;
  1310. + bindex = au_find_dbindex(root, mod->h_root);
  1311. + if (bindex < 0) {
  1312. + if (remount)
  1313. + return 0; /* success */
  1314. + err = -ENOENT;
  1315. + pr_err("%s no such branch\n", mod->path);
  1316. + goto out;
  1317. + }
  1318. + AuDbg("bindex b%d\n", bindex);
  1319. +
  1320. + err = test_br(mod->h_root->d_inode, mod->perm, mod->path);
  1321. + if (unlikely(err))
  1322. + goto out;
  1323. +
  1324. + br = au_sbr(sb, bindex);
  1325. + if (br->br_perm == mod->perm)
  1326. + return 0; /* success */
  1327. +
  1328. + if (au_br_writable(br->br_perm)) {
  1329. + /* remove whiteout base */
  1330. + err = au_br_init_wh(sb, br, mod->perm, mod->h_root);
  1331. + if (unlikely(err))
  1332. + goto out;
  1333. +
  1334. + if (!au_br_writable(mod->perm)) {
  1335. + /* rw --> ro, file might be mmapped */
  1336. + DiMustNoWaiters(root);
  1337. + IiMustNoWaiters(root->d_inode);
  1338. + di_write_unlock(root);
  1339. + err = au_br_mod_files_ro(sb, bindex);
  1340. + /* aufs_write_lock() calls ..._child() */
  1341. + di_write_lock_child(root);
  1342. +
  1343. + if (unlikely(err)) {
  1344. + rerr = -ENOMEM;
  1345. + br->br_wbr = kmalloc(sizeof(*br->br_wbr),
  1346. + GFP_NOFS);
  1347. + if (br->br_wbr) {
  1348. + path.mnt = br->br_mnt;
  1349. + path.dentry = mod->h_root;
  1350. + rerr = au_wbr_init(br, sb, br->br_perm,
  1351. + &path);
  1352. + }
  1353. + if (unlikely(rerr)) {
  1354. + AuIOErr("nested error %d (%d)\n",
  1355. + rerr, err);
  1356. + br->br_perm = mod->perm;
  1357. + }
  1358. + }
  1359. + }
  1360. + } else if (au_br_writable(mod->perm)) {
  1361. + /* ro --> rw */
  1362. + err = -ENOMEM;
  1363. + br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS);
  1364. + if (br->br_wbr) {
  1365. + path.mnt = br->br_mnt;
  1366. + path.dentry = mod->h_root;
  1367. + err = au_wbr_init(br, sb, mod->perm, &path);
  1368. + if (unlikely(err)) {
  1369. + kfree(br->br_wbr);
  1370. + br->br_wbr = NULL;
  1371. + }
  1372. + }
  1373. + }
  1374. +
  1375. + if (!err) {
  1376. + *do_refresh |= need_sigen_inc(br->br_perm, mod->perm);
  1377. + br->br_perm = mod->perm;
  1378. + }
  1379. +
  1380. +out:
  1381. + AuTraceErr(err);
  1382. + return err;
  1383. +}
  1384. diff -Nur linux-2.6.37.orig/fs/aufs/branch.h linux-2.6.37/fs/aufs/branch.h
  1385. --- linux-2.6.37.orig/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100
  1386. +++ linux-2.6.37/fs/aufs/branch.h 2011-01-11 20:15:11.000000000 +0100
  1387. @@ -0,0 +1,229 @@
  1388. +/*
  1389. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  1390. + *
  1391. + * This program, aufs is free software; you can redistribute it and/or modify
  1392. + * it under the terms of the GNU General Public License as published by
  1393. + * the Free Software Foundation; either version 2 of the License, or
  1394. + * (at your option) any later version.
  1395. + *
  1396. + * This program is distributed in the hope that it will be useful,
  1397. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1398. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1399. + * GNU General Public License for more details.
  1400. + *
  1401. + * You should have received a copy of the GNU General Public License
  1402. + * along with this program; if not, write to the Free Software
  1403. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  1404. + */
  1405. +
  1406. +/*
  1407. + * branch filesystems and xino for them
  1408. + */
  1409. +
  1410. +#ifndef __AUFS_BRANCH_H__
  1411. +#define __AUFS_BRANCH_H__
  1412. +
  1413. +#ifdef __KERNEL__
  1414. +
  1415. +#include <linux/fs.h>
  1416. +#include <linux/mount.h>
  1417. +#include <linux/aufs_type.h>
  1418. +#include "dynop.h"
  1419. +#include "rwsem.h"
  1420. +#include "super.h"
  1421. +
  1422. +/* ---------------------------------------------------------------------- */
  1423. +
  1424. +/* a xino file */
  1425. +struct au_xino_file {
  1426. + struct file *xi_file;
  1427. + struct mutex xi_nondir_mtx;
  1428. +
  1429. + /* todo: make xino files an array to support huge inode number */
  1430. +
  1431. +#ifdef CONFIG_DEBUG_FS
  1432. + struct dentry *xi_dbgaufs;
  1433. +#endif
  1434. +};
  1435. +
  1436. +/* members for writable branch only */
  1437. +enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
  1438. +struct au_wbr {
  1439. + struct au_rwsem wbr_wh_rwsem;
  1440. + struct dentry *wbr_wh[AuBrWh_Last];
  1441. + atomic_t wbr_wh_running;
  1442. +#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
  1443. +#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
  1444. +#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
  1445. +
  1446. + /* mfs mode */
  1447. + unsigned long long wbr_bytes;
  1448. +};
  1449. +
  1450. +/* ext2 has 3 types of operations at least, ext3 has 4 */
  1451. +#define AuBrDynOp (AuDyLast * 4)
  1452. +
  1453. +/* protected by superblock rwsem */
  1454. +struct au_branch {
  1455. + struct au_xino_file br_xino;
  1456. +
  1457. + aufs_bindex_t br_id;
  1458. +
  1459. + int br_perm;
  1460. + struct vfsmount *br_mnt;
  1461. + spinlock_t br_dykey_lock;
  1462. + struct au_dykey *br_dykey[AuBrDynOp];
  1463. + atomic_t br_count;
  1464. +
  1465. + struct au_wbr *br_wbr;
  1466. +
  1467. + /* xino truncation */
  1468. + blkcnt_t br_xino_upper; /* watermark in blocks */
  1469. + atomic_t br_xino_running;
  1470. +
  1471. +#ifdef CONFIG_AUFS_HFSNOTIFY
  1472. + struct fsnotify_group *br_hfsn_group;
  1473. + struct fsnotify_ops br_hfsn_ops;
  1474. +#endif
  1475. +
  1476. +#ifdef CONFIG_SYSFS
  1477. + /* an entry under sysfs per mount-point */
  1478. + char br_name[8];
  1479. + struct attribute br_attr;
  1480. +#endif
  1481. +};
  1482. +
  1483. +/* ---------------------------------------------------------------------- */
  1484. +
  1485. +/* branch permission and attribute */
  1486. +enum {
  1487. + AuBrPerm_RW, /* writable, linkable wh */
  1488. + AuBrPerm_RO, /* readonly, no wh */
  1489. + AuBrPerm_RR, /* natively readonly, no wh */
  1490. +
  1491. + AuBrPerm_RWNoLinkWH, /* un-linkable whiteouts */
  1492. +
  1493. + AuBrPerm_ROWH, /* whiteout-able */
  1494. + AuBrPerm_RRWH, /* whiteout-able */
  1495. +
  1496. + AuBrPerm_Last
  1497. +};
  1498. +
  1499. +static inline int au_br_writable(int brperm)
  1500. +{
  1501. + return brperm == AuBrPerm_RW || brperm == AuBrPerm_RWNoLinkWH;
  1502. +}
  1503. +
  1504. +static inline int au_br_whable(int brperm)
  1505. +{
  1506. + return brperm == AuBrPerm_RW
  1507. + || brperm == AuBrPerm_ROWH
  1508. + || brperm == AuBrPerm_RRWH;
  1509. +}
  1510. +
  1511. +static inline int au_br_rdonly(struct au_branch *br)
  1512. +{
  1513. + return ((br->br_mnt->mnt_sb->s_flags & MS_RDONLY)
  1514. + || !au_br_writable(br->br_perm))
  1515. + ? -EROFS : 0;
  1516. +}
  1517. +
  1518. +static inline int au_br_hnotifyable(int brperm __maybe_unused)
  1519. +{
  1520. +#ifdef CONFIG_AUFS_HNOTIFY
  1521. + return brperm != AuBrPerm_RR && brperm != AuBrPerm_RRWH;
  1522. +#else
  1523. + return 0;
  1524. +#endif
  1525. +}
  1526. +
  1527. +/* ---------------------------------------------------------------------- */
  1528. +
  1529. +/* branch.c */
  1530. +struct au_sbinfo;
  1531. +void au_br_free(struct au_sbinfo *sinfo);
  1532. +int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
  1533. +struct au_opt_add;
  1534. +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
  1535. +struct au_opt_del;
  1536. +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
  1537. +struct au_opt_mod;
  1538. +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
  1539. + int *do_refresh);
  1540. +
  1541. +/* xino.c */
  1542. +static const loff_t au_loff_max = LLONG_MAX;
  1543. +
  1544. +int au_xib_trunc(struct super_block *sb);
  1545. +ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size,
  1546. + loff_t *pos);
  1547. +ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
  1548. + loff_t *pos);
  1549. +struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
  1550. +struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
  1551. +ino_t au_xino_new_ino(struct super_block *sb);
  1552. +void au_xino_delete_inode(struct inode *inode, const int unlinked);
  1553. +int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  1554. + ino_t ino);
  1555. +int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  1556. + ino_t *ino);
  1557. +int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
  1558. + struct file *base_file, int do_test);
  1559. +int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
  1560. +
  1561. +struct au_opt_xino;
  1562. +int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
  1563. +void au_xino_clr(struct super_block *sb);
  1564. +struct file *au_xino_def(struct super_block *sb);
  1565. +int au_xino_path(struct seq_file *seq, struct file *file);
  1566. +
  1567. +/* ---------------------------------------------------------------------- */
  1568. +
  1569. +/* Superblock to branch */
  1570. +static inline
  1571. +aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
  1572. +{
  1573. + return au_sbr(sb, bindex)->br_id;
  1574. +}
  1575. +
  1576. +static inline
  1577. +struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
  1578. +{
  1579. + return au_sbr(sb, bindex)->br_mnt;
  1580. +}
  1581. +
  1582. +static inline
  1583. +struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
  1584. +{
  1585. + return au_sbr_mnt(sb, bindex)->mnt_sb;
  1586. +}
  1587. +
  1588. +static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
  1589. +{
  1590. + atomic_dec(&au_sbr(sb, bindex)->br_count);
  1591. +}
  1592. +
  1593. +static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
  1594. +{
  1595. + return au_sbr(sb, bindex)->br_perm;
  1596. +}
  1597. +
  1598. +static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
  1599. +{
  1600. + return au_br_whable(au_sbr_perm(sb, bindex));
  1601. +}
  1602. +
  1603. +/* ---------------------------------------------------------------------- */
  1604. +
  1605. +/*
  1606. + * wbr_wh_read_lock, wbr_wh_write_lock
  1607. + * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
  1608. + */
  1609. +AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
  1610. +
  1611. +#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
  1612. +#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
  1613. +#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
  1614. +
  1615. +#endif /* __KERNEL__ */
  1616. +#endif /* __AUFS_BRANCH_H__ */
  1617. diff -Nur linux-2.6.37.orig/fs/aufs/conf.mk linux-2.6.37/fs/aufs/conf.mk
  1618. --- linux-2.6.37.orig/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100
  1619. +++ linux-2.6.37/fs/aufs/conf.mk 2011-01-11 20:15:11.000000000 +0100
  1620. @@ -0,0 +1,37 @@
  1621. +
  1622. +AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
  1623. +
  1624. +define AuConf
  1625. +ifdef ${1}
  1626. +AuConfStr += ${1}=${${1}}
  1627. +endif
  1628. +endef
  1629. +
  1630. +AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
  1631. + SBILIST \
  1632. + HNOTIFY HFSNOTIFY \
  1633. + EXPORT INO_T_64 \
  1634. + RDU \
  1635. + SP_IATTR \
  1636. + SHWH \
  1637. + BR_RAMFS \
  1638. + BR_FUSE POLL \
  1639. + BR_HFSPLUS \
  1640. + BDEV_LOOP \
  1641. + DEBUG MAGIC_SYSRQ
  1642. +$(foreach i, ${AuConfAll}, \
  1643. + $(eval $(call AuConf,CONFIG_AUFS_${i})))
  1644. +
  1645. +AuConfName = ${obj}/conf.str
  1646. +${AuConfName}.tmp: FORCE
  1647. + @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
  1648. +${AuConfName}: ${AuConfName}.tmp
  1649. + @diff -q $< $@ > /dev/null 2>&1 || { \
  1650. + echo ' GEN ' $@; \
  1651. + cp -p $< $@; \
  1652. + }
  1653. +FORCE:
  1654. +clean-files += ${AuConfName} ${AuConfName}.tmp
  1655. +${obj}/sysfs.o: ${AuConfName}
  1656. +
  1657. +-include ${srctree}/${src}/conf_priv.mk
  1658. diff -Nur linux-2.6.37.orig/fs/aufs/cpup.c linux-2.6.37/fs/aufs/cpup.c
  1659. --- linux-2.6.37.orig/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
  1660. +++ linux-2.6.37/fs/aufs/cpup.c 2011-01-11 20:15:11.000000000 +0100
  1661. @@ -0,0 +1,1063 @@
  1662. +/*
  1663. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  1664. + *
  1665. + * This program, aufs is free software; you can redistribute it and/or modify
  1666. + * it under the terms of the GNU General Public License as published by
  1667. + * the Free Software Foundation; either version 2 of the License, or
  1668. + * (at your option) any later version.
  1669. + *
  1670. + * This program is distributed in the hope that it will be useful,
  1671. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1672. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1673. + * GNU General Public License for more details.
  1674. + *
  1675. + * You should have received a copy of the GNU General Public License
  1676. + * along with this program; if not, write to the Free Software
  1677. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  1678. + */
  1679. +
  1680. +/*
  1681. + * copy-up functions, see wbr_policy.c for copy-down
  1682. + */
  1683. +
  1684. +#include <linux/file.h>
  1685. +#include <linux/fs_stack.h>
  1686. +#include <linux/mm.h>
  1687. +#include <linux/uaccess.h>
  1688. +#include "aufs.h"
  1689. +
  1690. +void au_cpup_attr_flags(struct inode *dst, struct inode *src)
  1691. +{
  1692. + const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
  1693. + | S_NOATIME | S_NOCMTIME;
  1694. +
  1695. + dst->i_flags |= src->i_flags & ~mask;
  1696. + if (au_test_fs_notime(dst->i_sb))
  1697. + dst->i_flags |= S_NOATIME | S_NOCMTIME;
  1698. +}
  1699. +
  1700. +void au_cpup_attr_timesizes(struct inode *inode)
  1701. +{
  1702. + struct inode *h_inode;
  1703. +
  1704. + h_inode = au_h_iptr(inode, au_ibstart(inode));
  1705. + fsstack_copy_attr_times(inode, h_inode);
  1706. + fsstack_copy_inode_size(inode, h_inode);
  1707. +}
  1708. +
  1709. +void au_cpup_attr_nlink(struct inode *inode, int force)
  1710. +{
  1711. + struct inode *h_inode;
  1712. + struct super_block *sb;
  1713. + aufs_bindex_t bindex, bend;
  1714. +
  1715. + sb = inode->i_sb;
  1716. + bindex = au_ibstart(inode);
  1717. + h_inode = au_h_iptr(inode, bindex);
  1718. + if (!force
  1719. + && !S_ISDIR(h_inode->i_mode)
  1720. + && au_opt_test(au_mntflags(sb), PLINK)
  1721. + && au_plink_test(inode))
  1722. + return;
  1723. +
  1724. + inode->i_nlink = h_inode->i_nlink;
  1725. +
  1726. + /*
  1727. + * fewer nlink makes find(1) noisy, but larger nlink doesn't.
  1728. + * it may includes whplink directory.
  1729. + */
  1730. + if (S_ISDIR(h_inode->i_mode)) {
  1731. + bend = au_ibend(inode);
  1732. + for (bindex++; bindex <= bend; bindex++) {
  1733. + h_inode = au_h_iptr(inode, bindex);
  1734. + if (h_inode)
  1735. + au_add_nlink(inode, h_inode);
  1736. + }
  1737. + }
  1738. +}
  1739. +
  1740. +void au_cpup_attr_changeable(struct inode *inode)
  1741. +{
  1742. + struct inode *h_inode;
  1743. +
  1744. + h_inode = au_h_iptr(inode, au_ibstart(inode));
  1745. + inode->i_mode = h_inode->i_mode;
  1746. + inode->i_uid = h_inode->i_uid;
  1747. + inode->i_gid = h_inode->i_gid;
  1748. + au_cpup_attr_timesizes(inode);
  1749. + au_cpup_attr_flags(inode, h_inode);
  1750. +}
  1751. +
  1752. +void au_cpup_igen(struct inode *inode, struct inode *h_inode)
  1753. +{
  1754. + struct au_iinfo *iinfo = au_ii(inode);
  1755. +
  1756. + IiMustWriteLock(inode);
  1757. +
  1758. + iinfo->ii_higen = h_inode->i_generation;
  1759. + iinfo->ii_hsb1 = h_inode->i_sb;
  1760. +}
  1761. +
  1762. +void au_cpup_attr_all(struct inode *inode, int force)
  1763. +{
  1764. + struct inode *h_inode;
  1765. +
  1766. + h_inode = au_h_iptr(inode, au_ibstart(inode));
  1767. + au_cpup_attr_changeable(inode);
  1768. + if (inode->i_nlink > 0)
  1769. + au_cpup_attr_nlink(inode, force);
  1770. + inode->i_rdev = h_inode->i_rdev;
  1771. + inode->i_blkbits = h_inode->i_blkbits;
  1772. + au_cpup_igen(inode, h_inode);
  1773. +}
  1774. +
  1775. +/* ---------------------------------------------------------------------- */
  1776. +
  1777. +/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
  1778. +
  1779. +/* keep the timestamps of the parent dir when cpup */
  1780. +void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
  1781. + struct path *h_path)
  1782. +{
  1783. + struct inode *h_inode;
  1784. +
  1785. + dt->dt_dentry = dentry;
  1786. + dt->dt_h_path = *h_path;
  1787. + h_inode = h_path->dentry->d_inode;
  1788. + dt->dt_atime = h_inode->i_atime;
  1789. + dt->dt_mtime = h_inode->i_mtime;
  1790. + /* smp_mb(); */
  1791. +}
  1792. +
  1793. +void au_dtime_revert(struct au_dtime *dt)
  1794. +{
  1795. + struct iattr attr;
  1796. + int err;
  1797. +
  1798. + attr.ia_atime = dt->dt_atime;
  1799. + attr.ia_mtime = dt->dt_mtime;
  1800. + attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
  1801. + | ATTR_ATIME | ATTR_ATIME_SET;
  1802. +
  1803. + err = vfsub_notify_change(&dt->dt_h_path, &attr);
  1804. + if (unlikely(err))
  1805. + pr_warning("restoring timestamps failed(%d). ignored\n", err);
  1806. +}
  1807. +
  1808. +/* ---------------------------------------------------------------------- */
  1809. +
  1810. +static noinline_for_stack
  1811. +int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src)
  1812. +{
  1813. + int err, sbits;
  1814. + struct iattr ia;
  1815. + struct path h_path;
  1816. + struct inode *h_isrc, *h_idst;
  1817. +
  1818. + h_path.dentry = au_h_dptr(dst, bindex);
  1819. + h_idst = h_path.dentry->d_inode;
  1820. + h_path.mnt = au_sbr_mnt(dst->d_sb, bindex);
  1821. + h_isrc = h_src->d_inode;
  1822. + ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
  1823. + | ATTR_ATIME | ATTR_MTIME
  1824. + | ATTR_ATIME_SET | ATTR_MTIME_SET;
  1825. + ia.ia_uid = h_isrc->i_uid;
  1826. + ia.ia_gid = h_isrc->i_gid;
  1827. + ia.ia_atime = h_isrc->i_atime;
  1828. + ia.ia_mtime = h_isrc->i_mtime;
  1829. + if (h_idst->i_mode != h_isrc->i_mode
  1830. + && !S_ISLNK(h_idst->i_mode)) {
  1831. + ia.ia_valid |= ATTR_MODE;
  1832. + ia.ia_mode = h_isrc->i_mode;
  1833. + }
  1834. + sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
  1835. + au_cpup_attr_flags(h_idst, h_isrc);
  1836. + err = vfsub_notify_change(&h_path, &ia);
  1837. +
  1838. + /* is this nfs only? */
  1839. + if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
  1840. + ia.ia_valid = ATTR_FORCE | ATTR_MODE;
  1841. + ia.ia_mode = h_isrc->i_mode;
  1842. + err = vfsub_notify_change(&h_path, &ia);
  1843. + }
  1844. +
  1845. + return err;
  1846. +}
  1847. +
  1848. +/* ---------------------------------------------------------------------- */
  1849. +
  1850. +static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
  1851. + char *buf, unsigned long blksize)
  1852. +{
  1853. + int err;
  1854. + size_t sz, rbytes, wbytes;
  1855. + unsigned char all_zero;
  1856. + char *p, *zp;
  1857. + struct mutex *h_mtx;
  1858. + /* reduce stack usage */
  1859. + struct iattr *ia;
  1860. +
  1861. + zp = page_address(ZERO_PAGE(0));
  1862. + if (unlikely(!zp))
  1863. + return -ENOMEM; /* possible? */
  1864. +
  1865. + err = 0;
  1866. + all_zero = 0;
  1867. + while (len) {
  1868. + AuDbg("len %lld\n", len);
  1869. + sz = blksize;
  1870. + if (len < blksize)
  1871. + sz = len;
  1872. +
  1873. + rbytes = 0;
  1874. + /* todo: signal_pending? */
  1875. + while (!rbytes || err == -EAGAIN || err == -EINTR) {
  1876. + rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
  1877. + err = rbytes;
  1878. + }
  1879. + if (unlikely(err < 0))
  1880. + break;
  1881. +
  1882. + all_zero = 0;
  1883. + if (len >= rbytes && rbytes == blksize)
  1884. + all_zero = !memcmp(buf, zp, rbytes);
  1885. + if (!all_zero) {
  1886. + wbytes = rbytes;
  1887. + p = buf;
  1888. + while (wbytes) {
  1889. + size_t b;
  1890. +
  1891. + b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
  1892. + err = b;
  1893. + /* todo: signal_pending? */
  1894. + if (unlikely(err == -EAGAIN || err == -EINTR))
  1895. + continue;
  1896. + if (unlikely(err < 0))
  1897. + break;
  1898. + wbytes -= b;
  1899. + p += b;
  1900. + }
  1901. + } else {
  1902. + loff_t res;
  1903. +
  1904. + AuLabel(hole);
  1905. + res = vfsub_llseek(dst, rbytes, SEEK_CUR);
  1906. + err = res;
  1907. + if (unlikely(res < 0))
  1908. + break;
  1909. + }
  1910. + len -= rbytes;
  1911. + err = 0;
  1912. + }
  1913. +
  1914. + /* the last block may be a hole */
  1915. + if (!err && all_zero) {
  1916. + AuLabel(last hole);
  1917. +
  1918. + err = 1;
  1919. + if (au_test_nfs(dst->f_dentry->d_sb)) {
  1920. + /* nfs requires this step to make last hole */
  1921. + /* is this only nfs? */
  1922. + do {
  1923. + /* todo: signal_pending? */
  1924. + err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
  1925. + } while (err == -EAGAIN || err == -EINTR);
  1926. + if (err == 1)
  1927. + dst->f_pos--;
  1928. + }
  1929. +
  1930. + if (err == 1) {
  1931. + ia = (void *)buf;
  1932. + ia->ia_size = dst->f_pos;
  1933. + ia->ia_valid = ATTR_SIZE | ATTR_FILE;
  1934. + ia->ia_file = dst;
  1935. + h_mtx = &dst->f_dentry->d_inode->i_mutex;
  1936. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
  1937. + err = vfsub_notify_change(&dst->f_path, ia);
  1938. + mutex_unlock(h_mtx);
  1939. + }
  1940. + }
  1941. +
  1942. + return err;
  1943. +}
  1944. +
  1945. +int au_copy_file(struct file *dst, struct file *src, loff_t len)
  1946. +{
  1947. + int err;
  1948. + unsigned long blksize;
  1949. + unsigned char do_kfree;
  1950. + char *buf;
  1951. +
  1952. + err = -ENOMEM;
  1953. + blksize = dst->f_dentry->d_sb->s_blocksize;
  1954. + if (!blksize || PAGE_SIZE < blksize)
  1955. + blksize = PAGE_SIZE;
  1956. + AuDbg("blksize %lu\n", blksize);
  1957. + do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
  1958. + if (do_kfree)
  1959. + buf = kmalloc(blksize, GFP_NOFS);
  1960. + else
  1961. + buf = (void *)__get_free_page(GFP_NOFS);
  1962. + if (unlikely(!buf))
  1963. + goto out;
  1964. +
  1965. + if (len > (1 << 22))
  1966. + AuDbg("copying a large file %lld\n", (long long)len);
  1967. +
  1968. + src->f_pos = 0;
  1969. + dst->f_pos = 0;
  1970. + err = au_do_copy_file(dst, src, len, buf, blksize);
  1971. + if (do_kfree)
  1972. + kfree(buf);
  1973. + else
  1974. + free_page((unsigned long)buf);
  1975. +
  1976. +out:
  1977. + return err;
  1978. +}
  1979. +
  1980. +/*
  1981. + * to support a sparse file which is opened with O_APPEND,
  1982. + * we need to close the file.
  1983. + */
  1984. +static int au_cp_regular(struct dentry *dentry, aufs_bindex_t bdst,
  1985. + aufs_bindex_t bsrc, loff_t len)
  1986. +{
  1987. + int err, i;
  1988. + enum { SRC, DST };
  1989. + struct {
  1990. + aufs_bindex_t bindex;
  1991. + unsigned int flags;
  1992. + struct dentry *dentry;
  1993. + struct file *file;
  1994. + void *label, *label_file;
  1995. + } *f, file[] = {
  1996. + {
  1997. + .bindex = bsrc,
  1998. + .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
  1999. + .file = NULL,
  2000. + .label = &&out,
  2001. + .label_file = &&out_src
  2002. + },
  2003. + {
  2004. + .bindex = bdst,
  2005. + .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
  2006. + .file = NULL,
  2007. + .label = &&out_src,
  2008. + .label_file = &&out_dst
  2009. + }
  2010. + };
  2011. + struct super_block *sb;
  2012. +
  2013. + /* bsrc branch can be ro/rw. */
  2014. + sb = dentry->d_sb;
  2015. + f = file;
  2016. + for (i = 0; i < 2; i++, f++) {
  2017. + f->dentry = au_h_dptr(dentry, f->bindex);
  2018. + f->file = au_h_open(dentry, f->bindex, f->flags, /*file*/NULL);
  2019. + err = PTR_ERR(f->file);
  2020. + if (IS_ERR(f->file))
  2021. + goto *f->label;
  2022. + err = -EINVAL;
  2023. + if (unlikely(!f->file->f_op))
  2024. + goto *f->label_file;
  2025. + }
  2026. +
  2027. + /* try stopping to update while we copyup */
  2028. + IMustLock(file[SRC].dentry->d_inode);
  2029. + err = au_copy_file(file[DST].file, file[SRC].file, len);
  2030. +
  2031. +out_dst:
  2032. + fput(file[DST].file);
  2033. + au_sbr_put(sb, file[DST].bindex);
  2034. +out_src:
  2035. + fput(file[SRC].file);
  2036. + au_sbr_put(sb, file[SRC].bindex);
  2037. +out:
  2038. + return err;
  2039. +}
  2040. +
  2041. +static int au_do_cpup_regular(struct dentry *dentry, aufs_bindex_t bdst,
  2042. + aufs_bindex_t bsrc, loff_t len,
  2043. + struct inode *h_dir, struct path *h_path)
  2044. +{
  2045. + int err, rerr;
  2046. + loff_t l;
  2047. +
  2048. + err = 0;
  2049. + l = i_size_read(au_h_iptr(dentry->d_inode, bsrc));
  2050. + if (len == -1 || l < len)
  2051. + len = l;
  2052. + if (len)
  2053. + err = au_cp_regular(dentry, bdst, bsrc, len);
  2054. + if (!err)
  2055. + goto out; /* success */
  2056. +
  2057. + rerr = vfsub_unlink(h_dir, h_path, /*force*/0);
  2058. + if (rerr) {
  2059. + AuIOErr("failed unlinking cpup-ed %.*s(%d, %d)\n",
  2060. + AuDLNPair(h_path->dentry), err, rerr);
  2061. + err = -EIO;
  2062. + }
  2063. +
  2064. +out:
  2065. + return err;
  2066. +}
  2067. +
  2068. +static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
  2069. + struct inode *h_dir)
  2070. +{
  2071. + int err, symlen;
  2072. + mm_segment_t old_fs;
  2073. + union {
  2074. + char *k;
  2075. + char __user *u;
  2076. + } sym;
  2077. +
  2078. + err = -ENOSYS;
  2079. + if (unlikely(!h_src->d_inode->i_op->readlink))
  2080. + goto out;
  2081. +
  2082. + err = -ENOMEM;
  2083. + sym.k = __getname_gfp(GFP_NOFS);
  2084. + if (unlikely(!sym.k))
  2085. + goto out;
  2086. +
  2087. + old_fs = get_fs();
  2088. + set_fs(KERNEL_DS);
  2089. + symlen = h_src->d_inode->i_op->readlink(h_src, sym.u, PATH_MAX);
  2090. + err = symlen;
  2091. + set_fs(old_fs);
  2092. +
  2093. + if (symlen > 0) {
  2094. + sym.k[symlen] = 0;
  2095. + err = vfsub_symlink(h_dir, h_path, sym.k);
  2096. + }
  2097. + __putname(sym.k);
  2098. +
  2099. +out:
  2100. + return err;
  2101. +}
  2102. +
  2103. +/* return with the lower dst inode is locked */
  2104. +static noinline_for_stack
  2105. +int cpup_entry(struct dentry *dentry, aufs_bindex_t bdst,
  2106. + aufs_bindex_t bsrc, loff_t len, unsigned int flags,
  2107. + struct dentry *dst_parent)
  2108. +{
  2109. + int err;
  2110. + umode_t mode;
  2111. + unsigned int mnt_flags;
  2112. + unsigned char isdir;
  2113. + const unsigned char do_dt = !!au_ftest_cpup(flags, DTIME);
  2114. + struct au_dtime dt;
  2115. + struct path h_path;
  2116. + struct dentry *h_src, *h_dst, *h_parent;
  2117. + struct inode *h_inode, *h_dir;
  2118. + struct super_block *sb;
  2119. +
  2120. + /* bsrc branch can be ro/rw. */
  2121. + h_src = au_h_dptr(dentry, bsrc);
  2122. + h_inode = h_src->d_inode;
  2123. + AuDebugOn(h_inode != au_h_iptr(dentry->d_inode, bsrc));
  2124. +
  2125. + /* try stopping to be referenced while we are creating */
  2126. + h_dst = au_h_dptr(dentry, bdst);
  2127. + h_parent = h_dst->d_parent; /* dir inode is locked */
  2128. + h_dir = h_parent->d_inode;
  2129. + IMustLock(h_dir);
  2130. + AuDebugOn(h_parent != h_dst->d_parent);
  2131. +
  2132. + sb = dentry->d_sb;
  2133. + h_path.mnt = au_sbr_mnt(sb, bdst);
  2134. + if (do_dt) {
  2135. + h_path.dentry = h_parent;
  2136. + au_dtime_store(&dt, dst_parent, &h_path);
  2137. + }
  2138. + h_path.dentry = h_dst;
  2139. +
  2140. + isdir = 0;
  2141. + mode = h_inode->i_mode;
  2142. + switch (mode & S_IFMT) {
  2143. + case S_IFREG:
  2144. + /* try stopping to update while we are referencing */
  2145. + IMustLock(h_inode);
  2146. + err = vfsub_create(h_dir, &h_path, mode | S_IWUSR);
  2147. + if (!err)
  2148. + err = au_do_cpup_regular
  2149. + (dentry, bdst, bsrc, len,
  2150. + au_h_iptr(dst_parent->d_inode, bdst), &h_path);
  2151. + break;
  2152. + case S_IFDIR:
  2153. + isdir = 1;
  2154. + err = vfsub_mkdir(h_dir, &h_path, mode);
  2155. + if (!err) {
  2156. + /*
  2157. + * strange behaviour from the users view,
  2158. + * particularry setattr case
  2159. + */
  2160. + if (au_ibstart(dst_parent->d_inode) == bdst)
  2161. + au_cpup_attr_nlink(dst_parent->d_inode,
  2162. + /*force*/1);
  2163. + au_cpup_attr_nlink(dentry->d_inode, /*force*/1);
  2164. + }
  2165. + break;
  2166. + case S_IFLNK:
  2167. + err = au_do_cpup_symlink(&h_path, h_src, h_dir);
  2168. + break;
  2169. + case S_IFCHR:
  2170. + case S_IFBLK:
  2171. + AuDebugOn(!capable(CAP_MKNOD));
  2172. + /*FALLTHROUGH*/
  2173. + case S_IFIFO:
  2174. + case S_IFSOCK:
  2175. + err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
  2176. + break;
  2177. + default:
  2178. + AuIOErr("Unknown inode type 0%o\n", mode);
  2179. + err = -EIO;
  2180. + }
  2181. +
  2182. + mnt_flags = au_mntflags(sb);
  2183. + if (!au_opt_test(mnt_flags, UDBA_NONE)
  2184. + && !isdir
  2185. + && au_opt_test(mnt_flags, XINO)
  2186. + && h_inode->i_nlink == 1
  2187. + /* todo: unnecessary? */
  2188. + /* && dentry->d_inode->i_nlink == 1 */
  2189. + && bdst < bsrc
  2190. + && !au_ftest_cpup(flags, KEEPLINO))
  2191. + au_xino_write(sb, bsrc, h_inode->i_ino, /*ino*/0);
  2192. + /* ignore this error */
  2193. +
  2194. + if (do_dt)
  2195. + au_dtime_revert(&dt);
  2196. + return err;
  2197. +}
  2198. +
  2199. +/*
  2200. + * copyup the @dentry from @bsrc to @bdst.
  2201. + * the caller must set the both of lower dentries.
  2202. + * @len is for truncating when it is -1 copyup the entire file.
  2203. + * in link/rename cases, @dst_parent may be different from the real one.
  2204. + */
  2205. +static int au_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
  2206. + aufs_bindex_t bsrc, loff_t len, unsigned int flags,
  2207. + struct dentry *dst_parent)
  2208. +{
  2209. + int err, rerr;
  2210. + aufs_bindex_t old_ibstart;
  2211. + unsigned char isdir, plink;
  2212. + struct au_dtime dt;
  2213. + struct path h_path;
  2214. + struct dentry *h_src, *h_dst, *h_parent;
  2215. + struct inode *dst_inode, *h_dir, *inode;
  2216. + struct super_block *sb;
  2217. +
  2218. + AuDebugOn(bsrc <= bdst);
  2219. +
  2220. + sb = dentry->d_sb;
  2221. + h_path.mnt = au_sbr_mnt(sb, bdst);
  2222. + h_dst = au_h_dptr(dentry, bdst);
  2223. + h_parent = h_dst->d_parent; /* dir inode is locked */
  2224. + h_dir = h_parent->d_inode;
  2225. + IMustLock(h_dir);
  2226. +
  2227. + h_src = au_h_dptr(dentry, bsrc);
  2228. + inode = dentry->d_inode;
  2229. +
  2230. + if (!dst_parent)
  2231. + dst_parent = dget_parent(dentry);
  2232. + else
  2233. + dget(dst_parent);
  2234. +
  2235. + plink = !!au_opt_test(au_mntflags(sb), PLINK);
  2236. + dst_inode = au_h_iptr(inode, bdst);
  2237. + if (dst_inode) {
  2238. + if (unlikely(!plink)) {
  2239. + err = -EIO;
  2240. + AuIOErr("hi%lu(i%lu) exists on b%d "
  2241. + "but plink is disabled\n",
  2242. + dst_inode->i_ino, inode->i_ino, bdst);
  2243. + goto out;
  2244. + }
  2245. +
  2246. + if (dst_inode->i_nlink) {
  2247. + const int do_dt = au_ftest_cpup(flags, DTIME);
  2248. +
  2249. + h_src = au_plink_lkup(inode, bdst);
  2250. + err = PTR_ERR(h_src);
  2251. + if (IS_ERR(h_src))
  2252. + goto out;
  2253. + if (unlikely(!h_src->d_inode)) {
  2254. + err = -EIO;
  2255. + AuIOErr("i%lu exists on a upper branch "
  2256. + "but not pseudo-linked\n",
  2257. + inode->i_ino);
  2258. + dput(h_src);
  2259. + goto out;
  2260. + }
  2261. +
  2262. + if (do_dt) {
  2263. + h_path.dentry = h_parent;
  2264. + au_dtime_store(&dt, dst_parent, &h_path);
  2265. + }
  2266. + h_path.dentry = h_dst;
  2267. + err = vfsub_link(h_src, h_dir, &h_path);
  2268. + if (do_dt)
  2269. + au_dtime_revert(&dt);
  2270. + dput(h_src);
  2271. + goto out;
  2272. + } else
  2273. + /* todo: cpup_wh_file? */
  2274. + /* udba work */
  2275. + au_update_ibrange(inode, /*do_put_zero*/1);
  2276. + }
  2277. +
  2278. + old_ibstart = au_ibstart(inode);
  2279. + err = cpup_entry(dentry, bdst, bsrc, len, flags, dst_parent);
  2280. + if (unlikely(err))
  2281. + goto out;
  2282. + dst_inode = h_dst->d_inode;
  2283. + mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
  2284. +
  2285. + err = cpup_iattr(dentry, bdst, h_src);
  2286. + isdir = S_ISDIR(dst_inode->i_mode);
  2287. + if (!err) {
  2288. + if (bdst < old_ibstart) {
  2289. + if (S_ISREG(inode->i_mode)) {
  2290. + err = au_dy_iaop(inode, bdst, dst_inode);
  2291. + if (unlikely(err))
  2292. + goto out_rev;
  2293. + }
  2294. + au_set_ibstart(inode, bdst);
  2295. + }
  2296. + au_set_h_iptr(inode, bdst, au_igrab(dst_inode),
  2297. + au_hi_flags(inode, isdir));
  2298. + mutex_unlock(&dst_inode->i_mutex);
  2299. + if (!isdir
  2300. + && h_src->d_inode->i_nlink > 1
  2301. + && plink)
  2302. + au_plink_append(inode, bdst, h_dst);
  2303. + goto out; /* success */
  2304. + }
  2305. +
  2306. + /* revert */
  2307. +out_rev:
  2308. + h_path.dentry = h_parent;
  2309. + mutex_unlock(&dst_inode->i_mutex);
  2310. + au_dtime_store(&dt, dst_parent, &h_path);
  2311. + h_path.dentry = h_dst;
  2312. + if (!isdir)
  2313. + rerr = vfsub_unlink(h_dir, &h_path, /*force*/0);
  2314. + else
  2315. + rerr = vfsub_rmdir(h_dir, &h_path);
  2316. + au_dtime_revert(&dt);
  2317. + if (rerr) {
  2318. + AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
  2319. + err = -EIO;
  2320. + }
  2321. +
  2322. +out:
  2323. + dput(dst_parent);
  2324. + return err;
  2325. +}
  2326. +
  2327. +struct au_cpup_single_args {
  2328. + int *errp;
  2329. + struct dentry *dentry;
  2330. + aufs_bindex_t bdst, bsrc;
  2331. + loff_t len;
  2332. + unsigned int flags;
  2333. + struct dentry *dst_parent;
  2334. +};
  2335. +
  2336. +static void au_call_cpup_single(void *args)
  2337. +{
  2338. + struct au_cpup_single_args *a = args;
  2339. + *a->errp = au_cpup_single(a->dentry, a->bdst, a->bsrc, a->len,
  2340. + a->flags, a->dst_parent);
  2341. +}
  2342. +
  2343. +int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
  2344. + aufs_bindex_t bsrc, loff_t len, unsigned int flags,
  2345. + struct dentry *dst_parent)
  2346. +{
  2347. + int err, wkq_err;
  2348. + umode_t mode;
  2349. + struct dentry *h_dentry;
  2350. +
  2351. + h_dentry = au_h_dptr(dentry, bsrc);
  2352. + mode = h_dentry->d_inode->i_mode & S_IFMT;
  2353. + if ((mode != S_IFCHR && mode != S_IFBLK)
  2354. + || capable(CAP_MKNOD))
  2355. + err = au_cpup_single(dentry, bdst, bsrc, len, flags,
  2356. + dst_parent);
  2357. + else {
  2358. + struct au_cpup_single_args args = {
  2359. + .errp = &err,
  2360. + .dentry = dentry,
  2361. + .bdst = bdst,
  2362. + .bsrc = bsrc,
  2363. + .len = len,
  2364. + .flags = flags,
  2365. + .dst_parent = dst_parent
  2366. + };
  2367. + wkq_err = au_wkq_wait(au_call_cpup_single, &args);
  2368. + if (unlikely(wkq_err))
  2369. + err = wkq_err;
  2370. + }
  2371. +
  2372. + return err;
  2373. +}
  2374. +
  2375. +/*
  2376. + * copyup the @dentry from the first active lower branch to @bdst,
  2377. + * using au_cpup_single().
  2378. + */
  2379. +static int au_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
  2380. + unsigned int flags)
  2381. +{
  2382. + int err;
  2383. + aufs_bindex_t bsrc, bend;
  2384. +
  2385. + bend = au_dbend(dentry);
  2386. + for (bsrc = bdst + 1; bsrc <= bend; bsrc++)
  2387. + if (au_h_dptr(dentry, bsrc))
  2388. + break;
  2389. +
  2390. + err = au_lkup_neg(dentry, bdst);
  2391. + if (!err) {
  2392. + err = au_cpup_single(dentry, bdst, bsrc, len, flags, NULL);
  2393. + if (!err)
  2394. + return 0; /* success */
  2395. +
  2396. + /* revert */
  2397. + au_set_h_dptr(dentry, bdst, NULL);
  2398. + au_set_dbstart(dentry, bsrc);
  2399. + }
  2400. +
  2401. + return err;
  2402. +}
  2403. +
  2404. +struct au_cpup_simple_args {
  2405. + int *errp;
  2406. + struct dentry *dentry;
  2407. + aufs_bindex_t bdst;
  2408. + loff_t len;
  2409. + unsigned int flags;
  2410. +};
  2411. +
  2412. +static void au_call_cpup_simple(void *args)
  2413. +{
  2414. + struct au_cpup_simple_args *a = args;
  2415. + *a->errp = au_cpup_simple(a->dentry, a->bdst, a->len, a->flags);
  2416. +}
  2417. +
  2418. +int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
  2419. + unsigned int flags)
  2420. +{
  2421. + int err, wkq_err;
  2422. + unsigned char do_sio;
  2423. + struct dentry *parent;
  2424. + struct inode *h_dir;
  2425. +
  2426. + parent = dget_parent(dentry);
  2427. + h_dir = au_h_iptr(parent->d_inode, bdst);
  2428. + do_sio = !!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE);
  2429. + if (!do_sio) {
  2430. + /*
  2431. + * testing CAP_MKNOD is for generic fs,
  2432. + * but CAP_FSETID is for xfs only, currently.
  2433. + */
  2434. + umode_t mode = dentry->d_inode->i_mode;
  2435. + do_sio = (((mode & (S_IFCHR | S_IFBLK))
  2436. + && !capable(CAP_MKNOD))
  2437. + || ((mode & (S_ISUID | S_ISGID))
  2438. + && !capable(CAP_FSETID)));
  2439. + }
  2440. + if (!do_sio)
  2441. + err = au_cpup_simple(dentry, bdst, len, flags);
  2442. + else {
  2443. + struct au_cpup_simple_args args = {
  2444. + .errp = &err,
  2445. + .dentry = dentry,
  2446. + .bdst = bdst,
  2447. + .len = len,
  2448. + .flags = flags
  2449. + };
  2450. + wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
  2451. + if (unlikely(wkq_err))
  2452. + err = wkq_err;
  2453. + }
  2454. +
  2455. + dput(parent);
  2456. + return err;
  2457. +}
  2458. +
  2459. +/* ---------------------------------------------------------------------- */
  2460. +
  2461. +/*
  2462. + * copyup the deleted file for writing.
  2463. + */
  2464. +static int au_do_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst,
  2465. + struct dentry *wh_dentry, struct file *file,
  2466. + loff_t len)
  2467. +{
  2468. + int err;
  2469. + aufs_bindex_t bstart;
  2470. + struct au_dinfo *dinfo;
  2471. + struct dentry *h_d_dst, *h_d_start;
  2472. + struct au_hdentry *hdp;
  2473. +
  2474. + dinfo = au_di(dentry);
  2475. + AuRwMustWriteLock(&dinfo->di_rwsem);
  2476. +
  2477. + bstart = dinfo->di_bstart;
  2478. + hdp = dinfo->di_hdentry;
  2479. + h_d_dst = hdp[0 + bdst].hd_dentry;
  2480. + dinfo->di_bstart = bdst;
  2481. + hdp[0 + bdst].hd_dentry = wh_dentry;
  2482. + if (file) {
  2483. + h_d_start = hdp[0 + bstart].hd_dentry;
  2484. + hdp[0 + bstart].hd_dentry = au_hf_top(file)->f_dentry;
  2485. + }
  2486. + err = au_cpup_single(dentry, bdst, bstart, len, !AuCpup_DTIME,
  2487. + /*h_parent*/NULL);
  2488. + if (file) {
  2489. + if (!err)
  2490. + err = au_reopen_nondir(file);
  2491. + hdp[0 + bstart].hd_dentry = h_d_start;
  2492. + }
  2493. + hdp[0 + bdst].hd_dentry = h_d_dst;
  2494. + dinfo->di_bstart = bstart;
  2495. +
  2496. + return err;
  2497. +}
  2498. +
  2499. +static int au_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
  2500. + struct file *file)
  2501. +{
  2502. + int err;
  2503. + struct au_dtime dt;
  2504. + struct dentry *parent, *h_parent, *wh_dentry;
  2505. + struct au_branch *br;
  2506. + struct path h_path;
  2507. +
  2508. + br = au_sbr(dentry->d_sb, bdst);
  2509. + parent = dget_parent(dentry);
  2510. + h_parent = au_h_dptr(parent, bdst);
  2511. + wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
  2512. + err = PTR_ERR(wh_dentry);
  2513. + if (IS_ERR(wh_dentry))
  2514. + goto out;
  2515. +
  2516. + h_path.dentry = h_parent;
  2517. + h_path.mnt = br->br_mnt;
  2518. + au_dtime_store(&dt, parent, &h_path);
  2519. + err = au_do_cpup_wh(dentry, bdst, wh_dentry, file, len);
  2520. + if (unlikely(err))
  2521. + goto out_wh;
  2522. +
  2523. + dget(wh_dentry);
  2524. + h_path.dentry = wh_dentry;
  2525. + if (!S_ISDIR(wh_dentry->d_inode->i_mode))
  2526. + err = vfsub_unlink(h_parent->d_inode, &h_path, /*force*/0);
  2527. + else
  2528. + err = vfsub_rmdir(h_parent->d_inode, &h_path);
  2529. + if (unlikely(err)) {
  2530. + AuIOErr("failed remove copied-up tmp file %.*s(%d)\n",
  2531. + AuDLNPair(wh_dentry), err);
  2532. + err = -EIO;
  2533. + }
  2534. + au_dtime_revert(&dt);
  2535. + au_set_hi_wh(dentry->d_inode, bdst, wh_dentry);
  2536. +
  2537. +out_wh:
  2538. + dput(wh_dentry);
  2539. +out:
  2540. + dput(parent);
  2541. + return err;
  2542. +}
  2543. +
  2544. +struct au_cpup_wh_args {
  2545. + int *errp;
  2546. + struct dentry *dentry;
  2547. + aufs_bindex_t bdst;
  2548. + loff_t len;
  2549. + struct file *file;
  2550. +};
  2551. +
  2552. +static void au_call_cpup_wh(void *args)
  2553. +{
  2554. + struct au_cpup_wh_args *a = args;
  2555. + *a->errp = au_cpup_wh(a->dentry, a->bdst, a->len, a->file);
  2556. +}
  2557. +
  2558. +int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
  2559. + struct file *file)
  2560. +{
  2561. + int err, wkq_err;
  2562. + struct dentry *parent, *h_orph, *h_parent, *h_dentry;
  2563. + struct inode *dir, *h_dir, *h_tmpdir, *h_inode;
  2564. + struct au_wbr *wbr;
  2565. +
  2566. + parent = dget_parent(dentry);
  2567. + dir = parent->d_inode;
  2568. + h_orph = NULL;
  2569. + h_parent = NULL;
  2570. + h_dir = au_igrab(au_h_iptr(dir, bdst));
  2571. + h_tmpdir = h_dir;
  2572. + if (!h_dir->i_nlink) {
  2573. + wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
  2574. + h_orph = wbr->wbr_orph;
  2575. +
  2576. + h_parent = dget(au_h_dptr(parent, bdst));
  2577. + au_set_h_dptr(parent, bdst, dget(h_orph));
  2578. + h_tmpdir = h_orph->d_inode;
  2579. + au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
  2580. +
  2581. + /* this temporary unlock is safe */
  2582. + if (file)
  2583. + h_dentry = au_hf_top(file)->f_dentry;
  2584. + else
  2585. + h_dentry = au_h_dptr(dentry, au_dbstart(dentry));
  2586. + h_inode = h_dentry->d_inode;
  2587. + IMustLock(h_inode);
  2588. + mutex_unlock(&h_inode->i_mutex);
  2589. + mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
  2590. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  2591. + /* todo: au_h_open_pre()? */
  2592. + }
  2593. +
  2594. + if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE))
  2595. + err = au_cpup_wh(dentry, bdst, len, file);
  2596. + else {
  2597. + struct au_cpup_wh_args args = {
  2598. + .errp = &err,
  2599. + .dentry = dentry,
  2600. + .bdst = bdst,
  2601. + .len = len,
  2602. + .file = file
  2603. + };
  2604. + wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
  2605. + if (unlikely(wkq_err))
  2606. + err = wkq_err;
  2607. + }
  2608. +
  2609. + if (h_orph) {
  2610. + mutex_unlock(&h_tmpdir->i_mutex);
  2611. + /* todo: au_h_open_post()? */
  2612. + au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
  2613. + au_set_h_dptr(parent, bdst, h_parent);
  2614. + }
  2615. + iput(h_dir);
  2616. + dput(parent);
  2617. +
  2618. + return err;
  2619. +}
  2620. +
  2621. +/* ---------------------------------------------------------------------- */
  2622. +
  2623. +/*
  2624. + * generic routine for both of copy-up and copy-down.
  2625. + */
  2626. +/* cf. revalidate function in file.c */
  2627. +int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
  2628. + int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
  2629. + struct dentry *h_parent, void *arg),
  2630. + void *arg)
  2631. +{
  2632. + int err;
  2633. + struct au_pin pin;
  2634. + struct dentry *d, *parent, *h_parent, *real_parent;
  2635. +
  2636. + err = 0;
  2637. + parent = dget_parent(dentry);
  2638. + if (IS_ROOT(parent))
  2639. + goto out;
  2640. +
  2641. + au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
  2642. + au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
  2643. +
  2644. + /* do not use au_dpage */
  2645. + real_parent = parent;
  2646. + while (1) {
  2647. + dput(parent);
  2648. + parent = dget_parent(dentry);
  2649. + h_parent = au_h_dptr(parent, bdst);
  2650. + if (h_parent)
  2651. + goto out; /* success */
  2652. +
  2653. + /* find top dir which is necessary to cpup */
  2654. + do {
  2655. + d = parent;
  2656. + dput(parent);
  2657. + parent = dget_parent(d);
  2658. + di_read_lock_parent3(parent, !AuLock_IR);
  2659. + h_parent = au_h_dptr(parent, bdst);
  2660. + di_read_unlock(parent, !AuLock_IR);
  2661. + } while (!h_parent);
  2662. +
  2663. + if (d != real_parent)
  2664. + di_write_lock_child3(d);
  2665. +
  2666. + /* somebody else might create while we were sleeping */
  2667. + if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) {
  2668. + if (au_h_dptr(d, bdst))
  2669. + au_update_dbstart(d);
  2670. +
  2671. + au_pin_set_dentry(&pin, d);
  2672. + err = au_do_pin(&pin);
  2673. + if (!err) {
  2674. + err = cp(d, bdst, h_parent, arg);
  2675. + au_unpin(&pin);
  2676. + }
  2677. + }
  2678. +
  2679. + if (d != real_parent)
  2680. + di_write_unlock(d);
  2681. + if (unlikely(err))
  2682. + break;
  2683. + }
  2684. +
  2685. +out:
  2686. + dput(parent);
  2687. + return err;
  2688. +}
  2689. +
  2690. +static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
  2691. + struct dentry *h_parent __maybe_unused ,
  2692. + void *arg __maybe_unused)
  2693. +{
  2694. + return au_sio_cpup_simple(dentry, bdst, -1, AuCpup_DTIME);
  2695. +}
  2696. +
  2697. +int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
  2698. +{
  2699. + return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
  2700. +}
  2701. +
  2702. +int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
  2703. +{
  2704. + int err;
  2705. + struct dentry *parent;
  2706. + struct inode *dir;
  2707. +
  2708. + parent = dget_parent(dentry);
  2709. + dir = parent->d_inode;
  2710. + err = 0;
  2711. + if (au_h_iptr(dir, bdst))
  2712. + goto out;
  2713. +
  2714. + di_read_unlock(parent, AuLock_IR);
  2715. + di_write_lock_parent(parent);
  2716. + /* someone else might change our inode while we were sleeping */
  2717. + if (!au_h_iptr(dir, bdst))
  2718. + err = au_cpup_dirs(dentry, bdst);
  2719. + di_downgrade_lock(parent, AuLock_IR);
  2720. +
  2721. +out:
  2722. + dput(parent);
  2723. + return err;
  2724. +}
  2725. diff -Nur linux-2.6.37.orig/fs/aufs/cpup.h linux-2.6.37/fs/aufs/cpup.h
  2726. --- linux-2.6.37.orig/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100
  2727. +++ linux-2.6.37/fs/aufs/cpup.h 2011-01-11 20:15:11.000000000 +0100
  2728. @@ -0,0 +1,83 @@
  2729. +/*
  2730. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  2731. + *
  2732. + * This program, aufs is free software; you can redistribute it and/or modify
  2733. + * it under the terms of the GNU General Public License as published by
  2734. + * the Free Software Foundation; either version 2 of the License, or
  2735. + * (at your option) any later version.
  2736. + *
  2737. + * This program is distributed in the hope that it will be useful,
  2738. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2739. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2740. + * GNU General Public License for more details.
  2741. + *
  2742. + * You should have received a copy of the GNU General Public License
  2743. + * along with this program; if not, write to the Free Software
  2744. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  2745. + */
  2746. +
  2747. +/*
  2748. + * copy-up/down functions
  2749. + */
  2750. +
  2751. +#ifndef __AUFS_CPUP_H__
  2752. +#define __AUFS_CPUP_H__
  2753. +
  2754. +#ifdef __KERNEL__
  2755. +
  2756. +#include <linux/path.h>
  2757. +#include <linux/time.h>
  2758. +#include <linux/aufs_type.h>
  2759. +
  2760. +struct inode;
  2761. +struct file;
  2762. +
  2763. +void au_cpup_attr_flags(struct inode *dst, struct inode *src);
  2764. +void au_cpup_attr_timesizes(struct inode *inode);
  2765. +void au_cpup_attr_nlink(struct inode *inode, int force);
  2766. +void au_cpup_attr_changeable(struct inode *inode);
  2767. +void au_cpup_igen(struct inode *inode, struct inode *h_inode);
  2768. +void au_cpup_attr_all(struct inode *inode, int force);
  2769. +
  2770. +/* ---------------------------------------------------------------------- */
  2771. +
  2772. +/* cpup flags */
  2773. +#define AuCpup_DTIME 1 /* do dtime_store/revert */
  2774. +#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino,
  2775. + for link(2) */
  2776. +#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name)
  2777. +#define au_fset_cpup(flags, name) \
  2778. + do { (flags) |= AuCpup_##name; } while (0)
  2779. +#define au_fclr_cpup(flags, name) \
  2780. + do { (flags) &= ~AuCpup_##name; } while (0)
  2781. +
  2782. +int au_copy_file(struct file *dst, struct file *src, loff_t len);
  2783. +int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
  2784. + aufs_bindex_t bsrc, loff_t len, unsigned int flags,
  2785. + struct dentry *dst_parent);
  2786. +int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
  2787. + unsigned int flags);
  2788. +int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
  2789. + struct file *file);
  2790. +
  2791. +int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
  2792. + int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
  2793. + struct dentry *h_parent, void *arg),
  2794. + void *arg);
  2795. +int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
  2796. +int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
  2797. +
  2798. +/* ---------------------------------------------------------------------- */
  2799. +
  2800. +/* keep timestamps when copyup */
  2801. +struct au_dtime {
  2802. + struct dentry *dt_dentry;
  2803. + struct path dt_h_path;
  2804. + struct timespec dt_atime, dt_mtime;
  2805. +};
  2806. +void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
  2807. + struct path *h_path);
  2808. +void au_dtime_revert(struct au_dtime *dt);
  2809. +
  2810. +#endif /* __KERNEL__ */
  2811. +#endif /* __AUFS_CPUP_H__ */
  2812. diff -Nur linux-2.6.37.orig/fs/aufs/dbgaufs.c linux-2.6.37/fs/aufs/dbgaufs.c
  2813. --- linux-2.6.37.orig/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
  2814. +++ linux-2.6.37/fs/aufs/dbgaufs.c 2011-01-11 20:15:11.000000000 +0100
  2815. @@ -0,0 +1,334 @@
  2816. +/*
  2817. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  2818. + *
  2819. + * This program, aufs is free software; you can redistribute it and/or modify
  2820. + * it under the terms of the GNU General Public License as published by
  2821. + * the Free Software Foundation; either version 2 of the License, or
  2822. + * (at your option) any later version.
  2823. + *
  2824. + * This program is distributed in the hope that it will be useful,
  2825. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2826. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2827. + * GNU General Public License for more details.
  2828. + *
  2829. + * You should have received a copy of the GNU General Public License
  2830. + * along with this program; if not, write to the Free Software
  2831. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  2832. + */
  2833. +
  2834. +/*
  2835. + * debugfs interface
  2836. + */
  2837. +
  2838. +#include <linux/debugfs.h>
  2839. +#include "aufs.h"
  2840. +
  2841. +#ifndef CONFIG_SYSFS
  2842. +#error DEBUG_FS depends upon SYSFS
  2843. +#endif
  2844. +
  2845. +static struct dentry *dbgaufs;
  2846. +static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
  2847. +
  2848. +/* 20 is max digits length of ulong 64 */
  2849. +struct dbgaufs_arg {
  2850. + int n;
  2851. + char a[20 * 4];
  2852. +};
  2853. +
  2854. +/*
  2855. + * common function for all XINO files
  2856. + */
  2857. +static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
  2858. + struct file *file)
  2859. +{
  2860. + kfree(file->private_data);
  2861. + return 0;
  2862. +}
  2863. +
  2864. +static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
  2865. +{
  2866. + int err;
  2867. + struct kstat st;
  2868. + struct dbgaufs_arg *p;
  2869. +
  2870. + err = -ENOMEM;
  2871. + p = kmalloc(sizeof(*p), GFP_NOFS);
  2872. + if (unlikely(!p))
  2873. + goto out;
  2874. +
  2875. + err = 0;
  2876. + p->n = 0;
  2877. + file->private_data = p;
  2878. + if (!xf)
  2879. + goto out;
  2880. +
  2881. + err = vfs_getattr(xf->f_vfsmnt, xf->f_dentry, &st);
  2882. + if (!err) {
  2883. + if (do_fcnt)
  2884. + p->n = snprintf
  2885. + (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n",
  2886. + (long)file_count(xf), st.blocks, st.blksize,
  2887. + (long long)st.size);
  2888. + else
  2889. + p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n",
  2890. + st.blocks, st.blksize,
  2891. + (long long)st.size);
  2892. + AuDebugOn(p->n >= sizeof(p->a));
  2893. + } else {
  2894. + p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
  2895. + err = 0;
  2896. + }
  2897. +
  2898. +out:
  2899. + return err;
  2900. +
  2901. +}
  2902. +
  2903. +static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
  2904. + size_t count, loff_t *ppos)
  2905. +{
  2906. + struct dbgaufs_arg *p;
  2907. +
  2908. + p = file->private_data;
  2909. + return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
  2910. +}
  2911. +
  2912. +/* ---------------------------------------------------------------------- */
  2913. +
  2914. +static int dbgaufs_xib_open(struct inode *inode, struct file *file)
  2915. +{
  2916. + int err;
  2917. + struct au_sbinfo *sbinfo;
  2918. + struct super_block *sb;
  2919. +
  2920. + sbinfo = inode->i_private;
  2921. + sb = sbinfo->si_sb;
  2922. + si_noflush_read_lock(sb);
  2923. + err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0);
  2924. + si_read_unlock(sb);
  2925. + return err;
  2926. +}
  2927. +
  2928. +static const struct file_operations dbgaufs_xib_fop = {
  2929. + .owner = THIS_MODULE,
  2930. + .open = dbgaufs_xib_open,
  2931. + .release = dbgaufs_xi_release,
  2932. + .read = dbgaufs_xi_read
  2933. +};
  2934. +
  2935. +/* ---------------------------------------------------------------------- */
  2936. +
  2937. +#define DbgaufsXi_PREFIX "xi"
  2938. +
  2939. +static int dbgaufs_xino_open(struct inode *inode, struct file *file)
  2940. +{
  2941. + int err;
  2942. + long l;
  2943. + struct au_sbinfo *sbinfo;
  2944. + struct super_block *sb;
  2945. + struct file *xf;
  2946. + struct qstr *name;
  2947. +
  2948. + err = -ENOENT;
  2949. + xf = NULL;
  2950. + name = &file->f_dentry->d_name;
  2951. + if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
  2952. + || memcmp(name->name, DbgaufsXi_PREFIX,
  2953. + sizeof(DbgaufsXi_PREFIX) - 1)))
  2954. + goto out;
  2955. + err = strict_strtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
  2956. + if (unlikely(err))
  2957. + goto out;
  2958. +
  2959. + sbinfo = inode->i_private;
  2960. + sb = sbinfo->si_sb;
  2961. + si_noflush_read_lock(sb);
  2962. + if (l <= au_sbend(sb)) {
  2963. + xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file;
  2964. + err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1);
  2965. + } else
  2966. + err = -ENOENT;
  2967. + si_read_unlock(sb);
  2968. +
  2969. +out:
  2970. + return err;
  2971. +}
  2972. +
  2973. +static const struct file_operations dbgaufs_xino_fop = {
  2974. + .owner = THIS_MODULE,
  2975. + .open = dbgaufs_xino_open,
  2976. + .release = dbgaufs_xi_release,
  2977. + .read = dbgaufs_xi_read
  2978. +};
  2979. +
  2980. +void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
  2981. +{
  2982. + aufs_bindex_t bend;
  2983. + struct au_branch *br;
  2984. + struct au_xino_file *xi;
  2985. +
  2986. + if (!au_sbi(sb)->si_dbgaufs)
  2987. + return;
  2988. +
  2989. + bend = au_sbend(sb);
  2990. + for (; bindex <= bend; bindex++) {
  2991. + br = au_sbr(sb, bindex);
  2992. + xi = &br->br_xino;
  2993. + if (xi->xi_dbgaufs) {
  2994. + debugfs_remove(xi->xi_dbgaufs);
  2995. + xi->xi_dbgaufs = NULL;
  2996. + }
  2997. + }
  2998. +}
  2999. +
  3000. +void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
  3001. +{
  3002. + struct au_sbinfo *sbinfo;
  3003. + struct dentry *parent;
  3004. + struct au_branch *br;
  3005. + struct au_xino_file *xi;
  3006. + aufs_bindex_t bend;
  3007. + char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */
  3008. +
  3009. + sbinfo = au_sbi(sb);
  3010. + parent = sbinfo->si_dbgaufs;
  3011. + if (!parent)
  3012. + return;
  3013. +
  3014. + bend = au_sbend(sb);
  3015. + for (; bindex <= bend; bindex++) {
  3016. + snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
  3017. + br = au_sbr(sb, bindex);
  3018. + xi = &br->br_xino;
  3019. + AuDebugOn(xi->xi_dbgaufs);
  3020. + xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
  3021. + sbinfo, &dbgaufs_xino_fop);
  3022. + /* ignore an error */
  3023. + if (unlikely(!xi->xi_dbgaufs))
  3024. + AuWarn1("failed %s under debugfs\n", name);
  3025. + }
  3026. +}
  3027. +
  3028. +/* ---------------------------------------------------------------------- */
  3029. +
  3030. +#ifdef CONFIG_AUFS_EXPORT
  3031. +static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
  3032. +{
  3033. + int err;
  3034. + struct au_sbinfo *sbinfo;
  3035. + struct super_block *sb;
  3036. +
  3037. + sbinfo = inode->i_private;
  3038. + sb = sbinfo->si_sb;
  3039. + si_noflush_read_lock(sb);
  3040. + err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0);
  3041. + si_read_unlock(sb);
  3042. + return err;
  3043. +}
  3044. +
  3045. +static const struct file_operations dbgaufs_xigen_fop = {
  3046. + .owner = THIS_MODULE,
  3047. + .open = dbgaufs_xigen_open,
  3048. + .release = dbgaufs_xi_release,
  3049. + .read = dbgaufs_xi_read
  3050. +};
  3051. +
  3052. +static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
  3053. +{
  3054. + int err;
  3055. +
  3056. + /*
  3057. + * This function is a dynamic '__init' fucntion actually,
  3058. + * so the tiny check for si_rwsem is unnecessary.
  3059. + */
  3060. + /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
  3061. +
  3062. + err = -EIO;
  3063. + sbinfo->si_dbgaufs_xigen = debugfs_create_file
  3064. + ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
  3065. + &dbgaufs_xigen_fop);
  3066. + if (sbinfo->si_dbgaufs_xigen)
  3067. + err = 0;
  3068. +
  3069. + return err;
  3070. +}
  3071. +#else
  3072. +static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
  3073. +{
  3074. + return 0;
  3075. +}
  3076. +#endif /* CONFIG_AUFS_EXPORT */
  3077. +
  3078. +/* ---------------------------------------------------------------------- */
  3079. +
  3080. +void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
  3081. +{
  3082. + /*
  3083. + * This function is a dynamic '__init' fucntion actually,
  3084. + * so the tiny check for si_rwsem is unnecessary.
  3085. + */
  3086. + /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
  3087. +
  3088. + debugfs_remove_recursive(sbinfo->si_dbgaufs);
  3089. + sbinfo->si_dbgaufs = NULL;
  3090. + kobject_put(&sbinfo->si_kobj);
  3091. +}
  3092. +
  3093. +int dbgaufs_si_init(struct au_sbinfo *sbinfo)
  3094. +{
  3095. + int err;
  3096. + char name[SysaufsSiNameLen];
  3097. +
  3098. + /*
  3099. + * This function is a dynamic '__init' fucntion actually,
  3100. + * so the tiny check for si_rwsem is unnecessary.
  3101. + */
  3102. + /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
  3103. +
  3104. + err = -ENOENT;
  3105. + if (!dbgaufs) {
  3106. + AuErr1("/debug/aufs is uninitialized\n");
  3107. + goto out;
  3108. + }
  3109. +
  3110. + err = -EIO;
  3111. + sysaufs_name(sbinfo, name);
  3112. + sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
  3113. + if (unlikely(!sbinfo->si_dbgaufs))
  3114. + goto out;
  3115. + kobject_get(&sbinfo->si_kobj);
  3116. +
  3117. + sbinfo->si_dbgaufs_xib = debugfs_create_file
  3118. + ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
  3119. + &dbgaufs_xib_fop);
  3120. + if (unlikely(!sbinfo->si_dbgaufs_xib))
  3121. + goto out_dir;
  3122. +
  3123. + err = dbgaufs_xigen_init(sbinfo);
  3124. + if (!err)
  3125. + goto out; /* success */
  3126. +
  3127. +out_dir:
  3128. + dbgaufs_si_fin(sbinfo);
  3129. +out:
  3130. + return err;
  3131. +}
  3132. +
  3133. +/* ---------------------------------------------------------------------- */
  3134. +
  3135. +void dbgaufs_fin(void)
  3136. +{
  3137. + debugfs_remove(dbgaufs);
  3138. +}
  3139. +
  3140. +int __init dbgaufs_init(void)
  3141. +{
  3142. + int err;
  3143. +
  3144. + err = -EIO;
  3145. + dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
  3146. + if (dbgaufs)
  3147. + err = 0;
  3148. + return err;
  3149. +}
  3150. diff -Nur linux-2.6.37.orig/fs/aufs/dbgaufs.h linux-2.6.37/fs/aufs/dbgaufs.h
  3151. --- linux-2.6.37.orig/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
  3152. +++ linux-2.6.37/fs/aufs/dbgaufs.h 2011-01-11 20:15:11.000000000 +0100
  3153. @@ -0,0 +1,52 @@
  3154. +/*
  3155. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  3156. + *
  3157. + * This program, aufs is free software; you can redistribute it and/or modify
  3158. + * it under the terms of the GNU General Public License as published by
  3159. + * the Free Software Foundation; either version 2 of the License, or
  3160. + * (at your option) any later version.
  3161. + *
  3162. + * This program is distributed in the hope that it will be useful,
  3163. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3164. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3165. + * GNU General Public License for more details.
  3166. + *
  3167. + * You should have received a copy of the GNU General Public License
  3168. + * along with this program; if not, write to the Free Software
  3169. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  3170. + */
  3171. +
  3172. +/*
  3173. + * debugfs interface
  3174. + */
  3175. +
  3176. +#ifndef __DBGAUFS_H__
  3177. +#define __DBGAUFS_H__
  3178. +
  3179. +#ifdef __KERNEL__
  3180. +
  3181. +#include <linux/init.h>
  3182. +#include <linux/aufs_type.h>
  3183. +
  3184. +struct super_block;
  3185. +struct au_sbinfo;
  3186. +
  3187. +#ifdef CONFIG_DEBUG_FS
  3188. +/* dbgaufs.c */
  3189. +void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
  3190. +void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
  3191. +void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
  3192. +int dbgaufs_si_init(struct au_sbinfo *sbinfo);
  3193. +void dbgaufs_fin(void);
  3194. +int __init dbgaufs_init(void);
  3195. +#else
  3196. +AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
  3197. +AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
  3198. +AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
  3199. +AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
  3200. +AuStubVoid(dbgaufs_fin, void)
  3201. +AuStubInt0(__init dbgaufs_init, void)
  3202. +#endif /* CONFIG_DEBUG_FS */
  3203. +
  3204. +#endif /* __KERNEL__ */
  3205. +#endif /* __DBGAUFS_H__ */
  3206. diff -Nur linux-2.6.37.orig/fs/aufs/dcsub.c linux-2.6.37/fs/aufs/dcsub.c
  3207. --- linux-2.6.37.orig/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100
  3208. +++ linux-2.6.37/fs/aufs/dcsub.c 2011-01-11 20:15:11.000000000 +0100
  3209. @@ -0,0 +1,210 @@
  3210. +/*
  3211. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  3212. + *
  3213. + * This program, aufs is free software; you can redistribute it and/or modify
  3214. + * it under the terms of the GNU General Public License as published by
  3215. + * the Free Software Foundation; either version 2 of the License, or
  3216. + * (at your option) any later version.
  3217. + *
  3218. + * This program is distributed in the hope that it will be useful,
  3219. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3220. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3221. + * GNU General Public License for more details.
  3222. + *
  3223. + * You should have received a copy of the GNU General Public License
  3224. + * along with this program; if not, write to the Free Software
  3225. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  3226. + */
  3227. +
  3228. +/*
  3229. + * sub-routines for dentry cache
  3230. + */
  3231. +
  3232. +#include "aufs.h"
  3233. +
  3234. +static void au_dpage_free(struct au_dpage *dpage)
  3235. +{
  3236. + int i;
  3237. + struct dentry **p;
  3238. +
  3239. + p = dpage->dentries;
  3240. + for (i = 0; i < dpage->ndentry; i++)
  3241. + dput(*p++);
  3242. + free_page((unsigned long)dpage->dentries);
  3243. +}
  3244. +
  3245. +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
  3246. +{
  3247. + int err;
  3248. + void *p;
  3249. +
  3250. + err = -ENOMEM;
  3251. + dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
  3252. + if (unlikely(!dpages->dpages))
  3253. + goto out;
  3254. +
  3255. + p = (void *)__get_free_page(gfp);
  3256. + if (unlikely(!p))
  3257. + goto out_dpages;
  3258. +
  3259. + dpages->dpages[0].ndentry = 0;
  3260. + dpages->dpages[0].dentries = p;
  3261. + dpages->ndpage = 1;
  3262. + return 0; /* success */
  3263. +
  3264. +out_dpages:
  3265. + kfree(dpages->dpages);
  3266. +out:
  3267. + return err;
  3268. +}
  3269. +
  3270. +void au_dpages_free(struct au_dcsub_pages *dpages)
  3271. +{
  3272. + int i;
  3273. + struct au_dpage *p;
  3274. +
  3275. + p = dpages->dpages;
  3276. + for (i = 0; i < dpages->ndpage; i++)
  3277. + au_dpage_free(p++);
  3278. + kfree(dpages->dpages);
  3279. +}
  3280. +
  3281. +static int au_dpages_append(struct au_dcsub_pages *dpages,
  3282. + struct dentry *dentry, gfp_t gfp)
  3283. +{
  3284. + int err, sz;
  3285. + struct au_dpage *dpage;
  3286. + void *p;
  3287. +
  3288. + dpage = dpages->dpages + dpages->ndpage - 1;
  3289. + sz = PAGE_SIZE / sizeof(dentry);
  3290. + if (unlikely(dpage->ndentry >= sz)) {
  3291. + AuLabel(new dpage);
  3292. + err = -ENOMEM;
  3293. + sz = dpages->ndpage * sizeof(*dpages->dpages);
  3294. + p = au_kzrealloc(dpages->dpages, sz,
  3295. + sz + sizeof(*dpages->dpages), gfp);
  3296. + if (unlikely(!p))
  3297. + goto out;
  3298. +
  3299. + dpages->dpages = p;
  3300. + dpage = dpages->dpages + dpages->ndpage;
  3301. + p = (void *)__get_free_page(gfp);
  3302. + if (unlikely(!p))
  3303. + goto out;
  3304. +
  3305. + dpage->ndentry = 0;
  3306. + dpage->dentries = p;
  3307. + dpages->ndpage++;
  3308. + }
  3309. +
  3310. + /* d_count can be zero */
  3311. + dpage->dentries[dpage->ndentry++] = dget_locked(dentry);
  3312. + return 0; /* success */
  3313. +
  3314. +out:
  3315. + return err;
  3316. +}
  3317. +
  3318. +int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
  3319. + au_dpages_test test, void *arg)
  3320. +{
  3321. + int err;
  3322. + struct dentry *this_parent = root;
  3323. + struct list_head *next;
  3324. + struct super_block *sb = root->d_sb;
  3325. +
  3326. + err = 0;
  3327. + spin_lock(&dcache_lock);
  3328. +repeat:
  3329. + next = this_parent->d_subdirs.next;
  3330. +resume:
  3331. + if (this_parent->d_sb == sb
  3332. + && !IS_ROOT(this_parent)
  3333. + && au_di(this_parent)
  3334. + && (!test || test(this_parent, arg))) {
  3335. + err = au_dpages_append(dpages, this_parent, GFP_ATOMIC);
  3336. + if (unlikely(err))
  3337. + goto out;
  3338. + }
  3339. +
  3340. + while (next != &this_parent->d_subdirs) {
  3341. + struct list_head *tmp = next;
  3342. + struct dentry *dentry = list_entry(tmp, struct dentry,
  3343. + d_u.d_child);
  3344. + next = tmp->next;
  3345. + if (!list_empty(&dentry->d_subdirs)) {
  3346. + this_parent = dentry;
  3347. + goto repeat;
  3348. + }
  3349. + if (dentry->d_sb == sb
  3350. + && au_di(dentry)
  3351. + && (!test || test(dentry, arg))) {
  3352. + err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
  3353. + if (unlikely(err))
  3354. + goto out;
  3355. + }
  3356. + }
  3357. +
  3358. + if (this_parent != root) {
  3359. + next = this_parent->d_u.d_child.next;
  3360. + this_parent = this_parent->d_parent; /* dcache_lock is locked */
  3361. + goto resume;
  3362. + }
  3363. +out:
  3364. + spin_unlock(&dcache_lock);
  3365. + return err;
  3366. +}
  3367. +
  3368. +int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
  3369. + int do_include, au_dpages_test test, void *arg)
  3370. +{
  3371. + int err;
  3372. +
  3373. + err = 0;
  3374. + spin_lock(&dcache_lock);
  3375. + if (do_include && (!test || test(dentry, arg))) {
  3376. + err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
  3377. + if (unlikely(err))
  3378. + goto out;
  3379. + }
  3380. + while (!IS_ROOT(dentry)) {
  3381. + dentry = dentry->d_parent; /* dcache_lock is locked */
  3382. + if (!test || test(dentry, arg)) {
  3383. + err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
  3384. + if (unlikely(err))
  3385. + break;
  3386. + }
  3387. + }
  3388. +
  3389. +out:
  3390. + spin_unlock(&dcache_lock);
  3391. +
  3392. + return err;
  3393. +}
  3394. +
  3395. +static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg)
  3396. +{
  3397. + return au_di(dentry) && dentry->d_sb == arg;
  3398. +}
  3399. +
  3400. +int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
  3401. + struct dentry *dentry, int do_include)
  3402. +{
  3403. + return au_dcsub_pages_rev(dpages, dentry, do_include,
  3404. + au_dcsub_dpages_aufs, dentry->d_sb);
  3405. +}
  3406. +
  3407. +int au_test_subdir(struct dentry *d1, struct dentry *d2)
  3408. +{
  3409. + struct path path[2] = {
  3410. + {
  3411. + .dentry = d1
  3412. + },
  3413. + {
  3414. + .dentry = d2
  3415. + }
  3416. + };
  3417. +
  3418. + return path_is_under(path + 0, path + 1);
  3419. +}
  3420. diff -Nur linux-2.6.37.orig/fs/aufs/dcsub.h linux-2.6.37/fs/aufs/dcsub.h
  3421. --- linux-2.6.37.orig/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100
  3422. +++ linux-2.6.37/fs/aufs/dcsub.h 2011-01-11 20:15:11.000000000 +0100
  3423. @@ -0,0 +1,100 @@
  3424. +/*
  3425. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  3426. + *
  3427. + * This program, aufs is free software; you can redistribute it and/or modify
  3428. + * it under the terms of the GNU General Public License as published by
  3429. + * the Free Software Foundation; either version 2 of the License, or
  3430. + * (at your option) any later version.
  3431. + *
  3432. + * This program is distributed in the hope that it will be useful,
  3433. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3434. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3435. + * GNU General Public License for more details.
  3436. + *
  3437. + * You should have received a copy of the GNU General Public License
  3438. + * along with this program; if not, write to the Free Software
  3439. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  3440. + */
  3441. +
  3442. +/*
  3443. + * sub-routines for dentry cache
  3444. + */
  3445. +
  3446. +#ifndef __AUFS_DCSUB_H__
  3447. +#define __AUFS_DCSUB_H__
  3448. +
  3449. +#ifdef __KERNEL__
  3450. +
  3451. +#include <linux/dcache.h>
  3452. +#include <linux/fs.h>
  3453. +#include <linux/types.h>
  3454. +
  3455. +struct dentry;
  3456. +
  3457. +struct au_dpage {
  3458. + int ndentry;
  3459. + struct dentry **dentries;
  3460. +};
  3461. +
  3462. +struct au_dcsub_pages {
  3463. + int ndpage;
  3464. + struct au_dpage *dpages;
  3465. +};
  3466. +
  3467. +/* ---------------------------------------------------------------------- */
  3468. +
  3469. +/* dcsub.c */
  3470. +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
  3471. +void au_dpages_free(struct au_dcsub_pages *dpages);
  3472. +typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
  3473. +int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
  3474. + au_dpages_test test, void *arg);
  3475. +int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
  3476. + int do_include, au_dpages_test test, void *arg);
  3477. +int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
  3478. + struct dentry *dentry, int do_include);
  3479. +int au_test_subdir(struct dentry *d1, struct dentry *d2);
  3480. +
  3481. +/* ---------------------------------------------------------------------- */
  3482. +
  3483. +static inline int au_d_removed(struct dentry *d)
  3484. +{
  3485. + return !IS_ROOT(d) && d_unhashed(d);
  3486. +}
  3487. +
  3488. +static inline int au_d_hashed_positive(struct dentry *d)
  3489. +{
  3490. + int err;
  3491. + struct inode *inode = d->d_inode;
  3492. + err = 0;
  3493. + if (unlikely(d_unhashed(d) || !inode || !inode->i_nlink))
  3494. + err = -ENOENT;
  3495. + return err;
  3496. +}
  3497. +
  3498. +static inline int au_d_alive(struct dentry *d)
  3499. +{
  3500. + int err;
  3501. + struct inode *inode;
  3502. + err = 0;
  3503. + if (!IS_ROOT(d))
  3504. + err = au_d_hashed_positive(d);
  3505. + else {
  3506. + inode = d->d_inode;
  3507. + if (unlikely(au_d_removed(d) || !inode || !inode->i_nlink))
  3508. + err = -ENOENT;
  3509. + }
  3510. + return err;
  3511. +}
  3512. +
  3513. +static inline int au_alive_dir(struct dentry *d)
  3514. +{
  3515. + int err;
  3516. + err = au_d_alive(d);
  3517. + if (unlikely(err || IS_DEADDIR(d->d_inode)))
  3518. + err = -ENOENT;
  3519. + return err;
  3520. +}
  3521. +
  3522. +#endif /* __KERNEL__ */
  3523. +#endif /* __AUFS_DCSUB_H__ */
  3524. diff -Nur linux-2.6.37.orig/fs/aufs/debug.c linux-2.6.37/fs/aufs/debug.c
  3525. --- linux-2.6.37.orig/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
  3526. +++ linux-2.6.37/fs/aufs/debug.c 2011-01-11 20:15:11.000000000 +0100
  3527. @@ -0,0 +1,468 @@
  3528. +/*
  3529. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  3530. + *
  3531. + * This program, aufs is free software; you can redistribute it and/or modify
  3532. + * it under the terms of the GNU General Public License as published by
  3533. + * the Free Software Foundation; either version 2 of the License, or
  3534. + * (at your option) any later version.
  3535. + *
  3536. + * This program is distributed in the hope that it will be useful,
  3537. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3538. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3539. + * GNU General Public License for more details.
  3540. + *
  3541. + * You should have received a copy of the GNU General Public License
  3542. + * along with this program; if not, write to the Free Software
  3543. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  3544. + */
  3545. +
  3546. +/*
  3547. + * debug print functions
  3548. + */
  3549. +
  3550. +#include <linux/module.h>
  3551. +#include <linux/vt_kern.h>
  3552. +#include "aufs.h"
  3553. +
  3554. +int aufs_debug;
  3555. +MODULE_PARM_DESC(debug, "debug print");
  3556. +module_param_named(debug, aufs_debug, int, S_IRUGO | S_IWUSR | S_IWGRP);
  3557. +
  3558. +char *au_plevel = KERN_DEBUG;
  3559. +#define dpri(fmt, ...) do { \
  3560. + if ((au_plevel \
  3561. + && strcmp(au_plevel, KERN_DEBUG)) \
  3562. + || au_debug_test()) \
  3563. + printk("%s" fmt, au_plevel, ##__VA_ARGS__); \
  3564. +} while (0)
  3565. +
  3566. +/* ---------------------------------------------------------------------- */
  3567. +
  3568. +void au_dpri_whlist(struct au_nhash *whlist)
  3569. +{
  3570. + unsigned long ul, n;
  3571. + struct hlist_head *head;
  3572. + struct au_vdir_wh *tpos;
  3573. + struct hlist_node *pos;
  3574. +
  3575. + n = whlist->nh_num;
  3576. + head = whlist->nh_head;
  3577. + for (ul = 0; ul < n; ul++) {
  3578. + hlist_for_each_entry(tpos, pos, head, wh_hash)
  3579. + dpri("b%d, %.*s, %d\n",
  3580. + tpos->wh_bindex,
  3581. + tpos->wh_str.len, tpos->wh_str.name,
  3582. + tpos->wh_str.len);
  3583. + head++;
  3584. + }
  3585. +}
  3586. +
  3587. +void au_dpri_vdir(struct au_vdir *vdir)
  3588. +{
  3589. + unsigned long ul;
  3590. + union au_vdir_deblk_p p;
  3591. + unsigned char *o;
  3592. +
  3593. + if (!vdir || IS_ERR(vdir)) {
  3594. + dpri("err %ld\n", PTR_ERR(vdir));
  3595. + return;
  3596. + }
  3597. +
  3598. + dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n",
  3599. + vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
  3600. + vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
  3601. + for (ul = 0; ul < vdir->vd_nblk; ul++) {
  3602. + p.deblk = vdir->vd_deblk[ul];
  3603. + o = p.deblk;
  3604. + dpri("[%lu]: %p\n", ul, o);
  3605. + }
  3606. +}
  3607. +
  3608. +static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode,
  3609. + struct dentry *wh)
  3610. +{
  3611. + char *n = NULL;
  3612. + int l = 0;
  3613. +
  3614. + if (!inode || IS_ERR(inode)) {
  3615. + dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
  3616. + return -1;
  3617. + }
  3618. +
  3619. + /* the type of i_blocks depends upon CONFIG_LSF */
  3620. + BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
  3621. + && sizeof(inode->i_blocks) != sizeof(u64));
  3622. + if (wh) {
  3623. + n = (void *)wh->d_name.name;
  3624. + l = wh->d_name.len;
  3625. + }
  3626. +
  3627. + dpri("i%d: i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
  3628. + " ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
  3629. + bindex,
  3630. + inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
  3631. + atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
  3632. + i_size_read(inode), (unsigned long long)inode->i_blocks,
  3633. + (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
  3634. + inode->i_mapping ? inode->i_mapping->nrpages : 0,
  3635. + inode->i_state, inode->i_flags, inode->i_version,
  3636. + inode->i_generation,
  3637. + l ? ", wh " : "", l, n);
  3638. + return 0;
  3639. +}
  3640. +
  3641. +void au_dpri_inode(struct inode *inode)
  3642. +{
  3643. + struct au_iinfo *iinfo;
  3644. + aufs_bindex_t bindex;
  3645. + int err;
  3646. +
  3647. + err = do_pri_inode(-1, inode, NULL);
  3648. + if (err || !au_test_aufs(inode->i_sb))
  3649. + return;
  3650. +
  3651. + iinfo = au_ii(inode);
  3652. + if (!iinfo)
  3653. + return;
  3654. + dpri("i-1: bstart %d, bend %d, gen %d\n",
  3655. + iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode));
  3656. + if (iinfo->ii_bstart < 0)
  3657. + return;
  3658. + for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++)
  3659. + do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode,
  3660. + iinfo->ii_hinode[0 + bindex].hi_whdentry);
  3661. +}
  3662. +
  3663. +static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
  3664. +{
  3665. + struct dentry *wh = NULL;
  3666. +
  3667. + if (!dentry || IS_ERR(dentry)) {
  3668. + dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
  3669. + return -1;
  3670. + }
  3671. + /* do not call dget_parent() here */
  3672. + dpri("d%d: %.*s?/%.*s, %s, cnt %d, flags 0x%x\n",
  3673. + bindex,
  3674. + AuDLNPair(dentry->d_parent), AuDLNPair(dentry),
  3675. + dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
  3676. + atomic_read(&dentry->d_count), dentry->d_flags);
  3677. + if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) {
  3678. + struct au_iinfo *iinfo = au_ii(dentry->d_inode);
  3679. + if (iinfo)
  3680. + wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
  3681. + }
  3682. + do_pri_inode(bindex, dentry->d_inode, wh);
  3683. + return 0;
  3684. +}
  3685. +
  3686. +void au_dpri_dentry(struct dentry *dentry)
  3687. +{
  3688. + struct au_dinfo *dinfo;
  3689. + aufs_bindex_t bindex;
  3690. + int err;
  3691. + struct au_hdentry *hdp;
  3692. +
  3693. + err = do_pri_dentry(-1, dentry);
  3694. + if (err || !au_test_aufs(dentry->d_sb))
  3695. + return;
  3696. +
  3697. + dinfo = au_di(dentry);
  3698. + if (!dinfo)
  3699. + return;
  3700. + dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d\n",
  3701. + dinfo->di_bstart, dinfo->di_bend,
  3702. + dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry));
  3703. + if (dinfo->di_bstart < 0)
  3704. + return;
  3705. + hdp = dinfo->di_hdentry;
  3706. + for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++)
  3707. + do_pri_dentry(bindex, hdp[0 + bindex].hd_dentry);
  3708. +}
  3709. +
  3710. +static int do_pri_file(aufs_bindex_t bindex, struct file *file)
  3711. +{
  3712. + char a[32];
  3713. +
  3714. + if (!file || IS_ERR(file)) {
  3715. + dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
  3716. + return -1;
  3717. + }
  3718. + a[0] = 0;
  3719. + if (bindex < 0
  3720. + && file->f_dentry
  3721. + && au_test_aufs(file->f_dentry->d_sb)
  3722. + && au_fi(file))
  3723. + snprintf(a, sizeof(a), ", gen %d, mmapped %d",
  3724. + au_figen(file), !!au_fi(file)->fi_hvmop);
  3725. + dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
  3726. + bindex, file->f_mode, file->f_flags, (long)file_count(file),
  3727. + file->f_version, file->f_pos, a);
  3728. + if (file->f_dentry)
  3729. + do_pri_dentry(bindex, file->f_dentry);
  3730. + return 0;
  3731. +}
  3732. +
  3733. +void au_dpri_file(struct file *file)
  3734. +{
  3735. + struct au_finfo *finfo;
  3736. + struct au_fidir *fidir;
  3737. + struct au_hfile *hfile;
  3738. + aufs_bindex_t bindex;
  3739. + int err;
  3740. +
  3741. + err = do_pri_file(-1, file);
  3742. + if (err || !file->f_dentry || !au_test_aufs(file->f_dentry->d_sb))
  3743. + return;
  3744. +
  3745. + finfo = au_fi(file);
  3746. + if (!finfo)
  3747. + return;
  3748. + if (finfo->fi_btop < 0)
  3749. + return;
  3750. + fidir = finfo->fi_hdir;
  3751. + if (!fidir)
  3752. + do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
  3753. + else
  3754. + for (bindex = finfo->fi_btop;
  3755. + bindex >= 0 && bindex <= fidir->fd_bbot;
  3756. + bindex++) {
  3757. + hfile = fidir->fd_hfile + bindex;
  3758. + do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
  3759. + }
  3760. +}
  3761. +
  3762. +static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
  3763. +{
  3764. + struct vfsmount *mnt;
  3765. + struct super_block *sb;
  3766. +
  3767. + if (!br || IS_ERR(br))
  3768. + goto out;
  3769. + mnt = br->br_mnt;
  3770. + if (!mnt || IS_ERR(mnt))
  3771. + goto out;
  3772. + sb = mnt->mnt_sb;
  3773. + if (!sb || IS_ERR(sb))
  3774. + goto out;
  3775. +
  3776. + dpri("s%d: {perm 0x%x, cnt %d, wbr %p}, "
  3777. + "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
  3778. + "xino %d\n",
  3779. + bindex, br->br_perm, atomic_read(&br->br_count), br->br_wbr,
  3780. + au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
  3781. + sb->s_flags, sb->s_count,
  3782. + atomic_read(&sb->s_active), !!br->br_xino.xi_file);
  3783. + return 0;
  3784. +
  3785. +out:
  3786. + dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
  3787. + return -1;
  3788. +}
  3789. +
  3790. +void au_dpri_sb(struct super_block *sb)
  3791. +{
  3792. + struct au_sbinfo *sbinfo;
  3793. + aufs_bindex_t bindex;
  3794. + int err;
  3795. + /* to reuduce stack size */
  3796. + struct {
  3797. + struct vfsmount mnt;
  3798. + struct au_branch fake;
  3799. + } *a;
  3800. +
  3801. + /* this function can be called from magic sysrq */
  3802. + a = kzalloc(sizeof(*a), GFP_ATOMIC);
  3803. + if (unlikely(!a)) {
  3804. + dpri("no memory\n");
  3805. + return;
  3806. + }
  3807. +
  3808. + a->mnt.mnt_sb = sb;
  3809. + a->fake.br_perm = 0;
  3810. + a->fake.br_mnt = &a->mnt;
  3811. + a->fake.br_xino.xi_file = NULL;
  3812. + atomic_set(&a->fake.br_count, 0);
  3813. + smp_mb(); /* atomic_set */
  3814. + err = do_pri_br(-1, &a->fake);
  3815. + kfree(a);
  3816. + dpri("dev 0x%x\n", sb->s_dev);
  3817. + if (err || !au_test_aufs(sb))
  3818. + return;
  3819. +
  3820. + sbinfo = au_sbi(sb);
  3821. + if (!sbinfo)
  3822. + return;
  3823. + dpri("nw %d, gen %u, kobj %d\n",
  3824. + atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
  3825. + atomic_read(&sbinfo->si_kobj.kref.refcount));
  3826. + for (bindex = 0; bindex <= sbinfo->si_bend; bindex++)
  3827. + do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
  3828. +}
  3829. +
  3830. +/* ---------------------------------------------------------------------- */
  3831. +
  3832. +void au_dbg_sleep_jiffy(int jiffy)
  3833. +{
  3834. + while (jiffy)
  3835. + jiffy = schedule_timeout_uninterruptible(jiffy);
  3836. +}
  3837. +
  3838. +void au_dbg_iattr(struct iattr *ia)
  3839. +{
  3840. +#define AuBit(name) if (ia->ia_valid & ATTR_ ## name) \
  3841. + dpri(#name "\n")
  3842. + AuBit(MODE);
  3843. + AuBit(UID);
  3844. + AuBit(GID);
  3845. + AuBit(SIZE);
  3846. + AuBit(ATIME);
  3847. + AuBit(MTIME);
  3848. + AuBit(CTIME);
  3849. + AuBit(ATIME_SET);
  3850. + AuBit(MTIME_SET);
  3851. + AuBit(FORCE);
  3852. + AuBit(ATTR_FLAG);
  3853. + AuBit(KILL_SUID);
  3854. + AuBit(KILL_SGID);
  3855. + AuBit(FILE);
  3856. + AuBit(KILL_PRIV);
  3857. + AuBit(OPEN);
  3858. + AuBit(TIMES_SET);
  3859. +#undef AuBit
  3860. + dpri("ia_file %p\n", ia->ia_file);
  3861. +}
  3862. +
  3863. +/* ---------------------------------------------------------------------- */
  3864. +
  3865. +void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
  3866. +{
  3867. + struct inode *h_inode, *inode = dentry->d_inode;
  3868. + struct dentry *h_dentry;
  3869. + aufs_bindex_t bindex, bend, bi;
  3870. +
  3871. + if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */)
  3872. + return;
  3873. +
  3874. + bend = au_dbend(dentry);
  3875. + bi = au_ibend(inode);
  3876. + if (bi < bend)
  3877. + bend = bi;
  3878. + bindex = au_dbstart(dentry);
  3879. + bi = au_ibstart(inode);
  3880. + if (bi > bindex)
  3881. + bindex = bi;
  3882. +
  3883. + for (; bindex <= bend; bindex++) {
  3884. + h_dentry = au_h_dptr(dentry, bindex);
  3885. + if (!h_dentry)
  3886. + continue;
  3887. + h_inode = au_h_iptr(inode, bindex);
  3888. + if (unlikely(h_inode != h_dentry->d_inode)) {
  3889. + int old = au_debug_test();
  3890. + if (!old)
  3891. + au_debug(1);
  3892. + AuDbg("b%d, %s:%d\n", bindex, func, line);
  3893. + AuDbgDentry(dentry);
  3894. + AuDbgInode(inode);
  3895. + if (!old)
  3896. + au_debug(0);
  3897. + BUG();
  3898. + }
  3899. + }
  3900. +}
  3901. +
  3902. +void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen)
  3903. +{
  3904. + struct dentry *parent;
  3905. +
  3906. + parent = dget_parent(dentry);
  3907. + AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
  3908. + AuDebugOn(IS_ROOT(dentry));
  3909. + AuDebugOn(au_digen_test(parent, sigen));
  3910. + dput(parent);
  3911. +}
  3912. +
  3913. +void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen)
  3914. +{
  3915. + struct dentry *parent;
  3916. + struct inode *inode;
  3917. +
  3918. + parent = dget_parent(dentry);
  3919. + inode = dentry->d_inode;
  3920. + AuDebugOn(inode && S_ISDIR(dentry->d_inode->i_mode));
  3921. + AuDebugOn(au_digen_test(parent, sigen));
  3922. + dput(parent);
  3923. +}
  3924. +
  3925. +void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
  3926. +{
  3927. + int err, i, j;
  3928. + struct au_dcsub_pages dpages;
  3929. + struct au_dpage *dpage;
  3930. + struct dentry **dentries;
  3931. +
  3932. + err = au_dpages_init(&dpages, GFP_NOFS);
  3933. + AuDebugOn(err);
  3934. + err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
  3935. + AuDebugOn(err);
  3936. + for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
  3937. + dpage = dpages.dpages + i;
  3938. + dentries = dpage->dentries;
  3939. + for (j = dpage->ndentry - 1; !err && j >= 0; j--)
  3940. + AuDebugOn(au_digen_test(dentries[j], sigen));
  3941. + }
  3942. + au_dpages_free(&dpages);
  3943. +}
  3944. +
  3945. +void au_dbg_verify_kthread(void)
  3946. +{
  3947. + if (current->flags & PF_WQ_WORKER) {
  3948. + au_dbg_blocked();
  3949. + WARN_ON(1);
  3950. + }
  3951. +}
  3952. +
  3953. +/* ---------------------------------------------------------------------- */
  3954. +
  3955. +void au_debug_sbinfo_init(struct au_sbinfo *sbinfo __maybe_unused)
  3956. +{
  3957. +#ifdef AuForceNoPlink
  3958. + au_opt_clr(sbinfo->si_mntflags, PLINK);
  3959. +#endif
  3960. +#ifdef AuForceNoXino
  3961. + au_opt_clr(sbinfo->si_mntflags, XINO);
  3962. +#endif
  3963. +#ifdef AuForceNoRefrof
  3964. + au_opt_clr(sbinfo->si_mntflags, REFROF);
  3965. +#endif
  3966. +#ifdef AuForceHnotify
  3967. + au_opt_set_udba(sbinfo->si_mntflags, UDBA_HNOTIFY);
  3968. +#endif
  3969. +#ifdef AuForceRd0
  3970. + sbinfo->si_rdblk = 0;
  3971. + sbinfo->si_rdhash = 0;
  3972. +#endif
  3973. +}
  3974. +
  3975. +int __init au_debug_init(void)
  3976. +{
  3977. + aufs_bindex_t bindex;
  3978. + struct au_vdir_destr destr;
  3979. +
  3980. + bindex = -1;
  3981. + AuDebugOn(bindex >= 0);
  3982. +
  3983. + destr.len = -1;
  3984. + AuDebugOn(destr.len < NAME_MAX);
  3985. +
  3986. +#ifdef CONFIG_4KSTACKS
  3987. + pr_warning("CONFIG_4KSTACKS is defined.\n");
  3988. +#endif
  3989. +
  3990. +#ifdef AuForceNoBrs
  3991. + sysaufs_brs = 0;
  3992. +#endif
  3993. +
  3994. + return 0;
  3995. +}
  3996. diff -Nur linux-2.6.37.orig/fs/aufs/debug.h linux-2.6.37/fs/aufs/debug.h
  3997. --- linux-2.6.37.orig/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100
  3998. +++ linux-2.6.37/fs/aufs/debug.h 2011-01-11 20:15:11.000000000 +0100
  3999. @@ -0,0 +1,245 @@
  4000. +/*
  4001. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  4002. + *
  4003. + * This program, aufs is free software; you can redistribute it and/or modify
  4004. + * it under the terms of the GNU General Public License as published by
  4005. + * the Free Software Foundation; either version 2 of the License, or
  4006. + * (at your option) any later version.
  4007. + *
  4008. + * This program is distributed in the hope that it will be useful,
  4009. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4010. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4011. + * GNU General Public License for more details.
  4012. + *
  4013. + * You should have received a copy of the GNU General Public License
  4014. + * along with this program; if not, write to the Free Software
  4015. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  4016. + */
  4017. +
  4018. +/*
  4019. + * debug print functions
  4020. + */
  4021. +
  4022. +#ifndef __AUFS_DEBUG_H__
  4023. +#define __AUFS_DEBUG_H__
  4024. +
  4025. +#ifdef __KERNEL__
  4026. +
  4027. +#include <asm/system.h>
  4028. +#include <linux/bug.h>
  4029. +/* #include <linux/err.h> */
  4030. +#include <linux/init.h>
  4031. +#include <linux/module.h>
  4032. +#include <linux/kallsyms.h>
  4033. +/* #include <linux/kernel.h> */
  4034. +#include <linux/delay.h>
  4035. +/* #include <linux/kd.h> */
  4036. +#include <linux/sysrq.h>
  4037. +#include <linux/aufs_type.h>
  4038. +
  4039. +#include <asm/system.h>
  4040. +
  4041. +#ifdef CONFIG_AUFS_DEBUG
  4042. +#define AuDebugOn(a) BUG_ON(a)
  4043. +
  4044. +/* module parameter */
  4045. +extern int aufs_debug;
  4046. +static inline void au_debug(int n)
  4047. +{
  4048. + aufs_debug = n;
  4049. + smp_mb();
  4050. +}
  4051. +
  4052. +static inline int au_debug_test(void)
  4053. +{
  4054. + return aufs_debug;
  4055. +}
  4056. +#else
  4057. +#define AuDebugOn(a) do {} while (0)
  4058. +AuStubVoid(au_debug, int n)
  4059. +AuStubInt0(au_debug_test, void)
  4060. +#endif /* CONFIG_AUFS_DEBUG */
  4061. +
  4062. +/* ---------------------------------------------------------------------- */
  4063. +
  4064. +/* debug print */
  4065. +
  4066. +#define AuDbg(fmt, ...) do { \
  4067. + if (au_debug_test()) \
  4068. + pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
  4069. +} while (0)
  4070. +#define AuLabel(l) AuDbg(#l "\n")
  4071. +#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__)
  4072. +#define AuWarn1(fmt, ...) do { \
  4073. + static unsigned char _c; \
  4074. + if (!_c++) \
  4075. + pr_warning(fmt, ##__VA_ARGS__); \
  4076. +} while (0)
  4077. +
  4078. +#define AuErr1(fmt, ...) do { \
  4079. + static unsigned char _c; \
  4080. + if (!_c++) \
  4081. + pr_err(fmt, ##__VA_ARGS__); \
  4082. +} while (0)
  4083. +
  4084. +#define AuIOErr1(fmt, ...) do { \
  4085. + static unsigned char _c; \
  4086. + if (!_c++) \
  4087. + AuIOErr(fmt, ##__VA_ARGS__); \
  4088. +} while (0)
  4089. +
  4090. +#define AuUnsupportMsg "This operation is not supported." \
  4091. + " Please report this application to aufs-users ML."
  4092. +#define AuUnsupport(fmt, ...) do { \
  4093. + pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
  4094. + dump_stack(); \
  4095. +} while (0)
  4096. +
  4097. +#define AuTraceErr(e) do { \
  4098. + if (unlikely((e) < 0)) \
  4099. + AuDbg("err %d\n", (int)(e)); \
  4100. +} while (0)
  4101. +
  4102. +#define AuTraceErrPtr(p) do { \
  4103. + if (IS_ERR(p)) \
  4104. + AuDbg("err %ld\n", PTR_ERR(p)); \
  4105. +} while (0)
  4106. +
  4107. +/* dirty macros for debug print, use with "%.*s" and caution */
  4108. +#define AuLNPair(qstr) (qstr)->len, (qstr)->name
  4109. +#define AuDLNPair(d) AuLNPair(&(d)->d_name)
  4110. +
  4111. +/* ---------------------------------------------------------------------- */
  4112. +
  4113. +struct au_sbinfo;
  4114. +struct au_finfo;
  4115. +struct dentry;
  4116. +#ifdef CONFIG_AUFS_DEBUG
  4117. +extern char *au_plevel;
  4118. +struct au_nhash;
  4119. +void au_dpri_whlist(struct au_nhash *whlist);
  4120. +struct au_vdir;
  4121. +void au_dpri_vdir(struct au_vdir *vdir);
  4122. +struct inode;
  4123. +void au_dpri_inode(struct inode *inode);
  4124. +void au_dpri_dentry(struct dentry *dentry);
  4125. +struct file;
  4126. +void au_dpri_file(struct file *filp);
  4127. +struct super_block;
  4128. +void au_dpri_sb(struct super_block *sb);
  4129. +
  4130. +void au_dbg_sleep_jiffy(int jiffy);
  4131. +struct iattr;
  4132. +void au_dbg_iattr(struct iattr *ia);
  4133. +
  4134. +#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__)
  4135. +void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line);
  4136. +void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen);
  4137. +void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen);
  4138. +void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
  4139. +void au_dbg_verify_kthread(void);
  4140. +
  4141. +int __init au_debug_init(void);
  4142. +void au_debug_sbinfo_init(struct au_sbinfo *sbinfo);
  4143. +#define AuDbgWhlist(w) do { \
  4144. + AuDbg(#w "\n"); \
  4145. + au_dpri_whlist(w); \
  4146. +} while (0)
  4147. +
  4148. +#define AuDbgVdir(v) do { \
  4149. + AuDbg(#v "\n"); \
  4150. + au_dpri_vdir(v); \
  4151. +} while (0)
  4152. +
  4153. +#define AuDbgInode(i) do { \
  4154. + AuDbg(#i "\n"); \
  4155. + au_dpri_inode(i); \
  4156. +} while (0)
  4157. +
  4158. +#define AuDbgDentry(d) do { \
  4159. + AuDbg(#d "\n"); \
  4160. + au_dpri_dentry(d); \
  4161. +} while (0)
  4162. +
  4163. +#define AuDbgFile(f) do { \
  4164. + AuDbg(#f "\n"); \
  4165. + au_dpri_file(f); \
  4166. +} while (0)
  4167. +
  4168. +#define AuDbgSb(sb) do { \
  4169. + AuDbg(#sb "\n"); \
  4170. + au_dpri_sb(sb); \
  4171. +} while (0)
  4172. +
  4173. +#define AuDbgSleep(sec) do { \
  4174. + AuDbg("sleep %d sec\n", sec); \
  4175. + ssleep(sec); \
  4176. +} while (0)
  4177. +
  4178. +#define AuDbgSleepJiffy(jiffy) do { \
  4179. + AuDbg("sleep %d jiffies\n", jiffy); \
  4180. + au_dbg_sleep_jiffy(jiffy); \
  4181. +} while (0)
  4182. +
  4183. +#define AuDbgIAttr(ia) do { \
  4184. + AuDbg("ia_valid 0x%x\n", (ia)->ia_valid); \
  4185. + au_dbg_iattr(ia); \
  4186. +} while (0)
  4187. +
  4188. +#define AuDbgSym(addr) do { \
  4189. + char sym[KSYM_SYMBOL_LEN]; \
  4190. + sprint_symbol(sym, (unsigned long)addr); \
  4191. + AuDbg("%s\n", sym); \
  4192. +} while (0)
  4193. +
  4194. +#define AuInfoSym(addr) do { \
  4195. + char sym[KSYM_SYMBOL_LEN]; \
  4196. + sprint_symbol(sym, (unsigned long)addr); \
  4197. + AuInfo("%s\n", sym); \
  4198. +} while (0)
  4199. +#else
  4200. +AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
  4201. +AuStubVoid(au_dbg_verify_dir_parent, struct dentry *dentry, unsigned int sigen)
  4202. +AuStubVoid(au_dbg_verify_nondir_parent, struct dentry *dentry,
  4203. + unsigned int sigen)
  4204. +AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
  4205. +AuStubVoid(au_dbg_verify_kthread, void)
  4206. +AuStubInt0(__init au_debug_init, void)
  4207. +AuStubVoid(au_debug_sbinfo_init, struct au_sbinfo *sbinfo)
  4208. +
  4209. +#define AuDbgWhlist(w) do {} while (0)
  4210. +#define AuDbgVdir(v) do {} while (0)
  4211. +#define AuDbgInode(i) do {} while (0)
  4212. +#define AuDbgDentry(d) do {} while (0)
  4213. +#define AuDbgFile(f) do {} while (0)
  4214. +#define AuDbgSb(sb) do {} while (0)
  4215. +#define AuDbgSleep(sec) do {} while (0)
  4216. +#define AuDbgSleepJiffy(jiffy) do {} while (0)
  4217. +#define AuDbgIAttr(ia) do {} while (0)
  4218. +#define AuDbgSym(addr) do {} while (0)
  4219. +#define AuInfoSym(addr) do {} while (0)
  4220. +#endif /* CONFIG_AUFS_DEBUG */
  4221. +
  4222. +/* ---------------------------------------------------------------------- */
  4223. +
  4224. +#ifdef CONFIG_AUFS_MAGIC_SYSRQ
  4225. +int __init au_sysrq_init(void);
  4226. +void au_sysrq_fin(void);
  4227. +
  4228. +#ifdef CONFIG_HW_CONSOLE
  4229. +#define au_dbg_blocked() do { \
  4230. + WARN_ON(1); \
  4231. + handle_sysrq('w'); \
  4232. +} while (0)
  4233. +#else
  4234. +AuStubVoid(au_dbg_blocked, void)
  4235. +#endif
  4236. +
  4237. +#else
  4238. +AuStubInt0(__init au_sysrq_init, void)
  4239. +AuStubVoid(au_sysrq_fin, void)
  4240. +AuStubVoid(au_dbg_blocked, void)
  4241. +#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
  4242. +
  4243. +#endif /* __KERNEL__ */
  4244. +#endif /* __AUFS_DEBUG_H__ */
  4245. diff -Nur linux-2.6.37.orig/fs/aufs/dentry.c linux-2.6.37/fs/aufs/dentry.c
  4246. --- linux-2.6.37.orig/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100
  4247. +++ linux-2.6.37/fs/aufs/dentry.c 2011-01-11 20:15:11.000000000 +0100
  4248. @@ -0,0 +1,1131 @@
  4249. +/*
  4250. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  4251. + *
  4252. + * This program, aufs is free software; you can redistribute it and/or modify
  4253. + * it under the terms of the GNU General Public License as published by
  4254. + * the Free Software Foundation; either version 2 of the License, or
  4255. + * (at your option) any later version.
  4256. + *
  4257. + * This program is distributed in the hope that it will be useful,
  4258. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4259. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4260. + * GNU General Public License for more details.
  4261. + *
  4262. + * You should have received a copy of the GNU General Public License
  4263. + * along with this program; if not, write to the Free Software
  4264. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  4265. + */
  4266. +
  4267. +/*
  4268. + * lookup and dentry operations
  4269. + */
  4270. +
  4271. +#include <linux/namei.h>
  4272. +#include "aufs.h"
  4273. +
  4274. +static void au_h_nd(struct nameidata *h_nd, struct nameidata *nd)
  4275. +{
  4276. + if (nd) {
  4277. + *h_nd = *nd;
  4278. +
  4279. + /*
  4280. + * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
  4281. + * due to whiteout and branch permission.
  4282. + */
  4283. + h_nd->flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
  4284. + | LOOKUP_FOLLOW | LOOKUP_EXCL);
  4285. + /* unnecessary? */
  4286. + h_nd->intent.open.file = NULL;
  4287. + } else
  4288. + memset(h_nd, 0, sizeof(*h_nd));
  4289. +}
  4290. +
  4291. +struct au_lkup_one_args {
  4292. + struct dentry **errp;
  4293. + struct qstr *name;
  4294. + struct dentry *h_parent;
  4295. + struct au_branch *br;
  4296. + struct nameidata *nd;
  4297. +};
  4298. +
  4299. +struct dentry *au_lkup_one(struct qstr *name, struct dentry *h_parent,
  4300. + struct au_branch *br, struct nameidata *nd)
  4301. +{
  4302. + struct dentry *h_dentry;
  4303. + int err;
  4304. + struct nameidata h_nd;
  4305. +
  4306. + if (au_test_fs_null_nd(h_parent->d_sb))
  4307. + return vfsub_lookup_one_len(name->name, h_parent, name->len);
  4308. +
  4309. + au_h_nd(&h_nd, nd);
  4310. + h_nd.path.dentry = h_parent;
  4311. + h_nd.path.mnt = br->br_mnt;
  4312. +
  4313. + err = __lookup_one_len(name->name, &h_nd.last, NULL, name->len);
  4314. + h_dentry = ERR_PTR(err);
  4315. + if (!err) {
  4316. + path_get(&h_nd.path);
  4317. + h_dentry = vfsub_lookup_hash(&h_nd);
  4318. + path_put(&h_nd.path);
  4319. + }
  4320. +
  4321. + AuTraceErrPtr(h_dentry);
  4322. + return h_dentry;
  4323. +}
  4324. +
  4325. +static void au_call_lkup_one(void *args)
  4326. +{
  4327. + struct au_lkup_one_args *a = args;
  4328. + *a->errp = au_lkup_one(a->name, a->h_parent, a->br, a->nd);
  4329. +}
  4330. +
  4331. +#define AuLkup_ALLOW_NEG 1
  4332. +#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name)
  4333. +#define au_fset_lkup(flags, name) \
  4334. + do { (flags) |= AuLkup_##name; } while (0)
  4335. +#define au_fclr_lkup(flags, name) \
  4336. + do { (flags) &= ~AuLkup_##name; } while (0)
  4337. +
  4338. +struct au_do_lookup_args {
  4339. + unsigned int flags;
  4340. + mode_t type;
  4341. + struct nameidata *nd;
  4342. +};
  4343. +
  4344. +/*
  4345. + * returns positive/negative dentry, NULL or an error.
  4346. + * NULL means whiteout-ed or not-found.
  4347. + */
  4348. +static struct dentry*
  4349. +au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
  4350. + aufs_bindex_t bindex, struct qstr *wh_name,
  4351. + struct au_do_lookup_args *args)
  4352. +{
  4353. + struct dentry *h_dentry;
  4354. + struct inode *h_inode, *inode;
  4355. + struct au_branch *br;
  4356. + int wh_found, opq;
  4357. + unsigned char wh_able;
  4358. + const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
  4359. +
  4360. + wh_found = 0;
  4361. + br = au_sbr(dentry->d_sb, bindex);
  4362. + wh_able = !!au_br_whable(br->br_perm);
  4363. + if (wh_able)
  4364. + wh_found = au_wh_test(h_parent, wh_name, br, /*try_sio*/0);
  4365. + h_dentry = ERR_PTR(wh_found);
  4366. + if (!wh_found)
  4367. + goto real_lookup;
  4368. + if (unlikely(wh_found < 0))
  4369. + goto out;
  4370. +
  4371. + /* We found a whiteout */
  4372. + /* au_set_dbend(dentry, bindex); */
  4373. + au_set_dbwh(dentry, bindex);
  4374. + if (!allow_neg)
  4375. + return NULL; /* success */
  4376. +
  4377. +real_lookup:
  4378. + h_dentry = au_lkup_one(&dentry->d_name, h_parent, br, args->nd);
  4379. + if (IS_ERR(h_dentry))
  4380. + goto out;
  4381. +
  4382. + h_inode = h_dentry->d_inode;
  4383. + if (!h_inode) {
  4384. + if (!allow_neg)
  4385. + goto out_neg;
  4386. + } else if (wh_found
  4387. + || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
  4388. + goto out_neg;
  4389. +
  4390. + if (au_dbend(dentry) <= bindex)
  4391. + au_set_dbend(dentry, bindex);
  4392. + if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
  4393. + au_set_dbstart(dentry, bindex);
  4394. + au_set_h_dptr(dentry, bindex, h_dentry);
  4395. +
  4396. + inode = dentry->d_inode;
  4397. + if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able
  4398. + || (inode && !S_ISDIR(inode->i_mode)))
  4399. + goto out; /* success */
  4400. +
  4401. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  4402. + opq = au_diropq_test(h_dentry, br);
  4403. + mutex_unlock(&h_inode->i_mutex);
  4404. + if (opq > 0)
  4405. + au_set_dbdiropq(dentry, bindex);
  4406. + else if (unlikely(opq < 0)) {
  4407. + au_set_h_dptr(dentry, bindex, NULL);
  4408. + h_dentry = ERR_PTR(opq);
  4409. + }
  4410. + goto out;
  4411. +
  4412. +out_neg:
  4413. + dput(h_dentry);
  4414. + h_dentry = NULL;
  4415. +out:
  4416. + return h_dentry;
  4417. +}
  4418. +
  4419. +static int au_test_shwh(struct super_block *sb, const struct qstr *name)
  4420. +{
  4421. + if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
  4422. + && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
  4423. + return -EPERM;
  4424. + return 0;
  4425. +}
  4426. +
  4427. +/*
  4428. + * returns the number of lower positive dentries,
  4429. + * otherwise an error.
  4430. + * can be called at unlinking with @type is zero.
  4431. + */
  4432. +int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type,
  4433. + struct nameidata *nd)
  4434. +{
  4435. + int npositive, err;
  4436. + aufs_bindex_t bindex, btail, bdiropq;
  4437. + unsigned char isdir;
  4438. + struct qstr whname;
  4439. + struct au_do_lookup_args args = {
  4440. + .flags = 0,
  4441. + .type = type,
  4442. + .nd = nd
  4443. + };
  4444. + const struct qstr *name = &dentry->d_name;
  4445. + struct dentry *parent;
  4446. + struct inode *inode;
  4447. +
  4448. + err = au_test_shwh(dentry->d_sb, name);
  4449. + if (unlikely(err))
  4450. + goto out;
  4451. +
  4452. + err = au_wh_name_alloc(&whname, name);
  4453. + if (unlikely(err))
  4454. + goto out;
  4455. +
  4456. + inode = dentry->d_inode;
  4457. + isdir = !!(inode && S_ISDIR(inode->i_mode));
  4458. + if (!type)
  4459. + au_fset_lkup(args.flags, ALLOW_NEG);
  4460. +
  4461. + npositive = 0;
  4462. + parent = dget_parent(dentry);
  4463. + btail = au_dbtaildir(parent);
  4464. + for (bindex = bstart; bindex <= btail; bindex++) {
  4465. + struct dentry *h_parent, *h_dentry;
  4466. + struct inode *h_inode, *h_dir;
  4467. +
  4468. + h_dentry = au_h_dptr(dentry, bindex);
  4469. + if (h_dentry) {
  4470. + if (h_dentry->d_inode)
  4471. + npositive++;
  4472. + if (type != S_IFDIR)
  4473. + break;
  4474. + continue;
  4475. + }
  4476. + h_parent = au_h_dptr(parent, bindex);
  4477. + if (!h_parent)
  4478. + continue;
  4479. + h_dir = h_parent->d_inode;
  4480. + if (!h_dir || !S_ISDIR(h_dir->i_mode))
  4481. + continue;
  4482. +
  4483. + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
  4484. + h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
  4485. + &args);
  4486. + mutex_unlock(&h_dir->i_mutex);
  4487. + err = PTR_ERR(h_dentry);
  4488. + if (IS_ERR(h_dentry))
  4489. + goto out_parent;
  4490. + au_fclr_lkup(args.flags, ALLOW_NEG);
  4491. +
  4492. + if (au_dbwh(dentry) >= 0)
  4493. + break;
  4494. + if (!h_dentry)
  4495. + continue;
  4496. + h_inode = h_dentry->d_inode;
  4497. + if (!h_inode)
  4498. + continue;
  4499. + npositive++;
  4500. + if (!args.type)
  4501. + args.type = h_inode->i_mode & S_IFMT;
  4502. + if (args.type != S_IFDIR)
  4503. + break;
  4504. + else if (isdir) {
  4505. + /* the type of lower may be different */
  4506. + bdiropq = au_dbdiropq(dentry);
  4507. + if (bdiropq >= 0 && bdiropq <= bindex)
  4508. + break;
  4509. + }
  4510. + }
  4511. +
  4512. + if (npositive) {
  4513. + AuLabel(positive);
  4514. + au_update_dbstart(dentry);
  4515. + }
  4516. + err = npositive;
  4517. + if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
  4518. + && au_dbstart(dentry) < 0)) {
  4519. + err = -EIO;
  4520. + AuIOErr("both of real entry and whiteout found, %.*s, err %d\n",
  4521. + AuDLNPair(dentry), err);
  4522. + }
  4523. +
  4524. +out_parent:
  4525. + dput(parent);
  4526. + kfree(whname.name);
  4527. +out:
  4528. + return err;
  4529. +}
  4530. +
  4531. +struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
  4532. + struct au_branch *br)
  4533. +{
  4534. + struct dentry *dentry;
  4535. + int wkq_err;
  4536. +
  4537. + if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC))
  4538. + dentry = au_lkup_one(name, parent, br, /*nd*/NULL);
  4539. + else {
  4540. + struct au_lkup_one_args args = {
  4541. + .errp = &dentry,
  4542. + .name = name,
  4543. + .h_parent = parent,
  4544. + .br = br,
  4545. + .nd = NULL
  4546. + };
  4547. +
  4548. + wkq_err = au_wkq_wait(au_call_lkup_one, &args);
  4549. + if (unlikely(wkq_err))
  4550. + dentry = ERR_PTR(wkq_err);
  4551. + }
  4552. +
  4553. + return dentry;
  4554. +}
  4555. +
  4556. +/*
  4557. + * lookup @dentry on @bindex which should be negative.
  4558. + */
  4559. +int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex)
  4560. +{
  4561. + int err;
  4562. + struct dentry *parent, *h_parent, *h_dentry;
  4563. +
  4564. + parent = dget_parent(dentry);
  4565. + h_parent = au_h_dptr(parent, bindex);
  4566. + h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent,
  4567. + au_sbr(dentry->d_sb, bindex));
  4568. + err = PTR_ERR(h_dentry);
  4569. + if (IS_ERR(h_dentry))
  4570. + goto out;
  4571. + if (unlikely(h_dentry->d_inode)) {
  4572. + err = -EIO;
  4573. + AuIOErr("%.*s should be negative on b%d.\n",
  4574. + AuDLNPair(h_dentry), bindex);
  4575. + dput(h_dentry);
  4576. + goto out;
  4577. + }
  4578. +
  4579. + err = 0;
  4580. + if (bindex < au_dbstart(dentry))
  4581. + au_set_dbstart(dentry, bindex);
  4582. + if (au_dbend(dentry) < bindex)
  4583. + au_set_dbend(dentry, bindex);
  4584. + au_set_h_dptr(dentry, bindex, h_dentry);
  4585. +
  4586. +out:
  4587. + dput(parent);
  4588. + return err;
  4589. +}
  4590. +
  4591. +/* ---------------------------------------------------------------------- */
  4592. +
  4593. +/* subset of struct inode */
  4594. +struct au_iattr {
  4595. + unsigned long i_ino;
  4596. + /* unsigned int i_nlink; */
  4597. + uid_t i_uid;
  4598. + gid_t i_gid;
  4599. + u64 i_version;
  4600. +/*
  4601. + loff_t i_size;
  4602. + blkcnt_t i_blocks;
  4603. +*/
  4604. + umode_t i_mode;
  4605. +};
  4606. +
  4607. +static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
  4608. +{
  4609. + ia->i_ino = h_inode->i_ino;
  4610. + /* ia->i_nlink = h_inode->i_nlink; */
  4611. + ia->i_uid = h_inode->i_uid;
  4612. + ia->i_gid = h_inode->i_gid;
  4613. + ia->i_version = h_inode->i_version;
  4614. +/*
  4615. + ia->i_size = h_inode->i_size;
  4616. + ia->i_blocks = h_inode->i_blocks;
  4617. +*/
  4618. + ia->i_mode = (h_inode->i_mode & S_IFMT);
  4619. +}
  4620. +
  4621. +static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
  4622. +{
  4623. + return ia->i_ino != h_inode->i_ino
  4624. + /* || ia->i_nlink != h_inode->i_nlink */
  4625. + || ia->i_uid != h_inode->i_uid
  4626. + || ia->i_gid != h_inode->i_gid
  4627. + || ia->i_version != h_inode->i_version
  4628. +/*
  4629. + || ia->i_size != h_inode->i_size
  4630. + || ia->i_blocks != h_inode->i_blocks
  4631. +*/
  4632. + || ia->i_mode != (h_inode->i_mode & S_IFMT);
  4633. +}
  4634. +
  4635. +static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
  4636. + struct au_branch *br)
  4637. +{
  4638. + int err;
  4639. + struct au_iattr ia;
  4640. + struct inode *h_inode;
  4641. + struct dentry *h_d;
  4642. + struct super_block *h_sb;
  4643. +
  4644. + err = 0;
  4645. + memset(&ia, -1, sizeof(ia));
  4646. + h_sb = h_dentry->d_sb;
  4647. + h_inode = h_dentry->d_inode;
  4648. + if (h_inode)
  4649. + au_iattr_save(&ia, h_inode);
  4650. + else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
  4651. + /* nfs d_revalidate may return 0 for negative dentry */
  4652. + /* fuse d_revalidate always return 0 for negative dentry */
  4653. + goto out;
  4654. +
  4655. + /* main purpose is namei.c:cached_lookup() and d_revalidate */
  4656. + h_d = au_lkup_one(&h_dentry->d_name, h_parent, br, /*nd*/NULL);
  4657. + err = PTR_ERR(h_d);
  4658. + if (IS_ERR(h_d))
  4659. + goto out;
  4660. +
  4661. + err = 0;
  4662. + if (unlikely(h_d != h_dentry
  4663. + || h_d->d_inode != h_inode
  4664. + || (h_inode && au_iattr_test(&ia, h_inode))))
  4665. + err = au_busy_or_stale();
  4666. + dput(h_d);
  4667. +
  4668. +out:
  4669. + AuTraceErr(err);
  4670. + return err;
  4671. +}
  4672. +
  4673. +int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
  4674. + struct dentry *h_parent, struct au_branch *br)
  4675. +{
  4676. + int err;
  4677. +
  4678. + err = 0;
  4679. + if (udba == AuOpt_UDBA_REVAL) {
  4680. + IMustLock(h_dir);
  4681. + err = (h_dentry->d_parent->d_inode != h_dir);
  4682. + } else if (udba == AuOpt_UDBA_HNOTIFY)
  4683. + err = au_h_verify_dentry(h_dentry, h_parent, br);
  4684. +
  4685. + return err;
  4686. +}
  4687. +
  4688. +/* ---------------------------------------------------------------------- */
  4689. +
  4690. +static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
  4691. +{
  4692. + int err;
  4693. + aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq;
  4694. + struct au_hdentry tmp, *p, *q;
  4695. + struct au_dinfo *dinfo;
  4696. + struct super_block *sb;
  4697. +
  4698. + DiMustWriteLock(dentry);
  4699. +
  4700. + sb = dentry->d_sb;
  4701. + dinfo = au_di(dentry);
  4702. + bend = dinfo->di_bend;
  4703. + bwh = dinfo->di_bwh;
  4704. + bdiropq = dinfo->di_bdiropq;
  4705. + p = dinfo->di_hdentry + dinfo->di_bstart;
  4706. + for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
  4707. + if (!p->hd_dentry)
  4708. + continue;
  4709. +
  4710. + new_bindex = au_br_index(sb, p->hd_id);
  4711. + if (new_bindex == bindex)
  4712. + continue;
  4713. +
  4714. + if (dinfo->di_bwh == bindex)
  4715. + bwh = new_bindex;
  4716. + if (dinfo->di_bdiropq == bindex)
  4717. + bdiropq = new_bindex;
  4718. + if (new_bindex < 0) {
  4719. + au_hdput(p);
  4720. + p->hd_dentry = NULL;
  4721. + continue;
  4722. + }
  4723. +
  4724. + /* swap two lower dentries, and loop again */
  4725. + q = dinfo->di_hdentry + new_bindex;
  4726. + tmp = *q;
  4727. + *q = *p;
  4728. + *p = tmp;
  4729. + if (tmp.hd_dentry) {
  4730. + bindex--;
  4731. + p--;
  4732. + }
  4733. + }
  4734. +
  4735. + dinfo->di_bwh = -1;
  4736. + if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))
  4737. + dinfo->di_bwh = bwh;
  4738. +
  4739. + dinfo->di_bdiropq = -1;
  4740. + if (bdiropq >= 0
  4741. + && bdiropq <= au_sbend(sb)
  4742. + && au_sbr_whable(sb, bdiropq))
  4743. + dinfo->di_bdiropq = bdiropq;
  4744. +
  4745. + err = -EIO;
  4746. + dinfo->di_bstart = -1;
  4747. + dinfo->di_bend = -1;
  4748. + bend = au_dbend(parent);
  4749. + p = dinfo->di_hdentry;
  4750. + for (bindex = 0; bindex <= bend; bindex++, p++)
  4751. + if (p->hd_dentry) {
  4752. + dinfo->di_bstart = bindex;
  4753. + break;
  4754. + }
  4755. +
  4756. + if (dinfo->di_bstart >= 0) {
  4757. + p = dinfo->di_hdentry + bend;
  4758. + for (bindex = bend; bindex >= 0; bindex--, p--)
  4759. + if (p->hd_dentry) {
  4760. + dinfo->di_bend = bindex;
  4761. + err = 0;
  4762. + break;
  4763. + }
  4764. + }
  4765. +
  4766. + return err;
  4767. +}
  4768. +
  4769. +static void au_do_hide(struct dentry *dentry)
  4770. +{
  4771. + struct inode *inode;
  4772. +
  4773. + inode = dentry->d_inode;
  4774. + if (inode) {
  4775. + if (!S_ISDIR(inode->i_mode)) {
  4776. + if (inode->i_nlink && !d_unhashed(dentry))
  4777. + drop_nlink(inode);
  4778. + } else {
  4779. + clear_nlink(inode);
  4780. + /* stop next lookup */
  4781. + inode->i_flags |= S_DEAD;
  4782. + }
  4783. + smp_mb(); /* necessary? */
  4784. + }
  4785. + d_drop(dentry);
  4786. +}
  4787. +
  4788. +static int au_hide_children(struct dentry *parent)
  4789. +{
  4790. + int err, i, j, ndentry;
  4791. + struct au_dcsub_pages dpages;
  4792. + struct au_dpage *dpage;
  4793. + struct dentry *dentry;
  4794. +
  4795. + err = au_dpages_init(&dpages, GFP_NOFS);
  4796. + if (unlikely(err))
  4797. + goto out;
  4798. + err = au_dcsub_pages(&dpages, parent, NULL, NULL);
  4799. + if (unlikely(err))
  4800. + goto out_dpages;
  4801. +
  4802. + /* in reverse order */
  4803. + for (i = dpages.ndpage - 1; i >= 0; i--) {
  4804. + dpage = dpages.dpages + i;
  4805. + ndentry = dpage->ndentry;
  4806. + for (j = ndentry - 1; j >= 0; j--) {
  4807. + dentry = dpage->dentries[j];
  4808. + if (dentry != parent)
  4809. + au_do_hide(dentry);
  4810. + }
  4811. + }
  4812. +
  4813. +out_dpages:
  4814. + au_dpages_free(&dpages);
  4815. +out:
  4816. + return err;
  4817. +}
  4818. +
  4819. +static void au_hide(struct dentry *dentry)
  4820. +{
  4821. + int err;
  4822. + struct inode *inode;
  4823. +
  4824. + AuDbgDentry(dentry);
  4825. + inode = dentry->d_inode;
  4826. + if (inode && S_ISDIR(inode->i_mode)) {
  4827. + /* shrink_dcache_parent(dentry); */
  4828. + err = au_hide_children(dentry);
  4829. + if (unlikely(err))
  4830. + AuIOErr("%.*s, failed hiding children, ignored %d\n",
  4831. + AuDLNPair(dentry), err);
  4832. + }
  4833. + au_do_hide(dentry);
  4834. +}
  4835. +
  4836. +/*
  4837. + * By adding a dirty branch, a cached dentry may be affected in various ways.
  4838. + *
  4839. + * a dirty branch is added
  4840. + * - on the top of layers
  4841. + * - in the middle of layers
  4842. + * - to the bottom of layers
  4843. + *
  4844. + * on the added branch there exists
  4845. + * - a whiteout
  4846. + * - a diropq
  4847. + * - a same named entry
  4848. + * + exist
  4849. + * * negative --> positive
  4850. + * * positive --> positive
  4851. + * - type is unchanged
  4852. + * - type is changed
  4853. + * + doesn't exist
  4854. + * * negative --> negative
  4855. + * * positive --> negative (rejected by au_br_del() for non-dir case)
  4856. + * - none
  4857. + */
  4858. +static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
  4859. + struct au_dinfo *tmp)
  4860. +{
  4861. + int err;
  4862. + aufs_bindex_t bindex, bend;
  4863. + struct {
  4864. + struct dentry *dentry;
  4865. + struct inode *inode;
  4866. + mode_t mode;
  4867. + } orig_h, tmp_h;
  4868. + struct au_hdentry *hd;
  4869. + struct inode *inode, *h_inode;
  4870. + struct dentry *h_dentry;
  4871. +
  4872. + err = 0;
  4873. + AuDebugOn(dinfo->di_bstart < 0);
  4874. + orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry;
  4875. + orig_h.inode = orig_h.dentry->d_inode;
  4876. + orig_h.mode = 0;
  4877. + if (orig_h.inode)
  4878. + orig_h.mode = orig_h.inode->i_mode & S_IFMT;
  4879. + memset(&tmp_h, 0, sizeof(tmp_h));
  4880. + if (tmp->di_bstart >= 0) {
  4881. + tmp_h.dentry = tmp->di_hdentry[tmp->di_bstart].hd_dentry;
  4882. + tmp_h.inode = tmp_h.dentry->d_inode;
  4883. + if (tmp_h.inode)
  4884. + tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
  4885. + }
  4886. +
  4887. + inode = dentry->d_inode;
  4888. + if (!orig_h.inode) {
  4889. + AuDbg("nagative originally\n");
  4890. + if (inode) {
  4891. + au_hide(dentry);
  4892. + goto out;
  4893. + }
  4894. + AuDebugOn(inode);
  4895. + AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
  4896. + AuDebugOn(dinfo->di_bdiropq != -1);
  4897. +
  4898. + if (!tmp_h.inode) {
  4899. + AuDbg("negative --> negative\n");
  4900. + /* should have only one negative lower */
  4901. + if (tmp->di_bstart >= 0
  4902. + && tmp->di_bstart < dinfo->di_bstart) {
  4903. + AuDebugOn(tmp->di_bstart != tmp->di_bend);
  4904. + AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
  4905. + au_set_h_dptr(dentry, dinfo->di_bstart, NULL);
  4906. + au_di_cp(dinfo, tmp);
  4907. + hd = tmp->di_hdentry + tmp->di_bstart;
  4908. + au_set_h_dptr(dentry, tmp->di_bstart,
  4909. + dget(hd->hd_dentry));
  4910. + }
  4911. + au_dbg_verify_dinode(dentry);
  4912. + } else {
  4913. + AuDbg("negative --> positive\n");
  4914. + /*
  4915. + * similar to the behaviour of creating with bypassing
  4916. + * aufs.
  4917. + * unhash it in order to force an error in the
  4918. + * succeeding create operation.
  4919. + * we should not set S_DEAD here.
  4920. + */
  4921. + d_drop(dentry);
  4922. + /* au_di_swap(tmp, dinfo); */
  4923. + au_dbg_verify_dinode(dentry);
  4924. + }
  4925. + } else {
  4926. + AuDbg("positive originally\n");
  4927. + /* inode may be NULL */
  4928. + AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode);
  4929. + if (!tmp_h.inode) {
  4930. + AuDbg("positive --> negative\n");
  4931. + /* or bypassing aufs */
  4932. + au_hide(dentry);
  4933. + if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_bstart)
  4934. + dinfo->di_bwh = tmp->di_bwh;
  4935. + if (inode)
  4936. + err = au_refresh_hinode_self(inode);
  4937. + au_dbg_verify_dinode(dentry);
  4938. + } else if (orig_h.mode == tmp_h.mode) {
  4939. + AuDbg("positive --> positive, same type\n");
  4940. + if (!S_ISDIR(orig_h.mode)
  4941. + && dinfo->di_bstart > tmp->di_bstart) {
  4942. + /*
  4943. + * similar to the behaviour of removing and
  4944. + * creating.
  4945. + */
  4946. + au_hide(dentry);
  4947. + if (inode)
  4948. + err = au_refresh_hinode_self(inode);
  4949. + au_dbg_verify_dinode(dentry);
  4950. + } else {
  4951. + /* fill empty slots */
  4952. + if (dinfo->di_bstart > tmp->di_bstart)
  4953. + dinfo->di_bstart = tmp->di_bstart;
  4954. + if (dinfo->di_bend < tmp->di_bend)
  4955. + dinfo->di_bend = tmp->di_bend;
  4956. + dinfo->di_bwh = tmp->di_bwh;
  4957. + dinfo->di_bdiropq = tmp->di_bdiropq;
  4958. + hd = tmp->di_hdentry;
  4959. + bend = dinfo->di_bend;
  4960. + for (bindex = tmp->di_bstart; bindex <= bend;
  4961. + bindex++) {
  4962. + if (au_h_dptr(dentry, bindex))
  4963. + continue;
  4964. + h_dentry = hd[bindex].hd_dentry;
  4965. + if (!h_dentry)
  4966. + continue;
  4967. + h_inode = h_dentry->d_inode;
  4968. + AuDebugOn(!h_inode);
  4969. + AuDebugOn(orig_h.mode
  4970. + != (h_inode->i_mode
  4971. + & S_IFMT));
  4972. + au_set_h_dptr(dentry, bindex,
  4973. + dget(h_dentry));
  4974. + }
  4975. + err = au_refresh_hinode(inode, dentry);
  4976. + au_dbg_verify_dinode(dentry);
  4977. + }
  4978. + } else {
  4979. + AuDbg("positive --> positive, different type\n");
  4980. + /* similar to the behaviour of removing and creating */
  4981. + au_hide(dentry);
  4982. + if (inode)
  4983. + err = au_refresh_hinode_self(inode);
  4984. + au_dbg_verify_dinode(dentry);
  4985. + }
  4986. + }
  4987. +
  4988. +out:
  4989. + return err;
  4990. +}
  4991. +
  4992. +int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
  4993. +{
  4994. + int err, ebrange;
  4995. + unsigned int sigen;
  4996. + struct au_dinfo *dinfo, *tmp;
  4997. + struct super_block *sb;
  4998. + struct inode *inode;
  4999. +
  5000. + DiMustWriteLock(dentry);
  5001. + AuDebugOn(IS_ROOT(dentry));
  5002. + AuDebugOn(!parent->d_inode);
  5003. +
  5004. + sb = dentry->d_sb;
  5005. + inode = dentry->d_inode;
  5006. + sigen = au_sigen(sb);
  5007. + err = au_digen_test(parent, sigen);
  5008. + if (unlikely(err))
  5009. + goto out;
  5010. +
  5011. + dinfo = au_di(dentry);
  5012. + err = au_di_realloc(dinfo, au_sbend(sb) + 1);
  5013. + if (unlikely(err))
  5014. + goto out;
  5015. + ebrange = au_dbrange_test(dentry);
  5016. + if (!ebrange)
  5017. + ebrange = au_do_refresh_hdentry(dentry, parent);
  5018. +
  5019. + if (d_unhashed(dentry) || ebrange) {
  5020. + AuDebugOn(au_dbstart(dentry) < 0 && au_dbend(dentry) >= 0);
  5021. + if (inode)
  5022. + err = au_refresh_hinode_self(inode);
  5023. + au_dbg_verify_dinode(dentry);
  5024. + if (!err)
  5025. + goto out_dgen; /* success */
  5026. + goto out;
  5027. + }
  5028. +
  5029. + /* temporary dinfo */
  5030. + AuDbgDentry(dentry);
  5031. + err = -ENOMEM;
  5032. + tmp = au_di_alloc(sb, AuLsc_DI_TMP);
  5033. + if (unlikely(!tmp))
  5034. + goto out;
  5035. + au_di_swap(tmp, dinfo);
  5036. + /* returns the number of positive dentries */
  5037. + /*
  5038. + * if current working dir is removed, it returns an error.
  5039. + * but the dentry is legal.
  5040. + */
  5041. + err = au_lkup_dentry(dentry, /*bstart*/0, /*type*/0, /*nd*/NULL);
  5042. + AuDbgDentry(dentry);
  5043. + au_di_swap(tmp, dinfo);
  5044. + if (err == -ENOENT)
  5045. + err = 0;
  5046. + if (err >= 0) {
  5047. + /* compare/refresh by dinfo */
  5048. + AuDbgDentry(dentry);
  5049. + err = au_refresh_by_dinfo(dentry, dinfo, tmp);
  5050. + au_dbg_verify_dinode(dentry);
  5051. + AuTraceErr(err);
  5052. + }
  5053. + au_rw_write_unlock(&tmp->di_rwsem);
  5054. + au_di_free(tmp);
  5055. + if (unlikely(err))
  5056. + goto out;
  5057. +
  5058. +out_dgen:
  5059. + au_update_digen(dentry);
  5060. +out:
  5061. + if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) {
  5062. + AuIOErr("failed refreshing %.*s, %d\n",
  5063. + AuDLNPair(dentry), err);
  5064. + AuDbgDentry(dentry);
  5065. + }
  5066. + AuTraceErr(err);
  5067. + return err;
  5068. +}
  5069. +
  5070. +static noinline_for_stack
  5071. +int au_do_h_d_reval(struct dentry *h_dentry, struct nameidata *nd,
  5072. + struct dentry *dentry, aufs_bindex_t bindex)
  5073. +{
  5074. + int err, valid;
  5075. + int (*reval)(struct dentry *, struct nameidata *);
  5076. +
  5077. + err = 0;
  5078. + reval = NULL;
  5079. + if (h_dentry->d_op)
  5080. + reval = h_dentry->d_op->d_revalidate;
  5081. + if (!reval)
  5082. + goto out;
  5083. +
  5084. + AuDbg("b%d\n", bindex);
  5085. + if (au_test_fs_null_nd(h_dentry->d_sb))
  5086. + /* it may return tri-state */
  5087. + valid = reval(h_dentry, NULL);
  5088. + else {
  5089. + struct nameidata h_nd;
  5090. + int locked;
  5091. + struct dentry *parent;
  5092. +
  5093. + au_h_nd(&h_nd, nd);
  5094. + parent = nd->path.dentry;
  5095. + locked = (nd && nd->path.dentry != dentry);
  5096. + if (locked)
  5097. + di_read_lock_parent(parent, AuLock_IR);
  5098. + BUG_ON(bindex > au_dbend(parent));
  5099. + h_nd.path.dentry = au_h_dptr(parent, bindex);
  5100. + BUG_ON(!h_nd.path.dentry);
  5101. + h_nd.path.mnt = au_sbr(parent->d_sb, bindex)->br_mnt;
  5102. + path_get(&h_nd.path);
  5103. + valid = reval(h_dentry, &h_nd);
  5104. + path_put(&h_nd.path);
  5105. + if (locked)
  5106. + di_read_unlock(parent, AuLock_IR);
  5107. + }
  5108. +
  5109. + if (unlikely(valid < 0))
  5110. + err = valid;
  5111. + else if (!valid)
  5112. + err = -EINVAL;
  5113. +
  5114. +out:
  5115. + AuTraceErr(err);
  5116. + return err;
  5117. +}
  5118. +
  5119. +/* todo: remove this */
  5120. +static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
  5121. + struct nameidata *nd, int do_udba)
  5122. +{
  5123. + int err;
  5124. + umode_t mode, h_mode;
  5125. + aufs_bindex_t bindex, btail, bstart, ibs, ibe;
  5126. + unsigned char plus, unhashed, is_root, h_plus;
  5127. + struct inode *h_inode, *h_cached_inode;
  5128. + struct dentry *h_dentry;
  5129. + struct qstr *name, *h_name;
  5130. +
  5131. + err = 0;
  5132. + plus = 0;
  5133. + mode = 0;
  5134. + ibs = -1;
  5135. + ibe = -1;
  5136. + unhashed = !!d_unhashed(dentry);
  5137. + is_root = !!IS_ROOT(dentry);
  5138. + name = &dentry->d_name;
  5139. +
  5140. + /*
  5141. + * Theoretically, REVAL test should be unnecessary in case of
  5142. + * {FS,I}NOTIFY.
  5143. + * But {fs,i}notify doesn't fire some necessary events,
  5144. + * IN_ATTRIB for atime/nlink/pageio
  5145. + * IN_DELETE for NFS dentry
  5146. + * Let's do REVAL test too.
  5147. + */
  5148. + if (do_udba && inode) {
  5149. + mode = (inode->i_mode & S_IFMT);
  5150. + plus = (inode->i_nlink > 0);
  5151. + ibs = au_ibstart(inode);
  5152. + ibe = au_ibend(inode);
  5153. + }
  5154. +
  5155. + bstart = au_dbstart(dentry);
  5156. + btail = bstart;
  5157. + if (inode && S_ISDIR(inode->i_mode))
  5158. + btail = au_dbtaildir(dentry);
  5159. + for (bindex = bstart; bindex <= btail; bindex++) {
  5160. + h_dentry = au_h_dptr(dentry, bindex);
  5161. + if (!h_dentry)
  5162. + continue;
  5163. +
  5164. + AuDbg("b%d, %.*s\n", bindex, AuDLNPair(h_dentry));
  5165. + h_name = &h_dentry->d_name;
  5166. + if (unlikely(do_udba
  5167. + && !is_root
  5168. + && (unhashed != !!d_unhashed(h_dentry)
  5169. + || name->len != h_name->len
  5170. + || memcmp(name->name, h_name->name, name->len))
  5171. + )) {
  5172. + AuDbg("unhash 0x%x 0x%x, %.*s %.*s\n",
  5173. + unhashed, d_unhashed(h_dentry),
  5174. + AuDLNPair(dentry), AuDLNPair(h_dentry));
  5175. + goto err;
  5176. + }
  5177. +
  5178. + err = au_do_h_d_reval(h_dentry, nd, dentry, bindex);
  5179. + if (unlikely(err))
  5180. + /* do not goto err, to keep the errno */
  5181. + break;
  5182. +
  5183. + /* todo: plink too? */
  5184. + if (!do_udba)
  5185. + continue;
  5186. +
  5187. + /* UDBA tests */
  5188. + h_inode = h_dentry->d_inode;
  5189. + if (unlikely(!!inode != !!h_inode))
  5190. + goto err;
  5191. +
  5192. + h_plus = plus;
  5193. + h_mode = mode;
  5194. + h_cached_inode = h_inode;
  5195. + if (h_inode) {
  5196. + h_mode = (h_inode->i_mode & S_IFMT);
  5197. + h_plus = (h_inode->i_nlink > 0);
  5198. + }
  5199. + if (inode && ibs <= bindex && bindex <= ibe)
  5200. + h_cached_inode = au_h_iptr(inode, bindex);
  5201. +
  5202. + if (unlikely(plus != h_plus
  5203. + || mode != h_mode
  5204. + || h_cached_inode != h_inode))
  5205. + goto err;
  5206. + continue;
  5207. +
  5208. + err:
  5209. + err = -EINVAL;
  5210. + break;
  5211. + }
  5212. +
  5213. + return err;
  5214. +}
  5215. +
  5216. +/* todo: consolidate with do_refresh() and au_reval_for_attr() */
  5217. +static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
  5218. +{
  5219. + int err;
  5220. + struct dentry *parent;
  5221. +
  5222. + if (!au_digen_test(dentry, sigen))
  5223. + return 0;
  5224. +
  5225. + parent = dget_parent(dentry);
  5226. + di_read_lock_parent(parent, AuLock_IR);
  5227. + AuDebugOn(au_digen_test(parent, sigen));
  5228. + au_dbg_verify_gen(parent, sigen);
  5229. + err = au_refresh_dentry(dentry, parent);
  5230. + di_read_unlock(parent, AuLock_IR);
  5231. + dput(parent);
  5232. + AuTraceErr(err);
  5233. + return err;
  5234. +}
  5235. +
  5236. +int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
  5237. +{
  5238. + int err;
  5239. + struct dentry *d, *parent;
  5240. + struct inode *inode;
  5241. +
  5242. + if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
  5243. + return simple_reval_dpath(dentry, sigen);
  5244. +
  5245. + /* slow loop, keep it simple and stupid */
  5246. + /* cf: au_cpup_dirs() */
  5247. + err = 0;
  5248. + parent = NULL;
  5249. + while (au_digen_test(dentry, sigen)) {
  5250. + d = dentry;
  5251. + while (1) {
  5252. + dput(parent);
  5253. + parent = dget_parent(d);
  5254. + if (!au_digen_test(parent, sigen))
  5255. + break;
  5256. + d = parent;
  5257. + }
  5258. +
  5259. + inode = d->d_inode;
  5260. + if (d != dentry)
  5261. + di_write_lock_child2(d);
  5262. +
  5263. + /* someone might update our dentry while we were sleeping */
  5264. + if (au_digen_test(d, sigen)) {
  5265. + /*
  5266. + * todo: consolidate with simple_reval_dpath(),
  5267. + * do_refresh() and au_reval_for_attr().
  5268. + */
  5269. + di_read_lock_parent(parent, AuLock_IR);
  5270. + err = au_refresh_dentry(d, parent);
  5271. + di_read_unlock(parent, AuLock_IR);
  5272. + }
  5273. +
  5274. + if (d != dentry)
  5275. + di_write_unlock(d);
  5276. + dput(parent);
  5277. + if (unlikely(err))
  5278. + break;
  5279. + }
  5280. +
  5281. + return err;
  5282. +}
  5283. +
  5284. +/*
  5285. + * if valid returns 1, otherwise 0.
  5286. + */
  5287. +static int aufs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
  5288. +{
  5289. + int valid, err;
  5290. + unsigned int sigen;
  5291. + unsigned char do_udba;
  5292. + struct super_block *sb;
  5293. + struct inode *inode;
  5294. +
  5295. + valid = 0;
  5296. + if (unlikely(!au_di(dentry)))
  5297. + goto out;
  5298. +
  5299. + valid = 1;
  5300. + sb = dentry->d_sb;
  5301. + inode = dentry->d_inode;
  5302. + /*
  5303. + * todo: very ugly
  5304. + * i_mutex of parent dir may be held,
  5305. + * but we should not return 'invalid' due to busy.
  5306. + */
  5307. + err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM);
  5308. + if (unlikely(err)) {
  5309. + valid = err;
  5310. + AuTraceErr(err);
  5311. + goto out;
  5312. + }
  5313. + if (unlikely(au_dbrange_test(dentry))) {
  5314. + err = -EINVAL;
  5315. + AuTraceErr(err);
  5316. + goto out_dgrade;
  5317. + }
  5318. +
  5319. + sigen = au_sigen(sb);
  5320. + if (au_digen_test(dentry, sigen)) {
  5321. + AuDebugOn(IS_ROOT(dentry));
  5322. + err = au_reval_dpath(dentry, sigen);
  5323. + if (unlikely(err)) {
  5324. + AuTraceErr(err);
  5325. + goto out_dgrade;
  5326. + }
  5327. + }
  5328. + di_downgrade_lock(dentry, AuLock_IR);
  5329. +
  5330. + err = -EINVAL;
  5331. + if (inode && (IS_DEADDIR(inode) || !inode->i_nlink))
  5332. + goto out_inval;
  5333. +
  5334. + do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
  5335. + if (do_udba && inode) {
  5336. + aufs_bindex_t bstart = au_ibstart(inode);
  5337. + struct inode *h_inode;
  5338. +
  5339. + if (bstart >= 0) {
  5340. + h_inode = au_h_iptr(inode, bstart);
  5341. + if (h_inode && au_test_higen(inode, h_inode))
  5342. + goto out_inval;
  5343. + }
  5344. + }
  5345. +
  5346. + err = h_d_revalidate(dentry, inode, nd, do_udba);
  5347. + if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) {
  5348. + err = -EIO;
  5349. + AuDbg("both of real entry and whiteout found, %.*s, err %d\n",
  5350. + AuDLNPair(dentry), err);
  5351. + }
  5352. + goto out_inval;
  5353. +
  5354. +out_dgrade:
  5355. + di_downgrade_lock(dentry, AuLock_IR);
  5356. +out_inval:
  5357. + aufs_read_unlock(dentry, AuLock_IR);
  5358. + AuTraceErr(err);
  5359. + valid = !err;
  5360. +out:
  5361. + if (!valid) {
  5362. + AuDbg("%.*s invalid, %d\n", AuDLNPair(dentry), valid);
  5363. + d_drop(dentry);
  5364. + }
  5365. + return valid;
  5366. +}
  5367. +
  5368. +static void aufs_d_release(struct dentry *dentry)
  5369. +{
  5370. + if (au_di(dentry)) {
  5371. + au_di_fin(dentry);
  5372. + au_hn_di_reinit(dentry);
  5373. + }
  5374. +}
  5375. +
  5376. +const struct dentry_operations aufs_dop = {
  5377. + .d_revalidate = aufs_d_revalidate,
  5378. + .d_release = aufs_d_release
  5379. +};
  5380. diff -Nur linux-2.6.37.orig/fs/aufs/dentry.h linux-2.6.37/fs/aufs/dentry.h
  5381. --- linux-2.6.37.orig/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
  5382. +++ linux-2.6.37/fs/aufs/dentry.h 2011-01-11 20:15:11.000000000 +0100
  5383. @@ -0,0 +1,237 @@
  5384. +/*
  5385. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  5386. + *
  5387. + * This program, aufs is free software; you can redistribute it and/or modify
  5388. + * it under the terms of the GNU General Public License as published by
  5389. + * the Free Software Foundation; either version 2 of the License, or
  5390. + * (at your option) any later version.
  5391. + *
  5392. + * This program is distributed in the hope that it will be useful,
  5393. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  5394. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  5395. + * GNU General Public License for more details.
  5396. + *
  5397. + * You should have received a copy of the GNU General Public License
  5398. + * along with this program; if not, write to the Free Software
  5399. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  5400. + */
  5401. +
  5402. +/*
  5403. + * lookup and dentry operations
  5404. + */
  5405. +
  5406. +#ifndef __AUFS_DENTRY_H__
  5407. +#define __AUFS_DENTRY_H__
  5408. +
  5409. +#ifdef __KERNEL__
  5410. +
  5411. +#include <linux/dcache.h>
  5412. +#include <linux/aufs_type.h>
  5413. +#include "rwsem.h"
  5414. +
  5415. +struct au_hdentry {
  5416. + struct dentry *hd_dentry;
  5417. + aufs_bindex_t hd_id;
  5418. +};
  5419. +
  5420. +struct au_dinfo {
  5421. + atomic_t di_generation;
  5422. +
  5423. + struct au_rwsem di_rwsem;
  5424. + aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq;
  5425. + struct au_hdentry *di_hdentry;
  5426. +} ____cacheline_aligned_in_smp;
  5427. +
  5428. +/* ---------------------------------------------------------------------- */
  5429. +
  5430. +/* dentry.c */
  5431. +extern const struct dentry_operations aufs_dop;
  5432. +struct au_branch;
  5433. +struct dentry *au_lkup_one(struct qstr *name, struct dentry *h_parent,
  5434. + struct au_branch *br, struct nameidata *nd);
  5435. +struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
  5436. + struct au_branch *br);
  5437. +int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
  5438. + struct dentry *h_parent, struct au_branch *br);
  5439. +
  5440. +int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type,
  5441. + struct nameidata *nd);
  5442. +int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex);
  5443. +int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
  5444. +int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
  5445. +
  5446. +/* dinfo.c */
  5447. +void au_di_init_once(void *_di);
  5448. +struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
  5449. +void au_di_free(struct au_dinfo *dinfo);
  5450. +void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
  5451. +void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
  5452. +int au_di_init(struct dentry *dentry);
  5453. +void au_di_fin(struct dentry *dentry);
  5454. +int au_di_realloc(struct au_dinfo *dinfo, int nbr);
  5455. +
  5456. +void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
  5457. +void di_read_unlock(struct dentry *d, int flags);
  5458. +void di_downgrade_lock(struct dentry *d, int flags);
  5459. +void di_write_lock(struct dentry *d, unsigned int lsc);
  5460. +void di_write_unlock(struct dentry *d);
  5461. +void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
  5462. +void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
  5463. +void di_write_unlock2(struct dentry *d1, struct dentry *d2);
  5464. +
  5465. +struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
  5466. +aufs_bindex_t au_dbtail(struct dentry *dentry);
  5467. +aufs_bindex_t au_dbtaildir(struct dentry *dentry);
  5468. +
  5469. +void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
  5470. + struct dentry *h_dentry);
  5471. +int au_digen_test(struct dentry *dentry, unsigned int sigen);
  5472. +int au_dbrange_test(struct dentry *dentry);
  5473. +void au_update_digen(struct dentry *dentry);
  5474. +void au_update_dbrange(struct dentry *dentry, int do_put_zero);
  5475. +void au_update_dbstart(struct dentry *dentry);
  5476. +void au_update_dbend(struct dentry *dentry);
  5477. +int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
  5478. +
  5479. +/* ---------------------------------------------------------------------- */
  5480. +
  5481. +static inline struct au_dinfo *au_di(struct dentry *dentry)
  5482. +{
  5483. + return dentry->d_fsdata;
  5484. +}
  5485. +
  5486. +/* ---------------------------------------------------------------------- */
  5487. +
  5488. +/* lock subclass for dinfo */
  5489. +enum {
  5490. + AuLsc_DI_CHILD, /* child first */
  5491. + AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */
  5492. + AuLsc_DI_CHILD3, /* copyup dirs */
  5493. + AuLsc_DI_PARENT,
  5494. + AuLsc_DI_PARENT2,
  5495. + AuLsc_DI_PARENT3,
  5496. + AuLsc_DI_TMP /* temp for replacing dinfo */
  5497. +};
  5498. +
  5499. +/*
  5500. + * di_read_lock_child, di_write_lock_child,
  5501. + * di_read_lock_child2, di_write_lock_child2,
  5502. + * di_read_lock_child3, di_write_lock_child3,
  5503. + * di_read_lock_parent, di_write_lock_parent,
  5504. + * di_read_lock_parent2, di_write_lock_parent2,
  5505. + * di_read_lock_parent3, di_write_lock_parent3,
  5506. + */
  5507. +#define AuReadLockFunc(name, lsc) \
  5508. +static inline void di_read_lock_##name(struct dentry *d, int flags) \
  5509. +{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
  5510. +
  5511. +#define AuWriteLockFunc(name, lsc) \
  5512. +static inline void di_write_lock_##name(struct dentry *d) \
  5513. +{ di_write_lock(d, AuLsc_DI_##lsc); }
  5514. +
  5515. +#define AuRWLockFuncs(name, lsc) \
  5516. + AuReadLockFunc(name, lsc) \
  5517. + AuWriteLockFunc(name, lsc)
  5518. +
  5519. +AuRWLockFuncs(child, CHILD);
  5520. +AuRWLockFuncs(child2, CHILD2);
  5521. +AuRWLockFuncs(child3, CHILD3);
  5522. +AuRWLockFuncs(parent, PARENT);
  5523. +AuRWLockFuncs(parent2, PARENT2);
  5524. +AuRWLockFuncs(parent3, PARENT3);
  5525. +
  5526. +#undef AuReadLockFunc
  5527. +#undef AuWriteLockFunc
  5528. +#undef AuRWLockFuncs
  5529. +
  5530. +#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
  5531. +#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
  5532. +#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
  5533. +
  5534. +/* ---------------------------------------------------------------------- */
  5535. +
  5536. +/* todo: memory barrier? */
  5537. +static inline unsigned int au_digen(struct dentry *d)
  5538. +{
  5539. + return atomic_read(&au_di(d)->di_generation);
  5540. +}
  5541. +
  5542. +static inline void au_h_dentry_init(struct au_hdentry *hdentry)
  5543. +{
  5544. + hdentry->hd_dentry = NULL;
  5545. +}
  5546. +
  5547. +static inline void au_hdput(struct au_hdentry *hd)
  5548. +{
  5549. + if (hd)
  5550. + dput(hd->hd_dentry);
  5551. +}
  5552. +
  5553. +static inline aufs_bindex_t au_dbstart(struct dentry *dentry)
  5554. +{
  5555. + DiMustAnyLock(dentry);
  5556. + return au_di(dentry)->di_bstart;
  5557. +}
  5558. +
  5559. +static inline aufs_bindex_t au_dbend(struct dentry *dentry)
  5560. +{
  5561. + DiMustAnyLock(dentry);
  5562. + return au_di(dentry)->di_bend;
  5563. +}
  5564. +
  5565. +static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
  5566. +{
  5567. + DiMustAnyLock(dentry);
  5568. + return au_di(dentry)->di_bwh;
  5569. +}
  5570. +
  5571. +static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
  5572. +{
  5573. + DiMustAnyLock(dentry);
  5574. + return au_di(dentry)->di_bdiropq;
  5575. +}
  5576. +
  5577. +/* todo: hard/soft set? */
  5578. +static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex)
  5579. +{
  5580. + DiMustWriteLock(dentry);
  5581. + au_di(dentry)->di_bstart = bindex;
  5582. +}
  5583. +
  5584. +static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex)
  5585. +{
  5586. + DiMustWriteLock(dentry);
  5587. + au_di(dentry)->di_bend = bindex;
  5588. +}
  5589. +
  5590. +static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
  5591. +{
  5592. + DiMustWriteLock(dentry);
  5593. + /* dbwh can be outside of bstart - bend range */
  5594. + au_di(dentry)->di_bwh = bindex;
  5595. +}
  5596. +
  5597. +static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
  5598. +{
  5599. + DiMustWriteLock(dentry);
  5600. + au_di(dentry)->di_bdiropq = bindex;
  5601. +}
  5602. +
  5603. +/* ---------------------------------------------------------------------- */
  5604. +
  5605. +#ifdef CONFIG_AUFS_HNOTIFY
  5606. +static inline void au_digen_dec(struct dentry *d)
  5607. +{
  5608. + atomic_dec(&au_di(d)->di_generation);
  5609. +}
  5610. +
  5611. +static inline void au_hn_di_reinit(struct dentry *dentry)
  5612. +{
  5613. + dentry->d_fsdata = NULL;
  5614. +}
  5615. +#else
  5616. +AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
  5617. +#endif /* CONFIG_AUFS_HNOTIFY */
  5618. +
  5619. +#endif /* __KERNEL__ */
  5620. +#endif /* __AUFS_DENTRY_H__ */
  5621. diff -Nur linux-2.6.37.orig/fs/aufs/dinfo.c linux-2.6.37/fs/aufs/dinfo.c
  5622. --- linux-2.6.37.orig/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100
  5623. +++ linux-2.6.37/fs/aufs/dinfo.c 2011-01-11 20:15:11.000000000 +0100
  5624. @@ -0,0 +1,494 @@
  5625. +/*
  5626. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  5627. + *
  5628. + * This program, aufs is free software; you can redistribute it and/or modify
  5629. + * it under the terms of the GNU General Public License as published by
  5630. + * the Free Software Foundation; either version 2 of the License, or
  5631. + * (at your option) any later version.
  5632. + *
  5633. + * This program is distributed in the hope that it will be useful,
  5634. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  5635. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  5636. + * GNU General Public License for more details.
  5637. + *
  5638. + * You should have received a copy of the GNU General Public License
  5639. + * along with this program; if not, write to the Free Software
  5640. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  5641. + */
  5642. +
  5643. +/*
  5644. + * dentry private data
  5645. + */
  5646. +
  5647. +#include "aufs.h"
  5648. +
  5649. +void au_di_init_once(void *_dinfo)
  5650. +{
  5651. + struct au_dinfo *dinfo = _dinfo;
  5652. + static struct lock_class_key aufs_di;
  5653. +
  5654. + au_rw_init(&dinfo->di_rwsem);
  5655. + au_rw_class(&dinfo->di_rwsem, &aufs_di);
  5656. +}
  5657. +
  5658. +struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
  5659. +{
  5660. + struct au_dinfo *dinfo;
  5661. + int nbr, i;
  5662. +
  5663. + dinfo = au_cache_alloc_dinfo();
  5664. + if (unlikely(!dinfo))
  5665. + goto out;
  5666. +
  5667. + nbr = au_sbend(sb) + 1;
  5668. + if (nbr <= 0)
  5669. + nbr = 1;
  5670. + dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
  5671. + if (dinfo->di_hdentry) {
  5672. + au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
  5673. + dinfo->di_bstart = -1;
  5674. + dinfo->di_bend = -1;
  5675. + dinfo->di_bwh = -1;
  5676. + dinfo->di_bdiropq = -1;
  5677. + for (i = 0; i < nbr; i++)
  5678. + dinfo->di_hdentry[i].hd_id = -1;
  5679. + goto out;
  5680. + }
  5681. +
  5682. + au_cache_free_dinfo(dinfo);
  5683. + dinfo = NULL;
  5684. +
  5685. +out:
  5686. + return dinfo;
  5687. +}
  5688. +
  5689. +void au_di_free(struct au_dinfo *dinfo)
  5690. +{
  5691. + struct au_hdentry *p;
  5692. + aufs_bindex_t bend, bindex;
  5693. +
  5694. + /* dentry may not be revalidated */
  5695. + bindex = dinfo->di_bstart;
  5696. + if (bindex >= 0) {
  5697. + bend = dinfo->di_bend;
  5698. + p = dinfo->di_hdentry + bindex;
  5699. + while (bindex++ <= bend)
  5700. + au_hdput(p++);
  5701. + }
  5702. + kfree(dinfo->di_hdentry);
  5703. + au_cache_free_dinfo(dinfo);
  5704. +}
  5705. +
  5706. +void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
  5707. +{
  5708. + struct au_hdentry *p;
  5709. + aufs_bindex_t bi;
  5710. +
  5711. + AuRwMustWriteLock(&a->di_rwsem);
  5712. + AuRwMustWriteLock(&b->di_rwsem);
  5713. +
  5714. +#define DiSwap(v, name) \
  5715. + do { \
  5716. + v = a->di_##name; \
  5717. + a->di_##name = b->di_##name; \
  5718. + b->di_##name = v; \
  5719. + } while (0)
  5720. +
  5721. + DiSwap(p, hdentry);
  5722. + DiSwap(bi, bstart);
  5723. + DiSwap(bi, bend);
  5724. + DiSwap(bi, bwh);
  5725. + DiSwap(bi, bdiropq);
  5726. + /* smp_mb(); */
  5727. +
  5728. +#undef DiSwap
  5729. +}
  5730. +
  5731. +void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
  5732. +{
  5733. + AuRwMustWriteLock(&dst->di_rwsem);
  5734. + AuRwMustWriteLock(&src->di_rwsem);
  5735. +
  5736. + dst->di_bstart = src->di_bstart;
  5737. + dst->di_bend = src->di_bend;
  5738. + dst->di_bwh = src->di_bwh;
  5739. + dst->di_bdiropq = src->di_bdiropq;
  5740. + /* smp_mb(); */
  5741. +}
  5742. +
  5743. +int au_di_init(struct dentry *dentry)
  5744. +{
  5745. + int err;
  5746. + struct super_block *sb;
  5747. + struct au_dinfo *dinfo;
  5748. +
  5749. + err = 0;
  5750. + sb = dentry->d_sb;
  5751. + dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
  5752. + if (dinfo) {
  5753. + atomic_set(&dinfo->di_generation, au_sigen(sb));
  5754. + /* smp_mb(); */ /* atomic_set */
  5755. + dentry->d_op = &aufs_dop;
  5756. + dentry->d_fsdata = dinfo;
  5757. + } else
  5758. + err = -ENOMEM;
  5759. +
  5760. + return err;
  5761. +}
  5762. +
  5763. +void au_di_fin(struct dentry *dentry)
  5764. +{
  5765. + struct au_dinfo *dinfo;
  5766. +
  5767. + dinfo = au_di(dentry);
  5768. + AuRwDestroy(&dinfo->di_rwsem);
  5769. + au_di_free(dinfo);
  5770. +}
  5771. +
  5772. +int au_di_realloc(struct au_dinfo *dinfo, int nbr)
  5773. +{
  5774. + int err, sz;
  5775. + struct au_hdentry *hdp;
  5776. +
  5777. + AuRwMustWriteLock(&dinfo->di_rwsem);
  5778. +
  5779. + err = -ENOMEM;
  5780. + sz = sizeof(*hdp) * (dinfo->di_bend + 1);
  5781. + if (!sz)
  5782. + sz = sizeof(*hdp);
  5783. + hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS);
  5784. + if (hdp) {
  5785. + dinfo->di_hdentry = hdp;
  5786. + err = 0;
  5787. + }
  5788. +
  5789. + return err;
  5790. +}
  5791. +
  5792. +/* ---------------------------------------------------------------------- */
  5793. +
  5794. +static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
  5795. +{
  5796. + switch (lsc) {
  5797. + case AuLsc_DI_CHILD:
  5798. + ii_write_lock_child(inode);
  5799. + break;
  5800. + case AuLsc_DI_CHILD2:
  5801. + ii_write_lock_child2(inode);
  5802. + break;
  5803. + case AuLsc_DI_CHILD3:
  5804. + ii_write_lock_child3(inode);
  5805. + break;
  5806. + case AuLsc_DI_PARENT:
  5807. + ii_write_lock_parent(inode);
  5808. + break;
  5809. + case AuLsc_DI_PARENT2:
  5810. + ii_write_lock_parent2(inode);
  5811. + break;
  5812. + case AuLsc_DI_PARENT3:
  5813. + ii_write_lock_parent3(inode);
  5814. + break;
  5815. + default:
  5816. + BUG();
  5817. + }
  5818. +}
  5819. +
  5820. +static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
  5821. +{
  5822. + switch (lsc) {
  5823. + case AuLsc_DI_CHILD:
  5824. + ii_read_lock_child(inode);
  5825. + break;
  5826. + case AuLsc_DI_CHILD2:
  5827. + ii_read_lock_child2(inode);
  5828. + break;
  5829. + case AuLsc_DI_CHILD3:
  5830. + ii_read_lock_child3(inode);
  5831. + break;
  5832. + case AuLsc_DI_PARENT:
  5833. + ii_read_lock_parent(inode);
  5834. + break;
  5835. + case AuLsc_DI_PARENT2:
  5836. + ii_read_lock_parent2(inode);
  5837. + break;
  5838. + case AuLsc_DI_PARENT3:
  5839. + ii_read_lock_parent3(inode);
  5840. + break;
  5841. + default:
  5842. + BUG();
  5843. + }
  5844. +}
  5845. +
  5846. +void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
  5847. +{
  5848. + au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
  5849. + if (d->d_inode) {
  5850. + if (au_ftest_lock(flags, IW))
  5851. + do_ii_write_lock(d->d_inode, lsc);
  5852. + else if (au_ftest_lock(flags, IR))
  5853. + do_ii_read_lock(d->d_inode, lsc);
  5854. + }
  5855. +}
  5856. +
  5857. +void di_read_unlock(struct dentry *d, int flags)
  5858. +{
  5859. + if (d->d_inode) {
  5860. + if (au_ftest_lock(flags, IW)) {
  5861. + au_dbg_verify_dinode(d);
  5862. + ii_write_unlock(d->d_inode);
  5863. + } else if (au_ftest_lock(flags, IR)) {
  5864. + au_dbg_verify_dinode(d);
  5865. + ii_read_unlock(d->d_inode);
  5866. + }
  5867. + }
  5868. + au_rw_read_unlock(&au_di(d)->di_rwsem);
  5869. +}
  5870. +
  5871. +void di_downgrade_lock(struct dentry *d, int flags)
  5872. +{
  5873. + if (d->d_inode && au_ftest_lock(flags, IR))
  5874. + ii_downgrade_lock(d->d_inode);
  5875. + au_rw_dgrade_lock(&au_di(d)->di_rwsem);
  5876. +}
  5877. +
  5878. +void di_write_lock(struct dentry *d, unsigned int lsc)
  5879. +{
  5880. + au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
  5881. + if (d->d_inode)
  5882. + do_ii_write_lock(d->d_inode, lsc);
  5883. +}
  5884. +
  5885. +void di_write_unlock(struct dentry *d)
  5886. +{
  5887. + au_dbg_verify_dinode(d);
  5888. + if (d->d_inode)
  5889. + ii_write_unlock(d->d_inode);
  5890. + au_rw_write_unlock(&au_di(d)->di_rwsem);
  5891. +}
  5892. +
  5893. +void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
  5894. +{
  5895. + AuDebugOn(d1 == d2
  5896. + || d1->d_inode == d2->d_inode
  5897. + || d1->d_sb != d2->d_sb);
  5898. +
  5899. + if (isdir && au_test_subdir(d1, d2)) {
  5900. + di_write_lock_child(d1);
  5901. + di_write_lock_child2(d2);
  5902. + } else {
  5903. + /* there should be no races */
  5904. + di_write_lock_child(d2);
  5905. + di_write_lock_child2(d1);
  5906. + }
  5907. +}
  5908. +
  5909. +void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
  5910. +{
  5911. + AuDebugOn(d1 == d2
  5912. + || d1->d_inode == d2->d_inode
  5913. + || d1->d_sb != d2->d_sb);
  5914. +
  5915. + if (isdir && au_test_subdir(d1, d2)) {
  5916. + di_write_lock_parent(d1);
  5917. + di_write_lock_parent2(d2);
  5918. + } else {
  5919. + /* there should be no races */
  5920. + di_write_lock_parent(d2);
  5921. + di_write_lock_parent2(d1);
  5922. + }
  5923. +}
  5924. +
  5925. +void di_write_unlock2(struct dentry *d1, struct dentry *d2)
  5926. +{
  5927. + di_write_unlock(d1);
  5928. + if (d1->d_inode == d2->d_inode)
  5929. + au_rw_write_unlock(&au_di(d2)->di_rwsem);
  5930. + else
  5931. + di_write_unlock(d2);
  5932. +}
  5933. +
  5934. +/* ---------------------------------------------------------------------- */
  5935. +
  5936. +struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
  5937. +{
  5938. + struct dentry *d;
  5939. +
  5940. + DiMustAnyLock(dentry);
  5941. +
  5942. + if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
  5943. + return NULL;
  5944. + AuDebugOn(bindex < 0);
  5945. + d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry;
  5946. + AuDebugOn(d && (atomic_read(&d->d_count) <= 0));
  5947. + return d;
  5948. +}
  5949. +
  5950. +aufs_bindex_t au_dbtail(struct dentry *dentry)
  5951. +{
  5952. + aufs_bindex_t bend, bwh;
  5953. +
  5954. + bend = au_dbend(dentry);
  5955. + if (0 <= bend) {
  5956. + bwh = au_dbwh(dentry);
  5957. + if (!bwh)
  5958. + return bwh;
  5959. + if (0 < bwh && bwh < bend)
  5960. + return bwh - 1;
  5961. + }
  5962. + return bend;
  5963. +}
  5964. +
  5965. +aufs_bindex_t au_dbtaildir(struct dentry *dentry)
  5966. +{
  5967. + aufs_bindex_t bend, bopq;
  5968. +
  5969. + bend = au_dbtail(dentry);
  5970. + if (0 <= bend) {
  5971. + bopq = au_dbdiropq(dentry);
  5972. + if (0 <= bopq && bopq < bend)
  5973. + bend = bopq;
  5974. + }
  5975. + return bend;
  5976. +}
  5977. +
  5978. +/* ---------------------------------------------------------------------- */
  5979. +
  5980. +void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
  5981. + struct dentry *h_dentry)
  5982. +{
  5983. + struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
  5984. + struct au_branch *br;
  5985. +
  5986. + DiMustWriteLock(dentry);
  5987. +
  5988. + au_hdput(hd);
  5989. + hd->hd_dentry = h_dentry;
  5990. + if (h_dentry) {
  5991. + br = au_sbr(dentry->d_sb, bindex);
  5992. + hd->hd_id = br->br_id;
  5993. + }
  5994. +}
  5995. +
  5996. +int au_dbrange_test(struct dentry *dentry)
  5997. +{
  5998. + int err;
  5999. + aufs_bindex_t bstart, bend;
  6000. +
  6001. + err = 0;
  6002. + bstart = au_dbstart(dentry);
  6003. + bend = au_dbend(dentry);
  6004. + if (bstart >= 0)
  6005. + AuDebugOn(bend < 0 && bstart > bend);
  6006. + else {
  6007. + err = -EIO;
  6008. + AuDebugOn(bend >= 0);
  6009. + }
  6010. +
  6011. + return err;
  6012. +}
  6013. +
  6014. +int au_digen_test(struct dentry *dentry, unsigned int sigen)
  6015. +{
  6016. + int err;
  6017. +
  6018. + err = 0;
  6019. + if (unlikely(au_digen(dentry) != sigen
  6020. + || au_iigen_test(dentry->d_inode, sigen)))
  6021. + err = -EIO;
  6022. +
  6023. + return err;
  6024. +}
  6025. +
  6026. +void au_update_digen(struct dentry *dentry)
  6027. +{
  6028. + atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
  6029. + /* smp_mb(); */ /* atomic_set */
  6030. +}
  6031. +
  6032. +void au_update_dbrange(struct dentry *dentry, int do_put_zero)
  6033. +{
  6034. + struct au_dinfo *dinfo;
  6035. + struct dentry *h_d;
  6036. + struct au_hdentry *hdp;
  6037. +
  6038. + DiMustWriteLock(dentry);
  6039. +
  6040. + dinfo = au_di(dentry);
  6041. + if (!dinfo || dinfo->di_bstart < 0)
  6042. + return;
  6043. +
  6044. + hdp = dinfo->di_hdentry;
  6045. + if (do_put_zero) {
  6046. + aufs_bindex_t bindex, bend;
  6047. +
  6048. + bend = dinfo->di_bend;
  6049. + for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) {
  6050. + h_d = hdp[0 + bindex].hd_dentry;
  6051. + if (h_d && !h_d->d_inode)
  6052. + au_set_h_dptr(dentry, bindex, NULL);
  6053. + }
  6054. + }
  6055. +
  6056. + dinfo->di_bstart = -1;
  6057. + while (++dinfo->di_bstart <= dinfo->di_bend)
  6058. + if (hdp[0 + dinfo->di_bstart].hd_dentry)
  6059. + break;
  6060. + if (dinfo->di_bstart > dinfo->di_bend) {
  6061. + dinfo->di_bstart = -1;
  6062. + dinfo->di_bend = -1;
  6063. + return;
  6064. + }
  6065. +
  6066. + dinfo->di_bend++;
  6067. + while (0 <= --dinfo->di_bend)
  6068. + if (hdp[0 + dinfo->di_bend].hd_dentry)
  6069. + break;
  6070. + AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0);
  6071. +}
  6072. +
  6073. +void au_update_dbstart(struct dentry *dentry)
  6074. +{
  6075. + aufs_bindex_t bindex, bend;
  6076. + struct dentry *h_dentry;
  6077. +
  6078. + bend = au_dbend(dentry);
  6079. + for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
  6080. + h_dentry = au_h_dptr(dentry, bindex);
  6081. + if (!h_dentry)
  6082. + continue;
  6083. + if (h_dentry->d_inode) {
  6084. + au_set_dbstart(dentry, bindex);
  6085. + return;
  6086. + }
  6087. + au_set_h_dptr(dentry, bindex, NULL);
  6088. + }
  6089. +}
  6090. +
  6091. +void au_update_dbend(struct dentry *dentry)
  6092. +{
  6093. + aufs_bindex_t bindex, bstart;
  6094. + struct dentry *h_dentry;
  6095. +
  6096. + bstart = au_dbstart(dentry);
  6097. + for (bindex = au_dbend(dentry); bindex >= bstart; bindex--) {
  6098. + h_dentry = au_h_dptr(dentry, bindex);
  6099. + if (!h_dentry)
  6100. + continue;
  6101. + if (h_dentry->d_inode) {
  6102. + au_set_dbend(dentry, bindex);
  6103. + return;
  6104. + }
  6105. + au_set_h_dptr(dentry, bindex, NULL);
  6106. + }
  6107. +}
  6108. +
  6109. +int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
  6110. +{
  6111. + aufs_bindex_t bindex, bend;
  6112. +
  6113. + bend = au_dbend(dentry);
  6114. + for (bindex = au_dbstart(dentry); bindex <= bend; bindex++)
  6115. + if (au_h_dptr(dentry, bindex) == h_dentry)
  6116. + return bindex;
  6117. + return -1;
  6118. +}
  6119. diff -Nur linux-2.6.37.orig/fs/aufs/dir.c linux-2.6.37/fs/aufs/dir.c
  6120. --- linux-2.6.37.orig/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
  6121. +++ linux-2.6.37/fs/aufs/dir.c 2011-01-11 20:15:11.000000000 +0100
  6122. @@ -0,0 +1,648 @@
  6123. +/*
  6124. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  6125. + *
  6126. + * This program, aufs is free software; you can redistribute it and/or modify
  6127. + * it under the terms of the GNU General Public License as published by
  6128. + * the Free Software Foundation; either version 2 of the License, or
  6129. + * (at your option) any later version.
  6130. + *
  6131. + * This program is distributed in the hope that it will be useful,
  6132. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  6133. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  6134. + * GNU General Public License for more details.
  6135. + *
  6136. + * You should have received a copy of the GNU General Public License
  6137. + * along with this program; if not, write to the Free Software
  6138. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  6139. + */
  6140. +
  6141. +/*
  6142. + * directory operations
  6143. + */
  6144. +
  6145. +#include <linux/file.h>
  6146. +#include <linux/fs_stack.h>
  6147. +#include "aufs.h"
  6148. +
  6149. +void au_add_nlink(struct inode *dir, struct inode *h_dir)
  6150. +{
  6151. + AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
  6152. +
  6153. + dir->i_nlink += h_dir->i_nlink - 2;
  6154. + if (h_dir->i_nlink < 2)
  6155. + dir->i_nlink += 2;
  6156. +}
  6157. +
  6158. +void au_sub_nlink(struct inode *dir, struct inode *h_dir)
  6159. +{
  6160. + AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
  6161. +
  6162. + dir->i_nlink -= h_dir->i_nlink - 2;
  6163. + if (h_dir->i_nlink < 2)
  6164. + dir->i_nlink -= 2;
  6165. +}
  6166. +
  6167. +loff_t au_dir_size(struct file *file, struct dentry *dentry)
  6168. +{
  6169. + loff_t sz;
  6170. + aufs_bindex_t bindex, bend;
  6171. + struct file *h_file;
  6172. + struct dentry *h_dentry;
  6173. +
  6174. + sz = 0;
  6175. + if (file) {
  6176. + AuDebugOn(!file->f_dentry);
  6177. + AuDebugOn(!file->f_dentry->d_inode);
  6178. + AuDebugOn(!S_ISDIR(file->f_dentry->d_inode->i_mode));
  6179. +
  6180. + bend = au_fbend_dir(file);
  6181. + for (bindex = au_fbstart(file);
  6182. + bindex <= bend && sz < KMALLOC_MAX_SIZE;
  6183. + bindex++) {
  6184. + h_file = au_hf_dir(file, bindex);
  6185. + if (h_file
  6186. + && h_file->f_dentry
  6187. + && h_file->f_dentry->d_inode)
  6188. + sz += i_size_read(h_file->f_dentry->d_inode);
  6189. + }
  6190. + } else {
  6191. + AuDebugOn(!dentry);
  6192. + AuDebugOn(!dentry->d_inode);
  6193. + AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
  6194. +
  6195. + bend = au_dbtaildir(dentry);
  6196. + for (bindex = au_dbstart(dentry);
  6197. + bindex <= bend && sz < KMALLOC_MAX_SIZE;
  6198. + bindex++) {
  6199. + h_dentry = au_h_dptr(dentry, bindex);
  6200. + if (h_dentry && h_dentry->d_inode)
  6201. + sz += i_size_read(h_dentry->d_inode);
  6202. + }
  6203. + }
  6204. + if (sz < KMALLOC_MAX_SIZE)
  6205. + sz = roundup_pow_of_two(sz);
  6206. + if (sz > KMALLOC_MAX_SIZE)
  6207. + sz = KMALLOC_MAX_SIZE;
  6208. + else if (sz < NAME_MAX) {
  6209. + BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX);
  6210. + sz = AUFS_RDBLK_DEF;
  6211. + }
  6212. + return sz;
  6213. +}
  6214. +
  6215. +/* ---------------------------------------------------------------------- */
  6216. +
  6217. +static int reopen_dir(struct file *file)
  6218. +{
  6219. + int err;
  6220. + unsigned int flags;
  6221. + aufs_bindex_t bindex, btail, bstart;
  6222. + struct dentry *dentry, *h_dentry;
  6223. + struct file *h_file;
  6224. +
  6225. + /* open all lower dirs */
  6226. + dentry = file->f_dentry;
  6227. + bstart = au_dbstart(dentry);
  6228. + for (bindex = au_fbstart(file); bindex < bstart; bindex++)
  6229. + au_set_h_fptr(file, bindex, NULL);
  6230. + au_set_fbstart(file, bstart);
  6231. +
  6232. + btail = au_dbtaildir(dentry);
  6233. + for (bindex = au_fbend_dir(file); btail < bindex; bindex--)
  6234. + au_set_h_fptr(file, bindex, NULL);
  6235. + au_set_fbend_dir(file, btail);
  6236. +
  6237. + flags = vfsub_file_flags(file);
  6238. + for (bindex = bstart; bindex <= btail; bindex++) {
  6239. + h_dentry = au_h_dptr(dentry, bindex);
  6240. + if (!h_dentry)
  6241. + continue;
  6242. + h_file = au_hf_dir(file, bindex);
  6243. + if (h_file)
  6244. + continue;
  6245. +
  6246. + h_file = au_h_open(dentry, bindex, flags, file);
  6247. + err = PTR_ERR(h_file);
  6248. + if (IS_ERR(h_file))
  6249. + goto out; /* close all? */
  6250. + au_set_h_fptr(file, bindex, h_file);
  6251. + }
  6252. + au_update_figen(file);
  6253. + /* todo: necessary? */
  6254. + /* file->f_ra = h_file->f_ra; */
  6255. + err = 0;
  6256. +
  6257. +out:
  6258. + return err;
  6259. +}
  6260. +
  6261. +static int do_open_dir(struct file *file, int flags)
  6262. +{
  6263. + int err;
  6264. + aufs_bindex_t bindex, btail;
  6265. + struct dentry *dentry, *h_dentry;
  6266. + struct file *h_file;
  6267. +
  6268. + FiMustWriteLock(file);
  6269. +
  6270. + dentry = file->f_dentry;
  6271. + err = au_alive_dir(dentry);
  6272. + if (unlikely(err))
  6273. + goto out;
  6274. +
  6275. + file->f_version = dentry->d_inode->i_version;
  6276. + bindex = au_dbstart(dentry);
  6277. + au_set_fbstart(file, bindex);
  6278. + btail = au_dbtaildir(dentry);
  6279. + au_set_fbend_dir(file, btail);
  6280. + for (; !err && bindex <= btail; bindex++) {
  6281. + h_dentry = au_h_dptr(dentry, bindex);
  6282. + if (!h_dentry)
  6283. + continue;
  6284. +
  6285. + h_file = au_h_open(dentry, bindex, flags, file);
  6286. + if (IS_ERR(h_file)) {
  6287. + err = PTR_ERR(h_file);
  6288. + break;
  6289. + }
  6290. + au_set_h_fptr(file, bindex, h_file);
  6291. + }
  6292. + au_update_figen(file);
  6293. + /* todo: necessary? */
  6294. + /* file->f_ra = h_file->f_ra; */
  6295. + if (!err)
  6296. + return 0; /* success */
  6297. +
  6298. + /* close all */
  6299. + for (bindex = au_fbstart(file); bindex <= btail; bindex++)
  6300. + au_set_h_fptr(file, bindex, NULL);
  6301. + au_set_fbstart(file, -1);
  6302. + au_set_fbend_dir(file, -1);
  6303. +
  6304. +out:
  6305. + return err;
  6306. +}
  6307. +
  6308. +static int aufs_open_dir(struct inode *inode __maybe_unused,
  6309. + struct file *file)
  6310. +{
  6311. + int err;
  6312. + struct super_block *sb;
  6313. + struct au_fidir *fidir;
  6314. +
  6315. + err = -ENOMEM;
  6316. + sb = file->f_dentry->d_sb;
  6317. + si_read_lock(sb, AuLock_FLUSH);
  6318. + fidir = au_fidir_alloc(sb);
  6319. + if (fidir) {
  6320. + err = au_do_open(file, do_open_dir, fidir);
  6321. + if (unlikely(err))
  6322. + kfree(fidir);
  6323. + }
  6324. + si_read_unlock(sb);
  6325. + return err;
  6326. +}
  6327. +
  6328. +static int aufs_release_dir(struct inode *inode __maybe_unused,
  6329. + struct file *file)
  6330. +{
  6331. + struct au_vdir *vdir_cache;
  6332. + struct super_block *sb;
  6333. + struct au_finfo *finfo;
  6334. + struct au_fidir *fidir;
  6335. + aufs_bindex_t bindex, bend;
  6336. +
  6337. + sb = file->f_dentry->d_sb;
  6338. + finfo = au_fi(file);
  6339. + fidir = finfo->fi_hdir;
  6340. + if (fidir) {
  6341. + /* remove me from sb->s_files */
  6342. + file_sb_list_del(file);
  6343. +
  6344. + vdir_cache = fidir->fd_vdir_cache; /* lock-free */
  6345. + if (vdir_cache)
  6346. + au_vdir_free(vdir_cache);
  6347. +
  6348. + bindex = finfo->fi_btop;
  6349. + if (bindex >= 0) {
  6350. + /*
  6351. + * calls fput() instead of filp_close(),
  6352. + * since no dnotify or lock for the lower file.
  6353. + */
  6354. + bend = fidir->fd_bbot;
  6355. + for (; bindex <= bend; bindex++)
  6356. + au_set_h_fptr(file, bindex, NULL);
  6357. + }
  6358. + kfree(fidir);
  6359. + finfo->fi_hdir = NULL;
  6360. + }
  6361. + au_finfo_fin(file);
  6362. + return 0;
  6363. +}
  6364. +
  6365. +/* ---------------------------------------------------------------------- */
  6366. +
  6367. +static int au_do_flush_dir(struct file *file, fl_owner_t id)
  6368. +{
  6369. + int err;
  6370. + aufs_bindex_t bindex, bend;
  6371. + struct file *h_file;
  6372. +
  6373. + err = 0;
  6374. + bend = au_fbend_dir(file);
  6375. + for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
  6376. + h_file = au_hf_dir(file, bindex);
  6377. + if (h_file)
  6378. + err = vfsub_flush(h_file, id);
  6379. + }
  6380. + return err;
  6381. +}
  6382. +
  6383. +static int aufs_flush_dir(struct file *file, fl_owner_t id)
  6384. +{
  6385. + return au_do_flush(file, id, au_do_flush_dir);
  6386. +}
  6387. +
  6388. +/* ---------------------------------------------------------------------- */
  6389. +
  6390. +static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
  6391. +{
  6392. + int err;
  6393. + aufs_bindex_t bend, bindex;
  6394. + struct inode *inode;
  6395. + struct super_block *sb;
  6396. +
  6397. + err = 0;
  6398. + sb = dentry->d_sb;
  6399. + inode = dentry->d_inode;
  6400. + IMustLock(inode);
  6401. + bend = au_dbend(dentry);
  6402. + for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) {
  6403. + struct path h_path;
  6404. + struct inode *h_inode;
  6405. +
  6406. + if (au_test_ro(sb, bindex, inode))
  6407. + continue;
  6408. + h_path.dentry = au_h_dptr(dentry, bindex);
  6409. + if (!h_path.dentry)
  6410. + continue;
  6411. + h_inode = h_path.dentry->d_inode;
  6412. + if (!h_inode)
  6413. + continue;
  6414. +
  6415. + /* no mnt_want_write() */
  6416. + /* cf. fs/nsfd/vfs.c and fs/nfsd/nfs4recover.c */
  6417. + /* todo: inotiry fired? */
  6418. + h_path.mnt = au_sbr_mnt(sb, bindex);
  6419. + mutex_lock(&h_inode->i_mutex);
  6420. + err = filemap_fdatawrite(h_inode->i_mapping);
  6421. + AuDebugOn(!h_inode->i_fop);
  6422. + if (!err && h_inode->i_fop->fsync)
  6423. + err = h_inode->i_fop->fsync(NULL, datasync);
  6424. + if (!err)
  6425. + err = filemap_fdatawrite(h_inode->i_mapping);
  6426. + if (!err)
  6427. + vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
  6428. + mutex_unlock(&h_inode->i_mutex);
  6429. + }
  6430. +
  6431. + return err;
  6432. +}
  6433. +
  6434. +static int au_do_fsync_dir(struct file *file, int datasync)
  6435. +{
  6436. + int err;
  6437. + aufs_bindex_t bend, bindex;
  6438. + struct file *h_file;
  6439. + struct super_block *sb;
  6440. + struct inode *inode;
  6441. + struct mutex *h_mtx;
  6442. +
  6443. + err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
  6444. + if (unlikely(err))
  6445. + goto out;
  6446. +
  6447. + sb = file->f_dentry->d_sb;
  6448. + inode = file->f_dentry->d_inode;
  6449. + bend = au_fbend_dir(file);
  6450. + for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
  6451. + h_file = au_hf_dir(file, bindex);
  6452. + if (!h_file || au_test_ro(sb, bindex, inode))
  6453. + continue;
  6454. +
  6455. + err = vfs_fsync(h_file, datasync);
  6456. + if (!err) {
  6457. + h_mtx = &h_file->f_dentry->d_inode->i_mutex;
  6458. + mutex_lock(h_mtx);
  6459. + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
  6460. + /*ignore*/
  6461. + mutex_unlock(h_mtx);
  6462. + }
  6463. + }
  6464. +
  6465. +out:
  6466. + return err;
  6467. +}
  6468. +
  6469. +/*
  6470. + * @file may be NULL
  6471. + */
  6472. +static int aufs_fsync_dir(struct file *file, int datasync)
  6473. +{
  6474. + int err;
  6475. + struct dentry *dentry;
  6476. + struct super_block *sb;
  6477. +
  6478. + dentry = file->f_dentry;
  6479. + IMustLock(dentry->d_inode);
  6480. +
  6481. + err = 0;
  6482. + sb = dentry->d_sb;
  6483. + si_noflush_read_lock(sb);
  6484. + if (file)
  6485. + err = au_do_fsync_dir(file, datasync);
  6486. + else {
  6487. + di_write_lock_child(dentry);
  6488. + err = au_do_fsync_dir_no_file(dentry, datasync);
  6489. + }
  6490. + au_cpup_attr_timesizes(dentry->d_inode);
  6491. + di_write_unlock(dentry);
  6492. + if (file)
  6493. + fi_write_unlock(file);
  6494. +
  6495. + si_read_unlock(sb);
  6496. + return err;
  6497. +}
  6498. +
  6499. +/* ---------------------------------------------------------------------- */
  6500. +
  6501. +static int aufs_readdir(struct file *file, void *dirent, filldir_t filldir)
  6502. +{
  6503. + int err;
  6504. + struct dentry *dentry;
  6505. + struct inode *inode;
  6506. + struct super_block *sb;
  6507. +
  6508. + dentry = file->f_dentry;
  6509. + inode = dentry->d_inode;
  6510. + IMustLock(inode);
  6511. +
  6512. + sb = dentry->d_sb;
  6513. + si_read_lock(sb, AuLock_FLUSH);
  6514. + err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
  6515. + if (unlikely(err))
  6516. + goto out;
  6517. + err = au_alive_dir(dentry);
  6518. + if (!err)
  6519. + err = au_vdir_init(file);
  6520. + di_downgrade_lock(dentry, AuLock_IR);
  6521. + if (unlikely(err))
  6522. + goto out_unlock;
  6523. +
  6524. + if (!au_test_nfsd()) {
  6525. + err = au_vdir_fill_de(file, dirent, filldir);
  6526. + fsstack_copy_attr_atime(inode,
  6527. + au_h_iptr(inode, au_ibstart(inode)));
  6528. + } else {
  6529. + /*
  6530. + * nfsd filldir may call lookup_one_len(), vfs_getattr(),
  6531. + * encode_fh() and others.
  6532. + */
  6533. + struct inode *h_inode = au_h_iptr(inode, au_ibstart(inode));
  6534. +
  6535. + di_read_unlock(dentry, AuLock_IR);
  6536. + si_read_unlock(sb);
  6537. + err = au_vdir_fill_de(file, dirent, filldir);
  6538. + fsstack_copy_attr_atime(inode, h_inode);
  6539. + fi_write_unlock(file);
  6540. +
  6541. + AuTraceErr(err);
  6542. + return err;
  6543. + }
  6544. +
  6545. +out_unlock:
  6546. + di_read_unlock(dentry, AuLock_IR);
  6547. + fi_write_unlock(file);
  6548. +out:
  6549. + si_read_unlock(sb);
  6550. + return err;
  6551. +}
  6552. +
  6553. +/* ---------------------------------------------------------------------- */
  6554. +
  6555. +#define AuTestEmpty_WHONLY 1
  6556. +#define AuTestEmpty_CALLED (1 << 1)
  6557. +#define AuTestEmpty_SHWH (1 << 2)
  6558. +#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
  6559. +#define au_fset_testempty(flags, name) \
  6560. + do { (flags) |= AuTestEmpty_##name; } while (0)
  6561. +#define au_fclr_testempty(flags, name) \
  6562. + do { (flags) &= ~AuTestEmpty_##name; } while (0)
  6563. +
  6564. +#ifndef CONFIG_AUFS_SHWH
  6565. +#undef AuTestEmpty_SHWH
  6566. +#define AuTestEmpty_SHWH 0
  6567. +#endif
  6568. +
  6569. +struct test_empty_arg {
  6570. + struct au_nhash *whlist;
  6571. + unsigned int flags;
  6572. + int err;
  6573. + aufs_bindex_t bindex;
  6574. +};
  6575. +
  6576. +static int test_empty_cb(void *__arg, const char *__name, int namelen,
  6577. + loff_t offset __maybe_unused, u64 ino,
  6578. + unsigned int d_type)
  6579. +{
  6580. + struct test_empty_arg *arg = __arg;
  6581. + char *name = (void *)__name;
  6582. +
  6583. + arg->err = 0;
  6584. + au_fset_testempty(arg->flags, CALLED);
  6585. + /* smp_mb(); */
  6586. + if (name[0] == '.'
  6587. + && (namelen == 1 || (name[1] == '.' && namelen == 2)))
  6588. + goto out; /* success */
  6589. +
  6590. + if (namelen <= AUFS_WH_PFX_LEN
  6591. + || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
  6592. + if (au_ftest_testempty(arg->flags, WHONLY)
  6593. + && !au_nhash_test_known_wh(arg->whlist, name, namelen))
  6594. + arg->err = -ENOTEMPTY;
  6595. + goto out;
  6596. + }
  6597. +
  6598. + name += AUFS_WH_PFX_LEN;
  6599. + namelen -= AUFS_WH_PFX_LEN;
  6600. + if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
  6601. + arg->err = au_nhash_append_wh
  6602. + (arg->whlist, name, namelen, ino, d_type, arg->bindex,
  6603. + au_ftest_testempty(arg->flags, SHWH));
  6604. +
  6605. +out:
  6606. + /* smp_mb(); */
  6607. + AuTraceErr(arg->err);
  6608. + return arg->err;
  6609. +}
  6610. +
  6611. +static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
  6612. +{
  6613. + int err;
  6614. + struct file *h_file;
  6615. +
  6616. + h_file = au_h_open(dentry, arg->bindex,
  6617. + O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
  6618. + /*file*/NULL);
  6619. + err = PTR_ERR(h_file);
  6620. + if (IS_ERR(h_file))
  6621. + goto out;
  6622. +
  6623. + err = 0;
  6624. + if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
  6625. + && !h_file->f_dentry->d_inode->i_nlink)
  6626. + goto out_put;
  6627. +
  6628. + do {
  6629. + arg->err = 0;
  6630. + au_fclr_testempty(arg->flags, CALLED);
  6631. + /* smp_mb(); */
  6632. + err = vfsub_readdir(h_file, test_empty_cb, arg);
  6633. + if (err >= 0)
  6634. + err = arg->err;
  6635. + } while (!err && au_ftest_testempty(arg->flags, CALLED));
  6636. +
  6637. +out_put:
  6638. + fput(h_file);
  6639. + au_sbr_put(dentry->d_sb, arg->bindex);
  6640. +out:
  6641. + return err;
  6642. +}
  6643. +
  6644. +struct do_test_empty_args {
  6645. + int *errp;
  6646. + struct dentry *dentry;
  6647. + struct test_empty_arg *arg;
  6648. +};
  6649. +
  6650. +static void call_do_test_empty(void *args)
  6651. +{
  6652. + struct do_test_empty_args *a = args;
  6653. + *a->errp = do_test_empty(a->dentry, a->arg);
  6654. +}
  6655. +
  6656. +static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
  6657. +{
  6658. + int err, wkq_err;
  6659. + struct dentry *h_dentry;
  6660. + struct inode *h_inode;
  6661. +
  6662. + h_dentry = au_h_dptr(dentry, arg->bindex);
  6663. + h_inode = h_dentry->d_inode;
  6664. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  6665. + err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
  6666. + mutex_unlock(&h_inode->i_mutex);
  6667. + if (!err)
  6668. + err = do_test_empty(dentry, arg);
  6669. + else {
  6670. + struct do_test_empty_args args = {
  6671. + .errp = &err,
  6672. + .dentry = dentry,
  6673. + .arg = arg
  6674. + };
  6675. + unsigned int flags = arg->flags;
  6676. +
  6677. + wkq_err = au_wkq_wait(call_do_test_empty, &args);
  6678. + if (unlikely(wkq_err))
  6679. + err = wkq_err;
  6680. + arg->flags = flags;
  6681. + }
  6682. +
  6683. + return err;
  6684. +}
  6685. +
  6686. +int au_test_empty_lower(struct dentry *dentry)
  6687. +{
  6688. + int err;
  6689. + unsigned int rdhash;
  6690. + aufs_bindex_t bindex, bstart, btail;
  6691. + struct au_nhash whlist;
  6692. + struct test_empty_arg arg;
  6693. +
  6694. + SiMustAnyLock(dentry->d_sb);
  6695. +
  6696. + rdhash = au_sbi(dentry->d_sb)->si_rdhash;
  6697. + if (!rdhash)
  6698. + rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry));
  6699. + err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
  6700. + if (unlikely(err))
  6701. + goto out;
  6702. +
  6703. + arg.flags = 0;
  6704. + arg.whlist = &whlist;
  6705. + bstart = au_dbstart(dentry);
  6706. + if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
  6707. + au_fset_testempty(arg.flags, SHWH);
  6708. + arg.bindex = bstart;
  6709. + err = do_test_empty(dentry, &arg);
  6710. + if (unlikely(err))
  6711. + goto out_whlist;
  6712. +
  6713. + au_fset_testempty(arg.flags, WHONLY);
  6714. + btail = au_dbtaildir(dentry);
  6715. + for (bindex = bstart + 1; !err && bindex <= btail; bindex++) {
  6716. + struct dentry *h_dentry;
  6717. +
  6718. + h_dentry = au_h_dptr(dentry, bindex);
  6719. + if (h_dentry && h_dentry->d_inode) {
  6720. + arg.bindex = bindex;
  6721. + err = do_test_empty(dentry, &arg);
  6722. + }
  6723. + }
  6724. +
  6725. +out_whlist:
  6726. + au_nhash_wh_free(&whlist);
  6727. +out:
  6728. + return err;
  6729. +}
  6730. +
  6731. +int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
  6732. +{
  6733. + int err;
  6734. + struct test_empty_arg arg;
  6735. + aufs_bindex_t bindex, btail;
  6736. +
  6737. + err = 0;
  6738. + arg.whlist = whlist;
  6739. + arg.flags = AuTestEmpty_WHONLY;
  6740. + if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
  6741. + au_fset_testempty(arg.flags, SHWH);
  6742. + btail = au_dbtaildir(dentry);
  6743. + for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) {
  6744. + struct dentry *h_dentry;
  6745. +
  6746. + h_dentry = au_h_dptr(dentry, bindex);
  6747. + if (h_dentry && h_dentry->d_inode) {
  6748. + arg.bindex = bindex;
  6749. + err = sio_test_empty(dentry, &arg);
  6750. + }
  6751. + }
  6752. +
  6753. + return err;
  6754. +}
  6755. +
  6756. +/* ---------------------------------------------------------------------- */
  6757. +
  6758. +const struct file_operations aufs_dir_fop = {
  6759. + .owner = THIS_MODULE,
  6760. + .read = generic_read_dir,
  6761. + .readdir = aufs_readdir,
  6762. + .unlocked_ioctl = aufs_ioctl_dir,
  6763. +#ifdef CONFIG_COMPAT
  6764. + .compat_ioctl = aufs_compat_ioctl_dir,
  6765. +#endif
  6766. + .open = aufs_open_dir,
  6767. + .release = aufs_release_dir,
  6768. + .flush = aufs_flush_dir,
  6769. + .fsync = aufs_fsync_dir
  6770. +};
  6771. diff -Nur linux-2.6.37.orig/fs/aufs/dir.h linux-2.6.37/fs/aufs/dir.h
  6772. --- linux-2.6.37.orig/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100
  6773. +++ linux-2.6.37/fs/aufs/dir.h 2011-01-11 20:15:11.000000000 +0100
  6774. @@ -0,0 +1,138 @@
  6775. +/*
  6776. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  6777. + *
  6778. + * This program, aufs is free software; you can redistribute it and/or modify
  6779. + * it under the terms of the GNU General Public License as published by
  6780. + * the Free Software Foundation; either version 2 of the License, or
  6781. + * (at your option) any later version.
  6782. + *
  6783. + * This program is distributed in the hope that it will be useful,
  6784. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  6785. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  6786. + * GNU General Public License for more details.
  6787. + *
  6788. + * You should have received a copy of the GNU General Public License
  6789. + * along with this program; if not, write to the Free Software
  6790. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  6791. + */
  6792. +
  6793. +/*
  6794. + * directory operations
  6795. + */
  6796. +
  6797. +#ifndef __AUFS_DIR_H__
  6798. +#define __AUFS_DIR_H__
  6799. +
  6800. +#ifdef __KERNEL__
  6801. +
  6802. +#include <linux/fs.h>
  6803. +#include <linux/aufs_type.h>
  6804. +
  6805. +/* ---------------------------------------------------------------------- */
  6806. +
  6807. +/* need to be faster and smaller */
  6808. +
  6809. +struct au_nhash {
  6810. + unsigned int nh_num;
  6811. + struct hlist_head *nh_head;
  6812. +};
  6813. +
  6814. +struct au_vdir_destr {
  6815. + unsigned char len;
  6816. + unsigned char name[0];
  6817. +} __packed;
  6818. +
  6819. +struct au_vdir_dehstr {
  6820. + struct hlist_node hash;
  6821. + struct au_vdir_destr *str;
  6822. +} ____cacheline_aligned_in_smp;
  6823. +
  6824. +struct au_vdir_de {
  6825. + ino_t de_ino;
  6826. + unsigned char de_type;
  6827. + /* caution: packed */
  6828. + struct au_vdir_destr de_str;
  6829. +} __packed;
  6830. +
  6831. +struct au_vdir_wh {
  6832. + struct hlist_node wh_hash;
  6833. +#ifdef CONFIG_AUFS_SHWH
  6834. + ino_t wh_ino;
  6835. + aufs_bindex_t wh_bindex;
  6836. + unsigned char wh_type;
  6837. +#else
  6838. + aufs_bindex_t wh_bindex;
  6839. +#endif
  6840. + /* caution: packed */
  6841. + struct au_vdir_destr wh_str;
  6842. +} __packed;
  6843. +
  6844. +union au_vdir_deblk_p {
  6845. + unsigned char *deblk;
  6846. + struct au_vdir_de *de;
  6847. +};
  6848. +
  6849. +struct au_vdir {
  6850. + unsigned char **vd_deblk;
  6851. + unsigned long vd_nblk;
  6852. + struct {
  6853. + unsigned long ul;
  6854. + union au_vdir_deblk_p p;
  6855. + } vd_last;
  6856. +
  6857. + unsigned long vd_version;
  6858. + unsigned int vd_deblk_sz;
  6859. + unsigned long vd_jiffy;
  6860. +} ____cacheline_aligned_in_smp;
  6861. +
  6862. +/* ---------------------------------------------------------------------- */
  6863. +
  6864. +/* dir.c */
  6865. +extern const struct file_operations aufs_dir_fop;
  6866. +void au_add_nlink(struct inode *dir, struct inode *h_dir);
  6867. +void au_sub_nlink(struct inode *dir, struct inode *h_dir);
  6868. +loff_t au_dir_size(struct file *file, struct dentry *dentry);
  6869. +int au_test_empty_lower(struct dentry *dentry);
  6870. +int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
  6871. +
  6872. +/* vdir.c */
  6873. +unsigned int au_rdhash_est(loff_t sz);
  6874. +int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
  6875. +void au_nhash_wh_free(struct au_nhash *whlist);
  6876. +int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
  6877. + int limit);
  6878. +int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
  6879. +int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
  6880. + unsigned int d_type, aufs_bindex_t bindex,
  6881. + unsigned char shwh);
  6882. +void au_vdir_free(struct au_vdir *vdir);
  6883. +int au_vdir_init(struct file *file);
  6884. +int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir);
  6885. +
  6886. +/* ioctl.c */
  6887. +long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
  6888. +
  6889. +#ifdef CONFIG_AUFS_RDU
  6890. +/* rdu.c */
  6891. +long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
  6892. +#ifdef CONFIG_COMPAT
  6893. +long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
  6894. + unsigned long arg);
  6895. +#endif
  6896. +#else
  6897. +static inline long au_rdu_ioctl(struct file *file, unsigned int cmd,
  6898. + unsigned long arg)
  6899. +{
  6900. + return -EINVAL;
  6901. +}
  6902. +#ifdef CONFIG_COMPAT
  6903. +static inline long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
  6904. + unsigned long arg)
  6905. +{
  6906. + return -EINVAL;
  6907. +}
  6908. +#endif
  6909. +#endif
  6910. +
  6911. +#endif /* __KERNEL__ */
  6912. +#endif /* __AUFS_DIR_H__ */
  6913. diff -Nur linux-2.6.37.orig/fs/aufs/dynop.c linux-2.6.37/fs/aufs/dynop.c
  6914. --- linux-2.6.37.orig/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100
  6915. +++ linux-2.6.37/fs/aufs/dynop.c 2011-01-11 20:15:11.000000000 +0100
  6916. @@ -0,0 +1,425 @@
  6917. +/*
  6918. + * Copyright (C) 2010-2011 Junjiro R. Okajima
  6919. + *
  6920. + * This program, aufs is free software; you can redistribute it and/or modify
  6921. + * it under the terms of the GNU General Public License as published by
  6922. + * the Free Software Foundation; either version 2 of the License, or
  6923. + * (at your option) any later version.
  6924. + *
  6925. + * This program is distributed in the hope that it will be useful,
  6926. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  6927. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  6928. + * GNU General Public License for more details.
  6929. + *
  6930. + * You should have received a copy of the GNU General Public License
  6931. + * along with this program; if not, write to the Free Software
  6932. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  6933. + */
  6934. +
  6935. +/*
  6936. + * dynamically customizable operations for regular files
  6937. + */
  6938. +
  6939. +#include "aufs.h"
  6940. +
  6941. +#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop)
  6942. +
  6943. +/*
  6944. + * How large will these lists be?
  6945. + * Usually just a few elements, 20-30 at most for each, I guess.
  6946. + */
  6947. +static struct au_splhead dynop[AuDyLast];
  6948. +
  6949. +static struct au_dykey *dy_gfind_get(struct au_splhead *spl, const void *h_op)
  6950. +{
  6951. + struct au_dykey *key, *tmp;
  6952. + struct list_head *head;
  6953. +
  6954. + key = NULL;
  6955. + head = &spl->head;
  6956. + rcu_read_lock();
  6957. + list_for_each_entry_rcu(tmp, head, dk_list)
  6958. + if (tmp->dk_op.dy_hop == h_op) {
  6959. + key = tmp;
  6960. + kref_get(&key->dk_kref);
  6961. + break;
  6962. + }
  6963. + rcu_read_unlock();
  6964. +
  6965. + return key;
  6966. +}
  6967. +
  6968. +static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
  6969. +{
  6970. + struct au_dykey **k, *found;
  6971. + const void *h_op = key->dk_op.dy_hop;
  6972. + int i;
  6973. +
  6974. + found = NULL;
  6975. + k = br->br_dykey;
  6976. + for (i = 0; i < AuBrDynOp; i++)
  6977. + if (k[i]) {
  6978. + if (k[i]->dk_op.dy_hop == h_op) {
  6979. + found = k[i];
  6980. + break;
  6981. + }
  6982. + } else
  6983. + break;
  6984. + if (!found) {
  6985. + spin_lock(&br->br_dykey_lock);
  6986. + for (; i < AuBrDynOp; i++)
  6987. + if (k[i]) {
  6988. + if (k[i]->dk_op.dy_hop == h_op) {
  6989. + found = k[i];
  6990. + break;
  6991. + }
  6992. + } else {
  6993. + k[i] = key;
  6994. + break;
  6995. + }
  6996. + spin_unlock(&br->br_dykey_lock);
  6997. + BUG_ON(i == AuBrDynOp); /* expand the array */
  6998. + }
  6999. +
  7000. + return found;
  7001. +}
  7002. +
  7003. +/* kref_get() if @key is already added */
  7004. +static struct au_dykey *dy_gadd(struct au_splhead *spl, struct au_dykey *key)
  7005. +{
  7006. + struct au_dykey *tmp, *found;
  7007. + struct list_head *head;
  7008. + const void *h_op = key->dk_op.dy_hop;
  7009. +
  7010. + found = NULL;
  7011. + head = &spl->head;
  7012. + spin_lock(&spl->spin);
  7013. + list_for_each_entry(tmp, head, dk_list)
  7014. + if (tmp->dk_op.dy_hop == h_op) {
  7015. + kref_get(&tmp->dk_kref);
  7016. + found = tmp;
  7017. + break;
  7018. + }
  7019. + if (!found)
  7020. + list_add_rcu(&key->dk_list, head);
  7021. + spin_unlock(&spl->spin);
  7022. +
  7023. + if (!found)
  7024. + DyPrSym(key);
  7025. + return found;
  7026. +}
  7027. +
  7028. +static void dy_free_rcu(struct rcu_head *rcu)
  7029. +{
  7030. + struct au_dykey *key;
  7031. +
  7032. + key = container_of(rcu, struct au_dykey, dk_rcu);
  7033. + DyPrSym(key);
  7034. + kfree(key);
  7035. +}
  7036. +
  7037. +static void dy_free(struct kref *kref)
  7038. +{
  7039. + struct au_dykey *key;
  7040. + struct au_splhead *spl;
  7041. +
  7042. + key = container_of(kref, struct au_dykey, dk_kref);
  7043. + spl = dynop + key->dk_op.dy_type;
  7044. + au_spl_del_rcu(&key->dk_list, spl);
  7045. + call_rcu(&key->dk_rcu, dy_free_rcu);
  7046. +}
  7047. +
  7048. +void au_dy_put(struct au_dykey *key)
  7049. +{
  7050. + kref_put(&key->dk_kref, dy_free);
  7051. +}
  7052. +
  7053. +/* ---------------------------------------------------------------------- */
  7054. +
  7055. +#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *))
  7056. +
  7057. +#ifdef CONFIG_AUFS_DEBUG
  7058. +#define DyDbgDeclare(cnt) unsigned int cnt = 0
  7059. +#define DyDbgInc(cnt) do { cnt++; } while (0)
  7060. +#else
  7061. +#define DyDbgDeclare(cnt) do {} while (0)
  7062. +#define DyDbgInc(cnt) do {} while (0)
  7063. +#endif
  7064. +
  7065. +#define DySet(func, dst, src, h_op, h_sb) do { \
  7066. + DyDbgInc(cnt); \
  7067. + if (h_op->func) { \
  7068. + if (src.func) \
  7069. + dst.func = src.func; \
  7070. + else \
  7071. + AuDbg("%s %s\n", au_sbtype(h_sb), #func); \
  7072. + } \
  7073. +} while (0)
  7074. +
  7075. +#define DySetForce(func, dst, src) do { \
  7076. + AuDebugOn(!src.func); \
  7077. + DyDbgInc(cnt); \
  7078. + dst.func = src.func; \
  7079. +} while (0)
  7080. +
  7081. +#define DySetAop(func) \
  7082. + DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
  7083. +#define DySetAopForce(func) \
  7084. + DySetForce(func, dyaop->da_op, aufs_aop)
  7085. +
  7086. +static void dy_aop(struct au_dykey *key, const void *h_op,
  7087. + struct super_block *h_sb __maybe_unused)
  7088. +{
  7089. + struct au_dyaop *dyaop = (void *)key;
  7090. + const struct address_space_operations *h_aop = h_op;
  7091. + DyDbgDeclare(cnt);
  7092. +
  7093. + AuDbg("%s\n", au_sbtype(h_sb));
  7094. +
  7095. + DySetAop(writepage);
  7096. + DySetAopForce(readpage); /* force */
  7097. + DySetAop(sync_page);
  7098. + DySetAop(writepages);
  7099. + DySetAop(set_page_dirty);
  7100. + DySetAop(readpages);
  7101. + DySetAop(write_begin);
  7102. + DySetAop(write_end);
  7103. + DySetAop(bmap);
  7104. + DySetAop(invalidatepage);
  7105. + DySetAop(releasepage);
  7106. + /* these two will be changed according to an aufs mount option */
  7107. + DySetAop(direct_IO);
  7108. + DySetAop(get_xip_mem);
  7109. + DySetAop(migratepage);
  7110. + DySetAop(launder_page);
  7111. + DySetAop(is_partially_uptodate);
  7112. + DySetAop(error_remove_page);
  7113. +
  7114. + DyDbgSize(cnt, *h_aop);
  7115. + dyaop->da_get_xip_mem = h_aop->get_xip_mem;
  7116. +}
  7117. +
  7118. +#define DySetVmop(func) \
  7119. + DySet(func, dyvmop->dv_op, aufs_vm_ops, h_vmop, h_sb)
  7120. +#define DySetVmopForce(func) \
  7121. + DySetForce(func, dyvmop->dv_op, aufs_vm_ops)
  7122. +
  7123. +static void dy_vmop(struct au_dykey *key, const void *h_op,
  7124. + struct super_block *h_sb __maybe_unused)
  7125. +{
  7126. + struct au_dyvmop *dyvmop = (void *)key;
  7127. + const struct vm_operations_struct *h_vmop = h_op;
  7128. + DyDbgDeclare(cnt);
  7129. +
  7130. + AuDbg("%s\n", au_sbtype(h_sb));
  7131. +
  7132. + DySetVmop(open);
  7133. + DySetVmop(close);
  7134. + DySetVmop(fault);
  7135. + DySetVmop(page_mkwrite);
  7136. + DySetVmop(access);
  7137. +#ifdef CONFIG_NUMA
  7138. + DySetVmop(set_policy);
  7139. + DySetVmop(get_policy);
  7140. + DySetVmop(migrate);
  7141. +#endif
  7142. +
  7143. + DyDbgSize(cnt, *h_vmop);
  7144. +}
  7145. +
  7146. +/* ---------------------------------------------------------------------- */
  7147. +
  7148. +static void dy_bug(struct kref *kref)
  7149. +{
  7150. + BUG();
  7151. +}
  7152. +
  7153. +static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
  7154. +{
  7155. + struct au_dykey *key, *old;
  7156. + struct au_splhead *spl;
  7157. + struct op {
  7158. + unsigned int sz;
  7159. + void (*set)(struct au_dykey *key, const void *h_op,
  7160. + struct super_block *h_sb __maybe_unused);
  7161. + };
  7162. + static const struct op a[] = {
  7163. + [AuDy_AOP] = {
  7164. + .sz = sizeof(struct au_dyaop),
  7165. + .set = dy_aop
  7166. + },
  7167. + [AuDy_VMOP] = {
  7168. + .sz = sizeof(struct au_dyvmop),
  7169. + .set = dy_vmop
  7170. + }
  7171. + };
  7172. + const struct op *p;
  7173. +
  7174. + spl = dynop + op->dy_type;
  7175. + key = dy_gfind_get(spl, op->dy_hop);
  7176. + if (key)
  7177. + goto out_add; /* success */
  7178. +
  7179. + p = a + op->dy_type;
  7180. + key = kzalloc(p->sz, GFP_NOFS);
  7181. + if (unlikely(!key)) {
  7182. + key = ERR_PTR(-ENOMEM);
  7183. + goto out;
  7184. + }
  7185. +
  7186. + key->dk_op.dy_hop = op->dy_hop;
  7187. + kref_init(&key->dk_kref);
  7188. + p->set(key, op->dy_hop, br->br_mnt->mnt_sb);
  7189. + old = dy_gadd(spl, key);
  7190. + if (old) {
  7191. + kfree(key);
  7192. + key = old;
  7193. + }
  7194. +
  7195. +out_add:
  7196. + old = dy_bradd(br, key);
  7197. + if (old)
  7198. + /* its ref-count should never be zero here */
  7199. + kref_put(&key->dk_kref, dy_bug);
  7200. +out:
  7201. + return key;
  7202. +}
  7203. +
  7204. +/* ---------------------------------------------------------------------- */
  7205. +/*
  7206. + * Aufs prohibits O_DIRECT by defaut even if the branch supports it.
  7207. + * This behaviour is neccessary to return an error from open(O_DIRECT) instead
  7208. + * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
  7209. + * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
  7210. + * See the aufs manual in detail.
  7211. + *
  7212. + * To keep this behaviour, aufs has to set NULL to ->get_xip_mem too, and the
  7213. + * performance of fadvise() and madvise() may be affected.
  7214. + */
  7215. +static void dy_adx(struct au_dyaop *dyaop, int do_dx)
  7216. +{
  7217. + if (!do_dx) {
  7218. + dyaop->da_op.direct_IO = NULL;
  7219. + dyaop->da_op.get_xip_mem = NULL;
  7220. + } else {
  7221. + dyaop->da_op.direct_IO = aufs_aop.direct_IO;
  7222. + dyaop->da_op.get_xip_mem = aufs_aop.get_xip_mem;
  7223. + if (!dyaop->da_get_xip_mem)
  7224. + dyaop->da_op.get_xip_mem = NULL;
  7225. + }
  7226. +}
  7227. +
  7228. +static struct au_dyaop *dy_aget(struct au_branch *br,
  7229. + const struct address_space_operations *h_aop,
  7230. + int do_dx)
  7231. +{
  7232. + struct au_dyaop *dyaop;
  7233. + struct au_dynop op;
  7234. +
  7235. + op.dy_type = AuDy_AOP;
  7236. + op.dy_haop = h_aop;
  7237. + dyaop = (void *)dy_get(&op, br);
  7238. + if (IS_ERR(dyaop))
  7239. + goto out;
  7240. + dy_adx(dyaop, do_dx);
  7241. +
  7242. +out:
  7243. + return dyaop;
  7244. +}
  7245. +
  7246. +int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
  7247. + struct inode *h_inode)
  7248. +{
  7249. + int err, do_dx;
  7250. + struct super_block *sb;
  7251. + struct au_branch *br;
  7252. + struct au_dyaop *dyaop;
  7253. +
  7254. + AuDebugOn(!S_ISREG(h_inode->i_mode));
  7255. + IiMustWriteLock(inode);
  7256. +
  7257. + sb = inode->i_sb;
  7258. + br = au_sbr(sb, bindex);
  7259. + do_dx = !!au_opt_test(au_mntflags(sb), DIO);
  7260. + dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
  7261. + err = PTR_ERR(dyaop);
  7262. + if (IS_ERR(dyaop))
  7263. + /* unnecessary to call dy_fput() */
  7264. + goto out;
  7265. +
  7266. + err = 0;
  7267. + inode->i_mapping->a_ops = &dyaop->da_op;
  7268. +
  7269. +out:
  7270. + return err;
  7271. +}
  7272. +
  7273. +/*
  7274. + * Is it safe to replace a_ops during the inode/file is in operation?
  7275. + * Yes, I hope so.
  7276. + */
  7277. +int au_dy_irefresh(struct inode *inode)
  7278. +{
  7279. + int err;
  7280. + aufs_bindex_t bstart;
  7281. + struct inode *h_inode;
  7282. +
  7283. + err = 0;
  7284. + if (S_ISREG(inode->i_mode)) {
  7285. + bstart = au_ibstart(inode);
  7286. + h_inode = au_h_iptr(inode, bstart);
  7287. + err = au_dy_iaop(inode, bstart, h_inode);
  7288. + }
  7289. + return err;
  7290. +}
  7291. +
  7292. +void au_dy_arefresh(int do_dx)
  7293. +{
  7294. + struct au_splhead *spl;
  7295. + struct list_head *head;
  7296. + struct au_dykey *key;
  7297. +
  7298. + spl = dynop + AuDy_AOP;
  7299. + head = &spl->head;
  7300. + spin_lock(&spl->spin);
  7301. + list_for_each_entry(key, head, dk_list)
  7302. + dy_adx((void *)key, do_dx);
  7303. + spin_unlock(&spl->spin);
  7304. +}
  7305. +
  7306. +const struct vm_operations_struct *
  7307. +au_dy_vmop(struct file *file, struct au_branch *br,
  7308. + const struct vm_operations_struct *h_vmop)
  7309. +{
  7310. + struct au_dyvmop *dyvmop;
  7311. + struct au_dynop op;
  7312. +
  7313. + op.dy_type = AuDy_VMOP;
  7314. + op.dy_hvmop = h_vmop;
  7315. + dyvmop = (void *)dy_get(&op, br);
  7316. + if (IS_ERR(dyvmop))
  7317. + return (void *)dyvmop;
  7318. + return &dyvmop->dv_op;
  7319. +}
  7320. +
  7321. +/* ---------------------------------------------------------------------- */
  7322. +
  7323. +void __init au_dy_init(void)
  7324. +{
  7325. + int i;
  7326. +
  7327. + /* make sure that 'struct au_dykey *' can be any type */
  7328. + BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
  7329. + BUILD_BUG_ON(offsetof(struct au_dyvmop, dv_key));
  7330. +
  7331. + for (i = 0; i < AuDyLast; i++)
  7332. + au_spl_init(dynop + i);
  7333. +}
  7334. +
  7335. +void au_dy_fin(void)
  7336. +{
  7337. + int i;
  7338. +
  7339. + for (i = 0; i < AuDyLast; i++)
  7340. + WARN_ON(!list_empty(&dynop[i].head));
  7341. +}
  7342. diff -Nur linux-2.6.37.orig/fs/aufs/dynop.h linux-2.6.37/fs/aufs/dynop.h
  7343. --- linux-2.6.37.orig/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100
  7344. +++ linux-2.6.37/fs/aufs/dynop.h 2011-01-11 20:15:11.000000000 +0100
  7345. @@ -0,0 +1,89 @@
  7346. +/*
  7347. + * Copyright (C) 2010-2011 Junjiro R. Okajima
  7348. + *
  7349. + * This program, aufs is free software; you can redistribute it and/or modify
  7350. + * it under the terms of the GNU General Public License as published by
  7351. + * the Free Software Foundation; either version 2 of the License, or
  7352. + * (at your option) any later version.
  7353. + *
  7354. + * This program is distributed in the hope that it will be useful,
  7355. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7356. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  7357. + * GNU General Public License for more details.
  7358. + *
  7359. + * You should have received a copy of the GNU General Public License
  7360. + * along with this program; if not, write to the Free Software
  7361. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  7362. + */
  7363. +
  7364. +/*
  7365. + * dynamically customizable operations (for regular files only)
  7366. + */
  7367. +
  7368. +#ifndef __AUFS_DYNOP_H__
  7369. +#define __AUFS_DYNOP_H__
  7370. +
  7371. +#ifdef __KERNEL__
  7372. +
  7373. +#include <linux/fs.h>
  7374. +#include <linux/mm.h>
  7375. +#include <linux/rcupdate.h>
  7376. +#include <linux/aufs_type.h>
  7377. +#include "inode.h"
  7378. +
  7379. +enum {AuDy_AOP, AuDy_VMOP, AuDyLast};
  7380. +
  7381. +struct au_dynop {
  7382. + int dy_type;
  7383. + union {
  7384. + const void *dy_hop;
  7385. + const struct address_space_operations *dy_haop;
  7386. + const struct vm_operations_struct *dy_hvmop;
  7387. + };
  7388. +};
  7389. +
  7390. +struct au_dykey {
  7391. + union {
  7392. + struct list_head dk_list;
  7393. + struct rcu_head dk_rcu;
  7394. + };
  7395. + struct au_dynop dk_op;
  7396. +
  7397. + /*
  7398. + * during I am in the branch local array, kref is gotten. when the
  7399. + * branch is removed, kref is put.
  7400. + */
  7401. + struct kref dk_kref;
  7402. +};
  7403. +
  7404. +/* stop unioning since their sizes are very different from each other */
  7405. +struct au_dyaop {
  7406. + struct au_dykey da_key;
  7407. + struct address_space_operations da_op; /* not const */
  7408. + int (*da_get_xip_mem)(struct address_space *, pgoff_t, int,
  7409. + void **, unsigned long *);
  7410. +};
  7411. +
  7412. +struct au_dyvmop {
  7413. + struct au_dykey dv_key;
  7414. + struct vm_operations_struct dv_op; /* not const */
  7415. +};
  7416. +
  7417. +/* ---------------------------------------------------------------------- */
  7418. +
  7419. +/* dynop.c */
  7420. +struct au_branch;
  7421. +void au_dy_put(struct au_dykey *key);
  7422. +int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
  7423. + struct inode *h_inode);
  7424. +int au_dy_irefresh(struct inode *inode);
  7425. +void au_dy_arefresh(int do_dio);
  7426. +const struct vm_operations_struct *
  7427. +au_dy_vmop(struct file *file, struct au_branch *br,
  7428. + const struct vm_operations_struct *h_vmop);
  7429. +
  7430. +void __init au_dy_init(void);
  7431. +void au_dy_fin(void);
  7432. +
  7433. +#endif /* __KERNEL__ */
  7434. +#endif /* __AUFS_DYNOP_H__ */
  7435. diff -Nur linux-2.6.37.orig/fs/aufs/export.c linux-2.6.37/fs/aufs/export.c
  7436. --- linux-2.6.37.orig/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
  7437. +++ linux-2.6.37/fs/aufs/export.c 2011-01-11 20:15:11.000000000 +0100
  7438. @@ -0,0 +1,798 @@
  7439. +/*
  7440. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  7441. + *
  7442. + * This program, aufs is free software; you can redistribute it and/or modify
  7443. + * it under the terms of the GNU General Public License as published by
  7444. + * the Free Software Foundation; either version 2 of the License, or
  7445. + * (at your option) any later version.
  7446. + *
  7447. + * This program is distributed in the hope that it will be useful,
  7448. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7449. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  7450. + * GNU General Public License for more details.
  7451. + *
  7452. + * You should have received a copy of the GNU General Public License
  7453. + * along with this program; if not, write to the Free Software
  7454. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  7455. + */
  7456. +
  7457. +/*
  7458. + * export via nfs
  7459. + */
  7460. +
  7461. +#include <linux/exportfs.h>
  7462. +#include <linux/file.h>
  7463. +#include <linux/mnt_namespace.h>
  7464. +#include <linux/namei.h>
  7465. +#include <linux/nsproxy.h>
  7466. +#include <linux/random.h>
  7467. +#include <linux/writeback.h>
  7468. +#include "aufs.h"
  7469. +
  7470. +union conv {
  7471. +#ifdef CONFIG_AUFS_INO_T_64
  7472. + __u32 a[2];
  7473. +#else
  7474. + __u32 a[1];
  7475. +#endif
  7476. + ino_t ino;
  7477. +};
  7478. +
  7479. +static ino_t decode_ino(__u32 *a)
  7480. +{
  7481. + union conv u;
  7482. +
  7483. + BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
  7484. + u.a[0] = a[0];
  7485. +#ifdef CONFIG_AUFS_INO_T_64
  7486. + u.a[1] = a[1];
  7487. +#endif
  7488. + return u.ino;
  7489. +}
  7490. +
  7491. +static void encode_ino(__u32 *a, ino_t ino)
  7492. +{
  7493. + union conv u;
  7494. +
  7495. + u.ino = ino;
  7496. + a[0] = u.a[0];
  7497. +#ifdef CONFIG_AUFS_INO_T_64
  7498. + a[1] = u.a[1];
  7499. +#endif
  7500. +}
  7501. +
  7502. +/* NFS file handle */
  7503. +enum {
  7504. + Fh_br_id,
  7505. + Fh_sigen,
  7506. +#ifdef CONFIG_AUFS_INO_T_64
  7507. + /* support 64bit inode number */
  7508. + Fh_ino1,
  7509. + Fh_ino2,
  7510. + Fh_dir_ino1,
  7511. + Fh_dir_ino2,
  7512. +#else
  7513. + Fh_ino1,
  7514. + Fh_dir_ino1,
  7515. +#endif
  7516. + Fh_igen,
  7517. + Fh_h_type,
  7518. + Fh_tail,
  7519. +
  7520. + Fh_ino = Fh_ino1,
  7521. + Fh_dir_ino = Fh_dir_ino1
  7522. +};
  7523. +
  7524. +static int au_test_anon(struct dentry *dentry)
  7525. +{
  7526. + return !!(dentry->d_flags & DCACHE_DISCONNECTED);
  7527. +}
  7528. +
  7529. +/* ---------------------------------------------------------------------- */
  7530. +/* inode generation external table */
  7531. +
  7532. +void au_xigen_inc(struct inode *inode)
  7533. +{
  7534. + loff_t pos;
  7535. + ssize_t sz;
  7536. + __u32 igen;
  7537. + struct super_block *sb;
  7538. + struct au_sbinfo *sbinfo;
  7539. +
  7540. + sb = inode->i_sb;
  7541. + AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
  7542. +
  7543. + sbinfo = au_sbi(sb);
  7544. + pos = inode->i_ino;
  7545. + pos *= sizeof(igen);
  7546. + igen = inode->i_generation + 1;
  7547. + sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
  7548. + sizeof(igen), &pos);
  7549. + if (sz == sizeof(igen))
  7550. + return; /* success */
  7551. +
  7552. + if (unlikely(sz >= 0))
  7553. + AuIOErr("xigen error (%zd)\n", sz);
  7554. +}
  7555. +
  7556. +int au_xigen_new(struct inode *inode)
  7557. +{
  7558. + int err;
  7559. + loff_t pos;
  7560. + ssize_t sz;
  7561. + struct super_block *sb;
  7562. + struct au_sbinfo *sbinfo;
  7563. + struct file *file;
  7564. +
  7565. + err = 0;
  7566. + /* todo: dirty, at mount time */
  7567. + if (inode->i_ino == AUFS_ROOT_INO)
  7568. + goto out;
  7569. + sb = inode->i_sb;
  7570. + SiMustAnyLock(sb);
  7571. + if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
  7572. + goto out;
  7573. +
  7574. + err = -EFBIG;
  7575. + pos = inode->i_ino;
  7576. + if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
  7577. + AuIOErr1("too large i%lld\n", pos);
  7578. + goto out;
  7579. + }
  7580. + pos *= sizeof(inode->i_generation);
  7581. +
  7582. + err = 0;
  7583. + sbinfo = au_sbi(sb);
  7584. + file = sbinfo->si_xigen;
  7585. + BUG_ON(!file);
  7586. +
  7587. + if (i_size_read(file->f_dentry->d_inode)
  7588. + < pos + sizeof(inode->i_generation)) {
  7589. + inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
  7590. + sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
  7591. + sizeof(inode->i_generation), &pos);
  7592. + } else
  7593. + sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
  7594. + sizeof(inode->i_generation), &pos);
  7595. + if (sz == sizeof(inode->i_generation))
  7596. + goto out; /* success */
  7597. +
  7598. + err = sz;
  7599. + if (unlikely(sz >= 0)) {
  7600. + err = -EIO;
  7601. + AuIOErr("xigen error (%zd)\n", sz);
  7602. + }
  7603. +
  7604. +out:
  7605. + return err;
  7606. +}
  7607. +
  7608. +int au_xigen_set(struct super_block *sb, struct file *base)
  7609. +{
  7610. + int err;
  7611. + struct au_sbinfo *sbinfo;
  7612. + struct file *file;
  7613. +
  7614. + SiMustWriteLock(sb);
  7615. +
  7616. + sbinfo = au_sbi(sb);
  7617. + file = au_xino_create2(base, sbinfo->si_xigen);
  7618. + err = PTR_ERR(file);
  7619. + if (IS_ERR(file))
  7620. + goto out;
  7621. + err = 0;
  7622. + if (sbinfo->si_xigen)
  7623. + fput(sbinfo->si_xigen);
  7624. + sbinfo->si_xigen = file;
  7625. +
  7626. +out:
  7627. + return err;
  7628. +}
  7629. +
  7630. +void au_xigen_clr(struct super_block *sb)
  7631. +{
  7632. + struct au_sbinfo *sbinfo;
  7633. +
  7634. + SiMustWriteLock(sb);
  7635. +
  7636. + sbinfo = au_sbi(sb);
  7637. + if (sbinfo->si_xigen) {
  7638. + fput(sbinfo->si_xigen);
  7639. + sbinfo->si_xigen = NULL;
  7640. + }
  7641. +}
  7642. +
  7643. +/* ---------------------------------------------------------------------- */
  7644. +
  7645. +static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
  7646. + ino_t dir_ino)
  7647. +{
  7648. + struct dentry *dentry, *d;
  7649. + struct inode *inode;
  7650. + unsigned int sigen;
  7651. +
  7652. + dentry = NULL;
  7653. + inode = ilookup(sb, ino);
  7654. + if (!inode)
  7655. + goto out;
  7656. +
  7657. + dentry = ERR_PTR(-ESTALE);
  7658. + sigen = au_sigen(sb);
  7659. + if (unlikely(is_bad_inode(inode)
  7660. + || IS_DEADDIR(inode)
  7661. + || sigen != au_iigen(inode)))
  7662. + goto out_iput;
  7663. +
  7664. + dentry = NULL;
  7665. + if (!dir_ino || S_ISDIR(inode->i_mode))
  7666. + dentry = d_find_alias(inode);
  7667. + else {
  7668. + spin_lock(&dcache_lock);
  7669. + list_for_each_entry(d, &inode->i_dentry, d_alias)
  7670. + if (!au_test_anon(d)
  7671. + && d->d_parent->d_inode->i_ino == dir_ino) {
  7672. + dentry = dget_locked(d);
  7673. + break;
  7674. + }
  7675. + spin_unlock(&dcache_lock);
  7676. + }
  7677. + if (unlikely(dentry && au_digen_test(dentry, sigen))) {
  7678. + dput(dentry);
  7679. + dentry = ERR_PTR(-ESTALE);
  7680. + }
  7681. +
  7682. +out_iput:
  7683. + iput(inode);
  7684. +out:
  7685. + return dentry;
  7686. +}
  7687. +
  7688. +/* ---------------------------------------------------------------------- */
  7689. +
  7690. +/* todo: dirty? */
  7691. +/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
  7692. +
  7693. +struct au_compare_mnt_args {
  7694. + /* input */
  7695. + struct super_block *sb;
  7696. +
  7697. + /* output */
  7698. + struct vfsmount *mnt;
  7699. +};
  7700. +
  7701. +static int au_compare_mnt(struct vfsmount *mnt, void *arg)
  7702. +{
  7703. + struct au_compare_mnt_args *a = arg;
  7704. +
  7705. + if (mnt->mnt_sb != a->sb)
  7706. + return 0;
  7707. + a->mnt = mntget(mnt);
  7708. + return 1;
  7709. +}
  7710. +
  7711. +static struct vfsmount *au_mnt_get(struct super_block *sb)
  7712. +{
  7713. + int err;
  7714. + struct au_compare_mnt_args args = {
  7715. + .sb = sb
  7716. + };
  7717. + struct mnt_namespace *ns;
  7718. +
  7719. + br_read_lock(vfsmount_lock);
  7720. + /* no get/put ?? */
  7721. + AuDebugOn(!current->nsproxy);
  7722. + ns = current->nsproxy->mnt_ns;
  7723. + AuDebugOn(!ns);
  7724. + err = iterate_mounts(au_compare_mnt, &args, ns->root);
  7725. + br_read_unlock(vfsmount_lock);
  7726. + AuDebugOn(!err);
  7727. + AuDebugOn(!args.mnt);
  7728. + return args.mnt;
  7729. +}
  7730. +
  7731. +struct au_nfsd_si_lock {
  7732. + unsigned int sigen;
  7733. + aufs_bindex_t bindex, br_id;
  7734. + unsigned char force_lock;
  7735. +};
  7736. +
  7737. +static int si_nfsd_read_lock(struct super_block *sb,
  7738. + struct au_nfsd_si_lock *nsi_lock)
  7739. +{
  7740. + int err;
  7741. + aufs_bindex_t bindex;
  7742. +
  7743. + si_read_lock(sb, AuLock_FLUSH);
  7744. +
  7745. + /* branch id may be wrapped around */
  7746. + err = 0;
  7747. + bindex = au_br_index(sb, nsi_lock->br_id);
  7748. + if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
  7749. + goto out; /* success */
  7750. +
  7751. + err = -ESTALE;
  7752. + bindex = -1;
  7753. + if (!nsi_lock->force_lock)
  7754. + si_read_unlock(sb);
  7755. +
  7756. +out:
  7757. + nsi_lock->bindex = bindex;
  7758. + return err;
  7759. +}
  7760. +
  7761. +struct find_name_by_ino {
  7762. + int called, found;
  7763. + ino_t ino;
  7764. + char *name;
  7765. + int namelen;
  7766. +};
  7767. +
  7768. +static int
  7769. +find_name_by_ino(void *arg, const char *name, int namelen, loff_t offset,
  7770. + u64 ino, unsigned int d_type)
  7771. +{
  7772. + struct find_name_by_ino *a = arg;
  7773. +
  7774. + a->called++;
  7775. + if (a->ino != ino)
  7776. + return 0;
  7777. +
  7778. + memcpy(a->name, name, namelen);
  7779. + a->namelen = namelen;
  7780. + a->found = 1;
  7781. + return 1;
  7782. +}
  7783. +
  7784. +static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
  7785. + struct au_nfsd_si_lock *nsi_lock)
  7786. +{
  7787. + struct dentry *dentry, *parent;
  7788. + struct file *file;
  7789. + struct inode *dir;
  7790. + struct find_name_by_ino arg;
  7791. + int err;
  7792. +
  7793. + parent = path->dentry;
  7794. + if (nsi_lock)
  7795. + si_read_unlock(parent->d_sb);
  7796. + file = vfsub_dentry_open(path, au_dir_roflags);
  7797. + dentry = (void *)file;
  7798. + if (IS_ERR(file))
  7799. + goto out;
  7800. +
  7801. + dentry = ERR_PTR(-ENOMEM);
  7802. + arg.name = __getname_gfp(GFP_NOFS);
  7803. + if (unlikely(!arg.name))
  7804. + goto out_file;
  7805. + arg.ino = ino;
  7806. + arg.found = 0;
  7807. + do {
  7808. + arg.called = 0;
  7809. + /* smp_mb(); */
  7810. + err = vfsub_readdir(file, find_name_by_ino, &arg);
  7811. + } while (!err && !arg.found && arg.called);
  7812. + dentry = ERR_PTR(err);
  7813. + if (unlikely(err))
  7814. + goto out_name;
  7815. + dentry = ERR_PTR(-ENOENT);
  7816. + if (!arg.found)
  7817. + goto out_name;
  7818. +
  7819. + /* do not call au_lkup_one() */
  7820. + dir = parent->d_inode;
  7821. + mutex_lock(&dir->i_mutex);
  7822. + dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
  7823. + mutex_unlock(&dir->i_mutex);
  7824. + AuTraceErrPtr(dentry);
  7825. + if (IS_ERR(dentry))
  7826. + goto out_name;
  7827. + AuDebugOn(au_test_anon(dentry));
  7828. + if (unlikely(!dentry->d_inode)) {
  7829. + dput(dentry);
  7830. + dentry = ERR_PTR(-ENOENT);
  7831. + }
  7832. +
  7833. +out_name:
  7834. + __putname(arg.name);
  7835. +out_file:
  7836. + fput(file);
  7837. +out:
  7838. + if (unlikely(nsi_lock
  7839. + && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
  7840. + if (!IS_ERR(dentry)) {
  7841. + dput(dentry);
  7842. + dentry = ERR_PTR(-ESTALE);
  7843. + }
  7844. + AuTraceErrPtr(dentry);
  7845. + return dentry;
  7846. +}
  7847. +
  7848. +static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
  7849. + ino_t dir_ino,
  7850. + struct au_nfsd_si_lock *nsi_lock)
  7851. +{
  7852. + struct dentry *dentry;
  7853. + struct path path;
  7854. +
  7855. + if (dir_ino != AUFS_ROOT_INO) {
  7856. + path.dentry = decode_by_ino(sb, dir_ino, 0);
  7857. + dentry = path.dentry;
  7858. + if (!path.dentry || IS_ERR(path.dentry))
  7859. + goto out;
  7860. + AuDebugOn(au_test_anon(path.dentry));
  7861. + } else
  7862. + path.dentry = dget(sb->s_root);
  7863. +
  7864. + path.mnt = au_mnt_get(sb);
  7865. + dentry = au_lkup_by_ino(&path, ino, nsi_lock);
  7866. + path_put(&path);
  7867. +
  7868. +out:
  7869. + AuTraceErrPtr(dentry);
  7870. + return dentry;
  7871. +}
  7872. +
  7873. +/* ---------------------------------------------------------------------- */
  7874. +
  7875. +static int h_acceptable(void *expv, struct dentry *dentry)
  7876. +{
  7877. + return 1;
  7878. +}
  7879. +
  7880. +static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
  7881. + char *buf, int len, struct super_block *sb)
  7882. +{
  7883. + char *p;
  7884. + int n;
  7885. + struct path path;
  7886. +
  7887. + p = d_path(h_rootpath, buf, len);
  7888. + if (IS_ERR(p))
  7889. + goto out;
  7890. + n = strlen(p);
  7891. +
  7892. + path.mnt = h_rootpath->mnt;
  7893. + path.dentry = h_parent;
  7894. + p = d_path(&path, buf, len);
  7895. + if (IS_ERR(p))
  7896. + goto out;
  7897. + if (n != 1)
  7898. + p += n;
  7899. +
  7900. + path.mnt = au_mnt_get(sb);
  7901. + path.dentry = sb->s_root;
  7902. + p = d_path(&path, buf, len - strlen(p));
  7903. + mntput(path.mnt);
  7904. + if (IS_ERR(p))
  7905. + goto out;
  7906. + if (n != 1)
  7907. + p[strlen(p)] = '/';
  7908. +
  7909. +out:
  7910. + AuTraceErrPtr(p);
  7911. + return p;
  7912. +}
  7913. +
  7914. +static
  7915. +struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
  7916. + int fh_len, struct au_nfsd_si_lock *nsi_lock)
  7917. +{
  7918. + struct dentry *dentry, *h_parent, *root;
  7919. + struct super_block *h_sb;
  7920. + char *pathname, *p;
  7921. + struct vfsmount *h_mnt;
  7922. + struct au_branch *br;
  7923. + int err;
  7924. + struct path path;
  7925. +
  7926. + br = au_sbr(sb, nsi_lock->bindex);
  7927. + h_mnt = br->br_mnt;
  7928. + h_sb = h_mnt->mnt_sb;
  7929. + /* todo: call lower fh_to_dentry()? fh_to_parent()? */
  7930. + h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
  7931. + fh_len - Fh_tail, fh[Fh_h_type],
  7932. + h_acceptable, /*context*/NULL);
  7933. + dentry = h_parent;
  7934. + if (unlikely(!h_parent || IS_ERR(h_parent))) {
  7935. + AuWarn1("%s decode_fh failed, %ld\n",
  7936. + au_sbtype(h_sb), PTR_ERR(h_parent));
  7937. + goto out;
  7938. + }
  7939. + dentry = NULL;
  7940. + if (unlikely(au_test_anon(h_parent))) {
  7941. + AuWarn1("%s decode_fh returned a disconnected dentry\n",
  7942. + au_sbtype(h_sb));
  7943. + goto out_h_parent;
  7944. + }
  7945. +
  7946. + dentry = ERR_PTR(-ENOMEM);
  7947. + pathname = (void *)__get_free_page(GFP_NOFS);
  7948. + if (unlikely(!pathname))
  7949. + goto out_h_parent;
  7950. +
  7951. + root = sb->s_root;
  7952. + path.mnt = h_mnt;
  7953. + di_read_lock_parent(root, !AuLock_IR);
  7954. + path.dentry = au_h_dptr(root, nsi_lock->bindex);
  7955. + di_read_unlock(root, !AuLock_IR);
  7956. + p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
  7957. + dentry = (void *)p;
  7958. + if (IS_ERR(p))
  7959. + goto out_pathname;
  7960. +
  7961. + si_read_unlock(sb);
  7962. + err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
  7963. + dentry = ERR_PTR(err);
  7964. + if (unlikely(err))
  7965. + goto out_relock;
  7966. +
  7967. + dentry = ERR_PTR(-ENOENT);
  7968. + AuDebugOn(au_test_anon(path.dentry));
  7969. + if (unlikely(!path.dentry->d_inode))
  7970. + goto out_path;
  7971. +
  7972. + if (ino != path.dentry->d_inode->i_ino)
  7973. + dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
  7974. + else
  7975. + dentry = dget(path.dentry);
  7976. +
  7977. +out_path:
  7978. + path_put(&path);
  7979. +out_relock:
  7980. + if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
  7981. + if (!IS_ERR(dentry)) {
  7982. + dput(dentry);
  7983. + dentry = ERR_PTR(-ESTALE);
  7984. + }
  7985. +out_pathname:
  7986. + free_page((unsigned long)pathname);
  7987. +out_h_parent:
  7988. + dput(h_parent);
  7989. +out:
  7990. + AuTraceErrPtr(dentry);
  7991. + return dentry;
  7992. +}
  7993. +
  7994. +/* ---------------------------------------------------------------------- */
  7995. +
  7996. +static struct dentry *
  7997. +aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
  7998. + int fh_type)
  7999. +{
  8000. + struct dentry *dentry;
  8001. + __u32 *fh = fid->raw;
  8002. + struct au_branch *br;
  8003. + ino_t ino, dir_ino;
  8004. + struct au_nfsd_si_lock nsi_lock = {
  8005. + .force_lock = 0
  8006. + };
  8007. +
  8008. + dentry = ERR_PTR(-ESTALE);
  8009. + /* it should never happen, but the file handle is unreliable */
  8010. + if (unlikely(fh_len < Fh_tail))
  8011. + goto out;
  8012. + nsi_lock.sigen = fh[Fh_sigen];
  8013. + nsi_lock.br_id = fh[Fh_br_id];
  8014. +
  8015. + /* branch id may be wrapped around */
  8016. + br = NULL;
  8017. + if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
  8018. + goto out;
  8019. + nsi_lock.force_lock = 1;
  8020. +
  8021. + /* is this inode still cached? */
  8022. + ino = decode_ino(fh + Fh_ino);
  8023. + /* it should never happen */
  8024. + if (unlikely(ino == AUFS_ROOT_INO))
  8025. + goto out;
  8026. +
  8027. + dir_ino = decode_ino(fh + Fh_dir_ino);
  8028. + dentry = decode_by_ino(sb, ino, dir_ino);
  8029. + if (IS_ERR(dentry))
  8030. + goto out_unlock;
  8031. + if (dentry)
  8032. + goto accept;
  8033. +
  8034. + /* is the parent dir cached? */
  8035. + br = au_sbr(sb, nsi_lock.bindex);
  8036. + atomic_inc(&br->br_count);
  8037. + dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
  8038. + if (IS_ERR(dentry))
  8039. + goto out_unlock;
  8040. + if (dentry)
  8041. + goto accept;
  8042. +
  8043. + /* lookup path */
  8044. + dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
  8045. + if (IS_ERR(dentry))
  8046. + goto out_unlock;
  8047. + if (unlikely(!dentry))
  8048. + /* todo?: make it ESTALE */
  8049. + goto out_unlock;
  8050. +
  8051. +accept:
  8052. + if (!au_digen_test(dentry, au_sigen(sb))
  8053. + && dentry->d_inode->i_generation == fh[Fh_igen])
  8054. + goto out_unlock; /* success */
  8055. +
  8056. + dput(dentry);
  8057. + dentry = ERR_PTR(-ESTALE);
  8058. +out_unlock:
  8059. + if (br)
  8060. + atomic_dec(&br->br_count);
  8061. + si_read_unlock(sb);
  8062. +out:
  8063. + AuTraceErrPtr(dentry);
  8064. + return dentry;
  8065. +}
  8066. +
  8067. +#if 0 /* reserved for future use */
  8068. +/* support subtreecheck option */
  8069. +static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
  8070. + int fh_len, int fh_type)
  8071. +{
  8072. + struct dentry *parent;
  8073. + __u32 *fh = fid->raw;
  8074. + ino_t dir_ino;
  8075. +
  8076. + dir_ino = decode_ino(fh + Fh_dir_ino);
  8077. + parent = decode_by_ino(sb, dir_ino, 0);
  8078. + if (IS_ERR(parent))
  8079. + goto out;
  8080. + if (!parent)
  8081. + parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
  8082. + dir_ino, fh, fh_len);
  8083. +
  8084. +out:
  8085. + AuTraceErrPtr(parent);
  8086. + return parent;
  8087. +}
  8088. +#endif
  8089. +
  8090. +/* ---------------------------------------------------------------------- */
  8091. +
  8092. +static int aufs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
  8093. + int connectable)
  8094. +{
  8095. + int err;
  8096. + aufs_bindex_t bindex, bend;
  8097. + struct super_block *sb, *h_sb;
  8098. + struct inode *inode;
  8099. + struct dentry *parent, *h_parent;
  8100. + struct au_branch *br;
  8101. +
  8102. + AuDebugOn(au_test_anon(dentry));
  8103. +
  8104. + parent = NULL;
  8105. + err = -ENOSPC;
  8106. + if (unlikely(*max_len <= Fh_tail)) {
  8107. + AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
  8108. + goto out;
  8109. + }
  8110. +
  8111. + err = FILEID_ROOT;
  8112. + if (IS_ROOT(dentry)) {
  8113. + AuDebugOn(dentry->d_inode->i_ino != AUFS_ROOT_INO);
  8114. + goto out;
  8115. + }
  8116. +
  8117. + h_parent = NULL;
  8118. + err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_IR | AuLock_GEN);
  8119. + if (unlikely(err))
  8120. + goto out;
  8121. +
  8122. + inode = dentry->d_inode;
  8123. + AuDebugOn(!inode);
  8124. + sb = dentry->d_sb;
  8125. +#ifdef CONFIG_AUFS_DEBUG
  8126. + if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
  8127. + AuWarn1("NFS-exporting requires xino\n");
  8128. +#endif
  8129. + err = -EIO;
  8130. + parent = dget_parent(dentry);
  8131. + di_read_lock_parent(parent, !AuLock_IR);
  8132. + bend = au_dbtaildir(parent);
  8133. + for (bindex = au_dbstart(parent); bindex <= bend; bindex++) {
  8134. + h_parent = au_h_dptr(parent, bindex);
  8135. + if (h_parent) {
  8136. + dget(h_parent);
  8137. + break;
  8138. + }
  8139. + }
  8140. + if (unlikely(!h_parent))
  8141. + goto out_unlock;
  8142. +
  8143. + err = -EPERM;
  8144. + br = au_sbr(sb, bindex);
  8145. + h_sb = br->br_mnt->mnt_sb;
  8146. + if (unlikely(!h_sb->s_export_op)) {
  8147. + AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
  8148. + goto out_dput;
  8149. + }
  8150. +
  8151. + fh[Fh_br_id] = br->br_id;
  8152. + fh[Fh_sigen] = au_sigen(sb);
  8153. + encode_ino(fh + Fh_ino, inode->i_ino);
  8154. + encode_ino(fh + Fh_dir_ino, parent->d_inode->i_ino);
  8155. + fh[Fh_igen] = inode->i_generation;
  8156. +
  8157. + *max_len -= Fh_tail;
  8158. + fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
  8159. + max_len,
  8160. + /*connectable or subtreecheck*/0);
  8161. + err = fh[Fh_h_type];
  8162. + *max_len += Fh_tail;
  8163. + /* todo: macros? */
  8164. + if (err != 255)
  8165. + err = 99;
  8166. + else
  8167. + AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
  8168. +
  8169. +out_dput:
  8170. + dput(h_parent);
  8171. +out_unlock:
  8172. + di_read_unlock(parent, !AuLock_IR);
  8173. + dput(parent);
  8174. + aufs_read_unlock(dentry, AuLock_IR);
  8175. +out:
  8176. + if (unlikely(err < 0))
  8177. + err = 255;
  8178. + return err;
  8179. +}
  8180. +
  8181. +/* ---------------------------------------------------------------------- */
  8182. +
  8183. +static int aufs_commit_metadata(struct inode *inode)
  8184. +{
  8185. + int err;
  8186. + aufs_bindex_t bindex;
  8187. + struct super_block *sb;
  8188. + struct inode *h_inode;
  8189. + int (*f)(struct inode *inode);
  8190. +
  8191. + sb = inode->i_sb;
  8192. + si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
  8193. + ii_write_lock_child(inode);
  8194. + bindex = au_ibstart(inode);
  8195. + AuDebugOn(bindex < 0);
  8196. + h_inode = au_h_iptr(inode, bindex);
  8197. +
  8198. + f = h_inode->i_sb->s_export_op->commit_metadata;
  8199. + if (f)
  8200. + err = f(h_inode);
  8201. + else {
  8202. + struct writeback_control wbc = {
  8203. + .sync_mode = WB_SYNC_ALL,
  8204. + .nr_to_write = 0 /* metadata only */
  8205. + };
  8206. +
  8207. + err = sync_inode(h_inode, &wbc);
  8208. + }
  8209. +
  8210. + au_cpup_attr_timesizes(inode);
  8211. + ii_write_unlock(inode);
  8212. + si_read_unlock(sb);
  8213. + return err;
  8214. +}
  8215. +
  8216. +/* ---------------------------------------------------------------------- */
  8217. +
  8218. +static struct export_operations aufs_export_op = {
  8219. + .fh_to_dentry = aufs_fh_to_dentry,
  8220. + /* .fh_to_parent = aufs_fh_to_parent, */
  8221. + .encode_fh = aufs_encode_fh,
  8222. + .commit_metadata = aufs_commit_metadata
  8223. +};
  8224. +
  8225. +void au_export_init(struct super_block *sb)
  8226. +{
  8227. + struct au_sbinfo *sbinfo;
  8228. + __u32 u;
  8229. +
  8230. + sb->s_export_op = &aufs_export_op;
  8231. + sbinfo = au_sbi(sb);
  8232. + sbinfo->si_xigen = NULL;
  8233. + get_random_bytes(&u, sizeof(u));
  8234. + BUILD_BUG_ON(sizeof(u) != sizeof(int));
  8235. + atomic_set(&sbinfo->si_xigen_next, u);
  8236. +}
  8237. diff -Nur linux-2.6.37.orig/fs/aufs/f_op.c linux-2.6.37/fs/aufs/f_op.c
  8238. --- linux-2.6.37.orig/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100
  8239. +++ linux-2.6.37/fs/aufs/f_op.c 2011-01-11 20:15:11.000000000 +0100
  8240. @@ -0,0 +1,906 @@
  8241. +/*
  8242. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  8243. + *
  8244. + * This program, aufs is free software; you can redistribute it and/or modify
  8245. + * it under the terms of the GNU General Public License as published by
  8246. + * the Free Software Foundation; either version 2 of the License, or
  8247. + * (at your option) any later version.
  8248. + *
  8249. + * This program is distributed in the hope that it will be useful,
  8250. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  8251. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8252. + * GNU General Public License for more details.
  8253. + *
  8254. + * You should have received a copy of the GNU General Public License
  8255. + * along with this program; if not, write to the Free Software
  8256. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  8257. + */
  8258. +
  8259. +/*
  8260. + * file and vm operations
  8261. + */
  8262. +
  8263. +#include <linux/file.h>
  8264. +#include <linux/fs_stack.h>
  8265. +#include <linux/mman.h>
  8266. +#include <linux/mm.h>
  8267. +#include <linux/security.h>
  8268. +#include "aufs.h"
  8269. +
  8270. +int au_do_open_nondir(struct file *file, int flags)
  8271. +{
  8272. + int err;
  8273. + aufs_bindex_t bindex;
  8274. + struct file *h_file;
  8275. + struct dentry *dentry;
  8276. + struct au_finfo *finfo;
  8277. +
  8278. + FiMustWriteLock(file);
  8279. +
  8280. + dentry = file->f_dentry;
  8281. + err = au_d_alive(dentry);
  8282. + if (unlikely(err))
  8283. + goto out;
  8284. +
  8285. + finfo = au_fi(file);
  8286. + memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
  8287. + finfo->fi_hvmop = NULL;
  8288. + bindex = au_dbstart(dentry);
  8289. + h_file = au_h_open(dentry, bindex, flags, file);
  8290. + if (IS_ERR(h_file))
  8291. + err = PTR_ERR(h_file);
  8292. + else {
  8293. + au_set_fbstart(file, bindex);
  8294. + au_set_h_fptr(file, bindex, h_file);
  8295. + au_update_figen(file);
  8296. + /* todo: necessary? */
  8297. + /* file->f_ra = h_file->f_ra; */
  8298. + }
  8299. +
  8300. +out:
  8301. + return err;
  8302. +}
  8303. +
  8304. +static int aufs_open_nondir(struct inode *inode __maybe_unused,
  8305. + struct file *file)
  8306. +{
  8307. + int err;
  8308. + struct super_block *sb;
  8309. +
  8310. + AuDbg("%.*s, f_ flags 0x%x, f_mode 0x%x\n",
  8311. + AuDLNPair(file->f_dentry), vfsub_file_flags(file),
  8312. + file->f_mode);
  8313. +
  8314. + sb = file->f_dentry->d_sb;
  8315. + si_read_lock(sb, AuLock_FLUSH);
  8316. + err = au_do_open(file, au_do_open_nondir, /*fidir*/NULL);
  8317. + si_read_unlock(sb);
  8318. + return err;
  8319. +}
  8320. +
  8321. +int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
  8322. +{
  8323. + struct au_finfo *finfo;
  8324. + aufs_bindex_t bindex;
  8325. +
  8326. + finfo = au_fi(file);
  8327. + bindex = finfo->fi_btop;
  8328. + if (bindex >= 0) {
  8329. + /* remove me from sb->s_files */
  8330. + file_sb_list_del(file);
  8331. + au_set_h_fptr(file, bindex, NULL);
  8332. + }
  8333. +
  8334. + au_finfo_fin(file);
  8335. + return 0;
  8336. +}
  8337. +
  8338. +/* ---------------------------------------------------------------------- */
  8339. +
  8340. +static int au_do_flush_nondir(struct file *file, fl_owner_t id)
  8341. +{
  8342. + int err;
  8343. + struct file *h_file;
  8344. +
  8345. + err = 0;
  8346. + h_file = au_hf_top(file);
  8347. + if (h_file)
  8348. + err = vfsub_flush(h_file, id);
  8349. + return err;
  8350. +}
  8351. +
  8352. +static int aufs_flush_nondir(struct file *file, fl_owner_t id)
  8353. +{
  8354. + return au_do_flush(file, id, au_do_flush_nondir);
  8355. +}
  8356. +
  8357. +/* ---------------------------------------------------------------------- */
  8358. +
  8359. +static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
  8360. + loff_t *ppos)
  8361. +{
  8362. + ssize_t err;
  8363. + struct dentry *dentry;
  8364. + struct file *h_file;
  8365. + struct super_block *sb;
  8366. +
  8367. + dentry = file->f_dentry;
  8368. + sb = dentry->d_sb;
  8369. + si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
  8370. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
  8371. + if (unlikely(err))
  8372. + goto out;
  8373. +
  8374. + h_file = au_hf_top(file);
  8375. + err = vfsub_read_u(h_file, buf, count, ppos);
  8376. + /* todo: necessary? */
  8377. + /* file->f_ra = h_file->f_ra; */
  8378. + fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
  8379. +
  8380. + di_read_unlock(dentry, AuLock_IR);
  8381. + fi_read_unlock(file);
  8382. +out:
  8383. + si_read_unlock(sb);
  8384. + return err;
  8385. +}
  8386. +
  8387. +/*
  8388. + * todo: very ugly
  8389. + * it locks both of i_mutex and si_rwsem for read in safe.
  8390. + * if the plink maintenance mode continues forever (that is the problem),
  8391. + * may loop forever.
  8392. + */
  8393. +static void au_mtx_and_read_lock(struct inode *inode)
  8394. +{
  8395. + int err;
  8396. + struct super_block *sb = inode->i_sb;
  8397. +
  8398. + while (1) {
  8399. + mutex_lock(&inode->i_mutex);
  8400. + err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
  8401. + if (!err)
  8402. + break;
  8403. + mutex_unlock(&inode->i_mutex);
  8404. + si_read_lock(sb, AuLock_NOPLMW);
  8405. + si_read_unlock(sb);
  8406. + }
  8407. +}
  8408. +
  8409. +static ssize_t aufs_write(struct file *file, const char __user *ubuf,
  8410. + size_t count, loff_t *ppos)
  8411. +{
  8412. + ssize_t err;
  8413. + struct au_pin pin;
  8414. + struct dentry *dentry;
  8415. + struct inode *inode;
  8416. + struct file *h_file;
  8417. + char __user *buf = (char __user *)ubuf;
  8418. +
  8419. + dentry = file->f_dentry;
  8420. + inode = dentry->d_inode;
  8421. + au_mtx_and_read_lock(inode);
  8422. +
  8423. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  8424. + if (unlikely(err))
  8425. + goto out;
  8426. +
  8427. + err = au_ready_to_write(file, -1, &pin);
  8428. + di_downgrade_lock(dentry, AuLock_IR);
  8429. + if (unlikely(err))
  8430. + goto out_unlock;
  8431. +
  8432. + h_file = au_hf_top(file);
  8433. + au_unpin(&pin);
  8434. + err = vfsub_write_u(h_file, buf, count, ppos);
  8435. + au_cpup_attr_timesizes(inode);
  8436. + inode->i_mode = h_file->f_dentry->d_inode->i_mode;
  8437. +
  8438. +out_unlock:
  8439. + di_read_unlock(dentry, AuLock_IR);
  8440. + fi_write_unlock(file);
  8441. +out:
  8442. + si_read_unlock(inode->i_sb);
  8443. + mutex_unlock(&inode->i_mutex);
  8444. + return err;
  8445. +}
  8446. +
  8447. +static ssize_t au_do_aio(struct file *h_file, int rw, struct kiocb *kio,
  8448. + const struct iovec *iov, unsigned long nv, loff_t pos)
  8449. +{
  8450. + ssize_t err;
  8451. + struct file *file;
  8452. + ssize_t (*func)(struct kiocb *, const struct iovec *, unsigned long,
  8453. + loff_t);
  8454. +
  8455. + err = security_file_permission(h_file, rw);
  8456. + if (unlikely(err))
  8457. + goto out;
  8458. +
  8459. + err = -ENOSYS;
  8460. + func = NULL;
  8461. + if (rw == MAY_READ)
  8462. + func = h_file->f_op->aio_read;
  8463. + else if (rw == MAY_WRITE)
  8464. + func = h_file->f_op->aio_write;
  8465. + if (func) {
  8466. + file = kio->ki_filp;
  8467. + kio->ki_filp = h_file;
  8468. + err = func(kio, iov, nv, pos);
  8469. + kio->ki_filp = file;
  8470. + } else
  8471. + /* currently there is no such fs */
  8472. + WARN_ON_ONCE(1);
  8473. +
  8474. +out:
  8475. + return err;
  8476. +}
  8477. +
  8478. +static ssize_t aufs_aio_read(struct kiocb *kio, const struct iovec *iov,
  8479. + unsigned long nv, loff_t pos)
  8480. +{
  8481. + ssize_t err;
  8482. + struct file *file, *h_file;
  8483. + struct dentry *dentry;
  8484. + struct super_block *sb;
  8485. +
  8486. + file = kio->ki_filp;
  8487. + dentry = file->f_dentry;
  8488. + sb = dentry->d_sb;
  8489. + si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
  8490. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
  8491. + if (unlikely(err))
  8492. + goto out;
  8493. +
  8494. + h_file = au_hf_top(file);
  8495. + err = au_do_aio(h_file, MAY_READ, kio, iov, nv, pos);
  8496. + /* todo: necessary? */
  8497. + /* file->f_ra = h_file->f_ra; */
  8498. + fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
  8499. + di_read_unlock(dentry, AuLock_IR);
  8500. + fi_read_unlock(file);
  8501. +
  8502. +out:
  8503. + si_read_unlock(sb);
  8504. + return err;
  8505. +}
  8506. +
  8507. +static ssize_t aufs_aio_write(struct kiocb *kio, const struct iovec *iov,
  8508. + unsigned long nv, loff_t pos)
  8509. +{
  8510. + ssize_t err;
  8511. + struct au_pin pin;
  8512. + struct dentry *dentry;
  8513. + struct inode *inode;
  8514. + struct file *file, *h_file;
  8515. +
  8516. + file = kio->ki_filp;
  8517. + dentry = file->f_dentry;
  8518. + inode = dentry->d_inode;
  8519. + au_mtx_and_read_lock(inode);
  8520. +
  8521. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  8522. + if (unlikely(err))
  8523. + goto out;
  8524. +
  8525. + err = au_ready_to_write(file, -1, &pin);
  8526. + di_downgrade_lock(dentry, AuLock_IR);
  8527. + if (unlikely(err))
  8528. + goto out_unlock;
  8529. +
  8530. + au_unpin(&pin);
  8531. + h_file = au_hf_top(file);
  8532. + err = au_do_aio(h_file, MAY_WRITE, kio, iov, nv, pos);
  8533. + au_cpup_attr_timesizes(inode);
  8534. + inode->i_mode = h_file->f_dentry->d_inode->i_mode;
  8535. +
  8536. +out_unlock:
  8537. + di_read_unlock(dentry, AuLock_IR);
  8538. + fi_write_unlock(file);
  8539. +out:
  8540. + si_read_unlock(inode->i_sb);
  8541. + mutex_unlock(&inode->i_mutex);
  8542. + return err;
  8543. +}
  8544. +
  8545. +static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
  8546. + struct pipe_inode_info *pipe, size_t len,
  8547. + unsigned int flags)
  8548. +{
  8549. + ssize_t err;
  8550. + struct file *h_file;
  8551. + struct dentry *dentry;
  8552. + struct super_block *sb;
  8553. +
  8554. + dentry = file->f_dentry;
  8555. + sb = dentry->d_sb;
  8556. + si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
  8557. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
  8558. + if (unlikely(err))
  8559. + goto out;
  8560. +
  8561. + err = -EINVAL;
  8562. + h_file = au_hf_top(file);
  8563. + if (au_test_loopback_kthread()) {
  8564. + file->f_mapping = h_file->f_mapping;
  8565. + smp_mb(); /* unnecessary? */
  8566. + }
  8567. + err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
  8568. + /* todo: necessasry? */
  8569. + /* file->f_ra = h_file->f_ra; */
  8570. + fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
  8571. +
  8572. + di_read_unlock(dentry, AuLock_IR);
  8573. + fi_read_unlock(file);
  8574. +
  8575. +out:
  8576. + si_read_unlock(sb);
  8577. + return err;
  8578. +}
  8579. +
  8580. +static ssize_t
  8581. +aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
  8582. + size_t len, unsigned int flags)
  8583. +{
  8584. + ssize_t err;
  8585. + struct au_pin pin;
  8586. + struct dentry *dentry;
  8587. + struct inode *inode;
  8588. + struct file *h_file;
  8589. +
  8590. + dentry = file->f_dentry;
  8591. + inode = dentry->d_inode;
  8592. + au_mtx_and_read_lock(inode);
  8593. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  8594. + if (unlikely(err))
  8595. + goto out;
  8596. +
  8597. + err = au_ready_to_write(file, -1, &pin);
  8598. + di_downgrade_lock(dentry, AuLock_IR);
  8599. + if (unlikely(err))
  8600. + goto out_unlock;
  8601. +
  8602. + h_file = au_hf_top(file);
  8603. + au_unpin(&pin);
  8604. + err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
  8605. + au_cpup_attr_timesizes(inode);
  8606. + inode->i_mode = h_file->f_dentry->d_inode->i_mode;
  8607. +
  8608. +out_unlock:
  8609. + di_read_unlock(dentry, AuLock_IR);
  8610. + fi_write_unlock(file);
  8611. +out:
  8612. + si_read_unlock(inode->i_sb);
  8613. + mutex_unlock(&inode->i_mutex);
  8614. + return err;
  8615. +}
  8616. +
  8617. +/* ---------------------------------------------------------------------- */
  8618. +
  8619. +static struct file *au_safe_file(struct vm_area_struct *vma)
  8620. +{
  8621. + struct file *file;
  8622. +
  8623. + file = vma->vm_file;
  8624. + if (au_fi(file) && au_test_aufs(file->f_dentry->d_sb))
  8625. + return file;
  8626. + return NULL;
  8627. +}
  8628. +
  8629. +static void au_reset_file(struct vm_area_struct *vma, struct file *file)
  8630. +{
  8631. + vma->vm_file = file;
  8632. + /* smp_mb(); */ /* flush vm_file */
  8633. +}
  8634. +
  8635. +static int aufs_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
  8636. +{
  8637. + int err;
  8638. + static DECLARE_WAIT_QUEUE_HEAD(wq);
  8639. + struct file *file, *h_file;
  8640. + struct au_finfo *finfo;
  8641. +
  8642. + /* todo: non-robr mode, user vm_file as it is? */
  8643. + wait_event(wq, (file = au_safe_file(vma)));
  8644. +
  8645. + /* do not revalidate, no si lock */
  8646. + finfo = au_fi(file);
  8647. + AuDebugOn(finfo->fi_hdir);
  8648. + h_file = finfo->fi_htop.hf_file;
  8649. + AuDebugOn(!h_file || !finfo->fi_hvmop);
  8650. +
  8651. + mutex_lock(&finfo->fi_vm_mtx);
  8652. + vma->vm_file = h_file;
  8653. + err = finfo->fi_hvmop->fault(vma, vmf);
  8654. + /* todo: necessary? */
  8655. + /* file->f_ra = h_file->f_ra; */
  8656. + au_reset_file(vma, file);
  8657. + mutex_unlock(&finfo->fi_vm_mtx);
  8658. +#if 0 /* def CONFIG_SMP */
  8659. + /* wake_up_nr(&wq, online_cpu - 1); */
  8660. + wake_up_all(&wq);
  8661. +#else
  8662. + wake_up(&wq);
  8663. +#endif
  8664. +
  8665. + return err;
  8666. +}
  8667. +
  8668. +static int aufs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
  8669. +{
  8670. + int err;
  8671. + static DECLARE_WAIT_QUEUE_HEAD(wq);
  8672. + struct file *file, *h_file;
  8673. + struct au_finfo *finfo;
  8674. +
  8675. + wait_event(wq, (file = au_safe_file(vma)));
  8676. +
  8677. + finfo = au_fi(file);
  8678. + AuDebugOn(finfo->fi_hdir);
  8679. + h_file = finfo->fi_htop.hf_file;
  8680. + AuDebugOn(!h_file || !finfo->fi_hvmop);
  8681. +
  8682. + mutex_lock(&finfo->fi_vm_mtx);
  8683. + vma->vm_file = h_file;
  8684. + err = finfo->fi_hvmop->page_mkwrite(vma, vmf);
  8685. + au_reset_file(vma, file);
  8686. + mutex_unlock(&finfo->fi_vm_mtx);
  8687. + wake_up(&wq);
  8688. +
  8689. + return err;
  8690. +}
  8691. +
  8692. +static void aufs_vm_close(struct vm_area_struct *vma)
  8693. +{
  8694. + static DECLARE_WAIT_QUEUE_HEAD(wq);
  8695. + struct file *file, *h_file;
  8696. + struct au_finfo *finfo;
  8697. +
  8698. + wait_event(wq, (file = au_safe_file(vma)));
  8699. +
  8700. + finfo = au_fi(file);
  8701. + AuDebugOn(finfo->fi_hdir);
  8702. + h_file = finfo->fi_htop.hf_file;
  8703. + AuDebugOn(!h_file || !finfo->fi_hvmop);
  8704. +
  8705. + mutex_lock(&finfo->fi_vm_mtx);
  8706. + vma->vm_file = h_file;
  8707. + finfo->fi_hvmop->close(vma);
  8708. + au_reset_file(vma, file);
  8709. + mutex_unlock(&finfo->fi_vm_mtx);
  8710. + wake_up(&wq);
  8711. +}
  8712. +
  8713. +const struct vm_operations_struct aufs_vm_ops = {
  8714. + .close = aufs_vm_close,
  8715. + .fault = aufs_fault,
  8716. + .page_mkwrite = aufs_page_mkwrite
  8717. +};
  8718. +
  8719. +/* ---------------------------------------------------------------------- */
  8720. +
  8721. +/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
  8722. +#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b)
  8723. +
  8724. +static unsigned long au_arch_prot_conv(unsigned long flags)
  8725. +{
  8726. + /* currently ppc64 only */
  8727. +#ifdef CONFIG_PPC64
  8728. + /* cf. linux/arch/powerpc/include/asm/mman.h */
  8729. + AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO);
  8730. + return AuConv_VM_PROT(flags, SAO);
  8731. +#else
  8732. + AuDebugOn(arch_calc_vm_prot_bits(-1));
  8733. + return 0;
  8734. +#endif
  8735. +}
  8736. +
  8737. +static unsigned long au_prot_conv(unsigned long flags)
  8738. +{
  8739. + return AuConv_VM_PROT(flags, READ)
  8740. + | AuConv_VM_PROT(flags, WRITE)
  8741. + | AuConv_VM_PROT(flags, EXEC)
  8742. + | au_arch_prot_conv(flags);
  8743. +}
  8744. +
  8745. +/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */
  8746. +#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b)
  8747. +
  8748. +static unsigned long au_flag_conv(unsigned long flags)
  8749. +{
  8750. + return AuConv_VM_MAP(flags, GROWSDOWN)
  8751. + | AuConv_VM_MAP(flags, DENYWRITE)
  8752. + | AuConv_VM_MAP(flags, EXECUTABLE)
  8753. + | AuConv_VM_MAP(flags, LOCKED);
  8754. +}
  8755. +
  8756. +static struct vm_operations_struct *
  8757. +au_hvmop(struct file *h_file, struct vm_area_struct *vma, unsigned long *flags)
  8758. +{
  8759. + struct vm_operations_struct *h_vmop;
  8760. + unsigned long prot;
  8761. + int err;
  8762. +
  8763. + h_vmop = ERR_PTR(-ENODEV);
  8764. + if (!h_file->f_op || !h_file->f_op->mmap)
  8765. + goto out;
  8766. +
  8767. + prot = au_prot_conv(vma->vm_flags);
  8768. + err = security_file_mmap(h_file, /*reqprot*/prot, prot,
  8769. + au_flag_conv(vma->vm_flags), vma->vm_start, 0);
  8770. + h_vmop = ERR_PTR(err);
  8771. + if (unlikely(err))
  8772. + goto out;
  8773. +
  8774. + err = h_file->f_op->mmap(h_file, vma);
  8775. + h_vmop = ERR_PTR(err);
  8776. + if (unlikely(err))
  8777. + goto out;
  8778. +
  8779. + /* oops, it became 'const' */
  8780. + h_vmop = (struct vm_operations_struct *)vma->vm_ops;
  8781. + *flags = vma->vm_flags;
  8782. + err = do_munmap(current->mm, vma->vm_start,
  8783. + vma->vm_end - vma->vm_start);
  8784. + if (unlikely(err)) {
  8785. + AuIOErr("failed internal unmapping %.*s, %d\n",
  8786. + AuDLNPair(h_file->f_dentry), err);
  8787. + h_vmop = ERR_PTR(-EIO);
  8788. + }
  8789. +
  8790. +out:
  8791. + return h_vmop;
  8792. +}
  8793. +
  8794. +/*
  8795. + * This is another ugly approach to keep the lock order, particularly
  8796. + * mm->mmap_sem and aufs rwsem. The previous approach was reverted and you can
  8797. + * find it in git-log, if you want.
  8798. + *
  8799. + * native readdir: i_mutex, copy_to_user, mmap_sem
  8800. + * aufs readdir: i_mutex, rwsem, nested-i_mutex, copy_to_user, mmap_sem
  8801. + *
  8802. + * Before aufs_mmap() mmap_sem is acquired already, but aufs_mmap() has to
  8803. + * acquire aufs rwsem. It introduces a circular locking dependency.
  8804. + * To address this problem, aufs_mmap() delegates the part which requires aufs
  8805. + * rwsem to its internal workqueue.
  8806. + */
  8807. +
  8808. +/* very ugly approach */
  8809. +#include "mtx.h"
  8810. +
  8811. +struct au_mmap_pre_args {
  8812. + /* input */
  8813. + struct file *file;
  8814. + struct vm_area_struct *vma;
  8815. +
  8816. + /* output */
  8817. + int *errp;
  8818. + struct file *h_file;
  8819. + struct au_branch *br;
  8820. + int mmapped;
  8821. +};
  8822. +
  8823. +static int au_mmap_pre(struct file *file, struct vm_area_struct *vma,
  8824. + struct file **h_file, struct au_branch **br,
  8825. + int *mmapped)
  8826. +{
  8827. + int err;
  8828. + aufs_bindex_t bstart;
  8829. + const unsigned char wlock
  8830. + = !!(file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
  8831. + struct dentry *dentry;
  8832. + struct super_block *sb;
  8833. +
  8834. + dentry = file->f_dentry;
  8835. + sb = dentry->d_sb;
  8836. + si_read_lock(sb, AuLock_NOPLMW);
  8837. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  8838. + if (unlikely(err))
  8839. + goto out;
  8840. +
  8841. + *mmapped = !!au_test_mmapped(file);
  8842. + if (wlock) {
  8843. + struct au_pin pin;
  8844. +
  8845. + err = au_ready_to_write(file, -1, &pin);
  8846. + di_write_unlock(dentry);
  8847. + if (unlikely(err))
  8848. + goto out_unlock;
  8849. + au_unpin(&pin);
  8850. + } else
  8851. + di_write_unlock(dentry);
  8852. + bstart = au_fbstart(file);
  8853. + *br = au_sbr(sb, bstart);
  8854. + *h_file = au_hf_top(file);
  8855. + get_file(*h_file);
  8856. + au_fi_mmap_lock(file);
  8857. +
  8858. +out_unlock:
  8859. + fi_write_unlock(file);
  8860. +out:
  8861. + si_read_unlock(sb);
  8862. + return err;
  8863. +}
  8864. +
  8865. +static void au_call_mmap_pre(void *args)
  8866. +{
  8867. + struct au_mmap_pre_args *a = args;
  8868. + *a->errp = au_mmap_pre(a->file, a->vma, &a->h_file, &a->br,
  8869. + &a->mmapped);
  8870. +}
  8871. +
  8872. +static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
  8873. +{
  8874. + int err, wkq_err;
  8875. + unsigned long h_vmflags;
  8876. + struct au_finfo *finfo;
  8877. + struct dentry *h_dentry;
  8878. + struct vm_operations_struct *h_vmop, *vmop;
  8879. + struct au_mmap_pre_args args = {
  8880. + .file = file,
  8881. + .vma = vma,
  8882. + .errp = &err
  8883. + };
  8884. +
  8885. + wkq_err = au_wkq_wait_pre(au_call_mmap_pre, &args);
  8886. + if (unlikely(wkq_err))
  8887. + err = wkq_err;
  8888. + if (unlikely(err))
  8889. + goto out;
  8890. + finfo = au_fi(file);
  8891. + mutex_set_owner(&finfo->fi_mmap);
  8892. +
  8893. + h_dentry = args.h_file->f_dentry;
  8894. + if (!args.mmapped && au_test_fs_bad_mapping(h_dentry->d_sb)) {
  8895. + /*
  8896. + * by this assignment, f_mapping will differs from aufs inode
  8897. + * i_mapping.
  8898. + * if someone else mixes the use of f_dentry->d_inode and
  8899. + * f_mapping->host, then a problem may arise.
  8900. + */
  8901. + file->f_mapping = args.h_file->f_mapping;
  8902. + }
  8903. +
  8904. + /* always try this internal mmap to get vma flags */
  8905. + h_vmflags = 0; /* gcc warning */
  8906. + h_vmop = au_hvmop(args.h_file, vma, &h_vmflags);
  8907. + err = PTR_ERR(h_vmop);
  8908. + if (IS_ERR(h_vmop))
  8909. + goto out_unlock;
  8910. + AuDebugOn(args.mmapped && h_vmop != finfo->fi_hvmop);
  8911. +
  8912. + vmop = (void *)au_dy_vmop(file, args.br, h_vmop);
  8913. + err = PTR_ERR(vmop);
  8914. + if (IS_ERR(vmop))
  8915. + goto out_unlock;
  8916. +
  8917. + /*
  8918. + * unnecessary to handle MAP_DENYWRITE and deny_write_access()?
  8919. + * currently MAP_DENYWRITE from userspace is ignored, but elf loader
  8920. + * sets it. when FMODE_EXEC is set (by open_exec() or sys_uselib()),
  8921. + * both of the aufs file and the lower file is deny_write_access()-ed.
  8922. + * finally I hope we can skip handlling MAP_DENYWRITE here.
  8923. + */
  8924. + err = generic_file_mmap(file, vma);
  8925. + if (unlikely(err))
  8926. + goto out_unlock;
  8927. +
  8928. + vma->vm_ops = vmop;
  8929. + vma->vm_flags = h_vmflags;
  8930. + if (!args.mmapped)
  8931. + finfo->fi_hvmop = h_vmop;
  8932. +
  8933. + vfsub_file_accessed(args.h_file);
  8934. + /* update without lock, I don't think it a problem */
  8935. + fsstack_copy_attr_atime(file->f_dentry->d_inode, h_dentry->d_inode);
  8936. +
  8937. +out_unlock:
  8938. + au_fi_mmap_unlock(file);
  8939. + fput(args.h_file);
  8940. +out:
  8941. + return err;
  8942. +}
  8943. +
  8944. +/* ---------------------------------------------------------------------- */
  8945. +
  8946. +static int aufs_fsync_nondir(struct file *file, int datasync)
  8947. +{
  8948. + int err;
  8949. + struct au_pin pin;
  8950. + struct dentry *dentry;
  8951. + struct inode *inode;
  8952. + struct file *h_file;
  8953. + struct super_block *sb;
  8954. +
  8955. + dentry = file->f_dentry;
  8956. + inode = dentry->d_inode;
  8957. + IMustLock(file->f_mapping->host);
  8958. + if (inode != file->f_mapping->host) {
  8959. + mutex_unlock(&file->f_mapping->host->i_mutex);
  8960. + mutex_lock(&inode->i_mutex);
  8961. + }
  8962. + IMustLock(inode);
  8963. +
  8964. + sb = dentry->d_sb;
  8965. + err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
  8966. + if (unlikely(err))
  8967. + goto out;
  8968. +
  8969. + err = 0; /* -EBADF; */ /* posix? */
  8970. + if (unlikely(!(file->f_mode & FMODE_WRITE)))
  8971. + goto out_si;
  8972. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  8973. + if (unlikely(err))
  8974. + goto out_si;
  8975. +
  8976. + err = au_ready_to_write(file, -1, &pin);
  8977. + di_downgrade_lock(dentry, AuLock_IR);
  8978. + if (unlikely(err))
  8979. + goto out_unlock;
  8980. + au_unpin(&pin);
  8981. +
  8982. + err = -EINVAL;
  8983. + h_file = au_hf_top(file);
  8984. + if (h_file->f_op && h_file->f_op->fsync) {
  8985. + struct mutex *h_mtx;
  8986. +
  8987. + /*
  8988. + * no filemap_fdatawrite() since aufs file has no its own
  8989. + * mapping, but dir.
  8990. + */
  8991. + h_mtx = &h_file->f_dentry->d_inode->i_mutex;
  8992. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  8993. + err = h_file->f_op->fsync(h_file, datasync);
  8994. + if (!err)
  8995. + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
  8996. + /*ignore*/
  8997. + au_cpup_attr_timesizes(inode);
  8998. + mutex_unlock(h_mtx);
  8999. + }
  9000. +
  9001. +out_unlock:
  9002. + di_read_unlock(dentry, AuLock_IR);
  9003. + fi_write_unlock(file);
  9004. +out_si:
  9005. + si_read_unlock(sb);
  9006. +out:
  9007. + if (inode != file->f_mapping->host) {
  9008. + mutex_unlock(&inode->i_mutex);
  9009. + mutex_lock(&file->f_mapping->host->i_mutex);
  9010. + }
  9011. + return err;
  9012. +}
  9013. +
  9014. +/* no one supports this operation, currently */
  9015. +#if 0
  9016. +static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync)
  9017. +{
  9018. + int err;
  9019. + struct au_pin pin;
  9020. + struct dentry *dentry;
  9021. + struct inode *inode;
  9022. + struct file *file, *h_file;
  9023. +
  9024. + file = kio->ki_filp;
  9025. + dentry = file->f_dentry;
  9026. + inode = dentry->d_inode;
  9027. + au_mtx_and_read_lock(inode);
  9028. +
  9029. + err = 0; /* -EBADF; */ /* posix? */
  9030. + if (unlikely(!(file->f_mode & FMODE_WRITE)))
  9031. + goto out;
  9032. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  9033. + if (unlikely(err))
  9034. + goto out;
  9035. +
  9036. + err = au_ready_to_write(file, -1, &pin);
  9037. + di_downgrade_lock(dentry, AuLock_IR);
  9038. + if (unlikely(err))
  9039. + goto out_unlock;
  9040. + au_unpin(&pin);
  9041. +
  9042. + err = -ENOSYS;
  9043. + h_file = au_hf_top(file);
  9044. + if (h_file->f_op && h_file->f_op->aio_fsync) {
  9045. + struct dentry *h_d;
  9046. + struct mutex *h_mtx;
  9047. +
  9048. + h_d = h_file->f_dentry;
  9049. + h_mtx = &h_d->d_inode->i_mutex;
  9050. + if (!is_sync_kiocb(kio)) {
  9051. + get_file(h_file);
  9052. + fput(file);
  9053. + }
  9054. + kio->ki_filp = h_file;
  9055. + err = h_file->f_op->aio_fsync(kio, datasync);
  9056. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  9057. + if (!err)
  9058. + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
  9059. + /*ignore*/
  9060. + au_cpup_attr_timesizes(inode);
  9061. + mutex_unlock(h_mtx);
  9062. + }
  9063. +
  9064. +out_unlock:
  9065. + di_read_unlock(dentry, AuLock_IR);
  9066. + fi_write_unlock(file);
  9067. +out:
  9068. + si_read_unlock(inode->sb);
  9069. + mutex_unlock(&inode->i_mutex);
  9070. + return err;
  9071. +}
  9072. +#endif
  9073. +
  9074. +static int aufs_fasync(int fd, struct file *file, int flag)
  9075. +{
  9076. + int err;
  9077. + struct file *h_file;
  9078. + struct dentry *dentry;
  9079. + struct super_block *sb;
  9080. +
  9081. + dentry = file->f_dentry;
  9082. + sb = dentry->d_sb;
  9083. + si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
  9084. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
  9085. + if (unlikely(err))
  9086. + goto out;
  9087. +
  9088. + h_file = au_hf_top(file);
  9089. + if (h_file->f_op && h_file->f_op->fasync)
  9090. + err = h_file->f_op->fasync(fd, h_file, flag);
  9091. +
  9092. + di_read_unlock(dentry, AuLock_IR);
  9093. + fi_read_unlock(file);
  9094. +
  9095. +out:
  9096. + si_read_unlock(sb);
  9097. + return err;
  9098. +}
  9099. +
  9100. +/* ---------------------------------------------------------------------- */
  9101. +
  9102. +/* no one supports this operation, currently */
  9103. +#if 0
  9104. +static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
  9105. + size_t len, loff_t *pos , int more)
  9106. +{
  9107. +}
  9108. +#endif
  9109. +
  9110. +/* ---------------------------------------------------------------------- */
  9111. +
  9112. +const struct file_operations aufs_file_fop = {
  9113. + .owner = THIS_MODULE,
  9114. + /*
  9115. + * while generic_file_llseek/_unlocked() don't use BKL,
  9116. + * don't use it since it operates file->f_mapping->host.
  9117. + * in aufs, it may be a real file and may confuse users by UDBA.
  9118. + */
  9119. + /* .llseek = generic_file_llseek, */
  9120. +
  9121. + .read = aufs_read,
  9122. + .write = aufs_write,
  9123. + .aio_read = aufs_aio_read,
  9124. + .aio_write = aufs_aio_write,
  9125. +#ifdef CONFIG_AUFS_POLL
  9126. + .poll = aufs_poll,
  9127. +#endif
  9128. + .unlocked_ioctl = aufs_ioctl_nondir,
  9129. +#ifdef CONFIG_COMPAT
  9130. + .compat_ioctl = aufs_ioctl_nondir, /* same */
  9131. +#endif
  9132. + .mmap = aufs_mmap,
  9133. + .open = aufs_open_nondir,
  9134. + .flush = aufs_flush_nondir,
  9135. + .release = aufs_release_nondir,
  9136. + .fsync = aufs_fsync_nondir,
  9137. + /* .aio_fsync = aufs_aio_fsync_nondir, */
  9138. + .fasync = aufs_fasync,
  9139. + /* .sendpage = aufs_sendpage, */
  9140. + .splice_write = aufs_splice_write,
  9141. + .splice_read = aufs_splice_read,
  9142. +#if 0
  9143. + .aio_splice_write = aufs_aio_splice_write,
  9144. + .aio_splice_read = aufs_aio_splice_read
  9145. +#endif
  9146. +};
  9147. diff -Nur linux-2.6.37.orig/fs/aufs/f_op_sp.c linux-2.6.37/fs/aufs/f_op_sp.c
  9148. --- linux-2.6.37.orig/fs/aufs/f_op_sp.c 1970-01-01 01:00:00.000000000 +0100
  9149. +++ linux-2.6.37/fs/aufs/f_op_sp.c 2011-01-11 20:15:11.000000000 +0100
  9150. @@ -0,0 +1,299 @@
  9151. +/*
  9152. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  9153. + *
  9154. + * This program, aufs is free software; you can redistribute it and/or modify
  9155. + * it under the terms of the GNU General Public License as published by
  9156. + * the Free Software Foundation; either version 2 of the License, or
  9157. + * (at your option) any later version.
  9158. + *
  9159. + * This program is distributed in the hope that it will be useful,
  9160. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9161. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9162. + * GNU General Public License for more details.
  9163. + *
  9164. + * You should have received a copy of the GNU General Public License
  9165. + * along with this program; if not, write to the Free Software
  9166. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  9167. + */
  9168. +
  9169. +/*
  9170. + * file operations for special files.
  9171. + * while they exist in aufs virtually,
  9172. + * their file I/O is handled out of aufs.
  9173. + */
  9174. +
  9175. +#include <linux/fs_stack.h>
  9176. +#include "aufs.h"
  9177. +
  9178. +static ssize_t aufs_aio_read_sp(struct kiocb *kio, const struct iovec *iov,
  9179. + unsigned long nv, loff_t pos)
  9180. +{
  9181. + ssize_t err;
  9182. + aufs_bindex_t bstart;
  9183. + unsigned char wbr;
  9184. + struct file *file, *h_file;
  9185. + struct super_block *sb;
  9186. +
  9187. + file = kio->ki_filp;
  9188. + sb = file->f_dentry->d_sb;
  9189. + si_read_lock(sb, AuLock_FLUSH);
  9190. + fi_read_lock(file);
  9191. + bstart = au_fbstart(file);
  9192. + h_file = au_hf_top(file);
  9193. + fi_read_unlock(file);
  9194. + wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
  9195. + si_read_unlock(sb);
  9196. +
  9197. + /* do not change the file in kio */
  9198. + AuDebugOn(!h_file->f_op || !h_file->f_op->aio_read);
  9199. + err = h_file->f_op->aio_read(kio, iov, nv, pos);
  9200. + if (err > 0 && wbr)
  9201. + file_accessed(h_file);
  9202. +
  9203. + return err;
  9204. +}
  9205. +
  9206. +static ssize_t aufs_aio_write_sp(struct kiocb *kio, const struct iovec *iov,
  9207. + unsigned long nv, loff_t pos)
  9208. +{
  9209. + ssize_t err;
  9210. + aufs_bindex_t bstart;
  9211. + unsigned char wbr;
  9212. + struct super_block *sb;
  9213. + struct file *file, *h_file;
  9214. +
  9215. + file = kio->ki_filp;
  9216. + sb = file->f_dentry->d_sb;
  9217. + si_read_lock(sb, AuLock_FLUSH);
  9218. + fi_read_lock(file);
  9219. + bstart = au_fbstart(file);
  9220. + h_file = au_hf_top(file);
  9221. + fi_read_unlock(file);
  9222. + wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
  9223. + si_read_unlock(sb);
  9224. +
  9225. + /* do not change the file in kio */
  9226. + AuDebugOn(!h_file->f_op || !h_file->f_op->aio_write);
  9227. + err = h_file->f_op->aio_write(kio, iov, nv, pos);
  9228. + if (err > 0 && wbr)
  9229. + file_update_time(h_file);
  9230. +
  9231. + return err;
  9232. +}
  9233. +
  9234. +/* ---------------------------------------------------------------------- */
  9235. +
  9236. +static int aufs_release_sp(struct inode *inode, struct file *file)
  9237. +{
  9238. + int err;
  9239. + struct file *h_file;
  9240. +
  9241. + fi_read_lock(file);
  9242. + h_file = au_hf_top(file);
  9243. + fi_read_unlock(file);
  9244. + /* close this fifo in aufs */
  9245. + err = h_file->f_op->release(inode, file); /* ignore */
  9246. + aufs_release_nondir(inode, file); /* ignore */
  9247. + return err;
  9248. +}
  9249. +
  9250. +/* ---------------------------------------------------------------------- */
  9251. +
  9252. +/* currently, support only FIFO */
  9253. +enum {
  9254. + AuSp_FIFO, AuSp_FIFO_R, AuSp_FIFO_W, AuSp_FIFO_RW,
  9255. + /* AuSp_SOCK, AuSp_CHR, AuSp_BLK, */
  9256. + AuSp_Last
  9257. +};
  9258. +static int aufs_open_sp(struct inode *inode, struct file *file);
  9259. +static struct au_sp_fop {
  9260. + int done;
  9261. + struct file_operations fop; /* not 'const' */
  9262. + spinlock_t spin;
  9263. +} au_sp_fop[AuSp_Last] = {
  9264. + [AuSp_FIFO] = {
  9265. + .fop = {
  9266. + .owner = THIS_MODULE,
  9267. + .open = aufs_open_sp
  9268. + }
  9269. + }
  9270. +};
  9271. +
  9272. +static void au_init_fop_sp(struct file *file)
  9273. +{
  9274. + struct au_sp_fop *p;
  9275. + int i;
  9276. + struct file *h_file;
  9277. +
  9278. + p = au_sp_fop;
  9279. + if (unlikely(!p->done)) {
  9280. + /* initialize first time only */
  9281. + static DEFINE_SPINLOCK(spin);
  9282. +
  9283. + spin_lock(&spin);
  9284. + if (!p->done) {
  9285. + BUILD_BUG_ON(sizeof(au_sp_fop)/sizeof(*au_sp_fop)
  9286. + != AuSp_Last);
  9287. + for (i = 0; i < AuSp_Last; i++)
  9288. + spin_lock_init(&p[i].spin);
  9289. + p->done = 1;
  9290. + }
  9291. + spin_unlock(&spin);
  9292. + }
  9293. +
  9294. + switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) {
  9295. + case FMODE_READ:
  9296. + i = AuSp_FIFO_R;
  9297. + break;
  9298. + case FMODE_WRITE:
  9299. + i = AuSp_FIFO_W;
  9300. + break;
  9301. + case FMODE_READ | FMODE_WRITE:
  9302. + i = AuSp_FIFO_RW;
  9303. + break;
  9304. + default:
  9305. + BUG();
  9306. + }
  9307. +
  9308. + p += i;
  9309. + if (unlikely(!p->done)) {
  9310. + /* initialize first time only */
  9311. + h_file = au_hf_top(file);
  9312. + spin_lock(&p->spin);
  9313. + if (!p->done) {
  9314. + p->fop = *h_file->f_op;
  9315. + p->fop.owner = THIS_MODULE;
  9316. + if (p->fop.aio_read)
  9317. + p->fop.aio_read = aufs_aio_read_sp;
  9318. + if (p->fop.aio_write)
  9319. + p->fop.aio_write = aufs_aio_write_sp;
  9320. + p->fop.release = aufs_release_sp;
  9321. + p->done = 1;
  9322. + }
  9323. + spin_unlock(&p->spin);
  9324. + }
  9325. + file->f_op = &p->fop;
  9326. +}
  9327. +
  9328. +static int au_cpup_sp(struct dentry *dentry)
  9329. +{
  9330. + int err;
  9331. + aufs_bindex_t bcpup;
  9332. + struct au_pin pin;
  9333. + struct au_wr_dir_args wr_dir_args = {
  9334. + .force_btgt = -1,
  9335. + .flags = 0
  9336. + };
  9337. +
  9338. + AuDbg("%.*s\n", AuDLNPair(dentry));
  9339. +
  9340. + di_read_unlock(dentry, AuLock_IR);
  9341. + di_write_lock_child(dentry);
  9342. + err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
  9343. + if (unlikely(err < 0))
  9344. + goto out;
  9345. + bcpup = err;
  9346. + err = 0;
  9347. + if (bcpup == au_dbstart(dentry))
  9348. + goto out; /* success */
  9349. +
  9350. + err = au_pin(&pin, dentry, bcpup, au_opt_udba(dentry->d_sb),
  9351. + AuPin_MNT_WRITE);
  9352. + if (!err) {
  9353. + err = au_sio_cpup_simple(dentry, bcpup, -1, AuCpup_DTIME);
  9354. + au_unpin(&pin);
  9355. + }
  9356. +
  9357. +out:
  9358. + di_downgrade_lock(dentry, AuLock_IR);
  9359. + return err;
  9360. +}
  9361. +
  9362. +static int au_do_open_sp(struct file *file, int flags)
  9363. +{
  9364. + int err;
  9365. + struct dentry *dentry;
  9366. + struct super_block *sb;
  9367. + struct file *h_file;
  9368. + struct inode *h_inode;
  9369. +
  9370. + dentry = file->f_dentry;
  9371. + AuDbg("%.*s\n", AuDLNPair(dentry));
  9372. +
  9373. + /*
  9374. + * try copying-up.
  9375. + * operate on the ro branch is not an error.
  9376. + */
  9377. + au_cpup_sp(dentry); /* ignore */
  9378. +
  9379. + /* prepare h_file */
  9380. + err = au_do_open_nondir(file, vfsub_file_flags(file));
  9381. + if (unlikely(err))
  9382. + goto out;
  9383. +
  9384. + sb = dentry->d_sb;
  9385. + h_file = au_hf_top(file);
  9386. + h_inode = h_file->f_dentry->d_inode;
  9387. + di_read_unlock(dentry, AuLock_IR);
  9388. + fi_write_unlock(file);
  9389. + si_read_unlock(sb);
  9390. + /* open this fifo in aufs */
  9391. + err = h_inode->i_fop->open(file->f_dentry->d_inode, file);
  9392. + si_noflush_read_lock(sb);
  9393. + fi_write_lock(file);
  9394. + di_read_lock_child(dentry, AuLock_IR);
  9395. + if (!err)
  9396. + au_init_fop_sp(file);
  9397. +
  9398. +out:
  9399. + return err;
  9400. +}
  9401. +
  9402. +static int aufs_open_sp(struct inode *inode, struct file *file)
  9403. +{
  9404. + int err;
  9405. + struct super_block *sb;
  9406. +
  9407. + sb = file->f_dentry->d_sb;
  9408. + si_read_lock(sb, AuLock_FLUSH);
  9409. + err = au_do_open(file, au_do_open_sp, /*fidir*/NULL);
  9410. + si_read_unlock(sb);
  9411. + return err;
  9412. +}
  9413. +
  9414. +/* ---------------------------------------------------------------------- */
  9415. +
  9416. +void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev)
  9417. +{
  9418. + init_special_inode(inode, mode, rdev);
  9419. +
  9420. + switch (mode & S_IFMT) {
  9421. + case S_IFIFO:
  9422. + inode->i_fop = &au_sp_fop[AuSp_FIFO].fop;
  9423. + /*FALLTHROUGH*/
  9424. + case S_IFCHR:
  9425. + case S_IFBLK:
  9426. + case S_IFSOCK:
  9427. + break;
  9428. + default:
  9429. + AuDebugOn(1);
  9430. + }
  9431. +}
  9432. +
  9433. +int au_special_file(umode_t mode)
  9434. +{
  9435. + int ret;
  9436. +
  9437. + ret = 0;
  9438. + switch (mode & S_IFMT) {
  9439. + case S_IFIFO:
  9440. +#if 0
  9441. + case S_IFCHR:
  9442. + case S_IFBLK:
  9443. + case S_IFSOCK:
  9444. +#endif
  9445. + ret = 1;
  9446. + }
  9447. +
  9448. + return ret;
  9449. +}
  9450. diff -Nur linux-2.6.37.orig/fs/aufs/file.c linux-2.6.37/fs/aufs/file.c
  9451. --- linux-2.6.37.orig/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
  9452. +++ linux-2.6.37/fs/aufs/file.c 2011-01-11 20:15:11.000000000 +0100
  9453. @@ -0,0 +1,676 @@
  9454. +/*
  9455. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  9456. + *
  9457. + * This program, aufs is free software; you can redistribute it and/or modify
  9458. + * it under the terms of the GNU General Public License as published by
  9459. + * the Free Software Foundation; either version 2 of the License, or
  9460. + * (at your option) any later version.
  9461. + *
  9462. + * This program is distributed in the hope that it will be useful,
  9463. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9464. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9465. + * GNU General Public License for more details.
  9466. + *
  9467. + * You should have received a copy of the GNU General Public License
  9468. + * along with this program; if not, write to the Free Software
  9469. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  9470. + */
  9471. +
  9472. +/*
  9473. + * handling file/dir, and address_space operation
  9474. + */
  9475. +
  9476. +#include <linux/file.h>
  9477. +#include <linux/fsnotify.h>
  9478. +#include <linux/namei.h>
  9479. +#include <linux/pagemap.h>
  9480. +#include "aufs.h"
  9481. +
  9482. +/* drop flags for writing */
  9483. +unsigned int au_file_roflags(unsigned int flags)
  9484. +{
  9485. + flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
  9486. + flags |= O_RDONLY | O_NOATIME;
  9487. + return flags;
  9488. +}
  9489. +
  9490. +/* common functions to regular file and dir */
  9491. +struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
  9492. + struct file *file)
  9493. +{
  9494. + struct file *h_file;
  9495. + struct dentry *h_dentry;
  9496. + struct inode *h_inode;
  9497. + struct super_block *sb;
  9498. + struct au_branch *br;
  9499. + struct path h_path;
  9500. + int err, exec_flag;
  9501. +
  9502. + /* a race condition can happen between open and unlink/rmdir */
  9503. + h_file = ERR_PTR(-ENOENT);
  9504. + h_dentry = au_h_dptr(dentry, bindex);
  9505. + if (au_test_nfsd() && !h_dentry)
  9506. + goto out;
  9507. + h_inode = h_dentry->d_inode;
  9508. + if (au_test_nfsd() && !h_inode)
  9509. + goto out;
  9510. + if (unlikely((!d_unhashed(dentry) && au_d_removed(h_dentry))
  9511. + || !h_inode
  9512. + /* || !dentry->d_inode->i_nlink */
  9513. + ))
  9514. + goto out;
  9515. +
  9516. + sb = dentry->d_sb;
  9517. + br = au_sbr(sb, bindex);
  9518. + h_file = ERR_PTR(-EACCES);
  9519. + exec_flag = flags & vfsub_fmode_to_uint(FMODE_EXEC);
  9520. + if (exec_flag && (br->br_mnt->mnt_flags & MNT_NOEXEC))
  9521. + goto out;
  9522. +
  9523. + /* drop flags for writing */
  9524. + if (au_test_ro(sb, bindex, dentry->d_inode))
  9525. + flags = au_file_roflags(flags);
  9526. + flags &= ~O_CREAT;
  9527. + atomic_inc(&br->br_count);
  9528. + h_path.dentry = h_dentry;
  9529. + h_path.mnt = br->br_mnt;
  9530. + if (!au_special_file(h_inode->i_mode))
  9531. + h_file = vfsub_dentry_open(&h_path, flags);
  9532. + else {
  9533. + /* this block depends upon the configuration */
  9534. + di_read_unlock(dentry, AuLock_IR);
  9535. + fi_write_unlock(file);
  9536. + si_read_unlock(sb);
  9537. + h_file = vfsub_dentry_open(&h_path, flags);
  9538. + si_noflush_read_lock(sb);
  9539. + fi_write_lock(file);
  9540. + di_read_lock_child(dentry, AuLock_IR);
  9541. + }
  9542. + if (IS_ERR(h_file))
  9543. + goto out_br;
  9544. +
  9545. + if (exec_flag) {
  9546. + err = deny_write_access(h_file);
  9547. + if (unlikely(err)) {
  9548. + fput(h_file);
  9549. + h_file = ERR_PTR(err);
  9550. + goto out_br;
  9551. + }
  9552. + }
  9553. + fsnotify_open(h_file);
  9554. + goto out; /* success */
  9555. +
  9556. +out_br:
  9557. + atomic_dec(&br->br_count);
  9558. +out:
  9559. + return h_file;
  9560. +}
  9561. +
  9562. +int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
  9563. + struct au_fidir *fidir)
  9564. +{
  9565. + int err;
  9566. + struct dentry *dentry;
  9567. +
  9568. + err = au_finfo_init(file, fidir);
  9569. + if (unlikely(err))
  9570. + goto out;
  9571. +
  9572. + dentry = file->f_dentry;
  9573. + di_read_lock_child(dentry, AuLock_IR);
  9574. + err = open(file, vfsub_file_flags(file));
  9575. + di_read_unlock(dentry, AuLock_IR);
  9576. +
  9577. + fi_write_unlock(file);
  9578. + if (unlikely(err)) {
  9579. + au_fi(file)->fi_hdir = NULL;
  9580. + au_finfo_fin(file);
  9581. + }
  9582. +
  9583. +out:
  9584. + return err;
  9585. +}
  9586. +
  9587. +int au_reopen_nondir(struct file *file)
  9588. +{
  9589. + int err;
  9590. + aufs_bindex_t bstart;
  9591. + struct dentry *dentry;
  9592. + struct file *h_file, *h_file_tmp;
  9593. +
  9594. + dentry = file->f_dentry;
  9595. + AuDebugOn(au_special_file(dentry->d_inode->i_mode));
  9596. + bstart = au_dbstart(dentry);
  9597. + h_file_tmp = NULL;
  9598. + if (au_fbstart(file) == bstart) {
  9599. + h_file = au_hf_top(file);
  9600. + if (file->f_mode == h_file->f_mode)
  9601. + return 0; /* success */
  9602. + h_file_tmp = h_file;
  9603. + get_file(h_file_tmp);
  9604. + au_set_h_fptr(file, bstart, NULL);
  9605. + }
  9606. + AuDebugOn(au_fi(file)->fi_hdir);
  9607. + AuDebugOn(au_fbstart(file) < bstart);
  9608. +
  9609. + h_file = au_h_open(dentry, bstart, vfsub_file_flags(file) & ~O_TRUNC,
  9610. + file);
  9611. + err = PTR_ERR(h_file);
  9612. + if (IS_ERR(h_file))
  9613. + goto out; /* todo: close all? */
  9614. +
  9615. + err = 0;
  9616. + au_set_fbstart(file, bstart);
  9617. + au_set_h_fptr(file, bstart, h_file);
  9618. + au_update_figen(file);
  9619. + /* todo: necessary? */
  9620. + /* file->f_ra = h_file->f_ra; */
  9621. +
  9622. +out:
  9623. + if (h_file_tmp)
  9624. + fput(h_file_tmp);
  9625. + return err;
  9626. +}
  9627. +
  9628. +/* ---------------------------------------------------------------------- */
  9629. +
  9630. +static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
  9631. + struct dentry *hi_wh)
  9632. +{
  9633. + int err;
  9634. + aufs_bindex_t bstart;
  9635. + struct au_dinfo *dinfo;
  9636. + struct dentry *h_dentry;
  9637. + struct au_hdentry *hdp;
  9638. +
  9639. + dinfo = au_di(file->f_dentry);
  9640. + AuRwMustWriteLock(&dinfo->di_rwsem);
  9641. +
  9642. + bstart = dinfo->di_bstart;
  9643. + dinfo->di_bstart = btgt;
  9644. + hdp = dinfo->di_hdentry;
  9645. + h_dentry = hdp[0 + btgt].hd_dentry;
  9646. + hdp[0 + btgt].hd_dentry = hi_wh;
  9647. + err = au_reopen_nondir(file);
  9648. + hdp[0 + btgt].hd_dentry = h_dentry;
  9649. + dinfo->di_bstart = bstart;
  9650. +
  9651. + return err;
  9652. +}
  9653. +
  9654. +static int au_ready_to_write_wh(struct file *file, loff_t len,
  9655. + aufs_bindex_t bcpup)
  9656. +{
  9657. + int err;
  9658. + struct inode *inode, *h_inode;
  9659. + struct dentry *dentry, *h_dentry, *hi_wh;
  9660. +
  9661. + dentry = file->f_dentry;
  9662. + au_update_dbstart(dentry);
  9663. + inode = dentry->d_inode;
  9664. + h_inode = NULL;
  9665. + if (au_dbstart(dentry) <= bcpup && au_dbend(dentry) >= bcpup) {
  9666. + h_dentry = au_h_dptr(dentry, bcpup);
  9667. + if (h_dentry)
  9668. + h_inode = h_dentry->d_inode;
  9669. + }
  9670. + hi_wh = au_hi_wh(inode, bcpup);
  9671. + if (!hi_wh && !h_inode)
  9672. + err = au_sio_cpup_wh(dentry, bcpup, len, file);
  9673. + else
  9674. + /* already copied-up after unlink */
  9675. + err = au_reopen_wh(file, bcpup, hi_wh);
  9676. +
  9677. + if (!err
  9678. + && inode->i_nlink > 1
  9679. + && au_opt_test(au_mntflags(dentry->d_sb), PLINK))
  9680. + au_plink_append(inode, bcpup, au_h_dptr(dentry, bcpup));
  9681. +
  9682. + return err;
  9683. +}
  9684. +
  9685. +/*
  9686. + * prepare the @file for writing.
  9687. + */
  9688. +int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
  9689. +{
  9690. + int err;
  9691. + aufs_bindex_t bstart, bcpup, dbstart;
  9692. + struct dentry *dentry, *parent, *h_dentry;
  9693. + struct inode *h_inode, *inode;
  9694. + struct super_block *sb;
  9695. + struct file *h_file;
  9696. +
  9697. + dentry = file->f_dentry;
  9698. + sb = dentry->d_sb;
  9699. + inode = dentry->d_inode;
  9700. + AuDebugOn(au_special_file(inode->i_mode));
  9701. + bstart = au_fbstart(file);
  9702. + err = au_test_ro(sb, bstart, inode);
  9703. + if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
  9704. + err = au_pin(pin, dentry, bstart, AuOpt_UDBA_NONE, /*flags*/0);
  9705. + goto out;
  9706. + }
  9707. +
  9708. + /* need to cpup or reopen */
  9709. + parent = dget_parent(dentry);
  9710. + di_write_lock_parent(parent);
  9711. + err = AuWbrCopyup(au_sbi(sb), dentry);
  9712. + bcpup = err;
  9713. + if (unlikely(err < 0))
  9714. + goto out_dgrade;
  9715. + err = 0;
  9716. +
  9717. + if (!d_unhashed(dentry) && !au_h_dptr(parent, bcpup)) {
  9718. + err = au_cpup_dirs(dentry, bcpup);
  9719. + if (unlikely(err))
  9720. + goto out_dgrade;
  9721. + }
  9722. +
  9723. + err = au_pin(pin, dentry, bcpup, AuOpt_UDBA_NONE,
  9724. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  9725. + if (unlikely(err))
  9726. + goto out_dgrade;
  9727. +
  9728. + h_dentry = au_hf_top(file)->f_dentry;
  9729. + h_inode = h_dentry->d_inode;
  9730. + dbstart = au_dbstart(dentry);
  9731. + if (dbstart <= bcpup) {
  9732. + h_dentry = au_h_dptr(dentry, bcpup);
  9733. + AuDebugOn(!h_dentry);
  9734. + h_inode = h_dentry->d_inode;
  9735. + AuDebugOn(!h_inode);
  9736. + bstart = bcpup;
  9737. + }
  9738. +
  9739. + if (dbstart <= bcpup /* just reopen */
  9740. + || !d_unhashed(dentry) /* copyup and reopen */
  9741. + ) {
  9742. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  9743. + h_file = au_h_open_pre(dentry, bstart);
  9744. + if (IS_ERR(h_file)) {
  9745. + err = PTR_ERR(h_file);
  9746. + h_file = NULL;
  9747. + } else {
  9748. + di_downgrade_lock(parent, AuLock_IR);
  9749. + if (dbstart > bcpup)
  9750. + err = au_sio_cpup_simple(dentry, bcpup, len,
  9751. + AuCpup_DTIME);
  9752. + if (!err)
  9753. + err = au_reopen_nondir(file);
  9754. + }
  9755. + mutex_unlock(&h_inode->i_mutex);
  9756. + au_h_open_post(dentry, bstart, h_file);
  9757. + } else { /* copyup as wh and reopen */
  9758. + /*
  9759. + * since writable hfsplus branch is not supported,
  9760. + * h_open_pre/post() are unnecessary.
  9761. + */
  9762. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  9763. + err = au_ready_to_write_wh(file, len, bcpup);
  9764. + di_downgrade_lock(parent, AuLock_IR);
  9765. + mutex_unlock(&h_inode->i_mutex);
  9766. + }
  9767. +
  9768. + if (!err) {
  9769. + au_pin_set_parent_lflag(pin, /*lflag*/0);
  9770. + goto out_dput; /* success */
  9771. + }
  9772. + au_unpin(pin);
  9773. + goto out_unlock;
  9774. +
  9775. +out_dgrade:
  9776. + di_downgrade_lock(parent, AuLock_IR);
  9777. +out_unlock:
  9778. + di_read_unlock(parent, AuLock_IR);
  9779. +out_dput:
  9780. + dput(parent);
  9781. +out:
  9782. + return err;
  9783. +}
  9784. +
  9785. +/* ---------------------------------------------------------------------- */
  9786. +
  9787. +int au_do_flush(struct file *file, fl_owner_t id,
  9788. + int (*flush)(struct file *file, fl_owner_t id))
  9789. +{
  9790. + int err;
  9791. + struct dentry *dentry;
  9792. + struct super_block *sb;
  9793. + struct inode *inode;
  9794. +
  9795. + dentry = file->f_dentry;
  9796. + sb = dentry->d_sb;
  9797. + inode = dentry->d_inode;
  9798. + si_noflush_read_lock(sb);
  9799. + fi_read_lock(file);
  9800. + ii_read_lock_child(inode);
  9801. +
  9802. + err = flush(file, id);
  9803. + au_cpup_attr_timesizes(inode);
  9804. +
  9805. + ii_read_unlock(inode);
  9806. + fi_read_unlock(file);
  9807. + si_read_unlock(sb);
  9808. + return err;
  9809. +}
  9810. +
  9811. +/* ---------------------------------------------------------------------- */
  9812. +
  9813. +static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
  9814. +{
  9815. + int err;
  9816. + aufs_bindex_t bstart;
  9817. + struct au_pin pin;
  9818. + struct au_finfo *finfo;
  9819. + struct dentry *dentry, *parent, *hi_wh;
  9820. + struct inode *inode;
  9821. + struct super_block *sb;
  9822. +
  9823. + FiMustWriteLock(file);
  9824. +
  9825. + err = 0;
  9826. + finfo = au_fi(file);
  9827. + dentry = file->f_dentry;
  9828. + sb = dentry->d_sb;
  9829. + inode = dentry->d_inode;
  9830. + bstart = au_ibstart(inode);
  9831. + if (bstart == finfo->fi_btop || IS_ROOT(dentry))
  9832. + goto out;
  9833. +
  9834. + parent = dget_parent(dentry);
  9835. + if (au_test_ro(sb, bstart, inode)) {
  9836. + di_read_lock_parent(parent, !AuLock_IR);
  9837. + err = AuWbrCopyup(au_sbi(sb), dentry);
  9838. + bstart = err;
  9839. + di_read_unlock(parent, !AuLock_IR);
  9840. + if (unlikely(err < 0))
  9841. + goto out_parent;
  9842. + err = 0;
  9843. + }
  9844. +
  9845. + di_read_lock_parent(parent, AuLock_IR);
  9846. + hi_wh = au_hi_wh(inode, bstart);
  9847. + if (!S_ISDIR(inode->i_mode)
  9848. + && au_opt_test(au_mntflags(sb), PLINK)
  9849. + && au_plink_test(inode)
  9850. + && !d_unhashed(dentry)) {
  9851. + err = au_test_and_cpup_dirs(dentry, bstart);
  9852. + if (unlikely(err))
  9853. + goto out_unlock;
  9854. +
  9855. + /* always superio. */
  9856. + err = au_pin(&pin, dentry, bstart, AuOpt_UDBA_NONE,
  9857. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  9858. + if (!err)
  9859. + err = au_sio_cpup_simple(dentry, bstart, -1,
  9860. + AuCpup_DTIME);
  9861. + au_unpin(&pin);
  9862. + } else if (hi_wh) {
  9863. + /* already copied-up after unlink */
  9864. + err = au_reopen_wh(file, bstart, hi_wh);
  9865. + *need_reopen = 0;
  9866. + }
  9867. +
  9868. +out_unlock:
  9869. + di_read_unlock(parent, AuLock_IR);
  9870. +out_parent:
  9871. + dput(parent);
  9872. +out:
  9873. + return err;
  9874. +}
  9875. +
  9876. +static void au_do_refresh_dir(struct file *file)
  9877. +{
  9878. + aufs_bindex_t bindex, bend, new_bindex, brid;
  9879. + struct au_hfile *p, tmp, *q;
  9880. + struct au_finfo *finfo;
  9881. + struct super_block *sb;
  9882. + struct au_fidir *fidir;
  9883. +
  9884. + FiMustWriteLock(file);
  9885. +
  9886. + sb = file->f_dentry->d_sb;
  9887. + finfo = au_fi(file);
  9888. + fidir = finfo->fi_hdir;
  9889. + AuDebugOn(!fidir);
  9890. + p = fidir->fd_hfile + finfo->fi_btop;
  9891. + brid = p->hf_br->br_id;
  9892. + bend = fidir->fd_bbot;
  9893. + for (bindex = finfo->fi_btop; bindex <= bend; bindex++, p++) {
  9894. + if (!p->hf_file)
  9895. + continue;
  9896. +
  9897. + new_bindex = au_br_index(sb, p->hf_br->br_id);
  9898. + if (new_bindex == bindex)
  9899. + continue;
  9900. + if (new_bindex < 0) {
  9901. + au_set_h_fptr(file, bindex, NULL);
  9902. + continue;
  9903. + }
  9904. +
  9905. + /* swap two lower inode, and loop again */
  9906. + q = fidir->fd_hfile + new_bindex;
  9907. + tmp = *q;
  9908. + *q = *p;
  9909. + *p = tmp;
  9910. + if (tmp.hf_file) {
  9911. + bindex--;
  9912. + p--;
  9913. + }
  9914. + }
  9915. +
  9916. + p = fidir->fd_hfile;
  9917. + if (!au_test_mmapped(file) && !au_d_removed(file->f_dentry)) {
  9918. + bend = au_sbend(sb);
  9919. + for (finfo->fi_btop = 0; finfo->fi_btop <= bend;
  9920. + finfo->fi_btop++, p++)
  9921. + if (p->hf_file) {
  9922. + if (p->hf_file->f_dentry
  9923. + && p->hf_file->f_dentry->d_inode)
  9924. + break;
  9925. + else
  9926. + au_hfput(p, file);
  9927. + }
  9928. + } else {
  9929. + bend = au_br_index(sb, brid);
  9930. + for (finfo->fi_btop = 0; finfo->fi_btop < bend;
  9931. + finfo->fi_btop++, p++)
  9932. + if (p->hf_file)
  9933. + au_hfput(p, file);
  9934. + bend = au_sbend(sb);
  9935. + }
  9936. +
  9937. + p = fidir->fd_hfile + bend;
  9938. + for (fidir->fd_bbot = bend; fidir->fd_bbot >= finfo->fi_btop;
  9939. + fidir->fd_bbot--, p--)
  9940. + if (p->hf_file) {
  9941. + if (p->hf_file->f_dentry
  9942. + && p->hf_file->f_dentry->d_inode)
  9943. + break;
  9944. + else
  9945. + au_hfput(p, file);
  9946. + }
  9947. + AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
  9948. +}
  9949. +
  9950. +/*
  9951. + * after branch manipulating, refresh the file.
  9952. + */
  9953. +static int refresh_file(struct file *file, int (*reopen)(struct file *file))
  9954. +{
  9955. + int err, need_reopen;
  9956. + aufs_bindex_t bend, bindex;
  9957. + struct dentry *dentry;
  9958. + struct au_finfo *finfo;
  9959. + struct au_hfile *hfile;
  9960. +
  9961. + dentry = file->f_dentry;
  9962. + finfo = au_fi(file);
  9963. + if (!finfo->fi_hdir) {
  9964. + hfile = &finfo->fi_htop;
  9965. + AuDebugOn(!hfile->hf_file);
  9966. + bindex = au_br_index(dentry->d_sb, hfile->hf_br->br_id);
  9967. + AuDebugOn(bindex < 0);
  9968. + if (bindex != finfo->fi_btop)
  9969. + au_set_fbstart(file, bindex);
  9970. + } else {
  9971. + err = au_fidir_realloc(finfo, au_sbend(dentry->d_sb) + 1);
  9972. + if (unlikely(err))
  9973. + goto out;
  9974. + au_do_refresh_dir(file);
  9975. + }
  9976. +
  9977. + err = 0;
  9978. + need_reopen = 1;
  9979. + if (!au_test_mmapped(file))
  9980. + err = au_file_refresh_by_inode(file, &need_reopen);
  9981. + if (!err && need_reopen && !au_d_removed(dentry))
  9982. + err = reopen(file);
  9983. + if (!err) {
  9984. + au_update_figen(file);
  9985. + goto out; /* success */
  9986. + }
  9987. +
  9988. + /* error, close all lower files */
  9989. + if (finfo->fi_hdir) {
  9990. + bend = au_fbend_dir(file);
  9991. + for (bindex = au_fbstart(file); bindex <= bend; bindex++)
  9992. + au_set_h_fptr(file, bindex, NULL);
  9993. + }
  9994. +
  9995. +out:
  9996. + return err;
  9997. +}
  9998. +
  9999. +/* common function to regular file and dir */
  10000. +int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
  10001. + int wlock)
  10002. +{
  10003. + int err;
  10004. + unsigned int sigen, figen;
  10005. + aufs_bindex_t bstart;
  10006. + unsigned char pseudo_link;
  10007. + struct dentry *dentry;
  10008. + struct inode *inode;
  10009. +
  10010. + err = 0;
  10011. + dentry = file->f_dentry;
  10012. + inode = dentry->d_inode;
  10013. + AuDebugOn(au_special_file(inode->i_mode));
  10014. + sigen = au_sigen(dentry->d_sb);
  10015. + fi_write_lock(file);
  10016. + figen = au_figen(file);
  10017. + di_write_lock_child(dentry);
  10018. + bstart = au_dbstart(dentry);
  10019. + pseudo_link = (bstart != au_ibstart(inode));
  10020. + if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) {
  10021. + if (!wlock) {
  10022. + di_downgrade_lock(dentry, AuLock_IR);
  10023. + fi_downgrade_lock(file);
  10024. + }
  10025. + goto out; /* success */
  10026. + }
  10027. +
  10028. + AuDbg("sigen %d, figen %d\n", sigen, figen);
  10029. + if (au_digen_test(dentry, sigen)) {
  10030. + err = au_reval_dpath(dentry, sigen);
  10031. + AuDebugOn(!err && au_digen_test(dentry, sigen));
  10032. + }
  10033. +
  10034. + if (!err)
  10035. + err = refresh_file(file, reopen);
  10036. + if (!err) {
  10037. + if (!wlock) {
  10038. + di_downgrade_lock(dentry, AuLock_IR);
  10039. + fi_downgrade_lock(file);
  10040. + }
  10041. + } else {
  10042. + di_write_unlock(dentry);
  10043. + fi_write_unlock(file);
  10044. + }
  10045. +
  10046. +out:
  10047. + return err;
  10048. +}
  10049. +
  10050. +/* ---------------------------------------------------------------------- */
  10051. +
  10052. +/* cf. aufs_nopage() */
  10053. +/* for madvise(2) */
  10054. +static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
  10055. +{
  10056. + unlock_page(page);
  10057. + return 0;
  10058. +}
  10059. +
  10060. +/* it will never be called, but necessary to support O_DIRECT */
  10061. +static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb,
  10062. + const struct iovec *iov, loff_t offset,
  10063. + unsigned long nr_segs)
  10064. +{ BUG(); return 0; }
  10065. +
  10066. +/*
  10067. + * it will never be called, but madvise and fadvise behaves differently
  10068. + * when get_xip_mem is defined
  10069. + */
  10070. +static int aufs_get_xip_mem(struct address_space *mapping, pgoff_t pgoff,
  10071. + int create, void **kmem, unsigned long *pfn)
  10072. +{ BUG(); return 0; }
  10073. +
  10074. +/* they will never be called. */
  10075. +#ifdef CONFIG_AUFS_DEBUG
  10076. +static int aufs_write_begin(struct file *file, struct address_space *mapping,
  10077. + loff_t pos, unsigned len, unsigned flags,
  10078. + struct page **pagep, void **fsdata)
  10079. +{ AuUnsupport(); return 0; }
  10080. +static int aufs_write_end(struct file *file, struct address_space *mapping,
  10081. + loff_t pos, unsigned len, unsigned copied,
  10082. + struct page *page, void *fsdata)
  10083. +{ AuUnsupport(); return 0; }
  10084. +static int aufs_writepage(struct page *page, struct writeback_control *wbc)
  10085. +{ AuUnsupport(); return 0; }
  10086. +static void aufs_sync_page(struct page *page)
  10087. +{ AuUnsupport(); }
  10088. +
  10089. +static int aufs_set_page_dirty(struct page *page)
  10090. +{ AuUnsupport(); return 0; }
  10091. +static void aufs_invalidatepage(struct page *page, unsigned long offset)
  10092. +{ AuUnsupport(); }
  10093. +static int aufs_releasepage(struct page *page, gfp_t gfp)
  10094. +{ AuUnsupport(); return 0; }
  10095. +static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
  10096. + struct page *page)
  10097. +{ AuUnsupport(); return 0; }
  10098. +static int aufs_launder_page(struct page *page)
  10099. +{ AuUnsupport(); return 0; }
  10100. +static int aufs_is_partially_uptodate(struct page *page,
  10101. + read_descriptor_t *desc,
  10102. + unsigned long from)
  10103. +{ AuUnsupport(); return 0; }
  10104. +static int aufs_error_remove_page(struct address_space *mapping,
  10105. + struct page *page)
  10106. +{ AuUnsupport(); return 0; }
  10107. +#endif /* CONFIG_AUFS_DEBUG */
  10108. +
  10109. +const struct address_space_operations aufs_aop = {
  10110. + .readpage = aufs_readpage,
  10111. + .direct_IO = aufs_direct_IO,
  10112. + .get_xip_mem = aufs_get_xip_mem,
  10113. +#ifdef CONFIG_AUFS_DEBUG
  10114. + .writepage = aufs_writepage,
  10115. + .sync_page = aufs_sync_page,
  10116. + /* no writepages, because of writepage */
  10117. + .set_page_dirty = aufs_set_page_dirty,
  10118. + /* no readpages, because of readpage */
  10119. + .write_begin = aufs_write_begin,
  10120. + .write_end = aufs_write_end,
  10121. + /* no bmap, no block device */
  10122. + .invalidatepage = aufs_invalidatepage,
  10123. + .releasepage = aufs_releasepage,
  10124. + .migratepage = aufs_migratepage,
  10125. + .launder_page = aufs_launder_page,
  10126. + .is_partially_uptodate = aufs_is_partially_uptodate,
  10127. + .error_remove_page = aufs_error_remove_page
  10128. +#endif /* CONFIG_AUFS_DEBUG */
  10129. +};
  10130. diff -Nur linux-2.6.37.orig/fs/aufs/file.h linux-2.6.37/fs/aufs/file.h
  10131. --- linux-2.6.37.orig/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100
  10132. +++ linux-2.6.37/fs/aufs/file.h 2011-01-11 20:15:11.000000000 +0100
  10133. @@ -0,0 +1,238 @@
  10134. +/*
  10135. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  10136. + *
  10137. + * This program, aufs is free software; you can redistribute it and/or modify
  10138. + * it under the terms of the GNU General Public License as published by
  10139. + * the Free Software Foundation; either version 2 of the License, or
  10140. + * (at your option) any later version.
  10141. + *
  10142. + * This program is distributed in the hope that it will be useful,
  10143. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10144. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10145. + * GNU General Public License for more details.
  10146. + *
  10147. + * You should have received a copy of the GNU General Public License
  10148. + * along with this program; if not, write to the Free Software
  10149. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  10150. + */
  10151. +
  10152. +/*
  10153. + * file operations
  10154. + */
  10155. +
  10156. +#ifndef __AUFS_FILE_H__
  10157. +#define __AUFS_FILE_H__
  10158. +
  10159. +#ifdef __KERNEL__
  10160. +
  10161. +#include <linux/fs.h>
  10162. +#include <linux/poll.h>
  10163. +#include <linux/aufs_type.h>
  10164. +#include "rwsem.h"
  10165. +
  10166. +struct au_branch;
  10167. +struct au_hfile {
  10168. + struct file *hf_file;
  10169. + struct au_branch *hf_br;
  10170. +};
  10171. +
  10172. +struct au_vdir;
  10173. +struct au_fidir {
  10174. + aufs_bindex_t fd_bbot;
  10175. + aufs_bindex_t fd_nent;
  10176. + struct au_vdir *fd_vdir_cache;
  10177. + struct au_hfile fd_hfile[];
  10178. +};
  10179. +
  10180. +static inline int au_fidir_sz(int nent)
  10181. +{
  10182. + AuDebugOn(nent < 0);
  10183. + return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
  10184. +}
  10185. +
  10186. +struct au_finfo {
  10187. + atomic_t fi_generation;
  10188. +
  10189. + struct au_rwsem fi_rwsem;
  10190. + aufs_bindex_t fi_btop;
  10191. +
  10192. + /* do not union them */
  10193. + struct { /* for non-dir */
  10194. + struct au_hfile fi_htop;
  10195. + struct vm_operations_struct *fi_hvmop;
  10196. + struct mutex fi_vm_mtx;
  10197. + struct mutex fi_mmap;
  10198. + };
  10199. + struct au_fidir *fi_hdir; /* for dir only */
  10200. +} ____cacheline_aligned_in_smp;
  10201. +
  10202. +/* ---------------------------------------------------------------------- */
  10203. +
  10204. +/* file.c */
  10205. +extern const struct address_space_operations aufs_aop;
  10206. +unsigned int au_file_roflags(unsigned int flags);
  10207. +struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
  10208. + struct file *file);
  10209. +int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
  10210. + struct au_fidir *fidir);
  10211. +int au_reopen_nondir(struct file *file);
  10212. +struct au_pin;
  10213. +int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
  10214. +int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
  10215. + int wlock);
  10216. +int au_do_flush(struct file *file, fl_owner_t id,
  10217. + int (*flush)(struct file *file, fl_owner_t id));
  10218. +
  10219. +/* poll.c */
  10220. +#ifdef CONFIG_AUFS_POLL
  10221. +unsigned int aufs_poll(struct file *file, poll_table *wait);
  10222. +#endif
  10223. +
  10224. +#ifdef CONFIG_AUFS_BR_HFSPLUS
  10225. +/* hfsplus.c */
  10226. +struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex);
  10227. +void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
  10228. + struct file *h_file);
  10229. +#else
  10230. +static inline
  10231. +struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex)
  10232. +{
  10233. + return NULL;
  10234. +}
  10235. +
  10236. +AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
  10237. + struct file *h_file);
  10238. +#endif
  10239. +
  10240. +/* f_op.c */
  10241. +extern const struct file_operations aufs_file_fop;
  10242. +extern const struct vm_operations_struct aufs_vm_ops;
  10243. +int au_do_open_nondir(struct file *file, int flags);
  10244. +int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
  10245. +
  10246. +#ifdef CONFIG_AUFS_SP_IATTR
  10247. +/* f_op_sp.c */
  10248. +int au_special_file(umode_t mode);
  10249. +void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev);
  10250. +#else
  10251. +AuStubInt0(au_special_file, umode_t mode)
  10252. +static inline void au_init_special_fop(struct inode *inode, umode_t mode,
  10253. + dev_t rdev)
  10254. +{
  10255. + init_special_inode(inode, mode, rdev);
  10256. +}
  10257. +#endif
  10258. +
  10259. +/* finfo.c */
  10260. +void au_hfput(struct au_hfile *hf, struct file *file);
  10261. +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
  10262. + struct file *h_file);
  10263. +
  10264. +void au_update_figen(struct file *file);
  10265. +void au_fi_mmap_lock(struct file *file);
  10266. +void au_fi_mmap_unlock(struct file *file);
  10267. +struct au_fidir *au_fidir_alloc(struct super_block *sb);
  10268. +int au_fidir_realloc(struct au_finfo *finfo, int nbr);
  10269. +
  10270. +void au_fi_init_once(void *_fi);
  10271. +void au_finfo_fin(struct file *file);
  10272. +int au_finfo_init(struct file *file, struct au_fidir *fidir);
  10273. +
  10274. +/* ioctl.c */
  10275. +long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
  10276. +#ifdef CONFIG_COMPAT
  10277. +long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
  10278. + unsigned long arg);
  10279. +#endif
  10280. +
  10281. +/* ---------------------------------------------------------------------- */
  10282. +
  10283. +static inline struct au_finfo *au_fi(struct file *file)
  10284. +{
  10285. + return file->private_data;
  10286. +}
  10287. +
  10288. +/* ---------------------------------------------------------------------- */
  10289. +
  10290. +/*
  10291. + * fi_read_lock, fi_write_lock,
  10292. + * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
  10293. + */
  10294. +AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
  10295. +
  10296. +#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
  10297. +#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
  10298. +#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
  10299. +
  10300. +/* ---------------------------------------------------------------------- */
  10301. +
  10302. +/* todo: hard/soft set? */
  10303. +static inline aufs_bindex_t au_fbstart(struct file *file)
  10304. +{
  10305. + FiMustAnyLock(file);
  10306. + return au_fi(file)->fi_btop;
  10307. +}
  10308. +
  10309. +static inline aufs_bindex_t au_fbend_dir(struct file *file)
  10310. +{
  10311. + FiMustAnyLock(file);
  10312. + AuDebugOn(!au_fi(file)->fi_hdir);
  10313. + return au_fi(file)->fi_hdir->fd_bbot;
  10314. +}
  10315. +
  10316. +static inline struct au_vdir *au_fvdir_cache(struct file *file)
  10317. +{
  10318. + FiMustAnyLock(file);
  10319. + AuDebugOn(!au_fi(file)->fi_hdir);
  10320. + return au_fi(file)->fi_hdir->fd_vdir_cache;
  10321. +}
  10322. +
  10323. +static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex)
  10324. +{
  10325. + FiMustWriteLock(file);
  10326. + au_fi(file)->fi_btop = bindex;
  10327. +}
  10328. +
  10329. +static inline void au_set_fbend_dir(struct file *file, aufs_bindex_t bindex)
  10330. +{
  10331. + FiMustWriteLock(file);
  10332. + AuDebugOn(!au_fi(file)->fi_hdir);
  10333. + au_fi(file)->fi_hdir->fd_bbot = bindex;
  10334. +}
  10335. +
  10336. +static inline void au_set_fvdir_cache(struct file *file,
  10337. + struct au_vdir *vdir_cache)
  10338. +{
  10339. + FiMustWriteLock(file);
  10340. + AuDebugOn(!au_fi(file)->fi_hdir);
  10341. + au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
  10342. +}
  10343. +
  10344. +static inline struct file *au_hf_top(struct file *file)
  10345. +{
  10346. + FiMustAnyLock(file);
  10347. + AuDebugOn(au_fi(file)->fi_hdir);
  10348. + return au_fi(file)->fi_htop.hf_file;
  10349. +}
  10350. +
  10351. +static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
  10352. +{
  10353. + FiMustAnyLock(file);
  10354. + AuDebugOn(!au_fi(file)->fi_hdir);
  10355. + return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
  10356. +}
  10357. +
  10358. +/* todo: memory barrier? */
  10359. +static inline unsigned int au_figen(struct file *f)
  10360. +{
  10361. + return atomic_read(&au_fi(f)->fi_generation);
  10362. +}
  10363. +
  10364. +static inline int au_test_mmapped(struct file *f)
  10365. +{
  10366. + FiMustAnyLock(f);
  10367. + return !!(au_fi(f)->fi_hvmop);
  10368. +}
  10369. +
  10370. +#endif /* __KERNEL__ */
  10371. +#endif /* __AUFS_FILE_H__ */
  10372. diff -Nur linux-2.6.37.orig/fs/aufs/finfo.c linux-2.6.37/fs/aufs/finfo.c
  10373. --- linux-2.6.37.orig/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100
  10374. +++ linux-2.6.37/fs/aufs/finfo.c 2011-01-11 20:15:11.000000000 +0100
  10375. @@ -0,0 +1,174 @@
  10376. +/*
  10377. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  10378. + *
  10379. + * This program, aufs is free software; you can redistribute it and/or modify
  10380. + * it under the terms of the GNU General Public License as published by
  10381. + * the Free Software Foundation; either version 2 of the License, or
  10382. + * (at your option) any later version.
  10383. + *
  10384. + * This program is distributed in the hope that it will be useful,
  10385. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10386. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10387. + * GNU General Public License for more details.
  10388. + *
  10389. + * You should have received a copy of the GNU General Public License
  10390. + * along with this program; if not, write to the Free Software
  10391. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  10392. + */
  10393. +
  10394. +/*
  10395. + * file private data
  10396. + */
  10397. +
  10398. +#include <linux/file.h>
  10399. +#include "aufs.h"
  10400. +
  10401. +void au_hfput(struct au_hfile *hf, struct file *file)
  10402. +{
  10403. + /* todo: direct access f_flags */
  10404. + if (vfsub_file_flags(file) & vfsub_fmode_to_uint(FMODE_EXEC))
  10405. + allow_write_access(hf->hf_file);
  10406. + fput(hf->hf_file);
  10407. + hf->hf_file = NULL;
  10408. + atomic_dec(&hf->hf_br->br_count);
  10409. + hf->hf_br = NULL;
  10410. +}
  10411. +
  10412. +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
  10413. +{
  10414. + struct au_finfo *finfo = au_fi(file);
  10415. + struct au_hfile *hf;
  10416. + struct au_fidir *fidir;
  10417. +
  10418. + fidir = finfo->fi_hdir;
  10419. + if (!fidir) {
  10420. + AuDebugOn(finfo->fi_btop != bindex);
  10421. + hf = &finfo->fi_htop;
  10422. + } else
  10423. + hf = fidir->fd_hfile + bindex;
  10424. +
  10425. + if (hf && hf->hf_file)
  10426. + au_hfput(hf, file);
  10427. + if (val) {
  10428. + FiMustWriteLock(file);
  10429. + hf->hf_file = val;
  10430. + hf->hf_br = au_sbr(file->f_dentry->d_sb, bindex);
  10431. + }
  10432. +}
  10433. +
  10434. +void au_update_figen(struct file *file)
  10435. +{
  10436. + atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_dentry));
  10437. + /* smp_mb(); */ /* atomic_set */
  10438. +}
  10439. +
  10440. +/* ---------------------------------------------------------------------- */
  10441. +
  10442. +void au_fi_mmap_lock(struct file *file)
  10443. +{
  10444. + FiMustWriteLock(file);
  10445. + lockdep_off();
  10446. + mutex_lock(&au_fi(file)->fi_mmap);
  10447. + lockdep_on();
  10448. +}
  10449. +
  10450. +void au_fi_mmap_unlock(struct file *file)
  10451. +{
  10452. + lockdep_off();
  10453. + mutex_unlock(&au_fi(file)->fi_mmap);
  10454. + lockdep_on();
  10455. +}
  10456. +
  10457. +/* ---------------------------------------------------------------------- */
  10458. +
  10459. +struct au_fidir *au_fidir_alloc(struct super_block *sb)
  10460. +{
  10461. + struct au_fidir *fidir;
  10462. + int nbr;
  10463. +
  10464. + nbr = au_sbend(sb) + 1;
  10465. + if (nbr < 2)
  10466. + nbr = 2; /* initial allocate for 2 branches */
  10467. + fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS);
  10468. + if (fidir) {
  10469. + fidir->fd_bbot = -1;
  10470. + fidir->fd_nent = nbr;
  10471. + fidir->fd_vdir_cache = NULL;
  10472. + }
  10473. +
  10474. + return fidir;
  10475. +}
  10476. +
  10477. +int au_fidir_realloc(struct au_finfo *finfo, int nbr)
  10478. +{
  10479. + int err;
  10480. + struct au_fidir *fidir, *p;
  10481. +
  10482. + AuRwMustWriteLock(&finfo->fi_rwsem);
  10483. + fidir = finfo->fi_hdir;
  10484. + AuDebugOn(!fidir);
  10485. +
  10486. + err = -ENOMEM;
  10487. + p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr),
  10488. + GFP_NOFS);
  10489. + if (p) {
  10490. + p->fd_nent = nbr;
  10491. + finfo->fi_hdir = p;
  10492. + err = 0;
  10493. + }
  10494. +
  10495. + return err;
  10496. +}
  10497. +
  10498. +/* ---------------------------------------------------------------------- */
  10499. +
  10500. +void au_finfo_fin(struct file *file)
  10501. +{
  10502. + struct au_finfo *finfo;
  10503. +
  10504. + au_nfiles_dec(file->f_dentry->d_sb);
  10505. +
  10506. + finfo = au_fi(file);
  10507. + AuDebugOn(finfo->fi_hdir);
  10508. + AuRwDestroy(&finfo->fi_rwsem);
  10509. + au_cache_free_finfo(finfo);
  10510. +}
  10511. +
  10512. +void au_fi_init_once(void *_finfo)
  10513. +{
  10514. + struct au_finfo *finfo = _finfo;
  10515. + static struct lock_class_key aufs_fi, aufs_fi_vm, aufs_fi_mmap;
  10516. +
  10517. + au_rw_init(&finfo->fi_rwsem);
  10518. + au_rw_class(&finfo->fi_rwsem, &aufs_fi);
  10519. + mutex_init(&finfo->fi_vm_mtx);
  10520. + lockdep_set_class(&finfo->fi_vm_mtx, &aufs_fi_vm);
  10521. + mutex_init(&finfo->fi_mmap);
  10522. + lockdep_set_class(&finfo->fi_mmap, &aufs_fi_mmap);
  10523. +}
  10524. +
  10525. +int au_finfo_init(struct file *file, struct au_fidir *fidir)
  10526. +{
  10527. + int err;
  10528. + struct au_finfo *finfo;
  10529. + struct dentry *dentry;
  10530. +
  10531. + err = -ENOMEM;
  10532. + dentry = file->f_dentry;
  10533. + finfo = au_cache_alloc_finfo();
  10534. + if (unlikely(!finfo))
  10535. + goto out;
  10536. +
  10537. + err = 0;
  10538. + au_nfiles_inc(dentry->d_sb);
  10539. + au_rw_write_lock(&finfo->fi_rwsem);
  10540. + finfo->fi_btop = -1;
  10541. + finfo->fi_hdir = fidir;
  10542. + atomic_set(&finfo->fi_generation, au_digen(dentry));
  10543. + /* smp_mb(); */ /* atomic_set */
  10544. +
  10545. + file->private_data = finfo;
  10546. +
  10547. +out:
  10548. + return err;
  10549. +}
  10550. diff -Nur linux-2.6.37.orig/fs/aufs/fstype.h linux-2.6.37/fs/aufs/fstype.h
  10551. --- linux-2.6.37.orig/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100
  10552. +++ linux-2.6.37/fs/aufs/fstype.h 2011-01-11 20:15:11.000000000 +0100
  10553. @@ -0,0 +1,497 @@
  10554. +/*
  10555. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  10556. + *
  10557. + * This program, aufs is free software; you can redistribute it and/or modify
  10558. + * it under the terms of the GNU General Public License as published by
  10559. + * the Free Software Foundation; either version 2 of the License, or
  10560. + * (at your option) any later version.
  10561. + *
  10562. + * This program is distributed in the hope that it will be useful,
  10563. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10564. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10565. + * GNU General Public License for more details.
  10566. + *
  10567. + * You should have received a copy of the GNU General Public License
  10568. + * along with this program; if not, write to the Free Software
  10569. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  10570. + */
  10571. +
  10572. +/*
  10573. + * judging filesystem type
  10574. + */
  10575. +
  10576. +#ifndef __AUFS_FSTYPE_H__
  10577. +#define __AUFS_FSTYPE_H__
  10578. +
  10579. +#ifdef __KERNEL__
  10580. +
  10581. +#include <linux/fs.h>
  10582. +#include <linux/magic.h>
  10583. +#include <linux/romfs_fs.h>
  10584. +#include <linux/aufs_type.h>
  10585. +
  10586. +static inline int au_test_aufs(struct super_block *sb)
  10587. +{
  10588. + return sb->s_magic == AUFS_SUPER_MAGIC;
  10589. +}
  10590. +
  10591. +static inline const char *au_sbtype(struct super_block *sb)
  10592. +{
  10593. + return sb->s_type->name;
  10594. +}
  10595. +
  10596. +static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
  10597. +{
  10598. +#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE)
  10599. + return sb->s_magic == ROMFS_MAGIC;
  10600. +#else
  10601. + return 0;
  10602. +#endif
  10603. +}
  10604. +
  10605. +static inline int au_test_romfs(struct super_block *sb __maybe_unused)
  10606. +{
  10607. +#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE)
  10608. + return sb->s_magic == ISOFS_SUPER_MAGIC;
  10609. +#else
  10610. + return 0;
  10611. +#endif
  10612. +}
  10613. +
  10614. +static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
  10615. +{
  10616. +#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE)
  10617. + return sb->s_magic == CRAMFS_MAGIC;
  10618. +#endif
  10619. + return 0;
  10620. +}
  10621. +
  10622. +static inline int au_test_nfs(struct super_block *sb __maybe_unused)
  10623. +{
  10624. +#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE)
  10625. + return sb->s_magic == NFS_SUPER_MAGIC;
  10626. +#else
  10627. + return 0;
  10628. +#endif
  10629. +}
  10630. +
  10631. +static inline int au_test_fuse(struct super_block *sb __maybe_unused)
  10632. +{
  10633. +#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE)
  10634. + return sb->s_magic == FUSE_SUPER_MAGIC;
  10635. +#else
  10636. + return 0;
  10637. +#endif
  10638. +}
  10639. +
  10640. +static inline int au_test_xfs(struct super_block *sb __maybe_unused)
  10641. +{
  10642. +#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE)
  10643. + return sb->s_magic == XFS_SB_MAGIC;
  10644. +#else
  10645. + return 0;
  10646. +#endif
  10647. +}
  10648. +
  10649. +static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
  10650. +{
  10651. +#ifdef CONFIG_TMPFS
  10652. + return sb->s_magic == TMPFS_MAGIC;
  10653. +#else
  10654. + return 0;
  10655. +#endif
  10656. +}
  10657. +
  10658. +static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
  10659. +{
  10660. +#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE)
  10661. + return !strcmp(au_sbtype(sb), "ecryptfs");
  10662. +#else
  10663. + return 0;
  10664. +#endif
  10665. +}
  10666. +
  10667. +static inline int au_test_smbfs(struct super_block *sb __maybe_unused)
  10668. +{
  10669. +#if defined(CONFIG_SMB_FS) || defined(CONFIG_SMB_FS_MODULE)
  10670. + return sb->s_magic == SMB_SUPER_MAGIC;
  10671. +#else
  10672. + return 0;
  10673. +#endif
  10674. +}
  10675. +
  10676. +static inline int au_test_ocfs2(struct super_block *sb __maybe_unused)
  10677. +{
  10678. +#if defined(CONFIG_OCFS2_FS) || defined(CONFIG_OCFS2_FS_MODULE)
  10679. + return sb->s_magic == OCFS2_SUPER_MAGIC;
  10680. +#else
  10681. + return 0;
  10682. +#endif
  10683. +}
  10684. +
  10685. +static inline int au_test_ocfs2_dlmfs(struct super_block *sb __maybe_unused)
  10686. +{
  10687. +#if defined(CONFIG_OCFS2_FS_O2CB) || defined(CONFIG_OCFS2_FS_O2CB_MODULE)
  10688. + return sb->s_magic == DLMFS_MAGIC;
  10689. +#else
  10690. + return 0;
  10691. +#endif
  10692. +}
  10693. +
  10694. +static inline int au_test_coda(struct super_block *sb __maybe_unused)
  10695. +{
  10696. +#if defined(CONFIG_CODA_FS) || defined(CONFIG_CODA_FS_MODULE)
  10697. + return sb->s_magic == CODA_SUPER_MAGIC;
  10698. +#else
  10699. + return 0;
  10700. +#endif
  10701. +}
  10702. +
  10703. +static inline int au_test_v9fs(struct super_block *sb __maybe_unused)
  10704. +{
  10705. +#if defined(CONFIG_9P_FS) || defined(CONFIG_9P_FS_MODULE)
  10706. + return sb->s_magic == V9FS_MAGIC;
  10707. +#else
  10708. + return 0;
  10709. +#endif
  10710. +}
  10711. +
  10712. +static inline int au_test_ext4(struct super_block *sb __maybe_unused)
  10713. +{
  10714. +#if defined(CONFIG_EXT4DEV_FS) || defined(CONFIG_EXT4DEV_FS_MODULE)
  10715. + return sb->s_magic == EXT4_SUPER_MAGIC;
  10716. +#else
  10717. + return 0;
  10718. +#endif
  10719. +}
  10720. +
  10721. +static inline int au_test_sysv(struct super_block *sb __maybe_unused)
  10722. +{
  10723. +#if defined(CONFIG_SYSV_FS) || defined(CONFIG_SYSV_FS_MODULE)
  10724. + return !strcmp(au_sbtype(sb), "sysv");
  10725. +#else
  10726. + return 0;
  10727. +#endif
  10728. +}
  10729. +
  10730. +static inline int au_test_ramfs(struct super_block *sb)
  10731. +{
  10732. + return sb->s_magic == RAMFS_MAGIC;
  10733. +}
  10734. +
  10735. +static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
  10736. +{
  10737. +#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE)
  10738. + return sb->s_magic == UBIFS_SUPER_MAGIC;
  10739. +#else
  10740. + return 0;
  10741. +#endif
  10742. +}
  10743. +
  10744. +static inline int au_test_procfs(struct super_block *sb __maybe_unused)
  10745. +{
  10746. +#ifdef CONFIG_PROC_FS
  10747. + return sb->s_magic == PROC_SUPER_MAGIC;
  10748. +#else
  10749. + return 0;
  10750. +#endif
  10751. +}
  10752. +
  10753. +static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
  10754. +{
  10755. +#ifdef CONFIG_SYSFS
  10756. + return sb->s_magic == SYSFS_MAGIC;
  10757. +#else
  10758. + return 0;
  10759. +#endif
  10760. +}
  10761. +
  10762. +static inline int au_test_configfs(struct super_block *sb __maybe_unused)
  10763. +{
  10764. +#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE)
  10765. + return sb->s_magic == CONFIGFS_MAGIC;
  10766. +#else
  10767. + return 0;
  10768. +#endif
  10769. +}
  10770. +
  10771. +static inline int au_test_minix(struct super_block *sb __maybe_unused)
  10772. +{
  10773. +#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE)
  10774. + return sb->s_magic == MINIX3_SUPER_MAGIC
  10775. + || sb->s_magic == MINIX2_SUPER_MAGIC
  10776. + || sb->s_magic == MINIX2_SUPER_MAGIC2
  10777. + || sb->s_magic == MINIX_SUPER_MAGIC
  10778. + || sb->s_magic == MINIX_SUPER_MAGIC2;
  10779. +#else
  10780. + return 0;
  10781. +#endif
  10782. +}
  10783. +
  10784. +static inline int au_test_cifs(struct super_block *sb __maybe_unused)
  10785. +{
  10786. +#if defined(CONFIG_CIFS_FS) || defined(CONFIGCIFS_FS_MODULE)
  10787. + return sb->s_magic == CIFS_MAGIC_NUMBER;
  10788. +#else
  10789. + return 0;
  10790. +#endif
  10791. +}
  10792. +
  10793. +static inline int au_test_fat(struct super_block *sb __maybe_unused)
  10794. +{
  10795. +#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE)
  10796. + return sb->s_magic == MSDOS_SUPER_MAGIC;
  10797. +#else
  10798. + return 0;
  10799. +#endif
  10800. +}
  10801. +
  10802. +static inline int au_test_msdos(struct super_block *sb)
  10803. +{
  10804. + return au_test_fat(sb);
  10805. +}
  10806. +
  10807. +static inline int au_test_vfat(struct super_block *sb)
  10808. +{
  10809. + return au_test_fat(sb);
  10810. +}
  10811. +
  10812. +static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
  10813. +{
  10814. +#ifdef CONFIG_SECURITYFS
  10815. + return sb->s_magic == SECURITYFS_MAGIC;
  10816. +#else
  10817. + return 0;
  10818. +#endif
  10819. +}
  10820. +
  10821. +static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
  10822. +{
  10823. +#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE)
  10824. + return sb->s_magic == SQUASHFS_MAGIC;
  10825. +#else
  10826. + return 0;
  10827. +#endif
  10828. +}
  10829. +
  10830. +static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
  10831. +{
  10832. +#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE)
  10833. + return sb->s_magic == BTRFS_SUPER_MAGIC;
  10834. +#else
  10835. + return 0;
  10836. +#endif
  10837. +}
  10838. +
  10839. +static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
  10840. +{
  10841. +#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE)
  10842. + return sb->s_magic == XENFS_SUPER_MAGIC;
  10843. +#else
  10844. + return 0;
  10845. +#endif
  10846. +}
  10847. +
  10848. +static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
  10849. +{
  10850. +#ifdef CONFIG_DEBUG_FS
  10851. + return sb->s_magic == DEBUGFS_MAGIC;
  10852. +#else
  10853. + return 0;
  10854. +#endif
  10855. +}
  10856. +
  10857. +static inline int au_test_nilfs(struct super_block *sb __maybe_unused)
  10858. +{
  10859. +#if defined(CONFIG_NILFS) || defined(CONFIG_NILFS_MODULE)
  10860. + return sb->s_magic == NILFS_SUPER_MAGIC;
  10861. +#else
  10862. + return 0;
  10863. +#endif
  10864. +}
  10865. +
  10866. +static inline int au_test_hfsplus(struct super_block *sb __maybe_unused)
  10867. +{
  10868. +#if defined(CONFIG_HFSPLUS_FS) || defined(CONFIG_HFSPLUS_FS_MODULE)
  10869. + return sb->s_magic == HFSPLUS_SUPER_MAGIC;
  10870. +#else
  10871. + return 0;
  10872. +#endif
  10873. +}
  10874. +
  10875. +/* ---------------------------------------------------------------------- */
  10876. +/*
  10877. + * they can't be an aufs branch.
  10878. + */
  10879. +static inline int au_test_fs_unsuppoted(struct super_block *sb)
  10880. +{
  10881. + return
  10882. +#ifndef CONFIG_AUFS_BR_RAMFS
  10883. + au_test_ramfs(sb) ||
  10884. +#endif
  10885. + au_test_procfs(sb)
  10886. + || au_test_sysfs(sb)
  10887. + || au_test_configfs(sb)
  10888. + || au_test_debugfs(sb)
  10889. + || au_test_securityfs(sb)
  10890. + || au_test_xenfs(sb)
  10891. + || au_test_ecryptfs(sb)
  10892. + /* || !strcmp(au_sbtype(sb), "unionfs") */
  10893. + || au_test_aufs(sb); /* will be supported in next version */
  10894. +}
  10895. +
  10896. +/*
  10897. + * If the filesystem supports NFS-export, then it has to support NULL as
  10898. + * a nameidata parameter for ->create(), ->lookup() and ->d_revalidate().
  10899. + * We can apply this principle when we handle a lower filesystem.
  10900. + */
  10901. +static inline int au_test_fs_null_nd(struct super_block *sb)
  10902. +{
  10903. + return !!sb->s_export_op;
  10904. +}
  10905. +
  10906. +static inline int au_test_fs_remote(struct super_block *sb)
  10907. +{
  10908. + return !au_test_tmpfs(sb)
  10909. +#ifdef CONFIG_AUFS_BR_RAMFS
  10910. + && !au_test_ramfs(sb)
  10911. +#endif
  10912. + && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
  10913. +}
  10914. +
  10915. +/* ---------------------------------------------------------------------- */
  10916. +
  10917. +/*
  10918. + * Note: these functions (below) are created after reading ->getattr() in all
  10919. + * filesystems under linux/fs. it means we have to do so in every update...
  10920. + */
  10921. +
  10922. +/*
  10923. + * some filesystems require getattr to refresh the inode attributes before
  10924. + * referencing.
  10925. + * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
  10926. + * and leave the work for d_revalidate()
  10927. + */
  10928. +static inline int au_test_fs_refresh_iattr(struct super_block *sb)
  10929. +{
  10930. + return au_test_nfs(sb)
  10931. + || au_test_fuse(sb)
  10932. + /* || au_test_smbfs(sb) */ /* untested */
  10933. + /* || au_test_ocfs2(sb) */ /* untested */
  10934. + /* || au_test_btrfs(sb) */ /* untested */
  10935. + /* || au_test_coda(sb) */ /* untested */
  10936. + /* || au_test_v9fs(sb) */ /* untested */
  10937. + ;
  10938. +}
  10939. +
  10940. +/*
  10941. + * filesystems which don't maintain i_size or i_blocks.
  10942. + */
  10943. +static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
  10944. +{
  10945. + return au_test_xfs(sb)
  10946. + || au_test_btrfs(sb)
  10947. + || au_test_ubifs(sb)
  10948. + || au_test_hfsplus(sb) /* maintained, but incorrect */
  10949. + /* || au_test_ext4(sb) */ /* untested */
  10950. + /* || au_test_ocfs2(sb) */ /* untested */
  10951. + /* || au_test_ocfs2_dlmfs(sb) */ /* untested */
  10952. + /* || au_test_sysv(sb) */ /* untested */
  10953. + /* || au_test_minix(sb) */ /* untested */
  10954. + ;
  10955. +}
  10956. +
  10957. +/*
  10958. + * filesystems which don't store the correct value in some of their inode
  10959. + * attributes.
  10960. + */
  10961. +static inline int au_test_fs_bad_iattr(struct super_block *sb)
  10962. +{
  10963. + return au_test_fs_bad_iattr_size(sb)
  10964. + /* || au_test_cifs(sb) */ /* untested */
  10965. + || au_test_fat(sb)
  10966. + || au_test_msdos(sb)
  10967. + || au_test_vfat(sb);
  10968. +}
  10969. +
  10970. +/* they don't check i_nlink in link(2) */
  10971. +static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
  10972. +{
  10973. + return au_test_tmpfs(sb)
  10974. +#ifdef CONFIG_AUFS_BR_RAMFS
  10975. + || au_test_ramfs(sb)
  10976. +#endif
  10977. + || au_test_ubifs(sb)
  10978. + || au_test_btrfs(sb)
  10979. + || au_test_hfsplus(sb);
  10980. +}
  10981. +
  10982. +/*
  10983. + * filesystems which sets S_NOATIME and S_NOCMTIME.
  10984. + */
  10985. +static inline int au_test_fs_notime(struct super_block *sb)
  10986. +{
  10987. + return au_test_nfs(sb)
  10988. + || au_test_fuse(sb)
  10989. + || au_test_ubifs(sb)
  10990. + /* || au_test_cifs(sb) */ /* untested */
  10991. + ;
  10992. +}
  10993. +
  10994. +/*
  10995. + * filesystems which requires replacing i_mapping.
  10996. + */
  10997. +static inline int au_test_fs_bad_mapping(struct super_block *sb)
  10998. +{
  10999. + return au_test_fuse(sb)
  11000. + || au_test_ubifs(sb);
  11001. +}
  11002. +
  11003. +/* temporary support for i#1 in cramfs */
  11004. +static inline int au_test_fs_unique_ino(struct inode *inode)
  11005. +{
  11006. + if (au_test_cramfs(inode->i_sb))
  11007. + return inode->i_ino != 1;
  11008. + return 1;
  11009. +}
  11010. +
  11011. +/* ---------------------------------------------------------------------- */
  11012. +
  11013. +/*
  11014. + * the filesystem where the xino files placed must support i/o after unlink and
  11015. + * maintain i_size and i_blocks.
  11016. + */
  11017. +static inline int au_test_fs_bad_xino(struct super_block *sb)
  11018. +{
  11019. + return au_test_fs_remote(sb)
  11020. + || au_test_fs_bad_iattr_size(sb)
  11021. +#ifdef CONFIG_AUFS_BR_RAMFS
  11022. + || !(au_test_ramfs(sb) || au_test_fs_null_nd(sb))
  11023. +#else
  11024. + || !au_test_fs_null_nd(sb) /* to keep xino code simple */
  11025. +#endif
  11026. + /* don't want unnecessary work for xino */
  11027. + || au_test_aufs(sb)
  11028. + || au_test_ecryptfs(sb)
  11029. + || au_test_nilfs(sb);
  11030. +}
  11031. +
  11032. +static inline int au_test_fs_trunc_xino(struct super_block *sb)
  11033. +{
  11034. + return au_test_tmpfs(sb)
  11035. + || au_test_ramfs(sb);
  11036. +}
  11037. +
  11038. +/*
  11039. + * test if the @sb is real-readonly.
  11040. + */
  11041. +static inline int au_test_fs_rr(struct super_block *sb)
  11042. +{
  11043. + return au_test_squashfs(sb)
  11044. + || au_test_iso9660(sb)
  11045. + || au_test_cramfs(sb)
  11046. + || au_test_romfs(sb);
  11047. +}
  11048. +
  11049. +#endif /* __KERNEL__ */
  11050. +#endif /* __AUFS_FSTYPE_H__ */
  11051. diff -Nur linux-2.6.37.orig/fs/aufs/hfsnotify.c linux-2.6.37/fs/aufs/hfsnotify.c
  11052. --- linux-2.6.37.orig/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100
  11053. +++ linux-2.6.37/fs/aufs/hfsnotify.c 2011-01-11 20:15:11.000000000 +0100
  11054. @@ -0,0 +1,247 @@
  11055. +/*
  11056. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  11057. + *
  11058. + * This program, aufs is free software; you can redistribute it and/or modify
  11059. + * it under the terms of the GNU General Public License as published by
  11060. + * the Free Software Foundation; either version 2 of the License, or
  11061. + * (at your option) any later version.
  11062. + *
  11063. + * This program is distributed in the hope that it will be useful,
  11064. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11065. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11066. + * GNU General Public License for more details.
  11067. + *
  11068. + * You should have received a copy of the GNU General Public License
  11069. + * along with this program; if not, write to the Free Software
  11070. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  11071. + */
  11072. +
  11073. +/*
  11074. + * fsnotify for the lower directories
  11075. + */
  11076. +
  11077. +#include "aufs.h"
  11078. +
  11079. +/* FS_IN_IGNORED is unnecessary */
  11080. +static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE
  11081. + | FS_CREATE | FS_EVENT_ON_CHILD);
  11082. +static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
  11083. +
  11084. +static void au_hfsn_free_mark(struct fsnotify_mark *mark)
  11085. +{
  11086. + struct au_hnotify *hn = container_of(mark, struct au_hnotify,
  11087. + hn_mark);
  11088. + AuDbg("here\n");
  11089. + hn->hn_mark_dead = 1;
  11090. + smp_mb();
  11091. + wake_up_all(&au_hfsn_wq);
  11092. +}
  11093. +
  11094. +static int au_hfsn_alloc(struct au_hinode *hinode)
  11095. +{
  11096. + struct au_hnotify *hn;
  11097. + struct super_block *sb;
  11098. + struct au_branch *br;
  11099. + struct fsnotify_mark *mark;
  11100. + aufs_bindex_t bindex;
  11101. +
  11102. + hn = hinode->hi_notify;
  11103. + sb = hn->hn_aufs_inode->i_sb;
  11104. + bindex = au_br_index(sb, hinode->hi_id);
  11105. + br = au_sbr(sb, bindex);
  11106. + hn->hn_mark_dead = 0;
  11107. + mark = &hn->hn_mark;
  11108. + fsnotify_init_mark(mark, au_hfsn_free_mark);
  11109. + mark->mask = AuHfsnMask;
  11110. + /*
  11111. + * by udba rename or rmdir, aufs assign a new inode to the known
  11112. + * h_inode, so specify 1 to allow dups.
  11113. + */
  11114. + return fsnotify_add_mark(mark, br->br_hfsn_group, hinode->hi_inode,
  11115. + /*mnt*/NULL, /*allow_dups*/1);
  11116. +}
  11117. +
  11118. +static void au_hfsn_free(struct au_hinode *hinode)
  11119. +{
  11120. + struct au_hnotify *hn;
  11121. + struct fsnotify_mark *mark;
  11122. +
  11123. + hn = hinode->hi_notify;
  11124. + mark = &hn->hn_mark;
  11125. + fsnotify_destroy_mark(mark);
  11126. + fsnotify_put_mark(mark);
  11127. +
  11128. + /* TODO: bad approach */
  11129. + wait_event(au_hfsn_wq, hn->hn_mark_dead);
  11130. +}
  11131. +
  11132. +/* ---------------------------------------------------------------------- */
  11133. +
  11134. +static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
  11135. +{
  11136. + struct fsnotify_mark *mark;
  11137. +
  11138. + mark = &hinode->hi_notify->hn_mark;
  11139. + spin_lock(&mark->lock);
  11140. + if (do_set) {
  11141. + AuDebugOn(mark->mask & AuHfsnMask);
  11142. + mark->mask |= AuHfsnMask;
  11143. + } else {
  11144. + AuDebugOn(!(mark->mask & AuHfsnMask));
  11145. + mark->mask &= ~AuHfsnMask;
  11146. + }
  11147. + spin_unlock(&mark->lock);
  11148. + /* fsnotify_recalc_inode_mask(hinode->hi_inode); */
  11149. +}
  11150. +
  11151. +/* ---------------------------------------------------------------------- */
  11152. +
  11153. +/* #define AuDbgHnotify */
  11154. +#ifdef AuDbgHnotify
  11155. +static char *au_hfsn_name(u32 mask)
  11156. +{
  11157. +#ifdef CONFIG_AUFS_DEBUG
  11158. +#define test_ret(flag) if (mask & flag) \
  11159. + return #flag;
  11160. + test_ret(FS_ACCESS);
  11161. + test_ret(FS_MODIFY);
  11162. + test_ret(FS_ATTRIB);
  11163. + test_ret(FS_CLOSE_WRITE);
  11164. + test_ret(FS_CLOSE_NOWRITE);
  11165. + test_ret(FS_OPEN);
  11166. + test_ret(FS_MOVED_FROM);
  11167. + test_ret(FS_MOVED_TO);
  11168. + test_ret(FS_CREATE);
  11169. + test_ret(FS_DELETE);
  11170. + test_ret(FS_DELETE_SELF);
  11171. + test_ret(FS_MOVE_SELF);
  11172. + test_ret(FS_UNMOUNT);
  11173. + test_ret(FS_Q_OVERFLOW);
  11174. + test_ret(FS_IN_IGNORED);
  11175. + test_ret(FS_IN_ISDIR);
  11176. + test_ret(FS_IN_ONESHOT);
  11177. + test_ret(FS_EVENT_ON_CHILD);
  11178. + return "";
  11179. +#undef test_ret
  11180. +#else
  11181. + return "??";
  11182. +#endif
  11183. +}
  11184. +#endif
  11185. +
  11186. +/* ---------------------------------------------------------------------- */
  11187. +
  11188. +static int au_hfsn_handle_event(struct fsnotify_group *group,
  11189. + struct fsnotify_mark *inode_mark,
  11190. + struct fsnotify_mark *vfsmount_mark,
  11191. + struct fsnotify_event *event)
  11192. +{
  11193. + int err;
  11194. + struct au_hnotify *hnotify;
  11195. + struct inode *h_dir, *h_inode;
  11196. + __u32 mask;
  11197. + struct qstr h_child_qstr = {
  11198. + .name = event->file_name,
  11199. + .len = event->name_len
  11200. + };
  11201. +
  11202. + AuDebugOn(event->data_type != FSNOTIFY_EVENT_INODE);
  11203. +
  11204. + err = 0;
  11205. + /* if FS_UNMOUNT happens, there must be another bug */
  11206. + mask = event->mask;
  11207. + AuDebugOn(mask & FS_UNMOUNT);
  11208. + if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
  11209. + goto out;
  11210. +
  11211. + h_dir = event->to_tell;
  11212. + h_inode = event->inode;
  11213. +#ifdef AuDbgHnotify
  11214. + au_debug(1);
  11215. + if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
  11216. + || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
  11217. + AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
  11218. + h_dir->i_ino, mask, au_hfsn_name(mask),
  11219. + AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
  11220. + /* WARN_ON(1); */
  11221. + }
  11222. + au_debug(0);
  11223. +#endif
  11224. +
  11225. + AuDebugOn(!inode_mark);
  11226. + hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
  11227. + err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode);
  11228. +
  11229. +out:
  11230. + return err;
  11231. +}
  11232. +
  11233. +/* isn't it waste to ask every registered 'group'? */
  11234. +/* copied from linux/fs/notify/inotify/inotify_fsnotiry.c */
  11235. +/* it should be exported to modules */
  11236. +static bool au_hfsn_should_send_event(struct fsnotify_group *group,
  11237. + struct inode *h_inode,
  11238. + struct fsnotify_mark *inode_mark,
  11239. + struct fsnotify_mark *vfsmount_mark,
  11240. + __u32 mask, void *data, int data_type)
  11241. +{
  11242. + mask = (mask & ~FS_EVENT_ON_CHILD);
  11243. + return inode_mark->mask & mask;
  11244. +}
  11245. +
  11246. +static struct fsnotify_ops au_hfsn_ops = {
  11247. + .should_send_event = au_hfsn_should_send_event,
  11248. + .handle_event = au_hfsn_handle_event
  11249. +};
  11250. +
  11251. +/* ---------------------------------------------------------------------- */
  11252. +
  11253. +static void au_hfsn_fin_br(struct au_branch *br)
  11254. +{
  11255. + if (br->br_hfsn_group)
  11256. + fsnotify_put_group(br->br_hfsn_group);
  11257. +}
  11258. +
  11259. +static int au_hfsn_init_br(struct au_branch *br, int perm)
  11260. +{
  11261. + br->br_hfsn_group = NULL;
  11262. + br->br_hfsn_ops = au_hfsn_ops;
  11263. + return 0;
  11264. +}
  11265. +
  11266. +static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm)
  11267. +{
  11268. + int err;
  11269. +
  11270. + err = 0;
  11271. + if (udba != AuOpt_UDBA_HNOTIFY
  11272. + || !au_br_hnotifyable(perm)) {
  11273. + au_hfsn_fin_br(br);
  11274. + br->br_hfsn_group = NULL;
  11275. + goto out;
  11276. + }
  11277. +
  11278. + if (br->br_hfsn_group)
  11279. + goto out;
  11280. +
  11281. + br->br_hfsn_group = fsnotify_alloc_group(&br->br_hfsn_ops);
  11282. + if (IS_ERR(br->br_hfsn_group)) {
  11283. + err = PTR_ERR(br->br_hfsn_group);
  11284. + pr_err("fsnotify_alloc_group() failed, %d\n", err);
  11285. + br->br_hfsn_group = NULL;
  11286. + }
  11287. +
  11288. +out:
  11289. + AuTraceErr(err);
  11290. + return err;
  11291. +}
  11292. +
  11293. +const struct au_hnotify_op au_hnotify_op = {
  11294. + .ctl = au_hfsn_ctl,
  11295. + .alloc = au_hfsn_alloc,
  11296. + .free = au_hfsn_free,
  11297. +
  11298. + .reset_br = au_hfsn_reset_br,
  11299. + .fin_br = au_hfsn_fin_br,
  11300. + .init_br = au_hfsn_init_br
  11301. +};
  11302. diff -Nur linux-2.6.37.orig/fs/aufs/hfsplus.c linux-2.6.37/fs/aufs/hfsplus.c
  11303. --- linux-2.6.37.orig/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100
  11304. +++ linux-2.6.37/fs/aufs/hfsplus.c 2011-01-11 20:15:11.000000000 +0100
  11305. @@ -0,0 +1,58 @@
  11306. +/*
  11307. + * Copyright (C) 2010-2011 Junjiro R. Okajima
  11308. + *
  11309. + * This program, aufs is free software; you can redistribute it and/or modify
  11310. + * it under the terms of the GNU General Public License as published by
  11311. + * the Free Software Foundation; either version 2 of the License, or
  11312. + * (at your option) any later version.
  11313. + *
  11314. + * This program is distributed in the hope that it will be useful,
  11315. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11316. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11317. + * GNU General Public License for more details.
  11318. + *
  11319. + * You should have received a copy of the GNU General Public License
  11320. + * along with this program; if not, write to the Free Software
  11321. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  11322. + */
  11323. +
  11324. +/*
  11325. + * special support for filesystems which aqucires an inode mutex
  11326. + * at final closing a file, eg, hfsplus.
  11327. + *
  11328. + * This trick is very simple and stupid, just to open the file before really
  11329. + * neceeary open to tell hfsplus that this is not the final closing.
  11330. + * The caller should call au_h_open_pre() after acquiring the inode mutex,
  11331. + * and au_h_open_post() after releasing it.
  11332. + */
  11333. +
  11334. +#include <linux/file.h>
  11335. +#include "aufs.h"
  11336. +
  11337. +struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex)
  11338. +{
  11339. + struct file *h_file;
  11340. + struct dentry *h_dentry;
  11341. +
  11342. + h_dentry = au_h_dptr(dentry, bindex);
  11343. + AuDebugOn(!h_dentry);
  11344. + AuDebugOn(!h_dentry->d_inode);
  11345. + IMustLock(h_dentry->d_inode);
  11346. +
  11347. + h_file = NULL;
  11348. + if (au_test_hfsplus(h_dentry->d_sb)
  11349. + && S_ISREG(h_dentry->d_inode->i_mode))
  11350. + h_file = au_h_open(dentry, bindex,
  11351. + O_RDONLY | O_NOATIME | O_LARGEFILE,
  11352. + /*file*/NULL);
  11353. + return h_file;
  11354. +}
  11355. +
  11356. +void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
  11357. + struct file *h_file)
  11358. +{
  11359. + if (h_file) {
  11360. + fput(h_file);
  11361. + au_sbr_put(dentry->d_sb, bindex);
  11362. + }
  11363. +}
  11364. diff -Nur linux-2.6.37.orig/fs/aufs/hnotify.c linux-2.6.37/fs/aufs/hnotify.c
  11365. --- linux-2.6.37.orig/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100
  11366. +++ linux-2.6.37/fs/aufs/hnotify.c 2011-01-11 20:15:11.000000000 +0100
  11367. @@ -0,0 +1,694 @@
  11368. +/*
  11369. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  11370. + *
  11371. + * This program, aufs is free software; you can redistribute it and/or modify
  11372. + * it under the terms of the GNU General Public License as published by
  11373. + * the Free Software Foundation; either version 2 of the License, or
  11374. + * (at your option) any later version.
  11375. + *
  11376. + * This program is distributed in the hope that it will be useful,
  11377. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11378. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11379. + * GNU General Public License for more details.
  11380. + *
  11381. + * You should have received a copy of the GNU General Public License
  11382. + * along with this program; if not, write to the Free Software
  11383. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  11384. + */
  11385. +
  11386. +/*
  11387. + * abstraction to notify the direct changes on lower directories
  11388. + */
  11389. +
  11390. +#include "aufs.h"
  11391. +
  11392. +int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
  11393. +{
  11394. + int err;
  11395. + struct au_hnotify *hn;
  11396. +
  11397. + err = -ENOMEM;
  11398. + hn = au_cache_alloc_hnotify();
  11399. + if (hn) {
  11400. + hn->hn_aufs_inode = inode;
  11401. + hinode->hi_notify = hn;
  11402. + err = au_hnotify_op.alloc(hinode);
  11403. + AuTraceErr(err);
  11404. + if (unlikely(err)) {
  11405. + hinode->hi_notify = NULL;
  11406. + au_cache_free_hnotify(hn);
  11407. + /*
  11408. + * The upper dir was removed by udba, but the same named
  11409. + * dir left. In this case, aufs assignes a new inode
  11410. + * number and set the monitor again.
  11411. + * For the lower dir, the old monitnor is still left.
  11412. + */
  11413. + if (err == -EEXIST)
  11414. + err = 0;
  11415. + }
  11416. + }
  11417. +
  11418. + AuTraceErr(err);
  11419. + return err;
  11420. +}
  11421. +
  11422. +void au_hn_free(struct au_hinode *hinode)
  11423. +{
  11424. + struct au_hnotify *hn;
  11425. +
  11426. + hn = hinode->hi_notify;
  11427. + if (hn) {
  11428. + au_hnotify_op.free(hinode);
  11429. + au_cache_free_hnotify(hn);
  11430. + hinode->hi_notify = NULL;
  11431. + }
  11432. +}
  11433. +
  11434. +/* ---------------------------------------------------------------------- */
  11435. +
  11436. +void au_hn_ctl(struct au_hinode *hinode, int do_set)
  11437. +{
  11438. + if (hinode->hi_notify)
  11439. + au_hnotify_op.ctl(hinode, do_set);
  11440. +}
  11441. +
  11442. +void au_hn_reset(struct inode *inode, unsigned int flags)
  11443. +{
  11444. + aufs_bindex_t bindex, bend;
  11445. + struct inode *hi;
  11446. + struct dentry *iwhdentry;
  11447. +
  11448. + bend = au_ibend(inode);
  11449. + for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
  11450. + hi = au_h_iptr(inode, bindex);
  11451. + if (!hi)
  11452. + continue;
  11453. +
  11454. + /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */
  11455. + iwhdentry = au_hi_wh(inode, bindex);
  11456. + if (iwhdentry)
  11457. + dget(iwhdentry);
  11458. + au_igrab(hi);
  11459. + au_set_h_iptr(inode, bindex, NULL, 0);
  11460. + au_set_h_iptr(inode, bindex, au_igrab(hi),
  11461. + flags & ~AuHi_XINO);
  11462. + iput(hi);
  11463. + dput(iwhdentry);
  11464. + /* mutex_unlock(&hi->i_mutex); */
  11465. + }
  11466. +}
  11467. +
  11468. +/* ---------------------------------------------------------------------- */
  11469. +
  11470. +static int hn_xino(struct inode *inode, struct inode *h_inode)
  11471. +{
  11472. + int err;
  11473. + aufs_bindex_t bindex, bend, bfound, bstart;
  11474. + struct inode *h_i;
  11475. +
  11476. + err = 0;
  11477. + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
  11478. + pr_warning("branch root dir was changed\n");
  11479. + goto out;
  11480. + }
  11481. +
  11482. + bfound = -1;
  11483. + bend = au_ibend(inode);
  11484. + bstart = au_ibstart(inode);
  11485. +#if 0 /* reserved for future use */
  11486. + if (bindex == bend) {
  11487. + /* keep this ino in rename case */
  11488. + goto out;
  11489. + }
  11490. +#endif
  11491. + for (bindex = bstart; bindex <= bend; bindex++)
  11492. + if (au_h_iptr(inode, bindex) == h_inode) {
  11493. + bfound = bindex;
  11494. + break;
  11495. + }
  11496. + if (bfound < 0)
  11497. + goto out;
  11498. +
  11499. + for (bindex = bstart; bindex <= bend; bindex++) {
  11500. + h_i = au_h_iptr(inode, bindex);
  11501. + if (!h_i)
  11502. + continue;
  11503. +
  11504. + err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
  11505. + /* ignore this error */
  11506. + /* bad action? */
  11507. + }
  11508. +
  11509. + /* children inode number will be broken */
  11510. +
  11511. +out:
  11512. + AuTraceErr(err);
  11513. + return err;
  11514. +}
  11515. +
  11516. +static int hn_gen_tree(struct dentry *dentry)
  11517. +{
  11518. + int err, i, j, ndentry;
  11519. + struct au_dcsub_pages dpages;
  11520. + struct au_dpage *dpage;
  11521. + struct dentry **dentries;
  11522. +
  11523. + err = au_dpages_init(&dpages, GFP_NOFS);
  11524. + if (unlikely(err))
  11525. + goto out;
  11526. + err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
  11527. + if (unlikely(err))
  11528. + goto out_dpages;
  11529. +
  11530. + for (i = 0; i < dpages.ndpage; i++) {
  11531. + dpage = dpages.dpages + i;
  11532. + dentries = dpage->dentries;
  11533. + ndentry = dpage->ndentry;
  11534. + for (j = 0; j < ndentry; j++) {
  11535. + struct dentry *d;
  11536. +
  11537. + d = dentries[j];
  11538. + if (IS_ROOT(d))
  11539. + continue;
  11540. +
  11541. + au_digen_dec(d);
  11542. + if (d->d_inode)
  11543. + /* todo: reset children xino?
  11544. + cached children only? */
  11545. + au_iigen_dec(d->d_inode);
  11546. + }
  11547. + }
  11548. +
  11549. +out_dpages:
  11550. + au_dpages_free(&dpages);
  11551. +
  11552. + /* discard children */
  11553. + dentry_unhash(dentry);
  11554. + dput(dentry);
  11555. +out:
  11556. + return err;
  11557. +}
  11558. +
  11559. +/*
  11560. + * return 0 if processed.
  11561. + */
  11562. +static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
  11563. + const unsigned int isdir)
  11564. +{
  11565. + int err;
  11566. + struct dentry *d;
  11567. + struct qstr *dname;
  11568. +
  11569. + err = 1;
  11570. + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
  11571. + pr_warning("branch root dir was changed\n");
  11572. + err = 0;
  11573. + goto out;
  11574. + }
  11575. +
  11576. + if (!isdir) {
  11577. + AuDebugOn(!name);
  11578. + au_iigen_dec(inode);
  11579. + spin_lock(&dcache_lock);
  11580. + list_for_each_entry(d, &inode->i_dentry, d_alias) {
  11581. + dname = &d->d_name;
  11582. + if (dname->len != nlen
  11583. + && memcmp(dname->name, name, nlen))
  11584. + continue;
  11585. + err = 0;
  11586. + au_digen_dec(d);
  11587. + break;
  11588. + }
  11589. + spin_unlock(&dcache_lock);
  11590. + } else {
  11591. + au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
  11592. + d = d_find_alias(inode);
  11593. + if (!d) {
  11594. + au_iigen_dec(inode);
  11595. + goto out;
  11596. + }
  11597. +
  11598. + dname = &d->d_name;
  11599. + if (dname->len == nlen && !memcmp(dname->name, name, nlen))
  11600. + err = hn_gen_tree(d);
  11601. + dput(d);
  11602. + }
  11603. +
  11604. +out:
  11605. + AuTraceErr(err);
  11606. + return err;
  11607. +}
  11608. +
  11609. +static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
  11610. +{
  11611. + int err;
  11612. + struct inode *inode;
  11613. +
  11614. + inode = dentry->d_inode;
  11615. + if (IS_ROOT(dentry)
  11616. + /* || (inode && inode->i_ino == AUFS_ROOT_INO) */
  11617. + ) {
  11618. + pr_warning("branch root dir was changed\n");
  11619. + return 0;
  11620. + }
  11621. +
  11622. + err = 0;
  11623. + if (!isdir) {
  11624. + au_digen_dec(dentry);
  11625. + if (inode)
  11626. + au_iigen_dec(inode);
  11627. + } else {
  11628. + au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
  11629. + if (inode)
  11630. + err = hn_gen_tree(dentry);
  11631. + }
  11632. +
  11633. + AuTraceErr(err);
  11634. + return err;
  11635. +}
  11636. +
  11637. +/* ---------------------------------------------------------------------- */
  11638. +
  11639. +/* hnotify job flags */
  11640. +#define AuHnJob_XINO0 1
  11641. +#define AuHnJob_GEN (1 << 1)
  11642. +#define AuHnJob_DIRENT (1 << 2)
  11643. +#define AuHnJob_ISDIR (1 << 3)
  11644. +#define AuHnJob_TRYXINO0 (1 << 4)
  11645. +#define AuHnJob_MNTPNT (1 << 5)
  11646. +#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name)
  11647. +#define au_fset_hnjob(flags, name) \
  11648. + do { (flags) |= AuHnJob_##name; } while (0)
  11649. +#define au_fclr_hnjob(flags, name) \
  11650. + do { (flags) &= ~AuHnJob_##name; } while (0)
  11651. +
  11652. +enum {
  11653. + AuHn_CHILD,
  11654. + AuHn_PARENT,
  11655. + AuHnLast
  11656. +};
  11657. +
  11658. +struct au_hnotify_args {
  11659. + struct inode *h_dir, *dir, *h_child_inode;
  11660. + u32 mask;
  11661. + unsigned int flags[AuHnLast];
  11662. + unsigned int h_child_nlen;
  11663. + char h_child_name[];
  11664. +};
  11665. +
  11666. +struct hn_job_args {
  11667. + unsigned int flags;
  11668. + struct inode *inode, *h_inode, *dir, *h_dir;
  11669. + struct dentry *dentry;
  11670. + char *h_name;
  11671. + int h_nlen;
  11672. +};
  11673. +
  11674. +static int hn_job(struct hn_job_args *a)
  11675. +{
  11676. + const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
  11677. +
  11678. + /* reset xino */
  11679. + if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
  11680. + hn_xino(a->inode, a->h_inode); /* ignore this error */
  11681. +
  11682. + if (au_ftest_hnjob(a->flags, TRYXINO0)
  11683. + && a->inode
  11684. + && a->h_inode) {
  11685. + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
  11686. + if (!a->h_inode->i_nlink)
  11687. + hn_xino(a->inode, a->h_inode); /* ignore this error */
  11688. + mutex_unlock(&a->h_inode->i_mutex);
  11689. + }
  11690. +
  11691. + /* make the generation obsolete */
  11692. + if (au_ftest_hnjob(a->flags, GEN)) {
  11693. + int err = -1;
  11694. + if (a->inode)
  11695. + err = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
  11696. + isdir);
  11697. + if (err && a->dentry)
  11698. + hn_gen_by_name(a->dentry, isdir);
  11699. + /* ignore this error */
  11700. + }
  11701. +
  11702. + /* make dir entries obsolete */
  11703. + if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
  11704. + struct au_vdir *vdir;
  11705. +
  11706. + vdir = au_ivdir(a->inode);
  11707. + if (vdir)
  11708. + vdir->vd_jiffy = 0;
  11709. + /* IMustLock(a->inode); */
  11710. + /* a->inode->i_version++; */
  11711. + }
  11712. +
  11713. + /* can do nothing but warn */
  11714. + if (au_ftest_hnjob(a->flags, MNTPNT)
  11715. + && a->dentry
  11716. + && d_mountpoint(a->dentry))
  11717. + pr_warning("mount-point %.*s is removed or renamed\n",
  11718. + AuDLNPair(a->dentry));
  11719. +
  11720. + return 0;
  11721. +}
  11722. +
  11723. +/* ---------------------------------------------------------------------- */
  11724. +
  11725. +static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
  11726. + struct inode *dir)
  11727. +{
  11728. + struct dentry *dentry, *d, *parent;
  11729. + struct qstr *dname;
  11730. +
  11731. + parent = d_find_alias(dir);
  11732. + if (!parent)
  11733. + return NULL;
  11734. +
  11735. + dentry = NULL;
  11736. + spin_lock(&dcache_lock);
  11737. + list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) {
  11738. + /* AuDbg("%.*s\n", AuDLNPair(d)); */
  11739. + dname = &d->d_name;
  11740. + if (dname->len != nlen || memcmp(dname->name, name, nlen))
  11741. + continue;
  11742. + if (au_di(d))
  11743. + au_digen_dec(d);
  11744. + else
  11745. + continue;
  11746. + if (!atomic_read(&d->d_count))
  11747. + continue;
  11748. +
  11749. + dentry = dget(d);
  11750. + break;
  11751. + }
  11752. + spin_unlock(&dcache_lock);
  11753. + dput(parent);
  11754. +
  11755. + if (dentry)
  11756. + di_write_lock_child(dentry);
  11757. +
  11758. + return dentry;
  11759. +}
  11760. +
  11761. +static struct inode *lookup_wlock_by_ino(struct super_block *sb,
  11762. + aufs_bindex_t bindex, ino_t h_ino)
  11763. +{
  11764. + struct inode *inode;
  11765. + ino_t ino;
  11766. + int err;
  11767. +
  11768. + inode = NULL;
  11769. + err = au_xino_read(sb, bindex, h_ino, &ino);
  11770. + if (!err && ino)
  11771. + inode = ilookup(sb, ino);
  11772. + if (!inode)
  11773. + goto out;
  11774. +
  11775. + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
  11776. + pr_warning("wrong root branch\n");
  11777. + iput(inode);
  11778. + inode = NULL;
  11779. + goto out;
  11780. + }
  11781. +
  11782. + ii_write_lock_child(inode);
  11783. +
  11784. +out:
  11785. + return inode;
  11786. +}
  11787. +
  11788. +static void au_hn_bh(void *_args)
  11789. +{
  11790. + struct au_hnotify_args *a = _args;
  11791. + struct super_block *sb;
  11792. + aufs_bindex_t bindex, bend, bfound;
  11793. + unsigned char xino, try_iput;
  11794. + int err;
  11795. + struct inode *inode;
  11796. + ino_t h_ino;
  11797. + struct hn_job_args args;
  11798. + struct dentry *dentry;
  11799. + struct au_sbinfo *sbinfo;
  11800. +
  11801. + AuDebugOn(!_args);
  11802. + AuDebugOn(!a->h_dir);
  11803. + AuDebugOn(!a->dir);
  11804. + AuDebugOn(!a->mask);
  11805. + AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
  11806. + a->mask, a->dir->i_ino, a->h_dir->i_ino,
  11807. + a->h_child_inode ? a->h_child_inode->i_ino : 0);
  11808. +
  11809. + inode = NULL;
  11810. + dentry = NULL;
  11811. + /*
  11812. + * do not lock a->dir->i_mutex here
  11813. + * because of d_revalidate() may cause a deadlock.
  11814. + */
  11815. + sb = a->dir->i_sb;
  11816. + AuDebugOn(!sb);
  11817. + sbinfo = au_sbi(sb);
  11818. + AuDebugOn(!sbinfo);
  11819. + si_write_lock(sb, AuLock_NOPLMW);
  11820. +
  11821. + ii_read_lock_parent(a->dir);
  11822. + bfound = -1;
  11823. + bend = au_ibend(a->dir);
  11824. + for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
  11825. + if (au_h_iptr(a->dir, bindex) == a->h_dir) {
  11826. + bfound = bindex;
  11827. + break;
  11828. + }
  11829. + ii_read_unlock(a->dir);
  11830. + if (unlikely(bfound < 0))
  11831. + goto out;
  11832. +
  11833. + xino = !!au_opt_test(au_mntflags(sb), XINO);
  11834. + h_ino = 0;
  11835. + if (a->h_child_inode)
  11836. + h_ino = a->h_child_inode->i_ino;
  11837. +
  11838. + if (a->h_child_nlen
  11839. + && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
  11840. + || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
  11841. + dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
  11842. + a->dir);
  11843. + try_iput = 0;
  11844. + if (dentry)
  11845. + inode = dentry->d_inode;
  11846. + if (xino && !inode && h_ino
  11847. + && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
  11848. + || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
  11849. + || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
  11850. + inode = lookup_wlock_by_ino(sb, bfound, h_ino);
  11851. + try_iput = 1;
  11852. + }
  11853. +
  11854. + args.flags = a->flags[AuHn_CHILD];
  11855. + args.dentry = dentry;
  11856. + args.inode = inode;
  11857. + args.h_inode = a->h_child_inode;
  11858. + args.dir = a->dir;
  11859. + args.h_dir = a->h_dir;
  11860. + args.h_name = a->h_child_name;
  11861. + args.h_nlen = a->h_child_nlen;
  11862. + err = hn_job(&args);
  11863. + if (dentry) {
  11864. + if (au_di(dentry))
  11865. + di_write_unlock(dentry);
  11866. + dput(dentry);
  11867. + }
  11868. + if (inode && try_iput) {
  11869. + ii_write_unlock(inode);
  11870. + iput(inode);
  11871. + }
  11872. +
  11873. + ii_write_lock_parent(a->dir);
  11874. + args.flags = a->flags[AuHn_PARENT];
  11875. + args.dentry = NULL;
  11876. + args.inode = a->dir;
  11877. + args.h_inode = a->h_dir;
  11878. + args.dir = NULL;
  11879. + args.h_dir = NULL;
  11880. + args.h_name = NULL;
  11881. + args.h_nlen = 0;
  11882. + err = hn_job(&args);
  11883. + ii_write_unlock(a->dir);
  11884. +
  11885. +out:
  11886. + iput(a->h_child_inode);
  11887. + iput(a->h_dir);
  11888. + iput(a->dir);
  11889. + si_write_unlock(sb);
  11890. + au_nwt_done(&sbinfo->si_nowait);
  11891. + kfree(a);
  11892. +}
  11893. +
  11894. +/* ---------------------------------------------------------------------- */
  11895. +
  11896. +int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
  11897. + struct qstr *h_child_qstr, struct inode *h_child_inode)
  11898. +{
  11899. + int err, len;
  11900. + unsigned int flags[AuHnLast];
  11901. + unsigned char isdir, isroot, wh;
  11902. + struct inode *dir;
  11903. + struct au_hnotify_args *args;
  11904. + char *p, *h_child_name;
  11905. +
  11906. + err = 0;
  11907. + AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
  11908. + dir = igrab(hnotify->hn_aufs_inode);
  11909. + if (!dir)
  11910. + goto out;
  11911. +
  11912. + isroot = (dir->i_ino == AUFS_ROOT_INO);
  11913. + wh = 0;
  11914. + h_child_name = (void *)h_child_qstr->name;
  11915. + len = h_child_qstr->len;
  11916. + if (h_child_name) {
  11917. + if (len > AUFS_WH_PFX_LEN
  11918. + && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
  11919. + h_child_name += AUFS_WH_PFX_LEN;
  11920. + len -= AUFS_WH_PFX_LEN;
  11921. + wh = 1;
  11922. + }
  11923. + }
  11924. +
  11925. + isdir = 0;
  11926. + if (h_child_inode)
  11927. + isdir = !!S_ISDIR(h_child_inode->i_mode);
  11928. + flags[AuHn_PARENT] = AuHnJob_ISDIR;
  11929. + flags[AuHn_CHILD] = 0;
  11930. + if (isdir)
  11931. + flags[AuHn_CHILD] = AuHnJob_ISDIR;
  11932. + au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
  11933. + au_fset_hnjob(flags[AuHn_CHILD], GEN);
  11934. + switch (mask & FS_EVENTS_POSS_ON_CHILD) {
  11935. + case FS_MOVED_FROM:
  11936. + case FS_MOVED_TO:
  11937. + au_fset_hnjob(flags[AuHn_CHILD], XINO0);
  11938. + au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
  11939. + /*FALLTHROUGH*/
  11940. + case FS_CREATE:
  11941. + AuDebugOn(!h_child_name || !h_child_inode);
  11942. + break;
  11943. +
  11944. + case FS_DELETE:
  11945. + /*
  11946. + * aufs never be able to get this child inode.
  11947. + * revalidation should be in d_revalidate()
  11948. + * by checking i_nlink, i_generation or d_unhashed().
  11949. + */
  11950. + AuDebugOn(!h_child_name);
  11951. + au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
  11952. + au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
  11953. + break;
  11954. +
  11955. + default:
  11956. + AuDebugOn(1);
  11957. + }
  11958. +
  11959. + if (wh)
  11960. + h_child_inode = NULL;
  11961. +
  11962. + err = -ENOMEM;
  11963. + /* iput() and kfree() will be called in au_hnotify() */
  11964. + args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
  11965. + if (unlikely(!args)) {
  11966. + AuErr1("no memory\n");
  11967. + iput(dir);
  11968. + goto out;
  11969. + }
  11970. + args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
  11971. + args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
  11972. + args->mask = mask;
  11973. + args->dir = dir;
  11974. + args->h_dir = igrab(h_dir);
  11975. + if (h_child_inode)
  11976. + h_child_inode = igrab(h_child_inode); /* can be NULL */
  11977. + args->h_child_inode = h_child_inode;
  11978. + args->h_child_nlen = len;
  11979. + if (len) {
  11980. + p = (void *)args;
  11981. + p += sizeof(*args);
  11982. + memcpy(p, h_child_name, len);
  11983. + p[len] = 0;
  11984. + }
  11985. +
  11986. + err = au_wkq_nowait(au_hn_bh, args, dir->i_sb);
  11987. + if (unlikely(err)) {
  11988. + pr_err("wkq %d\n", err);
  11989. + iput(args->h_child_inode);
  11990. + iput(args->h_dir);
  11991. + iput(args->dir);
  11992. + kfree(args);
  11993. + }
  11994. +
  11995. +out:
  11996. + return err;
  11997. +}
  11998. +
  11999. +/* ---------------------------------------------------------------------- */
  12000. +
  12001. +int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
  12002. +{
  12003. + int err;
  12004. +
  12005. + AuDebugOn(!(udba & AuOptMask_UDBA));
  12006. +
  12007. + err = 0;
  12008. + if (au_hnotify_op.reset_br)
  12009. + err = au_hnotify_op.reset_br(udba, br, perm);
  12010. +
  12011. + return err;
  12012. +}
  12013. +
  12014. +int au_hnotify_init_br(struct au_branch *br, int perm)
  12015. +{
  12016. + int err;
  12017. +
  12018. + err = 0;
  12019. + if (au_hnotify_op.init_br)
  12020. + err = au_hnotify_op.init_br(br, perm);
  12021. +
  12022. + return err;
  12023. +}
  12024. +
  12025. +void au_hnotify_fin_br(struct au_branch *br)
  12026. +{
  12027. + if (au_hnotify_op.fin_br)
  12028. + au_hnotify_op.fin_br(br);
  12029. +}
  12030. +
  12031. +static void au_hn_destroy_cache(void)
  12032. +{
  12033. + kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]);
  12034. + au_cachep[AuCache_HNOTIFY] = NULL;
  12035. +}
  12036. +
  12037. +int __init au_hnotify_init(void)
  12038. +{
  12039. + int err;
  12040. +
  12041. + err = -ENOMEM;
  12042. + au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify);
  12043. + if (au_cachep[AuCache_HNOTIFY]) {
  12044. + err = 0;
  12045. + if (au_hnotify_op.init)
  12046. + err = au_hnotify_op.init();
  12047. + if (unlikely(err))
  12048. + au_hn_destroy_cache();
  12049. + }
  12050. + AuTraceErr(err);
  12051. + return err;
  12052. +}
  12053. +
  12054. +void au_hnotify_fin(void)
  12055. +{
  12056. + if (au_hnotify_op.fin)
  12057. + au_hnotify_op.fin();
  12058. + /* cf. au_cache_fin() */
  12059. + if (au_cachep[AuCache_HNOTIFY])
  12060. + au_hn_destroy_cache();
  12061. +}
  12062. diff -Nur linux-2.6.37.orig/fs/aufs/i_op.c linux-2.6.37/fs/aufs/i_op.c
  12063. --- linux-2.6.37.orig/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
  12064. +++ linux-2.6.37/fs/aufs/i_op.c 2011-01-11 20:15:11.000000000 +0100
  12065. @@ -0,0 +1,971 @@
  12066. +/*
  12067. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  12068. + *
  12069. + * This program, aufs is free software; you can redistribute it and/or modify
  12070. + * it under the terms of the GNU General Public License as published by
  12071. + * the Free Software Foundation; either version 2 of the License, or
  12072. + * (at your option) any later version.
  12073. + *
  12074. + * This program is distributed in the hope that it will be useful,
  12075. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12076. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12077. + * GNU General Public License for more details.
  12078. + *
  12079. + * You should have received a copy of the GNU General Public License
  12080. + * along with this program; if not, write to the Free Software
  12081. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  12082. + */
  12083. +
  12084. +/*
  12085. + * inode operations (except add/del/rename)
  12086. + */
  12087. +
  12088. +#include <linux/device_cgroup.h>
  12089. +#include <linux/fs_stack.h>
  12090. +#include <linux/mm.h>
  12091. +#include <linux/namei.h>
  12092. +#include <linux/security.h>
  12093. +#include <linux/uaccess.h>
  12094. +#include "aufs.h"
  12095. +
  12096. +static int h_permission(struct inode *h_inode, int mask,
  12097. + struct vfsmount *h_mnt, int brperm)
  12098. +{
  12099. + int err;
  12100. + const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
  12101. +
  12102. + err = -EACCES;
  12103. + if ((write_mask && IS_IMMUTABLE(h_inode))
  12104. + || ((mask & MAY_EXEC)
  12105. + && S_ISREG(h_inode->i_mode)
  12106. + && ((h_mnt->mnt_flags & MNT_NOEXEC)
  12107. + || !(h_inode->i_mode & S_IXUGO))))
  12108. + goto out;
  12109. +
  12110. + /*
  12111. + * - skip the lower fs test in the case of write to ro branch.
  12112. + * - nfs dir permission write check is optimized, but a policy for
  12113. + * link/rename requires a real check.
  12114. + */
  12115. + if ((write_mask && !au_br_writable(brperm))
  12116. + || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
  12117. + && write_mask && !(mask & MAY_READ))
  12118. + || !h_inode->i_op->permission) {
  12119. + /* AuLabel(generic_permission); */
  12120. + err = generic_permission(h_inode, mask,
  12121. + h_inode->i_op->check_acl);
  12122. + } else {
  12123. + /* AuLabel(h_inode->permission); */
  12124. + err = h_inode->i_op->permission(h_inode, mask);
  12125. + AuTraceErr(err);
  12126. + }
  12127. +
  12128. + if (!err)
  12129. + err = devcgroup_inode_permission(h_inode, mask);
  12130. + if (!err)
  12131. + err = security_inode_permission(h_inode, mask);
  12132. +
  12133. +#if 0
  12134. + if (!err) {
  12135. + /* todo: do we need to call ima_path_check()? */
  12136. + struct path h_path = {
  12137. + .dentry =
  12138. + .mnt = h_mnt
  12139. + };
  12140. + err = ima_path_check(&h_path,
  12141. + mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
  12142. + IMA_COUNT_LEAVE);
  12143. + }
  12144. +#endif
  12145. +
  12146. +out:
  12147. + return err;
  12148. +}
  12149. +
  12150. +static int aufs_permission(struct inode *inode, int mask)
  12151. +{
  12152. + int err;
  12153. + aufs_bindex_t bindex, bend;
  12154. + const unsigned char isdir = !!S_ISDIR(inode->i_mode),
  12155. + write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
  12156. + struct inode *h_inode;
  12157. + struct super_block *sb;
  12158. + struct au_branch *br;
  12159. +
  12160. + sb = inode->i_sb;
  12161. + si_read_lock(sb, AuLock_FLUSH);
  12162. + ii_read_lock_child(inode);
  12163. +#if 0
  12164. + err = au_iigen_test(inode, au_sigen(sb));
  12165. + if (unlikely(err))
  12166. + goto out;
  12167. +#endif
  12168. +
  12169. + if (!isdir || write_mask) {
  12170. + err = au_busy_or_stale();
  12171. + h_inode = au_h_iptr(inode, au_ibstart(inode));
  12172. + if (unlikely(!h_inode
  12173. + || (h_inode->i_mode & S_IFMT)
  12174. + != (inode->i_mode & S_IFMT)))
  12175. + goto out;
  12176. +
  12177. + err = 0;
  12178. + bindex = au_ibstart(inode);
  12179. + br = au_sbr(sb, bindex);
  12180. + err = h_permission(h_inode, mask, br->br_mnt, br->br_perm);
  12181. + if (write_mask
  12182. + && !err
  12183. + && !special_file(h_inode->i_mode)) {
  12184. + /* test whether the upper writable branch exists */
  12185. + err = -EROFS;
  12186. + for (; bindex >= 0; bindex--)
  12187. + if (!au_br_rdonly(au_sbr(sb, bindex))) {
  12188. + err = 0;
  12189. + break;
  12190. + }
  12191. + }
  12192. + goto out;
  12193. + }
  12194. +
  12195. + /* non-write to dir */
  12196. + err = 0;
  12197. + bend = au_ibend(inode);
  12198. + for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) {
  12199. + h_inode = au_h_iptr(inode, bindex);
  12200. + if (h_inode) {
  12201. + err = au_busy_or_stale();
  12202. + if (unlikely(!S_ISDIR(h_inode->i_mode)))
  12203. + break;
  12204. +
  12205. + br = au_sbr(sb, bindex);
  12206. + err = h_permission(h_inode, mask, br->br_mnt,
  12207. + br->br_perm);
  12208. + }
  12209. + }
  12210. +
  12211. +out:
  12212. + ii_read_unlock(inode);
  12213. + si_read_unlock(sb);
  12214. + return err;
  12215. +}
  12216. +
  12217. +/* ---------------------------------------------------------------------- */
  12218. +
  12219. +static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
  12220. + struct nameidata *nd)
  12221. +{
  12222. + struct dentry *ret, *parent;
  12223. + struct inode *inode;
  12224. + struct super_block *sb;
  12225. + int err, npositive;
  12226. +
  12227. + IMustLock(dir);
  12228. +
  12229. + sb = dir->i_sb;
  12230. + err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
  12231. + ret = ERR_PTR(err);
  12232. + if (unlikely(err))
  12233. + goto out;
  12234. +
  12235. + ret = ERR_PTR(-ENAMETOOLONG);
  12236. + if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
  12237. + goto out_si;
  12238. + err = au_di_init(dentry);
  12239. + ret = ERR_PTR(err);
  12240. + if (unlikely(err))
  12241. + goto out_si;
  12242. +
  12243. + npositive = 0; /* suppress a warning */
  12244. + parent = dentry->d_parent; /* dir inode is locked */
  12245. + di_read_lock_parent(parent, AuLock_IR);
  12246. + err = au_alive_dir(parent);
  12247. + if (!err)
  12248. + err = au_digen_test(parent, au_sigen(sb));
  12249. + if (!err) {
  12250. + npositive = au_lkup_dentry(dentry, au_dbstart(parent),
  12251. + /*type*/0, nd);
  12252. + err = npositive;
  12253. + }
  12254. + di_read_unlock(parent, AuLock_IR);
  12255. + ret = ERR_PTR(err);
  12256. + if (unlikely(err < 0))
  12257. + goto out_unlock;
  12258. +
  12259. + inode = NULL;
  12260. + if (npositive) {
  12261. + inode = au_new_inode(dentry, /*must_new*/0);
  12262. + ret = (void *)inode;
  12263. + }
  12264. + if (IS_ERR(inode))
  12265. + goto out_unlock;
  12266. +
  12267. + ret = d_splice_alias(inode, dentry);
  12268. + if (unlikely(IS_ERR(ret) && inode)) {
  12269. + ii_write_unlock(inode);
  12270. + iput(inode);
  12271. + }
  12272. +
  12273. +out_unlock:
  12274. + di_write_unlock(dentry);
  12275. +out_si:
  12276. + si_read_unlock(sb);
  12277. +out:
  12278. + return ret;
  12279. +}
  12280. +
  12281. +/* ---------------------------------------------------------------------- */
  12282. +
  12283. +static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
  12284. + const unsigned char add_entry, aufs_bindex_t bcpup,
  12285. + aufs_bindex_t bstart)
  12286. +{
  12287. + int err;
  12288. + struct dentry *h_parent;
  12289. + struct inode *h_dir;
  12290. +
  12291. + if (add_entry)
  12292. + IMustLock(parent->d_inode);
  12293. + else
  12294. + di_write_lock_parent(parent);
  12295. +
  12296. + err = 0;
  12297. + if (!au_h_dptr(parent, bcpup)) {
  12298. + if (bstart < bcpup)
  12299. + err = au_cpdown_dirs(dentry, bcpup);
  12300. + else
  12301. + err = au_cpup_dirs(dentry, bcpup);
  12302. + }
  12303. + if (!err && add_entry) {
  12304. + h_parent = au_h_dptr(parent, bcpup);
  12305. + h_dir = h_parent->d_inode;
  12306. + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
  12307. + err = au_lkup_neg(dentry, bcpup);
  12308. + /* todo: no unlock here */
  12309. + mutex_unlock(&h_dir->i_mutex);
  12310. +
  12311. + AuDbg("bcpup %d\n", bcpup);
  12312. + if (!err) {
  12313. + if (!dentry->d_inode)
  12314. + au_set_h_dptr(dentry, bstart, NULL);
  12315. + au_update_dbrange(dentry, /*do_put_zero*/0);
  12316. + }
  12317. + }
  12318. +
  12319. + if (!add_entry)
  12320. + di_write_unlock(parent);
  12321. + if (!err)
  12322. + err = bcpup; /* success */
  12323. +
  12324. + AuTraceErr(err);
  12325. + return err;
  12326. +}
  12327. +
  12328. +/*
  12329. + * decide the branch and the parent dir where we will create a new entry.
  12330. + * returns new bindex or an error.
  12331. + * copyup the parent dir if needed.
  12332. + */
  12333. +int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
  12334. + struct au_wr_dir_args *args)
  12335. +{
  12336. + int err;
  12337. + aufs_bindex_t bcpup, bstart, src_bstart;
  12338. + const unsigned char add_entry = !!au_ftest_wrdir(args->flags,
  12339. + ADD_ENTRY);
  12340. + struct super_block *sb;
  12341. + struct dentry *parent;
  12342. + struct au_sbinfo *sbinfo;
  12343. +
  12344. + sb = dentry->d_sb;
  12345. + sbinfo = au_sbi(sb);
  12346. + parent = dget_parent(dentry);
  12347. + bstart = au_dbstart(dentry);
  12348. + bcpup = bstart;
  12349. + if (args->force_btgt < 0) {
  12350. + if (src_dentry) {
  12351. + src_bstart = au_dbstart(src_dentry);
  12352. + if (src_bstart < bstart)
  12353. + bcpup = src_bstart;
  12354. + } else if (add_entry) {
  12355. + err = AuWbrCreate(sbinfo, dentry,
  12356. + au_ftest_wrdir(args->flags, ISDIR));
  12357. + bcpup = err;
  12358. + }
  12359. +
  12360. + if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) {
  12361. + if (add_entry)
  12362. + err = AuWbrCopyup(sbinfo, dentry);
  12363. + else {
  12364. + if (!IS_ROOT(dentry)) {
  12365. + di_read_lock_parent(parent, !AuLock_IR);
  12366. + err = AuWbrCopyup(sbinfo, dentry);
  12367. + di_read_unlock(parent, !AuLock_IR);
  12368. + } else
  12369. + err = AuWbrCopyup(sbinfo, dentry);
  12370. + }
  12371. + bcpup = err;
  12372. + if (unlikely(err < 0))
  12373. + goto out;
  12374. + }
  12375. + } else {
  12376. + bcpup = args->force_btgt;
  12377. + AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode));
  12378. + }
  12379. +
  12380. + AuDbg("bstart %d, bcpup %d\n", bstart, bcpup);
  12381. + err = bcpup;
  12382. + if (bcpup == bstart)
  12383. + goto out; /* success */
  12384. +
  12385. + /* copyup the new parent into the branch we process */
  12386. + err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart);
  12387. + if (err >= 0) {
  12388. + if (!dentry->d_inode) {
  12389. + au_set_h_dptr(dentry, bstart, NULL);
  12390. + au_set_dbstart(dentry, bcpup);
  12391. + au_set_dbend(dentry, bcpup);
  12392. + }
  12393. + AuDebugOn(add_entry && !au_h_dptr(dentry, bcpup));
  12394. + }
  12395. +
  12396. +out:
  12397. + dput(parent);
  12398. + return err;
  12399. +}
  12400. +
  12401. +/* ---------------------------------------------------------------------- */
  12402. +
  12403. +struct dentry *au_pinned_h_parent(struct au_pin *pin)
  12404. +{
  12405. + if (pin && pin->parent)
  12406. + return au_h_dptr(pin->parent, pin->bindex);
  12407. + return NULL;
  12408. +}
  12409. +
  12410. +void au_unpin(struct au_pin *p)
  12411. +{
  12412. + if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE))
  12413. + mnt_drop_write(p->h_mnt);
  12414. + if (!p->hdir)
  12415. + return;
  12416. +
  12417. + au_hn_imtx_unlock(p->hdir);
  12418. + if (!au_ftest_pin(p->flags, DI_LOCKED))
  12419. + di_read_unlock(p->parent, AuLock_IR);
  12420. + iput(p->hdir->hi_inode);
  12421. + dput(p->parent);
  12422. + p->parent = NULL;
  12423. + p->hdir = NULL;
  12424. + p->h_mnt = NULL;
  12425. +}
  12426. +
  12427. +int au_do_pin(struct au_pin *p)
  12428. +{
  12429. + int err;
  12430. + struct super_block *sb;
  12431. + struct dentry *h_dentry, *h_parent;
  12432. + struct au_branch *br;
  12433. + struct inode *h_dir;
  12434. +
  12435. + err = 0;
  12436. + sb = p->dentry->d_sb;
  12437. + br = au_sbr(sb, p->bindex);
  12438. + if (IS_ROOT(p->dentry)) {
  12439. + if (au_ftest_pin(p->flags, MNT_WRITE)) {
  12440. + p->h_mnt = br->br_mnt;
  12441. + err = mnt_want_write(p->h_mnt);
  12442. + if (unlikely(err)) {
  12443. + au_fclr_pin(p->flags, MNT_WRITE);
  12444. + goto out_err;
  12445. + }
  12446. + }
  12447. + goto out;
  12448. + }
  12449. +
  12450. + h_dentry = NULL;
  12451. + if (p->bindex <= au_dbend(p->dentry))
  12452. + h_dentry = au_h_dptr(p->dentry, p->bindex);
  12453. +
  12454. + p->parent = dget_parent(p->dentry);
  12455. + if (!au_ftest_pin(p->flags, DI_LOCKED))
  12456. + di_read_lock(p->parent, AuLock_IR, p->lsc_di);
  12457. +
  12458. + h_dir = NULL;
  12459. + h_parent = au_h_dptr(p->parent, p->bindex);
  12460. + p->hdir = au_hi(p->parent->d_inode, p->bindex);
  12461. + if (p->hdir)
  12462. + h_dir = p->hdir->hi_inode;
  12463. +
  12464. + /*
  12465. + * udba case, or
  12466. + * if DI_LOCKED is not set, then p->parent may be different
  12467. + * and h_parent can be NULL.
  12468. + */
  12469. + if (unlikely(!p->hdir || !h_dir || !h_parent)) {
  12470. + err = -EBUSY;
  12471. + if (!au_ftest_pin(p->flags, DI_LOCKED))
  12472. + di_read_unlock(p->parent, AuLock_IR);
  12473. + dput(p->parent);
  12474. + p->parent = NULL;
  12475. + goto out_err;
  12476. + }
  12477. +
  12478. + au_igrab(h_dir);
  12479. + au_hn_imtx_lock_nested(p->hdir, p->lsc_hi);
  12480. +
  12481. + if (unlikely(p->hdir->hi_inode != h_parent->d_inode)) {
  12482. + err = -EBUSY;
  12483. + goto out_unpin;
  12484. + }
  12485. + if (h_dentry) {
  12486. + err = au_h_verify(h_dentry, p->udba, h_dir, h_parent, br);
  12487. + if (unlikely(err)) {
  12488. + au_fclr_pin(p->flags, MNT_WRITE);
  12489. + goto out_unpin;
  12490. + }
  12491. + }
  12492. +
  12493. + if (au_ftest_pin(p->flags, MNT_WRITE)) {
  12494. + p->h_mnt = br->br_mnt;
  12495. + err = mnt_want_write(p->h_mnt);
  12496. + if (unlikely(err)) {
  12497. + au_fclr_pin(p->flags, MNT_WRITE);
  12498. + goto out_unpin;
  12499. + }
  12500. + }
  12501. + goto out; /* success */
  12502. +
  12503. +out_unpin:
  12504. + au_unpin(p);
  12505. +out_err:
  12506. + pr_err("err %d\n", err);
  12507. + err = au_busy_or_stale();
  12508. +out:
  12509. + return err;
  12510. +}
  12511. +
  12512. +void au_pin_init(struct au_pin *p, struct dentry *dentry,
  12513. + aufs_bindex_t bindex, int lsc_di, int lsc_hi,
  12514. + unsigned int udba, unsigned char flags)
  12515. +{
  12516. + p->dentry = dentry;
  12517. + p->udba = udba;
  12518. + p->lsc_di = lsc_di;
  12519. + p->lsc_hi = lsc_hi;
  12520. + p->flags = flags;
  12521. + p->bindex = bindex;
  12522. +
  12523. + p->parent = NULL;
  12524. + p->hdir = NULL;
  12525. + p->h_mnt = NULL;
  12526. +}
  12527. +
  12528. +int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
  12529. + unsigned int udba, unsigned char flags)
  12530. +{
  12531. + au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
  12532. + udba, flags);
  12533. + return au_do_pin(pin);
  12534. +}
  12535. +
  12536. +/* ---------------------------------------------------------------------- */
  12537. +
  12538. +/*
  12539. + * ->setattr() and ->getattr() are called in various cases.
  12540. + * chmod, stat: dentry is revalidated.
  12541. + * fchmod, fstat: file and dentry are not revalidated, additionally they may be
  12542. + * unhashed.
  12543. + * for ->setattr(), ia->ia_file is passed from ftruncate only.
  12544. + */
  12545. +/* todo: consolidate with do_refresh() and simple_reval_dpath() */
  12546. +static int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
  12547. +{
  12548. + int err;
  12549. + struct inode *inode;
  12550. + struct dentry *parent;
  12551. +
  12552. + err = 0;
  12553. + inode = dentry->d_inode;
  12554. + if (au_digen_test(dentry, sigen)) {
  12555. + parent = dget_parent(dentry);
  12556. + di_read_lock_parent(parent, AuLock_IR);
  12557. + err = au_refresh_dentry(dentry, parent);
  12558. + di_read_unlock(parent, AuLock_IR);
  12559. + dput(parent);
  12560. + }
  12561. +
  12562. + AuTraceErr(err);
  12563. + return err;
  12564. +}
  12565. +
  12566. +#define AuIcpup_DID_CPUP 1
  12567. +#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
  12568. +#define au_fset_icpup(flags, name) \
  12569. + do { (flags) |= AuIcpup_##name; } while (0)
  12570. +#define au_fclr_icpup(flags, name) \
  12571. + do { (flags) &= ~AuIcpup_##name; } while (0)
  12572. +
  12573. +struct au_icpup_args {
  12574. + unsigned char flags;
  12575. + unsigned char pin_flags;
  12576. + aufs_bindex_t btgt;
  12577. + unsigned int udba;
  12578. + struct au_pin pin;
  12579. + struct path h_path;
  12580. + struct inode *h_inode;
  12581. +};
  12582. +
  12583. +static int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
  12584. + struct au_icpup_args *a)
  12585. +{
  12586. + int err;
  12587. + loff_t sz;
  12588. + aufs_bindex_t bstart, ibstart;
  12589. + struct dentry *hi_wh, *parent;
  12590. + struct inode *inode;
  12591. + struct file *h_file;
  12592. + struct au_wr_dir_args wr_dir_args = {
  12593. + .force_btgt = -1,
  12594. + .flags = 0
  12595. + };
  12596. +
  12597. + bstart = au_dbstart(dentry);
  12598. + inode = dentry->d_inode;
  12599. + if (S_ISDIR(inode->i_mode))
  12600. + au_fset_wrdir(wr_dir_args.flags, ISDIR);
  12601. + /* plink or hi_wh() case */
  12602. + ibstart = au_ibstart(inode);
  12603. + if (bstart != ibstart && !au_test_ro(inode->i_sb, ibstart, inode))
  12604. + wr_dir_args.force_btgt = ibstart;
  12605. + err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
  12606. + if (unlikely(err < 0))
  12607. + goto out;
  12608. + a->btgt = err;
  12609. + if (err != bstart)
  12610. + au_fset_icpup(a->flags, DID_CPUP);
  12611. +
  12612. + err = 0;
  12613. + a->pin_flags = AuPin_MNT_WRITE;
  12614. + parent = NULL;
  12615. + if (!IS_ROOT(dentry)) {
  12616. + au_fset_pin(a->pin_flags, DI_LOCKED);
  12617. + parent = dget_parent(dentry);
  12618. + di_write_lock_parent(parent);
  12619. + }
  12620. +
  12621. + err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags);
  12622. + if (unlikely(err))
  12623. + goto out_parent;
  12624. +
  12625. + a->h_path.dentry = au_h_dptr(dentry, bstart);
  12626. + a->h_inode = a->h_path.dentry->d_inode;
  12627. + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
  12628. + sz = -1;
  12629. + if ((ia->ia_valid & ATTR_SIZE) && ia->ia_size < i_size_read(a->h_inode))
  12630. + sz = ia->ia_size;
  12631. +
  12632. + h_file = NULL;
  12633. + hi_wh = NULL;
  12634. + if (au_ftest_icpup(a->flags, DID_CPUP) && au_d_removed(dentry)) {
  12635. + hi_wh = au_hi_wh(inode, a->btgt);
  12636. + if (!hi_wh) {
  12637. + err = au_sio_cpup_wh(dentry, a->btgt, sz, /*file*/NULL);
  12638. + if (unlikely(err))
  12639. + goto out_unlock;
  12640. + hi_wh = au_hi_wh(inode, a->btgt);
  12641. + /* todo: revalidate hi_wh? */
  12642. + }
  12643. + }
  12644. +
  12645. + if (parent) {
  12646. + au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
  12647. + di_downgrade_lock(parent, AuLock_IR);
  12648. + dput(parent);
  12649. + parent = NULL;
  12650. + }
  12651. + if (!au_ftest_icpup(a->flags, DID_CPUP))
  12652. + goto out; /* success */
  12653. +
  12654. + if (!d_unhashed(dentry)) {
  12655. + h_file = au_h_open_pre(dentry, bstart);
  12656. + if (IS_ERR(h_file)) {
  12657. + err = PTR_ERR(h_file);
  12658. + h_file = NULL;
  12659. + } else
  12660. + err = au_sio_cpup_simple(dentry, a->btgt, sz,
  12661. + AuCpup_DTIME);
  12662. + if (!err)
  12663. + a->h_path.dentry = au_h_dptr(dentry, a->btgt);
  12664. + } else if (!hi_wh)
  12665. + a->h_path.dentry = au_h_dptr(dentry, a->btgt);
  12666. + else
  12667. + a->h_path.dentry = hi_wh; /* do not dget here */
  12668. +
  12669. +out_unlock:
  12670. + mutex_unlock(&a->h_inode->i_mutex);
  12671. + au_h_open_post(dentry, bstart, h_file);
  12672. + a->h_inode = a->h_path.dentry->d_inode;
  12673. + if (!err) {
  12674. + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
  12675. + goto out; /* success */
  12676. + }
  12677. +
  12678. + au_unpin(&a->pin);
  12679. +out_parent:
  12680. + if (parent) {
  12681. + di_write_unlock(parent);
  12682. + dput(parent);
  12683. + }
  12684. +out:
  12685. + return err;
  12686. +}
  12687. +
  12688. +static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
  12689. +{
  12690. + int err;
  12691. + struct inode *inode;
  12692. + struct super_block *sb;
  12693. + struct file *file;
  12694. + struct au_icpup_args *a;
  12695. +
  12696. + inode = dentry->d_inode;
  12697. + IMustLock(inode);
  12698. +
  12699. + err = -ENOMEM;
  12700. + a = kzalloc(sizeof(*a), GFP_NOFS);
  12701. + if (unlikely(!a))
  12702. + goto out;
  12703. +
  12704. + if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
  12705. + ia->ia_valid &= ~ATTR_MODE;
  12706. +
  12707. + file = NULL;
  12708. + sb = dentry->d_sb;
  12709. + err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
  12710. + if (unlikely(err))
  12711. + goto out_kfree;
  12712. +
  12713. + if (ia->ia_valid & ATTR_FILE) {
  12714. + /* currently ftruncate(2) only */
  12715. + AuDebugOn(!S_ISREG(inode->i_mode));
  12716. + file = ia->ia_file;
  12717. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
  12718. + if (unlikely(err))
  12719. + goto out_si;
  12720. + ia->ia_file = au_hf_top(file);
  12721. + a->udba = AuOpt_UDBA_NONE;
  12722. + } else {
  12723. + /* fchmod() doesn't pass ia_file */
  12724. + a->udba = au_opt_udba(sb);
  12725. + /* no au_d_removed(), to set UDBA_NONE for root */
  12726. + if (d_unhashed(dentry))
  12727. + a->udba = AuOpt_UDBA_NONE;
  12728. + di_write_lock_child(dentry);
  12729. + if (a->udba != AuOpt_UDBA_NONE) {
  12730. + AuDebugOn(IS_ROOT(dentry));
  12731. + err = au_reval_for_attr(dentry, au_sigen(sb));
  12732. + if (unlikely(err))
  12733. + goto out_dentry;
  12734. + }
  12735. + }
  12736. +
  12737. + err = au_pin_and_icpup(dentry, ia, a);
  12738. + if (unlikely(err < 0))
  12739. + goto out_dentry;
  12740. + if (au_ftest_icpup(a->flags, DID_CPUP)) {
  12741. + ia->ia_file = NULL;
  12742. + ia->ia_valid &= ~ATTR_FILE;
  12743. + }
  12744. +
  12745. + a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
  12746. + if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME))
  12747. + == (ATTR_MODE | ATTR_CTIME)) {
  12748. + err = security_path_chmod(a->h_path.dentry, a->h_path.mnt,
  12749. + ia->ia_mode);
  12750. + if (unlikely(err))
  12751. + goto out_unlock;
  12752. + } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
  12753. + && (ia->ia_valid & ATTR_CTIME)) {
  12754. + err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid);
  12755. + if (unlikely(err))
  12756. + goto out_unlock;
  12757. + }
  12758. +
  12759. + if (ia->ia_valid & ATTR_SIZE) {
  12760. + struct file *f;
  12761. +
  12762. + if (ia->ia_size < i_size_read(inode))
  12763. + /* unmap only */
  12764. + truncate_setsize(inode, ia->ia_size);
  12765. +
  12766. + f = NULL;
  12767. + if (ia->ia_valid & ATTR_FILE)
  12768. + f = ia->ia_file;
  12769. + mutex_unlock(&a->h_inode->i_mutex);
  12770. + err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
  12771. + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
  12772. + } else
  12773. + err = vfsub_notify_change(&a->h_path, ia);
  12774. + if (!err)
  12775. + au_cpup_attr_changeable(inode);
  12776. +
  12777. +out_unlock:
  12778. + mutex_unlock(&a->h_inode->i_mutex);
  12779. + au_unpin(&a->pin);
  12780. + if (unlikely(err))
  12781. + au_update_dbstart(dentry);
  12782. +out_dentry:
  12783. + di_write_unlock(dentry);
  12784. + if (file) {
  12785. + fi_write_unlock(file);
  12786. + ia->ia_file = file;
  12787. + ia->ia_valid |= ATTR_FILE;
  12788. + }
  12789. +out_si:
  12790. + si_read_unlock(sb);
  12791. +out_kfree:
  12792. + kfree(a);
  12793. +out:
  12794. + AuTraceErr(err);
  12795. + return err;
  12796. +}
  12797. +
  12798. +static void au_refresh_iattr(struct inode *inode, struct kstat *st,
  12799. + unsigned int nlink)
  12800. +{
  12801. + inode->i_mode = st->mode;
  12802. + inode->i_uid = st->uid;
  12803. + inode->i_gid = st->gid;
  12804. + inode->i_atime = st->atime;
  12805. + inode->i_mtime = st->mtime;
  12806. + inode->i_ctime = st->ctime;
  12807. +
  12808. + au_cpup_attr_nlink(inode, /*force*/0);
  12809. + if (S_ISDIR(inode->i_mode)) {
  12810. + inode->i_nlink -= nlink;
  12811. + inode->i_nlink += st->nlink;
  12812. + }
  12813. +
  12814. + spin_lock(&inode->i_lock);
  12815. + inode->i_blocks = st->blocks;
  12816. + i_size_write(inode, st->size);
  12817. + spin_unlock(&inode->i_lock);
  12818. +}
  12819. +
  12820. +static int aufs_getattr(struct vfsmount *mnt __maybe_unused,
  12821. + struct dentry *dentry, struct kstat *st)
  12822. +{
  12823. + int err;
  12824. + unsigned int mnt_flags;
  12825. + aufs_bindex_t bindex;
  12826. + unsigned char udba_none, positive;
  12827. + struct super_block *sb, *h_sb;
  12828. + struct inode *inode;
  12829. + struct vfsmount *h_mnt;
  12830. + struct dentry *h_dentry;
  12831. +
  12832. + sb = dentry->d_sb;
  12833. + inode = dentry->d_inode;
  12834. + err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
  12835. + if (unlikely(err))
  12836. + goto out;
  12837. + mnt_flags = au_mntflags(sb);
  12838. + udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
  12839. +
  12840. + /* support fstat(2) */
  12841. + if (!au_d_removed(dentry) && !udba_none) {
  12842. + unsigned int sigen = au_sigen(sb);
  12843. + err = au_digen_test(dentry, sigen);
  12844. + if (!err) {
  12845. + di_read_lock_child(dentry, AuLock_IR);
  12846. + err = au_dbrange_test(dentry);
  12847. + if (unlikely(err))
  12848. + goto out_unlock;
  12849. + } else {
  12850. + AuDebugOn(IS_ROOT(dentry));
  12851. + di_write_lock_child(dentry);
  12852. + err = au_dbrange_test(dentry);
  12853. + if (!err)
  12854. + err = au_reval_for_attr(dentry, sigen);
  12855. + di_downgrade_lock(dentry, AuLock_IR);
  12856. + if (unlikely(err))
  12857. + goto out_unlock;
  12858. + }
  12859. + } else
  12860. + di_read_lock_child(dentry, AuLock_IR);
  12861. +
  12862. + bindex = au_ibstart(inode);
  12863. + h_mnt = au_sbr_mnt(sb, bindex);
  12864. + h_sb = h_mnt->mnt_sb;
  12865. + if (!au_test_fs_bad_iattr(h_sb) && udba_none)
  12866. + goto out_fill; /* success */
  12867. +
  12868. + h_dentry = NULL;
  12869. + if (au_dbstart(dentry) == bindex)
  12870. + h_dentry = dget(au_h_dptr(dentry, bindex));
  12871. + else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
  12872. + h_dentry = au_plink_lkup(inode, bindex);
  12873. + if (IS_ERR(h_dentry))
  12874. + goto out_fill; /* pretending success */
  12875. + }
  12876. + /* illegally overlapped or something */
  12877. + if (unlikely(!h_dentry))
  12878. + goto out_fill; /* pretending success */
  12879. +
  12880. + positive = !!h_dentry->d_inode;
  12881. + if (positive)
  12882. + err = vfs_getattr(h_mnt, h_dentry, st);
  12883. + dput(h_dentry);
  12884. + if (!err) {
  12885. + if (positive)
  12886. + au_refresh_iattr(inode, st, h_dentry->d_inode->i_nlink);
  12887. + goto out_fill; /* success */
  12888. + }
  12889. + AuTraceErr(err);
  12890. + goto out_unlock;
  12891. +
  12892. +out_fill:
  12893. + generic_fillattr(inode, st);
  12894. +out_unlock:
  12895. + di_read_unlock(dentry, AuLock_IR);
  12896. + si_read_unlock(sb);
  12897. +out:
  12898. + AuTraceErr(err);
  12899. + return err;
  12900. +}
  12901. +
  12902. +/* ---------------------------------------------------------------------- */
  12903. +
  12904. +static int h_readlink(struct dentry *dentry, int bindex, char __user *buf,
  12905. + int bufsiz)
  12906. +{
  12907. + int err;
  12908. + struct super_block *sb;
  12909. + struct dentry *h_dentry;
  12910. +
  12911. + err = -EINVAL;
  12912. + h_dentry = au_h_dptr(dentry, bindex);
  12913. + if (unlikely(!h_dentry->d_inode->i_op->readlink))
  12914. + goto out;
  12915. +
  12916. + err = security_inode_readlink(h_dentry);
  12917. + if (unlikely(err))
  12918. + goto out;
  12919. +
  12920. + sb = dentry->d_sb;
  12921. + if (!au_test_ro(sb, bindex, dentry->d_inode)) {
  12922. + vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry);
  12923. + fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode);
  12924. + }
  12925. + err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz);
  12926. +
  12927. +out:
  12928. + return err;
  12929. +}
  12930. +
  12931. +static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
  12932. +{
  12933. + int err;
  12934. +
  12935. + err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
  12936. + if (unlikely(err))
  12937. + goto out;
  12938. + err = au_d_hashed_positive(dentry);
  12939. + if (!err)
  12940. + err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz);
  12941. + aufs_read_unlock(dentry, AuLock_IR);
  12942. +
  12943. +out:
  12944. + return err;
  12945. +}
  12946. +
  12947. +static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd)
  12948. +{
  12949. + int err;
  12950. + mm_segment_t old_fs;
  12951. + union {
  12952. + char *k;
  12953. + char __user *u;
  12954. + } buf;
  12955. +
  12956. + err = -ENOMEM;
  12957. + buf.k = __getname_gfp(GFP_NOFS);
  12958. + if (unlikely(!buf.k))
  12959. + goto out;
  12960. +
  12961. + err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
  12962. + if (unlikely(err))
  12963. + goto out_name;
  12964. +
  12965. + err = au_d_hashed_positive(dentry);
  12966. + if (!err) {
  12967. + old_fs = get_fs();
  12968. + set_fs(KERNEL_DS);
  12969. + err = h_readlink(dentry, au_dbstart(dentry), buf.u, PATH_MAX);
  12970. + set_fs(old_fs);
  12971. + }
  12972. + aufs_read_unlock(dentry, AuLock_IR);
  12973. +
  12974. + if (err >= 0) {
  12975. + buf.k[err] = 0;
  12976. + /* will be freed by put_link */
  12977. + nd_set_link(nd, buf.k);
  12978. + return NULL; /* success */
  12979. + }
  12980. +
  12981. +out_name:
  12982. + __putname(buf.k);
  12983. +out:
  12984. + path_put(&nd->path);
  12985. + AuTraceErr(err);
  12986. + return ERR_PTR(err);
  12987. +}
  12988. +
  12989. +static void aufs_put_link(struct dentry *dentry __maybe_unused,
  12990. + struct nameidata *nd, void *cookie __maybe_unused)
  12991. +{
  12992. + __putname(nd_get_link(nd));
  12993. +}
  12994. +
  12995. +/* ---------------------------------------------------------------------- */
  12996. +
  12997. +static void aufs_truncate_range(struct inode *inode __maybe_unused,
  12998. + loff_t start __maybe_unused,
  12999. + loff_t end __maybe_unused)
  13000. +{
  13001. + AuUnsupport();
  13002. +}
  13003. +
  13004. +/* ---------------------------------------------------------------------- */
  13005. +
  13006. +struct inode_operations aufs_symlink_iop = {
  13007. + .permission = aufs_permission,
  13008. + .setattr = aufs_setattr,
  13009. + .getattr = aufs_getattr,
  13010. + .readlink = aufs_readlink,
  13011. + .follow_link = aufs_follow_link,
  13012. + .put_link = aufs_put_link
  13013. +};
  13014. +
  13015. +struct inode_operations aufs_dir_iop = {
  13016. + .create = aufs_create,
  13017. + .lookup = aufs_lookup,
  13018. + .link = aufs_link,
  13019. + .unlink = aufs_unlink,
  13020. + .symlink = aufs_symlink,
  13021. + .mkdir = aufs_mkdir,
  13022. + .rmdir = aufs_rmdir,
  13023. + .mknod = aufs_mknod,
  13024. + .rename = aufs_rename,
  13025. +
  13026. + .permission = aufs_permission,
  13027. + .setattr = aufs_setattr,
  13028. + .getattr = aufs_getattr
  13029. +};
  13030. +
  13031. +struct inode_operations aufs_iop = {
  13032. + .permission = aufs_permission,
  13033. + .setattr = aufs_setattr,
  13034. + .getattr = aufs_getattr,
  13035. + .truncate_range = aufs_truncate_range
  13036. +};
  13037. diff -Nur linux-2.6.37.orig/fs/aufs/i_op_add.c linux-2.6.37/fs/aufs/i_op_add.c
  13038. --- linux-2.6.37.orig/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
  13039. +++ linux-2.6.37/fs/aufs/i_op_add.c 2011-01-11 20:15:11.000000000 +0100
  13040. @@ -0,0 +1,702 @@
  13041. +/*
  13042. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  13043. + *
  13044. + * This program, aufs is free software; you can redistribute it and/or modify
  13045. + * it under the terms of the GNU General Public License as published by
  13046. + * the Free Software Foundation; either version 2 of the License, or
  13047. + * (at your option) any later version.
  13048. + *
  13049. + * This program is distributed in the hope that it will be useful,
  13050. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13051. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13052. + * GNU General Public License for more details.
  13053. + *
  13054. + * You should have received a copy of the GNU General Public License
  13055. + * along with this program; if not, write to the Free Software
  13056. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  13057. + */
  13058. +
  13059. +/*
  13060. + * inode operations (add entry)
  13061. + */
  13062. +
  13063. +#include "aufs.h"
  13064. +
  13065. +/*
  13066. + * final procedure of adding a new entry, except link(2).
  13067. + * remove whiteout, instantiate, copyup the parent dir's times and size
  13068. + * and update version.
  13069. + * if it failed, re-create the removed whiteout.
  13070. + */
  13071. +static int epilog(struct inode *dir, aufs_bindex_t bindex,
  13072. + struct dentry *wh_dentry, struct dentry *dentry)
  13073. +{
  13074. + int err, rerr;
  13075. + aufs_bindex_t bwh;
  13076. + struct path h_path;
  13077. + struct inode *inode, *h_dir;
  13078. + struct dentry *wh;
  13079. +
  13080. + bwh = -1;
  13081. + if (wh_dentry) {
  13082. + h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
  13083. + IMustLock(h_dir);
  13084. + AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
  13085. + bwh = au_dbwh(dentry);
  13086. + h_path.dentry = wh_dentry;
  13087. + h_path.mnt = au_sbr_mnt(dir->i_sb, bindex);
  13088. + err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
  13089. + dentry);
  13090. + if (unlikely(err))
  13091. + goto out;
  13092. + }
  13093. +
  13094. + inode = au_new_inode(dentry, /*must_new*/1);
  13095. + if (!IS_ERR(inode)) {
  13096. + d_instantiate(dentry, inode);
  13097. + dir = dentry->d_parent->d_inode; /* dir inode is locked */
  13098. + IMustLock(dir);
  13099. + if (au_ibstart(dir) == au_dbstart(dentry))
  13100. + au_cpup_attr_timesizes(dir);
  13101. + dir->i_version++;
  13102. + return 0; /* success */
  13103. + }
  13104. +
  13105. + err = PTR_ERR(inode);
  13106. + if (!wh_dentry)
  13107. + goto out;
  13108. +
  13109. + /* revert */
  13110. + /* dir inode is locked */
  13111. + wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
  13112. + rerr = PTR_ERR(wh);
  13113. + if (IS_ERR(wh)) {
  13114. + AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
  13115. + AuDLNPair(dentry), err, rerr);
  13116. + err = -EIO;
  13117. + } else
  13118. + dput(wh);
  13119. +
  13120. +out:
  13121. + return err;
  13122. +}
  13123. +
  13124. +static int au_d_may_add(struct dentry *dentry)
  13125. +{
  13126. + int err;
  13127. +
  13128. + err = 0;
  13129. + if (unlikely(d_unhashed(dentry)))
  13130. + err = -ENOENT;
  13131. + if (unlikely(dentry->d_inode))
  13132. + err = -EEXIST;
  13133. + return err;
  13134. +}
  13135. +
  13136. +/*
  13137. + * simple tests for the adding inode operations.
  13138. + * following the checks in vfs, plus the parent-child relationship.
  13139. + */
  13140. +int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
  13141. + struct dentry *h_parent, int isdir)
  13142. +{
  13143. + int err;
  13144. + umode_t h_mode;
  13145. + struct dentry *h_dentry;
  13146. + struct inode *h_inode;
  13147. +
  13148. + err = -ENAMETOOLONG;
  13149. + if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
  13150. + goto out;
  13151. +
  13152. + h_dentry = au_h_dptr(dentry, bindex);
  13153. + h_inode = h_dentry->d_inode;
  13154. + if (!dentry->d_inode) {
  13155. + err = -EEXIST;
  13156. + if (unlikely(h_inode))
  13157. + goto out;
  13158. + } else {
  13159. + /* rename(2) case */
  13160. + err = -EIO;
  13161. + if (unlikely(!h_inode || !h_inode->i_nlink))
  13162. + goto out;
  13163. +
  13164. + h_mode = h_inode->i_mode;
  13165. + if (!isdir) {
  13166. + err = -EISDIR;
  13167. + if (unlikely(S_ISDIR(h_mode)))
  13168. + goto out;
  13169. + } else if (unlikely(!S_ISDIR(h_mode))) {
  13170. + err = -ENOTDIR;
  13171. + goto out;
  13172. + }
  13173. + }
  13174. +
  13175. + err = 0;
  13176. + /* expected parent dir is locked */
  13177. + if (unlikely(h_parent != h_dentry->d_parent))
  13178. + err = -EIO;
  13179. +
  13180. +out:
  13181. + AuTraceErr(err);
  13182. + return err;
  13183. +}
  13184. +
  13185. +/*
  13186. + * initial procedure of adding a new entry.
  13187. + * prepare writable branch and the parent dir, lock it,
  13188. + * and lookup whiteout for the new entry.
  13189. + */
  13190. +static struct dentry*
  13191. +lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
  13192. + struct dentry *src_dentry, struct au_pin *pin,
  13193. + struct au_wr_dir_args *wr_dir_args)
  13194. +{
  13195. + struct dentry *wh_dentry, *h_parent;
  13196. + struct super_block *sb;
  13197. + struct au_branch *br;
  13198. + int err;
  13199. + unsigned int udba;
  13200. + aufs_bindex_t bcpup;
  13201. +
  13202. + AuDbg("%.*s\n", AuDLNPair(dentry));
  13203. +
  13204. + err = au_wr_dir(dentry, src_dentry, wr_dir_args);
  13205. + bcpup = err;
  13206. + wh_dentry = ERR_PTR(err);
  13207. + if (unlikely(err < 0))
  13208. + goto out;
  13209. +
  13210. + sb = dentry->d_sb;
  13211. + udba = au_opt_udba(sb);
  13212. + err = au_pin(pin, dentry, bcpup, udba,
  13213. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  13214. + wh_dentry = ERR_PTR(err);
  13215. + if (unlikely(err))
  13216. + goto out;
  13217. +
  13218. + h_parent = au_pinned_h_parent(pin);
  13219. + if (udba != AuOpt_UDBA_NONE
  13220. + && au_dbstart(dentry) == bcpup)
  13221. + err = au_may_add(dentry, bcpup, h_parent,
  13222. + au_ftest_wrdir(wr_dir_args->flags, ISDIR));
  13223. + else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
  13224. + err = -ENAMETOOLONG;
  13225. + wh_dentry = ERR_PTR(err);
  13226. + if (unlikely(err))
  13227. + goto out_unpin;
  13228. +
  13229. + br = au_sbr(sb, bcpup);
  13230. + if (dt) {
  13231. + struct path tmp = {
  13232. + .dentry = h_parent,
  13233. + .mnt = br->br_mnt
  13234. + };
  13235. + au_dtime_store(dt, au_pinned_parent(pin), &tmp);
  13236. + }
  13237. +
  13238. + wh_dentry = NULL;
  13239. + if (bcpup != au_dbwh(dentry))
  13240. + goto out; /* success */
  13241. +
  13242. + wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
  13243. +
  13244. +out_unpin:
  13245. + if (IS_ERR(wh_dentry))
  13246. + au_unpin(pin);
  13247. +out:
  13248. + return wh_dentry;
  13249. +}
  13250. +
  13251. +/* ---------------------------------------------------------------------- */
  13252. +
  13253. +enum { Mknod, Symlink, Creat };
  13254. +struct simple_arg {
  13255. + int type;
  13256. + union {
  13257. + struct {
  13258. + int mode;
  13259. + struct nameidata *nd;
  13260. + } c;
  13261. + struct {
  13262. + const char *symname;
  13263. + } s;
  13264. + struct {
  13265. + int mode;
  13266. + dev_t dev;
  13267. + } m;
  13268. + } u;
  13269. +};
  13270. +
  13271. +static int add_simple(struct inode *dir, struct dentry *dentry,
  13272. + struct simple_arg *arg)
  13273. +{
  13274. + int err;
  13275. + aufs_bindex_t bstart;
  13276. + unsigned char created;
  13277. + struct au_dtime dt;
  13278. + struct au_pin pin;
  13279. + struct path h_path;
  13280. + struct dentry *wh_dentry, *parent;
  13281. + struct inode *h_dir;
  13282. + struct au_wr_dir_args wr_dir_args = {
  13283. + .force_btgt = -1,
  13284. + .flags = AuWrDir_ADD_ENTRY
  13285. + };
  13286. +
  13287. + AuDbg("%.*s\n", AuDLNPair(dentry));
  13288. + IMustLock(dir);
  13289. +
  13290. + parent = dentry->d_parent; /* dir inode is locked */
  13291. + err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
  13292. + if (unlikely(err))
  13293. + goto out;
  13294. + err = au_d_may_add(dentry);
  13295. + if (unlikely(err))
  13296. + goto out_unlock;
  13297. + di_write_lock_parent(parent);
  13298. + wh_dentry = lock_hdir_lkup_wh(dentry, &dt, /*src_dentry*/NULL, &pin,
  13299. + &wr_dir_args);
  13300. + err = PTR_ERR(wh_dentry);
  13301. + if (IS_ERR(wh_dentry))
  13302. + goto out_parent;
  13303. +
  13304. + bstart = au_dbstart(dentry);
  13305. + h_path.dentry = au_h_dptr(dentry, bstart);
  13306. + h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
  13307. + h_dir = au_pinned_h_dir(&pin);
  13308. + switch (arg->type) {
  13309. + case Creat:
  13310. + err = vfsub_create(h_dir, &h_path, arg->u.c.mode);
  13311. + break;
  13312. + case Symlink:
  13313. + err = vfsub_symlink(h_dir, &h_path, arg->u.s.symname);
  13314. + break;
  13315. + case Mknod:
  13316. + err = vfsub_mknod(h_dir, &h_path, arg->u.m.mode, arg->u.m.dev);
  13317. + break;
  13318. + default:
  13319. + BUG();
  13320. + }
  13321. + created = !err;
  13322. + if (!err)
  13323. + err = epilog(dir, bstart, wh_dentry, dentry);
  13324. +
  13325. + /* revert */
  13326. + if (unlikely(created && err && h_path.dentry->d_inode)) {
  13327. + int rerr;
  13328. + rerr = vfsub_unlink(h_dir, &h_path, /*force*/0);
  13329. + if (rerr) {
  13330. + AuIOErr("%.*s revert failure(%d, %d)\n",
  13331. + AuDLNPair(dentry), err, rerr);
  13332. + err = -EIO;
  13333. + }
  13334. + au_dtime_revert(&dt);
  13335. + }
  13336. +
  13337. + au_unpin(&pin);
  13338. + dput(wh_dentry);
  13339. +
  13340. +out_parent:
  13341. + di_write_unlock(parent);
  13342. +out_unlock:
  13343. + if (unlikely(err)) {
  13344. + au_update_dbstart(dentry);
  13345. + d_drop(dentry);
  13346. + }
  13347. + aufs_read_unlock(dentry, AuLock_DW);
  13348. +out:
  13349. + return err;
  13350. +}
  13351. +
  13352. +int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
  13353. +{
  13354. + struct simple_arg arg = {
  13355. + .type = Mknod,
  13356. + .u.m = {
  13357. + .mode = mode,
  13358. + .dev = dev
  13359. + }
  13360. + };
  13361. + return add_simple(dir, dentry, &arg);
  13362. +}
  13363. +
  13364. +int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
  13365. +{
  13366. + struct simple_arg arg = {
  13367. + .type = Symlink,
  13368. + .u.s.symname = symname
  13369. + };
  13370. + return add_simple(dir, dentry, &arg);
  13371. +}
  13372. +
  13373. +int aufs_create(struct inode *dir, struct dentry *dentry, int mode,
  13374. + struct nameidata *nd)
  13375. +{
  13376. + struct simple_arg arg = {
  13377. + .type = Creat,
  13378. + .u.c = {
  13379. + .mode = mode,
  13380. + .nd = nd
  13381. + }
  13382. + };
  13383. + return add_simple(dir, dentry, &arg);
  13384. +}
  13385. +
  13386. +/* ---------------------------------------------------------------------- */
  13387. +
  13388. +struct au_link_args {
  13389. + aufs_bindex_t bdst, bsrc;
  13390. + struct au_pin pin;
  13391. + struct path h_path;
  13392. + struct dentry *src_parent, *parent;
  13393. +};
  13394. +
  13395. +static int au_cpup_before_link(struct dentry *src_dentry,
  13396. + struct au_link_args *a)
  13397. +{
  13398. + int err;
  13399. + struct dentry *h_src_dentry;
  13400. + struct mutex *h_mtx;
  13401. + struct file *h_file;
  13402. +
  13403. + di_read_lock_parent(a->src_parent, AuLock_IR);
  13404. + err = au_test_and_cpup_dirs(src_dentry, a->bdst);
  13405. + if (unlikely(err))
  13406. + goto out;
  13407. +
  13408. + h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
  13409. + h_mtx = &h_src_dentry->d_inode->i_mutex;
  13410. + err = au_pin(&a->pin, src_dentry, a->bdst,
  13411. + au_opt_udba(src_dentry->d_sb),
  13412. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  13413. + if (unlikely(err))
  13414. + goto out;
  13415. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  13416. + h_file = au_h_open_pre(src_dentry, a->bsrc);
  13417. + if (IS_ERR(h_file)) {
  13418. + err = PTR_ERR(h_file);
  13419. + h_file = NULL;
  13420. + } else
  13421. + err = au_sio_cpup_simple(src_dentry, a->bdst, a->bsrc,
  13422. + AuCpup_DTIME /* | AuCpup_KEEPLINO */);
  13423. + mutex_unlock(h_mtx);
  13424. + au_h_open_post(src_dentry, a->bsrc, h_file);
  13425. + au_unpin(&a->pin);
  13426. +
  13427. +out:
  13428. + di_read_unlock(a->src_parent, AuLock_IR);
  13429. + return err;
  13430. +}
  13431. +
  13432. +static int au_cpup_or_link(struct dentry *src_dentry, struct au_link_args *a)
  13433. +{
  13434. + int err;
  13435. + unsigned char plink;
  13436. + struct inode *h_inode, *inode;
  13437. + struct dentry *h_src_dentry;
  13438. + struct super_block *sb;
  13439. + struct file *h_file;
  13440. +
  13441. + plink = 0;
  13442. + h_inode = NULL;
  13443. + sb = src_dentry->d_sb;
  13444. + inode = src_dentry->d_inode;
  13445. + if (au_ibstart(inode) <= a->bdst)
  13446. + h_inode = au_h_iptr(inode, a->bdst);
  13447. + if (!h_inode || !h_inode->i_nlink) {
  13448. + /* copyup src_dentry as the name of dentry. */
  13449. + au_set_dbstart(src_dentry, a->bdst);
  13450. + au_set_h_dptr(src_dentry, a->bdst, dget(a->h_path.dentry));
  13451. + h_inode = au_h_dptr(src_dentry, a->bsrc)->d_inode;
  13452. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  13453. + h_file = au_h_open_pre(src_dentry, a->bsrc);
  13454. + if (IS_ERR(h_file)) {
  13455. + err = PTR_ERR(h_file);
  13456. + h_file = NULL;
  13457. + } else
  13458. + err = au_sio_cpup_single(src_dentry, a->bdst, a->bsrc,
  13459. + -1, AuCpup_KEEPLINO,
  13460. + a->parent);
  13461. + mutex_unlock(&h_inode->i_mutex);
  13462. + au_h_open_post(src_dentry, a->bsrc, h_file);
  13463. + au_set_h_dptr(src_dentry, a->bdst, NULL);
  13464. + au_set_dbstart(src_dentry, a->bsrc);
  13465. + } else {
  13466. + /* the inode of src_dentry already exists on a.bdst branch */
  13467. + h_src_dentry = d_find_alias(h_inode);
  13468. + if (!h_src_dentry && au_plink_test(inode)) {
  13469. + plink = 1;
  13470. + h_src_dentry = au_plink_lkup(inode, a->bdst);
  13471. + err = PTR_ERR(h_src_dentry);
  13472. + if (IS_ERR(h_src_dentry))
  13473. + goto out;
  13474. +
  13475. + if (unlikely(!h_src_dentry->d_inode)) {
  13476. + dput(h_src_dentry);
  13477. + h_src_dentry = NULL;
  13478. + }
  13479. +
  13480. + }
  13481. + if (h_src_dentry) {
  13482. + err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
  13483. + &a->h_path);
  13484. + dput(h_src_dentry);
  13485. + } else {
  13486. + AuIOErr("no dentry found for hi%lu on b%d\n",
  13487. + h_inode->i_ino, a->bdst);
  13488. + err = -EIO;
  13489. + }
  13490. + }
  13491. +
  13492. + if (!err && !plink)
  13493. + au_plink_append(inode, a->bdst, a->h_path.dentry);
  13494. +
  13495. +out:
  13496. + return err;
  13497. +}
  13498. +
  13499. +int aufs_link(struct dentry *src_dentry, struct inode *dir,
  13500. + struct dentry *dentry)
  13501. +{
  13502. + int err, rerr;
  13503. + struct au_dtime dt;
  13504. + struct au_link_args *a;
  13505. + struct dentry *wh_dentry, *h_src_dentry;
  13506. + struct inode *inode;
  13507. + struct super_block *sb;
  13508. + struct au_wr_dir_args wr_dir_args = {
  13509. + /* .force_btgt = -1, */
  13510. + .flags = AuWrDir_ADD_ENTRY
  13511. + };
  13512. +
  13513. + IMustLock(dir);
  13514. + inode = src_dentry->d_inode;
  13515. + IMustLock(inode);
  13516. +
  13517. + err = -ENOMEM;
  13518. + a = kzalloc(sizeof(*a), GFP_NOFS);
  13519. + if (unlikely(!a))
  13520. + goto out;
  13521. +
  13522. + a->parent = dentry->d_parent; /* dir inode is locked */
  13523. + err = aufs_read_and_write_lock2(dentry, src_dentry,
  13524. + AuLock_NOPLM | AuLock_GEN);
  13525. + if (unlikely(err))
  13526. + goto out_kfree;
  13527. + err = au_d_hashed_positive(src_dentry);
  13528. + if (unlikely(err))
  13529. + goto out_unlock;
  13530. + err = au_d_may_add(dentry);
  13531. + if (unlikely(err))
  13532. + goto out_unlock;
  13533. +
  13534. + a->src_parent = dget_parent(src_dentry);
  13535. + wr_dir_args.force_btgt = au_dbstart(src_dentry);
  13536. +
  13537. + di_write_lock_parent(a->parent);
  13538. + wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
  13539. + wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
  13540. + &wr_dir_args);
  13541. + err = PTR_ERR(wh_dentry);
  13542. + if (IS_ERR(wh_dentry))
  13543. + goto out_parent;
  13544. +
  13545. + err = 0;
  13546. + sb = dentry->d_sb;
  13547. + a->bdst = au_dbstart(dentry);
  13548. + a->h_path.dentry = au_h_dptr(dentry, a->bdst);
  13549. + a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
  13550. + a->bsrc = au_dbstart(src_dentry);
  13551. + if (au_opt_test(au_mntflags(sb), PLINK)) {
  13552. + if (a->bdst < a->bsrc
  13553. + /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
  13554. + err = au_cpup_or_link(src_dentry, a);
  13555. + else {
  13556. + h_src_dentry = au_h_dptr(src_dentry, a->bdst);
  13557. + err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
  13558. + &a->h_path);
  13559. + }
  13560. + } else {
  13561. + /*
  13562. + * copyup src_dentry to the branch we process,
  13563. + * and then link(2) to it.
  13564. + */
  13565. + if (a->bdst < a->bsrc
  13566. + /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
  13567. + au_unpin(&a->pin);
  13568. + di_write_unlock(a->parent);
  13569. + err = au_cpup_before_link(src_dentry, a);
  13570. + di_write_lock_parent(a->parent);
  13571. + if (!err)
  13572. + err = au_pin(&a->pin, dentry, a->bdst,
  13573. + au_opt_udba(sb),
  13574. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  13575. + if (unlikely(err))
  13576. + goto out_wh;
  13577. + }
  13578. + if (!err) {
  13579. + h_src_dentry = au_h_dptr(src_dentry, a->bdst);
  13580. + err = -ENOENT;
  13581. + if (h_src_dentry && h_src_dentry->d_inode)
  13582. + err = vfsub_link(h_src_dentry,
  13583. + au_pinned_h_dir(&a->pin),
  13584. + &a->h_path);
  13585. + }
  13586. + }
  13587. + if (unlikely(err))
  13588. + goto out_unpin;
  13589. +
  13590. + if (wh_dentry) {
  13591. + a->h_path.dentry = wh_dentry;
  13592. + err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
  13593. + dentry);
  13594. + if (unlikely(err))
  13595. + goto out_revert;
  13596. + }
  13597. +
  13598. + dir->i_version++;
  13599. + if (au_ibstart(dir) == au_dbstart(dentry))
  13600. + au_cpup_attr_timesizes(dir);
  13601. + inc_nlink(inode);
  13602. + inode->i_ctime = dir->i_ctime;
  13603. + d_instantiate(dentry, au_igrab(inode));
  13604. + if (d_unhashed(a->h_path.dentry))
  13605. + /* some filesystem calls d_drop() */
  13606. + d_drop(dentry);
  13607. + goto out_unpin; /* success */
  13608. +
  13609. +out_revert:
  13610. + rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path, /*force*/0);
  13611. + if (unlikely(rerr)) {
  13612. + AuIOErr("%.*s reverting failed(%d, %d)\n",
  13613. + AuDLNPair(dentry), err, rerr);
  13614. + err = -EIO;
  13615. + }
  13616. + au_dtime_revert(&dt);
  13617. +out_unpin:
  13618. + au_unpin(&a->pin);
  13619. +out_wh:
  13620. + dput(wh_dentry);
  13621. +out_parent:
  13622. + di_write_unlock(a->parent);
  13623. + dput(a->src_parent);
  13624. +out_unlock:
  13625. + if (unlikely(err)) {
  13626. + au_update_dbstart(dentry);
  13627. + d_drop(dentry);
  13628. + }
  13629. + aufs_read_and_write_unlock2(dentry, src_dentry);
  13630. +out_kfree:
  13631. + kfree(a);
  13632. +out:
  13633. + return err;
  13634. +}
  13635. +
  13636. +int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
  13637. +{
  13638. + int err, rerr;
  13639. + aufs_bindex_t bindex;
  13640. + unsigned char diropq;
  13641. + struct path h_path;
  13642. + struct dentry *wh_dentry, *parent, *opq_dentry;
  13643. + struct mutex *h_mtx;
  13644. + struct super_block *sb;
  13645. + struct {
  13646. + struct au_pin pin;
  13647. + struct au_dtime dt;
  13648. + } *a; /* reduce the stack usage */
  13649. + struct au_wr_dir_args wr_dir_args = {
  13650. + .force_btgt = -1,
  13651. + .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
  13652. + };
  13653. +
  13654. + IMustLock(dir);
  13655. +
  13656. + err = -ENOMEM;
  13657. + a = kmalloc(sizeof(*a), GFP_NOFS);
  13658. + if (unlikely(!a))
  13659. + goto out;
  13660. +
  13661. + err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
  13662. + if (unlikely(err))
  13663. + goto out_free;
  13664. + err = au_d_may_add(dentry);
  13665. + if (unlikely(err))
  13666. + goto out_unlock;
  13667. +
  13668. + parent = dentry->d_parent; /* dir inode is locked */
  13669. + di_write_lock_parent(parent);
  13670. + wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
  13671. + &a->pin, &wr_dir_args);
  13672. + err = PTR_ERR(wh_dentry);
  13673. + if (IS_ERR(wh_dentry))
  13674. + goto out_parent;
  13675. +
  13676. + sb = dentry->d_sb;
  13677. + bindex = au_dbstart(dentry);
  13678. + h_path.dentry = au_h_dptr(dentry, bindex);
  13679. + h_path.mnt = au_sbr_mnt(sb, bindex);
  13680. + err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
  13681. + if (unlikely(err))
  13682. + goto out_unpin;
  13683. +
  13684. + /* make the dir opaque */
  13685. + diropq = 0;
  13686. + h_mtx = &h_path.dentry->d_inode->i_mutex;
  13687. + if (wh_dentry
  13688. + || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
  13689. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  13690. + opq_dentry = au_diropq_create(dentry, bindex);
  13691. + mutex_unlock(h_mtx);
  13692. + err = PTR_ERR(opq_dentry);
  13693. + if (IS_ERR(opq_dentry))
  13694. + goto out_dir;
  13695. + dput(opq_dentry);
  13696. + diropq = 1;
  13697. + }
  13698. +
  13699. + err = epilog(dir, bindex, wh_dentry, dentry);
  13700. + if (!err) {
  13701. + inc_nlink(dir);
  13702. + goto out_unpin; /* success */
  13703. + }
  13704. +
  13705. + /* revert */
  13706. + if (diropq) {
  13707. + AuLabel(revert opq);
  13708. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  13709. + rerr = au_diropq_remove(dentry, bindex);
  13710. + mutex_unlock(h_mtx);
  13711. + if (rerr) {
  13712. + AuIOErr("%.*s reverting diropq failed(%d, %d)\n",
  13713. + AuDLNPair(dentry), err, rerr);
  13714. + err = -EIO;
  13715. + }
  13716. + }
  13717. +
  13718. +out_dir:
  13719. + AuLabel(revert dir);
  13720. + rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
  13721. + if (rerr) {
  13722. + AuIOErr("%.*s reverting dir failed(%d, %d)\n",
  13723. + AuDLNPair(dentry), err, rerr);
  13724. + err = -EIO;
  13725. + }
  13726. + au_dtime_revert(&a->dt);
  13727. +out_unpin:
  13728. + au_unpin(&a->pin);
  13729. + dput(wh_dentry);
  13730. +out_parent:
  13731. + di_write_unlock(parent);
  13732. +out_unlock:
  13733. + if (unlikely(err)) {
  13734. + au_update_dbstart(dentry);
  13735. + d_drop(dentry);
  13736. + }
  13737. + aufs_read_unlock(dentry, AuLock_DW);
  13738. +out_free:
  13739. + kfree(a);
  13740. +out:
  13741. + return err;
  13742. +}
  13743. diff -Nur linux-2.6.37.orig/fs/aufs/i_op_del.c linux-2.6.37/fs/aufs/i_op_del.c
  13744. --- linux-2.6.37.orig/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
  13745. +++ linux-2.6.37/fs/aufs/i_op_del.c 2011-01-11 20:15:11.000000000 +0100
  13746. @@ -0,0 +1,481 @@
  13747. +/*
  13748. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  13749. + *
  13750. + * This program, aufs is free software; you can redistribute it and/or modify
  13751. + * it under the terms of the GNU General Public License as published by
  13752. + * the Free Software Foundation; either version 2 of the License, or
  13753. + * (at your option) any later version.
  13754. + *
  13755. + * This program is distributed in the hope that it will be useful,
  13756. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13757. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13758. + * GNU General Public License for more details.
  13759. + *
  13760. + * You should have received a copy of the GNU General Public License
  13761. + * along with this program; if not, write to the Free Software
  13762. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  13763. + */
  13764. +
  13765. +/*
  13766. + * inode operations (del entry)
  13767. + */
  13768. +
  13769. +#include "aufs.h"
  13770. +
  13771. +/*
  13772. + * decide if a new whiteout for @dentry is necessary or not.
  13773. + * when it is necessary, prepare the parent dir for the upper branch whose
  13774. + * branch index is @bcpup for creation. the actual creation of the whiteout will
  13775. + * be done by caller.
  13776. + * return value:
  13777. + * 0: wh is unnecessary
  13778. + * plus: wh is necessary
  13779. + * minus: error
  13780. + */
  13781. +int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
  13782. +{
  13783. + int need_wh, err;
  13784. + aufs_bindex_t bstart;
  13785. + struct super_block *sb;
  13786. +
  13787. + sb = dentry->d_sb;
  13788. + bstart = au_dbstart(dentry);
  13789. + if (*bcpup < 0) {
  13790. + *bcpup = bstart;
  13791. + if (au_test_ro(sb, bstart, dentry->d_inode)) {
  13792. + err = AuWbrCopyup(au_sbi(sb), dentry);
  13793. + *bcpup = err;
  13794. + if (unlikely(err < 0))
  13795. + goto out;
  13796. + }
  13797. + } else
  13798. + AuDebugOn(bstart < *bcpup
  13799. + || au_test_ro(sb, *bcpup, dentry->d_inode));
  13800. + AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
  13801. +
  13802. + if (*bcpup != bstart) {
  13803. + err = au_cpup_dirs(dentry, *bcpup);
  13804. + if (unlikely(err))
  13805. + goto out;
  13806. + need_wh = 1;
  13807. + } else {
  13808. + struct au_dinfo *dinfo, *tmp;
  13809. +
  13810. + need_wh = -ENOMEM;
  13811. + dinfo = au_di(dentry);
  13812. + tmp = au_di_alloc(sb, AuLsc_DI_TMP);
  13813. + if (tmp) {
  13814. + au_di_cp(tmp, dinfo);
  13815. + au_di_swap(tmp, dinfo);
  13816. + /* returns the number of positive dentries */
  13817. + need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0,
  13818. + /*nd*/NULL);
  13819. + au_di_swap(tmp, dinfo);
  13820. + au_rw_write_unlock(&tmp->di_rwsem);
  13821. + au_di_free(tmp);
  13822. + }
  13823. + }
  13824. + AuDbg("need_wh %d\n", need_wh);
  13825. + err = need_wh;
  13826. +
  13827. +out:
  13828. + return err;
  13829. +}
  13830. +
  13831. +/*
  13832. + * simple tests for the del-entry operations.
  13833. + * following the checks in vfs, plus the parent-child relationship.
  13834. + */
  13835. +int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
  13836. + struct dentry *h_parent, int isdir)
  13837. +{
  13838. + int err;
  13839. + umode_t h_mode;
  13840. + struct dentry *h_dentry, *h_latest;
  13841. + struct inode *h_inode;
  13842. +
  13843. + h_dentry = au_h_dptr(dentry, bindex);
  13844. + h_inode = h_dentry->d_inode;
  13845. + if (dentry->d_inode) {
  13846. + err = -ENOENT;
  13847. + if (unlikely(!h_inode || !h_inode->i_nlink))
  13848. + goto out;
  13849. +
  13850. + h_mode = h_inode->i_mode;
  13851. + if (!isdir) {
  13852. + err = -EISDIR;
  13853. + if (unlikely(S_ISDIR(h_mode)))
  13854. + goto out;
  13855. + } else if (unlikely(!S_ISDIR(h_mode))) {
  13856. + err = -ENOTDIR;
  13857. + goto out;
  13858. + }
  13859. + } else {
  13860. + /* rename(2) case */
  13861. + err = -EIO;
  13862. + if (unlikely(h_inode))
  13863. + goto out;
  13864. + }
  13865. +
  13866. + err = -ENOENT;
  13867. + /* expected parent dir is locked */
  13868. + if (unlikely(h_parent != h_dentry->d_parent))
  13869. + goto out;
  13870. + err = 0;
  13871. +
  13872. + /*
  13873. + * rmdir a dir may break the consistency on some filesystem.
  13874. + * let's try heavy test.
  13875. + */
  13876. + err = -EACCES;
  13877. + if (unlikely(au_test_h_perm(h_parent->d_inode, MAY_EXEC | MAY_WRITE)))
  13878. + goto out;
  13879. +
  13880. + h_latest = au_sio_lkup_one(&dentry->d_name, h_parent,
  13881. + au_sbr(dentry->d_sb, bindex));
  13882. + err = -EIO;
  13883. + if (IS_ERR(h_latest))
  13884. + goto out;
  13885. + if (h_latest == h_dentry)
  13886. + err = 0;
  13887. + dput(h_latest);
  13888. +
  13889. +out:
  13890. + return err;
  13891. +}
  13892. +
  13893. +/*
  13894. + * decide the branch where we operate for @dentry. the branch index will be set
  13895. + * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
  13896. + * dir for reverting.
  13897. + * when a new whiteout is necessary, create it.
  13898. + */
  13899. +static struct dentry*
  13900. +lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
  13901. + struct au_dtime *dt, struct au_pin *pin)
  13902. +{
  13903. + struct dentry *wh_dentry;
  13904. + struct super_block *sb;
  13905. + struct path h_path;
  13906. + int err, need_wh;
  13907. + unsigned int udba;
  13908. + aufs_bindex_t bcpup;
  13909. +
  13910. + need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
  13911. + wh_dentry = ERR_PTR(need_wh);
  13912. + if (unlikely(need_wh < 0))
  13913. + goto out;
  13914. +
  13915. + sb = dentry->d_sb;
  13916. + udba = au_opt_udba(sb);
  13917. + bcpup = *rbcpup;
  13918. + err = au_pin(pin, dentry, bcpup, udba,
  13919. + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
  13920. + wh_dentry = ERR_PTR(err);
  13921. + if (unlikely(err))
  13922. + goto out;
  13923. +
  13924. + h_path.dentry = au_pinned_h_parent(pin);
  13925. + if (udba != AuOpt_UDBA_NONE
  13926. + && au_dbstart(dentry) == bcpup) {
  13927. + err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
  13928. + wh_dentry = ERR_PTR(err);
  13929. + if (unlikely(err))
  13930. + goto out_unpin;
  13931. + }
  13932. +
  13933. + h_path.mnt = au_sbr_mnt(sb, bcpup);
  13934. + au_dtime_store(dt, au_pinned_parent(pin), &h_path);
  13935. + wh_dentry = NULL;
  13936. + if (!need_wh)
  13937. + goto out; /* success, no need to create whiteout */
  13938. +
  13939. + wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
  13940. + if (IS_ERR(wh_dentry))
  13941. + goto out_unpin;
  13942. +
  13943. + /* returns with the parent is locked and wh_dentry is dget-ed */
  13944. + goto out; /* success */
  13945. +
  13946. +out_unpin:
  13947. + au_unpin(pin);
  13948. +out:
  13949. + return wh_dentry;
  13950. +}
  13951. +
  13952. +/*
  13953. + * when removing a dir, rename it to a unique temporary whiteout-ed name first
  13954. + * in order to be revertible and save time for removing many child whiteouts
  13955. + * under the dir.
  13956. + * returns 1 when there are too many child whiteout and caller should remove
  13957. + * them asynchronously. returns 0 when the number of children is enough small to
  13958. + * remove now or the branch fs is a remote fs.
  13959. + * otherwise return an error.
  13960. + */
  13961. +static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
  13962. + struct au_nhash *whlist, struct inode *dir)
  13963. +{
  13964. + int rmdir_later, err, dirwh;
  13965. + struct dentry *h_dentry;
  13966. + struct super_block *sb;
  13967. +
  13968. + sb = dentry->d_sb;
  13969. + SiMustAnyLock(sb);
  13970. + h_dentry = au_h_dptr(dentry, bindex);
  13971. + err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
  13972. + if (unlikely(err))
  13973. + goto out;
  13974. +
  13975. + /* stop monitoring */
  13976. + au_hn_free(au_hi(dentry->d_inode, bindex));
  13977. +
  13978. + if (!au_test_fs_remote(h_dentry->d_sb)) {
  13979. + dirwh = au_sbi(sb)->si_dirwh;
  13980. + rmdir_later = (dirwh <= 1);
  13981. + if (!rmdir_later)
  13982. + rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
  13983. + dirwh);
  13984. + if (rmdir_later)
  13985. + return rmdir_later;
  13986. + }
  13987. +
  13988. + err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
  13989. + if (unlikely(err)) {
  13990. + AuIOErr("rmdir %.*s, b%d failed, %d. ignored\n",
  13991. + AuDLNPair(h_dentry), bindex, err);
  13992. + err = 0;
  13993. + }
  13994. +
  13995. +out:
  13996. + AuTraceErr(err);
  13997. + return err;
  13998. +}
  13999. +
  14000. +/*
  14001. + * final procedure for deleting a entry.
  14002. + * maintain dentry and iattr.
  14003. + */
  14004. +static void epilog(struct inode *dir, struct dentry *dentry,
  14005. + aufs_bindex_t bindex)
  14006. +{
  14007. + struct inode *inode;
  14008. +
  14009. + inode = dentry->d_inode;
  14010. + d_drop(dentry);
  14011. + inode->i_ctime = dir->i_ctime;
  14012. +
  14013. + if (au_ibstart(dir) == bindex)
  14014. + au_cpup_attr_timesizes(dir);
  14015. + dir->i_version++;
  14016. +}
  14017. +
  14018. +/*
  14019. + * when an error happened, remove the created whiteout and revert everything.
  14020. + */
  14021. +static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex,
  14022. + aufs_bindex_t bwh, struct dentry *wh_dentry,
  14023. + struct dentry *dentry, struct au_dtime *dt)
  14024. +{
  14025. + int rerr;
  14026. + struct path h_path = {
  14027. + .dentry = wh_dentry,
  14028. + .mnt = au_sbr_mnt(dir->i_sb, bindex)
  14029. + };
  14030. +
  14031. + rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
  14032. + if (!rerr) {
  14033. + au_set_dbwh(dentry, bwh);
  14034. + au_dtime_revert(dt);
  14035. + return 0;
  14036. + }
  14037. +
  14038. + AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
  14039. + AuDLNPair(dentry), err, rerr);
  14040. + return -EIO;
  14041. +}
  14042. +
  14043. +/* ---------------------------------------------------------------------- */
  14044. +
  14045. +int aufs_unlink(struct inode *dir, struct dentry *dentry)
  14046. +{
  14047. + int err;
  14048. + aufs_bindex_t bwh, bindex, bstart;
  14049. + struct au_dtime dt;
  14050. + struct au_pin pin;
  14051. + struct path h_path;
  14052. + struct inode *inode, *h_dir;
  14053. + struct dentry *parent, *wh_dentry;
  14054. +
  14055. + IMustLock(dir);
  14056. +
  14057. + err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
  14058. + if (unlikely(err))
  14059. + goto out;
  14060. + err = au_d_hashed_positive(dentry);
  14061. + if (unlikely(err))
  14062. + goto out_unlock;
  14063. + inode = dentry->d_inode;
  14064. + IMustLock(inode);
  14065. + err = -EISDIR;
  14066. + if (unlikely(S_ISDIR(inode->i_mode)))
  14067. + goto out_unlock; /* possible? */
  14068. +
  14069. + bstart = au_dbstart(dentry);
  14070. + bwh = au_dbwh(dentry);
  14071. + bindex = -1;
  14072. + parent = dentry->d_parent; /* dir inode is locked */
  14073. + di_write_lock_parent(parent);
  14074. + wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt, &pin);
  14075. + err = PTR_ERR(wh_dentry);
  14076. + if (IS_ERR(wh_dentry))
  14077. + goto out_parent;
  14078. +
  14079. + h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
  14080. + h_path.dentry = au_h_dptr(dentry, bstart);
  14081. + dget(h_path.dentry);
  14082. + if (bindex == bstart) {
  14083. + h_dir = au_pinned_h_dir(&pin);
  14084. + err = vfsub_unlink(h_dir, &h_path, /*force*/0);
  14085. + } else {
  14086. + /* dir inode is locked */
  14087. + h_dir = wh_dentry->d_parent->d_inode;
  14088. + IMustLock(h_dir);
  14089. + err = 0;
  14090. + }
  14091. +
  14092. + if (!err) {
  14093. + vfsub_drop_nlink(inode);
  14094. + epilog(dir, dentry, bindex);
  14095. +
  14096. + /* update target timestamps */
  14097. + if (bindex == bstart) {
  14098. + vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
  14099. + inode->i_ctime = h_path.dentry->d_inode->i_ctime;
  14100. + } else
  14101. + /* todo: this timestamp may be reverted later */
  14102. + inode->i_ctime = h_dir->i_ctime;
  14103. + goto out_unpin; /* success */
  14104. + }
  14105. +
  14106. + /* revert */
  14107. + if (wh_dentry) {
  14108. + int rerr;
  14109. +
  14110. + rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, &dt);
  14111. + if (rerr)
  14112. + err = rerr;
  14113. + }
  14114. +
  14115. +out_unpin:
  14116. + au_unpin(&pin);
  14117. + dput(wh_dentry);
  14118. + dput(h_path.dentry);
  14119. +out_parent:
  14120. + di_write_unlock(parent);
  14121. +out_unlock:
  14122. + aufs_read_unlock(dentry, AuLock_DW);
  14123. +out:
  14124. + return err;
  14125. +}
  14126. +
  14127. +int aufs_rmdir(struct inode *dir, struct dentry *dentry)
  14128. +{
  14129. + int err, rmdir_later;
  14130. + aufs_bindex_t bwh, bindex, bstart;
  14131. + struct au_dtime dt;
  14132. + struct au_pin pin;
  14133. + struct inode *inode;
  14134. + struct dentry *parent, *wh_dentry, *h_dentry;
  14135. + struct au_whtmp_rmdir *args;
  14136. +
  14137. + IMustLock(dir);
  14138. +
  14139. + err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
  14140. + if (unlikely(err))
  14141. + goto out;
  14142. +
  14143. + /* VFS already unhashes it */
  14144. + inode = dentry->d_inode;
  14145. + err = -ENOENT;
  14146. + if (unlikely(!inode || !inode->i_nlink
  14147. + || IS_DEADDIR(inode)))
  14148. + goto out_unlock;
  14149. + IMustLock(inode);
  14150. + err = -ENOTDIR;
  14151. + if (unlikely(!S_ISDIR(inode->i_mode)))
  14152. + goto out_unlock; /* possible? */
  14153. +
  14154. + err = -ENOMEM;
  14155. + args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
  14156. + if (unlikely(!args))
  14157. + goto out_unlock;
  14158. +
  14159. + parent = dentry->d_parent; /* dir inode is locked */
  14160. + di_write_lock_parent(parent);
  14161. + err = au_test_empty(dentry, &args->whlist);
  14162. + if (unlikely(err))
  14163. + goto out_parent;
  14164. +
  14165. + bstart = au_dbstart(dentry);
  14166. + bwh = au_dbwh(dentry);
  14167. + bindex = -1;
  14168. + wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &dt, &pin);
  14169. + err = PTR_ERR(wh_dentry);
  14170. + if (IS_ERR(wh_dentry))
  14171. + goto out_parent;
  14172. +
  14173. + h_dentry = au_h_dptr(dentry, bstart);
  14174. + dget(h_dentry);
  14175. + rmdir_later = 0;
  14176. + if (bindex == bstart) {
  14177. + err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir);
  14178. + if (err > 0) {
  14179. + rmdir_later = err;
  14180. + err = 0;
  14181. + }
  14182. + } else {
  14183. + /* stop monitoring */
  14184. + au_hn_free(au_hi(inode, bstart));
  14185. +
  14186. + /* dir inode is locked */
  14187. + IMustLock(wh_dentry->d_parent->d_inode);
  14188. + err = 0;
  14189. + }
  14190. +
  14191. + if (!err) {
  14192. + vfsub_dead_dir(inode);
  14193. + au_set_dbdiropq(dentry, -1);
  14194. + epilog(dir, dentry, bindex);
  14195. +
  14196. + if (rmdir_later) {
  14197. + au_whtmp_kick_rmdir(dir, bstart, h_dentry, args);
  14198. + args = NULL;
  14199. + }
  14200. +
  14201. + goto out_unpin; /* success */
  14202. + }
  14203. +
  14204. + /* revert */
  14205. + AuLabel(revert);
  14206. + if (wh_dentry) {
  14207. + int rerr;
  14208. +
  14209. + rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, &dt);
  14210. + if (rerr)
  14211. + err = rerr;
  14212. + }
  14213. +
  14214. +out_unpin:
  14215. + au_unpin(&pin);
  14216. + dput(wh_dentry);
  14217. + dput(h_dentry);
  14218. +out_parent:
  14219. + di_write_unlock(parent);
  14220. + if (args)
  14221. + au_whtmp_rmdir_free(args);
  14222. +out_unlock:
  14223. + aufs_read_unlock(dentry, AuLock_DW);
  14224. +out:
  14225. + AuTraceErr(err);
  14226. + return err;
  14227. +}
  14228. diff -Nur linux-2.6.37.orig/fs/aufs/i_op_ren.c linux-2.6.37/fs/aufs/i_op_ren.c
  14229. --- linux-2.6.37.orig/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
  14230. +++ linux-2.6.37/fs/aufs/i_op_ren.c 2011-01-11 20:15:11.000000000 +0100
  14231. @@ -0,0 +1,1017 @@
  14232. +/*
  14233. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  14234. + *
  14235. + * This program, aufs is free software; you can redistribute it and/or modify
  14236. + * it under the terms of the GNU General Public License as published by
  14237. + * the Free Software Foundation; either version 2 of the License, or
  14238. + * (at your option) any later version.
  14239. + *
  14240. + * This program is distributed in the hope that it will be useful,
  14241. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14242. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14243. + * GNU General Public License for more details.
  14244. + *
  14245. + * You should have received a copy of the GNU General Public License
  14246. + * along with this program; if not, write to the Free Software
  14247. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14248. + */
  14249. +
  14250. +/*
  14251. + * inode operation (rename entry)
  14252. + * todo: this is crazy monster
  14253. + */
  14254. +
  14255. +#include "aufs.h"
  14256. +
  14257. +enum { AuSRC, AuDST, AuSrcDst };
  14258. +enum { AuPARENT, AuCHILD, AuParentChild };
  14259. +
  14260. +#define AuRen_ISDIR 1
  14261. +#define AuRen_ISSAMEDIR (1 << 1)
  14262. +#define AuRen_WHSRC (1 << 2)
  14263. +#define AuRen_WHDST (1 << 3)
  14264. +#define AuRen_MNT_WRITE (1 << 4)
  14265. +#define AuRen_DT_DSTDIR (1 << 5)
  14266. +#define AuRen_DIROPQ (1 << 6)
  14267. +#define AuRen_CPUP (1 << 7)
  14268. +#define au_ftest_ren(flags, name) ((flags) & AuRen_##name)
  14269. +#define au_fset_ren(flags, name) \
  14270. + do { (flags) |= AuRen_##name; } while (0)
  14271. +#define au_fclr_ren(flags, name) \
  14272. + do { (flags) &= ~AuRen_##name; } while (0)
  14273. +
  14274. +struct au_ren_args {
  14275. + struct {
  14276. + struct dentry *dentry, *h_dentry, *parent, *h_parent,
  14277. + *wh_dentry;
  14278. + struct inode *dir, *inode;
  14279. + struct au_hinode *hdir;
  14280. + struct au_dtime dt[AuParentChild];
  14281. + aufs_bindex_t bstart;
  14282. + } sd[AuSrcDst];
  14283. +
  14284. +#define src_dentry sd[AuSRC].dentry
  14285. +#define src_dir sd[AuSRC].dir
  14286. +#define src_inode sd[AuSRC].inode
  14287. +#define src_h_dentry sd[AuSRC].h_dentry
  14288. +#define src_parent sd[AuSRC].parent
  14289. +#define src_h_parent sd[AuSRC].h_parent
  14290. +#define src_wh_dentry sd[AuSRC].wh_dentry
  14291. +#define src_hdir sd[AuSRC].hdir
  14292. +#define src_h_dir sd[AuSRC].hdir->hi_inode
  14293. +#define src_dt sd[AuSRC].dt
  14294. +#define src_bstart sd[AuSRC].bstart
  14295. +
  14296. +#define dst_dentry sd[AuDST].dentry
  14297. +#define dst_dir sd[AuDST].dir
  14298. +#define dst_inode sd[AuDST].inode
  14299. +#define dst_h_dentry sd[AuDST].h_dentry
  14300. +#define dst_parent sd[AuDST].parent
  14301. +#define dst_h_parent sd[AuDST].h_parent
  14302. +#define dst_wh_dentry sd[AuDST].wh_dentry
  14303. +#define dst_hdir sd[AuDST].hdir
  14304. +#define dst_h_dir sd[AuDST].hdir->hi_inode
  14305. +#define dst_dt sd[AuDST].dt
  14306. +#define dst_bstart sd[AuDST].bstart
  14307. +
  14308. + struct dentry *h_trap;
  14309. + struct au_branch *br;
  14310. + struct au_hinode *src_hinode;
  14311. + struct path h_path;
  14312. + struct au_nhash whlist;
  14313. + aufs_bindex_t btgt, src_bwh, src_bdiropq;
  14314. +
  14315. + unsigned int flags;
  14316. +
  14317. + struct au_whtmp_rmdir *thargs;
  14318. + struct dentry *h_dst;
  14319. +};
  14320. +
  14321. +/* ---------------------------------------------------------------------- */
  14322. +
  14323. +/*
  14324. + * functions for reverting.
  14325. + * when an error happened in a single rename systemcall, we should revert
  14326. + * everything as if nothing happend.
  14327. + * we don't need to revert the copied-up/down the parent dir since they are
  14328. + * harmless.
  14329. + */
  14330. +
  14331. +#define RevertFailure(fmt, ...) do { \
  14332. + AuIOErr("revert failure: " fmt " (%d, %d)\n", \
  14333. + ##__VA_ARGS__, err, rerr); \
  14334. + err = -EIO; \
  14335. +} while (0)
  14336. +
  14337. +static void au_ren_rev_diropq(int err, struct au_ren_args *a)
  14338. +{
  14339. + int rerr;
  14340. +
  14341. + au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
  14342. + rerr = au_diropq_remove(a->src_dentry, a->btgt);
  14343. + au_hn_imtx_unlock(a->src_hinode);
  14344. + au_set_dbdiropq(a->src_dentry, a->src_bdiropq);
  14345. + if (rerr)
  14346. + RevertFailure("remove diropq %.*s", AuDLNPair(a->src_dentry));
  14347. +}
  14348. +
  14349. +static void au_ren_rev_rename(int err, struct au_ren_args *a)
  14350. +{
  14351. + int rerr;
  14352. +
  14353. + a->h_path.dentry = au_lkup_one(&a->src_dentry->d_name, a->src_h_parent,
  14354. + a->br, /*nd*/NULL);
  14355. + rerr = PTR_ERR(a->h_path.dentry);
  14356. + if (IS_ERR(a->h_path.dentry)) {
  14357. + RevertFailure("au_lkup_one %.*s", AuDLNPair(a->src_dentry));
  14358. + return;
  14359. + }
  14360. +
  14361. + rerr = vfsub_rename(a->dst_h_dir,
  14362. + au_h_dptr(a->src_dentry, a->btgt),
  14363. + a->src_h_dir, &a->h_path);
  14364. + d_drop(a->h_path.dentry);
  14365. + dput(a->h_path.dentry);
  14366. + /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
  14367. + if (rerr)
  14368. + RevertFailure("rename %.*s", AuDLNPair(a->src_dentry));
  14369. +}
  14370. +
  14371. +static void au_ren_rev_cpup(int err, struct au_ren_args *a)
  14372. +{
  14373. + int rerr;
  14374. +
  14375. + a->h_path.dentry = a->dst_h_dentry;
  14376. + rerr = vfsub_unlink(a->dst_h_dir, &a->h_path, /*force*/0);
  14377. + au_set_h_dptr(a->src_dentry, a->btgt, NULL);
  14378. + au_set_dbstart(a->src_dentry, a->src_bstart);
  14379. + if (rerr)
  14380. + RevertFailure("unlink %.*s", AuDLNPair(a->dst_h_dentry));
  14381. +}
  14382. +
  14383. +static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
  14384. +{
  14385. + int rerr;
  14386. +
  14387. + a->h_path.dentry = au_lkup_one(&a->dst_dentry->d_name, a->dst_h_parent,
  14388. + a->br, /*nd*/NULL);
  14389. + rerr = PTR_ERR(a->h_path.dentry);
  14390. + if (IS_ERR(a->h_path.dentry)) {
  14391. + RevertFailure("lookup %.*s", AuDLNPair(a->dst_dentry));
  14392. + return;
  14393. + }
  14394. + if (a->h_path.dentry->d_inode) {
  14395. + d_drop(a->h_path.dentry);
  14396. + dput(a->h_path.dentry);
  14397. + return;
  14398. + }
  14399. +
  14400. + rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path);
  14401. + d_drop(a->h_path.dentry);
  14402. + dput(a->h_path.dentry);
  14403. + if (!rerr)
  14404. + au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
  14405. + else
  14406. + RevertFailure("rename %.*s", AuDLNPair(a->h_dst));
  14407. +}
  14408. +
  14409. +static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
  14410. +{
  14411. + int rerr;
  14412. +
  14413. + a->h_path.dentry = a->src_wh_dentry;
  14414. + rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
  14415. + au_set_dbwh(a->src_dentry, a->src_bwh);
  14416. + if (rerr)
  14417. + RevertFailure("unlink %.*s", AuDLNPair(a->src_wh_dentry));
  14418. +}
  14419. +#undef RevertFailure
  14420. +
  14421. +/* ---------------------------------------------------------------------- */
  14422. +
  14423. +/*
  14424. + * when we have to copyup the renaming entry, do it with the rename-target name
  14425. + * in order to minimize the cost (the later actual rename is unnecessary).
  14426. + * otherwise rename it on the target branch.
  14427. + */
  14428. +static int au_ren_or_cpup(struct au_ren_args *a)
  14429. +{
  14430. + int err;
  14431. + struct dentry *d;
  14432. +
  14433. + d = a->src_dentry;
  14434. + if (au_dbstart(d) == a->btgt) {
  14435. + a->h_path.dentry = a->dst_h_dentry;
  14436. + if (au_ftest_ren(a->flags, DIROPQ)
  14437. + && au_dbdiropq(d) == a->btgt)
  14438. + au_fclr_ren(a->flags, DIROPQ);
  14439. + AuDebugOn(au_dbstart(d) != a->btgt);
  14440. + err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
  14441. + a->dst_h_dir, &a->h_path);
  14442. + } else {
  14443. + struct mutex *h_mtx = &a->src_h_dentry->d_inode->i_mutex;
  14444. + struct file *h_file;
  14445. +
  14446. + au_fset_ren(a->flags, CPUP);
  14447. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  14448. + au_set_dbstart(d, a->btgt);
  14449. + au_set_h_dptr(d, a->btgt, dget(a->dst_h_dentry));
  14450. + h_file = au_h_open_pre(d, a->src_bstart);
  14451. + if (IS_ERR(h_file)) {
  14452. + err = PTR_ERR(h_file);
  14453. + h_file = NULL;
  14454. + } else
  14455. + err = au_sio_cpup_single(d, a->btgt, a->src_bstart, -1,
  14456. + !AuCpup_DTIME, a->dst_parent);
  14457. + mutex_unlock(h_mtx);
  14458. + au_h_open_post(d, a->src_bstart, h_file);
  14459. + if (!err) {
  14460. + d = a->dst_dentry;
  14461. + au_set_h_dptr(d, a->btgt, NULL);
  14462. + au_update_dbstart(d);
  14463. + } else {
  14464. + au_set_h_dptr(d, a->btgt, NULL);
  14465. + au_set_dbstart(d, a->src_bstart);
  14466. + }
  14467. + }
  14468. + if (!err && a->h_dst)
  14469. + /* it will be set to dinfo later */
  14470. + dget(a->h_dst);
  14471. +
  14472. + return err;
  14473. +}
  14474. +
  14475. +/* cf. aufs_rmdir() */
  14476. +static int au_ren_del_whtmp(struct au_ren_args *a)
  14477. +{
  14478. + int err;
  14479. + struct inode *dir;
  14480. +
  14481. + dir = a->dst_dir;
  14482. + SiMustAnyLock(dir->i_sb);
  14483. + if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
  14484. + au_sbi(dir->i_sb)->si_dirwh)
  14485. + || au_test_fs_remote(a->h_dst->d_sb)) {
  14486. + err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
  14487. + if (unlikely(err))
  14488. + pr_warning("failed removing whtmp dir %.*s (%d), "
  14489. + "ignored.\n", AuDLNPair(a->h_dst), err);
  14490. + } else {
  14491. + au_nhash_wh_free(&a->thargs->whlist);
  14492. + a->thargs->whlist = a->whlist;
  14493. + a->whlist.nh_num = 0;
  14494. + au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
  14495. + dput(a->h_dst);
  14496. + a->thargs = NULL;
  14497. + }
  14498. +
  14499. + return 0;
  14500. +}
  14501. +
  14502. +/* make it 'opaque' dir. */
  14503. +static int au_ren_diropq(struct au_ren_args *a)
  14504. +{
  14505. + int err;
  14506. + struct dentry *diropq;
  14507. +
  14508. + err = 0;
  14509. + a->src_bdiropq = au_dbdiropq(a->src_dentry);
  14510. + a->src_hinode = au_hi(a->src_inode, a->btgt);
  14511. + au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
  14512. + diropq = au_diropq_create(a->src_dentry, a->btgt);
  14513. + au_hn_imtx_unlock(a->src_hinode);
  14514. + if (IS_ERR(diropq))
  14515. + err = PTR_ERR(diropq);
  14516. + dput(diropq);
  14517. +
  14518. + return err;
  14519. +}
  14520. +
  14521. +static int do_rename(struct au_ren_args *a)
  14522. +{
  14523. + int err;
  14524. + struct dentry *d, *h_d;
  14525. +
  14526. + /* prepare workqueue args for asynchronous rmdir */
  14527. + h_d = a->dst_h_dentry;
  14528. + if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) {
  14529. + err = -ENOMEM;
  14530. + a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS);
  14531. + if (unlikely(!a->thargs))
  14532. + goto out;
  14533. + a->h_dst = dget(h_d);
  14534. + }
  14535. +
  14536. + /* create whiteout for src_dentry */
  14537. + if (au_ftest_ren(a->flags, WHSRC)) {
  14538. + a->src_bwh = au_dbwh(a->src_dentry);
  14539. + AuDebugOn(a->src_bwh >= 0);
  14540. + a->src_wh_dentry
  14541. + = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent);
  14542. + err = PTR_ERR(a->src_wh_dentry);
  14543. + if (IS_ERR(a->src_wh_dentry))
  14544. + goto out_thargs;
  14545. + }
  14546. +
  14547. + /* lookup whiteout for dentry */
  14548. + if (au_ftest_ren(a->flags, WHDST)) {
  14549. + h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name,
  14550. + a->br);
  14551. + err = PTR_ERR(h_d);
  14552. + if (IS_ERR(h_d))
  14553. + goto out_whsrc;
  14554. + if (!h_d->d_inode)
  14555. + dput(h_d);
  14556. + else
  14557. + a->dst_wh_dentry = h_d;
  14558. + }
  14559. +
  14560. + /* rename dentry to tmpwh */
  14561. + if (a->thargs) {
  14562. + err = au_whtmp_ren(a->dst_h_dentry, a->br);
  14563. + if (unlikely(err))
  14564. + goto out_whdst;
  14565. +
  14566. + d = a->dst_dentry;
  14567. + au_set_h_dptr(d, a->btgt, NULL);
  14568. + err = au_lkup_neg(d, a->btgt);
  14569. + if (unlikely(err))
  14570. + goto out_whtmp;
  14571. + a->dst_h_dentry = au_h_dptr(d, a->btgt);
  14572. + }
  14573. +
  14574. + /* cpup src */
  14575. + if (a->dst_h_dentry->d_inode && a->src_bstart != a->btgt) {
  14576. + struct mutex *h_mtx = &a->src_h_dentry->d_inode->i_mutex;
  14577. + struct file *h_file;
  14578. +
  14579. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  14580. + AuDebugOn(au_dbstart(a->src_dentry) != a->src_bstart);
  14581. + h_file = au_h_open_pre(a->src_dentry, a->src_bstart);
  14582. + if (IS_ERR(h_file)) {
  14583. + err = PTR_ERR(h_file);
  14584. + h_file = NULL;
  14585. + } else
  14586. + err = au_sio_cpup_simple(a->src_dentry, a->btgt, -1,
  14587. + !AuCpup_DTIME);
  14588. + mutex_unlock(h_mtx);
  14589. + au_h_open_post(a->src_dentry, a->src_bstart, h_file);
  14590. + if (unlikely(err))
  14591. + goto out_whtmp;
  14592. + }
  14593. +
  14594. + /* rename by vfs_rename or cpup */
  14595. + d = a->dst_dentry;
  14596. + if (au_ftest_ren(a->flags, ISDIR)
  14597. + && (a->dst_wh_dentry
  14598. + || au_dbdiropq(d) == a->btgt
  14599. + /* hide the lower to keep xino */
  14600. + || a->btgt < au_dbend(d)
  14601. + || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ)))
  14602. + au_fset_ren(a->flags, DIROPQ);
  14603. + err = au_ren_or_cpup(a);
  14604. + if (unlikely(err))
  14605. + /* leave the copied-up one */
  14606. + goto out_whtmp;
  14607. +
  14608. + /* make dir opaque */
  14609. + if (au_ftest_ren(a->flags, DIROPQ)) {
  14610. + err = au_ren_diropq(a);
  14611. + if (unlikely(err))
  14612. + goto out_rename;
  14613. + }
  14614. +
  14615. + /* update target timestamps */
  14616. + AuDebugOn(au_dbstart(a->src_dentry) != a->btgt);
  14617. + a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
  14618. + vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
  14619. + a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
  14620. +
  14621. + /* remove whiteout for dentry */
  14622. + if (a->dst_wh_dentry) {
  14623. + a->h_path.dentry = a->dst_wh_dentry;
  14624. + err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
  14625. + a->dst_dentry);
  14626. + if (unlikely(err))
  14627. + goto out_diropq;
  14628. + }
  14629. +
  14630. + /* remove whtmp */
  14631. + if (a->thargs)
  14632. + au_ren_del_whtmp(a); /* ignore this error */
  14633. +
  14634. + err = 0;
  14635. + goto out_success;
  14636. +
  14637. +out_diropq:
  14638. + if (au_ftest_ren(a->flags, DIROPQ))
  14639. + au_ren_rev_diropq(err, a);
  14640. +out_rename:
  14641. + if (!au_ftest_ren(a->flags, CPUP))
  14642. + au_ren_rev_rename(err, a);
  14643. + else
  14644. + au_ren_rev_cpup(err, a);
  14645. + dput(a->h_dst);
  14646. +out_whtmp:
  14647. + if (a->thargs)
  14648. + au_ren_rev_whtmp(err, a);
  14649. +out_whdst:
  14650. + dput(a->dst_wh_dentry);
  14651. + a->dst_wh_dentry = NULL;
  14652. +out_whsrc:
  14653. + if (a->src_wh_dentry)
  14654. + au_ren_rev_whsrc(err, a);
  14655. +out_success:
  14656. + dput(a->src_wh_dentry);
  14657. + dput(a->dst_wh_dentry);
  14658. +out_thargs:
  14659. + if (a->thargs) {
  14660. + dput(a->h_dst);
  14661. + au_whtmp_rmdir_free(a->thargs);
  14662. + a->thargs = NULL;
  14663. + }
  14664. +out:
  14665. + return err;
  14666. +}
  14667. +
  14668. +/* ---------------------------------------------------------------------- */
  14669. +
  14670. +/*
  14671. + * test if @dentry dir can be rename destination or not.
  14672. + * success means, it is a logically empty dir.
  14673. + */
  14674. +static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
  14675. +{
  14676. + return au_test_empty(dentry, whlist);
  14677. +}
  14678. +
  14679. +/*
  14680. + * test if @dentry dir can be rename source or not.
  14681. + * if it can, return 0 and @children is filled.
  14682. + * success means,
  14683. + * - it is a logically empty dir.
  14684. + * - or, it exists on writable branch and has no children including whiteouts
  14685. + * on the lower branch.
  14686. + */
  14687. +static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt)
  14688. +{
  14689. + int err;
  14690. + unsigned int rdhash;
  14691. + aufs_bindex_t bstart;
  14692. +
  14693. + bstart = au_dbstart(dentry);
  14694. + if (bstart != btgt) {
  14695. + struct au_nhash whlist;
  14696. +
  14697. + SiMustAnyLock(dentry->d_sb);
  14698. + rdhash = au_sbi(dentry->d_sb)->si_rdhash;
  14699. + if (!rdhash)
  14700. + rdhash = au_rdhash_est(au_dir_size(/*file*/NULL,
  14701. + dentry));
  14702. + err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
  14703. + if (unlikely(err))
  14704. + goto out;
  14705. + err = au_test_empty(dentry, &whlist);
  14706. + au_nhash_wh_free(&whlist);
  14707. + goto out;
  14708. + }
  14709. +
  14710. + if (bstart == au_dbtaildir(dentry))
  14711. + return 0; /* success */
  14712. +
  14713. + err = au_test_empty_lower(dentry);
  14714. +
  14715. +out:
  14716. + if (err == -ENOTEMPTY) {
  14717. + AuWarn1("renaming dir who has child(ren) on multiple branches,"
  14718. + " is not supported\n");
  14719. + err = -EXDEV;
  14720. + }
  14721. + return err;
  14722. +}
  14723. +
  14724. +/* side effect: sets whlist and h_dentry */
  14725. +static int au_ren_may_dir(struct au_ren_args *a)
  14726. +{
  14727. + int err;
  14728. + unsigned int rdhash;
  14729. + struct dentry *d;
  14730. +
  14731. + d = a->dst_dentry;
  14732. + SiMustAnyLock(d->d_sb);
  14733. +
  14734. + err = 0;
  14735. + if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) {
  14736. + rdhash = au_sbi(d->d_sb)->si_rdhash;
  14737. + if (!rdhash)
  14738. + rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d));
  14739. + err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS);
  14740. + if (unlikely(err))
  14741. + goto out;
  14742. +
  14743. + au_set_dbstart(d, a->dst_bstart);
  14744. + err = may_rename_dstdir(d, &a->whlist);
  14745. + au_set_dbstart(d, a->btgt);
  14746. + }
  14747. + a->dst_h_dentry = au_h_dptr(d, au_dbstart(d));
  14748. + if (unlikely(err))
  14749. + goto out;
  14750. +
  14751. + d = a->src_dentry;
  14752. + a->src_h_dentry = au_h_dptr(d, au_dbstart(d));
  14753. + if (au_ftest_ren(a->flags, ISDIR)) {
  14754. + err = may_rename_srcdir(d, a->btgt);
  14755. + if (unlikely(err)) {
  14756. + au_nhash_wh_free(&a->whlist);
  14757. + a->whlist.nh_num = 0;
  14758. + }
  14759. + }
  14760. +out:
  14761. + return err;
  14762. +}
  14763. +
  14764. +/* ---------------------------------------------------------------------- */
  14765. +
  14766. +/*
  14767. + * simple tests for rename.
  14768. + * following the checks in vfs, plus the parent-child relationship.
  14769. + */
  14770. +static int au_may_ren(struct au_ren_args *a)
  14771. +{
  14772. + int err, isdir;
  14773. + struct inode *h_inode;
  14774. +
  14775. + if (a->src_bstart == a->btgt) {
  14776. + err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
  14777. + au_ftest_ren(a->flags, ISDIR));
  14778. + if (unlikely(err))
  14779. + goto out;
  14780. + err = -EINVAL;
  14781. + if (unlikely(a->src_h_dentry == a->h_trap))
  14782. + goto out;
  14783. + }
  14784. +
  14785. + err = 0;
  14786. + if (a->dst_bstart != a->btgt)
  14787. + goto out;
  14788. +
  14789. + err = -EIO;
  14790. + h_inode = a->dst_h_dentry->d_inode;
  14791. + isdir = !!au_ftest_ren(a->flags, ISDIR);
  14792. + if (!a->dst_dentry->d_inode) {
  14793. + if (unlikely(h_inode))
  14794. + goto out;
  14795. + err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent,
  14796. + isdir);
  14797. + } else {
  14798. + if (unlikely(!h_inode || !h_inode->i_nlink))
  14799. + goto out;
  14800. + err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent,
  14801. + isdir);
  14802. + if (unlikely(err))
  14803. + goto out;
  14804. + err = -ENOTEMPTY;
  14805. + if (unlikely(a->dst_h_dentry == a->h_trap))
  14806. + goto out;
  14807. + err = 0;
  14808. + }
  14809. +
  14810. +out:
  14811. + if (unlikely(err == -ENOENT || err == -EEXIST))
  14812. + err = -EIO;
  14813. + AuTraceErr(err);
  14814. + return err;
  14815. +}
  14816. +
  14817. +/* ---------------------------------------------------------------------- */
  14818. +
  14819. +/*
  14820. + * locking order
  14821. + * (VFS)
  14822. + * - src_dir and dir by lock_rename()
  14823. + * - inode if exitsts
  14824. + * (aufs)
  14825. + * - lock all
  14826. + * + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
  14827. + * + si_read_lock
  14828. + * + di_write_lock2_child()
  14829. + * + di_write_lock_child()
  14830. + * + ii_write_lock_child()
  14831. + * + di_write_lock_child2()
  14832. + * + ii_write_lock_child2()
  14833. + * + src_parent and parent
  14834. + * + di_write_lock_parent()
  14835. + * + ii_write_lock_parent()
  14836. + * + di_write_lock_parent2()
  14837. + * + ii_write_lock_parent2()
  14838. + * + lower src_dir and dir by vfsub_lock_rename()
  14839. + * + verify the every relationships between child and parent. if any
  14840. + * of them failed, unlock all and return -EBUSY.
  14841. + */
  14842. +static void au_ren_unlock(struct au_ren_args *a)
  14843. +{
  14844. + struct super_block *sb;
  14845. +
  14846. + sb = a->dst_dentry->d_sb;
  14847. + if (au_ftest_ren(a->flags, MNT_WRITE))
  14848. + mnt_drop_write(a->br->br_mnt);
  14849. + vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
  14850. + a->dst_h_parent, a->dst_hdir);
  14851. +}
  14852. +
  14853. +static int au_ren_lock(struct au_ren_args *a)
  14854. +{
  14855. + int err;
  14856. + unsigned int udba;
  14857. +
  14858. + err = 0;
  14859. + a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
  14860. + a->src_hdir = au_hi(a->src_dir, a->btgt);
  14861. + a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
  14862. + a->dst_hdir = au_hi(a->dst_dir, a->btgt);
  14863. + a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
  14864. + a->dst_h_parent, a->dst_hdir);
  14865. + udba = au_opt_udba(a->src_dentry->d_sb);
  14866. + if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode
  14867. + || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode))
  14868. + err = au_busy_or_stale();
  14869. + if (!err && au_dbstart(a->src_dentry) == a->btgt)
  14870. + err = au_h_verify(a->src_h_dentry, udba,
  14871. + a->src_h_parent->d_inode, a->src_h_parent,
  14872. + a->br);
  14873. + if (!err && au_dbstart(a->dst_dentry) == a->btgt)
  14874. + err = au_h_verify(a->dst_h_dentry, udba,
  14875. + a->dst_h_parent->d_inode, a->dst_h_parent,
  14876. + a->br);
  14877. + if (!err) {
  14878. + err = mnt_want_write(a->br->br_mnt);
  14879. + if (unlikely(err))
  14880. + goto out_unlock;
  14881. + au_fset_ren(a->flags, MNT_WRITE);
  14882. + goto out; /* success */
  14883. + }
  14884. +
  14885. + err = au_busy_or_stale();
  14886. +
  14887. +out_unlock:
  14888. + au_ren_unlock(a);
  14889. +out:
  14890. + return err;
  14891. +}
  14892. +
  14893. +/* ---------------------------------------------------------------------- */
  14894. +
  14895. +static void au_ren_refresh_dir(struct au_ren_args *a)
  14896. +{
  14897. + struct inode *dir;
  14898. +
  14899. + dir = a->dst_dir;
  14900. + dir->i_version++;
  14901. + if (au_ftest_ren(a->flags, ISDIR)) {
  14902. + /* is this updating defined in POSIX? */
  14903. + au_cpup_attr_timesizes(a->src_inode);
  14904. + au_cpup_attr_nlink(dir, /*force*/1);
  14905. + }
  14906. +
  14907. + if (au_ibstart(dir) == a->btgt)
  14908. + au_cpup_attr_timesizes(dir);
  14909. +
  14910. + if (au_ftest_ren(a->flags, ISSAMEDIR))
  14911. + return;
  14912. +
  14913. + dir = a->src_dir;
  14914. + dir->i_version++;
  14915. + if (au_ftest_ren(a->flags, ISDIR))
  14916. + au_cpup_attr_nlink(dir, /*force*/1);
  14917. + if (au_ibstart(dir) == a->btgt)
  14918. + au_cpup_attr_timesizes(dir);
  14919. +}
  14920. +
  14921. +static void au_ren_refresh(struct au_ren_args *a)
  14922. +{
  14923. + aufs_bindex_t bend, bindex;
  14924. + struct dentry *d, *h_d;
  14925. + struct inode *i, *h_i;
  14926. + struct super_block *sb;
  14927. +
  14928. + d = a->dst_dentry;
  14929. + d_drop(d);
  14930. + if (a->h_dst)
  14931. + /* already dget-ed by au_ren_or_cpup() */
  14932. + au_set_h_dptr(d, a->btgt, a->h_dst);
  14933. +
  14934. + i = a->dst_inode;
  14935. + if (i) {
  14936. + if (!au_ftest_ren(a->flags, ISDIR))
  14937. + vfsub_drop_nlink(i);
  14938. + else {
  14939. + vfsub_dead_dir(i);
  14940. + au_cpup_attr_timesizes(i);
  14941. + }
  14942. + au_update_dbrange(d, /*do_put_zero*/1);
  14943. + } else {
  14944. + bend = a->btgt;
  14945. + for (bindex = au_dbstart(d); bindex < bend; bindex++)
  14946. + au_set_h_dptr(d, bindex, NULL);
  14947. + bend = au_dbend(d);
  14948. + for (bindex = a->btgt + 1; bindex <= bend; bindex++)
  14949. + au_set_h_dptr(d, bindex, NULL);
  14950. + au_update_dbrange(d, /*do_put_zero*/0);
  14951. + }
  14952. +
  14953. + d = a->src_dentry;
  14954. + au_set_dbwh(d, -1);
  14955. + bend = au_dbend(d);
  14956. + for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
  14957. + h_d = au_h_dptr(d, bindex);
  14958. + if (h_d)
  14959. + au_set_h_dptr(d, bindex, NULL);
  14960. + }
  14961. + au_set_dbend(d, a->btgt);
  14962. +
  14963. + sb = d->d_sb;
  14964. + i = a->src_inode;
  14965. + if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
  14966. + return; /* success */
  14967. +
  14968. + bend = au_ibend(i);
  14969. + for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
  14970. + h_i = au_h_iptr(i, bindex);
  14971. + if (h_i) {
  14972. + au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
  14973. + /* ignore this error */
  14974. + au_set_h_iptr(i, bindex, NULL, 0);
  14975. + }
  14976. + }
  14977. + au_set_ibend(i, a->btgt);
  14978. +}
  14979. +
  14980. +/* ---------------------------------------------------------------------- */
  14981. +
  14982. +/* mainly for link(2) and rename(2) */
  14983. +int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
  14984. +{
  14985. + aufs_bindex_t bdiropq, bwh;
  14986. + struct dentry *parent;
  14987. + struct au_branch *br;
  14988. +
  14989. + parent = dentry->d_parent;
  14990. + IMustLock(parent->d_inode); /* dir is locked */
  14991. +
  14992. + bdiropq = au_dbdiropq(parent);
  14993. + bwh = au_dbwh(dentry);
  14994. + br = au_sbr(dentry->d_sb, btgt);
  14995. + if (au_br_rdonly(br)
  14996. + || (0 <= bdiropq && bdiropq < btgt)
  14997. + || (0 <= bwh && bwh < btgt))
  14998. + btgt = -1;
  14999. +
  15000. + AuDbg("btgt %d\n", btgt);
  15001. + return btgt;
  15002. +}
  15003. +
  15004. +/* sets src_bstart, dst_bstart and btgt */
  15005. +static int au_ren_wbr(struct au_ren_args *a)
  15006. +{
  15007. + int err;
  15008. + struct au_wr_dir_args wr_dir_args = {
  15009. + /* .force_btgt = -1, */
  15010. + .flags = AuWrDir_ADD_ENTRY
  15011. + };
  15012. +
  15013. + a->src_bstart = au_dbstart(a->src_dentry);
  15014. + a->dst_bstart = au_dbstart(a->dst_dentry);
  15015. + if (au_ftest_ren(a->flags, ISDIR))
  15016. + au_fset_wrdir(wr_dir_args.flags, ISDIR);
  15017. + wr_dir_args.force_btgt = a->src_bstart;
  15018. + if (a->dst_inode && a->dst_bstart < a->src_bstart)
  15019. + wr_dir_args.force_btgt = a->dst_bstart;
  15020. + wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
  15021. + err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
  15022. + a->btgt = err;
  15023. +
  15024. + return err;
  15025. +}
  15026. +
  15027. +static void au_ren_dt(struct au_ren_args *a)
  15028. +{
  15029. + a->h_path.dentry = a->src_h_parent;
  15030. + au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
  15031. + if (!au_ftest_ren(a->flags, ISSAMEDIR)) {
  15032. + a->h_path.dentry = a->dst_h_parent;
  15033. + au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
  15034. + }
  15035. +
  15036. + au_fclr_ren(a->flags, DT_DSTDIR);
  15037. + if (!au_ftest_ren(a->flags, ISDIR))
  15038. + return;
  15039. +
  15040. + a->h_path.dentry = a->src_h_dentry;
  15041. + au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
  15042. + if (a->dst_h_dentry->d_inode) {
  15043. + au_fset_ren(a->flags, DT_DSTDIR);
  15044. + a->h_path.dentry = a->dst_h_dentry;
  15045. + au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
  15046. + }
  15047. +}
  15048. +
  15049. +static void au_ren_rev_dt(int err, struct au_ren_args *a)
  15050. +{
  15051. + struct dentry *h_d;
  15052. + struct mutex *h_mtx;
  15053. +
  15054. + au_dtime_revert(a->src_dt + AuPARENT);
  15055. + if (!au_ftest_ren(a->flags, ISSAMEDIR))
  15056. + au_dtime_revert(a->dst_dt + AuPARENT);
  15057. +
  15058. + if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) {
  15059. + h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
  15060. + h_mtx = &h_d->d_inode->i_mutex;
  15061. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  15062. + au_dtime_revert(a->src_dt + AuCHILD);
  15063. + mutex_unlock(h_mtx);
  15064. +
  15065. + if (au_ftest_ren(a->flags, DT_DSTDIR)) {
  15066. + h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
  15067. + h_mtx = &h_d->d_inode->i_mutex;
  15068. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
  15069. + au_dtime_revert(a->dst_dt + AuCHILD);
  15070. + mutex_unlock(h_mtx);
  15071. + }
  15072. + }
  15073. +}
  15074. +
  15075. +/* ---------------------------------------------------------------------- */
  15076. +
  15077. +int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
  15078. + struct inode *_dst_dir, struct dentry *_dst_dentry)
  15079. +{
  15080. + int err, flags;
  15081. + /* reduce stack space */
  15082. + struct au_ren_args *a;
  15083. +
  15084. + AuDbg("%.*s, %.*s\n", AuDLNPair(_src_dentry), AuDLNPair(_dst_dentry));
  15085. + IMustLock(_src_dir);
  15086. + IMustLock(_dst_dir);
  15087. +
  15088. + err = -ENOMEM;
  15089. + BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
  15090. + a = kzalloc(sizeof(*a), GFP_NOFS);
  15091. + if (unlikely(!a))
  15092. + goto out;
  15093. +
  15094. + a->src_dir = _src_dir;
  15095. + a->src_dentry = _src_dentry;
  15096. + a->src_inode = a->src_dentry->d_inode;
  15097. + a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
  15098. + a->dst_dir = _dst_dir;
  15099. + a->dst_dentry = _dst_dentry;
  15100. + a->dst_inode = a->dst_dentry->d_inode;
  15101. + a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
  15102. + if (a->dst_inode) {
  15103. + IMustLock(a->dst_inode);
  15104. + au_igrab(a->dst_inode);
  15105. + }
  15106. +
  15107. + err = -ENOTDIR;
  15108. + flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
  15109. + if (S_ISDIR(a->src_inode->i_mode)) {
  15110. + au_fset_ren(a->flags, ISDIR);
  15111. + if (unlikely(a->dst_inode && !S_ISDIR(a->dst_inode->i_mode)))
  15112. + goto out_free;
  15113. + err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
  15114. + AuLock_DIR | flags);
  15115. + } else
  15116. + err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
  15117. + flags);
  15118. + if (unlikely(err))
  15119. + goto out_free;
  15120. +
  15121. + err = au_d_hashed_positive(a->src_dentry);
  15122. + if (unlikely(err))
  15123. + goto out_unlock;
  15124. + err = -ENOENT;
  15125. + if (a->dst_inode) {
  15126. + /*
  15127. + * If it is a dir, VFS unhash dst_dentry before this
  15128. + * function. It means we cannot rely upon d_unhashed().
  15129. + */
  15130. + if (unlikely(!a->dst_inode->i_nlink))
  15131. + goto out_unlock;
  15132. + if (!S_ISDIR(a->dst_inode->i_mode)) {
  15133. + err = au_d_hashed_positive(a->dst_dentry);
  15134. + if (unlikely(err))
  15135. + goto out_unlock;
  15136. + } else if (unlikely(IS_DEADDIR(a->dst_inode)))
  15137. + goto out_unlock;
  15138. + } else if (unlikely(d_unhashed(a->dst_dentry)))
  15139. + goto out_unlock;
  15140. +
  15141. + au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
  15142. + di_write_lock_parent(a->dst_parent);
  15143. +
  15144. + /* which branch we process */
  15145. + err = au_ren_wbr(a);
  15146. + if (unlikely(err < 0))
  15147. + goto out_parent;
  15148. + a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
  15149. + a->h_path.mnt = a->br->br_mnt;
  15150. +
  15151. + /* are they available to be renamed */
  15152. + err = au_ren_may_dir(a);
  15153. + if (unlikely(err))
  15154. + goto out_children;
  15155. +
  15156. + /* prepare the writable parent dir on the same branch */
  15157. + if (a->dst_bstart == a->btgt) {
  15158. + au_fset_ren(a->flags, WHDST);
  15159. + } else {
  15160. + err = au_cpup_dirs(a->dst_dentry, a->btgt);
  15161. + if (unlikely(err))
  15162. + goto out_children;
  15163. + }
  15164. +
  15165. + if (a->src_dir != a->dst_dir) {
  15166. + /*
  15167. + * this temporary unlock is safe,
  15168. + * because both dir->i_mutex are locked.
  15169. + */
  15170. + di_write_unlock(a->dst_parent);
  15171. + di_write_lock_parent(a->src_parent);
  15172. + err = au_wr_dir_need_wh(a->src_dentry,
  15173. + au_ftest_ren(a->flags, ISDIR),
  15174. + &a->btgt);
  15175. + di_write_unlock(a->src_parent);
  15176. + di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1);
  15177. + au_fclr_ren(a->flags, ISSAMEDIR);
  15178. + } else
  15179. + err = au_wr_dir_need_wh(a->src_dentry,
  15180. + au_ftest_ren(a->flags, ISDIR),
  15181. + &a->btgt);
  15182. + if (unlikely(err < 0))
  15183. + goto out_children;
  15184. + if (err)
  15185. + au_fset_ren(a->flags, WHSRC);
  15186. +
  15187. + /* lock them all */
  15188. + err = au_ren_lock(a);
  15189. + if (unlikely(err))
  15190. + goto out_children;
  15191. +
  15192. + if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE))
  15193. + err = au_may_ren(a);
  15194. + else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN))
  15195. + err = -ENAMETOOLONG;
  15196. + if (unlikely(err))
  15197. + goto out_hdir;
  15198. +
  15199. + /* store timestamps to be revertible */
  15200. + au_ren_dt(a);
  15201. +
  15202. + /* here we go */
  15203. + err = do_rename(a);
  15204. + if (unlikely(err))
  15205. + goto out_dt;
  15206. +
  15207. + /* update dir attributes */
  15208. + au_ren_refresh_dir(a);
  15209. +
  15210. + /* dput/iput all lower dentries */
  15211. + au_ren_refresh(a);
  15212. +
  15213. + goto out_hdir; /* success */
  15214. +
  15215. +out_dt:
  15216. + au_ren_rev_dt(err, a);
  15217. +out_hdir:
  15218. + au_ren_unlock(a);
  15219. +out_children:
  15220. + au_nhash_wh_free(&a->whlist);
  15221. + if (err && a->dst_inode && a->dst_bstart != a->btgt) {
  15222. + AuDbg("bstart %d, btgt %d\n", a->dst_bstart, a->btgt);
  15223. + au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
  15224. + au_set_dbstart(a->dst_dentry, a->dst_bstart);
  15225. + }
  15226. +out_parent:
  15227. + if (!err)
  15228. + d_move(a->src_dentry, a->dst_dentry);
  15229. + else {
  15230. + au_update_dbstart(a->dst_dentry);
  15231. + if (!a->dst_inode)
  15232. + d_drop(a->dst_dentry);
  15233. + }
  15234. + if (au_ftest_ren(a->flags, ISSAMEDIR))
  15235. + di_write_unlock(a->dst_parent);
  15236. + else
  15237. + di_write_unlock2(a->src_parent, a->dst_parent);
  15238. +out_unlock:
  15239. + aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
  15240. +out_free:
  15241. + iput(a->dst_inode);
  15242. + if (a->thargs)
  15243. + au_whtmp_rmdir_free(a->thargs);
  15244. + kfree(a);
  15245. +out:
  15246. + AuTraceErr(err);
  15247. + return err;
  15248. +}
  15249. diff -Nur linux-2.6.37.orig/fs/aufs/iinfo.c linux-2.6.37/fs/aufs/iinfo.c
  15250. --- linux-2.6.37.orig/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100
  15251. +++ linux-2.6.37/fs/aufs/iinfo.c 2011-01-11 20:15:11.000000000 +0100
  15252. @@ -0,0 +1,263 @@
  15253. +/*
  15254. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  15255. + *
  15256. + * This program, aufs is free software; you can redistribute it and/or modify
  15257. + * it under the terms of the GNU General Public License as published by
  15258. + * the Free Software Foundation; either version 2 of the License, or
  15259. + * (at your option) any later version.
  15260. + *
  15261. + * This program is distributed in the hope that it will be useful,
  15262. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15263. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15264. + * GNU General Public License for more details.
  15265. + *
  15266. + * You should have received a copy of the GNU General Public License
  15267. + * along with this program; if not, write to the Free Software
  15268. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  15269. + */
  15270. +
  15271. +/*
  15272. + * inode private data
  15273. + */
  15274. +
  15275. +#include "aufs.h"
  15276. +
  15277. +struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
  15278. +{
  15279. + struct inode *h_inode;
  15280. +
  15281. + IiMustAnyLock(inode);
  15282. +
  15283. + h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode;
  15284. + AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
  15285. + return h_inode;
  15286. +}
  15287. +
  15288. +/* todo: hard/soft set? */
  15289. +void au_hiput(struct au_hinode *hinode)
  15290. +{
  15291. + au_hn_free(hinode);
  15292. + dput(hinode->hi_whdentry);
  15293. + iput(hinode->hi_inode);
  15294. +}
  15295. +
  15296. +unsigned int au_hi_flags(struct inode *inode, int isdir)
  15297. +{
  15298. + unsigned int flags;
  15299. + const unsigned int mnt_flags = au_mntflags(inode->i_sb);
  15300. +
  15301. + flags = 0;
  15302. + if (au_opt_test(mnt_flags, XINO))
  15303. + au_fset_hi(flags, XINO);
  15304. + if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY))
  15305. + au_fset_hi(flags, HNOTIFY);
  15306. + return flags;
  15307. +}
  15308. +
  15309. +void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
  15310. + struct inode *h_inode, unsigned int flags)
  15311. +{
  15312. + struct au_hinode *hinode;
  15313. + struct inode *hi;
  15314. + struct au_iinfo *iinfo = au_ii(inode);
  15315. +
  15316. + IiMustWriteLock(inode);
  15317. +
  15318. + hinode = iinfo->ii_hinode + bindex;
  15319. + hi = hinode->hi_inode;
  15320. + AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
  15321. +
  15322. + if (hi)
  15323. + au_hiput(hinode);
  15324. + hinode->hi_inode = h_inode;
  15325. + if (h_inode) {
  15326. + int err;
  15327. + struct super_block *sb = inode->i_sb;
  15328. + struct au_branch *br;
  15329. +
  15330. + AuDebugOn(inode->i_mode
  15331. + && (h_inode->i_mode & S_IFMT)
  15332. + != (inode->i_mode & S_IFMT));
  15333. + if (bindex == iinfo->ii_bstart)
  15334. + au_cpup_igen(inode, h_inode);
  15335. + br = au_sbr(sb, bindex);
  15336. + hinode->hi_id = br->br_id;
  15337. + if (au_ftest_hi(flags, XINO)) {
  15338. + err = au_xino_write(sb, bindex, h_inode->i_ino,
  15339. + inode->i_ino);
  15340. + if (unlikely(err))
  15341. + AuIOErr1("failed au_xino_write() %d\n", err);
  15342. + }
  15343. +
  15344. + if (au_ftest_hi(flags, HNOTIFY)
  15345. + && au_br_hnotifyable(br->br_perm)) {
  15346. + err = au_hn_alloc(hinode, inode);
  15347. + if (unlikely(err))
  15348. + AuIOErr1("au_hn_alloc() %d\n", err);
  15349. + }
  15350. + }
  15351. +}
  15352. +
  15353. +void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
  15354. + struct dentry *h_wh)
  15355. +{
  15356. + struct au_hinode *hinode;
  15357. +
  15358. + IiMustWriteLock(inode);
  15359. +
  15360. + hinode = au_ii(inode)->ii_hinode + bindex;
  15361. + AuDebugOn(hinode->hi_whdentry);
  15362. + hinode->hi_whdentry = h_wh;
  15363. +}
  15364. +
  15365. +void au_update_iigen(struct inode *inode)
  15366. +{
  15367. + atomic_set(&au_ii(inode)->ii_generation, au_sigen(inode->i_sb));
  15368. + /* smp_mb(); */ /* atomic_set */
  15369. +}
  15370. +
  15371. +/* it may be called at remount time, too */
  15372. +void au_update_ibrange(struct inode *inode, int do_put_zero)
  15373. +{
  15374. + struct au_iinfo *iinfo;
  15375. + aufs_bindex_t bindex, bend;
  15376. +
  15377. + iinfo = au_ii(inode);
  15378. + if (!iinfo)
  15379. + return;
  15380. +
  15381. + IiMustWriteLock(inode);
  15382. +
  15383. + if (do_put_zero && iinfo->ii_bstart >= 0) {
  15384. + for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
  15385. + bindex++) {
  15386. + struct inode *h_i;
  15387. +
  15388. + h_i = iinfo->ii_hinode[0 + bindex].hi_inode;
  15389. + if (h_i && !h_i->i_nlink)
  15390. + au_set_h_iptr(inode, bindex, NULL, 0);
  15391. + }
  15392. + }
  15393. +
  15394. + iinfo->ii_bstart = -1;
  15395. + iinfo->ii_bend = -1;
  15396. + bend = au_sbend(inode->i_sb);
  15397. + for (bindex = 0; bindex <= bend; bindex++)
  15398. + if (iinfo->ii_hinode[0 + bindex].hi_inode) {
  15399. + iinfo->ii_bstart = bindex;
  15400. + break;
  15401. + }
  15402. + if (iinfo->ii_bstart >= 0)
  15403. + for (bindex = bend; bindex >= iinfo->ii_bstart; bindex--)
  15404. + if (iinfo->ii_hinode[0 + bindex].hi_inode) {
  15405. + iinfo->ii_bend = bindex;
  15406. + break;
  15407. + }
  15408. + AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend);
  15409. +}
  15410. +
  15411. +/* ---------------------------------------------------------------------- */
  15412. +
  15413. +void au_icntnr_init_once(void *_c)
  15414. +{
  15415. + struct au_icntnr *c = _c;
  15416. + struct au_iinfo *iinfo = &c->iinfo;
  15417. + static struct lock_class_key aufs_ii;
  15418. +
  15419. + au_rw_init(&iinfo->ii_rwsem);
  15420. + au_rw_class(&iinfo->ii_rwsem, &aufs_ii);
  15421. + inode_init_once(&c->vfs_inode);
  15422. +}
  15423. +
  15424. +int au_iinfo_init(struct inode *inode)
  15425. +{
  15426. + struct au_iinfo *iinfo;
  15427. + struct super_block *sb;
  15428. + int nbr, i;
  15429. +
  15430. + sb = inode->i_sb;
  15431. + iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
  15432. + nbr = au_sbend(sb) + 1;
  15433. + if (unlikely(nbr <= 0))
  15434. + nbr = 1;
  15435. + iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
  15436. + if (iinfo->ii_hinode) {
  15437. + au_ninodes_inc(sb);
  15438. + for (i = 0; i < nbr; i++)
  15439. + iinfo->ii_hinode[i].hi_id = -1;
  15440. +
  15441. + atomic_set(&iinfo->ii_generation, au_sigen(sb));
  15442. + /* smp_mb(); */ /* atomic_set */
  15443. + iinfo->ii_bstart = -1;
  15444. + iinfo->ii_bend = -1;
  15445. + iinfo->ii_vdir = NULL;
  15446. + return 0;
  15447. + }
  15448. + return -ENOMEM;
  15449. +}
  15450. +
  15451. +int au_ii_realloc(struct au_iinfo *iinfo, int nbr)
  15452. +{
  15453. + int err, sz;
  15454. + struct au_hinode *hip;
  15455. +
  15456. + AuRwMustWriteLock(&iinfo->ii_rwsem);
  15457. +
  15458. + err = -ENOMEM;
  15459. + sz = sizeof(*hip) * (iinfo->ii_bend + 1);
  15460. + if (!sz)
  15461. + sz = sizeof(*hip);
  15462. + hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS);
  15463. + if (hip) {
  15464. + iinfo->ii_hinode = hip;
  15465. + err = 0;
  15466. + }
  15467. +
  15468. + return err;
  15469. +}
  15470. +
  15471. +void au_iinfo_fin(struct inode *inode)
  15472. +{
  15473. + struct au_iinfo *iinfo;
  15474. + struct au_hinode *hi;
  15475. + struct super_block *sb;
  15476. + aufs_bindex_t bindex, bend;
  15477. + const unsigned char unlinked = !inode->i_nlink;
  15478. +
  15479. + iinfo = au_ii(inode);
  15480. + /* bad_inode case */
  15481. + if (!iinfo)
  15482. + return;
  15483. +
  15484. + sb = inode->i_sb;
  15485. + au_ninodes_dec(sb);
  15486. + if (si_pid_test(sb))
  15487. + au_xino_delete_inode(inode, unlinked);
  15488. + else {
  15489. + /*
  15490. + * it is safe to hide the dependency between sbinfo and
  15491. + * sb->s_umount.
  15492. + */
  15493. + lockdep_off();
  15494. + si_noflush_read_lock(sb);
  15495. + au_xino_delete_inode(inode, unlinked);
  15496. + si_read_unlock(sb);
  15497. + lockdep_on();
  15498. + }
  15499. +
  15500. + if (iinfo->ii_vdir)
  15501. + au_vdir_free(iinfo->ii_vdir);
  15502. +
  15503. + bindex = iinfo->ii_bstart;
  15504. + if (bindex >= 0) {
  15505. + hi = iinfo->ii_hinode + bindex;
  15506. + bend = iinfo->ii_bend;
  15507. + while (bindex++ <= bend) {
  15508. + if (hi->hi_inode)
  15509. + au_hiput(hi);
  15510. + hi++;
  15511. + }
  15512. + }
  15513. + kfree(iinfo->ii_hinode);
  15514. + AuRwDestroy(&iinfo->ii_rwsem);
  15515. +}
  15516. diff -Nur linux-2.6.37.orig/fs/aufs/inode.c linux-2.6.37/fs/aufs/inode.c
  15517. --- linux-2.6.37.orig/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100
  15518. +++ linux-2.6.37/fs/aufs/inode.c 2011-01-11 20:15:11.000000000 +0100
  15519. @@ -0,0 +1,471 @@
  15520. +/*
  15521. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  15522. + *
  15523. + * This program, aufs is free software; you can redistribute it and/or modify
  15524. + * it under the terms of the GNU General Public License as published by
  15525. + * the Free Software Foundation; either version 2 of the License, or
  15526. + * (at your option) any later version.
  15527. + *
  15528. + * This program is distributed in the hope that it will be useful,
  15529. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15530. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15531. + * GNU General Public License for more details.
  15532. + *
  15533. + * You should have received a copy of the GNU General Public License
  15534. + * along with this program; if not, write to the Free Software
  15535. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  15536. + */
  15537. +
  15538. +/*
  15539. + * inode functions
  15540. + */
  15541. +
  15542. +#include "aufs.h"
  15543. +
  15544. +struct inode *au_igrab(struct inode *inode)
  15545. +{
  15546. + if (inode) {
  15547. + AuDebugOn(!atomic_read(&inode->i_count));
  15548. + atomic_inc(&inode->i_count);
  15549. + }
  15550. + return inode;
  15551. +}
  15552. +
  15553. +static void au_refresh_hinode_attr(struct inode *inode, int do_version)
  15554. +{
  15555. + au_cpup_attr_all(inode, /*force*/0);
  15556. + au_update_iigen(inode);
  15557. + if (do_version)
  15558. + inode->i_version++;
  15559. +}
  15560. +
  15561. +static int au_ii_refresh(struct inode *inode, int *update)
  15562. +{
  15563. + int err, e;
  15564. + umode_t type;
  15565. + aufs_bindex_t bindex, new_bindex;
  15566. + struct super_block *sb;
  15567. + struct au_iinfo *iinfo;
  15568. + struct au_hinode *p, *q, tmp;
  15569. +
  15570. + IiMustWriteLock(inode);
  15571. +
  15572. + *update = 0;
  15573. + sb = inode->i_sb;
  15574. + type = inode->i_mode & S_IFMT;
  15575. + iinfo = au_ii(inode);
  15576. + err = au_ii_realloc(iinfo, au_sbend(sb) + 1);
  15577. + if (unlikely(err))
  15578. + goto out;
  15579. +
  15580. + AuDebugOn(iinfo->ii_bstart < 0);
  15581. + p = iinfo->ii_hinode + iinfo->ii_bstart;
  15582. + for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
  15583. + bindex++, p++) {
  15584. + if (!p->hi_inode)
  15585. + continue;
  15586. +
  15587. + AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT));
  15588. + new_bindex = au_br_index(sb, p->hi_id);
  15589. + if (new_bindex == bindex)
  15590. + continue;
  15591. +
  15592. + if (new_bindex < 0) {
  15593. + *update = 1;
  15594. + au_hiput(p);
  15595. + p->hi_inode = NULL;
  15596. + continue;
  15597. + }
  15598. +
  15599. + if (new_bindex < iinfo->ii_bstart)
  15600. + iinfo->ii_bstart = new_bindex;
  15601. + if (iinfo->ii_bend < new_bindex)
  15602. + iinfo->ii_bend = new_bindex;
  15603. + /* swap two lower inode, and loop again */
  15604. + q = iinfo->ii_hinode + new_bindex;
  15605. + tmp = *q;
  15606. + *q = *p;
  15607. + *p = tmp;
  15608. + if (tmp.hi_inode) {
  15609. + bindex--;
  15610. + p--;
  15611. + }
  15612. + }
  15613. + au_update_ibrange(inode, /*do_put_zero*/0);
  15614. + e = au_dy_irefresh(inode);
  15615. + if (unlikely(e && !err))
  15616. + err = e;
  15617. +
  15618. +out:
  15619. + AuTraceErr(err);
  15620. + return err;
  15621. +}
  15622. +
  15623. +int au_refresh_hinode_self(struct inode *inode)
  15624. +{
  15625. + int err, update;
  15626. +
  15627. + err = au_ii_refresh(inode, &update);
  15628. + if (!err)
  15629. + au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
  15630. +
  15631. + AuTraceErr(err);
  15632. + return err;
  15633. +}
  15634. +
  15635. +int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
  15636. +{
  15637. + int err, e, update;
  15638. + unsigned int flags;
  15639. + umode_t mode;
  15640. + aufs_bindex_t bindex, bend;
  15641. + unsigned char isdir;
  15642. + struct au_hinode *p;
  15643. + struct au_iinfo *iinfo;
  15644. +
  15645. + err = au_ii_refresh(inode, &update);
  15646. + if (unlikely(err))
  15647. + goto out;
  15648. +
  15649. + update = 0;
  15650. + iinfo = au_ii(inode);
  15651. + p = iinfo->ii_hinode + iinfo->ii_bstart;
  15652. + mode = (inode->i_mode & S_IFMT);
  15653. + isdir = S_ISDIR(mode);
  15654. + flags = au_hi_flags(inode, isdir);
  15655. + bend = au_dbend(dentry);
  15656. + for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
  15657. + struct inode *h_i;
  15658. + struct dentry *h_d;
  15659. +
  15660. + h_d = au_h_dptr(dentry, bindex);
  15661. + if (!h_d || !h_d->d_inode)
  15662. + continue;
  15663. +
  15664. + AuDebugOn(mode != (h_d->d_inode->i_mode & S_IFMT));
  15665. + if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) {
  15666. + h_i = au_h_iptr(inode, bindex);
  15667. + if (h_i) {
  15668. + if (h_i == h_d->d_inode)
  15669. + continue;
  15670. + err = -EIO;
  15671. + break;
  15672. + }
  15673. + }
  15674. + if (bindex < iinfo->ii_bstart)
  15675. + iinfo->ii_bstart = bindex;
  15676. + if (iinfo->ii_bend < bindex)
  15677. + iinfo->ii_bend = bindex;
  15678. + au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags);
  15679. + update = 1;
  15680. + }
  15681. + au_update_ibrange(inode, /*do_put_zero*/0);
  15682. + e = au_dy_irefresh(inode);
  15683. + if (unlikely(e && !err))
  15684. + err = e;
  15685. + if (!err)
  15686. + au_refresh_hinode_attr(inode, update && isdir);
  15687. +
  15688. +out:
  15689. + AuTraceErr(err);
  15690. + return err;
  15691. +}
  15692. +
  15693. +static int set_inode(struct inode *inode, struct dentry *dentry)
  15694. +{
  15695. + int err;
  15696. + unsigned int flags;
  15697. + umode_t mode;
  15698. + aufs_bindex_t bindex, bstart, btail;
  15699. + unsigned char isdir;
  15700. + struct dentry *h_dentry;
  15701. + struct inode *h_inode;
  15702. + struct au_iinfo *iinfo;
  15703. +
  15704. + IiMustWriteLock(inode);
  15705. +
  15706. + err = 0;
  15707. + isdir = 0;
  15708. + bstart = au_dbstart(dentry);
  15709. + h_inode = au_h_dptr(dentry, bstart)->d_inode;
  15710. + mode = h_inode->i_mode;
  15711. + switch (mode & S_IFMT) {
  15712. + case S_IFREG:
  15713. + btail = au_dbtail(dentry);
  15714. + inode->i_op = &aufs_iop;
  15715. + inode->i_fop = &aufs_file_fop;
  15716. + err = au_dy_iaop(inode, bstart, h_inode);
  15717. + if (unlikely(err))
  15718. + goto out;
  15719. + break;
  15720. + case S_IFDIR:
  15721. + isdir = 1;
  15722. + btail = au_dbtaildir(dentry);
  15723. + inode->i_op = &aufs_dir_iop;
  15724. + inode->i_fop = &aufs_dir_fop;
  15725. + break;
  15726. + case S_IFLNK:
  15727. + btail = au_dbtail(dentry);
  15728. + inode->i_op = &aufs_symlink_iop;
  15729. + break;
  15730. + case S_IFBLK:
  15731. + case S_IFCHR:
  15732. + case S_IFIFO:
  15733. + case S_IFSOCK:
  15734. + btail = au_dbtail(dentry);
  15735. + inode->i_op = &aufs_iop;
  15736. + au_init_special_fop(inode, mode, h_inode->i_rdev);
  15737. + break;
  15738. + default:
  15739. + AuIOErr("Unknown file type 0%o\n", mode);
  15740. + err = -EIO;
  15741. + goto out;
  15742. + }
  15743. +
  15744. + /* do not set hnotify for whiteouted dirs (SHWH mode) */
  15745. + flags = au_hi_flags(inode, isdir);
  15746. + if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
  15747. + && au_ftest_hi(flags, HNOTIFY)
  15748. + && dentry->d_name.len > AUFS_WH_PFX_LEN
  15749. + && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
  15750. + au_fclr_hi(flags, HNOTIFY);
  15751. + iinfo = au_ii(inode);
  15752. + iinfo->ii_bstart = bstart;
  15753. + iinfo->ii_bend = btail;
  15754. + for (bindex = bstart; bindex <= btail; bindex++) {
  15755. + h_dentry = au_h_dptr(dentry, bindex);
  15756. + if (h_dentry)
  15757. + au_set_h_iptr(inode, bindex,
  15758. + au_igrab(h_dentry->d_inode), flags);
  15759. + }
  15760. + au_cpup_attr_all(inode, /*force*/1);
  15761. +
  15762. +out:
  15763. + return err;
  15764. +}
  15765. +
  15766. +/*
  15767. + * successful returns with iinfo write_locked
  15768. + * minus: errno
  15769. + * zero: success, matched
  15770. + * plus: no error, but unmatched
  15771. + */
  15772. +static int reval_inode(struct inode *inode, struct dentry *dentry)
  15773. +{
  15774. + int err;
  15775. + aufs_bindex_t bindex, bend;
  15776. + struct inode *h_inode, *h_dinode;
  15777. +
  15778. + /*
  15779. + * before this function, if aufs got any iinfo lock, it must be only
  15780. + * one, the parent dir.
  15781. + * it can happen by UDBA and the obsoleted inode number.
  15782. + */
  15783. + err = -EIO;
  15784. + if (unlikely(inode->i_ino == parent_ino(dentry)))
  15785. + goto out;
  15786. +
  15787. + err = 1;
  15788. + ii_write_lock_new_child(inode);
  15789. + h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode;
  15790. + bend = au_ibend(inode);
  15791. + for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
  15792. + h_inode = au_h_iptr(inode, bindex);
  15793. + if (h_inode && h_inode == h_dinode) {
  15794. + err = 0;
  15795. + if (au_iigen_test(inode, au_digen(dentry)))
  15796. + err = au_refresh_hinode(inode, dentry);
  15797. + break;
  15798. + }
  15799. + }
  15800. +
  15801. + if (unlikely(err))
  15802. + ii_write_unlock(inode);
  15803. +out:
  15804. + return err;
  15805. +}
  15806. +
  15807. +int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  15808. + unsigned int d_type, ino_t *ino)
  15809. +{
  15810. + int err;
  15811. + struct mutex *mtx;
  15812. +
  15813. + /* prevent hardlinked inode number from race condition */
  15814. + mtx = NULL;
  15815. + if (d_type != DT_DIR) {
  15816. + mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx;
  15817. + mutex_lock(mtx);
  15818. + }
  15819. + err = au_xino_read(sb, bindex, h_ino, ino);
  15820. + if (unlikely(err))
  15821. + goto out;
  15822. +
  15823. + if (!*ino) {
  15824. + err = -EIO;
  15825. + *ino = au_xino_new_ino(sb);
  15826. + if (unlikely(!*ino))
  15827. + goto out;
  15828. + err = au_xino_write(sb, bindex, h_ino, *ino);
  15829. + if (unlikely(err))
  15830. + goto out;
  15831. + }
  15832. +
  15833. +out:
  15834. + if (mtx)
  15835. + mutex_unlock(mtx);
  15836. + return err;
  15837. +}
  15838. +
  15839. +/* successful returns with iinfo write_locked */
  15840. +/* todo: return with unlocked? */
  15841. +struct inode *au_new_inode(struct dentry *dentry, int must_new)
  15842. +{
  15843. + struct inode *inode, *h_inode;
  15844. + struct dentry *h_dentry;
  15845. + struct super_block *sb;
  15846. + struct mutex *mtx;
  15847. + ino_t h_ino, ino;
  15848. + int err;
  15849. + aufs_bindex_t bstart;
  15850. +
  15851. + sb = dentry->d_sb;
  15852. + bstart = au_dbstart(dentry);
  15853. + h_dentry = au_h_dptr(dentry, bstart);
  15854. + h_inode = h_dentry->d_inode;
  15855. + h_ino = h_inode->i_ino;
  15856. +
  15857. + /*
  15858. + * stop 'race'-ing between hardlinks under different
  15859. + * parents.
  15860. + */
  15861. + mtx = NULL;
  15862. + if (!S_ISDIR(h_inode->i_mode))
  15863. + mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;
  15864. +
  15865. +new_ino:
  15866. + if (mtx)
  15867. + mutex_lock(mtx);
  15868. + err = au_xino_read(sb, bstart, h_ino, &ino);
  15869. + inode = ERR_PTR(err);
  15870. + if (unlikely(err))
  15871. + goto out;
  15872. +
  15873. + if (!ino) {
  15874. + ino = au_xino_new_ino(sb);
  15875. + if (unlikely(!ino)) {
  15876. + inode = ERR_PTR(-EIO);
  15877. + goto out;
  15878. + }
  15879. + }
  15880. +
  15881. + AuDbg("i%lu\n", (unsigned long)ino);
  15882. + inode = au_iget_locked(sb, ino);
  15883. + err = PTR_ERR(inode);
  15884. + if (IS_ERR(inode))
  15885. + goto out;
  15886. +
  15887. + AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
  15888. + if (inode->i_state & I_NEW) {
  15889. + ii_write_lock_new_child(inode);
  15890. + err = set_inode(inode, dentry);
  15891. + if (!err) {
  15892. + unlock_new_inode(inode);
  15893. + goto out; /* success */
  15894. + }
  15895. +
  15896. + /*
  15897. + * iget_failed() calls iput(), but we need to call
  15898. + * ii_write_unlock() after iget_failed(). so dirty hack for
  15899. + * i_count.
  15900. + */
  15901. + atomic_inc(&inode->i_count);
  15902. + iget_failed(inode);
  15903. + ii_write_unlock(inode);
  15904. + au_xino_write(sb, bstart, h_ino, /*ino*/0);
  15905. + /* ignore this error */
  15906. + goto out_iput;
  15907. + } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) {
  15908. + /*
  15909. + * horrible race condition between lookup, readdir and copyup
  15910. + * (or something).
  15911. + */
  15912. + if (mtx)
  15913. + mutex_unlock(mtx);
  15914. + err = reval_inode(inode, dentry);
  15915. + if (unlikely(err < 0)) {
  15916. + mtx = NULL;
  15917. + goto out_iput;
  15918. + }
  15919. +
  15920. + if (!err) {
  15921. + mtx = NULL;
  15922. + goto out; /* success */
  15923. + } else if (mtx)
  15924. + mutex_lock(mtx);
  15925. + }
  15926. +
  15927. + if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode)))
  15928. + AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
  15929. + " b%d, %s, %.*s, hi%lu, i%lu.\n",
  15930. + bstart, au_sbtype(h_dentry->d_sb), AuDLNPair(dentry),
  15931. + (unsigned long)h_ino, (unsigned long)ino);
  15932. + ino = 0;
  15933. + err = au_xino_write(sb, bstart, h_ino, /*ino*/0);
  15934. + if (!err) {
  15935. + iput(inode);
  15936. + if (mtx)
  15937. + mutex_unlock(mtx);
  15938. + goto new_ino;
  15939. + }
  15940. +
  15941. +out_iput:
  15942. + iput(inode);
  15943. + inode = ERR_PTR(err);
  15944. +out:
  15945. + if (mtx)
  15946. + mutex_unlock(mtx);
  15947. + return inode;
  15948. +}
  15949. +
  15950. +/* ---------------------------------------------------------------------- */
  15951. +
  15952. +int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
  15953. + struct inode *inode)
  15954. +{
  15955. + int err;
  15956. +
  15957. + err = au_br_rdonly(au_sbr(sb, bindex));
  15958. +
  15959. + /* pseudo-link after flushed may happen out of bounds */
  15960. + if (!err
  15961. + && inode
  15962. + && au_ibstart(inode) <= bindex
  15963. + && bindex <= au_ibend(inode)) {
  15964. + /*
  15965. + * permission check is unnecessary since vfsub routine
  15966. + * will be called later
  15967. + */
  15968. + struct inode *hi = au_h_iptr(inode, bindex);
  15969. + if (hi)
  15970. + err = IS_IMMUTABLE(hi) ? -EROFS : 0;
  15971. + }
  15972. +
  15973. + return err;
  15974. +}
  15975. +
  15976. +int au_test_h_perm(struct inode *h_inode, int mask)
  15977. +{
  15978. + if (!current_fsuid())
  15979. + return 0;
  15980. + return inode_permission(h_inode, mask);
  15981. +}
  15982. +
  15983. +int au_test_h_perm_sio(struct inode *h_inode, int mask)
  15984. +{
  15985. + if (au_test_nfs(h_inode->i_sb)
  15986. + && (mask & MAY_WRITE)
  15987. + && S_ISDIR(h_inode->i_mode))
  15988. + mask |= MAY_READ; /* force permission check */
  15989. + return au_test_h_perm(h_inode, mask);
  15990. +}
  15991. diff -Nur linux-2.6.37.orig/fs/aufs/inode.h linux-2.6.37/fs/aufs/inode.h
  15992. --- linux-2.6.37.orig/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
  15993. +++ linux-2.6.37/fs/aufs/inode.h 2011-01-11 20:15:11.000000000 +0100
  15994. @@ -0,0 +1,546 @@
  15995. +/*
  15996. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  15997. + *
  15998. + * This program, aufs is free software; you can redistribute it and/or modify
  15999. + * it under the terms of the GNU General Public License as published by
  16000. + * the Free Software Foundation; either version 2 of the License, or
  16001. + * (at your option) any later version.
  16002. + *
  16003. + * This program is distributed in the hope that it will be useful,
  16004. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16005. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16006. + * GNU General Public License for more details.
  16007. + *
  16008. + * You should have received a copy of the GNU General Public License
  16009. + * along with this program; if not, write to the Free Software
  16010. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16011. + */
  16012. +
  16013. +/*
  16014. + * inode operations
  16015. + */
  16016. +
  16017. +#ifndef __AUFS_INODE_H__
  16018. +#define __AUFS_INODE_H__
  16019. +
  16020. +#ifdef __KERNEL__
  16021. +
  16022. +#include <linux/fs.h>
  16023. +#include <linux/fsnotify.h>
  16024. +#include <linux/aufs_type.h>
  16025. +#include "rwsem.h"
  16026. +
  16027. +struct vfsmount;
  16028. +
  16029. +struct au_hnotify {
  16030. +#ifdef CONFIG_AUFS_HNOTIFY
  16031. +#ifdef CONFIG_AUFS_HFSNOTIFY
  16032. + /* never use fsnotify_add_vfsmount_mark() */
  16033. + struct fsnotify_mark hn_mark;
  16034. + int hn_mark_dead;
  16035. +#endif
  16036. + struct inode *hn_aufs_inode; /* no get/put */
  16037. +#endif
  16038. +} ____cacheline_aligned_in_smp;
  16039. +
  16040. +struct au_hinode {
  16041. + struct inode *hi_inode;
  16042. + aufs_bindex_t hi_id;
  16043. +#ifdef CONFIG_AUFS_HNOTIFY
  16044. + struct au_hnotify *hi_notify;
  16045. +#endif
  16046. +
  16047. + /* reference to the copied-up whiteout with get/put */
  16048. + struct dentry *hi_whdentry;
  16049. +};
  16050. +
  16051. +struct au_vdir;
  16052. +struct au_iinfo {
  16053. + atomic_t ii_generation;
  16054. + struct super_block *ii_hsb1; /* no get/put */
  16055. +
  16056. + struct au_rwsem ii_rwsem;
  16057. + aufs_bindex_t ii_bstart, ii_bend;
  16058. + __u32 ii_higen;
  16059. + struct au_hinode *ii_hinode;
  16060. + struct au_vdir *ii_vdir;
  16061. +};
  16062. +
  16063. +struct au_icntnr {
  16064. + struct au_iinfo iinfo;
  16065. + struct inode vfs_inode;
  16066. +} ____cacheline_aligned_in_smp;
  16067. +
  16068. +/* au_pin flags */
  16069. +#define AuPin_DI_LOCKED 1
  16070. +#define AuPin_MNT_WRITE (1 << 1)
  16071. +#define au_ftest_pin(flags, name) ((flags) & AuPin_##name)
  16072. +#define au_fset_pin(flags, name) \
  16073. + do { (flags) |= AuPin_##name; } while (0)
  16074. +#define au_fclr_pin(flags, name) \
  16075. + do { (flags) &= ~AuPin_##name; } while (0)
  16076. +
  16077. +struct au_pin {
  16078. + /* input */
  16079. + struct dentry *dentry;
  16080. + unsigned int udba;
  16081. + unsigned char lsc_di, lsc_hi, flags;
  16082. + aufs_bindex_t bindex;
  16083. +
  16084. + /* output */
  16085. + struct dentry *parent;
  16086. + struct au_hinode *hdir;
  16087. + struct vfsmount *h_mnt;
  16088. +};
  16089. +
  16090. +/* ---------------------------------------------------------------------- */
  16091. +
  16092. +static inline struct au_iinfo *au_ii(struct inode *inode)
  16093. +{
  16094. + struct au_iinfo *iinfo;
  16095. +
  16096. + iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
  16097. + if (iinfo->ii_hinode)
  16098. + return iinfo;
  16099. + return NULL; /* debugging bad_inode case */
  16100. +}
  16101. +
  16102. +/* ---------------------------------------------------------------------- */
  16103. +
  16104. +/* inode.c */
  16105. +struct inode *au_igrab(struct inode *inode);
  16106. +int au_refresh_hinode_self(struct inode *inode);
  16107. +int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
  16108. +int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  16109. + unsigned int d_type, ino_t *ino);
  16110. +struct inode *au_new_inode(struct dentry *dentry, int must_new);
  16111. +int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
  16112. + struct inode *inode);
  16113. +int au_test_h_perm(struct inode *h_inode, int mask);
  16114. +int au_test_h_perm_sio(struct inode *h_inode, int mask);
  16115. +
  16116. +static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex,
  16117. + ino_t h_ino, unsigned int d_type, ino_t *ino)
  16118. +{
  16119. +#ifdef CONFIG_AUFS_SHWH
  16120. + return au_ino(sb, bindex, h_ino, d_type, ino);
  16121. +#else
  16122. + return 0;
  16123. +#endif
  16124. +}
  16125. +
  16126. +/* i_op.c */
  16127. +extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
  16128. +
  16129. +/* au_wr_dir flags */
  16130. +#define AuWrDir_ADD_ENTRY 1
  16131. +#define AuWrDir_ISDIR (1 << 1)
  16132. +#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
  16133. +#define au_fset_wrdir(flags, name) \
  16134. + do { (flags) |= AuWrDir_##name; } while (0)
  16135. +#define au_fclr_wrdir(flags, name) \
  16136. + do { (flags) &= ~AuWrDir_##name; } while (0)
  16137. +
  16138. +struct au_wr_dir_args {
  16139. + aufs_bindex_t force_btgt;
  16140. + unsigned char flags;
  16141. +};
  16142. +int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
  16143. + struct au_wr_dir_args *args);
  16144. +
  16145. +struct dentry *au_pinned_h_parent(struct au_pin *pin);
  16146. +void au_pin_init(struct au_pin *pin, struct dentry *dentry,
  16147. + aufs_bindex_t bindex, int lsc_di, int lsc_hi,
  16148. + unsigned int udba, unsigned char flags);
  16149. +int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
  16150. + unsigned int udba, unsigned char flags) __must_check;
  16151. +int au_do_pin(struct au_pin *pin) __must_check;
  16152. +void au_unpin(struct au_pin *pin);
  16153. +
  16154. +/* i_op_add.c */
  16155. +int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
  16156. + struct dentry *h_parent, int isdir);
  16157. +int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev);
  16158. +int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
  16159. +int aufs_create(struct inode *dir, struct dentry *dentry, int mode,
  16160. + struct nameidata *nd);
  16161. +int aufs_link(struct dentry *src_dentry, struct inode *dir,
  16162. + struct dentry *dentry);
  16163. +int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
  16164. +
  16165. +/* i_op_del.c */
  16166. +int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
  16167. +int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
  16168. + struct dentry *h_parent, int isdir);
  16169. +int aufs_unlink(struct inode *dir, struct dentry *dentry);
  16170. +int aufs_rmdir(struct inode *dir, struct dentry *dentry);
  16171. +
  16172. +/* i_op_ren.c */
  16173. +int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
  16174. +int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
  16175. + struct inode *dir, struct dentry *dentry);
  16176. +
  16177. +/* iinfo.c */
  16178. +struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
  16179. +void au_hiput(struct au_hinode *hinode);
  16180. +void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
  16181. + struct dentry *h_wh);
  16182. +unsigned int au_hi_flags(struct inode *inode, int isdir);
  16183. +
  16184. +/* hinode flags */
  16185. +#define AuHi_XINO 1
  16186. +#define AuHi_HNOTIFY (1 << 1)
  16187. +#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
  16188. +#define au_fset_hi(flags, name) \
  16189. + do { (flags) |= AuHi_##name; } while (0)
  16190. +#define au_fclr_hi(flags, name) \
  16191. + do { (flags) &= ~AuHi_##name; } while (0)
  16192. +
  16193. +#ifndef CONFIG_AUFS_HNOTIFY
  16194. +#undef AuHi_HNOTIFY
  16195. +#define AuHi_HNOTIFY 0
  16196. +#endif
  16197. +
  16198. +void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
  16199. + struct inode *h_inode, unsigned int flags);
  16200. +
  16201. +void au_update_iigen(struct inode *inode);
  16202. +void au_update_ibrange(struct inode *inode, int do_put_zero);
  16203. +
  16204. +void au_icntnr_init_once(void *_c);
  16205. +int au_iinfo_init(struct inode *inode);
  16206. +void au_iinfo_fin(struct inode *inode);
  16207. +int au_ii_realloc(struct au_iinfo *iinfo, int nbr);
  16208. +
  16209. +#ifdef CONFIG_PROC_FS
  16210. +/* plink.c */
  16211. +int au_plink_maint(struct super_block *sb, int flags);
  16212. +void au_plink_maint_leave(struct au_sbinfo *sbinfo);
  16213. +int au_plink_maint_enter(struct super_block *sb);
  16214. +#ifdef CONFIG_AUFS_DEBUG
  16215. +void au_plink_list(struct super_block *sb);
  16216. +#else
  16217. +AuStubVoid(au_plink_list, struct super_block *sb)
  16218. +#endif
  16219. +int au_plink_test(struct inode *inode);
  16220. +struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
  16221. +void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
  16222. + struct dentry *h_dentry);
  16223. +void au_plink_put(struct super_block *sb, int verbose);
  16224. +void au_plink_clean(struct super_block *sb, int verbose);
  16225. +void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
  16226. +#else
  16227. +AuStubInt0(au_plink_maint, struct super_block *sb, int flags);
  16228. +AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo);
  16229. +AuStubInt0(au_plink_maint_enter, struct super_block *sb);
  16230. +AuStubVoid(au_plink_list, struct super_block *sb);
  16231. +AuStubInt0(au_plink_test, struct inode *inode);
  16232. +AuStub(struct dentry *, au_plink_lkup, return NULL,
  16233. + struct inode *inode, aufs_bindex_t bindex);
  16234. +AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex,
  16235. + struct dentry *h_dentry);
  16236. +AuStubVoid(au_plink_put, struct super_block *sb, int verbose);
  16237. +AuStubVoid(au_plink_clean, struct super_block *sb, int verbose);
  16238. +AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id);
  16239. +#endif /* CONFIG_PROC_FS */
  16240. +
  16241. +/* ---------------------------------------------------------------------- */
  16242. +
  16243. +/* lock subclass for iinfo */
  16244. +enum {
  16245. + AuLsc_II_CHILD, /* child first */
  16246. + AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */
  16247. + AuLsc_II_CHILD3, /* copyup dirs */
  16248. + AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
  16249. + AuLsc_II_PARENT2,
  16250. + AuLsc_II_PARENT3, /* copyup dirs */
  16251. + AuLsc_II_NEW_CHILD
  16252. +};
  16253. +
  16254. +/*
  16255. + * ii_read_lock_child, ii_write_lock_child,
  16256. + * ii_read_lock_child2, ii_write_lock_child2,
  16257. + * ii_read_lock_child3, ii_write_lock_child3,
  16258. + * ii_read_lock_parent, ii_write_lock_parent,
  16259. + * ii_read_lock_parent2, ii_write_lock_parent2,
  16260. + * ii_read_lock_parent3, ii_write_lock_parent3,
  16261. + * ii_read_lock_new_child, ii_write_lock_new_child,
  16262. + */
  16263. +#define AuReadLockFunc(name, lsc) \
  16264. +static inline void ii_read_lock_##name(struct inode *i) \
  16265. +{ \
  16266. + au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
  16267. +}
  16268. +
  16269. +#define AuWriteLockFunc(name, lsc) \
  16270. +static inline void ii_write_lock_##name(struct inode *i) \
  16271. +{ \
  16272. + au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
  16273. +}
  16274. +
  16275. +#define AuRWLockFuncs(name, lsc) \
  16276. + AuReadLockFunc(name, lsc) \
  16277. + AuWriteLockFunc(name, lsc)
  16278. +
  16279. +AuRWLockFuncs(child, CHILD);
  16280. +AuRWLockFuncs(child2, CHILD2);
  16281. +AuRWLockFuncs(child3, CHILD3);
  16282. +AuRWLockFuncs(parent, PARENT);
  16283. +AuRWLockFuncs(parent2, PARENT2);
  16284. +AuRWLockFuncs(parent3, PARENT3);
  16285. +AuRWLockFuncs(new_child, NEW_CHILD);
  16286. +
  16287. +#undef AuReadLockFunc
  16288. +#undef AuWriteLockFunc
  16289. +#undef AuRWLockFuncs
  16290. +
  16291. +/*
  16292. + * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
  16293. + */
  16294. +AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
  16295. +
  16296. +#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
  16297. +#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
  16298. +#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
  16299. +
  16300. +/* ---------------------------------------------------------------------- */
  16301. +
  16302. +static inline void au_icntnr_init(struct au_icntnr *c)
  16303. +{
  16304. +#ifdef CONFIG_AUFS_DEBUG
  16305. + c->vfs_inode.i_mode = 0;
  16306. +#endif
  16307. +}
  16308. +
  16309. +static inline unsigned int au_iigen(struct inode *inode)
  16310. +{
  16311. + return atomic_read(&au_ii(inode)->ii_generation);
  16312. +}
  16313. +
  16314. +/* tiny test for inode number */
  16315. +/* tmpfs generation is too rough */
  16316. +static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
  16317. +{
  16318. + struct au_iinfo *iinfo;
  16319. +
  16320. + iinfo = au_ii(inode);
  16321. + AuRwMustAnyLock(&iinfo->ii_rwsem);
  16322. + return !(iinfo->ii_hsb1 == h_inode->i_sb
  16323. + && iinfo->ii_higen == h_inode->i_generation);
  16324. +}
  16325. +
  16326. +static inline void au_iigen_dec(struct inode *inode)
  16327. +{
  16328. + atomic_dec(&au_ii(inode)->ii_generation);
  16329. +}
  16330. +
  16331. +static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
  16332. +{
  16333. + int err;
  16334. +
  16335. + err = 0;
  16336. + if (unlikely(inode && au_iigen(inode) != sigen))
  16337. + err = -EIO;
  16338. +
  16339. + return err;
  16340. +}
  16341. +
  16342. +/* ---------------------------------------------------------------------- */
  16343. +
  16344. +static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
  16345. + aufs_bindex_t bindex)
  16346. +{
  16347. + IiMustAnyLock(inode);
  16348. + return au_ii(inode)->ii_hinode[0 + bindex].hi_id;
  16349. +}
  16350. +
  16351. +static inline aufs_bindex_t au_ibstart(struct inode *inode)
  16352. +{
  16353. + IiMustAnyLock(inode);
  16354. + return au_ii(inode)->ii_bstart;
  16355. +}
  16356. +
  16357. +static inline aufs_bindex_t au_ibend(struct inode *inode)
  16358. +{
  16359. + IiMustAnyLock(inode);
  16360. + return au_ii(inode)->ii_bend;
  16361. +}
  16362. +
  16363. +static inline struct au_vdir *au_ivdir(struct inode *inode)
  16364. +{
  16365. + IiMustAnyLock(inode);
  16366. + return au_ii(inode)->ii_vdir;
  16367. +}
  16368. +
  16369. +static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
  16370. +{
  16371. + IiMustAnyLock(inode);
  16372. + return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry;
  16373. +}
  16374. +
  16375. +static inline void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex)
  16376. +{
  16377. + IiMustWriteLock(inode);
  16378. + au_ii(inode)->ii_bstart = bindex;
  16379. +}
  16380. +
  16381. +static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex)
  16382. +{
  16383. + IiMustWriteLock(inode);
  16384. + au_ii(inode)->ii_bend = bindex;
  16385. +}
  16386. +
  16387. +static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
  16388. +{
  16389. + IiMustWriteLock(inode);
  16390. + au_ii(inode)->ii_vdir = vdir;
  16391. +}
  16392. +
  16393. +static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
  16394. +{
  16395. + IiMustAnyLock(inode);
  16396. + return au_ii(inode)->ii_hinode + bindex;
  16397. +}
  16398. +
  16399. +/* ---------------------------------------------------------------------- */
  16400. +
  16401. +static inline struct dentry *au_pinned_parent(struct au_pin *pin)
  16402. +{
  16403. + if (pin)
  16404. + return pin->parent;
  16405. + return NULL;
  16406. +}
  16407. +
  16408. +static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
  16409. +{
  16410. + if (pin && pin->hdir)
  16411. + return pin->hdir->hi_inode;
  16412. + return NULL;
  16413. +}
  16414. +
  16415. +static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
  16416. +{
  16417. + if (pin)
  16418. + return pin->hdir;
  16419. + return NULL;
  16420. +}
  16421. +
  16422. +static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
  16423. +{
  16424. + if (pin)
  16425. + pin->dentry = dentry;
  16426. +}
  16427. +
  16428. +static inline void au_pin_set_parent_lflag(struct au_pin *pin,
  16429. + unsigned char lflag)
  16430. +{
  16431. + if (pin) {
  16432. + if (lflag)
  16433. + au_fset_pin(pin->flags, DI_LOCKED);
  16434. + else
  16435. + au_fclr_pin(pin->flags, DI_LOCKED);
  16436. + }
  16437. +}
  16438. +
  16439. +static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
  16440. +{
  16441. + if (pin) {
  16442. + dput(pin->parent);
  16443. + pin->parent = dget(parent);
  16444. + }
  16445. +}
  16446. +
  16447. +/* ---------------------------------------------------------------------- */
  16448. +
  16449. +struct au_branch;
  16450. +#ifdef CONFIG_AUFS_HNOTIFY
  16451. +struct au_hnotify_op {
  16452. + void (*ctl)(struct au_hinode *hinode, int do_set);
  16453. + int (*alloc)(struct au_hinode *hinode);
  16454. + void (*free)(struct au_hinode *hinode);
  16455. +
  16456. + void (*fin)(void);
  16457. + int (*init)(void);
  16458. +
  16459. + int (*reset_br)(unsigned int udba, struct au_branch *br, int perm);
  16460. + void (*fin_br)(struct au_branch *br);
  16461. + int (*init_br)(struct au_branch *br, int perm);
  16462. +};
  16463. +
  16464. +/* hnotify.c */
  16465. +int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
  16466. +void au_hn_free(struct au_hinode *hinode);
  16467. +void au_hn_ctl(struct au_hinode *hinode, int do_set);
  16468. +void au_hn_reset(struct inode *inode, unsigned int flags);
  16469. +int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
  16470. + struct qstr *h_child_qstr, struct inode *h_child_inode);
  16471. +int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm);
  16472. +int au_hnotify_init_br(struct au_branch *br, int perm);
  16473. +void au_hnotify_fin_br(struct au_branch *br);
  16474. +int __init au_hnotify_init(void);
  16475. +void au_hnotify_fin(void);
  16476. +
  16477. +/* hfsnotify.c */
  16478. +extern const struct au_hnotify_op au_hnotify_op;
  16479. +
  16480. +static inline
  16481. +void au_hn_init(struct au_hinode *hinode)
  16482. +{
  16483. + hinode->hi_notify = NULL;
  16484. +}
  16485. +
  16486. +#else
  16487. +static inline
  16488. +int au_hn_alloc(struct au_hinode *hinode __maybe_unused,
  16489. + struct inode *inode __maybe_unused)
  16490. +{
  16491. + return -EOPNOTSUPP;
  16492. +}
  16493. +
  16494. +AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused)
  16495. +AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused,
  16496. + int do_set __maybe_unused)
  16497. +AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused,
  16498. + unsigned int flags __maybe_unused)
  16499. +AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused,
  16500. + struct au_branch *br __maybe_unused,
  16501. + int perm __maybe_unused)
  16502. +AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused,
  16503. + int perm __maybe_unused)
  16504. +AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused)
  16505. +AuStubInt0(__init au_hnotify_init, void)
  16506. +AuStubVoid(au_hnotify_fin, void)
  16507. +AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused)
  16508. +#endif /* CONFIG_AUFS_HNOTIFY */
  16509. +
  16510. +static inline void au_hn_suspend(struct au_hinode *hdir)
  16511. +{
  16512. + au_hn_ctl(hdir, /*do_set*/0);
  16513. +}
  16514. +
  16515. +static inline void au_hn_resume(struct au_hinode *hdir)
  16516. +{
  16517. + au_hn_ctl(hdir, /*do_set*/1);
  16518. +}
  16519. +
  16520. +static inline void au_hn_imtx_lock(struct au_hinode *hdir)
  16521. +{
  16522. + mutex_lock(&hdir->hi_inode->i_mutex);
  16523. + au_hn_suspend(hdir);
  16524. +}
  16525. +
  16526. +static inline void au_hn_imtx_lock_nested(struct au_hinode *hdir,
  16527. + unsigned int sc __maybe_unused)
  16528. +{
  16529. + mutex_lock_nested(&hdir->hi_inode->i_mutex, sc);
  16530. + au_hn_suspend(hdir);
  16531. +}
  16532. +
  16533. +static inline void au_hn_imtx_unlock(struct au_hinode *hdir)
  16534. +{
  16535. + au_hn_resume(hdir);
  16536. + mutex_unlock(&hdir->hi_inode->i_mutex);
  16537. +}
  16538. +
  16539. +#endif /* __KERNEL__ */
  16540. +#endif /* __AUFS_INODE_H__ */
  16541. diff -Nur linux-2.6.37.orig/fs/aufs/ioctl.c linux-2.6.37/fs/aufs/ioctl.c
  16542. --- linux-2.6.37.orig/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100
  16543. +++ linux-2.6.37/fs/aufs/ioctl.c 2011-01-11 20:15:11.000000000 +0100
  16544. @@ -0,0 +1,150 @@
  16545. +/*
  16546. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  16547. + *
  16548. + * This program, aufs is free software; you can redistribute it and/or modify
  16549. + * it under the terms of the GNU General Public License as published by
  16550. + * the Free Software Foundation; either version 2 of the License, or
  16551. + * (at your option) any later version.
  16552. + *
  16553. + * This program is distributed in the hope that it will be useful,
  16554. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16555. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16556. + * GNU General Public License for more details.
  16557. + *
  16558. + * You should have received a copy of the GNU General Public License
  16559. + * along with this program; if not, write to the Free Software
  16560. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16561. + */
  16562. +
  16563. +/*
  16564. + * ioctl
  16565. + * plink-management and readdir in userspace.
  16566. + * assist the pathconf(3) wrapper library.
  16567. + */
  16568. +
  16569. +#include <linux/file.h>
  16570. +#include "aufs.h"
  16571. +
  16572. +static int au_wbr_fd(struct path *path)
  16573. +{
  16574. + int err, fd;
  16575. + aufs_bindex_t wbi, bindex, bend;
  16576. + struct file *h_file;
  16577. + struct super_block *sb;
  16578. + struct dentry *root;
  16579. + struct au_branch *wbr;
  16580. +
  16581. + err = get_unused_fd();
  16582. + if (unlikely(err < 0))
  16583. + goto out;
  16584. + fd = err;
  16585. +
  16586. + wbi = 0;
  16587. + sb = path->dentry->d_sb;
  16588. + root = sb->s_root;
  16589. + aufs_read_lock(root, AuLock_IR);
  16590. + wbr = au_sbr(sb, wbi);
  16591. + if (!(path->mnt->mnt_flags & MNT_READONLY)
  16592. + && !au_br_writable(wbr->br_perm)) {
  16593. + bend = au_sbend(sb);
  16594. + for (bindex = 1; bindex <= bend; bindex++) {
  16595. + wbr = au_sbr(sb, bindex);
  16596. + if (au_br_writable(wbr->br_perm)) {
  16597. + wbi = bindex;
  16598. + break;
  16599. + }
  16600. + }
  16601. + wbr = au_sbr(sb, wbi);
  16602. + }
  16603. + AuDbg("wbi %d\n", wbi);
  16604. + h_file = au_h_open(root, wbi, O_RDONLY | O_DIRECTORY | O_LARGEFILE,
  16605. + NULL);
  16606. + aufs_read_unlock(root, AuLock_IR);
  16607. + err = PTR_ERR(h_file);
  16608. + if (IS_ERR(h_file))
  16609. + goto out_fd;
  16610. +
  16611. + atomic_dec(&wbr->br_count); /* cf. au_h_open() */
  16612. + fd_install(fd, h_file);
  16613. + err = fd;
  16614. + goto out; /* success */
  16615. +
  16616. +out_fd:
  16617. + put_unused_fd(fd);
  16618. +out:
  16619. + return err;
  16620. +}
  16621. +
  16622. +/* ---------------------------------------------------------------------- */
  16623. +
  16624. +long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
  16625. +{
  16626. + long err;
  16627. +
  16628. + switch (cmd) {
  16629. + case AUFS_CTL_RDU:
  16630. + case AUFS_CTL_RDU_INO:
  16631. + err = au_rdu_ioctl(file, cmd, arg);
  16632. + break;
  16633. +
  16634. + case AUFS_CTL_WBR_FD:
  16635. + err = au_wbr_fd(&file->f_path);
  16636. + break;
  16637. +
  16638. + default:
  16639. + /* do not call the lower */
  16640. + AuDbg("0x%x\n", cmd);
  16641. + err = -ENOTTY;
  16642. + }
  16643. +
  16644. + AuTraceErr(err);
  16645. + return err;
  16646. +}
  16647. +
  16648. +long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
  16649. +{
  16650. + long err;
  16651. +
  16652. + switch (cmd) {
  16653. + case AUFS_CTL_WBR_FD:
  16654. + err = au_wbr_fd(&file->f_path);
  16655. + break;
  16656. +
  16657. + default:
  16658. + /* do not call the lower */
  16659. + AuDbg("0x%x\n", cmd);
  16660. + err = -ENOTTY;
  16661. + }
  16662. +
  16663. + AuTraceErr(err);
  16664. + return err;
  16665. +}
  16666. +
  16667. +#ifdef CONFIG_COMPAT
  16668. +long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
  16669. + unsigned long arg)
  16670. +{
  16671. + long err;
  16672. +
  16673. + switch (cmd) {
  16674. + case AUFS_CTL_RDU:
  16675. + case AUFS_CTL_RDU_INO:
  16676. + err = au_rdu_compat_ioctl(file, cmd, arg);
  16677. + break;
  16678. +
  16679. + default:
  16680. + err = aufs_ioctl_dir(file, cmd, arg);
  16681. + }
  16682. +
  16683. + AuTraceErr(err);
  16684. + return err;
  16685. +}
  16686. +
  16687. +#if 0 /* unused yet */
  16688. +long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
  16689. + unsigned long arg)
  16690. +{
  16691. + return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg));
  16692. +}
  16693. +#endif
  16694. +#endif
  16695. diff -Nur linux-2.6.37.orig/fs/aufs/loop.c linux-2.6.37/fs/aufs/loop.c
  16696. --- linux-2.6.37.orig/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100
  16697. +++ linux-2.6.37/fs/aufs/loop.c 2011-01-11 20:15:11.000000000 +0100
  16698. @@ -0,0 +1,63 @@
  16699. +/*
  16700. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  16701. + *
  16702. + * This program, aufs is free software; you can redistribute it and/or modify
  16703. + * it under the terms of the GNU General Public License as published by
  16704. + * the Free Software Foundation; either version 2 of the License, or
  16705. + * (at your option) any later version.
  16706. + *
  16707. + * This program is distributed in the hope that it will be useful,
  16708. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16709. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16710. + * GNU General Public License for more details.
  16711. + *
  16712. + * You should have received a copy of the GNU General Public License
  16713. + * along with this program; if not, write to the Free Software
  16714. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16715. + */
  16716. +
  16717. +/*
  16718. + * support for loopback block device as a branch
  16719. + */
  16720. +
  16721. +#include <linux/loop.h>
  16722. +#include "aufs.h"
  16723. +
  16724. +/*
  16725. + * test if two lower dentries have overlapping branches.
  16726. + */
  16727. +int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
  16728. +{
  16729. + struct super_block *h_sb;
  16730. + struct loop_device *l;
  16731. +
  16732. + h_sb = h_adding->d_sb;
  16733. + if (MAJOR(h_sb->s_dev) != LOOP_MAJOR)
  16734. + return 0;
  16735. +
  16736. + l = h_sb->s_bdev->bd_disk->private_data;
  16737. + h_adding = l->lo_backing_file->f_dentry;
  16738. + /*
  16739. + * h_adding can be local NFS.
  16740. + * in this case aufs cannot detect the loop.
  16741. + */
  16742. + if (unlikely(h_adding->d_sb == sb))
  16743. + return 1;
  16744. + return !!au_test_subdir(h_adding, sb->s_root);
  16745. +}
  16746. +
  16747. +/* true if a kernel thread named 'loop[0-9].*' accesses a file */
  16748. +int au_test_loopback_kthread(void)
  16749. +{
  16750. + int ret;
  16751. + struct task_struct *tsk = current;
  16752. +
  16753. + ret = 0;
  16754. + if (tsk->flags & PF_KTHREAD) {
  16755. + const char c = tsk->comm[4];
  16756. + ret = ('0' <= c && c <= '9'
  16757. + && !strncmp(tsk->comm, "loop", 4));
  16758. + }
  16759. +
  16760. + return ret;
  16761. +}
  16762. diff -Nur linux-2.6.37.orig/fs/aufs/loop.h linux-2.6.37/fs/aufs/loop.h
  16763. --- linux-2.6.37.orig/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
  16764. +++ linux-2.6.37/fs/aufs/loop.h 2011-01-11 20:15:11.000000000 +0100
  16765. @@ -0,0 +1,42 @@
  16766. +/*
  16767. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  16768. + *
  16769. + * This program, aufs is free software; you can redistribute it and/or modify
  16770. + * it under the terms of the GNU General Public License as published by
  16771. + * the Free Software Foundation; either version 2 of the License, or
  16772. + * (at your option) any later version.
  16773. + *
  16774. + * This program is distributed in the hope that it will be useful,
  16775. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16776. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16777. + * GNU General Public License for more details.
  16778. + *
  16779. + * You should have received a copy of the GNU General Public License
  16780. + * along with this program; if not, write to the Free Software
  16781. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16782. + */
  16783. +
  16784. +/*
  16785. + * support for loopback mount as a branch
  16786. + */
  16787. +
  16788. +#ifndef __AUFS_LOOP_H__
  16789. +#define __AUFS_LOOP_H__
  16790. +
  16791. +#ifdef __KERNEL__
  16792. +
  16793. +struct dentry;
  16794. +struct super_block;
  16795. +
  16796. +#ifdef CONFIG_AUFS_BDEV_LOOP
  16797. +/* loop.c */
  16798. +int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding);
  16799. +int au_test_loopback_kthread(void);
  16800. +#else
  16801. +AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
  16802. + struct dentry *h_adding)
  16803. +AuStubInt0(au_test_loopback_kthread, void)
  16804. +#endif /* BLK_DEV_LOOP */
  16805. +
  16806. +#endif /* __KERNEL__ */
  16807. +#endif /* __AUFS_LOOP_H__ */
  16808. diff -Nur linux-2.6.37.orig/fs/aufs/magic.mk linux-2.6.37/fs/aufs/magic.mk
  16809. --- linux-2.6.37.orig/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100
  16810. +++ linux-2.6.37/fs/aufs/magic.mk 2011-01-11 20:15:11.000000000 +0100
  16811. @@ -0,0 +1,54 @@
  16812. +
  16813. +# defined in ${srctree}/fs/fuse/inode.c
  16814. +# tristate
  16815. +ifdef CONFIG_FUSE_FS
  16816. +ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
  16817. +endif
  16818. +
  16819. +# defined in ${srctree}/fs/ocfs2/ocfs2_fs.h
  16820. +# tristate
  16821. +ifdef CONFIG_OCFS2_FS
  16822. +ccflags-y += -DOCFS2_SUPER_MAGIC=0x7461636f
  16823. +endif
  16824. +
  16825. +# defined in ${srctree}/fs/ocfs2/dlm/userdlm.h
  16826. +# tristate
  16827. +ifdef CONFIG_OCFS2_FS_O2CB
  16828. +ccflags-y += -DDLMFS_MAGIC=0x76a9f425
  16829. +endif
  16830. +
  16831. +# defined in ${srctree}/fs/cifs/cifsfs.c
  16832. +# tristate
  16833. +ifdef CONFIG_CIFS_FS
  16834. +ccflags-y += -DCIFS_MAGIC_NUMBER=0xFF534D42
  16835. +endif
  16836. +
  16837. +# defined in ${srctree}/fs/xfs/xfs_sb.h
  16838. +# tristate
  16839. +ifdef CONFIG_XFS_FS
  16840. +ccflags-y += -DXFS_SB_MAGIC=0x58465342
  16841. +endif
  16842. +
  16843. +# defined in ${srctree}/fs/configfs/mount.c
  16844. +# tristate
  16845. +ifdef CONFIG_CONFIGFS_FS
  16846. +ccflags-y += -DCONFIGFS_MAGIC=0x62656570
  16847. +endif
  16848. +
  16849. +# defined in ${srctree}/fs/9p/v9fs.h
  16850. +# tristate
  16851. +ifdef CONFIG_9P_FS
  16852. +ccflags-y += -DV9FS_MAGIC=0x01021997
  16853. +endif
  16854. +
  16855. +# defined in ${srctree}/fs/ubifs/ubifs.h
  16856. +# tristate
  16857. +ifdef CONFIG_UBIFS_FS
  16858. +ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
  16859. +endif
  16860. +
  16861. +# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h
  16862. +# tristate
  16863. +ifdef CONFIG_HFSPLUS_FS
  16864. +ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b
  16865. +endif
  16866. diff -Nur linux-2.6.37.orig/fs/aufs/module.c linux-2.6.37/fs/aufs/module.c
  16867. --- linux-2.6.37.orig/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100
  16868. +++ linux-2.6.37/fs/aufs/module.c 2011-01-11 20:15:11.000000000 +0100
  16869. @@ -0,0 +1,182 @@
  16870. +/*
  16871. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  16872. + *
  16873. + * This program, aufs is free software; you can redistribute it and/or modify
  16874. + * it under the terms of the GNU General Public License as published by
  16875. + * the Free Software Foundation; either version 2 of the License, or
  16876. + * (at your option) any later version.
  16877. + *
  16878. + * This program is distributed in the hope that it will be useful,
  16879. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16880. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16881. + * GNU General Public License for more details.
  16882. + *
  16883. + * You should have received a copy of the GNU General Public License
  16884. + * along with this program; if not, write to the Free Software
  16885. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16886. + */
  16887. +
  16888. +/*
  16889. + * module global variables and operations
  16890. + */
  16891. +
  16892. +#include <linux/module.h>
  16893. +#include <linux/seq_file.h>
  16894. +#include "aufs.h"
  16895. +
  16896. +void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp)
  16897. +{
  16898. + if (new_sz <= nused)
  16899. + return p;
  16900. +
  16901. + p = krealloc(p, new_sz, gfp);
  16902. + if (p)
  16903. + memset(p + nused, 0, new_sz - nused);
  16904. + return p;
  16905. +}
  16906. +
  16907. +/* ---------------------------------------------------------------------- */
  16908. +
  16909. +/*
  16910. + * aufs caches
  16911. + */
  16912. +struct kmem_cache *au_cachep[AuCache_Last];
  16913. +static int __init au_cache_init(void)
  16914. +{
  16915. + au_cachep[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
  16916. + if (au_cachep[AuCache_DINFO])
  16917. + au_cachep[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
  16918. + au_icntnr_init_once);
  16919. + if (au_cachep[AuCache_ICNTNR])
  16920. + au_cachep[AuCache_FINFO] = AuCacheCtor(au_finfo,
  16921. + au_fi_init_once);
  16922. + if (au_cachep[AuCache_FINFO])
  16923. + au_cachep[AuCache_VDIR] = AuCache(au_vdir);
  16924. + if (au_cachep[AuCache_VDIR])
  16925. + au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
  16926. + if (au_cachep[AuCache_DEHSTR])
  16927. + return 0;
  16928. +
  16929. + return -ENOMEM;
  16930. +}
  16931. +
  16932. +static void au_cache_fin(void)
  16933. +{
  16934. + int i;
  16935. +
  16936. + /* including AuCache_HNOTIFY */
  16937. + for (i = 0; i < AuCache_Last; i++)
  16938. + if (au_cachep[i]) {
  16939. + kmem_cache_destroy(au_cachep[i]);
  16940. + au_cachep[i] = NULL;
  16941. + }
  16942. +}
  16943. +
  16944. +/* ---------------------------------------------------------------------- */
  16945. +
  16946. +int au_dir_roflags;
  16947. +
  16948. +#ifdef CONFIG_AUFS_SBILIST
  16949. +struct au_splhead au_sbilist;
  16950. +#endif
  16951. +
  16952. +/*
  16953. + * functions for module interface.
  16954. + */
  16955. +MODULE_LICENSE("GPL");
  16956. +/* MODULE_LICENSE("GPL v2"); */
  16957. +MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
  16958. +MODULE_DESCRIPTION(AUFS_NAME
  16959. + " -- Advanced multi layered unification filesystem");
  16960. +MODULE_VERSION(AUFS_VERSION);
  16961. +
  16962. +/* this module parameter has no meaning when SYSFS is disabled */
  16963. +int sysaufs_brs = 1;
  16964. +MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
  16965. +module_param_named(brs, sysaufs_brs, int, S_IRUGO);
  16966. +
  16967. +/* ---------------------------------------------------------------------- */
  16968. +
  16969. +static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
  16970. +
  16971. +int au_seq_path(struct seq_file *seq, struct path *path)
  16972. +{
  16973. + return seq_path(seq, path, au_esc_chars);
  16974. +}
  16975. +
  16976. +/* ---------------------------------------------------------------------- */
  16977. +
  16978. +static int __init aufs_init(void)
  16979. +{
  16980. + int err, i;
  16981. + char *p;
  16982. +
  16983. + p = au_esc_chars;
  16984. + for (i = 1; i <= ' '; i++)
  16985. + *p++ = i;
  16986. + *p++ = '\\';
  16987. + *p++ = '\x7f';
  16988. + *p = 0;
  16989. +
  16990. + au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
  16991. +
  16992. + au_sbilist_init();
  16993. + sysaufs_brs_init();
  16994. + au_debug_init();
  16995. + au_dy_init();
  16996. + err = sysaufs_init();
  16997. + if (unlikely(err))
  16998. + goto out;
  16999. + err = au_procfs_init();
  17000. + if (unlikely(err))
  17001. + goto out_sysaufs;
  17002. + err = au_wkq_init();
  17003. + if (unlikely(err))
  17004. + goto out_procfs;
  17005. + err = au_hnotify_init();
  17006. + if (unlikely(err))
  17007. + goto out_wkq;
  17008. + err = au_sysrq_init();
  17009. + if (unlikely(err))
  17010. + goto out_hin;
  17011. + err = au_cache_init();
  17012. + if (unlikely(err))
  17013. + goto out_sysrq;
  17014. + err = register_filesystem(&aufs_fs_type);
  17015. + if (unlikely(err))
  17016. + goto out_cache;
  17017. + /* since we define pr_fmt, call printk directly */
  17018. + printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
  17019. + goto out; /* success */
  17020. +
  17021. +out_cache:
  17022. + au_cache_fin();
  17023. +out_sysrq:
  17024. + au_sysrq_fin();
  17025. +out_hin:
  17026. + au_hnotify_fin();
  17027. +out_wkq:
  17028. + au_wkq_fin();
  17029. +out_procfs:
  17030. + au_procfs_fin();
  17031. +out_sysaufs:
  17032. + sysaufs_fin();
  17033. + au_dy_fin();
  17034. +out:
  17035. + return err;
  17036. +}
  17037. +
  17038. +static void __exit aufs_exit(void)
  17039. +{
  17040. + unregister_filesystem(&aufs_fs_type);
  17041. + au_cache_fin();
  17042. + au_sysrq_fin();
  17043. + au_hnotify_fin();
  17044. + au_wkq_fin();
  17045. + au_procfs_fin();
  17046. + sysaufs_fin();
  17047. + au_dy_fin();
  17048. +}
  17049. +
  17050. +module_init(aufs_init);
  17051. +module_exit(aufs_exit);
  17052. diff -Nur linux-2.6.37.orig/fs/aufs/module.h linux-2.6.37/fs/aufs/module.h
  17053. --- linux-2.6.37.orig/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100
  17054. +++ linux-2.6.37/fs/aufs/module.h 2011-01-11 20:15:11.000000000 +0100
  17055. @@ -0,0 +1,91 @@
  17056. +/*
  17057. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  17058. + *
  17059. + * This program, aufs is free software; you can redistribute it and/or modify
  17060. + * it under the terms of the GNU General Public License as published by
  17061. + * the Free Software Foundation; either version 2 of the License, or
  17062. + * (at your option) any later version.
  17063. + *
  17064. + * This program is distributed in the hope that it will be useful,
  17065. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17066. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17067. + * GNU General Public License for more details.
  17068. + *
  17069. + * You should have received a copy of the GNU General Public License
  17070. + * along with this program; if not, write to the Free Software
  17071. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17072. + */
  17073. +
  17074. +/*
  17075. + * module initialization and module-global
  17076. + */
  17077. +
  17078. +#ifndef __AUFS_MODULE_H__
  17079. +#define __AUFS_MODULE_H__
  17080. +
  17081. +#ifdef __KERNEL__
  17082. +
  17083. +#include <linux/slab.h>
  17084. +
  17085. +struct path;
  17086. +struct seq_file;
  17087. +
  17088. +/* module parameters */
  17089. +extern int sysaufs_brs;
  17090. +
  17091. +/* ---------------------------------------------------------------------- */
  17092. +
  17093. +extern int au_dir_roflags;
  17094. +
  17095. +void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp);
  17096. +int au_seq_path(struct seq_file *seq, struct path *path);
  17097. +
  17098. +#ifdef CONFIG_PROC_FS
  17099. +/* procfs.c */
  17100. +int __init au_procfs_init(void);
  17101. +void au_procfs_fin(void);
  17102. +#else
  17103. +AuStubInt0(au_procfs_init, void);
  17104. +AuStubVoid(au_procfs_fin, void);
  17105. +#endif
  17106. +
  17107. +/* ---------------------------------------------------------------------- */
  17108. +
  17109. +/* kmem cache */
  17110. +enum {
  17111. + AuCache_DINFO,
  17112. + AuCache_ICNTNR,
  17113. + AuCache_FINFO,
  17114. + AuCache_VDIR,
  17115. + AuCache_DEHSTR,
  17116. +#ifdef CONFIG_AUFS_HNOTIFY
  17117. + AuCache_HNOTIFY,
  17118. +#endif
  17119. + AuCache_Last
  17120. +};
  17121. +
  17122. +#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
  17123. +#define AuCache(type) KMEM_CACHE(type, AuCacheFlags)
  17124. +#define AuCacheCtor(type, ctor) \
  17125. + kmem_cache_create(#type, sizeof(struct type), \
  17126. + __alignof__(struct type), AuCacheFlags, ctor)
  17127. +
  17128. +extern struct kmem_cache *au_cachep[];
  17129. +
  17130. +#define AuCacheFuncs(name, index) \
  17131. +static inline struct au_##name *au_cache_alloc_##name(void) \
  17132. +{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \
  17133. +static inline void au_cache_free_##name(struct au_##name *p) \
  17134. +{ kmem_cache_free(au_cachep[AuCache_##index], p); }
  17135. +
  17136. +AuCacheFuncs(dinfo, DINFO);
  17137. +AuCacheFuncs(icntnr, ICNTNR);
  17138. +AuCacheFuncs(finfo, FINFO);
  17139. +AuCacheFuncs(vdir, VDIR);
  17140. +AuCacheFuncs(vdir_dehstr, DEHSTR);
  17141. +#ifdef CONFIG_AUFS_HNOTIFY
  17142. +AuCacheFuncs(hnotify, HNOTIFY);
  17143. +#endif
  17144. +
  17145. +#endif /* __KERNEL__ */
  17146. +#endif /* __AUFS_MODULE_H__ */
  17147. diff -Nur linux-2.6.37.orig/fs/aufs/mtx.h linux-2.6.37/fs/aufs/mtx.h
  17148. --- linux-2.6.37.orig/fs/aufs/mtx.h 1970-01-01 01:00:00.000000000 +0100
  17149. +++ linux-2.6.37/fs/aufs/mtx.h 2011-01-11 20:15:11.000000000 +0100
  17150. @@ -0,0 +1,48 @@
  17151. +/*
  17152. + * Copyright (C) 2010-2011 Junjiro R. Okajima
  17153. + *
  17154. + * This program, aufs is free software; you can redistribute it and/or modify
  17155. + * it under the terms of the GNU General Public License as published by
  17156. + * the Free Software Foundation; either version 2 of the License, or
  17157. + * (at your option) any later version.
  17158. + *
  17159. + * This program is distributed in the hope that it will be useful,
  17160. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17161. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17162. + * GNU General Public License for more details.
  17163. + *
  17164. + * You should have received a copy of the GNU General Public License
  17165. + * along with this program; if not, write to the Free Software
  17166. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17167. + */
  17168. +
  17169. +/*
  17170. + * very ugly approach for aufs_mmap()
  17171. + * never include this file from other than f_op.c.
  17172. + * see f_op.c in detail.
  17173. + */
  17174. +
  17175. +#ifndef __AUFS_MTX_H__
  17176. +#define __AUFS_MTX_H__
  17177. +
  17178. +#ifdef __KERNEL__
  17179. +
  17180. +/* copied from ../kernel/mutex{,-debug}.h */
  17181. +struct mutex;
  17182. +struct thread_info;
  17183. +#ifdef CONFIG_DEBUG_MUTEXES
  17184. +static inline void mutex_set_owner(struct mutex *lock)
  17185. +{
  17186. + lock->owner = current_thread_info();
  17187. +}
  17188. +#else
  17189. +static inline void mutex_set_owner(struct mutex *lock)
  17190. +{
  17191. +#ifdef CONFIG_SMP
  17192. + lock->owner = current_thread_info();
  17193. +#endif
  17194. +}
  17195. +#endif
  17196. +
  17197. +#endif /* __KERNEL__ */
  17198. +#endif /* __AUFS_MTX_H__ */
  17199. diff -Nur linux-2.6.37.orig/fs/aufs/opts.c linux-2.6.37/fs/aufs/opts.c
  17200. --- linux-2.6.37.orig/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100
  17201. +++ linux-2.6.37/fs/aufs/opts.c 2011-01-11 20:15:11.000000000 +0100
  17202. @@ -0,0 +1,1595 @@
  17203. +/*
  17204. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  17205. + *
  17206. + * This program, aufs is free software; you can redistribute it and/or modify
  17207. + * it under the terms of the GNU General Public License as published by
  17208. + * the Free Software Foundation; either version 2 of the License, or
  17209. + * (at your option) any later version.
  17210. + *
  17211. + * This program is distributed in the hope that it will be useful,
  17212. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17213. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17214. + * GNU General Public License for more details.
  17215. + *
  17216. + * You should have received a copy of the GNU General Public License
  17217. + * along with this program; if not, write to the Free Software
  17218. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17219. + */
  17220. +
  17221. +/*
  17222. + * mount options/flags
  17223. + */
  17224. +
  17225. +#include <linux/file.h>
  17226. +#include <linux/jiffies.h>
  17227. +#include <linux/namei.h>
  17228. +#include <linux/types.h> /* a distribution requires */
  17229. +#include <linux/parser.h>
  17230. +#include "aufs.h"
  17231. +
  17232. +/* ---------------------------------------------------------------------- */
  17233. +
  17234. +enum {
  17235. + Opt_br,
  17236. + Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend,
  17237. + Opt_idel, Opt_imod, Opt_ireorder,
  17238. + Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, Opt_rendir,
  17239. + Opt_rdblk_def, Opt_rdhash_def,
  17240. + Opt_xino, Opt_zxino, Opt_noxino,
  17241. + Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
  17242. + Opt_trunc_xino_path, Opt_itrunc_xino,
  17243. + Opt_trunc_xib, Opt_notrunc_xib,
  17244. + Opt_shwh, Opt_noshwh,
  17245. + Opt_plink, Opt_noplink, Opt_list_plink,
  17246. + Opt_udba,
  17247. + Opt_dio, Opt_nodio,
  17248. + /* Opt_lock, Opt_unlock, */
  17249. + Opt_cmd, Opt_cmd_args,
  17250. + Opt_diropq_a, Opt_diropq_w,
  17251. + Opt_warn_perm, Opt_nowarn_perm,
  17252. + Opt_wbr_copyup, Opt_wbr_create,
  17253. + Opt_refrof, Opt_norefrof,
  17254. + Opt_verbose, Opt_noverbose,
  17255. + Opt_sum, Opt_nosum, Opt_wsum,
  17256. + Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
  17257. +};
  17258. +
  17259. +static match_table_t options = {
  17260. + {Opt_br, "br=%s"},
  17261. + {Opt_br, "br:%s"},
  17262. +
  17263. + {Opt_add, "add=%d:%s"},
  17264. + {Opt_add, "add:%d:%s"},
  17265. + {Opt_add, "ins=%d:%s"},
  17266. + {Opt_add, "ins:%d:%s"},
  17267. + {Opt_append, "append=%s"},
  17268. + {Opt_append, "append:%s"},
  17269. + {Opt_prepend, "prepend=%s"},
  17270. + {Opt_prepend, "prepend:%s"},
  17271. +
  17272. + {Opt_del, "del=%s"},
  17273. + {Opt_del, "del:%s"},
  17274. + /* {Opt_idel, "idel:%d"}, */
  17275. + {Opt_mod, "mod=%s"},
  17276. + {Opt_mod, "mod:%s"},
  17277. + /* {Opt_imod, "imod:%d:%s"}, */
  17278. +
  17279. + {Opt_dirwh, "dirwh=%d"},
  17280. +
  17281. + {Opt_xino, "xino=%s"},
  17282. + {Opt_noxino, "noxino"},
  17283. + {Opt_trunc_xino, "trunc_xino"},
  17284. + {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
  17285. + {Opt_notrunc_xino, "notrunc_xino"},
  17286. + {Opt_trunc_xino_path, "trunc_xino=%s"},
  17287. + {Opt_itrunc_xino, "itrunc_xino=%d"},
  17288. + /* {Opt_zxino, "zxino=%s"}, */
  17289. + {Opt_trunc_xib, "trunc_xib"},
  17290. + {Opt_notrunc_xib, "notrunc_xib"},
  17291. +
  17292. +#ifdef CONFIG_PROC_FS
  17293. + {Opt_plink, "plink"},
  17294. +#else
  17295. + {Opt_ignore_silent, "plink"},
  17296. +#endif
  17297. +
  17298. + {Opt_noplink, "noplink"},
  17299. +
  17300. +#ifdef CONFIG_AUFS_DEBUG
  17301. + {Opt_list_plink, "list_plink"},
  17302. +#endif
  17303. +
  17304. + {Opt_udba, "udba=%s"},
  17305. +
  17306. + {Opt_dio, "dio"},
  17307. + {Opt_nodio, "nodio"},
  17308. +
  17309. + {Opt_diropq_a, "diropq=always"},
  17310. + {Opt_diropq_a, "diropq=a"},
  17311. + {Opt_diropq_w, "diropq=whiteouted"},
  17312. + {Opt_diropq_w, "diropq=w"},
  17313. +
  17314. + {Opt_warn_perm, "warn_perm"},
  17315. + {Opt_nowarn_perm, "nowarn_perm"},
  17316. +
  17317. + /* keep them temporary */
  17318. + {Opt_ignore_silent, "coo=%s"},
  17319. + {Opt_ignore_silent, "nodlgt"},
  17320. + {Opt_ignore_silent, "nodirperm1"},
  17321. + {Opt_ignore_silent, "clean_plink"},
  17322. +
  17323. +#ifdef CONFIG_AUFS_SHWH
  17324. + {Opt_shwh, "shwh"},
  17325. +#endif
  17326. + {Opt_noshwh, "noshwh"},
  17327. +
  17328. + {Opt_rendir, "rendir=%d"},
  17329. +
  17330. + {Opt_refrof, "refrof"},
  17331. + {Opt_norefrof, "norefrof"},
  17332. +
  17333. + {Opt_verbose, "verbose"},
  17334. + {Opt_verbose, "v"},
  17335. + {Opt_noverbose, "noverbose"},
  17336. + {Opt_noverbose, "quiet"},
  17337. + {Opt_noverbose, "q"},
  17338. + {Opt_noverbose, "silent"},
  17339. +
  17340. + {Opt_sum, "sum"},
  17341. + {Opt_nosum, "nosum"},
  17342. + {Opt_wsum, "wsum"},
  17343. +
  17344. + {Opt_rdcache, "rdcache=%d"},
  17345. + {Opt_rdblk, "rdblk=%d"},
  17346. + {Opt_rdblk_def, "rdblk=def"},
  17347. + {Opt_rdhash, "rdhash=%d"},
  17348. + {Opt_rdhash_def, "rdhash=def"},
  17349. +
  17350. + {Opt_wbr_create, "create=%s"},
  17351. + {Opt_wbr_create, "create_policy=%s"},
  17352. + {Opt_wbr_copyup, "cpup=%s"},
  17353. + {Opt_wbr_copyup, "copyup=%s"},
  17354. + {Opt_wbr_copyup, "copyup_policy=%s"},
  17355. +
  17356. + /* internal use for the scripts */
  17357. + {Opt_ignore_silent, "si=%s"},
  17358. +
  17359. + {Opt_br, "dirs=%s"},
  17360. + {Opt_ignore, "debug=%d"},
  17361. + {Opt_ignore, "delete=whiteout"},
  17362. + {Opt_ignore, "delete=all"},
  17363. + {Opt_ignore, "imap=%s"},
  17364. +
  17365. + /* temporary workaround, due to old mount(8)? */
  17366. + {Opt_ignore_silent, "relatime"},
  17367. +
  17368. + {Opt_err, NULL}
  17369. +};
  17370. +
  17371. +/* ---------------------------------------------------------------------- */
  17372. +
  17373. +static const char *au_parser_pattern(int val, struct match_token *token)
  17374. +{
  17375. + while (token->pattern) {
  17376. + if (token->token == val)
  17377. + return token->pattern;
  17378. + token++;
  17379. + }
  17380. + BUG();
  17381. + return "??";
  17382. +}
  17383. +
  17384. +/* ---------------------------------------------------------------------- */
  17385. +
  17386. +static match_table_t brperms = {
  17387. + {AuBrPerm_RO, AUFS_BRPERM_RO},
  17388. + {AuBrPerm_RR, AUFS_BRPERM_RR},
  17389. + {AuBrPerm_RW, AUFS_BRPERM_RW},
  17390. +
  17391. + {AuBrPerm_ROWH, AUFS_BRPERM_ROWH},
  17392. + {AuBrPerm_RRWH, AUFS_BRPERM_RRWH},
  17393. + {AuBrPerm_RWNoLinkWH, AUFS_BRPERM_RWNLWH},
  17394. +
  17395. + {AuBrPerm_ROWH, "nfsro"},
  17396. + {AuBrPerm_RO, NULL}
  17397. +};
  17398. +
  17399. +static int noinline_for_stack br_perm_val(char *perm)
  17400. +{
  17401. + int val;
  17402. + substring_t args[MAX_OPT_ARGS];
  17403. +
  17404. + val = match_token(perm, brperms, args);
  17405. + return val;
  17406. +}
  17407. +
  17408. +const char *au_optstr_br_perm(int brperm)
  17409. +{
  17410. + return au_parser_pattern(brperm, (void *)brperms);
  17411. +}
  17412. +
  17413. +/* ---------------------------------------------------------------------- */
  17414. +
  17415. +static match_table_t udbalevel = {
  17416. + {AuOpt_UDBA_REVAL, "reval"},
  17417. + {AuOpt_UDBA_NONE, "none"},
  17418. +#ifdef CONFIG_AUFS_HNOTIFY
  17419. + {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
  17420. +#ifdef CONFIG_AUFS_HFSNOTIFY
  17421. + {AuOpt_UDBA_HNOTIFY, "fsnotify"},
  17422. +#endif
  17423. +#endif
  17424. + {-1, NULL}
  17425. +};
  17426. +
  17427. +static int noinline_for_stack udba_val(char *str)
  17428. +{
  17429. + substring_t args[MAX_OPT_ARGS];
  17430. +
  17431. + return match_token(str, udbalevel, args);
  17432. +}
  17433. +
  17434. +const char *au_optstr_udba(int udba)
  17435. +{
  17436. + return au_parser_pattern(udba, (void *)udbalevel);
  17437. +}
  17438. +
  17439. +/* ---------------------------------------------------------------------- */
  17440. +
  17441. +static match_table_t au_wbr_create_policy = {
  17442. + {AuWbrCreate_TDP, "tdp"},
  17443. + {AuWbrCreate_TDP, "top-down-parent"},
  17444. + {AuWbrCreate_RR, "rr"},
  17445. + {AuWbrCreate_RR, "round-robin"},
  17446. + {AuWbrCreate_MFS, "mfs"},
  17447. + {AuWbrCreate_MFS, "most-free-space"},
  17448. + {AuWbrCreate_MFSV, "mfs:%d"},
  17449. + {AuWbrCreate_MFSV, "most-free-space:%d"},
  17450. +
  17451. + {AuWbrCreate_MFSRR, "mfsrr:%d"},
  17452. + {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
  17453. + {AuWbrCreate_PMFS, "pmfs"},
  17454. + {AuWbrCreate_PMFSV, "pmfs:%d"},
  17455. +
  17456. + {-1, NULL}
  17457. +};
  17458. +
  17459. +/*
  17460. + * cf. linux/lib/parser.c and cmdline.c
  17461. + * gave up calling memparse() since it uses simple_strtoull() instead of
  17462. + * strict_...().
  17463. + */
  17464. +static int noinline_for_stack
  17465. +au_match_ull(substring_t *s, unsigned long long *result)
  17466. +{
  17467. + int err;
  17468. + unsigned int len;
  17469. + char a[32];
  17470. +
  17471. + err = -ERANGE;
  17472. + len = s->to - s->from;
  17473. + if (len + 1 <= sizeof(a)) {
  17474. + memcpy(a, s->from, len);
  17475. + a[len] = '\0';
  17476. + err = strict_strtoull(a, 0, result);
  17477. + }
  17478. + return err;
  17479. +}
  17480. +
  17481. +static int au_wbr_mfs_wmark(substring_t *arg, char *str,
  17482. + struct au_opt_wbr_create *create)
  17483. +{
  17484. + int err;
  17485. + unsigned long long ull;
  17486. +
  17487. + err = 0;
  17488. + if (!au_match_ull(arg, &ull))
  17489. + create->mfsrr_watermark = ull;
  17490. + else {
  17491. + pr_err("bad integer in %s\n", str);
  17492. + err = -EINVAL;
  17493. + }
  17494. +
  17495. + return err;
  17496. +}
  17497. +
  17498. +static int au_wbr_mfs_sec(substring_t *arg, char *str,
  17499. + struct au_opt_wbr_create *create)
  17500. +{
  17501. + int n, err;
  17502. +
  17503. + err = 0;
  17504. + if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
  17505. + create->mfs_second = n;
  17506. + else {
  17507. + pr_err("bad integer in %s\n", str);
  17508. + err = -EINVAL;
  17509. + }
  17510. +
  17511. + return err;
  17512. +}
  17513. +
  17514. +static int noinline_for_stack
  17515. +au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
  17516. +{
  17517. + int err, e;
  17518. + substring_t args[MAX_OPT_ARGS];
  17519. +
  17520. + err = match_token(str, au_wbr_create_policy, args);
  17521. + create->wbr_create = err;
  17522. + switch (err) {
  17523. + case AuWbrCreate_MFSRRV:
  17524. + e = au_wbr_mfs_wmark(&args[0], str, create);
  17525. + if (!e)
  17526. + e = au_wbr_mfs_sec(&args[1], str, create);
  17527. + if (unlikely(e))
  17528. + err = e;
  17529. + break;
  17530. + case AuWbrCreate_MFSRR:
  17531. + e = au_wbr_mfs_wmark(&args[0], str, create);
  17532. + if (unlikely(e)) {
  17533. + err = e;
  17534. + break;
  17535. + }
  17536. + /*FALLTHROUGH*/
  17537. + case AuWbrCreate_MFS:
  17538. + case AuWbrCreate_PMFS:
  17539. + create->mfs_second = AUFS_MFS_DEF_SEC;
  17540. + break;
  17541. + case AuWbrCreate_MFSV:
  17542. + case AuWbrCreate_PMFSV:
  17543. + e = au_wbr_mfs_sec(&args[0], str, create);
  17544. + if (unlikely(e))
  17545. + err = e;
  17546. + break;
  17547. + }
  17548. +
  17549. + return err;
  17550. +}
  17551. +
  17552. +const char *au_optstr_wbr_create(int wbr_create)
  17553. +{
  17554. + return au_parser_pattern(wbr_create, (void *)au_wbr_create_policy);
  17555. +}
  17556. +
  17557. +static match_table_t au_wbr_copyup_policy = {
  17558. + {AuWbrCopyup_TDP, "tdp"},
  17559. + {AuWbrCopyup_TDP, "top-down-parent"},
  17560. + {AuWbrCopyup_BUP, "bup"},
  17561. + {AuWbrCopyup_BUP, "bottom-up-parent"},
  17562. + {AuWbrCopyup_BU, "bu"},
  17563. + {AuWbrCopyup_BU, "bottom-up"},
  17564. + {-1, NULL}
  17565. +};
  17566. +
  17567. +static int noinline_for_stack au_wbr_copyup_val(char *str)
  17568. +{
  17569. + substring_t args[MAX_OPT_ARGS];
  17570. +
  17571. + return match_token(str, au_wbr_copyup_policy, args);
  17572. +}
  17573. +
  17574. +const char *au_optstr_wbr_copyup(int wbr_copyup)
  17575. +{
  17576. + return au_parser_pattern(wbr_copyup, (void *)au_wbr_copyup_policy);
  17577. +}
  17578. +
  17579. +/* ---------------------------------------------------------------------- */
  17580. +
  17581. +static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
  17582. +
  17583. +static void dump_opts(struct au_opts *opts)
  17584. +{
  17585. +#ifdef CONFIG_AUFS_DEBUG
  17586. + /* reduce stack space */
  17587. + union {
  17588. + struct au_opt_add *add;
  17589. + struct au_opt_del *del;
  17590. + struct au_opt_mod *mod;
  17591. + struct au_opt_xino *xino;
  17592. + struct au_opt_xino_itrunc *xino_itrunc;
  17593. + struct au_opt_wbr_create *create;
  17594. + } u;
  17595. + struct au_opt *opt;
  17596. +
  17597. + opt = opts->opt;
  17598. + while (opt->type != Opt_tail) {
  17599. + switch (opt->type) {
  17600. + case Opt_add:
  17601. + u.add = &opt->add;
  17602. + AuDbg("add {b%d, %s, 0x%x, %p}\n",
  17603. + u.add->bindex, u.add->pathname, u.add->perm,
  17604. + u.add->path.dentry);
  17605. + break;
  17606. + case Opt_del:
  17607. + case Opt_idel:
  17608. + u.del = &opt->del;
  17609. + AuDbg("del {%s, %p}\n",
  17610. + u.del->pathname, u.del->h_path.dentry);
  17611. + break;
  17612. + case Opt_mod:
  17613. + case Opt_imod:
  17614. + u.mod = &opt->mod;
  17615. + AuDbg("mod {%s, 0x%x, %p}\n",
  17616. + u.mod->path, u.mod->perm, u.mod->h_root);
  17617. + break;
  17618. + case Opt_append:
  17619. + u.add = &opt->add;
  17620. + AuDbg("append {b%d, %s, 0x%x, %p}\n",
  17621. + u.add->bindex, u.add->pathname, u.add->perm,
  17622. + u.add->path.dentry);
  17623. + break;
  17624. + case Opt_prepend:
  17625. + u.add = &opt->add;
  17626. + AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
  17627. + u.add->bindex, u.add->pathname, u.add->perm,
  17628. + u.add->path.dentry);
  17629. + break;
  17630. + case Opt_dirwh:
  17631. + AuDbg("dirwh %d\n", opt->dirwh);
  17632. + break;
  17633. + case Opt_rdcache:
  17634. + AuDbg("rdcache %d\n", opt->rdcache);
  17635. + break;
  17636. + case Opt_rdblk:
  17637. + AuDbg("rdblk %u\n", opt->rdblk);
  17638. + break;
  17639. + case Opt_rdblk_def:
  17640. + AuDbg("rdblk_def\n");
  17641. + break;
  17642. + case Opt_rdhash:
  17643. + AuDbg("rdhash %u\n", opt->rdhash);
  17644. + break;
  17645. + case Opt_rdhash_def:
  17646. + AuDbg("rdhash_def\n");
  17647. + break;
  17648. + case Opt_xino:
  17649. + u.xino = &opt->xino;
  17650. + AuDbg("xino {%s %.*s}\n",
  17651. + u.xino->path,
  17652. + AuDLNPair(u.xino->file->f_dentry));
  17653. + break;
  17654. + case Opt_trunc_xino:
  17655. + AuLabel(trunc_xino);
  17656. + break;
  17657. + case Opt_notrunc_xino:
  17658. + AuLabel(notrunc_xino);
  17659. + break;
  17660. + case Opt_trunc_xino_path:
  17661. + case Opt_itrunc_xino:
  17662. + u.xino_itrunc = &opt->xino_itrunc;
  17663. + AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
  17664. + break;
  17665. +
  17666. + case Opt_noxino:
  17667. + AuLabel(noxino);
  17668. + break;
  17669. + case Opt_trunc_xib:
  17670. + AuLabel(trunc_xib);
  17671. + break;
  17672. + case Opt_notrunc_xib:
  17673. + AuLabel(notrunc_xib);
  17674. + break;
  17675. + case Opt_shwh:
  17676. + AuLabel(shwh);
  17677. + break;
  17678. + case Opt_noshwh:
  17679. + AuLabel(noshwh);
  17680. + break;
  17681. + case Opt_plink:
  17682. + AuLabel(plink);
  17683. + break;
  17684. + case Opt_noplink:
  17685. + AuLabel(noplink);
  17686. + break;
  17687. + case Opt_list_plink:
  17688. + AuLabel(list_plink);
  17689. + break;
  17690. + case Opt_udba:
  17691. + AuDbg("udba %d, %s\n",
  17692. + opt->udba, au_optstr_udba(opt->udba));
  17693. + break;
  17694. + case Opt_dio:
  17695. + AuLabel(dio);
  17696. + break;
  17697. + case Opt_nodio:
  17698. + AuLabel(nodio);
  17699. + break;
  17700. + case Opt_diropq_a:
  17701. + AuLabel(diropq_a);
  17702. + break;
  17703. + case Opt_diropq_w:
  17704. + AuLabel(diropq_w);
  17705. + break;
  17706. + case Opt_warn_perm:
  17707. + AuLabel(warn_perm);
  17708. + break;
  17709. + case Opt_nowarn_perm:
  17710. + AuLabel(nowarn_perm);
  17711. + break;
  17712. + case Opt_refrof:
  17713. + AuLabel(refrof);
  17714. + break;
  17715. + case Opt_norefrof:
  17716. + AuLabel(norefrof);
  17717. + break;
  17718. + case Opt_verbose:
  17719. + AuLabel(verbose);
  17720. + break;
  17721. + case Opt_noverbose:
  17722. + AuLabel(noverbose);
  17723. + break;
  17724. + case Opt_sum:
  17725. + AuLabel(sum);
  17726. + break;
  17727. + case Opt_nosum:
  17728. + AuLabel(nosum);
  17729. + break;
  17730. + case Opt_wsum:
  17731. + AuLabel(wsum);
  17732. + break;
  17733. + case Opt_wbr_create:
  17734. + u.create = &opt->wbr_create;
  17735. + AuDbg("create %d, %s\n", u.create->wbr_create,
  17736. + au_optstr_wbr_create(u.create->wbr_create));
  17737. + switch (u.create->wbr_create) {
  17738. + case AuWbrCreate_MFSV:
  17739. + case AuWbrCreate_PMFSV:
  17740. + AuDbg("%d sec\n", u.create->mfs_second);
  17741. + break;
  17742. + case AuWbrCreate_MFSRR:
  17743. + AuDbg("%llu watermark\n",
  17744. + u.create->mfsrr_watermark);
  17745. + break;
  17746. + case AuWbrCreate_MFSRRV:
  17747. + AuDbg("%llu watermark, %d sec\n",
  17748. + u.create->mfsrr_watermark,
  17749. + u.create->mfs_second);
  17750. + break;
  17751. + }
  17752. + break;
  17753. + case Opt_wbr_copyup:
  17754. + AuDbg("copyup %d, %s\n", opt->wbr_copyup,
  17755. + au_optstr_wbr_copyup(opt->wbr_copyup));
  17756. + break;
  17757. + default:
  17758. + BUG();
  17759. + }
  17760. + opt++;
  17761. + }
  17762. +#endif
  17763. +}
  17764. +
  17765. +void au_opts_free(struct au_opts *opts)
  17766. +{
  17767. + struct au_opt *opt;
  17768. +
  17769. + opt = opts->opt;
  17770. + while (opt->type != Opt_tail) {
  17771. + switch (opt->type) {
  17772. + case Opt_add:
  17773. + case Opt_append:
  17774. + case Opt_prepend:
  17775. + path_put(&opt->add.path);
  17776. + break;
  17777. + case Opt_del:
  17778. + case Opt_idel:
  17779. + path_put(&opt->del.h_path);
  17780. + break;
  17781. + case Opt_mod:
  17782. + case Opt_imod:
  17783. + dput(opt->mod.h_root);
  17784. + break;
  17785. + case Opt_xino:
  17786. + fput(opt->xino.file);
  17787. + break;
  17788. + }
  17789. + opt++;
  17790. + }
  17791. +}
  17792. +
  17793. +static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
  17794. + aufs_bindex_t bindex)
  17795. +{
  17796. + int err;
  17797. + struct au_opt_add *add = &opt->add;
  17798. + char *p;
  17799. +
  17800. + add->bindex = bindex;
  17801. + add->perm = AuBrPerm_Last;
  17802. + add->pathname = opt_str;
  17803. + p = strchr(opt_str, '=');
  17804. + if (p) {
  17805. + *p++ = 0;
  17806. + if (*p)
  17807. + add->perm = br_perm_val(p);
  17808. + }
  17809. +
  17810. + err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
  17811. + if (!err) {
  17812. + if (!p) {
  17813. + add->perm = AuBrPerm_RO;
  17814. + if (au_test_fs_rr(add->path.dentry->d_sb))
  17815. + add->perm = AuBrPerm_RR;
  17816. + else if (!bindex && !(sb_flags & MS_RDONLY))
  17817. + add->perm = AuBrPerm_RW;
  17818. + }
  17819. + opt->type = Opt_add;
  17820. + goto out;
  17821. + }
  17822. + pr_err("lookup failed %s (%d)\n", add->pathname, err);
  17823. + err = -EINVAL;
  17824. +
  17825. +out:
  17826. + return err;
  17827. +}
  17828. +
  17829. +static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
  17830. +{
  17831. + int err;
  17832. +
  17833. + del->pathname = args[0].from;
  17834. + AuDbg("del path %s\n", del->pathname);
  17835. +
  17836. + err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
  17837. + if (unlikely(err))
  17838. + pr_err("lookup failed %s (%d)\n", del->pathname, err);
  17839. +
  17840. + return err;
  17841. +}
  17842. +
  17843. +#if 0 /* reserved for future use */
  17844. +static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
  17845. + struct au_opt_del *del, substring_t args[])
  17846. +{
  17847. + int err;
  17848. + struct dentry *root;
  17849. +
  17850. + err = -EINVAL;
  17851. + root = sb->s_root;
  17852. + aufs_read_lock(root, AuLock_FLUSH);
  17853. + if (bindex < 0 || au_sbend(sb) < bindex) {
  17854. + pr_err("out of bounds, %d\n", bindex);
  17855. + goto out;
  17856. + }
  17857. +
  17858. + err = 0;
  17859. + del->h_path.dentry = dget(au_h_dptr(root, bindex));
  17860. + del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
  17861. +
  17862. +out:
  17863. + aufs_read_unlock(root, !AuLock_IR);
  17864. + return err;
  17865. +}
  17866. +#endif
  17867. +
  17868. +static int noinline_for_stack
  17869. +au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
  17870. +{
  17871. + int err;
  17872. + struct path path;
  17873. + char *p;
  17874. +
  17875. + err = -EINVAL;
  17876. + mod->path = args[0].from;
  17877. + p = strchr(mod->path, '=');
  17878. + if (unlikely(!p)) {
  17879. + pr_err("no permssion %s\n", args[0].from);
  17880. + goto out;
  17881. + }
  17882. +
  17883. + *p++ = 0;
  17884. + err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
  17885. + if (unlikely(err)) {
  17886. + pr_err("lookup failed %s (%d)\n", mod->path, err);
  17887. + goto out;
  17888. + }
  17889. +
  17890. + mod->perm = br_perm_val(p);
  17891. + AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
  17892. + mod->h_root = dget(path.dentry);
  17893. + path_put(&path);
  17894. +
  17895. +out:
  17896. + return err;
  17897. +}
  17898. +
  17899. +#if 0 /* reserved for future use */
  17900. +static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
  17901. + struct au_opt_mod *mod, substring_t args[])
  17902. +{
  17903. + int err;
  17904. + struct dentry *root;
  17905. +
  17906. + err = -EINVAL;
  17907. + root = sb->s_root;
  17908. + aufs_read_lock(root, AuLock_FLUSH);
  17909. + if (bindex < 0 || au_sbend(sb) < bindex) {
  17910. + pr_err("out of bounds, %d\n", bindex);
  17911. + goto out;
  17912. + }
  17913. +
  17914. + err = 0;
  17915. + mod->perm = br_perm_val(args[1].from);
  17916. + AuDbg("mod path %s, perm 0x%x, %s\n",
  17917. + mod->path, mod->perm, args[1].from);
  17918. + mod->h_root = dget(au_h_dptr(root, bindex));
  17919. +
  17920. +out:
  17921. + aufs_read_unlock(root, !AuLock_IR);
  17922. + return err;
  17923. +}
  17924. +#endif
  17925. +
  17926. +static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
  17927. + substring_t args[])
  17928. +{
  17929. + int err;
  17930. + struct file *file;
  17931. +
  17932. + file = au_xino_create(sb, args[0].from, /*silent*/0);
  17933. + err = PTR_ERR(file);
  17934. + if (IS_ERR(file))
  17935. + goto out;
  17936. +
  17937. + err = -EINVAL;
  17938. + if (unlikely(file->f_dentry->d_sb == sb)) {
  17939. + fput(file);
  17940. + pr_err("%s must be outside\n", args[0].from);
  17941. + goto out;
  17942. + }
  17943. +
  17944. + err = 0;
  17945. + xino->file = file;
  17946. + xino->path = args[0].from;
  17947. +
  17948. +out:
  17949. + return err;
  17950. +}
  17951. +
  17952. +static int noinline_for_stack
  17953. +au_opts_parse_xino_itrunc_path(struct super_block *sb,
  17954. + struct au_opt_xino_itrunc *xino_itrunc,
  17955. + substring_t args[])
  17956. +{
  17957. + int err;
  17958. + aufs_bindex_t bend, bindex;
  17959. + struct path path;
  17960. + struct dentry *root;
  17961. +
  17962. + err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
  17963. + if (unlikely(err)) {
  17964. + pr_err("lookup failed %s (%d)\n", args[0].from, err);
  17965. + goto out;
  17966. + }
  17967. +
  17968. + xino_itrunc->bindex = -1;
  17969. + root = sb->s_root;
  17970. + aufs_read_lock(root, AuLock_FLUSH);
  17971. + bend = au_sbend(sb);
  17972. + for (bindex = 0; bindex <= bend; bindex++) {
  17973. + if (au_h_dptr(root, bindex) == path.dentry) {
  17974. + xino_itrunc->bindex = bindex;
  17975. + break;
  17976. + }
  17977. + }
  17978. + aufs_read_unlock(root, !AuLock_IR);
  17979. + path_put(&path);
  17980. +
  17981. + if (unlikely(xino_itrunc->bindex < 0)) {
  17982. + pr_err("no such branch %s\n", args[0].from);
  17983. + err = -EINVAL;
  17984. + }
  17985. +
  17986. +out:
  17987. + return err;
  17988. +}
  17989. +
  17990. +/* called without aufs lock */
  17991. +int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
  17992. +{
  17993. + int err, n, token;
  17994. + aufs_bindex_t bindex;
  17995. + unsigned char skipped;
  17996. + struct dentry *root;
  17997. + struct au_opt *opt, *opt_tail;
  17998. + char *opt_str;
  17999. + /* reduce the stack space */
  18000. + union {
  18001. + struct au_opt_xino_itrunc *xino_itrunc;
  18002. + struct au_opt_wbr_create *create;
  18003. + } u;
  18004. + struct {
  18005. + substring_t args[MAX_OPT_ARGS];
  18006. + } *a;
  18007. +
  18008. + err = -ENOMEM;
  18009. + a = kmalloc(sizeof(*a), GFP_NOFS);
  18010. + if (unlikely(!a))
  18011. + goto out;
  18012. +
  18013. + root = sb->s_root;
  18014. + err = 0;
  18015. + bindex = 0;
  18016. + opt = opts->opt;
  18017. + opt_tail = opt + opts->max_opt - 1;
  18018. + opt->type = Opt_tail;
  18019. + while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
  18020. + err = -EINVAL;
  18021. + skipped = 0;
  18022. + token = match_token(opt_str, options, a->args);
  18023. + switch (token) {
  18024. + case Opt_br:
  18025. + err = 0;
  18026. + while (!err && (opt_str = strsep(&a->args[0].from, ":"))
  18027. + && *opt_str) {
  18028. + err = opt_add(opt, opt_str, opts->sb_flags,
  18029. + bindex++);
  18030. + if (unlikely(!err && ++opt > opt_tail)) {
  18031. + err = -E2BIG;
  18032. + break;
  18033. + }
  18034. + opt->type = Opt_tail;
  18035. + skipped = 1;
  18036. + }
  18037. + break;
  18038. + case Opt_add:
  18039. + if (unlikely(match_int(&a->args[0], &n))) {
  18040. + pr_err("bad integer in %s\n", opt_str);
  18041. + break;
  18042. + }
  18043. + bindex = n;
  18044. + err = opt_add(opt, a->args[1].from, opts->sb_flags,
  18045. + bindex);
  18046. + if (!err)
  18047. + opt->type = token;
  18048. + break;
  18049. + case Opt_append:
  18050. + err = opt_add(opt, a->args[0].from, opts->sb_flags,
  18051. + /*dummy bindex*/1);
  18052. + if (!err)
  18053. + opt->type = token;
  18054. + break;
  18055. + case Opt_prepend:
  18056. + err = opt_add(opt, a->args[0].from, opts->sb_flags,
  18057. + /*bindex*/0);
  18058. + if (!err)
  18059. + opt->type = token;
  18060. + break;
  18061. + case Opt_del:
  18062. + err = au_opts_parse_del(&opt->del, a->args);
  18063. + if (!err)
  18064. + opt->type = token;
  18065. + break;
  18066. +#if 0 /* reserved for future use */
  18067. + case Opt_idel:
  18068. + del->pathname = "(indexed)";
  18069. + if (unlikely(match_int(&args[0], &n))) {
  18070. + pr_err("bad integer in %s\n", opt_str);
  18071. + break;
  18072. + }
  18073. + err = au_opts_parse_idel(sb, n, &opt->del, a->args);
  18074. + if (!err)
  18075. + opt->type = token;
  18076. + break;
  18077. +#endif
  18078. + case Opt_mod:
  18079. + err = au_opts_parse_mod(&opt->mod, a->args);
  18080. + if (!err)
  18081. + opt->type = token;
  18082. + break;
  18083. +#ifdef IMOD /* reserved for future use */
  18084. + case Opt_imod:
  18085. + u.mod->path = "(indexed)";
  18086. + if (unlikely(match_int(&a->args[0], &n))) {
  18087. + pr_err("bad integer in %s\n", opt_str);
  18088. + break;
  18089. + }
  18090. + err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
  18091. + if (!err)
  18092. + opt->type = token;
  18093. + break;
  18094. +#endif
  18095. + case Opt_xino:
  18096. + err = au_opts_parse_xino(sb, &opt->xino, a->args);
  18097. + if (!err)
  18098. + opt->type = token;
  18099. + break;
  18100. +
  18101. + case Opt_trunc_xino_path:
  18102. + err = au_opts_parse_xino_itrunc_path
  18103. + (sb, &opt->xino_itrunc, a->args);
  18104. + if (!err)
  18105. + opt->type = token;
  18106. + break;
  18107. +
  18108. + case Opt_itrunc_xino:
  18109. + u.xino_itrunc = &opt->xino_itrunc;
  18110. + if (unlikely(match_int(&a->args[0], &n))) {
  18111. + pr_err("bad integer in %s\n", opt_str);
  18112. + break;
  18113. + }
  18114. + u.xino_itrunc->bindex = n;
  18115. + aufs_read_lock(root, AuLock_FLUSH);
  18116. + if (n < 0 || au_sbend(sb) < n) {
  18117. + pr_err("out of bounds, %d\n", n);
  18118. + aufs_read_unlock(root, !AuLock_IR);
  18119. + break;
  18120. + }
  18121. + aufs_read_unlock(root, !AuLock_IR);
  18122. + err = 0;
  18123. + opt->type = token;
  18124. + break;
  18125. +
  18126. + case Opt_dirwh:
  18127. + if (unlikely(match_int(&a->args[0], &opt->dirwh)))
  18128. + break;
  18129. + err = 0;
  18130. + opt->type = token;
  18131. + break;
  18132. +
  18133. + case Opt_rdcache:
  18134. + if (unlikely(match_int(&a->args[0], &n))) {
  18135. + pr_err("bad integer in %s\n", opt_str);
  18136. + break;
  18137. + }
  18138. + if (unlikely(n > AUFS_RDCACHE_MAX)) {
  18139. + pr_err("rdcache must be smaller than %d\n",
  18140. + AUFS_RDCACHE_MAX);
  18141. + break;
  18142. + }
  18143. + opt->rdcache = n;
  18144. + err = 0;
  18145. + opt->type = token;
  18146. + break;
  18147. + case Opt_rdblk:
  18148. + if (unlikely(match_int(&a->args[0], &n)
  18149. + || n < 0
  18150. + || n > KMALLOC_MAX_SIZE)) {
  18151. + pr_err("bad integer in %s\n", opt_str);
  18152. + break;
  18153. + }
  18154. + if (unlikely(n && n < NAME_MAX)) {
  18155. + pr_err("rdblk must be larger than %d\n",
  18156. + NAME_MAX);
  18157. + break;
  18158. + }
  18159. + opt->rdblk = n;
  18160. + err = 0;
  18161. + opt->type = token;
  18162. + break;
  18163. + case Opt_rdhash:
  18164. + if (unlikely(match_int(&a->args[0], &n)
  18165. + || n < 0
  18166. + || n * sizeof(struct hlist_head)
  18167. + > KMALLOC_MAX_SIZE)) {
  18168. + pr_err("bad integer in %s\n", opt_str);
  18169. + break;
  18170. + }
  18171. + opt->rdhash = n;
  18172. + err = 0;
  18173. + opt->type = token;
  18174. + break;
  18175. +
  18176. + case Opt_trunc_xino:
  18177. + case Opt_notrunc_xino:
  18178. + case Opt_noxino:
  18179. + case Opt_trunc_xib:
  18180. + case Opt_notrunc_xib:
  18181. + case Opt_shwh:
  18182. + case Opt_noshwh:
  18183. + case Opt_plink:
  18184. + case Opt_noplink:
  18185. + case Opt_list_plink:
  18186. + case Opt_dio:
  18187. + case Opt_nodio:
  18188. + case Opt_diropq_a:
  18189. + case Opt_diropq_w:
  18190. + case Opt_warn_perm:
  18191. + case Opt_nowarn_perm:
  18192. + case Opt_refrof:
  18193. + case Opt_norefrof:
  18194. + case Opt_verbose:
  18195. + case Opt_noverbose:
  18196. + case Opt_sum:
  18197. + case Opt_nosum:
  18198. + case Opt_wsum:
  18199. + case Opt_rdblk_def:
  18200. + case Opt_rdhash_def:
  18201. + err = 0;
  18202. + opt->type = token;
  18203. + break;
  18204. +
  18205. + case Opt_udba:
  18206. + opt->udba = udba_val(a->args[0].from);
  18207. + if (opt->udba >= 0) {
  18208. + err = 0;
  18209. + opt->type = token;
  18210. + } else
  18211. + pr_err("wrong value, %s\n", opt_str);
  18212. + break;
  18213. +
  18214. + case Opt_wbr_create:
  18215. + u.create = &opt->wbr_create;
  18216. + u.create->wbr_create
  18217. + = au_wbr_create_val(a->args[0].from, u.create);
  18218. + if (u.create->wbr_create >= 0) {
  18219. + err = 0;
  18220. + opt->type = token;
  18221. + } else
  18222. + pr_err("wrong value, %s\n", opt_str);
  18223. + break;
  18224. + case Opt_wbr_copyup:
  18225. + opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
  18226. + if (opt->wbr_copyup >= 0) {
  18227. + err = 0;
  18228. + opt->type = token;
  18229. + } else
  18230. + pr_err("wrong value, %s\n", opt_str);
  18231. + break;
  18232. +
  18233. + case Opt_ignore:
  18234. + pr_warning("ignored %s\n", opt_str);
  18235. + /*FALLTHROUGH*/
  18236. + case Opt_ignore_silent:
  18237. + skipped = 1;
  18238. + err = 0;
  18239. + break;
  18240. + case Opt_err:
  18241. + pr_err("unknown option %s\n", opt_str);
  18242. + break;
  18243. + }
  18244. +
  18245. + if (!err && !skipped) {
  18246. + if (unlikely(++opt > opt_tail)) {
  18247. + err = -E2BIG;
  18248. + opt--;
  18249. + opt->type = Opt_tail;
  18250. + break;
  18251. + }
  18252. + opt->type = Opt_tail;
  18253. + }
  18254. + }
  18255. +
  18256. + kfree(a);
  18257. + dump_opts(opts);
  18258. + if (unlikely(err))
  18259. + au_opts_free(opts);
  18260. +
  18261. +out:
  18262. + return err;
  18263. +}
  18264. +
  18265. +static int au_opt_wbr_create(struct super_block *sb,
  18266. + struct au_opt_wbr_create *create)
  18267. +{
  18268. + int err;
  18269. + struct au_sbinfo *sbinfo;
  18270. +
  18271. + SiMustWriteLock(sb);
  18272. +
  18273. + err = 1; /* handled */
  18274. + sbinfo = au_sbi(sb);
  18275. + if (sbinfo->si_wbr_create_ops->fin) {
  18276. + err = sbinfo->si_wbr_create_ops->fin(sb);
  18277. + if (!err)
  18278. + err = 1;
  18279. + }
  18280. +
  18281. + sbinfo->si_wbr_create = create->wbr_create;
  18282. + sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
  18283. + switch (create->wbr_create) {
  18284. + case AuWbrCreate_MFSRRV:
  18285. + case AuWbrCreate_MFSRR:
  18286. + sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
  18287. + /*FALLTHROUGH*/
  18288. + case AuWbrCreate_MFS:
  18289. + case AuWbrCreate_MFSV:
  18290. + case AuWbrCreate_PMFS:
  18291. + case AuWbrCreate_PMFSV:
  18292. + sbinfo->si_wbr_mfs.mfs_expire
  18293. + = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
  18294. + break;
  18295. + }
  18296. +
  18297. + if (sbinfo->si_wbr_create_ops->init)
  18298. + sbinfo->si_wbr_create_ops->init(sb); /* ignore */
  18299. +
  18300. + return err;
  18301. +}
  18302. +
  18303. +/*
  18304. + * returns,
  18305. + * plus: processed without an error
  18306. + * zero: unprocessed
  18307. + */
  18308. +static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
  18309. + struct au_opts *opts)
  18310. +{
  18311. + int err;
  18312. + struct au_sbinfo *sbinfo;
  18313. +
  18314. + SiMustWriteLock(sb);
  18315. +
  18316. + err = 1; /* handled */
  18317. + sbinfo = au_sbi(sb);
  18318. + switch (opt->type) {
  18319. + case Opt_udba:
  18320. + sbinfo->si_mntflags &= ~AuOptMask_UDBA;
  18321. + sbinfo->si_mntflags |= opt->udba;
  18322. + opts->given_udba |= opt->udba;
  18323. + break;
  18324. +
  18325. + case Opt_plink:
  18326. + au_opt_set(sbinfo->si_mntflags, PLINK);
  18327. + break;
  18328. + case Opt_noplink:
  18329. + if (au_opt_test(sbinfo->si_mntflags, PLINK))
  18330. + au_plink_put(sb, /*verbose*/1);
  18331. + au_opt_clr(sbinfo->si_mntflags, PLINK);
  18332. + break;
  18333. + case Opt_list_plink:
  18334. + if (au_opt_test(sbinfo->si_mntflags, PLINK))
  18335. + au_plink_list(sb);
  18336. + break;
  18337. +
  18338. + case Opt_dio:
  18339. + au_opt_set(sbinfo->si_mntflags, DIO);
  18340. + au_fset_opts(opts->flags, REFRESH_DYAOP);
  18341. + break;
  18342. + case Opt_nodio:
  18343. + au_opt_clr(sbinfo->si_mntflags, DIO);
  18344. + au_fset_opts(opts->flags, REFRESH_DYAOP);
  18345. + break;
  18346. +
  18347. + case Opt_diropq_a:
  18348. + au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
  18349. + break;
  18350. + case Opt_diropq_w:
  18351. + au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
  18352. + break;
  18353. +
  18354. + case Opt_warn_perm:
  18355. + au_opt_set(sbinfo->si_mntflags, WARN_PERM);
  18356. + break;
  18357. + case Opt_nowarn_perm:
  18358. + au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
  18359. + break;
  18360. +
  18361. + case Opt_refrof:
  18362. + au_opt_set(sbinfo->si_mntflags, REFROF);
  18363. + break;
  18364. + case Opt_norefrof:
  18365. + au_opt_clr(sbinfo->si_mntflags, REFROF);
  18366. + break;
  18367. +
  18368. + case Opt_verbose:
  18369. + au_opt_set(sbinfo->si_mntflags, VERBOSE);
  18370. + break;
  18371. + case Opt_noverbose:
  18372. + au_opt_clr(sbinfo->si_mntflags, VERBOSE);
  18373. + break;
  18374. +
  18375. + case Opt_sum:
  18376. + au_opt_set(sbinfo->si_mntflags, SUM);
  18377. + break;
  18378. + case Opt_wsum:
  18379. + au_opt_clr(sbinfo->si_mntflags, SUM);
  18380. + au_opt_set(sbinfo->si_mntflags, SUM_W);
  18381. + case Opt_nosum:
  18382. + au_opt_clr(sbinfo->si_mntflags, SUM);
  18383. + au_opt_clr(sbinfo->si_mntflags, SUM_W);
  18384. + break;
  18385. +
  18386. + case Opt_wbr_create:
  18387. + err = au_opt_wbr_create(sb, &opt->wbr_create);
  18388. + break;
  18389. + case Opt_wbr_copyup:
  18390. + sbinfo->si_wbr_copyup = opt->wbr_copyup;
  18391. + sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
  18392. + break;
  18393. +
  18394. + case Opt_dirwh:
  18395. + sbinfo->si_dirwh = opt->dirwh;
  18396. + break;
  18397. +
  18398. + case Opt_rdcache:
  18399. + sbinfo->si_rdcache
  18400. + = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
  18401. + break;
  18402. + case Opt_rdblk:
  18403. + sbinfo->si_rdblk = opt->rdblk;
  18404. + break;
  18405. + case Opt_rdblk_def:
  18406. + sbinfo->si_rdblk = AUFS_RDBLK_DEF;
  18407. + break;
  18408. + case Opt_rdhash:
  18409. + sbinfo->si_rdhash = opt->rdhash;
  18410. + break;
  18411. + case Opt_rdhash_def:
  18412. + sbinfo->si_rdhash = AUFS_RDHASH_DEF;
  18413. + break;
  18414. +
  18415. + case Opt_shwh:
  18416. + au_opt_set(sbinfo->si_mntflags, SHWH);
  18417. + break;
  18418. + case Opt_noshwh:
  18419. + au_opt_clr(sbinfo->si_mntflags, SHWH);
  18420. + break;
  18421. +
  18422. + case Opt_trunc_xino:
  18423. + au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
  18424. + break;
  18425. + case Opt_notrunc_xino:
  18426. + au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
  18427. + break;
  18428. +
  18429. + case Opt_trunc_xino_path:
  18430. + case Opt_itrunc_xino:
  18431. + err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
  18432. + if (!err)
  18433. + err = 1;
  18434. + break;
  18435. +
  18436. + case Opt_trunc_xib:
  18437. + au_fset_opts(opts->flags, TRUNC_XIB);
  18438. + break;
  18439. + case Opt_notrunc_xib:
  18440. + au_fclr_opts(opts->flags, TRUNC_XIB);
  18441. + break;
  18442. +
  18443. + default:
  18444. + err = 0;
  18445. + break;
  18446. + }
  18447. +
  18448. + return err;
  18449. +}
  18450. +
  18451. +/*
  18452. + * returns tri-state.
  18453. + * plus: processed without an error
  18454. + * zero: unprocessed
  18455. + * minus: error
  18456. + */
  18457. +static int au_opt_br(struct super_block *sb, struct au_opt *opt,
  18458. + struct au_opts *opts)
  18459. +{
  18460. + int err, do_refresh;
  18461. +
  18462. + err = 0;
  18463. + switch (opt->type) {
  18464. + case Opt_append:
  18465. + opt->add.bindex = au_sbend(sb) + 1;
  18466. + if (opt->add.bindex < 0)
  18467. + opt->add.bindex = 0;
  18468. + goto add;
  18469. + case Opt_prepend:
  18470. + opt->add.bindex = 0;
  18471. + add:
  18472. + case Opt_add:
  18473. + err = au_br_add(sb, &opt->add,
  18474. + au_ftest_opts(opts->flags, REMOUNT));
  18475. + if (!err) {
  18476. + err = 1;
  18477. + au_fset_opts(opts->flags, REFRESH);
  18478. + }
  18479. + break;
  18480. +
  18481. + case Opt_del:
  18482. + case Opt_idel:
  18483. + err = au_br_del(sb, &opt->del,
  18484. + au_ftest_opts(opts->flags, REMOUNT));
  18485. + if (!err) {
  18486. + err = 1;
  18487. + au_fset_opts(opts->flags, TRUNC_XIB);
  18488. + au_fset_opts(opts->flags, REFRESH);
  18489. + }
  18490. + break;
  18491. +
  18492. + case Opt_mod:
  18493. + case Opt_imod:
  18494. + err = au_br_mod(sb, &opt->mod,
  18495. + au_ftest_opts(opts->flags, REMOUNT),
  18496. + &do_refresh);
  18497. + if (!err) {
  18498. + err = 1;
  18499. + if (do_refresh)
  18500. + au_fset_opts(opts->flags, REFRESH);
  18501. + }
  18502. + break;
  18503. + }
  18504. +
  18505. + return err;
  18506. +}
  18507. +
  18508. +static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
  18509. + struct au_opt_xino **opt_xino,
  18510. + struct au_opts *opts)
  18511. +{
  18512. + int err;
  18513. + aufs_bindex_t bend, bindex;
  18514. + struct dentry *root, *parent, *h_root;
  18515. +
  18516. + err = 0;
  18517. + switch (opt->type) {
  18518. + case Opt_xino:
  18519. + err = au_xino_set(sb, &opt->xino,
  18520. + !!au_ftest_opts(opts->flags, REMOUNT));
  18521. + if (unlikely(err))
  18522. + break;
  18523. +
  18524. + *opt_xino = &opt->xino;
  18525. + au_xino_brid_set(sb, -1);
  18526. +
  18527. + /* safe d_parent access */
  18528. + parent = opt->xino.file->f_dentry->d_parent;
  18529. + root = sb->s_root;
  18530. + bend = au_sbend(sb);
  18531. + for (bindex = 0; bindex <= bend; bindex++) {
  18532. + h_root = au_h_dptr(root, bindex);
  18533. + if (h_root == parent) {
  18534. + au_xino_brid_set(sb, au_sbr_id(sb, bindex));
  18535. + break;
  18536. + }
  18537. + }
  18538. + break;
  18539. +
  18540. + case Opt_noxino:
  18541. + au_xino_clr(sb);
  18542. + au_xino_brid_set(sb, -1);
  18543. + *opt_xino = (void *)-1;
  18544. + break;
  18545. + }
  18546. +
  18547. + return err;
  18548. +}
  18549. +
  18550. +int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
  18551. + unsigned int pending)
  18552. +{
  18553. + int err;
  18554. + aufs_bindex_t bindex, bend;
  18555. + unsigned char do_plink, skip, do_free;
  18556. + struct au_branch *br;
  18557. + struct au_wbr *wbr;
  18558. + struct dentry *root;
  18559. + struct inode *dir, *h_dir;
  18560. + struct au_sbinfo *sbinfo;
  18561. + struct au_hinode *hdir;
  18562. +
  18563. + SiMustAnyLock(sb);
  18564. +
  18565. + sbinfo = au_sbi(sb);
  18566. + AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
  18567. +
  18568. + if (!(sb_flags & MS_RDONLY)) {
  18569. + if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
  18570. + pr_warning("first branch should be rw\n");
  18571. + if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
  18572. + pr_warning("shwh should be used with ro\n");
  18573. + }
  18574. +
  18575. + if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
  18576. + && !au_opt_test(sbinfo->si_mntflags, XINO))
  18577. + pr_warning("udba=*notify requires xino\n");
  18578. +
  18579. + err = 0;
  18580. + root = sb->s_root;
  18581. + dir = root->d_inode;
  18582. + do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
  18583. + bend = au_sbend(sb);
  18584. + for (bindex = 0; !err && bindex <= bend; bindex++) {
  18585. + skip = 0;
  18586. + h_dir = au_h_iptr(dir, bindex);
  18587. + br = au_sbr(sb, bindex);
  18588. + do_free = 0;
  18589. +
  18590. + wbr = br->br_wbr;
  18591. + if (wbr)
  18592. + wbr_wh_read_lock(wbr);
  18593. +
  18594. + switch (br->br_perm) {
  18595. + case AuBrPerm_RO:
  18596. + case AuBrPerm_ROWH:
  18597. + case AuBrPerm_RR:
  18598. + case AuBrPerm_RRWH:
  18599. + do_free = !!wbr;
  18600. + skip = (!wbr
  18601. + || (!wbr->wbr_whbase
  18602. + && !wbr->wbr_plink
  18603. + && !wbr->wbr_orph));
  18604. + break;
  18605. +
  18606. + case AuBrPerm_RWNoLinkWH:
  18607. + /* skip = (!br->br_whbase && !br->br_orph); */
  18608. + skip = (!wbr || !wbr->wbr_whbase);
  18609. + if (skip && wbr) {
  18610. + if (do_plink)
  18611. + skip = !!wbr->wbr_plink;
  18612. + else
  18613. + skip = !wbr->wbr_plink;
  18614. + }
  18615. + break;
  18616. +
  18617. + case AuBrPerm_RW:
  18618. + /* skip = (br->br_whbase && br->br_ohph); */
  18619. + skip = (wbr && wbr->wbr_whbase);
  18620. + if (skip) {
  18621. + if (do_plink)
  18622. + skip = !!wbr->wbr_plink;
  18623. + else
  18624. + skip = !wbr->wbr_plink;
  18625. + }
  18626. + break;
  18627. +
  18628. + default:
  18629. + BUG();
  18630. + }
  18631. + if (wbr)
  18632. + wbr_wh_read_unlock(wbr);
  18633. +
  18634. + if (skip)
  18635. + continue;
  18636. +
  18637. + hdir = au_hi(dir, bindex);
  18638. + au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
  18639. + if (wbr)
  18640. + wbr_wh_write_lock(wbr);
  18641. + err = au_wh_init(au_h_dptr(root, bindex), br, sb);
  18642. + if (wbr)
  18643. + wbr_wh_write_unlock(wbr);
  18644. + au_hn_imtx_unlock(hdir);
  18645. +
  18646. + if (!err && do_free) {
  18647. + kfree(wbr);
  18648. + br->br_wbr = NULL;
  18649. + }
  18650. + }
  18651. +
  18652. + return err;
  18653. +}
  18654. +
  18655. +int au_opts_mount(struct super_block *sb, struct au_opts *opts)
  18656. +{
  18657. + int err;
  18658. + unsigned int tmp;
  18659. + aufs_bindex_t bindex, bend;
  18660. + struct au_opt *opt;
  18661. + struct au_opt_xino *opt_xino, xino;
  18662. + struct au_sbinfo *sbinfo;
  18663. + struct au_branch *br;
  18664. +
  18665. + SiMustWriteLock(sb);
  18666. +
  18667. + err = 0;
  18668. + opt_xino = NULL;
  18669. + opt = opts->opt;
  18670. + while (err >= 0 && opt->type != Opt_tail)
  18671. + err = au_opt_simple(sb, opt++, opts);
  18672. + if (err > 0)
  18673. + err = 0;
  18674. + else if (unlikely(err < 0))
  18675. + goto out;
  18676. +
  18677. + /* disable xino and udba temporary */
  18678. + sbinfo = au_sbi(sb);
  18679. + tmp = sbinfo->si_mntflags;
  18680. + au_opt_clr(sbinfo->si_mntflags, XINO);
  18681. + au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
  18682. +
  18683. + opt = opts->opt;
  18684. + while (err >= 0 && opt->type != Opt_tail)
  18685. + err = au_opt_br(sb, opt++, opts);
  18686. + if (err > 0)
  18687. + err = 0;
  18688. + else if (unlikely(err < 0))
  18689. + goto out;
  18690. +
  18691. + bend = au_sbend(sb);
  18692. + if (unlikely(bend < 0)) {
  18693. + err = -EINVAL;
  18694. + pr_err("no branches\n");
  18695. + goto out;
  18696. + }
  18697. +
  18698. + if (au_opt_test(tmp, XINO))
  18699. + au_opt_set(sbinfo->si_mntflags, XINO);
  18700. + opt = opts->opt;
  18701. + while (!err && opt->type != Opt_tail)
  18702. + err = au_opt_xino(sb, opt++, &opt_xino, opts);
  18703. + if (unlikely(err))
  18704. + goto out;
  18705. +
  18706. + err = au_opts_verify(sb, sb->s_flags, tmp);
  18707. + if (unlikely(err))
  18708. + goto out;
  18709. +
  18710. + /* restore xino */
  18711. + if (au_opt_test(tmp, XINO) && !opt_xino) {
  18712. + xino.file = au_xino_def(sb);
  18713. + err = PTR_ERR(xino.file);
  18714. + if (IS_ERR(xino.file))
  18715. + goto out;
  18716. +
  18717. + err = au_xino_set(sb, &xino, /*remount*/0);
  18718. + fput(xino.file);
  18719. + if (unlikely(err))
  18720. + goto out;
  18721. + }
  18722. +
  18723. + /* restore udba */
  18724. + tmp &= AuOptMask_UDBA;
  18725. + sbinfo->si_mntflags &= ~AuOptMask_UDBA;
  18726. + sbinfo->si_mntflags |= tmp;
  18727. + bend = au_sbend(sb);
  18728. + for (bindex = 0; bindex <= bend; bindex++) {
  18729. + br = au_sbr(sb, bindex);
  18730. + err = au_hnotify_reset_br(tmp, br, br->br_perm);
  18731. + if (unlikely(err))
  18732. + AuIOErr("hnotify failed on br %d, %d, ignored\n",
  18733. + bindex, err);
  18734. + /* go on even if err */
  18735. + }
  18736. + if (au_opt_test(tmp, UDBA_HNOTIFY)) {
  18737. + struct inode *dir = sb->s_root->d_inode;
  18738. + au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
  18739. + }
  18740. +
  18741. +out:
  18742. + return err;
  18743. +}
  18744. +
  18745. +int au_opts_remount(struct super_block *sb, struct au_opts *opts)
  18746. +{
  18747. + int err, rerr;
  18748. + struct inode *dir;
  18749. + struct au_opt_xino *opt_xino;
  18750. + struct au_opt *opt;
  18751. + struct au_sbinfo *sbinfo;
  18752. +
  18753. + SiMustWriteLock(sb);
  18754. +
  18755. + dir = sb->s_root->d_inode;
  18756. + sbinfo = au_sbi(sb);
  18757. + err = 0;
  18758. + opt_xino = NULL;
  18759. + opt = opts->opt;
  18760. + while (err >= 0 && opt->type != Opt_tail) {
  18761. + err = au_opt_simple(sb, opt, opts);
  18762. + if (!err)
  18763. + err = au_opt_br(sb, opt, opts);
  18764. + if (!err)
  18765. + err = au_opt_xino(sb, opt, &opt_xino, opts);
  18766. + opt++;
  18767. + }
  18768. + if (err > 0)
  18769. + err = 0;
  18770. + AuTraceErr(err);
  18771. + /* go on even err */
  18772. +
  18773. + rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
  18774. + if (unlikely(rerr && !err))
  18775. + err = rerr;
  18776. +
  18777. + if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
  18778. + rerr = au_xib_trunc(sb);
  18779. + if (unlikely(rerr && !err))
  18780. + err = rerr;
  18781. + }
  18782. +
  18783. + /* will be handled by the caller */
  18784. + if (!au_ftest_opts(opts->flags, REFRESH)
  18785. + && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO)))
  18786. + au_fset_opts(opts->flags, REFRESH);
  18787. +
  18788. + AuDbg("status 0x%x\n", opts->flags);
  18789. + return err;
  18790. +}
  18791. +
  18792. +/* ---------------------------------------------------------------------- */
  18793. +
  18794. +unsigned int au_opt_udba(struct super_block *sb)
  18795. +{
  18796. + return au_mntflags(sb) & AuOptMask_UDBA;
  18797. +}
  18798. diff -Nur linux-2.6.37.orig/fs/aufs/opts.h linux-2.6.37/fs/aufs/opts.h
  18799. --- linux-2.6.37.orig/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100
  18800. +++ linux-2.6.37/fs/aufs/opts.h 2011-01-11 20:15:11.000000000 +0100
  18801. @@ -0,0 +1,210 @@
  18802. +/*
  18803. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  18804. + *
  18805. + * This program, aufs is free software; you can redistribute it and/or modify
  18806. + * it under the terms of the GNU General Public License as published by
  18807. + * the Free Software Foundation; either version 2 of the License, or
  18808. + * (at your option) any later version.
  18809. + *
  18810. + * This program is distributed in the hope that it will be useful,
  18811. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18812. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18813. + * GNU General Public License for more details.
  18814. + *
  18815. + * You should have received a copy of the GNU General Public License
  18816. + * along with this program; if not, write to the Free Software
  18817. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18818. + */
  18819. +
  18820. +/*
  18821. + * mount options/flags
  18822. + */
  18823. +
  18824. +#ifndef __AUFS_OPTS_H__
  18825. +#define __AUFS_OPTS_H__
  18826. +
  18827. +#ifdef __KERNEL__
  18828. +
  18829. +#include <linux/path.h>
  18830. +#include <linux/aufs_type.h>
  18831. +
  18832. +struct file;
  18833. +struct super_block;
  18834. +
  18835. +/* ---------------------------------------------------------------------- */
  18836. +
  18837. +/* mount flags */
  18838. +#define AuOpt_XINO 1 /* external inode number bitmap
  18839. + and translation table */
  18840. +#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */
  18841. +#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */
  18842. +#define AuOpt_UDBA_REVAL (1 << 3)
  18843. +#define AuOpt_UDBA_HNOTIFY (1 << 4)
  18844. +#define AuOpt_SHWH (1 << 5) /* show whiteout */
  18845. +#define AuOpt_PLINK (1 << 6) /* pseudo-link */
  18846. +#define AuOpt_DIRPERM1 (1 << 7) /* unimplemented */
  18847. +#define AuOpt_REFROF (1 << 8) /* unimplemented */
  18848. +#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */
  18849. +#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
  18850. +#define AuOpt_SUM_W (1 << 11) /* unimplemented */
  18851. +#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */
  18852. +#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */
  18853. +#define AuOpt_DIO (1 << 14) /* direct io */
  18854. +
  18855. +#ifndef CONFIG_AUFS_HNOTIFY
  18856. +#undef AuOpt_UDBA_HNOTIFY
  18857. +#define AuOpt_UDBA_HNOTIFY 0
  18858. +#endif
  18859. +#ifndef CONFIG_AUFS_SHWH
  18860. +#undef AuOpt_SHWH
  18861. +#define AuOpt_SHWH 0
  18862. +#endif
  18863. +
  18864. +#define AuOpt_Def (AuOpt_XINO \
  18865. + | AuOpt_UDBA_REVAL \
  18866. + | AuOpt_PLINK \
  18867. + /* | AuOpt_DIRPERM1 */ \
  18868. + | AuOpt_WARN_PERM)
  18869. +#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
  18870. + | AuOpt_UDBA_REVAL \
  18871. + | AuOpt_UDBA_HNOTIFY)
  18872. +
  18873. +#define au_opt_test(flags, name) (flags & AuOpt_##name)
  18874. +#define au_opt_set(flags, name) do { \
  18875. + BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
  18876. + ((flags) |= AuOpt_##name); \
  18877. +} while (0)
  18878. +#define au_opt_set_udba(flags, name) do { \
  18879. + (flags) &= ~AuOptMask_UDBA; \
  18880. + ((flags) |= AuOpt_##name); \
  18881. +} while (0)
  18882. +#define au_opt_clr(flags, name) do { \
  18883. + ((flags) &= ~AuOpt_##name); \
  18884. +} while (0)
  18885. +
  18886. +static inline unsigned int au_opts_plink(unsigned int mntflags)
  18887. +{
  18888. +#ifdef CONFIG_PROC_FS
  18889. + return mntflags;
  18890. +#else
  18891. + return mntflags & ~AuOpt_PLINK;
  18892. +#endif
  18893. +}
  18894. +
  18895. +/* ---------------------------------------------------------------------- */
  18896. +
  18897. +/* policies to select one among multiple writable branches */
  18898. +enum {
  18899. + AuWbrCreate_TDP, /* top down parent */
  18900. + AuWbrCreate_RR, /* round robin */
  18901. + AuWbrCreate_MFS, /* most free space */
  18902. + AuWbrCreate_MFSV, /* mfs with seconds */
  18903. + AuWbrCreate_MFSRR, /* mfs then rr */
  18904. + AuWbrCreate_MFSRRV, /* mfs then rr with seconds */
  18905. + AuWbrCreate_PMFS, /* parent and mfs */
  18906. + AuWbrCreate_PMFSV, /* parent and mfs with seconds */
  18907. +
  18908. + AuWbrCreate_Def = AuWbrCreate_TDP
  18909. +};
  18910. +
  18911. +enum {
  18912. + AuWbrCopyup_TDP, /* top down parent */
  18913. + AuWbrCopyup_BUP, /* bottom up parent */
  18914. + AuWbrCopyup_BU, /* bottom up */
  18915. +
  18916. + AuWbrCopyup_Def = AuWbrCopyup_TDP
  18917. +};
  18918. +
  18919. +/* ---------------------------------------------------------------------- */
  18920. +
  18921. +struct au_opt_add {
  18922. + aufs_bindex_t bindex;
  18923. + char *pathname;
  18924. + int perm;
  18925. + struct path path;
  18926. +};
  18927. +
  18928. +struct au_opt_del {
  18929. + char *pathname;
  18930. + struct path h_path;
  18931. +};
  18932. +
  18933. +struct au_opt_mod {
  18934. + char *path;
  18935. + int perm;
  18936. + struct dentry *h_root;
  18937. +};
  18938. +
  18939. +struct au_opt_xino {
  18940. + char *path;
  18941. + struct file *file;
  18942. +};
  18943. +
  18944. +struct au_opt_xino_itrunc {
  18945. + aufs_bindex_t bindex;
  18946. +};
  18947. +
  18948. +struct au_opt_wbr_create {
  18949. + int wbr_create;
  18950. + int mfs_second;
  18951. + unsigned long long mfsrr_watermark;
  18952. +};
  18953. +
  18954. +struct au_opt {
  18955. + int type;
  18956. + union {
  18957. + struct au_opt_xino xino;
  18958. + struct au_opt_xino_itrunc xino_itrunc;
  18959. + struct au_opt_add add;
  18960. + struct au_opt_del del;
  18961. + struct au_opt_mod mod;
  18962. + int dirwh;
  18963. + int rdcache;
  18964. + unsigned int rdblk;
  18965. + unsigned int rdhash;
  18966. + int udba;
  18967. + struct au_opt_wbr_create wbr_create;
  18968. + int wbr_copyup;
  18969. + };
  18970. +};
  18971. +
  18972. +/* opts flags */
  18973. +#define AuOpts_REMOUNT 1
  18974. +#define AuOpts_REFRESH (1 << 1)
  18975. +#define AuOpts_TRUNC_XIB (1 << 2)
  18976. +#define AuOpts_REFRESH_DYAOP (1 << 3)
  18977. +#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
  18978. +#define au_fset_opts(flags, name) \
  18979. + do { (flags) |= AuOpts_##name; } while (0)
  18980. +#define au_fclr_opts(flags, name) \
  18981. + do { (flags) &= ~AuOpts_##name; } while (0)
  18982. +
  18983. +struct au_opts {
  18984. + struct au_opt *opt;
  18985. + int max_opt;
  18986. +
  18987. + unsigned int given_udba;
  18988. + unsigned int flags;
  18989. + unsigned long sb_flags;
  18990. +};
  18991. +
  18992. +/* ---------------------------------------------------------------------- */
  18993. +
  18994. +const char *au_optstr_br_perm(int brperm);
  18995. +const char *au_optstr_udba(int udba);
  18996. +const char *au_optstr_wbr_copyup(int wbr_copyup);
  18997. +const char *au_optstr_wbr_create(int wbr_create);
  18998. +
  18999. +void au_opts_free(struct au_opts *opts);
  19000. +int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
  19001. +int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
  19002. + unsigned int pending);
  19003. +int au_opts_mount(struct super_block *sb, struct au_opts *opts);
  19004. +int au_opts_remount(struct super_block *sb, struct au_opts *opts);
  19005. +
  19006. +unsigned int au_opt_udba(struct super_block *sb);
  19007. +
  19008. +/* ---------------------------------------------------------------------- */
  19009. +
  19010. +#endif /* __KERNEL__ */
  19011. +#endif /* __AUFS_OPTS_H__ */
  19012. diff -Nur linux-2.6.37.orig/fs/aufs/plink.c linux-2.6.37/fs/aufs/plink.c
  19013. --- linux-2.6.37.orig/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100
  19014. +++ linux-2.6.37/fs/aufs/plink.c 2011-01-11 20:15:11.000000000 +0100
  19015. @@ -0,0 +1,515 @@
  19016. +/*
  19017. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  19018. + *
  19019. + * This program, aufs is free software; you can redistribute it and/or modify
  19020. + * it under the terms of the GNU General Public License as published by
  19021. + * the Free Software Foundation; either version 2 of the License, or
  19022. + * (at your option) any later version.
  19023. + *
  19024. + * This program is distributed in the hope that it will be useful,
  19025. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19026. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19027. + * GNU General Public License for more details.
  19028. + *
  19029. + * You should have received a copy of the GNU General Public License
  19030. + * along with this program; if not, write to the Free Software
  19031. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  19032. + */
  19033. +
  19034. +/*
  19035. + * pseudo-link
  19036. + */
  19037. +
  19038. +#include "aufs.h"
  19039. +
  19040. +/*
  19041. + * the pseudo-link maintenance mode.
  19042. + * during a user process maintains the pseudo-links,
  19043. + * prohibit adding a new plink and branch manipulation.
  19044. + *
  19045. + * Flags
  19046. + * NOPLM:
  19047. + * For entry functions which will handle plink, and i_mutex is already held
  19048. + * in VFS.
  19049. + * They cannot wait and should return an error at once.
  19050. + * Callers has to check the error.
  19051. + * NOPLMW:
  19052. + * For entry functions which will handle plink, but i_mutex is not held
  19053. + * in VFS.
  19054. + * They can wait the plink maintenance mode to finish.
  19055. + *
  19056. + * They behave like F_SETLK and F_SETLKW.
  19057. + * If the caller never handle plink, then both flags are unnecessary.
  19058. + */
  19059. +
  19060. +int au_plink_maint(struct super_block *sb, int flags)
  19061. +{
  19062. + int err;
  19063. + pid_t pid, ppid;
  19064. + struct au_sbinfo *sbi;
  19065. +
  19066. + SiMustAnyLock(sb);
  19067. +
  19068. + err = 0;
  19069. + if (!au_opt_test(au_mntflags(sb), PLINK))
  19070. + goto out;
  19071. +
  19072. + sbi = au_sbi(sb);
  19073. + pid = sbi->si_plink_maint_pid;
  19074. + if (!pid || pid == current->pid)
  19075. + goto out;
  19076. +
  19077. + /* todo: it highly depends upon /sbin/mount.aufs */
  19078. + rcu_read_lock();
  19079. + ppid = task_pid_vnr(rcu_dereference(current->real_parent));
  19080. + rcu_read_unlock();
  19081. + if (pid == ppid)
  19082. + goto out;
  19083. +
  19084. + if (au_ftest_lock(flags, NOPLMW)) {
  19085. + /* if there is no i_mutex lock in VFS, we don't need to wait */
  19086. + /* AuDebugOn(!lockdep_depth(current)); */
  19087. + while (sbi->si_plink_maint_pid) {
  19088. + si_read_unlock(sb);
  19089. + /* gave up wake_up_bit() */
  19090. + wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
  19091. +
  19092. + if (au_ftest_lock(flags, FLUSH))
  19093. + au_nwt_flush(&sbi->si_nowait);
  19094. + si_noflush_read_lock(sb);
  19095. + }
  19096. + } else if (au_ftest_lock(flags, NOPLM)) {
  19097. + AuDbg("ppid %d, pid %d\n", ppid, pid);
  19098. + err = -EAGAIN;
  19099. + }
  19100. +
  19101. +out:
  19102. + return err;
  19103. +}
  19104. +
  19105. +void au_plink_maint_leave(struct au_sbinfo *sbinfo)
  19106. +{
  19107. + spin_lock(&sbinfo->si_plink_maint_lock);
  19108. + sbinfo->si_plink_maint_pid = 0;
  19109. + spin_unlock(&sbinfo->si_plink_maint_lock);
  19110. + wake_up_all(&sbinfo->si_plink_wq);
  19111. +}
  19112. +
  19113. +int au_plink_maint_enter(struct super_block *sb)
  19114. +{
  19115. + int err;
  19116. + struct au_sbinfo *sbinfo;
  19117. +
  19118. + err = 0;
  19119. + sbinfo = au_sbi(sb);
  19120. + /* make sure i am the only one in this fs */
  19121. + si_write_lock(sb, AuLock_FLUSH);
  19122. + if (au_opt_test(au_mntflags(sb), PLINK)) {
  19123. + spin_lock(&sbinfo->si_plink_maint_lock);
  19124. + if (!sbinfo->si_plink_maint_pid)
  19125. + sbinfo->si_plink_maint_pid = current->pid;
  19126. + else
  19127. + err = -EBUSY;
  19128. + spin_unlock(&sbinfo->si_plink_maint_lock);
  19129. + }
  19130. + si_write_unlock(sb);
  19131. +
  19132. + return err;
  19133. +}
  19134. +
  19135. +/* ---------------------------------------------------------------------- */
  19136. +
  19137. +struct pseudo_link {
  19138. + union {
  19139. + struct list_head list;
  19140. + struct rcu_head rcu;
  19141. + };
  19142. + struct inode *inode;
  19143. +};
  19144. +
  19145. +#ifdef CONFIG_AUFS_DEBUG
  19146. +void au_plink_list(struct super_block *sb)
  19147. +{
  19148. + struct au_sbinfo *sbinfo;
  19149. + struct list_head *plink_list;
  19150. + struct pseudo_link *plink;
  19151. +
  19152. + SiMustAnyLock(sb);
  19153. +
  19154. + sbinfo = au_sbi(sb);
  19155. + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
  19156. + AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
  19157. +
  19158. + plink_list = &sbinfo->si_plink.head;
  19159. + rcu_read_lock();
  19160. + list_for_each_entry_rcu(plink, plink_list, list)
  19161. + AuDbg("%lu\n", plink->inode->i_ino);
  19162. + rcu_read_unlock();
  19163. +}
  19164. +#endif
  19165. +
  19166. +/* is the inode pseudo-linked? */
  19167. +int au_plink_test(struct inode *inode)
  19168. +{
  19169. + int found;
  19170. + struct au_sbinfo *sbinfo;
  19171. + struct list_head *plink_list;
  19172. + struct pseudo_link *plink;
  19173. +
  19174. + sbinfo = au_sbi(inode->i_sb);
  19175. + AuRwMustAnyLock(&sbinfo->si_rwsem);
  19176. + AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
  19177. + AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
  19178. +
  19179. + found = 0;
  19180. + plink_list = &sbinfo->si_plink.head;
  19181. + rcu_read_lock();
  19182. + list_for_each_entry_rcu(plink, plink_list, list)
  19183. + if (plink->inode == inode) {
  19184. + found = 1;
  19185. + break;
  19186. + }
  19187. + rcu_read_unlock();
  19188. + return found;
  19189. +}
  19190. +
  19191. +/* ---------------------------------------------------------------------- */
  19192. +
  19193. +/*
  19194. + * generate a name for plink.
  19195. + * the file will be stored under AUFS_WH_PLINKDIR.
  19196. + */
  19197. +/* 20 is max digits length of ulong 64 */
  19198. +#define PLINK_NAME_LEN ((20 + 1) * 2)
  19199. +
  19200. +static int plink_name(char *name, int len, struct inode *inode,
  19201. + aufs_bindex_t bindex)
  19202. +{
  19203. + int rlen;
  19204. + struct inode *h_inode;
  19205. +
  19206. + h_inode = au_h_iptr(inode, bindex);
  19207. + rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
  19208. + return rlen;
  19209. +}
  19210. +
  19211. +struct au_do_plink_lkup_args {
  19212. + struct dentry **errp;
  19213. + struct qstr *tgtname;
  19214. + struct dentry *h_parent;
  19215. + struct au_branch *br;
  19216. +};
  19217. +
  19218. +static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
  19219. + struct dentry *h_parent,
  19220. + struct au_branch *br)
  19221. +{
  19222. + struct dentry *h_dentry;
  19223. + struct mutex *h_mtx;
  19224. +
  19225. + h_mtx = &h_parent->d_inode->i_mutex;
  19226. + mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
  19227. + h_dentry = au_lkup_one(tgtname, h_parent, br, /*nd*/NULL);
  19228. + mutex_unlock(h_mtx);
  19229. + return h_dentry;
  19230. +}
  19231. +
  19232. +static void au_call_do_plink_lkup(void *args)
  19233. +{
  19234. + struct au_do_plink_lkup_args *a = args;
  19235. + *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
  19236. +}
  19237. +
  19238. +/* lookup the plink-ed @inode under the branch at @bindex */
  19239. +struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
  19240. +{
  19241. + struct dentry *h_dentry, *h_parent;
  19242. + struct au_branch *br;
  19243. + struct inode *h_dir;
  19244. + int wkq_err;
  19245. + char a[PLINK_NAME_LEN];
  19246. + struct qstr tgtname = {
  19247. + .name = a
  19248. + };
  19249. +
  19250. + AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
  19251. +
  19252. + br = au_sbr(inode->i_sb, bindex);
  19253. + h_parent = br->br_wbr->wbr_plink;
  19254. + h_dir = h_parent->d_inode;
  19255. + tgtname.len = plink_name(a, sizeof(a), inode, bindex);
  19256. +
  19257. + if (current_fsuid()) {
  19258. + struct au_do_plink_lkup_args args = {
  19259. + .errp = &h_dentry,
  19260. + .tgtname = &tgtname,
  19261. + .h_parent = h_parent,
  19262. + .br = br
  19263. + };
  19264. +
  19265. + wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
  19266. + if (unlikely(wkq_err))
  19267. + h_dentry = ERR_PTR(wkq_err);
  19268. + } else
  19269. + h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
  19270. +
  19271. + return h_dentry;
  19272. +}
  19273. +
  19274. +/* create a pseudo-link */
  19275. +static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
  19276. + struct dentry *h_dentry, struct au_branch *br)
  19277. +{
  19278. + int err;
  19279. + struct path h_path = {
  19280. + .mnt = br->br_mnt
  19281. + };
  19282. + struct inode *h_dir;
  19283. +
  19284. + h_dir = h_parent->d_inode;
  19285. + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
  19286. +again:
  19287. + h_path.dentry = au_lkup_one(tgt, h_parent, br, /*nd*/NULL);
  19288. + err = PTR_ERR(h_path.dentry);
  19289. + if (IS_ERR(h_path.dentry))
  19290. + goto out;
  19291. +
  19292. + err = 0;
  19293. + /* wh.plink dir is not monitored */
  19294. + /* todo: is it really safe? */
  19295. + if (h_path.dentry->d_inode
  19296. + && h_path.dentry->d_inode != h_dentry->d_inode) {
  19297. + err = vfsub_unlink(h_dir, &h_path, /*force*/0);
  19298. + dput(h_path.dentry);
  19299. + h_path.dentry = NULL;
  19300. + if (!err)
  19301. + goto again;
  19302. + }
  19303. + if (!err && !h_path.dentry->d_inode)
  19304. + err = vfsub_link(h_dentry, h_dir, &h_path);
  19305. + dput(h_path.dentry);
  19306. +
  19307. +out:
  19308. + mutex_unlock(&h_dir->i_mutex);
  19309. + return err;
  19310. +}
  19311. +
  19312. +struct do_whplink_args {
  19313. + int *errp;
  19314. + struct qstr *tgt;
  19315. + struct dentry *h_parent;
  19316. + struct dentry *h_dentry;
  19317. + struct au_branch *br;
  19318. +};
  19319. +
  19320. +static void call_do_whplink(void *args)
  19321. +{
  19322. + struct do_whplink_args *a = args;
  19323. + *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
  19324. +}
  19325. +
  19326. +static int whplink(struct dentry *h_dentry, struct inode *inode,
  19327. + aufs_bindex_t bindex, struct au_branch *br)
  19328. +{
  19329. + int err, wkq_err;
  19330. + struct au_wbr *wbr;
  19331. + struct dentry *h_parent;
  19332. + struct inode *h_dir;
  19333. + char a[PLINK_NAME_LEN];
  19334. + struct qstr tgtname = {
  19335. + .name = a
  19336. + };
  19337. +
  19338. + wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
  19339. + h_parent = wbr->wbr_plink;
  19340. + h_dir = h_parent->d_inode;
  19341. + tgtname.len = plink_name(a, sizeof(a), inode, bindex);
  19342. +
  19343. + /* always superio. */
  19344. + if (current_fsuid()) {
  19345. + struct do_whplink_args args = {
  19346. + .errp = &err,
  19347. + .tgt = &tgtname,
  19348. + .h_parent = h_parent,
  19349. + .h_dentry = h_dentry,
  19350. + .br = br
  19351. + };
  19352. + wkq_err = au_wkq_wait(call_do_whplink, &args);
  19353. + if (unlikely(wkq_err))
  19354. + err = wkq_err;
  19355. + } else
  19356. + err = do_whplink(&tgtname, h_parent, h_dentry, br);
  19357. +
  19358. + return err;
  19359. +}
  19360. +
  19361. +/* free a single plink */
  19362. +static void do_put_plink(struct pseudo_link *plink, int do_del)
  19363. +{
  19364. + if (do_del)
  19365. + list_del(&plink->list);
  19366. + iput(plink->inode);
  19367. + kfree(plink);
  19368. +}
  19369. +
  19370. +static void do_put_plink_rcu(struct rcu_head *rcu)
  19371. +{
  19372. + struct pseudo_link *plink;
  19373. +
  19374. + plink = container_of(rcu, struct pseudo_link, rcu);
  19375. + iput(plink->inode);
  19376. + kfree(plink);
  19377. +}
  19378. +
  19379. +/*
  19380. + * create a new pseudo-link for @h_dentry on @bindex.
  19381. + * the linked inode is held in aufs @inode.
  19382. + */
  19383. +void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
  19384. + struct dentry *h_dentry)
  19385. +{
  19386. + struct super_block *sb;
  19387. + struct au_sbinfo *sbinfo;
  19388. + struct list_head *plink_list;
  19389. + struct pseudo_link *plink, *tmp;
  19390. + int found, err, cnt;
  19391. +
  19392. + sb = inode->i_sb;
  19393. + sbinfo = au_sbi(sb);
  19394. + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
  19395. + AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
  19396. +
  19397. + cnt = 0;
  19398. + found = 0;
  19399. + plink_list = &sbinfo->si_plink.head;
  19400. + rcu_read_lock();
  19401. + list_for_each_entry_rcu(plink, plink_list, list) {
  19402. + cnt++;
  19403. + if (plink->inode == inode) {
  19404. + found = 1;
  19405. + break;
  19406. + }
  19407. + }
  19408. + rcu_read_unlock();
  19409. + if (found)
  19410. + return;
  19411. +
  19412. + tmp = kmalloc(sizeof(*plink), GFP_NOFS);
  19413. + if (tmp)
  19414. + tmp->inode = au_igrab(inode);
  19415. + else {
  19416. + err = -ENOMEM;
  19417. + goto out;
  19418. + }
  19419. +
  19420. + spin_lock(&sbinfo->si_plink.spin);
  19421. + list_for_each_entry(plink, plink_list, list) {
  19422. + if (plink->inode == inode) {
  19423. + found = 1;
  19424. + break;
  19425. + }
  19426. + }
  19427. + if (!found)
  19428. + list_add_rcu(&tmp->list, plink_list);
  19429. + spin_unlock(&sbinfo->si_plink.spin);
  19430. + if (!found) {
  19431. + cnt++;
  19432. + WARN_ONCE(cnt > AUFS_PLINK_WARN,
  19433. + "unexpectedly many pseudo links, %d\n", cnt);
  19434. + err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
  19435. + } else {
  19436. + do_put_plink(tmp, 0);
  19437. + return;
  19438. + }
  19439. +
  19440. +out:
  19441. + if (unlikely(err)) {
  19442. + pr_warning("err %d, damaged pseudo link.\n", err);
  19443. + if (tmp) {
  19444. + au_spl_del_rcu(&tmp->list, &sbinfo->si_plink);
  19445. + call_rcu(&tmp->rcu, do_put_plink_rcu);
  19446. + }
  19447. + }
  19448. +}
  19449. +
  19450. +/* free all plinks */
  19451. +void au_plink_put(struct super_block *sb, int verbose)
  19452. +{
  19453. + struct au_sbinfo *sbinfo;
  19454. + struct list_head *plink_list;
  19455. + struct pseudo_link *plink, *tmp;
  19456. +
  19457. + SiMustWriteLock(sb);
  19458. +
  19459. + sbinfo = au_sbi(sb);
  19460. + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
  19461. + AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
  19462. +
  19463. + plink_list = &sbinfo->si_plink.head;
  19464. + /* no spin_lock since sbinfo is write-locked */
  19465. + WARN(verbose && !list_empty(plink_list), "pseudo-link is not flushed");
  19466. + list_for_each_entry_safe(plink, tmp, plink_list, list)
  19467. + do_put_plink(plink, 0);
  19468. + INIT_LIST_HEAD(plink_list);
  19469. +}
  19470. +
  19471. +void au_plink_clean(struct super_block *sb, int verbose)
  19472. +{
  19473. + struct dentry *root;
  19474. +
  19475. + root = sb->s_root;
  19476. + aufs_write_lock(root);
  19477. + if (au_opt_test(au_mntflags(sb), PLINK))
  19478. + au_plink_put(sb, verbose);
  19479. + aufs_write_unlock(root);
  19480. +}
  19481. +
  19482. +/* free the plinks on a branch specified by @br_id */
  19483. +void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
  19484. +{
  19485. + struct au_sbinfo *sbinfo;
  19486. + struct list_head *plink_list;
  19487. + struct pseudo_link *plink, *tmp;
  19488. + struct inode *inode;
  19489. + aufs_bindex_t bstart, bend, bindex;
  19490. + unsigned char do_put;
  19491. +
  19492. + SiMustWriteLock(sb);
  19493. +
  19494. + sbinfo = au_sbi(sb);
  19495. + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
  19496. + AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
  19497. +
  19498. + plink_list = &sbinfo->si_plink.head;
  19499. + /* no spin_lock since sbinfo is write-locked */
  19500. + list_for_each_entry_safe(plink, tmp, plink_list, list) {
  19501. + do_put = 0;
  19502. + inode = au_igrab(plink->inode);
  19503. + ii_write_lock_child(inode);
  19504. + bstart = au_ibstart(inode);
  19505. + bend = au_ibend(inode);
  19506. + if (bstart >= 0) {
  19507. + for (bindex = bstart; bindex <= bend; bindex++) {
  19508. + if (!au_h_iptr(inode, bindex)
  19509. + || au_ii_br_id(inode, bindex) != br_id)
  19510. + continue;
  19511. + au_set_h_iptr(inode, bindex, NULL, 0);
  19512. + do_put = 1;
  19513. + break;
  19514. + }
  19515. + } else
  19516. + do_put_plink(plink, 1);
  19517. +
  19518. + if (do_put) {
  19519. + for (bindex = bstart; bindex <= bend; bindex++)
  19520. + if (au_h_iptr(inode, bindex)) {
  19521. + do_put = 0;
  19522. + break;
  19523. + }
  19524. + if (do_put)
  19525. + do_put_plink(plink, 1);
  19526. + }
  19527. + ii_write_unlock(inode);
  19528. + iput(inode);
  19529. + }
  19530. +}
  19531. diff -Nur linux-2.6.37.orig/fs/aufs/poll.c linux-2.6.37/fs/aufs/poll.c
  19532. --- linux-2.6.37.orig/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100
  19533. +++ linux-2.6.37/fs/aufs/poll.c 2011-01-11 20:15:11.000000000 +0100
  19534. @@ -0,0 +1,56 @@
  19535. +/*
  19536. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  19537. + *
  19538. + * This program, aufs is free software; you can redistribute it and/or modify
  19539. + * it under the terms of the GNU General Public License as published by
  19540. + * the Free Software Foundation; either version 2 of the License, or
  19541. + * (at your option) any later version.
  19542. + *
  19543. + * This program is distributed in the hope that it will be useful,
  19544. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19545. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19546. + * GNU General Public License for more details.
  19547. + *
  19548. + * You should have received a copy of the GNU General Public License
  19549. + * along with this program; if not, write to the Free Software
  19550. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  19551. + */
  19552. +
  19553. +/*
  19554. + * poll operation
  19555. + * There is only one filesystem which implements ->poll operation, currently.
  19556. + */
  19557. +
  19558. +#include "aufs.h"
  19559. +
  19560. +unsigned int aufs_poll(struct file *file, poll_table *wait)
  19561. +{
  19562. + unsigned int mask;
  19563. + int err;
  19564. + struct file *h_file;
  19565. + struct dentry *dentry;
  19566. + struct super_block *sb;
  19567. +
  19568. + /* We should pretend an error happened. */
  19569. + mask = POLLERR /* | POLLIN | POLLOUT */;
  19570. + dentry = file->f_dentry;
  19571. + sb = dentry->d_sb;
  19572. + si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
  19573. + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
  19574. + if (unlikely(err))
  19575. + goto out;
  19576. +
  19577. + /* it is not an error if h_file has no operation */
  19578. + mask = DEFAULT_POLLMASK;
  19579. + h_file = au_hf_top(file);
  19580. + if (h_file->f_op && h_file->f_op->poll)
  19581. + mask = h_file->f_op->poll(h_file, wait);
  19582. +
  19583. + di_read_unlock(dentry, AuLock_IR);
  19584. + fi_read_unlock(file);
  19585. +
  19586. +out:
  19587. + si_read_unlock(sb);
  19588. + AuTraceErr((int)mask);
  19589. + return mask;
  19590. +}
  19591. diff -Nur linux-2.6.37.orig/fs/aufs/procfs.c linux-2.6.37/fs/aufs/procfs.c
  19592. --- linux-2.6.37.orig/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100
  19593. +++ linux-2.6.37/fs/aufs/procfs.c 2011-01-11 20:15:11.000000000 +0100
  19594. @@ -0,0 +1,169 @@
  19595. +/*
  19596. + * Copyright (C) 2010-2011 Junjiro R. Okajima
  19597. + *
  19598. + * This program, aufs is free software; you can redistribute it and/or modify
  19599. + * it under the terms of the GNU General Public License as published by
  19600. + * the Free Software Foundation; either version 2 of the License, or
  19601. + * (at your option) any later version.
  19602. + *
  19603. + * This program is distributed in the hope that it will be useful,
  19604. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19605. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19606. + * GNU General Public License for more details.
  19607. + *
  19608. + * You should have received a copy of the GNU General Public License
  19609. + * along with this program; if not, write to the Free Software
  19610. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  19611. + */
  19612. +
  19613. +/*
  19614. + * procfs interfaces
  19615. + */
  19616. +
  19617. +#include <linux/proc_fs.h>
  19618. +#include "aufs.h"
  19619. +
  19620. +static int au_procfs_plm_release(struct inode *inode, struct file *file)
  19621. +{
  19622. + struct au_sbinfo *sbinfo;
  19623. +
  19624. + sbinfo = file->private_data;
  19625. + if (sbinfo) {
  19626. + au_plink_maint_leave(sbinfo);
  19627. + kobject_put(&sbinfo->si_kobj);
  19628. + }
  19629. +
  19630. + return 0;
  19631. +}
  19632. +
  19633. +static void au_procfs_plm_write_clean(struct file *file)
  19634. +{
  19635. + struct au_sbinfo *sbinfo;
  19636. +
  19637. + sbinfo = file->private_data;
  19638. + if (sbinfo)
  19639. + au_plink_clean(sbinfo->si_sb, /*verbose*/0);
  19640. +}
  19641. +
  19642. +static int au_procfs_plm_write_si(struct file *file, unsigned long id)
  19643. +{
  19644. + int err;
  19645. + struct super_block *sb;
  19646. + struct au_sbinfo *sbinfo;
  19647. +
  19648. + err = -EBUSY;
  19649. + if (unlikely(file->private_data))
  19650. + goto out;
  19651. +
  19652. + sb = NULL;
  19653. + spin_lock(&au_sbilist.spin);
  19654. + list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
  19655. + if (id == sysaufs_si_id(sbinfo)) {
  19656. + kobject_get(&sbinfo->si_kobj);
  19657. + sb = sbinfo->si_sb;
  19658. + break;
  19659. + }
  19660. + spin_unlock(&au_sbilist.spin);
  19661. +
  19662. + err = -EINVAL;
  19663. + if (unlikely(!sb))
  19664. + goto out;
  19665. +
  19666. + err = au_plink_maint_enter(sb);
  19667. + if (!err)
  19668. + /* keep kobject_get() */
  19669. + file->private_data = sbinfo;
  19670. + else
  19671. + kobject_put(&sbinfo->si_kobj);
  19672. +out:
  19673. + return err;
  19674. +}
  19675. +
  19676. +/*
  19677. + * Accept a valid "si=xxxx" only.
  19678. + * Once it is accepted successfully, accept "clean" too.
  19679. + */
  19680. +static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf,
  19681. + size_t count, loff_t *ppos)
  19682. +{
  19683. + ssize_t err;
  19684. + unsigned long id;
  19685. + /* last newline is allowed */
  19686. + char buf[3 + sizeof(unsigned long) * 2 + 1];
  19687. +
  19688. + err = -EACCES;
  19689. + if (unlikely(!capable(CAP_SYS_ADMIN)))
  19690. + goto out;
  19691. +
  19692. + err = -EINVAL;
  19693. + if (unlikely(count > sizeof(buf)))
  19694. + goto out;
  19695. +
  19696. + err = copy_from_user(buf, ubuf, count);
  19697. + if (unlikely(err)) {
  19698. + err = -EFAULT;
  19699. + goto out;
  19700. + }
  19701. + buf[count] = 0;
  19702. +
  19703. + err = -EINVAL;
  19704. + if (!strcmp("clean", buf)) {
  19705. + au_procfs_plm_write_clean(file);
  19706. + goto out_success;
  19707. + } else if (unlikely(strncmp("si=", buf, 3)))
  19708. + goto out;
  19709. +
  19710. + err = strict_strtoul(buf + 3, 16, &id);
  19711. + if (unlikely(err))
  19712. + goto out;
  19713. +
  19714. + err = au_procfs_plm_write_si(file, id);
  19715. + if (unlikely(err))
  19716. + goto out;
  19717. +
  19718. +out_success:
  19719. + err = count; /* success */
  19720. +out:
  19721. + return err;
  19722. +}
  19723. +
  19724. +static const struct file_operations au_procfs_plm_fop = {
  19725. + .write = au_procfs_plm_write,
  19726. + .release = au_procfs_plm_release,
  19727. + .owner = THIS_MODULE
  19728. +};
  19729. +
  19730. +/* ---------------------------------------------------------------------- */
  19731. +
  19732. +static struct proc_dir_entry *au_procfs_dir;
  19733. +
  19734. +void au_procfs_fin(void)
  19735. +{
  19736. + remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir);
  19737. + remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
  19738. +}
  19739. +
  19740. +int __init au_procfs_init(void)
  19741. +{
  19742. + int err;
  19743. + struct proc_dir_entry *entry;
  19744. +
  19745. + err = -ENOMEM;
  19746. + au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL);
  19747. + if (unlikely(!au_procfs_dir))
  19748. + goto out;
  19749. +
  19750. + entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | S_IWUSR,
  19751. + au_procfs_dir, &au_procfs_plm_fop);
  19752. + if (unlikely(!entry))
  19753. + goto out_dir;
  19754. +
  19755. + err = 0;
  19756. + goto out; /* success */
  19757. +
  19758. +
  19759. +out_dir:
  19760. + remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
  19761. +out:
  19762. + return err;
  19763. +}
  19764. diff -Nur linux-2.6.37.orig/fs/aufs/rdu.c linux-2.6.37/fs/aufs/rdu.c
  19765. --- linux-2.6.37.orig/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100
  19766. +++ linux-2.6.37/fs/aufs/rdu.c 2011-01-11 20:15:11.000000000 +0100
  19767. @@ -0,0 +1,383 @@
  19768. +/*
  19769. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  19770. + *
  19771. + * This program, aufs is free software; you can redistribute it and/or modify
  19772. + * it under the terms of the GNU General Public License as published by
  19773. + * the Free Software Foundation; either version 2 of the License, or
  19774. + * (at your option) any later version.
  19775. + *
  19776. + * This program is distributed in the hope that it will be useful,
  19777. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19778. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19779. + * GNU General Public License for more details.
  19780. + *
  19781. + * You should have received a copy of the GNU General Public License
  19782. + * along with this program; if not, write to the Free Software
  19783. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  19784. + */
  19785. +
  19786. +/*
  19787. + * readdir in userspace.
  19788. + */
  19789. +
  19790. +#include <linux/compat.h>
  19791. +#include <linux/fs_stack.h>
  19792. +#include <linux/security.h>
  19793. +#include <linux/uaccess.h>
  19794. +#include <linux/aufs_type.h>
  19795. +#include "aufs.h"
  19796. +
  19797. +/* bits for struct aufs_rdu.flags */
  19798. +#define AuRdu_CALLED 1
  19799. +#define AuRdu_CONT (1 << 1)
  19800. +#define AuRdu_FULL (1 << 2)
  19801. +#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name)
  19802. +#define au_fset_rdu(flags, name) \
  19803. + do { (flags) |= AuRdu_##name; } while (0)
  19804. +#define au_fclr_rdu(flags, name) \
  19805. + do { (flags) &= ~AuRdu_##name; } while (0)
  19806. +
  19807. +struct au_rdu_arg {
  19808. + struct aufs_rdu *rdu;
  19809. + union au_rdu_ent_ul ent;
  19810. + unsigned long end;
  19811. +
  19812. + struct super_block *sb;
  19813. + int err;
  19814. +};
  19815. +
  19816. +static int au_rdu_fill(void *__arg, const char *name, int nlen,
  19817. + loff_t offset, u64 h_ino, unsigned int d_type)
  19818. +{
  19819. + int err, len;
  19820. + struct au_rdu_arg *arg = __arg;
  19821. + struct aufs_rdu *rdu = arg->rdu;
  19822. + struct au_rdu_ent ent;
  19823. +
  19824. + err = 0;
  19825. + arg->err = 0;
  19826. + au_fset_rdu(rdu->cookie.flags, CALLED);
  19827. + len = au_rdu_len(nlen);
  19828. + if (arg->ent.ul + len < arg->end) {
  19829. + ent.ino = h_ino;
  19830. + ent.bindex = rdu->cookie.bindex;
  19831. + ent.type = d_type;
  19832. + ent.nlen = nlen;
  19833. + if (unlikely(nlen > AUFS_MAX_NAMELEN))
  19834. + ent.type = DT_UNKNOWN;
  19835. +
  19836. + err = -EFAULT;
  19837. + if (copy_to_user(arg->ent.e, &ent, sizeof(ent)))
  19838. + goto out;
  19839. + if (copy_to_user(arg->ent.e->name, name, nlen))
  19840. + goto out;
  19841. + /* the terminating NULL */
  19842. + if (__put_user(0, arg->ent.e->name + nlen))
  19843. + goto out;
  19844. + err = 0;
  19845. + /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */
  19846. + arg->ent.ul += len;
  19847. + rdu->rent++;
  19848. + } else {
  19849. + err = -EFAULT;
  19850. + au_fset_rdu(rdu->cookie.flags, FULL);
  19851. + rdu->full = 1;
  19852. + rdu->tail = arg->ent;
  19853. + }
  19854. +
  19855. +out:
  19856. + /* AuTraceErr(err); */
  19857. + return err;
  19858. +}
  19859. +
  19860. +static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg)
  19861. +{
  19862. + int err;
  19863. + loff_t offset;
  19864. + struct au_rdu_cookie *cookie = &arg->rdu->cookie;
  19865. +
  19866. + offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET);
  19867. + err = offset;
  19868. + if (unlikely(offset != cookie->h_pos))
  19869. + goto out;
  19870. +
  19871. + err = 0;
  19872. + do {
  19873. + arg->err = 0;
  19874. + au_fclr_rdu(cookie->flags, CALLED);
  19875. + /* smp_mb(); */
  19876. + err = vfsub_readdir(h_file, au_rdu_fill, arg);
  19877. + if (err >= 0)
  19878. + err = arg->err;
  19879. + } while (!err
  19880. + && au_ftest_rdu(cookie->flags, CALLED)
  19881. + && !au_ftest_rdu(cookie->flags, FULL));
  19882. + cookie->h_pos = h_file->f_pos;
  19883. +
  19884. +out:
  19885. + AuTraceErr(err);
  19886. + return err;
  19887. +}
  19888. +
  19889. +static int au_rdu(struct file *file, struct aufs_rdu *rdu)
  19890. +{
  19891. + int err;
  19892. + aufs_bindex_t bend;
  19893. + struct au_rdu_arg arg;
  19894. + struct dentry *dentry;
  19895. + struct inode *inode;
  19896. + struct file *h_file;
  19897. + struct au_rdu_cookie *cookie = &rdu->cookie;
  19898. +
  19899. + err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz);
  19900. + if (unlikely(err)) {
  19901. + err = -EFAULT;
  19902. + AuTraceErr(err);
  19903. + goto out;
  19904. + }
  19905. + rdu->rent = 0;
  19906. + rdu->tail = rdu->ent;
  19907. + rdu->full = 0;
  19908. + arg.rdu = rdu;
  19909. + arg.ent = rdu->ent;
  19910. + arg.end = arg.ent.ul;
  19911. + arg.end += rdu->sz;
  19912. +
  19913. + err = -ENOTDIR;
  19914. + if (unlikely(!file->f_op || !file->f_op->readdir))
  19915. + goto out;
  19916. +
  19917. + err = security_file_permission(file, MAY_READ);
  19918. + AuTraceErr(err);
  19919. + if (unlikely(err))
  19920. + goto out;
  19921. +
  19922. + dentry = file->f_dentry;
  19923. + inode = dentry->d_inode;
  19924. +#if 1
  19925. + mutex_lock(&inode->i_mutex);
  19926. +#else
  19927. + err = mutex_lock_killable(&inode->i_mutex);
  19928. + AuTraceErr(err);
  19929. + if (unlikely(err))
  19930. + goto out;
  19931. +#endif
  19932. +
  19933. + arg.sb = inode->i_sb;
  19934. + err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM);
  19935. + if (unlikely(err))
  19936. + goto out_mtx;
  19937. + err = au_alive_dir(dentry);
  19938. + if (unlikely(err))
  19939. + goto out_si;
  19940. + /* todo: reval? */
  19941. + fi_read_lock(file);
  19942. +
  19943. + err = -EAGAIN;
  19944. + if (unlikely(au_ftest_rdu(cookie->flags, CONT)
  19945. + && cookie->generation != au_figen(file)))
  19946. + goto out_unlock;
  19947. +
  19948. + err = 0;
  19949. + if (!rdu->blk) {
  19950. + rdu->blk = au_sbi(arg.sb)->si_rdblk;
  19951. + if (!rdu->blk)
  19952. + rdu->blk = au_dir_size(file, /*dentry*/NULL);
  19953. + }
  19954. + bend = au_fbstart(file);
  19955. + if (cookie->bindex < bend)
  19956. + cookie->bindex = bend;
  19957. + bend = au_fbend_dir(file);
  19958. + /* AuDbg("b%d, b%d\n", cookie->bindex, bend); */
  19959. + for (; !err && cookie->bindex <= bend;
  19960. + cookie->bindex++, cookie->h_pos = 0) {
  19961. + h_file = au_hf_dir(file, cookie->bindex);
  19962. + if (!h_file)
  19963. + continue;
  19964. +
  19965. + au_fclr_rdu(cookie->flags, FULL);
  19966. + err = au_rdu_do(h_file, &arg);
  19967. + AuTraceErr(err);
  19968. + if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err))
  19969. + break;
  19970. + }
  19971. + AuDbg("rent %llu\n", rdu->rent);
  19972. +
  19973. + if (!err && !au_ftest_rdu(cookie->flags, CONT)) {
  19974. + rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH);
  19975. + au_fset_rdu(cookie->flags, CONT);
  19976. + cookie->generation = au_figen(file);
  19977. + }
  19978. +
  19979. + ii_read_lock_child(inode);
  19980. + fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibstart(inode)));
  19981. + ii_read_unlock(inode);
  19982. +
  19983. +out_unlock:
  19984. + fi_read_unlock(file);
  19985. +out_si:
  19986. + si_read_unlock(arg.sb);
  19987. +out_mtx:
  19988. + mutex_unlock(&inode->i_mutex);
  19989. +out:
  19990. + AuTraceErr(err);
  19991. + return err;
  19992. +}
  19993. +
  19994. +static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu)
  19995. +{
  19996. + int err;
  19997. + ino_t ino;
  19998. + unsigned long long nent;
  19999. + union au_rdu_ent_ul *u;
  20000. + struct au_rdu_ent ent;
  20001. + struct super_block *sb;
  20002. +
  20003. + err = 0;
  20004. + nent = rdu->nent;
  20005. + u = &rdu->ent;
  20006. + sb = file->f_dentry->d_sb;
  20007. + si_read_lock(sb, AuLock_FLUSH);
  20008. + while (nent-- > 0) {
  20009. + err = copy_from_user(&ent, u->e, sizeof(ent));
  20010. + if (!err)
  20011. + err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino));
  20012. + if (unlikely(err)) {
  20013. + err = -EFAULT;
  20014. + AuTraceErr(err);
  20015. + break;
  20016. + }
  20017. +
  20018. + /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */
  20019. + if (!ent.wh)
  20020. + err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino);
  20021. + else
  20022. + err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type,
  20023. + &ino);
  20024. + if (unlikely(err)) {
  20025. + AuTraceErr(err);
  20026. + break;
  20027. + }
  20028. +
  20029. + err = __put_user(ino, &u->e->ino);
  20030. + if (unlikely(err)) {
  20031. + err = -EFAULT;
  20032. + AuTraceErr(err);
  20033. + break;
  20034. + }
  20035. + u->ul += au_rdu_len(ent.nlen);
  20036. + }
  20037. + si_read_unlock(sb);
  20038. +
  20039. + return err;
  20040. +}
  20041. +
  20042. +/* ---------------------------------------------------------------------- */
  20043. +
  20044. +static int au_rdu_verify(struct aufs_rdu *rdu)
  20045. +{
  20046. + AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | "
  20047. + "%llu, b%d, 0x%x, g%u}\n",
  20048. + rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ],
  20049. + rdu->blk,
  20050. + rdu->rent, rdu->shwh, rdu->full,
  20051. + rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags,
  20052. + rdu->cookie.generation);
  20053. +
  20054. + if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu))
  20055. + return 0;
  20056. +
  20057. + AuDbg("%u:%u\n",
  20058. + rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu));
  20059. + return -EINVAL;
  20060. +}
  20061. +
  20062. +long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  20063. +{
  20064. + long err, e;
  20065. + struct aufs_rdu rdu;
  20066. + void __user *p = (void __user *)arg;
  20067. +
  20068. + err = copy_from_user(&rdu, p, sizeof(rdu));
  20069. + if (unlikely(err)) {
  20070. + err = -EFAULT;
  20071. + AuTraceErr(err);
  20072. + goto out;
  20073. + }
  20074. + err = au_rdu_verify(&rdu);
  20075. + if (unlikely(err))
  20076. + goto out;
  20077. +
  20078. + switch (cmd) {
  20079. + case AUFS_CTL_RDU:
  20080. + err = au_rdu(file, &rdu);
  20081. + if (unlikely(err))
  20082. + break;
  20083. +
  20084. + e = copy_to_user(p, &rdu, sizeof(rdu));
  20085. + if (unlikely(e)) {
  20086. + err = -EFAULT;
  20087. + AuTraceErr(err);
  20088. + }
  20089. + break;
  20090. + case AUFS_CTL_RDU_INO:
  20091. + err = au_rdu_ino(file, &rdu);
  20092. + break;
  20093. +
  20094. + default:
  20095. + /* err = -ENOTTY; */
  20096. + err = -EINVAL;
  20097. + }
  20098. +
  20099. +out:
  20100. + AuTraceErr(err);
  20101. + return err;
  20102. +}
  20103. +
  20104. +#ifdef CONFIG_COMPAT
  20105. +long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  20106. +{
  20107. + long err, e;
  20108. + struct aufs_rdu rdu;
  20109. + void __user *p = compat_ptr(arg);
  20110. +
  20111. + /* todo: get_user()? */
  20112. + err = copy_from_user(&rdu, p, sizeof(rdu));
  20113. + if (unlikely(err)) {
  20114. + err = -EFAULT;
  20115. + AuTraceErr(err);
  20116. + goto out;
  20117. + }
  20118. + rdu.ent.e = compat_ptr(rdu.ent.ul);
  20119. + err = au_rdu_verify(&rdu);
  20120. + if (unlikely(err))
  20121. + goto out;
  20122. +
  20123. + switch (cmd) {
  20124. + case AUFS_CTL_RDU:
  20125. + err = au_rdu(file, &rdu);
  20126. + if (unlikely(err))
  20127. + break;
  20128. +
  20129. + rdu.ent.ul = ptr_to_compat(rdu.ent.e);
  20130. + rdu.tail.ul = ptr_to_compat(rdu.tail.e);
  20131. + e = copy_to_user(p, &rdu, sizeof(rdu));
  20132. + if (unlikely(e)) {
  20133. + err = -EFAULT;
  20134. + AuTraceErr(err);
  20135. + }
  20136. + break;
  20137. + case AUFS_CTL_RDU_INO:
  20138. + err = au_rdu_ino(file, &rdu);
  20139. + break;
  20140. +
  20141. + default:
  20142. + /* err = -ENOTTY; */
  20143. + err = -EINVAL;
  20144. + }
  20145. +
  20146. +out:
  20147. + AuTraceErr(err);
  20148. + return err;
  20149. +}
  20150. +#endif
  20151. diff -Nur linux-2.6.37.orig/fs/aufs/rwsem.h linux-2.6.37/fs/aufs/rwsem.h
  20152. --- linux-2.6.37.orig/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100
  20153. +++ linux-2.6.37/fs/aufs/rwsem.h 2011-01-11 20:15:11.000000000 +0100
  20154. @@ -0,0 +1,189 @@
  20155. +/*
  20156. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  20157. + *
  20158. + * This program, aufs is free software; you can redistribute it and/or modify
  20159. + * it under the terms of the GNU General Public License as published by
  20160. + * the Free Software Foundation; either version 2 of the License, or
  20161. + * (at your option) any later version.
  20162. + *
  20163. + * This program is distributed in the hope that it will be useful,
  20164. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20165. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20166. + * GNU General Public License for more details.
  20167. + *
  20168. + * You should have received a copy of the GNU General Public License
  20169. + * along with this program; if not, write to the Free Software
  20170. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20171. + */
  20172. +
  20173. +/*
  20174. + * simple read-write semaphore wrappers
  20175. + */
  20176. +
  20177. +#ifndef __AUFS_RWSEM_H__
  20178. +#define __AUFS_RWSEM_H__
  20179. +
  20180. +#ifdef __KERNEL__
  20181. +
  20182. +#include <linux/rwsem.h>
  20183. +#include "debug.h"
  20184. +
  20185. +struct au_rwsem {
  20186. + struct rw_semaphore rwsem;
  20187. +#ifdef CONFIG_AUFS_DEBUG
  20188. + /* just for debugging, not almighty counter */
  20189. + atomic_t rcnt, wcnt;
  20190. +#endif
  20191. +};
  20192. +
  20193. +#ifdef CONFIG_AUFS_DEBUG
  20194. +#define AuDbgCntInit(rw) do { \
  20195. + atomic_set(&(rw)->rcnt, 0); \
  20196. + atomic_set(&(rw)->wcnt, 0); \
  20197. + smp_mb(); /* atomic set */ \
  20198. +} while (0)
  20199. +
  20200. +#define AuDbgRcntInc(rw) atomic_inc(&(rw)->rcnt)
  20201. +#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0)
  20202. +#define AuDbgWcntInc(rw) atomic_inc(&(rw)->wcnt)
  20203. +#define AuDbgWcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->wcnt) < 0)
  20204. +#else
  20205. +#define AuDbgCntInit(rw) do {} while (0)
  20206. +#define AuDbgRcntInc(rw) do {} while (0)
  20207. +#define AuDbgRcntDec(rw) do {} while (0)
  20208. +#define AuDbgWcntInc(rw) do {} while (0)
  20209. +#define AuDbgWcntDec(rw) do {} while (0)
  20210. +#endif /* CONFIG_AUFS_DEBUG */
  20211. +
  20212. +/* to debug easier, do not make them inlined functions */
  20213. +#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->rwsem.wait_list))
  20214. +/* rwsem_is_locked() is unusable */
  20215. +#define AuRwMustReadLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0)
  20216. +#define AuRwMustWriteLock(rw) AuDebugOn(atomic_read(&(rw)->wcnt) <= 0)
  20217. +#define AuRwMustAnyLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0 \
  20218. + && atomic_read(&(rw)->wcnt) <= 0)
  20219. +#define AuRwDestroy(rw) AuDebugOn(atomic_read(&(rw)->rcnt) \
  20220. + || atomic_read(&(rw)->wcnt))
  20221. +
  20222. +#define au_rw_class(rw, key) lockdep_set_class(&(rw)->rwsem, key)
  20223. +
  20224. +static inline void au_rw_init(struct au_rwsem *rw)
  20225. +{
  20226. + AuDbgCntInit(rw);
  20227. + init_rwsem(&rw->rwsem);
  20228. +}
  20229. +
  20230. +static inline void au_rw_init_wlock(struct au_rwsem *rw)
  20231. +{
  20232. + au_rw_init(rw);
  20233. + down_write(&rw->rwsem);
  20234. + AuDbgWcntInc(rw);
  20235. +}
  20236. +
  20237. +static inline void au_rw_init_wlock_nested(struct au_rwsem *rw,
  20238. + unsigned int lsc)
  20239. +{
  20240. + au_rw_init(rw);
  20241. + down_write_nested(&rw->rwsem, lsc);
  20242. + AuDbgWcntInc(rw);
  20243. +}
  20244. +
  20245. +static inline void au_rw_read_lock(struct au_rwsem *rw)
  20246. +{
  20247. + down_read(&rw->rwsem);
  20248. + AuDbgRcntInc(rw);
  20249. +}
  20250. +
  20251. +static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc)
  20252. +{
  20253. + down_read_nested(&rw->rwsem, lsc);
  20254. + AuDbgRcntInc(rw);
  20255. +}
  20256. +
  20257. +static inline void au_rw_read_unlock(struct au_rwsem *rw)
  20258. +{
  20259. + AuRwMustReadLock(rw);
  20260. + AuDbgRcntDec(rw);
  20261. + up_read(&rw->rwsem);
  20262. +}
  20263. +
  20264. +static inline void au_rw_dgrade_lock(struct au_rwsem *rw)
  20265. +{
  20266. + AuRwMustWriteLock(rw);
  20267. + AuDbgRcntInc(rw);
  20268. + AuDbgWcntDec(rw);
  20269. + downgrade_write(&rw->rwsem);
  20270. +}
  20271. +
  20272. +static inline void au_rw_write_lock(struct au_rwsem *rw)
  20273. +{
  20274. + down_write(&rw->rwsem);
  20275. + AuDbgWcntInc(rw);
  20276. +}
  20277. +
  20278. +static inline void au_rw_write_lock_nested(struct au_rwsem *rw,
  20279. + unsigned int lsc)
  20280. +{
  20281. + down_write_nested(&rw->rwsem, lsc);
  20282. + AuDbgWcntInc(rw);
  20283. +}
  20284. +
  20285. +static inline void au_rw_write_unlock(struct au_rwsem *rw)
  20286. +{
  20287. + AuRwMustWriteLock(rw);
  20288. + AuDbgWcntDec(rw);
  20289. + up_write(&rw->rwsem);
  20290. +}
  20291. +
  20292. +/* why is not _nested version defined */
  20293. +static inline int au_rw_read_trylock(struct au_rwsem *rw)
  20294. +{
  20295. + int ret = down_read_trylock(&rw->rwsem);
  20296. + if (ret)
  20297. + AuDbgRcntInc(rw);
  20298. + return ret;
  20299. +}
  20300. +
  20301. +static inline int au_rw_write_trylock(struct au_rwsem *rw)
  20302. +{
  20303. + int ret = down_write_trylock(&rw->rwsem);
  20304. + if (ret)
  20305. + AuDbgWcntInc(rw);
  20306. + return ret;
  20307. +}
  20308. +
  20309. +#undef AuDbgCntInit
  20310. +#undef AuDbgRcntInc
  20311. +#undef AuDbgRcntDec
  20312. +#undef AuDbgWcntInc
  20313. +#undef AuDbgWcntDec
  20314. +
  20315. +#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
  20316. +static inline void prefix##_read_lock(param) \
  20317. +{ au_rw_read_lock(rwsem); } \
  20318. +static inline void prefix##_write_lock(param) \
  20319. +{ au_rw_write_lock(rwsem); } \
  20320. +static inline int prefix##_read_trylock(param) \
  20321. +{ return au_rw_read_trylock(rwsem); } \
  20322. +static inline int prefix##_write_trylock(param) \
  20323. +{ return au_rw_write_trylock(rwsem); }
  20324. +/* why is not _nested version defined */
  20325. +/* static inline void prefix##_read_trylock_nested(param, lsc)
  20326. +{ au_rw_read_trylock_nested(rwsem, lsc)); }
  20327. +static inline void prefix##_write_trylock_nestd(param, lsc)
  20328. +{ au_rw_write_trylock_nested(rwsem, lsc); } */
  20329. +
  20330. +#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
  20331. +static inline void prefix##_read_unlock(param) \
  20332. +{ au_rw_read_unlock(rwsem); } \
  20333. +static inline void prefix##_write_unlock(param) \
  20334. +{ au_rw_write_unlock(rwsem); } \
  20335. +static inline void prefix##_downgrade_lock(param) \
  20336. +{ au_rw_dgrade_lock(rwsem); }
  20337. +
  20338. +#define AuSimpleRwsemFuncs(prefix, param, rwsem) \
  20339. + AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
  20340. + AuSimpleUnlockRwsemFuncs(prefix, param, rwsem)
  20341. +
  20342. +#endif /* __KERNEL__ */
  20343. +#endif /* __AUFS_RWSEM_H__ */
  20344. diff -Nur linux-2.6.37.orig/fs/aufs/sbinfo.c linux-2.6.37/fs/aufs/sbinfo.c
  20345. --- linux-2.6.37.orig/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100
  20346. +++ linux-2.6.37/fs/aufs/sbinfo.c 2011-01-11 20:15:11.000000000 +0100
  20347. @@ -0,0 +1,345 @@
  20348. +/*
  20349. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  20350. + *
  20351. + * This program, aufs is free software; you can redistribute it and/or modify
  20352. + * it under the terms of the GNU General Public License as published by
  20353. + * the Free Software Foundation; either version 2 of the License, or
  20354. + * (at your option) any later version.
  20355. + *
  20356. + * This program is distributed in the hope that it will be useful,
  20357. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20358. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20359. + * GNU General Public License for more details.
  20360. + *
  20361. + * You should have received a copy of the GNU General Public License
  20362. + * along with this program; if not, write to the Free Software
  20363. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20364. + */
  20365. +
  20366. +/*
  20367. + * superblock private data
  20368. + */
  20369. +
  20370. +#include <linux/jiffies.h>
  20371. +#include "aufs.h"
  20372. +
  20373. +/*
  20374. + * they are necessary regardless sysfs is disabled.
  20375. + */
  20376. +void au_si_free(struct kobject *kobj)
  20377. +{
  20378. + struct au_sbinfo *sbinfo;
  20379. + char *locked __maybe_unused; /* debug only */
  20380. +
  20381. + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
  20382. + AuDebugOn(!list_empty(&sbinfo->si_plink.head));
  20383. + AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
  20384. +
  20385. + au_rw_write_lock(&sbinfo->si_rwsem);
  20386. + au_br_free(sbinfo);
  20387. + au_rw_write_unlock(&sbinfo->si_rwsem);
  20388. +
  20389. + AuDebugOn(radix_tree_gang_lookup
  20390. + (&sbinfo->au_si_pid.tree, (void **)&locked,
  20391. + /*first_index*/PID_MAX_DEFAULT - 1,
  20392. + /*max_items*/sizeof(locked)/sizeof(*locked)));
  20393. +
  20394. + kfree(sbinfo->si_branch);
  20395. + kfree(sbinfo->au_si_pid.bitmap);
  20396. + mutex_destroy(&sbinfo->si_xib_mtx);
  20397. + AuRwDestroy(&sbinfo->si_rwsem);
  20398. +
  20399. + kfree(sbinfo);
  20400. +}
  20401. +
  20402. +int au_si_alloc(struct super_block *sb)
  20403. +{
  20404. + int err;
  20405. + struct au_sbinfo *sbinfo;
  20406. + static struct lock_class_key aufs_si;
  20407. +
  20408. + err = -ENOMEM;
  20409. + sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS);
  20410. + if (unlikely(!sbinfo))
  20411. + goto out;
  20412. +
  20413. + BUILD_BUG_ON(sizeof(unsigned long) !=
  20414. + sizeof(*sbinfo->au_si_pid.bitmap));
  20415. + sbinfo->au_si_pid.bitmap = kcalloc(BITS_TO_LONGS(PID_MAX_DEFAULT),
  20416. + sizeof(*sbinfo->au_si_pid.bitmap),
  20417. + GFP_NOFS);
  20418. + if (unlikely(!sbinfo->au_si_pid.bitmap))
  20419. + goto out_sbinfo;
  20420. +
  20421. + /* will be reallocated separately */
  20422. + sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
  20423. + if (unlikely(!sbinfo->si_branch))
  20424. + goto out_pidmap;
  20425. +
  20426. + err = sysaufs_si_init(sbinfo);
  20427. + if (unlikely(err))
  20428. + goto out_br;
  20429. +
  20430. + au_nwt_init(&sbinfo->si_nowait);
  20431. + au_rw_init_wlock(&sbinfo->si_rwsem);
  20432. + au_rw_class(&sbinfo->si_rwsem, &aufs_si);
  20433. + spin_lock_init(&sbinfo->au_si_pid.tree_lock);
  20434. + INIT_RADIX_TREE(&sbinfo->au_si_pid.tree, GFP_ATOMIC | __GFP_NOFAIL);
  20435. +
  20436. + atomic_long_set(&sbinfo->si_ninodes, 0);
  20437. + atomic_long_set(&sbinfo->si_nfiles, 0);
  20438. +
  20439. + sbinfo->si_bend = -1;
  20440. +
  20441. + sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
  20442. + sbinfo->si_wbr_create = AuWbrCreate_Def;
  20443. + sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup;
  20444. + sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create;
  20445. +
  20446. + sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
  20447. +
  20448. + mutex_init(&sbinfo->si_xib_mtx);
  20449. + sbinfo->si_xino_brid = -1;
  20450. + /* leave si_xib_last_pindex and si_xib_next_bit */
  20451. +
  20452. + sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
  20453. + sbinfo->si_rdblk = AUFS_RDBLK_DEF;
  20454. + sbinfo->si_rdhash = AUFS_RDHASH_DEF;
  20455. + sbinfo->si_dirwh = AUFS_DIRWH_DEF;
  20456. +
  20457. + au_spl_init(&sbinfo->si_plink);
  20458. + init_waitqueue_head(&sbinfo->si_plink_wq);
  20459. + spin_lock_init(&sbinfo->si_plink_maint_lock);
  20460. +
  20461. + /* leave other members for sysaufs and si_mnt. */
  20462. + sbinfo->si_sb = sb;
  20463. + sb->s_fs_info = sbinfo;
  20464. + si_pid_set(sb);
  20465. + au_debug_sbinfo_init(sbinfo);
  20466. + return 0; /* success */
  20467. +
  20468. +out_br:
  20469. + kfree(sbinfo->si_branch);
  20470. +out_pidmap:
  20471. + kfree(sbinfo->au_si_pid.bitmap);
  20472. +out_sbinfo:
  20473. + kfree(sbinfo);
  20474. +out:
  20475. + return err;
  20476. +}
  20477. +
  20478. +int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr)
  20479. +{
  20480. + int err, sz;
  20481. + struct au_branch **brp;
  20482. +
  20483. + AuRwMustWriteLock(&sbinfo->si_rwsem);
  20484. +
  20485. + err = -ENOMEM;
  20486. + sz = sizeof(*brp) * (sbinfo->si_bend + 1);
  20487. + if (unlikely(!sz))
  20488. + sz = sizeof(*brp);
  20489. + brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS);
  20490. + if (brp) {
  20491. + sbinfo->si_branch = brp;
  20492. + err = 0;
  20493. + }
  20494. +
  20495. + return err;
  20496. +}
  20497. +
  20498. +/* ---------------------------------------------------------------------- */
  20499. +
  20500. +unsigned int au_sigen_inc(struct super_block *sb)
  20501. +{
  20502. + unsigned int gen;
  20503. +
  20504. + SiMustWriteLock(sb);
  20505. +
  20506. + gen = ++au_sbi(sb)->si_generation;
  20507. + au_update_digen(sb->s_root);
  20508. + au_update_iigen(sb->s_root->d_inode);
  20509. + sb->s_root->d_inode->i_version++;
  20510. + return gen;
  20511. +}
  20512. +
  20513. +aufs_bindex_t au_new_br_id(struct super_block *sb)
  20514. +{
  20515. + aufs_bindex_t br_id;
  20516. + int i;
  20517. + struct au_sbinfo *sbinfo;
  20518. +
  20519. + SiMustWriteLock(sb);
  20520. +
  20521. + sbinfo = au_sbi(sb);
  20522. + for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
  20523. + br_id = ++sbinfo->si_last_br_id;
  20524. + AuDebugOn(br_id < 0);
  20525. + if (br_id && au_br_index(sb, br_id) < 0)
  20526. + return br_id;
  20527. + }
  20528. +
  20529. + return -1;
  20530. +}
  20531. +
  20532. +/* ---------------------------------------------------------------------- */
  20533. +
  20534. +/* it is ok that new 'nwt' tasks are appended while we are sleeping */
  20535. +int si_read_lock(struct super_block *sb, int flags)
  20536. +{
  20537. + int err;
  20538. +
  20539. + err = 0;
  20540. + if (au_ftest_lock(flags, FLUSH))
  20541. + au_nwt_flush(&au_sbi(sb)->si_nowait);
  20542. +
  20543. + si_noflush_read_lock(sb);
  20544. + err = au_plink_maint(sb, flags);
  20545. + if (unlikely(err))
  20546. + si_read_unlock(sb);
  20547. +
  20548. + return err;
  20549. +}
  20550. +
  20551. +int si_write_lock(struct super_block *sb, int flags)
  20552. +{
  20553. + int err;
  20554. +
  20555. + if (au_ftest_lock(flags, FLUSH))
  20556. + au_nwt_flush(&au_sbi(sb)->si_nowait);
  20557. +
  20558. + si_noflush_write_lock(sb);
  20559. + err = au_plink_maint(sb, flags);
  20560. + if (unlikely(err))
  20561. + si_write_unlock(sb);
  20562. +
  20563. + return err;
  20564. +}
  20565. +
  20566. +/* dentry and super_block lock. call at entry point */
  20567. +int aufs_read_lock(struct dentry *dentry, int flags)
  20568. +{
  20569. + int err;
  20570. + struct super_block *sb;
  20571. +
  20572. + sb = dentry->d_sb;
  20573. + err = si_read_lock(sb, flags);
  20574. + if (unlikely(err))
  20575. + goto out;
  20576. +
  20577. + if (au_ftest_lock(flags, DW))
  20578. + di_write_lock_child(dentry);
  20579. + else
  20580. + di_read_lock_child(dentry, flags);
  20581. +
  20582. + if (au_ftest_lock(flags, GEN)) {
  20583. + err = au_digen_test(dentry, au_sigen(sb));
  20584. + AuDebugOn(!err && au_dbrange_test(dentry));
  20585. + if (unlikely(err))
  20586. + aufs_read_unlock(dentry, flags);
  20587. + }
  20588. +
  20589. +out:
  20590. + return err;
  20591. +}
  20592. +
  20593. +void aufs_read_unlock(struct dentry *dentry, int flags)
  20594. +{
  20595. + if (au_ftest_lock(flags, DW))
  20596. + di_write_unlock(dentry);
  20597. + else
  20598. + di_read_unlock(dentry, flags);
  20599. + si_read_unlock(dentry->d_sb);
  20600. +}
  20601. +
  20602. +void aufs_write_lock(struct dentry *dentry)
  20603. +{
  20604. + si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW);
  20605. + di_write_lock_child(dentry);
  20606. +}
  20607. +
  20608. +void aufs_write_unlock(struct dentry *dentry)
  20609. +{
  20610. + di_write_unlock(dentry);
  20611. + si_write_unlock(dentry->d_sb);
  20612. +}
  20613. +
  20614. +int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
  20615. +{
  20616. + int err;
  20617. + unsigned int sigen;
  20618. + struct super_block *sb;
  20619. +
  20620. + sb = d1->d_sb;
  20621. + err = si_read_lock(sb, flags);
  20622. + if (unlikely(err))
  20623. + goto out;
  20624. +
  20625. + di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR));
  20626. +
  20627. + if (au_ftest_lock(flags, GEN)) {
  20628. + sigen = au_sigen(sb);
  20629. + err = au_digen_test(d1, sigen);
  20630. + AuDebugOn(!err && au_dbrange_test(d1));
  20631. + if (!err) {
  20632. + err = au_digen_test(d2, sigen);
  20633. + AuDebugOn(!err && au_dbrange_test(d2));
  20634. + }
  20635. + if (unlikely(err))
  20636. + aufs_read_and_write_unlock2(d1, d2);
  20637. + }
  20638. +
  20639. +out:
  20640. + return err;
  20641. +}
  20642. +
  20643. +void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
  20644. +{
  20645. + di_write_unlock2(d1, d2);
  20646. + si_read_unlock(d1->d_sb);
  20647. +}
  20648. +
  20649. +/* ---------------------------------------------------------------------- */
  20650. +
  20651. +int si_pid_test_slow(struct super_block *sb)
  20652. +{
  20653. + void *p;
  20654. +
  20655. + rcu_read_lock();
  20656. + p = radix_tree_lookup(&au_sbi(sb)->au_si_pid.tree, current->pid);
  20657. + rcu_read_unlock();
  20658. +
  20659. + return (long)p;
  20660. +}
  20661. +
  20662. +void si_pid_set_slow(struct super_block *sb)
  20663. +{
  20664. + int err;
  20665. + struct au_sbinfo *sbinfo;
  20666. +
  20667. + AuDebugOn(si_pid_test_slow(sb));
  20668. +
  20669. + sbinfo = au_sbi(sb);
  20670. + err = radix_tree_preload(GFP_NOFS | __GFP_NOFAIL);
  20671. + AuDebugOn(err);
  20672. + spin_lock(&sbinfo->au_si_pid.tree_lock);
  20673. + err = radix_tree_insert(&sbinfo->au_si_pid.tree, current->pid,
  20674. + (void *)1);
  20675. + spin_unlock(&sbinfo->au_si_pid.tree_lock);
  20676. + AuDebugOn(err);
  20677. + radix_tree_preload_end();
  20678. +}
  20679. +
  20680. +void si_pid_clr_slow(struct super_block *sb)
  20681. +{
  20682. + void *p;
  20683. + struct au_sbinfo *sbinfo;
  20684. +
  20685. + AuDebugOn(!si_pid_test_slow(sb));
  20686. +
  20687. + sbinfo = au_sbi(sb);
  20688. + spin_lock(&sbinfo->au_si_pid.tree_lock);
  20689. + p = radix_tree_delete(&sbinfo->au_si_pid.tree, current->pid);
  20690. + spin_unlock(&sbinfo->au_si_pid.tree_lock);
  20691. + AuDebugOn(1 != (long)p);
  20692. +}
  20693. diff -Nur linux-2.6.37.orig/fs/aufs/spl.h linux-2.6.37/fs/aufs/spl.h
  20694. --- linux-2.6.37.orig/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100
  20695. +++ linux-2.6.37/fs/aufs/spl.h 2011-01-11 20:15:11.000000000 +0100
  20696. @@ -0,0 +1,66 @@
  20697. +/*
  20698. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  20699. + *
  20700. + * This program, aufs is free software; you can redistribute it and/or modify
  20701. + * it under the terms of the GNU General Public License as published by
  20702. + * the Free Software Foundation; either version 2 of the License, or
  20703. + * (at your option) any later version.
  20704. + *
  20705. + * This program is distributed in the hope that it will be useful,
  20706. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20707. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20708. + * GNU General Public License for more details.
  20709. + *
  20710. + * You should have received a copy of the GNU General Public License
  20711. + * along with this program; if not, write to the Free Software
  20712. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20713. + */
  20714. +
  20715. +/*
  20716. + * simple list protected by a spinlock
  20717. + */
  20718. +
  20719. +#ifndef __AUFS_SPL_H__
  20720. +#define __AUFS_SPL_H__
  20721. +
  20722. +#ifdef __KERNEL__
  20723. +
  20724. +#include <linux/spinlock.h>
  20725. +#include <linux/list.h>
  20726. +#include <linux/rculist.h>
  20727. +
  20728. +struct au_splhead {
  20729. + spinlock_t spin;
  20730. + struct list_head head;
  20731. +};
  20732. +
  20733. +static inline void au_spl_init(struct au_splhead *spl)
  20734. +{
  20735. + spin_lock_init(&spl->spin);
  20736. + INIT_LIST_HEAD(&spl->head);
  20737. +}
  20738. +
  20739. +static inline void au_spl_add(struct list_head *list, struct au_splhead *spl)
  20740. +{
  20741. + spin_lock(&spl->spin);
  20742. + list_add(list, &spl->head);
  20743. + spin_unlock(&spl->spin);
  20744. +}
  20745. +
  20746. +static inline void au_spl_del(struct list_head *list, struct au_splhead *spl)
  20747. +{
  20748. + spin_lock(&spl->spin);
  20749. + list_del(list);
  20750. + spin_unlock(&spl->spin);
  20751. +}
  20752. +
  20753. +static inline void au_spl_del_rcu(struct list_head *list,
  20754. + struct au_splhead *spl)
  20755. +{
  20756. + spin_lock(&spl->spin);
  20757. + list_del_rcu(list);
  20758. + spin_unlock(&spl->spin);
  20759. +}
  20760. +
  20761. +#endif /* __KERNEL__ */
  20762. +#endif /* __AUFS_SPL_H__ */
  20763. diff -Nur linux-2.6.37.orig/fs/aufs/super.c linux-2.6.37/fs/aufs/super.c
  20764. --- linux-2.6.37.orig/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
  20765. +++ linux-2.6.37/fs/aufs/super.c 2011-01-11 20:15:11.000000000 +0100
  20766. @@ -0,0 +1,913 @@
  20767. +/*
  20768. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  20769. + *
  20770. + * This program, aufs is free software; you can redistribute it and/or modify
  20771. + * it under the terms of the GNU General Public License as published by
  20772. + * the Free Software Foundation; either version 2 of the License, or
  20773. + * (at your option) any later version.
  20774. + *
  20775. + * This program is distributed in the hope that it will be useful,
  20776. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20777. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20778. + * GNU General Public License for more details.
  20779. + *
  20780. + * You should have received a copy of the GNU General Public License
  20781. + * along with this program; if not, write to the Free Software
  20782. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20783. + */
  20784. +
  20785. +/*
  20786. + * mount and super_block operations
  20787. + */
  20788. +
  20789. +#include <linux/buffer_head.h>
  20790. +#include <linux/jiffies.h>
  20791. +#include <linux/module.h>
  20792. +#include <linux/seq_file.h>
  20793. +#include <linux/statfs.h>
  20794. +#include <linux/vmalloc.h>
  20795. +#include <linux/writeback.h>
  20796. +#include "aufs.h"
  20797. +
  20798. +/*
  20799. + * super_operations
  20800. + */
  20801. +static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
  20802. +{
  20803. + struct au_icntnr *c;
  20804. +
  20805. + c = au_cache_alloc_icntnr();
  20806. + if (c) {
  20807. + au_icntnr_init(c);
  20808. + c->vfs_inode.i_version = 1; /* sigen(sb); */
  20809. + c->iinfo.ii_hinode = NULL;
  20810. + return &c->vfs_inode;
  20811. + }
  20812. + return NULL;
  20813. +}
  20814. +
  20815. +static void aufs_destroy_inode(struct inode *inode)
  20816. +{
  20817. + au_iinfo_fin(inode);
  20818. + au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
  20819. +}
  20820. +
  20821. +struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
  20822. +{
  20823. + struct inode *inode;
  20824. + int err;
  20825. +
  20826. + inode = iget_locked(sb, ino);
  20827. + if (unlikely(!inode)) {
  20828. + inode = ERR_PTR(-ENOMEM);
  20829. + goto out;
  20830. + }
  20831. + if (!(inode->i_state & I_NEW))
  20832. + goto out;
  20833. +
  20834. + err = au_xigen_new(inode);
  20835. + if (!err)
  20836. + err = au_iinfo_init(inode);
  20837. + if (!err)
  20838. + inode->i_version++;
  20839. + else {
  20840. + iget_failed(inode);
  20841. + inode = ERR_PTR(err);
  20842. + }
  20843. +
  20844. +out:
  20845. + /* never return NULL */
  20846. + AuDebugOn(!inode);
  20847. + AuTraceErrPtr(inode);
  20848. + return inode;
  20849. +}
  20850. +
  20851. +/* lock free root dinfo */
  20852. +static int au_show_brs(struct seq_file *seq, struct super_block *sb)
  20853. +{
  20854. + int err;
  20855. + aufs_bindex_t bindex, bend;
  20856. + struct path path;
  20857. + struct au_hdentry *hdp;
  20858. + struct au_branch *br;
  20859. +
  20860. + err = 0;
  20861. + bend = au_sbend(sb);
  20862. + hdp = au_di(sb->s_root)->di_hdentry;
  20863. + for (bindex = 0; !err && bindex <= bend; bindex++) {
  20864. + br = au_sbr(sb, bindex);
  20865. + path.mnt = br->br_mnt;
  20866. + path.dentry = hdp[bindex].hd_dentry;
  20867. + err = au_seq_path(seq, &path);
  20868. + if (err > 0)
  20869. + err = seq_printf(seq, "=%s",
  20870. + au_optstr_br_perm(br->br_perm));
  20871. + if (!err && bindex != bend)
  20872. + err = seq_putc(seq, ':');
  20873. + }
  20874. +
  20875. + return err;
  20876. +}
  20877. +
  20878. +static void au_show_wbr_create(struct seq_file *m, int v,
  20879. + struct au_sbinfo *sbinfo)
  20880. +{
  20881. + const char *pat;
  20882. +
  20883. + AuRwMustAnyLock(&sbinfo->si_rwsem);
  20884. +
  20885. + seq_printf(m, ",create=");
  20886. + pat = au_optstr_wbr_create(v);
  20887. + switch (v) {
  20888. + case AuWbrCreate_TDP:
  20889. + case AuWbrCreate_RR:
  20890. + case AuWbrCreate_MFS:
  20891. + case AuWbrCreate_PMFS:
  20892. + seq_printf(m, pat);
  20893. + break;
  20894. + case AuWbrCreate_MFSV:
  20895. + seq_printf(m, /*pat*/"mfs:%lu",
  20896. + jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
  20897. + / MSEC_PER_SEC);
  20898. + break;
  20899. + case AuWbrCreate_PMFSV:
  20900. + seq_printf(m, /*pat*/"pmfs:%lu",
  20901. + jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
  20902. + / MSEC_PER_SEC);
  20903. + break;
  20904. + case AuWbrCreate_MFSRR:
  20905. + seq_printf(m, /*pat*/"mfsrr:%llu",
  20906. + sbinfo->si_wbr_mfs.mfsrr_watermark);
  20907. + break;
  20908. + case AuWbrCreate_MFSRRV:
  20909. + seq_printf(m, /*pat*/"mfsrr:%llu:%lu",
  20910. + sbinfo->si_wbr_mfs.mfsrr_watermark,
  20911. + jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
  20912. + / MSEC_PER_SEC);
  20913. + break;
  20914. + }
  20915. +}
  20916. +
  20917. +static int au_show_xino(struct seq_file *seq, struct vfsmount *mnt)
  20918. +{
  20919. +#ifdef CONFIG_SYSFS
  20920. + return 0;
  20921. +#else
  20922. + int err;
  20923. + const int len = sizeof(AUFS_XINO_FNAME) - 1;
  20924. + aufs_bindex_t bindex, brid;
  20925. + struct super_block *sb;
  20926. + struct qstr *name;
  20927. + struct file *f;
  20928. + struct dentry *d, *h_root;
  20929. + struct au_hdentry *hdp;
  20930. +
  20931. + AuRwMustAnyLock(&sbinfo->si_rwsem);
  20932. +
  20933. + err = 0;
  20934. + sb = mnt->mnt_sb;
  20935. + f = au_sbi(sb)->si_xib;
  20936. + if (!f)
  20937. + goto out;
  20938. +
  20939. + /* stop printing the default xino path on the first writable branch */
  20940. + h_root = NULL;
  20941. + brid = au_xino_brid(sb);
  20942. + if (brid >= 0) {
  20943. + bindex = au_br_index(sb, brid);
  20944. + hdp = au_di(sb->s_root)->di_hdentry;
  20945. + h_root = hdp[0 + bindex].hd_dentry;
  20946. + }
  20947. + d = f->f_dentry;
  20948. + name = &d->d_name;
  20949. + /* safe ->d_parent because the file is unlinked */
  20950. + if (d->d_parent == h_root
  20951. + && name->len == len
  20952. + && !memcmp(name->name, AUFS_XINO_FNAME, len))
  20953. + goto out;
  20954. +
  20955. + seq_puts(seq, ",xino=");
  20956. + err = au_xino_path(seq, f);
  20957. +
  20958. +out:
  20959. + return err;
  20960. +#endif
  20961. +}
  20962. +
  20963. +/* seq_file will re-call me in case of too long string */
  20964. +static int aufs_show_options(struct seq_file *m, struct vfsmount *mnt)
  20965. +{
  20966. + int err;
  20967. + unsigned int mnt_flags, v;
  20968. + struct super_block *sb;
  20969. + struct au_sbinfo *sbinfo;
  20970. +
  20971. +#define AuBool(name, str) do { \
  20972. + v = au_opt_test(mnt_flags, name); \
  20973. + if (v != au_opt_test(AuOpt_Def, name)) \
  20974. + seq_printf(m, ",%s" #str, v ? "" : "no"); \
  20975. +} while (0)
  20976. +
  20977. +#define AuStr(name, str) do { \
  20978. + v = mnt_flags & AuOptMask_##name; \
  20979. + if (v != (AuOpt_Def & AuOptMask_##name)) \
  20980. + seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
  20981. +} while (0)
  20982. +
  20983. +#define AuUInt(name, str, val) do { \
  20984. + if (val != AUFS_##name##_DEF) \
  20985. + seq_printf(m, "," #str "=%u", val); \
  20986. +} while (0)
  20987. +
  20988. + /* lock free root dinfo */
  20989. + sb = mnt->mnt_sb;
  20990. + si_noflush_read_lock(sb);
  20991. + sbinfo = au_sbi(sb);
  20992. + seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
  20993. +
  20994. + mnt_flags = au_mntflags(sb);
  20995. + if (au_opt_test(mnt_flags, XINO)) {
  20996. + err = au_show_xino(m, mnt);
  20997. + if (unlikely(err))
  20998. + goto out;
  20999. + } else
  21000. + seq_puts(m, ",noxino");
  21001. +
  21002. + AuBool(TRUNC_XINO, trunc_xino);
  21003. + AuStr(UDBA, udba);
  21004. + AuBool(SHWH, shwh);
  21005. + AuBool(PLINK, plink);
  21006. + AuBool(DIO, dio);
  21007. + /* AuBool(DIRPERM1, dirperm1); */
  21008. + /* AuBool(REFROF, refrof); */
  21009. +
  21010. + v = sbinfo->si_wbr_create;
  21011. + if (v != AuWbrCreate_Def)
  21012. + au_show_wbr_create(m, v, sbinfo);
  21013. +
  21014. + v = sbinfo->si_wbr_copyup;
  21015. + if (v != AuWbrCopyup_Def)
  21016. + seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
  21017. +
  21018. + v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
  21019. + if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
  21020. + seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
  21021. +
  21022. + AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
  21023. +
  21024. + v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC;
  21025. + AuUInt(RDCACHE, rdcache, v);
  21026. +
  21027. + AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
  21028. + AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
  21029. +
  21030. + AuBool(SUM, sum);
  21031. + /* AuBool(SUM_W, wsum); */
  21032. + AuBool(WARN_PERM, warn_perm);
  21033. + AuBool(VERBOSE, verbose);
  21034. +
  21035. +out:
  21036. + /* be sure to print "br:" last */
  21037. + if (!sysaufs_brs) {
  21038. + seq_puts(m, ",br:");
  21039. + au_show_brs(m, sb);
  21040. + }
  21041. + si_read_unlock(sb);
  21042. + return 0;
  21043. +
  21044. +#undef AuBool
  21045. +#undef AuStr
  21046. +#undef AuUInt
  21047. +}
  21048. +
  21049. +/* ---------------------------------------------------------------------- */
  21050. +
  21051. +/* sum mode which returns the summation for statfs(2) */
  21052. +
  21053. +static u64 au_add_till_max(u64 a, u64 b)
  21054. +{
  21055. + u64 old;
  21056. +
  21057. + old = a;
  21058. + a += b;
  21059. + if (old < a)
  21060. + return a;
  21061. + return ULLONG_MAX;
  21062. +}
  21063. +
  21064. +static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
  21065. +{
  21066. + int err;
  21067. + u64 blocks, bfree, bavail, files, ffree;
  21068. + aufs_bindex_t bend, bindex, i;
  21069. + unsigned char shared;
  21070. + struct path h_path;
  21071. + struct super_block *h_sb;
  21072. +
  21073. + blocks = 0;
  21074. + bfree = 0;
  21075. + bavail = 0;
  21076. + files = 0;
  21077. + ffree = 0;
  21078. +
  21079. + err = 0;
  21080. + bend = au_sbend(sb);
  21081. + for (bindex = bend; bindex >= 0; bindex--) {
  21082. + h_path.mnt = au_sbr_mnt(sb, bindex);
  21083. + h_sb = h_path.mnt->mnt_sb;
  21084. + shared = 0;
  21085. + for (i = bindex + 1; !shared && i <= bend; i++)
  21086. + shared = (au_sbr_sb(sb, i) == h_sb);
  21087. + if (shared)
  21088. + continue;
  21089. +
  21090. + /* sb->s_root for NFS is unreliable */
  21091. + h_path.dentry = h_path.mnt->mnt_root;
  21092. + err = vfs_statfs(&h_path, buf);
  21093. + if (unlikely(err))
  21094. + goto out;
  21095. +
  21096. + blocks = au_add_till_max(blocks, buf->f_blocks);
  21097. + bfree = au_add_till_max(bfree, buf->f_bfree);
  21098. + bavail = au_add_till_max(bavail, buf->f_bavail);
  21099. + files = au_add_till_max(files, buf->f_files);
  21100. + ffree = au_add_till_max(ffree, buf->f_ffree);
  21101. + }
  21102. +
  21103. + buf->f_blocks = blocks;
  21104. + buf->f_bfree = bfree;
  21105. + buf->f_bavail = bavail;
  21106. + buf->f_files = files;
  21107. + buf->f_ffree = ffree;
  21108. +
  21109. +out:
  21110. + return err;
  21111. +}
  21112. +
  21113. +static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
  21114. +{
  21115. + int err;
  21116. + struct path h_path;
  21117. + struct super_block *sb;
  21118. +
  21119. + /* lock free root dinfo */
  21120. + sb = dentry->d_sb;
  21121. + si_noflush_read_lock(sb);
  21122. + if (!au_opt_test(au_mntflags(sb), SUM)) {
  21123. + /* sb->s_root for NFS is unreliable */
  21124. + h_path.mnt = au_sbr_mnt(sb, 0);
  21125. + h_path.dentry = h_path.mnt->mnt_root;
  21126. + err = vfs_statfs(&h_path, buf);
  21127. + } else
  21128. + err = au_statfs_sum(sb, buf);
  21129. + si_read_unlock(sb);
  21130. +
  21131. + if (!err) {
  21132. + buf->f_type = AUFS_SUPER_MAGIC;
  21133. + buf->f_namelen = AUFS_MAX_NAMELEN;
  21134. + memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
  21135. + }
  21136. + /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
  21137. +
  21138. + return err;
  21139. +}
  21140. +
  21141. +/* ---------------------------------------------------------------------- */
  21142. +
  21143. +/* final actions when unmounting a file system */
  21144. +static void aufs_put_super(struct super_block *sb)
  21145. +{
  21146. + struct au_sbinfo *sbinfo;
  21147. +
  21148. + sbinfo = au_sbi(sb);
  21149. + if (!sbinfo)
  21150. + return;
  21151. +
  21152. + dbgaufs_si_fin(sbinfo);
  21153. + kobject_put(&sbinfo->si_kobj);
  21154. +}
  21155. +
  21156. +/* ---------------------------------------------------------------------- */
  21157. +
  21158. +void au_array_free(void *array)
  21159. +{
  21160. + if (array) {
  21161. + if (!is_vmalloc_addr(array))
  21162. + kfree(array);
  21163. + else
  21164. + vfree(array);
  21165. + }
  21166. +}
  21167. +
  21168. +void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg)
  21169. +{
  21170. + void *array;
  21171. + unsigned long long n;
  21172. +
  21173. + array = NULL;
  21174. + n = 0;
  21175. + if (!*hint)
  21176. + goto out;
  21177. +
  21178. + if (*hint > ULLONG_MAX / sizeof(array)) {
  21179. + array = ERR_PTR(-EMFILE);
  21180. + pr_err("hint %llu\n", *hint);
  21181. + goto out;
  21182. + }
  21183. +
  21184. + array = kmalloc(sizeof(array) * *hint, GFP_NOFS);
  21185. + if (unlikely(!array))
  21186. + array = vmalloc(sizeof(array) * *hint);
  21187. + if (unlikely(!array)) {
  21188. + array = ERR_PTR(-ENOMEM);
  21189. + goto out;
  21190. + }
  21191. +
  21192. + n = cb(array, *hint, arg);
  21193. + AuDebugOn(n > *hint);
  21194. +
  21195. +out:
  21196. + *hint = n;
  21197. + return array;
  21198. +}
  21199. +
  21200. +static unsigned long long au_iarray_cb(void *a,
  21201. + unsigned long long max __maybe_unused,
  21202. + void *arg)
  21203. +{
  21204. + unsigned long long n;
  21205. + struct inode **p, *inode;
  21206. + struct list_head *head;
  21207. +
  21208. + n = 0;
  21209. + p = a;
  21210. + head = arg;
  21211. + spin_lock(&inode_lock);
  21212. + list_for_each_entry(inode, head, i_sb_list) {
  21213. + if (!is_bad_inode(inode)
  21214. + && au_ii(inode)->ii_bstart >= 0) {
  21215. + au_igrab(inode);
  21216. + *p++ = inode;
  21217. + n++;
  21218. + AuDebugOn(n > max);
  21219. + }
  21220. + }
  21221. + spin_unlock(&inode_lock);
  21222. +
  21223. + return n;
  21224. +}
  21225. +
  21226. +struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max)
  21227. +{
  21228. + *max = atomic_long_read(&au_sbi(sb)->si_ninodes);
  21229. + return au_array_alloc(max, au_iarray_cb, &sb->s_inodes);
  21230. +}
  21231. +
  21232. +void au_iarray_free(struct inode **a, unsigned long long max)
  21233. +{
  21234. + unsigned long long ull;
  21235. +
  21236. + for (ull = 0; ull < max; ull++)
  21237. + iput(a[ull]);
  21238. + au_array_free(a);
  21239. +}
  21240. +
  21241. +/* ---------------------------------------------------------------------- */
  21242. +
  21243. +/*
  21244. + * refresh dentry and inode at remount time.
  21245. + */
  21246. +/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */
  21247. +static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags,
  21248. + struct dentry *parent)
  21249. +{
  21250. + int err;
  21251. +
  21252. + di_write_lock_child(dentry);
  21253. + di_read_lock_parent(parent, AuLock_IR);
  21254. + err = au_refresh_dentry(dentry, parent);
  21255. + if (!err && dir_flags)
  21256. + au_hn_reset(dentry->d_inode, dir_flags);
  21257. + di_read_unlock(parent, AuLock_IR);
  21258. + di_write_unlock(dentry);
  21259. +
  21260. + return err;
  21261. +}
  21262. +
  21263. +static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
  21264. + struct au_sbinfo *sbinfo,
  21265. + const unsigned int dir_flags)
  21266. +{
  21267. + int err;
  21268. + struct dentry *parent;
  21269. + struct inode *inode;
  21270. +
  21271. + err = 0;
  21272. + parent = dget_parent(dentry);
  21273. + if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
  21274. + inode = dentry->d_inode;
  21275. + if (inode) {
  21276. + if (!S_ISDIR(inode->i_mode))
  21277. + err = au_do_refresh(dentry, /*dir_flags*/0,
  21278. + parent);
  21279. + else {
  21280. + err = au_do_refresh(dentry, dir_flags, parent);
  21281. + if (unlikely(err))
  21282. + au_fset_si(sbinfo, FAILED_REFRESH_DIR);
  21283. + }
  21284. + } else
  21285. + err = au_do_refresh(dentry, /*dir_flags*/0, parent);
  21286. + AuDbgDentry(dentry);
  21287. + }
  21288. + dput(parent);
  21289. +
  21290. + AuTraceErr(err);
  21291. + return err;
  21292. +}
  21293. +
  21294. +static int au_refresh_d(struct super_block *sb)
  21295. +{
  21296. + int err, i, j, ndentry, e;
  21297. + unsigned int sigen;
  21298. + struct au_dcsub_pages dpages;
  21299. + struct au_dpage *dpage;
  21300. + struct dentry **dentries, *d;
  21301. + struct au_sbinfo *sbinfo;
  21302. + struct dentry *root = sb->s_root;
  21303. + const unsigned int dir_flags = au_hi_flags(root->d_inode, /*isdir*/1);
  21304. +
  21305. + err = au_dpages_init(&dpages, GFP_NOFS);
  21306. + if (unlikely(err))
  21307. + goto out;
  21308. + err = au_dcsub_pages(&dpages, root, NULL, NULL);
  21309. + if (unlikely(err))
  21310. + goto out_dpages;
  21311. +
  21312. + sigen = au_sigen(sb);
  21313. + sbinfo = au_sbi(sb);
  21314. + for (i = 0; i < dpages.ndpage; i++) {
  21315. + dpage = dpages.dpages + i;
  21316. + dentries = dpage->dentries;
  21317. + ndentry = dpage->ndentry;
  21318. + for (j = 0; j < ndentry; j++) {
  21319. + d = dentries[j];
  21320. + e = au_do_refresh_d(d, sigen, sbinfo, dir_flags);
  21321. + if (unlikely(e && !err))
  21322. + err = e;
  21323. + /* go on even err */
  21324. + }
  21325. + }
  21326. +
  21327. +out_dpages:
  21328. + au_dpages_free(&dpages);
  21329. +out:
  21330. + return err;
  21331. +}
  21332. +
  21333. +static int au_refresh_i(struct super_block *sb)
  21334. +{
  21335. + int err, e;
  21336. + unsigned int sigen;
  21337. + unsigned long long max, ull;
  21338. + struct inode *inode, **array;
  21339. +
  21340. + array = au_iarray_alloc(sb, &max);
  21341. + err = PTR_ERR(array);
  21342. + if (IS_ERR(array))
  21343. + goto out;
  21344. +
  21345. + err = 0;
  21346. + sigen = au_sigen(sb);
  21347. + for (ull = 0; ull < max; ull++) {
  21348. + inode = array[ull];
  21349. + if (au_iigen(inode) != sigen) {
  21350. + ii_write_lock_child(inode);
  21351. + e = au_refresh_hinode_self(inode);
  21352. + ii_write_unlock(inode);
  21353. + if (unlikely(e)) {
  21354. + pr_err("error %d, i%lu\n", e, inode->i_ino);
  21355. + if (!err)
  21356. + err = e;
  21357. + /* go on even if err */
  21358. + }
  21359. + }
  21360. + }
  21361. +
  21362. + au_iarray_free(array, max);
  21363. +
  21364. +out:
  21365. + return err;
  21366. +}
  21367. +
  21368. +static void au_remount_refresh(struct super_block *sb)
  21369. +{
  21370. + int err, e;
  21371. + unsigned int udba;
  21372. + aufs_bindex_t bindex, bend;
  21373. + struct dentry *root;
  21374. + struct inode *inode;
  21375. + struct au_branch *br;
  21376. +
  21377. + au_sigen_inc(sb);
  21378. + au_fclr_si(au_sbi(sb), FAILED_REFRESH_DIR);
  21379. +
  21380. + root = sb->s_root;
  21381. + DiMustNoWaiters(root);
  21382. + inode = root->d_inode;
  21383. + IiMustNoWaiters(inode);
  21384. +
  21385. + udba = au_opt_udba(sb);
  21386. + bend = au_sbend(sb);
  21387. + for (bindex = 0; bindex <= bend; bindex++) {
  21388. + br = au_sbr(sb, bindex);
  21389. + err = au_hnotify_reset_br(udba, br, br->br_perm);
  21390. + if (unlikely(err))
  21391. + AuIOErr("hnotify failed on br %d, %d, ignored\n",
  21392. + bindex, err);
  21393. + /* go on even if err */
  21394. + }
  21395. + au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
  21396. +
  21397. + di_write_unlock(root);
  21398. + err = au_refresh_d(sb);
  21399. + e = au_refresh_i(sb);
  21400. + if (unlikely(e && !err))
  21401. + err = e;
  21402. + /* aufs_write_lock() calls ..._child() */
  21403. + di_write_lock_child(root);
  21404. +
  21405. + au_cpup_attr_all(inode, /*force*/1);
  21406. +
  21407. + if (unlikely(err))
  21408. + AuIOErr("refresh failed, ignored, %d\n", err);
  21409. +}
  21410. +
  21411. +/* stop extra interpretation of errno in mount(8), and strange error messages */
  21412. +static int cvt_err(int err)
  21413. +{
  21414. + AuTraceErr(err);
  21415. +
  21416. + switch (err) {
  21417. + case -ENOENT:
  21418. + case -ENOTDIR:
  21419. + case -EEXIST:
  21420. + case -EIO:
  21421. + err = -EINVAL;
  21422. + }
  21423. + return err;
  21424. +}
  21425. +
  21426. +static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
  21427. +{
  21428. + int err, do_dx;
  21429. + unsigned int mntflags;
  21430. + struct au_opts opts;
  21431. + struct dentry *root;
  21432. + struct inode *inode;
  21433. + struct au_sbinfo *sbinfo;
  21434. +
  21435. + err = 0;
  21436. + root = sb->s_root;
  21437. + if (!data || !*data) {
  21438. + err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
  21439. + if (!err) {
  21440. + di_write_lock_child(root);
  21441. + err = au_opts_verify(sb, *flags, /*pending*/0);
  21442. + aufs_write_unlock(root);
  21443. + }
  21444. + goto out;
  21445. + }
  21446. +
  21447. + err = -ENOMEM;
  21448. + memset(&opts, 0, sizeof(opts));
  21449. + opts.opt = (void *)__get_free_page(GFP_NOFS);
  21450. + if (unlikely(!opts.opt))
  21451. + goto out;
  21452. + opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
  21453. + opts.flags = AuOpts_REMOUNT;
  21454. + opts.sb_flags = *flags;
  21455. +
  21456. + /* parse it before aufs lock */
  21457. + err = au_opts_parse(sb, data, &opts);
  21458. + if (unlikely(err))
  21459. + goto out_opts;
  21460. +
  21461. + sbinfo = au_sbi(sb);
  21462. + inode = root->d_inode;
  21463. + mutex_lock(&inode->i_mutex);
  21464. + err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
  21465. + if (unlikely(err))
  21466. + goto out_mtx;
  21467. + di_write_lock_child(root);
  21468. +
  21469. + /* au_opts_remount() may return an error */
  21470. + err = au_opts_remount(sb, &opts);
  21471. + au_opts_free(&opts);
  21472. +
  21473. + if (au_ftest_opts(opts.flags, REFRESH))
  21474. + au_remount_refresh(sb);
  21475. +
  21476. + if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
  21477. + mntflags = au_mntflags(sb);
  21478. + do_dx = !!au_opt_test(mntflags, DIO);
  21479. + au_dy_arefresh(do_dx);
  21480. + }
  21481. +
  21482. + aufs_write_unlock(root);
  21483. +
  21484. +out_mtx:
  21485. + mutex_unlock(&inode->i_mutex);
  21486. +out_opts:
  21487. + free_page((unsigned long)opts.opt);
  21488. +out:
  21489. + err = cvt_err(err);
  21490. + AuTraceErr(err);
  21491. + return err;
  21492. +}
  21493. +
  21494. +static const struct super_operations aufs_sop = {
  21495. + .alloc_inode = aufs_alloc_inode,
  21496. + .destroy_inode = aufs_destroy_inode,
  21497. + /* always deleting, no clearing */
  21498. + .drop_inode = generic_delete_inode,
  21499. + .show_options = aufs_show_options,
  21500. + .statfs = aufs_statfs,
  21501. + .put_super = aufs_put_super,
  21502. + .remount_fs = aufs_remount_fs
  21503. +};
  21504. +
  21505. +/* ---------------------------------------------------------------------- */
  21506. +
  21507. +static int alloc_root(struct super_block *sb)
  21508. +{
  21509. + int err;
  21510. + struct inode *inode;
  21511. + struct dentry *root;
  21512. +
  21513. + err = -ENOMEM;
  21514. + inode = au_iget_locked(sb, AUFS_ROOT_INO);
  21515. + err = PTR_ERR(inode);
  21516. + if (IS_ERR(inode))
  21517. + goto out;
  21518. +
  21519. + inode->i_op = &aufs_dir_iop;
  21520. + inode->i_fop = &aufs_dir_fop;
  21521. + inode->i_mode = S_IFDIR;
  21522. + inode->i_nlink = 2;
  21523. + unlock_new_inode(inode);
  21524. +
  21525. + root = d_alloc_root(inode);
  21526. + if (unlikely(!root))
  21527. + goto out_iput;
  21528. + err = PTR_ERR(root);
  21529. + if (IS_ERR(root))
  21530. + goto out_iput;
  21531. +
  21532. + err = au_di_init(root);
  21533. + if (!err) {
  21534. + sb->s_root = root;
  21535. + return 0; /* success */
  21536. + }
  21537. + dput(root);
  21538. + goto out; /* do not iput */
  21539. +
  21540. +out_iput:
  21541. + iget_failed(inode);
  21542. +out:
  21543. + return err;
  21544. +
  21545. +}
  21546. +
  21547. +static int aufs_fill_super(struct super_block *sb, void *raw_data,
  21548. + int silent __maybe_unused)
  21549. +{
  21550. + int err;
  21551. + struct au_opts opts;
  21552. + struct dentry *root;
  21553. + struct inode *inode;
  21554. + char *arg = raw_data;
  21555. +
  21556. + if (unlikely(!arg || !*arg)) {
  21557. + err = -EINVAL;
  21558. + pr_err("no arg\n");
  21559. + goto out;
  21560. + }
  21561. +
  21562. + err = -ENOMEM;
  21563. + memset(&opts, 0, sizeof(opts));
  21564. + opts.opt = (void *)__get_free_page(GFP_NOFS);
  21565. + if (unlikely(!opts.opt))
  21566. + goto out;
  21567. + opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
  21568. + opts.sb_flags = sb->s_flags;
  21569. +
  21570. + err = au_si_alloc(sb);
  21571. + if (unlikely(err))
  21572. + goto out_opts;
  21573. +
  21574. + /* all timestamps always follow the ones on the branch */
  21575. + sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
  21576. + sb->s_op = &aufs_sop;
  21577. + sb->s_magic = AUFS_SUPER_MAGIC;
  21578. + sb->s_maxbytes = 0;
  21579. + au_export_init(sb);
  21580. +
  21581. + err = alloc_root(sb);
  21582. + if (unlikely(err)) {
  21583. + si_write_unlock(sb);
  21584. + goto out_info;
  21585. + }
  21586. + root = sb->s_root;
  21587. + inode = root->d_inode;
  21588. +
  21589. + /*
  21590. + * actually we can parse options regardless aufs lock here.
  21591. + * but at remount time, parsing must be done before aufs lock.
  21592. + * so we follow the same rule.
  21593. + */
  21594. + ii_write_lock_parent(inode);
  21595. + aufs_write_unlock(root);
  21596. + err = au_opts_parse(sb, arg, &opts);
  21597. + if (unlikely(err))
  21598. + goto out_root;
  21599. +
  21600. + /* lock vfs_inode first, then aufs. */
  21601. + mutex_lock(&inode->i_mutex);
  21602. + aufs_write_lock(root);
  21603. + err = au_opts_mount(sb, &opts);
  21604. + au_opts_free(&opts);
  21605. + aufs_write_unlock(root);
  21606. + mutex_unlock(&inode->i_mutex);
  21607. + if (!err)
  21608. + goto out_opts; /* success */
  21609. +
  21610. +out_root:
  21611. + dput(root);
  21612. + sb->s_root = NULL;
  21613. +out_info:
  21614. + kobject_put(&au_sbi(sb)->si_kobj);
  21615. + sb->s_fs_info = NULL;
  21616. +out_opts:
  21617. + free_page((unsigned long)opts.opt);
  21618. +out:
  21619. + AuTraceErr(err);
  21620. + err = cvt_err(err);
  21621. + AuTraceErr(err);
  21622. + return err;
  21623. +}
  21624. +
  21625. +/* ---------------------------------------------------------------------- */
  21626. +
  21627. +static int aufs_get_sb(struct file_system_type *fs_type, int flags,
  21628. + const char *dev_name __maybe_unused, void *raw_data,
  21629. + struct vfsmount *mnt)
  21630. +{
  21631. + int err;
  21632. + struct super_block *sb;
  21633. +
  21634. + /* all timestamps always follow the ones on the branch */
  21635. + /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
  21636. + err = get_sb_nodev(fs_type, flags, raw_data, aufs_fill_super, mnt);
  21637. + if (!err) {
  21638. + sb = mnt->mnt_sb;
  21639. + si_write_lock(sb, !AuLock_FLUSH);
  21640. + sysaufs_brs_add(sb, 0);
  21641. + si_write_unlock(sb);
  21642. + au_sbilist_add(sb);
  21643. + }
  21644. + return err;
  21645. +}
  21646. +
  21647. +static void aufs_kill_sb(struct super_block *sb)
  21648. +{
  21649. + struct au_sbinfo *sbinfo;
  21650. +
  21651. + sbinfo = au_sbi(sb);
  21652. + if (sbinfo) {
  21653. + au_sbilist_del(sb);
  21654. + aufs_write_lock(sb->s_root);
  21655. + if (sbinfo->si_wbr_create_ops->fin)
  21656. + sbinfo->si_wbr_create_ops->fin(sb);
  21657. + if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
  21658. + au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
  21659. + au_remount_refresh(sb);
  21660. + }
  21661. + if (au_opt_test(sbinfo->si_mntflags, PLINK))
  21662. + au_plink_put(sb, /*verbose*/1);
  21663. + au_xino_clr(sb);
  21664. + aufs_write_unlock(sb->s_root);
  21665. + au_nwt_flush(&sbinfo->si_nowait);
  21666. + }
  21667. + generic_shutdown_super(sb);
  21668. +}
  21669. +
  21670. +struct file_system_type aufs_fs_type = {
  21671. + .name = AUFS_FSTYPE,
  21672. + .fs_flags =
  21673. + FS_RENAME_DOES_D_MOVE /* a race between rename and others */
  21674. + | FS_REVAL_DOT, /* for NFS branch and udba */
  21675. + .get_sb = aufs_get_sb,
  21676. + .kill_sb = aufs_kill_sb,
  21677. + /* no need to __module_get() and module_put(). */
  21678. + .owner = THIS_MODULE,
  21679. +};
  21680. diff -Nur linux-2.6.37.orig/fs/aufs/super.h linux-2.6.37/fs/aufs/super.h
  21681. --- linux-2.6.37.orig/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100
  21682. +++ linux-2.6.37/fs/aufs/super.h 2011-01-11 20:15:11.000000000 +0100
  21683. @@ -0,0 +1,527 @@
  21684. +/*
  21685. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  21686. + *
  21687. + * This program, aufs is free software; you can redistribute it and/or modify
  21688. + * it under the terms of the GNU General Public License as published by
  21689. + * the Free Software Foundation; either version 2 of the License, or
  21690. + * (at your option) any later version.
  21691. + *
  21692. + * This program is distributed in the hope that it will be useful,
  21693. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21694. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21695. + * GNU General Public License for more details.
  21696. + *
  21697. + * You should have received a copy of the GNU General Public License
  21698. + * along with this program; if not, write to the Free Software
  21699. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  21700. + */
  21701. +
  21702. +/*
  21703. + * super_block operations
  21704. + */
  21705. +
  21706. +#ifndef __AUFS_SUPER_H__
  21707. +#define __AUFS_SUPER_H__
  21708. +
  21709. +#ifdef __KERNEL__
  21710. +
  21711. +#include <linux/fs.h>
  21712. +#include <linux/aufs_type.h>
  21713. +#include "rwsem.h"
  21714. +#include "spl.h"
  21715. +#include "wkq.h"
  21716. +
  21717. +typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *);
  21718. +typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t,
  21719. + loff_t *);
  21720. +
  21721. +/* policies to select one among multiple writable branches */
  21722. +struct au_wbr_copyup_operations {
  21723. + int (*copyup)(struct dentry *dentry);
  21724. +};
  21725. +
  21726. +struct au_wbr_create_operations {
  21727. + int (*create)(struct dentry *dentry, int isdir);
  21728. + int (*init)(struct super_block *sb);
  21729. + int (*fin)(struct super_block *sb);
  21730. +};
  21731. +
  21732. +struct au_wbr_mfs {
  21733. + struct mutex mfs_lock; /* protect this structure */
  21734. + unsigned long mfs_jiffy;
  21735. + unsigned long mfs_expire;
  21736. + aufs_bindex_t mfs_bindex;
  21737. +
  21738. + unsigned long long mfsrr_bytes;
  21739. + unsigned long long mfsrr_watermark;
  21740. +};
  21741. +
  21742. +struct au_branch;
  21743. +struct au_sbinfo {
  21744. + /* nowait tasks in the system-wide workqueue */
  21745. + struct au_nowait_tasks si_nowait;
  21746. +
  21747. + /*
  21748. + * tried sb->s_umount, but failed due to the dependecy between i_mutex.
  21749. + * rwsem for au_sbinfo is necessary.
  21750. + */
  21751. + struct au_rwsem si_rwsem;
  21752. +
  21753. + /* prevent recursive locking in deleting inode */
  21754. + struct {
  21755. + unsigned long *bitmap;
  21756. + spinlock_t tree_lock;
  21757. + struct radix_tree_root tree;
  21758. + } au_si_pid;
  21759. +
  21760. + /*
  21761. + * dirty approach to protect sb->sb_inodes and ->s_files from remount.
  21762. + */
  21763. + atomic_long_t si_ninodes, si_nfiles;
  21764. +
  21765. + /* branch management */
  21766. + unsigned int si_generation;
  21767. +
  21768. + /* see above flags */
  21769. + unsigned char au_si_status;
  21770. +
  21771. + aufs_bindex_t si_bend;
  21772. +
  21773. + /* dirty trick to keep br_id plus */
  21774. + unsigned int si_last_br_id :
  21775. + sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1;
  21776. + struct au_branch **si_branch;
  21777. +
  21778. + /* policy to select a writable branch */
  21779. + unsigned char si_wbr_copyup;
  21780. + unsigned char si_wbr_create;
  21781. + struct au_wbr_copyup_operations *si_wbr_copyup_ops;
  21782. + struct au_wbr_create_operations *si_wbr_create_ops;
  21783. +
  21784. + /* round robin */
  21785. + atomic_t si_wbr_rr_next;
  21786. +
  21787. + /* most free space */
  21788. + struct au_wbr_mfs si_wbr_mfs;
  21789. +
  21790. + /* mount flags */
  21791. + /* include/asm-ia64/siginfo.h defines a macro named si_flags */
  21792. + unsigned int si_mntflags;
  21793. +
  21794. + /* external inode number (bitmap and translation table) */
  21795. + au_readf_t si_xread;
  21796. + au_writef_t si_xwrite;
  21797. + struct file *si_xib;
  21798. + struct mutex si_xib_mtx; /* protect xib members */
  21799. + unsigned long *si_xib_buf;
  21800. + unsigned long si_xib_last_pindex;
  21801. + int si_xib_next_bit;
  21802. + aufs_bindex_t si_xino_brid;
  21803. + /* reserved for future use */
  21804. + /* unsigned long long si_xib_limit; */ /* Max xib file size */
  21805. +
  21806. +#ifdef CONFIG_AUFS_EXPORT
  21807. + /* i_generation */
  21808. + struct file *si_xigen;
  21809. + atomic_t si_xigen_next;
  21810. +#endif
  21811. +
  21812. + /* vdir parameters */
  21813. + unsigned long si_rdcache; /* max cache time in jiffies */
  21814. + unsigned int si_rdblk; /* deblk size */
  21815. + unsigned int si_rdhash; /* hash size */
  21816. +
  21817. + /*
  21818. + * If the number of whiteouts are larger than si_dirwh, leave all of
  21819. + * them after au_whtmp_ren to reduce the cost of rmdir(2).
  21820. + * future fsck.aufs or kernel thread will remove them later.
  21821. + * Otherwise, remove all whiteouts and the dir in rmdir(2).
  21822. + */
  21823. + unsigned int si_dirwh;
  21824. +
  21825. + /*
  21826. + * rename(2) a directory with all children.
  21827. + */
  21828. + /* reserved for future use */
  21829. + /* int si_rendir; */
  21830. +
  21831. + /* pseudo_link list */
  21832. + struct au_splhead si_plink;
  21833. + wait_queue_head_t si_plink_wq;
  21834. + spinlock_t si_plink_maint_lock;
  21835. + pid_t si_plink_maint_pid;
  21836. +
  21837. + /*
  21838. + * sysfs and lifetime management.
  21839. + * this is not a small structure and it may be a waste of memory in case
  21840. + * of sysfs is disabled, particulary when many aufs-es are mounted.
  21841. + * but using sysfs is majority.
  21842. + */
  21843. + struct kobject si_kobj;
  21844. +#ifdef CONFIG_DEBUG_FS
  21845. + struct dentry *si_dbgaufs, *si_dbgaufs_xib;
  21846. +#ifdef CONFIG_AUFS_EXPORT
  21847. + struct dentry *si_dbgaufs_xigen;
  21848. +#endif
  21849. +#endif
  21850. +
  21851. +#ifdef CONFIG_AUFS_SBILIST
  21852. + struct list_head si_list;
  21853. +#endif
  21854. +
  21855. + /* dirty, necessary for unmounting, sysfs and sysrq */
  21856. + struct super_block *si_sb;
  21857. +};
  21858. +
  21859. +/* sbinfo status flags */
  21860. +/*
  21861. + * set true when refresh_dirs() failed at remount time.
  21862. + * then try refreshing dirs at access time again.
  21863. + * if it is false, refreshing dirs at access time is unnecesary
  21864. + */
  21865. +#define AuSi_FAILED_REFRESH_DIR 1
  21866. +static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
  21867. + unsigned int flag)
  21868. +{
  21869. + AuRwMustAnyLock(&sbi->si_rwsem);
  21870. + return sbi->au_si_status & flag;
  21871. +}
  21872. +#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name)
  21873. +#define au_fset_si(sbinfo, name) do { \
  21874. + AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
  21875. + (sbinfo)->au_si_status |= AuSi_##name; \
  21876. +} while (0)
  21877. +#define au_fclr_si(sbinfo, name) do { \
  21878. + AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
  21879. + (sbinfo)->au_si_status &= ~AuSi_##name; \
  21880. +} while (0)
  21881. +
  21882. +/* ---------------------------------------------------------------------- */
  21883. +
  21884. +/* policy to select one among writable branches */
  21885. +#define AuWbrCopyup(sbinfo, ...) \
  21886. + ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__))
  21887. +#define AuWbrCreate(sbinfo, ...) \
  21888. + ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__))
  21889. +
  21890. +/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
  21891. +#define AuLock_DW 1 /* write-lock dentry */
  21892. +#define AuLock_IR (1 << 1) /* read-lock inode */
  21893. +#define AuLock_IW (1 << 2) /* write-lock inode */
  21894. +#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
  21895. +#define AuLock_DIR (1 << 4) /* target is a dir */
  21896. +#define AuLock_NOPLM (1 << 5) /* return err in plm mode */
  21897. +#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */
  21898. +#define AuLock_GEN (1 << 7) /* test digen/iigen */
  21899. +#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
  21900. +#define au_fset_lock(flags, name) \
  21901. + do { (flags) |= AuLock_##name; } while (0)
  21902. +#define au_fclr_lock(flags, name) \
  21903. + do { (flags) &= ~AuLock_##name; } while (0)
  21904. +
  21905. +/* ---------------------------------------------------------------------- */
  21906. +
  21907. +/* super.c */
  21908. +extern struct file_system_type aufs_fs_type;
  21909. +struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
  21910. +typedef unsigned long long (*au_arraycb_t)(void *array, unsigned long long max,
  21911. + void *arg);
  21912. +void au_array_free(void *array);
  21913. +void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg);
  21914. +struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
  21915. +void au_iarray_free(struct inode **a, unsigned long long max);
  21916. +
  21917. +/* sbinfo.c */
  21918. +void au_si_free(struct kobject *kobj);
  21919. +int au_si_alloc(struct super_block *sb);
  21920. +int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr);
  21921. +
  21922. +unsigned int au_sigen_inc(struct super_block *sb);
  21923. +aufs_bindex_t au_new_br_id(struct super_block *sb);
  21924. +
  21925. +int si_read_lock(struct super_block *sb, int flags);
  21926. +int si_write_lock(struct super_block *sb, int flags);
  21927. +int aufs_read_lock(struct dentry *dentry, int flags);
  21928. +void aufs_read_unlock(struct dentry *dentry, int flags);
  21929. +void aufs_write_lock(struct dentry *dentry);
  21930. +void aufs_write_unlock(struct dentry *dentry);
  21931. +int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
  21932. +void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
  21933. +
  21934. +int si_pid_test_slow(struct super_block *sb);
  21935. +void si_pid_set_slow(struct super_block *sb);
  21936. +void si_pid_clr_slow(struct super_block *sb);
  21937. +
  21938. +/* wbr_policy.c */
  21939. +extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
  21940. +extern struct au_wbr_create_operations au_wbr_create_ops[];
  21941. +int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
  21942. +
  21943. +/* ---------------------------------------------------------------------- */
  21944. +
  21945. +static inline struct au_sbinfo *au_sbi(struct super_block *sb)
  21946. +{
  21947. + return sb->s_fs_info;
  21948. +}
  21949. +
  21950. +/* ---------------------------------------------------------------------- */
  21951. +
  21952. +#ifdef CONFIG_AUFS_EXPORT
  21953. +void au_export_init(struct super_block *sb);
  21954. +
  21955. +static inline int au_test_nfsd(void)
  21956. +{
  21957. + struct task_struct *tsk = current;
  21958. +
  21959. + return (tsk->flags & PF_KTHREAD)
  21960. + && !strcmp(tsk->comm, "nfsd");
  21961. +}
  21962. +
  21963. +void au_xigen_inc(struct inode *inode);
  21964. +int au_xigen_new(struct inode *inode);
  21965. +int au_xigen_set(struct super_block *sb, struct file *base);
  21966. +void au_xigen_clr(struct super_block *sb);
  21967. +
  21968. +static inline int au_busy_or_stale(void)
  21969. +{
  21970. + if (!au_test_nfsd())
  21971. + return -EBUSY;
  21972. + return -ESTALE;
  21973. +}
  21974. +#else
  21975. +AuStubVoid(au_export_init, struct super_block *sb)
  21976. +AuStubInt0(au_test_nfsd, void)
  21977. +AuStubVoid(au_xigen_inc, struct inode *inode)
  21978. +AuStubInt0(au_xigen_new, struct inode *inode)
  21979. +AuStubInt0(au_xigen_set, struct super_block *sb, struct file *base)
  21980. +AuStubVoid(au_xigen_clr, struct super_block *sb)
  21981. +static inline int au_busy_or_stale(void)
  21982. +{
  21983. + return -EBUSY;
  21984. +}
  21985. +#endif /* CONFIG_AUFS_EXPORT */
  21986. +
  21987. +/* ---------------------------------------------------------------------- */
  21988. +
  21989. +#ifdef CONFIG_AUFS_SBILIST
  21990. +/* module.c */
  21991. +extern struct au_splhead au_sbilist;
  21992. +
  21993. +static inline void au_sbilist_init(void)
  21994. +{
  21995. + au_spl_init(&au_sbilist);
  21996. +}
  21997. +
  21998. +static inline void au_sbilist_add(struct super_block *sb)
  21999. +{
  22000. + au_spl_add(&au_sbi(sb)->si_list, &au_sbilist);
  22001. +}
  22002. +
  22003. +static inline void au_sbilist_del(struct super_block *sb)
  22004. +{
  22005. + au_spl_del(&au_sbi(sb)->si_list, &au_sbilist);
  22006. +}
  22007. +#else
  22008. +AuStubVoid(au_sbilist_init, void)
  22009. +AuStubVoid(au_sbilist_add, struct super_block*)
  22010. +AuStubVoid(au_sbilist_del, struct super_block*)
  22011. +#endif
  22012. +
  22013. +/* ---------------------------------------------------------------------- */
  22014. +
  22015. +static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
  22016. +{
  22017. + /*
  22018. + * This function is a dynamic '__init' fucntion actually,
  22019. + * so the tiny check for si_rwsem is unnecessary.
  22020. + */
  22021. + /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
  22022. +#ifdef CONFIG_DEBUG_FS
  22023. + sbinfo->si_dbgaufs = NULL;
  22024. + sbinfo->si_dbgaufs_xib = NULL;
  22025. +#ifdef CONFIG_AUFS_EXPORT
  22026. + sbinfo->si_dbgaufs_xigen = NULL;
  22027. +#endif
  22028. +#endif
  22029. +}
  22030. +
  22031. +/* ---------------------------------------------------------------------- */
  22032. +
  22033. +static inline pid_t si_pid_bit(void)
  22034. +{
  22035. + /* the origin of pid is 1, but the bitmap's is 0 */
  22036. + return current->pid - 1;
  22037. +}
  22038. +
  22039. +static inline int si_pid_test(struct super_block *sb)
  22040. +{
  22041. + pid_t bit = si_pid_bit();
  22042. + if (bit < PID_MAX_DEFAULT)
  22043. + return test_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
  22044. + else
  22045. + return si_pid_test_slow(sb);
  22046. +}
  22047. +
  22048. +static inline void si_pid_set(struct super_block *sb)
  22049. +{
  22050. + pid_t bit = si_pid_bit();
  22051. + if (bit < PID_MAX_DEFAULT) {
  22052. + AuDebugOn(test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
  22053. + set_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
  22054. + /* smp_mb(); */
  22055. + } else
  22056. + si_pid_set_slow(sb);
  22057. +}
  22058. +
  22059. +static inline void si_pid_clr(struct super_block *sb)
  22060. +{
  22061. + pid_t bit = si_pid_bit();
  22062. + if (bit < PID_MAX_DEFAULT) {
  22063. + AuDebugOn(!test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
  22064. + clear_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
  22065. + /* smp_mb(); */
  22066. + } else
  22067. + si_pid_clr_slow(sb);
  22068. +}
  22069. +
  22070. +/* ---------------------------------------------------------------------- */
  22071. +
  22072. +/* lock superblock. mainly for entry point functions */
  22073. +/*
  22074. + * __si_read_lock, __si_write_lock,
  22075. + * __si_read_unlock, __si_write_unlock, __si_downgrade_lock
  22076. + */
  22077. +AuSimpleRwsemFuncs(__si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
  22078. +
  22079. +#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
  22080. +#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
  22081. +#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
  22082. +
  22083. +static inline void si_noflush_read_lock(struct super_block *sb)
  22084. +{
  22085. + __si_read_lock(sb);
  22086. + si_pid_set(sb);
  22087. +}
  22088. +
  22089. +static inline int si_noflush_read_trylock(struct super_block *sb)
  22090. +{
  22091. + int locked = __si_read_trylock(sb);
  22092. + if (locked)
  22093. + si_pid_set(sb);
  22094. + return locked;
  22095. +}
  22096. +
  22097. +static inline void si_noflush_write_lock(struct super_block *sb)
  22098. +{
  22099. + __si_write_lock(sb);
  22100. + si_pid_set(sb);
  22101. +}
  22102. +
  22103. +static inline int si_noflush_write_trylock(struct super_block *sb)
  22104. +{
  22105. + int locked = __si_write_trylock(sb);
  22106. + if (locked)
  22107. + si_pid_set(sb);
  22108. + return locked;
  22109. +}
  22110. +
  22111. +#if 0 /* unused */
  22112. +static inline int si_read_trylock(struct super_block *sb, int flags)
  22113. +{
  22114. + if (au_ftest_lock(flags, FLUSH))
  22115. + au_nwt_flush(&au_sbi(sb)->si_nowait);
  22116. + return si_noflush_read_trylock(sb);
  22117. +}
  22118. +#endif
  22119. +
  22120. +static inline void si_read_unlock(struct super_block *sb)
  22121. +{
  22122. + si_pid_clr(sb);
  22123. + __si_read_unlock(sb);
  22124. +}
  22125. +
  22126. +#if 0 /* unused */
  22127. +static inline int si_write_trylock(struct super_block *sb, int flags)
  22128. +{
  22129. + if (au_ftest_lock(flags, FLUSH))
  22130. + au_nwt_flush(&au_sbi(sb)->si_nowait);
  22131. + return si_noflush_write_trylock(sb);
  22132. +}
  22133. +#endif
  22134. +
  22135. +static inline void si_write_unlock(struct super_block *sb)
  22136. +{
  22137. + si_pid_clr(sb);
  22138. + __si_write_unlock(sb);
  22139. +}
  22140. +
  22141. +#if 0 /* unused */
  22142. +static inline void si_downgrade_lock(struct super_block *sb)
  22143. +{
  22144. + __si_downgrade_lock(sb);
  22145. +}
  22146. +#endif
  22147. +
  22148. +/* ---------------------------------------------------------------------- */
  22149. +
  22150. +static inline aufs_bindex_t au_sbend(struct super_block *sb)
  22151. +{
  22152. + SiMustAnyLock(sb);
  22153. + return au_sbi(sb)->si_bend;
  22154. +}
  22155. +
  22156. +static inline unsigned int au_mntflags(struct super_block *sb)
  22157. +{
  22158. + SiMustAnyLock(sb);
  22159. + return au_sbi(sb)->si_mntflags;
  22160. +}
  22161. +
  22162. +static inline unsigned int au_sigen(struct super_block *sb)
  22163. +{
  22164. + SiMustAnyLock(sb);
  22165. + return au_sbi(sb)->si_generation;
  22166. +}
  22167. +
  22168. +static inline void au_ninodes_inc(struct super_block *sb)
  22169. +{
  22170. + atomic_long_inc(&au_sbi(sb)->si_ninodes);
  22171. +}
  22172. +
  22173. +static inline void au_ninodes_dec(struct super_block *sb)
  22174. +{
  22175. + AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_ninodes));
  22176. + atomic_long_dec(&au_sbi(sb)->si_ninodes);
  22177. +}
  22178. +
  22179. +static inline void au_nfiles_inc(struct super_block *sb)
  22180. +{
  22181. + atomic_long_inc(&au_sbi(sb)->si_nfiles);
  22182. +}
  22183. +
  22184. +static inline void au_nfiles_dec(struct super_block *sb)
  22185. +{
  22186. + AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_nfiles));
  22187. + atomic_long_dec(&au_sbi(sb)->si_nfiles);
  22188. +}
  22189. +
  22190. +static inline struct au_branch *au_sbr(struct super_block *sb,
  22191. + aufs_bindex_t bindex)
  22192. +{
  22193. + SiMustAnyLock(sb);
  22194. + return au_sbi(sb)->si_branch[0 + bindex];
  22195. +}
  22196. +
  22197. +static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid)
  22198. +{
  22199. + SiMustWriteLock(sb);
  22200. + au_sbi(sb)->si_xino_brid = brid;
  22201. +}
  22202. +
  22203. +static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
  22204. +{
  22205. + SiMustAnyLock(sb);
  22206. + return au_sbi(sb)->si_xino_brid;
  22207. +}
  22208. +
  22209. +#endif /* __KERNEL__ */
  22210. +#endif /* __AUFS_SUPER_H__ */
  22211. diff -Nur linux-2.6.37.orig/fs/aufs/sysaufs.c linux-2.6.37/fs/aufs/sysaufs.c
  22212. --- linux-2.6.37.orig/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
  22213. +++ linux-2.6.37/fs/aufs/sysaufs.c 2011-01-11 20:15:11.000000000 +0100
  22214. @@ -0,0 +1,107 @@
  22215. +/*
  22216. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  22217. + *
  22218. + * This program, aufs is free software; you can redistribute it and/or modify
  22219. + * it under the terms of the GNU General Public License as published by
  22220. + * the Free Software Foundation; either version 2 of the License, or
  22221. + * (at your option) any later version.
  22222. + *
  22223. + * This program is distributed in the hope that it will be useful,
  22224. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22225. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22226. + * GNU General Public License for more details.
  22227. + *
  22228. + * You should have received a copy of the GNU General Public License
  22229. + * along with this program; if not, write to the Free Software
  22230. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22231. + */
  22232. +
  22233. +/*
  22234. + * sysfs interface and lifetime management
  22235. + * they are necessary regardless sysfs is disabled.
  22236. + */
  22237. +
  22238. +#include <linux/fs.h>
  22239. +#include <linux/random.h>
  22240. +#include <linux/sysfs.h>
  22241. +#include "aufs.h"
  22242. +
  22243. +unsigned long sysaufs_si_mask;
  22244. +struct kset *sysaufs_kset;
  22245. +
  22246. +#define AuSiAttr(_name) { \
  22247. + .attr = { .name = __stringify(_name), .mode = 0444 }, \
  22248. + .show = sysaufs_si_##_name, \
  22249. +}
  22250. +
  22251. +static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
  22252. +struct attribute *sysaufs_si_attrs[] = {
  22253. + &sysaufs_si_attr_xi_path.attr,
  22254. + NULL,
  22255. +};
  22256. +
  22257. +static const struct sysfs_ops au_sbi_ops = {
  22258. + .show = sysaufs_si_show
  22259. +};
  22260. +
  22261. +static struct kobj_type au_sbi_ktype = {
  22262. + .release = au_si_free,
  22263. + .sysfs_ops = &au_sbi_ops,
  22264. + .default_attrs = sysaufs_si_attrs
  22265. +};
  22266. +
  22267. +/* ---------------------------------------------------------------------- */
  22268. +
  22269. +int sysaufs_si_init(struct au_sbinfo *sbinfo)
  22270. +{
  22271. + int err;
  22272. +
  22273. + sbinfo->si_kobj.kset = sysaufs_kset;
  22274. + /* cf. sysaufs_name() */
  22275. + err = kobject_init_and_add
  22276. + (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL,
  22277. + SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
  22278. +
  22279. + dbgaufs_si_null(sbinfo);
  22280. + if (!err) {
  22281. + err = dbgaufs_si_init(sbinfo);
  22282. + if (unlikely(err))
  22283. + kobject_put(&sbinfo->si_kobj);
  22284. + }
  22285. + return err;
  22286. +}
  22287. +
  22288. +void sysaufs_fin(void)
  22289. +{
  22290. + dbgaufs_fin();
  22291. + sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group);
  22292. + kset_unregister(sysaufs_kset);
  22293. +}
  22294. +
  22295. +int __init sysaufs_init(void)
  22296. +{
  22297. + int err;
  22298. +
  22299. + do {
  22300. + get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
  22301. + } while (!sysaufs_si_mask);
  22302. +
  22303. + err = -EINVAL;
  22304. + sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
  22305. + if (unlikely(!sysaufs_kset))
  22306. + goto out;
  22307. + err = PTR_ERR(sysaufs_kset);
  22308. + if (IS_ERR(sysaufs_kset))
  22309. + goto out;
  22310. + err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group);
  22311. + if (unlikely(err)) {
  22312. + kset_unregister(sysaufs_kset);
  22313. + goto out;
  22314. + }
  22315. +
  22316. + err = dbgaufs_init();
  22317. + if (unlikely(err))
  22318. + sysaufs_fin();
  22319. +out:
  22320. + return err;
  22321. +}
  22322. diff -Nur linux-2.6.37.orig/fs/aufs/sysaufs.h linux-2.6.37/fs/aufs/sysaufs.h
  22323. --- linux-2.6.37.orig/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
  22324. +++ linux-2.6.37/fs/aufs/sysaufs.h 2011-01-11 20:15:11.000000000 +0100
  22325. @@ -0,0 +1,105 @@
  22326. +/*
  22327. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  22328. + *
  22329. + * This program, aufs is free software; you can redistribute it and/or modify
  22330. + * it under the terms of the GNU General Public License as published by
  22331. + * the Free Software Foundation; either version 2 of the License, or
  22332. + * (at your option) any later version.
  22333. + *
  22334. + * This program is distributed in the hope that it will be useful,
  22335. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22336. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22337. + * GNU General Public License for more details.
  22338. + *
  22339. + * You should have received a copy of the GNU General Public License
  22340. + * along with this program; if not, write to the Free Software
  22341. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22342. + */
  22343. +
  22344. +/*
  22345. + * sysfs interface and mount lifetime management
  22346. + */
  22347. +
  22348. +#ifndef __SYSAUFS_H__
  22349. +#define __SYSAUFS_H__
  22350. +
  22351. +#ifdef __KERNEL__
  22352. +
  22353. +#include <linux/sysfs.h>
  22354. +#include <linux/aufs_type.h>
  22355. +#include "module.h"
  22356. +
  22357. +struct super_block;
  22358. +struct au_sbinfo;
  22359. +
  22360. +struct sysaufs_si_attr {
  22361. + struct attribute attr;
  22362. + int (*show)(struct seq_file *seq, struct super_block *sb);
  22363. +};
  22364. +
  22365. +/* ---------------------------------------------------------------------- */
  22366. +
  22367. +/* sysaufs.c */
  22368. +extern unsigned long sysaufs_si_mask;
  22369. +extern struct kset *sysaufs_kset;
  22370. +extern struct attribute *sysaufs_si_attrs[];
  22371. +int sysaufs_si_init(struct au_sbinfo *sbinfo);
  22372. +int __init sysaufs_init(void);
  22373. +void sysaufs_fin(void);
  22374. +
  22375. +/* ---------------------------------------------------------------------- */
  22376. +
  22377. +/* some people doesn't like to show a pointer in kernel */
  22378. +static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
  22379. +{
  22380. + return sysaufs_si_mask ^ (unsigned long)sbinfo;
  22381. +}
  22382. +
  22383. +#define SysaufsSiNamePrefix "si_"
  22384. +#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16)
  22385. +static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
  22386. +{
  22387. + snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
  22388. + sysaufs_si_id(sbinfo));
  22389. +}
  22390. +
  22391. +struct au_branch;
  22392. +#ifdef CONFIG_SYSFS
  22393. +/* sysfs.c */
  22394. +extern struct attribute_group *sysaufs_attr_group;
  22395. +
  22396. +int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
  22397. +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
  22398. + char *buf);
  22399. +
  22400. +void sysaufs_br_init(struct au_branch *br);
  22401. +void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
  22402. +void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
  22403. +
  22404. +#define sysaufs_brs_init() do {} while (0)
  22405. +
  22406. +#else
  22407. +#define sysaufs_attr_group NULL
  22408. +
  22409. +AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb)
  22410. +
  22411. +static inline
  22412. +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
  22413. + char *buf)
  22414. +{
  22415. + return 0;
  22416. +}
  22417. +
  22418. +AuStubVoid(sysaufs_br_init, struct au_branch *br)
  22419. +AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
  22420. +AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
  22421. +
  22422. +static inline void sysaufs_brs_init(void)
  22423. +{
  22424. + sysaufs_brs = 0;
  22425. +}
  22426. +
  22427. +#endif /* CONFIG_SYSFS */
  22428. +
  22429. +#endif /* __KERNEL__ */
  22430. +#endif /* __SYSAUFS_H__ */
  22431. diff -Nur linux-2.6.37.orig/fs/aufs/sysfs.c linux-2.6.37/fs/aufs/sysfs.c
  22432. --- linux-2.6.37.orig/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100
  22433. +++ linux-2.6.37/fs/aufs/sysfs.c 2011-01-11 20:15:11.000000000 +0100
  22434. @@ -0,0 +1,250 @@
  22435. +/*
  22436. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  22437. + *
  22438. + * This program, aufs is free software; you can redistribute it and/or modify
  22439. + * it under the terms of the GNU General Public License as published by
  22440. + * the Free Software Foundation; either version 2 of the License, or
  22441. + * (at your option) any later version.
  22442. + *
  22443. + * This program is distributed in the hope that it will be useful,
  22444. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22445. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22446. + * GNU General Public License for more details.
  22447. + *
  22448. + * You should have received a copy of the GNU General Public License
  22449. + * along with this program; if not, write to the Free Software
  22450. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22451. + */
  22452. +
  22453. +/*
  22454. + * sysfs interface
  22455. + */
  22456. +
  22457. +#include <linux/fs.h>
  22458. +#include <linux/module.h>
  22459. +#include <linux/seq_file.h>
  22460. +#include <linux/sysfs.h>
  22461. +#include "aufs.h"
  22462. +
  22463. +#ifdef CONFIG_AUFS_FS_MODULE
  22464. +/* this entry violates the "one line per file" policy of sysfs */
  22465. +static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr,
  22466. + char *buf)
  22467. +{
  22468. + ssize_t err;
  22469. + static char *conf =
  22470. +/* this file is generated at compiling */
  22471. +#include "conf.str"
  22472. + ;
  22473. +
  22474. + err = snprintf(buf, PAGE_SIZE, conf);
  22475. + if (unlikely(err >= PAGE_SIZE))
  22476. + err = -EFBIG;
  22477. + return err;
  22478. +}
  22479. +
  22480. +static struct kobj_attribute au_config_attr = __ATTR_RO(config);
  22481. +#endif
  22482. +
  22483. +static struct attribute *au_attr[] = {
  22484. +#ifdef CONFIG_AUFS_FS_MODULE
  22485. + &au_config_attr.attr,
  22486. +#endif
  22487. + NULL, /* need to NULL terminate the list of attributes */
  22488. +};
  22489. +
  22490. +static struct attribute_group sysaufs_attr_group_body = {
  22491. + .attrs = au_attr
  22492. +};
  22493. +
  22494. +struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
  22495. +
  22496. +/* ---------------------------------------------------------------------- */
  22497. +
  22498. +int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
  22499. +{
  22500. + int err;
  22501. +
  22502. + SiMustAnyLock(sb);
  22503. +
  22504. + err = 0;
  22505. + if (au_opt_test(au_mntflags(sb), XINO)) {
  22506. + err = au_xino_path(seq, au_sbi(sb)->si_xib);
  22507. + seq_putc(seq, '\n');
  22508. + }
  22509. + return err;
  22510. +}
  22511. +
  22512. +/*
  22513. + * the lifetime of branch is independent from the entry under sysfs.
  22514. + * sysfs handles the lifetime of the entry, and never call ->show() after it is
  22515. + * unlinked.
  22516. + */
  22517. +static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
  22518. + aufs_bindex_t bindex)
  22519. +{
  22520. + struct path path;
  22521. + struct dentry *root;
  22522. + struct au_branch *br;
  22523. +
  22524. + AuDbg("b%d\n", bindex);
  22525. +
  22526. + root = sb->s_root;
  22527. + di_read_lock_parent(root, !AuLock_IR);
  22528. + br = au_sbr(sb, bindex);
  22529. + path.mnt = br->br_mnt;
  22530. + path.dentry = au_h_dptr(root, bindex);
  22531. + au_seq_path(seq, &path);
  22532. + di_read_unlock(root, !AuLock_IR);
  22533. + seq_printf(seq, "=%s\n", au_optstr_br_perm(br->br_perm));
  22534. + return 0;
  22535. +}
  22536. +
  22537. +/* ---------------------------------------------------------------------- */
  22538. +
  22539. +static struct seq_file *au_seq(char *p, ssize_t len)
  22540. +{
  22541. + struct seq_file *seq;
  22542. +
  22543. + seq = kzalloc(sizeof(*seq), GFP_NOFS);
  22544. + if (seq) {
  22545. + /* mutex_init(&seq.lock); */
  22546. + seq->buf = p;
  22547. + seq->size = len;
  22548. + return seq; /* success */
  22549. + }
  22550. +
  22551. + seq = ERR_PTR(-ENOMEM);
  22552. + return seq;
  22553. +}
  22554. +
  22555. +#define SysaufsBr_PREFIX "br"
  22556. +
  22557. +/* todo: file size may exceed PAGE_SIZE */
  22558. +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
  22559. + char *buf)
  22560. +{
  22561. + ssize_t err;
  22562. + long l;
  22563. + aufs_bindex_t bend;
  22564. + struct au_sbinfo *sbinfo;
  22565. + struct super_block *sb;
  22566. + struct seq_file *seq;
  22567. + char *name;
  22568. + struct attribute **cattr;
  22569. +
  22570. + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
  22571. + sb = sbinfo->si_sb;
  22572. +
  22573. + /*
  22574. + * prevent a race condition between sysfs and aufs.
  22575. + * for instance, sysfs_file_read() calls sysfs_get_active_two() which
  22576. + * prohibits maintaining the sysfs entries.
  22577. + * hew we acquire read lock after sysfs_get_active_two().
  22578. + * on the other hand, the remount process may maintain the sysfs/aufs
  22579. + * entries after acquiring write lock.
  22580. + * it can cause a deadlock.
  22581. + * simply we gave up processing read here.
  22582. + */
  22583. + err = -EBUSY;
  22584. + if (unlikely(!si_noflush_read_trylock(sb)))
  22585. + goto out;
  22586. +
  22587. + seq = au_seq(buf, PAGE_SIZE);
  22588. + err = PTR_ERR(seq);
  22589. + if (IS_ERR(seq))
  22590. + goto out_unlock;
  22591. +
  22592. + name = (void *)attr->name;
  22593. + cattr = sysaufs_si_attrs;
  22594. + while (*cattr) {
  22595. + if (!strcmp(name, (*cattr)->name)) {
  22596. + err = container_of(*cattr, struct sysaufs_si_attr, attr)
  22597. + ->show(seq, sb);
  22598. + goto out_seq;
  22599. + }
  22600. + cattr++;
  22601. + }
  22602. +
  22603. + bend = au_sbend(sb);
  22604. + if (!strncmp(name, SysaufsBr_PREFIX, sizeof(SysaufsBr_PREFIX) - 1)) {
  22605. + name += sizeof(SysaufsBr_PREFIX) - 1;
  22606. + err = strict_strtol(name, 10, &l);
  22607. + if (!err) {
  22608. + if (l <= bend)
  22609. + err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l);
  22610. + else
  22611. + err = -ENOENT;
  22612. + }
  22613. + goto out_seq;
  22614. + }
  22615. + BUG();
  22616. +
  22617. +out_seq:
  22618. + if (!err) {
  22619. + err = seq->count;
  22620. + /* sysfs limit */
  22621. + if (unlikely(err == PAGE_SIZE))
  22622. + err = -EFBIG;
  22623. + }
  22624. + kfree(seq);
  22625. +out_unlock:
  22626. + si_read_unlock(sb);
  22627. +out:
  22628. + return err;
  22629. +}
  22630. +
  22631. +/* ---------------------------------------------------------------------- */
  22632. +
  22633. +void sysaufs_br_init(struct au_branch *br)
  22634. +{
  22635. + struct attribute *attr = &br->br_attr;
  22636. +
  22637. + sysfs_attr_init(attr);
  22638. + attr->name = br->br_name;
  22639. + attr->mode = S_IRUGO;
  22640. +}
  22641. +
  22642. +void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
  22643. +{
  22644. + struct au_branch *br;
  22645. + struct kobject *kobj;
  22646. + aufs_bindex_t bend;
  22647. +
  22648. + dbgaufs_brs_del(sb, bindex);
  22649. +
  22650. + if (!sysaufs_brs)
  22651. + return;
  22652. +
  22653. + kobj = &au_sbi(sb)->si_kobj;
  22654. + bend = au_sbend(sb);
  22655. + for (; bindex <= bend; bindex++) {
  22656. + br = au_sbr(sb, bindex);
  22657. + sysfs_remove_file(kobj, &br->br_attr);
  22658. + }
  22659. +}
  22660. +
  22661. +void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
  22662. +{
  22663. + int err;
  22664. + aufs_bindex_t bend;
  22665. + struct kobject *kobj;
  22666. + struct au_branch *br;
  22667. +
  22668. + dbgaufs_brs_add(sb, bindex);
  22669. +
  22670. + if (!sysaufs_brs)
  22671. + return;
  22672. +
  22673. + kobj = &au_sbi(sb)->si_kobj;
  22674. + bend = au_sbend(sb);
  22675. + for (; bindex <= bend; bindex++) {
  22676. + br = au_sbr(sb, bindex);
  22677. + snprintf(br->br_name, sizeof(br->br_name), SysaufsBr_PREFIX
  22678. + "%d", bindex);
  22679. + err = sysfs_create_file(kobj, &br->br_attr);
  22680. + if (unlikely(err))
  22681. + pr_warning("failed %s under sysfs(%d)\n",
  22682. + br->br_name, err);
  22683. + }
  22684. +}
  22685. diff -Nur linux-2.6.37.orig/fs/aufs/sysrq.c linux-2.6.37/fs/aufs/sysrq.c
  22686. --- linux-2.6.37.orig/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100
  22687. +++ linux-2.6.37/fs/aufs/sysrq.c 2011-01-11 20:15:11.000000000 +0100
  22688. @@ -0,0 +1,148 @@
  22689. +/*
  22690. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  22691. + *
  22692. + * This program, aufs is free software; you can redistribute it and/or modify
  22693. + * it under the terms of the GNU General Public License as published by
  22694. + * the Free Software Foundation; either version 2 of the License, or
  22695. + * (at your option) any later version.
  22696. + *
  22697. + * This program is distributed in the hope that it will be useful,
  22698. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22699. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22700. + * GNU General Public License for more details.
  22701. + *
  22702. + * You should have received a copy of the GNU General Public License
  22703. + * along with this program; if not, write to the Free Software
  22704. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22705. + */
  22706. +
  22707. +/*
  22708. + * magic sysrq hanlder
  22709. + */
  22710. +
  22711. +#include <linux/fs.h>
  22712. +#include <linux/module.h>
  22713. +#include <linux/moduleparam.h>
  22714. +/* #include <linux/sysrq.h> */
  22715. +#include <linux/writeback.h>
  22716. +#include "aufs.h"
  22717. +
  22718. +/* ---------------------------------------------------------------------- */
  22719. +
  22720. +static void sysrq_sb(struct super_block *sb)
  22721. +{
  22722. + char *plevel;
  22723. + struct au_sbinfo *sbinfo;
  22724. + struct file *file;
  22725. +
  22726. + plevel = au_plevel;
  22727. + au_plevel = KERN_WARNING;
  22728. +
  22729. + sbinfo = au_sbi(sb);
  22730. + /* since we define pr_fmt, call printk directly */
  22731. + printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo));
  22732. + printk(KERN_WARNING AUFS_NAME ": superblock\n");
  22733. + au_dpri_sb(sb);
  22734. +
  22735. +#if 0
  22736. + printk(KERN_WARNING AUFS_NAME ": root dentry\n");
  22737. + au_dpri_dentry(sb->s_root);
  22738. + printk(KERN_WARNING AUFS_NAME ": root inode\n");
  22739. + au_dpri_inode(sb->s_root->d_inode);
  22740. +#endif
  22741. +
  22742. +#if 0
  22743. + do {
  22744. + int err, i, j, ndentry;
  22745. + struct au_dcsub_pages dpages;
  22746. + struct au_dpage *dpage;
  22747. +
  22748. + err = au_dpages_init(&dpages, GFP_ATOMIC);
  22749. + if (unlikely(err))
  22750. + break;
  22751. + err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL);
  22752. + if (!err)
  22753. + for (i = 0; i < dpages.ndpage; i++) {
  22754. + dpage = dpages.dpages + i;
  22755. + ndentry = dpage->ndentry;
  22756. + for (j = 0; j < ndentry; j++)
  22757. + au_dpri_dentry(dpage->dentries[j]);
  22758. + }
  22759. + au_dpages_free(&dpages);
  22760. + } while (0);
  22761. +#endif
  22762. +
  22763. +#if 1
  22764. + {
  22765. + struct inode *i;
  22766. + printk(KERN_WARNING AUFS_NAME ": isolated inode\n");
  22767. + spin_lock(&inode_lock);
  22768. + list_for_each_entry(i, &sb->s_inodes, i_sb_list)
  22769. + if (1 || list_empty(&i->i_dentry))
  22770. + au_dpri_inode(i);
  22771. + spin_unlock(&inode_lock);
  22772. + }
  22773. +#endif
  22774. + printk(KERN_WARNING AUFS_NAME ": files\n");
  22775. + lg_global_lock(files_lglock);
  22776. + do_file_list_for_each_entry(sb, file) {
  22777. + umode_t mode;
  22778. + mode = file->f_dentry->d_inode->i_mode;
  22779. + if (!special_file(mode) || au_special_file(mode))
  22780. + au_dpri_file(file);
  22781. + } while_file_list_for_each_entry;
  22782. + lg_global_unlock(files_lglock);
  22783. + printk(KERN_WARNING AUFS_NAME ": done\n");
  22784. +
  22785. + au_plevel = plevel;
  22786. +}
  22787. +
  22788. +/* ---------------------------------------------------------------------- */
  22789. +
  22790. +/* module parameter */
  22791. +static char *aufs_sysrq_key = "a";
  22792. +module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO);
  22793. +MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
  22794. +
  22795. +static void au_sysrq(int key __maybe_unused)
  22796. +{
  22797. + struct au_sbinfo *sbinfo;
  22798. +
  22799. + lockdep_off();
  22800. + spin_lock(&au_sbilist.spin);
  22801. + list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
  22802. + sysrq_sb(sbinfo->si_sb);
  22803. + spin_unlock(&au_sbilist.spin);
  22804. + lockdep_on();
  22805. +}
  22806. +
  22807. +static struct sysrq_key_op au_sysrq_op = {
  22808. + .handler = au_sysrq,
  22809. + .help_msg = "Aufs",
  22810. + .action_msg = "Aufs",
  22811. + .enable_mask = SYSRQ_ENABLE_DUMP
  22812. +};
  22813. +
  22814. +/* ---------------------------------------------------------------------- */
  22815. +
  22816. +int __init au_sysrq_init(void)
  22817. +{
  22818. + int err;
  22819. + char key;
  22820. +
  22821. + err = -1;
  22822. + key = *aufs_sysrq_key;
  22823. + if ('a' <= key && key <= 'z')
  22824. + err = register_sysrq_key(key, &au_sysrq_op);
  22825. + if (unlikely(err))
  22826. + pr_err("err %d, sysrq=%c\n", err, key);
  22827. + return err;
  22828. +}
  22829. +
  22830. +void au_sysrq_fin(void)
  22831. +{
  22832. + int err;
  22833. + err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
  22834. + if (unlikely(err))
  22835. + pr_err("err %d (ignored)\n", err);
  22836. +}
  22837. diff -Nur linux-2.6.37.orig/fs/aufs/vdir.c linux-2.6.37/fs/aufs/vdir.c
  22838. --- linux-2.6.37.orig/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100
  22839. +++ linux-2.6.37/fs/aufs/vdir.c 2011-01-11 20:15:11.000000000 +0100
  22840. @@ -0,0 +1,886 @@
  22841. +/*
  22842. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  22843. + *
  22844. + * This program, aufs is free software; you can redistribute it and/or modify
  22845. + * it under the terms of the GNU General Public License as published by
  22846. + * the Free Software Foundation; either version 2 of the License, or
  22847. + * (at your option) any later version.
  22848. + *
  22849. + * This program is distributed in the hope that it will be useful,
  22850. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22851. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22852. + * GNU General Public License for more details.
  22853. + *
  22854. + * You should have received a copy of the GNU General Public License
  22855. + * along with this program; if not, write to the Free Software
  22856. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22857. + */
  22858. +
  22859. +/*
  22860. + * virtual or vertical directory
  22861. + */
  22862. +
  22863. +#include <linux/hash.h>
  22864. +#include "aufs.h"
  22865. +
  22866. +static unsigned int calc_size(int nlen)
  22867. +{
  22868. + return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
  22869. +}
  22870. +
  22871. +static int set_deblk_end(union au_vdir_deblk_p *p,
  22872. + union au_vdir_deblk_p *deblk_end)
  22873. +{
  22874. + if (calc_size(0) <= deblk_end->deblk - p->deblk) {
  22875. + p->de->de_str.len = 0;
  22876. + /* smp_mb(); */
  22877. + return 0;
  22878. + }
  22879. + return -1; /* error */
  22880. +}
  22881. +
  22882. +/* returns true or false */
  22883. +static int is_deblk_end(union au_vdir_deblk_p *p,
  22884. + union au_vdir_deblk_p *deblk_end)
  22885. +{
  22886. + if (calc_size(0) <= deblk_end->deblk - p->deblk)
  22887. + return !p->de->de_str.len;
  22888. + return 1;
  22889. +}
  22890. +
  22891. +static unsigned char *last_deblk(struct au_vdir *vdir)
  22892. +{
  22893. + return vdir->vd_deblk[vdir->vd_nblk - 1];
  22894. +}
  22895. +
  22896. +/* ---------------------------------------------------------------------- */
  22897. +
  22898. +/* estimate the apropriate size for name hash table */
  22899. +unsigned int au_rdhash_est(loff_t sz)
  22900. +{
  22901. + unsigned int n;
  22902. +
  22903. + n = UINT_MAX;
  22904. + sz >>= 10;
  22905. + if (sz < n)
  22906. + n = sz;
  22907. + if (sz < AUFS_RDHASH_DEF)
  22908. + n = AUFS_RDHASH_DEF;
  22909. + /* pr_info("n %u\n", n); */
  22910. + return n;
  22911. +}
  22912. +
  22913. +/*
  22914. + * the allocated memory has to be freed by
  22915. + * au_nhash_wh_free() or au_nhash_de_free().
  22916. + */
  22917. +int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
  22918. +{
  22919. + struct hlist_head *head;
  22920. + unsigned int u;
  22921. +
  22922. + head = kmalloc(sizeof(*nhash->nh_head) * num_hash, gfp);
  22923. + if (head) {
  22924. + nhash->nh_num = num_hash;
  22925. + nhash->nh_head = head;
  22926. + for (u = 0; u < num_hash; u++)
  22927. + INIT_HLIST_HEAD(head++);
  22928. + return 0; /* success */
  22929. + }
  22930. +
  22931. + return -ENOMEM;
  22932. +}
  22933. +
  22934. +static void nhash_count(struct hlist_head *head)
  22935. +{
  22936. +#if 0
  22937. + unsigned long n;
  22938. + struct hlist_node *pos;
  22939. +
  22940. + n = 0;
  22941. + hlist_for_each(pos, head)
  22942. + n++;
  22943. + pr_info("%lu\n", n);
  22944. +#endif
  22945. +}
  22946. +
  22947. +static void au_nhash_wh_do_free(struct hlist_head *head)
  22948. +{
  22949. + struct au_vdir_wh *tpos;
  22950. + struct hlist_node *pos, *node;
  22951. +
  22952. + hlist_for_each_entry_safe(tpos, pos, node, head, wh_hash) {
  22953. + /* hlist_del(pos); */
  22954. + kfree(tpos);
  22955. + }
  22956. +}
  22957. +
  22958. +static void au_nhash_de_do_free(struct hlist_head *head)
  22959. +{
  22960. + struct au_vdir_dehstr *tpos;
  22961. + struct hlist_node *pos, *node;
  22962. +
  22963. + hlist_for_each_entry_safe(tpos, pos, node, head, hash) {
  22964. + /* hlist_del(pos); */
  22965. + au_cache_free_vdir_dehstr(tpos);
  22966. + }
  22967. +}
  22968. +
  22969. +static void au_nhash_do_free(struct au_nhash *nhash,
  22970. + void (*free)(struct hlist_head *head))
  22971. +{
  22972. + unsigned int n;
  22973. + struct hlist_head *head;
  22974. +
  22975. + n = nhash->nh_num;
  22976. + if (!n)
  22977. + return;
  22978. +
  22979. + head = nhash->nh_head;
  22980. + while (n-- > 0) {
  22981. + nhash_count(head);
  22982. + free(head++);
  22983. + }
  22984. + kfree(nhash->nh_head);
  22985. +}
  22986. +
  22987. +void au_nhash_wh_free(struct au_nhash *whlist)
  22988. +{
  22989. + au_nhash_do_free(whlist, au_nhash_wh_do_free);
  22990. +}
  22991. +
  22992. +static void au_nhash_de_free(struct au_nhash *delist)
  22993. +{
  22994. + au_nhash_do_free(delist, au_nhash_de_do_free);
  22995. +}
  22996. +
  22997. +/* ---------------------------------------------------------------------- */
  22998. +
  22999. +int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
  23000. + int limit)
  23001. +{
  23002. + int num;
  23003. + unsigned int u, n;
  23004. + struct hlist_head *head;
  23005. + struct au_vdir_wh *tpos;
  23006. + struct hlist_node *pos;
  23007. +
  23008. + num = 0;
  23009. + n = whlist->nh_num;
  23010. + head = whlist->nh_head;
  23011. + for (u = 0; u < n; u++, head++)
  23012. + hlist_for_each_entry(tpos, pos, head, wh_hash)
  23013. + if (tpos->wh_bindex == btgt && ++num > limit)
  23014. + return 1;
  23015. + return 0;
  23016. +}
  23017. +
  23018. +static struct hlist_head *au_name_hash(struct au_nhash *nhash,
  23019. + unsigned char *name,
  23020. + unsigned int len)
  23021. +{
  23022. + unsigned int v;
  23023. + /* const unsigned int magic_bit = 12; */
  23024. +
  23025. + AuDebugOn(!nhash->nh_num || !nhash->nh_head);
  23026. +
  23027. + v = 0;
  23028. + while (len--)
  23029. + v += *name++;
  23030. + /* v = hash_long(v, magic_bit); */
  23031. + v %= nhash->nh_num;
  23032. + return nhash->nh_head + v;
  23033. +}
  23034. +
  23035. +static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
  23036. + int nlen)
  23037. +{
  23038. + return str->len == nlen && !memcmp(str->name, name, nlen);
  23039. +}
  23040. +
  23041. +/* returns found or not */
  23042. +int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
  23043. +{
  23044. + struct hlist_head *head;
  23045. + struct au_vdir_wh *tpos;
  23046. + struct hlist_node *pos;
  23047. + struct au_vdir_destr *str;
  23048. +
  23049. + head = au_name_hash(whlist, name, nlen);
  23050. + hlist_for_each_entry(tpos, pos, head, wh_hash) {
  23051. + str = &tpos->wh_str;
  23052. + AuDbg("%.*s\n", str->len, str->name);
  23053. + if (au_nhash_test_name(str, name, nlen))
  23054. + return 1;
  23055. + }
  23056. + return 0;
  23057. +}
  23058. +
  23059. +/* returns found(true) or not */
  23060. +static int test_known(struct au_nhash *delist, char *name, int nlen)
  23061. +{
  23062. + struct hlist_head *head;
  23063. + struct au_vdir_dehstr *tpos;
  23064. + struct hlist_node *pos;
  23065. + struct au_vdir_destr *str;
  23066. +
  23067. + head = au_name_hash(delist, name, nlen);
  23068. + hlist_for_each_entry(tpos, pos, head, hash) {
  23069. + str = tpos->str;
  23070. + AuDbg("%.*s\n", str->len, str->name);
  23071. + if (au_nhash_test_name(str, name, nlen))
  23072. + return 1;
  23073. + }
  23074. + return 0;
  23075. +}
  23076. +
  23077. +static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
  23078. + unsigned char d_type)
  23079. +{
  23080. +#ifdef CONFIG_AUFS_SHWH
  23081. + wh->wh_ino = ino;
  23082. + wh->wh_type = d_type;
  23083. +#endif
  23084. +}
  23085. +
  23086. +/* ---------------------------------------------------------------------- */
  23087. +
  23088. +int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
  23089. + unsigned int d_type, aufs_bindex_t bindex,
  23090. + unsigned char shwh)
  23091. +{
  23092. + int err;
  23093. + struct au_vdir_destr *str;
  23094. + struct au_vdir_wh *wh;
  23095. +
  23096. + AuDbg("%.*s\n", nlen, name);
  23097. + AuDebugOn(!whlist->nh_num || !whlist->nh_head);
  23098. +
  23099. + err = -ENOMEM;
  23100. + wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
  23101. + if (unlikely(!wh))
  23102. + goto out;
  23103. +
  23104. + err = 0;
  23105. + wh->wh_bindex = bindex;
  23106. + if (shwh)
  23107. + au_shwh_init_wh(wh, ino, d_type);
  23108. + str = &wh->wh_str;
  23109. + str->len = nlen;
  23110. + memcpy(str->name, name, nlen);
  23111. + hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
  23112. + /* smp_mb(); */
  23113. +
  23114. +out:
  23115. + return err;
  23116. +}
  23117. +
  23118. +static int append_deblk(struct au_vdir *vdir)
  23119. +{
  23120. + int err;
  23121. + unsigned long ul;
  23122. + const unsigned int deblk_sz = vdir->vd_deblk_sz;
  23123. + union au_vdir_deblk_p p, deblk_end;
  23124. + unsigned char **o;
  23125. +
  23126. + err = -ENOMEM;
  23127. + o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
  23128. + GFP_NOFS);
  23129. + if (unlikely(!o))
  23130. + goto out;
  23131. +
  23132. + vdir->vd_deblk = o;
  23133. + p.deblk = kmalloc(deblk_sz, GFP_NOFS);
  23134. + if (p.deblk) {
  23135. + ul = vdir->vd_nblk++;
  23136. + vdir->vd_deblk[ul] = p.deblk;
  23137. + vdir->vd_last.ul = ul;
  23138. + vdir->vd_last.p.deblk = p.deblk;
  23139. + deblk_end.deblk = p.deblk + deblk_sz;
  23140. + err = set_deblk_end(&p, &deblk_end);
  23141. + }
  23142. +
  23143. +out:
  23144. + return err;
  23145. +}
  23146. +
  23147. +static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
  23148. + unsigned int d_type, struct au_nhash *delist)
  23149. +{
  23150. + int err;
  23151. + unsigned int sz;
  23152. + const unsigned int deblk_sz = vdir->vd_deblk_sz;
  23153. + union au_vdir_deblk_p p, *room, deblk_end;
  23154. + struct au_vdir_dehstr *dehstr;
  23155. +
  23156. + p.deblk = last_deblk(vdir);
  23157. + deblk_end.deblk = p.deblk + deblk_sz;
  23158. + room = &vdir->vd_last.p;
  23159. + AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
  23160. + || !is_deblk_end(room, &deblk_end));
  23161. +
  23162. + sz = calc_size(nlen);
  23163. + if (unlikely(sz > deblk_end.deblk - room->deblk)) {
  23164. + err = append_deblk(vdir);
  23165. + if (unlikely(err))
  23166. + goto out;
  23167. +
  23168. + p.deblk = last_deblk(vdir);
  23169. + deblk_end.deblk = p.deblk + deblk_sz;
  23170. + /* smp_mb(); */
  23171. + AuDebugOn(room->deblk != p.deblk);
  23172. + }
  23173. +
  23174. + err = -ENOMEM;
  23175. + dehstr = au_cache_alloc_vdir_dehstr();
  23176. + if (unlikely(!dehstr))
  23177. + goto out;
  23178. +
  23179. + dehstr->str = &room->de->de_str;
  23180. + hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
  23181. + room->de->de_ino = ino;
  23182. + room->de->de_type = d_type;
  23183. + room->de->de_str.len = nlen;
  23184. + memcpy(room->de->de_str.name, name, nlen);
  23185. +
  23186. + err = 0;
  23187. + room->deblk += sz;
  23188. + if (unlikely(set_deblk_end(room, &deblk_end)))
  23189. + err = append_deblk(vdir);
  23190. + /* smp_mb(); */
  23191. +
  23192. +out:
  23193. + return err;
  23194. +}
  23195. +
  23196. +/* ---------------------------------------------------------------------- */
  23197. +
  23198. +void au_vdir_free(struct au_vdir *vdir)
  23199. +{
  23200. + unsigned char **deblk;
  23201. +
  23202. + deblk = vdir->vd_deblk;
  23203. + while (vdir->vd_nblk--)
  23204. + kfree(*deblk++);
  23205. + kfree(vdir->vd_deblk);
  23206. + au_cache_free_vdir(vdir);
  23207. +}
  23208. +
  23209. +static struct au_vdir *alloc_vdir(struct file *file)
  23210. +{
  23211. + struct au_vdir *vdir;
  23212. + struct super_block *sb;
  23213. + int err;
  23214. +
  23215. + sb = file->f_dentry->d_sb;
  23216. + SiMustAnyLock(sb);
  23217. +
  23218. + err = -ENOMEM;
  23219. + vdir = au_cache_alloc_vdir();
  23220. + if (unlikely(!vdir))
  23221. + goto out;
  23222. +
  23223. + vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
  23224. + if (unlikely(!vdir->vd_deblk))
  23225. + goto out_free;
  23226. +
  23227. + vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
  23228. + if (!vdir->vd_deblk_sz) {
  23229. + /* estimate the apropriate size for deblk */
  23230. + vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
  23231. + /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
  23232. + }
  23233. + vdir->vd_nblk = 0;
  23234. + vdir->vd_version = 0;
  23235. + vdir->vd_jiffy = 0;
  23236. + err = append_deblk(vdir);
  23237. + if (!err)
  23238. + return vdir; /* success */
  23239. +
  23240. + kfree(vdir->vd_deblk);
  23241. +
  23242. +out_free:
  23243. + au_cache_free_vdir(vdir);
  23244. +out:
  23245. + vdir = ERR_PTR(err);
  23246. + return vdir;
  23247. +}
  23248. +
  23249. +static int reinit_vdir(struct au_vdir *vdir)
  23250. +{
  23251. + int err;
  23252. + union au_vdir_deblk_p p, deblk_end;
  23253. +
  23254. + while (vdir->vd_nblk > 1) {
  23255. + kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
  23256. + /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
  23257. + vdir->vd_nblk--;
  23258. + }
  23259. + p.deblk = vdir->vd_deblk[0];
  23260. + deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
  23261. + err = set_deblk_end(&p, &deblk_end);
  23262. + /* keep vd_dblk_sz */
  23263. + vdir->vd_last.ul = 0;
  23264. + vdir->vd_last.p.deblk = vdir->vd_deblk[0];
  23265. + vdir->vd_version = 0;
  23266. + vdir->vd_jiffy = 0;
  23267. + /* smp_mb(); */
  23268. + return err;
  23269. +}
  23270. +
  23271. +/* ---------------------------------------------------------------------- */
  23272. +
  23273. +#define AuFillVdir_CALLED 1
  23274. +#define AuFillVdir_WHABLE (1 << 1)
  23275. +#define AuFillVdir_SHWH (1 << 2)
  23276. +#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
  23277. +#define au_fset_fillvdir(flags, name) \
  23278. + do { (flags) |= AuFillVdir_##name; } while (0)
  23279. +#define au_fclr_fillvdir(flags, name) \
  23280. + do { (flags) &= ~AuFillVdir_##name; } while (0)
  23281. +
  23282. +#ifndef CONFIG_AUFS_SHWH
  23283. +#undef AuFillVdir_SHWH
  23284. +#define AuFillVdir_SHWH 0
  23285. +#endif
  23286. +
  23287. +struct fillvdir_arg {
  23288. + struct file *file;
  23289. + struct au_vdir *vdir;
  23290. + struct au_nhash delist;
  23291. + struct au_nhash whlist;
  23292. + aufs_bindex_t bindex;
  23293. + unsigned int flags;
  23294. + int err;
  23295. +};
  23296. +
  23297. +static int fillvdir(void *__arg, const char *__name, int nlen,
  23298. + loff_t offset __maybe_unused, u64 h_ino,
  23299. + unsigned int d_type)
  23300. +{
  23301. + struct fillvdir_arg *arg = __arg;
  23302. + char *name = (void *)__name;
  23303. + struct super_block *sb;
  23304. + ino_t ino;
  23305. + const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
  23306. +
  23307. + arg->err = 0;
  23308. + sb = arg->file->f_dentry->d_sb;
  23309. + au_fset_fillvdir(arg->flags, CALLED);
  23310. + /* smp_mb(); */
  23311. + if (nlen <= AUFS_WH_PFX_LEN
  23312. + || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
  23313. + if (test_known(&arg->delist, name, nlen)
  23314. + || au_nhash_test_known_wh(&arg->whlist, name, nlen))
  23315. + goto out; /* already exists or whiteouted */
  23316. +
  23317. + sb = arg->file->f_dentry->d_sb;
  23318. + arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
  23319. + if (!arg->err) {
  23320. + if (unlikely(nlen > AUFS_MAX_NAMELEN))
  23321. + d_type = DT_UNKNOWN;
  23322. + arg->err = append_de(arg->vdir, name, nlen, ino,
  23323. + d_type, &arg->delist);
  23324. + }
  23325. + } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
  23326. + name += AUFS_WH_PFX_LEN;
  23327. + nlen -= AUFS_WH_PFX_LEN;
  23328. + if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
  23329. + goto out; /* already whiteouted */
  23330. +
  23331. + if (shwh)
  23332. + arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
  23333. + &ino);
  23334. + if (!arg->err) {
  23335. + if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
  23336. + d_type = DT_UNKNOWN;
  23337. + arg->err = au_nhash_append_wh
  23338. + (&arg->whlist, name, nlen, ino, d_type,
  23339. + arg->bindex, shwh);
  23340. + }
  23341. + }
  23342. +
  23343. +out:
  23344. + if (!arg->err)
  23345. + arg->vdir->vd_jiffy = jiffies;
  23346. + /* smp_mb(); */
  23347. + AuTraceErr(arg->err);
  23348. + return arg->err;
  23349. +}
  23350. +
  23351. +static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
  23352. + struct au_nhash *whlist, struct au_nhash *delist)
  23353. +{
  23354. +#ifdef CONFIG_AUFS_SHWH
  23355. + int err;
  23356. + unsigned int nh, u;
  23357. + struct hlist_head *head;
  23358. + struct au_vdir_wh *tpos;
  23359. + struct hlist_node *pos, *n;
  23360. + char *p, *o;
  23361. + struct au_vdir_destr *destr;
  23362. +
  23363. + AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
  23364. +
  23365. + err = -ENOMEM;
  23366. + o = p = __getname_gfp(GFP_NOFS);
  23367. + if (unlikely(!p))
  23368. + goto out;
  23369. +
  23370. + err = 0;
  23371. + nh = whlist->nh_num;
  23372. + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
  23373. + p += AUFS_WH_PFX_LEN;
  23374. + for (u = 0; u < nh; u++) {
  23375. + head = whlist->nh_head + u;
  23376. + hlist_for_each_entry_safe(tpos, pos, n, head, wh_hash) {
  23377. + destr = &tpos->wh_str;
  23378. + memcpy(p, destr->name, destr->len);
  23379. + err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
  23380. + tpos->wh_ino, tpos->wh_type, delist);
  23381. + if (unlikely(err))
  23382. + break;
  23383. + }
  23384. + }
  23385. +
  23386. + __putname(o);
  23387. +
  23388. +out:
  23389. + AuTraceErr(err);
  23390. + return err;
  23391. +#else
  23392. + return 0;
  23393. +#endif
  23394. +}
  23395. +
  23396. +static int au_do_read_vdir(struct fillvdir_arg *arg)
  23397. +{
  23398. + int err;
  23399. + unsigned int rdhash;
  23400. + loff_t offset;
  23401. + aufs_bindex_t bend, bindex, bstart;
  23402. + unsigned char shwh;
  23403. + struct file *hf, *file;
  23404. + struct super_block *sb;
  23405. +
  23406. + file = arg->file;
  23407. + sb = file->f_dentry->d_sb;
  23408. + SiMustAnyLock(sb);
  23409. +
  23410. + rdhash = au_sbi(sb)->si_rdhash;
  23411. + if (!rdhash)
  23412. + rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
  23413. + err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
  23414. + if (unlikely(err))
  23415. + goto out;
  23416. + err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
  23417. + if (unlikely(err))
  23418. + goto out_delist;
  23419. +
  23420. + err = 0;
  23421. + arg->flags = 0;
  23422. + shwh = 0;
  23423. + if (au_opt_test(au_mntflags(sb), SHWH)) {
  23424. + shwh = 1;
  23425. + au_fset_fillvdir(arg->flags, SHWH);
  23426. + }
  23427. + bstart = au_fbstart(file);
  23428. + bend = au_fbend_dir(file);
  23429. + for (bindex = bstart; !err && bindex <= bend; bindex++) {
  23430. + hf = au_hf_dir(file, bindex);
  23431. + if (!hf)
  23432. + continue;
  23433. +
  23434. + offset = vfsub_llseek(hf, 0, SEEK_SET);
  23435. + err = offset;
  23436. + if (unlikely(offset))
  23437. + break;
  23438. +
  23439. + arg->bindex = bindex;
  23440. + au_fclr_fillvdir(arg->flags, WHABLE);
  23441. + if (shwh
  23442. + || (bindex != bend
  23443. + && au_br_whable(au_sbr_perm(sb, bindex))))
  23444. + au_fset_fillvdir(arg->flags, WHABLE);
  23445. + do {
  23446. + arg->err = 0;
  23447. + au_fclr_fillvdir(arg->flags, CALLED);
  23448. + /* smp_mb(); */
  23449. + err = vfsub_readdir(hf, fillvdir, arg);
  23450. + if (err >= 0)
  23451. + err = arg->err;
  23452. + } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
  23453. + }
  23454. +
  23455. + if (!err && shwh)
  23456. + err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
  23457. +
  23458. + au_nhash_wh_free(&arg->whlist);
  23459. +
  23460. +out_delist:
  23461. + au_nhash_de_free(&arg->delist);
  23462. +out:
  23463. + return err;
  23464. +}
  23465. +
  23466. +static int read_vdir(struct file *file, int may_read)
  23467. +{
  23468. + int err;
  23469. + unsigned long expire;
  23470. + unsigned char do_read;
  23471. + struct fillvdir_arg arg;
  23472. + struct inode *inode;
  23473. + struct au_vdir *vdir, *allocated;
  23474. +
  23475. + err = 0;
  23476. + inode = file->f_dentry->d_inode;
  23477. + IMustLock(inode);
  23478. + SiMustAnyLock(inode->i_sb);
  23479. +
  23480. + allocated = NULL;
  23481. + do_read = 0;
  23482. + expire = au_sbi(inode->i_sb)->si_rdcache;
  23483. + vdir = au_ivdir(inode);
  23484. + if (!vdir) {
  23485. + do_read = 1;
  23486. + vdir = alloc_vdir(file);
  23487. + err = PTR_ERR(vdir);
  23488. + if (IS_ERR(vdir))
  23489. + goto out;
  23490. + err = 0;
  23491. + allocated = vdir;
  23492. + } else if (may_read
  23493. + && (inode->i_version != vdir->vd_version
  23494. + || time_after(jiffies, vdir->vd_jiffy + expire))) {
  23495. + do_read = 1;
  23496. + err = reinit_vdir(vdir);
  23497. + if (unlikely(err))
  23498. + goto out;
  23499. + }
  23500. +
  23501. + if (!do_read)
  23502. + return 0; /* success */
  23503. +
  23504. + arg.file = file;
  23505. + arg.vdir = vdir;
  23506. + err = au_do_read_vdir(&arg);
  23507. + if (!err) {
  23508. + /* file->f_pos = 0; */
  23509. + vdir->vd_version = inode->i_version;
  23510. + vdir->vd_last.ul = 0;
  23511. + vdir->vd_last.p.deblk = vdir->vd_deblk[0];
  23512. + if (allocated)
  23513. + au_set_ivdir(inode, allocated);
  23514. + } else if (allocated)
  23515. + au_vdir_free(allocated);
  23516. +
  23517. +out:
  23518. + return err;
  23519. +}
  23520. +
  23521. +static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
  23522. +{
  23523. + int err, rerr;
  23524. + unsigned long ul, n;
  23525. + const unsigned int deblk_sz = src->vd_deblk_sz;
  23526. +
  23527. + AuDebugOn(tgt->vd_nblk != 1);
  23528. +
  23529. + err = -ENOMEM;
  23530. + if (tgt->vd_nblk < src->vd_nblk) {
  23531. + unsigned char **p;
  23532. +
  23533. + p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
  23534. + GFP_NOFS);
  23535. + if (unlikely(!p))
  23536. + goto out;
  23537. + tgt->vd_deblk = p;
  23538. + }
  23539. +
  23540. + if (tgt->vd_deblk_sz != deblk_sz) {
  23541. + unsigned char *p;
  23542. +
  23543. + tgt->vd_deblk_sz = deblk_sz;
  23544. + p = krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS);
  23545. + if (unlikely(!p))
  23546. + goto out;
  23547. + tgt->vd_deblk[0] = p;
  23548. + }
  23549. + memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
  23550. + tgt->vd_version = src->vd_version;
  23551. + tgt->vd_jiffy = src->vd_jiffy;
  23552. +
  23553. + n = src->vd_nblk;
  23554. + for (ul = 1; ul < n; ul++) {
  23555. + tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
  23556. + GFP_NOFS);
  23557. + if (unlikely(!tgt->vd_deblk[ul]))
  23558. + goto out;
  23559. + tgt->vd_nblk++;
  23560. + }
  23561. + tgt->vd_nblk = n;
  23562. + tgt->vd_last.ul = tgt->vd_last.ul;
  23563. + tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul];
  23564. + tgt->vd_last.p.deblk += src->vd_last.p.deblk
  23565. + - src->vd_deblk[src->vd_last.ul];
  23566. + /* smp_mb(); */
  23567. + return 0; /* success */
  23568. +
  23569. +out:
  23570. + rerr = reinit_vdir(tgt);
  23571. + BUG_ON(rerr);
  23572. + return err;
  23573. +}
  23574. +
  23575. +int au_vdir_init(struct file *file)
  23576. +{
  23577. + int err;
  23578. + struct inode *inode;
  23579. + struct au_vdir *vdir_cache, *allocated;
  23580. +
  23581. + err = read_vdir(file, !file->f_pos);
  23582. + if (unlikely(err))
  23583. + goto out;
  23584. +
  23585. + allocated = NULL;
  23586. + vdir_cache = au_fvdir_cache(file);
  23587. + if (!vdir_cache) {
  23588. + vdir_cache = alloc_vdir(file);
  23589. + err = PTR_ERR(vdir_cache);
  23590. + if (IS_ERR(vdir_cache))
  23591. + goto out;
  23592. + allocated = vdir_cache;
  23593. + } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
  23594. + err = reinit_vdir(vdir_cache);
  23595. + if (unlikely(err))
  23596. + goto out;
  23597. + } else
  23598. + return 0; /* success */
  23599. +
  23600. + inode = file->f_dentry->d_inode;
  23601. + err = copy_vdir(vdir_cache, au_ivdir(inode));
  23602. + if (!err) {
  23603. + file->f_version = inode->i_version;
  23604. + if (allocated)
  23605. + au_set_fvdir_cache(file, allocated);
  23606. + } else if (allocated)
  23607. + au_vdir_free(allocated);
  23608. +
  23609. +out:
  23610. + return err;
  23611. +}
  23612. +
  23613. +static loff_t calc_offset(struct au_vdir *vdir)
  23614. +{
  23615. + loff_t offset;
  23616. + union au_vdir_deblk_p p;
  23617. +
  23618. + p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
  23619. + offset = vdir->vd_last.p.deblk - p.deblk;
  23620. + offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
  23621. + return offset;
  23622. +}
  23623. +
  23624. +/* returns true or false */
  23625. +static int seek_vdir(struct file *file)
  23626. +{
  23627. + int valid;
  23628. + unsigned int deblk_sz;
  23629. + unsigned long ul, n;
  23630. + loff_t offset;
  23631. + union au_vdir_deblk_p p, deblk_end;
  23632. + struct au_vdir *vdir_cache;
  23633. +
  23634. + valid = 1;
  23635. + vdir_cache = au_fvdir_cache(file);
  23636. + offset = calc_offset(vdir_cache);
  23637. + AuDbg("offset %lld\n", offset);
  23638. + if (file->f_pos == offset)
  23639. + goto out;
  23640. +
  23641. + vdir_cache->vd_last.ul = 0;
  23642. + vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
  23643. + if (!file->f_pos)
  23644. + goto out;
  23645. +
  23646. + valid = 0;
  23647. + deblk_sz = vdir_cache->vd_deblk_sz;
  23648. + ul = div64_u64(file->f_pos, deblk_sz);
  23649. + AuDbg("ul %lu\n", ul);
  23650. + if (ul >= vdir_cache->vd_nblk)
  23651. + goto out;
  23652. +
  23653. + n = vdir_cache->vd_nblk;
  23654. + for (; ul < n; ul++) {
  23655. + p.deblk = vdir_cache->vd_deblk[ul];
  23656. + deblk_end.deblk = p.deblk + deblk_sz;
  23657. + offset = ul;
  23658. + offset *= deblk_sz;
  23659. + while (!is_deblk_end(&p, &deblk_end) && offset < file->f_pos) {
  23660. + unsigned int l;
  23661. +
  23662. + l = calc_size(p.de->de_str.len);
  23663. + offset += l;
  23664. + p.deblk += l;
  23665. + }
  23666. + if (!is_deblk_end(&p, &deblk_end)) {
  23667. + valid = 1;
  23668. + vdir_cache->vd_last.ul = ul;
  23669. + vdir_cache->vd_last.p = p;
  23670. + break;
  23671. + }
  23672. + }
  23673. +
  23674. +out:
  23675. + /* smp_mb(); */
  23676. + AuTraceErr(!valid);
  23677. + return valid;
  23678. +}
  23679. +
  23680. +int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir)
  23681. +{
  23682. + int err;
  23683. + unsigned int l, deblk_sz;
  23684. + union au_vdir_deblk_p deblk_end;
  23685. + struct au_vdir *vdir_cache;
  23686. + struct au_vdir_de *de;
  23687. +
  23688. + vdir_cache = au_fvdir_cache(file);
  23689. + if (!seek_vdir(file))
  23690. + return 0;
  23691. +
  23692. + deblk_sz = vdir_cache->vd_deblk_sz;
  23693. + while (1) {
  23694. + deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
  23695. + deblk_end.deblk += deblk_sz;
  23696. + while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
  23697. + de = vdir_cache->vd_last.p.de;
  23698. + AuDbg("%.*s, off%lld, i%lu, dt%d\n",
  23699. + de->de_str.len, de->de_str.name, file->f_pos,
  23700. + (unsigned long)de->de_ino, de->de_type);
  23701. + err = filldir(dirent, de->de_str.name, de->de_str.len,
  23702. + file->f_pos, de->de_ino, de->de_type);
  23703. + if (unlikely(err)) {
  23704. + AuTraceErr(err);
  23705. + /* todo: ignore the error caused by udba? */
  23706. + /* return err; */
  23707. + return 0;
  23708. + }
  23709. +
  23710. + l = calc_size(de->de_str.len);
  23711. + vdir_cache->vd_last.p.deblk += l;
  23712. + file->f_pos += l;
  23713. + }
  23714. + if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
  23715. + vdir_cache->vd_last.ul++;
  23716. + vdir_cache->vd_last.p.deblk
  23717. + = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
  23718. + file->f_pos = deblk_sz * vdir_cache->vd_last.ul;
  23719. + continue;
  23720. + }
  23721. + break;
  23722. + }
  23723. +
  23724. + /* smp_mb(); */
  23725. + return 0;
  23726. +}
  23727. diff -Nur linux-2.6.37.orig/fs/aufs/vfsub.c linux-2.6.37/fs/aufs/vfsub.c
  23728. --- linux-2.6.37.orig/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100
  23729. +++ linux-2.6.37/fs/aufs/vfsub.c 2011-01-11 20:15:11.000000000 +0100
  23730. @@ -0,0 +1,790 @@
  23731. +/*
  23732. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  23733. + *
  23734. + * This program, aufs is free software; you can redistribute it and/or modify
  23735. + * it under the terms of the GNU General Public License as published by
  23736. + * the Free Software Foundation; either version 2 of the License, or
  23737. + * (at your option) any later version.
  23738. + *
  23739. + * This program is distributed in the hope that it will be useful,
  23740. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23741. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23742. + * GNU General Public License for more details.
  23743. + *
  23744. + * You should have received a copy of the GNU General Public License
  23745. + * along with this program; if not, write to the Free Software
  23746. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  23747. + */
  23748. +
  23749. +/*
  23750. + * sub-routines for VFS
  23751. + */
  23752. +
  23753. +#include <linux/file.h>
  23754. +#include <linux/ima.h>
  23755. +#include <linux/namei.h>
  23756. +#include <linux/security.h>
  23757. +#include <linux/splice.h>
  23758. +#include <linux/uaccess.h>
  23759. +#include "aufs.h"
  23760. +
  23761. +int vfsub_update_h_iattr(struct path *h_path, int *did)
  23762. +{
  23763. + int err;
  23764. + struct kstat st;
  23765. + struct super_block *h_sb;
  23766. +
  23767. + /* for remote fs, leave work for its getattr or d_revalidate */
  23768. + /* for bad i_attr fs, handle them in aufs_getattr() */
  23769. + /* still some fs may acquire i_mutex. we need to skip them */
  23770. + err = 0;
  23771. + if (!did)
  23772. + did = &err;
  23773. + h_sb = h_path->dentry->d_sb;
  23774. + *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
  23775. + if (*did)
  23776. + err = vfs_getattr(h_path->mnt, h_path->dentry, &st);
  23777. +
  23778. + return err;
  23779. +}
  23780. +
  23781. +/* ---------------------------------------------------------------------- */
  23782. +
  23783. +static int au_conv_oflags(int flags)
  23784. +{
  23785. + int mask = 0;
  23786. +
  23787. +#ifdef CONFIG_IMA
  23788. + fmode_t fmode;
  23789. +
  23790. + /* mask = MAY_OPEN; */
  23791. + fmode = OPEN_FMODE(flags);
  23792. + if (fmode & FMODE_READ)
  23793. + mask |= MAY_READ;
  23794. + if ((fmode & FMODE_WRITE)
  23795. + || (flags & O_TRUNC))
  23796. + mask |= MAY_WRITE;
  23797. + /*
  23798. + * if (flags & O_APPEND)
  23799. + * mask |= MAY_APPEND;
  23800. + */
  23801. + if (flags & vfsub_fmode_to_uint(FMODE_EXEC))
  23802. + mask |= MAY_EXEC;
  23803. +
  23804. + AuDbg("flags 0x%x, mask 0x%x\n", flags, mask);
  23805. +#endif
  23806. +
  23807. + return mask;
  23808. +}
  23809. +
  23810. +struct file *vfsub_dentry_open(struct path *path, int flags)
  23811. +{
  23812. + struct file *file;
  23813. + int err;
  23814. +
  23815. + path_get(path);
  23816. + file = dentry_open(path->dentry, path->mnt,
  23817. + flags /* | vfsub_fmode_to_uint(FMODE_NONOTIFY) */,
  23818. + current_cred());
  23819. + if (IS_ERR(file))
  23820. + goto out;
  23821. +
  23822. + err = ima_file_check(file, au_conv_oflags(flags));
  23823. + if (unlikely(err)) {
  23824. + fput(file);
  23825. + file = ERR_PTR(err);
  23826. + }
  23827. +out:
  23828. + return file;
  23829. +}
  23830. +
  23831. +struct file *vfsub_filp_open(const char *path, int oflags, int mode)
  23832. +{
  23833. + struct file *file;
  23834. +
  23835. + file = filp_open(path,
  23836. + oflags /* | vfsub_fmode_to_uint(FMODE_NONOTIFY) */,
  23837. + mode);
  23838. + if (IS_ERR(file))
  23839. + goto out;
  23840. + vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
  23841. +
  23842. +out:
  23843. + return file;
  23844. +}
  23845. +
  23846. +int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
  23847. +{
  23848. + int err;
  23849. +
  23850. + err = kern_path(name, flags, path);
  23851. + if (!err && path->dentry->d_inode)
  23852. + vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
  23853. + return err;
  23854. +}
  23855. +
  23856. +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
  23857. + int len)
  23858. +{
  23859. + struct path path = {
  23860. + .mnt = NULL
  23861. + };
  23862. +
  23863. + /* VFS checks it too, but by WARN_ON_ONCE() */
  23864. + IMustLock(parent->d_inode);
  23865. +
  23866. + path.dentry = lookup_one_len(name, parent, len);
  23867. + if (IS_ERR(path.dentry))
  23868. + goto out;
  23869. + if (path.dentry->d_inode)
  23870. + vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
  23871. +
  23872. +out:
  23873. + AuTraceErrPtr(path.dentry);
  23874. + return path.dentry;
  23875. +}
  23876. +
  23877. +struct dentry *vfsub_lookup_hash(struct nameidata *nd)
  23878. +{
  23879. + struct path path = {
  23880. + .mnt = nd->path.mnt
  23881. + };
  23882. +
  23883. + IMustLock(nd->path.dentry->d_inode);
  23884. +
  23885. + path.dentry = lookup_hash(nd);
  23886. + if (IS_ERR(path.dentry))
  23887. + goto out;
  23888. + if (path.dentry->d_inode)
  23889. + vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
  23890. +
  23891. +out:
  23892. + AuTraceErrPtr(path.dentry);
  23893. + return path.dentry;
  23894. +}
  23895. +
  23896. +/* ---------------------------------------------------------------------- */
  23897. +
  23898. +struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
  23899. + struct dentry *d2, struct au_hinode *hdir2)
  23900. +{
  23901. + struct dentry *d;
  23902. +
  23903. + d = lock_rename(d1, d2);
  23904. + au_hn_suspend(hdir1);
  23905. + if (hdir1 != hdir2)
  23906. + au_hn_suspend(hdir2);
  23907. +
  23908. + return d;
  23909. +}
  23910. +
  23911. +void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
  23912. + struct dentry *d2, struct au_hinode *hdir2)
  23913. +{
  23914. + au_hn_resume(hdir1);
  23915. + if (hdir1 != hdir2)
  23916. + au_hn_resume(hdir2);
  23917. + unlock_rename(d1, d2);
  23918. +}
  23919. +
  23920. +/* ---------------------------------------------------------------------- */
  23921. +
  23922. +int vfsub_create(struct inode *dir, struct path *path, int mode)
  23923. +{
  23924. + int err;
  23925. + struct dentry *d;
  23926. +
  23927. + IMustLock(dir);
  23928. +
  23929. + d = path->dentry;
  23930. + path->dentry = d->d_parent;
  23931. + err = security_path_mknod(path, d, mode, 0);
  23932. + path->dentry = d;
  23933. + if (unlikely(err))
  23934. + goto out;
  23935. +
  23936. + if (au_test_fs_null_nd(dir->i_sb))
  23937. + err = vfs_create(dir, path->dentry, mode, NULL);
  23938. + else {
  23939. + struct nameidata h_nd;
  23940. +
  23941. + memset(&h_nd, 0, sizeof(h_nd));
  23942. + h_nd.flags = LOOKUP_CREATE;
  23943. + h_nd.intent.open.flags = O_CREAT
  23944. + | vfsub_fmode_to_uint(FMODE_READ);
  23945. + h_nd.intent.open.create_mode = mode;
  23946. + h_nd.path.dentry = path->dentry->d_parent;
  23947. + h_nd.path.mnt = path->mnt;
  23948. + path_get(&h_nd.path);
  23949. + err = vfs_create(dir, path->dentry, mode, &h_nd);
  23950. + path_put(&h_nd.path);
  23951. + }
  23952. +
  23953. + if (!err) {
  23954. + struct path tmp = *path;
  23955. + int did;
  23956. +
  23957. + vfsub_update_h_iattr(&tmp, &did);
  23958. + if (did) {
  23959. + tmp.dentry = path->dentry->d_parent;
  23960. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  23961. + }
  23962. + /*ignore*/
  23963. + }
  23964. +
  23965. +out:
  23966. + return err;
  23967. +}
  23968. +
  23969. +int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
  23970. +{
  23971. + int err;
  23972. + struct dentry *d;
  23973. +
  23974. + IMustLock(dir);
  23975. +
  23976. + d = path->dentry;
  23977. + path->dentry = d->d_parent;
  23978. + err = security_path_symlink(path, d, symname);
  23979. + path->dentry = d;
  23980. + if (unlikely(err))
  23981. + goto out;
  23982. +
  23983. + err = vfs_symlink(dir, path->dentry, symname);
  23984. + if (!err) {
  23985. + struct path tmp = *path;
  23986. + int did;
  23987. +
  23988. + vfsub_update_h_iattr(&tmp, &did);
  23989. + if (did) {
  23990. + tmp.dentry = path->dentry->d_parent;
  23991. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  23992. + }
  23993. + /*ignore*/
  23994. + }
  23995. +
  23996. +out:
  23997. + return err;
  23998. +}
  23999. +
  24000. +int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
  24001. +{
  24002. + int err;
  24003. + struct dentry *d;
  24004. +
  24005. + IMustLock(dir);
  24006. +
  24007. + d = path->dentry;
  24008. + path->dentry = d->d_parent;
  24009. + err = security_path_mknod(path, d, mode, dev);
  24010. + path->dentry = d;
  24011. + if (unlikely(err))
  24012. + goto out;
  24013. +
  24014. + err = vfs_mknod(dir, path->dentry, mode, dev);
  24015. + if (!err) {
  24016. + struct path tmp = *path;
  24017. + int did;
  24018. +
  24019. + vfsub_update_h_iattr(&tmp, &did);
  24020. + if (did) {
  24021. + tmp.dentry = path->dentry->d_parent;
  24022. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  24023. + }
  24024. + /*ignore*/
  24025. + }
  24026. +
  24027. +out:
  24028. + return err;
  24029. +}
  24030. +
  24031. +static int au_test_nlink(struct inode *inode)
  24032. +{
  24033. + const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
  24034. +
  24035. + if (!au_test_fs_no_limit_nlink(inode->i_sb)
  24036. + || inode->i_nlink < link_max)
  24037. + return 0;
  24038. + return -EMLINK;
  24039. +}
  24040. +
  24041. +int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path)
  24042. +{
  24043. + int err;
  24044. + struct dentry *d;
  24045. +
  24046. + IMustLock(dir);
  24047. +
  24048. + err = au_test_nlink(src_dentry->d_inode);
  24049. + if (unlikely(err))
  24050. + return err;
  24051. +
  24052. + d = path->dentry;
  24053. + path->dentry = d->d_parent;
  24054. + err = security_path_link(src_dentry, path, d);
  24055. + path->dentry = d;
  24056. + if (unlikely(err))
  24057. + goto out;
  24058. +
  24059. + err = vfs_link(src_dentry, dir, path->dentry);
  24060. + if (!err) {
  24061. + struct path tmp = *path;
  24062. + int did;
  24063. +
  24064. + /* fuse has different memory inode for the same inumber */
  24065. + vfsub_update_h_iattr(&tmp, &did);
  24066. + if (did) {
  24067. + tmp.dentry = path->dentry->d_parent;
  24068. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  24069. + tmp.dentry = src_dentry;
  24070. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  24071. + }
  24072. + /*ignore*/
  24073. + }
  24074. +
  24075. +out:
  24076. + return err;
  24077. +}
  24078. +
  24079. +int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
  24080. + struct inode *dir, struct path *path)
  24081. +{
  24082. + int err;
  24083. + struct path tmp = {
  24084. + .mnt = path->mnt
  24085. + };
  24086. + struct dentry *d;
  24087. +
  24088. + IMustLock(dir);
  24089. + IMustLock(src_dir);
  24090. +
  24091. + d = path->dentry;
  24092. + path->dentry = d->d_parent;
  24093. + tmp.dentry = src_dentry->d_parent;
  24094. + err = security_path_rename(&tmp, src_dentry, path, d);
  24095. + path->dentry = d;
  24096. + if (unlikely(err))
  24097. + goto out;
  24098. +
  24099. + err = vfs_rename(src_dir, src_dentry, dir, path->dentry);
  24100. + if (!err) {
  24101. + int did;
  24102. +
  24103. + tmp.dentry = d->d_parent;
  24104. + vfsub_update_h_iattr(&tmp, &did);
  24105. + if (did) {
  24106. + tmp.dentry = src_dentry;
  24107. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  24108. + tmp.dentry = src_dentry->d_parent;
  24109. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  24110. + }
  24111. + /*ignore*/
  24112. + }
  24113. +
  24114. +out:
  24115. + return err;
  24116. +}
  24117. +
  24118. +int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
  24119. +{
  24120. + int err;
  24121. + struct dentry *d;
  24122. +
  24123. + IMustLock(dir);
  24124. +
  24125. + d = path->dentry;
  24126. + path->dentry = d->d_parent;
  24127. + err = security_path_mkdir(path, d, mode);
  24128. + path->dentry = d;
  24129. + if (unlikely(err))
  24130. + goto out;
  24131. +
  24132. + err = vfs_mkdir(dir, path->dentry, mode);
  24133. + if (!err) {
  24134. + struct path tmp = *path;
  24135. + int did;
  24136. +
  24137. + vfsub_update_h_iattr(&tmp, &did);
  24138. + if (did) {
  24139. + tmp.dentry = path->dentry->d_parent;
  24140. + vfsub_update_h_iattr(&tmp, /*did*/NULL);
  24141. + }
  24142. + /*ignore*/
  24143. + }
  24144. +
  24145. +out:
  24146. + return err;
  24147. +}
  24148. +
  24149. +int vfsub_rmdir(struct inode *dir, struct path *path)
  24150. +{
  24151. + int err;
  24152. + struct dentry *d;
  24153. +
  24154. + IMustLock(dir);
  24155. +
  24156. + d = path->dentry;
  24157. + path->dentry = d->d_parent;
  24158. + err = security_path_rmdir(path, d);
  24159. + path->dentry = d;
  24160. + if (unlikely(err))
  24161. + goto out;
  24162. +
  24163. + err = vfs_rmdir(dir, path->dentry);
  24164. + if (!err) {
  24165. + struct path tmp = {
  24166. + .dentry = path->dentry->d_parent,
  24167. + .mnt = path->mnt
  24168. + };
  24169. +
  24170. + vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
  24171. + }
  24172. +
  24173. +out:
  24174. + return err;
  24175. +}
  24176. +
  24177. +/* ---------------------------------------------------------------------- */
  24178. +
  24179. +ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
  24180. + loff_t *ppos)
  24181. +{
  24182. + ssize_t err;
  24183. +
  24184. + err = vfs_read(file, ubuf, count, ppos);
  24185. + if (err >= 0)
  24186. + vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
  24187. + return err;
  24188. +}
  24189. +
  24190. +/* todo: kernel_read()? */
  24191. +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
  24192. + loff_t *ppos)
  24193. +{
  24194. + ssize_t err;
  24195. + mm_segment_t oldfs;
  24196. + union {
  24197. + void *k;
  24198. + char __user *u;
  24199. + } buf;
  24200. +
  24201. + buf.k = kbuf;
  24202. + oldfs = get_fs();
  24203. + set_fs(KERNEL_DS);
  24204. + err = vfsub_read_u(file, buf.u, count, ppos);
  24205. + set_fs(oldfs);
  24206. + return err;
  24207. +}
  24208. +
  24209. +ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
  24210. + loff_t *ppos)
  24211. +{
  24212. + ssize_t err;
  24213. +
  24214. + err = vfs_write(file, ubuf, count, ppos);
  24215. + if (err >= 0)
  24216. + vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
  24217. + return err;
  24218. +}
  24219. +
  24220. +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
  24221. +{
  24222. + ssize_t err;
  24223. + mm_segment_t oldfs;
  24224. + union {
  24225. + void *k;
  24226. + const char __user *u;
  24227. + } buf;
  24228. +
  24229. + buf.k = kbuf;
  24230. + oldfs = get_fs();
  24231. + set_fs(KERNEL_DS);
  24232. + err = vfsub_write_u(file, buf.u, count, ppos);
  24233. + set_fs(oldfs);
  24234. + return err;
  24235. +}
  24236. +
  24237. +int vfsub_flush(struct file *file, fl_owner_t id)
  24238. +{
  24239. + int err;
  24240. +
  24241. + err = 0;
  24242. + if (file->f_op && file->f_op->flush) {
  24243. + err = file->f_op->flush(file, id);
  24244. + if (!err)
  24245. + vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
  24246. + /*ignore*/
  24247. + }
  24248. + return err;
  24249. +}
  24250. +
  24251. +int vfsub_readdir(struct file *file, filldir_t filldir, void *arg)
  24252. +{
  24253. + int err;
  24254. +
  24255. + err = vfs_readdir(file, filldir, arg);
  24256. + if (err >= 0)
  24257. + vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
  24258. + return err;
  24259. +}
  24260. +
  24261. +long vfsub_splice_to(struct file *in, loff_t *ppos,
  24262. + struct pipe_inode_info *pipe, size_t len,
  24263. + unsigned int flags)
  24264. +{
  24265. + long err;
  24266. +
  24267. + err = do_splice_to(in, ppos, pipe, len, flags);
  24268. + file_accessed(in);
  24269. + if (err >= 0)
  24270. + vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
  24271. + return err;
  24272. +}
  24273. +
  24274. +long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
  24275. + loff_t *ppos, size_t len, unsigned int flags)
  24276. +{
  24277. + long err;
  24278. +
  24279. + err = do_splice_from(pipe, out, ppos, len, flags);
  24280. + if (err >= 0)
  24281. + vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
  24282. + return err;
  24283. +}
  24284. +
  24285. +/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
  24286. +int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
  24287. + struct file *h_file)
  24288. +{
  24289. + int err;
  24290. + struct inode *h_inode;
  24291. +
  24292. + h_inode = h_path->dentry->d_inode;
  24293. + if (!h_file) {
  24294. + err = mnt_want_write(h_path->mnt);
  24295. + if (err)
  24296. + goto out;
  24297. + err = inode_permission(h_inode, MAY_WRITE);
  24298. + if (err)
  24299. + goto out_mnt;
  24300. + err = get_write_access(h_inode);
  24301. + if (err)
  24302. + goto out_mnt;
  24303. + err = break_lease(h_inode, O_WRONLY);
  24304. + if (err)
  24305. + goto out_inode;
  24306. + }
  24307. +
  24308. + err = locks_verify_truncate(h_inode, h_file, length);
  24309. + if (!err)
  24310. + err = security_path_truncate(h_path);
  24311. + if (!err)
  24312. + err = do_truncate(h_path->dentry, length, attr, h_file);
  24313. +
  24314. +out_inode:
  24315. + if (!h_file)
  24316. + put_write_access(h_inode);
  24317. +out_mnt:
  24318. + if (!h_file)
  24319. + mnt_drop_write(h_path->mnt);
  24320. +out:
  24321. + return err;
  24322. +}
  24323. +
  24324. +/* ---------------------------------------------------------------------- */
  24325. +
  24326. +struct au_vfsub_mkdir_args {
  24327. + int *errp;
  24328. + struct inode *dir;
  24329. + struct path *path;
  24330. + int mode;
  24331. +};
  24332. +
  24333. +static void au_call_vfsub_mkdir(void *args)
  24334. +{
  24335. + struct au_vfsub_mkdir_args *a = args;
  24336. + *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
  24337. +}
  24338. +
  24339. +int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
  24340. +{
  24341. + int err, do_sio, wkq_err;
  24342. +
  24343. + do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
  24344. + if (!do_sio)
  24345. + err = vfsub_mkdir(dir, path, mode);
  24346. + else {
  24347. + struct au_vfsub_mkdir_args args = {
  24348. + .errp = &err,
  24349. + .dir = dir,
  24350. + .path = path,
  24351. + .mode = mode
  24352. + };
  24353. + wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
  24354. + if (unlikely(wkq_err))
  24355. + err = wkq_err;
  24356. + }
  24357. +
  24358. + return err;
  24359. +}
  24360. +
  24361. +struct au_vfsub_rmdir_args {
  24362. + int *errp;
  24363. + struct inode *dir;
  24364. + struct path *path;
  24365. +};
  24366. +
  24367. +static void au_call_vfsub_rmdir(void *args)
  24368. +{
  24369. + struct au_vfsub_rmdir_args *a = args;
  24370. + *a->errp = vfsub_rmdir(a->dir, a->path);
  24371. +}
  24372. +
  24373. +int vfsub_sio_rmdir(struct inode *dir, struct path *path)
  24374. +{
  24375. + int err, do_sio, wkq_err;
  24376. +
  24377. + do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
  24378. + if (!do_sio)
  24379. + err = vfsub_rmdir(dir, path);
  24380. + else {
  24381. + struct au_vfsub_rmdir_args args = {
  24382. + .errp = &err,
  24383. + .dir = dir,
  24384. + .path = path
  24385. + };
  24386. + wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
  24387. + if (unlikely(wkq_err))
  24388. + err = wkq_err;
  24389. + }
  24390. +
  24391. + return err;
  24392. +}
  24393. +
  24394. +/* ---------------------------------------------------------------------- */
  24395. +
  24396. +struct notify_change_args {
  24397. + int *errp;
  24398. + struct path *path;
  24399. + struct iattr *ia;
  24400. +};
  24401. +
  24402. +static void call_notify_change(void *args)
  24403. +{
  24404. + struct notify_change_args *a = args;
  24405. + struct inode *h_inode;
  24406. +
  24407. + h_inode = a->path->dentry->d_inode;
  24408. + IMustLock(h_inode);
  24409. +
  24410. + *a->errp = -EPERM;
  24411. + if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
  24412. + *a->errp = notify_change(a->path->dentry, a->ia);
  24413. + if (!*a->errp)
  24414. + vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
  24415. + }
  24416. + AuTraceErr(*a->errp);
  24417. +}
  24418. +
  24419. +int vfsub_notify_change(struct path *path, struct iattr *ia)
  24420. +{
  24421. + int err;
  24422. + struct notify_change_args args = {
  24423. + .errp = &err,
  24424. + .path = path,
  24425. + .ia = ia
  24426. + };
  24427. +
  24428. + call_notify_change(&args);
  24429. +
  24430. + return err;
  24431. +}
  24432. +
  24433. +int vfsub_sio_notify_change(struct path *path, struct iattr *ia)
  24434. +{
  24435. + int err, wkq_err;
  24436. + struct notify_change_args args = {
  24437. + .errp = &err,
  24438. + .path = path,
  24439. + .ia = ia
  24440. + };
  24441. +
  24442. + wkq_err = au_wkq_wait(call_notify_change, &args);
  24443. + if (unlikely(wkq_err))
  24444. + err = wkq_err;
  24445. +
  24446. + return err;
  24447. +}
  24448. +
  24449. +/* ---------------------------------------------------------------------- */
  24450. +
  24451. +struct unlink_args {
  24452. + int *errp;
  24453. + struct inode *dir;
  24454. + struct path *path;
  24455. +};
  24456. +
  24457. +static void call_unlink(void *args)
  24458. +{
  24459. + struct unlink_args *a = args;
  24460. + struct dentry *d = a->path->dentry;
  24461. + struct inode *h_inode;
  24462. + const int stop_sillyrename = (au_test_nfs(d->d_sb)
  24463. + && atomic_read(&d->d_count) == 1);
  24464. +
  24465. + IMustLock(a->dir);
  24466. +
  24467. + a->path->dentry = d->d_parent;
  24468. + *a->errp = security_path_unlink(a->path, d);
  24469. + a->path->dentry = d;
  24470. + if (unlikely(*a->errp))
  24471. + return;
  24472. +
  24473. + if (!stop_sillyrename)
  24474. + dget(d);
  24475. + h_inode = d->d_inode;
  24476. + if (h_inode)
  24477. + atomic_inc(&h_inode->i_count);
  24478. +
  24479. + *a->errp = vfs_unlink(a->dir, d);
  24480. + if (!*a->errp) {
  24481. + struct path tmp = {
  24482. + .dentry = d->d_parent,
  24483. + .mnt = a->path->mnt
  24484. + };
  24485. + vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
  24486. + }
  24487. +
  24488. + if (!stop_sillyrename)
  24489. + dput(d);
  24490. + if (h_inode)
  24491. + iput(h_inode);
  24492. +
  24493. + AuTraceErr(*a->errp);
  24494. +}
  24495. +
  24496. +/*
  24497. + * @dir: must be locked.
  24498. + * @dentry: target dentry.
  24499. + */
  24500. +int vfsub_unlink(struct inode *dir, struct path *path, int force)
  24501. +{
  24502. + int err;
  24503. + struct unlink_args args = {
  24504. + .errp = &err,
  24505. + .dir = dir,
  24506. + .path = path
  24507. + };
  24508. +
  24509. + if (!force)
  24510. + call_unlink(&args);
  24511. + else {
  24512. + int wkq_err;
  24513. +
  24514. + wkq_err = au_wkq_wait(call_unlink, &args);
  24515. + if (unlikely(wkq_err))
  24516. + err = wkq_err;
  24517. + }
  24518. +
  24519. + return err;
  24520. +}
  24521. diff -Nur linux-2.6.37.orig/fs/aufs/vfsub.h linux-2.6.37/fs/aufs/vfsub.h
  24522. --- linux-2.6.37.orig/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
  24523. +++ linux-2.6.37/fs/aufs/vfsub.h 2011-01-11 20:15:11.000000000 +0100
  24524. @@ -0,0 +1,226 @@
  24525. +/*
  24526. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  24527. + *
  24528. + * This program, aufs is free software; you can redistribute it and/or modify
  24529. + * it under the terms of the GNU General Public License as published by
  24530. + * the Free Software Foundation; either version 2 of the License, or
  24531. + * (at your option) any later version.
  24532. + *
  24533. + * This program is distributed in the hope that it will be useful,
  24534. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24535. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24536. + * GNU General Public License for more details.
  24537. + *
  24538. + * You should have received a copy of the GNU General Public License
  24539. + * along with this program; if not, write to the Free Software
  24540. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  24541. + */
  24542. +
  24543. +/*
  24544. + * sub-routines for VFS
  24545. + */
  24546. +
  24547. +#ifndef __AUFS_VFSUB_H__
  24548. +#define __AUFS_VFSUB_H__
  24549. +
  24550. +#ifdef __KERNEL__
  24551. +
  24552. +#include <linux/fs.h>
  24553. +#include <linux/lglock.h>
  24554. +#include "debug.h"
  24555. +
  24556. +/* copied from linux/fs/internal.h */
  24557. +DECLARE_BRLOCK(vfsmount_lock);
  24558. +extern void file_sb_list_del(struct file *f);
  24559. +
  24560. +/* copied from linux/fs/file_table.c */
  24561. +DECLARE_LGLOCK(files_lglock);
  24562. +#ifdef CONFIG_SMP
  24563. +/*
  24564. + * These macros iterate all files on all CPUs for a given superblock.
  24565. + * files_lglock must be held globally.
  24566. + */
  24567. +#define do_file_list_for_each_entry(__sb, __file) \
  24568. +{ \
  24569. + int i; \
  24570. + for_each_possible_cpu(i) { \
  24571. + struct list_head *list; \
  24572. + list = per_cpu_ptr((__sb)->s_files, i); \
  24573. + list_for_each_entry((__file), list, f_u.fu_list)
  24574. +
  24575. +#define while_file_list_for_each_entry \
  24576. + } \
  24577. +}
  24578. +
  24579. +#else
  24580. +
  24581. +#define do_file_list_for_each_entry(__sb, __file) \
  24582. +{ \
  24583. + struct list_head *list; \
  24584. + list = &(sb)->s_files; \
  24585. + list_for_each_entry((__file), list, f_u.fu_list)
  24586. +
  24587. +#define while_file_list_for_each_entry \
  24588. +}
  24589. +#endif
  24590. +
  24591. +/* ---------------------------------------------------------------------- */
  24592. +
  24593. +/* lock subclass for lower inode */
  24594. +/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
  24595. +/* reduce? gave up. */
  24596. +enum {
  24597. + AuLsc_I_Begin = I_MUTEX_QUOTA, /* 4 */
  24598. + AuLsc_I_PARENT, /* lower inode, parent first */
  24599. + AuLsc_I_PARENT2, /* copyup dirs */
  24600. + AuLsc_I_PARENT3, /* copyup wh */
  24601. + AuLsc_I_CHILD,
  24602. + AuLsc_I_CHILD2,
  24603. + AuLsc_I_End
  24604. +};
  24605. +
  24606. +/* to debug easier, do not make them inlined functions */
  24607. +#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
  24608. +#define IMustLock(i) MtxMustLock(&(i)->i_mutex)
  24609. +
  24610. +/* ---------------------------------------------------------------------- */
  24611. +
  24612. +static inline void vfsub_drop_nlink(struct inode *inode)
  24613. +{
  24614. + AuDebugOn(!inode->i_nlink);
  24615. + drop_nlink(inode);
  24616. +}
  24617. +
  24618. +static inline void vfsub_dead_dir(struct inode *inode)
  24619. +{
  24620. + AuDebugOn(!S_ISDIR(inode->i_mode));
  24621. + inode->i_flags |= S_DEAD;
  24622. + clear_nlink(inode);
  24623. +}
  24624. +
  24625. +/* ---------------------------------------------------------------------- */
  24626. +
  24627. +int vfsub_update_h_iattr(struct path *h_path, int *did);
  24628. +struct file *vfsub_dentry_open(struct path *path, int flags);
  24629. +struct file *vfsub_filp_open(const char *path, int oflags, int mode);
  24630. +int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
  24631. +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
  24632. + int len);
  24633. +struct dentry *vfsub_lookup_hash(struct nameidata *nd);
  24634. +
  24635. +/* ---------------------------------------------------------------------- */
  24636. +
  24637. +struct au_hinode;
  24638. +struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
  24639. + struct dentry *d2, struct au_hinode *hdir2);
  24640. +void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
  24641. + struct dentry *d2, struct au_hinode *hdir2);
  24642. +
  24643. +int vfsub_create(struct inode *dir, struct path *path, int mode);
  24644. +int vfsub_symlink(struct inode *dir, struct path *path,
  24645. + const char *symname);
  24646. +int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
  24647. +int vfsub_link(struct dentry *src_dentry, struct inode *dir,
  24648. + struct path *path);
  24649. +int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
  24650. + struct inode *hdir, struct path *path);
  24651. +int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
  24652. +int vfsub_rmdir(struct inode *dir, struct path *path);
  24653. +
  24654. +/* ---------------------------------------------------------------------- */
  24655. +
  24656. +ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
  24657. + loff_t *ppos);
  24658. +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
  24659. + loff_t *ppos);
  24660. +ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
  24661. + loff_t *ppos);
  24662. +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
  24663. + loff_t *ppos);
  24664. +int vfsub_flush(struct file *file, fl_owner_t id);
  24665. +int vfsub_readdir(struct file *file, filldir_t filldir, void *arg);
  24666. +
  24667. +static inline unsigned int vfsub_file_flags(struct file *file)
  24668. +{
  24669. + unsigned int flags;
  24670. +
  24671. + spin_lock(&file->f_lock);
  24672. + flags = file->f_flags;
  24673. + spin_unlock(&file->f_lock);
  24674. +
  24675. + return flags;
  24676. +}
  24677. +
  24678. +static inline void vfsub_file_accessed(struct file *h_file)
  24679. +{
  24680. + file_accessed(h_file);
  24681. + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
  24682. +}
  24683. +
  24684. +static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
  24685. + struct dentry *h_dentry)
  24686. +{
  24687. + struct path h_path = {
  24688. + .dentry = h_dentry,
  24689. + .mnt = h_mnt
  24690. + };
  24691. + touch_atime(h_mnt, h_dentry);
  24692. + vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
  24693. +}
  24694. +
  24695. +long vfsub_splice_to(struct file *in, loff_t *ppos,
  24696. + struct pipe_inode_info *pipe, size_t len,
  24697. + unsigned int flags);
  24698. +long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
  24699. + loff_t *ppos, size_t len, unsigned int flags);
  24700. +int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
  24701. + struct file *h_file);
  24702. +
  24703. +/* ---------------------------------------------------------------------- */
  24704. +
  24705. +static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
  24706. +{
  24707. + loff_t err;
  24708. +
  24709. + err = vfs_llseek(file, offset, origin);
  24710. + return err;
  24711. +}
  24712. +
  24713. +/* ---------------------------------------------------------------------- */
  24714. +
  24715. +/* dirty workaround for strict type of fmode_t */
  24716. +union vfsub_fmu {
  24717. + fmode_t fm;
  24718. + unsigned int ui;
  24719. +};
  24720. +
  24721. +static inline unsigned int vfsub_fmode_to_uint(fmode_t fm)
  24722. +{
  24723. + union vfsub_fmu u = {
  24724. + .fm = fm
  24725. + };
  24726. +
  24727. + BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui));
  24728. +
  24729. + return u.ui;
  24730. +}
  24731. +
  24732. +static inline fmode_t vfsub_uint_to_fmode(unsigned int ui)
  24733. +{
  24734. + union vfsub_fmu u = {
  24735. + .ui = ui
  24736. + };
  24737. +
  24738. + return u.fm;
  24739. +}
  24740. +
  24741. +/* ---------------------------------------------------------------------- */
  24742. +
  24743. +int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
  24744. +int vfsub_sio_rmdir(struct inode *dir, struct path *path);
  24745. +int vfsub_sio_notify_change(struct path *path, struct iattr *ia);
  24746. +int vfsub_notify_change(struct path *path, struct iattr *ia);
  24747. +int vfsub_unlink(struct inode *dir, struct path *path, int force);
  24748. +
  24749. +#endif /* __KERNEL__ */
  24750. +#endif /* __AUFS_VFSUB_H__ */
  24751. diff -Nur linux-2.6.37.orig/fs/aufs/wbr_policy.c linux-2.6.37/fs/aufs/wbr_policy.c
  24752. --- linux-2.6.37.orig/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100
  24753. +++ linux-2.6.37/fs/aufs/wbr_policy.c 2011-01-11 20:15:11.000000000 +0100
  24754. @@ -0,0 +1,700 @@
  24755. +/*
  24756. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  24757. + *
  24758. + * This program, aufs is free software; you can redistribute it and/or modify
  24759. + * it under the terms of the GNU General Public License as published by
  24760. + * the Free Software Foundation; either version 2 of the License, or
  24761. + * (at your option) any later version.
  24762. + *
  24763. + * This program is distributed in the hope that it will be useful,
  24764. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24765. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24766. + * GNU General Public License for more details.
  24767. + *
  24768. + * You should have received a copy of the GNU General Public License
  24769. + * along with this program; if not, write to the Free Software
  24770. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  24771. + */
  24772. +
  24773. +/*
  24774. + * policies for selecting one among multiple writable branches
  24775. + */
  24776. +
  24777. +#include <linux/statfs.h>
  24778. +#include "aufs.h"
  24779. +
  24780. +/* subset of cpup_attr() */
  24781. +static noinline_for_stack
  24782. +int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
  24783. +{
  24784. + int err, sbits;
  24785. + struct iattr ia;
  24786. + struct inode *h_isrc;
  24787. +
  24788. + h_isrc = h_src->d_inode;
  24789. + ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
  24790. + ia.ia_mode = h_isrc->i_mode;
  24791. + ia.ia_uid = h_isrc->i_uid;
  24792. + ia.ia_gid = h_isrc->i_gid;
  24793. + sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
  24794. + au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc);
  24795. + err = vfsub_sio_notify_change(h_path, &ia);
  24796. +
  24797. + /* is this nfs only? */
  24798. + if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
  24799. + ia.ia_valid = ATTR_FORCE | ATTR_MODE;
  24800. + ia.ia_mode = h_isrc->i_mode;
  24801. + err = vfsub_sio_notify_change(h_path, &ia);
  24802. + }
  24803. +
  24804. + return err;
  24805. +}
  24806. +
  24807. +#define AuCpdown_PARENT_OPQ 1
  24808. +#define AuCpdown_WHED (1 << 1)
  24809. +#define AuCpdown_MADE_DIR (1 << 2)
  24810. +#define AuCpdown_DIROPQ (1 << 3)
  24811. +#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name)
  24812. +#define au_fset_cpdown(flags, name) \
  24813. + do { (flags) |= AuCpdown_##name; } while (0)
  24814. +#define au_fclr_cpdown(flags, name) \
  24815. + do { (flags) &= ~AuCpdown_##name; } while (0)
  24816. +
  24817. +struct au_cpdown_dir_args {
  24818. + struct dentry *parent;
  24819. + unsigned int flags;
  24820. +};
  24821. +
  24822. +static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
  24823. + struct au_cpdown_dir_args *a)
  24824. +{
  24825. + int err;
  24826. + struct dentry *opq_dentry;
  24827. +
  24828. + opq_dentry = au_diropq_create(dentry, bdst);
  24829. + err = PTR_ERR(opq_dentry);
  24830. + if (IS_ERR(opq_dentry))
  24831. + goto out;
  24832. + dput(opq_dentry);
  24833. + au_fset_cpdown(a->flags, DIROPQ);
  24834. +
  24835. +out:
  24836. + return err;
  24837. +}
  24838. +
  24839. +static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
  24840. + struct inode *dir, aufs_bindex_t bdst)
  24841. +{
  24842. + int err;
  24843. + struct path h_path;
  24844. + struct au_branch *br;
  24845. +
  24846. + br = au_sbr(dentry->d_sb, bdst);
  24847. + h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
  24848. + err = PTR_ERR(h_path.dentry);
  24849. + if (IS_ERR(h_path.dentry))
  24850. + goto out;
  24851. +
  24852. + err = 0;
  24853. + if (h_path.dentry->d_inode) {
  24854. + h_path.mnt = br->br_mnt;
  24855. + err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
  24856. + dentry);
  24857. + }
  24858. + dput(h_path.dentry);
  24859. +
  24860. +out:
  24861. + return err;
  24862. +}
  24863. +
  24864. +static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
  24865. + struct dentry *h_parent, void *arg)
  24866. +{
  24867. + int err, rerr;
  24868. + aufs_bindex_t bopq, bstart;
  24869. + struct path h_path;
  24870. + struct dentry *parent;
  24871. + struct inode *h_dir, *h_inode, *inode, *dir;
  24872. + struct au_cpdown_dir_args *args = arg;
  24873. +
  24874. + bstart = au_dbstart(dentry);
  24875. + /* dentry is di-locked */
  24876. + parent = dget_parent(dentry);
  24877. + dir = parent->d_inode;
  24878. + h_dir = h_parent->d_inode;
  24879. + AuDebugOn(h_dir != au_h_iptr(dir, bdst));
  24880. + IMustLock(h_dir);
  24881. +
  24882. + err = au_lkup_neg(dentry, bdst);
  24883. + if (unlikely(err < 0))
  24884. + goto out;
  24885. + h_path.dentry = au_h_dptr(dentry, bdst);
  24886. + h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
  24887. + err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path,
  24888. + S_IRWXU | S_IRUGO | S_IXUGO);
  24889. + if (unlikely(err))
  24890. + goto out_put;
  24891. + au_fset_cpdown(args->flags, MADE_DIR);
  24892. +
  24893. + bopq = au_dbdiropq(dentry);
  24894. + au_fclr_cpdown(args->flags, WHED);
  24895. + au_fclr_cpdown(args->flags, DIROPQ);
  24896. + if (au_dbwh(dentry) == bdst)
  24897. + au_fset_cpdown(args->flags, WHED);
  24898. + if (!au_ftest_cpdown(args->flags, PARENT_OPQ) && bopq <= bdst)
  24899. + au_fset_cpdown(args->flags, PARENT_OPQ);
  24900. + h_inode = h_path.dentry->d_inode;
  24901. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  24902. + if (au_ftest_cpdown(args->flags, WHED)) {
  24903. + err = au_cpdown_dir_opq(dentry, bdst, args);
  24904. + if (unlikely(err)) {
  24905. + mutex_unlock(&h_inode->i_mutex);
  24906. + goto out_dir;
  24907. + }
  24908. + }
  24909. +
  24910. + err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart));
  24911. + mutex_unlock(&h_inode->i_mutex);
  24912. + if (unlikely(err))
  24913. + goto out_opq;
  24914. +
  24915. + if (au_ftest_cpdown(args->flags, WHED)) {
  24916. + err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
  24917. + if (unlikely(err))
  24918. + goto out_opq;
  24919. + }
  24920. +
  24921. + inode = dentry->d_inode;
  24922. + if (au_ibend(inode) < bdst)
  24923. + au_set_ibend(inode, bdst);
  24924. + au_set_h_iptr(inode, bdst, au_igrab(h_inode),
  24925. + au_hi_flags(inode, /*isdir*/1));
  24926. + goto out; /* success */
  24927. +
  24928. + /* revert */
  24929. +out_opq:
  24930. + if (au_ftest_cpdown(args->flags, DIROPQ)) {
  24931. + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
  24932. + rerr = au_diropq_remove(dentry, bdst);
  24933. + mutex_unlock(&h_inode->i_mutex);
  24934. + if (unlikely(rerr)) {
  24935. + AuIOErr("failed removing diropq for %.*s b%d (%d)\n",
  24936. + AuDLNPair(dentry), bdst, rerr);
  24937. + err = -EIO;
  24938. + goto out;
  24939. + }
  24940. + }
  24941. +out_dir:
  24942. + if (au_ftest_cpdown(args->flags, MADE_DIR)) {
  24943. + rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
  24944. + if (unlikely(rerr)) {
  24945. + AuIOErr("failed removing %.*s b%d (%d)\n",
  24946. + AuDLNPair(dentry), bdst, rerr);
  24947. + err = -EIO;
  24948. + }
  24949. + }
  24950. +out_put:
  24951. + au_set_h_dptr(dentry, bdst, NULL);
  24952. + if (au_dbend(dentry) == bdst)
  24953. + au_update_dbend(dentry);
  24954. +out:
  24955. + dput(parent);
  24956. + return err;
  24957. +}
  24958. +
  24959. +int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
  24960. +{
  24961. + int err;
  24962. + struct au_cpdown_dir_args args = {
  24963. + .parent = dget_parent(dentry),
  24964. + .flags = 0
  24965. + };
  24966. +
  24967. + err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &args);
  24968. + dput(args.parent);
  24969. +
  24970. + return err;
  24971. +}
  24972. +
  24973. +/* ---------------------------------------------------------------------- */
  24974. +
  24975. +/* policies for create */
  24976. +
  24977. +static int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex)
  24978. +{
  24979. + int err, i, j, ndentry;
  24980. + aufs_bindex_t bopq;
  24981. + struct au_dcsub_pages dpages;
  24982. + struct au_dpage *dpage;
  24983. + struct dentry **dentries, *parent, *d;
  24984. +
  24985. + err = au_dpages_init(&dpages, GFP_NOFS);
  24986. + if (unlikely(err))
  24987. + goto out;
  24988. + parent = dget_parent(dentry);
  24989. + err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0);
  24990. + if (unlikely(err))
  24991. + goto out_free;
  24992. +
  24993. + err = bindex;
  24994. + for (i = 0; i < dpages.ndpage; i++) {
  24995. + dpage = dpages.dpages + i;
  24996. + dentries = dpage->dentries;
  24997. + ndentry = dpage->ndentry;
  24998. + for (j = 0; j < ndentry; j++) {
  24999. + d = dentries[j];
  25000. + di_read_lock_parent2(d, !AuLock_IR);
  25001. + bopq = au_dbdiropq(d);
  25002. + di_read_unlock(d, !AuLock_IR);
  25003. + if (bopq >= 0 && bopq < err)
  25004. + err = bopq;
  25005. + }
  25006. + }
  25007. +
  25008. +out_free:
  25009. + dput(parent);
  25010. + au_dpages_free(&dpages);
  25011. +out:
  25012. + return err;
  25013. +}
  25014. +
  25015. +static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
  25016. +{
  25017. + for (; bindex >= 0; bindex--)
  25018. + if (!au_br_rdonly(au_sbr(sb, bindex)))
  25019. + return bindex;
  25020. + return -EROFS;
  25021. +}
  25022. +
  25023. +/* top down parent */
  25024. +static int au_wbr_create_tdp(struct dentry *dentry, int isdir __maybe_unused)
  25025. +{
  25026. + int err;
  25027. + aufs_bindex_t bstart, bindex;
  25028. + struct super_block *sb;
  25029. + struct dentry *parent, *h_parent;
  25030. +
  25031. + sb = dentry->d_sb;
  25032. + bstart = au_dbstart(dentry);
  25033. + err = bstart;
  25034. + if (!au_br_rdonly(au_sbr(sb, bstart)))
  25035. + goto out;
  25036. +
  25037. + err = -EROFS;
  25038. + parent = dget_parent(dentry);
  25039. + for (bindex = au_dbstart(parent); bindex < bstart; bindex++) {
  25040. + h_parent = au_h_dptr(parent, bindex);
  25041. + if (!h_parent || !h_parent->d_inode)
  25042. + continue;
  25043. +
  25044. + if (!au_br_rdonly(au_sbr(sb, bindex))) {
  25045. + err = bindex;
  25046. + break;
  25047. + }
  25048. + }
  25049. + dput(parent);
  25050. +
  25051. + /* bottom up here */
  25052. + if (unlikely(err < 0)) {
  25053. + err = au_wbr_bu(sb, bstart - 1);
  25054. + if (err >= 0)
  25055. + err = au_wbr_nonopq(dentry, err);
  25056. + }
  25057. +
  25058. +out:
  25059. + AuDbg("b%d\n", err);
  25060. + return err;
  25061. +}
  25062. +
  25063. +/* ---------------------------------------------------------------------- */
  25064. +
  25065. +/* an exception for the policy other than tdp */
  25066. +static int au_wbr_create_exp(struct dentry *dentry)
  25067. +{
  25068. + int err;
  25069. + aufs_bindex_t bwh, bdiropq;
  25070. + struct dentry *parent;
  25071. +
  25072. + err = -1;
  25073. + bwh = au_dbwh(dentry);
  25074. + parent = dget_parent(dentry);
  25075. + bdiropq = au_dbdiropq(parent);
  25076. + if (bwh >= 0) {
  25077. + if (bdiropq >= 0)
  25078. + err = min(bdiropq, bwh);
  25079. + else
  25080. + err = bwh;
  25081. + AuDbg("%d\n", err);
  25082. + } else if (bdiropq >= 0) {
  25083. + err = bdiropq;
  25084. + AuDbg("%d\n", err);
  25085. + }
  25086. + dput(parent);
  25087. +
  25088. + if (err >= 0)
  25089. + err = au_wbr_nonopq(dentry, err);
  25090. +
  25091. + if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
  25092. + err = -1;
  25093. +
  25094. + AuDbg("%d\n", err);
  25095. + return err;
  25096. +}
  25097. +
  25098. +/* ---------------------------------------------------------------------- */
  25099. +
  25100. +/* round robin */
  25101. +static int au_wbr_create_init_rr(struct super_block *sb)
  25102. +{
  25103. + int err;
  25104. +
  25105. + err = au_wbr_bu(sb, au_sbend(sb));
  25106. + atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
  25107. + /* smp_mb(); */
  25108. +
  25109. + AuDbg("b%d\n", err);
  25110. + return err;
  25111. +}
  25112. +
  25113. +static int au_wbr_create_rr(struct dentry *dentry, int isdir)
  25114. +{
  25115. + int err, nbr;
  25116. + unsigned int u;
  25117. + aufs_bindex_t bindex, bend;
  25118. + struct super_block *sb;
  25119. + atomic_t *next;
  25120. +
  25121. + err = au_wbr_create_exp(dentry);
  25122. + if (err >= 0)
  25123. + goto out;
  25124. +
  25125. + sb = dentry->d_sb;
  25126. + next = &au_sbi(sb)->si_wbr_rr_next;
  25127. + bend = au_sbend(sb);
  25128. + nbr = bend + 1;
  25129. + for (bindex = 0; bindex <= bend; bindex++) {
  25130. + if (!isdir) {
  25131. + err = atomic_dec_return(next) + 1;
  25132. + /* modulo for 0 is meaningless */
  25133. + if (unlikely(!err))
  25134. + err = atomic_dec_return(next) + 1;
  25135. + } else
  25136. + err = atomic_read(next);
  25137. + AuDbg("%d\n", err);
  25138. + u = err;
  25139. + err = u % nbr;
  25140. + AuDbg("%d\n", err);
  25141. + if (!au_br_rdonly(au_sbr(sb, err)))
  25142. + break;
  25143. + err = -EROFS;
  25144. + }
  25145. +
  25146. + if (err >= 0)
  25147. + err = au_wbr_nonopq(dentry, err);
  25148. +
  25149. +out:
  25150. + AuDbg("%d\n", err);
  25151. + return err;
  25152. +}
  25153. +
  25154. +/* ---------------------------------------------------------------------- */
  25155. +
  25156. +/* most free space */
  25157. +static void au_mfs(struct dentry *dentry)
  25158. +{
  25159. + struct super_block *sb;
  25160. + struct au_branch *br;
  25161. + struct au_wbr_mfs *mfs;
  25162. + aufs_bindex_t bindex, bend;
  25163. + int err;
  25164. + unsigned long long b, bavail;
  25165. + struct path h_path;
  25166. + /* reduce the stack usage */
  25167. + struct kstatfs *st;
  25168. +
  25169. + st = kmalloc(sizeof(*st), GFP_NOFS);
  25170. + if (unlikely(!st)) {
  25171. + AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
  25172. + return;
  25173. + }
  25174. +
  25175. + bavail = 0;
  25176. + sb = dentry->d_sb;
  25177. + mfs = &au_sbi(sb)->si_wbr_mfs;
  25178. + MtxMustLock(&mfs->mfs_lock);
  25179. + mfs->mfs_bindex = -EROFS;
  25180. + mfs->mfsrr_bytes = 0;
  25181. + bend = au_sbend(sb);
  25182. + for (bindex = 0; bindex <= bend; bindex++) {
  25183. + br = au_sbr(sb, bindex);
  25184. + if (au_br_rdonly(br))
  25185. + continue;
  25186. +
  25187. + /* sb->s_root for NFS is unreliable */
  25188. + h_path.mnt = br->br_mnt;
  25189. + h_path.dentry = h_path.mnt->mnt_root;
  25190. + err = vfs_statfs(&h_path, st);
  25191. + if (unlikely(err)) {
  25192. + AuWarn1("failed statfs, b%d, %d\n", bindex, err);
  25193. + continue;
  25194. + }
  25195. +
  25196. + /* when the available size is equal, select the lower one */
  25197. + BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
  25198. + || sizeof(b) < sizeof(st->f_bsize));
  25199. + b = st->f_bavail * st->f_bsize;
  25200. + br->br_wbr->wbr_bytes = b;
  25201. + if (b >= bavail) {
  25202. + bavail = b;
  25203. + mfs->mfs_bindex = bindex;
  25204. + mfs->mfs_jiffy = jiffies;
  25205. + }
  25206. + }
  25207. +
  25208. + mfs->mfsrr_bytes = bavail;
  25209. + AuDbg("b%d\n", mfs->mfs_bindex);
  25210. + kfree(st);
  25211. +}
  25212. +
  25213. +static int au_wbr_create_mfs(struct dentry *dentry, int isdir __maybe_unused)
  25214. +{
  25215. + int err;
  25216. + struct super_block *sb;
  25217. + struct au_wbr_mfs *mfs;
  25218. +
  25219. + err = au_wbr_create_exp(dentry);
  25220. + if (err >= 0)
  25221. + goto out;
  25222. +
  25223. + sb = dentry->d_sb;
  25224. + mfs = &au_sbi(sb)->si_wbr_mfs;
  25225. + mutex_lock(&mfs->mfs_lock);
  25226. + if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
  25227. + || mfs->mfs_bindex < 0
  25228. + || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
  25229. + au_mfs(dentry);
  25230. + mutex_unlock(&mfs->mfs_lock);
  25231. + err = mfs->mfs_bindex;
  25232. +
  25233. + if (err >= 0)
  25234. + err = au_wbr_nonopq(dentry, err);
  25235. +
  25236. +out:
  25237. + AuDbg("b%d\n", err);
  25238. + return err;
  25239. +}
  25240. +
  25241. +static int au_wbr_create_init_mfs(struct super_block *sb)
  25242. +{
  25243. + struct au_wbr_mfs *mfs;
  25244. +
  25245. + mfs = &au_sbi(sb)->si_wbr_mfs;
  25246. + mutex_init(&mfs->mfs_lock);
  25247. + mfs->mfs_jiffy = 0;
  25248. + mfs->mfs_bindex = -EROFS;
  25249. +
  25250. + return 0;
  25251. +}
  25252. +
  25253. +static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
  25254. +{
  25255. + mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
  25256. + return 0;
  25257. +}
  25258. +
  25259. +/* ---------------------------------------------------------------------- */
  25260. +
  25261. +/* most free space and then round robin */
  25262. +static int au_wbr_create_mfsrr(struct dentry *dentry, int isdir)
  25263. +{
  25264. + int err;
  25265. + struct au_wbr_mfs *mfs;
  25266. +
  25267. + err = au_wbr_create_mfs(dentry, isdir);
  25268. + if (err >= 0) {
  25269. + mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
  25270. + mutex_lock(&mfs->mfs_lock);
  25271. + if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
  25272. + err = au_wbr_create_rr(dentry, isdir);
  25273. + mutex_unlock(&mfs->mfs_lock);
  25274. + }
  25275. +
  25276. + AuDbg("b%d\n", err);
  25277. + return err;
  25278. +}
  25279. +
  25280. +static int au_wbr_create_init_mfsrr(struct super_block *sb)
  25281. +{
  25282. + int err;
  25283. +
  25284. + au_wbr_create_init_mfs(sb); /* ignore */
  25285. + err = au_wbr_create_init_rr(sb);
  25286. +
  25287. + return err;
  25288. +}
  25289. +
  25290. +/* ---------------------------------------------------------------------- */
  25291. +
  25292. +/* top down parent and most free space */
  25293. +static int au_wbr_create_pmfs(struct dentry *dentry, int isdir)
  25294. +{
  25295. + int err, e2;
  25296. + unsigned long long b;
  25297. + aufs_bindex_t bindex, bstart, bend;
  25298. + struct super_block *sb;
  25299. + struct dentry *parent, *h_parent;
  25300. + struct au_branch *br;
  25301. +
  25302. + err = au_wbr_create_tdp(dentry, isdir);
  25303. + if (unlikely(err < 0))
  25304. + goto out;
  25305. + parent = dget_parent(dentry);
  25306. + bstart = au_dbstart(parent);
  25307. + bend = au_dbtaildir(parent);
  25308. + if (bstart == bend)
  25309. + goto out_parent; /* success */
  25310. +
  25311. + e2 = au_wbr_create_mfs(dentry, isdir);
  25312. + if (e2 < 0)
  25313. + goto out_parent; /* success */
  25314. +
  25315. + /* when the available size is equal, select upper one */
  25316. + sb = dentry->d_sb;
  25317. + br = au_sbr(sb, err);
  25318. + b = br->br_wbr->wbr_bytes;
  25319. + AuDbg("b%d, %llu\n", err, b);
  25320. +
  25321. + for (bindex = bstart; bindex <= bend; bindex++) {
  25322. + h_parent = au_h_dptr(parent, bindex);
  25323. + if (!h_parent || !h_parent->d_inode)
  25324. + continue;
  25325. +
  25326. + br = au_sbr(sb, bindex);
  25327. + if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
  25328. + b = br->br_wbr->wbr_bytes;
  25329. + err = bindex;
  25330. + AuDbg("b%d, %llu\n", err, b);
  25331. + }
  25332. + }
  25333. +
  25334. + if (err >= 0)
  25335. + err = au_wbr_nonopq(dentry, err);
  25336. +
  25337. +out_parent:
  25338. + dput(parent);
  25339. +out:
  25340. + AuDbg("b%d\n", err);
  25341. + return err;
  25342. +}
  25343. +
  25344. +/* ---------------------------------------------------------------------- */
  25345. +
  25346. +/* policies for copyup */
  25347. +
  25348. +/* top down parent */
  25349. +static int au_wbr_copyup_tdp(struct dentry *dentry)
  25350. +{
  25351. + return au_wbr_create_tdp(dentry, /*isdir, anything is ok*/0);
  25352. +}
  25353. +
  25354. +/* bottom up parent */
  25355. +static int au_wbr_copyup_bup(struct dentry *dentry)
  25356. +{
  25357. + int err;
  25358. + aufs_bindex_t bindex, bstart;
  25359. + struct dentry *parent, *h_parent;
  25360. + struct super_block *sb;
  25361. +
  25362. + err = -EROFS;
  25363. + sb = dentry->d_sb;
  25364. + parent = dget_parent(dentry);
  25365. + bstart = au_dbstart(parent);
  25366. + for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) {
  25367. + h_parent = au_h_dptr(parent, bindex);
  25368. + if (!h_parent || !h_parent->d_inode)
  25369. + continue;
  25370. +
  25371. + if (!au_br_rdonly(au_sbr(sb, bindex))) {
  25372. + err = bindex;
  25373. + break;
  25374. + }
  25375. + }
  25376. + dput(parent);
  25377. +
  25378. + /* bottom up here */
  25379. + if (unlikely(err < 0))
  25380. + err = au_wbr_bu(sb, bstart - 1);
  25381. +
  25382. + AuDbg("b%d\n", err);
  25383. + return err;
  25384. +}
  25385. +
  25386. +/* bottom up */
  25387. +static int au_wbr_copyup_bu(struct dentry *dentry)
  25388. +{
  25389. + int err;
  25390. + aufs_bindex_t bstart;
  25391. +
  25392. + bstart = au_dbstart(dentry);
  25393. + err = au_wbr_bu(dentry->d_sb, bstart);
  25394. + AuDbg("b%d\n", err);
  25395. + if (err > bstart)
  25396. + err = au_wbr_nonopq(dentry, err);
  25397. +
  25398. + AuDbg("b%d\n", err);
  25399. + return err;
  25400. +}
  25401. +
  25402. +/* ---------------------------------------------------------------------- */
  25403. +
  25404. +struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
  25405. + [AuWbrCopyup_TDP] = {
  25406. + .copyup = au_wbr_copyup_tdp
  25407. + },
  25408. + [AuWbrCopyup_BUP] = {
  25409. + .copyup = au_wbr_copyup_bup
  25410. + },
  25411. + [AuWbrCopyup_BU] = {
  25412. + .copyup = au_wbr_copyup_bu
  25413. + }
  25414. +};
  25415. +
  25416. +struct au_wbr_create_operations au_wbr_create_ops[] = {
  25417. + [AuWbrCreate_TDP] = {
  25418. + .create = au_wbr_create_tdp
  25419. + },
  25420. + [AuWbrCreate_RR] = {
  25421. + .create = au_wbr_create_rr,
  25422. + .init = au_wbr_create_init_rr
  25423. + },
  25424. + [AuWbrCreate_MFS] = {
  25425. + .create = au_wbr_create_mfs,
  25426. + .init = au_wbr_create_init_mfs,
  25427. + .fin = au_wbr_create_fin_mfs
  25428. + },
  25429. + [AuWbrCreate_MFSV] = {
  25430. + .create = au_wbr_create_mfs,
  25431. + .init = au_wbr_create_init_mfs,
  25432. + .fin = au_wbr_create_fin_mfs
  25433. + },
  25434. + [AuWbrCreate_MFSRR] = {
  25435. + .create = au_wbr_create_mfsrr,
  25436. + .init = au_wbr_create_init_mfsrr,
  25437. + .fin = au_wbr_create_fin_mfs
  25438. + },
  25439. + [AuWbrCreate_MFSRRV] = {
  25440. + .create = au_wbr_create_mfsrr,
  25441. + .init = au_wbr_create_init_mfsrr,
  25442. + .fin = au_wbr_create_fin_mfs
  25443. + },
  25444. + [AuWbrCreate_PMFS] = {
  25445. + .create = au_wbr_create_pmfs,
  25446. + .init = au_wbr_create_init_mfs,
  25447. + .fin = au_wbr_create_fin_mfs
  25448. + },
  25449. + [AuWbrCreate_PMFSV] = {
  25450. + .create = au_wbr_create_pmfs,
  25451. + .init = au_wbr_create_init_mfs,
  25452. + .fin = au_wbr_create_fin_mfs
  25453. + }
  25454. +};
  25455. diff -Nur linux-2.6.37.orig/fs/aufs/whout.c linux-2.6.37/fs/aufs/whout.c
  25456. --- linux-2.6.37.orig/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100
  25457. +++ linux-2.6.37/fs/aufs/whout.c 2011-01-11 20:15:11.000000000 +0100
  25458. @@ -0,0 +1,1062 @@
  25459. +/*
  25460. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  25461. + *
  25462. + * This program, aufs is free software; you can redistribute it and/or modify
  25463. + * it under the terms of the GNU General Public License as published by
  25464. + * the Free Software Foundation; either version 2 of the License, or
  25465. + * (at your option) any later version.
  25466. + *
  25467. + * This program is distributed in the hope that it will be useful,
  25468. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25469. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25470. + * GNU General Public License for more details.
  25471. + *
  25472. + * You should have received a copy of the GNU General Public License
  25473. + * along with this program; if not, write to the Free Software
  25474. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  25475. + */
  25476. +
  25477. +/*
  25478. + * whiteout for logical deletion and opaque directory
  25479. + */
  25480. +
  25481. +#include <linux/fs.h>
  25482. +#include "aufs.h"
  25483. +
  25484. +#define WH_MASK S_IRUGO
  25485. +
  25486. +/*
  25487. + * If a directory contains this file, then it is opaque. We start with the
  25488. + * .wh. flag so that it is blocked by lookup.
  25489. + */
  25490. +static struct qstr diropq_name = {
  25491. + .name = AUFS_WH_DIROPQ,
  25492. + .len = sizeof(AUFS_WH_DIROPQ) - 1
  25493. +};
  25494. +
  25495. +/*
  25496. + * generate whiteout name, which is NOT terminated by NULL.
  25497. + * @name: original d_name.name
  25498. + * @len: original d_name.len
  25499. + * @wh: whiteout qstr
  25500. + * returns zero when succeeds, otherwise error.
  25501. + * succeeded value as wh->name should be freed by kfree().
  25502. + */
  25503. +int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
  25504. +{
  25505. + char *p;
  25506. +
  25507. + if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
  25508. + return -ENAMETOOLONG;
  25509. +
  25510. + wh->len = name->len + AUFS_WH_PFX_LEN;
  25511. + p = kmalloc(wh->len, GFP_NOFS);
  25512. + wh->name = p;
  25513. + if (p) {
  25514. + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
  25515. + memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
  25516. + /* smp_mb(); */
  25517. + return 0;
  25518. + }
  25519. + return -ENOMEM;
  25520. +}
  25521. +
  25522. +/* ---------------------------------------------------------------------- */
  25523. +
  25524. +/*
  25525. + * test if the @wh_name exists under @h_parent.
  25526. + * @try_sio specifies the necessary of super-io.
  25527. + */
  25528. +int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
  25529. + struct au_branch *br, int try_sio)
  25530. +{
  25531. + int err;
  25532. + struct dentry *wh_dentry;
  25533. +
  25534. + if (!try_sio)
  25535. + wh_dentry = au_lkup_one(wh_name, h_parent, br, /*nd*/NULL);
  25536. + else
  25537. + wh_dentry = au_sio_lkup_one(wh_name, h_parent, br);
  25538. + err = PTR_ERR(wh_dentry);
  25539. + if (IS_ERR(wh_dentry))
  25540. + goto out;
  25541. +
  25542. + err = 0;
  25543. + if (!wh_dentry->d_inode)
  25544. + goto out_wh; /* success */
  25545. +
  25546. + err = 1;
  25547. + if (S_ISREG(wh_dentry->d_inode->i_mode))
  25548. + goto out_wh; /* success */
  25549. +
  25550. + err = -EIO;
  25551. + AuIOErr("%.*s Invalid whiteout entry type 0%o.\n",
  25552. + AuDLNPair(wh_dentry), wh_dentry->d_inode->i_mode);
  25553. +
  25554. +out_wh:
  25555. + dput(wh_dentry);
  25556. +out:
  25557. + return err;
  25558. +}
  25559. +
  25560. +/*
  25561. + * test if the @h_dentry sets opaque or not.
  25562. + */
  25563. +int au_diropq_test(struct dentry *h_dentry, struct au_branch *br)
  25564. +{
  25565. + int err;
  25566. + struct inode *h_dir;
  25567. +
  25568. + h_dir = h_dentry->d_inode;
  25569. + err = au_wh_test(h_dentry, &diropq_name, br,
  25570. + au_test_h_perm_sio(h_dir, MAY_EXEC));
  25571. + return err;
  25572. +}
  25573. +
  25574. +/*
  25575. + * returns a negative dentry whose name is unique and temporary.
  25576. + */
  25577. +struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
  25578. + struct qstr *prefix)
  25579. +{
  25580. + struct dentry *dentry;
  25581. + int i;
  25582. + char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN_MIN + 1],
  25583. + *name, *p;
  25584. + /* strict atomic_t is unnecessary here */
  25585. + static unsigned short cnt;
  25586. + struct qstr qs;
  25587. +
  25588. + BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
  25589. +
  25590. + name = defname;
  25591. + qs.len = sizeof(defname) - DNAME_INLINE_LEN_MIN + prefix->len - 1;
  25592. + if (unlikely(prefix->len > DNAME_INLINE_LEN_MIN)) {
  25593. + dentry = ERR_PTR(-ENAMETOOLONG);
  25594. + if (unlikely(qs.len > NAME_MAX))
  25595. + goto out;
  25596. + dentry = ERR_PTR(-ENOMEM);
  25597. + name = kmalloc(qs.len + 1, GFP_NOFS);
  25598. + if (unlikely(!name))
  25599. + goto out;
  25600. + }
  25601. +
  25602. + /* doubly whiteout-ed */
  25603. + memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
  25604. + p = name + AUFS_WH_PFX_LEN * 2;
  25605. + memcpy(p, prefix->name, prefix->len);
  25606. + p += prefix->len;
  25607. + *p++ = '.';
  25608. + AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
  25609. +
  25610. + qs.name = name;
  25611. + for (i = 0; i < 3; i++) {
  25612. + sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
  25613. + dentry = au_sio_lkup_one(&qs, h_parent, br);
  25614. + if (IS_ERR(dentry) || !dentry->d_inode)
  25615. + goto out_name;
  25616. + dput(dentry);
  25617. + }
  25618. + /* pr_warning("could not get random name\n"); */
  25619. + dentry = ERR_PTR(-EEXIST);
  25620. + AuDbg("%.*s\n", AuLNPair(&qs));
  25621. + BUG();
  25622. +
  25623. +out_name:
  25624. + if (name != defname)
  25625. + kfree(name);
  25626. +out:
  25627. + AuTraceErrPtr(dentry);
  25628. + return dentry;
  25629. +}
  25630. +
  25631. +/*
  25632. + * rename the @h_dentry on @br to the whiteouted temporary name.
  25633. + */
  25634. +int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
  25635. +{
  25636. + int err;
  25637. + struct path h_path = {
  25638. + .mnt = br->br_mnt
  25639. + };
  25640. + struct inode *h_dir;
  25641. + struct dentry *h_parent;
  25642. +
  25643. + h_parent = h_dentry->d_parent; /* dir inode is locked */
  25644. + h_dir = h_parent->d_inode;
  25645. + IMustLock(h_dir);
  25646. +
  25647. + h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
  25648. + err = PTR_ERR(h_path.dentry);
  25649. + if (IS_ERR(h_path.dentry))
  25650. + goto out;
  25651. +
  25652. + /* under the same dir, no need to lock_rename() */
  25653. + err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path);
  25654. + AuTraceErr(err);
  25655. + dput(h_path.dentry);
  25656. +
  25657. +out:
  25658. + AuTraceErr(err);
  25659. + return err;
  25660. +}
  25661. +
  25662. +/* ---------------------------------------------------------------------- */
  25663. +/*
  25664. + * functions for removing a whiteout
  25665. + */
  25666. +
  25667. +static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
  25668. +{
  25669. + int force;
  25670. +
  25671. + /*
  25672. + * forces superio when the dir has a sticky bit.
  25673. + * this may be a violation of unix fs semantics.
  25674. + */
  25675. + force = (h_dir->i_mode & S_ISVTX)
  25676. + && h_path->dentry->d_inode->i_uid != current_fsuid();
  25677. + return vfsub_unlink(h_dir, h_path, force);
  25678. +}
  25679. +
  25680. +int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
  25681. + struct dentry *dentry)
  25682. +{
  25683. + int err;
  25684. +
  25685. + err = do_unlink_wh(h_dir, h_path);
  25686. + if (!err && dentry)
  25687. + au_set_dbwh(dentry, -1);
  25688. +
  25689. + return err;
  25690. +}
  25691. +
  25692. +static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
  25693. + struct au_branch *br)
  25694. +{
  25695. + int err;
  25696. + struct path h_path = {
  25697. + .mnt = br->br_mnt
  25698. + };
  25699. +
  25700. + err = 0;
  25701. + h_path.dentry = au_lkup_one(wh, h_parent, br, /*nd*/NULL);
  25702. + if (IS_ERR(h_path.dentry))
  25703. + err = PTR_ERR(h_path.dentry);
  25704. + else {
  25705. + if (h_path.dentry->d_inode
  25706. + && S_ISREG(h_path.dentry->d_inode->i_mode))
  25707. + err = do_unlink_wh(h_parent->d_inode, &h_path);
  25708. + dput(h_path.dentry);
  25709. + }
  25710. +
  25711. + return err;
  25712. +}
  25713. +
  25714. +/* ---------------------------------------------------------------------- */
  25715. +/*
  25716. + * initialize/clean whiteout for a branch
  25717. + */
  25718. +
  25719. +static void au_wh_clean(struct inode *h_dir, struct path *whpath,
  25720. + const int isdir)
  25721. +{
  25722. + int err;
  25723. +
  25724. + if (!whpath->dentry->d_inode)
  25725. + return;
  25726. +
  25727. + err = mnt_want_write(whpath->mnt);
  25728. + if (!err) {
  25729. + if (isdir)
  25730. + err = vfsub_rmdir(h_dir, whpath);
  25731. + else
  25732. + err = vfsub_unlink(h_dir, whpath, /*force*/0);
  25733. + mnt_drop_write(whpath->mnt);
  25734. + }
  25735. + if (unlikely(err))
  25736. + pr_warning("failed removing %.*s (%d), ignored.\n",
  25737. + AuDLNPair(whpath->dentry), err);
  25738. +}
  25739. +
  25740. +static int test_linkable(struct dentry *h_root)
  25741. +{
  25742. + struct inode *h_dir = h_root->d_inode;
  25743. +
  25744. + if (h_dir->i_op->link)
  25745. + return 0;
  25746. +
  25747. + pr_err("%.*s (%s) doesn't support link(2), use noplink and rw+nolwh\n",
  25748. + AuDLNPair(h_root), au_sbtype(h_root->d_sb));
  25749. + return -ENOSYS;
  25750. +}
  25751. +
  25752. +/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
  25753. +static int au_whdir(struct inode *h_dir, struct path *path)
  25754. +{
  25755. + int err;
  25756. +
  25757. + err = -EEXIST;
  25758. + if (!path->dentry->d_inode) {
  25759. + int mode = S_IRWXU;
  25760. +
  25761. + if (au_test_nfs(path->dentry->d_sb))
  25762. + mode |= S_IXUGO;
  25763. + err = mnt_want_write(path->mnt);
  25764. + if (!err) {
  25765. + err = vfsub_mkdir(h_dir, path, mode);
  25766. + mnt_drop_write(path->mnt);
  25767. + }
  25768. + } else if (S_ISDIR(path->dentry->d_inode->i_mode))
  25769. + err = 0;
  25770. + else
  25771. + pr_err("unknown %.*s exists\n", AuDLNPair(path->dentry));
  25772. +
  25773. + return err;
  25774. +}
  25775. +
  25776. +struct au_wh_base {
  25777. + const struct qstr *name;
  25778. + struct dentry *dentry;
  25779. +};
  25780. +
  25781. +static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
  25782. + struct path *h_path)
  25783. +{
  25784. + h_path->dentry = base[AuBrWh_BASE].dentry;
  25785. + au_wh_clean(h_dir, h_path, /*isdir*/0);
  25786. + h_path->dentry = base[AuBrWh_PLINK].dentry;
  25787. + au_wh_clean(h_dir, h_path, /*isdir*/1);
  25788. + h_path->dentry = base[AuBrWh_ORPH].dentry;
  25789. + au_wh_clean(h_dir, h_path, /*isdir*/1);
  25790. +}
  25791. +
  25792. +/*
  25793. + * returns tri-state,
  25794. + * minus: error, caller should print the mesage
  25795. + * zero: succuess
  25796. + * plus: error, caller should NOT print the mesage
  25797. + */
  25798. +static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
  25799. + int do_plink, struct au_wh_base base[],
  25800. + struct path *h_path)
  25801. +{
  25802. + int err;
  25803. + struct inode *h_dir;
  25804. +
  25805. + h_dir = h_root->d_inode;
  25806. + h_path->dentry = base[AuBrWh_BASE].dentry;
  25807. + au_wh_clean(h_dir, h_path, /*isdir*/0);
  25808. + h_path->dentry = base[AuBrWh_PLINK].dentry;
  25809. + if (do_plink) {
  25810. + err = test_linkable(h_root);
  25811. + if (unlikely(err)) {
  25812. + err = 1;
  25813. + goto out;
  25814. + }
  25815. +
  25816. + err = au_whdir(h_dir, h_path);
  25817. + if (unlikely(err))
  25818. + goto out;
  25819. + wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
  25820. + } else
  25821. + au_wh_clean(h_dir, h_path, /*isdir*/1);
  25822. + h_path->dentry = base[AuBrWh_ORPH].dentry;
  25823. + err = au_whdir(h_dir, h_path);
  25824. + if (unlikely(err))
  25825. + goto out;
  25826. + wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
  25827. +
  25828. +out:
  25829. + return err;
  25830. +}
  25831. +
  25832. +/*
  25833. + * for the moment, aufs supports the branch filesystem which does not support
  25834. + * link(2). testing on FAT which does not support i_op->setattr() fully either,
  25835. + * copyup failed. finally, such filesystem will not be used as the writable
  25836. + * branch.
  25837. + *
  25838. + * returns tri-state, see above.
  25839. + */
  25840. +static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
  25841. + int do_plink, struct au_wh_base base[],
  25842. + struct path *h_path)
  25843. +{
  25844. + int err;
  25845. + struct inode *h_dir;
  25846. +
  25847. + WbrWhMustWriteLock(wbr);
  25848. +
  25849. + err = test_linkable(h_root);
  25850. + if (unlikely(err)) {
  25851. + err = 1;
  25852. + goto out;
  25853. + }
  25854. +
  25855. + /*
  25856. + * todo: should this create be done in /sbin/mount.aufs helper?
  25857. + */
  25858. + err = -EEXIST;
  25859. + h_dir = h_root->d_inode;
  25860. + if (!base[AuBrWh_BASE].dentry->d_inode) {
  25861. + err = mnt_want_write(h_path->mnt);
  25862. + if (!err) {
  25863. + h_path->dentry = base[AuBrWh_BASE].dentry;
  25864. + err = vfsub_create(h_dir, h_path, WH_MASK);
  25865. + mnt_drop_write(h_path->mnt);
  25866. + }
  25867. + } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode))
  25868. + err = 0;
  25869. + else
  25870. + pr_err("unknown %.*s/%.*s exists\n",
  25871. + AuDLNPair(h_root), AuDLNPair(base[AuBrWh_BASE].dentry));
  25872. + if (unlikely(err))
  25873. + goto out;
  25874. +
  25875. + h_path->dentry = base[AuBrWh_PLINK].dentry;
  25876. + if (do_plink) {
  25877. + err = au_whdir(h_dir, h_path);
  25878. + if (unlikely(err))
  25879. + goto out;
  25880. + wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
  25881. + } else
  25882. + au_wh_clean(h_dir, h_path, /*isdir*/1);
  25883. + wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
  25884. +
  25885. + h_path->dentry = base[AuBrWh_ORPH].dentry;
  25886. + err = au_whdir(h_dir, h_path);
  25887. + if (unlikely(err))
  25888. + goto out;
  25889. + wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
  25890. +
  25891. +out:
  25892. + return err;
  25893. +}
  25894. +
  25895. +/*
  25896. + * initialize the whiteout base file/dir for @br.
  25897. + */
  25898. +int au_wh_init(struct dentry *h_root, struct au_branch *br,
  25899. + struct super_block *sb)
  25900. +{
  25901. + int err, i;
  25902. + const unsigned char do_plink
  25903. + = !!au_opt_test(au_mntflags(sb), PLINK);
  25904. + struct path path = {
  25905. + .mnt = br->br_mnt
  25906. + };
  25907. + struct inode *h_dir;
  25908. + struct au_wbr *wbr = br->br_wbr;
  25909. + static const struct qstr base_name[] = {
  25910. + [AuBrWh_BASE] = {
  25911. + .name = AUFS_BASE_NAME,
  25912. + .len = sizeof(AUFS_BASE_NAME) - 1
  25913. + },
  25914. + [AuBrWh_PLINK] = {
  25915. + .name = AUFS_PLINKDIR_NAME,
  25916. + .len = sizeof(AUFS_PLINKDIR_NAME) - 1
  25917. + },
  25918. + [AuBrWh_ORPH] = {
  25919. + .name = AUFS_ORPHDIR_NAME,
  25920. + .len = sizeof(AUFS_ORPHDIR_NAME) - 1
  25921. + }
  25922. + };
  25923. + struct au_wh_base base[] = {
  25924. + [AuBrWh_BASE] = {
  25925. + .name = base_name + AuBrWh_BASE,
  25926. + .dentry = NULL
  25927. + },
  25928. + [AuBrWh_PLINK] = {
  25929. + .name = base_name + AuBrWh_PLINK,
  25930. + .dentry = NULL
  25931. + },
  25932. + [AuBrWh_ORPH] = {
  25933. + .name = base_name + AuBrWh_ORPH,
  25934. + .dentry = NULL
  25935. + }
  25936. + };
  25937. +
  25938. + if (wbr)
  25939. + WbrWhMustWriteLock(wbr);
  25940. +
  25941. + for (i = 0; i < AuBrWh_Last; i++) {
  25942. + /* doubly whiteouted */
  25943. + struct dentry *d;
  25944. +
  25945. + d = au_wh_lkup(h_root, (void *)base[i].name, br);
  25946. + err = PTR_ERR(d);
  25947. + if (IS_ERR(d))
  25948. + goto out;
  25949. +
  25950. + base[i].dentry = d;
  25951. + AuDebugOn(wbr
  25952. + && wbr->wbr_wh[i]
  25953. + && wbr->wbr_wh[i] != base[i].dentry);
  25954. + }
  25955. +
  25956. + if (wbr)
  25957. + for (i = 0; i < AuBrWh_Last; i++) {
  25958. + dput(wbr->wbr_wh[i]);
  25959. + wbr->wbr_wh[i] = NULL;
  25960. + }
  25961. +
  25962. + err = 0;
  25963. + switch (br->br_perm) {
  25964. + case AuBrPerm_RO:
  25965. + case AuBrPerm_ROWH:
  25966. + case AuBrPerm_RR:
  25967. + case AuBrPerm_RRWH:
  25968. + h_dir = h_root->d_inode;
  25969. + au_wh_init_ro(h_dir, base, &path);
  25970. + break;
  25971. +
  25972. + case AuBrPerm_RWNoLinkWH:
  25973. + err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
  25974. + if (err > 0)
  25975. + goto out;
  25976. + else if (err)
  25977. + goto out_err;
  25978. + break;
  25979. +
  25980. + case AuBrPerm_RW:
  25981. + err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
  25982. + if (err > 0)
  25983. + goto out;
  25984. + else if (err)
  25985. + goto out_err;
  25986. + break;
  25987. +
  25988. + default:
  25989. + BUG();
  25990. + }
  25991. + goto out; /* success */
  25992. +
  25993. +out_err:
  25994. + pr_err("an error(%d) on the writable branch %.*s(%s)\n",
  25995. + err, AuDLNPair(h_root), au_sbtype(h_root->d_sb));
  25996. +out:
  25997. + for (i = 0; i < AuBrWh_Last; i++)
  25998. + dput(base[i].dentry);
  25999. + return err;
  26000. +}
  26001. +
  26002. +/* ---------------------------------------------------------------------- */
  26003. +/*
  26004. + * whiteouts are all hard-linked usually.
  26005. + * when its link count reaches a ceiling, we create a new whiteout base
  26006. + * asynchronously.
  26007. + */
  26008. +
  26009. +struct reinit_br_wh {
  26010. + struct super_block *sb;
  26011. + struct au_branch *br;
  26012. +};
  26013. +
  26014. +static void reinit_br_wh(void *arg)
  26015. +{
  26016. + int err;
  26017. + aufs_bindex_t bindex;
  26018. + struct path h_path;
  26019. + struct reinit_br_wh *a = arg;
  26020. + struct au_wbr *wbr;
  26021. + struct inode *dir;
  26022. + struct dentry *h_root;
  26023. + struct au_hinode *hdir;
  26024. +
  26025. + err = 0;
  26026. + wbr = a->br->br_wbr;
  26027. + /* big aufs lock */
  26028. + si_noflush_write_lock(a->sb);
  26029. + if (!au_br_writable(a->br->br_perm))
  26030. + goto out;
  26031. + bindex = au_br_index(a->sb, a->br->br_id);
  26032. + if (unlikely(bindex < 0))
  26033. + goto out;
  26034. +
  26035. + di_read_lock_parent(a->sb->s_root, AuLock_IR);
  26036. + dir = a->sb->s_root->d_inode;
  26037. + hdir = au_hi(dir, bindex);
  26038. + h_root = au_h_dptr(a->sb->s_root, bindex);
  26039. +
  26040. + au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
  26041. + wbr_wh_write_lock(wbr);
  26042. + err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
  26043. + h_root, a->br);
  26044. + if (!err) {
  26045. + err = mnt_want_write(a->br->br_mnt);
  26046. + if (!err) {
  26047. + h_path.dentry = wbr->wbr_whbase;
  26048. + h_path.mnt = a->br->br_mnt;
  26049. + err = vfsub_unlink(hdir->hi_inode, &h_path, /*force*/0);
  26050. + mnt_drop_write(a->br->br_mnt);
  26051. + }
  26052. + } else {
  26053. + pr_warning("%.*s is moved, ignored\n",
  26054. + AuDLNPair(wbr->wbr_whbase));
  26055. + err = 0;
  26056. + }
  26057. + dput(wbr->wbr_whbase);
  26058. + wbr->wbr_whbase = NULL;
  26059. + if (!err)
  26060. + err = au_wh_init(h_root, a->br, a->sb);
  26061. + wbr_wh_write_unlock(wbr);
  26062. + au_hn_imtx_unlock(hdir);
  26063. + di_read_unlock(a->sb->s_root, AuLock_IR);
  26064. +
  26065. +out:
  26066. + if (wbr)
  26067. + atomic_dec(&wbr->wbr_wh_running);
  26068. + atomic_dec(&a->br->br_count);
  26069. + si_write_unlock(a->sb);
  26070. + au_nwt_done(&au_sbi(a->sb)->si_nowait);
  26071. + kfree(arg);
  26072. + if (unlikely(err))
  26073. + AuIOErr("err %d\n", err);
  26074. +}
  26075. +
  26076. +static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
  26077. +{
  26078. + int do_dec, wkq_err;
  26079. + struct reinit_br_wh *arg;
  26080. +
  26081. + do_dec = 1;
  26082. + if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
  26083. + goto out;
  26084. +
  26085. + /* ignore ENOMEM */
  26086. + arg = kmalloc(sizeof(*arg), GFP_NOFS);
  26087. + if (arg) {
  26088. + /*
  26089. + * dec(wh_running), kfree(arg) and dec(br_count)
  26090. + * in reinit function
  26091. + */
  26092. + arg->sb = sb;
  26093. + arg->br = br;
  26094. + atomic_inc(&br->br_count);
  26095. + wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb);
  26096. + if (unlikely(wkq_err)) {
  26097. + atomic_dec(&br->br_wbr->wbr_wh_running);
  26098. + atomic_dec(&br->br_count);
  26099. + kfree(arg);
  26100. + }
  26101. + do_dec = 0;
  26102. + }
  26103. +
  26104. +out:
  26105. + if (do_dec)
  26106. + atomic_dec(&br->br_wbr->wbr_wh_running);
  26107. +}
  26108. +
  26109. +/* ---------------------------------------------------------------------- */
  26110. +
  26111. +/*
  26112. + * create the whiteout @wh.
  26113. + */
  26114. +static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
  26115. + struct dentry *wh)
  26116. +{
  26117. + int err;
  26118. + struct path h_path = {
  26119. + .dentry = wh
  26120. + };
  26121. + struct au_branch *br;
  26122. + struct au_wbr *wbr;
  26123. + struct dentry *h_parent;
  26124. + struct inode *h_dir;
  26125. +
  26126. + h_parent = wh->d_parent; /* dir inode is locked */
  26127. + h_dir = h_parent->d_inode;
  26128. + IMustLock(h_dir);
  26129. +
  26130. + br = au_sbr(sb, bindex);
  26131. + h_path.mnt = br->br_mnt;
  26132. + wbr = br->br_wbr;
  26133. + wbr_wh_read_lock(wbr);
  26134. + if (wbr->wbr_whbase) {
  26135. + err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path);
  26136. + if (!err || err != -EMLINK)
  26137. + goto out;
  26138. +
  26139. + /* link count full. re-initialize br_whbase. */
  26140. + kick_reinit_br_wh(sb, br);
  26141. + }
  26142. +
  26143. + /* return this error in this context */
  26144. + err = vfsub_create(h_dir, &h_path, WH_MASK);
  26145. +
  26146. +out:
  26147. + wbr_wh_read_unlock(wbr);
  26148. + return err;
  26149. +}
  26150. +
  26151. +/* ---------------------------------------------------------------------- */
  26152. +
  26153. +/*
  26154. + * create or remove the diropq.
  26155. + */
  26156. +static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
  26157. + unsigned int flags)
  26158. +{
  26159. + struct dentry *opq_dentry, *h_dentry;
  26160. + struct super_block *sb;
  26161. + struct au_branch *br;
  26162. + int err;
  26163. +
  26164. + sb = dentry->d_sb;
  26165. + br = au_sbr(sb, bindex);
  26166. + h_dentry = au_h_dptr(dentry, bindex);
  26167. + opq_dentry = au_lkup_one(&diropq_name, h_dentry, br, /*nd*/NULL);
  26168. + if (IS_ERR(opq_dentry))
  26169. + goto out;
  26170. +
  26171. + if (au_ftest_diropq(flags, CREATE)) {
  26172. + err = link_or_create_wh(sb, bindex, opq_dentry);
  26173. + if (!err) {
  26174. + au_set_dbdiropq(dentry, bindex);
  26175. + goto out; /* success */
  26176. + }
  26177. + } else {
  26178. + struct path tmp = {
  26179. + .dentry = opq_dentry,
  26180. + .mnt = br->br_mnt
  26181. + };
  26182. + err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp);
  26183. + if (!err)
  26184. + au_set_dbdiropq(dentry, -1);
  26185. + }
  26186. + dput(opq_dentry);
  26187. + opq_dentry = ERR_PTR(err);
  26188. +
  26189. +out:
  26190. + return opq_dentry;
  26191. +}
  26192. +
  26193. +struct do_diropq_args {
  26194. + struct dentry **errp;
  26195. + struct dentry *dentry;
  26196. + aufs_bindex_t bindex;
  26197. + unsigned int flags;
  26198. +};
  26199. +
  26200. +static void call_do_diropq(void *args)
  26201. +{
  26202. + struct do_diropq_args *a = args;
  26203. + *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
  26204. +}
  26205. +
  26206. +struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
  26207. + unsigned int flags)
  26208. +{
  26209. + struct dentry *diropq, *h_dentry;
  26210. +
  26211. + h_dentry = au_h_dptr(dentry, bindex);
  26212. + if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE))
  26213. + diropq = do_diropq(dentry, bindex, flags);
  26214. + else {
  26215. + int wkq_err;
  26216. + struct do_diropq_args args = {
  26217. + .errp = &diropq,
  26218. + .dentry = dentry,
  26219. + .bindex = bindex,
  26220. + .flags = flags
  26221. + };
  26222. +
  26223. + wkq_err = au_wkq_wait(call_do_diropq, &args);
  26224. + if (unlikely(wkq_err))
  26225. + diropq = ERR_PTR(wkq_err);
  26226. + }
  26227. +
  26228. + return diropq;
  26229. +}
  26230. +
  26231. +/* ---------------------------------------------------------------------- */
  26232. +
  26233. +/*
  26234. + * lookup whiteout dentry.
  26235. + * @h_parent: lower parent dentry which must exist and be locked
  26236. + * @base_name: name of dentry which will be whiteouted
  26237. + * returns dentry for whiteout.
  26238. + */
  26239. +struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
  26240. + struct au_branch *br)
  26241. +{
  26242. + int err;
  26243. + struct qstr wh_name;
  26244. + struct dentry *wh_dentry;
  26245. +
  26246. + err = au_wh_name_alloc(&wh_name, base_name);
  26247. + wh_dentry = ERR_PTR(err);
  26248. + if (!err) {
  26249. + wh_dentry = au_lkup_one(&wh_name, h_parent, br, /*nd*/NULL);
  26250. + kfree(wh_name.name);
  26251. + }
  26252. + return wh_dentry;
  26253. +}
  26254. +
  26255. +/*
  26256. + * link/create a whiteout for @dentry on @bindex.
  26257. + */
  26258. +struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
  26259. + struct dentry *h_parent)
  26260. +{
  26261. + struct dentry *wh_dentry;
  26262. + struct super_block *sb;
  26263. + int err;
  26264. +
  26265. + sb = dentry->d_sb;
  26266. + wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
  26267. + if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) {
  26268. + err = link_or_create_wh(sb, bindex, wh_dentry);
  26269. + if (!err)
  26270. + au_set_dbwh(dentry, bindex);
  26271. + else {
  26272. + dput(wh_dentry);
  26273. + wh_dentry = ERR_PTR(err);
  26274. + }
  26275. + }
  26276. +
  26277. + return wh_dentry;
  26278. +}
  26279. +
  26280. +/* ---------------------------------------------------------------------- */
  26281. +
  26282. +/* Delete all whiteouts in this directory on branch bindex. */
  26283. +static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
  26284. + aufs_bindex_t bindex, struct au_branch *br)
  26285. +{
  26286. + int err;
  26287. + unsigned long ul, n;
  26288. + struct qstr wh_name;
  26289. + char *p;
  26290. + struct hlist_head *head;
  26291. + struct au_vdir_wh *tpos;
  26292. + struct hlist_node *pos;
  26293. + struct au_vdir_destr *str;
  26294. +
  26295. + err = -ENOMEM;
  26296. + p = __getname_gfp(GFP_NOFS);
  26297. + wh_name.name = p;
  26298. + if (unlikely(!wh_name.name))
  26299. + goto out;
  26300. +
  26301. + err = 0;
  26302. + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
  26303. + p += AUFS_WH_PFX_LEN;
  26304. + n = whlist->nh_num;
  26305. + head = whlist->nh_head;
  26306. + for (ul = 0; !err && ul < n; ul++, head++) {
  26307. + hlist_for_each_entry(tpos, pos, head, wh_hash) {
  26308. + if (tpos->wh_bindex != bindex)
  26309. + continue;
  26310. +
  26311. + str = &tpos->wh_str;
  26312. + if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
  26313. + memcpy(p, str->name, str->len);
  26314. + wh_name.len = AUFS_WH_PFX_LEN + str->len;
  26315. + err = unlink_wh_name(h_dentry, &wh_name, br);
  26316. + if (!err)
  26317. + continue;
  26318. + break;
  26319. + }
  26320. + AuIOErr("whiteout name too long %.*s\n",
  26321. + str->len, str->name);
  26322. + err = -EIO;
  26323. + break;
  26324. + }
  26325. + }
  26326. + __putname(wh_name.name);
  26327. +
  26328. +out:
  26329. + return err;
  26330. +}
  26331. +
  26332. +struct del_wh_children_args {
  26333. + int *errp;
  26334. + struct dentry *h_dentry;
  26335. + struct au_nhash *whlist;
  26336. + aufs_bindex_t bindex;
  26337. + struct au_branch *br;
  26338. +};
  26339. +
  26340. +static void call_del_wh_children(void *args)
  26341. +{
  26342. + struct del_wh_children_args *a = args;
  26343. + *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
  26344. +}
  26345. +
  26346. +/* ---------------------------------------------------------------------- */
  26347. +
  26348. +struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
  26349. +{
  26350. + struct au_whtmp_rmdir *whtmp;
  26351. + int err;
  26352. + unsigned int rdhash;
  26353. +
  26354. + SiMustAnyLock(sb);
  26355. +
  26356. + whtmp = kmalloc(sizeof(*whtmp), gfp);
  26357. + if (unlikely(!whtmp)) {
  26358. + whtmp = ERR_PTR(-ENOMEM);
  26359. + goto out;
  26360. + }
  26361. +
  26362. + whtmp->dir = NULL;
  26363. + whtmp->br = NULL;
  26364. + whtmp->wh_dentry = NULL;
  26365. + /* no estimation for dir size */
  26366. + rdhash = au_sbi(sb)->si_rdhash;
  26367. + if (!rdhash)
  26368. + rdhash = AUFS_RDHASH_DEF;
  26369. + err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
  26370. + if (unlikely(err)) {
  26371. + kfree(whtmp);
  26372. + whtmp = ERR_PTR(err);
  26373. + }
  26374. +
  26375. +out:
  26376. + return whtmp;
  26377. +}
  26378. +
  26379. +void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
  26380. +{
  26381. + if (whtmp->br)
  26382. + atomic_dec(&whtmp->br->br_count);
  26383. + dput(whtmp->wh_dentry);
  26384. + iput(whtmp->dir);
  26385. + au_nhash_wh_free(&whtmp->whlist);
  26386. + kfree(whtmp);
  26387. +}
  26388. +
  26389. +/*
  26390. + * rmdir the whiteouted temporary named dir @h_dentry.
  26391. + * @whlist: whiteouted children.
  26392. + */
  26393. +int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
  26394. + struct dentry *wh_dentry, struct au_nhash *whlist)
  26395. +{
  26396. + int err;
  26397. + struct path h_tmp;
  26398. + struct inode *wh_inode, *h_dir;
  26399. + struct au_branch *br;
  26400. +
  26401. + h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
  26402. + IMustLock(h_dir);
  26403. +
  26404. + br = au_sbr(dir->i_sb, bindex);
  26405. + wh_inode = wh_dentry->d_inode;
  26406. + mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
  26407. +
  26408. + /*
  26409. + * someone else might change some whiteouts while we were sleeping.
  26410. + * it means this whlist may have an obsoleted entry.
  26411. + */
  26412. + if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
  26413. + err = del_wh_children(wh_dentry, whlist, bindex, br);
  26414. + else {
  26415. + int wkq_err;
  26416. + struct del_wh_children_args args = {
  26417. + .errp = &err,
  26418. + .h_dentry = wh_dentry,
  26419. + .whlist = whlist,
  26420. + .bindex = bindex,
  26421. + .br = br
  26422. + };
  26423. +
  26424. + wkq_err = au_wkq_wait(call_del_wh_children, &args);
  26425. + if (unlikely(wkq_err))
  26426. + err = wkq_err;
  26427. + }
  26428. + mutex_unlock(&wh_inode->i_mutex);
  26429. +
  26430. + if (!err) {
  26431. + h_tmp.dentry = wh_dentry;
  26432. + h_tmp.mnt = br->br_mnt;
  26433. + err = vfsub_rmdir(h_dir, &h_tmp);
  26434. + }
  26435. +
  26436. + if (!err) {
  26437. + if (au_ibstart(dir) == bindex) {
  26438. + /* todo: dir->i_mutex is necessary */
  26439. + au_cpup_attr_timesizes(dir);
  26440. + vfsub_drop_nlink(dir);
  26441. + }
  26442. + return 0; /* success */
  26443. + }
  26444. +
  26445. + pr_warning("failed removing %.*s(%d), ignored\n",
  26446. + AuDLNPair(wh_dentry), err);
  26447. + return err;
  26448. +}
  26449. +
  26450. +static void call_rmdir_whtmp(void *args)
  26451. +{
  26452. + int err;
  26453. + aufs_bindex_t bindex;
  26454. + struct au_whtmp_rmdir *a = args;
  26455. + struct super_block *sb;
  26456. + struct dentry *h_parent;
  26457. + struct inode *h_dir;
  26458. + struct au_hinode *hdir;
  26459. +
  26460. + /* rmdir by nfsd may cause deadlock with this i_mutex */
  26461. + /* mutex_lock(&a->dir->i_mutex); */
  26462. + err = -EROFS;
  26463. + sb = a->dir->i_sb;
  26464. + si_read_lock(sb, !AuLock_FLUSH);
  26465. + if (!au_br_writable(a->br->br_perm))
  26466. + goto out;
  26467. + bindex = au_br_index(sb, a->br->br_id);
  26468. + if (unlikely(bindex < 0))
  26469. + goto out;
  26470. +
  26471. + err = -EIO;
  26472. + ii_write_lock_parent(a->dir);
  26473. + h_parent = dget_parent(a->wh_dentry);
  26474. + h_dir = h_parent->d_inode;
  26475. + hdir = au_hi(a->dir, bindex);
  26476. + au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
  26477. + err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
  26478. + a->br);
  26479. + if (!err) {
  26480. + err = mnt_want_write(a->br->br_mnt);
  26481. + if (!err) {
  26482. + err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry,
  26483. + &a->whlist);
  26484. + mnt_drop_write(a->br->br_mnt);
  26485. + }
  26486. + }
  26487. + au_hn_imtx_unlock(hdir);
  26488. + dput(h_parent);
  26489. + ii_write_unlock(a->dir);
  26490. +
  26491. +out:
  26492. + /* mutex_unlock(&a->dir->i_mutex); */
  26493. + au_whtmp_rmdir_free(a);
  26494. + si_read_unlock(sb);
  26495. + au_nwt_done(&au_sbi(sb)->si_nowait);
  26496. + if (unlikely(err))
  26497. + AuIOErr("err %d\n", err);
  26498. +}
  26499. +
  26500. +void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
  26501. + struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
  26502. +{
  26503. + int wkq_err;
  26504. + struct super_block *sb;
  26505. +
  26506. + IMustLock(dir);
  26507. +
  26508. + /* all post-process will be done in do_rmdir_whtmp(). */
  26509. + sb = dir->i_sb;
  26510. + args->dir = au_igrab(dir);
  26511. + args->br = au_sbr(sb, bindex);
  26512. + atomic_inc(&args->br->br_count);
  26513. + args->wh_dentry = dget(wh_dentry);
  26514. + wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb);
  26515. + if (unlikely(wkq_err)) {
  26516. + pr_warning("rmdir error %.*s (%d), ignored\n",
  26517. + AuDLNPair(wh_dentry), wkq_err);
  26518. + au_whtmp_rmdir_free(args);
  26519. + }
  26520. +}
  26521. diff -Nur linux-2.6.37.orig/fs/aufs/whout.h linux-2.6.37/fs/aufs/whout.h
  26522. --- linux-2.6.37.orig/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100
  26523. +++ linux-2.6.37/fs/aufs/whout.h 2011-01-11 20:15:11.000000000 +0100
  26524. @@ -0,0 +1,89 @@
  26525. +/*
  26526. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  26527. + *
  26528. + * This program, aufs is free software; you can redistribute it and/or modify
  26529. + * it under the terms of the GNU General Public License as published by
  26530. + * the Free Software Foundation; either version 2 of the License, or
  26531. + * (at your option) any later version.
  26532. + *
  26533. + * This program is distributed in the hope that it will be useful,
  26534. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  26535. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26536. + * GNU General Public License for more details.
  26537. + *
  26538. + * You should have received a copy of the GNU General Public License
  26539. + * along with this program; if not, write to the Free Software
  26540. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  26541. + */
  26542. +
  26543. +/*
  26544. + * whiteout for logical deletion and opaque directory
  26545. + */
  26546. +
  26547. +#ifndef __AUFS_WHOUT_H__
  26548. +#define __AUFS_WHOUT_H__
  26549. +
  26550. +#ifdef __KERNEL__
  26551. +
  26552. +#include <linux/aufs_type.h>
  26553. +#include "dir.h"
  26554. +
  26555. +/* whout.c */
  26556. +int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
  26557. +struct au_branch;
  26558. +int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
  26559. + struct au_branch *br, int try_sio);
  26560. +int au_diropq_test(struct dentry *h_dentry, struct au_branch *br);
  26561. +struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
  26562. + struct qstr *prefix);
  26563. +int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
  26564. +int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
  26565. + struct dentry *dentry);
  26566. +int au_wh_init(struct dentry *h_parent, struct au_branch *br,
  26567. + struct super_block *sb);
  26568. +
  26569. +/* diropq flags */
  26570. +#define AuDiropq_CREATE 1
  26571. +#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name)
  26572. +#define au_fset_diropq(flags, name) \
  26573. + do { (flags) |= AuDiropq_##name; } while (0)
  26574. +#define au_fclr_diropq(flags, name) \
  26575. + do { (flags) &= ~AuDiropq_##name; } while (0)
  26576. +
  26577. +struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
  26578. + unsigned int flags);
  26579. +struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
  26580. + struct au_branch *br);
  26581. +struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
  26582. + struct dentry *h_parent);
  26583. +
  26584. +/* real rmdir for the whiteout-ed dir */
  26585. +struct au_whtmp_rmdir {
  26586. + struct inode *dir;
  26587. + struct au_branch *br;
  26588. + struct dentry *wh_dentry;
  26589. + struct au_nhash whlist;
  26590. +};
  26591. +
  26592. +struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
  26593. +void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
  26594. +int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
  26595. + struct dentry *wh_dentry, struct au_nhash *whlist);
  26596. +void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
  26597. + struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
  26598. +
  26599. +/* ---------------------------------------------------------------------- */
  26600. +
  26601. +static inline struct dentry *au_diropq_create(struct dentry *dentry,
  26602. + aufs_bindex_t bindex)
  26603. +{
  26604. + return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
  26605. +}
  26606. +
  26607. +static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
  26608. +{
  26609. + return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
  26610. +}
  26611. +
  26612. +#endif /* __KERNEL__ */
  26613. +#endif /* __AUFS_WHOUT_H__ */
  26614. diff -Nur linux-2.6.37.orig/fs/aufs/wkq.c linux-2.6.37/fs/aufs/wkq.c
  26615. --- linux-2.6.37.orig/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100
  26616. +++ linux-2.6.37/fs/aufs/wkq.c 2011-01-11 20:15:11.000000000 +0100
  26617. @@ -0,0 +1,236 @@
  26618. +/*
  26619. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  26620. + *
  26621. + * This program, aufs is free software; you can redistribute it and/or modify
  26622. + * it under the terms of the GNU General Public License as published by
  26623. + * the Free Software Foundation; either version 2 of the License, or
  26624. + * (at your option) any later version.
  26625. + *
  26626. + * This program is distributed in the hope that it will be useful,
  26627. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  26628. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26629. + * GNU General Public License for more details.
  26630. + *
  26631. + * You should have received a copy of the GNU General Public License
  26632. + * along with this program; if not, write to the Free Software
  26633. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  26634. + */
  26635. +
  26636. +/*
  26637. + * workqueue for asynchronous/super-io operations
  26638. + * todo: try new dredential scheme
  26639. + */
  26640. +
  26641. +#include <linux/module.h>
  26642. +#include "aufs.h"
  26643. +
  26644. +/* internal workqueue named AUFS_WKQ_NAME and AUFS_WKQ_PRE_NAME */
  26645. +enum {
  26646. + AuWkq_INORMAL,
  26647. + AuWkq_IPRE
  26648. +};
  26649. +
  26650. +static struct {
  26651. + char *name;
  26652. + struct workqueue_struct *wkq;
  26653. +} au_wkq[] = {
  26654. + [AuWkq_INORMAL] = {
  26655. + .name = AUFS_WKQ_NAME
  26656. + },
  26657. + [AuWkq_IPRE] = {
  26658. + .name = AUFS_WKQ_PRE_NAME
  26659. + }
  26660. +};
  26661. +
  26662. +struct au_wkinfo {
  26663. + struct work_struct wk;
  26664. + struct kobject *kobj;
  26665. +
  26666. + unsigned int flags; /* see wkq.h */
  26667. +
  26668. + au_wkq_func_t func;
  26669. + void *args;
  26670. +
  26671. + struct completion *comp;
  26672. +};
  26673. +
  26674. +/* ---------------------------------------------------------------------- */
  26675. +
  26676. +static void wkq_func(struct work_struct *wk)
  26677. +{
  26678. + struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
  26679. +
  26680. + AuDebugOn(current_fsuid());
  26681. + AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY);
  26682. +
  26683. + wkinfo->func(wkinfo->args);
  26684. + if (au_ftest_wkq(wkinfo->flags, WAIT))
  26685. + complete(wkinfo->comp);
  26686. + else {
  26687. + kobject_put(wkinfo->kobj);
  26688. + module_put(THIS_MODULE);
  26689. + kfree(wkinfo);
  26690. + }
  26691. +}
  26692. +
  26693. +/*
  26694. + * Since struct completion is large, try allocating it dynamically.
  26695. + */
  26696. +#if defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS)
  26697. +#define AuWkqCompDeclare(name) struct completion *comp = NULL
  26698. +
  26699. +static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
  26700. +{
  26701. + *comp = kmalloc(sizeof(**comp), GFP_NOFS);
  26702. + if (*comp) {
  26703. + init_completion(*comp);
  26704. + wkinfo->comp = *comp;
  26705. + return 0;
  26706. + }
  26707. + return -ENOMEM;
  26708. +}
  26709. +
  26710. +static void au_wkq_comp_free(struct completion *comp)
  26711. +{
  26712. + kfree(comp);
  26713. +}
  26714. +
  26715. +#else
  26716. +
  26717. +/* no braces */
  26718. +#define AuWkqCompDeclare(name) \
  26719. + DECLARE_COMPLETION_ONSTACK(_ ## name); \
  26720. + struct completion *comp = &_ ## name
  26721. +
  26722. +static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
  26723. +{
  26724. + wkinfo->comp = *comp;
  26725. + return 0;
  26726. +}
  26727. +
  26728. +static void au_wkq_comp_free(struct completion *comp __maybe_unused)
  26729. +{
  26730. + /* empty */
  26731. +}
  26732. +#endif /* 4KSTACKS */
  26733. +
  26734. +static void au_wkq_run(struct au_wkinfo *wkinfo, unsigned int flags)
  26735. +{
  26736. + struct workqueue_struct *wkq;
  26737. +
  26738. + au_dbg_verify_kthread();
  26739. + if (flags & AuWkq_WAIT) {
  26740. + INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func);
  26741. + wkq = au_wkq[AuWkq_INORMAL].wkq;
  26742. + if (flags & AuWkq_PRE)
  26743. + wkq = au_wkq[AuWkq_IPRE].wkq;
  26744. + queue_work(wkq, &wkinfo->wk);
  26745. + } else {
  26746. + INIT_WORK(&wkinfo->wk, wkq_func);
  26747. + schedule_work(&wkinfo->wk);
  26748. + }
  26749. +}
  26750. +
  26751. +/*
  26752. + * Be careful. It is easy to make deadlock happen.
  26753. + * processA: lock, wkq and wait
  26754. + * processB: wkq and wait, lock in wkq
  26755. + * --> deadlock
  26756. + */
  26757. +int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args)
  26758. +{
  26759. + int err;
  26760. + AuWkqCompDeclare(comp);
  26761. + struct au_wkinfo wkinfo = {
  26762. + .flags = flags,
  26763. + .func = func,
  26764. + .args = args
  26765. + };
  26766. +
  26767. + err = au_wkq_comp_alloc(&wkinfo, &comp);
  26768. + if (!err) {
  26769. + au_wkq_run(&wkinfo, flags);
  26770. + /* no timeout, no interrupt */
  26771. + wait_for_completion(wkinfo.comp);
  26772. + au_wkq_comp_free(comp);
  26773. + destroy_work_on_stack(&wkinfo.wk);
  26774. + }
  26775. +
  26776. + return err;
  26777. +
  26778. +}
  26779. +
  26780. +/*
  26781. + * Note: dget/dput() in func for aufs dentries are not supported. It will be a
  26782. + * problem in a concurrent umounting.
  26783. + */
  26784. +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb)
  26785. +{
  26786. + int err;
  26787. + struct au_wkinfo *wkinfo;
  26788. +
  26789. + atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
  26790. +
  26791. + /*
  26792. + * wkq_func() must free this wkinfo.
  26793. + * it highly depends upon the implementation of workqueue.
  26794. + */
  26795. + err = 0;
  26796. + wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
  26797. + if (wkinfo) {
  26798. + wkinfo->kobj = &au_sbi(sb)->si_kobj;
  26799. + wkinfo->flags = !AuWkq_WAIT;
  26800. + wkinfo->func = func;
  26801. + wkinfo->args = args;
  26802. + wkinfo->comp = NULL;
  26803. + kobject_get(wkinfo->kobj);
  26804. + __module_get(THIS_MODULE);
  26805. +
  26806. + au_wkq_run(wkinfo, !AuWkq_WAIT);
  26807. + } else {
  26808. + err = -ENOMEM;
  26809. + au_nwt_done(&au_sbi(sb)->si_nowait);
  26810. + }
  26811. +
  26812. + return err;
  26813. +}
  26814. +
  26815. +/* ---------------------------------------------------------------------- */
  26816. +
  26817. +void au_nwt_init(struct au_nowait_tasks *nwt)
  26818. +{
  26819. + atomic_set(&nwt->nw_len, 0);
  26820. + /* smp_mb(); */ /* atomic_set */
  26821. + init_waitqueue_head(&nwt->nw_wq);
  26822. +}
  26823. +
  26824. +void au_wkq_fin(void)
  26825. +{
  26826. + int i;
  26827. +
  26828. + for (i = 0; i < ARRAY_SIZE(au_wkq); i++)
  26829. + if (au_wkq[i].wkq)
  26830. + destroy_workqueue(au_wkq[i].wkq);
  26831. +}
  26832. +
  26833. +int __init au_wkq_init(void)
  26834. +{
  26835. + int err, i;
  26836. +
  26837. + err = 0;
  26838. + for (i = 0; !err && i < ARRAY_SIZE(au_wkq); i++) {
  26839. + BUILD_BUG_ON(!WQ_RESCUER);
  26840. + au_wkq[i].wkq = alloc_workqueue(au_wkq[i].name, !WQ_RESCUER,
  26841. + WQ_DFL_ACTIVE);
  26842. + if (IS_ERR(au_wkq[i].wkq))
  26843. + err = PTR_ERR(au_wkq[i].wkq);
  26844. + else if (!au_wkq[i].wkq)
  26845. + err = -ENOMEM;
  26846. + if (unlikely(err))
  26847. + au_wkq[i].wkq = NULL;
  26848. + }
  26849. + if (unlikely(err))
  26850. + au_wkq_fin();
  26851. +
  26852. + return err;
  26853. +}
  26854. diff -Nur linux-2.6.37.orig/fs/aufs/wkq.h linux-2.6.37/fs/aufs/wkq.h
  26855. --- linux-2.6.37.orig/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100
  26856. +++ linux-2.6.37/fs/aufs/wkq.h 2011-01-11 20:15:11.000000000 +0100
  26857. @@ -0,0 +1,90 @@
  26858. +/*
  26859. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  26860. + *
  26861. + * This program, aufs is free software; you can redistribute it and/or modify
  26862. + * it under the terms of the GNU General Public License as published by
  26863. + * the Free Software Foundation; either version 2 of the License, or
  26864. + * (at your option) any later version.
  26865. + *
  26866. + * This program is distributed in the hope that it will be useful,
  26867. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  26868. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26869. + * GNU General Public License for more details.
  26870. + *
  26871. + * You should have received a copy of the GNU General Public License
  26872. + * along with this program; if not, write to the Free Software
  26873. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  26874. + */
  26875. +
  26876. +/*
  26877. + * workqueue for asynchronous/super-io operations
  26878. + * todo: try new credentials management scheme
  26879. + */
  26880. +
  26881. +#ifndef __AUFS_WKQ_H__
  26882. +#define __AUFS_WKQ_H__
  26883. +
  26884. +#ifdef __KERNEL__
  26885. +
  26886. +#include <linux/sched.h>
  26887. +#include <linux/wait.h>
  26888. +#include <linux/aufs_type.h>
  26889. +
  26890. +struct super_block;
  26891. +
  26892. +/* ---------------------------------------------------------------------- */
  26893. +
  26894. +/*
  26895. + * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
  26896. + */
  26897. +struct au_nowait_tasks {
  26898. + atomic_t nw_len;
  26899. + wait_queue_head_t nw_wq;
  26900. +};
  26901. +
  26902. +/* ---------------------------------------------------------------------- */
  26903. +
  26904. +typedef void (*au_wkq_func_t)(void *args);
  26905. +
  26906. +/* wkq flags */
  26907. +#define AuWkq_WAIT 1
  26908. +#define AuWkq_PRE (1 << 1)
  26909. +#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name)
  26910. +#define au_fset_wkq(flags, name) \
  26911. + do { (flags) |= AuWkq_##name; } while (0)
  26912. +#define au_fclr_wkq(flags, name) \
  26913. + do { (flags) &= ~AuWkq_##name; } while (0)
  26914. +
  26915. +/* wkq.c */
  26916. +int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args);
  26917. +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb);
  26918. +void au_nwt_init(struct au_nowait_tasks *nwt);
  26919. +int __init au_wkq_init(void);
  26920. +void au_wkq_fin(void);
  26921. +
  26922. +/* ---------------------------------------------------------------------- */
  26923. +
  26924. +static inline int au_wkq_wait_pre(au_wkq_func_t func, void *args)
  26925. +{
  26926. + return au_wkq_do_wait(AuWkq_WAIT | AuWkq_PRE, func, args);
  26927. +}
  26928. +
  26929. +static inline int au_wkq_wait(au_wkq_func_t func, void *args)
  26930. +{
  26931. + return au_wkq_do_wait(AuWkq_WAIT, func, args);
  26932. +}
  26933. +
  26934. +static inline void au_nwt_done(struct au_nowait_tasks *nwt)
  26935. +{
  26936. + if (atomic_dec_and_test(&nwt->nw_len))
  26937. + wake_up_all(&nwt->nw_wq);
  26938. +}
  26939. +
  26940. +static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
  26941. +{
  26942. + wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
  26943. + return 0;
  26944. +}
  26945. +
  26946. +#endif /* __KERNEL__ */
  26947. +#endif /* __AUFS_WKQ_H__ */
  26948. diff -Nur linux-2.6.37.orig/fs/aufs/xino.c linux-2.6.37/fs/aufs/xino.c
  26949. --- linux-2.6.37.orig/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100
  26950. +++ linux-2.6.37/fs/aufs/xino.c 2011-01-11 20:15:11.000000000 +0100
  26951. @@ -0,0 +1,1265 @@
  26952. +/*
  26953. + * Copyright (C) 2005-2011 Junjiro R. Okajima
  26954. + *
  26955. + * This program, aufs is free software; you can redistribute it and/or modify
  26956. + * it under the terms of the GNU General Public License as published by
  26957. + * the Free Software Foundation; either version 2 of the License, or
  26958. + * (at your option) any later version.
  26959. + *
  26960. + * This program is distributed in the hope that it will be useful,
  26961. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  26962. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26963. + * GNU General Public License for more details.
  26964. + *
  26965. + * You should have received a copy of the GNU General Public License
  26966. + * along with this program; if not, write to the Free Software
  26967. + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  26968. + */
  26969. +
  26970. +/*
  26971. + * external inode number translation table and bitmap
  26972. + */
  26973. +
  26974. +#include <linux/file.h>
  26975. +#include <linux/seq_file.h>
  26976. +#include <linux/uaccess.h>
  26977. +#include "aufs.h"
  26978. +
  26979. +ssize_t xino_fread(au_readf_t func, struct file *file, void *kbuf, size_t size,
  26980. + loff_t *pos)
  26981. +{
  26982. + ssize_t err;
  26983. + mm_segment_t oldfs;
  26984. + union {
  26985. + void *k;
  26986. + char __user *u;
  26987. + } buf;
  26988. +
  26989. + buf.k = kbuf;
  26990. + oldfs = get_fs();
  26991. + set_fs(KERNEL_DS);
  26992. + do {
  26993. + /* todo: signal_pending? */
  26994. + err = func(file, buf.u, size, pos);
  26995. + } while (err == -EAGAIN || err == -EINTR);
  26996. + set_fs(oldfs);
  26997. +
  26998. +#if 0 /* reserved for future use */
  26999. + if (err > 0)
  27000. + fsnotify_access(file->f_dentry);
  27001. +#endif
  27002. +
  27003. + return err;
  27004. +}
  27005. +
  27006. +/* ---------------------------------------------------------------------- */
  27007. +
  27008. +static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *kbuf,
  27009. + size_t size, loff_t *pos)
  27010. +{
  27011. + ssize_t err;
  27012. + mm_segment_t oldfs;
  27013. + union {
  27014. + void *k;
  27015. + const char __user *u;
  27016. + } buf;
  27017. +
  27018. + buf.k = kbuf;
  27019. + oldfs = get_fs();
  27020. + set_fs(KERNEL_DS);
  27021. + do {
  27022. + /* todo: signal_pending? */
  27023. + err = func(file, buf.u, size, pos);
  27024. + } while (err == -EAGAIN || err == -EINTR);
  27025. + set_fs(oldfs);
  27026. +
  27027. +#if 0 /* reserved for future use */
  27028. + if (err > 0)
  27029. + fsnotify_modify(file->f_dentry);
  27030. +#endif
  27031. +
  27032. + return err;
  27033. +}
  27034. +
  27035. +struct do_xino_fwrite_args {
  27036. + ssize_t *errp;
  27037. + au_writef_t func;
  27038. + struct file *file;
  27039. + void *buf;
  27040. + size_t size;
  27041. + loff_t *pos;
  27042. +};
  27043. +
  27044. +static void call_do_xino_fwrite(void *args)
  27045. +{
  27046. + struct do_xino_fwrite_args *a = args;
  27047. + *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
  27048. +}
  27049. +
  27050. +ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
  27051. + loff_t *pos)
  27052. +{
  27053. + ssize_t err;
  27054. +
  27055. + /* todo: signal block and no wkq? */
  27056. + if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
  27057. + lockdep_off();
  27058. + err = do_xino_fwrite(func, file, buf, size, pos);
  27059. + lockdep_on();
  27060. + } else {
  27061. + /*
  27062. + * it breaks RLIMIT_FSIZE and normal user's limit,
  27063. + * users should care about quota and real 'filesystem full.'
  27064. + */
  27065. + int wkq_err;
  27066. + struct do_xino_fwrite_args args = {
  27067. + .errp = &err,
  27068. + .func = func,
  27069. + .file = file,
  27070. + .buf = buf,
  27071. + .size = size,
  27072. + .pos = pos
  27073. + };
  27074. +
  27075. + wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
  27076. + if (unlikely(wkq_err))
  27077. + err = wkq_err;
  27078. + }
  27079. +
  27080. + return err;
  27081. +}
  27082. +
  27083. +/* ---------------------------------------------------------------------- */
  27084. +
  27085. +/*
  27086. + * create a new xinofile at the same place/path as @base_file.
  27087. + */
  27088. +struct file *au_xino_create2(struct file *base_file, struct file *copy_src)
  27089. +{
  27090. + struct file *file;
  27091. + struct dentry *base, *parent;
  27092. + struct inode *dir;
  27093. + struct qstr *name;
  27094. + struct path path;
  27095. + int err;
  27096. +
  27097. + base = base_file->f_dentry;
  27098. + parent = base->d_parent; /* dir inode is locked */
  27099. + dir = parent->d_inode;
  27100. + IMustLock(dir);
  27101. +
  27102. + file = ERR_PTR(-EINVAL);
  27103. + name = &base->d_name;
  27104. + path.dentry = vfsub_lookup_one_len(name->name, parent, name->len);
  27105. + if (IS_ERR(path.dentry)) {
  27106. + file = (void *)path.dentry;
  27107. + pr_err("%.*s lookup err %ld\n",
  27108. + AuLNPair(name), PTR_ERR(path.dentry));
  27109. + goto out;
  27110. + }
  27111. +
  27112. + /* no need to mnt_want_write() since we call dentry_open() later */
  27113. + err = vfs_create(dir, path.dentry, S_IRUGO | S_IWUGO, NULL);
  27114. + if (unlikely(err)) {
  27115. + file = ERR_PTR(err);
  27116. + pr_err("%.*s create err %d\n", AuLNPair(name), err);
  27117. + goto out_dput;
  27118. + }
  27119. +
  27120. + path.mnt = base_file->f_vfsmnt;
  27121. + file = vfsub_dentry_open(&path,
  27122. + O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
  27123. + /* | FMODE_NONOTIFY */);
  27124. + if (IS_ERR(file)) {
  27125. + pr_err("%.*s open err %ld\n", AuLNPair(name), PTR_ERR(file));
  27126. + goto out_dput;
  27127. + }
  27128. +
  27129. + err = vfsub_unlink(dir, &file->f_path, /*force*/0);
  27130. + if (unlikely(err)) {
  27131. + pr_err("%.*s unlink err %d\n", AuLNPair(name), err);
  27132. + goto out_fput;
  27133. + }
  27134. +
  27135. + if (copy_src) {
  27136. + /* no one can touch copy_src xino */
  27137. + err = au_copy_file(file, copy_src,
  27138. + i_size_read(copy_src->f_dentry->d_inode));
  27139. + if (unlikely(err)) {
  27140. + pr_err("%.*s copy err %d\n", AuLNPair(name), err);
  27141. + goto out_fput;
  27142. + }
  27143. + }
  27144. + goto out_dput; /* success */
  27145. +
  27146. +out_fput:
  27147. + fput(file);
  27148. + file = ERR_PTR(err);
  27149. +out_dput:
  27150. + dput(path.dentry);
  27151. +out:
  27152. + return file;
  27153. +}
  27154. +
  27155. +struct au_xino_lock_dir {
  27156. + struct au_hinode *hdir;
  27157. + struct dentry *parent;
  27158. + struct mutex *mtx;
  27159. +};
  27160. +
  27161. +static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
  27162. + struct au_xino_lock_dir *ldir)
  27163. +{
  27164. + aufs_bindex_t brid, bindex;
  27165. +
  27166. + ldir->hdir = NULL;
  27167. + bindex = -1;
  27168. + brid = au_xino_brid(sb);
  27169. + if (brid >= 0)
  27170. + bindex = au_br_index(sb, brid);
  27171. + if (bindex >= 0) {
  27172. + ldir->hdir = au_hi(sb->s_root->d_inode, bindex);
  27173. + au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
  27174. + } else {
  27175. + ldir->parent = dget_parent(xino->f_dentry);
  27176. + ldir->mtx = &ldir->parent->d_inode->i_mutex;
  27177. + mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT);
  27178. + }
  27179. +}
  27180. +
  27181. +static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
  27182. +{
  27183. + if (ldir->hdir)
  27184. + au_hn_imtx_unlock(ldir->hdir);
  27185. + else {
  27186. + mutex_unlock(ldir->mtx);
  27187. + dput(ldir->parent);
  27188. + }
  27189. +}
  27190. +
  27191. +/* ---------------------------------------------------------------------- */
  27192. +
  27193. +/* trucate xino files asynchronously */
  27194. +
  27195. +int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex)
  27196. +{
  27197. + int err;
  27198. + aufs_bindex_t bi, bend;
  27199. + struct au_branch *br;
  27200. + struct file *new_xino, *file;
  27201. + struct super_block *h_sb;
  27202. + struct au_xino_lock_dir ldir;
  27203. +
  27204. + err = -EINVAL;
  27205. + bend = au_sbend(sb);
  27206. + if (unlikely(bindex < 0 || bend < bindex))
  27207. + goto out;
  27208. + br = au_sbr(sb, bindex);
  27209. + file = br->br_xino.xi_file;
  27210. + if (!file)
  27211. + goto out;
  27212. +
  27213. + au_xino_lock_dir(sb, file, &ldir);
  27214. + /* mnt_want_write() is unnecessary here */
  27215. + new_xino = au_xino_create2(file, file);
  27216. + au_xino_unlock_dir(&ldir);
  27217. + err = PTR_ERR(new_xino);
  27218. + if (IS_ERR(new_xino))
  27219. + goto out;
  27220. + err = 0;
  27221. + fput(file);
  27222. + br->br_xino.xi_file = new_xino;
  27223. +
  27224. + h_sb = br->br_mnt->mnt_sb;
  27225. + for (bi = 0; bi <= bend; bi++) {
  27226. + if (unlikely(bi == bindex))
  27227. + continue;
  27228. + br = au_sbr(sb, bi);
  27229. + if (br->br_mnt->mnt_sb != h_sb)
  27230. + continue;
  27231. +
  27232. + fput(br->br_xino.xi_file);
  27233. + br->br_xino.xi_file = new_xino;
  27234. + get_file(new_xino);
  27235. + }
  27236. +
  27237. +out:
  27238. + return err;
  27239. +}
  27240. +
  27241. +struct xino_do_trunc_args {
  27242. + struct super_block *sb;
  27243. + struct au_branch *br;
  27244. +};
  27245. +
  27246. +static void xino_do_trunc(void *_args)
  27247. +{
  27248. + struct xino_do_trunc_args *args = _args;
  27249. + struct super_block *sb;
  27250. + struct au_branch *br;
  27251. + struct inode *dir;
  27252. + int err;
  27253. + aufs_bindex_t bindex;
  27254. +
  27255. + err = 0;
  27256. + sb = args->sb;
  27257. + dir = sb->s_root->d_inode;
  27258. + br = args->br;
  27259. +
  27260. + si_noflush_write_lock(sb);
  27261. + ii_read_lock_parent(dir);
  27262. + bindex = au_br_index(sb, br->br_id);
  27263. + err = au_xino_trunc(sb, bindex);
  27264. + if (!err
  27265. + && br->br_xino.xi_file->f_dentry->d_inode->i_blocks
  27266. + >= br->br_xino_upper)
  27267. + br->br_xino_upper += AUFS_XINO_TRUNC_STEP;
  27268. +
  27269. + ii_read_unlock(dir);
  27270. + if (unlikely(err))
  27271. + pr_warning("err b%d, (%d)\n", bindex, err);
  27272. + atomic_dec(&br->br_xino_running);
  27273. + atomic_dec(&br->br_count);
  27274. + si_write_unlock(sb);
  27275. + au_nwt_done(&au_sbi(sb)->si_nowait);
  27276. + kfree(args);
  27277. +}
  27278. +
  27279. +static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
  27280. +{
  27281. + struct xino_do_trunc_args *args;
  27282. + int wkq_err;
  27283. +
  27284. + if (br->br_xino.xi_file->f_dentry->d_inode->i_blocks
  27285. + < br->br_xino_upper)
  27286. + return;
  27287. +
  27288. + if (atomic_inc_return(&br->br_xino_running) > 1)
  27289. + goto out;
  27290. +
  27291. + /* lock and kfree() will be called in trunc_xino() */
  27292. + args = kmalloc(sizeof(*args), GFP_NOFS);
  27293. + if (unlikely(!args)) {
  27294. + AuErr1("no memory\n");
  27295. + goto out_args;
  27296. + }
  27297. +
  27298. + atomic_inc(&br->br_count);
  27299. + args->sb = sb;
  27300. + args->br = br;
  27301. + wkq_err = au_wkq_nowait(xino_do_trunc, args, sb);
  27302. + if (!wkq_err)
  27303. + return; /* success */
  27304. +
  27305. + pr_err("wkq %d\n", wkq_err);
  27306. + atomic_dec(&br->br_count);
  27307. +
  27308. +out_args:
  27309. + kfree(args);
  27310. +out:
  27311. + atomic_dec(&br->br_xino_running);
  27312. +}
  27313. +
  27314. +/* ---------------------------------------------------------------------- */
  27315. +
  27316. +static int au_xino_do_write(au_writef_t write, struct file *file,
  27317. + ino_t h_ino, ino_t ino)
  27318. +{
  27319. + loff_t pos;
  27320. + ssize_t sz;
  27321. +
  27322. + pos = h_ino;
  27323. + if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) {
  27324. + AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
  27325. + return -EFBIG;
  27326. + }
  27327. + pos *= sizeof(ino);
  27328. + sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos);
  27329. + if (sz == sizeof(ino))
  27330. + return 0; /* success */
  27331. +
  27332. + AuIOErr("write failed (%zd)\n", sz);
  27333. + return -EIO;
  27334. +}
  27335. +
  27336. +/*
  27337. + * write @ino to the xinofile for the specified branch{@sb, @bindex}
  27338. + * at the position of @h_ino.
  27339. + * even if @ino is zero, it is written to the xinofile and means no entry.
  27340. + * if the size of the xino file on a specific filesystem exceeds the watermark,
  27341. + * try truncating it.
  27342. + */
  27343. +int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  27344. + ino_t ino)
  27345. +{
  27346. + int err;
  27347. + unsigned int mnt_flags;
  27348. + struct au_branch *br;
  27349. +
  27350. + BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max)
  27351. + || ((loff_t)-1) > 0);
  27352. + SiMustAnyLock(sb);
  27353. +
  27354. + mnt_flags = au_mntflags(sb);
  27355. + if (!au_opt_test(mnt_flags, XINO))
  27356. + return 0;
  27357. +
  27358. + br = au_sbr(sb, bindex);
  27359. + err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
  27360. + h_ino, ino);
  27361. + if (!err) {
  27362. + if (au_opt_test(mnt_flags, TRUNC_XINO)
  27363. + && au_test_fs_trunc_xino(br->br_mnt->mnt_sb))
  27364. + xino_try_trunc(sb, br);
  27365. + return 0; /* success */
  27366. + }
  27367. +
  27368. + AuIOErr("write failed (%d)\n", err);
  27369. + return -EIO;
  27370. +}
  27371. +
  27372. +/* ---------------------------------------------------------------------- */
  27373. +
  27374. +/* aufs inode number bitmap */
  27375. +
  27376. +static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
  27377. +static ino_t xib_calc_ino(unsigned long pindex, int bit)
  27378. +{
  27379. + ino_t ino;
  27380. +
  27381. + AuDebugOn(bit < 0 || page_bits <= bit);
  27382. + ino = AUFS_FIRST_INO + pindex * page_bits + bit;
  27383. + return ino;
  27384. +}
  27385. +
  27386. +static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
  27387. +{
  27388. + AuDebugOn(ino < AUFS_FIRST_INO);
  27389. + ino -= AUFS_FIRST_INO;
  27390. + *pindex = ino / page_bits;
  27391. + *bit = ino % page_bits;
  27392. +}
  27393. +
  27394. +static int xib_pindex(struct super_block *sb, unsigned long pindex)
  27395. +{
  27396. + int err;
  27397. + loff_t pos;
  27398. + ssize_t sz;
  27399. + struct au_sbinfo *sbinfo;
  27400. + struct file *xib;
  27401. + unsigned long *p;
  27402. +
  27403. + sbinfo = au_sbi(sb);
  27404. + MtxMustLock(&sbinfo->si_xib_mtx);
  27405. + AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
  27406. + || !au_opt_test(sbinfo->si_mntflags, XINO));
  27407. +
  27408. + if (pindex == sbinfo->si_xib_last_pindex)
  27409. + return 0;
  27410. +
  27411. + xib = sbinfo->si_xib;
  27412. + p = sbinfo->si_xib_buf;
  27413. + pos = sbinfo->si_xib_last_pindex;
  27414. + pos *= PAGE_SIZE;
  27415. + sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
  27416. + if (unlikely(sz != PAGE_SIZE))
  27417. + goto out;
  27418. +
  27419. + pos = pindex;
  27420. + pos *= PAGE_SIZE;
  27421. + if (i_size_read(xib->f_dentry->d_inode) >= pos + PAGE_SIZE)
  27422. + sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
  27423. + else {
  27424. + memset(p, 0, PAGE_SIZE);
  27425. + sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
  27426. + }
  27427. + if (sz == PAGE_SIZE) {
  27428. + sbinfo->si_xib_last_pindex = pindex;
  27429. + return 0; /* success */
  27430. + }
  27431. +
  27432. +out:
  27433. + AuIOErr1("write failed (%zd)\n", sz);
  27434. + err = sz;
  27435. + if (sz >= 0)
  27436. + err = -EIO;
  27437. + return err;
  27438. +}
  27439. +
  27440. +/* ---------------------------------------------------------------------- */
  27441. +
  27442. +static void au_xib_clear_bit(struct inode *inode)
  27443. +{
  27444. + int err, bit;
  27445. + unsigned long pindex;
  27446. + struct super_block *sb;
  27447. + struct au_sbinfo *sbinfo;
  27448. +
  27449. + AuDebugOn(inode->i_nlink);
  27450. +
  27451. + sb = inode->i_sb;
  27452. + xib_calc_bit(inode->i_ino, &pindex, &bit);
  27453. + AuDebugOn(page_bits <= bit);
  27454. + sbinfo = au_sbi(sb);
  27455. + mutex_lock(&sbinfo->si_xib_mtx);
  27456. + err = xib_pindex(sb, pindex);
  27457. + if (!err) {
  27458. + clear_bit(bit, sbinfo->si_xib_buf);
  27459. + sbinfo->si_xib_next_bit = bit;
  27460. + }
  27461. + mutex_unlock(&sbinfo->si_xib_mtx);
  27462. +}
  27463. +
  27464. +/* for s_op->delete_inode() */
  27465. +void au_xino_delete_inode(struct inode *inode, const int unlinked)
  27466. +{
  27467. + int err;
  27468. + unsigned int mnt_flags;
  27469. + aufs_bindex_t bindex, bend, bi;
  27470. + unsigned char try_trunc;
  27471. + struct au_iinfo *iinfo;
  27472. + struct super_block *sb;
  27473. + struct au_hinode *hi;
  27474. + struct inode *h_inode;
  27475. + struct au_branch *br;
  27476. + au_writef_t xwrite;
  27477. +
  27478. + sb = inode->i_sb;
  27479. + mnt_flags = au_mntflags(sb);
  27480. + if (!au_opt_test(mnt_flags, XINO)
  27481. + || inode->i_ino == AUFS_ROOT_INO)
  27482. + return;
  27483. +
  27484. + if (unlinked) {
  27485. + au_xigen_inc(inode);
  27486. + au_xib_clear_bit(inode);
  27487. + }
  27488. +
  27489. + iinfo = au_ii(inode);
  27490. + if (!iinfo)
  27491. + return;
  27492. +
  27493. + bindex = iinfo->ii_bstart;
  27494. + if (bindex < 0)
  27495. + return;
  27496. +
  27497. + xwrite = au_sbi(sb)->si_xwrite;
  27498. + try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO);
  27499. + hi = iinfo->ii_hinode + bindex;
  27500. + bend = iinfo->ii_bend;
  27501. + for (; bindex <= bend; bindex++, hi++) {
  27502. + h_inode = hi->hi_inode;
  27503. + if (!h_inode
  27504. + || (!unlinked && h_inode->i_nlink))
  27505. + continue;
  27506. +
  27507. + /* inode may not be revalidated */
  27508. + bi = au_br_index(sb, hi->hi_id);
  27509. + if (bi < 0)
  27510. + continue;
  27511. +
  27512. + br = au_sbr(sb, bi);
  27513. + err = au_xino_do_write(xwrite, br->br_xino.xi_file,
  27514. + h_inode->i_ino, /*ino*/0);
  27515. + if (!err && try_trunc
  27516. + && au_test_fs_trunc_xino(br->br_mnt->mnt_sb))
  27517. + xino_try_trunc(sb, br);
  27518. + }
  27519. +}
  27520. +
  27521. +/* get an unused inode number from bitmap */
  27522. +ino_t au_xino_new_ino(struct super_block *sb)
  27523. +{
  27524. + ino_t ino;
  27525. + unsigned long *p, pindex, ul, pend;
  27526. + struct au_sbinfo *sbinfo;
  27527. + struct file *file;
  27528. + int free_bit, err;
  27529. +
  27530. + if (!au_opt_test(au_mntflags(sb), XINO))
  27531. + return iunique(sb, AUFS_FIRST_INO);
  27532. +
  27533. + sbinfo = au_sbi(sb);
  27534. + mutex_lock(&sbinfo->si_xib_mtx);
  27535. + p = sbinfo->si_xib_buf;
  27536. + free_bit = sbinfo->si_xib_next_bit;
  27537. + if (free_bit < page_bits && !test_bit(free_bit, p))
  27538. + goto out; /* success */
  27539. + free_bit = find_first_zero_bit(p, page_bits);
  27540. + if (free_bit < page_bits)
  27541. + goto out; /* success */
  27542. +
  27543. + pindex = sbinfo->si_xib_last_pindex;
  27544. + for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
  27545. + err = xib_pindex(sb, ul);
  27546. + if (unlikely(err))
  27547. + goto out_err;
  27548. + free_bit = find_first_zero_bit(p, page_bits);
  27549. + if (free_bit < page_bits)
  27550. + goto out; /* success */
  27551. + }
  27552. +
  27553. + file = sbinfo->si_xib;
  27554. + pend = i_size_read(file->f_dentry->d_inode) / PAGE_SIZE;
  27555. + for (ul = pindex + 1; ul <= pend; ul++) {
  27556. + err = xib_pindex(sb, ul);
  27557. + if (unlikely(err))
  27558. + goto out_err;
  27559. + free_bit = find_first_zero_bit(p, page_bits);
  27560. + if (free_bit < page_bits)
  27561. + goto out; /* success */
  27562. + }
  27563. + BUG();
  27564. +
  27565. +out:
  27566. + set_bit(free_bit, p);
  27567. + sbinfo->si_xib_next_bit = free_bit + 1;
  27568. + pindex = sbinfo->si_xib_last_pindex;
  27569. + mutex_unlock(&sbinfo->si_xib_mtx);
  27570. + ino = xib_calc_ino(pindex, free_bit);
  27571. + AuDbg("i%lu\n", (unsigned long)ino);
  27572. + return ino;
  27573. +out_err:
  27574. + mutex_unlock(&sbinfo->si_xib_mtx);
  27575. + AuDbg("i0\n");
  27576. + return 0;
  27577. +}
  27578. +
  27579. +/*
  27580. + * read @ino from xinofile for the specified branch{@sb, @bindex}
  27581. + * at the position of @h_ino.
  27582. + * if @ino does not exist and @do_new is true, get new one.
  27583. + */
  27584. +int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
  27585. + ino_t *ino)
  27586. +{
  27587. + int err;
  27588. + ssize_t sz;
  27589. + loff_t pos;
  27590. + struct file *file;
  27591. + struct au_sbinfo *sbinfo;
  27592. +
  27593. + *ino = 0;
  27594. + if (!au_opt_test(au_mntflags(sb), XINO))
  27595. + return 0; /* no xino */
  27596. +
  27597. + err = 0;
  27598. + sbinfo = au_sbi(sb);
  27599. + pos = h_ino;
  27600. + if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) {
  27601. + AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
  27602. + return -EFBIG;
  27603. + }
  27604. + pos *= sizeof(*ino);
  27605. +
  27606. + file = au_sbr(sb, bindex)->br_xino.xi_file;
  27607. + if (i_size_read(file->f_dentry->d_inode) < pos + sizeof(*ino))
  27608. + return 0; /* no ino */
  27609. +
  27610. + sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos);
  27611. + if (sz == sizeof(*ino))
  27612. + return 0; /* success */
  27613. +
  27614. + err = sz;
  27615. + if (unlikely(sz >= 0)) {
  27616. + err = -EIO;
  27617. + AuIOErr("xino read error (%zd)\n", sz);
  27618. + }
  27619. +
  27620. + return err;
  27621. +}
  27622. +
  27623. +/* ---------------------------------------------------------------------- */
  27624. +
  27625. +/* create and set a new xino file */
  27626. +
  27627. +struct file *au_xino_create(struct super_block *sb, char *fname, int silent)
  27628. +{
  27629. + struct file *file;
  27630. + struct dentry *h_parent, *d;
  27631. + struct inode *h_dir;
  27632. + int err;
  27633. +
  27634. + /*
  27635. + * at mount-time, and the xino file is the default path,
  27636. + * hnotify is disabled so we have no notify events to ignore.
  27637. + * when a user specified the xino, we cannot get au_hdir to be ignored.
  27638. + */
  27639. + file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
  27640. + /* | FMODE_NONOTIFY */,
  27641. + S_IRUGO | S_IWUGO);
  27642. + if (IS_ERR(file)) {
  27643. + if (!silent)
  27644. + pr_err("open %s(%ld)\n", fname, PTR_ERR(file));
  27645. + return file;
  27646. + }
  27647. +
  27648. + /* keep file count */
  27649. + h_parent = dget_parent(file->f_dentry);
  27650. + h_dir = h_parent->d_inode;
  27651. + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
  27652. + /* mnt_want_write() is unnecessary here */
  27653. + err = vfsub_unlink(h_dir, &file->f_path, /*force*/0);
  27654. + mutex_unlock(&h_dir->i_mutex);
  27655. + dput(h_parent);
  27656. + if (unlikely(err)) {
  27657. + if (!silent)
  27658. + pr_err("unlink %s(%d)\n", fname, err);
  27659. + goto out;
  27660. + }
  27661. +
  27662. + err = -EINVAL;
  27663. + d = file->f_dentry;
  27664. + if (unlikely(sb == d->d_sb)) {
  27665. + if (!silent)
  27666. + pr_err("%s must be outside\n", fname);
  27667. + goto out;
  27668. + }
  27669. + if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
  27670. + if (!silent)
  27671. + pr_err("xino doesn't support %s(%s)\n",
  27672. + fname, au_sbtype(d->d_sb));
  27673. + goto out;
  27674. + }
  27675. + return file; /* success */
  27676. +
  27677. +out:
  27678. + fput(file);
  27679. + file = ERR_PTR(err);
  27680. + return file;
  27681. +}
  27682. +
  27683. +/*
  27684. + * find another branch who is on the same filesystem of the specified
  27685. + * branch{@btgt}. search until @bend.
  27686. + */
  27687. +static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
  27688. + aufs_bindex_t bend)
  27689. +{
  27690. + aufs_bindex_t bindex;
  27691. + struct super_block *tgt_sb = au_sbr_sb(sb, btgt);
  27692. +
  27693. + for (bindex = 0; bindex < btgt; bindex++)
  27694. + if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
  27695. + return bindex;
  27696. + for (bindex++; bindex <= bend; bindex++)
  27697. + if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
  27698. + return bindex;
  27699. + return -1;
  27700. +}
  27701. +
  27702. +/* ---------------------------------------------------------------------- */
  27703. +
  27704. +/*
  27705. + * initialize the xinofile for the specified branch @br
  27706. + * at the place/path where @base_file indicates.
  27707. + * test whether another branch is on the same filesystem or not,
  27708. + * if @do_test is true.
  27709. + */
  27710. +int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
  27711. + struct file *base_file, int do_test)
  27712. +{
  27713. + int err;
  27714. + ino_t ino;
  27715. + aufs_bindex_t bend, bindex;
  27716. + struct au_branch *shared_br, *b;
  27717. + struct file *file;
  27718. + struct super_block *tgt_sb;
  27719. +
  27720. + shared_br = NULL;
  27721. + bend = au_sbend(sb);
  27722. + if (do_test) {
  27723. + tgt_sb = br->br_mnt->mnt_sb;
  27724. + for (bindex = 0; bindex <= bend; bindex++) {
  27725. + b = au_sbr(sb, bindex);
  27726. + if (tgt_sb == b->br_mnt->mnt_sb) {
  27727. + shared_br = b;
  27728. + break;
  27729. + }
  27730. + }
  27731. + }
  27732. +
  27733. + if (!shared_br || !shared_br->br_xino.xi_file) {
  27734. + struct au_xino_lock_dir ldir;
  27735. +
  27736. + au_xino_lock_dir(sb, base_file, &ldir);
  27737. + /* mnt_want_write() is unnecessary here */
  27738. + file = au_xino_create2(base_file, NULL);
  27739. + au_xino_unlock_dir(&ldir);
  27740. + err = PTR_ERR(file);
  27741. + if (IS_ERR(file))
  27742. + goto out;
  27743. + br->br_xino.xi_file = file;
  27744. + } else {
  27745. + br->br_xino.xi_file = shared_br->br_xino.xi_file;
  27746. + get_file(br->br_xino.xi_file);
  27747. + }
  27748. +
  27749. + ino = AUFS_ROOT_INO;
  27750. + err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
  27751. + h_ino, ino);
  27752. + if (unlikely(err)) {
  27753. + fput(br->br_xino.xi_file);
  27754. + br->br_xino.xi_file = NULL;
  27755. + }
  27756. +
  27757. +out:
  27758. + return err;
  27759. +}
  27760. +
  27761. +/* ---------------------------------------------------------------------- */
  27762. +
  27763. +/* trucate a xino bitmap file */
  27764. +
  27765. +/* todo: slow */
  27766. +static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
  27767. +{
  27768. + int err, bit;
  27769. + ssize_t sz;
  27770. + unsigned long pindex;
  27771. + loff_t pos, pend;
  27772. + struct au_sbinfo *sbinfo;
  27773. + au_readf_t func;
  27774. + ino_t *ino;
  27775. + unsigned long *p;
  27776. +
  27777. + err = 0;
  27778. + sbinfo = au_sbi(sb);
  27779. + MtxMustLock(&sbinfo->si_xib_mtx);
  27780. + p = sbinfo->si_xib_buf;
  27781. + func = sbinfo->si_xread;
  27782. + pend = i_size_read(file->f_dentry->d_inode);
  27783. + pos = 0;
  27784. + while (pos < pend) {
  27785. + sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
  27786. + err = sz;
  27787. + if (unlikely(sz <= 0))
  27788. + goto out;
  27789. +
  27790. + err = 0;
  27791. + for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
  27792. + if (unlikely(*ino < AUFS_FIRST_INO))
  27793. + continue;
  27794. +
  27795. + xib_calc_bit(*ino, &pindex, &bit);
  27796. + AuDebugOn(page_bits <= bit);
  27797. + err = xib_pindex(sb, pindex);
  27798. + if (!err)
  27799. + set_bit(bit, p);
  27800. + else
  27801. + goto out;
  27802. + }
  27803. + }
  27804. +
  27805. +out:
  27806. + return err;
  27807. +}
  27808. +
  27809. +static int xib_restore(struct super_block *sb)
  27810. +{
  27811. + int err;
  27812. + aufs_bindex_t bindex, bend;
  27813. + void *page;
  27814. +
  27815. + err = -ENOMEM;
  27816. + page = (void *)__get_free_page(GFP_NOFS);
  27817. + if (unlikely(!page))
  27818. + goto out;
  27819. +
  27820. + err = 0;
  27821. + bend = au_sbend(sb);
  27822. + for (bindex = 0; !err && bindex <= bend; bindex++)
  27823. + if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0)
  27824. + err = do_xib_restore
  27825. + (sb, au_sbr(sb, bindex)->br_xino.xi_file, page);
  27826. + else
  27827. + AuDbg("b%d\n", bindex);
  27828. + free_page((unsigned long)page);
  27829. +
  27830. +out:
  27831. + return err;
  27832. +}
  27833. +
  27834. +int au_xib_trunc(struct super_block *sb)
  27835. +{
  27836. + int err;
  27837. + ssize_t sz;
  27838. + loff_t pos;
  27839. + struct au_xino_lock_dir ldir;
  27840. + struct au_sbinfo *sbinfo;
  27841. + unsigned long *p;
  27842. + struct file *file;
  27843. +
  27844. + SiMustWriteLock(sb);
  27845. +
  27846. + err = 0;
  27847. + sbinfo = au_sbi(sb);
  27848. + if (!au_opt_test(sbinfo->si_mntflags, XINO))
  27849. + goto out;
  27850. +
  27851. + file = sbinfo->si_xib;
  27852. + if (i_size_read(file->f_dentry->d_inode) <= PAGE_SIZE)
  27853. + goto out;
  27854. +
  27855. + au_xino_lock_dir(sb, file, &ldir);
  27856. + /* mnt_want_write() is unnecessary here */
  27857. + file = au_xino_create2(sbinfo->si_xib, NULL);
  27858. + au_xino_unlock_dir(&ldir);
  27859. + err = PTR_ERR(file);
  27860. + if (IS_ERR(file))
  27861. + goto out;
  27862. + fput(sbinfo->si_xib);
  27863. + sbinfo->si_xib = file;
  27864. +
  27865. + p = sbinfo->si_xib_buf;
  27866. + memset(p, 0, PAGE_SIZE);
  27867. + pos = 0;
  27868. + sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
  27869. + if (unlikely(sz != PAGE_SIZE)) {
  27870. + err = sz;
  27871. + AuIOErr("err %d\n", err);
  27872. + if (sz >= 0)
  27873. + err = -EIO;
  27874. + goto out;
  27875. + }
  27876. +
  27877. + mutex_lock(&sbinfo->si_xib_mtx);
  27878. + /* mnt_want_write() is unnecessary here */
  27879. + err = xib_restore(sb);
  27880. + mutex_unlock(&sbinfo->si_xib_mtx);
  27881. +
  27882. +out:
  27883. + return err;
  27884. +}
  27885. +
  27886. +/* ---------------------------------------------------------------------- */
  27887. +
  27888. +/*
  27889. + * xino mount option handlers
  27890. + */
  27891. +static au_readf_t find_readf(struct file *h_file)
  27892. +{
  27893. + const struct file_operations *fop = h_file->f_op;
  27894. +
  27895. + if (fop) {
  27896. + if (fop->read)
  27897. + return fop->read;
  27898. + if (fop->aio_read)
  27899. + return do_sync_read;
  27900. + }
  27901. + return ERR_PTR(-ENOSYS);
  27902. +}
  27903. +
  27904. +static au_writef_t find_writef(struct file *h_file)
  27905. +{
  27906. + const struct file_operations *fop = h_file->f_op;
  27907. +
  27908. + if (fop) {
  27909. + if (fop->write)
  27910. + return fop->write;
  27911. + if (fop->aio_write)
  27912. + return do_sync_write;
  27913. + }
  27914. + return ERR_PTR(-ENOSYS);
  27915. +}
  27916. +
  27917. +/* xino bitmap */
  27918. +static void xino_clear_xib(struct super_block *sb)
  27919. +{
  27920. + struct au_sbinfo *sbinfo;
  27921. +
  27922. + SiMustWriteLock(sb);
  27923. +
  27924. + sbinfo = au_sbi(sb);
  27925. + sbinfo->si_xread = NULL;
  27926. + sbinfo->si_xwrite = NULL;
  27927. + if (sbinfo->si_xib)
  27928. + fput(sbinfo->si_xib);
  27929. + sbinfo->si_xib = NULL;
  27930. + free_page((unsigned long)sbinfo->si_xib_buf);
  27931. + sbinfo->si_xib_buf = NULL;
  27932. +}
  27933. +
  27934. +static int au_xino_set_xib(struct super_block *sb, struct file *base)
  27935. +{
  27936. + int err;
  27937. + loff_t pos;
  27938. + struct au_sbinfo *sbinfo;
  27939. + struct file *file;
  27940. +
  27941. + SiMustWriteLock(sb);
  27942. +
  27943. + sbinfo = au_sbi(sb);
  27944. + file = au_xino_create2(base, sbinfo->si_xib);
  27945. + err = PTR_ERR(file);
  27946. + if (IS_ERR(file))
  27947. + goto out;
  27948. + if (sbinfo->si_xib)
  27949. + fput(sbinfo->si_xib);
  27950. + sbinfo->si_xib = file;
  27951. + sbinfo->si_xread = find_readf(file);
  27952. + sbinfo->si_xwrite = find_writef(file);
  27953. +
  27954. + err = -ENOMEM;
  27955. + if (!sbinfo->si_xib_buf)
  27956. + sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
  27957. + if (unlikely(!sbinfo->si_xib_buf))
  27958. + goto out_unset;
  27959. +
  27960. + sbinfo->si_xib_last_pindex = 0;
  27961. + sbinfo->si_xib_next_bit = 0;
  27962. + if (i_size_read(file->f_dentry->d_inode) < PAGE_SIZE) {
  27963. + pos = 0;
  27964. + err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
  27965. + PAGE_SIZE, &pos);
  27966. + if (unlikely(err != PAGE_SIZE))
  27967. + goto out_free;
  27968. + }
  27969. + err = 0;
  27970. + goto out; /* success */
  27971. +
  27972. +out_free:
  27973. + free_page((unsigned long)sbinfo->si_xib_buf);
  27974. + sbinfo->si_xib_buf = NULL;
  27975. + if (err >= 0)
  27976. + err = -EIO;
  27977. +out_unset:
  27978. + fput(sbinfo->si_xib);
  27979. + sbinfo->si_xib = NULL;
  27980. + sbinfo->si_xread = NULL;
  27981. + sbinfo->si_xwrite = NULL;
  27982. +out:
  27983. + return err;
  27984. +}
  27985. +
  27986. +/* xino for each branch */
  27987. +static void xino_clear_br(struct super_block *sb)
  27988. +{
  27989. + aufs_bindex_t bindex, bend;
  27990. + struct au_branch *br;
  27991. +
  27992. + bend = au_sbend(sb);
  27993. + for (bindex = 0; bindex <= bend; bindex++) {
  27994. + br = au_sbr(sb, bindex);
  27995. + if (!br || !br->br_xino.xi_file)
  27996. + continue;
  27997. +
  27998. + fput(br->br_xino.xi_file);
  27999. + br->br_xino.xi_file = NULL;
  28000. + }
  28001. +}
  28002. +
  28003. +static int au_xino_set_br(struct super_block *sb, struct file *base)
  28004. +{
  28005. + int err;
  28006. + ino_t ino;
  28007. + aufs_bindex_t bindex, bend, bshared;
  28008. + struct {
  28009. + struct file *old, *new;
  28010. + } *fpair, *p;
  28011. + struct au_branch *br;
  28012. + struct inode *inode;
  28013. + au_writef_t writef;
  28014. +
  28015. + SiMustWriteLock(sb);
  28016. +
  28017. + err = -ENOMEM;
  28018. + bend = au_sbend(sb);
  28019. + fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS);
  28020. + if (unlikely(!fpair))
  28021. + goto out;
  28022. +
  28023. + inode = sb->s_root->d_inode;
  28024. + ino = AUFS_ROOT_INO;
  28025. + writef = au_sbi(sb)->si_xwrite;
  28026. + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
  28027. + br = au_sbr(sb, bindex);
  28028. + bshared = is_sb_shared(sb, bindex, bindex - 1);
  28029. + if (bshared >= 0) {
  28030. + /* shared xino */
  28031. + *p = fpair[bshared];
  28032. + get_file(p->new);
  28033. + }
  28034. +
  28035. + if (!p->new) {
  28036. + /* new xino */
  28037. + p->old = br->br_xino.xi_file;
  28038. + p->new = au_xino_create2(base, br->br_xino.xi_file);
  28039. + err = PTR_ERR(p->new);
  28040. + if (IS_ERR(p->new)) {
  28041. + p->new = NULL;
  28042. + goto out_pair;
  28043. + }
  28044. + }
  28045. +
  28046. + err = au_xino_do_write(writef, p->new,
  28047. + au_h_iptr(inode, bindex)->i_ino, ino);
  28048. + if (unlikely(err))
  28049. + goto out_pair;
  28050. + }
  28051. +
  28052. + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
  28053. + br = au_sbr(sb, bindex);
  28054. + if (br->br_xino.xi_file)
  28055. + fput(br->br_xino.xi_file);
  28056. + get_file(p->new);
  28057. + br->br_xino.xi_file = p->new;
  28058. + }
  28059. +
  28060. +out_pair:
  28061. + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++)
  28062. + if (p->new)
  28063. + fput(p->new);
  28064. + else
  28065. + break;
  28066. + kfree(fpair);
  28067. +out:
  28068. + return err;
  28069. +}
  28070. +
  28071. +void au_xino_clr(struct super_block *sb)
  28072. +{
  28073. + struct au_sbinfo *sbinfo;
  28074. +
  28075. + au_xigen_clr(sb);
  28076. + xino_clear_xib(sb);
  28077. + xino_clear_br(sb);
  28078. + sbinfo = au_sbi(sb);
  28079. + /* lvalue, do not call au_mntflags() */
  28080. + au_opt_clr(sbinfo->si_mntflags, XINO);
  28081. +}
  28082. +
  28083. +int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount)
  28084. +{
  28085. + int err, skip;
  28086. + struct dentry *parent, *cur_parent;
  28087. + struct qstr *dname, *cur_name;
  28088. + struct file *cur_xino;
  28089. + struct inode *dir;
  28090. + struct au_sbinfo *sbinfo;
  28091. +
  28092. + SiMustWriteLock(sb);
  28093. +
  28094. + err = 0;
  28095. + sbinfo = au_sbi(sb);
  28096. + parent = dget_parent(xino->file->f_dentry);
  28097. + if (remount) {
  28098. + skip = 0;
  28099. + dname = &xino->file->f_dentry->d_name;
  28100. + cur_xino = sbinfo->si_xib;
  28101. + if (cur_xino) {
  28102. + cur_parent = dget_parent(cur_xino->f_dentry);
  28103. + cur_name = &cur_xino->f_dentry->d_name;
  28104. + skip = (cur_parent == parent
  28105. + && dname->len == cur_name->len
  28106. + && !memcmp(dname->name, cur_name->name,
  28107. + dname->len));
  28108. + dput(cur_parent);
  28109. + }
  28110. + if (skip)
  28111. + goto out;
  28112. + }
  28113. +
  28114. + au_opt_set(sbinfo->si_mntflags, XINO);
  28115. + dir = parent->d_inode;
  28116. + mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT);
  28117. + /* mnt_want_write() is unnecessary here */
  28118. + err = au_xino_set_xib(sb, xino->file);
  28119. + if (!err)
  28120. + err = au_xigen_set(sb, xino->file);
  28121. + if (!err)
  28122. + err = au_xino_set_br(sb, xino->file);
  28123. + mutex_unlock(&dir->i_mutex);
  28124. + if (!err)
  28125. + goto out; /* success */
  28126. +
  28127. + /* reset all */
  28128. + AuIOErr("failed creating xino(%d).\n", err);
  28129. +
  28130. +out:
  28131. + dput(parent);
  28132. + return err;
  28133. +}
  28134. +
  28135. +/* ---------------------------------------------------------------------- */
  28136. +
  28137. +/*
  28138. + * create a xinofile at the default place/path.
  28139. + */
  28140. +struct file *au_xino_def(struct super_block *sb)
  28141. +{
  28142. + struct file *file;
  28143. + char *page, *p;
  28144. + struct au_branch *br;
  28145. + struct super_block *h_sb;
  28146. + struct path path;
  28147. + aufs_bindex_t bend, bindex, bwr;
  28148. +
  28149. + br = NULL;
  28150. + bend = au_sbend(sb);
  28151. + bwr = -1;
  28152. + for (bindex = 0; bindex <= bend; bindex++) {
  28153. + br = au_sbr(sb, bindex);
  28154. + if (au_br_writable(br->br_perm)
  28155. + && !au_test_fs_bad_xino(br->br_mnt->mnt_sb)) {
  28156. + bwr = bindex;
  28157. + break;
  28158. + }
  28159. + }
  28160. +
  28161. + if (bwr >= 0) {
  28162. + file = ERR_PTR(-ENOMEM);
  28163. + page = __getname_gfp(GFP_NOFS);
  28164. + if (unlikely(!page))
  28165. + goto out;
  28166. + path.mnt = br->br_mnt;
  28167. + path.dentry = au_h_dptr(sb->s_root, bwr);
  28168. + p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
  28169. + file = (void *)p;
  28170. + if (!IS_ERR(p)) {
  28171. + strcat(p, "/" AUFS_XINO_FNAME);
  28172. + AuDbg("%s\n", p);
  28173. + file = au_xino_create(sb, p, /*silent*/0);
  28174. + if (!IS_ERR(file))
  28175. + au_xino_brid_set(sb, br->br_id);
  28176. + }
  28177. + __putname(page);
  28178. + } else {
  28179. + file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
  28180. + if (IS_ERR(file))
  28181. + goto out;
  28182. + h_sb = file->f_dentry->d_sb;
  28183. + if (unlikely(au_test_fs_bad_xino(h_sb))) {
  28184. + pr_err("xino doesn't support %s(%s)\n",
  28185. + AUFS_XINO_DEFPATH, au_sbtype(h_sb));
  28186. + fput(file);
  28187. + file = ERR_PTR(-EINVAL);
  28188. + }
  28189. + if (!IS_ERR(file))
  28190. + au_xino_brid_set(sb, -1);
  28191. + }
  28192. +
  28193. +out:
  28194. + return file;
  28195. +}
  28196. +
  28197. +/* ---------------------------------------------------------------------- */
  28198. +
  28199. +int au_xino_path(struct seq_file *seq, struct file *file)
  28200. +{
  28201. + int err;
  28202. +
  28203. + err = au_seq_path(seq, &file->f_path);
  28204. + if (unlikely(err < 0))
  28205. + goto out;
  28206. +
  28207. + err = 0;
  28208. +#define Deleted "\\040(deleted)"
  28209. + seq->count -= sizeof(Deleted) - 1;
  28210. + AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
  28211. + sizeof(Deleted) - 1));
  28212. +#undef Deleted
  28213. +
  28214. +out:
  28215. + return err;
  28216. +}
  28217. diff -Nur linux-2.6.37.orig/fs/file_table.c linux-2.6.37/fs/file_table.c
  28218. --- linux-2.6.37.orig/fs/file_table.c 2011-01-05 01:50:19.000000000 +0100
  28219. +++ linux-2.6.37/fs/file_table.c 2011-01-11 20:15:11.000000000 +0100
  28220. @@ -393,6 +393,8 @@
  28221. }
  28222. }
  28223. +EXPORT_SYMBOL(file_sb_list_del);
  28224. +
  28225. #ifdef CONFIG_SMP
  28226. /*
  28227. diff -Nur linux-2.6.37.orig/fs/inode.c linux-2.6.37/fs/inode.c
  28228. --- linux-2.6.37.orig/fs/inode.c 2011-01-05 01:50:19.000000000 +0100
  28229. +++ linux-2.6.37/fs/inode.c 2011-01-11 20:15:11.000000000 +0100
  28230. @@ -82,6 +82,7 @@
  28231. * the i_state of an inode while it is in use..
  28232. */
  28233. DEFINE_SPINLOCK(inode_lock);
  28234. +EXPORT_SYMBOL(inode_lock);
  28235. /*
  28236. * iprune_sem provides exclusion between the kswapd or try_to_free_pages
  28237. diff -Nur linux-2.6.37.orig/fs/namei.c linux-2.6.37/fs/namei.c
  28238. --- linux-2.6.37.orig/fs/namei.c 2011-01-05 01:50:19.000000000 +0100
  28239. +++ linux-2.6.37/fs/namei.c 2011-01-11 20:15:11.000000000 +0100
  28240. @@ -347,6 +347,7 @@
  28241. return 0;
  28242. }
  28243. +EXPORT_SYMBOL(deny_write_access);
  28244. /**
  28245. * path_get - get a reference to a path
  28246. @@ -1161,12 +1162,13 @@
  28247. * needs parent already locked. Doesn't follow mounts.
  28248. * SMP-safe.
  28249. */
  28250. -static struct dentry *lookup_hash(struct nameidata *nd)
  28251. +struct dentry *lookup_hash(struct nameidata *nd)
  28252. {
  28253. return __lookup_hash(&nd->last, nd->path.dentry, nd);
  28254. }
  28255. +EXPORT_SYMBOL(lookup_hash);
  28256. -static int __lookup_one_len(const char *name, struct qstr *this,
  28257. +int __lookup_one_len(const char *name, struct qstr *this,
  28258. struct dentry *base, int len)
  28259. {
  28260. unsigned long hash;
  28261. @@ -1187,6 +1189,7 @@
  28262. this->hash = end_name_hash(hash);
  28263. return 0;
  28264. }
  28265. +EXPORT_SYMBOL(__lookup_one_len);
  28266. /**
  28267. * lookup_one_len - filesystem helper to lookup single pathname component
  28268. diff -Nur linux-2.6.37.orig/fs/namespace.c linux-2.6.37/fs/namespace.c
  28269. --- linux-2.6.37.orig/fs/namespace.c 2011-01-05 01:50:19.000000000 +0100
  28270. +++ linux-2.6.37/fs/namespace.c 2011-01-11 20:15:13.000000000 +0100
  28271. @@ -1321,6 +1321,7 @@
  28272. }
  28273. return 0;
  28274. }
  28275. +EXPORT_SYMBOL(iterate_mounts);
  28276. static void cleanup_group_ids(struct vfsmount *mnt, struct vfsmount *end)
  28277. {
  28278. diff -Nur linux-2.6.37.orig/fs/notify/group.c linux-2.6.37/fs/notify/group.c
  28279. --- linux-2.6.37.orig/fs/notify/group.c 2011-01-05 01:50:19.000000000 +0100
  28280. +++ linux-2.6.37/fs/notify/group.c 2011-01-11 20:15:13.000000000 +0100
  28281. @@ -22,6 +22,7 @@
  28282. #include <linux/srcu.h>
  28283. #include <linux/rculist.h>
  28284. #include <linux/wait.h>
  28285. +#include <linux/module.h>
  28286. #include <linux/fsnotify_backend.h>
  28287. #include "fsnotify.h"
  28288. @@ -70,6 +71,7 @@
  28289. if (atomic_dec_and_test(&group->refcnt))
  28290. fsnotify_destroy_group(group);
  28291. }
  28292. +EXPORT_SYMBOL(fsnotify_put_group);
  28293. /*
  28294. * Create a new fsnotify_group and hold a reference for the group returned.
  28295. @@ -102,3 +104,4 @@
  28296. return group;
  28297. }
  28298. +EXPORT_SYMBOL(fsnotify_alloc_group);
  28299. diff -Nur linux-2.6.37.orig/fs/notify/mark.c linux-2.6.37/fs/notify/mark.c
  28300. --- linux-2.6.37.orig/fs/notify/mark.c 2011-01-05 01:50:19.000000000 +0100
  28301. +++ linux-2.6.37/fs/notify/mark.c 2011-01-11 20:15:13.000000000 +0100
  28302. @@ -113,6 +113,7 @@
  28303. if (atomic_dec_and_test(&mark->refcnt))
  28304. mark->free_mark(mark);
  28305. }
  28306. +EXPORT_SYMBOL(fsnotify_put_mark);
  28307. /*
  28308. * Any time a mark is getting freed we end up here.
  28309. @@ -190,6 +191,7 @@
  28310. if (unlikely(atomic_dec_and_test(&group->num_marks)))
  28311. fsnotify_final_destroy_group(group);
  28312. }
  28313. +EXPORT_SYMBOL(fsnotify_destroy_mark);
  28314. void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask)
  28315. {
  28316. @@ -277,6 +279,7 @@
  28317. return ret;
  28318. }
  28319. +EXPORT_SYMBOL(fsnotify_add_mark);
  28320. /*
  28321. * clear any marks in a group in which mark->flags & flags is true
  28322. @@ -332,6 +335,7 @@
  28323. atomic_set(&mark->refcnt, 1);
  28324. mark->free_mark = free_mark;
  28325. }
  28326. +EXPORT_SYMBOL(fsnotify_init_mark);
  28327. static int fsnotify_mark_destroy(void *ignored)
  28328. {
  28329. diff -Nur linux-2.6.37.orig/fs/open.c linux-2.6.37/fs/open.c
  28330. --- linux-2.6.37.orig/fs/open.c 2011-01-05 01:50:19.000000000 +0100
  28331. +++ linux-2.6.37/fs/open.c 2011-01-11 20:15:13.000000000 +0100
  28332. @@ -60,6 +60,7 @@
  28333. mutex_unlock(&dentry->d_inode->i_mutex);
  28334. return ret;
  28335. }
  28336. +EXPORT_SYMBOL(do_truncate);
  28337. static long do_sys_truncate(const char __user *pathname, loff_t length)
  28338. {
  28339. diff -Nur linux-2.6.37.orig/fs/splice.c linux-2.6.37/fs/splice.c
  28340. --- linux-2.6.37.orig/fs/splice.c 2011-01-05 01:50:19.000000000 +0100
  28341. +++ linux-2.6.37/fs/splice.c 2011-01-11 20:15:13.000000000 +0100
  28342. @@ -1092,8 +1092,8 @@
  28343. /*
  28344. * Attempt to initiate a splice from pipe to file.
  28345. */
  28346. -static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  28347. - loff_t *ppos, size_t len, unsigned int flags)
  28348. +long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  28349. + loff_t *ppos, size_t len, unsigned int flags)
  28350. {
  28351. ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
  28352. loff_t *, size_t, unsigned int);
  28353. @@ -1116,13 +1116,14 @@
  28354. return splice_write(pipe, out, ppos, len, flags);
  28355. }
  28356. +EXPORT_SYMBOL(do_splice_from);
  28357. /*
  28358. * Attempt to initiate a splice from a file to a pipe.
  28359. */
  28360. -static long do_splice_to(struct file *in, loff_t *ppos,
  28361. - struct pipe_inode_info *pipe, size_t len,
  28362. - unsigned int flags)
  28363. +long do_splice_to(struct file *in, loff_t *ppos,
  28364. + struct pipe_inode_info *pipe, size_t len,
  28365. + unsigned int flags)
  28366. {
  28367. ssize_t (*splice_read)(struct file *, loff_t *,
  28368. struct pipe_inode_info *, size_t, unsigned int);
  28369. @@ -1142,6 +1143,7 @@
  28370. return splice_read(in, ppos, pipe, len, flags);
  28371. }
  28372. +EXPORT_SYMBOL(do_splice_to);
  28373. /**
  28374. * splice_direct_to_actor - splices data directly between two non-pipes
  28375. diff -Nur linux-2.6.37.orig/security/commoncap.c linux-2.6.37/security/commoncap.c
  28376. --- linux-2.6.37.orig/security/commoncap.c 2011-01-05 01:50:19.000000000 +0100
  28377. +++ linux-2.6.37/security/commoncap.c 2011-01-11 20:15:13.000000000 +0100
  28378. @@ -929,3 +929,4 @@
  28379. }
  28380. return ret;
  28381. }
  28382. +EXPORT_SYMBOL(cap_file_mmap);
  28383. diff -Nur linux-2.6.37.orig/security/device_cgroup.c linux-2.6.37/security/device_cgroup.c
  28384. --- linux-2.6.37.orig/security/device_cgroup.c 2011-01-05 01:50:19.000000000 +0100
  28385. +++ linux-2.6.37/security/device_cgroup.c 2011-01-11 20:15:13.000000000 +0100
  28386. @@ -515,6 +515,7 @@
  28387. return -EPERM;
  28388. }
  28389. +EXPORT_SYMBOL(devcgroup_inode_permission);
  28390. int devcgroup_inode_mknod(int mode, dev_t dev)
  28391. {
  28392. diff -Nur linux-2.6.37.orig/security/security.c linux-2.6.37/security/security.c
  28393. --- linux-2.6.37.orig/security/security.c 2011-01-05 01:50:19.000000000 +0100
  28394. +++ linux-2.6.37/security/security.c 2011-01-11 20:15:13.000000000 +0100
  28395. @@ -360,6 +360,7 @@
  28396. return 0;
  28397. return security_ops->path_mkdir(dir, dentry, mode);
  28398. }
  28399. +EXPORT_SYMBOL(security_path_mkdir);
  28400. int security_path_rmdir(struct path *dir, struct dentry *dentry)
  28401. {
  28402. @@ -367,6 +368,7 @@
  28403. return 0;
  28404. return security_ops->path_rmdir(dir, dentry);
  28405. }
  28406. +EXPORT_SYMBOL(security_path_rmdir);
  28407. int security_path_unlink(struct path *dir, struct dentry *dentry)
  28408. {
  28409. @@ -374,6 +376,7 @@
  28410. return 0;
  28411. return security_ops->path_unlink(dir, dentry);
  28412. }
  28413. +EXPORT_SYMBOL(security_path_unlink);
  28414. int security_path_symlink(struct path *dir, struct dentry *dentry,
  28415. const char *old_name)
  28416. @@ -382,6 +385,7 @@
  28417. return 0;
  28418. return security_ops->path_symlink(dir, dentry, old_name);
  28419. }
  28420. +EXPORT_SYMBOL(security_path_symlink);
  28421. int security_path_link(struct dentry *old_dentry, struct path *new_dir,
  28422. struct dentry *new_dentry)
  28423. @@ -390,6 +394,7 @@
  28424. return 0;
  28425. return security_ops->path_link(old_dentry, new_dir, new_dentry);
  28426. }
  28427. +EXPORT_SYMBOL(security_path_link);
  28428. int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
  28429. struct path *new_dir, struct dentry *new_dentry)
  28430. @@ -400,6 +405,7 @@
  28431. return security_ops->path_rename(old_dir, old_dentry, new_dir,
  28432. new_dentry);
  28433. }
  28434. +EXPORT_SYMBOL(security_path_rename);
  28435. int security_path_truncate(struct path *path)
  28436. {
  28437. @@ -407,6 +413,7 @@
  28438. return 0;
  28439. return security_ops->path_truncate(path);
  28440. }
  28441. +EXPORT_SYMBOL(security_path_truncate);
  28442. int security_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
  28443. mode_t mode)
  28444. @@ -415,6 +422,7 @@
  28445. return 0;
  28446. return security_ops->path_chmod(dentry, mnt, mode);
  28447. }
  28448. +EXPORT_SYMBOL(security_path_chmod);
  28449. int security_path_chown(struct path *path, uid_t uid, gid_t gid)
  28450. {
  28451. @@ -422,6 +430,7 @@
  28452. return 0;
  28453. return security_ops->path_chown(path, uid, gid);
  28454. }
  28455. +EXPORT_SYMBOL(security_path_chown);
  28456. int security_path_chroot(struct path *path)
  28457. {
  28458. @@ -498,6 +507,7 @@
  28459. return 0;
  28460. return security_ops->inode_readlink(dentry);
  28461. }
  28462. +EXPORT_SYMBOL(security_inode_readlink);
  28463. int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
  28464. {
  28465. @@ -512,6 +522,7 @@
  28466. return 0;
  28467. return security_ops->inode_permission(inode, mask);
  28468. }
  28469. +EXPORT_SYMBOL(security_inode_permission);
  28470. int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
  28471. {
  28472. @@ -611,6 +622,7 @@
  28473. return fsnotify_perm(file, mask);
  28474. }
  28475. +EXPORT_SYMBOL(security_file_permission);
  28476. int security_file_alloc(struct file *file)
  28477. {
  28478. @@ -638,6 +650,7 @@
  28479. return ret;
  28480. return ima_file_mmap(file, prot);
  28481. }
  28482. +EXPORT_SYMBOL(security_file_mmap);
  28483. int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
  28484. unsigned long prot)