aufs2.patch 831 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176291772917829179291802918129182291832918429185291862918729188291892919029191291922919329194291952919629197291982919929200292012920229203292042920529206292072920829209292102921129212292132921429215292162921729218292192922029221292222922329224292252922629227292282922929230292312923229233292342923529236292372923829239292402924129242292432924429245292462924729248292492925029251292522925329254292552925629257292582925929260292612926229263292642926529266292672926829269292702927129272292732927429275292762927729278292792928029281292822928329284292852928629287292882928929290292912929229293292942929529296292972929829299293002930129302293032930429305293062930729308293092931029311293122931329314293152931629317293182931929320293212932229323293242932529326293272932829329293302933129332293332933429335293362933729338293392934029341293422934329344293452934629347293482934929350293512935229353293542935529356293572935829359293602936129362293632936429365293662936729368293692937029371293722937329374293752937629377293782937929380293812938229383293842938529386293872938829389293902939129392293932939429395293962939729398293992940029401294022940329404294052940629407294082940929410294112941229413294142941529416294172941829419294202942129422294232942429425294262942729428294292943029431294322943329434294352943629437294382943929440294412944229443294442944529446294472944829449294502945129452294532945429455294562945729458294592946029461294622946329464294652946629467294682946929470294712947229473294742947529476294772947829479294802948129482294832948429485294862948729488294892949029491294922949329494294952949629497294982949929500295012950229503295042950529506295072950829509295102951129512295132951429515295162951729518295192952029521295222952329524295252952629527295282952929530295312953229533295342953529536295372953829539295402954129542295432954429545295462954729548295492955029551295522955329554295552955629557295582955929560295612956229563295642956529566295672956829569295702957129572295732957429575295762957729578295792958029581295822958329584295852958629587295882958929590295912959229593295942959529596295972959829599296002960129602296032960429605296062960729608296092961029611296122961329614296152961629617296182961929620296212962229623296242962529626296272962829629296302963129632296332963429635296362963729638296392964029641296422964329644296452964629647296482964929650296512965229653296542965529656296572965829659296602966129662296632966429665296662966729668296692967029671296722967329674296752967629677296782967929680296812968229683296842968529686296872968829689296902969129692296932969429695296962969729698296992970029701297022970329704297052970629707297082970929710297112971229713297142971529716297172971829719297202972129722297232972429725297262972729728297292973029731297322973329734297352973629737297382973929740297412974229743297442974529746297472974829749297502975129752297532975429755297562975729758297592976029761297622976329764297652976629767297682976929770297712977229773297742977529776297772977829779297802978129782297832978429785297862978729788297892979029791297922979329794297952979629797297982979929800298012980229803298042980529806298072980829809298102981129812298132981429815298162981729818298192982029821298222982329824298252982629827298282982929830298312983229833298342983529836298372983829839298402984129842298432984429845298462984729848298492985029851298522985329854298552985629857298582985929860298612986229863298642986529866298672986829869298702987129872298732987429875298762987729878298792988029881298822988329884298852988629887298882988929890298912989229893298942989529896298972989829899299002990129902299032990429905299062990729908299092991029911299122991329914299152991629917299182991929920299212992229923299242992529926299272992829929299302993129932299332993429935299362993729938299392994029941299422994329944299452994629947299482994929950299512995229953299542995529956299572995829959299602996129962299632996429965299662996729968299692997029971299722997329974299752997629977299782997929980299812998229983299842998529986299872998829989299902999129992299932999429995299962999729998299993000030001300023000330004300053000630007300083000930010300113001230013300143001530016300173001830019300203002130022300233002430025300263002730028300293003030031300323003330034300353003630037300383003930040300413004230043300443004530046300473004830049300503005130052300533005430055300563005730058300593006030061300623006330064300653006630067300683006930070300713007230073300743007530076300773007830079300803008130082300833008430085300863008730088300893009030091300923009330094300953009630097300983009930100301013010230103301043010530106301073010830109301103011130112301133011430115301163011730118301193012030121301223012330124301253012630127301283012930130301313013230133301343013530136301373013830139301403014130142301433014430145301463014730148301493015030151301523015330154301553015630157301583015930160301613016230163301643016530166301673016830169301703017130172301733017430175301763017730178301793018030181301823018330184301853018630187301883018930190301913019230193301943019530196301973019830199302003020130202302033020430205302063020730208302093021030211302123021330214302153021630217302183021930220302213022230223302243022530226302273022830229302303023130232302333023430235302363023730238302393024030241302423024330244302453024630247302483024930250302513025230253302543025530256302573025830259302603026130262302633026430265302663026730268302693027030271302723027330274302753027630277302783027930280302813028230283302843028530286302873028830289302903029130292302933029430295302963029730298302993030030301303023030330304303053030630307303083030930310303113031230313303143031530316303173031830319303203032130322303233032430325303263032730328303293033030331303323033330334303353033630337303383033930340303413034230343303443034530346303473034830349303503035130352303533035430355303563035730358303593036030361303623036330364303653036630367303683036930370303713037230373303743037530376303773037830379303803038130382303833038430385303863038730388303893039030391303923039330394303953039630397303983039930400304013040230403304043040530406304073040830409304103041130412304133041430415304163041730418304193042030421304223042330424304253042630427304283042930430304313043230433304343043530436304373043830439304403044130442304433044430445304463044730448304493045030451304523045330454304553045630457304583045930460304613046230463304643046530466304673046830469304703047130472304733047430475304763047730478304793048030481304823048330484304853048630487304883048930490304913049230493304943049530496304973049830499305003050130502305033050430505305063050730508305093051030511305123051330514305153051630517305183051930520305213052230523305243052530526305273052830529305303053130532305333053430535305363053730538305393054030541305423054330544305453054630547305483054930550305513055230553305543055530556305573055830559305603056130562305633056430565305663056730568305693057030571305723057330574305753057630577305783057930580305813058230583305843058530586305873058830589305903059130592305933059430595305963059730598305993060030601306023060330604306053060630607306083060930610306113061230613306143061530616306173061830619306203062130622306233062430625306263062730628306293063030631306323063330634306353063630637306383063930640306413064230643306443064530646306473064830649306503065130652306533065430655306563065730658306593066030661306623066330664306653066630667306683066930670306713067230673306743067530676306773067830679306803068130682306833068430685306863068730688306893069030691306923069330694306953069630697306983069930700307013070230703307043070530706307073070830709307103071130712307133071430715307163071730718307193072030721307223072330724307253072630727307283072930730307313073230733307343073530736307373073830739307403074130742307433074430745307463074730748307493075030751307523075330754307553075630757307583075930760307613076230763307643076530766307673076830769307703077130772307733077430775307763077730778307793078030781307823078330784307853078630787307883078930790307913079230793307943079530796307973079830799308003080130802308033080430805308063080730808308093081030811308123081330814308153081630817308183081930820308213082230823308243082530826308273082830829308303083130832308333083430835308363083730838308393084030841308423084330844308453084630847308483084930850308513085230853308543085530856308573085830859308603086130862308633086430865308663086730868308693087030871308723087330874308753087630877308783087930880308813088230883308843088530886308873088830889308903089130892308933089430895308963089730898308993090030901309023090330904309053090630907309083090930910309113091230913309143091530916309173091830919309203092130922309233092430925309263092730928309293093030931309323093330934309353093630937309383093930940309413094230943309443094530946309473094830949309503095130952309533095430955309563095730958309593096030961309623096330964309653096630967309683096930970309713097230973309743097530976309773097830979309803098130982309833098430985309863098730988309893099030991309923099330994309953099630997309983099931000310013100231003310043100531006310073100831009310103101131012310133101431015310163101731018310193102031021310223102331024310253102631027310283102931030310313103231033310343103531036310373103831039310403104131042310433104431045310463104731048310493105031051310523105331054310553105631057310583105931060310613106231063310643106531066310673106831069310703107131072310733107431075310763107731078310793108031081310823108331084310853108631087310883108931090310913109231093310943109531096310973109831099311003110131102311033110431105311063110731108311093111031111311123111331114311153111631117311183111931120311213112231123311243112531126311273112831129311303113131132311333113431135311363113731138311393114031141311423114331144311453114631147311483114931150311513115231153311543115531156311573115831159311603116131162311633116431165311663116731168311693117031171311723117331174311753117631177311783117931180311813118231183311843118531186311873118831189311903119131192311933119431195311963119731198311993120031201312023120331204312053120631207312083120931210312113121231213312143121531216312173121831219312203122131222312233122431225312263122731228312293123031231312323123331234312353123631237312383123931240312413124231243312443124531246312473124831249312503125131252312533125431255312563125731258312593126031261312623126331264312653126631267312683126931270312713127231273312743127531276312773127831279312803128131282312833128431285312863128731288312893129031291312923129331294312953129631297312983129931300313013130231303313043130531306313073130831309313103131131312313133131431315313163131731318313193132031321313223132331324313253132631327313283132931330313313133231333313343133531336313373133831339313403134131342313433134431345313463134731348313493135031351313523135331354313553135631357313583135931360313613136231363313643136531366313673136831369313703137131372313733137431375313763137731378313793138031381313823138331384313853138631387313883138931390313913139231393313943139531396313973139831399314003140131402314033140431405314063140731408314093141031411314123141331414314153141631417314183141931420314213142231423314243142531426314273142831429314303143131432314333143431435314363143731438314393144031441314423144331444314453144631447314483144931450314513145231453314543145531456314573145831459314603146131462314633146431465314663146731468314693147031471314723147331474314753147631477314783147931480314813148231483314843148531486314873148831489314903149131492314933149431495314963149731498314993150031501315023150331504315053150631507315083150931510315113151231513315143151531516315173151831519315203152131522315233152431525315263152731528315293153031531315323153331534315353153631537315383153931540315413154231543315443154531546315473154831549315503155131552315533155431555315563155731558315593156031561315623156331564315653156631567315683156931570315713157231573315743157531576315773157831579315803158131582315833158431585315863158731588315893159031591315923159331594315953159631597315983159931600316013160231603316043160531606316073160831609316103161131612316133161431615316163161731618316193162031621316223162331624316253162631627316283162931630316313163231633316343163531636316373163831639316403164131642316433164431645316463164731648316493165031651316523165331654316553165631657316583165931660316613166231663316643166531666316673166831669316703167131672316733167431675316763167731678316793168031681316823168331684316853168631687316883168931690316913169231693316943169531696316973169831699317003170131702317033170431705317063170731708317093171031711317123171331714317153171631717317183171931720317213172231723317243172531726317273172831729317303173131732317333173431735317363173731738317393174031741317423174331744317453174631747317483174931750317513175231753317543175531756317573175831759317603176131762317633176431765317663176731768317693177031771317723177331774317753177631777317783177931780317813178231783317843178531786317873178831789317903179131792317933179431795317963179731798317993180031801318023180331804318053180631807318083180931810318113181231813318143181531816318173181831819318203182131822318233182431825318263182731828318293183031831318323183331834318353183631837318383183931840318413184231843318443184531846318473184831849318503185131852318533185431855318563185731858318593186031861318623186331864318653186631867318683186931870318713187231873318743187531876318773187831879318803188131882318833188431885318863188731888318893189031891318923189331894318953189631897318983189931900319013190231903319043190531906319073190831909319103191131912319133191431915319163191731918319193192031921319223192331924319253192631927319283192931930319313193231933319343193531936319373193831939319403194131942319433194431945319463194731948319493195031951319523195331954319553195631957319583195931960319613196231963319643196531966319673196831969319703197131972319733197431975319763197731978319793198031981319823198331984319853198631987319883198931990319913199231993319943199531996319973199831999320003200132002320033200432005320063200732008320093201032011320123201332014320153201632017320183201932020320213202232023320243202532026320273202832029320303203132032320333203432035320363203732038320393204032041320423204332044320453204632047320483204932050320513205232053320543205532056320573205832059320603206132062320633206432065320663206732068320693207032071320723207332074320753207632077320783207932080320813208232083320843208532086320873208832089320903209132092320933209432095320963209732098320993210032101321023210332104321053210632107321083210932110321113211232113321143211532116321173211832119321203212132122321233212432125321263212732128321293213032131321323213332134321353213632137321383213932140321413214232143321443214532146321473214832149321503215132152321533215432155321563215732158321593216032161321623216332164321653216632167321683216932170321713217232173321743217532176321773217832179321803218132182321833218432185321863218732188321893219032191321923219332194321953219632197321983219932200322013220232203322043220532206322073220832209322103221132212322133221432215322163221732218322193222032221322223222332224322253222632227322283222932230322313223232233322343223532236322373223832239322403224132242322433224432245322463224732248322493225032251322523225332254322553225632257322583225932260322613226232263322643226532266322673226832269322703227132272322733227432275322763227732278322793228032281322823228332284322853228632287322883228932290322913229232293322943229532296322973229832299323003230132302323033230432305323063230732308323093231032311323123231332314323153231632317323183231932320323213232232323323243232532326323273232832329323303233132332323333233432335323363233732338323393234032341323423234332344323453234632347323483234932350323513235232353323543235532356323573235832359323603236132362323633236432365323663236732368323693237032371323723237332374323753237632377323783237932380323813238232383323843238532386323873238832389323903239132392323933239432395323963239732398323993240032401324023240332404324053240632407324083240932410324113241232413324143241532416324173241832419324203242132422324233242432425324263242732428324293243032431324323243332434324353243632437324383243932440324413244232443324443244532446324473244832449324503245132452324533245432455324563245732458324593246032461324623246332464324653246632467324683246932470324713247232473324743247532476324773247832479324803248132482324833248432485324863248732488324893249032491324923249332494324953249632497324983249932500325013250232503325043250532506325073250832509325103251132512325133251432515325163251732518325193252032521325223252332524325253252632527325283252932530325313253232533325343253532536325373253832539325403254132542325433254432545325463254732548325493255032551325523255332554325553255632557325583255932560325613256232563325643256532566325673256832569325703257132572325733257432575325763257732578325793258032581325823258332584325853258632587325883258932590325913259232593325943259532596325973259832599326003260132602326033260432605326063260732608326093261032611326123261332614326153261632617326183261932620326213262232623326243262532626326273262832629326303263132632326333263432635326363263732638326393264032641326423264332644326453264632647326483264932650326513265232653326543265532656326573265832659326603266132662326633266432665326663266732668326693267032671326723267332674326753267632677326783267932680326813268232683326843268532686326873268832689326903269132692326933269432695326963269732698326993270032701327023270332704327053270632707327083270932710327113271232713327143271532716327173271832719327203272132722327233272432725327263272732728327293273032731327323273332734327353273632737327383273932740327413274232743327443274532746327473274832749327503275132752327533275432755327563275732758327593276032761327623276332764327653276632767327683276932770327713277232773327743277532776327773277832779327803278132782327833278432785327863278732788327893279032791327923279332794327953279632797327983279932800328013280232803328043280532806328073280832809328103281132812328133281432815328163281732818328193282032821328223282332824328253282632827328283282932830328313283232833328343283532836328373283832839328403284132842328433284432845328463284732848328493285032851328523285332854328553285632857328583285932860328613286232863328643286532866328673286832869328703287132872328733287432875328763287732878328793288032881328823288332884328853288632887328883288932890328913289232893328943289532896328973289832899329003290132902329033290432905329063290732908329093291032911329123291332914329153291632917329183291932920329213292232923329243292532926329273292832929329303293132932329333293432935329363293732938329393294032941329423294332944329453294632947329483294932950329513295232953329543295532956329573295832959329603296132962329633296432965329663296732968329693297032971329723297332974329753297632977329783297932980329813298232983329843298532986329873298832989329903299132992329933299432995329963299732998329993300033001330023300333004330053300633007330083300933010330113301233013330143301533016330173301833019330203302133022330233302433025330263302733028330293303033031330323303333034330353303633037330383303933040330413304233043330443304533046330473304833049330503305133052330533305433055330563305733058330593306033061330623306333064330653306633067330683306933070330713307233073330743307533076330773307833079330803308133082330833308433085330863308733088330893309033091330923309333094330953309633097330983309933100331013310233103331043310533106331073310833109331103311133112331133311433115331163311733118331193312033121331223312333124331253312633127331283312933130331313313233133331343313533136331373313833139331403314133142331433314433145331463314733148331493315033151331523315333154331553315633157331583315933160331613316233163331643316533166331673316833169331703317133172331733317433175331763317733178331793318033181331823318333184331853318633187331883318933190331913319233193331943319533196331973319833199332003320133202332033320433205332063320733208332093321033211332123321333214332153321633217332183321933220332213322233223332243322533226332273322833229332303323133232332333323433235332363323733238332393324033241332423324333244332453324633247332483324933250332513325233253332543325533256332573325833259332603326133262332633326433265332663326733268332693327033271332723327333274332753327633277332783327933280332813328233283332843328533286332873328833289332903329133292332933329433295332963329733298332993330033301333023330333304333053330633307333083330933310333113331233313333143331533316333173331833319333203332133322333233332433325333263332733328333293333033331333323333333334333353333633337333383333933340333413334233343333443334533346333473334833349333503335133352333533335433355333563335733358333593336033361333623336333364333653336633367333683336933370333713337233373333743337533376333773337833379333803338133382333833338433385333863338733388333893339033391333923339333394333953339633397333983339933400334013340233403334043340533406334073340833409334103341133412334133341433415334163341733418334193342033421334223342333424334253342633427334283342933430334313343233433334343343533436334373343833439334403344133442334433344433445334463344733448334493345033451334523345333454334553345633457334583345933460334613346233463334643346533466334673346833469334703347133472334733347433475334763347733478334793348033481334823348333484334853348633487334883348933490334913349233493334943349533496334973349833499335003350133502335033350433505335063350733508335093351033511335123351333514335153351633517335183351933520335213352233523335243352533526335273352833529335303353133532
  1. diff -Nur linux-2.6.36.orig/fs/Kconfig linux-2.6.36/fs/Kconfig
  2. --- linux-2.6.36.orig/fs/Kconfig 2010-10-20 22:30:22.000000000 +0200
  3. +++ linux-2.6.36/fs/Kconfig 2011-01-10 19:52:38.000000000 +0100
  4. @@ -189,6 +189,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.36.orig/fs/Makefile linux-2.6.36/fs/Makefile
  11. --- linux-2.6.36.orig/fs/Makefile 2010-10-20 22:30:22.000000000 +0200
  12. +++ linux-2.6.36/fs/Makefile 2011-01-10 19:52:38.000000000 +0100
  13. @@ -126,3 +126,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.36.orig/fs/aufs/Kconfig linux-2.6.36/fs/aufs/Kconfig
  19. --- linux-2.6.36.orig/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100
  20. +++ linux-2.6.36/fs/aufs/Kconfig 2011-01-10 19:24:41.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.36.orig/fs/aufs/Makefile linux-2.6.36/fs/aufs/Makefile
  203. --- linux-2.6.36.orig/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100
  204. +++ linux-2.6.36/fs/aufs/Makefile 2011-01-10 19:24:41.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.36.orig/fs/aufs/aufs.h linux-2.6.36/fs/aufs/aufs.h
  245. --- linux-2.6.36.orig/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100
  246. +++ linux-2.6.36/fs/aufs/aufs.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/branch.c linux-2.6.36/fs/aufs/branch.c
  310. --- linux-2.6.36.orig/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100
  311. +++ linux-2.6.36/fs/aufs/branch.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/branch.h linux-2.6.36/fs/aufs/branch.h
  1385. --- linux-2.6.36.orig/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100
  1386. +++ linux-2.6.36/fs/aufs/branch.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/conf.mk linux-2.6.36/fs/aufs/conf.mk
  1618. --- linux-2.6.36.orig/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100
  1619. +++ linux-2.6.36/fs/aufs/conf.mk 2011-01-10 19:24:41.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.36.orig/fs/aufs/cpup.c linux-2.6.36/fs/aufs/cpup.c
  1659. --- linux-2.6.36.orig/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
  1660. +++ linux-2.6.36/fs/aufs/cpup.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/cpup.h linux-2.6.36/fs/aufs/cpup.h
  2726. --- linux-2.6.36.orig/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100
  2727. +++ linux-2.6.36/fs/aufs/cpup.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/dbgaufs.c linux-2.6.36/fs/aufs/dbgaufs.c
  2813. --- linux-2.6.36.orig/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
  2814. +++ linux-2.6.36/fs/aufs/dbgaufs.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/dbgaufs.h linux-2.6.36/fs/aufs/dbgaufs.h
  3151. --- linux-2.6.36.orig/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
  3152. +++ linux-2.6.36/fs/aufs/dbgaufs.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/dcsub.c linux-2.6.36/fs/aufs/dcsub.c
  3207. --- linux-2.6.36.orig/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100
  3208. +++ linux-2.6.36/fs/aufs/dcsub.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/dcsub.h linux-2.6.36/fs/aufs/dcsub.h
  3421. --- linux-2.6.36.orig/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100
  3422. +++ linux-2.6.36/fs/aufs/dcsub.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/debug.c linux-2.6.36/fs/aufs/debug.c
  3525. --- linux-2.6.36.orig/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
  3526. +++ linux-2.6.36/fs/aufs/debug.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/debug.h linux-2.6.36/fs/aufs/debug.h
  3997. --- linux-2.6.36.orig/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100
  3998. +++ linux-2.6.36/fs/aufs/debug.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/dentry.c linux-2.6.36/fs/aufs/dentry.c
  4246. --- linux-2.6.36.orig/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100
  4247. +++ linux-2.6.36/fs/aufs/dentry.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/dentry.h linux-2.6.36/fs/aufs/dentry.h
  5381. --- linux-2.6.36.orig/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
  5382. +++ linux-2.6.36/fs/aufs/dentry.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/dinfo.c linux-2.6.36/fs/aufs/dinfo.c
  5622. --- linux-2.6.36.orig/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100
  5623. +++ linux-2.6.36/fs/aufs/dinfo.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/dir.c linux-2.6.36/fs/aufs/dir.c
  6120. --- linux-2.6.36.orig/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
  6121. +++ linux-2.6.36/fs/aufs/dir.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/dir.h linux-2.6.36/fs/aufs/dir.h
  6772. --- linux-2.6.36.orig/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100
  6773. +++ linux-2.6.36/fs/aufs/dir.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/dynop.c linux-2.6.36/fs/aufs/dynop.c
  6914. --- linux-2.6.36.orig/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100
  6915. +++ linux-2.6.36/fs/aufs/dynop.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/dynop.h linux-2.6.36/fs/aufs/dynop.h
  7343. --- linux-2.6.36.orig/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100
  7344. +++ linux-2.6.36/fs/aufs/dynop.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/export.c linux-2.6.36/fs/aufs/export.c
  7436. --- linux-2.6.36.orig/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
  7437. +++ linux-2.6.36/fs/aufs/export.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/f_op.c linux-2.6.36/fs/aufs/f_op.c
  8238. --- linux-2.6.36.orig/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100
  8239. +++ linux-2.6.36/fs/aufs/f_op.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/f_op_sp.c linux-2.6.36/fs/aufs/f_op_sp.c
  9148. --- linux-2.6.36.orig/fs/aufs/f_op_sp.c 1970-01-01 01:00:00.000000000 +0100
  9149. +++ linux-2.6.36/fs/aufs/f_op_sp.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/file.c linux-2.6.36/fs/aufs/file.c
  9451. --- linux-2.6.36.orig/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
  9452. +++ linux-2.6.36/fs/aufs/file.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/file.h linux-2.6.36/fs/aufs/file.h
  10131. --- linux-2.6.36.orig/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100
  10132. +++ linux-2.6.36/fs/aufs/file.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/finfo.c linux-2.6.36/fs/aufs/finfo.c
  10373. --- linux-2.6.36.orig/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100
  10374. +++ linux-2.6.36/fs/aufs/finfo.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/fstype.h linux-2.6.36/fs/aufs/fstype.h
  10551. --- linux-2.6.36.orig/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100
  10552. +++ linux-2.6.36/fs/aufs/fstype.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/hfsnotify.c linux-2.6.36/fs/aufs/hfsnotify.c
  11052. --- linux-2.6.36.orig/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100
  11053. +++ linux-2.6.36/fs/aufs/hfsnotify.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/hfsplus.c linux-2.6.36/fs/aufs/hfsplus.c
  11303. --- linux-2.6.36.orig/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100
  11304. +++ linux-2.6.36/fs/aufs/hfsplus.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/hnotify.c linux-2.6.36/fs/aufs/hnotify.c
  11365. --- linux-2.6.36.orig/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100
  11366. +++ linux-2.6.36/fs/aufs/hnotify.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/i_op.c linux-2.6.36/fs/aufs/i_op.c
  12063. --- linux-2.6.36.orig/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
  12064. +++ linux-2.6.36/fs/aufs/i_op.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/i_op_add.c linux-2.6.36/fs/aufs/i_op_add.c
  13038. --- linux-2.6.36.orig/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
  13039. +++ linux-2.6.36/fs/aufs/i_op_add.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/i_op_del.c linux-2.6.36/fs/aufs/i_op_del.c
  13744. --- linux-2.6.36.orig/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
  13745. +++ linux-2.6.36/fs/aufs/i_op_del.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/i_op_ren.c linux-2.6.36/fs/aufs/i_op_ren.c
  14229. --- linux-2.6.36.orig/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
  14230. +++ linux-2.6.36/fs/aufs/i_op_ren.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/iinfo.c linux-2.6.36/fs/aufs/iinfo.c
  15250. --- linux-2.6.36.orig/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100
  15251. +++ linux-2.6.36/fs/aufs/iinfo.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/inode.c linux-2.6.36/fs/aufs/inode.c
  15517. --- linux-2.6.36.orig/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100
  15518. +++ linux-2.6.36/fs/aufs/inode.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/inode.h linux-2.6.36/fs/aufs/inode.h
  15992. --- linux-2.6.36.orig/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
  15993. +++ linux-2.6.36/fs/aufs/inode.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/ioctl.c linux-2.6.36/fs/aufs/ioctl.c
  16542. --- linux-2.6.36.orig/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100
  16543. +++ linux-2.6.36/fs/aufs/ioctl.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/loop.c linux-2.6.36/fs/aufs/loop.c
  16696. --- linux-2.6.36.orig/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100
  16697. +++ linux-2.6.36/fs/aufs/loop.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/loop.h linux-2.6.36/fs/aufs/loop.h
  16763. --- linux-2.6.36.orig/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
  16764. +++ linux-2.6.36/fs/aufs/loop.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/magic.mk linux-2.6.36/fs/aufs/magic.mk
  16809. --- linux-2.6.36.orig/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100
  16810. +++ linux-2.6.36/fs/aufs/magic.mk 2011-01-10 19:24:41.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.36.orig/fs/aufs/module.c linux-2.6.36/fs/aufs/module.c
  16867. --- linux-2.6.36.orig/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100
  16868. +++ linux-2.6.36/fs/aufs/module.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/module.h linux-2.6.36/fs/aufs/module.h
  17053. --- linux-2.6.36.orig/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100
  17054. +++ linux-2.6.36/fs/aufs/module.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/mtx.h linux-2.6.36/fs/aufs/mtx.h
  17148. --- linux-2.6.36.orig/fs/aufs/mtx.h 1970-01-01 01:00:00.000000000 +0100
  17149. +++ linux-2.6.36/fs/aufs/mtx.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/opts.c linux-2.6.36/fs/aufs/opts.c
  17200. --- linux-2.6.36.orig/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100
  17201. +++ linux-2.6.36/fs/aufs/opts.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/opts.h linux-2.6.36/fs/aufs/opts.h
  18799. --- linux-2.6.36.orig/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100
  18800. +++ linux-2.6.36/fs/aufs/opts.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/plink.c linux-2.6.36/fs/aufs/plink.c
  19013. --- linux-2.6.36.orig/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100
  19014. +++ linux-2.6.36/fs/aufs/plink.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/poll.c linux-2.6.36/fs/aufs/poll.c
  19532. --- linux-2.6.36.orig/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100
  19533. +++ linux-2.6.36/fs/aufs/poll.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/procfs.c linux-2.6.36/fs/aufs/procfs.c
  19592. --- linux-2.6.36.orig/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100
  19593. +++ linux-2.6.36/fs/aufs/procfs.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/rdu.c linux-2.6.36/fs/aufs/rdu.c
  19765. --- linux-2.6.36.orig/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100
  19766. +++ linux-2.6.36/fs/aufs/rdu.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/rwsem.h linux-2.6.36/fs/aufs/rwsem.h
  20152. --- linux-2.6.36.orig/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100
  20153. +++ linux-2.6.36/fs/aufs/rwsem.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/sbinfo.c linux-2.6.36/fs/aufs/sbinfo.c
  20345. --- linux-2.6.36.orig/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100
  20346. +++ linux-2.6.36/fs/aufs/sbinfo.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/spl.h linux-2.6.36/fs/aufs/spl.h
  20694. --- linux-2.6.36.orig/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100
  20695. +++ linux-2.6.36/fs/aufs/spl.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/super.c linux-2.6.36/fs/aufs/super.c
  20764. --- linux-2.6.36.orig/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
  20765. +++ linux-2.6.36/fs/aufs/super.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/super.h linux-2.6.36/fs/aufs/super.h
  21681. --- linux-2.6.36.orig/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100
  21682. +++ linux-2.6.36/fs/aufs/super.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/sysaufs.c linux-2.6.36/fs/aufs/sysaufs.c
  22212. --- linux-2.6.36.orig/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
  22213. +++ linux-2.6.36/fs/aufs/sysaufs.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/sysaufs.h linux-2.6.36/fs/aufs/sysaufs.h
  22323. --- linux-2.6.36.orig/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
  22324. +++ linux-2.6.36/fs/aufs/sysaufs.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/sysfs.c linux-2.6.36/fs/aufs/sysfs.c
  22432. --- linux-2.6.36.orig/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100
  22433. +++ linux-2.6.36/fs/aufs/sysfs.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/sysrq.c linux-2.6.36/fs/aufs/sysrq.c
  22686. --- linux-2.6.36.orig/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100
  22687. +++ linux-2.6.36/fs/aufs/sysrq.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/vdir.c linux-2.6.36/fs/aufs/vdir.c
  22838. --- linux-2.6.36.orig/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100
  22839. +++ linux-2.6.36/fs/aufs/vdir.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/vfsub.c linux-2.6.36/fs/aufs/vfsub.c
  23728. --- linux-2.6.36.orig/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100
  23729. +++ linux-2.6.36/fs/aufs/vfsub.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/vfsub.h linux-2.6.36/fs/aufs/vfsub.h
  24522. --- linux-2.6.36.orig/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
  24523. +++ linux-2.6.36/fs/aufs/vfsub.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/wbr_policy.c linux-2.6.36/fs/aufs/wbr_policy.c
  24752. --- linux-2.6.36.orig/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100
  24753. +++ linux-2.6.36/fs/aufs/wbr_policy.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/whout.c linux-2.6.36/fs/aufs/whout.c
  25456. --- linux-2.6.36.orig/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100
  25457. +++ linux-2.6.36/fs/aufs/whout.c 2011-01-10 19:24:41.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.36.orig/fs/aufs/whout.h linux-2.6.36/fs/aufs/whout.h
  26522. --- linux-2.6.36.orig/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100
  26523. +++ linux-2.6.36/fs/aufs/whout.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/wkq.c linux-2.6.36/fs/aufs/wkq.c
  26615. --- linux-2.6.36.orig/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100
  26616. +++ linux-2.6.36/fs/aufs/wkq.c 2011-01-10 19:24:41.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_ON_STACK(&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.36.orig/fs/aufs/wkq.h linux-2.6.36/fs/aufs/wkq.h
  26855. --- linux-2.6.36.orig/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100
  26856. +++ linux-2.6.36/fs/aufs/wkq.h 2011-01-10 19:24:41.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.36.orig/fs/aufs/xino.c linux-2.6.36/fs/aufs/xino.c
  26949. --- linux-2.6.36.orig/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100
  26950. +++ linux-2.6.36/fs/aufs/xino.c 2011-01-10 19:24:41.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.36.orig/fs/file_table.c linux-2.6.36/fs/file_table.c
  28218. --- linux-2.6.36.orig/fs/file_table.c 2010-10-20 22:30:22.000000000 +0200
  28219. +++ linux-2.6.36/fs/file_table.c 2011-01-10 19:52:38.000000000 +0100
  28220. @@ -394,6 +394,8 @@
  28221. }
  28222. }
  28223. +EXPORT_SYMBOL(file_sb_list_del);
  28224. +
  28225. #ifdef CONFIG_SMP
  28226. /*
  28227. diff -Nur linux-2.6.36.orig/fs/inode.c linux-2.6.36/fs/inode.c
  28228. --- linux-2.6.36.orig/fs/inode.c 2010-10-20 22:30:22.000000000 +0200
  28229. +++ linux-2.6.36/fs/inode.c 2011-01-10 19:52:38.000000000 +0100
  28230. @@ -83,6 +83,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.36.orig/fs/namei.c linux-2.6.36/fs/namei.c
  28238. --- linux-2.6.36.orig/fs/namei.c 2010-10-20 22:30:22.000000000 +0200
  28239. +++ linux-2.6.36/fs/namei.c 2011-01-10 19:52:38.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. @@ -1159,7 +1160,7 @@
  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. int err;
  28254. @@ -1168,8 +1169,9 @@
  28255. return ERR_PTR(err);
  28256. return __lookup_hash(&nd->last, nd->path.dentry, nd);
  28257. }
  28258. +EXPORT_SYMBOL(lookup_hash);
  28259. -static int __lookup_one_len(const char *name, struct qstr *this,
  28260. +int __lookup_one_len(const char *name, struct qstr *this,
  28261. struct dentry *base, int len)
  28262. {
  28263. unsigned long hash;
  28264. @@ -1190,6 +1192,7 @@
  28265. this->hash = end_name_hash(hash);
  28266. return 0;
  28267. }
  28268. +EXPORT_SYMBOL(__lookup_one_len);
  28269. /**
  28270. * lookup_one_len - filesystem helper to lookup single pathname component
  28271. diff -Nur linux-2.6.36.orig/fs/namei.c.orig linux-2.6.36/fs/namei.c.orig
  28272. --- linux-2.6.36.orig/fs/namei.c.orig 1970-01-01 01:00:00.000000000 +0100
  28273. +++ linux-2.6.36/fs/namei.c.orig 2011-01-10 19:52:38.000000000 +0100
  28274. @@ -0,0 +1,2921 @@
  28275. +/*
  28276. + * linux/fs/namei.c
  28277. + *
  28278. + * Copyright (C) 1991, 1992 Linus Torvalds
  28279. + */
  28280. +
  28281. +/*
  28282. + * Some corrections by tytso.
  28283. + */
  28284. +
  28285. +/* [Feb 1997 T. Schoebel-Theuer] Complete rewrite of the pathname
  28286. + * lookup logic.
  28287. + */
  28288. +/* [Feb-Apr 2000, AV] Rewrite to the new namespace architecture.
  28289. + */
  28290. +
  28291. +#include <linux/init.h>
  28292. +#include <linux/module.h>
  28293. +#include <linux/slab.h>
  28294. +#include <linux/fs.h>
  28295. +#include <linux/namei.h>
  28296. +#include <linux/pagemap.h>
  28297. +#include <linux/fsnotify.h>
  28298. +#include <linux/personality.h>
  28299. +#include <linux/security.h>
  28300. +#include <linux/ima.h>
  28301. +#include <linux/syscalls.h>
  28302. +#include <linux/mount.h>
  28303. +#include <linux/audit.h>
  28304. +#include <linux/capability.h>
  28305. +#include <linux/file.h>
  28306. +#include <linux/fcntl.h>
  28307. +#include <linux/device_cgroup.h>
  28308. +#include <linux/fs_struct.h>
  28309. +#include <asm/uaccess.h>
  28310. +
  28311. +#include "internal.h"
  28312. +
  28313. +/* [Feb-1997 T. Schoebel-Theuer]
  28314. + * Fundamental changes in the pathname lookup mechanisms (namei)
  28315. + * were necessary because of omirr. The reason is that omirr needs
  28316. + * to know the _real_ pathname, not the user-supplied one, in case
  28317. + * of symlinks (and also when transname replacements occur).
  28318. + *
  28319. + * The new code replaces the old recursive symlink resolution with
  28320. + * an iterative one (in case of non-nested symlink chains). It does
  28321. + * this with calls to <fs>_follow_link().
  28322. + * As a side effect, dir_namei(), _namei() and follow_link() are now
  28323. + * replaced with a single function lookup_dentry() that can handle all
  28324. + * the special cases of the former code.
  28325. + *
  28326. + * With the new dcache, the pathname is stored at each inode, at least as
  28327. + * long as the refcount of the inode is positive. As a side effect, the
  28328. + * size of the dcache depends on the inode cache and thus is dynamic.
  28329. + *
  28330. + * [29-Apr-1998 C. Scott Ananian] Updated above description of symlink
  28331. + * resolution to correspond with current state of the code.
  28332. + *
  28333. + * Note that the symlink resolution is not *completely* iterative.
  28334. + * There is still a significant amount of tail- and mid- recursion in
  28335. + * the algorithm. Also, note that <fs>_readlink() is not used in
  28336. + * lookup_dentry(): lookup_dentry() on the result of <fs>_readlink()
  28337. + * may return different results than <fs>_follow_link(). Many virtual
  28338. + * filesystems (including /proc) exhibit this behavior.
  28339. + */
  28340. +
  28341. +/* [24-Feb-97 T. Schoebel-Theuer] Side effects caused by new implementation:
  28342. + * New symlink semantics: when open() is called with flags O_CREAT | O_EXCL
  28343. + * and the name already exists in form of a symlink, try to create the new
  28344. + * name indicated by the symlink. The old code always complained that the
  28345. + * name already exists, due to not following the symlink even if its target
  28346. + * is nonexistent. The new semantics affects also mknod() and link() when
  28347. + * the name is a symlink pointing to a non-existant name.
  28348. + *
  28349. + * I don't know which semantics is the right one, since I have no access
  28350. + * to standards. But I found by trial that HP-UX 9.0 has the full "new"
  28351. + * semantics implemented, while SunOS 4.1.1 and Solaris (SunOS 5.4) have the
  28352. + * "old" one. Personally, I think the new semantics is much more logical.
  28353. + * Note that "ln old new" where "new" is a symlink pointing to a non-existing
  28354. + * file does succeed in both HP-UX and SunOs, but not in Solaris
  28355. + * and in the old Linux semantics.
  28356. + */
  28357. +
  28358. +/* [16-Dec-97 Kevin Buhr] For security reasons, we change some symlink
  28359. + * semantics. See the comments in "open_namei" and "do_link" below.
  28360. + *
  28361. + * [10-Sep-98 Alan Modra] Another symlink change.
  28362. + */
  28363. +
  28364. +/* [Feb-Apr 2000 AV] Complete rewrite. Rules for symlinks:
  28365. + * inside the path - always follow.
  28366. + * in the last component in creation/removal/renaming - never follow.
  28367. + * if LOOKUP_FOLLOW passed - follow.
  28368. + * if the pathname has trailing slashes - follow.
  28369. + * otherwise - don't follow.
  28370. + * (applied in that order).
  28371. + *
  28372. + * [Jun 2000 AV] Inconsistent behaviour of open() in case if flags==O_CREAT
  28373. + * restored for 2.4. This is the last surviving part of old 4.2BSD bug.
  28374. + * During the 2.4 we need to fix the userland stuff depending on it -
  28375. + * hopefully we will be able to get rid of that wart in 2.5. So far only
  28376. + * XEmacs seems to be relying on it...
  28377. + */
  28378. +/*
  28379. + * [Sep 2001 AV] Single-semaphore locking scheme (kudos to David Holland)
  28380. + * implemented. Let's see if raised priority of ->s_vfs_rename_mutex gives
  28381. + * any extra contention...
  28382. + */
  28383. +
  28384. +/* In order to reduce some races, while at the same time doing additional
  28385. + * checking and hopefully speeding things up, we copy filenames to the
  28386. + * kernel data space before using them..
  28387. + *
  28388. + * POSIX.1 2.4: an empty pathname is invalid (ENOENT).
  28389. + * PATH_MAX includes the nul terminator --RR.
  28390. + */
  28391. +static int do_getname(const char __user *filename, char *page)
  28392. +{
  28393. + int retval;
  28394. + unsigned long len = PATH_MAX;
  28395. +
  28396. + if (!segment_eq(get_fs(), KERNEL_DS)) {
  28397. + if ((unsigned long) filename >= TASK_SIZE)
  28398. + return -EFAULT;
  28399. + if (TASK_SIZE - (unsigned long) filename < PATH_MAX)
  28400. + len = TASK_SIZE - (unsigned long) filename;
  28401. + }
  28402. +
  28403. + retval = strncpy_from_user(page, filename, len);
  28404. + if (retval > 0) {
  28405. + if (retval < len)
  28406. + return 0;
  28407. + return -ENAMETOOLONG;
  28408. + } else if (!retval)
  28409. + retval = -ENOENT;
  28410. + return retval;
  28411. +}
  28412. +
  28413. +char * getname(const char __user * filename)
  28414. +{
  28415. + char *tmp, *result;
  28416. +
  28417. + result = ERR_PTR(-ENOMEM);
  28418. + tmp = __getname();
  28419. + if (tmp) {
  28420. + int retval = do_getname(filename, tmp);
  28421. +
  28422. + result = tmp;
  28423. + if (retval < 0) {
  28424. + __putname(tmp);
  28425. + result = ERR_PTR(retval);
  28426. + }
  28427. + }
  28428. + audit_getname(result);
  28429. + return result;
  28430. +}
  28431. +
  28432. +#ifdef CONFIG_AUDITSYSCALL
  28433. +void putname(const char *name)
  28434. +{
  28435. + if (unlikely(!audit_dummy_context()))
  28436. + audit_putname(name);
  28437. + else
  28438. + __putname(name);
  28439. +}
  28440. +EXPORT_SYMBOL(putname);
  28441. +#endif
  28442. +
  28443. +/*
  28444. + * This does basic POSIX ACL permission checking
  28445. + */
  28446. +static int acl_permission_check(struct inode *inode, int mask,
  28447. + int (*check_acl)(struct inode *inode, int mask))
  28448. +{
  28449. + umode_t mode = inode->i_mode;
  28450. +
  28451. + mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
  28452. +
  28453. + if (current_fsuid() == inode->i_uid)
  28454. + mode >>= 6;
  28455. + else {
  28456. + if (IS_POSIXACL(inode) && (mode & S_IRWXG) && check_acl) {
  28457. + int error = check_acl(inode, mask);
  28458. + if (error != -EAGAIN)
  28459. + return error;
  28460. + }
  28461. +
  28462. + if (in_group_p(inode->i_gid))
  28463. + mode >>= 3;
  28464. + }
  28465. +
  28466. + /*
  28467. + * If the DACs are ok we don't need any capability check.
  28468. + */
  28469. + if ((mask & ~mode) == 0)
  28470. + return 0;
  28471. + return -EACCES;
  28472. +}
  28473. +
  28474. +/**
  28475. + * generic_permission - check for access rights on a Posix-like filesystem
  28476. + * @inode: inode to check access rights for
  28477. + * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
  28478. + * @check_acl: optional callback to check for Posix ACLs
  28479. + *
  28480. + * Used to check for read/write/execute permissions on a file.
  28481. + * We use "fsuid" for this, letting us set arbitrary permissions
  28482. + * for filesystem access without changing the "normal" uids which
  28483. + * are used for other things..
  28484. + */
  28485. +int generic_permission(struct inode *inode, int mask,
  28486. + int (*check_acl)(struct inode *inode, int mask))
  28487. +{
  28488. + int ret;
  28489. +
  28490. + /*
  28491. + * Do the basic POSIX ACL permission checks.
  28492. + */
  28493. + ret = acl_permission_check(inode, mask, check_acl);
  28494. + if (ret != -EACCES)
  28495. + return ret;
  28496. +
  28497. + /*
  28498. + * Read/write DACs are always overridable.
  28499. + * Executable DACs are overridable if at least one exec bit is set.
  28500. + */
  28501. + if (!(mask & MAY_EXEC) || execute_ok(inode))
  28502. + if (capable(CAP_DAC_OVERRIDE))
  28503. + return 0;
  28504. +
  28505. + /*
  28506. + * Searching includes executable on directories, else just read.
  28507. + */
  28508. + mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
  28509. + if (mask == MAY_READ || (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE)))
  28510. + if (capable(CAP_DAC_READ_SEARCH))
  28511. + return 0;
  28512. +
  28513. + return -EACCES;
  28514. +}
  28515. +
  28516. +/**
  28517. + * inode_permission - check for access rights to a given inode
  28518. + * @inode: inode to check permission on
  28519. + * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
  28520. + *
  28521. + * Used to check for read/write/execute permissions on an inode.
  28522. + * We use "fsuid" for this, letting us set arbitrary permissions
  28523. + * for filesystem access without changing the "normal" uids which
  28524. + * are used for other things.
  28525. + */
  28526. +int inode_permission(struct inode *inode, int mask)
  28527. +{
  28528. + int retval;
  28529. +
  28530. + if (mask & MAY_WRITE) {
  28531. + umode_t mode = inode->i_mode;
  28532. +
  28533. + /*
  28534. + * Nobody gets write access to a read-only fs.
  28535. + */
  28536. + if (IS_RDONLY(inode) &&
  28537. + (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
  28538. + return -EROFS;
  28539. +
  28540. + /*
  28541. + * Nobody gets write access to an immutable file.
  28542. + */
  28543. + if (IS_IMMUTABLE(inode))
  28544. + return -EACCES;
  28545. + }
  28546. +
  28547. + if (inode->i_op->permission)
  28548. + retval = inode->i_op->permission(inode, mask);
  28549. + else
  28550. + retval = generic_permission(inode, mask, inode->i_op->check_acl);
  28551. +
  28552. + if (retval)
  28553. + return retval;
  28554. +
  28555. + retval = devcgroup_inode_permission(inode, mask);
  28556. + if (retval)
  28557. + return retval;
  28558. +
  28559. + return security_inode_permission(inode, mask);
  28560. +}
  28561. +
  28562. +/**
  28563. + * file_permission - check for additional access rights to a given file
  28564. + * @file: file to check access rights for
  28565. + * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
  28566. + *
  28567. + * Used to check for read/write/execute permissions on an already opened
  28568. + * file.
  28569. + *
  28570. + * Note:
  28571. + * Do not use this function in new code. All access checks should
  28572. + * be done using inode_permission().
  28573. + */
  28574. +int file_permission(struct file *file, int mask)
  28575. +{
  28576. + return inode_permission(file->f_path.dentry->d_inode, mask);
  28577. +}
  28578. +
  28579. +/*
  28580. + * get_write_access() gets write permission for a file.
  28581. + * put_write_access() releases this write permission.
  28582. + * This is used for regular files.
  28583. + * We cannot support write (and maybe mmap read-write shared) accesses and
  28584. + * MAP_DENYWRITE mmappings simultaneously. The i_writecount field of an inode
  28585. + * can have the following values:
  28586. + * 0: no writers, no VM_DENYWRITE mappings
  28587. + * < 0: (-i_writecount) vm_area_structs with VM_DENYWRITE set exist
  28588. + * > 0: (i_writecount) users are writing to the file.
  28589. + *
  28590. + * Normally we operate on that counter with atomic_{inc,dec} and it's safe
  28591. + * except for the cases where we don't hold i_writecount yet. Then we need to
  28592. + * use {get,deny}_write_access() - these functions check the sign and refuse
  28593. + * to do the change if sign is wrong. Exclusion between them is provided by
  28594. + * the inode->i_lock spinlock.
  28595. + */
  28596. +
  28597. +int get_write_access(struct inode * inode)
  28598. +{
  28599. + spin_lock(&inode->i_lock);
  28600. + if (atomic_read(&inode->i_writecount) < 0) {
  28601. + spin_unlock(&inode->i_lock);
  28602. + return -ETXTBSY;
  28603. + }
  28604. + atomic_inc(&inode->i_writecount);
  28605. + spin_unlock(&inode->i_lock);
  28606. +
  28607. + return 0;
  28608. +}
  28609. +
  28610. +int deny_write_access(struct file * file)
  28611. +{
  28612. + struct inode *inode = file->f_path.dentry->d_inode;
  28613. +
  28614. + spin_lock(&inode->i_lock);
  28615. + if (atomic_read(&inode->i_writecount) > 0) {
  28616. + spin_unlock(&inode->i_lock);
  28617. + return -ETXTBSY;
  28618. + }
  28619. + atomic_dec(&inode->i_writecount);
  28620. + spin_unlock(&inode->i_lock);
  28621. +
  28622. + return 0;
  28623. +}
  28624. +EXPORT_SYMBOL(deny_write_access);
  28625. +
  28626. +/**
  28627. + * path_get - get a reference to a path
  28628. + * @path: path to get the reference to
  28629. + *
  28630. + * Given a path increment the reference count to the dentry and the vfsmount.
  28631. + */
  28632. +void path_get(struct path *path)
  28633. +{
  28634. + mntget(path->mnt);
  28635. + dget(path->dentry);
  28636. +}
  28637. +EXPORT_SYMBOL(path_get);
  28638. +
  28639. +/**
  28640. + * path_put - put a reference to a path
  28641. + * @path: path to put the reference to
  28642. + *
  28643. + * Given a path decrement the reference count to the dentry and the vfsmount.
  28644. + */
  28645. +void path_put(struct path *path)
  28646. +{
  28647. + dput(path->dentry);
  28648. + mntput(path->mnt);
  28649. +}
  28650. +EXPORT_SYMBOL(path_put);
  28651. +
  28652. +/**
  28653. + * release_open_intent - free up open intent resources
  28654. + * @nd: pointer to nameidata
  28655. + */
  28656. +void release_open_intent(struct nameidata *nd)
  28657. +{
  28658. + if (nd->intent.open.file->f_path.dentry == NULL)
  28659. + put_filp(nd->intent.open.file);
  28660. + else
  28661. + fput(nd->intent.open.file);
  28662. +}
  28663. +
  28664. +static inline struct dentry *
  28665. +do_revalidate(struct dentry *dentry, struct nameidata *nd)
  28666. +{
  28667. + int status = dentry->d_op->d_revalidate(dentry, nd);
  28668. + if (unlikely(status <= 0)) {
  28669. + /*
  28670. + * The dentry failed validation.
  28671. + * If d_revalidate returned 0 attempt to invalidate
  28672. + * the dentry otherwise d_revalidate is asking us
  28673. + * to return a fail status.
  28674. + */
  28675. + if (!status) {
  28676. + if (!d_invalidate(dentry)) {
  28677. + dput(dentry);
  28678. + dentry = NULL;
  28679. + }
  28680. + } else {
  28681. + dput(dentry);
  28682. + dentry = ERR_PTR(status);
  28683. + }
  28684. + }
  28685. + return dentry;
  28686. +}
  28687. +
  28688. +/*
  28689. + * force_reval_path - force revalidation of a dentry
  28690. + *
  28691. + * In some situations the path walking code will trust dentries without
  28692. + * revalidating them. This causes problems for filesystems that depend on
  28693. + * d_revalidate to handle file opens (e.g. NFSv4). When FS_REVAL_DOT is set
  28694. + * (which indicates that it's possible for the dentry to go stale), force
  28695. + * a d_revalidate call before proceeding.
  28696. + *
  28697. + * Returns 0 if the revalidation was successful. If the revalidation fails,
  28698. + * either return the error returned by d_revalidate or -ESTALE if the
  28699. + * revalidation it just returned 0. If d_revalidate returns 0, we attempt to
  28700. + * invalidate the dentry. It's up to the caller to handle putting references
  28701. + * to the path if necessary.
  28702. + */
  28703. +static int
  28704. +force_reval_path(struct path *path, struct nameidata *nd)
  28705. +{
  28706. + int status;
  28707. + struct dentry *dentry = path->dentry;
  28708. +
  28709. + /*
  28710. + * only check on filesystems where it's possible for the dentry to
  28711. + * become stale. It's assumed that if this flag is set then the
  28712. + * d_revalidate op will also be defined.
  28713. + */
  28714. + if (!(dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT))
  28715. + return 0;
  28716. +
  28717. + status = dentry->d_op->d_revalidate(dentry, nd);
  28718. + if (status > 0)
  28719. + return 0;
  28720. +
  28721. + if (!status) {
  28722. + d_invalidate(dentry);
  28723. + status = -ESTALE;
  28724. + }
  28725. + return status;
  28726. +}
  28727. +
  28728. +/*
  28729. + * Short-cut version of permission(), for calling on directories
  28730. + * during pathname resolution. Combines parts of permission()
  28731. + * and generic_permission(), and tests ONLY for MAY_EXEC permission.
  28732. + *
  28733. + * If appropriate, check DAC only. If not appropriate, or
  28734. + * short-cut DAC fails, then call ->permission() to do more
  28735. + * complete permission check.
  28736. + */
  28737. +static int exec_permission(struct inode *inode)
  28738. +{
  28739. + int ret;
  28740. +
  28741. + if (inode->i_op->permission) {
  28742. + ret = inode->i_op->permission(inode, MAY_EXEC);
  28743. + if (!ret)
  28744. + goto ok;
  28745. + return ret;
  28746. + }
  28747. + ret = acl_permission_check(inode, MAY_EXEC, inode->i_op->check_acl);
  28748. + if (!ret)
  28749. + goto ok;
  28750. +
  28751. + if (capable(CAP_DAC_OVERRIDE) || capable(CAP_DAC_READ_SEARCH))
  28752. + goto ok;
  28753. +
  28754. + return ret;
  28755. +ok:
  28756. + return security_inode_permission(inode, MAY_EXEC);
  28757. +}
  28758. +
  28759. +static __always_inline void set_root(struct nameidata *nd)
  28760. +{
  28761. + if (!nd->root.mnt)
  28762. + get_fs_root(current->fs, &nd->root);
  28763. +}
  28764. +
  28765. +static int link_path_walk(const char *, struct nameidata *);
  28766. +
  28767. +static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link)
  28768. +{
  28769. + if (IS_ERR(link))
  28770. + goto fail;
  28771. +
  28772. + if (*link == '/') {
  28773. + set_root(nd);
  28774. + path_put(&nd->path);
  28775. + nd->path = nd->root;
  28776. + path_get(&nd->root);
  28777. + }
  28778. +
  28779. + return link_path_walk(link, nd);
  28780. +fail:
  28781. + path_put(&nd->path);
  28782. + return PTR_ERR(link);
  28783. +}
  28784. +
  28785. +static void path_put_conditional(struct path *path, struct nameidata *nd)
  28786. +{
  28787. + dput(path->dentry);
  28788. + if (path->mnt != nd->path.mnt)
  28789. + mntput(path->mnt);
  28790. +}
  28791. +
  28792. +static inline void path_to_nameidata(struct path *path, struct nameidata *nd)
  28793. +{
  28794. + dput(nd->path.dentry);
  28795. + if (nd->path.mnt != path->mnt) {
  28796. + mntput(nd->path.mnt);
  28797. + nd->path.mnt = path->mnt;
  28798. + }
  28799. + nd->path.dentry = path->dentry;
  28800. +}
  28801. +
  28802. +static __always_inline int
  28803. +__do_follow_link(struct path *path, struct nameidata *nd, void **p)
  28804. +{
  28805. + int error;
  28806. + struct dentry *dentry = path->dentry;
  28807. +
  28808. + touch_atime(path->mnt, dentry);
  28809. + nd_set_link(nd, NULL);
  28810. +
  28811. + if (path->mnt != nd->path.mnt) {
  28812. + path_to_nameidata(path, nd);
  28813. + dget(dentry);
  28814. + }
  28815. + mntget(path->mnt);
  28816. + nd->last_type = LAST_BIND;
  28817. + *p = dentry->d_inode->i_op->follow_link(dentry, nd);
  28818. + error = PTR_ERR(*p);
  28819. + if (!IS_ERR(*p)) {
  28820. + char *s = nd_get_link(nd);
  28821. + error = 0;
  28822. + if (s)
  28823. + error = __vfs_follow_link(nd, s);
  28824. + else if (nd->last_type == LAST_BIND) {
  28825. + error = force_reval_path(&nd->path, nd);
  28826. + if (error)
  28827. + path_put(&nd->path);
  28828. + }
  28829. + }
  28830. + return error;
  28831. +}
  28832. +
  28833. +/*
  28834. + * This limits recursive symlink follows to 8, while
  28835. + * limiting consecutive symlinks to 40.
  28836. + *
  28837. + * Without that kind of total limit, nasty chains of consecutive
  28838. + * symlinks can cause almost arbitrarily long lookups.
  28839. + */
  28840. +static inline int do_follow_link(struct path *path, struct nameidata *nd)
  28841. +{
  28842. + void *cookie;
  28843. + int err = -ELOOP;
  28844. + if (current->link_count >= MAX_NESTED_LINKS)
  28845. + goto loop;
  28846. + if (current->total_link_count >= 40)
  28847. + goto loop;
  28848. + BUG_ON(nd->depth >= MAX_NESTED_LINKS);
  28849. + cond_resched();
  28850. + err = security_inode_follow_link(path->dentry, nd);
  28851. + if (err)
  28852. + goto loop;
  28853. + current->link_count++;
  28854. + current->total_link_count++;
  28855. + nd->depth++;
  28856. + err = __do_follow_link(path, nd, &cookie);
  28857. + if (!IS_ERR(cookie) && path->dentry->d_inode->i_op->put_link)
  28858. + path->dentry->d_inode->i_op->put_link(path->dentry, nd, cookie);
  28859. + path_put(path);
  28860. + current->link_count--;
  28861. + nd->depth--;
  28862. + return err;
  28863. +loop:
  28864. + path_put_conditional(path, nd);
  28865. + path_put(&nd->path);
  28866. + return err;
  28867. +}
  28868. +
  28869. +int follow_up(struct path *path)
  28870. +{
  28871. + struct vfsmount *parent;
  28872. + struct dentry *mountpoint;
  28873. +
  28874. + br_read_lock(vfsmount_lock);
  28875. + parent = path->mnt->mnt_parent;
  28876. + if (parent == path->mnt) {
  28877. + br_read_unlock(vfsmount_lock);
  28878. + return 0;
  28879. + }
  28880. + mntget(parent);
  28881. + mountpoint = dget(path->mnt->mnt_mountpoint);
  28882. + br_read_unlock(vfsmount_lock);
  28883. + dput(path->dentry);
  28884. + path->dentry = mountpoint;
  28885. + mntput(path->mnt);
  28886. + path->mnt = parent;
  28887. + return 1;
  28888. +}
  28889. +
  28890. +/* no need for dcache_lock, as serialization is taken care in
  28891. + * namespace.c
  28892. + */
  28893. +static int __follow_mount(struct path *path)
  28894. +{
  28895. + int res = 0;
  28896. + while (d_mountpoint(path->dentry)) {
  28897. + struct vfsmount *mounted = lookup_mnt(path);
  28898. + if (!mounted)
  28899. + break;
  28900. + dput(path->dentry);
  28901. + if (res)
  28902. + mntput(path->mnt);
  28903. + path->mnt = mounted;
  28904. + path->dentry = dget(mounted->mnt_root);
  28905. + res = 1;
  28906. + }
  28907. + return res;
  28908. +}
  28909. +
  28910. +static void follow_mount(struct path *path)
  28911. +{
  28912. + while (d_mountpoint(path->dentry)) {
  28913. + struct vfsmount *mounted = lookup_mnt(path);
  28914. + if (!mounted)
  28915. + break;
  28916. + dput(path->dentry);
  28917. + mntput(path->mnt);
  28918. + path->mnt = mounted;
  28919. + path->dentry = dget(mounted->mnt_root);
  28920. + }
  28921. +}
  28922. +
  28923. +/* no need for dcache_lock, as serialization is taken care in
  28924. + * namespace.c
  28925. + */
  28926. +int follow_down(struct path *path)
  28927. +{
  28928. + struct vfsmount *mounted;
  28929. +
  28930. + mounted = lookup_mnt(path);
  28931. + if (mounted) {
  28932. + dput(path->dentry);
  28933. + mntput(path->mnt);
  28934. + path->mnt = mounted;
  28935. + path->dentry = dget(mounted->mnt_root);
  28936. + return 1;
  28937. + }
  28938. + return 0;
  28939. +}
  28940. +
  28941. +static __always_inline void follow_dotdot(struct nameidata *nd)
  28942. +{
  28943. + set_root(nd);
  28944. +
  28945. + while(1) {
  28946. + struct dentry *old = nd->path.dentry;
  28947. +
  28948. + if (nd->path.dentry == nd->root.dentry &&
  28949. + nd->path.mnt == nd->root.mnt) {
  28950. + break;
  28951. + }
  28952. + if (nd->path.dentry != nd->path.mnt->mnt_root) {
  28953. + /* rare case of legitimate dget_parent()... */
  28954. + nd->path.dentry = dget_parent(nd->path.dentry);
  28955. + dput(old);
  28956. + break;
  28957. + }
  28958. + if (!follow_up(&nd->path))
  28959. + break;
  28960. + }
  28961. + follow_mount(&nd->path);
  28962. +}
  28963. +
  28964. +/*
  28965. + * Allocate a dentry with name and parent, and perform a parent
  28966. + * directory ->lookup on it. Returns the new dentry, or ERR_PTR
  28967. + * on error. parent->d_inode->i_mutex must be held. d_lookup must
  28968. + * have verified that no child exists while under i_mutex.
  28969. + */
  28970. +static struct dentry *d_alloc_and_lookup(struct dentry *parent,
  28971. + struct qstr *name, struct nameidata *nd)
  28972. +{
  28973. + struct inode *inode = parent->d_inode;
  28974. + struct dentry *dentry;
  28975. + struct dentry *old;
  28976. +
  28977. + /* Don't create child dentry for a dead directory. */
  28978. + if (unlikely(IS_DEADDIR(inode)))
  28979. + return ERR_PTR(-ENOENT);
  28980. +
  28981. + dentry = d_alloc(parent, name);
  28982. + if (unlikely(!dentry))
  28983. + return ERR_PTR(-ENOMEM);
  28984. +
  28985. + old = inode->i_op->lookup(inode, dentry, nd);
  28986. + if (unlikely(old)) {
  28987. + dput(dentry);
  28988. + dentry = old;
  28989. + }
  28990. + return dentry;
  28991. +}
  28992. +
  28993. +/*
  28994. + * It's more convoluted than I'd like it to be, but... it's still fairly
  28995. + * small and for now I'd prefer to have fast path as straight as possible.
  28996. + * It _is_ time-critical.
  28997. + */
  28998. +static int do_lookup(struct nameidata *nd, struct qstr *name,
  28999. + struct path *path)
  29000. +{
  29001. + struct vfsmount *mnt = nd->path.mnt;
  29002. + struct dentry *dentry, *parent;
  29003. + struct inode *dir;
  29004. + /*
  29005. + * See if the low-level filesystem might want
  29006. + * to use its own hash..
  29007. + */
  29008. + if (nd->path.dentry->d_op && nd->path.dentry->d_op->d_hash) {
  29009. + int err = nd->path.dentry->d_op->d_hash(nd->path.dentry, name);
  29010. + if (err < 0)
  29011. + return err;
  29012. + }
  29013. +
  29014. + /*
  29015. + * Rename seqlock is not required here because in the off chance
  29016. + * of a false negative due to a concurrent rename, we're going to
  29017. + * do the non-racy lookup, below.
  29018. + */
  29019. + dentry = __d_lookup(nd->path.dentry, name);
  29020. + if (!dentry)
  29021. + goto need_lookup;
  29022. +found:
  29023. + if (dentry->d_op && dentry->d_op->d_revalidate)
  29024. + goto need_revalidate;
  29025. +done:
  29026. + path->mnt = mnt;
  29027. + path->dentry = dentry;
  29028. + __follow_mount(path);
  29029. + return 0;
  29030. +
  29031. +need_lookup:
  29032. + parent = nd->path.dentry;
  29033. + dir = parent->d_inode;
  29034. +
  29035. + mutex_lock(&dir->i_mutex);
  29036. + /*
  29037. + * First re-do the cached lookup just in case it was created
  29038. + * while we waited for the directory semaphore, or the first
  29039. + * lookup failed due to an unrelated rename.
  29040. + *
  29041. + * This could use version numbering or similar to avoid unnecessary
  29042. + * cache lookups, but then we'd have to do the first lookup in the
  29043. + * non-racy way. However in the common case here, everything should
  29044. + * be hot in cache, so would it be a big win?
  29045. + */
  29046. + dentry = d_lookup(parent, name);
  29047. + if (likely(!dentry)) {
  29048. + dentry = d_alloc_and_lookup(parent, name, nd);
  29049. + mutex_unlock(&dir->i_mutex);
  29050. + if (IS_ERR(dentry))
  29051. + goto fail;
  29052. + goto done;
  29053. + }
  29054. + /*
  29055. + * Uhhuh! Nasty case: the cache was re-populated while
  29056. + * we waited on the semaphore. Need to revalidate.
  29057. + */
  29058. + mutex_unlock(&dir->i_mutex);
  29059. + goto found;
  29060. +
  29061. +need_revalidate:
  29062. + dentry = do_revalidate(dentry, nd);
  29063. + if (!dentry)
  29064. + goto need_lookup;
  29065. + if (IS_ERR(dentry))
  29066. + goto fail;
  29067. + goto done;
  29068. +
  29069. +fail:
  29070. + return PTR_ERR(dentry);
  29071. +}
  29072. +
  29073. +/*
  29074. + * This is a temporary kludge to deal with "automount" symlinks; proper
  29075. + * solution is to trigger them on follow_mount(), so that do_lookup()
  29076. + * would DTRT. To be killed before 2.6.34-final.
  29077. + */
  29078. +static inline int follow_on_final(struct inode *inode, unsigned lookup_flags)
  29079. +{
  29080. + return inode && unlikely(inode->i_op->follow_link) &&
  29081. + ((lookup_flags & LOOKUP_FOLLOW) || S_ISDIR(inode->i_mode));
  29082. +}
  29083. +
  29084. +/*
  29085. + * Name resolution.
  29086. + * This is the basic name resolution function, turning a pathname into
  29087. + * the final dentry. We expect 'base' to be positive and a directory.
  29088. + *
  29089. + * Returns 0 and nd will have valid dentry and mnt on success.
  29090. + * Returns error and drops reference to input namei data on failure.
  29091. + */
  29092. +static int link_path_walk(const char *name, struct nameidata *nd)
  29093. +{
  29094. + struct path next;
  29095. + struct inode *inode;
  29096. + int err;
  29097. + unsigned int lookup_flags = nd->flags;
  29098. +
  29099. + while (*name=='/')
  29100. + name++;
  29101. + if (!*name)
  29102. + goto return_reval;
  29103. +
  29104. + inode = nd->path.dentry->d_inode;
  29105. + if (nd->depth)
  29106. + lookup_flags = LOOKUP_FOLLOW | (nd->flags & LOOKUP_CONTINUE);
  29107. +
  29108. + /* At this point we know we have a real path component. */
  29109. + for(;;) {
  29110. + unsigned long hash;
  29111. + struct qstr this;
  29112. + unsigned int c;
  29113. +
  29114. + nd->flags |= LOOKUP_CONTINUE;
  29115. + err = exec_permission(inode);
  29116. + if (err)
  29117. + break;
  29118. +
  29119. + this.name = name;
  29120. + c = *(const unsigned char *)name;
  29121. +
  29122. + hash = init_name_hash();
  29123. + do {
  29124. + name++;
  29125. + hash = partial_name_hash(c, hash);
  29126. + c = *(const unsigned char *)name;
  29127. + } while (c && (c != '/'));
  29128. + this.len = name - (const char *) this.name;
  29129. + this.hash = end_name_hash(hash);
  29130. +
  29131. + /* remove trailing slashes? */
  29132. + if (!c)
  29133. + goto last_component;
  29134. + while (*++name == '/');
  29135. + if (!*name)
  29136. + goto last_with_slashes;
  29137. +
  29138. + /*
  29139. + * "." and ".." are special - ".." especially so because it has
  29140. + * to be able to know about the current root directory and
  29141. + * parent relationships.
  29142. + */
  29143. + if (this.name[0] == '.') switch (this.len) {
  29144. + default:
  29145. + break;
  29146. + case 2:
  29147. + if (this.name[1] != '.')
  29148. + break;
  29149. + follow_dotdot(nd);
  29150. + inode = nd->path.dentry->d_inode;
  29151. + /* fallthrough */
  29152. + case 1:
  29153. + continue;
  29154. + }
  29155. + /* This does the actual lookups.. */
  29156. + err = do_lookup(nd, &this, &next);
  29157. + if (err)
  29158. + break;
  29159. +
  29160. + err = -ENOENT;
  29161. + inode = next.dentry->d_inode;
  29162. + if (!inode)
  29163. + goto out_dput;
  29164. +
  29165. + if (inode->i_op->follow_link) {
  29166. + err = do_follow_link(&next, nd);
  29167. + if (err)
  29168. + goto return_err;
  29169. + err = -ENOENT;
  29170. + inode = nd->path.dentry->d_inode;
  29171. + if (!inode)
  29172. + break;
  29173. + } else
  29174. + path_to_nameidata(&next, nd);
  29175. + err = -ENOTDIR;
  29176. + if (!inode->i_op->lookup)
  29177. + break;
  29178. + continue;
  29179. + /* here ends the main loop */
  29180. +
  29181. +last_with_slashes:
  29182. + lookup_flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
  29183. +last_component:
  29184. + /* Clear LOOKUP_CONTINUE iff it was previously unset */
  29185. + nd->flags &= lookup_flags | ~LOOKUP_CONTINUE;
  29186. + if (lookup_flags & LOOKUP_PARENT)
  29187. + goto lookup_parent;
  29188. + if (this.name[0] == '.') switch (this.len) {
  29189. + default:
  29190. + break;
  29191. + case 2:
  29192. + if (this.name[1] != '.')
  29193. + break;
  29194. + follow_dotdot(nd);
  29195. + inode = nd->path.dentry->d_inode;
  29196. + /* fallthrough */
  29197. + case 1:
  29198. + goto return_reval;
  29199. + }
  29200. + err = do_lookup(nd, &this, &next);
  29201. + if (err)
  29202. + break;
  29203. + inode = next.dentry->d_inode;
  29204. + if (follow_on_final(inode, lookup_flags)) {
  29205. + err = do_follow_link(&next, nd);
  29206. + if (err)
  29207. + goto return_err;
  29208. + inode = nd->path.dentry->d_inode;
  29209. + } else
  29210. + path_to_nameidata(&next, nd);
  29211. + err = -ENOENT;
  29212. + if (!inode)
  29213. + break;
  29214. + if (lookup_flags & LOOKUP_DIRECTORY) {
  29215. + err = -ENOTDIR;
  29216. + if (!inode->i_op->lookup)
  29217. + break;
  29218. + }
  29219. + goto return_base;
  29220. +lookup_parent:
  29221. + nd->last = this;
  29222. + nd->last_type = LAST_NORM;
  29223. + if (this.name[0] != '.')
  29224. + goto return_base;
  29225. + if (this.len == 1)
  29226. + nd->last_type = LAST_DOT;
  29227. + else if (this.len == 2 && this.name[1] == '.')
  29228. + nd->last_type = LAST_DOTDOT;
  29229. + else
  29230. + goto return_base;
  29231. +return_reval:
  29232. + /*
  29233. + * We bypassed the ordinary revalidation routines.
  29234. + * We may need to check the cached dentry for staleness.
  29235. + */
  29236. + if (nd->path.dentry && nd->path.dentry->d_sb &&
  29237. + (nd->path.dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) {
  29238. + err = -ESTALE;
  29239. + /* Note: we do not d_invalidate() */
  29240. + if (!nd->path.dentry->d_op->d_revalidate(
  29241. + nd->path.dentry, nd))
  29242. + break;
  29243. + }
  29244. +return_base:
  29245. + return 0;
  29246. +out_dput:
  29247. + path_put_conditional(&next, nd);
  29248. + break;
  29249. + }
  29250. + path_put(&nd->path);
  29251. +return_err:
  29252. + return err;
  29253. +}
  29254. +
  29255. +static int path_walk(const char *name, struct nameidata *nd)
  29256. +{
  29257. + struct path save = nd->path;
  29258. + int result;
  29259. +
  29260. + current->total_link_count = 0;
  29261. +
  29262. + /* make sure the stuff we saved doesn't go away */
  29263. + path_get(&save);
  29264. +
  29265. + result = link_path_walk(name, nd);
  29266. + if (result == -ESTALE) {
  29267. + /* nd->path had been dropped */
  29268. + current->total_link_count = 0;
  29269. + nd->path = save;
  29270. + path_get(&nd->path);
  29271. + nd->flags |= LOOKUP_REVAL;
  29272. + result = link_path_walk(name, nd);
  29273. + }
  29274. +
  29275. + path_put(&save);
  29276. +
  29277. + return result;
  29278. +}
  29279. +
  29280. +static int path_init(int dfd, const char *name, unsigned int flags, struct nameidata *nd)
  29281. +{
  29282. + int retval = 0;
  29283. + int fput_needed;
  29284. + struct file *file;
  29285. +
  29286. + nd->last_type = LAST_ROOT; /* if there are only slashes... */
  29287. + nd->flags = flags;
  29288. + nd->depth = 0;
  29289. + nd->root.mnt = NULL;
  29290. +
  29291. + if (*name=='/') {
  29292. + set_root(nd);
  29293. + nd->path = nd->root;
  29294. + path_get(&nd->root);
  29295. + } else if (dfd == AT_FDCWD) {
  29296. + get_fs_pwd(current->fs, &nd->path);
  29297. + } else {
  29298. + struct dentry *dentry;
  29299. +
  29300. + file = fget_light(dfd, &fput_needed);
  29301. + retval = -EBADF;
  29302. + if (!file)
  29303. + goto out_fail;
  29304. +
  29305. + dentry = file->f_path.dentry;
  29306. +
  29307. + retval = -ENOTDIR;
  29308. + if (!S_ISDIR(dentry->d_inode->i_mode))
  29309. + goto fput_fail;
  29310. +
  29311. + retval = file_permission(file, MAY_EXEC);
  29312. + if (retval)
  29313. + goto fput_fail;
  29314. +
  29315. + nd->path = file->f_path;
  29316. + path_get(&file->f_path);
  29317. +
  29318. + fput_light(file, fput_needed);
  29319. + }
  29320. + return 0;
  29321. +
  29322. +fput_fail:
  29323. + fput_light(file, fput_needed);
  29324. +out_fail:
  29325. + return retval;
  29326. +}
  29327. +
  29328. +/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
  29329. +static int do_path_lookup(int dfd, const char *name,
  29330. + unsigned int flags, struct nameidata *nd)
  29331. +{
  29332. + int retval = path_init(dfd, name, flags, nd);
  29333. + if (!retval)
  29334. + retval = path_walk(name, nd);
  29335. + if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
  29336. + nd->path.dentry->d_inode))
  29337. + audit_inode(name, nd->path.dentry);
  29338. + if (nd->root.mnt) {
  29339. + path_put(&nd->root);
  29340. + nd->root.mnt = NULL;
  29341. + }
  29342. + return retval;
  29343. +}
  29344. +
  29345. +int path_lookup(const char *name, unsigned int flags,
  29346. + struct nameidata *nd)
  29347. +{
  29348. + return do_path_lookup(AT_FDCWD, name, flags, nd);
  29349. +}
  29350. +
  29351. +int kern_path(const char *name, unsigned int flags, struct path *path)
  29352. +{
  29353. + struct nameidata nd;
  29354. + int res = do_path_lookup(AT_FDCWD, name, flags, &nd);
  29355. + if (!res)
  29356. + *path = nd.path;
  29357. + return res;
  29358. +}
  29359. +
  29360. +/**
  29361. + * vfs_path_lookup - lookup a file path relative to a dentry-vfsmount pair
  29362. + * @dentry: pointer to dentry of the base directory
  29363. + * @mnt: pointer to vfs mount of the base directory
  29364. + * @name: pointer to file name
  29365. + * @flags: lookup flags
  29366. + * @nd: pointer to nameidata
  29367. + */
  29368. +int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
  29369. + const char *name, unsigned int flags,
  29370. + struct nameidata *nd)
  29371. +{
  29372. + int retval;
  29373. +
  29374. + /* same as do_path_lookup */
  29375. + nd->last_type = LAST_ROOT;
  29376. + nd->flags = flags;
  29377. + nd->depth = 0;
  29378. +
  29379. + nd->path.dentry = dentry;
  29380. + nd->path.mnt = mnt;
  29381. + path_get(&nd->path);
  29382. + nd->root = nd->path;
  29383. + path_get(&nd->root);
  29384. +
  29385. + retval = path_walk(name, nd);
  29386. + if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
  29387. + nd->path.dentry->d_inode))
  29388. + audit_inode(name, nd->path.dentry);
  29389. +
  29390. + path_put(&nd->root);
  29391. + nd->root.mnt = NULL;
  29392. +
  29393. + return retval;
  29394. +}
  29395. +
  29396. +static struct dentry *__lookup_hash(struct qstr *name,
  29397. + struct dentry *base, struct nameidata *nd)
  29398. +{
  29399. + struct dentry *dentry;
  29400. + struct inode *inode;
  29401. + int err;
  29402. +
  29403. + inode = base->d_inode;
  29404. +
  29405. + /*
  29406. + * See if the low-level filesystem might want
  29407. + * to use its own hash..
  29408. + */
  29409. + if (base->d_op && base->d_op->d_hash) {
  29410. + err = base->d_op->d_hash(base, name);
  29411. + dentry = ERR_PTR(err);
  29412. + if (err < 0)
  29413. + goto out;
  29414. + }
  29415. +
  29416. + /*
  29417. + * Don't bother with __d_lookup: callers are for creat as
  29418. + * well as unlink, so a lot of the time it would cost
  29419. + * a double lookup.
  29420. + */
  29421. + dentry = d_lookup(base, name);
  29422. +
  29423. + if (dentry && dentry->d_op && dentry->d_op->d_revalidate)
  29424. + dentry = do_revalidate(dentry, nd);
  29425. +
  29426. + if (!dentry)
  29427. + dentry = d_alloc_and_lookup(base, name, nd);
  29428. +out:
  29429. + return dentry;
  29430. +}
  29431. +
  29432. +/*
  29433. + * Restricted form of lookup. Doesn't follow links, single-component only,
  29434. + * needs parent already locked. Doesn't follow mounts.
  29435. + * SMP-safe.
  29436. + */
  29437. +static struct dentry *lookup_hash(struct nameidata *nd)
  29438. +{
  29439. + int err;
  29440. +
  29441. + err = exec_permission(nd->path.dentry->d_inode);
  29442. + if (err)
  29443. + return ERR_PTR(err);
  29444. + return __lookup_hash(&nd->last, nd->path.dentry, nd);
  29445. +}
  29446. +EXPORT_SYMBOL(lookup_hash);
  29447. +
  29448. +static int __lookup_one_len(const char *name, struct qstr *this,
  29449. + struct dentry *base, int len)
  29450. +{
  29451. + unsigned long hash;
  29452. + unsigned int c;
  29453. +
  29454. + this->name = name;
  29455. + this->len = len;
  29456. + if (!len)
  29457. + return -EACCES;
  29458. +
  29459. + hash = init_name_hash();
  29460. + while (len--) {
  29461. + c = *(const unsigned char *)name++;
  29462. + if (c == '/' || c == '\0')
  29463. + return -EACCES;
  29464. + hash = partial_name_hash(c, hash);
  29465. + }
  29466. + this->hash = end_name_hash(hash);
  29467. + return 0;
  29468. +}
  29469. +EXPORT_SYMBOL(__lookup_one_len);
  29470. +
  29471. +/**
  29472. + * lookup_one_len - filesystem helper to lookup single pathname component
  29473. + * @name: pathname component to lookup
  29474. + * @base: base directory to lookup from
  29475. + * @len: maximum length @len should be interpreted to
  29476. + *
  29477. + * Note that this routine is purely a helper for filesystem usage and should
  29478. + * not be called by generic code. Also note that by using this function the
  29479. + * nameidata argument is passed to the filesystem methods and a filesystem
  29480. + * using this helper needs to be prepared for that.
  29481. + */
  29482. +struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
  29483. +{
  29484. + int err;
  29485. + struct qstr this;
  29486. +
  29487. + WARN_ON_ONCE(!mutex_is_locked(&base->d_inode->i_mutex));
  29488. +
  29489. + err = __lookup_one_len(name, &this, base, len);
  29490. + if (err)
  29491. + return ERR_PTR(err);
  29492. +
  29493. + err = exec_permission(base->d_inode);
  29494. + if (err)
  29495. + return ERR_PTR(err);
  29496. + return __lookup_hash(&this, base, NULL);
  29497. +}
  29498. +
  29499. +int user_path_at(int dfd, const char __user *name, unsigned flags,
  29500. + struct path *path)
  29501. +{
  29502. + struct nameidata nd;
  29503. + char *tmp = getname(name);
  29504. + int err = PTR_ERR(tmp);
  29505. + if (!IS_ERR(tmp)) {
  29506. +
  29507. + BUG_ON(flags & LOOKUP_PARENT);
  29508. +
  29509. + err = do_path_lookup(dfd, tmp, flags, &nd);
  29510. + putname(tmp);
  29511. + if (!err)
  29512. + *path = nd.path;
  29513. + }
  29514. + return err;
  29515. +}
  29516. +
  29517. +static int user_path_parent(int dfd, const char __user *path,
  29518. + struct nameidata *nd, char **name)
  29519. +{
  29520. + char *s = getname(path);
  29521. + int error;
  29522. +
  29523. + if (IS_ERR(s))
  29524. + return PTR_ERR(s);
  29525. +
  29526. + error = do_path_lookup(dfd, s, LOOKUP_PARENT, nd);
  29527. + if (error)
  29528. + putname(s);
  29529. + else
  29530. + *name = s;
  29531. +
  29532. + return error;
  29533. +}
  29534. +
  29535. +/*
  29536. + * It's inline, so penalty for filesystems that don't use sticky bit is
  29537. + * minimal.
  29538. + */
  29539. +static inline int check_sticky(struct inode *dir, struct inode *inode)
  29540. +{
  29541. + uid_t fsuid = current_fsuid();
  29542. +
  29543. + if (!(dir->i_mode & S_ISVTX))
  29544. + return 0;
  29545. + if (inode->i_uid == fsuid)
  29546. + return 0;
  29547. + if (dir->i_uid == fsuid)
  29548. + return 0;
  29549. + return !capable(CAP_FOWNER);
  29550. +}
  29551. +
  29552. +/*
  29553. + * Check whether we can remove a link victim from directory dir, check
  29554. + * whether the type of victim is right.
  29555. + * 1. We can't do it if dir is read-only (done in permission())
  29556. + * 2. We should have write and exec permissions on dir
  29557. + * 3. We can't remove anything from append-only dir
  29558. + * 4. We can't do anything with immutable dir (done in permission())
  29559. + * 5. If the sticky bit on dir is set we should either
  29560. + * a. be owner of dir, or
  29561. + * b. be owner of victim, or
  29562. + * c. have CAP_FOWNER capability
  29563. + * 6. If the victim is append-only or immutable we can't do antyhing with
  29564. + * links pointing to it.
  29565. + * 7. If we were asked to remove a directory and victim isn't one - ENOTDIR.
  29566. + * 8. If we were asked to remove a non-directory and victim isn't one - EISDIR.
  29567. + * 9. We can't remove a root or mountpoint.
  29568. + * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
  29569. + * nfs_async_unlink().
  29570. + */
  29571. +static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
  29572. +{
  29573. + int error;
  29574. +
  29575. + if (!victim->d_inode)
  29576. + return -ENOENT;
  29577. +
  29578. + BUG_ON(victim->d_parent->d_inode != dir);
  29579. + audit_inode_child(victim, dir);
  29580. +
  29581. + error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
  29582. + if (error)
  29583. + return error;
  29584. + if (IS_APPEND(dir))
  29585. + return -EPERM;
  29586. + if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
  29587. + IS_IMMUTABLE(victim->d_inode) || IS_SWAPFILE(victim->d_inode))
  29588. + return -EPERM;
  29589. + if (isdir) {
  29590. + if (!S_ISDIR(victim->d_inode->i_mode))
  29591. + return -ENOTDIR;
  29592. + if (IS_ROOT(victim))
  29593. + return -EBUSY;
  29594. + } else if (S_ISDIR(victim->d_inode->i_mode))
  29595. + return -EISDIR;
  29596. + if (IS_DEADDIR(dir))
  29597. + return -ENOENT;
  29598. + if (victim->d_flags & DCACHE_NFSFS_RENAMED)
  29599. + return -EBUSY;
  29600. + return 0;
  29601. +}
  29602. +
  29603. +/* Check whether we can create an object with dentry child in directory
  29604. + * dir.
  29605. + * 1. We can't do it if child already exists (open has special treatment for
  29606. + * this case, but since we are inlined it's OK)
  29607. + * 2. We can't do it if dir is read-only (done in permission())
  29608. + * 3. We should have write and exec permissions on dir
  29609. + * 4. We can't do it if dir is immutable (done in permission())
  29610. + */
  29611. +static inline int may_create(struct inode *dir, struct dentry *child)
  29612. +{
  29613. + if (child->d_inode)
  29614. + return -EEXIST;
  29615. + if (IS_DEADDIR(dir))
  29616. + return -ENOENT;
  29617. + return inode_permission(dir, MAY_WRITE | MAY_EXEC);
  29618. +}
  29619. +
  29620. +/*
  29621. + * p1 and p2 should be directories on the same fs.
  29622. + */
  29623. +struct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
  29624. +{
  29625. + struct dentry *p;
  29626. +
  29627. + if (p1 == p2) {
  29628. + mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT);
  29629. + return NULL;
  29630. + }
  29631. +
  29632. + mutex_lock(&p1->d_inode->i_sb->s_vfs_rename_mutex);
  29633. +
  29634. + p = d_ancestor(p2, p1);
  29635. + if (p) {
  29636. + mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_PARENT);
  29637. + mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_CHILD);
  29638. + return p;
  29639. + }
  29640. +
  29641. + p = d_ancestor(p1, p2);
  29642. + if (p) {
  29643. + mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT);
  29644. + mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_CHILD);
  29645. + return p;
  29646. + }
  29647. +
  29648. + mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT);
  29649. + mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_CHILD);
  29650. + return NULL;
  29651. +}
  29652. +
  29653. +void unlock_rename(struct dentry *p1, struct dentry *p2)
  29654. +{
  29655. + mutex_unlock(&p1->d_inode->i_mutex);
  29656. + if (p1 != p2) {
  29657. + mutex_unlock(&p2->d_inode->i_mutex);
  29658. + mutex_unlock(&p1->d_inode->i_sb->s_vfs_rename_mutex);
  29659. + }
  29660. +}
  29661. +
  29662. +int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
  29663. + struct nameidata *nd)
  29664. +{
  29665. + int error = may_create(dir, dentry);
  29666. +
  29667. + if (error)
  29668. + return error;
  29669. +
  29670. + if (!dir->i_op->create)
  29671. + return -EACCES; /* shouldn't it be ENOSYS? */
  29672. + mode &= S_IALLUGO;
  29673. + mode |= S_IFREG;
  29674. + error = security_inode_create(dir, dentry, mode);
  29675. + if (error)
  29676. + return error;
  29677. + error = dir->i_op->create(dir, dentry, mode, nd);
  29678. + if (!error)
  29679. + fsnotify_create(dir, dentry);
  29680. + return error;
  29681. +}
  29682. +
  29683. +int may_open(struct path *path, int acc_mode, int flag)
  29684. +{
  29685. + struct dentry *dentry = path->dentry;
  29686. + struct inode *inode = dentry->d_inode;
  29687. + int error;
  29688. +
  29689. + if (!inode)
  29690. + return -ENOENT;
  29691. +
  29692. + switch (inode->i_mode & S_IFMT) {
  29693. + case S_IFLNK:
  29694. + return -ELOOP;
  29695. + case S_IFDIR:
  29696. + if (acc_mode & MAY_WRITE)
  29697. + return -EISDIR;
  29698. + break;
  29699. + case S_IFBLK:
  29700. + case S_IFCHR:
  29701. + if (path->mnt->mnt_flags & MNT_NODEV)
  29702. + return -EACCES;
  29703. + /*FALLTHRU*/
  29704. + case S_IFIFO:
  29705. + case S_IFSOCK:
  29706. + flag &= ~O_TRUNC;
  29707. + break;
  29708. + }
  29709. +
  29710. + error = inode_permission(inode, acc_mode);
  29711. + if (error)
  29712. + return error;
  29713. +
  29714. + /*
  29715. + * An append-only file must be opened in append mode for writing.
  29716. + */
  29717. + if (IS_APPEND(inode)) {
  29718. + if ((flag & O_ACCMODE) != O_RDONLY && !(flag & O_APPEND))
  29719. + return -EPERM;
  29720. + if (flag & O_TRUNC)
  29721. + return -EPERM;
  29722. + }
  29723. +
  29724. + /* O_NOATIME can only be set by the owner or superuser */
  29725. + if (flag & O_NOATIME && !is_owner_or_cap(inode))
  29726. + return -EPERM;
  29727. +
  29728. + /*
  29729. + * Ensure there are no outstanding leases on the file.
  29730. + */
  29731. + return break_lease(inode, flag);
  29732. +}
  29733. +
  29734. +static int handle_truncate(struct path *path)
  29735. +{
  29736. + struct inode *inode = path->dentry->d_inode;
  29737. + int error = get_write_access(inode);
  29738. + if (error)
  29739. + return error;
  29740. + /*
  29741. + * Refuse to truncate files with mandatory locks held on them.
  29742. + */
  29743. + error = locks_verify_locked(inode);
  29744. + if (!error)
  29745. + error = security_path_truncate(path);
  29746. + if (!error) {
  29747. + error = do_truncate(path->dentry, 0,
  29748. + ATTR_MTIME|ATTR_CTIME|ATTR_OPEN,
  29749. + NULL);
  29750. + }
  29751. + put_write_access(inode);
  29752. + return error;
  29753. +}
  29754. +
  29755. +/*
  29756. + * Be careful about ever adding any more callers of this
  29757. + * function. Its flags must be in the namei format, not
  29758. + * what get passed to sys_open().
  29759. + */
  29760. +static int __open_namei_create(struct nameidata *nd, struct path *path,
  29761. + int open_flag, int mode)
  29762. +{
  29763. + int error;
  29764. + struct dentry *dir = nd->path.dentry;
  29765. +
  29766. + if (!IS_POSIXACL(dir->d_inode))
  29767. + mode &= ~current_umask();
  29768. + error = security_path_mknod(&nd->path, path->dentry, mode, 0);
  29769. + if (error)
  29770. + goto out_unlock;
  29771. + error = vfs_create(dir->d_inode, path->dentry, mode, nd);
  29772. +out_unlock:
  29773. + mutex_unlock(&dir->d_inode->i_mutex);
  29774. + dput(nd->path.dentry);
  29775. + nd->path.dentry = path->dentry;
  29776. + if (error)
  29777. + return error;
  29778. + /* Don't check for write permission, don't truncate */
  29779. + return may_open(&nd->path, 0, open_flag & ~O_TRUNC);
  29780. +}
  29781. +
  29782. +/*
  29783. + * Note that while the flag value (low two bits) for sys_open means:
  29784. + * 00 - read-only
  29785. + * 01 - write-only
  29786. + * 10 - read-write
  29787. + * 11 - special
  29788. + * it is changed into
  29789. + * 00 - no permissions needed
  29790. + * 01 - read-permission
  29791. + * 10 - write-permission
  29792. + * 11 - read-write
  29793. + * for the internal routines (ie open_namei()/follow_link() etc)
  29794. + * This is more logical, and also allows the 00 "no perm needed"
  29795. + * to be used for symlinks (where the permissions are checked
  29796. + * later).
  29797. + *
  29798. +*/
  29799. +static inline int open_to_namei_flags(int flag)
  29800. +{
  29801. + if ((flag+1) & O_ACCMODE)
  29802. + flag++;
  29803. + return flag;
  29804. +}
  29805. +
  29806. +static int open_will_truncate(int flag, struct inode *inode)
  29807. +{
  29808. + /*
  29809. + * We'll never write to the fs underlying
  29810. + * a device file.
  29811. + */
  29812. + if (special_file(inode->i_mode))
  29813. + return 0;
  29814. + return (flag & O_TRUNC);
  29815. +}
  29816. +
  29817. +static struct file *finish_open(struct nameidata *nd,
  29818. + int open_flag, int acc_mode)
  29819. +{
  29820. + struct file *filp;
  29821. + int will_truncate;
  29822. + int error;
  29823. +
  29824. + will_truncate = open_will_truncate(open_flag, nd->path.dentry->d_inode);
  29825. + if (will_truncate) {
  29826. + error = mnt_want_write(nd->path.mnt);
  29827. + if (error)
  29828. + goto exit;
  29829. + }
  29830. + error = may_open(&nd->path, acc_mode, open_flag);
  29831. + if (error) {
  29832. + if (will_truncate)
  29833. + mnt_drop_write(nd->path.mnt);
  29834. + goto exit;
  29835. + }
  29836. + filp = nameidata_to_filp(nd);
  29837. + if (!IS_ERR(filp)) {
  29838. + error = ima_file_check(filp, acc_mode);
  29839. + if (error) {
  29840. + fput(filp);
  29841. + filp = ERR_PTR(error);
  29842. + }
  29843. + }
  29844. + if (!IS_ERR(filp)) {
  29845. + if (will_truncate) {
  29846. + error = handle_truncate(&nd->path);
  29847. + if (error) {
  29848. + fput(filp);
  29849. + filp = ERR_PTR(error);
  29850. + }
  29851. + }
  29852. + }
  29853. + /*
  29854. + * It is now safe to drop the mnt write
  29855. + * because the filp has had a write taken
  29856. + * on its behalf.
  29857. + */
  29858. + if (will_truncate)
  29859. + mnt_drop_write(nd->path.mnt);
  29860. + return filp;
  29861. +
  29862. +exit:
  29863. + if (!IS_ERR(nd->intent.open.file))
  29864. + release_open_intent(nd);
  29865. + path_put(&nd->path);
  29866. + return ERR_PTR(error);
  29867. +}
  29868. +
  29869. +static struct file *do_last(struct nameidata *nd, struct path *path,
  29870. + int open_flag, int acc_mode,
  29871. + int mode, const char *pathname)
  29872. +{
  29873. + struct dentry *dir = nd->path.dentry;
  29874. + struct file *filp;
  29875. + int error = -EISDIR;
  29876. +
  29877. + switch (nd->last_type) {
  29878. + case LAST_DOTDOT:
  29879. + follow_dotdot(nd);
  29880. + dir = nd->path.dentry;
  29881. + case LAST_DOT:
  29882. + if (nd->path.mnt->mnt_sb->s_type->fs_flags & FS_REVAL_DOT) {
  29883. + if (!dir->d_op->d_revalidate(dir, nd)) {
  29884. + error = -ESTALE;
  29885. + goto exit;
  29886. + }
  29887. + }
  29888. + /* fallthrough */
  29889. + case LAST_ROOT:
  29890. + if (open_flag & O_CREAT)
  29891. + goto exit;
  29892. + /* fallthrough */
  29893. + case LAST_BIND:
  29894. + audit_inode(pathname, dir);
  29895. + goto ok;
  29896. + }
  29897. +
  29898. + /* trailing slashes? */
  29899. + if (nd->last.name[nd->last.len]) {
  29900. + if (open_flag & O_CREAT)
  29901. + goto exit;
  29902. + nd->flags |= LOOKUP_DIRECTORY | LOOKUP_FOLLOW;
  29903. + }
  29904. +
  29905. + /* just plain open? */
  29906. + if (!(open_flag & O_CREAT)) {
  29907. + error = do_lookup(nd, &nd->last, path);
  29908. + if (error)
  29909. + goto exit;
  29910. + error = -ENOENT;
  29911. + if (!path->dentry->d_inode)
  29912. + goto exit_dput;
  29913. + if (path->dentry->d_inode->i_op->follow_link)
  29914. + return NULL;
  29915. + error = -ENOTDIR;
  29916. + if (nd->flags & LOOKUP_DIRECTORY) {
  29917. + if (!path->dentry->d_inode->i_op->lookup)
  29918. + goto exit_dput;
  29919. + }
  29920. + path_to_nameidata(path, nd);
  29921. + audit_inode(pathname, nd->path.dentry);
  29922. + goto ok;
  29923. + }
  29924. +
  29925. + /* OK, it's O_CREAT */
  29926. + mutex_lock(&dir->d_inode->i_mutex);
  29927. +
  29928. + path->dentry = lookup_hash(nd);
  29929. + path->mnt = nd->path.mnt;
  29930. +
  29931. + error = PTR_ERR(path->dentry);
  29932. + if (IS_ERR(path->dentry)) {
  29933. + mutex_unlock(&dir->d_inode->i_mutex);
  29934. + goto exit;
  29935. + }
  29936. +
  29937. + if (IS_ERR(nd->intent.open.file)) {
  29938. + error = PTR_ERR(nd->intent.open.file);
  29939. + goto exit_mutex_unlock;
  29940. + }
  29941. +
  29942. + /* Negative dentry, just create the file */
  29943. + if (!path->dentry->d_inode) {
  29944. + /*
  29945. + * This write is needed to ensure that a
  29946. + * ro->rw transition does not occur between
  29947. + * the time when the file is created and when
  29948. + * a permanent write count is taken through
  29949. + * the 'struct file' in nameidata_to_filp().
  29950. + */
  29951. + error = mnt_want_write(nd->path.mnt);
  29952. + if (error)
  29953. + goto exit_mutex_unlock;
  29954. + error = __open_namei_create(nd, path, open_flag, mode);
  29955. + if (error) {
  29956. + mnt_drop_write(nd->path.mnt);
  29957. + goto exit;
  29958. + }
  29959. + filp = nameidata_to_filp(nd);
  29960. + mnt_drop_write(nd->path.mnt);
  29961. + if (!IS_ERR(filp)) {
  29962. + error = ima_file_check(filp, acc_mode);
  29963. + if (error) {
  29964. + fput(filp);
  29965. + filp = ERR_PTR(error);
  29966. + }
  29967. + }
  29968. + return filp;
  29969. + }
  29970. +
  29971. + /*
  29972. + * It already exists.
  29973. + */
  29974. + mutex_unlock(&dir->d_inode->i_mutex);
  29975. + audit_inode(pathname, path->dentry);
  29976. +
  29977. + error = -EEXIST;
  29978. + if (open_flag & O_EXCL)
  29979. + goto exit_dput;
  29980. +
  29981. + if (__follow_mount(path)) {
  29982. + error = -ELOOP;
  29983. + if (open_flag & O_NOFOLLOW)
  29984. + goto exit_dput;
  29985. + }
  29986. +
  29987. + error = -ENOENT;
  29988. + if (!path->dentry->d_inode)
  29989. + goto exit_dput;
  29990. +
  29991. + if (path->dentry->d_inode->i_op->follow_link)
  29992. + return NULL;
  29993. +
  29994. + path_to_nameidata(path, nd);
  29995. + error = -EISDIR;
  29996. + if (S_ISDIR(path->dentry->d_inode->i_mode))
  29997. + goto exit;
  29998. +ok:
  29999. + filp = finish_open(nd, open_flag, acc_mode);
  30000. + return filp;
  30001. +
  30002. +exit_mutex_unlock:
  30003. + mutex_unlock(&dir->d_inode->i_mutex);
  30004. +exit_dput:
  30005. + path_put_conditional(path, nd);
  30006. +exit:
  30007. + if (!IS_ERR(nd->intent.open.file))
  30008. + release_open_intent(nd);
  30009. + path_put(&nd->path);
  30010. + return ERR_PTR(error);
  30011. +}
  30012. +
  30013. +/*
  30014. + * Note that the low bits of the passed in "open_flag"
  30015. + * are not the same as in the local variable "flag". See
  30016. + * open_to_namei_flags() for more details.
  30017. + */
  30018. +struct file *do_filp_open(int dfd, const char *pathname,
  30019. + int open_flag, int mode, int acc_mode)
  30020. +{
  30021. + struct file *filp;
  30022. + struct nameidata nd;
  30023. + int error;
  30024. + struct path path;
  30025. + int count = 0;
  30026. + int flag = open_to_namei_flags(open_flag);
  30027. + int force_reval = 0;
  30028. +
  30029. + if (!(open_flag & O_CREAT))
  30030. + mode = 0;
  30031. +
  30032. + /*
  30033. + * O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only
  30034. + * check for O_DSYNC if the need any syncing at all we enforce it's
  30035. + * always set instead of having to deal with possibly weird behaviour
  30036. + * for malicious applications setting only __O_SYNC.
  30037. + */
  30038. + if (open_flag & __O_SYNC)
  30039. + open_flag |= O_DSYNC;
  30040. +
  30041. + if (!acc_mode)
  30042. + acc_mode = MAY_OPEN | ACC_MODE(open_flag);
  30043. +
  30044. + /* O_TRUNC implies we need access checks for write permissions */
  30045. + if (open_flag & O_TRUNC)
  30046. + acc_mode |= MAY_WRITE;
  30047. +
  30048. + /* Allow the LSM permission hook to distinguish append
  30049. + access from general write access. */
  30050. + if (open_flag & O_APPEND)
  30051. + acc_mode |= MAY_APPEND;
  30052. +
  30053. + /* find the parent */
  30054. +reval:
  30055. + error = path_init(dfd, pathname, LOOKUP_PARENT, &nd);
  30056. + if (error)
  30057. + return ERR_PTR(error);
  30058. + if (force_reval)
  30059. + nd.flags |= LOOKUP_REVAL;
  30060. +
  30061. + current->total_link_count = 0;
  30062. + error = link_path_walk(pathname, &nd);
  30063. + if (error) {
  30064. + filp = ERR_PTR(error);
  30065. + goto out;
  30066. + }
  30067. + if (unlikely(!audit_dummy_context()) && (open_flag & O_CREAT))
  30068. + audit_inode(pathname, nd.path.dentry);
  30069. +
  30070. + /*
  30071. + * We have the parent and last component.
  30072. + */
  30073. +
  30074. + error = -ENFILE;
  30075. + filp = get_empty_filp();
  30076. + if (filp == NULL)
  30077. + goto exit_parent;
  30078. + nd.intent.open.file = filp;
  30079. + filp->f_flags = open_flag;
  30080. + nd.intent.open.flags = flag;
  30081. + nd.intent.open.create_mode = mode;
  30082. + nd.flags &= ~LOOKUP_PARENT;
  30083. + nd.flags |= LOOKUP_OPEN;
  30084. + if (open_flag & O_CREAT) {
  30085. + nd.flags |= LOOKUP_CREATE;
  30086. + if (open_flag & O_EXCL)
  30087. + nd.flags |= LOOKUP_EXCL;
  30088. + }
  30089. + if (open_flag & O_DIRECTORY)
  30090. + nd.flags |= LOOKUP_DIRECTORY;
  30091. + if (!(open_flag & O_NOFOLLOW))
  30092. + nd.flags |= LOOKUP_FOLLOW;
  30093. + filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname);
  30094. + while (unlikely(!filp)) { /* trailing symlink */
  30095. + struct path holder;
  30096. + struct inode *inode = path.dentry->d_inode;
  30097. + void *cookie;
  30098. + error = -ELOOP;
  30099. + /* S_ISDIR part is a temporary automount kludge */
  30100. + if (!(nd.flags & LOOKUP_FOLLOW) && !S_ISDIR(inode->i_mode))
  30101. + goto exit_dput;
  30102. + if (count++ == 32)
  30103. + goto exit_dput;
  30104. + /*
  30105. + * This is subtle. Instead of calling do_follow_link() we do
  30106. + * the thing by hands. The reason is that this way we have zero
  30107. + * link_count and path_walk() (called from ->follow_link)
  30108. + * honoring LOOKUP_PARENT. After that we have the parent and
  30109. + * last component, i.e. we are in the same situation as after
  30110. + * the first path_walk(). Well, almost - if the last component
  30111. + * is normal we get its copy stored in nd->last.name and we will
  30112. + * have to putname() it when we are done. Procfs-like symlinks
  30113. + * just set LAST_BIND.
  30114. + */
  30115. + nd.flags |= LOOKUP_PARENT;
  30116. + error = security_inode_follow_link(path.dentry, &nd);
  30117. + if (error)
  30118. + goto exit_dput;
  30119. + error = __do_follow_link(&path, &nd, &cookie);
  30120. + if (unlikely(error)) {
  30121. + /* nd.path had been dropped */
  30122. + if (!IS_ERR(cookie) && inode->i_op->put_link)
  30123. + inode->i_op->put_link(path.dentry, &nd, cookie);
  30124. + path_put(&path);
  30125. + release_open_intent(&nd);
  30126. + filp = ERR_PTR(error);
  30127. + goto out;
  30128. + }
  30129. + holder = path;
  30130. + nd.flags &= ~LOOKUP_PARENT;
  30131. + filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname);
  30132. + if (inode->i_op->put_link)
  30133. + inode->i_op->put_link(holder.dentry, &nd, cookie);
  30134. + path_put(&holder);
  30135. + }
  30136. +out:
  30137. + if (nd.root.mnt)
  30138. + path_put(&nd.root);
  30139. + if (filp == ERR_PTR(-ESTALE) && !force_reval) {
  30140. + force_reval = 1;
  30141. + goto reval;
  30142. + }
  30143. + return filp;
  30144. +
  30145. +exit_dput:
  30146. + path_put_conditional(&path, &nd);
  30147. + if (!IS_ERR(nd.intent.open.file))
  30148. + release_open_intent(&nd);
  30149. +exit_parent:
  30150. + path_put(&nd.path);
  30151. + filp = ERR_PTR(error);
  30152. + goto out;
  30153. +}
  30154. +
  30155. +/**
  30156. + * filp_open - open file and return file pointer
  30157. + *
  30158. + * @filename: path to open
  30159. + * @flags: open flags as per the open(2) second argument
  30160. + * @mode: mode for the new file if O_CREAT is set, else ignored
  30161. + *
  30162. + * This is the helper to open a file from kernelspace if you really
  30163. + * have to. But in generally you should not do this, so please move
  30164. + * along, nothing to see here..
  30165. + */
  30166. +struct file *filp_open(const char *filename, int flags, int mode)
  30167. +{
  30168. + return do_filp_open(AT_FDCWD, filename, flags, mode, 0);
  30169. +}
  30170. +EXPORT_SYMBOL(filp_open);
  30171. +
  30172. +/**
  30173. + * lookup_create - lookup a dentry, creating it if it doesn't exist
  30174. + * @nd: nameidata info
  30175. + * @is_dir: directory flag
  30176. + *
  30177. + * Simple function to lookup and return a dentry and create it
  30178. + * if it doesn't exist. Is SMP-safe.
  30179. + *
  30180. + * Returns with nd->path.dentry->d_inode->i_mutex locked.
  30181. + */
  30182. +struct dentry *lookup_create(struct nameidata *nd, int is_dir)
  30183. +{
  30184. + struct dentry *dentry = ERR_PTR(-EEXIST);
  30185. +
  30186. + mutex_lock_nested(&nd->path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
  30187. + /*
  30188. + * Yucky last component or no last component at all?
  30189. + * (foo/., foo/.., /////)
  30190. + */
  30191. + if (nd->last_type != LAST_NORM)
  30192. + goto fail;
  30193. + nd->flags &= ~LOOKUP_PARENT;
  30194. + nd->flags |= LOOKUP_CREATE | LOOKUP_EXCL;
  30195. + nd->intent.open.flags = O_EXCL;
  30196. +
  30197. + /*
  30198. + * Do the final lookup.
  30199. + */
  30200. + dentry = lookup_hash(nd);
  30201. + if (IS_ERR(dentry))
  30202. + goto fail;
  30203. +
  30204. + if (dentry->d_inode)
  30205. + goto eexist;
  30206. + /*
  30207. + * Special case - lookup gave negative, but... we had foo/bar/
  30208. + * From the vfs_mknod() POV we just have a negative dentry -
  30209. + * all is fine. Let's be bastards - you had / on the end, you've
  30210. + * been asking for (non-existent) directory. -ENOENT for you.
  30211. + */
  30212. + if (unlikely(!is_dir && nd->last.name[nd->last.len])) {
  30213. + dput(dentry);
  30214. + dentry = ERR_PTR(-ENOENT);
  30215. + }
  30216. + return dentry;
  30217. +eexist:
  30218. + dput(dentry);
  30219. + dentry = ERR_PTR(-EEXIST);
  30220. +fail:
  30221. + return dentry;
  30222. +}
  30223. +EXPORT_SYMBOL_GPL(lookup_create);
  30224. +
  30225. +int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
  30226. +{
  30227. + int error = may_create(dir, dentry);
  30228. +
  30229. + if (error)
  30230. + return error;
  30231. +
  30232. + if ((S_ISCHR(mode) || S_ISBLK(mode)) && !capable(CAP_MKNOD))
  30233. + return -EPERM;
  30234. +
  30235. + if (!dir->i_op->mknod)
  30236. + return -EPERM;
  30237. +
  30238. + error = devcgroup_inode_mknod(mode, dev);
  30239. + if (error)
  30240. + return error;
  30241. +
  30242. + error = security_inode_mknod(dir, dentry, mode, dev);
  30243. + if (error)
  30244. + return error;
  30245. +
  30246. + error = dir->i_op->mknod(dir, dentry, mode, dev);
  30247. + if (!error)
  30248. + fsnotify_create(dir, dentry);
  30249. + return error;
  30250. +}
  30251. +
  30252. +static int may_mknod(mode_t mode)
  30253. +{
  30254. + switch (mode & S_IFMT) {
  30255. + case S_IFREG:
  30256. + case S_IFCHR:
  30257. + case S_IFBLK:
  30258. + case S_IFIFO:
  30259. + case S_IFSOCK:
  30260. + case 0: /* zero mode translates to S_IFREG */
  30261. + return 0;
  30262. + case S_IFDIR:
  30263. + return -EPERM;
  30264. + default:
  30265. + return -EINVAL;
  30266. + }
  30267. +}
  30268. +
  30269. +SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode,
  30270. + unsigned, dev)
  30271. +{
  30272. + int error;
  30273. + char *tmp;
  30274. + struct dentry *dentry;
  30275. + struct nameidata nd;
  30276. +
  30277. + if (S_ISDIR(mode))
  30278. + return -EPERM;
  30279. +
  30280. + error = user_path_parent(dfd, filename, &nd, &tmp);
  30281. + if (error)
  30282. + return error;
  30283. +
  30284. + dentry = lookup_create(&nd, 0);
  30285. + if (IS_ERR(dentry)) {
  30286. + error = PTR_ERR(dentry);
  30287. + goto out_unlock;
  30288. + }
  30289. + if (!IS_POSIXACL(nd.path.dentry->d_inode))
  30290. + mode &= ~current_umask();
  30291. + error = may_mknod(mode);
  30292. + if (error)
  30293. + goto out_dput;
  30294. + error = mnt_want_write(nd.path.mnt);
  30295. + if (error)
  30296. + goto out_dput;
  30297. + error = security_path_mknod(&nd.path, dentry, mode, dev);
  30298. + if (error)
  30299. + goto out_drop_write;
  30300. + switch (mode & S_IFMT) {
  30301. + case 0: case S_IFREG:
  30302. + error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);
  30303. + break;
  30304. + case S_IFCHR: case S_IFBLK:
  30305. + error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,
  30306. + new_decode_dev(dev));
  30307. + break;
  30308. + case S_IFIFO: case S_IFSOCK:
  30309. + error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0);
  30310. + break;
  30311. + }
  30312. +out_drop_write:
  30313. + mnt_drop_write(nd.path.mnt);
  30314. +out_dput:
  30315. + dput(dentry);
  30316. +out_unlock:
  30317. + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
  30318. + path_put(&nd.path);
  30319. + putname(tmp);
  30320. +
  30321. + return error;
  30322. +}
  30323. +
  30324. +SYSCALL_DEFINE3(mknod, const char __user *, filename, int, mode, unsigned, dev)
  30325. +{
  30326. + return sys_mknodat(AT_FDCWD, filename, mode, dev);
  30327. +}
  30328. +
  30329. +int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
  30330. +{
  30331. + int error = may_create(dir, dentry);
  30332. +
  30333. + if (error)
  30334. + return error;
  30335. +
  30336. + if (!dir->i_op->mkdir)
  30337. + return -EPERM;
  30338. +
  30339. + mode &= (S_IRWXUGO|S_ISVTX);
  30340. + error = security_inode_mkdir(dir, dentry, mode);
  30341. + if (error)
  30342. + return error;
  30343. +
  30344. + error = dir->i_op->mkdir(dir, dentry, mode);
  30345. + if (!error)
  30346. + fsnotify_mkdir(dir, dentry);
  30347. + return error;
  30348. +}
  30349. +
  30350. +SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, int, mode)
  30351. +{
  30352. + int error = 0;
  30353. + char * tmp;
  30354. + struct dentry *dentry;
  30355. + struct nameidata nd;
  30356. +
  30357. + error = user_path_parent(dfd, pathname, &nd, &tmp);
  30358. + if (error)
  30359. + goto out_err;
  30360. +
  30361. + dentry = lookup_create(&nd, 1);
  30362. + error = PTR_ERR(dentry);
  30363. + if (IS_ERR(dentry))
  30364. + goto out_unlock;
  30365. +
  30366. + if (!IS_POSIXACL(nd.path.dentry->d_inode))
  30367. + mode &= ~current_umask();
  30368. + error = mnt_want_write(nd.path.mnt);
  30369. + if (error)
  30370. + goto out_dput;
  30371. + error = security_path_mkdir(&nd.path, dentry, mode);
  30372. + if (error)
  30373. + goto out_drop_write;
  30374. + error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
  30375. +out_drop_write:
  30376. + mnt_drop_write(nd.path.mnt);
  30377. +out_dput:
  30378. + dput(dentry);
  30379. +out_unlock:
  30380. + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
  30381. + path_put(&nd.path);
  30382. + putname(tmp);
  30383. +out_err:
  30384. + return error;
  30385. +}
  30386. +
  30387. +SYSCALL_DEFINE2(mkdir, const char __user *, pathname, int, mode)
  30388. +{
  30389. + return sys_mkdirat(AT_FDCWD, pathname, mode);
  30390. +}
  30391. +
  30392. +/*
  30393. + * We try to drop the dentry early: we should have
  30394. + * a usage count of 2 if we're the only user of this
  30395. + * dentry, and if that is true (possibly after pruning
  30396. + * the dcache), then we drop the dentry now.
  30397. + *
  30398. + * A low-level filesystem can, if it choses, legally
  30399. + * do a
  30400. + *
  30401. + * if (!d_unhashed(dentry))
  30402. + * return -EBUSY;
  30403. + *
  30404. + * if it cannot handle the case of removing a directory
  30405. + * that is still in use by something else..
  30406. + */
  30407. +void dentry_unhash(struct dentry *dentry)
  30408. +{
  30409. + dget(dentry);
  30410. + shrink_dcache_parent(dentry);
  30411. + spin_lock(&dcache_lock);
  30412. + spin_lock(&dentry->d_lock);
  30413. + if (atomic_read(&dentry->d_count) == 2)
  30414. + __d_drop(dentry);
  30415. + spin_unlock(&dentry->d_lock);
  30416. + spin_unlock(&dcache_lock);
  30417. +}
  30418. +
  30419. +int vfs_rmdir(struct inode *dir, struct dentry *dentry)
  30420. +{
  30421. + int error = may_delete(dir, dentry, 1);
  30422. +
  30423. + if (error)
  30424. + return error;
  30425. +
  30426. + if (!dir->i_op->rmdir)
  30427. + return -EPERM;
  30428. +
  30429. + mutex_lock(&dentry->d_inode->i_mutex);
  30430. + dentry_unhash(dentry);
  30431. + if (d_mountpoint(dentry))
  30432. + error = -EBUSY;
  30433. + else {
  30434. + error = security_inode_rmdir(dir, dentry);
  30435. + if (!error) {
  30436. + error = dir->i_op->rmdir(dir, dentry);
  30437. + if (!error) {
  30438. + dentry->d_inode->i_flags |= S_DEAD;
  30439. + dont_mount(dentry);
  30440. + }
  30441. + }
  30442. + }
  30443. + mutex_unlock(&dentry->d_inode->i_mutex);
  30444. + if (!error) {
  30445. + d_delete(dentry);
  30446. + }
  30447. + dput(dentry);
  30448. +
  30449. + return error;
  30450. +}
  30451. +
  30452. +static long do_rmdir(int dfd, const char __user *pathname)
  30453. +{
  30454. + int error = 0;
  30455. + char * name;
  30456. + struct dentry *dentry;
  30457. + struct nameidata nd;
  30458. +
  30459. + error = user_path_parent(dfd, pathname, &nd, &name);
  30460. + if (error)
  30461. + return error;
  30462. +
  30463. + switch(nd.last_type) {
  30464. + case LAST_DOTDOT:
  30465. + error = -ENOTEMPTY;
  30466. + goto exit1;
  30467. + case LAST_DOT:
  30468. + error = -EINVAL;
  30469. + goto exit1;
  30470. + case LAST_ROOT:
  30471. + error = -EBUSY;
  30472. + goto exit1;
  30473. + }
  30474. +
  30475. + nd.flags &= ~LOOKUP_PARENT;
  30476. +
  30477. + mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
  30478. + dentry = lookup_hash(&nd);
  30479. + error = PTR_ERR(dentry);
  30480. + if (IS_ERR(dentry))
  30481. + goto exit2;
  30482. + error = mnt_want_write(nd.path.mnt);
  30483. + if (error)
  30484. + goto exit3;
  30485. + error = security_path_rmdir(&nd.path, dentry);
  30486. + if (error)
  30487. + goto exit4;
  30488. + error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
  30489. +exit4:
  30490. + mnt_drop_write(nd.path.mnt);
  30491. +exit3:
  30492. + dput(dentry);
  30493. +exit2:
  30494. + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
  30495. +exit1:
  30496. + path_put(&nd.path);
  30497. + putname(name);
  30498. + return error;
  30499. +}
  30500. +
  30501. +SYSCALL_DEFINE1(rmdir, const char __user *, pathname)
  30502. +{
  30503. + return do_rmdir(AT_FDCWD, pathname);
  30504. +}
  30505. +
  30506. +int vfs_unlink(struct inode *dir, struct dentry *dentry)
  30507. +{
  30508. + int error = may_delete(dir, dentry, 0);
  30509. +
  30510. + if (error)
  30511. + return error;
  30512. +
  30513. + if (!dir->i_op->unlink)
  30514. + return -EPERM;
  30515. +
  30516. + mutex_lock(&dentry->d_inode->i_mutex);
  30517. + if (d_mountpoint(dentry))
  30518. + error = -EBUSY;
  30519. + else {
  30520. + error = security_inode_unlink(dir, dentry);
  30521. + if (!error) {
  30522. + error = dir->i_op->unlink(dir, dentry);
  30523. + if (!error)
  30524. + dont_mount(dentry);
  30525. + }
  30526. + }
  30527. + mutex_unlock(&dentry->d_inode->i_mutex);
  30528. +
  30529. + /* We don't d_delete() NFS sillyrenamed files--they still exist. */
  30530. + if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) {
  30531. + fsnotify_link_count(dentry->d_inode);
  30532. + d_delete(dentry);
  30533. + }
  30534. +
  30535. + return error;
  30536. +}
  30537. +
  30538. +/*
  30539. + * Make sure that the actual truncation of the file will occur outside its
  30540. + * directory's i_mutex. Truncate can take a long time if there is a lot of
  30541. + * writeout happening, and we don't want to prevent access to the directory
  30542. + * while waiting on the I/O.
  30543. + */
  30544. +static long do_unlinkat(int dfd, const char __user *pathname)
  30545. +{
  30546. + int error;
  30547. + char *name;
  30548. + struct dentry *dentry;
  30549. + struct nameidata nd;
  30550. + struct inode *inode = NULL;
  30551. +
  30552. + error = user_path_parent(dfd, pathname, &nd, &name);
  30553. + if (error)
  30554. + return error;
  30555. +
  30556. + error = -EISDIR;
  30557. + if (nd.last_type != LAST_NORM)
  30558. + goto exit1;
  30559. +
  30560. + nd.flags &= ~LOOKUP_PARENT;
  30561. +
  30562. + mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
  30563. + dentry = lookup_hash(&nd);
  30564. + error = PTR_ERR(dentry);
  30565. + if (!IS_ERR(dentry)) {
  30566. + /* Why not before? Because we want correct error value */
  30567. + if (nd.last.name[nd.last.len])
  30568. + goto slashes;
  30569. + inode = dentry->d_inode;
  30570. + if (inode)
  30571. + atomic_inc(&inode->i_count);
  30572. + error = mnt_want_write(nd.path.mnt);
  30573. + if (error)
  30574. + goto exit2;
  30575. + error = security_path_unlink(&nd.path, dentry);
  30576. + if (error)
  30577. + goto exit3;
  30578. + error = vfs_unlink(nd.path.dentry->d_inode, dentry);
  30579. +exit3:
  30580. + mnt_drop_write(nd.path.mnt);
  30581. + exit2:
  30582. + dput(dentry);
  30583. + }
  30584. + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
  30585. + if (inode)
  30586. + iput(inode); /* truncate the inode here */
  30587. +exit1:
  30588. + path_put(&nd.path);
  30589. + putname(name);
  30590. + return error;
  30591. +
  30592. +slashes:
  30593. + error = !dentry->d_inode ? -ENOENT :
  30594. + S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
  30595. + goto exit2;
  30596. +}
  30597. +
  30598. +SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag)
  30599. +{
  30600. + if ((flag & ~AT_REMOVEDIR) != 0)
  30601. + return -EINVAL;
  30602. +
  30603. + if (flag & AT_REMOVEDIR)
  30604. + return do_rmdir(dfd, pathname);
  30605. +
  30606. + return do_unlinkat(dfd, pathname);
  30607. +}
  30608. +
  30609. +SYSCALL_DEFINE1(unlink, const char __user *, pathname)
  30610. +{
  30611. + return do_unlinkat(AT_FDCWD, pathname);
  30612. +}
  30613. +
  30614. +int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
  30615. +{
  30616. + int error = may_create(dir, dentry);
  30617. +
  30618. + if (error)
  30619. + return error;
  30620. +
  30621. + if (!dir->i_op->symlink)
  30622. + return -EPERM;
  30623. +
  30624. + error = security_inode_symlink(dir, dentry, oldname);
  30625. + if (error)
  30626. + return error;
  30627. +
  30628. + error = dir->i_op->symlink(dir, dentry, oldname);
  30629. + if (!error)
  30630. + fsnotify_create(dir, dentry);
  30631. + return error;
  30632. +}
  30633. +
  30634. +SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
  30635. + int, newdfd, const char __user *, newname)
  30636. +{
  30637. + int error;
  30638. + char *from;
  30639. + char *to;
  30640. + struct dentry *dentry;
  30641. + struct nameidata nd;
  30642. +
  30643. + from = getname(oldname);
  30644. + if (IS_ERR(from))
  30645. + return PTR_ERR(from);
  30646. +
  30647. + error = user_path_parent(newdfd, newname, &nd, &to);
  30648. + if (error)
  30649. + goto out_putname;
  30650. +
  30651. + dentry = lookup_create(&nd, 0);
  30652. + error = PTR_ERR(dentry);
  30653. + if (IS_ERR(dentry))
  30654. + goto out_unlock;
  30655. +
  30656. + error = mnt_want_write(nd.path.mnt);
  30657. + if (error)
  30658. + goto out_dput;
  30659. + error = security_path_symlink(&nd.path, dentry, from);
  30660. + if (error)
  30661. + goto out_drop_write;
  30662. + error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
  30663. +out_drop_write:
  30664. + mnt_drop_write(nd.path.mnt);
  30665. +out_dput:
  30666. + dput(dentry);
  30667. +out_unlock:
  30668. + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
  30669. + path_put(&nd.path);
  30670. + putname(to);
  30671. +out_putname:
  30672. + putname(from);
  30673. + return error;
  30674. +}
  30675. +
  30676. +SYSCALL_DEFINE2(symlink, const char __user *, oldname, const char __user *, newname)
  30677. +{
  30678. + return sys_symlinkat(oldname, AT_FDCWD, newname);
  30679. +}
  30680. +
  30681. +int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
  30682. +{
  30683. + struct inode *inode = old_dentry->d_inode;
  30684. + int error;
  30685. +
  30686. + if (!inode)
  30687. + return -ENOENT;
  30688. +
  30689. + error = may_create(dir, new_dentry);
  30690. + if (error)
  30691. + return error;
  30692. +
  30693. + if (dir->i_sb != inode->i_sb)
  30694. + return -EXDEV;
  30695. +
  30696. + /*
  30697. + * A link to an append-only or immutable file cannot be created.
  30698. + */
  30699. + if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
  30700. + return -EPERM;
  30701. + if (!dir->i_op->link)
  30702. + return -EPERM;
  30703. + if (S_ISDIR(inode->i_mode))
  30704. + return -EPERM;
  30705. +
  30706. + error = security_inode_link(old_dentry, dir, new_dentry);
  30707. + if (error)
  30708. + return error;
  30709. +
  30710. + mutex_lock(&inode->i_mutex);
  30711. + error = dir->i_op->link(old_dentry, dir, new_dentry);
  30712. + mutex_unlock(&inode->i_mutex);
  30713. + if (!error)
  30714. + fsnotify_link(dir, inode, new_dentry);
  30715. + return error;
  30716. +}
  30717. +
  30718. +/*
  30719. + * Hardlinks are often used in delicate situations. We avoid
  30720. + * security-related surprises by not following symlinks on the
  30721. + * newname. --KAB
  30722. + *
  30723. + * We don't follow them on the oldname either to be compatible
  30724. + * with linux 2.0, and to avoid hard-linking to directories
  30725. + * and other special files. --ADM
  30726. + */
  30727. +SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
  30728. + int, newdfd, const char __user *, newname, int, flags)
  30729. +{
  30730. + struct dentry *new_dentry;
  30731. + struct nameidata nd;
  30732. + struct path old_path;
  30733. + int error;
  30734. + char *to;
  30735. +
  30736. + if ((flags & ~AT_SYMLINK_FOLLOW) != 0)
  30737. + return -EINVAL;
  30738. +
  30739. + error = user_path_at(olddfd, oldname,
  30740. + flags & AT_SYMLINK_FOLLOW ? LOOKUP_FOLLOW : 0,
  30741. + &old_path);
  30742. + if (error)
  30743. + return error;
  30744. +
  30745. + error = user_path_parent(newdfd, newname, &nd, &to);
  30746. + if (error)
  30747. + goto out;
  30748. + error = -EXDEV;
  30749. + if (old_path.mnt != nd.path.mnt)
  30750. + goto out_release;
  30751. + new_dentry = lookup_create(&nd, 0);
  30752. + error = PTR_ERR(new_dentry);
  30753. + if (IS_ERR(new_dentry))
  30754. + goto out_unlock;
  30755. + error = mnt_want_write(nd.path.mnt);
  30756. + if (error)
  30757. + goto out_dput;
  30758. + error = security_path_link(old_path.dentry, &nd.path, new_dentry);
  30759. + if (error)
  30760. + goto out_drop_write;
  30761. + error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
  30762. +out_drop_write:
  30763. + mnt_drop_write(nd.path.mnt);
  30764. +out_dput:
  30765. + dput(new_dentry);
  30766. +out_unlock:
  30767. + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
  30768. +out_release:
  30769. + path_put(&nd.path);
  30770. + putname(to);
  30771. +out:
  30772. + path_put(&old_path);
  30773. +
  30774. + return error;
  30775. +}
  30776. +
  30777. +SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname)
  30778. +{
  30779. + return sys_linkat(AT_FDCWD, oldname, AT_FDCWD, newname, 0);
  30780. +}
  30781. +
  30782. +/*
  30783. + * The worst of all namespace operations - renaming directory. "Perverted"
  30784. + * doesn't even start to describe it. Somebody in UCB had a heck of a trip...
  30785. + * Problems:
  30786. + * a) we can get into loop creation. Check is done in is_subdir().
  30787. + * b) race potential - two innocent renames can create a loop together.
  30788. + * That's where 4.4 screws up. Current fix: serialization on
  30789. + * sb->s_vfs_rename_mutex. We might be more accurate, but that's another
  30790. + * story.
  30791. + * c) we have to lock _three_ objects - parents and victim (if it exists).
  30792. + * And that - after we got ->i_mutex on parents (until then we don't know
  30793. + * whether the target exists). Solution: try to be smart with locking
  30794. + * order for inodes. We rely on the fact that tree topology may change
  30795. + * only under ->s_vfs_rename_mutex _and_ that parent of the object we
  30796. + * move will be locked. Thus we can rank directories by the tree
  30797. + * (ancestors first) and rank all non-directories after them.
  30798. + * That works since everybody except rename does "lock parent, lookup,
  30799. + * lock child" and rename is under ->s_vfs_rename_mutex.
  30800. + * HOWEVER, it relies on the assumption that any object with ->lookup()
  30801. + * has no more than 1 dentry. If "hybrid" objects will ever appear,
  30802. + * we'd better make sure that there's no link(2) for them.
  30803. + * d) some filesystems don't support opened-but-unlinked directories,
  30804. + * either because of layout or because they are not ready to deal with
  30805. + * all cases correctly. The latter will be fixed (taking this sort of
  30806. + * stuff into VFS), but the former is not going away. Solution: the same
  30807. + * trick as in rmdir().
  30808. + * e) conversion from fhandle to dentry may come in the wrong moment - when
  30809. + * we are removing the target. Solution: we will have to grab ->i_mutex
  30810. + * in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on
  30811. + * ->i_mutex on parents, which works but leads to some truly excessive
  30812. + * locking].
  30813. + */
  30814. +static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
  30815. + struct inode *new_dir, struct dentry *new_dentry)
  30816. +{
  30817. + int error = 0;
  30818. + struct inode *target;
  30819. +
  30820. + /*
  30821. + * If we are going to change the parent - check write permissions,
  30822. + * we'll need to flip '..'.
  30823. + */
  30824. + if (new_dir != old_dir) {
  30825. + error = inode_permission(old_dentry->d_inode, MAY_WRITE);
  30826. + if (error)
  30827. + return error;
  30828. + }
  30829. +
  30830. + error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry);
  30831. + if (error)
  30832. + return error;
  30833. +
  30834. + target = new_dentry->d_inode;
  30835. + if (target)
  30836. + mutex_lock(&target->i_mutex);
  30837. + if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
  30838. + error = -EBUSY;
  30839. + else {
  30840. + if (target)
  30841. + dentry_unhash(new_dentry);
  30842. + error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
  30843. + }
  30844. + if (target) {
  30845. + if (!error) {
  30846. + target->i_flags |= S_DEAD;
  30847. + dont_mount(new_dentry);
  30848. + }
  30849. + mutex_unlock(&target->i_mutex);
  30850. + if (d_unhashed(new_dentry))
  30851. + d_rehash(new_dentry);
  30852. + dput(new_dentry);
  30853. + }
  30854. + if (!error)
  30855. + if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE))
  30856. + d_move(old_dentry,new_dentry);
  30857. + return error;
  30858. +}
  30859. +
  30860. +static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
  30861. + struct inode *new_dir, struct dentry *new_dentry)
  30862. +{
  30863. + struct inode *target;
  30864. + int error;
  30865. +
  30866. + error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry);
  30867. + if (error)
  30868. + return error;
  30869. +
  30870. + dget(new_dentry);
  30871. + target = new_dentry->d_inode;
  30872. + if (target)
  30873. + mutex_lock(&target->i_mutex);
  30874. + if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
  30875. + error = -EBUSY;
  30876. + else
  30877. + error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
  30878. + if (!error) {
  30879. + if (target)
  30880. + dont_mount(new_dentry);
  30881. + if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE))
  30882. + d_move(old_dentry, new_dentry);
  30883. + }
  30884. + if (target)
  30885. + mutex_unlock(&target->i_mutex);
  30886. + dput(new_dentry);
  30887. + return error;
  30888. +}
  30889. +
  30890. +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
  30891. + struct inode *new_dir, struct dentry *new_dentry)
  30892. +{
  30893. + int error;
  30894. + int is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
  30895. + const unsigned char *old_name;
  30896. +
  30897. + if (old_dentry->d_inode == new_dentry->d_inode)
  30898. + return 0;
  30899. +
  30900. + error = may_delete(old_dir, old_dentry, is_dir);
  30901. + if (error)
  30902. + return error;
  30903. +
  30904. + if (!new_dentry->d_inode)
  30905. + error = may_create(new_dir, new_dentry);
  30906. + else
  30907. + error = may_delete(new_dir, new_dentry, is_dir);
  30908. + if (error)
  30909. + return error;
  30910. +
  30911. + if (!old_dir->i_op->rename)
  30912. + return -EPERM;
  30913. +
  30914. + old_name = fsnotify_oldname_init(old_dentry->d_name.name);
  30915. +
  30916. + if (is_dir)
  30917. + error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
  30918. + else
  30919. + error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
  30920. + if (!error)
  30921. + fsnotify_move(old_dir, new_dir, old_name, is_dir,
  30922. + new_dentry->d_inode, old_dentry);
  30923. + fsnotify_oldname_free(old_name);
  30924. +
  30925. + return error;
  30926. +}
  30927. +
  30928. +SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
  30929. + int, newdfd, const char __user *, newname)
  30930. +{
  30931. + struct dentry *old_dir, *new_dir;
  30932. + struct dentry *old_dentry, *new_dentry;
  30933. + struct dentry *trap;
  30934. + struct nameidata oldnd, newnd;
  30935. + char *from;
  30936. + char *to;
  30937. + int error;
  30938. +
  30939. + error = user_path_parent(olddfd, oldname, &oldnd, &from);
  30940. + if (error)
  30941. + goto exit;
  30942. +
  30943. + error = user_path_parent(newdfd, newname, &newnd, &to);
  30944. + if (error)
  30945. + goto exit1;
  30946. +
  30947. + error = -EXDEV;
  30948. + if (oldnd.path.mnt != newnd.path.mnt)
  30949. + goto exit2;
  30950. +
  30951. + old_dir = oldnd.path.dentry;
  30952. + error = -EBUSY;
  30953. + if (oldnd.last_type != LAST_NORM)
  30954. + goto exit2;
  30955. +
  30956. + new_dir = newnd.path.dentry;
  30957. + if (newnd.last_type != LAST_NORM)
  30958. + goto exit2;
  30959. +
  30960. + oldnd.flags &= ~LOOKUP_PARENT;
  30961. + newnd.flags &= ~LOOKUP_PARENT;
  30962. + newnd.flags |= LOOKUP_RENAME_TARGET;
  30963. +
  30964. + trap = lock_rename(new_dir, old_dir);
  30965. +
  30966. + old_dentry = lookup_hash(&oldnd);
  30967. + error = PTR_ERR(old_dentry);
  30968. + if (IS_ERR(old_dentry))
  30969. + goto exit3;
  30970. + /* source must exist */
  30971. + error = -ENOENT;
  30972. + if (!old_dentry->d_inode)
  30973. + goto exit4;
  30974. + /* unless the source is a directory trailing slashes give -ENOTDIR */
  30975. + if (!S_ISDIR(old_dentry->d_inode->i_mode)) {
  30976. + error = -ENOTDIR;
  30977. + if (oldnd.last.name[oldnd.last.len])
  30978. + goto exit4;
  30979. + if (newnd.last.name[newnd.last.len])
  30980. + goto exit4;
  30981. + }
  30982. + /* source should not be ancestor of target */
  30983. + error = -EINVAL;
  30984. + if (old_dentry == trap)
  30985. + goto exit4;
  30986. + new_dentry = lookup_hash(&newnd);
  30987. + error = PTR_ERR(new_dentry);
  30988. + if (IS_ERR(new_dentry))
  30989. + goto exit4;
  30990. + /* target should not be an ancestor of source */
  30991. + error = -ENOTEMPTY;
  30992. + if (new_dentry == trap)
  30993. + goto exit5;
  30994. +
  30995. + error = mnt_want_write(oldnd.path.mnt);
  30996. + if (error)
  30997. + goto exit5;
  30998. + error = security_path_rename(&oldnd.path, old_dentry,
  30999. + &newnd.path, new_dentry);
  31000. + if (error)
  31001. + goto exit6;
  31002. + error = vfs_rename(old_dir->d_inode, old_dentry,
  31003. + new_dir->d_inode, new_dentry);
  31004. +exit6:
  31005. + mnt_drop_write(oldnd.path.mnt);
  31006. +exit5:
  31007. + dput(new_dentry);
  31008. +exit4:
  31009. + dput(old_dentry);
  31010. +exit3:
  31011. + unlock_rename(new_dir, old_dir);
  31012. +exit2:
  31013. + path_put(&newnd.path);
  31014. + putname(to);
  31015. +exit1:
  31016. + path_put(&oldnd.path);
  31017. + putname(from);
  31018. +exit:
  31019. + return error;
  31020. +}
  31021. +
  31022. +SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newname)
  31023. +{
  31024. + return sys_renameat(AT_FDCWD, oldname, AT_FDCWD, newname);
  31025. +}
  31026. +
  31027. +int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const char *link)
  31028. +{
  31029. + int len;
  31030. +
  31031. + len = PTR_ERR(link);
  31032. + if (IS_ERR(link))
  31033. + goto out;
  31034. +
  31035. + len = strlen(link);
  31036. + if (len > (unsigned) buflen)
  31037. + len = buflen;
  31038. + if (copy_to_user(buffer, link, len))
  31039. + len = -EFAULT;
  31040. +out:
  31041. + return len;
  31042. +}
  31043. +
  31044. +/*
  31045. + * A helper for ->readlink(). This should be used *ONLY* for symlinks that
  31046. + * have ->follow_link() touching nd only in nd_set_link(). Using (or not
  31047. + * using) it for any given inode is up to filesystem.
  31048. + */
  31049. +int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen)
  31050. +{
  31051. + struct nameidata nd;
  31052. + void *cookie;
  31053. + int res;
  31054. +
  31055. + nd.depth = 0;
  31056. + cookie = dentry->d_inode->i_op->follow_link(dentry, &nd);
  31057. + if (IS_ERR(cookie))
  31058. + return PTR_ERR(cookie);
  31059. +
  31060. + res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd));
  31061. + if (dentry->d_inode->i_op->put_link)
  31062. + dentry->d_inode->i_op->put_link(dentry, &nd, cookie);
  31063. + return res;
  31064. +}
  31065. +
  31066. +int vfs_follow_link(struct nameidata *nd, const char *link)
  31067. +{
  31068. + return __vfs_follow_link(nd, link);
  31069. +}
  31070. +
  31071. +/* get the link contents into pagecache */
  31072. +static char *page_getlink(struct dentry * dentry, struct page **ppage)
  31073. +{
  31074. + char *kaddr;
  31075. + struct page *page;
  31076. + struct address_space *mapping = dentry->d_inode->i_mapping;
  31077. + page = read_mapping_page(mapping, 0, NULL);
  31078. + if (IS_ERR(page))
  31079. + return (char*)page;
  31080. + *ppage = page;
  31081. + kaddr = kmap(page);
  31082. + nd_terminate_link(kaddr, dentry->d_inode->i_size, PAGE_SIZE - 1);
  31083. + return kaddr;
  31084. +}
  31085. +
  31086. +int page_readlink(struct dentry *dentry, char __user *buffer, int buflen)
  31087. +{
  31088. + struct page *page = NULL;
  31089. + char *s = page_getlink(dentry, &page);
  31090. + int res = vfs_readlink(dentry,buffer,buflen,s);
  31091. + if (page) {
  31092. + kunmap(page);
  31093. + page_cache_release(page);
  31094. + }
  31095. + return res;
  31096. +}
  31097. +
  31098. +void *page_follow_link_light(struct dentry *dentry, struct nameidata *nd)
  31099. +{
  31100. + struct page *page = NULL;
  31101. + nd_set_link(nd, page_getlink(dentry, &page));
  31102. + return page;
  31103. +}
  31104. +
  31105. +void page_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
  31106. +{
  31107. + struct page *page = cookie;
  31108. +
  31109. + if (page) {
  31110. + kunmap(page);
  31111. + page_cache_release(page);
  31112. + }
  31113. +}
  31114. +
  31115. +/*
  31116. + * The nofs argument instructs pagecache_write_begin to pass AOP_FLAG_NOFS
  31117. + */
  31118. +int __page_symlink(struct inode *inode, const char *symname, int len, int nofs)
  31119. +{
  31120. + struct address_space *mapping = inode->i_mapping;
  31121. + struct page *page;
  31122. + void *fsdata;
  31123. + int err;
  31124. + char *kaddr;
  31125. + unsigned int flags = AOP_FLAG_UNINTERRUPTIBLE;
  31126. + if (nofs)
  31127. + flags |= AOP_FLAG_NOFS;
  31128. +
  31129. +retry:
  31130. + err = pagecache_write_begin(NULL, mapping, 0, len-1,
  31131. + flags, &page, &fsdata);
  31132. + if (err)
  31133. + goto fail;
  31134. +
  31135. + kaddr = kmap_atomic(page, KM_USER0);
  31136. + memcpy(kaddr, symname, len-1);
  31137. + kunmap_atomic(kaddr, KM_USER0);
  31138. +
  31139. + err = pagecache_write_end(NULL, mapping, 0, len-1, len-1,
  31140. + page, fsdata);
  31141. + if (err < 0)
  31142. + goto fail;
  31143. + if (err < len-1)
  31144. + goto retry;
  31145. +
  31146. + mark_inode_dirty(inode);
  31147. + return 0;
  31148. +fail:
  31149. + return err;
  31150. +}
  31151. +
  31152. +int page_symlink(struct inode *inode, const char *symname, int len)
  31153. +{
  31154. + return __page_symlink(inode, symname, len,
  31155. + !(mapping_gfp_mask(inode->i_mapping) & __GFP_FS));
  31156. +}
  31157. +
  31158. +const struct inode_operations page_symlink_inode_operations = {
  31159. + .readlink = generic_readlink,
  31160. + .follow_link = page_follow_link_light,
  31161. + .put_link = page_put_link,
  31162. +};
  31163. +
  31164. +EXPORT_SYMBOL(user_path_at);
  31165. +EXPORT_SYMBOL(follow_down);
  31166. +EXPORT_SYMBOL(follow_up);
  31167. +EXPORT_SYMBOL(get_write_access); /* binfmt_aout */
  31168. +EXPORT_SYMBOL(getname);
  31169. +EXPORT_SYMBOL(lock_rename);
  31170. +EXPORT_SYMBOL(lookup_one_len);
  31171. +EXPORT_SYMBOL(page_follow_link_light);
  31172. +EXPORT_SYMBOL(page_put_link);
  31173. +EXPORT_SYMBOL(page_readlink);
  31174. +EXPORT_SYMBOL(__page_symlink);
  31175. +EXPORT_SYMBOL(page_symlink);
  31176. +EXPORT_SYMBOL(page_symlink_inode_operations);
  31177. +EXPORT_SYMBOL(path_lookup);
  31178. +EXPORT_SYMBOL(kern_path);
  31179. +EXPORT_SYMBOL(vfs_path_lookup);
  31180. +EXPORT_SYMBOL(inode_permission);
  31181. +EXPORT_SYMBOL(file_permission);
  31182. +EXPORT_SYMBOL(unlock_rename);
  31183. +EXPORT_SYMBOL(vfs_create);
  31184. +EXPORT_SYMBOL(vfs_follow_link);
  31185. +EXPORT_SYMBOL(vfs_link);
  31186. +EXPORT_SYMBOL(vfs_mkdir);
  31187. +EXPORT_SYMBOL(vfs_mknod);
  31188. +EXPORT_SYMBOL(generic_permission);
  31189. +EXPORT_SYMBOL(vfs_readlink);
  31190. +EXPORT_SYMBOL(vfs_rename);
  31191. +EXPORT_SYMBOL(vfs_rmdir);
  31192. +EXPORT_SYMBOL(vfs_symlink);
  31193. +EXPORT_SYMBOL(vfs_unlink);
  31194. +EXPORT_SYMBOL(dentry_unhash);
  31195. +EXPORT_SYMBOL(generic_readlink);
  31196. diff -Nur linux-2.6.36.orig/fs/namespace.c linux-2.6.36/fs/namespace.c
  31197. --- linux-2.6.36.orig/fs/namespace.c 2010-10-20 22:30:22.000000000 +0200
  31198. +++ linux-2.6.36/fs/namespace.c 2011-01-10 19:52:38.000000000 +0100
  31199. @@ -1322,6 +1322,7 @@
  31200. }
  31201. return 0;
  31202. }
  31203. +EXPORT_SYMBOL(iterate_mounts);
  31204. static void cleanup_group_ids(struct vfsmount *mnt, struct vfsmount *end)
  31205. {
  31206. diff -Nur linux-2.6.36.orig/fs/notify/group.c linux-2.6.36/fs/notify/group.c
  31207. --- linux-2.6.36.orig/fs/notify/group.c 2010-10-20 22:30:22.000000000 +0200
  31208. +++ linux-2.6.36/fs/notify/group.c 2011-01-10 19:52:38.000000000 +0100
  31209. @@ -22,6 +22,7 @@
  31210. #include <linux/srcu.h>
  31211. #include <linux/rculist.h>
  31212. #include <linux/wait.h>
  31213. +#include <linux/module.h>
  31214. #include <linux/fsnotify_backend.h>
  31215. #include "fsnotify.h"
  31216. @@ -70,6 +71,7 @@
  31217. if (atomic_dec_and_test(&group->refcnt))
  31218. fsnotify_destroy_group(group);
  31219. }
  31220. +EXPORT_SYMBOL(fsnotify_put_group);
  31221. /*
  31222. * Create a new fsnotify_group and hold a reference for the group returned.
  31223. @@ -102,3 +104,4 @@
  31224. return group;
  31225. }
  31226. +EXPORT_SYMBOL(fsnotify_alloc_group);
  31227. diff -Nur linux-2.6.36.orig/fs/notify/mark.c linux-2.6.36/fs/notify/mark.c
  31228. --- linux-2.6.36.orig/fs/notify/mark.c 2010-10-20 22:30:22.000000000 +0200
  31229. +++ linux-2.6.36/fs/notify/mark.c 2011-01-10 19:52:38.000000000 +0100
  31230. @@ -113,6 +113,7 @@
  31231. if (atomic_dec_and_test(&mark->refcnt))
  31232. mark->free_mark(mark);
  31233. }
  31234. +EXPORT_SYMBOL(fsnotify_put_mark);
  31235. /*
  31236. * Any time a mark is getting freed we end up here.
  31237. @@ -190,6 +191,7 @@
  31238. if (unlikely(atomic_dec_and_test(&group->num_marks)))
  31239. fsnotify_final_destroy_group(group);
  31240. }
  31241. +EXPORT_SYMBOL(fsnotify_destroy_mark);
  31242. void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask)
  31243. {
  31244. @@ -277,6 +279,7 @@
  31245. return ret;
  31246. }
  31247. +EXPORT_SYMBOL(fsnotify_add_mark);
  31248. /*
  31249. * clear any marks in a group in which mark->flags & flags is true
  31250. @@ -332,6 +335,7 @@
  31251. atomic_set(&mark->refcnt, 1);
  31252. mark->free_mark = free_mark;
  31253. }
  31254. +EXPORT_SYMBOL(fsnotify_init_mark);
  31255. static int fsnotify_mark_destroy(void *ignored)
  31256. {
  31257. diff -Nur linux-2.6.36.orig/fs/open.c linux-2.6.36/fs/open.c
  31258. --- linux-2.6.36.orig/fs/open.c 2010-10-20 22:30:22.000000000 +0200
  31259. +++ linux-2.6.36/fs/open.c 2011-01-10 19:52:38.000000000 +0100
  31260. @@ -60,6 +60,7 @@
  31261. mutex_unlock(&dentry->d_inode->i_mutex);
  31262. return ret;
  31263. }
  31264. +EXPORT_SYMBOL(do_truncate);
  31265. static long do_sys_truncate(const char __user *pathname, loff_t length)
  31266. {
  31267. diff -Nur linux-2.6.36.orig/fs/splice.c linux-2.6.36/fs/splice.c
  31268. --- linux-2.6.36.orig/fs/splice.c 2010-10-20 22:30:22.000000000 +0200
  31269. +++ linux-2.6.36/fs/splice.c 2011-01-10 19:52:38.000000000 +0100
  31270. @@ -1092,8 +1092,8 @@
  31271. /*
  31272. * Attempt to initiate a splice from pipe to file.
  31273. */
  31274. -static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  31275. - loff_t *ppos, size_t len, unsigned int flags)
  31276. +long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  31277. + loff_t *ppos, size_t len, unsigned int flags)
  31278. {
  31279. ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
  31280. loff_t *, size_t, unsigned int);
  31281. @@ -1116,13 +1116,14 @@
  31282. return splice_write(pipe, out, ppos, len, flags);
  31283. }
  31284. +EXPORT_SYMBOL(do_splice_from);
  31285. /*
  31286. * Attempt to initiate a splice from a file to a pipe.
  31287. */
  31288. -static long do_splice_to(struct file *in, loff_t *ppos,
  31289. - struct pipe_inode_info *pipe, size_t len,
  31290. - unsigned int flags)
  31291. +long do_splice_to(struct file *in, loff_t *ppos,
  31292. + struct pipe_inode_info *pipe, size_t len,
  31293. + unsigned int flags)
  31294. {
  31295. ssize_t (*splice_read)(struct file *, loff_t *,
  31296. struct pipe_inode_info *, size_t, unsigned int);
  31297. @@ -1142,6 +1143,7 @@
  31298. return splice_read(in, ppos, pipe, len, flags);
  31299. }
  31300. +EXPORT_SYMBOL(do_splice_to);
  31301. /**
  31302. * splice_direct_to_actor - splices data directly between two non-pipes
  31303. diff -Nur linux-2.6.36.orig/fs/splice.c.orig linux-2.6.36/fs/splice.c.orig
  31304. --- linux-2.6.36.orig/fs/splice.c.orig 1970-01-01 01:00:00.000000000 +0100
  31305. +++ linux-2.6.36/fs/splice.c.orig 2011-01-10 19:52:38.000000000 +0100
  31306. @@ -0,0 +1,2076 @@
  31307. +/*
  31308. + * "splice": joining two ropes together by interweaving their strands.
  31309. + *
  31310. + * This is the "extended pipe" functionality, where a pipe is used as
  31311. + * an arbitrary in-memory buffer. Think of a pipe as a small kernel
  31312. + * buffer that you can use to transfer data from one end to the other.
  31313. + *
  31314. + * The traditional unix read/write is extended with a "splice()" operation
  31315. + * that transfers data buffers to or from a pipe buffer.
  31316. + *
  31317. + * Named by Larry McVoy, original implementation from Linus, extended by
  31318. + * Jens to support splicing to files, network, direct splicing, etc and
  31319. + * fixing lots of bugs.
  31320. + *
  31321. + * Copyright (C) 2005-2006 Jens Axboe <axboe@kernel.dk>
  31322. + * Copyright (C) 2005-2006 Linus Torvalds <torvalds@osdl.org>
  31323. + * Copyright (C) 2006 Ingo Molnar <mingo@elte.hu>
  31324. + *
  31325. + */
  31326. +#include <linux/fs.h>
  31327. +#include <linux/file.h>
  31328. +#include <linux/pagemap.h>
  31329. +#include <linux/splice.h>
  31330. +#include <linux/memcontrol.h>
  31331. +#include <linux/mm_inline.h>
  31332. +#include <linux/swap.h>
  31333. +#include <linux/writeback.h>
  31334. +#include <linux/buffer_head.h>
  31335. +#include <linux/module.h>
  31336. +#include <linux/syscalls.h>
  31337. +#include <linux/uio.h>
  31338. +#include <linux/security.h>
  31339. +#include <linux/gfp.h>
  31340. +
  31341. +/*
  31342. + * Attempt to steal a page from a pipe buffer. This should perhaps go into
  31343. + * a vm helper function, it's already simplified quite a bit by the
  31344. + * addition of remove_mapping(). If success is returned, the caller may
  31345. + * attempt to reuse this page for another destination.
  31346. + */
  31347. +static int page_cache_pipe_buf_steal(struct pipe_inode_info *pipe,
  31348. + struct pipe_buffer *buf)
  31349. +{
  31350. + struct page *page = buf->page;
  31351. + struct address_space *mapping;
  31352. +
  31353. + lock_page(page);
  31354. +
  31355. + mapping = page_mapping(page);
  31356. + if (mapping) {
  31357. + WARN_ON(!PageUptodate(page));
  31358. +
  31359. + /*
  31360. + * At least for ext2 with nobh option, we need to wait on
  31361. + * writeback completing on this page, since we'll remove it
  31362. + * from the pagecache. Otherwise truncate wont wait on the
  31363. + * page, allowing the disk blocks to be reused by someone else
  31364. + * before we actually wrote our data to them. fs corruption
  31365. + * ensues.
  31366. + */
  31367. + wait_on_page_writeback(page);
  31368. +
  31369. + if (page_has_private(page) &&
  31370. + !try_to_release_page(page, GFP_KERNEL))
  31371. + goto out_unlock;
  31372. +
  31373. + /*
  31374. + * If we succeeded in removing the mapping, set LRU flag
  31375. + * and return good.
  31376. + */
  31377. + if (remove_mapping(mapping, page)) {
  31378. + buf->flags |= PIPE_BUF_FLAG_LRU;
  31379. + return 0;
  31380. + }
  31381. + }
  31382. +
  31383. + /*
  31384. + * Raced with truncate or failed to remove page from current
  31385. + * address space, unlock and return failure.
  31386. + */
  31387. +out_unlock:
  31388. + unlock_page(page);
  31389. + return 1;
  31390. +}
  31391. +
  31392. +static void page_cache_pipe_buf_release(struct pipe_inode_info *pipe,
  31393. + struct pipe_buffer *buf)
  31394. +{
  31395. + page_cache_release(buf->page);
  31396. + buf->flags &= ~PIPE_BUF_FLAG_LRU;
  31397. +}
  31398. +
  31399. +/*
  31400. + * Check whether the contents of buf is OK to access. Since the content
  31401. + * is a page cache page, IO may be in flight.
  31402. + */
  31403. +static int page_cache_pipe_buf_confirm(struct pipe_inode_info *pipe,
  31404. + struct pipe_buffer *buf)
  31405. +{
  31406. + struct page *page = buf->page;
  31407. + int err;
  31408. +
  31409. + if (!PageUptodate(page)) {
  31410. + lock_page(page);
  31411. +
  31412. + /*
  31413. + * Page got truncated/unhashed. This will cause a 0-byte
  31414. + * splice, if this is the first page.
  31415. + */
  31416. + if (!page->mapping) {
  31417. + err = -ENODATA;
  31418. + goto error;
  31419. + }
  31420. +
  31421. + /*
  31422. + * Uh oh, read-error from disk.
  31423. + */
  31424. + if (!PageUptodate(page)) {
  31425. + err = -EIO;
  31426. + goto error;
  31427. + }
  31428. +
  31429. + /*
  31430. + * Page is ok afterall, we are done.
  31431. + */
  31432. + unlock_page(page);
  31433. + }
  31434. +
  31435. + return 0;
  31436. +error:
  31437. + unlock_page(page);
  31438. + return err;
  31439. +}
  31440. +
  31441. +static const struct pipe_buf_operations page_cache_pipe_buf_ops = {
  31442. + .can_merge = 0,
  31443. + .map = generic_pipe_buf_map,
  31444. + .unmap = generic_pipe_buf_unmap,
  31445. + .confirm = page_cache_pipe_buf_confirm,
  31446. + .release = page_cache_pipe_buf_release,
  31447. + .steal = page_cache_pipe_buf_steal,
  31448. + .get = generic_pipe_buf_get,
  31449. +};
  31450. +
  31451. +static int user_page_pipe_buf_steal(struct pipe_inode_info *pipe,
  31452. + struct pipe_buffer *buf)
  31453. +{
  31454. + if (!(buf->flags & PIPE_BUF_FLAG_GIFT))
  31455. + return 1;
  31456. +
  31457. + buf->flags |= PIPE_BUF_FLAG_LRU;
  31458. + return generic_pipe_buf_steal(pipe, buf);
  31459. +}
  31460. +
  31461. +static const struct pipe_buf_operations user_page_pipe_buf_ops = {
  31462. + .can_merge = 0,
  31463. + .map = generic_pipe_buf_map,
  31464. + .unmap = generic_pipe_buf_unmap,
  31465. + .confirm = generic_pipe_buf_confirm,
  31466. + .release = page_cache_pipe_buf_release,
  31467. + .steal = user_page_pipe_buf_steal,
  31468. + .get = generic_pipe_buf_get,
  31469. +};
  31470. +
  31471. +/**
  31472. + * splice_to_pipe - fill passed data into a pipe
  31473. + * @pipe: pipe to fill
  31474. + * @spd: data to fill
  31475. + *
  31476. + * Description:
  31477. + * @spd contains a map of pages and len/offset tuples, along with
  31478. + * the struct pipe_buf_operations associated with these pages. This
  31479. + * function will link that data to the pipe.
  31480. + *
  31481. + */
  31482. +ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
  31483. + struct splice_pipe_desc *spd)
  31484. +{
  31485. + unsigned int spd_pages = spd->nr_pages;
  31486. + int ret, do_wakeup, page_nr;
  31487. +
  31488. + ret = 0;
  31489. + do_wakeup = 0;
  31490. + page_nr = 0;
  31491. +
  31492. + pipe_lock(pipe);
  31493. +
  31494. + for (;;) {
  31495. + if (!pipe->readers) {
  31496. + send_sig(SIGPIPE, current, 0);
  31497. + if (!ret)
  31498. + ret = -EPIPE;
  31499. + break;
  31500. + }
  31501. +
  31502. + if (pipe->nrbufs < pipe->buffers) {
  31503. + int newbuf = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1);
  31504. + struct pipe_buffer *buf = pipe->bufs + newbuf;
  31505. +
  31506. + buf->page = spd->pages[page_nr];
  31507. + buf->offset = spd->partial[page_nr].offset;
  31508. + buf->len = spd->partial[page_nr].len;
  31509. + buf->private = spd->partial[page_nr].private;
  31510. + buf->ops = spd->ops;
  31511. + if (spd->flags & SPLICE_F_GIFT)
  31512. + buf->flags |= PIPE_BUF_FLAG_GIFT;
  31513. +
  31514. + pipe->nrbufs++;
  31515. + page_nr++;
  31516. + ret += buf->len;
  31517. +
  31518. + if (pipe->inode)
  31519. + do_wakeup = 1;
  31520. +
  31521. + if (!--spd->nr_pages)
  31522. + break;
  31523. + if (pipe->nrbufs < pipe->buffers)
  31524. + continue;
  31525. +
  31526. + break;
  31527. + }
  31528. +
  31529. + if (spd->flags & SPLICE_F_NONBLOCK) {
  31530. + if (!ret)
  31531. + ret = -EAGAIN;
  31532. + break;
  31533. + }
  31534. +
  31535. + if (signal_pending(current)) {
  31536. + if (!ret)
  31537. + ret = -ERESTARTSYS;
  31538. + break;
  31539. + }
  31540. +
  31541. + if (do_wakeup) {
  31542. + smp_mb();
  31543. + if (waitqueue_active(&pipe->wait))
  31544. + wake_up_interruptible_sync(&pipe->wait);
  31545. + kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
  31546. + do_wakeup = 0;
  31547. + }
  31548. +
  31549. + pipe->waiting_writers++;
  31550. + pipe_wait(pipe);
  31551. + pipe->waiting_writers--;
  31552. + }
  31553. +
  31554. + pipe_unlock(pipe);
  31555. +
  31556. + if (do_wakeup) {
  31557. + smp_mb();
  31558. + if (waitqueue_active(&pipe->wait))
  31559. + wake_up_interruptible(&pipe->wait);
  31560. + kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
  31561. + }
  31562. +
  31563. + while (page_nr < spd_pages)
  31564. + spd->spd_release(spd, page_nr++);
  31565. +
  31566. + return ret;
  31567. +}
  31568. +
  31569. +static void spd_release_page(struct splice_pipe_desc *spd, unsigned int i)
  31570. +{
  31571. + page_cache_release(spd->pages[i]);
  31572. +}
  31573. +
  31574. +/*
  31575. + * Check if we need to grow the arrays holding pages and partial page
  31576. + * descriptions.
  31577. + */
  31578. +int splice_grow_spd(struct pipe_inode_info *pipe, struct splice_pipe_desc *spd)
  31579. +{
  31580. + if (pipe->buffers <= PIPE_DEF_BUFFERS)
  31581. + return 0;
  31582. +
  31583. + spd->pages = kmalloc(pipe->buffers * sizeof(struct page *), GFP_KERNEL);
  31584. + spd->partial = kmalloc(pipe->buffers * sizeof(struct partial_page), GFP_KERNEL);
  31585. +
  31586. + if (spd->pages && spd->partial)
  31587. + return 0;
  31588. +
  31589. + kfree(spd->pages);
  31590. + kfree(spd->partial);
  31591. + return -ENOMEM;
  31592. +}
  31593. +
  31594. +void splice_shrink_spd(struct pipe_inode_info *pipe,
  31595. + struct splice_pipe_desc *spd)
  31596. +{
  31597. + if (pipe->buffers <= PIPE_DEF_BUFFERS)
  31598. + return;
  31599. +
  31600. + kfree(spd->pages);
  31601. + kfree(spd->partial);
  31602. +}
  31603. +
  31604. +static int
  31605. +__generic_file_splice_read(struct file *in, loff_t *ppos,
  31606. + struct pipe_inode_info *pipe, size_t len,
  31607. + unsigned int flags)
  31608. +{
  31609. + struct address_space *mapping = in->f_mapping;
  31610. + unsigned int loff, nr_pages, req_pages;
  31611. + struct page *pages[PIPE_DEF_BUFFERS];
  31612. + struct partial_page partial[PIPE_DEF_BUFFERS];
  31613. + struct page *page;
  31614. + pgoff_t index, end_index;
  31615. + loff_t isize;
  31616. + int error, page_nr;
  31617. + struct splice_pipe_desc spd = {
  31618. + .pages = pages,
  31619. + .partial = partial,
  31620. + .flags = flags,
  31621. + .ops = &page_cache_pipe_buf_ops,
  31622. + .spd_release = spd_release_page,
  31623. + };
  31624. +
  31625. + if (splice_grow_spd(pipe, &spd))
  31626. + return -ENOMEM;
  31627. +
  31628. + index = *ppos >> PAGE_CACHE_SHIFT;
  31629. + loff = *ppos & ~PAGE_CACHE_MASK;
  31630. + req_pages = (len + loff + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
  31631. + nr_pages = min(req_pages, pipe->buffers);
  31632. +
  31633. + /*
  31634. + * Lookup the (hopefully) full range of pages we need.
  31635. + */
  31636. + spd.nr_pages = find_get_pages_contig(mapping, index, nr_pages, spd.pages);
  31637. + index += spd.nr_pages;
  31638. +
  31639. + /*
  31640. + * If find_get_pages_contig() returned fewer pages than we needed,
  31641. + * readahead/allocate the rest and fill in the holes.
  31642. + */
  31643. + if (spd.nr_pages < nr_pages)
  31644. + page_cache_sync_readahead(mapping, &in->f_ra, in,
  31645. + index, req_pages - spd.nr_pages);
  31646. +
  31647. + error = 0;
  31648. + while (spd.nr_pages < nr_pages) {
  31649. + /*
  31650. + * Page could be there, find_get_pages_contig() breaks on
  31651. + * the first hole.
  31652. + */
  31653. + page = find_get_page(mapping, index);
  31654. + if (!page) {
  31655. + /*
  31656. + * page didn't exist, allocate one.
  31657. + */
  31658. + page = page_cache_alloc_cold(mapping);
  31659. + if (!page)
  31660. + break;
  31661. +
  31662. + error = add_to_page_cache_lru(page, mapping, index,
  31663. + GFP_KERNEL);
  31664. + if (unlikely(error)) {
  31665. + page_cache_release(page);
  31666. + if (error == -EEXIST)
  31667. + continue;
  31668. + break;
  31669. + }
  31670. + /*
  31671. + * add_to_page_cache() locks the page, unlock it
  31672. + * to avoid convoluting the logic below even more.
  31673. + */
  31674. + unlock_page(page);
  31675. + }
  31676. +
  31677. + spd.pages[spd.nr_pages++] = page;
  31678. + index++;
  31679. + }
  31680. +
  31681. + /*
  31682. + * Now loop over the map and see if we need to start IO on any
  31683. + * pages, fill in the partial map, etc.
  31684. + */
  31685. + index = *ppos >> PAGE_CACHE_SHIFT;
  31686. + nr_pages = spd.nr_pages;
  31687. + spd.nr_pages = 0;
  31688. + for (page_nr = 0; page_nr < nr_pages; page_nr++) {
  31689. + unsigned int this_len;
  31690. +
  31691. + if (!len)
  31692. + break;
  31693. +
  31694. + /*
  31695. + * this_len is the max we'll use from this page
  31696. + */
  31697. + this_len = min_t(unsigned long, len, PAGE_CACHE_SIZE - loff);
  31698. + page = spd.pages[page_nr];
  31699. +
  31700. + if (PageReadahead(page))
  31701. + page_cache_async_readahead(mapping, &in->f_ra, in,
  31702. + page, index, req_pages - page_nr);
  31703. +
  31704. + /*
  31705. + * If the page isn't uptodate, we may need to start io on it
  31706. + */
  31707. + if (!PageUptodate(page)) {
  31708. + lock_page(page);
  31709. +
  31710. + /*
  31711. + * Page was truncated, or invalidated by the
  31712. + * filesystem. Redo the find/create, but this time the
  31713. + * page is kept locked, so there's no chance of another
  31714. + * race with truncate/invalidate.
  31715. + */
  31716. + if (!page->mapping) {
  31717. + unlock_page(page);
  31718. + page = find_or_create_page(mapping, index,
  31719. + mapping_gfp_mask(mapping));
  31720. +
  31721. + if (!page) {
  31722. + error = -ENOMEM;
  31723. + break;
  31724. + }
  31725. + page_cache_release(spd.pages[page_nr]);
  31726. + spd.pages[page_nr] = page;
  31727. + }
  31728. + /*
  31729. + * page was already under io and is now done, great
  31730. + */
  31731. + if (PageUptodate(page)) {
  31732. + unlock_page(page);
  31733. + goto fill_it;
  31734. + }
  31735. +
  31736. + /*
  31737. + * need to read in the page
  31738. + */
  31739. + error = mapping->a_ops->readpage(in, page);
  31740. + if (unlikely(error)) {
  31741. + /*
  31742. + * We really should re-lookup the page here,
  31743. + * but it complicates things a lot. Instead
  31744. + * lets just do what we already stored, and
  31745. + * we'll get it the next time we are called.
  31746. + */
  31747. + if (error == AOP_TRUNCATED_PAGE)
  31748. + error = 0;
  31749. +
  31750. + break;
  31751. + }
  31752. + }
  31753. +fill_it:
  31754. + /*
  31755. + * i_size must be checked after PageUptodate.
  31756. + */
  31757. + isize = i_size_read(mapping->host);
  31758. + end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
  31759. + if (unlikely(!isize || index > end_index))
  31760. + break;
  31761. +
  31762. + /*
  31763. + * if this is the last page, see if we need to shrink
  31764. + * the length and stop
  31765. + */
  31766. + if (end_index == index) {
  31767. + unsigned int plen;
  31768. +
  31769. + /*
  31770. + * max good bytes in this page
  31771. + */
  31772. + plen = ((isize - 1) & ~PAGE_CACHE_MASK) + 1;
  31773. + if (plen <= loff)
  31774. + break;
  31775. +
  31776. + /*
  31777. + * force quit after adding this page
  31778. + */
  31779. + this_len = min(this_len, plen - loff);
  31780. + len = this_len;
  31781. + }
  31782. +
  31783. + spd.partial[page_nr].offset = loff;
  31784. + spd.partial[page_nr].len = this_len;
  31785. + len -= this_len;
  31786. + loff = 0;
  31787. + spd.nr_pages++;
  31788. + index++;
  31789. + }
  31790. +
  31791. + /*
  31792. + * Release any pages at the end, if we quit early. 'page_nr' is how far
  31793. + * we got, 'nr_pages' is how many pages are in the map.
  31794. + */
  31795. + while (page_nr < nr_pages)
  31796. + page_cache_release(spd.pages[page_nr++]);
  31797. + in->f_ra.prev_pos = (loff_t)index << PAGE_CACHE_SHIFT;
  31798. +
  31799. + if (spd.nr_pages)
  31800. + error = splice_to_pipe(pipe, &spd);
  31801. +
  31802. + splice_shrink_spd(pipe, &spd);
  31803. + return error;
  31804. +}
  31805. +
  31806. +/**
  31807. + * generic_file_splice_read - splice data from file to a pipe
  31808. + * @in: file to splice from
  31809. + * @ppos: position in @in
  31810. + * @pipe: pipe to splice to
  31811. + * @len: number of bytes to splice
  31812. + * @flags: splice modifier flags
  31813. + *
  31814. + * Description:
  31815. + * Will read pages from given file and fill them into a pipe. Can be
  31816. + * used as long as the address_space operations for the source implements
  31817. + * a readpage() hook.
  31818. + *
  31819. + */
  31820. +ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
  31821. + struct pipe_inode_info *pipe, size_t len,
  31822. + unsigned int flags)
  31823. +{
  31824. + loff_t isize, left;
  31825. + int ret;
  31826. +
  31827. + isize = i_size_read(in->f_mapping->host);
  31828. + if (unlikely(*ppos >= isize))
  31829. + return 0;
  31830. +
  31831. + left = isize - *ppos;
  31832. + if (unlikely(left < len))
  31833. + len = left;
  31834. +
  31835. + ret = __generic_file_splice_read(in, ppos, pipe, len, flags);
  31836. + if (ret > 0) {
  31837. + *ppos += ret;
  31838. + file_accessed(in);
  31839. + }
  31840. +
  31841. + return ret;
  31842. +}
  31843. +EXPORT_SYMBOL(generic_file_splice_read);
  31844. +
  31845. +static const struct pipe_buf_operations default_pipe_buf_ops = {
  31846. + .can_merge = 0,
  31847. + .map = generic_pipe_buf_map,
  31848. + .unmap = generic_pipe_buf_unmap,
  31849. + .confirm = generic_pipe_buf_confirm,
  31850. + .release = generic_pipe_buf_release,
  31851. + .steal = generic_pipe_buf_steal,
  31852. + .get = generic_pipe_buf_get,
  31853. +};
  31854. +
  31855. +static ssize_t kernel_readv(struct file *file, const struct iovec *vec,
  31856. + unsigned long vlen, loff_t offset)
  31857. +{
  31858. + mm_segment_t old_fs;
  31859. + loff_t pos = offset;
  31860. + ssize_t res;
  31861. +
  31862. + old_fs = get_fs();
  31863. + set_fs(get_ds());
  31864. + /* The cast to a user pointer is valid due to the set_fs() */
  31865. + res = vfs_readv(file, (const struct iovec __user *)vec, vlen, &pos);
  31866. + set_fs(old_fs);
  31867. +
  31868. + return res;
  31869. +}
  31870. +
  31871. +static ssize_t kernel_write(struct file *file, const char *buf, size_t count,
  31872. + loff_t pos)
  31873. +{
  31874. + mm_segment_t old_fs;
  31875. + ssize_t res;
  31876. +
  31877. + old_fs = get_fs();
  31878. + set_fs(get_ds());
  31879. + /* The cast to a user pointer is valid due to the set_fs() */
  31880. + res = vfs_write(file, (const char __user *)buf, count, &pos);
  31881. + set_fs(old_fs);
  31882. +
  31883. + return res;
  31884. +}
  31885. +
  31886. +ssize_t default_file_splice_read(struct file *in, loff_t *ppos,
  31887. + struct pipe_inode_info *pipe, size_t len,
  31888. + unsigned int flags)
  31889. +{
  31890. + unsigned int nr_pages;
  31891. + unsigned int nr_freed;
  31892. + size_t offset;
  31893. + struct page *pages[PIPE_DEF_BUFFERS];
  31894. + struct partial_page partial[PIPE_DEF_BUFFERS];
  31895. + struct iovec *vec, __vec[PIPE_DEF_BUFFERS];
  31896. + ssize_t res;
  31897. + size_t this_len;
  31898. + int error;
  31899. + int i;
  31900. + struct splice_pipe_desc spd = {
  31901. + .pages = pages,
  31902. + .partial = partial,
  31903. + .flags = flags,
  31904. + .ops = &default_pipe_buf_ops,
  31905. + .spd_release = spd_release_page,
  31906. + };
  31907. +
  31908. + if (splice_grow_spd(pipe, &spd))
  31909. + return -ENOMEM;
  31910. +
  31911. + res = -ENOMEM;
  31912. + vec = __vec;
  31913. + if (pipe->buffers > PIPE_DEF_BUFFERS) {
  31914. + vec = kmalloc(pipe->buffers * sizeof(struct iovec), GFP_KERNEL);
  31915. + if (!vec)
  31916. + goto shrink_ret;
  31917. + }
  31918. +
  31919. + offset = *ppos & ~PAGE_CACHE_MASK;
  31920. + nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
  31921. +
  31922. + for (i = 0; i < nr_pages && i < pipe->buffers && len; i++) {
  31923. + struct page *page;
  31924. +
  31925. + page = alloc_page(GFP_USER);
  31926. + error = -ENOMEM;
  31927. + if (!page)
  31928. + goto err;
  31929. +
  31930. + this_len = min_t(size_t, len, PAGE_CACHE_SIZE - offset);
  31931. + vec[i].iov_base = (void __user *) page_address(page);
  31932. + vec[i].iov_len = this_len;
  31933. + spd.pages[i] = page;
  31934. + spd.nr_pages++;
  31935. + len -= this_len;
  31936. + offset = 0;
  31937. + }
  31938. +
  31939. + res = kernel_readv(in, vec, spd.nr_pages, *ppos);
  31940. + if (res < 0) {
  31941. + error = res;
  31942. + goto err;
  31943. + }
  31944. +
  31945. + error = 0;
  31946. + if (!res)
  31947. + goto err;
  31948. +
  31949. + nr_freed = 0;
  31950. + for (i = 0; i < spd.nr_pages; i++) {
  31951. + this_len = min_t(size_t, vec[i].iov_len, res);
  31952. + spd.partial[i].offset = 0;
  31953. + spd.partial[i].len = this_len;
  31954. + if (!this_len) {
  31955. + __free_page(spd.pages[i]);
  31956. + spd.pages[i] = NULL;
  31957. + nr_freed++;
  31958. + }
  31959. + res -= this_len;
  31960. + }
  31961. + spd.nr_pages -= nr_freed;
  31962. +
  31963. + res = splice_to_pipe(pipe, &spd);
  31964. + if (res > 0)
  31965. + *ppos += res;
  31966. +
  31967. +shrink_ret:
  31968. + if (vec != __vec)
  31969. + kfree(vec);
  31970. + splice_shrink_spd(pipe, &spd);
  31971. + return res;
  31972. +
  31973. +err:
  31974. + for (i = 0; i < spd.nr_pages; i++)
  31975. + __free_page(spd.pages[i]);
  31976. +
  31977. + res = error;
  31978. + goto shrink_ret;
  31979. +}
  31980. +EXPORT_SYMBOL(default_file_splice_read);
  31981. +
  31982. +/*
  31983. + * Send 'sd->len' bytes to socket from 'sd->file' at position 'sd->pos'
  31984. + * using sendpage(). Return the number of bytes sent.
  31985. + */
  31986. +static int pipe_to_sendpage(struct pipe_inode_info *pipe,
  31987. + struct pipe_buffer *buf, struct splice_desc *sd)
  31988. +{
  31989. + struct file *file = sd->u.file;
  31990. + loff_t pos = sd->pos;
  31991. + int ret, more;
  31992. +
  31993. + ret = buf->ops->confirm(pipe, buf);
  31994. + if (!ret) {
  31995. + more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len;
  31996. + if (file->f_op && file->f_op->sendpage)
  31997. + ret = file->f_op->sendpage(file, buf->page, buf->offset,
  31998. + sd->len, &pos, more);
  31999. + else
  32000. + ret = -EINVAL;
  32001. + }
  32002. +
  32003. + return ret;
  32004. +}
  32005. +
  32006. +/*
  32007. + * This is a little more tricky than the file -> pipe splicing. There are
  32008. + * basically three cases:
  32009. + *
  32010. + * - Destination page already exists in the address space and there
  32011. + * are users of it. For that case we have no other option that
  32012. + * copying the data. Tough luck.
  32013. + * - Destination page already exists in the address space, but there
  32014. + * are no users of it. Make sure it's uptodate, then drop it. Fall
  32015. + * through to last case.
  32016. + * - Destination page does not exist, we can add the pipe page to
  32017. + * the page cache and avoid the copy.
  32018. + *
  32019. + * If asked to move pages to the output file (SPLICE_F_MOVE is set in
  32020. + * sd->flags), we attempt to migrate pages from the pipe to the output
  32021. + * file address space page cache. This is possible if no one else has
  32022. + * the pipe page referenced outside of the pipe and page cache. If
  32023. + * SPLICE_F_MOVE isn't set, or we cannot move the page, we simply create
  32024. + * a new page in the output file page cache and fill/dirty that.
  32025. + */
  32026. +int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
  32027. + struct splice_desc *sd)
  32028. +{
  32029. + struct file *file = sd->u.file;
  32030. + struct address_space *mapping = file->f_mapping;
  32031. + unsigned int offset, this_len;
  32032. + struct page *page;
  32033. + void *fsdata;
  32034. + int ret;
  32035. +
  32036. + /*
  32037. + * make sure the data in this buffer is uptodate
  32038. + */
  32039. + ret = buf->ops->confirm(pipe, buf);
  32040. + if (unlikely(ret))
  32041. + return ret;
  32042. +
  32043. + offset = sd->pos & ~PAGE_CACHE_MASK;
  32044. +
  32045. + this_len = sd->len;
  32046. + if (this_len + offset > PAGE_CACHE_SIZE)
  32047. + this_len = PAGE_CACHE_SIZE - offset;
  32048. +
  32049. + ret = pagecache_write_begin(file, mapping, sd->pos, this_len,
  32050. + AOP_FLAG_UNINTERRUPTIBLE, &page, &fsdata);
  32051. + if (unlikely(ret))
  32052. + goto out;
  32053. +
  32054. + if (buf->page != page) {
  32055. + /*
  32056. + * Careful, ->map() uses KM_USER0!
  32057. + */
  32058. + char *src = buf->ops->map(pipe, buf, 1);
  32059. + char *dst = kmap_atomic(page, KM_USER1);
  32060. +
  32061. + memcpy(dst + offset, src + buf->offset, this_len);
  32062. + flush_dcache_page(page);
  32063. + kunmap_atomic(dst, KM_USER1);
  32064. + buf->ops->unmap(pipe, buf, src);
  32065. + }
  32066. + ret = pagecache_write_end(file, mapping, sd->pos, this_len, this_len,
  32067. + page, fsdata);
  32068. +out:
  32069. + return ret;
  32070. +}
  32071. +EXPORT_SYMBOL(pipe_to_file);
  32072. +
  32073. +static void wakeup_pipe_writers(struct pipe_inode_info *pipe)
  32074. +{
  32075. + smp_mb();
  32076. + if (waitqueue_active(&pipe->wait))
  32077. + wake_up_interruptible(&pipe->wait);
  32078. + kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
  32079. +}
  32080. +
  32081. +/**
  32082. + * splice_from_pipe_feed - feed available data from a pipe to a file
  32083. + * @pipe: pipe to splice from
  32084. + * @sd: information to @actor
  32085. + * @actor: handler that splices the data
  32086. + *
  32087. + * Description:
  32088. + * This function loops over the pipe and calls @actor to do the
  32089. + * actual moving of a single struct pipe_buffer to the desired
  32090. + * destination. It returns when there's no more buffers left in
  32091. + * the pipe or if the requested number of bytes (@sd->total_len)
  32092. + * have been copied. It returns a positive number (one) if the
  32093. + * pipe needs to be filled with more data, zero if the required
  32094. + * number of bytes have been copied and -errno on error.
  32095. + *
  32096. + * This, together with splice_from_pipe_{begin,end,next}, may be
  32097. + * used to implement the functionality of __splice_from_pipe() when
  32098. + * locking is required around copying the pipe buffers to the
  32099. + * destination.
  32100. + */
  32101. +int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_desc *sd,
  32102. + splice_actor *actor)
  32103. +{
  32104. + int ret;
  32105. +
  32106. + while (pipe->nrbufs) {
  32107. + struct pipe_buffer *buf = pipe->bufs + pipe->curbuf;
  32108. + const struct pipe_buf_operations *ops = buf->ops;
  32109. +
  32110. + sd->len = buf->len;
  32111. + if (sd->len > sd->total_len)
  32112. + sd->len = sd->total_len;
  32113. +
  32114. + ret = actor(pipe, buf, sd);
  32115. + if (ret <= 0) {
  32116. + if (ret == -ENODATA)
  32117. + ret = 0;
  32118. + return ret;
  32119. + }
  32120. + buf->offset += ret;
  32121. + buf->len -= ret;
  32122. +
  32123. + sd->num_spliced += ret;
  32124. + sd->len -= ret;
  32125. + sd->pos += ret;
  32126. + sd->total_len -= ret;
  32127. +
  32128. + if (!buf->len) {
  32129. + buf->ops = NULL;
  32130. + ops->release(pipe, buf);
  32131. + pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1);
  32132. + pipe->nrbufs--;
  32133. + if (pipe->inode)
  32134. + sd->need_wakeup = true;
  32135. + }
  32136. +
  32137. + if (!sd->total_len)
  32138. + return 0;
  32139. + }
  32140. +
  32141. + return 1;
  32142. +}
  32143. +EXPORT_SYMBOL(splice_from_pipe_feed);
  32144. +
  32145. +/**
  32146. + * splice_from_pipe_next - wait for some data to splice from
  32147. + * @pipe: pipe to splice from
  32148. + * @sd: information about the splice operation
  32149. + *
  32150. + * Description:
  32151. + * This function will wait for some data and return a positive
  32152. + * value (one) if pipe buffers are available. It will return zero
  32153. + * or -errno if no more data needs to be spliced.
  32154. + */
  32155. +int splice_from_pipe_next(struct pipe_inode_info *pipe, struct splice_desc *sd)
  32156. +{
  32157. + while (!pipe->nrbufs) {
  32158. + if (!pipe->writers)
  32159. + return 0;
  32160. +
  32161. + if (!pipe->waiting_writers && sd->num_spliced)
  32162. + return 0;
  32163. +
  32164. + if (sd->flags & SPLICE_F_NONBLOCK)
  32165. + return -EAGAIN;
  32166. +
  32167. + if (signal_pending(current))
  32168. + return -ERESTARTSYS;
  32169. +
  32170. + if (sd->need_wakeup) {
  32171. + wakeup_pipe_writers(pipe);
  32172. + sd->need_wakeup = false;
  32173. + }
  32174. +
  32175. + pipe_wait(pipe);
  32176. + }
  32177. +
  32178. + return 1;
  32179. +}
  32180. +EXPORT_SYMBOL(splice_from_pipe_next);
  32181. +
  32182. +/**
  32183. + * splice_from_pipe_begin - start splicing from pipe
  32184. + * @sd: information about the splice operation
  32185. + *
  32186. + * Description:
  32187. + * This function should be called before a loop containing
  32188. + * splice_from_pipe_next() and splice_from_pipe_feed() to
  32189. + * initialize the necessary fields of @sd.
  32190. + */
  32191. +void splice_from_pipe_begin(struct splice_desc *sd)
  32192. +{
  32193. + sd->num_spliced = 0;
  32194. + sd->need_wakeup = false;
  32195. +}
  32196. +EXPORT_SYMBOL(splice_from_pipe_begin);
  32197. +
  32198. +/**
  32199. + * splice_from_pipe_end - finish splicing from pipe
  32200. + * @pipe: pipe to splice from
  32201. + * @sd: information about the splice operation
  32202. + *
  32203. + * Description:
  32204. + * This function will wake up pipe writers if necessary. It should
  32205. + * be called after a loop containing splice_from_pipe_next() and
  32206. + * splice_from_pipe_feed().
  32207. + */
  32208. +void splice_from_pipe_end(struct pipe_inode_info *pipe, struct splice_desc *sd)
  32209. +{
  32210. + if (sd->need_wakeup)
  32211. + wakeup_pipe_writers(pipe);
  32212. +}
  32213. +EXPORT_SYMBOL(splice_from_pipe_end);
  32214. +
  32215. +/**
  32216. + * __splice_from_pipe - splice data from a pipe to given actor
  32217. + * @pipe: pipe to splice from
  32218. + * @sd: information to @actor
  32219. + * @actor: handler that splices the data
  32220. + *
  32221. + * Description:
  32222. + * This function does little more than loop over the pipe and call
  32223. + * @actor to do the actual moving of a single struct pipe_buffer to
  32224. + * the desired destination. See pipe_to_file, pipe_to_sendpage, or
  32225. + * pipe_to_user.
  32226. + *
  32227. + */
  32228. +ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd,
  32229. + splice_actor *actor)
  32230. +{
  32231. + int ret;
  32232. +
  32233. + splice_from_pipe_begin(sd);
  32234. + do {
  32235. + ret = splice_from_pipe_next(pipe, sd);
  32236. + if (ret > 0)
  32237. + ret = splice_from_pipe_feed(pipe, sd, actor);
  32238. + } while (ret > 0);
  32239. + splice_from_pipe_end(pipe, sd);
  32240. +
  32241. + return sd->num_spliced ? sd->num_spliced : ret;
  32242. +}
  32243. +EXPORT_SYMBOL(__splice_from_pipe);
  32244. +
  32245. +/**
  32246. + * splice_from_pipe - splice data from a pipe to a file
  32247. + * @pipe: pipe to splice from
  32248. + * @out: file to splice to
  32249. + * @ppos: position in @out
  32250. + * @len: how many bytes to splice
  32251. + * @flags: splice modifier flags
  32252. + * @actor: handler that splices the data
  32253. + *
  32254. + * Description:
  32255. + * See __splice_from_pipe. This function locks the pipe inode,
  32256. + * otherwise it's identical to __splice_from_pipe().
  32257. + *
  32258. + */
  32259. +ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
  32260. + loff_t *ppos, size_t len, unsigned int flags,
  32261. + splice_actor *actor)
  32262. +{
  32263. + ssize_t ret;
  32264. + struct splice_desc sd = {
  32265. + .total_len = len,
  32266. + .flags = flags,
  32267. + .pos = *ppos,
  32268. + .u.file = out,
  32269. + };
  32270. +
  32271. + pipe_lock(pipe);
  32272. + ret = __splice_from_pipe(pipe, &sd, actor);
  32273. + pipe_unlock(pipe);
  32274. +
  32275. + return ret;
  32276. +}
  32277. +
  32278. +/**
  32279. + * generic_file_splice_write - splice data from a pipe to a file
  32280. + * @pipe: pipe info
  32281. + * @out: file to write to
  32282. + * @ppos: position in @out
  32283. + * @len: number of bytes to splice
  32284. + * @flags: splice modifier flags
  32285. + *
  32286. + * Description:
  32287. + * Will either move or copy pages (determined by @flags options) from
  32288. + * the given pipe inode to the given file.
  32289. + *
  32290. + */
  32291. +ssize_t
  32292. +generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
  32293. + loff_t *ppos, size_t len, unsigned int flags)
  32294. +{
  32295. + struct address_space *mapping = out->f_mapping;
  32296. + struct inode *inode = mapping->host;
  32297. + struct splice_desc sd = {
  32298. + .total_len = len,
  32299. + .flags = flags,
  32300. + .pos = *ppos,
  32301. + .u.file = out,
  32302. + };
  32303. + ssize_t ret;
  32304. +
  32305. + pipe_lock(pipe);
  32306. +
  32307. + splice_from_pipe_begin(&sd);
  32308. + do {
  32309. + ret = splice_from_pipe_next(pipe, &sd);
  32310. + if (ret <= 0)
  32311. + break;
  32312. +
  32313. + mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD);
  32314. + ret = file_remove_suid(out);
  32315. + if (!ret) {
  32316. + file_update_time(out);
  32317. + ret = splice_from_pipe_feed(pipe, &sd, pipe_to_file);
  32318. + }
  32319. + mutex_unlock(&inode->i_mutex);
  32320. + } while (ret > 0);
  32321. + splice_from_pipe_end(pipe, &sd);
  32322. +
  32323. + pipe_unlock(pipe);
  32324. +
  32325. + if (sd.num_spliced)
  32326. + ret = sd.num_spliced;
  32327. +
  32328. + if (ret > 0) {
  32329. + unsigned long nr_pages;
  32330. + int err;
  32331. +
  32332. + nr_pages = (ret + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
  32333. +
  32334. + err = generic_write_sync(out, *ppos, ret);
  32335. + if (err)
  32336. + ret = err;
  32337. + else
  32338. + *ppos += ret;
  32339. + balance_dirty_pages_ratelimited_nr(mapping, nr_pages);
  32340. + }
  32341. +
  32342. + return ret;
  32343. +}
  32344. +
  32345. +EXPORT_SYMBOL(generic_file_splice_write);
  32346. +
  32347. +static int write_pipe_buf(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
  32348. + struct splice_desc *sd)
  32349. +{
  32350. + int ret;
  32351. + void *data;
  32352. +
  32353. + ret = buf->ops->confirm(pipe, buf);
  32354. + if (ret)
  32355. + return ret;
  32356. +
  32357. + data = buf->ops->map(pipe, buf, 0);
  32358. + ret = kernel_write(sd->u.file, data + buf->offset, sd->len, sd->pos);
  32359. + buf->ops->unmap(pipe, buf, data);
  32360. +
  32361. + return ret;
  32362. +}
  32363. +
  32364. +static ssize_t default_file_splice_write(struct pipe_inode_info *pipe,
  32365. + struct file *out, loff_t *ppos,
  32366. + size_t len, unsigned int flags)
  32367. +{
  32368. + ssize_t ret;
  32369. +
  32370. + ret = splice_from_pipe(pipe, out, ppos, len, flags, write_pipe_buf);
  32371. + if (ret > 0)
  32372. + *ppos += ret;
  32373. +
  32374. + return ret;
  32375. +}
  32376. +
  32377. +/**
  32378. + * generic_splice_sendpage - splice data from a pipe to a socket
  32379. + * @pipe: pipe to splice from
  32380. + * @out: socket to write to
  32381. + * @ppos: position in @out
  32382. + * @len: number of bytes to splice
  32383. + * @flags: splice modifier flags
  32384. + *
  32385. + * Description:
  32386. + * Will send @len bytes from the pipe to a network socket. No data copying
  32387. + * is involved.
  32388. + *
  32389. + */
  32390. +ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out,
  32391. + loff_t *ppos, size_t len, unsigned int flags)
  32392. +{
  32393. + return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_sendpage);
  32394. +}
  32395. +
  32396. +EXPORT_SYMBOL(generic_splice_sendpage);
  32397. +
  32398. +/*
  32399. + * Attempt to initiate a splice from pipe to file.
  32400. + */
  32401. +static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  32402. + loff_t *ppos, size_t len, unsigned int flags)
  32403. +{
  32404. + ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
  32405. + loff_t *, size_t, unsigned int);
  32406. + int ret;
  32407. +
  32408. + if (unlikely(!(out->f_mode & FMODE_WRITE)))
  32409. + return -EBADF;
  32410. +
  32411. + if (unlikely(out->f_flags & O_APPEND))
  32412. + return -EINVAL;
  32413. +
  32414. + ret = rw_verify_area(WRITE, out, ppos, len);
  32415. + if (unlikely(ret < 0))
  32416. + return ret;
  32417. +
  32418. + if (out->f_op && out->f_op->splice_write)
  32419. + splice_write = out->f_op->splice_write;
  32420. + else
  32421. + splice_write = default_file_splice_write;
  32422. +
  32423. + return splice_write(pipe, out, ppos, len, flags);
  32424. +}
  32425. +EXPORT_SYMBOL(do_splice_from);
  32426. +
  32427. +/*
  32428. + * Attempt to initiate a splice from a file to a pipe.
  32429. + */
  32430. +static long do_splice_to(struct file *in, loff_t *ppos,
  32431. + struct pipe_inode_info *pipe, size_t len,
  32432. + unsigned int flags)
  32433. +{
  32434. + ssize_t (*splice_read)(struct file *, loff_t *,
  32435. + struct pipe_inode_info *, size_t, unsigned int);
  32436. + int ret;
  32437. +
  32438. + if (unlikely(!(in->f_mode & FMODE_READ)))
  32439. + return -EBADF;
  32440. +
  32441. + ret = rw_verify_area(READ, in, ppos, len);
  32442. + if (unlikely(ret < 0))
  32443. + return ret;
  32444. +
  32445. + if (in->f_op && in->f_op->splice_read)
  32446. + splice_read = in->f_op->splice_read;
  32447. + else
  32448. + splice_read = default_file_splice_read;
  32449. +
  32450. + return splice_read(in, ppos, pipe, len, flags);
  32451. +}
  32452. +EXPORT_SYMBOL(do_splice_to);
  32453. +
  32454. +/**
  32455. + * splice_direct_to_actor - splices data directly between two non-pipes
  32456. + * @in: file to splice from
  32457. + * @sd: actor information on where to splice to
  32458. + * @actor: handles the data splicing
  32459. + *
  32460. + * Description:
  32461. + * This is a special case helper to splice directly between two
  32462. + * points, without requiring an explicit pipe. Internally an allocated
  32463. + * pipe is cached in the process, and reused during the lifetime of
  32464. + * that process.
  32465. + *
  32466. + */
  32467. +ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
  32468. + splice_direct_actor *actor)
  32469. +{
  32470. + struct pipe_inode_info *pipe;
  32471. + long ret, bytes;
  32472. + umode_t i_mode;
  32473. + size_t len;
  32474. + int i, flags;
  32475. +
  32476. + /*
  32477. + * We require the input being a regular file, as we don't want to
  32478. + * randomly drop data for eg socket -> socket splicing. Use the
  32479. + * piped splicing for that!
  32480. + */
  32481. + i_mode = in->f_path.dentry->d_inode->i_mode;
  32482. + if (unlikely(!S_ISREG(i_mode) && !S_ISBLK(i_mode)))
  32483. + return -EINVAL;
  32484. +
  32485. + /*
  32486. + * neither in nor out is a pipe, setup an internal pipe attached to
  32487. + * 'out' and transfer the wanted data from 'in' to 'out' through that
  32488. + */
  32489. + pipe = current->splice_pipe;
  32490. + if (unlikely(!pipe)) {
  32491. + pipe = alloc_pipe_info(NULL);
  32492. + if (!pipe)
  32493. + return -ENOMEM;
  32494. +
  32495. + /*
  32496. + * We don't have an immediate reader, but we'll read the stuff
  32497. + * out of the pipe right after the splice_to_pipe(). So set
  32498. + * PIPE_READERS appropriately.
  32499. + */
  32500. + pipe->readers = 1;
  32501. +
  32502. + current->splice_pipe = pipe;
  32503. + }
  32504. +
  32505. + /*
  32506. + * Do the splice.
  32507. + */
  32508. + ret = 0;
  32509. + bytes = 0;
  32510. + len = sd->total_len;
  32511. + flags = sd->flags;
  32512. +
  32513. + /*
  32514. + * Don't block on output, we have to drain the direct pipe.
  32515. + */
  32516. + sd->flags &= ~SPLICE_F_NONBLOCK;
  32517. +
  32518. + while (len) {
  32519. + size_t read_len;
  32520. + loff_t pos = sd->pos, prev_pos = pos;
  32521. +
  32522. + ret = do_splice_to(in, &pos, pipe, len, flags);
  32523. + if (unlikely(ret <= 0))
  32524. + goto out_release;
  32525. +
  32526. + read_len = ret;
  32527. + sd->total_len = read_len;
  32528. +
  32529. + /*
  32530. + * NOTE: nonblocking mode only applies to the input. We
  32531. + * must not do the output in nonblocking mode as then we
  32532. + * could get stuck data in the internal pipe:
  32533. + */
  32534. + ret = actor(pipe, sd);
  32535. + if (unlikely(ret <= 0)) {
  32536. + sd->pos = prev_pos;
  32537. + goto out_release;
  32538. + }
  32539. +
  32540. + bytes += ret;
  32541. + len -= ret;
  32542. + sd->pos = pos;
  32543. +
  32544. + if (ret < read_len) {
  32545. + sd->pos = prev_pos + ret;
  32546. + goto out_release;
  32547. + }
  32548. + }
  32549. +
  32550. +done:
  32551. + pipe->nrbufs = pipe->curbuf = 0;
  32552. + file_accessed(in);
  32553. + return bytes;
  32554. +
  32555. +out_release:
  32556. + /*
  32557. + * If we did an incomplete transfer we must release
  32558. + * the pipe buffers in question:
  32559. + */
  32560. + for (i = 0; i < pipe->buffers; i++) {
  32561. + struct pipe_buffer *buf = pipe->bufs + i;
  32562. +
  32563. + if (buf->ops) {
  32564. + buf->ops->release(pipe, buf);
  32565. + buf->ops = NULL;
  32566. + }
  32567. + }
  32568. +
  32569. + if (!bytes)
  32570. + bytes = ret;
  32571. +
  32572. + goto done;
  32573. +}
  32574. +EXPORT_SYMBOL(splice_direct_to_actor);
  32575. +
  32576. +static int direct_splice_actor(struct pipe_inode_info *pipe,
  32577. + struct splice_desc *sd)
  32578. +{
  32579. + struct file *file = sd->u.file;
  32580. +
  32581. + return do_splice_from(pipe, file, &file->f_pos, sd->total_len,
  32582. + sd->flags);
  32583. +}
  32584. +
  32585. +/**
  32586. + * do_splice_direct - splices data directly between two files
  32587. + * @in: file to splice from
  32588. + * @ppos: input file offset
  32589. + * @out: file to splice to
  32590. + * @len: number of bytes to splice
  32591. + * @flags: splice modifier flags
  32592. + *
  32593. + * Description:
  32594. + * For use by do_sendfile(). splice can easily emulate sendfile, but
  32595. + * doing it in the application would incur an extra system call
  32596. + * (splice in + splice out, as compared to just sendfile()). So this helper
  32597. + * can splice directly through a process-private pipe.
  32598. + *
  32599. + */
  32600. +long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
  32601. + size_t len, unsigned int flags)
  32602. +{
  32603. + struct splice_desc sd = {
  32604. + .len = len,
  32605. + .total_len = len,
  32606. + .flags = flags,
  32607. + .pos = *ppos,
  32608. + .u.file = out,
  32609. + };
  32610. + long ret;
  32611. +
  32612. + ret = splice_direct_to_actor(in, &sd, direct_splice_actor);
  32613. + if (ret > 0)
  32614. + *ppos = sd.pos;
  32615. +
  32616. + return ret;
  32617. +}
  32618. +
  32619. +static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
  32620. + struct pipe_inode_info *opipe,
  32621. + size_t len, unsigned int flags);
  32622. +/*
  32623. + * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same
  32624. + * location, so checking ->i_pipe is not enough to verify that this is a
  32625. + * pipe.
  32626. + */
  32627. +static inline struct pipe_inode_info *pipe_info(struct inode *inode)
  32628. +{
  32629. + if (S_ISFIFO(inode->i_mode))
  32630. + return inode->i_pipe;
  32631. +
  32632. + return NULL;
  32633. +}
  32634. +
  32635. +/*
  32636. + * Determine where to splice to/from.
  32637. + */
  32638. +static long do_splice(struct file *in, loff_t __user *off_in,
  32639. + struct file *out, loff_t __user *off_out,
  32640. + size_t len, unsigned int flags)
  32641. +{
  32642. + struct pipe_inode_info *ipipe;
  32643. + struct pipe_inode_info *opipe;
  32644. + loff_t offset, *off;
  32645. + long ret;
  32646. +
  32647. + ipipe = pipe_info(in->f_path.dentry->d_inode);
  32648. + opipe = pipe_info(out->f_path.dentry->d_inode);
  32649. +
  32650. + if (ipipe && opipe) {
  32651. + if (off_in || off_out)
  32652. + return -ESPIPE;
  32653. +
  32654. + if (!(in->f_mode & FMODE_READ))
  32655. + return -EBADF;
  32656. +
  32657. + if (!(out->f_mode & FMODE_WRITE))
  32658. + return -EBADF;
  32659. +
  32660. + /* Splicing to self would be fun, but... */
  32661. + if (ipipe == opipe)
  32662. + return -EINVAL;
  32663. +
  32664. + return splice_pipe_to_pipe(ipipe, opipe, len, flags);
  32665. + }
  32666. +
  32667. + if (ipipe) {
  32668. + if (off_in)
  32669. + return -ESPIPE;
  32670. + if (off_out) {
  32671. + if (!(out->f_mode & FMODE_PWRITE))
  32672. + return -EINVAL;
  32673. + if (copy_from_user(&offset, off_out, sizeof(loff_t)))
  32674. + return -EFAULT;
  32675. + off = &offset;
  32676. + } else
  32677. + off = &out->f_pos;
  32678. +
  32679. + ret = do_splice_from(ipipe, out, off, len, flags);
  32680. +
  32681. + if (off_out && copy_to_user(off_out, off, sizeof(loff_t)))
  32682. + ret = -EFAULT;
  32683. +
  32684. + return ret;
  32685. + }
  32686. +
  32687. + if (opipe) {
  32688. + if (off_out)
  32689. + return -ESPIPE;
  32690. + if (off_in) {
  32691. + if (!(in->f_mode & FMODE_PREAD))
  32692. + return -EINVAL;
  32693. + if (copy_from_user(&offset, off_in, sizeof(loff_t)))
  32694. + return -EFAULT;
  32695. + off = &offset;
  32696. + } else
  32697. + off = &in->f_pos;
  32698. +
  32699. + ret = do_splice_to(in, off, opipe, len, flags);
  32700. +
  32701. + if (off_in && copy_to_user(off_in, off, sizeof(loff_t)))
  32702. + ret = -EFAULT;
  32703. +
  32704. + return ret;
  32705. + }
  32706. +
  32707. + return -EINVAL;
  32708. +}
  32709. +
  32710. +/*
  32711. + * Map an iov into an array of pages and offset/length tupples. With the
  32712. + * partial_page structure, we can map several non-contiguous ranges into
  32713. + * our ones pages[] map instead of splitting that operation into pieces.
  32714. + * Could easily be exported as a generic helper for other users, in which
  32715. + * case one would probably want to add a 'max_nr_pages' parameter as well.
  32716. + */
  32717. +static int get_iovec_page_array(const struct iovec __user *iov,
  32718. + unsigned int nr_vecs, struct page **pages,
  32719. + struct partial_page *partial, int aligned,
  32720. + unsigned int pipe_buffers)
  32721. +{
  32722. + int buffers = 0, error = 0;
  32723. +
  32724. + while (nr_vecs) {
  32725. + unsigned long off, npages;
  32726. + struct iovec entry;
  32727. + void __user *base;
  32728. + size_t len;
  32729. + int i;
  32730. +
  32731. + error = -EFAULT;
  32732. + if (copy_from_user(&entry, iov, sizeof(entry)))
  32733. + break;
  32734. +
  32735. + base = entry.iov_base;
  32736. + len = entry.iov_len;
  32737. +
  32738. + /*
  32739. + * Sanity check this iovec. 0 read succeeds.
  32740. + */
  32741. + error = 0;
  32742. + if (unlikely(!len))
  32743. + break;
  32744. + error = -EFAULT;
  32745. + if (!access_ok(VERIFY_READ, base, len))
  32746. + break;
  32747. +
  32748. + /*
  32749. + * Get this base offset and number of pages, then map
  32750. + * in the user pages.
  32751. + */
  32752. + off = (unsigned long) base & ~PAGE_MASK;
  32753. +
  32754. + /*
  32755. + * If asked for alignment, the offset must be zero and the
  32756. + * length a multiple of the PAGE_SIZE.
  32757. + */
  32758. + error = -EINVAL;
  32759. + if (aligned && (off || len & ~PAGE_MASK))
  32760. + break;
  32761. +
  32762. + npages = (off + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
  32763. + if (npages > pipe_buffers - buffers)
  32764. + npages = pipe_buffers - buffers;
  32765. +
  32766. + error = get_user_pages_fast((unsigned long)base, npages,
  32767. + 0, &pages[buffers]);
  32768. +
  32769. + if (unlikely(error <= 0))
  32770. + break;
  32771. +
  32772. + /*
  32773. + * Fill this contiguous range into the partial page map.
  32774. + */
  32775. + for (i = 0; i < error; i++) {
  32776. + const int plen = min_t(size_t, len, PAGE_SIZE - off);
  32777. +
  32778. + partial[buffers].offset = off;
  32779. + partial[buffers].len = plen;
  32780. +
  32781. + off = 0;
  32782. + len -= plen;
  32783. + buffers++;
  32784. + }
  32785. +
  32786. + /*
  32787. + * We didn't complete this iov, stop here since it probably
  32788. + * means we have to move some of this into a pipe to
  32789. + * be able to continue.
  32790. + */
  32791. + if (len)
  32792. + break;
  32793. +
  32794. + /*
  32795. + * Don't continue if we mapped fewer pages than we asked for,
  32796. + * or if we mapped the max number of pages that we have
  32797. + * room for.
  32798. + */
  32799. + if (error < npages || buffers == pipe_buffers)
  32800. + break;
  32801. +
  32802. + nr_vecs--;
  32803. + iov++;
  32804. + }
  32805. +
  32806. + if (buffers)
  32807. + return buffers;
  32808. +
  32809. + return error;
  32810. +}
  32811. +
  32812. +static int pipe_to_user(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
  32813. + struct splice_desc *sd)
  32814. +{
  32815. + char *src;
  32816. + int ret;
  32817. +
  32818. + ret = buf->ops->confirm(pipe, buf);
  32819. + if (unlikely(ret))
  32820. + return ret;
  32821. +
  32822. + /*
  32823. + * See if we can use the atomic maps, by prefaulting in the
  32824. + * pages and doing an atomic copy
  32825. + */
  32826. + if (!fault_in_pages_writeable(sd->u.userptr, sd->len)) {
  32827. + src = buf->ops->map(pipe, buf, 1);
  32828. + ret = __copy_to_user_inatomic(sd->u.userptr, src + buf->offset,
  32829. + sd->len);
  32830. + buf->ops->unmap(pipe, buf, src);
  32831. + if (!ret) {
  32832. + ret = sd->len;
  32833. + goto out;
  32834. + }
  32835. + }
  32836. +
  32837. + /*
  32838. + * No dice, use slow non-atomic map and copy
  32839. + */
  32840. + src = buf->ops->map(pipe, buf, 0);
  32841. +
  32842. + ret = sd->len;
  32843. + if (copy_to_user(sd->u.userptr, src + buf->offset, sd->len))
  32844. + ret = -EFAULT;
  32845. +
  32846. + buf->ops->unmap(pipe, buf, src);
  32847. +out:
  32848. + if (ret > 0)
  32849. + sd->u.userptr += ret;
  32850. + return ret;
  32851. +}
  32852. +
  32853. +/*
  32854. + * For lack of a better implementation, implement vmsplice() to userspace
  32855. + * as a simple copy of the pipes pages to the user iov.
  32856. + */
  32857. +static long vmsplice_to_user(struct file *file, const struct iovec __user *iov,
  32858. + unsigned long nr_segs, unsigned int flags)
  32859. +{
  32860. + struct pipe_inode_info *pipe;
  32861. + struct splice_desc sd;
  32862. + ssize_t size;
  32863. + int error;
  32864. + long ret;
  32865. +
  32866. + pipe = pipe_info(file->f_path.dentry->d_inode);
  32867. + if (!pipe)
  32868. + return -EBADF;
  32869. +
  32870. + pipe_lock(pipe);
  32871. +
  32872. + error = ret = 0;
  32873. + while (nr_segs) {
  32874. + void __user *base;
  32875. + size_t len;
  32876. +
  32877. + /*
  32878. + * Get user address base and length for this iovec.
  32879. + */
  32880. + error = get_user(base, &iov->iov_base);
  32881. + if (unlikely(error))
  32882. + break;
  32883. + error = get_user(len, &iov->iov_len);
  32884. + if (unlikely(error))
  32885. + break;
  32886. +
  32887. + /*
  32888. + * Sanity check this iovec. 0 read succeeds.
  32889. + */
  32890. + if (unlikely(!len))
  32891. + break;
  32892. + if (unlikely(!base)) {
  32893. + error = -EFAULT;
  32894. + break;
  32895. + }
  32896. +
  32897. + if (unlikely(!access_ok(VERIFY_WRITE, base, len))) {
  32898. + error = -EFAULT;
  32899. + break;
  32900. + }
  32901. +
  32902. + sd.len = 0;
  32903. + sd.total_len = len;
  32904. + sd.flags = flags;
  32905. + sd.u.userptr = base;
  32906. + sd.pos = 0;
  32907. +
  32908. + size = __splice_from_pipe(pipe, &sd, pipe_to_user);
  32909. + if (size < 0) {
  32910. + if (!ret)
  32911. + ret = size;
  32912. +
  32913. + break;
  32914. + }
  32915. +
  32916. + ret += size;
  32917. +
  32918. + if (size < len)
  32919. + break;
  32920. +
  32921. + nr_segs--;
  32922. + iov++;
  32923. + }
  32924. +
  32925. + pipe_unlock(pipe);
  32926. +
  32927. + if (!ret)
  32928. + ret = error;
  32929. +
  32930. + return ret;
  32931. +}
  32932. +
  32933. +/*
  32934. + * vmsplice splices a user address range into a pipe. It can be thought of
  32935. + * as splice-from-memory, where the regular splice is splice-from-file (or
  32936. + * to file). In both cases the output is a pipe, naturally.
  32937. + */
  32938. +static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov,
  32939. + unsigned long nr_segs, unsigned int flags)
  32940. +{
  32941. + struct pipe_inode_info *pipe;
  32942. + struct page *pages[PIPE_DEF_BUFFERS];
  32943. + struct partial_page partial[PIPE_DEF_BUFFERS];
  32944. + struct splice_pipe_desc spd = {
  32945. + .pages = pages,
  32946. + .partial = partial,
  32947. + .flags = flags,
  32948. + .ops = &user_page_pipe_buf_ops,
  32949. + .spd_release = spd_release_page,
  32950. + };
  32951. + long ret;
  32952. +
  32953. + pipe = pipe_info(file->f_path.dentry->d_inode);
  32954. + if (!pipe)
  32955. + return -EBADF;
  32956. +
  32957. + if (splice_grow_spd(pipe, &spd))
  32958. + return -ENOMEM;
  32959. +
  32960. + spd.nr_pages = get_iovec_page_array(iov, nr_segs, spd.pages,
  32961. + spd.partial, flags & SPLICE_F_GIFT,
  32962. + pipe->buffers);
  32963. + if (spd.nr_pages <= 0)
  32964. + ret = spd.nr_pages;
  32965. + else
  32966. + ret = splice_to_pipe(pipe, &spd);
  32967. +
  32968. + splice_shrink_spd(pipe, &spd);
  32969. + return ret;
  32970. +}
  32971. +
  32972. +/*
  32973. + * Note that vmsplice only really supports true splicing _from_ user memory
  32974. + * to a pipe, not the other way around. Splicing from user memory is a simple
  32975. + * operation that can be supported without any funky alignment restrictions
  32976. + * or nasty vm tricks. We simply map in the user memory and fill them into
  32977. + * a pipe. The reverse isn't quite as easy, though. There are two possible
  32978. + * solutions for that:
  32979. + *
  32980. + * - memcpy() the data internally, at which point we might as well just
  32981. + * do a regular read() on the buffer anyway.
  32982. + * - Lots of nasty vm tricks, that are neither fast nor flexible (it
  32983. + * has restriction limitations on both ends of the pipe).
  32984. + *
  32985. + * Currently we punt and implement it as a normal copy, see pipe_to_user().
  32986. + *
  32987. + */
  32988. +SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, iov,
  32989. + unsigned long, nr_segs, unsigned int, flags)
  32990. +{
  32991. + struct file *file;
  32992. + long error;
  32993. + int fput;
  32994. +
  32995. + if (unlikely(nr_segs > UIO_MAXIOV))
  32996. + return -EINVAL;
  32997. + else if (unlikely(!nr_segs))
  32998. + return 0;
  32999. +
  33000. + error = -EBADF;
  33001. + file = fget_light(fd, &fput);
  33002. + if (file) {
  33003. + if (file->f_mode & FMODE_WRITE)
  33004. + error = vmsplice_to_pipe(file, iov, nr_segs, flags);
  33005. + else if (file->f_mode & FMODE_READ)
  33006. + error = vmsplice_to_user(file, iov, nr_segs, flags);
  33007. +
  33008. + fput_light(file, fput);
  33009. + }
  33010. +
  33011. + return error;
  33012. +}
  33013. +
  33014. +SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in,
  33015. + int, fd_out, loff_t __user *, off_out,
  33016. + size_t, len, unsigned int, flags)
  33017. +{
  33018. + long error;
  33019. + struct file *in, *out;
  33020. + int fput_in, fput_out;
  33021. +
  33022. + if (unlikely(!len))
  33023. + return 0;
  33024. +
  33025. + error = -EBADF;
  33026. + in = fget_light(fd_in, &fput_in);
  33027. + if (in) {
  33028. + if (in->f_mode & FMODE_READ) {
  33029. + out = fget_light(fd_out, &fput_out);
  33030. + if (out) {
  33031. + if (out->f_mode & FMODE_WRITE)
  33032. + error = do_splice(in, off_in,
  33033. + out, off_out,
  33034. + len, flags);
  33035. + fput_light(out, fput_out);
  33036. + }
  33037. + }
  33038. +
  33039. + fput_light(in, fput_in);
  33040. + }
  33041. +
  33042. + return error;
  33043. +}
  33044. +
  33045. +/*
  33046. + * Make sure there's data to read. Wait for input if we can, otherwise
  33047. + * return an appropriate error.
  33048. + */
  33049. +static int ipipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
  33050. +{
  33051. + int ret;
  33052. +
  33053. + /*
  33054. + * Check ->nrbufs without the inode lock first. This function
  33055. + * is speculative anyways, so missing one is ok.
  33056. + */
  33057. + if (pipe->nrbufs)
  33058. + return 0;
  33059. +
  33060. + ret = 0;
  33061. + pipe_lock(pipe);
  33062. +
  33063. + while (!pipe->nrbufs) {
  33064. + if (signal_pending(current)) {
  33065. + ret = -ERESTARTSYS;
  33066. + break;
  33067. + }
  33068. + if (!pipe->writers)
  33069. + break;
  33070. + if (!pipe->waiting_writers) {
  33071. + if (flags & SPLICE_F_NONBLOCK) {
  33072. + ret = -EAGAIN;
  33073. + break;
  33074. + }
  33075. + }
  33076. + pipe_wait(pipe);
  33077. + }
  33078. +
  33079. + pipe_unlock(pipe);
  33080. + return ret;
  33081. +}
  33082. +
  33083. +/*
  33084. + * Make sure there's writeable room. Wait for room if we can, otherwise
  33085. + * return an appropriate error.
  33086. + */
  33087. +static int opipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
  33088. +{
  33089. + int ret;
  33090. +
  33091. + /*
  33092. + * Check ->nrbufs without the inode lock first. This function
  33093. + * is speculative anyways, so missing one is ok.
  33094. + */
  33095. + if (pipe->nrbufs < pipe->buffers)
  33096. + return 0;
  33097. +
  33098. + ret = 0;
  33099. + pipe_lock(pipe);
  33100. +
  33101. + while (pipe->nrbufs >= pipe->buffers) {
  33102. + if (!pipe->readers) {
  33103. + send_sig(SIGPIPE, current, 0);
  33104. + ret = -EPIPE;
  33105. + break;
  33106. + }
  33107. + if (flags & SPLICE_F_NONBLOCK) {
  33108. + ret = -EAGAIN;
  33109. + break;
  33110. + }
  33111. + if (signal_pending(current)) {
  33112. + ret = -ERESTARTSYS;
  33113. + break;
  33114. + }
  33115. + pipe->waiting_writers++;
  33116. + pipe_wait(pipe);
  33117. + pipe->waiting_writers--;
  33118. + }
  33119. +
  33120. + pipe_unlock(pipe);
  33121. + return ret;
  33122. +}
  33123. +
  33124. +/*
  33125. + * Splice contents of ipipe to opipe.
  33126. + */
  33127. +static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
  33128. + struct pipe_inode_info *opipe,
  33129. + size_t len, unsigned int flags)
  33130. +{
  33131. + struct pipe_buffer *ibuf, *obuf;
  33132. + int ret = 0, nbuf;
  33133. + bool input_wakeup = false;
  33134. +
  33135. +
  33136. +retry:
  33137. + ret = ipipe_prep(ipipe, flags);
  33138. + if (ret)
  33139. + return ret;
  33140. +
  33141. + ret = opipe_prep(opipe, flags);
  33142. + if (ret)
  33143. + return ret;
  33144. +
  33145. + /*
  33146. + * Potential ABBA deadlock, work around it by ordering lock
  33147. + * grabbing by pipe info address. Otherwise two different processes
  33148. + * could deadlock (one doing tee from A -> B, the other from B -> A).
  33149. + */
  33150. + pipe_double_lock(ipipe, opipe);
  33151. +
  33152. + do {
  33153. + if (!opipe->readers) {
  33154. + send_sig(SIGPIPE, current, 0);
  33155. + if (!ret)
  33156. + ret = -EPIPE;
  33157. + break;
  33158. + }
  33159. +
  33160. + if (!ipipe->nrbufs && !ipipe->writers)
  33161. + break;
  33162. +
  33163. + /*
  33164. + * Cannot make any progress, because either the input
  33165. + * pipe is empty or the output pipe is full.
  33166. + */
  33167. + if (!ipipe->nrbufs || opipe->nrbufs >= opipe->buffers) {
  33168. + /* Already processed some buffers, break */
  33169. + if (ret)
  33170. + break;
  33171. +
  33172. + if (flags & SPLICE_F_NONBLOCK) {
  33173. + ret = -EAGAIN;
  33174. + break;
  33175. + }
  33176. +
  33177. + /*
  33178. + * We raced with another reader/writer and haven't
  33179. + * managed to process any buffers. A zero return
  33180. + * value means EOF, so retry instead.
  33181. + */
  33182. + pipe_unlock(ipipe);
  33183. + pipe_unlock(opipe);
  33184. + goto retry;
  33185. + }
  33186. +
  33187. + ibuf = ipipe->bufs + ipipe->curbuf;
  33188. + nbuf = (opipe->curbuf + opipe->nrbufs) & (opipe->buffers - 1);
  33189. + obuf = opipe->bufs + nbuf;
  33190. +
  33191. + if (len >= ibuf->len) {
  33192. + /*
  33193. + * Simply move the whole buffer from ipipe to opipe
  33194. + */
  33195. + *obuf = *ibuf;
  33196. + ibuf->ops = NULL;
  33197. + opipe->nrbufs++;
  33198. + ipipe->curbuf = (ipipe->curbuf + 1) & (ipipe->buffers - 1);
  33199. + ipipe->nrbufs--;
  33200. + input_wakeup = true;
  33201. + } else {
  33202. + /*
  33203. + * Get a reference to this pipe buffer,
  33204. + * so we can copy the contents over.
  33205. + */
  33206. + ibuf->ops->get(ipipe, ibuf);
  33207. + *obuf = *ibuf;
  33208. +
  33209. + /*
  33210. + * Don't inherit the gift flag, we need to
  33211. + * prevent multiple steals of this page.
  33212. + */
  33213. + obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
  33214. +
  33215. + obuf->len = len;
  33216. + opipe->nrbufs++;
  33217. + ibuf->offset += obuf->len;
  33218. + ibuf->len -= obuf->len;
  33219. + }
  33220. + ret += obuf->len;
  33221. + len -= obuf->len;
  33222. + } while (len);
  33223. +
  33224. + pipe_unlock(ipipe);
  33225. + pipe_unlock(opipe);
  33226. +
  33227. + /*
  33228. + * If we put data in the output pipe, wakeup any potential readers.
  33229. + */
  33230. + if (ret > 0) {
  33231. + smp_mb();
  33232. + if (waitqueue_active(&opipe->wait))
  33233. + wake_up_interruptible(&opipe->wait);
  33234. + kill_fasync(&opipe->fasync_readers, SIGIO, POLL_IN);
  33235. + }
  33236. + if (input_wakeup)
  33237. + wakeup_pipe_writers(ipipe);
  33238. +
  33239. + return ret;
  33240. +}
  33241. +
  33242. +/*
  33243. + * Link contents of ipipe to opipe.
  33244. + */
  33245. +static int link_pipe(struct pipe_inode_info *ipipe,
  33246. + struct pipe_inode_info *opipe,
  33247. + size_t len, unsigned int flags)
  33248. +{
  33249. + struct pipe_buffer *ibuf, *obuf;
  33250. + int ret = 0, i = 0, nbuf;
  33251. +
  33252. + /*
  33253. + * Potential ABBA deadlock, work around it by ordering lock
  33254. + * grabbing by pipe info address. Otherwise two different processes
  33255. + * could deadlock (one doing tee from A -> B, the other from B -> A).
  33256. + */
  33257. + pipe_double_lock(ipipe, opipe);
  33258. +
  33259. + do {
  33260. + if (!opipe->readers) {
  33261. + send_sig(SIGPIPE, current, 0);
  33262. + if (!ret)
  33263. + ret = -EPIPE;
  33264. + break;
  33265. + }
  33266. +
  33267. + /*
  33268. + * If we have iterated all input buffers or ran out of
  33269. + * output room, break.
  33270. + */
  33271. + if (i >= ipipe->nrbufs || opipe->nrbufs >= opipe->buffers)
  33272. + break;
  33273. +
  33274. + ibuf = ipipe->bufs + ((ipipe->curbuf + i) & (ipipe->buffers-1));
  33275. + nbuf = (opipe->curbuf + opipe->nrbufs) & (opipe->buffers - 1);
  33276. +
  33277. + /*
  33278. + * Get a reference to this pipe buffer,
  33279. + * so we can copy the contents over.
  33280. + */
  33281. + ibuf->ops->get(ipipe, ibuf);
  33282. +
  33283. + obuf = opipe->bufs + nbuf;
  33284. + *obuf = *ibuf;
  33285. +
  33286. + /*
  33287. + * Don't inherit the gift flag, we need to
  33288. + * prevent multiple steals of this page.
  33289. + */
  33290. + obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
  33291. +
  33292. + if (obuf->len > len)
  33293. + obuf->len = len;
  33294. +
  33295. + opipe->nrbufs++;
  33296. + ret += obuf->len;
  33297. + len -= obuf->len;
  33298. + i++;
  33299. + } while (len);
  33300. +
  33301. + /*
  33302. + * return EAGAIN if we have the potential of some data in the
  33303. + * future, otherwise just return 0
  33304. + */
  33305. + if (!ret && ipipe->waiting_writers && (flags & SPLICE_F_NONBLOCK))
  33306. + ret = -EAGAIN;
  33307. +
  33308. + pipe_unlock(ipipe);
  33309. + pipe_unlock(opipe);
  33310. +
  33311. + /*
  33312. + * If we put data in the output pipe, wakeup any potential readers.
  33313. + */
  33314. + if (ret > 0) {
  33315. + smp_mb();
  33316. + if (waitqueue_active(&opipe->wait))
  33317. + wake_up_interruptible(&opipe->wait);
  33318. + kill_fasync(&opipe->fasync_readers, SIGIO, POLL_IN);
  33319. + }
  33320. +
  33321. + return ret;
  33322. +}
  33323. +
  33324. +/*
  33325. + * This is a tee(1) implementation that works on pipes. It doesn't copy
  33326. + * any data, it simply references the 'in' pages on the 'out' pipe.
  33327. + * The 'flags' used are the SPLICE_F_* variants, currently the only
  33328. + * applicable one is SPLICE_F_NONBLOCK.
  33329. + */
  33330. +static long do_tee(struct file *in, struct file *out, size_t len,
  33331. + unsigned int flags)
  33332. +{
  33333. + struct pipe_inode_info *ipipe = pipe_info(in->f_path.dentry->d_inode);
  33334. + struct pipe_inode_info *opipe = pipe_info(out->f_path.dentry->d_inode);
  33335. + int ret = -EINVAL;
  33336. +
  33337. + /*
  33338. + * Duplicate the contents of ipipe to opipe without actually
  33339. + * copying the data.
  33340. + */
  33341. + if (ipipe && opipe && ipipe != opipe) {
  33342. + /*
  33343. + * Keep going, unless we encounter an error. The ipipe/opipe
  33344. + * ordering doesn't really matter.
  33345. + */
  33346. + ret = ipipe_prep(ipipe, flags);
  33347. + if (!ret) {
  33348. + ret = opipe_prep(opipe, flags);
  33349. + if (!ret)
  33350. + ret = link_pipe(ipipe, opipe, len, flags);
  33351. + }
  33352. + }
  33353. +
  33354. + return ret;
  33355. +}
  33356. +
  33357. +SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags)
  33358. +{
  33359. + struct file *in;
  33360. + int error, fput_in;
  33361. +
  33362. + if (unlikely(!len))
  33363. + return 0;
  33364. +
  33365. + error = -EBADF;
  33366. + in = fget_light(fdin, &fput_in);
  33367. + if (in) {
  33368. + if (in->f_mode & FMODE_READ) {
  33369. + int fput_out;
  33370. + struct file *out = fget_light(fdout, &fput_out);
  33371. +
  33372. + if (out) {
  33373. + if (out->f_mode & FMODE_WRITE)
  33374. + error = do_tee(in, out, len, flags);
  33375. + fput_light(out, fput_out);
  33376. + }
  33377. + }
  33378. + fput_light(in, fput_in);
  33379. + }
  33380. +
  33381. + return error;
  33382. +}
  33383. diff -Nur linux-2.6.36.orig/security/commoncap.c linux-2.6.36/security/commoncap.c
  33384. --- linux-2.6.36.orig/security/commoncap.c 2010-10-20 22:30:22.000000000 +0200
  33385. +++ linux-2.6.36/security/commoncap.c 2011-01-10 19:52:38.000000000 +0100
  33386. @@ -951,3 +951,4 @@
  33387. }
  33388. return ret;
  33389. }
  33390. +EXPORT_SYMBOL(cap_file_mmap);
  33391. diff -Nur linux-2.6.36.orig/security/device_cgroup.c linux-2.6.36/security/device_cgroup.c
  33392. --- linux-2.6.36.orig/security/device_cgroup.c 2010-10-20 22:30:22.000000000 +0200
  33393. +++ linux-2.6.36/security/device_cgroup.c 2011-01-10 19:52:38.000000000 +0100
  33394. @@ -515,6 +515,7 @@
  33395. return -EPERM;
  33396. }
  33397. +EXPORT_SYMBOL(devcgroup_inode_permission);
  33398. int devcgroup_inode_mknod(int mode, dev_t dev)
  33399. {
  33400. diff -Nur linux-2.6.36.orig/security/security.c linux-2.6.36/security/security.c
  33401. --- linux-2.6.36.orig/security/security.c 2010-10-20 22:30:22.000000000 +0200
  33402. +++ linux-2.6.36/security/security.c 2011-01-10 19:52:38.000000000 +0100
  33403. @@ -376,6 +376,7 @@
  33404. return 0;
  33405. return security_ops->path_mkdir(dir, dentry, mode);
  33406. }
  33407. +EXPORT_SYMBOL(security_path_mkdir);
  33408. int security_path_rmdir(struct path *dir, struct dentry *dentry)
  33409. {
  33410. @@ -383,6 +384,7 @@
  33411. return 0;
  33412. return security_ops->path_rmdir(dir, dentry);
  33413. }
  33414. +EXPORT_SYMBOL(security_path_rmdir);
  33415. int security_path_unlink(struct path *dir, struct dentry *dentry)
  33416. {
  33417. @@ -390,6 +392,7 @@
  33418. return 0;
  33419. return security_ops->path_unlink(dir, dentry);
  33420. }
  33421. +EXPORT_SYMBOL(security_path_unlink);
  33422. int security_path_symlink(struct path *dir, struct dentry *dentry,
  33423. const char *old_name)
  33424. @@ -398,6 +401,7 @@
  33425. return 0;
  33426. return security_ops->path_symlink(dir, dentry, old_name);
  33427. }
  33428. +EXPORT_SYMBOL(security_path_symlink);
  33429. int security_path_link(struct dentry *old_dentry, struct path *new_dir,
  33430. struct dentry *new_dentry)
  33431. @@ -406,6 +410,7 @@
  33432. return 0;
  33433. return security_ops->path_link(old_dentry, new_dir, new_dentry);
  33434. }
  33435. +EXPORT_SYMBOL(security_path_link);
  33436. int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
  33437. struct path *new_dir, struct dentry *new_dentry)
  33438. @@ -416,6 +421,7 @@
  33439. return security_ops->path_rename(old_dir, old_dentry, new_dir,
  33440. new_dentry);
  33441. }
  33442. +EXPORT_SYMBOL(security_path_rename);
  33443. int security_path_truncate(struct path *path)
  33444. {
  33445. @@ -423,6 +429,7 @@
  33446. return 0;
  33447. return security_ops->path_truncate(path);
  33448. }
  33449. +EXPORT_SYMBOL(security_path_truncate);
  33450. int security_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
  33451. mode_t mode)
  33452. @@ -431,6 +438,7 @@
  33453. return 0;
  33454. return security_ops->path_chmod(dentry, mnt, mode);
  33455. }
  33456. +EXPORT_SYMBOL(security_path_chmod);
  33457. int security_path_chown(struct path *path, uid_t uid, gid_t gid)
  33458. {
  33459. @@ -438,6 +446,7 @@
  33460. return 0;
  33461. return security_ops->path_chown(path, uid, gid);
  33462. }
  33463. +EXPORT_SYMBOL(security_path_chown);
  33464. int security_path_chroot(struct path *path)
  33465. {
  33466. @@ -514,6 +523,7 @@
  33467. return 0;
  33468. return security_ops->inode_readlink(dentry);
  33469. }
  33470. +EXPORT_SYMBOL(security_inode_readlink);
  33471. int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
  33472. {
  33473. @@ -528,6 +538,7 @@
  33474. return 0;
  33475. return security_ops->inode_permission(inode, mask);
  33476. }
  33477. +EXPORT_SYMBOL(security_inode_permission);
  33478. int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
  33479. {
  33480. @@ -627,6 +638,7 @@
  33481. return fsnotify_perm(file, mask);
  33482. }
  33483. +EXPORT_SYMBOL(security_file_permission);
  33484. int security_file_alloc(struct file *file)
  33485. {
  33486. @@ -654,6 +666,7 @@
  33487. return ret;
  33488. return ima_file_mmap(file, prot);
  33489. }
  33490. +EXPORT_SYMBOL(security_file_mmap);
  33491. int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
  33492. unsigned long prot)