yaffs_vfs.c 87 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665
  1. /*
  2. * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  3. *
  4. * Copyright (C) 2002-2011 Aleph One Ltd.
  5. * for Toby Churchill Ltd and Brightstar Engineering
  6. *
  7. * Created by Charles Manning <charles@aleph1.co.uk>
  8. * Acknowledgements:
  9. * Luc van OostenRyck for numerous patches.
  10. * Nick Bane for numerous patches.
  11. * Nick Bane for 2.5/2.6 integration.
  12. * Andras Toth for mknod rdev issue.
  13. * Michael Fischer for finding the problem with inode inconsistency.
  14. * Some code bodily lifted from JFFS
  15. *
  16. * This program is free software; you can redistribute it and/or modify
  17. * it under the terms of the GNU General Public License version 2 as
  18. * published by the Free Software Foundation.
  19. */
  20. /*
  21. *
  22. * This is the file system front-end to YAFFS that hooks it up to
  23. * the VFS.
  24. *
  25. * Special notes:
  26. * >> 2.4: sb->u.generic_sbp points to the struct yaffs_dev associated with
  27. * this superblock
  28. * >> 2.6: sb->s_fs_info points to the struct yaffs_dev associated with this
  29. * superblock
  30. * >> inode->u.generic_ip points to the associated struct yaffs_obj.
  31. */
  32. /*
  33. * There are two variants of the VFS glue code. This variant should compile
  34. * for any version of Linux.
  35. */
  36. #include <linux/version.h>
  37. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10))
  38. #define YAFFS_COMPILE_BACKGROUND
  39. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23))
  40. #define YAFFS_COMPILE_FREEZER
  41. #endif
  42. #endif
  43. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
  44. #define YAFFS_COMPILE_EXPORTFS
  45. #endif
  46. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
  47. #define YAFFS_USE_SETATTR_COPY
  48. #define YAFFS_USE_TRUNCATE_SETSIZE
  49. #endif
  50. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
  51. #define YAFFS_HAS_EVICT_INODE
  52. #endif
  53. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
  54. #define YAFFS_NEW_FOLLOW_LINK 1
  55. #else
  56. #define YAFFS_NEW_FOLLOW_LINK 0
  57. #endif
  58. #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
  59. #define YAFFS_HAS_WRITE_SUPER
  60. #endif
  61. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
  62. #include <linux/config.h>
  63. #endif
  64. #include <linux/kernel.h>
  65. #include <linux/module.h>
  66. #include <linux/slab.h>
  67. #include <linux/init.h>
  68. #include <linux/fs.h>
  69. #include <linux/proc_fs.h>
  70. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39))
  71. #include <linux/smp_lock.h>
  72. #endif
  73. #include <linux/pagemap.h>
  74. #include <linux/mtd/mtd.h>
  75. #include <linux/interrupt.h>
  76. #include <linux/string.h>
  77. #include <linux/ctype.h>
  78. #if (YAFFS_NEW_FOLLOW_LINK == 1)
  79. #include <linux/namei.h>
  80. #endif
  81. #ifdef YAFFS_COMPILE_EXPORTFS
  82. #include <linux/exportfs.h>
  83. #endif
  84. #ifdef YAFFS_COMPILE_BACKGROUND
  85. #include <linux/kthread.h>
  86. #include <linux/delay.h>
  87. #endif
  88. #ifdef YAFFS_COMPILE_FREEZER
  89. #include <linux/freezer.h>
  90. #endif
  91. #include <asm/div64.h>
  92. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
  93. #include <linux/statfs.h>
  94. #define UnlockPage(p) unlock_page(p)
  95. #define Page_Uptodate(page) test_bit(PG_uptodate, &(page)->flags)
  96. /* FIXME: use sb->s_id instead ? */
  97. #define yaffs_devname(sb, buf) bdevname(sb->s_bdev, buf)
  98. #else
  99. #include <linux/locks.h>
  100. #define BDEVNAME_SIZE 0
  101. #define yaffs_devname(sb, buf) kdevname(sb->s_dev)
  102. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0))
  103. /* added NCB 26/5/2006 for 2.4.25-vrs2-tcl1 kernel */
  104. #define __user
  105. #endif
  106. #endif
  107. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26))
  108. #define YPROC_ROOT (&proc_root)
  109. #else
  110. #define YPROC_ROOT NULL
  111. #endif
  112. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26))
  113. #define Y_INIT_TIMER(a) init_timer(a)
  114. #else
  115. #define Y_INIT_TIMER(a) init_timer_on_stack(a)
  116. #endif
  117. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 27))
  118. #define YAFFS_USE_WRITE_BEGIN_END 1
  119. #else
  120. #define YAFFS_USE_WRITE_BEGIN_END 0
  121. #endif
  122. #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
  123. #define YAFFS_SUPER_HAS_DIRTY
  124. #endif
  125. #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
  126. #define set_nlink(inode, count) do { (inode)->i_nlink = (count); } while(0)
  127. #endif
  128. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 28))
  129. static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size)
  130. {
  131. uint64_t result = partition_size;
  132. do_div(result, block_size);
  133. return (uint32_t) result;
  134. }
  135. #else
  136. #define YCALCBLOCKS(s, b) ((s)/(b))
  137. #endif
  138. #include <linux/uaccess.h>
  139. #include <linux/mtd/mtd.h>
  140. #include "yportenv.h"
  141. #include "yaffs_trace.h"
  142. #include "yaffs_guts.h"
  143. #include "yaffs_attribs.h"
  144. #include "yaffs_linux.h"
  145. #include "yaffs_mtdif.h"
  146. #include "yaffs_packedtags2.h"
  147. #include "yaffs_getblockinfo.h"
  148. unsigned int yaffs_trace_mask =
  149. YAFFS_TRACE_BAD_BLOCKS |
  150. YAFFS_TRACE_ALWAYS |
  151. 0;
  152. unsigned int yaffs_wr_attempts = YAFFS_WR_ATTEMPTS;
  153. unsigned int yaffs_auto_checkpoint = 1;
  154. unsigned int yaffs_gc_control = 1;
  155. unsigned int yaffs_bg_enable = 1;
  156. unsigned int yaffs_auto_select = 1;
  157. /* Module Parameters */
  158. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
  159. module_param(yaffs_trace_mask, uint, 0644);
  160. module_param(yaffs_wr_attempts, uint, 0644);
  161. module_param(yaffs_auto_checkpoint, uint, 0644);
  162. module_param(yaffs_gc_control, uint, 0644);
  163. module_param(yaffs_bg_enable, uint, 0644);
  164. #else
  165. MODULE_PARM(yaffs_trace_mask, "i");
  166. MODULE_PARM(yaffs_wr_attempts, "i");
  167. MODULE_PARM(yaffs_auto_checkpoint, "i");
  168. MODULE_PARM(yaffs_gc_control, "i");
  169. #endif
  170. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25))
  171. /* use iget and read_inode */
  172. #define Y_IGET(sb, inum) iget((sb), (inum))
  173. #else
  174. /* Call local equivalent */
  175. #define YAFFS_USE_OWN_IGET
  176. #define Y_IGET(sb, inum) yaffs_iget((sb), (inum))
  177. #endif
  178. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
  179. #define yaffs_inode_to_obj_lv(iptr) ((iptr)->i_private)
  180. #else
  181. #define yaffs_inode_to_obj_lv(iptr) ((iptr)->u.generic_ip)
  182. #endif
  183. #define yaffs_inode_to_obj(iptr) \
  184. ((struct yaffs_obj *)(yaffs_inode_to_obj_lv(iptr)))
  185. #define yaffs_dentry_to_obj(dptr) yaffs_inode_to_obj((dptr)->d_inode)
  186. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
  187. #define yaffs_super_to_dev(sb) ((struct yaffs_dev *)sb->s_fs_info)
  188. #else
  189. #define yaffs_super_to_dev(sb) ((struct yaffs_dev *)sb->u.generic_sbp)
  190. #endif
  191. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
  192. #define Y_CLEAR_INODE(i) clear_inode(i)
  193. #else
  194. #define Y_CLEAR_INODE(i) end_writeback(i)
  195. #endif
  196. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
  197. #define YAFFS_USE_DIR_ITERATE
  198. #endif
  199. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
  200. #define YAFFS_NEW_PROCFS
  201. #include <linux/seq_file.h>
  202. #endif
  203. #define update_dir_time(dir) do {\
  204. (dir)->i_ctime = (dir)->i_mtime = CURRENT_TIME; \
  205. } while (0)
  206. static void yaffs_fill_inode_from_obj(struct inode *inode,
  207. struct yaffs_obj *obj);
  208. static void yaffs_gross_lock(struct yaffs_dev *dev)
  209. {
  210. yaffs_trace(YAFFS_TRACE_LOCK, "yaffs locking %p", current);
  211. mutex_lock(&(yaffs_dev_to_lc(dev)->gross_lock));
  212. yaffs_trace(YAFFS_TRACE_LOCK, "yaffs locked %p", current);
  213. }
  214. static void yaffs_gross_unlock(struct yaffs_dev *dev)
  215. {
  216. yaffs_trace(YAFFS_TRACE_LOCK, "yaffs unlocking %p", current);
  217. mutex_unlock(&(yaffs_dev_to_lc(dev)->gross_lock));
  218. }
  219. static int yaffs_readpage_nolock(struct file *f, struct page *pg)
  220. {
  221. /* Lifted from jffs2 */
  222. struct yaffs_obj *obj;
  223. unsigned char *pg_buf;
  224. int ret;
  225. loff_t pos = ((loff_t) pg->index) << PAGE_CACHE_SHIFT;
  226. struct yaffs_dev *dev;
  227. yaffs_trace(YAFFS_TRACE_OS,
  228. "yaffs_readpage_nolock at %lld, size %08x",
  229. (long long)pos,
  230. (unsigned)PAGE_CACHE_SIZE);
  231. obj = yaffs_dentry_to_obj(f->f_dentry);
  232. dev = obj->my_dev;
  233. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
  234. BUG_ON(!PageLocked(pg));
  235. #else
  236. if (!PageLocked(pg))
  237. PAGE_BUG(pg);
  238. #endif
  239. pg_buf = kmap(pg);
  240. /* FIXME: Can kmap fail? */
  241. yaffs_gross_lock(dev);
  242. ret = yaffs_file_rd(obj, pg_buf, pos, PAGE_CACHE_SIZE);
  243. yaffs_gross_unlock(dev);
  244. if (ret >= 0)
  245. ret = 0;
  246. if (ret) {
  247. ClearPageUptodate(pg);
  248. SetPageError(pg);
  249. } else {
  250. SetPageUptodate(pg);
  251. ClearPageError(pg);
  252. }
  253. flush_dcache_page(pg);
  254. kunmap(pg);
  255. yaffs_trace(YAFFS_TRACE_OS, "yaffs_readpage_nolock done");
  256. return ret;
  257. }
  258. static int yaffs_readpage_unlock(struct file *f, struct page *pg)
  259. {
  260. int ret = yaffs_readpage_nolock(f, pg);
  261. UnlockPage(pg);
  262. return ret;
  263. }
  264. static int yaffs_readpage(struct file *f, struct page *pg)
  265. {
  266. int ret;
  267. yaffs_trace(YAFFS_TRACE_OS, "yaffs_readpage");
  268. ret = yaffs_readpage_unlock(f, pg);
  269. yaffs_trace(YAFFS_TRACE_OS, "yaffs_readpage done");
  270. return ret;
  271. }
  272. static void yaffs_set_super_dirty_val(struct yaffs_dev *dev, int val)
  273. {
  274. struct yaffs_linux_context *lc = yaffs_dev_to_lc(dev);
  275. if (lc)
  276. lc->dirty = val;
  277. # ifdef YAFFS_SUPER_HAS_DIRTY
  278. {
  279. struct super_block *sb = lc->super;
  280. if (sb)
  281. sb->s_dirt = val;
  282. }
  283. #endif
  284. }
  285. static void yaffs_set_super_dirty(struct yaffs_dev *dev)
  286. {
  287. yaffs_set_super_dirty_val(dev, 1);
  288. }
  289. static void yaffs_clear_super_dirty(struct yaffs_dev *dev)
  290. {
  291. yaffs_set_super_dirty_val(dev, 0);
  292. }
  293. static int yaffs_check_super_dirty(struct yaffs_dev *dev)
  294. {
  295. struct yaffs_linux_context *lc = yaffs_dev_to_lc(dev);
  296. if (lc && lc->dirty)
  297. return 1;
  298. # ifdef YAFFS_SUPER_HAS_DIRTY
  299. {
  300. struct super_block *sb = lc->super;
  301. if (sb && sb->s_dirt)
  302. return 1;
  303. }
  304. #endif
  305. return 0;
  306. }
  307. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
  308. static int yaffs_writepage(struct page *page, struct writeback_control *wbc)
  309. #else
  310. static int yaffs_writepage(struct page *page)
  311. #endif
  312. {
  313. struct yaffs_dev *dev;
  314. struct address_space *mapping = page->mapping;
  315. struct inode *inode;
  316. unsigned long end_index;
  317. char *buffer;
  318. struct yaffs_obj *obj;
  319. int n_written = 0;
  320. unsigned n_bytes;
  321. loff_t i_size;
  322. if (!mapping)
  323. BUG();
  324. inode = mapping->host;
  325. if (!inode)
  326. BUG();
  327. i_size = i_size_read(inode);
  328. end_index = i_size >> PAGE_CACHE_SHIFT;
  329. if (page->index < end_index)
  330. n_bytes = PAGE_CACHE_SIZE;
  331. else {
  332. n_bytes = i_size & (PAGE_CACHE_SIZE - 1);
  333. if (page->index > end_index || !n_bytes) {
  334. yaffs_trace(YAFFS_TRACE_OS,
  335. "yaffs_writepage at %lld, inode size = %lld!!",
  336. ((loff_t)page->index) << PAGE_CACHE_SHIFT,
  337. inode->i_size);
  338. yaffs_trace(YAFFS_TRACE_OS,
  339. " -> don't care!!");
  340. zero_user_segment(page, 0, PAGE_CACHE_SIZE);
  341. set_page_writeback(page);
  342. unlock_page(page);
  343. end_page_writeback(page);
  344. return 0;
  345. }
  346. }
  347. if (n_bytes != PAGE_CACHE_SIZE)
  348. zero_user_segment(page, n_bytes, PAGE_CACHE_SIZE);
  349. get_page(page);
  350. buffer = kmap(page);
  351. obj = yaffs_inode_to_obj(inode);
  352. dev = obj->my_dev;
  353. yaffs_gross_lock(dev);
  354. yaffs_trace(YAFFS_TRACE_OS,
  355. "yaffs_writepage at %lld, size %08x",
  356. ((loff_t)page->index) << PAGE_CACHE_SHIFT, n_bytes);
  357. yaffs_trace(YAFFS_TRACE_OS,
  358. "writepag0: obj = %lld, ino = %lld",
  359. obj->variant.file_variant.file_size, inode->i_size);
  360. n_written = yaffs_wr_file(obj, buffer,
  361. ((loff_t)page->index) << PAGE_CACHE_SHIFT, n_bytes, 0);
  362. yaffs_set_super_dirty(dev);
  363. yaffs_trace(YAFFS_TRACE_OS,
  364. "writepag1: obj = %lld, ino = %lld",
  365. obj->variant.file_variant.file_size, inode->i_size);
  366. yaffs_gross_unlock(dev);
  367. kunmap(page);
  368. set_page_writeback(page);
  369. unlock_page(page);
  370. end_page_writeback(page);
  371. put_page(page);
  372. return (n_written == n_bytes) ? 0 : -ENOSPC;
  373. }
  374. /* Space holding and freeing is done to ensure we have space available for write_begin/end */
  375. /* For now we just assume few parallel writes and check against a small number. */
  376. /* Todo: need to do this with a counter to handle parallel reads better */
  377. static ssize_t yaffs_hold_space(struct file *f)
  378. {
  379. struct yaffs_obj *obj;
  380. struct yaffs_dev *dev;
  381. int n_free_chunks;
  382. obj = yaffs_dentry_to_obj(f->f_dentry);
  383. dev = obj->my_dev;
  384. yaffs_gross_lock(dev);
  385. n_free_chunks = yaffs_get_n_free_chunks(dev);
  386. yaffs_gross_unlock(dev);
  387. return (n_free_chunks > 20) ? 1 : 0;
  388. }
  389. static void yaffs_release_space(struct file *f)
  390. {
  391. struct yaffs_obj *obj;
  392. struct yaffs_dev *dev;
  393. obj = yaffs_dentry_to_obj(f->f_dentry);
  394. dev = obj->my_dev;
  395. yaffs_gross_lock(dev);
  396. yaffs_gross_unlock(dev);
  397. }
  398. #if (YAFFS_USE_WRITE_BEGIN_END > 0)
  399. static int yaffs_write_begin(struct file *filp, struct address_space *mapping,
  400. loff_t pos, unsigned len, unsigned flags,
  401. struct page **pagep, void **fsdata)
  402. {
  403. struct page *pg = NULL;
  404. pgoff_t index = pos >> PAGE_CACHE_SHIFT;
  405. int ret = 0;
  406. int space_held = 0;
  407. /* Get a page */
  408. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
  409. pg = grab_cache_page_write_begin(mapping, index, flags);
  410. #else
  411. pg = __grab_cache_page(mapping, index);
  412. #endif
  413. *pagep = pg;
  414. if (!pg) {
  415. ret = -ENOMEM;
  416. goto out;
  417. }
  418. yaffs_trace(YAFFS_TRACE_OS,
  419. "start yaffs_write_begin index %d(%x) uptodate %d",
  420. (int)index, (int)index, Page_Uptodate(pg) ? 1 : 0);
  421. /* Get fs space */
  422. space_held = yaffs_hold_space(filp);
  423. if (!space_held) {
  424. ret = -ENOSPC;
  425. goto out;
  426. }
  427. /* Update page if required */
  428. if (!Page_Uptodate(pg))
  429. ret = yaffs_readpage_nolock(filp, pg);
  430. if (ret)
  431. goto out;
  432. /* Happy path return */
  433. yaffs_trace(YAFFS_TRACE_OS, "end yaffs_write_begin - ok");
  434. return 0;
  435. out:
  436. yaffs_trace(YAFFS_TRACE_OS,
  437. "end yaffs_write_begin fail returning %d", ret);
  438. if (space_held)
  439. yaffs_release_space(filp);
  440. if (pg) {
  441. unlock_page(pg);
  442. page_cache_release(pg);
  443. }
  444. return ret;
  445. }
  446. #else
  447. static int yaffs_prepare_write(struct file *f, struct page *pg,
  448. unsigned offset, unsigned to)
  449. {
  450. yaffs_trace(YAFFS_TRACE_OS, "yaffs_prepair_write");
  451. if (!Page_Uptodate(pg))
  452. return yaffs_readpage_nolock(f, pg);
  453. return 0;
  454. }
  455. #endif
  456. static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
  457. loff_t * pos)
  458. {
  459. struct yaffs_obj *obj;
  460. int n_written;
  461. loff_t ipos;
  462. struct inode *inode;
  463. struct yaffs_dev *dev;
  464. obj = yaffs_dentry_to_obj(f->f_dentry);
  465. if (!obj) {
  466. yaffs_trace(YAFFS_TRACE_OS,
  467. "yaffs_file_write: hey obj is null!");
  468. return -EINVAL;
  469. }
  470. dev = obj->my_dev;
  471. yaffs_gross_lock(dev);
  472. inode = f->f_dentry->d_inode;
  473. if (!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND)
  474. ipos = inode->i_size;
  475. else
  476. ipos = *pos;
  477. yaffs_trace(YAFFS_TRACE_OS,
  478. "yaffs_file_write about to write writing %u(%x) bytes to object %d at %lld",
  479. (unsigned)n, (unsigned)n, obj->obj_id, ipos);
  480. n_written = yaffs_wr_file(obj, buf, ipos, n, 0);
  481. yaffs_set_super_dirty(dev);
  482. yaffs_trace(YAFFS_TRACE_OS,
  483. "yaffs_file_write: %d(%x) bytes written",
  484. (unsigned)n, (unsigned)n);
  485. if (n_written > 0) {
  486. ipos += n_written;
  487. *pos = ipos;
  488. if (ipos > inode->i_size) {
  489. inode->i_size = ipos;
  490. inode->i_blocks = (ipos + 511) >> 9;
  491. yaffs_trace(YAFFS_TRACE_OS,
  492. "yaffs_file_write size updated to %lld bytes, %d blocks",
  493. ipos, (int)(inode->i_blocks));
  494. }
  495. }
  496. yaffs_gross_unlock(dev);
  497. return (n_written == 0) && (n > 0) ? -ENOSPC : n_written;
  498. }
  499. #if (YAFFS_USE_WRITE_BEGIN_END > 0)
  500. static int yaffs_write_end(struct file *filp, struct address_space *mapping,
  501. loff_t pos, unsigned len, unsigned copied,
  502. struct page *pg, void *fsdadata)
  503. {
  504. int ret = 0;
  505. void *addr, *kva;
  506. uint32_t offset_into_page = pos & (PAGE_CACHE_SIZE - 1);
  507. kva = kmap(pg);
  508. addr = kva + offset_into_page;
  509. yaffs_trace(YAFFS_TRACE_OS,
  510. "yaffs_write_end addr %p pos %lld n_bytes %d",
  511. addr, pos, copied);
  512. ret = yaffs_file_write(filp, addr, copied, &pos);
  513. if (ret != copied) {
  514. yaffs_trace(YAFFS_TRACE_OS,
  515. "yaffs_write_end not same size ret %d copied %d",
  516. ret, copied);
  517. SetPageError(pg);
  518. }
  519. kunmap(pg);
  520. yaffs_release_space(filp);
  521. unlock_page(pg);
  522. page_cache_release(pg);
  523. return ret;
  524. }
  525. #else
  526. static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset,
  527. unsigned to)
  528. {
  529. void *addr, *kva;
  530. loff_t pos = (((loff_t) pg->index) << PAGE_CACHE_SHIFT) + offset;
  531. int n_bytes = to - offset;
  532. int n_written;
  533. kva = kmap(pg);
  534. addr = kva + offset;
  535. yaffs_trace(YAFFS_TRACE_OS,
  536. "yaffs_commit_write addr %p pos %lld n_bytes %d",
  537. addr, pos, n_bytes);
  538. n_written = yaffs_file_write(f, addr, n_bytes, &pos);
  539. if (n_written != n_bytes) {
  540. yaffs_trace(YAFFS_TRACE_OS,
  541. "yaffs_commit_write not same size n_written %d n_bytes %d",
  542. n_written, n_bytes);
  543. SetPageError(pg);
  544. }
  545. kunmap(pg);
  546. yaffs_trace(YAFFS_TRACE_OS,
  547. "yaffs_commit_write returning %d",
  548. n_written == n_bytes ? 0 : n_written);
  549. return n_written == n_bytes ? 0 : n_written;
  550. }
  551. #endif
  552. static struct address_space_operations yaffs_file_address_operations = {
  553. .readpage = yaffs_readpage,
  554. .writepage = yaffs_writepage,
  555. #if (YAFFS_USE_WRITE_BEGIN_END > 0)
  556. .write_begin = yaffs_write_begin,
  557. .write_end = yaffs_write_end,
  558. #else
  559. .prepare_write = yaffs_prepare_write,
  560. .commit_write = yaffs_commit_write,
  561. #endif
  562. };
  563. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
  564. static int yaffs_file_flush(struct file *file, fl_owner_t id)
  565. #else
  566. static int yaffs_file_flush(struct file *file)
  567. #endif
  568. {
  569. struct yaffs_obj *obj = yaffs_dentry_to_obj(file->f_dentry);
  570. struct yaffs_dev *dev = obj->my_dev;
  571. yaffs_trace(YAFFS_TRACE_OS,
  572. "yaffs_file_flush object %d (%s)",
  573. obj->obj_id,
  574. obj->dirty ? "dirty" : "clean");
  575. yaffs_gross_lock(dev);
  576. yaffs_flush_file(obj, 1, 0, 0);
  577. yaffs_gross_unlock(dev);
  578. return 0;
  579. }
  580. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
  581. static int yaffs_sync_object(struct file *file, loff_t start, loff_t end, int datasync)
  582. #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34))
  583. static int yaffs_sync_object(struct file *file, int datasync)
  584. #else
  585. static int yaffs_sync_object(struct file *file, struct dentry *dentry,
  586. int datasync)
  587. #endif
  588. {
  589. struct yaffs_obj *obj;
  590. struct yaffs_dev *dev;
  591. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34))
  592. struct dentry *dentry = file->f_path.dentry;
  593. #endif
  594. obj = yaffs_dentry_to_obj(dentry);
  595. dev = obj->my_dev;
  596. yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC,
  597. "yaffs_sync_object");
  598. yaffs_gross_lock(dev);
  599. yaffs_flush_file(obj, 1, datasync, 0);
  600. yaffs_gross_unlock(dev);
  601. return 0;
  602. }
  603. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22))
  604. static const struct file_operations yaffs_file_operations = {
  605. .read = do_sync_read,
  606. .write = do_sync_write,
  607. .aio_read = generic_file_aio_read,
  608. .aio_write = generic_file_aio_write,
  609. .mmap = generic_file_mmap,
  610. .flush = yaffs_file_flush,
  611. .fsync = yaffs_sync_object,
  612. .splice_read = generic_file_splice_read,
  613. .splice_write = generic_file_splice_write,
  614. .llseek = generic_file_llseek,
  615. };
  616. #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
  617. static const struct file_operations yaffs_file_operations = {
  618. .read = do_sync_read,
  619. .write = do_sync_write,
  620. .aio_read = generic_file_aio_read,
  621. .aio_write = generic_file_aio_write,
  622. .mmap = generic_file_mmap,
  623. .flush = yaffs_file_flush,
  624. .fsync = yaffs_sync_object,
  625. .sendfile = generic_file_sendfile,
  626. };
  627. #else
  628. static const struct file_operations yaffs_file_operations = {
  629. .read = generic_file_read,
  630. .write = generic_file_write,
  631. .mmap = generic_file_mmap,
  632. .flush = yaffs_file_flush,
  633. .fsync = yaffs_sync_object,
  634. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
  635. .sendfile = generic_file_sendfile,
  636. #endif
  637. };
  638. #endif
  639. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25))
  640. static void zero_user_segment(struct page *page, unsigned start, unsigned end)
  641. {
  642. void *kaddr = kmap_atomic(page, KM_USER0);
  643. memset(kaddr + start, 0, end - start);
  644. kunmap_atomic(kaddr, KM_USER0);
  645. flush_dcache_page(page);
  646. }
  647. #endif
  648. static int yaffs_vfs_setsize(struct inode *inode, loff_t newsize)
  649. {
  650. #ifdef YAFFS_USE_TRUNCATE_SETSIZE
  651. truncate_setsize(inode, newsize);
  652. return 0;
  653. #else
  654. truncate_inode_pages(&inode->i_data, newsize);
  655. return 0;
  656. #endif
  657. }
  658. static int yaffs_vfs_setattr(struct inode *inode, struct iattr *attr)
  659. {
  660. #ifdef YAFFS_USE_SETATTR_COPY
  661. setattr_copy(inode, attr);
  662. return 0;
  663. #else
  664. return inode_setattr(inode, attr);
  665. #endif
  666. }
  667. static int yaffs_setattr(struct dentry *dentry, struct iattr *attr)
  668. {
  669. struct inode *inode = dentry->d_inode;
  670. int error = 0;
  671. struct yaffs_dev *dev;
  672. yaffs_trace(YAFFS_TRACE_OS,
  673. "yaffs_setattr of object %d",
  674. yaffs_inode_to_obj(inode)->obj_id);
  675. #if 0
  676. /* Fail if a requested resize >= 2GB */
  677. if (attr->ia_valid & ATTR_SIZE && (attr->ia_size >> 31))
  678. error = -EINVAL;
  679. #endif
  680. if (error == 0)
  681. error = inode_change_ok(inode, attr);
  682. if (error == 0) {
  683. int result;
  684. if (!error) {
  685. error = yaffs_vfs_setattr(inode, attr);
  686. yaffs_trace(YAFFS_TRACE_OS, "inode_setattr called");
  687. if (attr->ia_valid & ATTR_SIZE) {
  688. yaffs_vfs_setsize(inode, attr->ia_size);
  689. inode->i_blocks = (inode->i_size + 511) >> 9;
  690. }
  691. }
  692. dev = yaffs_inode_to_obj(inode)->my_dev;
  693. if (attr->ia_valid & ATTR_SIZE) {
  694. yaffs_trace(YAFFS_TRACE_OS,
  695. "resize to %d(%x)",
  696. (int)(attr->ia_size),
  697. (int)(attr->ia_size));
  698. }
  699. yaffs_gross_lock(dev);
  700. result = yaffs_set_attribs(yaffs_inode_to_obj(inode), attr);
  701. if (result == YAFFS_OK) {
  702. error = 0;
  703. } else {
  704. error = -EPERM;
  705. }
  706. yaffs_gross_unlock(dev);
  707. }
  708. yaffs_trace(YAFFS_TRACE_OS, "yaffs_setattr done returning %d", error);
  709. return error;
  710. }
  711. static int yaffs_setxattr(struct dentry *dentry, const char *name,
  712. const void *value, size_t size, int flags)
  713. {
  714. struct inode *inode = dentry->d_inode;
  715. int error = 0;
  716. struct yaffs_dev *dev;
  717. struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
  718. yaffs_trace(YAFFS_TRACE_OS, "yaffs_setxattr of object %d", obj->obj_id);
  719. if (error == 0) {
  720. int result;
  721. dev = obj->my_dev;
  722. yaffs_gross_lock(dev);
  723. result = yaffs_set_xattrib(obj, name, value, size, flags);
  724. if (result == YAFFS_OK)
  725. error = 0;
  726. else if (result < 0)
  727. error = result;
  728. yaffs_gross_unlock(dev);
  729. }
  730. yaffs_trace(YAFFS_TRACE_OS, "yaffs_setxattr done returning %d", error);
  731. return error;
  732. }
  733. static ssize_t yaffs_getxattr(struct dentry * dentry, const char *name,
  734. void *buff, size_t size)
  735. {
  736. struct inode *inode = dentry->d_inode;
  737. int error = 0;
  738. struct yaffs_dev *dev;
  739. struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
  740. yaffs_trace(YAFFS_TRACE_OS,
  741. "yaffs_getxattr \"%s\" from object %d",
  742. name, obj->obj_id);
  743. if (error == 0) {
  744. dev = obj->my_dev;
  745. yaffs_gross_lock(dev);
  746. error = yaffs_get_xattrib(obj, name, buff, size);
  747. yaffs_gross_unlock(dev);
  748. }
  749. yaffs_trace(YAFFS_TRACE_OS, "yaffs_getxattr done returning %d", error);
  750. return error;
  751. }
  752. static int yaffs_removexattr(struct dentry *dentry, const char *name)
  753. {
  754. struct inode *inode = dentry->d_inode;
  755. int error = 0;
  756. struct yaffs_dev *dev;
  757. struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
  758. yaffs_trace(YAFFS_TRACE_OS,
  759. "yaffs_removexattr of object %d", obj->obj_id);
  760. if (error == 0) {
  761. int result;
  762. dev = obj->my_dev;
  763. yaffs_gross_lock(dev);
  764. result = yaffs_remove_xattrib(obj, name);
  765. if (result == YAFFS_OK)
  766. error = 0;
  767. else if (result < 0)
  768. error = result;
  769. yaffs_gross_unlock(dev);
  770. }
  771. yaffs_trace(YAFFS_TRACE_OS,
  772. "yaffs_removexattr done returning %d", error);
  773. return error;
  774. }
  775. static ssize_t yaffs_listxattr(struct dentry * dentry, char *buff, size_t size)
  776. {
  777. struct inode *inode = dentry->d_inode;
  778. int error = 0;
  779. struct yaffs_dev *dev;
  780. struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
  781. yaffs_trace(YAFFS_TRACE_OS,
  782. "yaffs_listxattr of object %d", obj->obj_id);
  783. if (error == 0) {
  784. dev = obj->my_dev;
  785. yaffs_gross_lock(dev);
  786. error = yaffs_list_xattrib(obj, buff, size);
  787. yaffs_gross_unlock(dev);
  788. }
  789. yaffs_trace(YAFFS_TRACE_OS,
  790. "yaffs_listxattr done returning %d", error);
  791. return error;
  792. }
  793. static const struct inode_operations yaffs_file_inode_operations = {
  794. .setattr = yaffs_setattr,
  795. .setxattr = yaffs_setxattr,
  796. .getxattr = yaffs_getxattr,
  797. .listxattr = yaffs_listxattr,
  798. .removexattr = yaffs_removexattr,
  799. };
  800. static int yaffs_readlink(struct dentry *dentry, char __user * buffer,
  801. int buflen)
  802. {
  803. unsigned char *alias;
  804. int ret;
  805. struct yaffs_dev *dev = yaffs_dentry_to_obj(dentry)->my_dev;
  806. yaffs_gross_lock(dev);
  807. alias = yaffs_get_symlink_alias(yaffs_dentry_to_obj(dentry));
  808. yaffs_gross_unlock(dev);
  809. if (!alias)
  810. return -ENOMEM;
  811. #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0)
  812. ret = vfs_readlink(dentry, buffer, buflen, alias);
  813. #else
  814. ret = readlink_copy(buffer, buflen, alias);
  815. #endif
  816. kfree(alias);
  817. return ret;
  818. }
  819. #if (YAFFS_NEW_FOLLOW_LINK == 1)
  820. static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
  821. {
  822. void *ret;
  823. #else
  824. static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
  825. {
  826. int ret
  827. #endif
  828. unsigned char *alias;
  829. int ret_int = 0;
  830. struct yaffs_dev *dev = yaffs_dentry_to_obj(dentry)->my_dev;
  831. yaffs_gross_lock(dev);
  832. alias = yaffs_get_symlink_alias(yaffs_dentry_to_obj(dentry));
  833. yaffs_gross_unlock(dev);
  834. if (!alias) {
  835. ret_int = -ENOMEM;
  836. goto out;
  837. }
  838. #if (YAFFS_NEW_FOLLOW_LINK == 1)
  839. nd_set_link(nd, alias);
  840. ret = alias;
  841. out:
  842. if (ret_int)
  843. ret = ERR_PTR(ret_int);
  844. return ret;
  845. #else
  846. ret = vfs_follow_link(nd, alias);
  847. kfree(alias);
  848. out:
  849. if (ret_int)
  850. ret = ret_int;
  851. return ret;
  852. #endif
  853. }
  854. #ifdef YAFFS_HAS_PUT_INODE
  855. /* For now put inode is just for debugging
  856. * Put inode is called when the inode **structure** is put.
  857. */
  858. static void yaffs_put_inode(struct inode *inode)
  859. {
  860. yaffs_trace(YAFFS_TRACE_OS,
  861. "yaffs_put_inode: ino %d, count %d"),
  862. (int)inode->i_ino, atomic_read(&inode->i_count);
  863. }
  864. #endif
  865. #if (YAFFS_NEW_FOLLOW_LINK == 1)
  866. void yaffs_put_link(struct dentry *dentry, struct nameidata *nd, void *alias)
  867. {
  868. kfree(alias);
  869. }
  870. #endif
  871. static const struct inode_operations yaffs_symlink_inode_operations = {
  872. .readlink = yaffs_readlink,
  873. .follow_link = yaffs_follow_link,
  874. #if (YAFFS_NEW_FOLLOW_LINK == 1)
  875. .put_link = yaffs_put_link,
  876. #endif
  877. .setattr = yaffs_setattr,
  878. .setxattr = yaffs_setxattr,
  879. .getxattr = yaffs_getxattr,
  880. .listxattr = yaffs_listxattr,
  881. .removexattr = yaffs_removexattr,
  882. };
  883. #ifdef YAFFS_USE_OWN_IGET
  884. static struct inode *yaffs_iget(struct super_block *sb, unsigned long ino)
  885. {
  886. struct inode *inode;
  887. struct yaffs_obj *obj;
  888. struct yaffs_dev *dev = yaffs_super_to_dev(sb);
  889. yaffs_trace(YAFFS_TRACE_OS, "yaffs_iget for %lu", ino);
  890. inode = iget_locked(sb, ino);
  891. if (!inode)
  892. return ERR_PTR(-ENOMEM);
  893. if (!(inode->i_state & I_NEW))
  894. return inode;
  895. /* NB This is called as a side effect of other functions, but
  896. * we had to release the lock to prevent deadlocks, so
  897. * need to lock again.
  898. */
  899. yaffs_gross_lock(dev);
  900. obj = yaffs_find_by_number(dev, inode->i_ino);
  901. yaffs_fill_inode_from_obj(inode, obj);
  902. yaffs_gross_unlock(dev);
  903. unlock_new_inode(inode);
  904. return inode;
  905. }
  906. #else
  907. static void yaffs_read_inode(struct inode *inode)
  908. {
  909. /* NB This is called as a side effect of other functions, but
  910. * we had to release the lock to prevent deadlocks, so
  911. * need to lock again.
  912. */
  913. struct yaffs_obj *obj;
  914. struct yaffs_dev *dev = yaffs_super_to_dev(inode->i_sb);
  915. yaffs_trace(YAFFS_TRACE_OS,
  916. "yaffs_read_inode for %d", (int)inode->i_ino);
  917. if (current != yaffs_dev_to_lc(dev)->readdir_process)
  918. yaffs_gross_lock(dev);
  919. obj = yaffs_find_by_number(dev, inode->i_ino);
  920. yaffs_fill_inode_from_obj(inode, obj);
  921. if (current != yaffs_dev_to_lc(dev)->readdir_process)
  922. yaffs_gross_unlock(dev);
  923. }
  924. #endif
  925. struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,
  926. struct yaffs_obj *obj)
  927. {
  928. struct inode *inode;
  929. if (!sb) {
  930. yaffs_trace(YAFFS_TRACE_OS,
  931. "yaffs_get_inode for NULL super_block!!");
  932. return NULL;
  933. }
  934. if (!obj) {
  935. yaffs_trace(YAFFS_TRACE_OS,
  936. "yaffs_get_inode for NULL object!!");
  937. return NULL;
  938. }
  939. yaffs_trace(YAFFS_TRACE_OS,
  940. "yaffs_get_inode for object %d", obj->obj_id);
  941. inode = Y_IGET(sb, obj->obj_id);
  942. if (IS_ERR(inode))
  943. return NULL;
  944. /* NB Side effect: iget calls back to yaffs_read_inode(). */
  945. /* iget also increments the inode's i_count */
  946. /* NB You can't be holding gross_lock or deadlock will happen! */
  947. return inode;
  948. }
  949. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
  950. #define YCRED(x) x
  951. #else
  952. #define YCRED(x) (x->cred)
  953. #endif
  954. #if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)
  955. #define YPROC_uid(p) (YCRED(p)->fsuid)
  956. #define YPROC_gid(p) (YCRED(p)->fsgid)
  957. #define EXTRACT_gid(x) x
  958. #define EXTRACT_uid(x) x
  959. #define MAKE_gid(x) x
  960. #define MAKE_uid(x) x
  961. #else
  962. #define YPROC_uid(p) from_kuid(&init_user_ns, YCRED(p)->fsuid)
  963. #define YPROC_gid(p) from_kgid(&init_user_ns, YCRED(p)->fsgid)
  964. #define EXTRACT_gid(x) from_kgid(&init_user_ns, x)
  965. #define EXTRACT_uid(x) from_kuid(&init_user_ns, x)
  966. #define MAKE_gid(x) make_kgid(&init_user_ns, x)
  967. #define MAKE_uid(x) make_kuid(&init_user_ns, x)
  968. #endif
  969. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
  970. static int yaffs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
  971. dev_t rdev)
  972. #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
  973. static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
  974. dev_t rdev)
  975. #else
  976. static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
  977. int rdev)
  978. #endif
  979. {
  980. struct inode *inode;
  981. struct yaffs_obj *obj = NULL;
  982. struct yaffs_dev *dev;
  983. struct yaffs_obj *parent = yaffs_inode_to_obj(dir);
  984. int error = -ENOSPC;
  985. uid_t uid = YPROC_uid(current);
  986. gid_t gid =
  987. (dir->i_mode & S_ISGID) ? EXTRACT_gid(dir->i_gid) : YPROC_gid(current);
  988. if ((dir->i_mode & S_ISGID) && S_ISDIR(mode))
  989. mode |= S_ISGID;
  990. if (parent) {
  991. yaffs_trace(YAFFS_TRACE_OS,
  992. "yaffs_mknod: parent object %d type %d",
  993. parent->obj_id, parent->variant_type);
  994. } else {
  995. yaffs_trace(YAFFS_TRACE_OS,
  996. "yaffs_mknod: could not get parent object");
  997. return -EPERM;
  998. }
  999. yaffs_trace(YAFFS_TRACE_OS,
  1000. "yaffs_mknod: making oject for %s, mode %x dev %x",
  1001. dentry->d_name.name, mode, rdev);
  1002. dev = parent->my_dev;
  1003. yaffs_gross_lock(dev);
  1004. switch (mode & S_IFMT) {
  1005. default:
  1006. /* Special (socket, fifo, device...) */
  1007. yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod: making special");
  1008. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
  1009. obj =
  1010. yaffs_create_special(parent, dentry->d_name.name, mode, uid,
  1011. gid, old_encode_dev(rdev));
  1012. #else
  1013. obj =
  1014. yaffs_create_special(parent, dentry->d_name.name, mode, uid,
  1015. gid, rdev);
  1016. #endif
  1017. break;
  1018. case S_IFREG: /* file */
  1019. yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod: making file");
  1020. obj = yaffs_create_file(parent, dentry->d_name.name, mode, uid,
  1021. gid);
  1022. break;
  1023. case S_IFDIR: /* directory */
  1024. yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod: making directory");
  1025. obj = yaffs_create_dir(parent, dentry->d_name.name, mode,
  1026. uid, gid);
  1027. break;
  1028. case S_IFLNK: /* symlink */
  1029. yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod: making symlink");
  1030. obj = NULL; /* Do we ever get here? */
  1031. break;
  1032. }
  1033. /* Can not call yaffs_get_inode() with gross lock held */
  1034. yaffs_gross_unlock(dev);
  1035. if (obj) {
  1036. inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj);
  1037. d_instantiate(dentry, inode);
  1038. update_dir_time(dir);
  1039. yaffs_trace(YAFFS_TRACE_OS,
  1040. "yaffs_mknod created object %d count = %d",
  1041. obj->obj_id, atomic_read(&inode->i_count));
  1042. error = 0;
  1043. yaffs_fill_inode_from_obj(dir, parent);
  1044. } else {
  1045. yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod failed making object");
  1046. error = -ENOMEM;
  1047. }
  1048. return error;
  1049. }
  1050. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
  1051. static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
  1052. #else
  1053. static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
  1054. #endif
  1055. {
  1056. int ret_val;
  1057. yaffs_trace(YAFFS_TRACE_OS, "yaffs_mkdir");
  1058. ret_val = yaffs_mknod(dir, dentry, mode | S_IFDIR, 0);
  1059. return ret_val;
  1060. }
  1061. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
  1062. static int yaffs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
  1063. bool dummy)
  1064. #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
  1065. static int yaffs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
  1066. struct nameidata *n)
  1067. #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
  1068. static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode,
  1069. struct nameidata *n)
  1070. #else
  1071. static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode)
  1072. #endif
  1073. {
  1074. yaffs_trace(YAFFS_TRACE_OS, "yaffs_create");
  1075. return yaffs_mknod(dir, dentry, mode | S_IFREG, 0);
  1076. }
  1077. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
  1078. static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry,
  1079. unsigned int dummy)
  1080. #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
  1081. static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry,
  1082. struct nameidata *n)
  1083. #else
  1084. static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry)
  1085. #endif
  1086. {
  1087. struct yaffs_obj *obj;
  1088. struct inode *inode = NULL; /* NCB 2.5/2.6 needs NULL here */
  1089. struct yaffs_dev *dev = yaffs_inode_to_obj(dir)->my_dev;
  1090. if (current != yaffs_dev_to_lc(dev)->readdir_process)
  1091. yaffs_gross_lock(dev);
  1092. yaffs_trace(YAFFS_TRACE_OS, "yaffs_lookup for %d:%s",
  1093. yaffs_inode_to_obj(dir)->obj_id, dentry->d_name.name);
  1094. obj = yaffs_find_by_name(yaffs_inode_to_obj(dir), dentry->d_name.name);
  1095. obj = yaffs_get_equivalent_obj(obj); /* in case it was a hardlink */
  1096. /* Can't hold gross lock when calling yaffs_get_inode() */
  1097. if (current != yaffs_dev_to_lc(dev)->readdir_process)
  1098. yaffs_gross_unlock(dev);
  1099. if (obj) {
  1100. yaffs_trace(YAFFS_TRACE_OS,
  1101. "yaffs_lookup found %d", obj->obj_id);
  1102. inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
  1103. } else {
  1104. yaffs_trace(YAFFS_TRACE_OS, "yaffs_lookup not found");
  1105. }
  1106. /* added NCB for 2.5/6 compatability - forces add even if inode is
  1107. * NULL which creates dentry hash */
  1108. d_add(dentry, inode);
  1109. return NULL;
  1110. }
  1111. /*
  1112. * Create a link...
  1113. */
  1114. static int yaffs_link(struct dentry *old_dentry, struct inode *dir,
  1115. struct dentry *dentry)
  1116. {
  1117. struct inode *inode = old_dentry->d_inode;
  1118. struct yaffs_obj *obj = NULL;
  1119. struct yaffs_obj *link = NULL;
  1120. struct yaffs_dev *dev;
  1121. yaffs_trace(YAFFS_TRACE_OS, "yaffs_link");
  1122. obj = yaffs_inode_to_obj(inode);
  1123. dev = obj->my_dev;
  1124. yaffs_gross_lock(dev);
  1125. if (!S_ISDIR(inode->i_mode)) /* Don't link directories */
  1126. link =
  1127. yaffs_link_obj(yaffs_inode_to_obj(dir), dentry->d_name.name,
  1128. obj);
  1129. if (link) {
  1130. set_nlink(old_dentry->d_inode, yaffs_get_obj_link_count(obj));
  1131. d_instantiate(dentry, old_dentry->d_inode);
  1132. atomic_inc(&old_dentry->d_inode->i_count);
  1133. yaffs_trace(YAFFS_TRACE_OS,
  1134. "yaffs_link link count %d i_count %d",
  1135. old_dentry->d_inode->i_nlink,
  1136. atomic_read(&old_dentry->d_inode->i_count));
  1137. }
  1138. yaffs_gross_unlock(dev);
  1139. if (link) {
  1140. update_dir_time(dir);
  1141. return 0;
  1142. }
  1143. return -EPERM;
  1144. }
  1145. static int yaffs_symlink(struct inode *dir, struct dentry *dentry,
  1146. const char *symname)
  1147. {
  1148. struct yaffs_obj *obj;
  1149. struct yaffs_dev *dev;
  1150. uid_t uid = YPROC_uid(current);
  1151. gid_t gid =
  1152. (dir->i_mode & S_ISGID) ? EXTRACT_gid(dir->i_gid) : YPROC_gid(current);
  1153. yaffs_trace(YAFFS_TRACE_OS, "yaffs_symlink");
  1154. if (strnlen(dentry->d_name.name, YAFFS_MAX_NAME_LENGTH + 1) >
  1155. YAFFS_MAX_NAME_LENGTH)
  1156. return -ENAMETOOLONG;
  1157. if (strnlen(symname, YAFFS_MAX_ALIAS_LENGTH + 1) >
  1158. YAFFS_MAX_ALIAS_LENGTH)
  1159. return -ENAMETOOLONG;
  1160. dev = yaffs_inode_to_obj(dir)->my_dev;
  1161. yaffs_gross_lock(dev);
  1162. obj = yaffs_create_symlink(yaffs_inode_to_obj(dir), dentry->d_name.name,
  1163. S_IFLNK | S_IRWXUGO, uid, gid, symname);
  1164. yaffs_gross_unlock(dev);
  1165. if (obj) {
  1166. struct inode *inode;
  1167. inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
  1168. d_instantiate(dentry, inode);
  1169. update_dir_time(dir);
  1170. yaffs_trace(YAFFS_TRACE_OS, "symlink created OK");
  1171. return 0;
  1172. } else {
  1173. yaffs_trace(YAFFS_TRACE_OS, "symlink not created");
  1174. }
  1175. return -ENOMEM;
  1176. }
  1177. /*
  1178. * The VFS layer already does all the dentry stuff for rename.
  1179. *
  1180. * NB: POSIX says you can rename an object over an old object of the same name
  1181. */
  1182. static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry,
  1183. struct inode *new_dir, struct dentry *new_dentry)
  1184. {
  1185. struct yaffs_dev *dev;
  1186. int ret_val = YAFFS_FAIL;
  1187. struct yaffs_obj *target;
  1188. yaffs_trace(YAFFS_TRACE_OS, "yaffs_rename");
  1189. dev = yaffs_inode_to_obj(old_dir)->my_dev;
  1190. yaffs_gross_lock(dev);
  1191. /* Check if the target is an existing directory that is not empty. */
  1192. target = yaffs_find_by_name(yaffs_inode_to_obj(new_dir),
  1193. new_dentry->d_name.name);
  1194. if (target && target->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY &&
  1195. !list_empty(&target->variant.dir_variant.children)) {
  1196. yaffs_trace(YAFFS_TRACE_OS, "target is non-empty dir");
  1197. ret_val = YAFFS_FAIL;
  1198. } else {
  1199. /* Now does unlinking internally using shadowing mechanism */
  1200. yaffs_trace(YAFFS_TRACE_OS, "calling yaffs_rename_obj");
  1201. ret_val = yaffs_rename_obj(yaffs_inode_to_obj(old_dir),
  1202. old_dentry->d_name.name,
  1203. yaffs_inode_to_obj(new_dir),
  1204. new_dentry->d_name.name);
  1205. }
  1206. yaffs_gross_unlock(dev);
  1207. if (ret_val == YAFFS_OK) {
  1208. if (target)
  1209. inode_dec_link_count(new_dentry->d_inode);
  1210. update_dir_time(old_dir);
  1211. if (old_dir != new_dir)
  1212. update_dir_time(new_dir);
  1213. return 0;
  1214. } else {
  1215. return -ENOTEMPTY;
  1216. }
  1217. }
  1218. static int yaffs_unlink(struct inode *dir, struct dentry *dentry)
  1219. {
  1220. int ret_val;
  1221. struct yaffs_dev *dev;
  1222. struct yaffs_obj *obj;
  1223. yaffs_trace(YAFFS_TRACE_OS, "yaffs_unlink %d:%s",
  1224. (int)(dir->i_ino), dentry->d_name.name);
  1225. obj = yaffs_inode_to_obj(dir);
  1226. dev = obj->my_dev;
  1227. yaffs_gross_lock(dev);
  1228. ret_val = yaffs_unlinker(obj, dentry->d_name.name);
  1229. if (ret_val == YAFFS_OK) {
  1230. inode_dec_link_count(dentry->d_inode);
  1231. dir->i_version++;
  1232. yaffs_gross_unlock(dev);
  1233. update_dir_time(dir);
  1234. return 0;
  1235. }
  1236. yaffs_gross_unlock(dev);
  1237. return -ENOTEMPTY;
  1238. }
  1239. static const struct inode_operations yaffs_dir_inode_operations = {
  1240. .create = yaffs_create,
  1241. .lookup = yaffs_lookup,
  1242. .link = yaffs_link,
  1243. .unlink = yaffs_unlink,
  1244. .symlink = yaffs_symlink,
  1245. .mkdir = yaffs_mkdir,
  1246. .rmdir = yaffs_unlink,
  1247. .mknod = yaffs_mknod,
  1248. .rename = yaffs_rename,
  1249. .setattr = yaffs_setattr,
  1250. .setxattr = yaffs_setxattr,
  1251. .getxattr = yaffs_getxattr,
  1252. .listxattr = yaffs_listxattr,
  1253. .removexattr = yaffs_removexattr,
  1254. };
  1255. /*-----------------------------------------------------------------*/
  1256. /* Directory search context allows us to unlock access to yaffs during
  1257. * filldir without causing problems with the directory being modified.
  1258. * This is similar to the tried and tested mechanism used in yaffs direct.
  1259. *
  1260. * A search context iterates along a doubly linked list of siblings in the
  1261. * directory. If the iterating object is deleted then this would corrupt
  1262. * the list iteration, likely causing a crash. The search context avoids
  1263. * this by using the remove_obj_fn to move the search context to the
  1264. * next object before the object is deleted.
  1265. *
  1266. * Many readdirs (and thus seach conexts) may be alive simulateously so
  1267. * each struct yaffs_dev has a list of these.
  1268. *
  1269. * A seach context lives for the duration of a readdir.
  1270. *
  1271. * All these functions must be called while yaffs is locked.
  1272. */
  1273. struct yaffs_search_context {
  1274. struct yaffs_dev *dev;
  1275. struct yaffs_obj *dir_obj;
  1276. struct yaffs_obj *next_return;
  1277. struct list_head others;
  1278. };
  1279. /*
  1280. * yaffs_new_search() creates a new search context, initialises it and
  1281. * adds it to the device's search context list.
  1282. *
  1283. * Called at start of readdir.
  1284. */
  1285. static struct yaffs_search_context *yaffs_new_search(struct yaffs_obj *dir)
  1286. {
  1287. struct yaffs_dev *dev = dir->my_dev;
  1288. struct yaffs_search_context *sc =
  1289. kmalloc(sizeof(struct yaffs_search_context), GFP_NOFS);
  1290. if (sc) {
  1291. sc->dir_obj = dir;
  1292. sc->dev = dev;
  1293. if (list_empty(&sc->dir_obj->variant.dir_variant.children))
  1294. sc->next_return = NULL;
  1295. else
  1296. sc->next_return =
  1297. list_entry(dir->variant.dir_variant.children.next,
  1298. struct yaffs_obj, siblings);
  1299. INIT_LIST_HEAD(&sc->others);
  1300. list_add(&sc->others, &(yaffs_dev_to_lc(dev)->search_contexts));
  1301. }
  1302. return sc;
  1303. }
  1304. /*
  1305. * yaffs_search_end() disposes of a search context and cleans up.
  1306. */
  1307. static void yaffs_search_end(struct yaffs_search_context *sc)
  1308. {
  1309. if (sc) {
  1310. list_del(&sc->others);
  1311. kfree(sc);
  1312. }
  1313. }
  1314. /*
  1315. * yaffs_search_advance() moves a search context to the next object.
  1316. * Called when the search iterates or when an object removal causes
  1317. * the search context to be moved to the next object.
  1318. */
  1319. static void yaffs_search_advance(struct yaffs_search_context *sc)
  1320. {
  1321. if (!sc)
  1322. return;
  1323. if (sc->next_return == NULL ||
  1324. list_empty(&sc->dir_obj->variant.dir_variant.children))
  1325. sc->next_return = NULL;
  1326. else {
  1327. struct list_head *next = sc->next_return->siblings.next;
  1328. if (next == &sc->dir_obj->variant.dir_variant.children)
  1329. sc->next_return = NULL; /* end of list */
  1330. else
  1331. sc->next_return =
  1332. list_entry(next, struct yaffs_obj, siblings);
  1333. }
  1334. }
  1335. /*
  1336. * yaffs_remove_obj_callback() is called when an object is unlinked.
  1337. * We check open search contexts and advance any which are currently
  1338. * on the object being iterated.
  1339. */
  1340. static void yaffs_remove_obj_callback(struct yaffs_obj *obj)
  1341. {
  1342. struct list_head *i;
  1343. struct yaffs_search_context *sc;
  1344. struct list_head *search_contexts =
  1345. &(yaffs_dev_to_lc(obj->my_dev)->search_contexts);
  1346. /* Iterate through the directory search contexts.
  1347. * If any are currently on the object being removed, then advance
  1348. * the search context to the next object to prevent a hanging pointer.
  1349. */
  1350. list_for_each(i, search_contexts) {
  1351. sc = list_entry(i, struct yaffs_search_context, others);
  1352. if (sc->next_return == obj)
  1353. yaffs_search_advance(sc);
  1354. }
  1355. }
  1356. /*-----------------------------------------------------------------*/
  1357. #ifdef YAFFS_USE_DIR_ITERATE
  1358. static int yaffs_iterate(struct file *f, struct dir_context *dc)
  1359. {
  1360. struct yaffs_obj *obj;
  1361. struct yaffs_dev *dev;
  1362. struct yaffs_search_context *sc;
  1363. unsigned long curoffs;
  1364. struct yaffs_obj *l;
  1365. int ret_val = 0;
  1366. char name[YAFFS_MAX_NAME_LENGTH + 1];
  1367. obj = yaffs_dentry_to_obj(f->f_dentry);
  1368. dev = obj->my_dev;
  1369. yaffs_gross_lock(dev);
  1370. yaffs_dev_to_lc(dev)->readdir_process = current;
  1371. sc = yaffs_new_search(obj);
  1372. if (!sc) {
  1373. ret_val = -ENOMEM;
  1374. goto out;
  1375. }
  1376. if (!dir_emit_dots(f, dc))
  1377. return 0;
  1378. curoffs = 1;
  1379. while (sc->next_return) {
  1380. curoffs++;
  1381. l = sc->next_return;
  1382. if (curoffs >= dc->pos) {
  1383. int this_inode = yaffs_get_obj_inode(l);
  1384. int this_type = yaffs_get_obj_type(l);
  1385. yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1);
  1386. yaffs_trace(YAFFS_TRACE_OS,
  1387. "yaffs_readdir: %s inode %d",
  1388. name, yaffs_get_obj_inode(l));
  1389. yaffs_gross_unlock(dev);
  1390. if (!dir_emit(dc,
  1391. name,
  1392. strlen(name),
  1393. this_inode,
  1394. this_type)) {
  1395. yaffs_gross_lock(dev);
  1396. goto out;
  1397. }
  1398. yaffs_gross_lock(dev);
  1399. dc->pos++;
  1400. f->f_pos++;
  1401. }
  1402. yaffs_search_advance(sc);
  1403. }
  1404. out:
  1405. yaffs_search_end(sc);
  1406. yaffs_dev_to_lc(dev)->readdir_process = NULL;
  1407. yaffs_gross_unlock(dev);
  1408. return ret_val;
  1409. }
  1410. #else
  1411. static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
  1412. {
  1413. struct yaffs_obj *obj;
  1414. struct yaffs_dev *dev;
  1415. struct yaffs_search_context *sc;
  1416. struct inode *inode = f->f_dentry->d_inode;
  1417. unsigned long offset, curoffs;
  1418. struct yaffs_obj *l;
  1419. int ret_val = 0;
  1420. char name[YAFFS_MAX_NAME_LENGTH + 1];
  1421. obj = yaffs_dentry_to_obj(f->f_dentry);
  1422. dev = obj->my_dev;
  1423. yaffs_gross_lock(dev);
  1424. yaffs_dev_to_lc(dev)->readdir_process = current;
  1425. offset = f->f_pos;
  1426. sc = yaffs_new_search(obj);
  1427. if (!sc) {
  1428. ret_val = -ENOMEM;
  1429. goto out;
  1430. }
  1431. yaffs_trace(YAFFS_TRACE_OS,
  1432. "yaffs_readdir: starting at %d", (int)offset);
  1433. if (offset == 0) {
  1434. yaffs_trace(YAFFS_TRACE_OS,
  1435. "yaffs_readdir: entry . ino %d",
  1436. (int)inode->i_ino);
  1437. yaffs_gross_unlock(dev);
  1438. if (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR) < 0) {
  1439. yaffs_gross_lock(dev);
  1440. goto out;
  1441. }
  1442. yaffs_gross_lock(dev);
  1443. offset++;
  1444. f->f_pos++;
  1445. }
  1446. if (offset == 1) {
  1447. yaffs_trace(YAFFS_TRACE_OS,
  1448. "yaffs_readdir: entry .. ino %d",
  1449. (int)f->f_dentry->d_parent->d_inode->i_ino);
  1450. yaffs_gross_unlock(dev);
  1451. if (filldir(dirent, "..", 2, offset,
  1452. f->f_dentry->d_parent->d_inode->i_ino,
  1453. DT_DIR) < 0) {
  1454. yaffs_gross_lock(dev);
  1455. goto out;
  1456. }
  1457. yaffs_gross_lock(dev);
  1458. offset++;
  1459. f->f_pos++;
  1460. }
  1461. curoffs = 1;
  1462. /* If the directory has changed since the open or last call to
  1463. readdir, rewind to after the 2 canned entries. */
  1464. if (f->f_version != inode->i_version) {
  1465. offset = 2;
  1466. f->f_pos = offset;
  1467. f->f_version = inode->i_version;
  1468. }
  1469. while (sc->next_return) {
  1470. curoffs++;
  1471. l = sc->next_return;
  1472. if (curoffs >= offset) {
  1473. int this_inode = yaffs_get_obj_inode(l);
  1474. int this_type = yaffs_get_obj_type(l);
  1475. yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1);
  1476. yaffs_trace(YAFFS_TRACE_OS,
  1477. "yaffs_readdir: %s inode %d",
  1478. name, yaffs_get_obj_inode(l));
  1479. yaffs_gross_unlock(dev);
  1480. if (filldir(dirent,
  1481. name,
  1482. strlen(name),
  1483. offset, this_inode, this_type) < 0) {
  1484. yaffs_gross_lock(dev);
  1485. goto out;
  1486. }
  1487. yaffs_gross_lock(dev);
  1488. offset++;
  1489. f->f_pos++;
  1490. }
  1491. yaffs_search_advance(sc);
  1492. }
  1493. out:
  1494. yaffs_search_end(sc);
  1495. yaffs_dev_to_lc(dev)->readdir_process = NULL;
  1496. yaffs_gross_unlock(dev);
  1497. return ret_val;
  1498. }
  1499. #endif
  1500. static const struct file_operations yaffs_dir_operations = {
  1501. .read = generic_read_dir,
  1502. #ifdef YAFFS_USE_DIR_ITERATE
  1503. .iterate = yaffs_iterate,
  1504. #else
  1505. .readdir = yaffs_readdir,
  1506. #endif
  1507. .fsync = yaffs_sync_object,
  1508. .llseek = generic_file_llseek,
  1509. };
  1510. static void yaffs_fill_inode_from_obj(struct inode *inode,
  1511. struct yaffs_obj *obj)
  1512. {
  1513. if (inode && obj) {
  1514. /* Check mode against the variant type and attempt to repair if broken. */
  1515. u32 mode = obj->yst_mode;
  1516. switch (obj->variant_type) {
  1517. case YAFFS_OBJECT_TYPE_FILE:
  1518. if (!S_ISREG(mode)) {
  1519. obj->yst_mode &= ~S_IFMT;
  1520. obj->yst_mode |= S_IFREG;
  1521. }
  1522. break;
  1523. case YAFFS_OBJECT_TYPE_SYMLINK:
  1524. if (!S_ISLNK(mode)) {
  1525. obj->yst_mode &= ~S_IFMT;
  1526. obj->yst_mode |= S_IFLNK;
  1527. }
  1528. break;
  1529. case YAFFS_OBJECT_TYPE_DIRECTORY:
  1530. if (!S_ISDIR(mode)) {
  1531. obj->yst_mode &= ~S_IFMT;
  1532. obj->yst_mode |= S_IFDIR;
  1533. }
  1534. break;
  1535. case YAFFS_OBJECT_TYPE_UNKNOWN:
  1536. case YAFFS_OBJECT_TYPE_HARDLINK:
  1537. case YAFFS_OBJECT_TYPE_SPECIAL:
  1538. default:
  1539. /* TODO? */
  1540. break;
  1541. }
  1542. inode->i_flags |= S_NOATIME;
  1543. inode->i_ino = obj->obj_id;
  1544. inode->i_mode = obj->yst_mode;
  1545. inode->i_uid = MAKE_uid(obj->yst_uid);
  1546. inode->i_gid = MAKE_gid(obj->yst_gid);
  1547. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
  1548. inode->i_blksize = inode->i_sb->s_blocksize;
  1549. #endif
  1550. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
  1551. inode->i_rdev = old_decode_dev(obj->yst_rdev);
  1552. inode->i_atime.tv_sec = (time_t) (obj->yst_atime);
  1553. inode->i_atime.tv_nsec = 0;
  1554. inode->i_mtime.tv_sec = (time_t) obj->yst_mtime;
  1555. inode->i_mtime.tv_nsec = 0;
  1556. inode->i_ctime.tv_sec = (time_t) obj->yst_ctime;
  1557. inode->i_ctime.tv_nsec = 0;
  1558. #else
  1559. inode->i_rdev = obj->yst_rdev;
  1560. inode->i_atime = obj->yst_atime;
  1561. inode->i_mtime = obj->yst_mtime;
  1562. inode->i_ctime = obj->yst_ctime;
  1563. #endif
  1564. inode->i_size = yaffs_get_obj_length(obj);
  1565. inode->i_blocks = (inode->i_size + 511) >> 9;
  1566. set_nlink(inode, yaffs_get_obj_link_count(obj));
  1567. yaffs_trace(YAFFS_TRACE_OS,
  1568. "yaffs_fill_inode mode %x uid %d gid %d size %lld count %d",
  1569. inode->i_mode, obj->yst_uid, obj->yst_gid,
  1570. inode->i_size, atomic_read(&inode->i_count));
  1571. switch (obj->yst_mode & S_IFMT) {
  1572. default: /* fifo, device or socket */
  1573. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
  1574. init_special_inode(inode, obj->yst_mode,
  1575. old_decode_dev(obj->yst_rdev));
  1576. #else
  1577. init_special_inode(inode, obj->yst_mode,
  1578. (dev_t) (obj->yst_rdev));
  1579. #endif
  1580. break;
  1581. case S_IFREG: /* file */
  1582. inode->i_op = &yaffs_file_inode_operations;
  1583. inode->i_fop = &yaffs_file_operations;
  1584. inode->i_mapping->a_ops =
  1585. &yaffs_file_address_operations;
  1586. break;
  1587. case S_IFDIR: /* directory */
  1588. inode->i_op = &yaffs_dir_inode_operations;
  1589. inode->i_fop = &yaffs_dir_operations;
  1590. break;
  1591. case S_IFLNK: /* symlink */
  1592. inode->i_op = &yaffs_symlink_inode_operations;
  1593. break;
  1594. }
  1595. yaffs_inode_to_obj_lv(inode) = obj;
  1596. obj->my_inode = inode;
  1597. } else {
  1598. yaffs_trace(YAFFS_TRACE_OS,
  1599. "yaffs_fill_inode invalid parameters");
  1600. }
  1601. }
  1602. /*
  1603. * yaffs background thread functions .
  1604. * yaffs_bg_thread_fn() the thread function
  1605. * yaffs_bg_start() launches the background thread.
  1606. * yaffs_bg_stop() cleans up the background thread.
  1607. *
  1608. * NB:
  1609. * The thread should only run after the yaffs is initialised
  1610. * The thread should be stopped before yaffs is unmounted.
  1611. * The thread should not do any writing while the fs is in read only.
  1612. */
  1613. static unsigned yaffs_bg_gc_urgency(struct yaffs_dev *dev)
  1614. {
  1615. unsigned erased_chunks =
  1616. dev->n_erased_blocks * dev->param.chunks_per_block;
  1617. struct yaffs_linux_context *context = yaffs_dev_to_lc(dev);
  1618. unsigned scattered = 0; /* Free chunks not in an erased block */
  1619. if (erased_chunks < dev->n_free_chunks)
  1620. scattered = (dev->n_free_chunks - erased_chunks);
  1621. if (!context->bg_running)
  1622. return 0;
  1623. else if (scattered < (dev->param.chunks_per_block * 2))
  1624. return 0;
  1625. else if (erased_chunks > dev->n_free_chunks / 2)
  1626. return 0;
  1627. else if (erased_chunks > dev->n_free_chunks / 4)
  1628. return 1;
  1629. else
  1630. return 2;
  1631. }
  1632. #ifdef YAFFS_COMPILE_BACKGROUND
  1633. void yaffs_background_waker(unsigned long data)
  1634. {
  1635. wake_up_process((struct task_struct *)data);
  1636. }
  1637. static int yaffs_bg_thread_fn(void *data)
  1638. {
  1639. struct yaffs_dev *dev = (struct yaffs_dev *)data;
  1640. struct yaffs_linux_context *context = yaffs_dev_to_lc(dev);
  1641. unsigned long now = jiffies;
  1642. unsigned long next_dir_update = now;
  1643. unsigned long next_gc = now;
  1644. unsigned long expires;
  1645. unsigned int urgency;
  1646. int gc_result;
  1647. struct timer_list timer;
  1648. yaffs_trace(YAFFS_TRACE_BACKGROUND,
  1649. "yaffs_background starting for dev %p", (void *)dev);
  1650. #ifdef YAFFS_COMPILE_FREEZER
  1651. set_freezable();
  1652. #endif
  1653. while (context->bg_running) {
  1654. yaffs_trace(YAFFS_TRACE_BACKGROUND, "yaffs_background");
  1655. if (kthread_should_stop())
  1656. break;
  1657. #ifdef YAFFS_COMPILE_FREEZER
  1658. if (try_to_freeze())
  1659. continue;
  1660. #endif
  1661. yaffs_gross_lock(dev);
  1662. now = jiffies;
  1663. if (time_after(now, next_dir_update) && yaffs_bg_enable) {
  1664. yaffs_update_dirty_dirs(dev);
  1665. next_dir_update = now + HZ;
  1666. }
  1667. if (time_after(now, next_gc) && yaffs_bg_enable) {
  1668. if (!dev->is_checkpointed) {
  1669. urgency = yaffs_bg_gc_urgency(dev);
  1670. gc_result = yaffs_bg_gc(dev, urgency);
  1671. if (urgency > 1)
  1672. next_gc = now + HZ / 20 + 1;
  1673. else if (urgency > 0)
  1674. next_gc = now + HZ / 10 + 1;
  1675. else
  1676. next_gc = now + HZ * 2;
  1677. } else {
  1678. /*
  1679. * gc not running so set to next_dir_update
  1680. * to cut down on wake ups
  1681. */
  1682. next_gc = next_dir_update;
  1683. }
  1684. }
  1685. yaffs_gross_unlock(dev);
  1686. #if 1
  1687. expires = next_dir_update;
  1688. if (time_before(next_gc, expires))
  1689. expires = next_gc;
  1690. if (time_before(expires, now))
  1691. expires = now + HZ;
  1692. Y_INIT_TIMER(&timer);
  1693. timer.expires = expires + 1;
  1694. timer.data = (unsigned long)current;
  1695. timer.function = yaffs_background_waker;
  1696. set_current_state(TASK_INTERRUPTIBLE);
  1697. add_timer(&timer);
  1698. schedule();
  1699. del_timer_sync(&timer);
  1700. #else
  1701. msleep(10);
  1702. #endif
  1703. }
  1704. return 0;
  1705. }
  1706. static int yaffs_bg_start(struct yaffs_dev *dev)
  1707. {
  1708. int retval = 0;
  1709. struct yaffs_linux_context *context = yaffs_dev_to_lc(dev);
  1710. if (dev->read_only)
  1711. return -1;
  1712. context->bg_running = 1;
  1713. context->bg_thread = kthread_run(yaffs_bg_thread_fn,
  1714. (void *)dev, "yaffs-bg-%d",
  1715. context->mount_id);
  1716. if (IS_ERR(context->bg_thread)) {
  1717. retval = PTR_ERR(context->bg_thread);
  1718. context->bg_thread = NULL;
  1719. context->bg_running = 0;
  1720. }
  1721. return retval;
  1722. }
  1723. static void yaffs_bg_stop(struct yaffs_dev *dev)
  1724. {
  1725. struct yaffs_linux_context *ctxt = yaffs_dev_to_lc(dev);
  1726. ctxt->bg_running = 0;
  1727. if (ctxt->bg_thread) {
  1728. kthread_stop(ctxt->bg_thread);
  1729. ctxt->bg_thread = NULL;
  1730. }
  1731. }
  1732. #else
  1733. static int yaffs_bg_thread_fn(void *data)
  1734. {
  1735. return 0;
  1736. }
  1737. static int yaffs_bg_start(struct yaffs_dev *dev)
  1738. {
  1739. return 0;
  1740. }
  1741. static void yaffs_bg_stop(struct yaffs_dev *dev)
  1742. {
  1743. }
  1744. #endif
  1745. static void yaffs_flush_inodes(struct super_block *sb)
  1746. {
  1747. struct inode *iptr;
  1748. struct yaffs_obj *obj;
  1749. list_for_each_entry(iptr, &sb->s_inodes, i_sb_list) {
  1750. obj = yaffs_inode_to_obj(iptr);
  1751. if (obj) {
  1752. yaffs_trace(YAFFS_TRACE_OS,
  1753. "flushing obj %d",
  1754. obj->obj_id);
  1755. yaffs_flush_file(obj, 1, 0, 0);
  1756. }
  1757. }
  1758. }
  1759. static void yaffs_flush_super(struct super_block *sb, int do_checkpoint)
  1760. {
  1761. struct yaffs_dev *dev = yaffs_super_to_dev(sb);
  1762. if (!dev)
  1763. return;
  1764. yaffs_flush_inodes(sb);
  1765. yaffs_update_dirty_dirs(dev);
  1766. yaffs_flush_whole_cache(dev, 1);
  1767. if (do_checkpoint)
  1768. yaffs_checkpoint_save(dev);
  1769. }
  1770. static LIST_HEAD(yaffs_context_list);
  1771. struct mutex yaffs_context_lock;
  1772. static void yaffs_put_super(struct super_block *sb)
  1773. {
  1774. struct yaffs_dev *dev = yaffs_super_to_dev(sb);
  1775. struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
  1776. yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_ALWAYS,
  1777. "yaffs_put_super");
  1778. yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_BACKGROUND,
  1779. "Shutting down yaffs background thread");
  1780. yaffs_bg_stop(dev);
  1781. yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_BACKGROUND,
  1782. "yaffs background thread shut down");
  1783. yaffs_gross_lock(dev);
  1784. yaffs_flush_super(sb, 1);
  1785. yaffs_deinitialise(dev);
  1786. yaffs_gross_unlock(dev);
  1787. mutex_lock(&yaffs_context_lock);
  1788. list_del_init(&(yaffs_dev_to_lc(dev)->context_list));
  1789. mutex_unlock(&yaffs_context_lock);
  1790. if (yaffs_dev_to_lc(dev)->spare_buffer) {
  1791. kfree(yaffs_dev_to_lc(dev)->spare_buffer);
  1792. yaffs_dev_to_lc(dev)->spare_buffer = NULL;
  1793. }
  1794. kfree(dev);
  1795. yaffs_put_mtd_device(mtd);
  1796. yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_ALWAYS,
  1797. "yaffs_put_super done");
  1798. }
  1799. static unsigned yaffs_gc_control_callback(struct yaffs_dev *dev)
  1800. {
  1801. return yaffs_gc_control;
  1802. }
  1803. #ifdef YAFFS_COMPILE_EXPORTFS
  1804. static struct inode *yaffs2_nfs_get_inode(struct super_block *sb, uint64_t ino,
  1805. uint32_t generation)
  1806. {
  1807. return Y_IGET(sb, ino);
  1808. }
  1809. static struct dentry *yaffs2_fh_to_dentry(struct super_block *sb,
  1810. struct fid *fid, int fh_len,
  1811. int fh_type)
  1812. {
  1813. return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
  1814. yaffs2_nfs_get_inode);
  1815. }
  1816. static struct dentry *yaffs2_fh_to_parent(struct super_block *sb,
  1817. struct fid *fid, int fh_len,
  1818. int fh_type)
  1819. {
  1820. return generic_fh_to_parent(sb, fid, fh_len, fh_type,
  1821. yaffs2_nfs_get_inode);
  1822. }
  1823. struct dentry *yaffs2_get_parent(struct dentry *dentry)
  1824. {
  1825. struct super_block *sb = dentry->d_inode->i_sb;
  1826. struct dentry *parent = ERR_PTR(-ENOENT);
  1827. struct inode *inode;
  1828. unsigned long parent_ino;
  1829. struct yaffs_obj *d_obj;
  1830. struct yaffs_obj *parent_obj;
  1831. d_obj = yaffs_inode_to_obj(dentry->d_inode);
  1832. if (d_obj) {
  1833. parent_obj = d_obj->parent;
  1834. if (parent_obj) {
  1835. parent_ino = yaffs_get_obj_inode(parent_obj);
  1836. inode = Y_IGET(sb, parent_ino);
  1837. if (IS_ERR(inode)) {
  1838. parent = ERR_CAST(inode);
  1839. } else {
  1840. parent = d_obtain_alias(inode);
  1841. if (!IS_ERR(parent)) {
  1842. parent = ERR_PTR(-ENOMEM);
  1843. iput(inode);
  1844. }
  1845. }
  1846. }
  1847. }
  1848. return parent;
  1849. }
  1850. /* Just declare a zero structure as a NULL value implies
  1851. * using the default functions of exportfs.
  1852. */
  1853. static struct export_operations yaffs_export_ops = {
  1854. .fh_to_dentry = yaffs2_fh_to_dentry,
  1855. .fh_to_parent = yaffs2_fh_to_parent,
  1856. .get_parent = yaffs2_get_parent,
  1857. };
  1858. #endif
  1859. static void yaffs_unstitch_obj(struct inode *inode, struct yaffs_obj *obj)
  1860. {
  1861. /* Clear the association between the inode and
  1862. * the struct yaffs_obj.
  1863. */
  1864. obj->my_inode = NULL;
  1865. yaffs_inode_to_obj_lv(inode) = NULL;
  1866. /* If the object freeing was deferred, then the real
  1867. * free happens now.
  1868. * This should fix the inode inconsistency problem.
  1869. */
  1870. yaffs_handle_defered_free(obj);
  1871. }
  1872. #ifdef YAFFS_HAS_EVICT_INODE
  1873. /* yaffs_evict_inode combines into one operation what was previously done in
  1874. * yaffs_clear_inode() and yaffs_delete_inode()
  1875. *
  1876. */
  1877. static void yaffs_evict_inode(struct inode *inode)
  1878. {
  1879. struct yaffs_obj *obj;
  1880. struct yaffs_dev *dev;
  1881. int deleteme = 0;
  1882. obj = yaffs_inode_to_obj(inode);
  1883. yaffs_trace(YAFFS_TRACE_OS,
  1884. "yaffs_evict_inode: ino %d, count %d %s",
  1885. (int)inode->i_ino, atomic_read(&inode->i_count),
  1886. obj ? "object exists" : "null object");
  1887. if (!inode->i_nlink && !is_bad_inode(inode))
  1888. deleteme = 1;
  1889. truncate_inode_pages(&inode->i_data, 0);
  1890. Y_CLEAR_INODE(inode);
  1891. if (deleteme && obj) {
  1892. dev = obj->my_dev;
  1893. yaffs_gross_lock(dev);
  1894. yaffs_del_obj(obj);
  1895. yaffs_gross_unlock(dev);
  1896. }
  1897. if (obj) {
  1898. dev = obj->my_dev;
  1899. yaffs_gross_lock(dev);
  1900. yaffs_unstitch_obj(inode, obj);
  1901. yaffs_gross_unlock(dev);
  1902. }
  1903. }
  1904. #else
  1905. /* clear is called to tell the fs to release any per-inode data it holds.
  1906. * The object might still exist on disk and is just being thrown out of the cache
  1907. * or else the object has actually been deleted and we're being called via
  1908. * the chain
  1909. * yaffs_delete_inode() -> clear_inode()->yaffs_clear_inode()
  1910. */
  1911. static void yaffs_clear_inode(struct inode *inode)
  1912. {
  1913. struct yaffs_obj *obj;
  1914. struct yaffs_dev *dev;
  1915. obj = yaffs_inode_to_obj(inode);
  1916. yaffs_trace(YAFFS_TRACE_OS,
  1917. "yaffs_clear_inode: ino %d, count %d %s",
  1918. (int)inode->i_ino, atomic_read(&inode->i_count),
  1919. obj ? "object exists" : "null object");
  1920. if (obj) {
  1921. dev = obj->my_dev;
  1922. yaffs_gross_lock(dev);
  1923. yaffs_unstitch_obj(inode, obj);
  1924. yaffs_gross_unlock(dev);
  1925. }
  1926. }
  1927. /* delete is called when the link count is zero and the inode
  1928. * is put (ie. nobody wants to know about it anymore, time to
  1929. * delete the file).
  1930. * NB Must call clear_inode()
  1931. */
  1932. static void yaffs_delete_inode(struct inode *inode)
  1933. {
  1934. struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
  1935. struct yaffs_dev *dev;
  1936. yaffs_trace(YAFFS_TRACE_OS,
  1937. "yaffs_delete_inode: ino %d, count %d %s",
  1938. (int)inode->i_ino, atomic_read(&inode->i_count),
  1939. obj ? "object exists" : "null object");
  1940. if (obj) {
  1941. dev = obj->my_dev;
  1942. yaffs_gross_lock(dev);
  1943. yaffs_del_obj(obj);
  1944. yaffs_gross_unlock(dev);
  1945. }
  1946. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
  1947. truncate_inode_pages(&inode->i_data, 0);
  1948. #endif
  1949. clear_inode(inode);
  1950. }
  1951. #endif
  1952. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
  1953. static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf)
  1954. {
  1955. struct yaffs_dev *dev = yaffs_dentry_to_obj(dentry)->my_dev;
  1956. struct super_block *sb = dentry->d_sb;
  1957. #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
  1958. static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf)
  1959. {
  1960. struct yaffs_dev *dev = yaffs_super_to_dev(sb);
  1961. #else
  1962. static int yaffs_statfs(struct super_block *sb, struct statfs *buf)
  1963. {
  1964. struct yaffs_dev *dev = yaffs_super_to_dev(sb);
  1965. #endif
  1966. yaffs_trace(YAFFS_TRACE_OS, "yaffs_statfs");
  1967. yaffs_gross_lock(dev);
  1968. buf->f_type = YAFFS_MAGIC;
  1969. buf->f_bsize = sb->s_blocksize;
  1970. buf->f_namelen = 255;
  1971. if (dev->data_bytes_per_chunk & (dev->data_bytes_per_chunk - 1)) {
  1972. /* Do this if chunk size is not a power of 2 */
  1973. uint64_t bytes_in_dev;
  1974. uint64_t bytes_free;
  1975. bytes_in_dev =
  1976. ((uint64_t)
  1977. ((dev->param.end_block - dev->param.start_block +
  1978. 1))) * ((uint64_t) (dev->param.chunks_per_block *
  1979. dev->data_bytes_per_chunk));
  1980. do_div(bytes_in_dev, sb->s_blocksize); /* bytes_in_dev becomes the number of blocks */
  1981. buf->f_blocks = bytes_in_dev;
  1982. bytes_free = ((uint64_t) (yaffs_get_n_free_chunks(dev))) *
  1983. ((uint64_t) (dev->data_bytes_per_chunk));
  1984. do_div(bytes_free, sb->s_blocksize);
  1985. buf->f_bfree = bytes_free;
  1986. } else if (sb->s_blocksize > dev->data_bytes_per_chunk) {
  1987. buf->f_blocks =
  1988. (dev->param.end_block - dev->param.start_block + 1) *
  1989. dev->param.chunks_per_block /
  1990. (sb->s_blocksize / dev->data_bytes_per_chunk);
  1991. buf->f_bfree =
  1992. yaffs_get_n_free_chunks(dev) /
  1993. (sb->s_blocksize / dev->data_bytes_per_chunk);
  1994. } else {
  1995. buf->f_blocks =
  1996. (dev->param.end_block - dev->param.start_block + 1) *
  1997. dev->param.chunks_per_block *
  1998. (dev->data_bytes_per_chunk / sb->s_blocksize);
  1999. buf->f_bfree =
  2000. yaffs_get_n_free_chunks(dev) *
  2001. (dev->data_bytes_per_chunk / sb->s_blocksize);
  2002. }
  2003. buf->f_files = 0;
  2004. buf->f_ffree = 0;
  2005. buf->f_bavail = buf->f_bfree;
  2006. yaffs_gross_unlock(dev);
  2007. return 0;
  2008. }
  2009. static int yaffs_do_sync_fs(struct super_block *sb, int request_checkpoint)
  2010. {
  2011. struct yaffs_dev *dev = yaffs_super_to_dev(sb);
  2012. unsigned int oneshot_checkpoint = (yaffs_auto_checkpoint & 4);
  2013. unsigned gc_urgent = yaffs_bg_gc_urgency(dev);
  2014. int do_checkpoint;
  2015. int dirty = yaffs_check_super_dirty(dev);
  2016. yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC | YAFFS_TRACE_BACKGROUND,
  2017. "yaffs_do_sync_fs: gc-urgency %d %s %s%s",
  2018. gc_urgent,
  2019. dirty ? "dirty" : "clean",
  2020. request_checkpoint ? "checkpoint requested" : "no checkpoint",
  2021. oneshot_checkpoint ? " one-shot" : "");
  2022. yaffs_gross_lock(dev);
  2023. do_checkpoint = ((request_checkpoint && !gc_urgent) ||
  2024. oneshot_checkpoint) && !dev->is_checkpointed;
  2025. if (dirty || do_checkpoint) {
  2026. yaffs_flush_super(sb, !dev->is_checkpointed && do_checkpoint);
  2027. yaffs_clear_super_dirty(dev);
  2028. if (oneshot_checkpoint)
  2029. yaffs_auto_checkpoint &= ~4;
  2030. }
  2031. yaffs_gross_unlock(dev);
  2032. return 0;
  2033. }
  2034. #ifdef YAFFS_HAS_WRITE_SUPER
  2035. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
  2036. static void yaffs_write_super(struct super_block *sb)
  2037. #else
  2038. static int yaffs_write_super(struct super_block *sb)
  2039. #endif
  2040. {
  2041. unsigned request_checkpoint = (yaffs_auto_checkpoint >= 2);
  2042. yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC | YAFFS_TRACE_BACKGROUND,
  2043. "yaffs_write_super %s",
  2044. request_checkpoint ? " checkpt" : "");
  2045. yaffs_do_sync_fs(sb, request_checkpoint);
  2046. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
  2047. return 0;
  2048. #endif
  2049. }
  2050. #endif
  2051. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
  2052. static int yaffs_sync_fs(struct super_block *sb, int wait)
  2053. #else
  2054. static int yaffs_sync_fs(struct super_block *sb)
  2055. #endif
  2056. {
  2057. unsigned request_checkpoint = (yaffs_auto_checkpoint >= 1);
  2058. yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC,
  2059. "yaffs_sync_fs%s", request_checkpoint ? " checkpt" : "");
  2060. yaffs_do_sync_fs(sb, request_checkpoint);
  2061. return 0;
  2062. }
  2063. /* the function only is used to change dev->read_only when this file system
  2064. * is remounted.
  2065. */
  2066. static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data)
  2067. {
  2068. int read_only = 0;
  2069. struct mtd_info *mtd;
  2070. struct yaffs_dev *dev = 0;
  2071. /* Get the device */
  2072. mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
  2073. if (!mtd) {
  2074. yaffs_trace(YAFFS_TRACE_ALWAYS,
  2075. "MTD device #%u doesn't appear to exist",
  2076. MINOR(sb->s_dev));
  2077. return 1;
  2078. }
  2079. /* Check it's NAND */
  2080. if (mtd->type != MTD_NANDFLASH) {
  2081. yaffs_trace(YAFFS_TRACE_ALWAYS,
  2082. "MTD device is not NAND it's type %d",
  2083. mtd->type);
  2084. return 1;
  2085. }
  2086. read_only = ((*flags & MS_RDONLY) != 0);
  2087. if (!read_only && !(mtd->flags & MTD_WRITEABLE)) {
  2088. read_only = 1;
  2089. printk(KERN_INFO
  2090. "yaffs: mtd is read only, setting superblock read only");
  2091. *flags |= MS_RDONLY;
  2092. }
  2093. dev = sb->s_fs_info;
  2094. dev->read_only = read_only;
  2095. return 0;
  2096. }
  2097. static const struct super_operations yaffs_super_ops = {
  2098. .statfs = yaffs_statfs,
  2099. #ifndef YAFFS_USE_OWN_IGET
  2100. .read_inode = yaffs_read_inode,
  2101. #endif
  2102. #ifdef YAFFS_HAS_PUT_INODE
  2103. .put_inode = yaffs_put_inode,
  2104. #endif
  2105. .put_super = yaffs_put_super,
  2106. #ifdef YAFFS_HAS_EVICT_INODE
  2107. .evict_inode = yaffs_evict_inode,
  2108. #else
  2109. .delete_inode = yaffs_delete_inode,
  2110. .clear_inode = yaffs_clear_inode,
  2111. #endif
  2112. .sync_fs = yaffs_sync_fs,
  2113. #ifdef YAFFS_HAS_WRITE_SUPER
  2114. .write_super = yaffs_write_super,
  2115. #endif
  2116. .remount_fs = yaffs_remount_fs,
  2117. };
  2118. struct yaffs_options {
  2119. int inband_tags;
  2120. int skip_checkpoint_read;
  2121. int skip_checkpoint_write;
  2122. int no_cache;
  2123. int tags_ecc_on;
  2124. int tags_ecc_overridden;
  2125. int lazy_loading_enabled;
  2126. int lazy_loading_overridden;
  2127. int empty_lost_and_found;
  2128. int empty_lost_and_found_overridden;
  2129. int disable_summary;
  2130. };
  2131. #define MAX_OPT_LEN 30
  2132. static int yaffs_parse_options(struct yaffs_options *options,
  2133. const char *options_str)
  2134. {
  2135. char cur_opt[MAX_OPT_LEN + 1];
  2136. int p;
  2137. int error = 0;
  2138. /* Parse through the options which is a comma seperated list */
  2139. while (options_str && *options_str && !error) {
  2140. memset(cur_opt, 0, MAX_OPT_LEN + 1);
  2141. p = 0;
  2142. while (*options_str == ',')
  2143. options_str++;
  2144. while (*options_str && *options_str != ',') {
  2145. if (p < MAX_OPT_LEN) {
  2146. cur_opt[p] = *options_str;
  2147. p++;
  2148. }
  2149. options_str++;
  2150. }
  2151. if (!strcmp(cur_opt, "inband-tags")) {
  2152. options->inband_tags = 1;
  2153. } else if (!strcmp(cur_opt, "tags-ecc-off")) {
  2154. options->tags_ecc_on = 0;
  2155. options->tags_ecc_overridden = 1;
  2156. } else if (!strcmp(cur_opt, "tags-ecc-on")) {
  2157. options->tags_ecc_on = 1;
  2158. options->tags_ecc_overridden = 1;
  2159. } else if (!strcmp(cur_opt, "lazy-loading-off")) {
  2160. options->lazy_loading_enabled = 0;
  2161. options->lazy_loading_overridden = 1;
  2162. } else if (!strcmp(cur_opt, "lazy-loading-on")) {
  2163. options->lazy_loading_enabled = 1;
  2164. options->lazy_loading_overridden = 1;
  2165. } else if (!strcmp(cur_opt, "disable-summary")) {
  2166. options->disable_summary = 1;
  2167. } else if (!strcmp(cur_opt, "empty-lost-and-found-off")) {
  2168. options->empty_lost_and_found = 0;
  2169. options->empty_lost_and_found_overridden = 1;
  2170. } else if (!strcmp(cur_opt, "empty-lost-and-found-on")) {
  2171. options->empty_lost_and_found = 1;
  2172. options->empty_lost_and_found_overridden = 1;
  2173. } else if (!strcmp(cur_opt, "no-cache")) {
  2174. options->no_cache = 1;
  2175. } else if (!strcmp(cur_opt, "no-checkpoint-read")) {
  2176. options->skip_checkpoint_read = 1;
  2177. } else if (!strcmp(cur_opt, "no-checkpoint-write")) {
  2178. options->skip_checkpoint_write = 1;
  2179. } else if (!strcmp(cur_opt, "no-checkpoint")) {
  2180. options->skip_checkpoint_read = 1;
  2181. options->skip_checkpoint_write = 1;
  2182. } else {
  2183. printk(KERN_INFO "yaffs: Bad mount option \"%s\"\n",
  2184. cur_opt);
  2185. error = 1;
  2186. }
  2187. }
  2188. return error;
  2189. }
  2190. static struct dentry *yaffs_make_root(struct inode *inode)
  2191. {
  2192. #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0))
  2193. struct dentry *root = d_alloc_root(inode);
  2194. if (!root)
  2195. iput(inode);
  2196. return root;
  2197. #else
  2198. return d_make_root(inode);
  2199. #endif
  2200. }
  2201. static struct super_block *yaffs_internal_read_super(int yaffs_version,
  2202. struct super_block *sb,
  2203. void *data, int silent)
  2204. {
  2205. int n_blocks;
  2206. struct inode *inode = NULL;
  2207. struct dentry *root;
  2208. struct yaffs_dev *dev = 0;
  2209. char devname_buf[BDEVNAME_SIZE + 1];
  2210. struct mtd_info *mtd;
  2211. int err;
  2212. char *data_str = (char *)data;
  2213. struct yaffs_linux_context *context = NULL;
  2214. struct yaffs_param *param;
  2215. int read_only = 0;
  2216. int inband_tags = 0;
  2217. struct yaffs_options options;
  2218. unsigned mount_id;
  2219. int found;
  2220. struct yaffs_linux_context *context_iterator;
  2221. struct list_head *l;
  2222. if (!sb) {
  2223. printk(KERN_INFO "yaffs: sb is NULL\n");
  2224. return NULL;
  2225. }
  2226. sb->s_magic = YAFFS_MAGIC;
  2227. sb->s_op = &yaffs_super_ops;
  2228. sb->s_flags |= MS_NOATIME;
  2229. read_only = ((sb->s_flags & MS_RDONLY) != 0);
  2230. #ifdef YAFFS_COMPILE_EXPORTFS
  2231. sb->s_export_op = &yaffs_export_ops;
  2232. #endif
  2233. if (!sb->s_dev)
  2234. printk(KERN_INFO "yaffs: sb->s_dev is NULL\n");
  2235. else if (!yaffs_devname(sb, devname_buf))
  2236. printk(KERN_INFO "yaffs: devname is NULL\n");
  2237. else
  2238. printk(KERN_INFO "yaffs: dev is %d name is \"%s\" %s\n",
  2239. sb->s_dev,
  2240. yaffs_devname(sb, devname_buf), read_only ? "ro" : "rw");
  2241. if (!data_str)
  2242. data_str = "";
  2243. printk(KERN_INFO "yaffs: passed flags \"%s\"\n", data_str);
  2244. memset(&options, 0, sizeof(options));
  2245. if (yaffs_parse_options(&options, data_str)) {
  2246. /* Option parsing failed */
  2247. return NULL;
  2248. }
  2249. sb->s_blocksize = PAGE_CACHE_SIZE;
  2250. sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
  2251. yaffs_trace(YAFFS_TRACE_OS,
  2252. "yaffs_read_super: Using yaffs%d", yaffs_version);
  2253. yaffs_trace(YAFFS_TRACE_OS,
  2254. "yaffs_read_super: block size %d", (int)(sb->s_blocksize));
  2255. yaffs_trace(YAFFS_TRACE_ALWAYS,
  2256. "yaffs: Attempting MTD mount of %u.%u,\"%s\"",
  2257. MAJOR(sb->s_dev), MINOR(sb->s_dev),
  2258. yaffs_devname(sb, devname_buf));
  2259. /* Get the device */
  2260. mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
  2261. if (IS_ERR(mtd)) {
  2262. yaffs_trace(YAFFS_TRACE_ALWAYS,
  2263. "yaffs: MTD device %u either not valid or unavailable",
  2264. MINOR(sb->s_dev));
  2265. return NULL;
  2266. }
  2267. if (yaffs_auto_select && yaffs_version == 1 && WRITE_SIZE(mtd) >= 2048) {
  2268. yaffs_trace(YAFFS_TRACE_ALWAYS, "auto selecting yaffs2");
  2269. yaffs_version = 2;
  2270. }
  2271. /* Added NCB 26/5/2006 for completeness */
  2272. if (yaffs_version == 2 && !options.inband_tags
  2273. && WRITE_SIZE(mtd) == 512) {
  2274. yaffs_trace(YAFFS_TRACE_ALWAYS, "auto selecting yaffs1");
  2275. yaffs_version = 1;
  2276. }
  2277. if (mtd->oobavail < sizeof(struct yaffs_packed_tags2) ||
  2278. options.inband_tags)
  2279. inband_tags = 1;
  2280. if(yaffs_verify_mtd(mtd, yaffs_version, inband_tags) < 0)
  2281. return NULL;
  2282. /* OK, so if we got here, we have an MTD that's NAND and looks
  2283. * like it has the right capabilities
  2284. * Set the struct yaffs_dev up for mtd
  2285. */
  2286. if (!read_only && !(mtd->flags & MTD_WRITEABLE)) {
  2287. read_only = 1;
  2288. printk(KERN_INFO
  2289. "yaffs: mtd is read only, setting superblock read only\n"
  2290. );
  2291. sb->s_flags |= MS_RDONLY;
  2292. }
  2293. dev = kmalloc(sizeof(struct yaffs_dev), GFP_KERNEL);
  2294. context = kmalloc(sizeof(struct yaffs_linux_context), GFP_KERNEL);
  2295. if (!dev || !context) {
  2296. kfree(dev);
  2297. kfree(context);
  2298. dev = NULL;
  2299. context = NULL;
  2300. /* Deep shit could not allocate device structure */
  2301. yaffs_trace(YAFFS_TRACE_ALWAYS,
  2302. "yaffs_read_super: Failed trying to allocate struct yaffs_dev."
  2303. );
  2304. return NULL;
  2305. }
  2306. memset(dev, 0, sizeof(struct yaffs_dev));
  2307. param = &(dev->param);
  2308. memset(context, 0, sizeof(struct yaffs_linux_context));
  2309. dev->os_context = context;
  2310. INIT_LIST_HEAD(&(context->context_list));
  2311. context->dev = dev;
  2312. context->super = sb;
  2313. dev->read_only = read_only;
  2314. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
  2315. sb->s_fs_info = dev;
  2316. #else
  2317. sb->u.generic_sbp = dev;
  2318. #endif
  2319. dev->driver_context = mtd;
  2320. param->name = mtd->name;
  2321. /* Set up the memory size parameters.... */
  2322. param->n_reserved_blocks = 5;
  2323. param->n_caches = (options.no_cache) ? 0 : 10;
  2324. param->inband_tags = inband_tags;
  2325. param->enable_xattr = 1;
  2326. if (options.lazy_loading_overridden)
  2327. param->disable_lazy_load = !options.lazy_loading_enabled;
  2328. param->defered_dir_update = 1;
  2329. if (options.tags_ecc_overridden)
  2330. param->no_tags_ecc = !options.tags_ecc_on;
  2331. param->empty_lost_n_found = 1;
  2332. param->refresh_period = 500;
  2333. param->disable_summary = options.disable_summary;
  2334. #ifdef CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING
  2335. param->disable_bad_block_marking = 1;
  2336. #endif
  2337. if (options.empty_lost_and_found_overridden)
  2338. param->empty_lost_n_found = options.empty_lost_and_found;
  2339. /* ... and the functions. */
  2340. if (yaffs_version == 2) {
  2341. param->is_yaffs2 = 1;
  2342. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
  2343. param->total_bytes_per_chunk = mtd->writesize;
  2344. param->chunks_per_block = mtd->erasesize / mtd->writesize;
  2345. #else
  2346. param->total_bytes_per_chunk = mtd->oobblock;
  2347. param->chunks_per_block = mtd->erasesize / mtd->oobblock;
  2348. #endif
  2349. n_blocks = YCALCBLOCKS(mtd->size, mtd->erasesize);
  2350. param->start_block = 0;
  2351. param->end_block = n_blocks - 1;
  2352. } else {
  2353. param->is_yaffs2 = 0;
  2354. n_blocks = YCALCBLOCKS(mtd->size,
  2355. YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
  2356. param->chunks_per_block = YAFFS_CHUNKS_PER_BLOCK;
  2357. param->total_bytes_per_chunk = YAFFS_BYTES_PER_CHUNK;
  2358. }
  2359. param->start_block = 0;
  2360. param->end_block = n_blocks - 1;
  2361. yaffs_mtd_drv_install(dev);
  2362. param->sb_dirty_fn = yaffs_set_super_dirty;
  2363. param->gc_control_fn = yaffs_gc_control_callback;
  2364. yaffs_dev_to_lc(dev)->super = sb;
  2365. param->use_nand_ecc = 1;
  2366. param->skip_checkpt_rd = options.skip_checkpoint_read;
  2367. param->skip_checkpt_wr = options.skip_checkpoint_write;
  2368. mutex_lock(&yaffs_context_lock);
  2369. /* Get a mount id */
  2370. found = 0;
  2371. for (mount_id = 0; !found; mount_id++) {
  2372. found = 1;
  2373. list_for_each(l, &yaffs_context_list) {
  2374. context_iterator =
  2375. list_entry(l, struct yaffs_linux_context,
  2376. context_list);
  2377. if (context_iterator->mount_id == mount_id)
  2378. found = 0;
  2379. }
  2380. }
  2381. context->mount_id = mount_id;
  2382. list_add_tail(&(yaffs_dev_to_lc(dev)->context_list),
  2383. &yaffs_context_list);
  2384. mutex_unlock(&yaffs_context_lock);
  2385. /* Directory search handling... */
  2386. INIT_LIST_HEAD(&(yaffs_dev_to_lc(dev)->search_contexts));
  2387. param->remove_obj_fn = yaffs_remove_obj_callback;
  2388. mutex_init(&(yaffs_dev_to_lc(dev)->gross_lock));
  2389. yaffs_gross_lock(dev);
  2390. err = yaffs_guts_initialise(dev);
  2391. yaffs_trace(YAFFS_TRACE_OS,
  2392. "yaffs_read_super: guts initialised %s",
  2393. (err == YAFFS_OK) ? "OK" : "FAILED");
  2394. if (err == YAFFS_OK)
  2395. yaffs_bg_start(dev);
  2396. if (!context->bg_thread)
  2397. param->defered_dir_update = 0;
  2398. sb->s_maxbytes = yaffs_max_file_size(dev);
  2399. /* Release lock before yaffs_get_inode() */
  2400. yaffs_gross_unlock(dev);
  2401. /* Create root inode */
  2402. if (err == YAFFS_OK)
  2403. inode = yaffs_get_inode(sb, S_IFDIR | 0755, 0, yaffs_root(dev));
  2404. if (!inode)
  2405. return NULL;
  2406. inode->i_op = &yaffs_dir_inode_operations;
  2407. inode->i_fop = &yaffs_dir_operations;
  2408. yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: got root inode");
  2409. root = yaffs_make_root(inode);
  2410. if (!root)
  2411. return NULL;
  2412. sb->s_root = root;
  2413. if(!dev->is_checkpointed)
  2414. yaffs_set_super_dirty(dev);
  2415. yaffs_trace(YAFFS_TRACE_ALWAYS,
  2416. "yaffs_read_super: is_checkpointed %d",
  2417. dev->is_checkpointed);
  2418. yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: done");
  2419. return sb;
  2420. }
  2421. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
  2422. static int yaffs_internal_read_super_mtd(struct super_block *sb, void *data,
  2423. int silent)
  2424. {
  2425. return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL;
  2426. }
  2427. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
  2428. static struct dentry *yaffs_mount(struct file_system_type *fs_type, int flags,
  2429. const char *dev_name, void *data)
  2430. {
  2431. return mount_bdev(fs_type, flags, dev_name, data, yaffs_internal_read_super_mtd);
  2432. }
  2433. #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
  2434. static int yaffs_read_super(struct file_system_type *fs,
  2435. int flags, const char *dev_name,
  2436. void *data, struct vfsmount *mnt)
  2437. {
  2438. return get_sb_bdev(fs, flags, dev_name, data,
  2439. yaffs_internal_read_super_mtd, mnt);
  2440. }
  2441. #else
  2442. static struct super_block *yaffs_read_super(struct file_system_type *fs,
  2443. int flags, const char *dev_name,
  2444. void *data)
  2445. {
  2446. return get_sb_bdev(fs, flags, dev_name, data,
  2447. yaffs_internal_read_super_mtd);
  2448. }
  2449. #endif
  2450. static struct file_system_type yaffs_fs_type = {
  2451. .owner = THIS_MODULE,
  2452. .name = "yaffs",
  2453. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
  2454. .mount = yaffs_mount,
  2455. #else
  2456. .get_sb = yaffs_read_super,
  2457. #endif
  2458. .kill_sb = kill_block_super,
  2459. .fs_flags = FS_REQUIRES_DEV,
  2460. };
  2461. #else
  2462. static struct super_block *yaffs_read_super(struct super_block *sb, void *data,
  2463. int silent)
  2464. {
  2465. return yaffs_internal_read_super(1, sb, data, silent);
  2466. }
  2467. static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super,
  2468. FS_REQUIRES_DEV);
  2469. #endif
  2470. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
  2471. static int yaffs2_internal_read_super_mtd(struct super_block *sb, void *data,
  2472. int silent)
  2473. {
  2474. return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL;
  2475. }
  2476. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
  2477. static struct dentry *yaffs2_mount(struct file_system_type *fs_type, int flags,
  2478. const char *dev_name, void *data)
  2479. {
  2480. return mount_bdev(fs_type, flags, dev_name, data, yaffs2_internal_read_super_mtd);
  2481. }
  2482. #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
  2483. static int yaffs2_read_super(struct file_system_type *fs,
  2484. int flags, const char *dev_name, void *data,
  2485. struct vfsmount *mnt)
  2486. {
  2487. return get_sb_bdev(fs, flags, dev_name, data,
  2488. yaffs2_internal_read_super_mtd, mnt);
  2489. }
  2490. #else
  2491. static struct super_block *yaffs2_read_super(struct file_system_type *fs,
  2492. int flags, const char *dev_name,
  2493. void *data)
  2494. {
  2495. return get_sb_bdev(fs, flags, dev_name, data,
  2496. yaffs2_internal_read_super_mtd);
  2497. }
  2498. #endif
  2499. static struct file_system_type yaffs2_fs_type = {
  2500. .owner = THIS_MODULE,
  2501. .name = "yaffs2",
  2502. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
  2503. .mount = yaffs2_mount,
  2504. #else
  2505. .get_sb = yaffs2_read_super,
  2506. #endif
  2507. .kill_sb = kill_block_super,
  2508. .fs_flags = FS_REQUIRES_DEV,
  2509. };
  2510. #else
  2511. static struct super_block *yaffs2_read_super(struct super_block *sb,
  2512. void *data, int silent)
  2513. {
  2514. return yaffs_internal_read_super(2, sb, data, silent);
  2515. }
  2516. static DECLARE_FSTYPE(yaffs2_fs_type, "yaffs2", yaffs2_read_super,
  2517. FS_REQUIRES_DEV);
  2518. #endif
  2519. static struct proc_dir_entry *my_proc_entry;
  2520. static char *yaffs_dump_dev_part0(char *buf, struct yaffs_dev *dev)
  2521. {
  2522. struct yaffs_param *param = &dev->param;
  2523. int bs[10];
  2524. yaffs_count_blocks_by_state(dev,bs);
  2525. buf += sprintf(buf, "start_block.......... %d\n", param->start_block);
  2526. buf += sprintf(buf, "end_block............ %d\n", param->end_block);
  2527. buf += sprintf(buf, "total_bytes_per_chunk %d\n",
  2528. param->total_bytes_per_chunk);
  2529. buf += sprintf(buf, "use_nand_ecc......... %d\n", param->use_nand_ecc);
  2530. buf += sprintf(buf, "no_tags_ecc.......... %d\n", param->no_tags_ecc);
  2531. buf += sprintf(buf, "is_yaffs2............ %d\n", param->is_yaffs2);
  2532. buf += sprintf(buf, "inband_tags.......... %d\n", param->inband_tags);
  2533. buf += sprintf(buf, "empty_lost_n_found... %d\n",
  2534. param->empty_lost_n_found);
  2535. buf += sprintf(buf, "disable_lazy_load.... %d\n",
  2536. param->disable_lazy_load);
  2537. buf += sprintf(buf, "disable_bad_block_mrk %d\n",
  2538. param->disable_bad_block_marking);
  2539. buf += sprintf(buf, "refresh_period....... %d\n",
  2540. param->refresh_period);
  2541. buf += sprintf(buf, "n_caches............. %d\n", param->n_caches);
  2542. buf += sprintf(buf, "n_reserved_blocks.... %d\n",
  2543. param->n_reserved_blocks);
  2544. buf += sprintf(buf, "always_check_erased.. %d\n",
  2545. param->always_check_erased);
  2546. buf += sprintf(buf, "\n");
  2547. buf += sprintf(buf, "block count by state\n");
  2548. buf += sprintf(buf, "0:%d 1:%d 2:%d 3:%d 4:%d\n",
  2549. bs[0], bs[1], bs[2], bs[3], bs[4]);
  2550. buf += sprintf(buf, "5:%d 6:%d 7:%d 8:%d 9:%d\n",
  2551. bs[5], bs[6], bs[7], bs[8], bs[9]);
  2552. return buf;
  2553. }
  2554. static char *yaffs_dump_dev_part1(char *buf, struct yaffs_dev *dev)
  2555. {
  2556. buf += sprintf(buf, "max file size....... %lld\n",
  2557. (long long) yaffs_max_file_size(dev));
  2558. buf += sprintf(buf, "data_bytes_per_chunk. %d\n",
  2559. dev->data_bytes_per_chunk);
  2560. buf += sprintf(buf, "chunk_grp_bits....... %d\n", dev->chunk_grp_bits);
  2561. buf += sprintf(buf, "chunk_grp_size....... %d\n", dev->chunk_grp_size);
  2562. buf += sprintf(buf, "n_erased_blocks...... %d\n", dev->n_erased_blocks);
  2563. buf += sprintf(buf, "blocks_in_checkpt.... %d\n",
  2564. dev->blocks_in_checkpt);
  2565. buf += sprintf(buf, "\n");
  2566. buf += sprintf(buf, "n_tnodes............. %d\n", dev->n_tnodes);
  2567. buf += sprintf(buf, "n_obj................ %d\n", dev->n_obj);
  2568. buf += sprintf(buf, "n_free_chunks........ %d\n", dev->n_free_chunks);
  2569. buf += sprintf(buf, "\n");
  2570. buf += sprintf(buf, "n_page_writes........ %u\n", dev->n_page_writes);
  2571. buf += sprintf(buf, "n_page_reads......... %u\n", dev->n_page_reads);
  2572. buf += sprintf(buf, "n_erasures........... %u\n", dev->n_erasures);
  2573. buf += sprintf(buf, "n_gc_copies.......... %u\n", dev->n_gc_copies);
  2574. buf += sprintf(buf, "all_gcs.............. %u\n", dev->all_gcs);
  2575. buf += sprintf(buf, "passive_gc_count..... %u\n",
  2576. dev->passive_gc_count);
  2577. buf += sprintf(buf, "oldest_dirty_gc_count %u\n",
  2578. dev->oldest_dirty_gc_count);
  2579. buf += sprintf(buf, "n_gc_blocks.......... %u\n", dev->n_gc_blocks);
  2580. buf += sprintf(buf, "bg_gcs............... %u\n", dev->bg_gcs);
  2581. buf += sprintf(buf, "n_retried_writes..... %u\n",
  2582. dev->n_retried_writes);
  2583. buf += sprintf(buf, "n_retired_blocks..... %u\n",
  2584. dev->n_retired_blocks);
  2585. buf += sprintf(buf, "n_ecc_fixed.......... %u\n", dev->n_ecc_fixed);
  2586. buf += sprintf(buf, "n_ecc_unfixed........ %u\n", dev->n_ecc_unfixed);
  2587. buf += sprintf(buf, "n_tags_ecc_fixed..... %u\n",
  2588. dev->n_tags_ecc_fixed);
  2589. buf += sprintf(buf, "n_tags_ecc_unfixed... %u\n",
  2590. dev->n_tags_ecc_unfixed);
  2591. buf += sprintf(buf, "cache_hits........... %u\n", dev->cache_hits);
  2592. buf += sprintf(buf, "n_deleted_files...... %u\n", dev->n_deleted_files);
  2593. buf += sprintf(buf, "n_unlinked_files..... %u\n",
  2594. dev->n_unlinked_files);
  2595. buf += sprintf(buf, "refresh_count........ %u\n", dev->refresh_count);
  2596. buf += sprintf(buf, "n_bg_deletions....... %u\n", dev->n_bg_deletions);
  2597. buf += sprintf(buf, "tags_used............ %u\n", dev->tags_used);
  2598. buf += sprintf(buf, "summary_used......... %u\n", dev->summary_used);
  2599. return buf;
  2600. }
  2601. static int yaffs_proc_read(char *page,
  2602. char **start,
  2603. off_t offset, int count, int *eof, void *data)
  2604. {
  2605. struct list_head *item;
  2606. char *buf = page;
  2607. int step = offset;
  2608. int n = 0;
  2609. /* Get proc_file_read() to step 'offset' by one on each sucessive call.
  2610. * We use 'offset' (*ppos) to indicate where we are in dev_list.
  2611. * This also assumes the user has posted a read buffer large
  2612. * enough to hold the complete output; but that's life in /proc.
  2613. */
  2614. *(int *)start = 1;
  2615. /* Print header first */
  2616. if (step == 0)
  2617. buf +=
  2618. sprintf(buf,
  2619. "Multi-version YAFFS."
  2620. "\n");
  2621. else if (step == 1)
  2622. buf += sprintf(buf, "\n");
  2623. else {
  2624. step -= 2;
  2625. mutex_lock(&yaffs_context_lock);
  2626. /* Locate and print the Nth entry. Order N-squared but N is small. */
  2627. list_for_each(item, &yaffs_context_list) {
  2628. struct yaffs_linux_context *dc =
  2629. list_entry(item, struct yaffs_linux_context,
  2630. context_list);
  2631. struct yaffs_dev *dev = dc->dev;
  2632. if (n < (step & ~1)) {
  2633. n += 2;
  2634. continue;
  2635. }
  2636. if ((step & 1) == 0) {
  2637. buf +=
  2638. sprintf(buf, "\nDevice %d \"%s\"\n", n,
  2639. dev->param.name);
  2640. buf = yaffs_dump_dev_part0(buf, dev);
  2641. } else {
  2642. buf = yaffs_dump_dev_part1(buf, dev);
  2643. }
  2644. break;
  2645. }
  2646. mutex_unlock(&yaffs_context_lock);
  2647. }
  2648. return buf - page < count ? buf - page : count;
  2649. }
  2650. /**
  2651. * Set the verbosity of the warnings and error messages.
  2652. *
  2653. * Note that the names can only be a..z or _ with the current code.
  2654. */
  2655. static struct {
  2656. char *mask_name;
  2657. unsigned mask_bitfield;
  2658. } mask_flags[] = {
  2659. {"allocate", YAFFS_TRACE_ALLOCATE},
  2660. {"always", YAFFS_TRACE_ALWAYS},
  2661. {"background", YAFFS_TRACE_BACKGROUND},
  2662. {"bad_blocks", YAFFS_TRACE_BAD_BLOCKS},
  2663. {"buffers", YAFFS_TRACE_BUFFERS},
  2664. {"bug", YAFFS_TRACE_BUG},
  2665. {"checkpt", YAFFS_TRACE_CHECKPOINT},
  2666. {"deletion", YAFFS_TRACE_DELETION},
  2667. {"erase", YAFFS_TRACE_ERASE},
  2668. {"error", YAFFS_TRACE_ERROR},
  2669. {"gc_detail", YAFFS_TRACE_GC_DETAIL},
  2670. {"gc", YAFFS_TRACE_GC},
  2671. {"lock", YAFFS_TRACE_LOCK},
  2672. {"mtd", YAFFS_TRACE_MTD},
  2673. {"nandaccess", YAFFS_TRACE_NANDACCESS},
  2674. {"os", YAFFS_TRACE_OS},
  2675. {"scan_debug", YAFFS_TRACE_SCAN_DEBUG},
  2676. {"scan", YAFFS_TRACE_SCAN},
  2677. {"mount", YAFFS_TRACE_MOUNT},
  2678. {"tracing", YAFFS_TRACE_TRACING},
  2679. {"sync", YAFFS_TRACE_SYNC},
  2680. {"write", YAFFS_TRACE_WRITE},
  2681. {"verify", YAFFS_TRACE_VERIFY},
  2682. {"verify_nand", YAFFS_TRACE_VERIFY_NAND},
  2683. {"verify_full", YAFFS_TRACE_VERIFY_FULL},
  2684. {"verify_all", YAFFS_TRACE_VERIFY_ALL},
  2685. {"all", 0xffffffff},
  2686. {"none", 0},
  2687. {NULL, 0},
  2688. };
  2689. #define MAX_MASK_NAME_LENGTH 40
  2690. static int yaffs_proc_write_trace_options(struct file *file, const char *buf,
  2691. unsigned long count)
  2692. {
  2693. unsigned rg = 0, mask_bitfield;
  2694. char *end;
  2695. char *mask_name;
  2696. const char *x;
  2697. char substring[MAX_MASK_NAME_LENGTH + 1];
  2698. int i;
  2699. int done = 0;
  2700. int add, len = 0;
  2701. int pos = 0;
  2702. rg = yaffs_trace_mask;
  2703. while (!done && (pos < count)) {
  2704. done = 1;
  2705. while ((pos < count) && isspace(buf[pos]))
  2706. pos++;
  2707. switch (buf[pos]) {
  2708. case '+':
  2709. case '-':
  2710. case '=':
  2711. add = buf[pos];
  2712. pos++;
  2713. break;
  2714. default:
  2715. add = ' ';
  2716. break;
  2717. }
  2718. mask_name = NULL;
  2719. mask_bitfield = simple_strtoul(buf + pos, &end, 0);
  2720. if (end > buf + pos) {
  2721. mask_name = "numeral";
  2722. len = end - (buf + pos);
  2723. pos += len;
  2724. done = 0;
  2725. } else {
  2726. for (x = buf + pos, i = 0;
  2727. (*x == '_' || (*x >= 'a' && *x <= 'z')) &&
  2728. i < MAX_MASK_NAME_LENGTH; x++, i++, pos++)
  2729. substring[i] = *x;
  2730. substring[i] = '\0';
  2731. for (i = 0; mask_flags[i].mask_name != NULL; i++) {
  2732. if (strcmp(substring, mask_flags[i].mask_name)
  2733. == 0) {
  2734. mask_name = mask_flags[i].mask_name;
  2735. mask_bitfield =
  2736. mask_flags[i].mask_bitfield;
  2737. done = 0;
  2738. break;
  2739. }
  2740. }
  2741. }
  2742. if (mask_name != NULL) {
  2743. done = 0;
  2744. switch (add) {
  2745. case '-':
  2746. rg &= ~mask_bitfield;
  2747. break;
  2748. case '+':
  2749. rg |= mask_bitfield;
  2750. break;
  2751. case '=':
  2752. rg = mask_bitfield;
  2753. break;
  2754. default:
  2755. rg |= mask_bitfield;
  2756. break;
  2757. }
  2758. }
  2759. }
  2760. yaffs_trace_mask = rg | YAFFS_TRACE_ALWAYS;
  2761. printk(KERN_DEBUG "new trace = 0x%08X\n", yaffs_trace_mask);
  2762. if (rg & YAFFS_TRACE_ALWAYS) {
  2763. for (i = 0; mask_flags[i].mask_name != NULL; i++) {
  2764. char flag;
  2765. flag = ((rg & mask_flags[i].mask_bitfield) ==
  2766. mask_flags[i].mask_bitfield) ? '+' : '-';
  2767. printk(KERN_DEBUG "%c%s\n", flag,
  2768. mask_flags[i].mask_name);
  2769. }
  2770. }
  2771. return count;
  2772. }
  2773. /* Debug strings are of the form:
  2774. * .bnnn print info on block n
  2775. * .cobjn,chunkn print nand chunk id for objn:chunkn
  2776. */
  2777. static int yaffs_proc_debug_write(struct file *file, const char *buf,
  2778. unsigned long count)
  2779. {
  2780. char str[100];
  2781. char *p0;
  2782. char *p1;
  2783. long p1_val;
  2784. long p0_val;
  2785. char cmd;
  2786. struct list_head *item;
  2787. memset(str, 0, sizeof(str));
  2788. memcpy(str, buf, min((size_t)count, sizeof(str) -1));
  2789. cmd = str[1];
  2790. p0 = str + 2;
  2791. p1 = p0;
  2792. while (*p1 && *p1 != ',') {
  2793. p1++;
  2794. }
  2795. *p1 = '\0';
  2796. p1++;
  2797. p0_val = simple_strtol(p0, NULL, 0);
  2798. p1_val = simple_strtol(p1, NULL, 0);
  2799. mutex_lock(&yaffs_context_lock);
  2800. /* Locate and print the Nth entry. Order N-squared but N is small. */
  2801. list_for_each(item, &yaffs_context_list) {
  2802. struct yaffs_linux_context *dc =
  2803. list_entry(item, struct yaffs_linux_context,
  2804. context_list);
  2805. struct yaffs_dev *dev = dc->dev;
  2806. if (cmd == 'b') {
  2807. struct yaffs_block_info *bi;
  2808. bi = yaffs_get_block_info(dev,p0_val);
  2809. if(bi) {
  2810. printk("Block %d: state %d, retire %d, use %d, seq %d\n",
  2811. (int)p0_val, bi->block_state,
  2812. bi->needs_retiring, bi->pages_in_use,
  2813. bi->seq_number);
  2814. }
  2815. } else if (cmd == 'c') {
  2816. struct yaffs_obj *obj;
  2817. int nand_chunk;
  2818. obj = yaffs_find_by_number(dev, p0_val);
  2819. if (!obj)
  2820. printk("No obj %d\n", (int)p0_val);
  2821. else {
  2822. if(p1_val == 0)
  2823. nand_chunk = obj->hdr_chunk;
  2824. else
  2825. nand_chunk =
  2826. yaffs_find_chunk_in_file(obj,
  2827. p1_val, NULL);
  2828. printk("Nand chunk for %d:%d is %d\n",
  2829. (int)p0_val, (int)p1_val, nand_chunk);
  2830. }
  2831. }
  2832. }
  2833. mutex_unlock(&yaffs_context_lock);
  2834. return count;
  2835. }
  2836. #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
  2837. static int yaffs_proc_write(struct file *file, const char *buf,
  2838. unsigned long count, void *ppos)
  2839. #else
  2840. static ssize_t yaffs_proc_write(struct file *file, const char __user *buf,
  2841. size_t count, loff_t *ppos)
  2842. #endif
  2843. {
  2844. if (buf[0] == '.')
  2845. return yaffs_proc_debug_write(file, buf, count);
  2846. return yaffs_proc_write_trace_options(file, buf, count);
  2847. }
  2848. /* Stuff to handle installation of file systems */
  2849. struct file_system_to_install {
  2850. struct file_system_type *fst;
  2851. int installed;
  2852. };
  2853. static struct file_system_to_install fs_to_install[] = {
  2854. {&yaffs_fs_type, 0},
  2855. {&yaffs2_fs_type, 0},
  2856. {NULL, 0}
  2857. };
  2858. #ifdef YAFFS_NEW_PROCFS
  2859. static int yaffs_proc_show(struct seq_file *m, void *v)
  2860. {
  2861. /* FIXME: Unify in a better way? */
  2862. char buffer[512];
  2863. char *start;
  2864. int len;
  2865. len = yaffs_proc_read(buffer, &start, 0, sizeof(buffer), NULL, NULL);
  2866. seq_puts(m, buffer);
  2867. return 0;
  2868. }
  2869. static int yaffs_proc_open(struct inode *inode, struct file *file)
  2870. {
  2871. return single_open(file, yaffs_proc_show, NULL);
  2872. }
  2873. static struct file_operations procfs_ops = {
  2874. .owner = THIS_MODULE,
  2875. .open = yaffs_proc_open,
  2876. .read = seq_read,
  2877. .write = yaffs_proc_write,
  2878. };
  2879. static int yaffs_procfs_init(void)
  2880. {
  2881. /* Install the proc_fs entries */
  2882. my_proc_entry = proc_create("yaffs",
  2883. S_IRUGO | S_IFREG,
  2884. YPROC_ROOT,
  2885. &procfs_ops);
  2886. if (my_proc_entry) {
  2887. return 0;
  2888. } else {
  2889. return -ENOMEM;
  2890. }
  2891. }
  2892. #else
  2893. static int yaffs_procfs_init(void)
  2894. {
  2895. /* Install the proc_fs entries */
  2896. my_proc_entry = create_proc_entry("yaffs",
  2897. S_IRUGO | S_IFREG, YPROC_ROOT);
  2898. if (my_proc_entry) {
  2899. my_proc_entry->write_proc = yaffs_proc_write;
  2900. my_proc_entry->read_proc = yaffs_proc_read;
  2901. my_proc_entry->data = NULL;
  2902. return 0;
  2903. } else {
  2904. return -ENOMEM;
  2905. }
  2906. }
  2907. #endif
  2908. static int __init init_yaffs_fs(void)
  2909. {
  2910. int error = 0;
  2911. struct file_system_to_install *fsinst;
  2912. yaffs_trace(YAFFS_TRACE_ALWAYS,
  2913. "yaffs Installing.");
  2914. mutex_init(&yaffs_context_lock);
  2915. error = yaffs_procfs_init();
  2916. if (error)
  2917. return error;
  2918. /* Now add the file system entries */
  2919. fsinst = fs_to_install;
  2920. while (fsinst->fst && !error) {
  2921. error = register_filesystem(fsinst->fst);
  2922. if (!error)
  2923. fsinst->installed = 1;
  2924. fsinst++;
  2925. }
  2926. /* Any errors? uninstall */
  2927. if (error) {
  2928. fsinst = fs_to_install;
  2929. while (fsinst->fst) {
  2930. if (fsinst->installed) {
  2931. unregister_filesystem(fsinst->fst);
  2932. fsinst->installed = 0;
  2933. }
  2934. fsinst++;
  2935. }
  2936. }
  2937. return error;
  2938. }
  2939. static void __exit exit_yaffs_fs(void)
  2940. {
  2941. struct file_system_to_install *fsinst;
  2942. yaffs_trace(YAFFS_TRACE_ALWAYS,
  2943. "yaffs removing.");
  2944. remove_proc_entry("yaffs", YPROC_ROOT);
  2945. fsinst = fs_to_install;
  2946. while (fsinst->fst) {
  2947. if (fsinst->installed) {
  2948. unregister_filesystem(fsinst->fst);
  2949. fsinst->installed = 0;
  2950. }
  2951. fsinst++;
  2952. }
  2953. }
  2954. module_init(init_yaffs_fs)
  2955. module_exit(exit_yaffs_fs)
  2956. MODULE_DESCRIPTION("YAFFS2 - a NAND specific flash file system");
  2957. MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002-2011");
  2958. MODULE_LICENSE("GPL");