cifssmb.c 193 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570
  1. /*
  2. * fs/cifs/cifssmb.c
  3. *
  4. * Copyright (C) International Business Machines Corp., 2002,2010
  5. * Author(s): Steve French (sfrench@us.ibm.com)
  6. *
  7. * Contains the routines for constructing the SMB PDUs themselves
  8. *
  9. * This library is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU Lesser General Public License as published
  11. * by the Free Software Foundation; either version 2.1 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
  17. * the GNU Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public License
  20. * along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22. */
  23. /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
  24. /* These are mostly routines that operate on a pathname, or on a tree id */
  25. /* (mounted volume), but there are eight handle based routines which must be */
  26. /* treated slightly differently for reconnection purposes since we never */
  27. /* want to reuse a stale file handle and only the caller knows the file info */
  28. #include <linux/fs.h>
  29. #include <linux/kernel.h>
  30. #include <linux/vfs.h>
  31. #include <linux/slab.h>
  32. #include <linux/posix_acl_xattr.h>
  33. #include <linux/pagemap.h>
  34. #include <linux/swap.h>
  35. #include <linux/task_io_accounting_ops.h>
  36. #include <asm/uaccess.h>
  37. #include "cifspdu.h"
  38. #include "cifsglob.h"
  39. #include "cifsacl.h"
  40. #include "cifsproto.h"
  41. #include "cifs_unicode.h"
  42. #include "cifs_debug.h"
  43. #include "fscache.h"
  44. #ifdef CONFIG_CIFS_POSIX
  45. static struct {
  46. int index;
  47. char *name;
  48. } protocols[] = {
  49. #ifdef CONFIG_CIFS_WEAK_PW_HASH
  50. {LANMAN_PROT, "\2LM1.2X002"},
  51. {LANMAN2_PROT, "\2LANMAN2.1"},
  52. #endif /* weak password hashing for legacy clients */
  53. {CIFS_PROT, "\2NT LM 0.12"},
  54. {POSIX_PROT, "\2POSIX 2"},
  55. {BAD_PROT, "\2"}
  56. };
  57. #else
  58. static struct {
  59. int index;
  60. char *name;
  61. } protocols[] = {
  62. #ifdef CONFIG_CIFS_WEAK_PW_HASH
  63. {LANMAN_PROT, "\2LM1.2X002"},
  64. {LANMAN2_PROT, "\2LANMAN2.1"},
  65. #endif /* weak password hashing for legacy clients */
  66. {CIFS_PROT, "\2NT LM 0.12"},
  67. {BAD_PROT, "\2"}
  68. };
  69. #endif
  70. /* define the number of elements in the cifs dialect array */
  71. #ifdef CONFIG_CIFS_POSIX
  72. #ifdef CONFIG_CIFS_WEAK_PW_HASH
  73. #define CIFS_NUM_PROT 4
  74. #else
  75. #define CIFS_NUM_PROT 2
  76. #endif /* CIFS_WEAK_PW_HASH */
  77. #else /* not posix */
  78. #ifdef CONFIG_CIFS_WEAK_PW_HASH
  79. #define CIFS_NUM_PROT 3
  80. #else
  81. #define CIFS_NUM_PROT 1
  82. #endif /* CONFIG_CIFS_WEAK_PW_HASH */
  83. #endif /* CIFS_POSIX */
  84. /*
  85. * Mark as invalid, all open files on tree connections since they
  86. * were closed when session to server was lost.
  87. */
  88. void
  89. cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
  90. {
  91. struct cifsFileInfo *open_file = NULL;
  92. struct list_head *tmp;
  93. struct list_head *tmp1;
  94. /* list all files open on tree connection and mark them invalid */
  95. spin_lock(&tcon->open_file_lock);
  96. list_for_each_safe(tmp, tmp1, &tcon->openFileList) {
  97. open_file = list_entry(tmp, struct cifsFileInfo, tlist);
  98. open_file->invalidHandle = true;
  99. open_file->oplock_break_cancelled = true;
  100. }
  101. spin_unlock(&tcon->open_file_lock);
  102. /*
  103. * BB Add call to invalidate_inodes(sb) for all superblocks mounted
  104. * to this tcon.
  105. */
  106. }
  107. /* reconnect the socket, tcon, and smb session if needed */
  108. static int
  109. cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
  110. {
  111. int rc;
  112. struct cifs_ses *ses;
  113. struct TCP_Server_Info *server;
  114. struct nls_table *nls_codepage;
  115. /*
  116. * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
  117. * tcp and smb session status done differently for those three - in the
  118. * calling routine
  119. */
  120. if (!tcon)
  121. return 0;
  122. ses = tcon->ses;
  123. server = ses->server;
  124. /*
  125. * only tree disconnect, open, and write, (and ulogoff which does not
  126. * have tcon) are allowed as we start force umount
  127. */
  128. if (tcon->tidStatus == CifsExiting) {
  129. if (smb_command != SMB_COM_WRITE_ANDX &&
  130. smb_command != SMB_COM_OPEN_ANDX &&
  131. smb_command != SMB_COM_TREE_DISCONNECT) {
  132. cifs_dbg(FYI, "can not send cmd %d while umounting\n",
  133. smb_command);
  134. return -ENODEV;
  135. }
  136. }
  137. /*
  138. * Give demultiplex thread up to 10 seconds to reconnect, should be
  139. * greater than cifs socket timeout which is 7 seconds
  140. */
  141. while (server->tcpStatus == CifsNeedReconnect) {
  142. rc = wait_event_interruptible_timeout(server->response_q,
  143. (server->tcpStatus != CifsNeedReconnect),
  144. 10 * HZ);
  145. if (rc < 0) {
  146. cifs_dbg(FYI, "%s: aborting reconnect due to a received"
  147. " signal by the process\n", __func__);
  148. return -ERESTARTSYS;
  149. }
  150. /* are we still trying to reconnect? */
  151. if (server->tcpStatus != CifsNeedReconnect)
  152. break;
  153. /*
  154. * on "soft" mounts we wait once. Hard mounts keep
  155. * retrying until process is killed or server comes
  156. * back on-line
  157. */
  158. if (!tcon->retry) {
  159. cifs_dbg(FYI, "gave up waiting on reconnect in smb_init\n");
  160. return -EHOSTDOWN;
  161. }
  162. }
  163. if (!ses->need_reconnect && !tcon->need_reconnect)
  164. return 0;
  165. nls_codepage = load_nls_default();
  166. /*
  167. * need to prevent multiple threads trying to simultaneously
  168. * reconnect the same SMB session
  169. */
  170. mutex_lock(&ses->session_mutex);
  171. rc = cifs_negotiate_protocol(0, ses);
  172. if (rc == 0 && ses->need_reconnect)
  173. rc = cifs_setup_session(0, ses, nls_codepage);
  174. /* do we need to reconnect tcon? */
  175. if (rc || !tcon->need_reconnect) {
  176. mutex_unlock(&ses->session_mutex);
  177. goto out;
  178. }
  179. cifs_mark_open_files_invalid(tcon);
  180. rc = CIFSTCon(0, ses, tcon->treeName, tcon, nls_codepage);
  181. mutex_unlock(&ses->session_mutex);
  182. cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
  183. if (rc)
  184. goto out;
  185. atomic_inc(&tconInfoReconnectCount);
  186. /* tell server Unix caps we support */
  187. if (ses->capabilities & CAP_UNIX)
  188. reset_cifs_unix_caps(0, tcon, NULL, NULL);
  189. /*
  190. * Removed call to reopen open files here. It is safer (and faster) to
  191. * reopen files one at a time as needed in read and write.
  192. *
  193. * FIXME: what about file locks? don't we need to reclaim them ASAP?
  194. */
  195. out:
  196. /*
  197. * Check if handle based operation so we know whether we can continue
  198. * or not without returning to caller to reset file handle
  199. */
  200. switch (smb_command) {
  201. case SMB_COM_READ_ANDX:
  202. case SMB_COM_WRITE_ANDX:
  203. case SMB_COM_CLOSE:
  204. case SMB_COM_FIND_CLOSE2:
  205. case SMB_COM_LOCKING_ANDX:
  206. rc = -EAGAIN;
  207. }
  208. unload_nls(nls_codepage);
  209. return rc;
  210. }
  211. /* Allocate and return pointer to an SMB request buffer, and set basic
  212. SMB information in the SMB header. If the return code is zero, this
  213. function must have filled in request_buf pointer */
  214. static int
  215. small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
  216. void **request_buf)
  217. {
  218. int rc;
  219. rc = cifs_reconnect_tcon(tcon, smb_command);
  220. if (rc)
  221. return rc;
  222. *request_buf = cifs_small_buf_get();
  223. if (*request_buf == NULL) {
  224. /* BB should we add a retry in here if not a writepage? */
  225. return -ENOMEM;
  226. }
  227. header_assemble((struct smb_hdr *) *request_buf, smb_command,
  228. tcon, wct);
  229. if (tcon != NULL)
  230. cifs_stats_inc(&tcon->num_smbs_sent);
  231. return 0;
  232. }
  233. int
  234. small_smb_init_no_tc(const int smb_command, const int wct,
  235. struct cifs_ses *ses, void **request_buf)
  236. {
  237. int rc;
  238. struct smb_hdr *buffer;
  239. rc = small_smb_init(smb_command, wct, NULL, request_buf);
  240. if (rc)
  241. return rc;
  242. buffer = (struct smb_hdr *)*request_buf;
  243. buffer->Mid = get_next_mid(ses->server);
  244. if (ses->capabilities & CAP_UNICODE)
  245. buffer->Flags2 |= SMBFLG2_UNICODE;
  246. if (ses->capabilities & CAP_STATUS32)
  247. buffer->Flags2 |= SMBFLG2_ERR_STATUS;
  248. /* uid, tid can stay at zero as set in header assemble */
  249. /* BB add support for turning on the signing when
  250. this function is used after 1st of session setup requests */
  251. return rc;
  252. }
  253. /* If the return code is zero, this function must fill in request_buf pointer */
  254. static int
  255. __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
  256. void **request_buf, void **response_buf)
  257. {
  258. *request_buf = cifs_buf_get();
  259. if (*request_buf == NULL) {
  260. /* BB should we add a retry in here if not a writepage? */
  261. return -ENOMEM;
  262. }
  263. /* Although the original thought was we needed the response buf for */
  264. /* potential retries of smb operations it turns out we can determine */
  265. /* from the mid flags when the request buffer can be resent without */
  266. /* having to use a second distinct buffer for the response */
  267. if (response_buf)
  268. *response_buf = *request_buf;
  269. header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
  270. wct);
  271. if (tcon != NULL)
  272. cifs_stats_inc(&tcon->num_smbs_sent);
  273. return 0;
  274. }
  275. /* If the return code is zero, this function must fill in request_buf pointer */
  276. static int
  277. smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
  278. void **request_buf, void **response_buf)
  279. {
  280. int rc;
  281. rc = cifs_reconnect_tcon(tcon, smb_command);
  282. if (rc)
  283. return rc;
  284. return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
  285. }
  286. static int
  287. smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
  288. void **request_buf, void **response_buf)
  289. {
  290. if (tcon->ses->need_reconnect || tcon->need_reconnect)
  291. return -EHOSTDOWN;
  292. return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
  293. }
  294. static int validate_t2(struct smb_t2_rsp *pSMB)
  295. {
  296. unsigned int total_size;
  297. /* check for plausible wct */
  298. if (pSMB->hdr.WordCount < 10)
  299. goto vt2_err;
  300. /* check for parm and data offset going beyond end of smb */
  301. if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
  302. get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
  303. goto vt2_err;
  304. total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
  305. if (total_size >= 512)
  306. goto vt2_err;
  307. /* check that bcc is at least as big as parms + data, and that it is
  308. * less than negotiated smb buffer
  309. */
  310. total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
  311. if (total_size > get_bcc(&pSMB->hdr) ||
  312. total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
  313. goto vt2_err;
  314. return 0;
  315. vt2_err:
  316. cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
  317. sizeof(struct smb_t2_rsp) + 16);
  318. return -EINVAL;
  319. }
  320. static int
  321. decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
  322. {
  323. int rc = 0;
  324. u16 count;
  325. char *guid = pSMBr->u.extended_response.GUID;
  326. struct TCP_Server_Info *server = ses->server;
  327. count = get_bcc(&pSMBr->hdr);
  328. if (count < SMB1_CLIENT_GUID_SIZE)
  329. return -EIO;
  330. spin_lock(&cifs_tcp_ses_lock);
  331. if (server->srv_count > 1) {
  332. spin_unlock(&cifs_tcp_ses_lock);
  333. if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
  334. cifs_dbg(FYI, "server UID changed\n");
  335. memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
  336. }
  337. } else {
  338. spin_unlock(&cifs_tcp_ses_lock);
  339. memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
  340. }
  341. if (count == SMB1_CLIENT_GUID_SIZE) {
  342. server->sec_ntlmssp = true;
  343. } else {
  344. count -= SMB1_CLIENT_GUID_SIZE;
  345. rc = decode_negTokenInit(
  346. pSMBr->u.extended_response.SecurityBlob, count, server);
  347. if (rc != 1)
  348. return -EINVAL;
  349. }
  350. return 0;
  351. }
  352. int
  353. cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
  354. {
  355. bool srv_sign_required = server->sec_mode & server->vals->signing_required;
  356. bool srv_sign_enabled = server->sec_mode & server->vals->signing_enabled;
  357. bool mnt_sign_enabled = global_secflags & CIFSSEC_MAY_SIGN;
  358. /*
  359. * Is signing required by mnt options? If not then check
  360. * global_secflags to see if it is there.
  361. */
  362. if (!mnt_sign_required)
  363. mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) ==
  364. CIFSSEC_MUST_SIGN);
  365. /*
  366. * If signing is required then it's automatically enabled too,
  367. * otherwise, check to see if the secflags allow it.
  368. */
  369. mnt_sign_enabled = mnt_sign_required ? mnt_sign_required :
  370. (global_secflags & CIFSSEC_MAY_SIGN);
  371. /* If server requires signing, does client allow it? */
  372. if (srv_sign_required) {
  373. if (!mnt_sign_enabled) {
  374. cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!");
  375. return -ENOTSUPP;
  376. }
  377. server->sign = true;
  378. }
  379. /* If client requires signing, does server allow it? */
  380. if (mnt_sign_required) {
  381. if (!srv_sign_enabled) {
  382. cifs_dbg(VFS, "Server does not support signing!");
  383. return -ENOTSUPP;
  384. }
  385. server->sign = true;
  386. }
  387. return 0;
  388. }
  389. #ifdef CONFIG_CIFS_WEAK_PW_HASH
  390. static int
  391. decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
  392. {
  393. __s16 tmp;
  394. struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
  395. if (server->dialect != LANMAN_PROT && server->dialect != LANMAN2_PROT)
  396. return -EOPNOTSUPP;
  397. server->sec_mode = le16_to_cpu(rsp->SecurityMode);
  398. server->maxReq = min_t(unsigned int,
  399. le16_to_cpu(rsp->MaxMpxCount),
  400. cifs_max_pending);
  401. set_credits(server, server->maxReq);
  402. server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
  403. /* even though we do not use raw we might as well set this
  404. accurately, in case we ever find a need for it */
  405. if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
  406. server->max_rw = 0xFF00;
  407. server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
  408. } else {
  409. server->max_rw = 0;/* do not need to use raw anyway */
  410. server->capabilities = CAP_MPX_MODE;
  411. }
  412. tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
  413. if (tmp == -1) {
  414. /* OS/2 often does not set timezone therefore
  415. * we must use server time to calc time zone.
  416. * Could deviate slightly from the right zone.
  417. * Smallest defined timezone difference is 15 minutes
  418. * (i.e. Nepal). Rounding up/down is done to match
  419. * this requirement.
  420. */
  421. int val, seconds, remain, result;
  422. struct timespec ts, utc;
  423. utc = CURRENT_TIME;
  424. ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
  425. rsp->SrvTime.Time, 0);
  426. cifs_dbg(FYI, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n",
  427. (int)ts.tv_sec, (int)utc.tv_sec,
  428. (int)(utc.tv_sec - ts.tv_sec));
  429. val = (int)(utc.tv_sec - ts.tv_sec);
  430. seconds = abs(val);
  431. result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
  432. remain = seconds % MIN_TZ_ADJ;
  433. if (remain >= (MIN_TZ_ADJ / 2))
  434. result += MIN_TZ_ADJ;
  435. if (val < 0)
  436. result = -result;
  437. server->timeAdj = result;
  438. } else {
  439. server->timeAdj = (int)tmp;
  440. server->timeAdj *= 60; /* also in seconds */
  441. }
  442. cifs_dbg(FYI, "server->timeAdj: %d seconds\n", server->timeAdj);
  443. /* BB get server time for time conversions and add
  444. code to use it and timezone since this is not UTC */
  445. if (rsp->EncryptionKeyLength ==
  446. cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
  447. memcpy(server->cryptkey, rsp->EncryptionKey,
  448. CIFS_CRYPTO_KEY_SIZE);
  449. } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
  450. return -EIO; /* need cryptkey unless plain text */
  451. }
  452. cifs_dbg(FYI, "LANMAN negotiated\n");
  453. return 0;
  454. }
  455. #else
  456. static inline int
  457. decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
  458. {
  459. cifs_dbg(VFS, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
  460. return -EOPNOTSUPP;
  461. }
  462. #endif
  463. static bool
  464. should_set_ext_sec_flag(enum securityEnum sectype)
  465. {
  466. switch (sectype) {
  467. case RawNTLMSSP:
  468. case Kerberos:
  469. return true;
  470. case Unspecified:
  471. if (global_secflags &
  472. (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
  473. return true;
  474. /* Fallthrough */
  475. default:
  476. return false;
  477. }
  478. }
  479. int
  480. CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
  481. {
  482. NEGOTIATE_REQ *pSMB;
  483. NEGOTIATE_RSP *pSMBr;
  484. int rc = 0;
  485. int bytes_returned;
  486. int i;
  487. struct TCP_Server_Info *server = ses->server;
  488. u16 count;
  489. if (!server) {
  490. WARN(1, "%s: server is NULL!\n", __func__);
  491. return -EIO;
  492. }
  493. rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
  494. (void **) &pSMB, (void **) &pSMBr);
  495. if (rc)
  496. return rc;
  497. pSMB->hdr.Mid = get_next_mid(server);
  498. pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
  499. if (should_set_ext_sec_flag(ses->sectype)) {
  500. cifs_dbg(FYI, "Requesting extended security.");
  501. pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
  502. }
  503. count = 0;
  504. /*
  505. * We know that all the name entries in the protocols array
  506. * are short (< 16 bytes anyway) and are NUL terminated.
  507. */
  508. for (i = 0; i < CIFS_NUM_PROT; i++) {
  509. size_t len = strlen(protocols[i].name) + 1;
  510. memcpy(pSMB->DialectsArray+count, protocols[i].name, len);
  511. count += len;
  512. }
  513. inc_rfc1001_len(pSMB, count);
  514. pSMB->ByteCount = cpu_to_le16(count);
  515. rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
  516. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  517. if (rc != 0)
  518. goto neg_err_exit;
  519. server->dialect = le16_to_cpu(pSMBr->DialectIndex);
  520. cifs_dbg(FYI, "Dialect: %d\n", server->dialect);
  521. /* Check wct = 1 error case */
  522. if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) {
  523. /* core returns wct = 1, but we do not ask for core - otherwise
  524. small wct just comes when dialect index is -1 indicating we
  525. could not negotiate a common dialect */
  526. rc = -EOPNOTSUPP;
  527. goto neg_err_exit;
  528. } else if (pSMBr->hdr.WordCount == 13) {
  529. server->negflavor = CIFS_NEGFLAVOR_LANMAN;
  530. rc = decode_lanman_negprot_rsp(server, pSMBr);
  531. goto signing_check;
  532. } else if (pSMBr->hdr.WordCount != 17) {
  533. /* unknown wct */
  534. rc = -EOPNOTSUPP;
  535. goto neg_err_exit;
  536. }
  537. /* else wct == 17, NTLM or better */
  538. server->sec_mode = pSMBr->SecurityMode;
  539. if ((server->sec_mode & SECMODE_USER) == 0)
  540. cifs_dbg(FYI, "share mode security\n");
  541. /* one byte, so no need to convert this or EncryptionKeyLen from
  542. little endian */
  543. server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
  544. cifs_max_pending);
  545. set_credits(server, server->maxReq);
  546. /* probably no need to store and check maxvcs */
  547. server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
  548. server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
  549. cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
  550. server->capabilities = le32_to_cpu(pSMBr->Capabilities);
  551. server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
  552. server->timeAdj *= 60;
  553. if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
  554. server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
  555. memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
  556. CIFS_CRYPTO_KEY_SIZE);
  557. } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
  558. server->capabilities & CAP_EXTENDED_SECURITY) {
  559. server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
  560. rc = decode_ext_sec_blob(ses, pSMBr);
  561. } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
  562. rc = -EIO; /* no crypt key only if plain text pwd */
  563. } else {
  564. server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
  565. server->capabilities &= ~CAP_EXTENDED_SECURITY;
  566. }
  567. signing_check:
  568. if (!rc)
  569. rc = cifs_enable_signing(server, ses->sign);
  570. neg_err_exit:
  571. cifs_buf_release(pSMB);
  572. cifs_dbg(FYI, "negprot rc %d\n", rc);
  573. return rc;
  574. }
  575. int
  576. CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
  577. {
  578. struct smb_hdr *smb_buffer;
  579. int rc = 0;
  580. cifs_dbg(FYI, "In tree disconnect\n");
  581. /* BB: do we need to check this? These should never be NULL. */
  582. if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
  583. return -EIO;
  584. /*
  585. * No need to return error on this operation if tid invalidated and
  586. * closed on server already e.g. due to tcp session crashing. Also,
  587. * the tcon is no longer on the list, so no need to take lock before
  588. * checking this.
  589. */
  590. if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
  591. return 0;
  592. rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
  593. (void **)&smb_buffer);
  594. if (rc)
  595. return rc;
  596. rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
  597. if (rc)
  598. cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
  599. /* No need to return error on this operation if tid invalidated and
  600. closed on server already e.g. due to tcp session crashing */
  601. if (rc == -EAGAIN)
  602. rc = 0;
  603. return rc;
  604. }
  605. /*
  606. * This is a no-op for now. We're not really interested in the reply, but
  607. * rather in the fact that the server sent one and that server->lstrp
  608. * gets updated.
  609. *
  610. * FIXME: maybe we should consider checking that the reply matches request?
  611. */
  612. static void
  613. cifs_echo_callback(struct mid_q_entry *mid)
  614. {
  615. struct TCP_Server_Info *server = mid->callback_data;
  616. mutex_lock(&server->srv_mutex);
  617. DeleteMidQEntry(mid);
  618. mutex_unlock(&server->srv_mutex);
  619. add_credits(server, 1, CIFS_ECHO_OP);
  620. }
  621. int
  622. CIFSSMBEcho(struct TCP_Server_Info *server)
  623. {
  624. ECHO_REQ *smb;
  625. int rc = 0;
  626. struct kvec iov;
  627. struct smb_rqst rqst = { .rq_iov = &iov,
  628. .rq_nvec = 1 };
  629. cifs_dbg(FYI, "In echo request\n");
  630. rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
  631. if (rc)
  632. return rc;
  633. if (server->capabilities & CAP_UNICODE)
  634. smb->hdr.Flags2 |= SMBFLG2_UNICODE;
  635. /* set up echo request */
  636. smb->hdr.Tid = 0xffff;
  637. smb->hdr.WordCount = 1;
  638. put_unaligned_le16(1, &smb->EchoCount);
  639. put_bcc(1, &smb->hdr);
  640. smb->Data[0] = 'a';
  641. inc_rfc1001_len(smb, 3);
  642. iov.iov_base = smb;
  643. iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
  644. rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback,
  645. server, CIFS_ASYNC_OP | CIFS_ECHO_OP);
  646. if (rc)
  647. cifs_dbg(FYI, "Echo request failed: %d\n", rc);
  648. cifs_small_buf_release(smb);
  649. return rc;
  650. }
  651. int
  652. CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
  653. {
  654. LOGOFF_ANDX_REQ *pSMB;
  655. int rc = 0;
  656. cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
  657. /*
  658. * BB: do we need to check validity of ses and server? They should
  659. * always be valid since we have an active reference. If not, that
  660. * should probably be a BUG()
  661. */
  662. if (!ses || !ses->server)
  663. return -EIO;
  664. mutex_lock(&ses->session_mutex);
  665. if (ses->need_reconnect)
  666. goto session_already_dead; /* no need to send SMBlogoff if uid
  667. already closed due to reconnect */
  668. rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
  669. if (rc) {
  670. mutex_unlock(&ses->session_mutex);
  671. return rc;
  672. }
  673. pSMB->hdr.Mid = get_next_mid(ses->server);
  674. if (ses->server->sign)
  675. pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
  676. pSMB->hdr.Uid = ses->Suid;
  677. pSMB->AndXCommand = 0xFF;
  678. rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
  679. session_already_dead:
  680. mutex_unlock(&ses->session_mutex);
  681. /* if session dead then we do not need to do ulogoff,
  682. since server closed smb session, no sense reporting
  683. error */
  684. if (rc == -EAGAIN)
  685. rc = 0;
  686. return rc;
  687. }
  688. int
  689. CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
  690. const char *fileName, __u16 type,
  691. const struct nls_table *nls_codepage, int remap)
  692. {
  693. TRANSACTION2_SPI_REQ *pSMB = NULL;
  694. TRANSACTION2_SPI_RSP *pSMBr = NULL;
  695. struct unlink_psx_rq *pRqD;
  696. int name_len;
  697. int rc = 0;
  698. int bytes_returned = 0;
  699. __u16 params, param_offset, offset, byte_count;
  700. cifs_dbg(FYI, "In POSIX delete\n");
  701. PsxDelete:
  702. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  703. (void **) &pSMBr);
  704. if (rc)
  705. return rc;
  706. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  707. name_len =
  708. cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
  709. PATH_MAX, nls_codepage, remap);
  710. name_len++; /* trailing null */
  711. name_len *= 2;
  712. } else { /* BB add path length overrun check */
  713. name_len = strnlen(fileName, PATH_MAX);
  714. name_len++; /* trailing null */
  715. strncpy(pSMB->FileName, fileName, name_len);
  716. }
  717. params = 6 + name_len;
  718. pSMB->MaxParameterCount = cpu_to_le16(2);
  719. pSMB->MaxDataCount = 0; /* BB double check this with jra */
  720. pSMB->MaxSetupCount = 0;
  721. pSMB->Reserved = 0;
  722. pSMB->Flags = 0;
  723. pSMB->Timeout = 0;
  724. pSMB->Reserved2 = 0;
  725. param_offset = offsetof(struct smb_com_transaction2_spi_req,
  726. InformationLevel) - 4;
  727. offset = param_offset + params;
  728. /* Setup pointer to Request Data (inode type) */
  729. pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
  730. pRqD->type = cpu_to_le16(type);
  731. pSMB->ParameterOffset = cpu_to_le16(param_offset);
  732. pSMB->DataOffset = cpu_to_le16(offset);
  733. pSMB->SetupCount = 1;
  734. pSMB->Reserved3 = 0;
  735. pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
  736. byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
  737. pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
  738. pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
  739. pSMB->ParameterCount = cpu_to_le16(params);
  740. pSMB->TotalParameterCount = pSMB->ParameterCount;
  741. pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
  742. pSMB->Reserved4 = 0;
  743. inc_rfc1001_len(pSMB, byte_count);
  744. pSMB->ByteCount = cpu_to_le16(byte_count);
  745. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  746. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  747. if (rc)
  748. cifs_dbg(FYI, "Posix delete returned %d\n", rc);
  749. cifs_buf_release(pSMB);
  750. cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
  751. if (rc == -EAGAIN)
  752. goto PsxDelete;
  753. return rc;
  754. }
  755. int
  756. CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
  757. struct cifs_sb_info *cifs_sb)
  758. {
  759. DELETE_FILE_REQ *pSMB = NULL;
  760. DELETE_FILE_RSP *pSMBr = NULL;
  761. int rc = 0;
  762. int bytes_returned;
  763. int name_len;
  764. int remap = cifs_remap(cifs_sb);
  765. DelFileRetry:
  766. rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
  767. (void **) &pSMBr);
  768. if (rc)
  769. return rc;
  770. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  771. name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
  772. PATH_MAX, cifs_sb->local_nls,
  773. remap);
  774. name_len++; /* trailing null */
  775. name_len *= 2;
  776. } else { /* BB improve check for buffer overruns BB */
  777. name_len = strnlen(name, PATH_MAX);
  778. name_len++; /* trailing null */
  779. strncpy(pSMB->fileName, name, name_len);
  780. }
  781. pSMB->SearchAttributes =
  782. cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
  783. pSMB->BufferFormat = 0x04;
  784. inc_rfc1001_len(pSMB, name_len + 1);
  785. pSMB->ByteCount = cpu_to_le16(name_len + 1);
  786. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  787. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  788. cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
  789. if (rc)
  790. cifs_dbg(FYI, "Error in RMFile = %d\n", rc);
  791. cifs_buf_release(pSMB);
  792. if (rc == -EAGAIN)
  793. goto DelFileRetry;
  794. return rc;
  795. }
  796. int
  797. CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
  798. struct cifs_sb_info *cifs_sb)
  799. {
  800. DELETE_DIRECTORY_REQ *pSMB = NULL;
  801. DELETE_DIRECTORY_RSP *pSMBr = NULL;
  802. int rc = 0;
  803. int bytes_returned;
  804. int name_len;
  805. int remap = cifs_remap(cifs_sb);
  806. cifs_dbg(FYI, "In CIFSSMBRmDir\n");
  807. RmDirRetry:
  808. rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
  809. (void **) &pSMBr);
  810. if (rc)
  811. return rc;
  812. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  813. name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
  814. PATH_MAX, cifs_sb->local_nls,
  815. remap);
  816. name_len++; /* trailing null */
  817. name_len *= 2;
  818. } else { /* BB improve check for buffer overruns BB */
  819. name_len = strnlen(name, PATH_MAX);
  820. name_len++; /* trailing null */
  821. strncpy(pSMB->DirName, name, name_len);
  822. }
  823. pSMB->BufferFormat = 0x04;
  824. inc_rfc1001_len(pSMB, name_len + 1);
  825. pSMB->ByteCount = cpu_to_le16(name_len + 1);
  826. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  827. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  828. cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
  829. if (rc)
  830. cifs_dbg(FYI, "Error in RMDir = %d\n", rc);
  831. cifs_buf_release(pSMB);
  832. if (rc == -EAGAIN)
  833. goto RmDirRetry;
  834. return rc;
  835. }
  836. int
  837. CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
  838. struct cifs_sb_info *cifs_sb)
  839. {
  840. int rc = 0;
  841. CREATE_DIRECTORY_REQ *pSMB = NULL;
  842. CREATE_DIRECTORY_RSP *pSMBr = NULL;
  843. int bytes_returned;
  844. int name_len;
  845. int remap = cifs_remap(cifs_sb);
  846. cifs_dbg(FYI, "In CIFSSMBMkDir\n");
  847. MkDirRetry:
  848. rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
  849. (void **) &pSMBr);
  850. if (rc)
  851. return rc;
  852. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  853. name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
  854. PATH_MAX, cifs_sb->local_nls,
  855. remap);
  856. name_len++; /* trailing null */
  857. name_len *= 2;
  858. } else { /* BB improve check for buffer overruns BB */
  859. name_len = strnlen(name, PATH_MAX);
  860. name_len++; /* trailing null */
  861. strncpy(pSMB->DirName, name, name_len);
  862. }
  863. pSMB->BufferFormat = 0x04;
  864. inc_rfc1001_len(pSMB, name_len + 1);
  865. pSMB->ByteCount = cpu_to_le16(name_len + 1);
  866. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  867. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  868. cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
  869. if (rc)
  870. cifs_dbg(FYI, "Error in Mkdir = %d\n", rc);
  871. cifs_buf_release(pSMB);
  872. if (rc == -EAGAIN)
  873. goto MkDirRetry;
  874. return rc;
  875. }
  876. int
  877. CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
  878. __u32 posix_flags, __u64 mode, __u16 *netfid,
  879. FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
  880. const char *name, const struct nls_table *nls_codepage,
  881. int remap)
  882. {
  883. TRANSACTION2_SPI_REQ *pSMB = NULL;
  884. TRANSACTION2_SPI_RSP *pSMBr = NULL;
  885. int name_len;
  886. int rc = 0;
  887. int bytes_returned = 0;
  888. __u16 params, param_offset, offset, byte_count, count;
  889. OPEN_PSX_REQ *pdata;
  890. OPEN_PSX_RSP *psx_rsp;
  891. cifs_dbg(FYI, "In POSIX Create\n");
  892. PsxCreat:
  893. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  894. (void **) &pSMBr);
  895. if (rc)
  896. return rc;
  897. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  898. name_len =
  899. cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
  900. PATH_MAX, nls_codepage, remap);
  901. name_len++; /* trailing null */
  902. name_len *= 2;
  903. } else { /* BB improve the check for buffer overruns BB */
  904. name_len = strnlen(name, PATH_MAX);
  905. name_len++; /* trailing null */
  906. strncpy(pSMB->FileName, name, name_len);
  907. }
  908. params = 6 + name_len;
  909. count = sizeof(OPEN_PSX_REQ);
  910. pSMB->MaxParameterCount = cpu_to_le16(2);
  911. pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
  912. pSMB->MaxSetupCount = 0;
  913. pSMB->Reserved = 0;
  914. pSMB->Flags = 0;
  915. pSMB->Timeout = 0;
  916. pSMB->Reserved2 = 0;
  917. param_offset = offsetof(struct smb_com_transaction2_spi_req,
  918. InformationLevel) - 4;
  919. offset = param_offset + params;
  920. pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
  921. pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
  922. pdata->Permissions = cpu_to_le64(mode);
  923. pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
  924. pdata->OpenFlags = cpu_to_le32(*pOplock);
  925. pSMB->ParameterOffset = cpu_to_le16(param_offset);
  926. pSMB->DataOffset = cpu_to_le16(offset);
  927. pSMB->SetupCount = 1;
  928. pSMB->Reserved3 = 0;
  929. pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
  930. byte_count = 3 /* pad */ + params + count;
  931. pSMB->DataCount = cpu_to_le16(count);
  932. pSMB->ParameterCount = cpu_to_le16(params);
  933. pSMB->TotalDataCount = pSMB->DataCount;
  934. pSMB->TotalParameterCount = pSMB->ParameterCount;
  935. pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
  936. pSMB->Reserved4 = 0;
  937. inc_rfc1001_len(pSMB, byte_count);
  938. pSMB->ByteCount = cpu_to_le16(byte_count);
  939. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  940. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  941. if (rc) {
  942. cifs_dbg(FYI, "Posix create returned %d\n", rc);
  943. goto psx_create_err;
  944. }
  945. cifs_dbg(FYI, "copying inode info\n");
  946. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  947. if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
  948. rc = -EIO; /* bad smb */
  949. goto psx_create_err;
  950. }
  951. /* copy return information to pRetData */
  952. psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
  953. + le16_to_cpu(pSMBr->t2.DataOffset));
  954. *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
  955. if (netfid)
  956. *netfid = psx_rsp->Fid; /* cifs fid stays in le */
  957. /* Let caller know file was created so we can set the mode. */
  958. /* Do we care about the CreateAction in any other cases? */
  959. if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
  960. *pOplock |= CIFS_CREATE_ACTION;
  961. /* check to make sure response data is there */
  962. if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
  963. pRetData->Type = cpu_to_le32(-1); /* unknown */
  964. cifs_dbg(NOISY, "unknown type\n");
  965. } else {
  966. if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
  967. + sizeof(FILE_UNIX_BASIC_INFO)) {
  968. cifs_dbg(VFS, "Open response data too small\n");
  969. pRetData->Type = cpu_to_le32(-1);
  970. goto psx_create_err;
  971. }
  972. memcpy((char *) pRetData,
  973. (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
  974. sizeof(FILE_UNIX_BASIC_INFO));
  975. }
  976. psx_create_err:
  977. cifs_buf_release(pSMB);
  978. if (posix_flags & SMB_O_DIRECTORY)
  979. cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
  980. else
  981. cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
  982. if (rc == -EAGAIN)
  983. goto PsxCreat;
  984. return rc;
  985. }
  986. static __u16 convert_disposition(int disposition)
  987. {
  988. __u16 ofun = 0;
  989. switch (disposition) {
  990. case FILE_SUPERSEDE:
  991. ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
  992. break;
  993. case FILE_OPEN:
  994. ofun = SMBOPEN_OAPPEND;
  995. break;
  996. case FILE_CREATE:
  997. ofun = SMBOPEN_OCREATE;
  998. break;
  999. case FILE_OPEN_IF:
  1000. ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
  1001. break;
  1002. case FILE_OVERWRITE:
  1003. ofun = SMBOPEN_OTRUNC;
  1004. break;
  1005. case FILE_OVERWRITE_IF:
  1006. ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
  1007. break;
  1008. default:
  1009. cifs_dbg(FYI, "unknown disposition %d\n", disposition);
  1010. ofun = SMBOPEN_OAPPEND; /* regular open */
  1011. }
  1012. return ofun;
  1013. }
  1014. static int
  1015. access_flags_to_smbopen_mode(const int access_flags)
  1016. {
  1017. int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
  1018. if (masked_flags == GENERIC_READ)
  1019. return SMBOPEN_READ;
  1020. else if (masked_flags == GENERIC_WRITE)
  1021. return SMBOPEN_WRITE;
  1022. /* just go for read/write */
  1023. return SMBOPEN_READWRITE;
  1024. }
  1025. int
  1026. SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
  1027. const char *fileName, const int openDisposition,
  1028. const int access_flags, const int create_options, __u16 *netfid,
  1029. int *pOplock, FILE_ALL_INFO *pfile_info,
  1030. const struct nls_table *nls_codepage, int remap)
  1031. {
  1032. int rc = -EACCES;
  1033. OPENX_REQ *pSMB = NULL;
  1034. OPENX_RSP *pSMBr = NULL;
  1035. int bytes_returned;
  1036. int name_len;
  1037. __u16 count;
  1038. OldOpenRetry:
  1039. rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
  1040. (void **) &pSMBr);
  1041. if (rc)
  1042. return rc;
  1043. pSMB->AndXCommand = 0xFF; /* none */
  1044. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  1045. count = 1; /* account for one byte pad to word boundary */
  1046. name_len =
  1047. cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
  1048. fileName, PATH_MAX, nls_codepage, remap);
  1049. name_len++; /* trailing null */
  1050. name_len *= 2;
  1051. } else { /* BB improve check for buffer overruns BB */
  1052. count = 0; /* no pad */
  1053. name_len = strnlen(fileName, PATH_MAX);
  1054. name_len++; /* trailing null */
  1055. strncpy(pSMB->fileName, fileName, name_len);
  1056. }
  1057. if (*pOplock & REQ_OPLOCK)
  1058. pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
  1059. else if (*pOplock & REQ_BATCHOPLOCK)
  1060. pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
  1061. pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
  1062. pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
  1063. pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
  1064. /* set file as system file if special file such
  1065. as fifo and server expecting SFU style and
  1066. no Unix extensions */
  1067. if (create_options & CREATE_OPTION_SPECIAL)
  1068. pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
  1069. else /* BB FIXME BB */
  1070. pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
  1071. if (create_options & CREATE_OPTION_READONLY)
  1072. pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
  1073. /* BB FIXME BB */
  1074. /* pSMB->CreateOptions = cpu_to_le32(create_options &
  1075. CREATE_OPTIONS_MASK); */
  1076. /* BB FIXME END BB */
  1077. pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
  1078. pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
  1079. count += name_len;
  1080. inc_rfc1001_len(pSMB, count);
  1081. pSMB->ByteCount = cpu_to_le16(count);
  1082. /* long_op set to 1 to allow for oplock break timeouts */
  1083. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  1084. (struct smb_hdr *)pSMBr, &bytes_returned, 0);
  1085. cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
  1086. if (rc) {
  1087. cifs_dbg(FYI, "Error in Open = %d\n", rc);
  1088. } else {
  1089. /* BB verify if wct == 15 */
  1090. /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
  1091. *netfid = pSMBr->Fid; /* cifs fid stays in le */
  1092. /* Let caller know file was created so we can set the mode. */
  1093. /* Do we care about the CreateAction in any other cases? */
  1094. /* BB FIXME BB */
  1095. /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
  1096. *pOplock |= CIFS_CREATE_ACTION; */
  1097. /* BB FIXME END */
  1098. if (pfile_info) {
  1099. pfile_info->CreationTime = 0; /* BB convert CreateTime*/
  1100. pfile_info->LastAccessTime = 0; /* BB fixme */
  1101. pfile_info->LastWriteTime = 0; /* BB fixme */
  1102. pfile_info->ChangeTime = 0; /* BB fixme */
  1103. pfile_info->Attributes =
  1104. cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
  1105. /* the file_info buf is endian converted by caller */
  1106. pfile_info->AllocationSize =
  1107. cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
  1108. pfile_info->EndOfFile = pfile_info->AllocationSize;
  1109. pfile_info->NumberOfLinks = cpu_to_le32(1);
  1110. pfile_info->DeletePending = 0;
  1111. }
  1112. }
  1113. cifs_buf_release(pSMB);
  1114. if (rc == -EAGAIN)
  1115. goto OldOpenRetry;
  1116. return rc;
  1117. }
  1118. int
  1119. CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
  1120. FILE_ALL_INFO *buf)
  1121. {
  1122. int rc = -EACCES;
  1123. OPEN_REQ *req = NULL;
  1124. OPEN_RSP *rsp = NULL;
  1125. int bytes_returned;
  1126. int name_len;
  1127. __u16 count;
  1128. struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
  1129. struct cifs_tcon *tcon = oparms->tcon;
  1130. int remap = cifs_remap(cifs_sb);
  1131. const struct nls_table *nls = cifs_sb->local_nls;
  1132. int create_options = oparms->create_options;
  1133. int desired_access = oparms->desired_access;
  1134. int disposition = oparms->disposition;
  1135. const char *path = oparms->path;
  1136. openRetry:
  1137. rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
  1138. (void **)&rsp);
  1139. if (rc)
  1140. return rc;
  1141. /* no commands go after this */
  1142. req->AndXCommand = 0xFF;
  1143. if (req->hdr.Flags2 & SMBFLG2_UNICODE) {
  1144. /* account for one byte pad to word boundary */
  1145. count = 1;
  1146. name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1),
  1147. path, PATH_MAX, nls, remap);
  1148. /* trailing null */
  1149. name_len++;
  1150. name_len *= 2;
  1151. req->NameLength = cpu_to_le16(name_len);
  1152. } else {
  1153. /* BB improve check for buffer overruns BB */
  1154. /* no pad */
  1155. count = 0;
  1156. name_len = strnlen(path, PATH_MAX);
  1157. /* trailing null */
  1158. name_len++;
  1159. req->NameLength = cpu_to_le16(name_len);
  1160. strncpy(req->fileName, path, name_len);
  1161. }
  1162. if (*oplock & REQ_OPLOCK)
  1163. req->OpenFlags = cpu_to_le32(REQ_OPLOCK);
  1164. else if (*oplock & REQ_BATCHOPLOCK)
  1165. req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
  1166. req->DesiredAccess = cpu_to_le32(desired_access);
  1167. req->AllocationSize = 0;
  1168. /*
  1169. * Set file as system file if special file such as fifo and server
  1170. * expecting SFU style and no Unix extensions.
  1171. */
  1172. if (create_options & CREATE_OPTION_SPECIAL)
  1173. req->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
  1174. else
  1175. req->FileAttributes = cpu_to_le32(ATTR_NORMAL);
  1176. /*
  1177. * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case
  1178. * sensitive checks for other servers such as Samba.
  1179. */
  1180. if (tcon->ses->capabilities & CAP_UNIX)
  1181. req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
  1182. if (create_options & CREATE_OPTION_READONLY)
  1183. req->FileAttributes |= cpu_to_le32(ATTR_READONLY);
  1184. req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
  1185. req->CreateDisposition = cpu_to_le32(disposition);
  1186. req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
  1187. /* BB Expirement with various impersonation levels and verify */
  1188. req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
  1189. req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
  1190. count += name_len;
  1191. inc_rfc1001_len(req, count);
  1192. req->ByteCount = cpu_to_le16(count);
  1193. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
  1194. (struct smb_hdr *)rsp, &bytes_returned, 0);
  1195. cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
  1196. if (rc) {
  1197. cifs_dbg(FYI, "Error in Open = %d\n", rc);
  1198. cifs_buf_release(req);
  1199. if (rc == -EAGAIN)
  1200. goto openRetry;
  1201. return rc;
  1202. }
  1203. /* 1 byte no need to le_to_cpu */
  1204. *oplock = rsp->OplockLevel;
  1205. /* cifs fid stays in le */
  1206. oparms->fid->netfid = rsp->Fid;
  1207. /* Let caller know file was created so we can set the mode. */
  1208. /* Do we care about the CreateAction in any other cases? */
  1209. if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction)
  1210. *oplock |= CIFS_CREATE_ACTION;
  1211. if (buf) {
  1212. /* copy from CreationTime to Attributes */
  1213. memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
  1214. /* the file_info buf is endian converted by caller */
  1215. buf->AllocationSize = rsp->AllocationSize;
  1216. buf->EndOfFile = rsp->EndOfFile;
  1217. buf->NumberOfLinks = cpu_to_le32(1);
  1218. buf->DeletePending = 0;
  1219. }
  1220. cifs_buf_release(req);
  1221. return rc;
  1222. }
  1223. /*
  1224. * Discard any remaining data in the current SMB. To do this, we borrow the
  1225. * current bigbuf.
  1226. */
  1227. static int
  1228. discard_remaining_data(struct TCP_Server_Info *server)
  1229. {
  1230. unsigned int rfclen = get_rfc1002_length(server->smallbuf);
  1231. int remaining = rfclen + 4 - server->total_read;
  1232. while (remaining > 0) {
  1233. int length;
  1234. length = cifs_read_from_socket(server, server->bigbuf,
  1235. min_t(unsigned int, remaining,
  1236. CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
  1237. if (length < 0)
  1238. return length;
  1239. server->total_read += length;
  1240. remaining -= length;
  1241. }
  1242. return 0;
  1243. }
  1244. static int
  1245. cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
  1246. {
  1247. int length;
  1248. struct cifs_readdata *rdata = mid->callback_data;
  1249. length = discard_remaining_data(server);
  1250. dequeue_mid(mid, rdata->result);
  1251. mid->resp_buf = server->smallbuf;
  1252. server->smallbuf = NULL;
  1253. return length;
  1254. }
  1255. int
  1256. cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
  1257. {
  1258. int length, len;
  1259. unsigned int data_offset, data_len;
  1260. struct cifs_readdata *rdata = mid->callback_data;
  1261. char *buf = server->smallbuf;
  1262. unsigned int buflen = get_rfc1002_length(buf) + 4;
  1263. cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
  1264. __func__, mid->mid, rdata->offset, rdata->bytes);
  1265. /*
  1266. * read the rest of READ_RSP header (sans Data array), or whatever we
  1267. * can if there's not enough data. At this point, we've read down to
  1268. * the Mid.
  1269. */
  1270. len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
  1271. HEADER_SIZE(server) + 1;
  1272. rdata->iov.iov_base = buf + HEADER_SIZE(server) - 1;
  1273. rdata->iov.iov_len = len;
  1274. length = cifs_readv_from_socket(server, &rdata->iov, 1, len);
  1275. if (length < 0)
  1276. return length;
  1277. server->total_read += length;
  1278. if (server->ops->is_session_expired &&
  1279. server->ops->is_session_expired(buf)) {
  1280. cifs_reconnect(server);
  1281. wake_up(&server->response_q);
  1282. return -1;
  1283. }
  1284. if (server->ops->is_status_pending &&
  1285. server->ops->is_status_pending(buf, server, 0)) {
  1286. discard_remaining_data(server);
  1287. return -1;
  1288. }
  1289. /* Was the SMB read successful? */
  1290. rdata->result = server->ops->map_error(buf, false);
  1291. if (rdata->result != 0) {
  1292. cifs_dbg(FYI, "%s: server returned error %d\n",
  1293. __func__, rdata->result);
  1294. return cifs_readv_discard(server, mid);
  1295. }
  1296. /* Is there enough to get to the rest of the READ_RSP header? */
  1297. if (server->total_read < server->vals->read_rsp_size) {
  1298. cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
  1299. __func__, server->total_read,
  1300. server->vals->read_rsp_size);
  1301. rdata->result = -EIO;
  1302. return cifs_readv_discard(server, mid);
  1303. }
  1304. data_offset = server->ops->read_data_offset(buf) + 4;
  1305. if (data_offset < server->total_read) {
  1306. /*
  1307. * win2k8 sometimes sends an offset of 0 when the read
  1308. * is beyond the EOF. Treat it as if the data starts just after
  1309. * the header.
  1310. */
  1311. cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
  1312. __func__, data_offset);
  1313. data_offset = server->total_read;
  1314. } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
  1315. /* data_offset is beyond the end of smallbuf */
  1316. cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
  1317. __func__, data_offset);
  1318. rdata->result = -EIO;
  1319. return cifs_readv_discard(server, mid);
  1320. }
  1321. cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
  1322. __func__, server->total_read, data_offset);
  1323. len = data_offset - server->total_read;
  1324. if (len > 0) {
  1325. /* read any junk before data into the rest of smallbuf */
  1326. rdata->iov.iov_base = buf + server->total_read;
  1327. rdata->iov.iov_len = len;
  1328. length = cifs_readv_from_socket(server, &rdata->iov, 1, len);
  1329. if (length < 0)
  1330. return length;
  1331. server->total_read += length;
  1332. }
  1333. /* set up first iov for signature check */
  1334. rdata->iov.iov_base = buf;
  1335. rdata->iov.iov_len = server->total_read;
  1336. cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
  1337. rdata->iov.iov_base, rdata->iov.iov_len);
  1338. /* how much data is in the response? */
  1339. data_len = server->ops->read_data_length(buf);
  1340. if (data_offset + data_len > buflen) {
  1341. /* data_len is corrupt -- discard frame */
  1342. rdata->result = -EIO;
  1343. return cifs_readv_discard(server, mid);
  1344. }
  1345. length = rdata->read_into_pages(server, rdata, data_len);
  1346. if (length < 0)
  1347. return length;
  1348. server->total_read += length;
  1349. cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
  1350. server->total_read, buflen, data_len);
  1351. /* discard anything left over */
  1352. if (server->total_read < buflen)
  1353. return cifs_readv_discard(server, mid);
  1354. dequeue_mid(mid, false);
  1355. mid->resp_buf = server->smallbuf;
  1356. server->smallbuf = NULL;
  1357. return length;
  1358. }
  1359. static void
  1360. cifs_readv_callback(struct mid_q_entry *mid)
  1361. {
  1362. struct cifs_readdata *rdata = mid->callback_data;
  1363. struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
  1364. struct TCP_Server_Info *server = tcon->ses->server;
  1365. struct smb_rqst rqst = { .rq_iov = &rdata->iov,
  1366. .rq_nvec = 1,
  1367. .rq_pages = rdata->pages,
  1368. .rq_npages = rdata->nr_pages,
  1369. .rq_pagesz = rdata->pagesz,
  1370. .rq_tailsz = rdata->tailsz };
  1371. cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
  1372. __func__, mid->mid, mid->mid_state, rdata->result,
  1373. rdata->bytes);
  1374. switch (mid->mid_state) {
  1375. case MID_RESPONSE_RECEIVED:
  1376. /* result already set, check signature */
  1377. if (server->sign) {
  1378. int rc = 0;
  1379. rc = cifs_verify_signature(&rqst, server,
  1380. mid->sequence_number);
  1381. if (rc)
  1382. cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
  1383. rc);
  1384. }
  1385. /* FIXME: should this be counted toward the initiating task? */
  1386. task_io_account_read(rdata->got_bytes);
  1387. cifs_stats_bytes_read(tcon, rdata->got_bytes);
  1388. break;
  1389. case MID_REQUEST_SUBMITTED:
  1390. case MID_RETRY_NEEDED:
  1391. rdata->result = -EAGAIN;
  1392. if (server->sign && rdata->got_bytes)
  1393. /* reset bytes number since we can not check a sign */
  1394. rdata->got_bytes = 0;
  1395. /* FIXME: should this be counted toward the initiating task? */
  1396. task_io_account_read(rdata->got_bytes);
  1397. cifs_stats_bytes_read(tcon, rdata->got_bytes);
  1398. break;
  1399. default:
  1400. rdata->result = -EIO;
  1401. }
  1402. queue_work(cifsiod_wq, &rdata->work);
  1403. mutex_lock(&server->srv_mutex);
  1404. DeleteMidQEntry(mid);
  1405. mutex_unlock(&server->srv_mutex);
  1406. add_credits(server, 1, 0);
  1407. }
  1408. /* cifs_async_readv - send an async write, and set up mid to handle result */
  1409. int
  1410. cifs_async_readv(struct cifs_readdata *rdata)
  1411. {
  1412. int rc;
  1413. READ_REQ *smb = NULL;
  1414. int wct;
  1415. struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
  1416. struct smb_rqst rqst = { .rq_iov = &rdata->iov,
  1417. .rq_nvec = 1 };
  1418. cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
  1419. __func__, rdata->offset, rdata->bytes);
  1420. if (tcon->ses->capabilities & CAP_LARGE_FILES)
  1421. wct = 12;
  1422. else {
  1423. wct = 10; /* old style read */
  1424. if ((rdata->offset >> 32) > 0) {
  1425. /* can not handle this big offset for old */
  1426. return -EIO;
  1427. }
  1428. }
  1429. rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
  1430. if (rc)
  1431. return rc;
  1432. smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
  1433. smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
  1434. smb->AndXCommand = 0xFF; /* none */
  1435. smb->Fid = rdata->cfile->fid.netfid;
  1436. smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
  1437. if (wct == 12)
  1438. smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
  1439. smb->Remaining = 0;
  1440. smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
  1441. smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
  1442. if (wct == 12)
  1443. smb->ByteCount = 0;
  1444. else {
  1445. /* old style read */
  1446. struct smb_com_readx_req *smbr =
  1447. (struct smb_com_readx_req *)smb;
  1448. smbr->ByteCount = 0;
  1449. }
  1450. /* 4 for RFC1001 length + 1 for BCC */
  1451. rdata->iov.iov_base = smb;
  1452. rdata->iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
  1453. kref_get(&rdata->refcount);
  1454. rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
  1455. cifs_readv_callback, rdata, 0);
  1456. if (rc == 0)
  1457. cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
  1458. else
  1459. kref_put(&rdata->refcount, cifs_readdata_release);
  1460. cifs_small_buf_release(smb);
  1461. return rc;
  1462. }
  1463. int
  1464. CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
  1465. unsigned int *nbytes, char **buf, int *pbuf_type)
  1466. {
  1467. int rc = -EACCES;
  1468. READ_REQ *pSMB = NULL;
  1469. READ_RSP *pSMBr = NULL;
  1470. char *pReadData = NULL;
  1471. int wct;
  1472. int resp_buf_type = 0;
  1473. struct kvec iov[1];
  1474. __u32 pid = io_parms->pid;
  1475. __u16 netfid = io_parms->netfid;
  1476. __u64 offset = io_parms->offset;
  1477. struct cifs_tcon *tcon = io_parms->tcon;
  1478. unsigned int count = io_parms->length;
  1479. cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
  1480. if (tcon->ses->capabilities & CAP_LARGE_FILES)
  1481. wct = 12;
  1482. else {
  1483. wct = 10; /* old style read */
  1484. if ((offset >> 32) > 0) {
  1485. /* can not handle this big offset for old */
  1486. return -EIO;
  1487. }
  1488. }
  1489. *nbytes = 0;
  1490. rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
  1491. if (rc)
  1492. return rc;
  1493. pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
  1494. pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
  1495. /* tcon and ses pointer are checked in smb_init */
  1496. if (tcon->ses->server == NULL)
  1497. return -ECONNABORTED;
  1498. pSMB->AndXCommand = 0xFF; /* none */
  1499. pSMB->Fid = netfid;
  1500. pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
  1501. if (wct == 12)
  1502. pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
  1503. pSMB->Remaining = 0;
  1504. pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
  1505. pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
  1506. if (wct == 12)
  1507. pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
  1508. else {
  1509. /* old style read */
  1510. struct smb_com_readx_req *pSMBW =
  1511. (struct smb_com_readx_req *)pSMB;
  1512. pSMBW->ByteCount = 0;
  1513. }
  1514. iov[0].iov_base = (char *)pSMB;
  1515. iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
  1516. rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
  1517. &resp_buf_type, CIFS_LOG_ERROR);
  1518. cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
  1519. pSMBr = (READ_RSP *)iov[0].iov_base;
  1520. if (rc) {
  1521. cifs_dbg(VFS, "Send error in read = %d\n", rc);
  1522. } else {
  1523. int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
  1524. data_length = data_length << 16;
  1525. data_length += le16_to_cpu(pSMBr->DataLength);
  1526. *nbytes = data_length;
  1527. /*check that DataLength would not go beyond end of SMB */
  1528. if ((data_length > CIFSMaxBufSize)
  1529. || (data_length > count)) {
  1530. cifs_dbg(FYI, "bad length %d for count %d\n",
  1531. data_length, count);
  1532. rc = -EIO;
  1533. *nbytes = 0;
  1534. } else {
  1535. pReadData = (char *) (&pSMBr->hdr.Protocol) +
  1536. le16_to_cpu(pSMBr->DataOffset);
  1537. /* if (rc = copy_to_user(buf, pReadData, data_length)) {
  1538. cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
  1539. rc = -EFAULT;
  1540. }*/ /* can not use copy_to_user when using page cache*/
  1541. if (*buf)
  1542. memcpy(*buf, pReadData, data_length);
  1543. }
  1544. }
  1545. /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
  1546. if (*buf) {
  1547. free_rsp_buf(resp_buf_type, iov[0].iov_base);
  1548. } else if (resp_buf_type != CIFS_NO_BUFFER) {
  1549. /* return buffer to caller to free */
  1550. *buf = iov[0].iov_base;
  1551. if (resp_buf_type == CIFS_SMALL_BUFFER)
  1552. *pbuf_type = CIFS_SMALL_BUFFER;
  1553. else if (resp_buf_type == CIFS_LARGE_BUFFER)
  1554. *pbuf_type = CIFS_LARGE_BUFFER;
  1555. } /* else no valid buffer on return - leave as null */
  1556. /* Note: On -EAGAIN error only caller can retry on handle based calls
  1557. since file handle passed in no longer valid */
  1558. return rc;
  1559. }
  1560. int
  1561. CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
  1562. unsigned int *nbytes, const char *buf,
  1563. const char __user *ubuf, const int long_op)
  1564. {
  1565. int rc = -EACCES;
  1566. WRITE_REQ *pSMB = NULL;
  1567. WRITE_RSP *pSMBr = NULL;
  1568. int bytes_returned, wct;
  1569. __u32 bytes_sent;
  1570. __u16 byte_count;
  1571. __u32 pid = io_parms->pid;
  1572. __u16 netfid = io_parms->netfid;
  1573. __u64 offset = io_parms->offset;
  1574. struct cifs_tcon *tcon = io_parms->tcon;
  1575. unsigned int count = io_parms->length;
  1576. *nbytes = 0;
  1577. /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/
  1578. if (tcon->ses == NULL)
  1579. return -ECONNABORTED;
  1580. if (tcon->ses->capabilities & CAP_LARGE_FILES)
  1581. wct = 14;
  1582. else {
  1583. wct = 12;
  1584. if ((offset >> 32) > 0) {
  1585. /* can not handle big offset for old srv */
  1586. return -EIO;
  1587. }
  1588. }
  1589. rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
  1590. (void **) &pSMBr);
  1591. if (rc)
  1592. return rc;
  1593. pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
  1594. pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
  1595. /* tcon and ses pointer are checked in smb_init */
  1596. if (tcon->ses->server == NULL)
  1597. return -ECONNABORTED;
  1598. pSMB->AndXCommand = 0xFF; /* none */
  1599. pSMB->Fid = netfid;
  1600. pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
  1601. if (wct == 14)
  1602. pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
  1603. pSMB->Reserved = 0xFFFFFFFF;
  1604. pSMB->WriteMode = 0;
  1605. pSMB->Remaining = 0;
  1606. /* Can increase buffer size if buffer is big enough in some cases ie we
  1607. can send more if LARGE_WRITE_X capability returned by the server and if
  1608. our buffer is big enough or if we convert to iovecs on socket writes
  1609. and eliminate the copy to the CIFS buffer */
  1610. if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
  1611. bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
  1612. } else {
  1613. bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
  1614. & ~0xFF;
  1615. }
  1616. if (bytes_sent > count)
  1617. bytes_sent = count;
  1618. pSMB->DataOffset =
  1619. cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
  1620. if (buf)
  1621. memcpy(pSMB->Data, buf, bytes_sent);
  1622. else if (ubuf) {
  1623. if (copy_from_user(pSMB->Data, ubuf, bytes_sent)) {
  1624. cifs_buf_release(pSMB);
  1625. return -EFAULT;
  1626. }
  1627. } else if (count != 0) {
  1628. /* No buffer */
  1629. cifs_buf_release(pSMB);
  1630. return -EINVAL;
  1631. } /* else setting file size with write of zero bytes */
  1632. if (wct == 14)
  1633. byte_count = bytes_sent + 1; /* pad */
  1634. else /* wct == 12 */
  1635. byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
  1636. pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
  1637. pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
  1638. inc_rfc1001_len(pSMB, byte_count);
  1639. if (wct == 14)
  1640. pSMB->ByteCount = cpu_to_le16(byte_count);
  1641. else { /* old style write has byte count 4 bytes earlier
  1642. so 4 bytes pad */
  1643. struct smb_com_writex_req *pSMBW =
  1644. (struct smb_com_writex_req *)pSMB;
  1645. pSMBW->ByteCount = cpu_to_le16(byte_count);
  1646. }
  1647. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  1648. (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
  1649. cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
  1650. if (rc) {
  1651. cifs_dbg(FYI, "Send error in write = %d\n", rc);
  1652. } else {
  1653. *nbytes = le16_to_cpu(pSMBr->CountHigh);
  1654. *nbytes = (*nbytes) << 16;
  1655. *nbytes += le16_to_cpu(pSMBr->Count);
  1656. /*
  1657. * Mask off high 16 bits when bytes written as returned by the
  1658. * server is greater than bytes requested by the client. Some
  1659. * OS/2 servers are known to set incorrect CountHigh values.
  1660. */
  1661. if (*nbytes > count)
  1662. *nbytes &= 0xFFFF;
  1663. }
  1664. cifs_buf_release(pSMB);
  1665. /* Note: On -EAGAIN error only caller can retry on handle based calls
  1666. since file handle passed in no longer valid */
  1667. return rc;
  1668. }
  1669. void
  1670. cifs_writedata_release(struct kref *refcount)
  1671. {
  1672. struct cifs_writedata *wdata = container_of(refcount,
  1673. struct cifs_writedata, refcount);
  1674. if (wdata->cfile)
  1675. cifsFileInfo_put(wdata->cfile);
  1676. kfree(wdata);
  1677. }
  1678. /*
  1679. * Write failed with a retryable error. Resend the write request. It's also
  1680. * possible that the page was redirtied so re-clean the page.
  1681. */
  1682. static void
  1683. cifs_writev_requeue(struct cifs_writedata *wdata)
  1684. {
  1685. int i, rc = 0;
  1686. struct inode *inode = d_inode(wdata->cfile->dentry);
  1687. struct TCP_Server_Info *server;
  1688. unsigned int rest_len;
  1689. server = tlink_tcon(wdata->cfile->tlink)->ses->server;
  1690. i = 0;
  1691. rest_len = wdata->bytes;
  1692. do {
  1693. struct cifs_writedata *wdata2;
  1694. unsigned int j, nr_pages, wsize, tailsz, cur_len;
  1695. wsize = server->ops->wp_retry_size(inode);
  1696. if (wsize < rest_len) {
  1697. nr_pages = wsize / PAGE_CACHE_SIZE;
  1698. if (!nr_pages) {
  1699. rc = -ENOTSUPP;
  1700. break;
  1701. }
  1702. cur_len = nr_pages * PAGE_CACHE_SIZE;
  1703. tailsz = PAGE_CACHE_SIZE;
  1704. } else {
  1705. nr_pages = DIV_ROUND_UP(rest_len, PAGE_CACHE_SIZE);
  1706. cur_len = rest_len;
  1707. tailsz = rest_len - (nr_pages - 1) * PAGE_CACHE_SIZE;
  1708. }
  1709. wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete);
  1710. if (!wdata2) {
  1711. rc = -ENOMEM;
  1712. break;
  1713. }
  1714. for (j = 0; j < nr_pages; j++) {
  1715. wdata2->pages[j] = wdata->pages[i + j];
  1716. lock_page(wdata2->pages[j]);
  1717. clear_page_dirty_for_io(wdata2->pages[j]);
  1718. }
  1719. wdata2->sync_mode = wdata->sync_mode;
  1720. wdata2->nr_pages = nr_pages;
  1721. wdata2->offset = page_offset(wdata2->pages[0]);
  1722. wdata2->pagesz = PAGE_CACHE_SIZE;
  1723. wdata2->tailsz = tailsz;
  1724. wdata2->bytes = cur_len;
  1725. wdata2->cfile = find_writable_file(CIFS_I(inode), false);
  1726. if (!wdata2->cfile) {
  1727. cifs_dbg(VFS, "No writable handles for inode\n");
  1728. rc = -EBADF;
  1729. break;
  1730. }
  1731. wdata2->pid = wdata2->cfile->pid;
  1732. rc = server->ops->async_writev(wdata2, cifs_writedata_release);
  1733. for (j = 0; j < nr_pages; j++) {
  1734. unlock_page(wdata2->pages[j]);
  1735. if (rc != 0 && rc != -EAGAIN) {
  1736. SetPageError(wdata2->pages[j]);
  1737. end_page_writeback(wdata2->pages[j]);
  1738. page_cache_release(wdata2->pages[j]);
  1739. }
  1740. }
  1741. if (rc) {
  1742. kref_put(&wdata2->refcount, cifs_writedata_release);
  1743. if (rc == -EAGAIN)
  1744. continue;
  1745. break;
  1746. }
  1747. rest_len -= cur_len;
  1748. i += nr_pages;
  1749. } while (i < wdata->nr_pages);
  1750. mapping_set_error(inode->i_mapping, rc);
  1751. kref_put(&wdata->refcount, cifs_writedata_release);
  1752. }
  1753. void
  1754. cifs_writev_complete(struct work_struct *work)
  1755. {
  1756. struct cifs_writedata *wdata = container_of(work,
  1757. struct cifs_writedata, work);
  1758. struct inode *inode = d_inode(wdata->cfile->dentry);
  1759. int i = 0;
  1760. if (wdata->result == 0) {
  1761. spin_lock(&inode->i_lock);
  1762. cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
  1763. spin_unlock(&inode->i_lock);
  1764. cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
  1765. wdata->bytes);
  1766. } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
  1767. return cifs_writev_requeue(wdata);
  1768. for (i = 0; i < wdata->nr_pages; i++) {
  1769. struct page *page = wdata->pages[i];
  1770. if (wdata->result == -EAGAIN)
  1771. __set_page_dirty_nobuffers(page);
  1772. else if (wdata->result < 0)
  1773. SetPageError(page);
  1774. end_page_writeback(page);
  1775. page_cache_release(page);
  1776. }
  1777. if (wdata->result != -EAGAIN)
  1778. mapping_set_error(inode->i_mapping, wdata->result);
  1779. kref_put(&wdata->refcount, cifs_writedata_release);
  1780. }
  1781. struct cifs_writedata *
  1782. cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
  1783. {
  1784. struct cifs_writedata *wdata;
  1785. /* writedata + number of page pointers */
  1786. wdata = kzalloc(sizeof(*wdata) +
  1787. sizeof(struct page *) * nr_pages, GFP_NOFS);
  1788. if (wdata != NULL) {
  1789. kref_init(&wdata->refcount);
  1790. INIT_LIST_HEAD(&wdata->list);
  1791. init_completion(&wdata->done);
  1792. INIT_WORK(&wdata->work, complete);
  1793. }
  1794. return wdata;
  1795. }
  1796. /*
  1797. * Check the mid_state and signature on received buffer (if any), and queue the
  1798. * workqueue completion task.
  1799. */
  1800. static void
  1801. cifs_writev_callback(struct mid_q_entry *mid)
  1802. {
  1803. struct cifs_writedata *wdata = mid->callback_data;
  1804. struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
  1805. struct TCP_Server_Info *server = tcon->ses->server;
  1806. unsigned int written;
  1807. WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
  1808. switch (mid->mid_state) {
  1809. case MID_RESPONSE_RECEIVED:
  1810. wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
  1811. if (wdata->result != 0)
  1812. break;
  1813. written = le16_to_cpu(smb->CountHigh);
  1814. written <<= 16;
  1815. written += le16_to_cpu(smb->Count);
  1816. /*
  1817. * Mask off high 16 bits when bytes written as returned
  1818. * by the server is greater than bytes requested by the
  1819. * client. OS/2 servers are known to set incorrect
  1820. * CountHigh values.
  1821. */
  1822. if (written > wdata->bytes)
  1823. written &= 0xFFFF;
  1824. if (written < wdata->bytes)
  1825. wdata->result = -ENOSPC;
  1826. else
  1827. wdata->bytes = written;
  1828. break;
  1829. case MID_REQUEST_SUBMITTED:
  1830. case MID_RETRY_NEEDED:
  1831. wdata->result = -EAGAIN;
  1832. break;
  1833. default:
  1834. wdata->result = -EIO;
  1835. break;
  1836. }
  1837. queue_work(cifsiod_wq, &wdata->work);
  1838. mutex_lock(&server->srv_mutex);
  1839. DeleteMidQEntry(mid);
  1840. mutex_unlock(&server->srv_mutex);
  1841. add_credits(tcon->ses->server, 1, 0);
  1842. }
  1843. /* cifs_async_writev - send an async write, and set up mid to handle result */
  1844. int
  1845. cifs_async_writev(struct cifs_writedata *wdata,
  1846. void (*release)(struct kref *kref))
  1847. {
  1848. int rc = -EACCES;
  1849. WRITE_REQ *smb = NULL;
  1850. int wct;
  1851. struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
  1852. struct kvec iov;
  1853. struct smb_rqst rqst = { };
  1854. if (tcon->ses->capabilities & CAP_LARGE_FILES) {
  1855. wct = 14;
  1856. } else {
  1857. wct = 12;
  1858. if (wdata->offset >> 32 > 0) {
  1859. /* can not handle big offset for old srv */
  1860. return -EIO;
  1861. }
  1862. }
  1863. rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
  1864. if (rc)
  1865. goto async_writev_out;
  1866. smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
  1867. smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
  1868. smb->AndXCommand = 0xFF; /* none */
  1869. smb->Fid = wdata->cfile->fid.netfid;
  1870. smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
  1871. if (wct == 14)
  1872. smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
  1873. smb->Reserved = 0xFFFFFFFF;
  1874. smb->WriteMode = 0;
  1875. smb->Remaining = 0;
  1876. smb->DataOffset =
  1877. cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
  1878. /* 4 for RFC1001 length + 1 for BCC */
  1879. iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4 + 1;
  1880. iov.iov_base = smb;
  1881. rqst.rq_iov = &iov;
  1882. rqst.rq_nvec = 1;
  1883. rqst.rq_pages = wdata->pages;
  1884. rqst.rq_npages = wdata->nr_pages;
  1885. rqst.rq_pagesz = wdata->pagesz;
  1886. rqst.rq_tailsz = wdata->tailsz;
  1887. cifs_dbg(FYI, "async write at %llu %u bytes\n",
  1888. wdata->offset, wdata->bytes);
  1889. smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
  1890. smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
  1891. if (wct == 14) {
  1892. inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
  1893. put_bcc(wdata->bytes + 1, &smb->hdr);
  1894. } else {
  1895. /* wct == 12 */
  1896. struct smb_com_writex_req *smbw =
  1897. (struct smb_com_writex_req *)smb;
  1898. inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
  1899. put_bcc(wdata->bytes + 5, &smbw->hdr);
  1900. iov.iov_len += 4; /* pad bigger by four bytes */
  1901. }
  1902. kref_get(&wdata->refcount);
  1903. rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
  1904. cifs_writev_callback, wdata, 0);
  1905. if (rc == 0)
  1906. cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
  1907. else
  1908. kref_put(&wdata->refcount, release);
  1909. async_writev_out:
  1910. cifs_small_buf_release(smb);
  1911. return rc;
  1912. }
  1913. int
  1914. CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
  1915. unsigned int *nbytes, struct kvec *iov, int n_vec)
  1916. {
  1917. int rc = -EACCES;
  1918. WRITE_REQ *pSMB = NULL;
  1919. int wct;
  1920. int smb_hdr_len;
  1921. int resp_buf_type = 0;
  1922. __u32 pid = io_parms->pid;
  1923. __u16 netfid = io_parms->netfid;
  1924. __u64 offset = io_parms->offset;
  1925. struct cifs_tcon *tcon = io_parms->tcon;
  1926. unsigned int count = io_parms->length;
  1927. *nbytes = 0;
  1928. cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count);
  1929. if (tcon->ses->capabilities & CAP_LARGE_FILES) {
  1930. wct = 14;
  1931. } else {
  1932. wct = 12;
  1933. if ((offset >> 32) > 0) {
  1934. /* can not handle big offset for old srv */
  1935. return -EIO;
  1936. }
  1937. }
  1938. rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
  1939. if (rc)
  1940. return rc;
  1941. pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
  1942. pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
  1943. /* tcon and ses pointer are checked in smb_init */
  1944. if (tcon->ses->server == NULL)
  1945. return -ECONNABORTED;
  1946. pSMB->AndXCommand = 0xFF; /* none */
  1947. pSMB->Fid = netfid;
  1948. pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
  1949. if (wct == 14)
  1950. pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
  1951. pSMB->Reserved = 0xFFFFFFFF;
  1952. pSMB->WriteMode = 0;
  1953. pSMB->Remaining = 0;
  1954. pSMB->DataOffset =
  1955. cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
  1956. pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
  1957. pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
  1958. /* header + 1 byte pad */
  1959. smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
  1960. if (wct == 14)
  1961. inc_rfc1001_len(pSMB, count + 1);
  1962. else /* wct == 12 */
  1963. inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
  1964. if (wct == 14)
  1965. pSMB->ByteCount = cpu_to_le16(count + 1);
  1966. else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
  1967. struct smb_com_writex_req *pSMBW =
  1968. (struct smb_com_writex_req *)pSMB;
  1969. pSMBW->ByteCount = cpu_to_le16(count + 5);
  1970. }
  1971. iov[0].iov_base = pSMB;
  1972. if (wct == 14)
  1973. iov[0].iov_len = smb_hdr_len + 4;
  1974. else /* wct == 12 pad bigger by four bytes */
  1975. iov[0].iov_len = smb_hdr_len + 8;
  1976. rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0);
  1977. cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
  1978. if (rc) {
  1979. cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
  1980. } else if (resp_buf_type == 0) {
  1981. /* presumably this can not happen, but best to be safe */
  1982. rc = -EIO;
  1983. } else {
  1984. WRITE_RSP *pSMBr = (WRITE_RSP *)iov[0].iov_base;
  1985. *nbytes = le16_to_cpu(pSMBr->CountHigh);
  1986. *nbytes = (*nbytes) << 16;
  1987. *nbytes += le16_to_cpu(pSMBr->Count);
  1988. /*
  1989. * Mask off high 16 bits when bytes written as returned by the
  1990. * server is greater than bytes requested by the client. OS/2
  1991. * servers are known to set incorrect CountHigh values.
  1992. */
  1993. if (*nbytes > count)
  1994. *nbytes &= 0xFFFF;
  1995. }
  1996. /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
  1997. free_rsp_buf(resp_buf_type, iov[0].iov_base);
  1998. /* Note: On -EAGAIN error only caller can retry on handle based calls
  1999. since file handle passed in no longer valid */
  2000. return rc;
  2001. }
  2002. int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
  2003. const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
  2004. const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
  2005. {
  2006. int rc = 0;
  2007. LOCK_REQ *pSMB = NULL;
  2008. struct kvec iov[2];
  2009. int resp_buf_type;
  2010. __u16 count;
  2011. cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n",
  2012. num_lock, num_unlock);
  2013. rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
  2014. if (rc)
  2015. return rc;
  2016. pSMB->Timeout = 0;
  2017. pSMB->NumberOfLocks = cpu_to_le16(num_lock);
  2018. pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
  2019. pSMB->LockType = lock_type;
  2020. pSMB->AndXCommand = 0xFF; /* none */
  2021. pSMB->Fid = netfid; /* netfid stays le */
  2022. count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
  2023. inc_rfc1001_len(pSMB, count);
  2024. pSMB->ByteCount = cpu_to_le16(count);
  2025. iov[0].iov_base = (char *)pSMB;
  2026. iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
  2027. (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
  2028. iov[1].iov_base = (char *)buf;
  2029. iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
  2030. cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
  2031. rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP);
  2032. if (rc)
  2033. cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc);
  2034. return rc;
  2035. }
  2036. int
  2037. CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
  2038. const __u16 smb_file_id, const __u32 netpid, const __u64 len,
  2039. const __u64 offset, const __u32 numUnlock,
  2040. const __u32 numLock, const __u8 lockType,
  2041. const bool waitFlag, const __u8 oplock_level)
  2042. {
  2043. int rc = 0;
  2044. LOCK_REQ *pSMB = NULL;
  2045. /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
  2046. int bytes_returned;
  2047. int flags = 0;
  2048. __u16 count;
  2049. cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
  2050. (int)waitFlag, numLock);
  2051. rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
  2052. if (rc)
  2053. return rc;
  2054. if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
  2055. /* no response expected */
  2056. flags = CIFS_ASYNC_OP | CIFS_OBREAK_OP;
  2057. pSMB->Timeout = 0;
  2058. } else if (waitFlag) {
  2059. flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
  2060. pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
  2061. } else {
  2062. pSMB->Timeout = 0;
  2063. }
  2064. pSMB->NumberOfLocks = cpu_to_le16(numLock);
  2065. pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
  2066. pSMB->LockType = lockType;
  2067. pSMB->OplockLevel = oplock_level;
  2068. pSMB->AndXCommand = 0xFF; /* none */
  2069. pSMB->Fid = smb_file_id; /* netfid stays le */
  2070. if ((numLock != 0) || (numUnlock != 0)) {
  2071. pSMB->Locks[0].Pid = cpu_to_le16(netpid);
  2072. /* BB where to store pid high? */
  2073. pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
  2074. pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
  2075. pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
  2076. pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
  2077. count = sizeof(LOCKING_ANDX_RANGE);
  2078. } else {
  2079. /* oplock break */
  2080. count = 0;
  2081. }
  2082. inc_rfc1001_len(pSMB, count);
  2083. pSMB->ByteCount = cpu_to_le16(count);
  2084. if (waitFlag) {
  2085. rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
  2086. (struct smb_hdr *) pSMB, &bytes_returned);
  2087. cifs_small_buf_release(pSMB);
  2088. } else {
  2089. rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
  2090. /* SMB buffer freed by function above */
  2091. }
  2092. cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
  2093. if (rc)
  2094. cifs_dbg(FYI, "Send error in Lock = %d\n", rc);
  2095. /* Note: On -EAGAIN error only caller can retry on handle based calls
  2096. since file handle passed in no longer valid */
  2097. return rc;
  2098. }
  2099. int
  2100. CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
  2101. const __u16 smb_file_id, const __u32 netpid,
  2102. const loff_t start_offset, const __u64 len,
  2103. struct file_lock *pLockData, const __u16 lock_type,
  2104. const bool waitFlag)
  2105. {
  2106. struct smb_com_transaction2_sfi_req *pSMB = NULL;
  2107. struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
  2108. struct cifs_posix_lock *parm_data;
  2109. int rc = 0;
  2110. int timeout = 0;
  2111. int bytes_returned = 0;
  2112. int resp_buf_type = 0;
  2113. __u16 params, param_offset, offset, byte_count, count;
  2114. struct kvec iov[1];
  2115. cifs_dbg(FYI, "Posix Lock\n");
  2116. rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
  2117. if (rc)
  2118. return rc;
  2119. pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
  2120. params = 6;
  2121. pSMB->MaxSetupCount = 0;
  2122. pSMB->Reserved = 0;
  2123. pSMB->Flags = 0;
  2124. pSMB->Reserved2 = 0;
  2125. param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
  2126. offset = param_offset + params;
  2127. count = sizeof(struct cifs_posix_lock);
  2128. pSMB->MaxParameterCount = cpu_to_le16(2);
  2129. pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
  2130. pSMB->SetupCount = 1;
  2131. pSMB->Reserved3 = 0;
  2132. if (pLockData)
  2133. pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
  2134. else
  2135. pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
  2136. byte_count = 3 /* pad */ + params + count;
  2137. pSMB->DataCount = cpu_to_le16(count);
  2138. pSMB->ParameterCount = cpu_to_le16(params);
  2139. pSMB->TotalDataCount = pSMB->DataCount;
  2140. pSMB->TotalParameterCount = pSMB->ParameterCount;
  2141. pSMB->ParameterOffset = cpu_to_le16(param_offset);
  2142. parm_data = (struct cifs_posix_lock *)
  2143. (((char *) &pSMB->hdr.Protocol) + offset);
  2144. parm_data->lock_type = cpu_to_le16(lock_type);
  2145. if (waitFlag) {
  2146. timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
  2147. parm_data->lock_flags = cpu_to_le16(1);
  2148. pSMB->Timeout = cpu_to_le32(-1);
  2149. } else
  2150. pSMB->Timeout = 0;
  2151. parm_data->pid = cpu_to_le32(netpid);
  2152. parm_data->start = cpu_to_le64(start_offset);
  2153. parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
  2154. pSMB->DataOffset = cpu_to_le16(offset);
  2155. pSMB->Fid = smb_file_id;
  2156. pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
  2157. pSMB->Reserved4 = 0;
  2158. inc_rfc1001_len(pSMB, byte_count);
  2159. pSMB->ByteCount = cpu_to_le16(byte_count);
  2160. if (waitFlag) {
  2161. rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
  2162. (struct smb_hdr *) pSMBr, &bytes_returned);
  2163. } else {
  2164. iov[0].iov_base = (char *)pSMB;
  2165. iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
  2166. rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
  2167. &resp_buf_type, timeout);
  2168. pSMB = NULL; /* request buf already freed by SendReceive2. Do
  2169. not try to free it twice below on exit */
  2170. pSMBr = (struct smb_com_transaction2_sfi_rsp *)iov[0].iov_base;
  2171. }
  2172. if (rc) {
  2173. cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
  2174. } else if (pLockData) {
  2175. /* lock structure can be returned on get */
  2176. __u16 data_offset;
  2177. __u16 data_count;
  2178. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  2179. if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
  2180. rc = -EIO; /* bad smb */
  2181. goto plk_err_exit;
  2182. }
  2183. data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
  2184. data_count = le16_to_cpu(pSMBr->t2.DataCount);
  2185. if (data_count < sizeof(struct cifs_posix_lock)) {
  2186. rc = -EIO;
  2187. goto plk_err_exit;
  2188. }
  2189. parm_data = (struct cifs_posix_lock *)
  2190. ((char *)&pSMBr->hdr.Protocol + data_offset);
  2191. if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
  2192. pLockData->fl_type = F_UNLCK;
  2193. else {
  2194. if (parm_data->lock_type ==
  2195. cpu_to_le16(CIFS_RDLCK))
  2196. pLockData->fl_type = F_RDLCK;
  2197. else if (parm_data->lock_type ==
  2198. cpu_to_le16(CIFS_WRLCK))
  2199. pLockData->fl_type = F_WRLCK;
  2200. pLockData->fl_start = le64_to_cpu(parm_data->start);
  2201. pLockData->fl_end = pLockData->fl_start +
  2202. le64_to_cpu(parm_data->length) - 1;
  2203. pLockData->fl_pid = le32_to_cpu(parm_data->pid);
  2204. }
  2205. }
  2206. plk_err_exit:
  2207. if (pSMB)
  2208. cifs_small_buf_release(pSMB);
  2209. free_rsp_buf(resp_buf_type, iov[0].iov_base);
  2210. /* Note: On -EAGAIN error only caller can retry on handle based calls
  2211. since file handle passed in no longer valid */
  2212. return rc;
  2213. }
  2214. int
  2215. CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
  2216. {
  2217. int rc = 0;
  2218. CLOSE_REQ *pSMB = NULL;
  2219. cifs_dbg(FYI, "In CIFSSMBClose\n");
  2220. /* do not retry on dead session on close */
  2221. rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
  2222. if (rc == -EAGAIN)
  2223. return 0;
  2224. if (rc)
  2225. return rc;
  2226. pSMB->FileID = (__u16) smb_file_id;
  2227. pSMB->LastWriteTime = 0xFFFFFFFF;
  2228. pSMB->ByteCount = 0;
  2229. rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
  2230. cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
  2231. if (rc) {
  2232. if (rc != -EINTR) {
  2233. /* EINTR is expected when user ctl-c to kill app */
  2234. cifs_dbg(VFS, "Send error in Close = %d\n", rc);
  2235. }
  2236. }
  2237. /* Since session is dead, file will be closed on server already */
  2238. if (rc == -EAGAIN)
  2239. rc = 0;
  2240. return rc;
  2241. }
  2242. int
  2243. CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
  2244. {
  2245. int rc = 0;
  2246. FLUSH_REQ *pSMB = NULL;
  2247. cifs_dbg(FYI, "In CIFSSMBFlush\n");
  2248. rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
  2249. if (rc)
  2250. return rc;
  2251. pSMB->FileID = (__u16) smb_file_id;
  2252. pSMB->ByteCount = 0;
  2253. rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
  2254. cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
  2255. if (rc)
  2256. cifs_dbg(VFS, "Send error in Flush = %d\n", rc);
  2257. return rc;
  2258. }
  2259. int
  2260. CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
  2261. const char *from_name, const char *to_name,
  2262. struct cifs_sb_info *cifs_sb)
  2263. {
  2264. int rc = 0;
  2265. RENAME_REQ *pSMB = NULL;
  2266. RENAME_RSP *pSMBr = NULL;
  2267. int bytes_returned;
  2268. int name_len, name_len2;
  2269. __u16 count;
  2270. int remap = cifs_remap(cifs_sb);
  2271. cifs_dbg(FYI, "In CIFSSMBRename\n");
  2272. renameRetry:
  2273. rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
  2274. (void **) &pSMBr);
  2275. if (rc)
  2276. return rc;
  2277. pSMB->BufferFormat = 0x04;
  2278. pSMB->SearchAttributes =
  2279. cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
  2280. ATTR_DIRECTORY);
  2281. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  2282. name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
  2283. from_name, PATH_MAX,
  2284. cifs_sb->local_nls, remap);
  2285. name_len++; /* trailing null */
  2286. name_len *= 2;
  2287. pSMB->OldFileName[name_len] = 0x04; /* pad */
  2288. /* protocol requires ASCII signature byte on Unicode string */
  2289. pSMB->OldFileName[name_len + 1] = 0x00;
  2290. name_len2 =
  2291. cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
  2292. to_name, PATH_MAX, cifs_sb->local_nls,
  2293. remap);
  2294. name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
  2295. name_len2 *= 2; /* convert to bytes */
  2296. } else { /* BB improve the check for buffer overruns BB */
  2297. name_len = strnlen(from_name, PATH_MAX);
  2298. name_len++; /* trailing null */
  2299. strncpy(pSMB->OldFileName, from_name, name_len);
  2300. name_len2 = strnlen(to_name, PATH_MAX);
  2301. name_len2++; /* trailing null */
  2302. pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
  2303. strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
  2304. name_len2++; /* trailing null */
  2305. name_len2++; /* signature byte */
  2306. }
  2307. count = 1 /* 1st signature byte */ + name_len + name_len2;
  2308. inc_rfc1001_len(pSMB, count);
  2309. pSMB->ByteCount = cpu_to_le16(count);
  2310. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  2311. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  2312. cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
  2313. if (rc)
  2314. cifs_dbg(FYI, "Send error in rename = %d\n", rc);
  2315. cifs_buf_release(pSMB);
  2316. if (rc == -EAGAIN)
  2317. goto renameRetry;
  2318. return rc;
  2319. }
  2320. int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
  2321. int netfid, const char *target_name,
  2322. const struct nls_table *nls_codepage, int remap)
  2323. {
  2324. struct smb_com_transaction2_sfi_req *pSMB = NULL;
  2325. struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
  2326. struct set_file_rename *rename_info;
  2327. char *data_offset;
  2328. char dummy_string[30];
  2329. int rc = 0;
  2330. int bytes_returned = 0;
  2331. int len_of_str;
  2332. __u16 params, param_offset, offset, count, byte_count;
  2333. cifs_dbg(FYI, "Rename to File by handle\n");
  2334. rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
  2335. (void **) &pSMBr);
  2336. if (rc)
  2337. return rc;
  2338. params = 6;
  2339. pSMB->MaxSetupCount = 0;
  2340. pSMB->Reserved = 0;
  2341. pSMB->Flags = 0;
  2342. pSMB->Timeout = 0;
  2343. pSMB->Reserved2 = 0;
  2344. param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
  2345. offset = param_offset + params;
  2346. data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
  2347. rename_info = (struct set_file_rename *) data_offset;
  2348. pSMB->MaxParameterCount = cpu_to_le16(2);
  2349. pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
  2350. pSMB->SetupCount = 1;
  2351. pSMB->Reserved3 = 0;
  2352. pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
  2353. byte_count = 3 /* pad */ + params;
  2354. pSMB->ParameterCount = cpu_to_le16(params);
  2355. pSMB->TotalParameterCount = pSMB->ParameterCount;
  2356. pSMB->ParameterOffset = cpu_to_le16(param_offset);
  2357. pSMB->DataOffset = cpu_to_le16(offset);
  2358. /* construct random name ".cifs_tmp<inodenum><mid>" */
  2359. rename_info->overwrite = cpu_to_le32(1);
  2360. rename_info->root_fid = 0;
  2361. /* unicode only call */
  2362. if (target_name == NULL) {
  2363. sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
  2364. len_of_str =
  2365. cifsConvertToUTF16((__le16 *)rename_info->target_name,
  2366. dummy_string, 24, nls_codepage, remap);
  2367. } else {
  2368. len_of_str =
  2369. cifsConvertToUTF16((__le16 *)rename_info->target_name,
  2370. target_name, PATH_MAX, nls_codepage,
  2371. remap);
  2372. }
  2373. rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
  2374. count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
  2375. byte_count += count;
  2376. pSMB->DataCount = cpu_to_le16(count);
  2377. pSMB->TotalDataCount = pSMB->DataCount;
  2378. pSMB->Fid = netfid;
  2379. pSMB->InformationLevel =
  2380. cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
  2381. pSMB->Reserved4 = 0;
  2382. inc_rfc1001_len(pSMB, byte_count);
  2383. pSMB->ByteCount = cpu_to_le16(byte_count);
  2384. rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
  2385. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  2386. cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
  2387. if (rc)
  2388. cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n",
  2389. rc);
  2390. cifs_buf_release(pSMB);
  2391. /* Note: On -EAGAIN error only caller can retry on handle based calls
  2392. since file handle passed in no longer valid */
  2393. return rc;
  2394. }
  2395. int
  2396. CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon,
  2397. const char *fromName, const __u16 target_tid, const char *toName,
  2398. const int flags, const struct nls_table *nls_codepage, int remap)
  2399. {
  2400. int rc = 0;
  2401. COPY_REQ *pSMB = NULL;
  2402. COPY_RSP *pSMBr = NULL;
  2403. int bytes_returned;
  2404. int name_len, name_len2;
  2405. __u16 count;
  2406. cifs_dbg(FYI, "In CIFSSMBCopy\n");
  2407. copyRetry:
  2408. rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
  2409. (void **) &pSMBr);
  2410. if (rc)
  2411. return rc;
  2412. pSMB->BufferFormat = 0x04;
  2413. pSMB->Tid2 = target_tid;
  2414. pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
  2415. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  2416. name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
  2417. fromName, PATH_MAX, nls_codepage,
  2418. remap);
  2419. name_len++; /* trailing null */
  2420. name_len *= 2;
  2421. pSMB->OldFileName[name_len] = 0x04; /* pad */
  2422. /* protocol requires ASCII signature byte on Unicode string */
  2423. pSMB->OldFileName[name_len + 1] = 0x00;
  2424. name_len2 =
  2425. cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
  2426. toName, PATH_MAX, nls_codepage, remap);
  2427. name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
  2428. name_len2 *= 2; /* convert to bytes */
  2429. } else { /* BB improve the check for buffer overruns BB */
  2430. name_len = strnlen(fromName, PATH_MAX);
  2431. name_len++; /* trailing null */
  2432. strncpy(pSMB->OldFileName, fromName, name_len);
  2433. name_len2 = strnlen(toName, PATH_MAX);
  2434. name_len2++; /* trailing null */
  2435. pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
  2436. strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
  2437. name_len2++; /* trailing null */
  2438. name_len2++; /* signature byte */
  2439. }
  2440. count = 1 /* 1st signature byte */ + name_len + name_len2;
  2441. inc_rfc1001_len(pSMB, count);
  2442. pSMB->ByteCount = cpu_to_le16(count);
  2443. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  2444. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  2445. if (rc) {
  2446. cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n",
  2447. rc, le16_to_cpu(pSMBr->CopyCount));
  2448. }
  2449. cifs_buf_release(pSMB);
  2450. if (rc == -EAGAIN)
  2451. goto copyRetry;
  2452. return rc;
  2453. }
  2454. int
  2455. CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
  2456. const char *fromName, const char *toName,
  2457. const struct nls_table *nls_codepage, int remap)
  2458. {
  2459. TRANSACTION2_SPI_REQ *pSMB = NULL;
  2460. TRANSACTION2_SPI_RSP *pSMBr = NULL;
  2461. char *data_offset;
  2462. int name_len;
  2463. int name_len_target;
  2464. int rc = 0;
  2465. int bytes_returned = 0;
  2466. __u16 params, param_offset, offset, byte_count;
  2467. cifs_dbg(FYI, "In Symlink Unix style\n");
  2468. createSymLinkRetry:
  2469. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  2470. (void **) &pSMBr);
  2471. if (rc)
  2472. return rc;
  2473. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  2474. name_len =
  2475. cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName,
  2476. /* find define for this maxpathcomponent */
  2477. PATH_MAX, nls_codepage, remap);
  2478. name_len++; /* trailing null */
  2479. name_len *= 2;
  2480. } else { /* BB improve the check for buffer overruns BB */
  2481. name_len = strnlen(fromName, PATH_MAX);
  2482. name_len++; /* trailing null */
  2483. strncpy(pSMB->FileName, fromName, name_len);
  2484. }
  2485. params = 6 + name_len;
  2486. pSMB->MaxSetupCount = 0;
  2487. pSMB->Reserved = 0;
  2488. pSMB->Flags = 0;
  2489. pSMB->Timeout = 0;
  2490. pSMB->Reserved2 = 0;
  2491. param_offset = offsetof(struct smb_com_transaction2_spi_req,
  2492. InformationLevel) - 4;
  2493. offset = param_offset + params;
  2494. data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
  2495. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  2496. name_len_target =
  2497. cifsConvertToUTF16((__le16 *) data_offset, toName,
  2498. /* find define for this maxpathcomponent */
  2499. PATH_MAX, nls_codepage, remap);
  2500. name_len_target++; /* trailing null */
  2501. name_len_target *= 2;
  2502. } else { /* BB improve the check for buffer overruns BB */
  2503. name_len_target = strnlen(toName, PATH_MAX);
  2504. name_len_target++; /* trailing null */
  2505. strncpy(data_offset, toName, name_len_target);
  2506. }
  2507. pSMB->MaxParameterCount = cpu_to_le16(2);
  2508. /* BB find exact max on data count below from sess */
  2509. pSMB->MaxDataCount = cpu_to_le16(1000);
  2510. pSMB->SetupCount = 1;
  2511. pSMB->Reserved3 = 0;
  2512. pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
  2513. byte_count = 3 /* pad */ + params + name_len_target;
  2514. pSMB->DataCount = cpu_to_le16(name_len_target);
  2515. pSMB->ParameterCount = cpu_to_le16(params);
  2516. pSMB->TotalDataCount = pSMB->DataCount;
  2517. pSMB->TotalParameterCount = pSMB->ParameterCount;
  2518. pSMB->ParameterOffset = cpu_to_le16(param_offset);
  2519. pSMB->DataOffset = cpu_to_le16(offset);
  2520. pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
  2521. pSMB->Reserved4 = 0;
  2522. inc_rfc1001_len(pSMB, byte_count);
  2523. pSMB->ByteCount = cpu_to_le16(byte_count);
  2524. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  2525. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  2526. cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
  2527. if (rc)
  2528. cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n",
  2529. rc);
  2530. cifs_buf_release(pSMB);
  2531. if (rc == -EAGAIN)
  2532. goto createSymLinkRetry;
  2533. return rc;
  2534. }
  2535. int
  2536. CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
  2537. const char *fromName, const char *toName,
  2538. const struct nls_table *nls_codepage, int remap)
  2539. {
  2540. TRANSACTION2_SPI_REQ *pSMB = NULL;
  2541. TRANSACTION2_SPI_RSP *pSMBr = NULL;
  2542. char *data_offset;
  2543. int name_len;
  2544. int name_len_target;
  2545. int rc = 0;
  2546. int bytes_returned = 0;
  2547. __u16 params, param_offset, offset, byte_count;
  2548. cifs_dbg(FYI, "In Create Hard link Unix style\n");
  2549. createHardLinkRetry:
  2550. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  2551. (void **) &pSMBr);
  2552. if (rc)
  2553. return rc;
  2554. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  2555. name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
  2556. PATH_MAX, nls_codepage, remap);
  2557. name_len++; /* trailing null */
  2558. name_len *= 2;
  2559. } else { /* BB improve the check for buffer overruns BB */
  2560. name_len = strnlen(toName, PATH_MAX);
  2561. name_len++; /* trailing null */
  2562. strncpy(pSMB->FileName, toName, name_len);
  2563. }
  2564. params = 6 + name_len;
  2565. pSMB->MaxSetupCount = 0;
  2566. pSMB->Reserved = 0;
  2567. pSMB->Flags = 0;
  2568. pSMB->Timeout = 0;
  2569. pSMB->Reserved2 = 0;
  2570. param_offset = offsetof(struct smb_com_transaction2_spi_req,
  2571. InformationLevel) - 4;
  2572. offset = param_offset + params;
  2573. data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
  2574. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  2575. name_len_target =
  2576. cifsConvertToUTF16((__le16 *) data_offset, fromName,
  2577. PATH_MAX, nls_codepage, remap);
  2578. name_len_target++; /* trailing null */
  2579. name_len_target *= 2;
  2580. } else { /* BB improve the check for buffer overruns BB */
  2581. name_len_target = strnlen(fromName, PATH_MAX);
  2582. name_len_target++; /* trailing null */
  2583. strncpy(data_offset, fromName, name_len_target);
  2584. }
  2585. pSMB->MaxParameterCount = cpu_to_le16(2);
  2586. /* BB find exact max on data count below from sess*/
  2587. pSMB->MaxDataCount = cpu_to_le16(1000);
  2588. pSMB->SetupCount = 1;
  2589. pSMB->Reserved3 = 0;
  2590. pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
  2591. byte_count = 3 /* pad */ + params + name_len_target;
  2592. pSMB->ParameterCount = cpu_to_le16(params);
  2593. pSMB->TotalParameterCount = pSMB->ParameterCount;
  2594. pSMB->DataCount = cpu_to_le16(name_len_target);
  2595. pSMB->TotalDataCount = pSMB->DataCount;
  2596. pSMB->ParameterOffset = cpu_to_le16(param_offset);
  2597. pSMB->DataOffset = cpu_to_le16(offset);
  2598. pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
  2599. pSMB->Reserved4 = 0;
  2600. inc_rfc1001_len(pSMB, byte_count);
  2601. pSMB->ByteCount = cpu_to_le16(byte_count);
  2602. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  2603. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  2604. cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
  2605. if (rc)
  2606. cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n",
  2607. rc);
  2608. cifs_buf_release(pSMB);
  2609. if (rc == -EAGAIN)
  2610. goto createHardLinkRetry;
  2611. return rc;
  2612. }
  2613. int
  2614. CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
  2615. const char *from_name, const char *to_name,
  2616. struct cifs_sb_info *cifs_sb)
  2617. {
  2618. int rc = 0;
  2619. NT_RENAME_REQ *pSMB = NULL;
  2620. RENAME_RSP *pSMBr = NULL;
  2621. int bytes_returned;
  2622. int name_len, name_len2;
  2623. __u16 count;
  2624. int remap = cifs_remap(cifs_sb);
  2625. cifs_dbg(FYI, "In CIFSCreateHardLink\n");
  2626. winCreateHardLinkRetry:
  2627. rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
  2628. (void **) &pSMBr);
  2629. if (rc)
  2630. return rc;
  2631. pSMB->SearchAttributes =
  2632. cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
  2633. ATTR_DIRECTORY);
  2634. pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
  2635. pSMB->ClusterCount = 0;
  2636. pSMB->BufferFormat = 0x04;
  2637. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  2638. name_len =
  2639. cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
  2640. PATH_MAX, cifs_sb->local_nls, remap);
  2641. name_len++; /* trailing null */
  2642. name_len *= 2;
  2643. /* protocol specifies ASCII buffer format (0x04) for unicode */
  2644. pSMB->OldFileName[name_len] = 0x04;
  2645. pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
  2646. name_len2 =
  2647. cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
  2648. to_name, PATH_MAX, cifs_sb->local_nls,
  2649. remap);
  2650. name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
  2651. name_len2 *= 2; /* convert to bytes */
  2652. } else { /* BB improve the check for buffer overruns BB */
  2653. name_len = strnlen(from_name, PATH_MAX);
  2654. name_len++; /* trailing null */
  2655. strncpy(pSMB->OldFileName, from_name, name_len);
  2656. name_len2 = strnlen(to_name, PATH_MAX);
  2657. name_len2++; /* trailing null */
  2658. pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
  2659. strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
  2660. name_len2++; /* trailing null */
  2661. name_len2++; /* signature byte */
  2662. }
  2663. count = 1 /* string type byte */ + name_len + name_len2;
  2664. inc_rfc1001_len(pSMB, count);
  2665. pSMB->ByteCount = cpu_to_le16(count);
  2666. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  2667. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  2668. cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
  2669. if (rc)
  2670. cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc);
  2671. cifs_buf_release(pSMB);
  2672. if (rc == -EAGAIN)
  2673. goto winCreateHardLinkRetry;
  2674. return rc;
  2675. }
  2676. int
  2677. CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
  2678. const unsigned char *searchName, char **symlinkinfo,
  2679. const struct nls_table *nls_codepage, int remap)
  2680. {
  2681. /* SMB_QUERY_FILE_UNIX_LINK */
  2682. TRANSACTION2_QPI_REQ *pSMB = NULL;
  2683. TRANSACTION2_QPI_RSP *pSMBr = NULL;
  2684. int rc = 0;
  2685. int bytes_returned;
  2686. int name_len;
  2687. __u16 params, byte_count;
  2688. char *data_start;
  2689. cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName);
  2690. querySymLinkRetry:
  2691. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  2692. (void **) &pSMBr);
  2693. if (rc)
  2694. return rc;
  2695. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  2696. name_len =
  2697. cifsConvertToUTF16((__le16 *) pSMB->FileName,
  2698. searchName, PATH_MAX, nls_codepage,
  2699. remap);
  2700. name_len++; /* trailing null */
  2701. name_len *= 2;
  2702. } else { /* BB improve the check for buffer overruns BB */
  2703. name_len = strnlen(searchName, PATH_MAX);
  2704. name_len++; /* trailing null */
  2705. strncpy(pSMB->FileName, searchName, name_len);
  2706. }
  2707. params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
  2708. pSMB->TotalDataCount = 0;
  2709. pSMB->MaxParameterCount = cpu_to_le16(2);
  2710. pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
  2711. pSMB->MaxSetupCount = 0;
  2712. pSMB->Reserved = 0;
  2713. pSMB->Flags = 0;
  2714. pSMB->Timeout = 0;
  2715. pSMB->Reserved2 = 0;
  2716. pSMB->ParameterOffset = cpu_to_le16(offsetof(
  2717. struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
  2718. pSMB->DataCount = 0;
  2719. pSMB->DataOffset = 0;
  2720. pSMB->SetupCount = 1;
  2721. pSMB->Reserved3 = 0;
  2722. pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
  2723. byte_count = params + 1 /* pad */ ;
  2724. pSMB->TotalParameterCount = cpu_to_le16(params);
  2725. pSMB->ParameterCount = pSMB->TotalParameterCount;
  2726. pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
  2727. pSMB->Reserved4 = 0;
  2728. inc_rfc1001_len(pSMB, byte_count);
  2729. pSMB->ByteCount = cpu_to_le16(byte_count);
  2730. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  2731. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  2732. if (rc) {
  2733. cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
  2734. } else {
  2735. /* decode response */
  2736. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  2737. /* BB also check enough total bytes returned */
  2738. if (rc || get_bcc(&pSMBr->hdr) < 2)
  2739. rc = -EIO;
  2740. else {
  2741. bool is_unicode;
  2742. u16 count = le16_to_cpu(pSMBr->t2.DataCount);
  2743. data_start = ((char *) &pSMBr->hdr.Protocol) +
  2744. le16_to_cpu(pSMBr->t2.DataOffset);
  2745. if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
  2746. is_unicode = true;
  2747. else
  2748. is_unicode = false;
  2749. /* BB FIXME investigate remapping reserved chars here */
  2750. *symlinkinfo = cifs_strndup_from_utf16(data_start,
  2751. count, is_unicode, nls_codepage);
  2752. if (!*symlinkinfo)
  2753. rc = -ENOMEM;
  2754. }
  2755. }
  2756. cifs_buf_release(pSMB);
  2757. if (rc == -EAGAIN)
  2758. goto querySymLinkRetry;
  2759. return rc;
  2760. }
  2761. /*
  2762. * Recent Windows versions now create symlinks more frequently
  2763. * and they use the "reparse point" mechanism below. We can of course
  2764. * do symlinks nicely to Samba and other servers which support the
  2765. * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
  2766. * "MF" symlinks optionally, but for recent Windows we really need to
  2767. * reenable the code below and fix the cifs_symlink callers to handle this.
  2768. * In the interim this code has been moved to its own config option so
  2769. * it is not compiled in by default until callers fixed up and more tested.
  2770. */
  2771. int
  2772. CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
  2773. __u16 fid, char **symlinkinfo,
  2774. const struct nls_table *nls_codepage)
  2775. {
  2776. int rc = 0;
  2777. int bytes_returned;
  2778. struct smb_com_transaction_ioctl_req *pSMB;
  2779. struct smb_com_transaction_ioctl_rsp *pSMBr;
  2780. bool is_unicode;
  2781. unsigned int sub_len;
  2782. char *sub_start;
  2783. struct reparse_symlink_data *reparse_buf;
  2784. struct reparse_posix_data *posix_buf;
  2785. __u32 data_offset, data_count;
  2786. char *end_of_smb;
  2787. cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
  2788. rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
  2789. (void **) &pSMBr);
  2790. if (rc)
  2791. return rc;
  2792. pSMB->TotalParameterCount = 0 ;
  2793. pSMB->TotalDataCount = 0;
  2794. pSMB->MaxParameterCount = cpu_to_le32(2);
  2795. /* BB find exact data count max from sess structure BB */
  2796. pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
  2797. pSMB->MaxSetupCount = 4;
  2798. pSMB->Reserved = 0;
  2799. pSMB->ParameterOffset = 0;
  2800. pSMB->DataCount = 0;
  2801. pSMB->DataOffset = 0;
  2802. pSMB->SetupCount = 4;
  2803. pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
  2804. pSMB->ParameterCount = pSMB->TotalParameterCount;
  2805. pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
  2806. pSMB->IsFsctl = 1; /* FSCTL */
  2807. pSMB->IsRootFlag = 0;
  2808. pSMB->Fid = fid; /* file handle always le */
  2809. pSMB->ByteCount = 0;
  2810. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  2811. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  2812. if (rc) {
  2813. cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
  2814. goto qreparse_out;
  2815. }
  2816. data_offset = le32_to_cpu(pSMBr->DataOffset);
  2817. data_count = le32_to_cpu(pSMBr->DataCount);
  2818. if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
  2819. /* BB also check enough total bytes returned */
  2820. rc = -EIO; /* bad smb */
  2821. goto qreparse_out;
  2822. }
  2823. if (!data_count || (data_count > 2048)) {
  2824. rc = -EIO;
  2825. cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
  2826. goto qreparse_out;
  2827. }
  2828. end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
  2829. reparse_buf = (struct reparse_symlink_data *)
  2830. ((char *)&pSMBr->hdr.Protocol + data_offset);
  2831. if ((char *)reparse_buf >= end_of_smb) {
  2832. rc = -EIO;
  2833. goto qreparse_out;
  2834. }
  2835. if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
  2836. cifs_dbg(FYI, "NFS style reparse tag\n");
  2837. posix_buf = (struct reparse_posix_data *)reparse_buf;
  2838. if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
  2839. cifs_dbg(FYI, "unsupported file type 0x%llx\n",
  2840. le64_to_cpu(posix_buf->InodeType));
  2841. rc = -EOPNOTSUPP;
  2842. goto qreparse_out;
  2843. }
  2844. is_unicode = true;
  2845. sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
  2846. if (posix_buf->PathBuffer + sub_len > end_of_smb) {
  2847. cifs_dbg(FYI, "reparse buf beyond SMB\n");
  2848. rc = -EIO;
  2849. goto qreparse_out;
  2850. }
  2851. *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
  2852. sub_len, is_unicode, nls_codepage);
  2853. goto qreparse_out;
  2854. } else if (reparse_buf->ReparseTag !=
  2855. cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
  2856. rc = -EOPNOTSUPP;
  2857. goto qreparse_out;
  2858. }
  2859. /* Reparse tag is NTFS symlink */
  2860. sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
  2861. reparse_buf->PathBuffer;
  2862. sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
  2863. if (sub_start + sub_len > end_of_smb) {
  2864. cifs_dbg(FYI, "reparse buf beyond SMB\n");
  2865. rc = -EIO;
  2866. goto qreparse_out;
  2867. }
  2868. if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
  2869. is_unicode = true;
  2870. else
  2871. is_unicode = false;
  2872. /* BB FIXME investigate remapping reserved chars here */
  2873. *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
  2874. nls_codepage);
  2875. if (!*symlinkinfo)
  2876. rc = -ENOMEM;
  2877. qreparse_out:
  2878. cifs_buf_release(pSMB);
  2879. /*
  2880. * Note: On -EAGAIN error only caller can retry on handle based calls
  2881. * since file handle passed in no longer valid.
  2882. */
  2883. return rc;
  2884. }
  2885. int
  2886. CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
  2887. __u16 fid)
  2888. {
  2889. int rc = 0;
  2890. int bytes_returned;
  2891. struct smb_com_transaction_compr_ioctl_req *pSMB;
  2892. struct smb_com_transaction_ioctl_rsp *pSMBr;
  2893. cifs_dbg(FYI, "Set compression for %u\n", fid);
  2894. rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
  2895. (void **) &pSMBr);
  2896. if (rc)
  2897. return rc;
  2898. pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
  2899. pSMB->TotalParameterCount = 0;
  2900. pSMB->TotalDataCount = cpu_to_le32(2);
  2901. pSMB->MaxParameterCount = 0;
  2902. pSMB->MaxDataCount = 0;
  2903. pSMB->MaxSetupCount = 4;
  2904. pSMB->Reserved = 0;
  2905. pSMB->ParameterOffset = 0;
  2906. pSMB->DataCount = cpu_to_le32(2);
  2907. pSMB->DataOffset =
  2908. cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
  2909. compression_state) - 4); /* 84 */
  2910. pSMB->SetupCount = 4;
  2911. pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
  2912. pSMB->ParameterCount = 0;
  2913. pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION);
  2914. pSMB->IsFsctl = 1; /* FSCTL */
  2915. pSMB->IsRootFlag = 0;
  2916. pSMB->Fid = fid; /* file handle always le */
  2917. /* 3 byte pad, followed by 2 byte compress state */
  2918. pSMB->ByteCount = cpu_to_le16(5);
  2919. inc_rfc1001_len(pSMB, 5);
  2920. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  2921. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  2922. if (rc)
  2923. cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
  2924. cifs_buf_release(pSMB);
  2925. /*
  2926. * Note: On -EAGAIN error only caller can retry on handle based calls
  2927. * since file handle passed in no longer valid.
  2928. */
  2929. return rc;
  2930. }
  2931. #ifdef CONFIG_CIFS_POSIX
  2932. /*Convert an Access Control Entry from wire format to local POSIX xattr format*/
  2933. static void cifs_convert_ace(posix_acl_xattr_entry *ace,
  2934. struct cifs_posix_ace *cifs_ace)
  2935. {
  2936. /* u8 cifs fields do not need le conversion */
  2937. ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
  2938. ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
  2939. ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
  2940. /*
  2941. cifs_dbg(FYI, "perm %d tag %d id %d\n",
  2942. ace->e_perm, ace->e_tag, ace->e_id);
  2943. */
  2944. return;
  2945. }
  2946. /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
  2947. static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
  2948. const int acl_type, const int size_of_data_area)
  2949. {
  2950. int size = 0;
  2951. int i;
  2952. __u16 count;
  2953. struct cifs_posix_ace *pACE;
  2954. struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
  2955. posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)trgt;
  2956. if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
  2957. return -EOPNOTSUPP;
  2958. if (acl_type & ACL_TYPE_ACCESS) {
  2959. count = le16_to_cpu(cifs_acl->access_entry_count);
  2960. pACE = &cifs_acl->ace_array[0];
  2961. size = sizeof(struct cifs_posix_acl);
  2962. size += sizeof(struct cifs_posix_ace) * count;
  2963. /* check if we would go beyond end of SMB */
  2964. if (size_of_data_area < size) {
  2965. cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n",
  2966. size_of_data_area, size);
  2967. return -EINVAL;
  2968. }
  2969. } else if (acl_type & ACL_TYPE_DEFAULT) {
  2970. count = le16_to_cpu(cifs_acl->access_entry_count);
  2971. size = sizeof(struct cifs_posix_acl);
  2972. size += sizeof(struct cifs_posix_ace) * count;
  2973. /* skip past access ACEs to get to default ACEs */
  2974. pACE = &cifs_acl->ace_array[count];
  2975. count = le16_to_cpu(cifs_acl->default_entry_count);
  2976. size += sizeof(struct cifs_posix_ace) * count;
  2977. /* check if we would go beyond end of SMB */
  2978. if (size_of_data_area < size)
  2979. return -EINVAL;
  2980. } else {
  2981. /* illegal type */
  2982. return -EINVAL;
  2983. }
  2984. size = posix_acl_xattr_size(count);
  2985. if ((buflen == 0) || (local_acl == NULL)) {
  2986. /* used to query ACL EA size */
  2987. } else if (size > buflen) {
  2988. return -ERANGE;
  2989. } else /* buffer big enough */ {
  2990. local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
  2991. for (i = 0; i < count ; i++) {
  2992. cifs_convert_ace(&local_acl->a_entries[i], pACE);
  2993. pACE++;
  2994. }
  2995. }
  2996. return size;
  2997. }
  2998. static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
  2999. const posix_acl_xattr_entry *local_ace)
  3000. {
  3001. __u16 rc = 0; /* 0 = ACL converted ok */
  3002. cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
  3003. cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
  3004. /* BB is there a better way to handle the large uid? */
  3005. if (local_ace->e_id == cpu_to_le32(-1)) {
  3006. /* Probably no need to le convert -1 on any arch but can not hurt */
  3007. cifs_ace->cifs_uid = cpu_to_le64(-1);
  3008. } else
  3009. cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
  3010. /*
  3011. cifs_dbg(FYI, "perm %d tag %d id %d\n",
  3012. ace->e_perm, ace->e_tag, ace->e_id);
  3013. */
  3014. return rc;
  3015. }
  3016. /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
  3017. static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
  3018. const int buflen, const int acl_type)
  3019. {
  3020. __u16 rc = 0;
  3021. struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
  3022. posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)pACL;
  3023. int count;
  3024. int i;
  3025. if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
  3026. return 0;
  3027. count = posix_acl_xattr_count((size_t)buflen);
  3028. cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n",
  3029. count, buflen, le32_to_cpu(local_acl->a_version));
  3030. if (le32_to_cpu(local_acl->a_version) != 2) {
  3031. cifs_dbg(FYI, "unknown POSIX ACL version %d\n",
  3032. le32_to_cpu(local_acl->a_version));
  3033. return 0;
  3034. }
  3035. cifs_acl->version = cpu_to_le16(1);
  3036. if (acl_type == ACL_TYPE_ACCESS) {
  3037. cifs_acl->access_entry_count = cpu_to_le16(count);
  3038. cifs_acl->default_entry_count = cpu_to_le16(0xFFFF);
  3039. } else if (acl_type == ACL_TYPE_DEFAULT) {
  3040. cifs_acl->default_entry_count = cpu_to_le16(count);
  3041. cifs_acl->access_entry_count = cpu_to_le16(0xFFFF);
  3042. } else {
  3043. cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
  3044. return 0;
  3045. }
  3046. for (i = 0; i < count; i++) {
  3047. rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
  3048. &local_acl->a_entries[i]);
  3049. if (rc != 0) {
  3050. /* ACE not converted */
  3051. break;
  3052. }
  3053. }
  3054. if (rc == 0) {
  3055. rc = (__u16)(count * sizeof(struct cifs_posix_ace));
  3056. rc += sizeof(struct cifs_posix_acl);
  3057. /* BB add check to make sure ACL does not overflow SMB */
  3058. }
  3059. return rc;
  3060. }
  3061. int
  3062. CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
  3063. const unsigned char *searchName,
  3064. char *acl_inf, const int buflen, const int acl_type,
  3065. const struct nls_table *nls_codepage, int remap)
  3066. {
  3067. /* SMB_QUERY_POSIX_ACL */
  3068. TRANSACTION2_QPI_REQ *pSMB = NULL;
  3069. TRANSACTION2_QPI_RSP *pSMBr = NULL;
  3070. int rc = 0;
  3071. int bytes_returned;
  3072. int name_len;
  3073. __u16 params, byte_count;
  3074. cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName);
  3075. queryAclRetry:
  3076. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  3077. (void **) &pSMBr);
  3078. if (rc)
  3079. return rc;
  3080. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  3081. name_len =
  3082. cifsConvertToUTF16((__le16 *) pSMB->FileName,
  3083. searchName, PATH_MAX, nls_codepage,
  3084. remap);
  3085. name_len++; /* trailing null */
  3086. name_len *= 2;
  3087. pSMB->FileName[name_len] = 0;
  3088. pSMB->FileName[name_len+1] = 0;
  3089. } else { /* BB improve the check for buffer overruns BB */
  3090. name_len = strnlen(searchName, PATH_MAX);
  3091. name_len++; /* trailing null */
  3092. strncpy(pSMB->FileName, searchName, name_len);
  3093. }
  3094. params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
  3095. pSMB->TotalDataCount = 0;
  3096. pSMB->MaxParameterCount = cpu_to_le16(2);
  3097. /* BB find exact max data count below from sess structure BB */
  3098. pSMB->MaxDataCount = cpu_to_le16(4000);
  3099. pSMB->MaxSetupCount = 0;
  3100. pSMB->Reserved = 0;
  3101. pSMB->Flags = 0;
  3102. pSMB->Timeout = 0;
  3103. pSMB->Reserved2 = 0;
  3104. pSMB->ParameterOffset = cpu_to_le16(
  3105. offsetof(struct smb_com_transaction2_qpi_req,
  3106. InformationLevel) - 4);
  3107. pSMB->DataCount = 0;
  3108. pSMB->DataOffset = 0;
  3109. pSMB->SetupCount = 1;
  3110. pSMB->Reserved3 = 0;
  3111. pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
  3112. byte_count = params + 1 /* pad */ ;
  3113. pSMB->TotalParameterCount = cpu_to_le16(params);
  3114. pSMB->ParameterCount = pSMB->TotalParameterCount;
  3115. pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
  3116. pSMB->Reserved4 = 0;
  3117. inc_rfc1001_len(pSMB, byte_count);
  3118. pSMB->ByteCount = cpu_to_le16(byte_count);
  3119. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  3120. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  3121. cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
  3122. if (rc) {
  3123. cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc);
  3124. } else {
  3125. /* decode response */
  3126. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  3127. /* BB also check enough total bytes returned */
  3128. if (rc || get_bcc(&pSMBr->hdr) < 2)
  3129. rc = -EIO; /* bad smb */
  3130. else {
  3131. __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
  3132. __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
  3133. rc = cifs_copy_posix_acl(acl_inf,
  3134. (char *)&pSMBr->hdr.Protocol+data_offset,
  3135. buflen, acl_type, count);
  3136. }
  3137. }
  3138. cifs_buf_release(pSMB);
  3139. if (rc == -EAGAIN)
  3140. goto queryAclRetry;
  3141. return rc;
  3142. }
  3143. int
  3144. CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon,
  3145. const unsigned char *fileName,
  3146. const char *local_acl, const int buflen,
  3147. const int acl_type,
  3148. const struct nls_table *nls_codepage, int remap)
  3149. {
  3150. struct smb_com_transaction2_spi_req *pSMB = NULL;
  3151. struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
  3152. char *parm_data;
  3153. int name_len;
  3154. int rc = 0;
  3155. int bytes_returned = 0;
  3156. __u16 params, byte_count, data_count, param_offset, offset;
  3157. cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName);
  3158. setAclRetry:
  3159. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  3160. (void **) &pSMBr);
  3161. if (rc)
  3162. return rc;
  3163. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  3164. name_len =
  3165. cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
  3166. PATH_MAX, nls_codepage, remap);
  3167. name_len++; /* trailing null */
  3168. name_len *= 2;
  3169. } else { /* BB improve the check for buffer overruns BB */
  3170. name_len = strnlen(fileName, PATH_MAX);
  3171. name_len++; /* trailing null */
  3172. strncpy(pSMB->FileName, fileName, name_len);
  3173. }
  3174. params = 6 + name_len;
  3175. pSMB->MaxParameterCount = cpu_to_le16(2);
  3176. /* BB find max SMB size from sess */
  3177. pSMB->MaxDataCount = cpu_to_le16(1000);
  3178. pSMB->MaxSetupCount = 0;
  3179. pSMB->Reserved = 0;
  3180. pSMB->Flags = 0;
  3181. pSMB->Timeout = 0;
  3182. pSMB->Reserved2 = 0;
  3183. param_offset = offsetof(struct smb_com_transaction2_spi_req,
  3184. InformationLevel) - 4;
  3185. offset = param_offset + params;
  3186. parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
  3187. pSMB->ParameterOffset = cpu_to_le16(param_offset);
  3188. /* convert to on the wire format for POSIX ACL */
  3189. data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
  3190. if (data_count == 0) {
  3191. rc = -EOPNOTSUPP;
  3192. goto setACLerrorExit;
  3193. }
  3194. pSMB->DataOffset = cpu_to_le16(offset);
  3195. pSMB->SetupCount = 1;
  3196. pSMB->Reserved3 = 0;
  3197. pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
  3198. pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
  3199. byte_count = 3 /* pad */ + params + data_count;
  3200. pSMB->DataCount = cpu_to_le16(data_count);
  3201. pSMB->TotalDataCount = pSMB->DataCount;
  3202. pSMB->ParameterCount = cpu_to_le16(params);
  3203. pSMB->TotalParameterCount = pSMB->ParameterCount;
  3204. pSMB->Reserved4 = 0;
  3205. inc_rfc1001_len(pSMB, byte_count);
  3206. pSMB->ByteCount = cpu_to_le16(byte_count);
  3207. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  3208. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  3209. if (rc)
  3210. cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
  3211. setACLerrorExit:
  3212. cifs_buf_release(pSMB);
  3213. if (rc == -EAGAIN)
  3214. goto setAclRetry;
  3215. return rc;
  3216. }
  3217. /* BB fix tabs in this function FIXME BB */
  3218. int
  3219. CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
  3220. const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
  3221. {
  3222. int rc = 0;
  3223. struct smb_t2_qfi_req *pSMB = NULL;
  3224. struct smb_t2_qfi_rsp *pSMBr = NULL;
  3225. int bytes_returned;
  3226. __u16 params, byte_count;
  3227. cifs_dbg(FYI, "In GetExtAttr\n");
  3228. if (tcon == NULL)
  3229. return -ENODEV;
  3230. GetExtAttrRetry:
  3231. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  3232. (void **) &pSMBr);
  3233. if (rc)
  3234. return rc;
  3235. params = 2 /* level */ + 2 /* fid */;
  3236. pSMB->t2.TotalDataCount = 0;
  3237. pSMB->t2.MaxParameterCount = cpu_to_le16(4);
  3238. /* BB find exact max data count below from sess structure BB */
  3239. pSMB->t2.MaxDataCount = cpu_to_le16(4000);
  3240. pSMB->t2.MaxSetupCount = 0;
  3241. pSMB->t2.Reserved = 0;
  3242. pSMB->t2.Flags = 0;
  3243. pSMB->t2.Timeout = 0;
  3244. pSMB->t2.Reserved2 = 0;
  3245. pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
  3246. Fid) - 4);
  3247. pSMB->t2.DataCount = 0;
  3248. pSMB->t2.DataOffset = 0;
  3249. pSMB->t2.SetupCount = 1;
  3250. pSMB->t2.Reserved3 = 0;
  3251. pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
  3252. byte_count = params + 1 /* pad */ ;
  3253. pSMB->t2.TotalParameterCount = cpu_to_le16(params);
  3254. pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
  3255. pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
  3256. pSMB->Pad = 0;
  3257. pSMB->Fid = netfid;
  3258. inc_rfc1001_len(pSMB, byte_count);
  3259. pSMB->t2.ByteCount = cpu_to_le16(byte_count);
  3260. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  3261. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  3262. if (rc) {
  3263. cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
  3264. } else {
  3265. /* decode response */
  3266. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  3267. /* BB also check enough total bytes returned */
  3268. if (rc || get_bcc(&pSMBr->hdr) < 2)
  3269. /* If rc should we check for EOPNOSUPP and
  3270. disable the srvino flag? or in caller? */
  3271. rc = -EIO; /* bad smb */
  3272. else {
  3273. __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
  3274. __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
  3275. struct file_chattr_info *pfinfo;
  3276. /* BB Do we need a cast or hash here ? */
  3277. if (count != 16) {
  3278. cifs_dbg(FYI, "Illegal size ret in GetExtAttr\n");
  3279. rc = -EIO;
  3280. goto GetExtAttrOut;
  3281. }
  3282. pfinfo = (struct file_chattr_info *)
  3283. (data_offset + (char *) &pSMBr->hdr.Protocol);
  3284. *pExtAttrBits = le64_to_cpu(pfinfo->mode);
  3285. *pMask = le64_to_cpu(pfinfo->mask);
  3286. }
  3287. }
  3288. GetExtAttrOut:
  3289. cifs_buf_release(pSMB);
  3290. if (rc == -EAGAIN)
  3291. goto GetExtAttrRetry;
  3292. return rc;
  3293. }
  3294. #endif /* CONFIG_POSIX */
  3295. #ifdef CONFIG_CIFS_ACL
  3296. /*
  3297. * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
  3298. * all NT TRANSACTS that we init here have total parm and data under about 400
  3299. * bytes (to fit in small cifs buffer size), which is the case so far, it
  3300. * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
  3301. * returned setup area) and MaxParameterCount (returned parms size) must be set
  3302. * by caller
  3303. */
  3304. static int
  3305. smb_init_nttransact(const __u16 sub_command, const int setup_count,
  3306. const int parm_len, struct cifs_tcon *tcon,
  3307. void **ret_buf)
  3308. {
  3309. int rc;
  3310. __u32 temp_offset;
  3311. struct smb_com_ntransact_req *pSMB;
  3312. rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
  3313. (void **)&pSMB);
  3314. if (rc)
  3315. return rc;
  3316. *ret_buf = (void *)pSMB;
  3317. pSMB->Reserved = 0;
  3318. pSMB->TotalParameterCount = cpu_to_le32(parm_len);
  3319. pSMB->TotalDataCount = 0;
  3320. pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
  3321. pSMB->ParameterCount = pSMB->TotalParameterCount;
  3322. pSMB->DataCount = pSMB->TotalDataCount;
  3323. temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
  3324. (setup_count * 2) - 4 /* for rfc1001 length itself */;
  3325. pSMB->ParameterOffset = cpu_to_le32(temp_offset);
  3326. pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
  3327. pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
  3328. pSMB->SubCommand = cpu_to_le16(sub_command);
  3329. return 0;
  3330. }
  3331. static int
  3332. validate_ntransact(char *buf, char **ppparm, char **ppdata,
  3333. __u32 *pparmlen, __u32 *pdatalen)
  3334. {
  3335. char *end_of_smb;
  3336. __u32 data_count, data_offset, parm_count, parm_offset;
  3337. struct smb_com_ntransact_rsp *pSMBr;
  3338. u16 bcc;
  3339. *pdatalen = 0;
  3340. *pparmlen = 0;
  3341. if (buf == NULL)
  3342. return -EINVAL;
  3343. pSMBr = (struct smb_com_ntransact_rsp *)buf;
  3344. bcc = get_bcc(&pSMBr->hdr);
  3345. end_of_smb = 2 /* sizeof byte count */ + bcc +
  3346. (char *)&pSMBr->ByteCount;
  3347. data_offset = le32_to_cpu(pSMBr->DataOffset);
  3348. data_count = le32_to_cpu(pSMBr->DataCount);
  3349. parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
  3350. parm_count = le32_to_cpu(pSMBr->ParameterCount);
  3351. *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
  3352. *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
  3353. /* should we also check that parm and data areas do not overlap? */
  3354. if (*ppparm > end_of_smb) {
  3355. cifs_dbg(FYI, "parms start after end of smb\n");
  3356. return -EINVAL;
  3357. } else if (parm_count + *ppparm > end_of_smb) {
  3358. cifs_dbg(FYI, "parm end after end of smb\n");
  3359. return -EINVAL;
  3360. } else if (*ppdata > end_of_smb) {
  3361. cifs_dbg(FYI, "data starts after end of smb\n");
  3362. return -EINVAL;
  3363. } else if (data_count + *ppdata > end_of_smb) {
  3364. cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
  3365. *ppdata, data_count, (data_count + *ppdata),
  3366. end_of_smb, pSMBr);
  3367. return -EINVAL;
  3368. } else if (parm_count + data_count > bcc) {
  3369. cifs_dbg(FYI, "parm count and data count larger than SMB\n");
  3370. return -EINVAL;
  3371. }
  3372. *pdatalen = data_count;
  3373. *pparmlen = parm_count;
  3374. return 0;
  3375. }
  3376. /* Get Security Descriptor (by handle) from remote server for a file or dir */
  3377. int
  3378. CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
  3379. struct cifs_ntsd **acl_inf, __u32 *pbuflen)
  3380. {
  3381. int rc = 0;
  3382. int buf_type = 0;
  3383. QUERY_SEC_DESC_REQ *pSMB;
  3384. struct kvec iov[1];
  3385. cifs_dbg(FYI, "GetCifsACL\n");
  3386. *pbuflen = 0;
  3387. *acl_inf = NULL;
  3388. rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
  3389. 8 /* parm len */, tcon, (void **) &pSMB);
  3390. if (rc)
  3391. return rc;
  3392. pSMB->MaxParameterCount = cpu_to_le32(4);
  3393. /* BB TEST with big acls that might need to be e.g. larger than 16K */
  3394. pSMB->MaxSetupCount = 0;
  3395. pSMB->Fid = fid; /* file handle always le */
  3396. pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
  3397. CIFS_ACL_DACL);
  3398. pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
  3399. inc_rfc1001_len(pSMB, 11);
  3400. iov[0].iov_base = (char *)pSMB;
  3401. iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
  3402. rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
  3403. 0);
  3404. cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
  3405. if (rc) {
  3406. cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc);
  3407. } else { /* decode response */
  3408. __le32 *parm;
  3409. __u32 parm_len;
  3410. __u32 acl_len;
  3411. struct smb_com_ntransact_rsp *pSMBr;
  3412. char *pdata;
  3413. /* validate_nttransact */
  3414. rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
  3415. &pdata, &parm_len, pbuflen);
  3416. if (rc)
  3417. goto qsec_out;
  3418. pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
  3419. cifs_dbg(FYI, "smb %p parm %p data %p\n",
  3420. pSMBr, parm, *acl_inf);
  3421. if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
  3422. rc = -EIO; /* bad smb */
  3423. *pbuflen = 0;
  3424. goto qsec_out;
  3425. }
  3426. /* BB check that data area is minimum length and as big as acl_len */
  3427. acl_len = le32_to_cpu(*parm);
  3428. if (acl_len != *pbuflen) {
  3429. cifs_dbg(VFS, "acl length %d does not match %d\n",
  3430. acl_len, *pbuflen);
  3431. if (*pbuflen > acl_len)
  3432. *pbuflen = acl_len;
  3433. }
  3434. /* check if buffer is big enough for the acl
  3435. header followed by the smallest SID */
  3436. if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
  3437. (*pbuflen >= 64 * 1024)) {
  3438. cifs_dbg(VFS, "bad acl length %d\n", *pbuflen);
  3439. rc = -EINVAL;
  3440. *pbuflen = 0;
  3441. } else {
  3442. *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL);
  3443. if (*acl_inf == NULL) {
  3444. *pbuflen = 0;
  3445. rc = -ENOMEM;
  3446. }
  3447. }
  3448. }
  3449. qsec_out:
  3450. free_rsp_buf(buf_type, iov[0].iov_base);
  3451. /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
  3452. return rc;
  3453. }
  3454. int
  3455. CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
  3456. struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
  3457. {
  3458. __u16 byte_count, param_count, data_count, param_offset, data_offset;
  3459. int rc = 0;
  3460. int bytes_returned = 0;
  3461. SET_SEC_DESC_REQ *pSMB = NULL;
  3462. void *pSMBr;
  3463. setCifsAclRetry:
  3464. rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
  3465. if (rc)
  3466. return rc;
  3467. pSMB->MaxSetupCount = 0;
  3468. pSMB->Reserved = 0;
  3469. param_count = 8;
  3470. param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
  3471. data_count = acllen;
  3472. data_offset = param_offset + param_count;
  3473. byte_count = 3 /* pad */ + param_count;
  3474. pSMB->DataCount = cpu_to_le32(data_count);
  3475. pSMB->TotalDataCount = pSMB->DataCount;
  3476. pSMB->MaxParameterCount = cpu_to_le32(4);
  3477. pSMB->MaxDataCount = cpu_to_le32(16384);
  3478. pSMB->ParameterCount = cpu_to_le32(param_count);
  3479. pSMB->ParameterOffset = cpu_to_le32(param_offset);
  3480. pSMB->TotalParameterCount = pSMB->ParameterCount;
  3481. pSMB->DataOffset = cpu_to_le32(data_offset);
  3482. pSMB->SetupCount = 0;
  3483. pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
  3484. pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
  3485. pSMB->Fid = fid; /* file handle always le */
  3486. pSMB->Reserved2 = 0;
  3487. pSMB->AclFlags = cpu_to_le32(aclflag);
  3488. if (pntsd && acllen) {
  3489. memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
  3490. data_offset, pntsd, acllen);
  3491. inc_rfc1001_len(pSMB, byte_count + data_count);
  3492. } else
  3493. inc_rfc1001_len(pSMB, byte_count);
  3494. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  3495. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  3496. cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
  3497. bytes_returned, rc);
  3498. if (rc)
  3499. cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc);
  3500. cifs_buf_release(pSMB);
  3501. if (rc == -EAGAIN)
  3502. goto setCifsAclRetry;
  3503. return (rc);
  3504. }
  3505. #endif /* CONFIG_CIFS_ACL */
  3506. /* Legacy Query Path Information call for lookup to old servers such
  3507. as Win9x/WinME */
  3508. int
  3509. SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
  3510. const char *search_name, FILE_ALL_INFO *data,
  3511. const struct nls_table *nls_codepage, int remap)
  3512. {
  3513. QUERY_INFORMATION_REQ *pSMB;
  3514. QUERY_INFORMATION_RSP *pSMBr;
  3515. int rc = 0;
  3516. int bytes_returned;
  3517. int name_len;
  3518. cifs_dbg(FYI, "In SMBQPath path %s\n", search_name);
  3519. QInfRetry:
  3520. rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
  3521. (void **) &pSMBr);
  3522. if (rc)
  3523. return rc;
  3524. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  3525. name_len =
  3526. cifsConvertToUTF16((__le16 *) pSMB->FileName,
  3527. search_name, PATH_MAX, nls_codepage,
  3528. remap);
  3529. name_len++; /* trailing null */
  3530. name_len *= 2;
  3531. } else {
  3532. name_len = strnlen(search_name, PATH_MAX);
  3533. name_len++; /* trailing null */
  3534. strncpy(pSMB->FileName, search_name, name_len);
  3535. }
  3536. pSMB->BufferFormat = 0x04;
  3537. name_len++; /* account for buffer type byte */
  3538. inc_rfc1001_len(pSMB, (__u16)name_len);
  3539. pSMB->ByteCount = cpu_to_le16(name_len);
  3540. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  3541. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  3542. if (rc) {
  3543. cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
  3544. } else if (data) {
  3545. struct timespec ts;
  3546. __u32 time = le32_to_cpu(pSMBr->last_write_time);
  3547. /* decode response */
  3548. /* BB FIXME - add time zone adjustment BB */
  3549. memset(data, 0, sizeof(FILE_ALL_INFO));
  3550. ts.tv_nsec = 0;
  3551. ts.tv_sec = time;
  3552. /* decode time fields */
  3553. data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
  3554. data->LastWriteTime = data->ChangeTime;
  3555. data->LastAccessTime = 0;
  3556. data->AllocationSize =
  3557. cpu_to_le64(le32_to_cpu(pSMBr->size));
  3558. data->EndOfFile = data->AllocationSize;
  3559. data->Attributes =
  3560. cpu_to_le32(le16_to_cpu(pSMBr->attr));
  3561. } else
  3562. rc = -EIO; /* bad buffer passed in */
  3563. cifs_buf_release(pSMB);
  3564. if (rc == -EAGAIN)
  3565. goto QInfRetry;
  3566. return rc;
  3567. }
  3568. int
  3569. CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
  3570. u16 netfid, FILE_ALL_INFO *pFindData)
  3571. {
  3572. struct smb_t2_qfi_req *pSMB = NULL;
  3573. struct smb_t2_qfi_rsp *pSMBr = NULL;
  3574. int rc = 0;
  3575. int bytes_returned;
  3576. __u16 params, byte_count;
  3577. QFileInfoRetry:
  3578. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  3579. (void **) &pSMBr);
  3580. if (rc)
  3581. return rc;
  3582. params = 2 /* level */ + 2 /* fid */;
  3583. pSMB->t2.TotalDataCount = 0;
  3584. pSMB->t2.MaxParameterCount = cpu_to_le16(4);
  3585. /* BB find exact max data count below from sess structure BB */
  3586. pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
  3587. pSMB->t2.MaxSetupCount = 0;
  3588. pSMB->t2.Reserved = 0;
  3589. pSMB->t2.Flags = 0;
  3590. pSMB->t2.Timeout = 0;
  3591. pSMB->t2.Reserved2 = 0;
  3592. pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
  3593. Fid) - 4);
  3594. pSMB->t2.DataCount = 0;
  3595. pSMB->t2.DataOffset = 0;
  3596. pSMB->t2.SetupCount = 1;
  3597. pSMB->t2.Reserved3 = 0;
  3598. pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
  3599. byte_count = params + 1 /* pad */ ;
  3600. pSMB->t2.TotalParameterCount = cpu_to_le16(params);
  3601. pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
  3602. pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
  3603. pSMB->Pad = 0;
  3604. pSMB->Fid = netfid;
  3605. inc_rfc1001_len(pSMB, byte_count);
  3606. pSMB->t2.ByteCount = cpu_to_le16(byte_count);
  3607. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  3608. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  3609. if (rc) {
  3610. cifs_dbg(FYI, "Send error in QFileInfo = %d", rc);
  3611. } else { /* decode response */
  3612. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  3613. if (rc) /* BB add auto retry on EOPNOTSUPP? */
  3614. rc = -EIO;
  3615. else if (get_bcc(&pSMBr->hdr) < 40)
  3616. rc = -EIO; /* bad smb */
  3617. else if (pFindData) {
  3618. __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
  3619. memcpy((char *) pFindData,
  3620. (char *) &pSMBr->hdr.Protocol +
  3621. data_offset, sizeof(FILE_ALL_INFO));
  3622. } else
  3623. rc = -ENOMEM;
  3624. }
  3625. cifs_buf_release(pSMB);
  3626. if (rc == -EAGAIN)
  3627. goto QFileInfoRetry;
  3628. return rc;
  3629. }
  3630. int
  3631. CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
  3632. const char *search_name, FILE_ALL_INFO *data,
  3633. int legacy /* old style infolevel */,
  3634. const struct nls_table *nls_codepage, int remap)
  3635. {
  3636. /* level 263 SMB_QUERY_FILE_ALL_INFO */
  3637. TRANSACTION2_QPI_REQ *pSMB = NULL;
  3638. TRANSACTION2_QPI_RSP *pSMBr = NULL;
  3639. int rc = 0;
  3640. int bytes_returned;
  3641. int name_len;
  3642. __u16 params, byte_count;
  3643. /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */
  3644. QPathInfoRetry:
  3645. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  3646. (void **) &pSMBr);
  3647. if (rc)
  3648. return rc;
  3649. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  3650. name_len =
  3651. cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
  3652. PATH_MAX, nls_codepage, remap);
  3653. name_len++; /* trailing null */
  3654. name_len *= 2;
  3655. } else { /* BB improve the check for buffer overruns BB */
  3656. name_len = strnlen(search_name, PATH_MAX);
  3657. name_len++; /* trailing null */
  3658. strncpy(pSMB->FileName, search_name, name_len);
  3659. }
  3660. params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
  3661. pSMB->TotalDataCount = 0;
  3662. pSMB->MaxParameterCount = cpu_to_le16(2);
  3663. /* BB find exact max SMB PDU from sess structure BB */
  3664. pSMB->MaxDataCount = cpu_to_le16(4000);
  3665. pSMB->MaxSetupCount = 0;
  3666. pSMB->Reserved = 0;
  3667. pSMB->Flags = 0;
  3668. pSMB->Timeout = 0;
  3669. pSMB->Reserved2 = 0;
  3670. pSMB->ParameterOffset = cpu_to_le16(offsetof(
  3671. struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
  3672. pSMB->DataCount = 0;
  3673. pSMB->DataOffset = 0;
  3674. pSMB->SetupCount = 1;
  3675. pSMB->Reserved3 = 0;
  3676. pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
  3677. byte_count = params + 1 /* pad */ ;
  3678. pSMB->TotalParameterCount = cpu_to_le16(params);
  3679. pSMB->ParameterCount = pSMB->TotalParameterCount;
  3680. if (legacy)
  3681. pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
  3682. else
  3683. pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
  3684. pSMB->Reserved4 = 0;
  3685. inc_rfc1001_len(pSMB, byte_count);
  3686. pSMB->ByteCount = cpu_to_le16(byte_count);
  3687. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  3688. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  3689. if (rc) {
  3690. cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
  3691. } else { /* decode response */
  3692. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  3693. if (rc) /* BB add auto retry on EOPNOTSUPP? */
  3694. rc = -EIO;
  3695. else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
  3696. rc = -EIO; /* bad smb */
  3697. else if (legacy && get_bcc(&pSMBr->hdr) < 24)
  3698. rc = -EIO; /* 24 or 26 expected but we do not read
  3699. last field */
  3700. else if (data) {
  3701. int size;
  3702. __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
  3703. /*
  3704. * On legacy responses we do not read the last field,
  3705. * EAsize, fortunately since it varies by subdialect and
  3706. * also note it differs on Set vs Get, ie two bytes or 4
  3707. * bytes depending but we don't care here.
  3708. */
  3709. if (legacy)
  3710. size = sizeof(FILE_INFO_STANDARD);
  3711. else
  3712. size = sizeof(FILE_ALL_INFO);
  3713. memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
  3714. data_offset, size);
  3715. } else
  3716. rc = -ENOMEM;
  3717. }
  3718. cifs_buf_release(pSMB);
  3719. if (rc == -EAGAIN)
  3720. goto QPathInfoRetry;
  3721. return rc;
  3722. }
  3723. int
  3724. CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
  3725. u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
  3726. {
  3727. struct smb_t2_qfi_req *pSMB = NULL;
  3728. struct smb_t2_qfi_rsp *pSMBr = NULL;
  3729. int rc = 0;
  3730. int bytes_returned;
  3731. __u16 params, byte_count;
  3732. UnixQFileInfoRetry:
  3733. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  3734. (void **) &pSMBr);
  3735. if (rc)
  3736. return rc;
  3737. params = 2 /* level */ + 2 /* fid */;
  3738. pSMB->t2.TotalDataCount = 0;
  3739. pSMB->t2.MaxParameterCount = cpu_to_le16(4);
  3740. /* BB find exact max data count below from sess structure BB */
  3741. pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
  3742. pSMB->t2.MaxSetupCount = 0;
  3743. pSMB->t2.Reserved = 0;
  3744. pSMB->t2.Flags = 0;
  3745. pSMB->t2.Timeout = 0;
  3746. pSMB->t2.Reserved2 = 0;
  3747. pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
  3748. Fid) - 4);
  3749. pSMB->t2.DataCount = 0;
  3750. pSMB->t2.DataOffset = 0;
  3751. pSMB->t2.SetupCount = 1;
  3752. pSMB->t2.Reserved3 = 0;
  3753. pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
  3754. byte_count = params + 1 /* pad */ ;
  3755. pSMB->t2.TotalParameterCount = cpu_to_le16(params);
  3756. pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
  3757. pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
  3758. pSMB->Pad = 0;
  3759. pSMB->Fid = netfid;
  3760. inc_rfc1001_len(pSMB, byte_count);
  3761. pSMB->t2.ByteCount = cpu_to_le16(byte_count);
  3762. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  3763. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  3764. if (rc) {
  3765. cifs_dbg(FYI, "Send error in UnixQFileInfo = %d", rc);
  3766. } else { /* decode response */
  3767. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  3768. if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
  3769. cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
  3770. rc = -EIO; /* bad smb */
  3771. } else {
  3772. __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
  3773. memcpy((char *) pFindData,
  3774. (char *) &pSMBr->hdr.Protocol +
  3775. data_offset,
  3776. sizeof(FILE_UNIX_BASIC_INFO));
  3777. }
  3778. }
  3779. cifs_buf_release(pSMB);
  3780. if (rc == -EAGAIN)
  3781. goto UnixQFileInfoRetry;
  3782. return rc;
  3783. }
  3784. int
  3785. CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
  3786. const unsigned char *searchName,
  3787. FILE_UNIX_BASIC_INFO *pFindData,
  3788. const struct nls_table *nls_codepage, int remap)
  3789. {
  3790. /* SMB_QUERY_FILE_UNIX_BASIC */
  3791. TRANSACTION2_QPI_REQ *pSMB = NULL;
  3792. TRANSACTION2_QPI_RSP *pSMBr = NULL;
  3793. int rc = 0;
  3794. int bytes_returned = 0;
  3795. int name_len;
  3796. __u16 params, byte_count;
  3797. cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName);
  3798. UnixQPathInfoRetry:
  3799. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  3800. (void **) &pSMBr);
  3801. if (rc)
  3802. return rc;
  3803. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  3804. name_len =
  3805. cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
  3806. PATH_MAX, nls_codepage, remap);
  3807. name_len++; /* trailing null */
  3808. name_len *= 2;
  3809. } else { /* BB improve the check for buffer overruns BB */
  3810. name_len = strnlen(searchName, PATH_MAX);
  3811. name_len++; /* trailing null */
  3812. strncpy(pSMB->FileName, searchName, name_len);
  3813. }
  3814. params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
  3815. pSMB->TotalDataCount = 0;
  3816. pSMB->MaxParameterCount = cpu_to_le16(2);
  3817. /* BB find exact max SMB PDU from sess structure BB */
  3818. pSMB->MaxDataCount = cpu_to_le16(4000);
  3819. pSMB->MaxSetupCount = 0;
  3820. pSMB->Reserved = 0;
  3821. pSMB->Flags = 0;
  3822. pSMB->Timeout = 0;
  3823. pSMB->Reserved2 = 0;
  3824. pSMB->ParameterOffset = cpu_to_le16(offsetof(
  3825. struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
  3826. pSMB->DataCount = 0;
  3827. pSMB->DataOffset = 0;
  3828. pSMB->SetupCount = 1;
  3829. pSMB->Reserved3 = 0;
  3830. pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
  3831. byte_count = params + 1 /* pad */ ;
  3832. pSMB->TotalParameterCount = cpu_to_le16(params);
  3833. pSMB->ParameterCount = pSMB->TotalParameterCount;
  3834. pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
  3835. pSMB->Reserved4 = 0;
  3836. inc_rfc1001_len(pSMB, byte_count);
  3837. pSMB->ByteCount = cpu_to_le16(byte_count);
  3838. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  3839. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  3840. if (rc) {
  3841. cifs_dbg(FYI, "Send error in UnixQPathInfo = %d", rc);
  3842. } else { /* decode response */
  3843. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  3844. if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
  3845. cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
  3846. rc = -EIO; /* bad smb */
  3847. } else {
  3848. __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
  3849. memcpy((char *) pFindData,
  3850. (char *) &pSMBr->hdr.Protocol +
  3851. data_offset,
  3852. sizeof(FILE_UNIX_BASIC_INFO));
  3853. }
  3854. }
  3855. cifs_buf_release(pSMB);
  3856. if (rc == -EAGAIN)
  3857. goto UnixQPathInfoRetry;
  3858. return rc;
  3859. }
  3860. /* xid, tcon, searchName and codepage are input parms, rest are returned */
  3861. int
  3862. CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
  3863. const char *searchName, struct cifs_sb_info *cifs_sb,
  3864. __u16 *pnetfid, __u16 search_flags,
  3865. struct cifs_search_info *psrch_inf, bool msearch)
  3866. {
  3867. /* level 257 SMB_ */
  3868. TRANSACTION2_FFIRST_REQ *pSMB = NULL;
  3869. TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
  3870. T2_FFIRST_RSP_PARMS *parms;
  3871. int rc = 0;
  3872. int bytes_returned = 0;
  3873. int name_len, remap;
  3874. __u16 params, byte_count;
  3875. struct nls_table *nls_codepage;
  3876. cifs_dbg(FYI, "In FindFirst for %s\n", searchName);
  3877. findFirstRetry:
  3878. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  3879. (void **) &pSMBr);
  3880. if (rc)
  3881. return rc;
  3882. nls_codepage = cifs_sb->local_nls;
  3883. remap = cifs_remap(cifs_sb);
  3884. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  3885. name_len =
  3886. cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
  3887. PATH_MAX, nls_codepage, remap);
  3888. /* We can not add the asterik earlier in case
  3889. it got remapped to 0xF03A as if it were part of the
  3890. directory name instead of a wildcard */
  3891. name_len *= 2;
  3892. if (msearch) {
  3893. pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
  3894. pSMB->FileName[name_len+1] = 0;
  3895. pSMB->FileName[name_len+2] = '*';
  3896. pSMB->FileName[name_len+3] = 0;
  3897. name_len += 4; /* now the trailing null */
  3898. /* null terminate just in case */
  3899. pSMB->FileName[name_len] = 0;
  3900. pSMB->FileName[name_len+1] = 0;
  3901. name_len += 2;
  3902. }
  3903. } else { /* BB add check for overrun of SMB buf BB */
  3904. name_len = strnlen(searchName, PATH_MAX);
  3905. /* BB fix here and in unicode clause above ie
  3906. if (name_len > buffersize-header)
  3907. free buffer exit; BB */
  3908. strncpy(pSMB->FileName, searchName, name_len);
  3909. if (msearch) {
  3910. pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
  3911. pSMB->FileName[name_len+1] = '*';
  3912. pSMB->FileName[name_len+2] = 0;
  3913. name_len += 3;
  3914. }
  3915. }
  3916. params = 12 + name_len /* includes null */ ;
  3917. pSMB->TotalDataCount = 0; /* no EAs */
  3918. pSMB->MaxParameterCount = cpu_to_le16(10);
  3919. pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
  3920. pSMB->MaxSetupCount = 0;
  3921. pSMB->Reserved = 0;
  3922. pSMB->Flags = 0;
  3923. pSMB->Timeout = 0;
  3924. pSMB->Reserved2 = 0;
  3925. byte_count = params + 1 /* pad */ ;
  3926. pSMB->TotalParameterCount = cpu_to_le16(params);
  3927. pSMB->ParameterCount = pSMB->TotalParameterCount;
  3928. pSMB->ParameterOffset = cpu_to_le16(
  3929. offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
  3930. - 4);
  3931. pSMB->DataCount = 0;
  3932. pSMB->DataOffset = 0;
  3933. pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
  3934. pSMB->Reserved3 = 0;
  3935. pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
  3936. pSMB->SearchAttributes =
  3937. cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
  3938. ATTR_DIRECTORY);
  3939. pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
  3940. pSMB->SearchFlags = cpu_to_le16(search_flags);
  3941. pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
  3942. /* BB what should we set StorageType to? Does it matter? BB */
  3943. pSMB->SearchStorageType = 0;
  3944. inc_rfc1001_len(pSMB, byte_count);
  3945. pSMB->ByteCount = cpu_to_le16(byte_count);
  3946. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  3947. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  3948. cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
  3949. if (rc) {/* BB add logic to retry regular search if Unix search
  3950. rejected unexpectedly by server */
  3951. /* BB Add code to handle unsupported level rc */
  3952. cifs_dbg(FYI, "Error in FindFirst = %d\n", rc);
  3953. cifs_buf_release(pSMB);
  3954. /* BB eventually could optimize out free and realloc of buf */
  3955. /* for this case */
  3956. if (rc == -EAGAIN)
  3957. goto findFirstRetry;
  3958. } else { /* decode response */
  3959. /* BB remember to free buffer if error BB */
  3960. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  3961. if (rc == 0) {
  3962. unsigned int lnoff;
  3963. if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
  3964. psrch_inf->unicode = true;
  3965. else
  3966. psrch_inf->unicode = false;
  3967. psrch_inf->ntwrk_buf_start = (char *)pSMBr;
  3968. psrch_inf->smallBuf = 0;
  3969. psrch_inf->srch_entries_start =
  3970. (char *) &pSMBr->hdr.Protocol +
  3971. le16_to_cpu(pSMBr->t2.DataOffset);
  3972. parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
  3973. le16_to_cpu(pSMBr->t2.ParameterOffset));
  3974. if (parms->EndofSearch)
  3975. psrch_inf->endOfSearch = true;
  3976. else
  3977. psrch_inf->endOfSearch = false;
  3978. psrch_inf->entries_in_buffer =
  3979. le16_to_cpu(parms->SearchCount);
  3980. psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
  3981. psrch_inf->entries_in_buffer;
  3982. lnoff = le16_to_cpu(parms->LastNameOffset);
  3983. if (CIFSMaxBufSize < lnoff) {
  3984. cifs_dbg(VFS, "ignoring corrupt resume name\n");
  3985. psrch_inf->last_entry = NULL;
  3986. return rc;
  3987. }
  3988. psrch_inf->last_entry = psrch_inf->srch_entries_start +
  3989. lnoff;
  3990. if (pnetfid)
  3991. *pnetfid = parms->SearchHandle;
  3992. } else {
  3993. cifs_buf_release(pSMB);
  3994. }
  3995. }
  3996. return rc;
  3997. }
  3998. int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
  3999. __u16 searchHandle, __u16 search_flags,
  4000. struct cifs_search_info *psrch_inf)
  4001. {
  4002. TRANSACTION2_FNEXT_REQ *pSMB = NULL;
  4003. TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
  4004. T2_FNEXT_RSP_PARMS *parms;
  4005. char *response_data;
  4006. int rc = 0;
  4007. int bytes_returned;
  4008. unsigned int name_len;
  4009. __u16 params, byte_count;
  4010. cifs_dbg(FYI, "In FindNext\n");
  4011. if (psrch_inf->endOfSearch)
  4012. return -ENOENT;
  4013. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  4014. (void **) &pSMBr);
  4015. if (rc)
  4016. return rc;
  4017. params = 14; /* includes 2 bytes of null string, converted to LE below*/
  4018. byte_count = 0;
  4019. pSMB->TotalDataCount = 0; /* no EAs */
  4020. pSMB->MaxParameterCount = cpu_to_le16(8);
  4021. pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
  4022. pSMB->MaxSetupCount = 0;
  4023. pSMB->Reserved = 0;
  4024. pSMB->Flags = 0;
  4025. pSMB->Timeout = 0;
  4026. pSMB->Reserved2 = 0;
  4027. pSMB->ParameterOffset = cpu_to_le16(
  4028. offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
  4029. pSMB->DataCount = 0;
  4030. pSMB->DataOffset = 0;
  4031. pSMB->SetupCount = 1;
  4032. pSMB->Reserved3 = 0;
  4033. pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
  4034. pSMB->SearchHandle = searchHandle; /* always kept as le */
  4035. pSMB->SearchCount =
  4036. cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
  4037. pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
  4038. pSMB->ResumeKey = psrch_inf->resume_key;
  4039. pSMB->SearchFlags = cpu_to_le16(search_flags);
  4040. name_len = psrch_inf->resume_name_len;
  4041. params += name_len;
  4042. if (name_len < PATH_MAX) {
  4043. memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
  4044. byte_count += name_len;
  4045. /* 14 byte parm len above enough for 2 byte null terminator */
  4046. pSMB->ResumeFileName[name_len] = 0;
  4047. pSMB->ResumeFileName[name_len+1] = 0;
  4048. } else {
  4049. rc = -EINVAL;
  4050. goto FNext2_err_exit;
  4051. }
  4052. byte_count = params + 1 /* pad */ ;
  4053. pSMB->TotalParameterCount = cpu_to_le16(params);
  4054. pSMB->ParameterCount = pSMB->TotalParameterCount;
  4055. inc_rfc1001_len(pSMB, byte_count);
  4056. pSMB->ByteCount = cpu_to_le16(byte_count);
  4057. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  4058. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  4059. cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
  4060. if (rc) {
  4061. if (rc == -EBADF) {
  4062. psrch_inf->endOfSearch = true;
  4063. cifs_buf_release(pSMB);
  4064. rc = 0; /* search probably was closed at end of search*/
  4065. } else
  4066. cifs_dbg(FYI, "FindNext returned = %d\n", rc);
  4067. } else { /* decode response */
  4068. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  4069. if (rc == 0) {
  4070. unsigned int lnoff;
  4071. /* BB fixme add lock for file (srch_info) struct here */
  4072. if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
  4073. psrch_inf->unicode = true;
  4074. else
  4075. psrch_inf->unicode = false;
  4076. response_data = (char *) &pSMBr->hdr.Protocol +
  4077. le16_to_cpu(pSMBr->t2.ParameterOffset);
  4078. parms = (T2_FNEXT_RSP_PARMS *)response_data;
  4079. response_data = (char *)&pSMBr->hdr.Protocol +
  4080. le16_to_cpu(pSMBr->t2.DataOffset);
  4081. if (psrch_inf->smallBuf)
  4082. cifs_small_buf_release(
  4083. psrch_inf->ntwrk_buf_start);
  4084. else
  4085. cifs_buf_release(psrch_inf->ntwrk_buf_start);
  4086. psrch_inf->srch_entries_start = response_data;
  4087. psrch_inf->ntwrk_buf_start = (char *)pSMB;
  4088. psrch_inf->smallBuf = 0;
  4089. if (parms->EndofSearch)
  4090. psrch_inf->endOfSearch = true;
  4091. else
  4092. psrch_inf->endOfSearch = false;
  4093. psrch_inf->entries_in_buffer =
  4094. le16_to_cpu(parms->SearchCount);
  4095. psrch_inf->index_of_last_entry +=
  4096. psrch_inf->entries_in_buffer;
  4097. lnoff = le16_to_cpu(parms->LastNameOffset);
  4098. if (CIFSMaxBufSize < lnoff) {
  4099. cifs_dbg(VFS, "ignoring corrupt resume name\n");
  4100. psrch_inf->last_entry = NULL;
  4101. return rc;
  4102. } else
  4103. psrch_inf->last_entry =
  4104. psrch_inf->srch_entries_start + lnoff;
  4105. /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
  4106. psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
  4107. /* BB fixme add unlock here */
  4108. }
  4109. }
  4110. /* BB On error, should we leave previous search buf (and count and
  4111. last entry fields) intact or free the previous one? */
  4112. /* Note: On -EAGAIN error only caller can retry on handle based calls
  4113. since file handle passed in no longer valid */
  4114. FNext2_err_exit:
  4115. if (rc != 0)
  4116. cifs_buf_release(pSMB);
  4117. return rc;
  4118. }
  4119. int
  4120. CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
  4121. const __u16 searchHandle)
  4122. {
  4123. int rc = 0;
  4124. FINDCLOSE_REQ *pSMB = NULL;
  4125. cifs_dbg(FYI, "In CIFSSMBFindClose\n");
  4126. rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
  4127. /* no sense returning error if session restarted
  4128. as file handle has been closed */
  4129. if (rc == -EAGAIN)
  4130. return 0;
  4131. if (rc)
  4132. return rc;
  4133. pSMB->FileID = searchHandle;
  4134. pSMB->ByteCount = 0;
  4135. rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
  4136. if (rc)
  4137. cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
  4138. cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
  4139. /* Since session is dead, search handle closed on server already */
  4140. if (rc == -EAGAIN)
  4141. rc = 0;
  4142. return rc;
  4143. }
  4144. int
  4145. CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
  4146. const char *search_name, __u64 *inode_number,
  4147. const struct nls_table *nls_codepage, int remap)
  4148. {
  4149. int rc = 0;
  4150. TRANSACTION2_QPI_REQ *pSMB = NULL;
  4151. TRANSACTION2_QPI_RSP *pSMBr = NULL;
  4152. int name_len, bytes_returned;
  4153. __u16 params, byte_count;
  4154. cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name);
  4155. if (tcon == NULL)
  4156. return -ENODEV;
  4157. GetInodeNumberRetry:
  4158. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  4159. (void **) &pSMBr);
  4160. if (rc)
  4161. return rc;
  4162. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  4163. name_len =
  4164. cifsConvertToUTF16((__le16 *) pSMB->FileName,
  4165. search_name, PATH_MAX, nls_codepage,
  4166. remap);
  4167. name_len++; /* trailing null */
  4168. name_len *= 2;
  4169. } else { /* BB improve the check for buffer overruns BB */
  4170. name_len = strnlen(search_name, PATH_MAX);
  4171. name_len++; /* trailing null */
  4172. strncpy(pSMB->FileName, search_name, name_len);
  4173. }
  4174. params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
  4175. pSMB->TotalDataCount = 0;
  4176. pSMB->MaxParameterCount = cpu_to_le16(2);
  4177. /* BB find exact max data count below from sess structure BB */
  4178. pSMB->MaxDataCount = cpu_to_le16(4000);
  4179. pSMB->MaxSetupCount = 0;
  4180. pSMB->Reserved = 0;
  4181. pSMB->Flags = 0;
  4182. pSMB->Timeout = 0;
  4183. pSMB->Reserved2 = 0;
  4184. pSMB->ParameterOffset = cpu_to_le16(offsetof(
  4185. struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
  4186. pSMB->DataCount = 0;
  4187. pSMB->DataOffset = 0;
  4188. pSMB->SetupCount = 1;
  4189. pSMB->Reserved3 = 0;
  4190. pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
  4191. byte_count = params + 1 /* pad */ ;
  4192. pSMB->TotalParameterCount = cpu_to_le16(params);
  4193. pSMB->ParameterCount = pSMB->TotalParameterCount;
  4194. pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
  4195. pSMB->Reserved4 = 0;
  4196. inc_rfc1001_len(pSMB, byte_count);
  4197. pSMB->ByteCount = cpu_to_le16(byte_count);
  4198. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  4199. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  4200. if (rc) {
  4201. cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
  4202. } else {
  4203. /* decode response */
  4204. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  4205. /* BB also check enough total bytes returned */
  4206. if (rc || get_bcc(&pSMBr->hdr) < 2)
  4207. /* If rc should we check for EOPNOSUPP and
  4208. disable the srvino flag? or in caller? */
  4209. rc = -EIO; /* bad smb */
  4210. else {
  4211. __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
  4212. __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
  4213. struct file_internal_info *pfinfo;
  4214. /* BB Do we need a cast or hash here ? */
  4215. if (count < 8) {
  4216. cifs_dbg(FYI, "Illegal size ret in QryIntrnlInf\n");
  4217. rc = -EIO;
  4218. goto GetInodeNumOut;
  4219. }
  4220. pfinfo = (struct file_internal_info *)
  4221. (data_offset + (char *) &pSMBr->hdr.Protocol);
  4222. *inode_number = le64_to_cpu(pfinfo->UniqueId);
  4223. }
  4224. }
  4225. GetInodeNumOut:
  4226. cifs_buf_release(pSMB);
  4227. if (rc == -EAGAIN)
  4228. goto GetInodeNumberRetry;
  4229. return rc;
  4230. }
  4231. /* parses DFS refferal V3 structure
  4232. * caller is responsible for freeing target_nodes
  4233. * returns:
  4234. * on success - 0
  4235. * on failure - errno
  4236. */
  4237. static int
  4238. parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
  4239. unsigned int *num_of_nodes,
  4240. struct dfs_info3_param **target_nodes,
  4241. const struct nls_table *nls_codepage, int remap,
  4242. const char *searchName)
  4243. {
  4244. int i, rc = 0;
  4245. char *data_end;
  4246. bool is_unicode;
  4247. struct dfs_referral_level_3 *ref;
  4248. if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
  4249. is_unicode = true;
  4250. else
  4251. is_unicode = false;
  4252. *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
  4253. if (*num_of_nodes < 1) {
  4254. cifs_dbg(VFS, "num_referrals: must be at least > 0, but we get num_referrals = %d\n",
  4255. *num_of_nodes);
  4256. rc = -EINVAL;
  4257. goto parse_DFS_referrals_exit;
  4258. }
  4259. ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
  4260. if (ref->VersionNumber != cpu_to_le16(3)) {
  4261. cifs_dbg(VFS, "Referrals of V%d version are not supported, should be V3\n",
  4262. le16_to_cpu(ref->VersionNumber));
  4263. rc = -EINVAL;
  4264. goto parse_DFS_referrals_exit;
  4265. }
  4266. /* get the upper boundary of the resp buffer */
  4267. data_end = (char *)(&(pSMBr->PathConsumed)) +
  4268. le16_to_cpu(pSMBr->t2.DataCount);
  4269. cifs_dbg(FYI, "num_referrals: %d dfs flags: 0x%x ...\n",
  4270. *num_of_nodes, le32_to_cpu(pSMBr->DFSFlags));
  4271. *target_nodes = kcalloc(*num_of_nodes, sizeof(struct dfs_info3_param),
  4272. GFP_KERNEL);
  4273. if (*target_nodes == NULL) {
  4274. rc = -ENOMEM;
  4275. goto parse_DFS_referrals_exit;
  4276. }
  4277. /* collect necessary data from referrals */
  4278. for (i = 0; i < *num_of_nodes; i++) {
  4279. char *temp;
  4280. int max_len;
  4281. struct dfs_info3_param *node = (*target_nodes)+i;
  4282. node->flags = le32_to_cpu(pSMBr->DFSFlags);
  4283. if (is_unicode) {
  4284. __le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
  4285. GFP_KERNEL);
  4286. if (tmp == NULL) {
  4287. rc = -ENOMEM;
  4288. goto parse_DFS_referrals_exit;
  4289. }
  4290. cifsConvertToUTF16((__le16 *) tmp, searchName,
  4291. PATH_MAX, nls_codepage, remap);
  4292. node->path_consumed = cifs_utf16_bytes(tmp,
  4293. le16_to_cpu(pSMBr->PathConsumed),
  4294. nls_codepage);
  4295. kfree(tmp);
  4296. } else
  4297. node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
  4298. node->server_type = le16_to_cpu(ref->ServerType);
  4299. node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
  4300. /* copy DfsPath */
  4301. temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
  4302. max_len = data_end - temp;
  4303. node->path_name = cifs_strndup_from_utf16(temp, max_len,
  4304. is_unicode, nls_codepage);
  4305. if (!node->path_name) {
  4306. rc = -ENOMEM;
  4307. goto parse_DFS_referrals_exit;
  4308. }
  4309. /* copy link target UNC */
  4310. temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
  4311. max_len = data_end - temp;
  4312. node->node_name = cifs_strndup_from_utf16(temp, max_len,
  4313. is_unicode, nls_codepage);
  4314. if (!node->node_name) {
  4315. rc = -ENOMEM;
  4316. goto parse_DFS_referrals_exit;
  4317. }
  4318. ref++;
  4319. }
  4320. parse_DFS_referrals_exit:
  4321. if (rc) {
  4322. free_dfs_info_array(*target_nodes, *num_of_nodes);
  4323. *target_nodes = NULL;
  4324. *num_of_nodes = 0;
  4325. }
  4326. return rc;
  4327. }
  4328. int
  4329. CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
  4330. const char *search_name, struct dfs_info3_param **target_nodes,
  4331. unsigned int *num_of_nodes,
  4332. const struct nls_table *nls_codepage, int remap)
  4333. {
  4334. /* TRANS2_GET_DFS_REFERRAL */
  4335. TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
  4336. TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
  4337. int rc = 0;
  4338. int bytes_returned;
  4339. int name_len;
  4340. __u16 params, byte_count;
  4341. *num_of_nodes = 0;
  4342. *target_nodes = NULL;
  4343. cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name);
  4344. if (ses == NULL)
  4345. return -ENODEV;
  4346. getDFSRetry:
  4347. rc = smb_init(SMB_COM_TRANSACTION2, 15, NULL, (void **) &pSMB,
  4348. (void **) &pSMBr);
  4349. if (rc)
  4350. return rc;
  4351. /* server pointer checked in called function,
  4352. but should never be null here anyway */
  4353. pSMB->hdr.Mid = get_next_mid(ses->server);
  4354. pSMB->hdr.Tid = ses->ipc_tid;
  4355. pSMB->hdr.Uid = ses->Suid;
  4356. if (ses->capabilities & CAP_STATUS32)
  4357. pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
  4358. if (ses->capabilities & CAP_DFS)
  4359. pSMB->hdr.Flags2 |= SMBFLG2_DFS;
  4360. if (ses->capabilities & CAP_UNICODE) {
  4361. pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
  4362. name_len =
  4363. cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
  4364. search_name, PATH_MAX, nls_codepage,
  4365. remap);
  4366. name_len++; /* trailing null */
  4367. name_len *= 2;
  4368. } else { /* BB improve the check for buffer overruns BB */
  4369. name_len = strnlen(search_name, PATH_MAX);
  4370. name_len++; /* trailing null */
  4371. strncpy(pSMB->RequestFileName, search_name, name_len);
  4372. }
  4373. if (ses->server->sign)
  4374. pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
  4375. pSMB->hdr.Uid = ses->Suid;
  4376. params = 2 /* level */ + name_len /*includes null */ ;
  4377. pSMB->TotalDataCount = 0;
  4378. pSMB->DataCount = 0;
  4379. pSMB->DataOffset = 0;
  4380. pSMB->MaxParameterCount = 0;
  4381. /* BB find exact max SMB PDU from sess structure BB */
  4382. pSMB->MaxDataCount = cpu_to_le16(4000);
  4383. pSMB->MaxSetupCount = 0;
  4384. pSMB->Reserved = 0;
  4385. pSMB->Flags = 0;
  4386. pSMB->Timeout = 0;
  4387. pSMB->Reserved2 = 0;
  4388. pSMB->ParameterOffset = cpu_to_le16(offsetof(
  4389. struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
  4390. pSMB->SetupCount = 1;
  4391. pSMB->Reserved3 = 0;
  4392. pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
  4393. byte_count = params + 3 /* pad */ ;
  4394. pSMB->ParameterCount = cpu_to_le16(params);
  4395. pSMB->TotalParameterCount = pSMB->ParameterCount;
  4396. pSMB->MaxReferralLevel = cpu_to_le16(3);
  4397. inc_rfc1001_len(pSMB, byte_count);
  4398. pSMB->ByteCount = cpu_to_le16(byte_count);
  4399. rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
  4400. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  4401. if (rc) {
  4402. cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
  4403. goto GetDFSRefExit;
  4404. }
  4405. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  4406. /* BB Also check if enough total bytes returned? */
  4407. if (rc || get_bcc(&pSMBr->hdr) < 17) {
  4408. rc = -EIO; /* bad smb */
  4409. goto GetDFSRefExit;
  4410. }
  4411. cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n",
  4412. get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset));
  4413. /* parse returned result into more usable form */
  4414. rc = parse_DFS_referrals(pSMBr, num_of_nodes,
  4415. target_nodes, nls_codepage, remap,
  4416. search_name);
  4417. GetDFSRefExit:
  4418. cifs_buf_release(pSMB);
  4419. if (rc == -EAGAIN)
  4420. goto getDFSRetry;
  4421. return rc;
  4422. }
  4423. /* Query File System Info such as free space to old servers such as Win 9x */
  4424. int
  4425. SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
  4426. struct kstatfs *FSData)
  4427. {
  4428. /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
  4429. TRANSACTION2_QFSI_REQ *pSMB = NULL;
  4430. TRANSACTION2_QFSI_RSP *pSMBr = NULL;
  4431. FILE_SYSTEM_ALLOC_INFO *response_data;
  4432. int rc = 0;
  4433. int bytes_returned = 0;
  4434. __u16 params, byte_count;
  4435. cifs_dbg(FYI, "OldQFSInfo\n");
  4436. oldQFSInfoRetry:
  4437. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  4438. (void **) &pSMBr);
  4439. if (rc)
  4440. return rc;
  4441. params = 2; /* level */
  4442. pSMB->TotalDataCount = 0;
  4443. pSMB->MaxParameterCount = cpu_to_le16(2);
  4444. pSMB->MaxDataCount = cpu_to_le16(1000);
  4445. pSMB->MaxSetupCount = 0;
  4446. pSMB->Reserved = 0;
  4447. pSMB->Flags = 0;
  4448. pSMB->Timeout = 0;
  4449. pSMB->Reserved2 = 0;
  4450. byte_count = params + 1 /* pad */ ;
  4451. pSMB->TotalParameterCount = cpu_to_le16(params);
  4452. pSMB->ParameterCount = pSMB->TotalParameterCount;
  4453. pSMB->ParameterOffset = cpu_to_le16(offsetof(
  4454. struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
  4455. pSMB->DataCount = 0;
  4456. pSMB->DataOffset = 0;
  4457. pSMB->SetupCount = 1;
  4458. pSMB->Reserved3 = 0;
  4459. pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
  4460. pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
  4461. inc_rfc1001_len(pSMB, byte_count);
  4462. pSMB->ByteCount = cpu_to_le16(byte_count);
  4463. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  4464. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  4465. if (rc) {
  4466. cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
  4467. } else { /* decode response */
  4468. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  4469. if (rc || get_bcc(&pSMBr->hdr) < 18)
  4470. rc = -EIO; /* bad smb */
  4471. else {
  4472. __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
  4473. cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n",
  4474. get_bcc(&pSMBr->hdr), data_offset);
  4475. response_data = (FILE_SYSTEM_ALLOC_INFO *)
  4476. (((char *) &pSMBr->hdr.Protocol) + data_offset);
  4477. FSData->f_bsize =
  4478. le16_to_cpu(response_data->BytesPerSector) *
  4479. le32_to_cpu(response_data->
  4480. SectorsPerAllocationUnit);
  4481. FSData->f_blocks =
  4482. le32_to_cpu(response_data->TotalAllocationUnits);
  4483. FSData->f_bfree = FSData->f_bavail =
  4484. le32_to_cpu(response_data->FreeAllocationUnits);
  4485. cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
  4486. (unsigned long long)FSData->f_blocks,
  4487. (unsigned long long)FSData->f_bfree,
  4488. FSData->f_bsize);
  4489. }
  4490. }
  4491. cifs_buf_release(pSMB);
  4492. if (rc == -EAGAIN)
  4493. goto oldQFSInfoRetry;
  4494. return rc;
  4495. }
  4496. int
  4497. CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
  4498. struct kstatfs *FSData)
  4499. {
  4500. /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
  4501. TRANSACTION2_QFSI_REQ *pSMB = NULL;
  4502. TRANSACTION2_QFSI_RSP *pSMBr = NULL;
  4503. FILE_SYSTEM_INFO *response_data;
  4504. int rc = 0;
  4505. int bytes_returned = 0;
  4506. __u16 params, byte_count;
  4507. cifs_dbg(FYI, "In QFSInfo\n");
  4508. QFSInfoRetry:
  4509. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  4510. (void **) &pSMBr);
  4511. if (rc)
  4512. return rc;
  4513. params = 2; /* level */
  4514. pSMB->TotalDataCount = 0;
  4515. pSMB->MaxParameterCount = cpu_to_le16(2);
  4516. pSMB->MaxDataCount = cpu_to_le16(1000);
  4517. pSMB->MaxSetupCount = 0;
  4518. pSMB->Reserved = 0;
  4519. pSMB->Flags = 0;
  4520. pSMB->Timeout = 0;
  4521. pSMB->Reserved2 = 0;
  4522. byte_count = params + 1 /* pad */ ;
  4523. pSMB->TotalParameterCount = cpu_to_le16(params);
  4524. pSMB->ParameterCount = pSMB->TotalParameterCount;
  4525. pSMB->ParameterOffset = cpu_to_le16(offsetof(
  4526. struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
  4527. pSMB->DataCount = 0;
  4528. pSMB->DataOffset = 0;
  4529. pSMB->SetupCount = 1;
  4530. pSMB->Reserved3 = 0;
  4531. pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
  4532. pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
  4533. inc_rfc1001_len(pSMB, byte_count);
  4534. pSMB->ByteCount = cpu_to_le16(byte_count);
  4535. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  4536. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  4537. if (rc) {
  4538. cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
  4539. } else { /* decode response */
  4540. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  4541. if (rc || get_bcc(&pSMBr->hdr) < 24)
  4542. rc = -EIO; /* bad smb */
  4543. else {
  4544. __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
  4545. response_data =
  4546. (FILE_SYSTEM_INFO
  4547. *) (((char *) &pSMBr->hdr.Protocol) +
  4548. data_offset);
  4549. FSData->f_bsize =
  4550. le32_to_cpu(response_data->BytesPerSector) *
  4551. le32_to_cpu(response_data->
  4552. SectorsPerAllocationUnit);
  4553. FSData->f_blocks =
  4554. le64_to_cpu(response_data->TotalAllocationUnits);
  4555. FSData->f_bfree = FSData->f_bavail =
  4556. le64_to_cpu(response_data->FreeAllocationUnits);
  4557. cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n",
  4558. (unsigned long long)FSData->f_blocks,
  4559. (unsigned long long)FSData->f_bfree,
  4560. FSData->f_bsize);
  4561. }
  4562. }
  4563. cifs_buf_release(pSMB);
  4564. if (rc == -EAGAIN)
  4565. goto QFSInfoRetry;
  4566. return rc;
  4567. }
  4568. int
  4569. CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
  4570. {
  4571. /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
  4572. TRANSACTION2_QFSI_REQ *pSMB = NULL;
  4573. TRANSACTION2_QFSI_RSP *pSMBr = NULL;
  4574. FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
  4575. int rc = 0;
  4576. int bytes_returned = 0;
  4577. __u16 params, byte_count;
  4578. cifs_dbg(FYI, "In QFSAttributeInfo\n");
  4579. QFSAttributeRetry:
  4580. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  4581. (void **) &pSMBr);
  4582. if (rc)
  4583. return rc;
  4584. params = 2; /* level */
  4585. pSMB->TotalDataCount = 0;
  4586. pSMB->MaxParameterCount = cpu_to_le16(2);
  4587. /* BB find exact max SMB PDU from sess structure BB */
  4588. pSMB->MaxDataCount = cpu_to_le16(1000);
  4589. pSMB->MaxSetupCount = 0;
  4590. pSMB->Reserved = 0;
  4591. pSMB->Flags = 0;
  4592. pSMB->Timeout = 0;
  4593. pSMB->Reserved2 = 0;
  4594. byte_count = params + 1 /* pad */ ;
  4595. pSMB->TotalParameterCount = cpu_to_le16(params);
  4596. pSMB->ParameterCount = pSMB->TotalParameterCount;
  4597. pSMB->ParameterOffset = cpu_to_le16(offsetof(
  4598. struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
  4599. pSMB->DataCount = 0;
  4600. pSMB->DataOffset = 0;
  4601. pSMB->SetupCount = 1;
  4602. pSMB->Reserved3 = 0;
  4603. pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
  4604. pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
  4605. inc_rfc1001_len(pSMB, byte_count);
  4606. pSMB->ByteCount = cpu_to_le16(byte_count);
  4607. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  4608. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  4609. if (rc) {
  4610. cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
  4611. } else { /* decode response */
  4612. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  4613. if (rc || get_bcc(&pSMBr->hdr) < 13) {
  4614. /* BB also check if enough bytes returned */
  4615. rc = -EIO; /* bad smb */
  4616. } else {
  4617. __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
  4618. response_data =
  4619. (FILE_SYSTEM_ATTRIBUTE_INFO
  4620. *) (((char *) &pSMBr->hdr.Protocol) +
  4621. data_offset);
  4622. memcpy(&tcon->fsAttrInfo, response_data,
  4623. sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
  4624. }
  4625. }
  4626. cifs_buf_release(pSMB);
  4627. if (rc == -EAGAIN)
  4628. goto QFSAttributeRetry;
  4629. return rc;
  4630. }
  4631. int
  4632. CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
  4633. {
  4634. /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
  4635. TRANSACTION2_QFSI_REQ *pSMB = NULL;
  4636. TRANSACTION2_QFSI_RSP *pSMBr = NULL;
  4637. FILE_SYSTEM_DEVICE_INFO *response_data;
  4638. int rc = 0;
  4639. int bytes_returned = 0;
  4640. __u16 params, byte_count;
  4641. cifs_dbg(FYI, "In QFSDeviceInfo\n");
  4642. QFSDeviceRetry:
  4643. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  4644. (void **) &pSMBr);
  4645. if (rc)
  4646. return rc;
  4647. params = 2; /* level */
  4648. pSMB->TotalDataCount = 0;
  4649. pSMB->MaxParameterCount = cpu_to_le16(2);
  4650. /* BB find exact max SMB PDU from sess structure BB */
  4651. pSMB->MaxDataCount = cpu_to_le16(1000);
  4652. pSMB->MaxSetupCount = 0;
  4653. pSMB->Reserved = 0;
  4654. pSMB->Flags = 0;
  4655. pSMB->Timeout = 0;
  4656. pSMB->Reserved2 = 0;
  4657. byte_count = params + 1 /* pad */ ;
  4658. pSMB->TotalParameterCount = cpu_to_le16(params);
  4659. pSMB->ParameterCount = pSMB->TotalParameterCount;
  4660. pSMB->ParameterOffset = cpu_to_le16(offsetof(
  4661. struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
  4662. pSMB->DataCount = 0;
  4663. pSMB->DataOffset = 0;
  4664. pSMB->SetupCount = 1;
  4665. pSMB->Reserved3 = 0;
  4666. pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
  4667. pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
  4668. inc_rfc1001_len(pSMB, byte_count);
  4669. pSMB->ByteCount = cpu_to_le16(byte_count);
  4670. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  4671. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  4672. if (rc) {
  4673. cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
  4674. } else { /* decode response */
  4675. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  4676. if (rc || get_bcc(&pSMBr->hdr) <
  4677. sizeof(FILE_SYSTEM_DEVICE_INFO))
  4678. rc = -EIO; /* bad smb */
  4679. else {
  4680. __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
  4681. response_data =
  4682. (FILE_SYSTEM_DEVICE_INFO *)
  4683. (((char *) &pSMBr->hdr.Protocol) +
  4684. data_offset);
  4685. memcpy(&tcon->fsDevInfo, response_data,
  4686. sizeof(FILE_SYSTEM_DEVICE_INFO));
  4687. }
  4688. }
  4689. cifs_buf_release(pSMB);
  4690. if (rc == -EAGAIN)
  4691. goto QFSDeviceRetry;
  4692. return rc;
  4693. }
  4694. int
  4695. CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
  4696. {
  4697. /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
  4698. TRANSACTION2_QFSI_REQ *pSMB = NULL;
  4699. TRANSACTION2_QFSI_RSP *pSMBr = NULL;
  4700. FILE_SYSTEM_UNIX_INFO *response_data;
  4701. int rc = 0;
  4702. int bytes_returned = 0;
  4703. __u16 params, byte_count;
  4704. cifs_dbg(FYI, "In QFSUnixInfo\n");
  4705. QFSUnixRetry:
  4706. rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
  4707. (void **) &pSMB, (void **) &pSMBr);
  4708. if (rc)
  4709. return rc;
  4710. params = 2; /* level */
  4711. pSMB->TotalDataCount = 0;
  4712. pSMB->DataCount = 0;
  4713. pSMB->DataOffset = 0;
  4714. pSMB->MaxParameterCount = cpu_to_le16(2);
  4715. /* BB find exact max SMB PDU from sess structure BB */
  4716. pSMB->MaxDataCount = cpu_to_le16(100);
  4717. pSMB->MaxSetupCount = 0;
  4718. pSMB->Reserved = 0;
  4719. pSMB->Flags = 0;
  4720. pSMB->Timeout = 0;
  4721. pSMB->Reserved2 = 0;
  4722. byte_count = params + 1 /* pad */ ;
  4723. pSMB->ParameterCount = cpu_to_le16(params);
  4724. pSMB->TotalParameterCount = pSMB->ParameterCount;
  4725. pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
  4726. smb_com_transaction2_qfsi_req, InformationLevel) - 4);
  4727. pSMB->SetupCount = 1;
  4728. pSMB->Reserved3 = 0;
  4729. pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
  4730. pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
  4731. inc_rfc1001_len(pSMB, byte_count);
  4732. pSMB->ByteCount = cpu_to_le16(byte_count);
  4733. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  4734. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  4735. if (rc) {
  4736. cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
  4737. } else { /* decode response */
  4738. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  4739. if (rc || get_bcc(&pSMBr->hdr) < 13) {
  4740. rc = -EIO; /* bad smb */
  4741. } else {
  4742. __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
  4743. response_data =
  4744. (FILE_SYSTEM_UNIX_INFO
  4745. *) (((char *) &pSMBr->hdr.Protocol) +
  4746. data_offset);
  4747. memcpy(&tcon->fsUnixInfo, response_data,
  4748. sizeof(FILE_SYSTEM_UNIX_INFO));
  4749. }
  4750. }
  4751. cifs_buf_release(pSMB);
  4752. if (rc == -EAGAIN)
  4753. goto QFSUnixRetry;
  4754. return rc;
  4755. }
  4756. int
  4757. CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
  4758. {
  4759. /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
  4760. TRANSACTION2_SETFSI_REQ *pSMB = NULL;
  4761. TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
  4762. int rc = 0;
  4763. int bytes_returned = 0;
  4764. __u16 params, param_offset, offset, byte_count;
  4765. cifs_dbg(FYI, "In SETFSUnixInfo\n");
  4766. SETFSUnixRetry:
  4767. /* BB switch to small buf init to save memory */
  4768. rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
  4769. (void **) &pSMB, (void **) &pSMBr);
  4770. if (rc)
  4771. return rc;
  4772. params = 4; /* 2 bytes zero followed by info level. */
  4773. pSMB->MaxSetupCount = 0;
  4774. pSMB->Reserved = 0;
  4775. pSMB->Flags = 0;
  4776. pSMB->Timeout = 0;
  4777. pSMB->Reserved2 = 0;
  4778. param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
  4779. - 4;
  4780. offset = param_offset + params;
  4781. pSMB->MaxParameterCount = cpu_to_le16(4);
  4782. /* BB find exact max SMB PDU from sess structure BB */
  4783. pSMB->MaxDataCount = cpu_to_le16(100);
  4784. pSMB->SetupCount = 1;
  4785. pSMB->Reserved3 = 0;
  4786. pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
  4787. byte_count = 1 /* pad */ + params + 12;
  4788. pSMB->DataCount = cpu_to_le16(12);
  4789. pSMB->ParameterCount = cpu_to_le16(params);
  4790. pSMB->TotalDataCount = pSMB->DataCount;
  4791. pSMB->TotalParameterCount = pSMB->ParameterCount;
  4792. pSMB->ParameterOffset = cpu_to_le16(param_offset);
  4793. pSMB->DataOffset = cpu_to_le16(offset);
  4794. /* Params. */
  4795. pSMB->FileNum = 0;
  4796. pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
  4797. /* Data. */
  4798. pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
  4799. pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
  4800. pSMB->ClientUnixCap = cpu_to_le64(cap);
  4801. inc_rfc1001_len(pSMB, byte_count);
  4802. pSMB->ByteCount = cpu_to_le16(byte_count);
  4803. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  4804. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  4805. if (rc) {
  4806. cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
  4807. } else { /* decode response */
  4808. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  4809. if (rc)
  4810. rc = -EIO; /* bad smb */
  4811. }
  4812. cifs_buf_release(pSMB);
  4813. if (rc == -EAGAIN)
  4814. goto SETFSUnixRetry;
  4815. return rc;
  4816. }
  4817. int
  4818. CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
  4819. struct kstatfs *FSData)
  4820. {
  4821. /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
  4822. TRANSACTION2_QFSI_REQ *pSMB = NULL;
  4823. TRANSACTION2_QFSI_RSP *pSMBr = NULL;
  4824. FILE_SYSTEM_POSIX_INFO *response_data;
  4825. int rc = 0;
  4826. int bytes_returned = 0;
  4827. __u16 params, byte_count;
  4828. cifs_dbg(FYI, "In QFSPosixInfo\n");
  4829. QFSPosixRetry:
  4830. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  4831. (void **) &pSMBr);
  4832. if (rc)
  4833. return rc;
  4834. params = 2; /* level */
  4835. pSMB->TotalDataCount = 0;
  4836. pSMB->DataCount = 0;
  4837. pSMB->DataOffset = 0;
  4838. pSMB->MaxParameterCount = cpu_to_le16(2);
  4839. /* BB find exact max SMB PDU from sess structure BB */
  4840. pSMB->MaxDataCount = cpu_to_le16(100);
  4841. pSMB->MaxSetupCount = 0;
  4842. pSMB->Reserved = 0;
  4843. pSMB->Flags = 0;
  4844. pSMB->Timeout = 0;
  4845. pSMB->Reserved2 = 0;
  4846. byte_count = params + 1 /* pad */ ;
  4847. pSMB->ParameterCount = cpu_to_le16(params);
  4848. pSMB->TotalParameterCount = pSMB->ParameterCount;
  4849. pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
  4850. smb_com_transaction2_qfsi_req, InformationLevel) - 4);
  4851. pSMB->SetupCount = 1;
  4852. pSMB->Reserved3 = 0;
  4853. pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
  4854. pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
  4855. inc_rfc1001_len(pSMB, byte_count);
  4856. pSMB->ByteCount = cpu_to_le16(byte_count);
  4857. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  4858. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  4859. if (rc) {
  4860. cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
  4861. } else { /* decode response */
  4862. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  4863. if (rc || get_bcc(&pSMBr->hdr) < 13) {
  4864. rc = -EIO; /* bad smb */
  4865. } else {
  4866. __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
  4867. response_data =
  4868. (FILE_SYSTEM_POSIX_INFO
  4869. *) (((char *) &pSMBr->hdr.Protocol) +
  4870. data_offset);
  4871. FSData->f_bsize =
  4872. le32_to_cpu(response_data->BlockSize);
  4873. FSData->f_blocks =
  4874. le64_to_cpu(response_data->TotalBlocks);
  4875. FSData->f_bfree =
  4876. le64_to_cpu(response_data->BlocksAvail);
  4877. if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
  4878. FSData->f_bavail = FSData->f_bfree;
  4879. } else {
  4880. FSData->f_bavail =
  4881. le64_to_cpu(response_data->UserBlocksAvail);
  4882. }
  4883. if (response_data->TotalFileNodes != cpu_to_le64(-1))
  4884. FSData->f_files =
  4885. le64_to_cpu(response_data->TotalFileNodes);
  4886. if (response_data->FreeFileNodes != cpu_to_le64(-1))
  4887. FSData->f_ffree =
  4888. le64_to_cpu(response_data->FreeFileNodes);
  4889. }
  4890. }
  4891. cifs_buf_release(pSMB);
  4892. if (rc == -EAGAIN)
  4893. goto QFSPosixRetry;
  4894. return rc;
  4895. }
  4896. /*
  4897. * We can not use write of zero bytes trick to set file size due to need for
  4898. * large file support. Also note that this SetPathInfo is preferred to
  4899. * SetFileInfo based method in next routine which is only needed to work around
  4900. * a sharing violation bugin Samba which this routine can run into.
  4901. */
  4902. int
  4903. CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
  4904. const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
  4905. bool set_allocation)
  4906. {
  4907. struct smb_com_transaction2_spi_req *pSMB = NULL;
  4908. struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
  4909. struct file_end_of_file_info *parm_data;
  4910. int name_len;
  4911. int rc = 0;
  4912. int bytes_returned = 0;
  4913. int remap = cifs_remap(cifs_sb);
  4914. __u16 params, byte_count, data_count, param_offset, offset;
  4915. cifs_dbg(FYI, "In SetEOF\n");
  4916. SetEOFRetry:
  4917. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  4918. (void **) &pSMBr);
  4919. if (rc)
  4920. return rc;
  4921. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  4922. name_len =
  4923. cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
  4924. PATH_MAX, cifs_sb->local_nls, remap);
  4925. name_len++; /* trailing null */
  4926. name_len *= 2;
  4927. } else { /* BB improve the check for buffer overruns BB */
  4928. name_len = strnlen(file_name, PATH_MAX);
  4929. name_len++; /* trailing null */
  4930. strncpy(pSMB->FileName, file_name, name_len);
  4931. }
  4932. params = 6 + name_len;
  4933. data_count = sizeof(struct file_end_of_file_info);
  4934. pSMB->MaxParameterCount = cpu_to_le16(2);
  4935. pSMB->MaxDataCount = cpu_to_le16(4100);
  4936. pSMB->MaxSetupCount = 0;
  4937. pSMB->Reserved = 0;
  4938. pSMB->Flags = 0;
  4939. pSMB->Timeout = 0;
  4940. pSMB->Reserved2 = 0;
  4941. param_offset = offsetof(struct smb_com_transaction2_spi_req,
  4942. InformationLevel) - 4;
  4943. offset = param_offset + params;
  4944. if (set_allocation) {
  4945. if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
  4946. pSMB->InformationLevel =
  4947. cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
  4948. else
  4949. pSMB->InformationLevel =
  4950. cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
  4951. } else /* Set File Size */ {
  4952. if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
  4953. pSMB->InformationLevel =
  4954. cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
  4955. else
  4956. pSMB->InformationLevel =
  4957. cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
  4958. }
  4959. parm_data =
  4960. (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
  4961. offset);
  4962. pSMB->ParameterOffset = cpu_to_le16(param_offset);
  4963. pSMB->DataOffset = cpu_to_le16(offset);
  4964. pSMB->SetupCount = 1;
  4965. pSMB->Reserved3 = 0;
  4966. pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
  4967. byte_count = 3 /* pad */ + params + data_count;
  4968. pSMB->DataCount = cpu_to_le16(data_count);
  4969. pSMB->TotalDataCount = pSMB->DataCount;
  4970. pSMB->ParameterCount = cpu_to_le16(params);
  4971. pSMB->TotalParameterCount = pSMB->ParameterCount;
  4972. pSMB->Reserved4 = 0;
  4973. inc_rfc1001_len(pSMB, byte_count);
  4974. parm_data->FileSize = cpu_to_le64(size);
  4975. pSMB->ByteCount = cpu_to_le16(byte_count);
  4976. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  4977. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  4978. if (rc)
  4979. cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
  4980. cifs_buf_release(pSMB);
  4981. if (rc == -EAGAIN)
  4982. goto SetEOFRetry;
  4983. return rc;
  4984. }
  4985. int
  4986. CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
  4987. struct cifsFileInfo *cfile, __u64 size, bool set_allocation)
  4988. {
  4989. struct smb_com_transaction2_sfi_req *pSMB = NULL;
  4990. struct file_end_of_file_info *parm_data;
  4991. int rc = 0;
  4992. __u16 params, param_offset, offset, byte_count, count;
  4993. cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
  4994. (long long)size);
  4995. rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
  4996. if (rc)
  4997. return rc;
  4998. pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
  4999. pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
  5000. params = 6;
  5001. pSMB->MaxSetupCount = 0;
  5002. pSMB->Reserved = 0;
  5003. pSMB->Flags = 0;
  5004. pSMB->Timeout = 0;
  5005. pSMB->Reserved2 = 0;
  5006. param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
  5007. offset = param_offset + params;
  5008. count = sizeof(struct file_end_of_file_info);
  5009. pSMB->MaxParameterCount = cpu_to_le16(2);
  5010. /* BB find exact max SMB PDU from sess structure BB */
  5011. pSMB->MaxDataCount = cpu_to_le16(1000);
  5012. pSMB->SetupCount = 1;
  5013. pSMB->Reserved3 = 0;
  5014. pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
  5015. byte_count = 3 /* pad */ + params + count;
  5016. pSMB->DataCount = cpu_to_le16(count);
  5017. pSMB->ParameterCount = cpu_to_le16(params);
  5018. pSMB->TotalDataCount = pSMB->DataCount;
  5019. pSMB->TotalParameterCount = pSMB->ParameterCount;
  5020. pSMB->ParameterOffset = cpu_to_le16(param_offset);
  5021. parm_data =
  5022. (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
  5023. + offset);
  5024. pSMB->DataOffset = cpu_to_le16(offset);
  5025. parm_data->FileSize = cpu_to_le64(size);
  5026. pSMB->Fid = cfile->fid.netfid;
  5027. if (set_allocation) {
  5028. if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
  5029. pSMB->InformationLevel =
  5030. cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
  5031. else
  5032. pSMB->InformationLevel =
  5033. cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
  5034. } else /* Set File Size */ {
  5035. if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
  5036. pSMB->InformationLevel =
  5037. cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
  5038. else
  5039. pSMB->InformationLevel =
  5040. cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
  5041. }
  5042. pSMB->Reserved4 = 0;
  5043. inc_rfc1001_len(pSMB, byte_count);
  5044. pSMB->ByteCount = cpu_to_le16(byte_count);
  5045. rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
  5046. if (rc) {
  5047. cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
  5048. rc);
  5049. }
  5050. /* Note: On -EAGAIN error only caller can retry on handle based calls
  5051. since file handle passed in no longer valid */
  5052. return rc;
  5053. }
  5054. /* Some legacy servers such as NT4 require that the file times be set on
  5055. an open handle, rather than by pathname - this is awkward due to
  5056. potential access conflicts on the open, but it is unavoidable for these
  5057. old servers since the only other choice is to go from 100 nanosecond DCE
  5058. time and resort to the original setpathinfo level which takes the ancient
  5059. DOS time format with 2 second granularity */
  5060. int
  5061. CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
  5062. const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
  5063. {
  5064. struct smb_com_transaction2_sfi_req *pSMB = NULL;
  5065. char *data_offset;
  5066. int rc = 0;
  5067. __u16 params, param_offset, offset, byte_count, count;
  5068. cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
  5069. rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
  5070. if (rc)
  5071. return rc;
  5072. pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
  5073. pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
  5074. params = 6;
  5075. pSMB->MaxSetupCount = 0;
  5076. pSMB->Reserved = 0;
  5077. pSMB->Flags = 0;
  5078. pSMB->Timeout = 0;
  5079. pSMB->Reserved2 = 0;
  5080. param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
  5081. offset = param_offset + params;
  5082. data_offset = (char *)pSMB +
  5083. offsetof(struct smb_hdr, Protocol) + offset;
  5084. count = sizeof(FILE_BASIC_INFO);
  5085. pSMB->MaxParameterCount = cpu_to_le16(2);
  5086. /* BB find max SMB PDU from sess */
  5087. pSMB->MaxDataCount = cpu_to_le16(1000);
  5088. pSMB->SetupCount = 1;
  5089. pSMB->Reserved3 = 0;
  5090. pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
  5091. byte_count = 3 /* pad */ + params + count;
  5092. pSMB->DataCount = cpu_to_le16(count);
  5093. pSMB->ParameterCount = cpu_to_le16(params);
  5094. pSMB->TotalDataCount = pSMB->DataCount;
  5095. pSMB->TotalParameterCount = pSMB->ParameterCount;
  5096. pSMB->ParameterOffset = cpu_to_le16(param_offset);
  5097. pSMB->DataOffset = cpu_to_le16(offset);
  5098. pSMB->Fid = fid;
  5099. if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
  5100. pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
  5101. else
  5102. pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
  5103. pSMB->Reserved4 = 0;
  5104. inc_rfc1001_len(pSMB, byte_count);
  5105. pSMB->ByteCount = cpu_to_le16(byte_count);
  5106. memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
  5107. rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
  5108. if (rc)
  5109. cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
  5110. rc);
  5111. /* Note: On -EAGAIN error only caller can retry on handle based calls
  5112. since file handle passed in no longer valid */
  5113. return rc;
  5114. }
  5115. int
  5116. CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
  5117. bool delete_file, __u16 fid, __u32 pid_of_opener)
  5118. {
  5119. struct smb_com_transaction2_sfi_req *pSMB = NULL;
  5120. char *data_offset;
  5121. int rc = 0;
  5122. __u16 params, param_offset, offset, byte_count, count;
  5123. cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
  5124. rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
  5125. if (rc)
  5126. return rc;
  5127. pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
  5128. pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
  5129. params = 6;
  5130. pSMB->MaxSetupCount = 0;
  5131. pSMB->Reserved = 0;
  5132. pSMB->Flags = 0;
  5133. pSMB->Timeout = 0;
  5134. pSMB->Reserved2 = 0;
  5135. param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
  5136. offset = param_offset + params;
  5137. data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
  5138. count = 1;
  5139. pSMB->MaxParameterCount = cpu_to_le16(2);
  5140. /* BB find max SMB PDU from sess */
  5141. pSMB->MaxDataCount = cpu_to_le16(1000);
  5142. pSMB->SetupCount = 1;
  5143. pSMB->Reserved3 = 0;
  5144. pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
  5145. byte_count = 3 /* pad */ + params + count;
  5146. pSMB->DataCount = cpu_to_le16(count);
  5147. pSMB->ParameterCount = cpu_to_le16(params);
  5148. pSMB->TotalDataCount = pSMB->DataCount;
  5149. pSMB->TotalParameterCount = pSMB->ParameterCount;
  5150. pSMB->ParameterOffset = cpu_to_le16(param_offset);
  5151. pSMB->DataOffset = cpu_to_le16(offset);
  5152. pSMB->Fid = fid;
  5153. pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
  5154. pSMB->Reserved4 = 0;
  5155. inc_rfc1001_len(pSMB, byte_count);
  5156. pSMB->ByteCount = cpu_to_le16(byte_count);
  5157. *data_offset = delete_file ? 1 : 0;
  5158. rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
  5159. if (rc)
  5160. cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
  5161. return rc;
  5162. }
  5163. int
  5164. CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
  5165. const char *fileName, const FILE_BASIC_INFO *data,
  5166. const struct nls_table *nls_codepage, int remap)
  5167. {
  5168. TRANSACTION2_SPI_REQ *pSMB = NULL;
  5169. TRANSACTION2_SPI_RSP *pSMBr = NULL;
  5170. int name_len;
  5171. int rc = 0;
  5172. int bytes_returned = 0;
  5173. char *data_offset;
  5174. __u16 params, param_offset, offset, byte_count, count;
  5175. cifs_dbg(FYI, "In SetTimes\n");
  5176. SetTimesRetry:
  5177. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  5178. (void **) &pSMBr);
  5179. if (rc)
  5180. return rc;
  5181. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  5182. name_len =
  5183. cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
  5184. PATH_MAX, nls_codepage, remap);
  5185. name_len++; /* trailing null */
  5186. name_len *= 2;
  5187. } else { /* BB improve the check for buffer overruns BB */
  5188. name_len = strnlen(fileName, PATH_MAX);
  5189. name_len++; /* trailing null */
  5190. strncpy(pSMB->FileName, fileName, name_len);
  5191. }
  5192. params = 6 + name_len;
  5193. count = sizeof(FILE_BASIC_INFO);
  5194. pSMB->MaxParameterCount = cpu_to_le16(2);
  5195. /* BB find max SMB PDU from sess structure BB */
  5196. pSMB->MaxDataCount = cpu_to_le16(1000);
  5197. pSMB->MaxSetupCount = 0;
  5198. pSMB->Reserved = 0;
  5199. pSMB->Flags = 0;
  5200. pSMB->Timeout = 0;
  5201. pSMB->Reserved2 = 0;
  5202. param_offset = offsetof(struct smb_com_transaction2_spi_req,
  5203. InformationLevel) - 4;
  5204. offset = param_offset + params;
  5205. data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
  5206. pSMB->ParameterOffset = cpu_to_le16(param_offset);
  5207. pSMB->DataOffset = cpu_to_le16(offset);
  5208. pSMB->SetupCount = 1;
  5209. pSMB->Reserved3 = 0;
  5210. pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
  5211. byte_count = 3 /* pad */ + params + count;
  5212. pSMB->DataCount = cpu_to_le16(count);
  5213. pSMB->ParameterCount = cpu_to_le16(params);
  5214. pSMB->TotalDataCount = pSMB->DataCount;
  5215. pSMB->TotalParameterCount = pSMB->ParameterCount;
  5216. if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
  5217. pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
  5218. else
  5219. pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
  5220. pSMB->Reserved4 = 0;
  5221. inc_rfc1001_len(pSMB, byte_count);
  5222. memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
  5223. pSMB->ByteCount = cpu_to_le16(byte_count);
  5224. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  5225. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  5226. if (rc)
  5227. cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
  5228. cifs_buf_release(pSMB);
  5229. if (rc == -EAGAIN)
  5230. goto SetTimesRetry;
  5231. return rc;
  5232. }
  5233. /* Can not be used to set time stamps yet (due to old DOS time format) */
  5234. /* Can be used to set attributes */
  5235. #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
  5236. handling it anyway and NT4 was what we thought it would be needed for
  5237. Do not delete it until we prove whether needed for Win9x though */
  5238. int
  5239. CIFSSMBSetAttrLegacy(unsigned int xid, struct cifs_tcon *tcon, char *fileName,
  5240. __u16 dos_attrs, const struct nls_table *nls_codepage)
  5241. {
  5242. SETATTR_REQ *pSMB = NULL;
  5243. SETATTR_RSP *pSMBr = NULL;
  5244. int rc = 0;
  5245. int bytes_returned;
  5246. int name_len;
  5247. cifs_dbg(FYI, "In SetAttrLegacy\n");
  5248. SetAttrLgcyRetry:
  5249. rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
  5250. (void **) &pSMBr);
  5251. if (rc)
  5252. return rc;
  5253. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  5254. name_len =
  5255. ConvertToUTF16((__le16 *) pSMB->fileName, fileName,
  5256. PATH_MAX, nls_codepage);
  5257. name_len++; /* trailing null */
  5258. name_len *= 2;
  5259. } else { /* BB improve the check for buffer overruns BB */
  5260. name_len = strnlen(fileName, PATH_MAX);
  5261. name_len++; /* trailing null */
  5262. strncpy(pSMB->fileName, fileName, name_len);
  5263. }
  5264. pSMB->attr = cpu_to_le16(dos_attrs);
  5265. pSMB->BufferFormat = 0x04;
  5266. inc_rfc1001_len(pSMB, name_len + 1);
  5267. pSMB->ByteCount = cpu_to_le16(name_len + 1);
  5268. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  5269. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  5270. if (rc)
  5271. cifs_dbg(FYI, "Error in LegacySetAttr = %d\n", rc);
  5272. cifs_buf_release(pSMB);
  5273. if (rc == -EAGAIN)
  5274. goto SetAttrLgcyRetry;
  5275. return rc;
  5276. }
  5277. #endif /* temporarily unneeded SetAttr legacy function */
  5278. static void
  5279. cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
  5280. const struct cifs_unix_set_info_args *args)
  5281. {
  5282. u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
  5283. u64 mode = args->mode;
  5284. if (uid_valid(args->uid))
  5285. uid = from_kuid(&init_user_ns, args->uid);
  5286. if (gid_valid(args->gid))
  5287. gid = from_kgid(&init_user_ns, args->gid);
  5288. /*
  5289. * Samba server ignores set of file size to zero due to bugs in some
  5290. * older clients, but we should be precise - we use SetFileSize to
  5291. * set file size and do not want to truncate file size to zero
  5292. * accidentally as happened on one Samba server beta by putting
  5293. * zero instead of -1 here
  5294. */
  5295. data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
  5296. data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
  5297. data_offset->LastStatusChange = cpu_to_le64(args->ctime);
  5298. data_offset->LastAccessTime = cpu_to_le64(args->atime);
  5299. data_offset->LastModificationTime = cpu_to_le64(args->mtime);
  5300. data_offset->Uid = cpu_to_le64(uid);
  5301. data_offset->Gid = cpu_to_le64(gid);
  5302. /* better to leave device as zero when it is */
  5303. data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
  5304. data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
  5305. data_offset->Permissions = cpu_to_le64(mode);
  5306. if (S_ISREG(mode))
  5307. data_offset->Type = cpu_to_le32(UNIX_FILE);
  5308. else if (S_ISDIR(mode))
  5309. data_offset->Type = cpu_to_le32(UNIX_DIR);
  5310. else if (S_ISLNK(mode))
  5311. data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
  5312. else if (S_ISCHR(mode))
  5313. data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
  5314. else if (S_ISBLK(mode))
  5315. data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
  5316. else if (S_ISFIFO(mode))
  5317. data_offset->Type = cpu_to_le32(UNIX_FIFO);
  5318. else if (S_ISSOCK(mode))
  5319. data_offset->Type = cpu_to_le32(UNIX_SOCKET);
  5320. }
  5321. int
  5322. CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
  5323. const struct cifs_unix_set_info_args *args,
  5324. u16 fid, u32 pid_of_opener)
  5325. {
  5326. struct smb_com_transaction2_sfi_req *pSMB = NULL;
  5327. char *data_offset;
  5328. int rc = 0;
  5329. u16 params, param_offset, offset, byte_count, count;
  5330. cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
  5331. rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
  5332. if (rc)
  5333. return rc;
  5334. pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
  5335. pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
  5336. params = 6;
  5337. pSMB->MaxSetupCount = 0;
  5338. pSMB->Reserved = 0;
  5339. pSMB->Flags = 0;
  5340. pSMB->Timeout = 0;
  5341. pSMB->Reserved2 = 0;
  5342. param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
  5343. offset = param_offset + params;
  5344. data_offset = (char *)pSMB +
  5345. offsetof(struct smb_hdr, Protocol) + offset;
  5346. count = sizeof(FILE_UNIX_BASIC_INFO);
  5347. pSMB->MaxParameterCount = cpu_to_le16(2);
  5348. /* BB find max SMB PDU from sess */
  5349. pSMB->MaxDataCount = cpu_to_le16(1000);
  5350. pSMB->SetupCount = 1;
  5351. pSMB->Reserved3 = 0;
  5352. pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
  5353. byte_count = 3 /* pad */ + params + count;
  5354. pSMB->DataCount = cpu_to_le16(count);
  5355. pSMB->ParameterCount = cpu_to_le16(params);
  5356. pSMB->TotalDataCount = pSMB->DataCount;
  5357. pSMB->TotalParameterCount = pSMB->ParameterCount;
  5358. pSMB->ParameterOffset = cpu_to_le16(param_offset);
  5359. pSMB->DataOffset = cpu_to_le16(offset);
  5360. pSMB->Fid = fid;
  5361. pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
  5362. pSMB->Reserved4 = 0;
  5363. inc_rfc1001_len(pSMB, byte_count);
  5364. pSMB->ByteCount = cpu_to_le16(byte_count);
  5365. cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
  5366. rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
  5367. if (rc)
  5368. cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
  5369. rc);
  5370. /* Note: On -EAGAIN error only caller can retry on handle based calls
  5371. since file handle passed in no longer valid */
  5372. return rc;
  5373. }
  5374. int
  5375. CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
  5376. const char *file_name,
  5377. const struct cifs_unix_set_info_args *args,
  5378. const struct nls_table *nls_codepage, int remap)
  5379. {
  5380. TRANSACTION2_SPI_REQ *pSMB = NULL;
  5381. TRANSACTION2_SPI_RSP *pSMBr = NULL;
  5382. int name_len;
  5383. int rc = 0;
  5384. int bytes_returned = 0;
  5385. FILE_UNIX_BASIC_INFO *data_offset;
  5386. __u16 params, param_offset, offset, count, byte_count;
  5387. cifs_dbg(FYI, "In SetUID/GID/Mode\n");
  5388. setPermsRetry:
  5389. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  5390. (void **) &pSMBr);
  5391. if (rc)
  5392. return rc;
  5393. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  5394. name_len =
  5395. cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name,
  5396. PATH_MAX, nls_codepage, remap);
  5397. name_len++; /* trailing null */
  5398. name_len *= 2;
  5399. } else { /* BB improve the check for buffer overruns BB */
  5400. name_len = strnlen(file_name, PATH_MAX);
  5401. name_len++; /* trailing null */
  5402. strncpy(pSMB->FileName, file_name, name_len);
  5403. }
  5404. params = 6 + name_len;
  5405. count = sizeof(FILE_UNIX_BASIC_INFO);
  5406. pSMB->MaxParameterCount = cpu_to_le16(2);
  5407. /* BB find max SMB PDU from sess structure BB */
  5408. pSMB->MaxDataCount = cpu_to_le16(1000);
  5409. pSMB->MaxSetupCount = 0;
  5410. pSMB->Reserved = 0;
  5411. pSMB->Flags = 0;
  5412. pSMB->Timeout = 0;
  5413. pSMB->Reserved2 = 0;
  5414. param_offset = offsetof(struct smb_com_transaction2_spi_req,
  5415. InformationLevel) - 4;
  5416. offset = param_offset + params;
  5417. data_offset =
  5418. (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
  5419. offset);
  5420. memset(data_offset, 0, count);
  5421. pSMB->DataOffset = cpu_to_le16(offset);
  5422. pSMB->ParameterOffset = cpu_to_le16(param_offset);
  5423. pSMB->SetupCount = 1;
  5424. pSMB->Reserved3 = 0;
  5425. pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
  5426. byte_count = 3 /* pad */ + params + count;
  5427. pSMB->ParameterCount = cpu_to_le16(params);
  5428. pSMB->DataCount = cpu_to_le16(count);
  5429. pSMB->TotalParameterCount = pSMB->ParameterCount;
  5430. pSMB->TotalDataCount = pSMB->DataCount;
  5431. pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
  5432. pSMB->Reserved4 = 0;
  5433. inc_rfc1001_len(pSMB, byte_count);
  5434. cifs_fill_unix_set_info(data_offset, args);
  5435. pSMB->ByteCount = cpu_to_le16(byte_count);
  5436. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  5437. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  5438. if (rc)
  5439. cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
  5440. cifs_buf_release(pSMB);
  5441. if (rc == -EAGAIN)
  5442. goto setPermsRetry;
  5443. return rc;
  5444. }
  5445. #ifdef CONFIG_CIFS_XATTR
  5446. /*
  5447. * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
  5448. * function used by listxattr and getxattr type calls. When ea_name is set,
  5449. * it looks for that attribute name and stuffs that value into the EAData
  5450. * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
  5451. * buffer. In both cases, the return value is either the length of the
  5452. * resulting data or a negative error code. If EAData is a NULL pointer then
  5453. * the data isn't copied to it, but the length is returned.
  5454. */
  5455. ssize_t
  5456. CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
  5457. const unsigned char *searchName, const unsigned char *ea_name,
  5458. char *EAData, size_t buf_size,
  5459. const struct nls_table *nls_codepage, int remap)
  5460. {
  5461. /* BB assumes one setup word */
  5462. TRANSACTION2_QPI_REQ *pSMB = NULL;
  5463. TRANSACTION2_QPI_RSP *pSMBr = NULL;
  5464. int rc = 0;
  5465. int bytes_returned;
  5466. int list_len;
  5467. struct fealist *ea_response_data;
  5468. struct fea *temp_fea;
  5469. char *temp_ptr;
  5470. char *end_of_smb;
  5471. __u16 params, byte_count, data_offset;
  5472. unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
  5473. cifs_dbg(FYI, "In Query All EAs path %s\n", searchName);
  5474. QAllEAsRetry:
  5475. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  5476. (void **) &pSMBr);
  5477. if (rc)
  5478. return rc;
  5479. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  5480. list_len =
  5481. cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
  5482. PATH_MAX, nls_codepage, remap);
  5483. list_len++; /* trailing null */
  5484. list_len *= 2;
  5485. } else { /* BB improve the check for buffer overruns BB */
  5486. list_len = strnlen(searchName, PATH_MAX);
  5487. list_len++; /* trailing null */
  5488. strncpy(pSMB->FileName, searchName, list_len);
  5489. }
  5490. params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
  5491. pSMB->TotalDataCount = 0;
  5492. pSMB->MaxParameterCount = cpu_to_le16(2);
  5493. /* BB find exact max SMB PDU from sess structure BB */
  5494. pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
  5495. pSMB->MaxSetupCount = 0;
  5496. pSMB->Reserved = 0;
  5497. pSMB->Flags = 0;
  5498. pSMB->Timeout = 0;
  5499. pSMB->Reserved2 = 0;
  5500. pSMB->ParameterOffset = cpu_to_le16(offsetof(
  5501. struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
  5502. pSMB->DataCount = 0;
  5503. pSMB->DataOffset = 0;
  5504. pSMB->SetupCount = 1;
  5505. pSMB->Reserved3 = 0;
  5506. pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
  5507. byte_count = params + 1 /* pad */ ;
  5508. pSMB->TotalParameterCount = cpu_to_le16(params);
  5509. pSMB->ParameterCount = pSMB->TotalParameterCount;
  5510. pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
  5511. pSMB->Reserved4 = 0;
  5512. inc_rfc1001_len(pSMB, byte_count);
  5513. pSMB->ByteCount = cpu_to_le16(byte_count);
  5514. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  5515. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  5516. if (rc) {
  5517. cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
  5518. goto QAllEAsOut;
  5519. }
  5520. /* BB also check enough total bytes returned */
  5521. /* BB we need to improve the validity checking
  5522. of these trans2 responses */
  5523. rc = validate_t2((struct smb_t2_rsp *)pSMBr);
  5524. if (rc || get_bcc(&pSMBr->hdr) < 4) {
  5525. rc = -EIO; /* bad smb */
  5526. goto QAllEAsOut;
  5527. }
  5528. /* check that length of list is not more than bcc */
  5529. /* check that each entry does not go beyond length
  5530. of list */
  5531. /* check that each element of each entry does not
  5532. go beyond end of list */
  5533. /* validate_trans2_offsets() */
  5534. /* BB check if start of smb + data_offset > &bcc+ bcc */
  5535. data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
  5536. ea_response_data = (struct fealist *)
  5537. (((char *) &pSMBr->hdr.Protocol) + data_offset);
  5538. list_len = le32_to_cpu(ea_response_data->list_len);
  5539. cifs_dbg(FYI, "ea length %d\n", list_len);
  5540. if (list_len <= 8) {
  5541. cifs_dbg(FYI, "empty EA list returned from server\n");
  5542. /* didn't find the named attribute */
  5543. if (ea_name)
  5544. rc = -ENODATA;
  5545. goto QAllEAsOut;
  5546. }
  5547. /* make sure list_len doesn't go past end of SMB */
  5548. end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
  5549. if ((char *)ea_response_data + list_len > end_of_smb) {
  5550. cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
  5551. rc = -EIO;
  5552. goto QAllEAsOut;
  5553. }
  5554. /* account for ea list len */
  5555. list_len -= 4;
  5556. temp_fea = ea_response_data->list;
  5557. temp_ptr = (char *)temp_fea;
  5558. while (list_len > 0) {
  5559. unsigned int name_len;
  5560. __u16 value_len;
  5561. list_len -= 4;
  5562. temp_ptr += 4;
  5563. /* make sure we can read name_len and value_len */
  5564. if (list_len < 0) {
  5565. cifs_dbg(FYI, "EA entry goes beyond length of list\n");
  5566. rc = -EIO;
  5567. goto QAllEAsOut;
  5568. }
  5569. name_len = temp_fea->name_len;
  5570. value_len = le16_to_cpu(temp_fea->value_len);
  5571. list_len -= name_len + 1 + value_len;
  5572. if (list_len < 0) {
  5573. cifs_dbg(FYI, "EA entry goes beyond length of list\n");
  5574. rc = -EIO;
  5575. goto QAllEAsOut;
  5576. }
  5577. if (ea_name) {
  5578. if (ea_name_len == name_len &&
  5579. memcmp(ea_name, temp_ptr, name_len) == 0) {
  5580. temp_ptr += name_len + 1;
  5581. rc = value_len;
  5582. if (buf_size == 0)
  5583. goto QAllEAsOut;
  5584. if ((size_t)value_len > buf_size) {
  5585. rc = -ERANGE;
  5586. goto QAllEAsOut;
  5587. }
  5588. memcpy(EAData, temp_ptr, value_len);
  5589. goto QAllEAsOut;
  5590. }
  5591. } else {
  5592. /* account for prefix user. and trailing null */
  5593. rc += (5 + 1 + name_len);
  5594. if (rc < (int) buf_size) {
  5595. memcpy(EAData, "user.", 5);
  5596. EAData += 5;
  5597. memcpy(EAData, temp_ptr, name_len);
  5598. EAData += name_len;
  5599. /* null terminate name */
  5600. *EAData = 0;
  5601. ++EAData;
  5602. } else if (buf_size == 0) {
  5603. /* skip copy - calc size only */
  5604. } else {
  5605. /* stop before overrun buffer */
  5606. rc = -ERANGE;
  5607. break;
  5608. }
  5609. }
  5610. temp_ptr += name_len + 1 + value_len;
  5611. temp_fea = (struct fea *)temp_ptr;
  5612. }
  5613. /* didn't find the named attribute */
  5614. if (ea_name)
  5615. rc = -ENODATA;
  5616. QAllEAsOut:
  5617. cifs_buf_release(pSMB);
  5618. if (rc == -EAGAIN)
  5619. goto QAllEAsRetry;
  5620. return (ssize_t)rc;
  5621. }
  5622. int
  5623. CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
  5624. const char *fileName, const char *ea_name, const void *ea_value,
  5625. const __u16 ea_value_len, const struct nls_table *nls_codepage,
  5626. int remap)
  5627. {
  5628. struct smb_com_transaction2_spi_req *pSMB = NULL;
  5629. struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
  5630. struct fealist *parm_data;
  5631. int name_len;
  5632. int rc = 0;
  5633. int bytes_returned = 0;
  5634. __u16 params, param_offset, byte_count, offset, count;
  5635. cifs_dbg(FYI, "In SetEA\n");
  5636. SetEARetry:
  5637. rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
  5638. (void **) &pSMBr);
  5639. if (rc)
  5640. return rc;
  5641. if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
  5642. name_len =
  5643. cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
  5644. PATH_MAX, nls_codepage, remap);
  5645. name_len++; /* trailing null */
  5646. name_len *= 2;
  5647. } else { /* BB improve the check for buffer overruns BB */
  5648. name_len = strnlen(fileName, PATH_MAX);
  5649. name_len++; /* trailing null */
  5650. strncpy(pSMB->FileName, fileName, name_len);
  5651. }
  5652. params = 6 + name_len;
  5653. /* done calculating parms using name_len of file name,
  5654. now use name_len to calculate length of ea name
  5655. we are going to create in the inode xattrs */
  5656. if (ea_name == NULL)
  5657. name_len = 0;
  5658. else
  5659. name_len = strnlen(ea_name, 255);
  5660. count = sizeof(*parm_data) + ea_value_len + name_len;
  5661. pSMB->MaxParameterCount = cpu_to_le16(2);
  5662. /* BB find max SMB PDU from sess */
  5663. pSMB->MaxDataCount = cpu_to_le16(1000);
  5664. pSMB->MaxSetupCount = 0;
  5665. pSMB->Reserved = 0;
  5666. pSMB->Flags = 0;
  5667. pSMB->Timeout = 0;
  5668. pSMB->Reserved2 = 0;
  5669. param_offset = offsetof(struct smb_com_transaction2_spi_req,
  5670. InformationLevel) - 4;
  5671. offset = param_offset + params;
  5672. pSMB->InformationLevel =
  5673. cpu_to_le16(SMB_SET_FILE_EA);
  5674. parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
  5675. pSMB->ParameterOffset = cpu_to_le16(param_offset);
  5676. pSMB->DataOffset = cpu_to_le16(offset);
  5677. pSMB->SetupCount = 1;
  5678. pSMB->Reserved3 = 0;
  5679. pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
  5680. byte_count = 3 /* pad */ + params + count;
  5681. pSMB->DataCount = cpu_to_le16(count);
  5682. parm_data->list_len = cpu_to_le32(count);
  5683. parm_data->list[0].EA_flags = 0;
  5684. /* we checked above that name len is less than 255 */
  5685. parm_data->list[0].name_len = (__u8)name_len;
  5686. /* EA names are always ASCII */
  5687. if (ea_name)
  5688. strncpy(parm_data->list[0].name, ea_name, name_len);
  5689. parm_data->list[0].name[name_len] = 0;
  5690. parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
  5691. /* caller ensures that ea_value_len is less than 64K but
  5692. we need to ensure that it fits within the smb */
  5693. /*BB add length check to see if it would fit in
  5694. negotiated SMB buffer size BB */
  5695. /* if (ea_value_len > buffer_size - 512 (enough for header)) */
  5696. if (ea_value_len)
  5697. memcpy(parm_data->list[0].name+name_len+1,
  5698. ea_value, ea_value_len);
  5699. pSMB->TotalDataCount = pSMB->DataCount;
  5700. pSMB->ParameterCount = cpu_to_le16(params);
  5701. pSMB->TotalParameterCount = pSMB->ParameterCount;
  5702. pSMB->Reserved4 = 0;
  5703. inc_rfc1001_len(pSMB, byte_count);
  5704. pSMB->ByteCount = cpu_to_le16(byte_count);
  5705. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  5706. (struct smb_hdr *) pSMBr, &bytes_returned, 0);
  5707. if (rc)
  5708. cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
  5709. cifs_buf_release(pSMB);
  5710. if (rc == -EAGAIN)
  5711. goto SetEARetry;
  5712. return rc;
  5713. }
  5714. #endif
  5715. #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
  5716. /*
  5717. * Years ago the kernel added a "dnotify" function for Samba server,
  5718. * to allow network clients (such as Windows) to display updated
  5719. * lists of files in directory listings automatically when
  5720. * files are added by one user when another user has the
  5721. * same directory open on their desktop. The Linux cifs kernel
  5722. * client hooked into the kernel side of this interface for
  5723. * the same reason, but ironically when the VFS moved from
  5724. * "dnotify" to "inotify" it became harder to plug in Linux
  5725. * network file system clients (the most obvious use case
  5726. * for notify interfaces is when multiple users can update
  5727. * the contents of the same directory - exactly what network
  5728. * file systems can do) although the server (Samba) could
  5729. * still use it. For the short term we leave the worker
  5730. * function ifdeffed out (below) until inotify is fixed
  5731. * in the VFS to make it easier to plug in network file
  5732. * system clients. If inotify turns out to be permanently
  5733. * incompatible for network fs clients, we could instead simply
  5734. * expose this config flag by adding a future cifs (and smb2) notify ioctl.
  5735. */
  5736. int CIFSSMBNotify(const unsigned int xid, struct cifs_tcon *tcon,
  5737. const int notify_subdirs, const __u16 netfid,
  5738. __u32 filter, struct file *pfile, int multishot,
  5739. const struct nls_table *nls_codepage)
  5740. {
  5741. int rc = 0;
  5742. struct smb_com_transaction_change_notify_req *pSMB = NULL;
  5743. struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
  5744. struct dir_notify_req *dnotify_req;
  5745. int bytes_returned;
  5746. cifs_dbg(FYI, "In CIFSSMBNotify for file handle %d\n", (int)netfid);
  5747. rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
  5748. (void **) &pSMBr);
  5749. if (rc)
  5750. return rc;
  5751. pSMB->TotalParameterCount = 0 ;
  5752. pSMB->TotalDataCount = 0;
  5753. pSMB->MaxParameterCount = cpu_to_le32(2);
  5754. pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
  5755. pSMB->MaxSetupCount = 4;
  5756. pSMB->Reserved = 0;
  5757. pSMB->ParameterOffset = 0;
  5758. pSMB->DataCount = 0;
  5759. pSMB->DataOffset = 0;
  5760. pSMB->SetupCount = 4; /* single byte does not need le conversion */
  5761. pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
  5762. pSMB->ParameterCount = pSMB->TotalParameterCount;
  5763. if (notify_subdirs)
  5764. pSMB->WatchTree = 1; /* one byte - no le conversion needed */
  5765. pSMB->Reserved2 = 0;
  5766. pSMB->CompletionFilter = cpu_to_le32(filter);
  5767. pSMB->Fid = netfid; /* file handle always le */
  5768. pSMB->ByteCount = 0;
  5769. rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
  5770. (struct smb_hdr *)pSMBr, &bytes_returned,
  5771. CIFS_ASYNC_OP);
  5772. if (rc) {
  5773. cifs_dbg(FYI, "Error in Notify = %d\n", rc);
  5774. } else {
  5775. /* Add file to outstanding requests */
  5776. /* BB change to kmem cache alloc */
  5777. dnotify_req = kmalloc(
  5778. sizeof(struct dir_notify_req),
  5779. GFP_KERNEL);
  5780. if (dnotify_req) {
  5781. dnotify_req->Pid = pSMB->hdr.Pid;
  5782. dnotify_req->PidHigh = pSMB->hdr.PidHigh;
  5783. dnotify_req->Mid = pSMB->hdr.Mid;
  5784. dnotify_req->Tid = pSMB->hdr.Tid;
  5785. dnotify_req->Uid = pSMB->hdr.Uid;
  5786. dnotify_req->netfid = netfid;
  5787. dnotify_req->pfile = pfile;
  5788. dnotify_req->filter = filter;
  5789. dnotify_req->multishot = multishot;
  5790. spin_lock(&GlobalMid_Lock);
  5791. list_add_tail(&dnotify_req->lhead,
  5792. &GlobalDnotifyReqList);
  5793. spin_unlock(&GlobalMid_Lock);
  5794. } else
  5795. rc = -ENOMEM;
  5796. }
  5797. cifs_buf_release(pSMB);
  5798. return rc;
  5799. }
  5800. #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */