vvfat.c 102 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288
  1. /* vim:set shiftwidth=4 ts=4: */
  2. /*
  3. * QEMU Block driver for virtual VFAT (shadows a local directory)
  4. *
  5. * Copyright (c) 2004,2005 Johannes E. Schindelin
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. * THE SOFTWARE.
  24. */
  25. #include "qemu/osdep.h"
  26. #include <dirent.h>
  27. #include <glib/gstdio.h>
  28. #include "qapi/error.h"
  29. #include "block/block-io.h"
  30. #include "block/block_int.h"
  31. #include "block/qdict.h"
  32. #include "qemu/module.h"
  33. #include "qemu/option.h"
  34. #include "qemu/bswap.h"
  35. #include "migration/blocker.h"
  36. #include "qobject/qdict.h"
  37. #include "qobject/qstring.h"
  38. #include "qemu/ctype.h"
  39. #include "qemu/cutils.h"
  40. #include "qemu/error-report.h"
  41. #ifndef S_IWGRP
  42. #define S_IWGRP 0
  43. #endif
  44. #ifndef S_IWOTH
  45. #define S_IWOTH 0
  46. #endif
  47. /* TODO: add ":bootsector=blabla.img:" */
  48. /* LATER TODO: add automatic boot sector generation from
  49. BOOTEASY.ASM and Ranish Partition Manager
  50. Note that DOS assumes the system files to be the first files in the
  51. file system (test if the boot sector still relies on that fact)! */
  52. /* MAYBE TODO: write block-visofs.c */
  53. /* TODO: call try_commit() only after a timeout */
  54. /* #define DEBUG */
  55. #ifdef DEBUG
  56. #define DLOG(a) a
  57. static void checkpoint(void);
  58. #else
  59. #define DLOG(a)
  60. #endif
  61. /* bootsector OEM name. see related compatibility problems at:
  62. * https://jdebp.eu/FGA/volume-boot-block-oem-name-field.html
  63. * http://seasip.info/Misc/oemid.html
  64. */
  65. #define BOOTSECTOR_OEM_NAME "MSWIN4.1"
  66. #define DIR_DELETED 0xe5
  67. #define DIR_KANJI DIR_DELETED
  68. #define DIR_KANJI_FAKE 0x05
  69. #define DIR_FREE 0x00
  70. /* dynamic array functions */
  71. typedef struct array_t {
  72. char* pointer;
  73. unsigned int size,next,item_size;
  74. } array_t;
  75. static inline void array_init(array_t* array,unsigned int item_size)
  76. {
  77. array->pointer = NULL;
  78. array->size=0;
  79. array->next=0;
  80. array->item_size=item_size;
  81. }
  82. static inline void array_free(array_t* array)
  83. {
  84. g_free(array->pointer);
  85. array->size=array->next=0;
  86. }
  87. /* does not automatically grow */
  88. static inline void* array_get(array_t* array,unsigned int index) {
  89. assert(index < array->next);
  90. assert(array->pointer);
  91. return array->pointer + index * array->item_size;
  92. }
  93. static inline void array_ensure_allocated(array_t *array, int index)
  94. {
  95. if((index + 1) * array->item_size > array->size) {
  96. int new_size = (index + 32) * array->item_size;
  97. array->pointer = g_realloc(array->pointer, new_size);
  98. assert(array->pointer);
  99. memset(array->pointer + array->size, 0, new_size - array->size);
  100. array->size = new_size;
  101. array->next = index + 1;
  102. }
  103. }
  104. static inline void* array_get_next(array_t* array) {
  105. unsigned int next = array->next;
  106. array_ensure_allocated(array, next);
  107. array->next = next + 1;
  108. return array_get(array, next);
  109. }
  110. static inline void* array_insert(array_t* array,unsigned int index,unsigned int count) {
  111. if((array->next+count)*array->item_size>array->size) {
  112. int increment=count*array->item_size;
  113. array->pointer=g_realloc(array->pointer,array->size+increment);
  114. if(!array->pointer)
  115. return NULL;
  116. array->size+=increment;
  117. }
  118. memmove(array->pointer+(index+count)*array->item_size,
  119. array->pointer+index*array->item_size,
  120. (array->next-index)*array->item_size);
  121. array->next+=count;
  122. return array->pointer+index*array->item_size;
  123. }
  124. static inline int array_remove_slice(array_t* array,int index, int count)
  125. {
  126. assert(index >=0);
  127. assert(count > 0);
  128. assert(index + count <= array->next);
  129. memmove(array->pointer + index * array->item_size,
  130. array->pointer + (index + count) * array->item_size,
  131. (array->next - index - count) * array->item_size);
  132. array->next -= count;
  133. return 0;
  134. }
  135. static int array_remove(array_t* array,int index)
  136. {
  137. return array_remove_slice(array, index, 1);
  138. }
  139. /* return the index for a given member */
  140. static int array_index(array_t* array, void* pointer)
  141. {
  142. size_t offset = (char*)pointer - array->pointer;
  143. assert((offset % array->item_size) == 0);
  144. assert(offset/array->item_size < array->next);
  145. return offset/array->item_size;
  146. }
  147. /* These structures are used to fake a disk and the VFAT filesystem.
  148. * For this reason we need to use QEMU_PACKED. */
  149. typedef struct bootsector_t {
  150. uint8_t jump[3];
  151. uint8_t name[8];
  152. uint16_t sector_size;
  153. uint8_t sectors_per_cluster;
  154. uint16_t reserved_sectors;
  155. uint8_t number_of_fats;
  156. uint16_t root_entries;
  157. uint16_t total_sectors16;
  158. uint8_t media_type;
  159. uint16_t sectors_per_fat;
  160. uint16_t sectors_per_track;
  161. uint16_t number_of_heads;
  162. uint32_t hidden_sectors;
  163. uint32_t total_sectors;
  164. union {
  165. struct {
  166. uint8_t drive_number;
  167. uint8_t reserved1;
  168. uint8_t signature;
  169. uint32_t id;
  170. uint8_t volume_label[11];
  171. uint8_t fat_type[8];
  172. uint8_t ignored[0x1c0];
  173. } QEMU_PACKED fat16;
  174. struct {
  175. uint32_t sectors_per_fat;
  176. uint16_t flags;
  177. uint8_t major,minor;
  178. uint32_t first_cluster_of_root_dir;
  179. uint16_t info_sector;
  180. uint16_t backup_boot_sector;
  181. uint8_t reserved[12];
  182. uint8_t drive_number;
  183. uint8_t reserved1;
  184. uint8_t signature;
  185. uint32_t id;
  186. uint8_t volume_label[11];
  187. uint8_t fat_type[8];
  188. uint8_t ignored[0x1a4];
  189. } QEMU_PACKED fat32;
  190. } u;
  191. uint8_t magic[2];
  192. } QEMU_PACKED bootsector_t;
  193. typedef struct {
  194. uint8_t head;
  195. uint8_t sector;
  196. uint8_t cylinder;
  197. } mbr_chs_t;
  198. typedef struct partition_t {
  199. uint8_t attributes; /* 0x80 = bootable */
  200. mbr_chs_t start_CHS;
  201. uint8_t fs_type; /* 0x1 = FAT12, 0x6 = FAT16, 0xe = FAT16_LBA, 0xb = FAT32, 0xc = FAT32_LBA */
  202. mbr_chs_t end_CHS;
  203. uint32_t start_sector_long;
  204. uint32_t length_sector_long;
  205. } QEMU_PACKED partition_t;
  206. typedef struct mbr_t {
  207. uint8_t ignored[0x1b8];
  208. uint32_t nt_id;
  209. uint8_t ignored2[2];
  210. partition_t partition[4];
  211. uint8_t magic[2];
  212. } QEMU_PACKED mbr_t;
  213. typedef struct direntry_t {
  214. uint8_t name[8 + 3];
  215. uint8_t attributes;
  216. uint8_t reserved[2];
  217. uint16_t ctime;
  218. uint16_t cdate;
  219. uint16_t adate;
  220. uint16_t begin_hi;
  221. uint16_t mtime;
  222. uint16_t mdate;
  223. uint16_t begin;
  224. uint32_t size;
  225. } QEMU_PACKED direntry_t;
  226. /* this structure are used to transparently access the files */
  227. typedef struct mapping_t {
  228. /* begin is the first cluster, end is the last+1 */
  229. uint32_t begin,end;
  230. /* as s->directory is growable, no pointer may be used here */
  231. unsigned int dir_index;
  232. /* the clusters of a file may be in any order; this points to the first */
  233. int first_mapping_index;
  234. union {
  235. /* offset is
  236. * - the offset in the file (in clusters) for a file, or
  237. * - the next cluster of the directory for a directory
  238. */
  239. struct {
  240. uint32_t offset;
  241. } file;
  242. struct {
  243. int parent_mapping_index;
  244. int first_dir_index;
  245. } dir;
  246. } info;
  247. /* path contains the full path, i.e. it always starts with s->path */
  248. char* path;
  249. enum {
  250. MODE_UNDEFINED = 0,
  251. MODE_NORMAL = 1,
  252. MODE_MODIFIED = 2,
  253. MODE_DIRECTORY = 4,
  254. MODE_DELETED = 8,
  255. } mode;
  256. int read_only;
  257. } mapping_t;
  258. #ifdef DEBUG
  259. static void print_direntry(const struct direntry_t*);
  260. static void print_mapping(const struct mapping_t* mapping);
  261. #endif
  262. /* here begins the real VVFAT driver */
  263. typedef struct BDRVVVFATState {
  264. CoMutex lock;
  265. BlockDriverState* bs; /* pointer to parent */
  266. unsigned char first_sectors[0x40*0x200];
  267. int fat_type; /* 16 or 32 */
  268. array_t fat,directory,mapping;
  269. char volume_label[11];
  270. uint32_t offset_to_bootsector; /* 0 for floppy, 0x3f for disk */
  271. unsigned int cluster_size;
  272. unsigned int sectors_per_cluster;
  273. unsigned int sectors_per_fat;
  274. uint32_t last_cluster_of_root_directory;
  275. /* how many entries are available in root directory (0 for FAT32) */
  276. uint16_t root_entries;
  277. uint32_t sector_count; /* total number of sectors of the partition */
  278. uint32_t cluster_count; /* total number of clusters of this partition */
  279. uint32_t max_fat_value;
  280. uint32_t offset_to_fat;
  281. uint32_t offset_to_root_dir;
  282. int current_fd;
  283. mapping_t* current_mapping;
  284. unsigned char* cluster; /* points to current cluster */
  285. unsigned char* cluster_buffer; /* points to a buffer to hold temp data */
  286. unsigned int current_cluster;
  287. /* write support */
  288. char* qcow_filename;
  289. BdrvChild* qcow;
  290. void* fat2;
  291. char* used_clusters;
  292. array_t commits;
  293. const char* path;
  294. int downcase_short_names;
  295. Error *migration_blocker;
  296. } BDRVVVFATState;
  297. /* take the sector position spos and convert it to Cylinder/Head/Sector position
  298. * if the position is outside the specified geometry, fill maximum value for CHS
  299. * and return 1 to signal overflow.
  300. */
  301. static int sector2CHS(mbr_chs_t *chs, int spos, int cyls, int heads, int secs)
  302. {
  303. int head,sector;
  304. sector = spos % secs; spos /= secs;
  305. head = spos % heads; spos /= heads;
  306. if (spos >= cyls) {
  307. /* Overflow,
  308. it happens if 32bit sector positions are used, while CHS is only 24bit.
  309. Windows/Dos is said to take 1023/255/63 as nonrepresentable CHS */
  310. chs->head = 0xFF;
  311. chs->sector = 0xFF;
  312. chs->cylinder = 0xFF;
  313. return 1;
  314. }
  315. chs->head = (uint8_t)head;
  316. chs->sector = (uint8_t)( (sector+1) | ((spos>>8)<<6) );
  317. chs->cylinder = (uint8_t)spos;
  318. return 0;
  319. }
  320. static void init_mbr(BDRVVVFATState *s, int cyls, int heads, int secs)
  321. {
  322. /* TODO: if the files mbr.img and bootsect.img exist, use them */
  323. mbr_t* real_mbr=(mbr_t*)s->first_sectors;
  324. partition_t* partition = &(real_mbr->partition[0]);
  325. int lba;
  326. memset(s->first_sectors,0,512);
  327. /* Win NT Disk Signature */
  328. real_mbr->nt_id= cpu_to_le32(0xbe1afdfa);
  329. partition->attributes=0x80; /* bootable */
  330. /* LBA is used when partition is outside the CHS geometry */
  331. lba = sector2CHS(&partition->start_CHS, s->offset_to_bootsector,
  332. cyls, heads, secs);
  333. lba |= sector2CHS(&partition->end_CHS, s->bs->total_sectors - 1,
  334. cyls, heads, secs);
  335. /*LBA partitions are identified only by start/length_sector_long not by CHS*/
  336. partition->start_sector_long = cpu_to_le32(s->offset_to_bootsector);
  337. partition->length_sector_long = cpu_to_le32(s->bs->total_sectors
  338. - s->offset_to_bootsector);
  339. /* FAT12/FAT16/FAT32 */
  340. /* DOS uses different types when partition is LBA,
  341. probably to prevent older versions from using CHS on them */
  342. partition->fs_type = s->fat_type == 12 ? 0x1 :
  343. s->fat_type == 16 ? (lba ? 0xe : 0x06) :
  344. /*s->fat_type == 32*/ (lba ? 0xc : 0x0b);
  345. real_mbr->magic[0]=0x55; real_mbr->magic[1]=0xaa;
  346. }
  347. /* direntry functions */
  348. static direntry_t *create_long_filename(BDRVVVFATState *s, const char *filename)
  349. {
  350. int number_of_entries, i;
  351. glong length;
  352. gunichar2 *longname = g_utf8_to_utf16(filename, -1, NULL, &length, NULL);
  353. if (!longname) {
  354. fprintf(stderr, "vvfat: invalid UTF-8 name: %s\n", filename);
  355. return NULL;
  356. }
  357. number_of_entries = DIV_ROUND_UP(length * 2, 26);
  358. for(i=0;i<number_of_entries;i++) {
  359. direntry_t *entry=array_get_next(&(s->directory));
  360. entry->attributes=0xf;
  361. entry->reserved[0]=0;
  362. entry->begin=0;
  363. entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
  364. }
  365. for(i=0;i<26*number_of_entries;i++) {
  366. unsigned char *entry=array_get(&(s->directory),s->directory.next-1-(i/26));
  367. int offset=(i%26);
  368. if(offset<10) offset=1+offset;
  369. else if(offset<22) offset=14+offset-10;
  370. else offset=28+offset-22;
  371. if (i >= 2 * length + 2) {
  372. entry[offset] = 0xff;
  373. } else if (i % 2 == 0) {
  374. entry[offset] = longname[i / 2] & 0xff;
  375. } else {
  376. entry[offset] = longname[i / 2] >> 8;
  377. }
  378. }
  379. g_free(longname);
  380. return array_get(&(s->directory),s->directory.next-number_of_entries);
  381. }
  382. static char is_free(const direntry_t* direntry)
  383. {
  384. return direntry->name[0] == DIR_DELETED || direntry->name[0] == DIR_FREE;
  385. }
  386. static char is_volume_label(const direntry_t* direntry)
  387. {
  388. return direntry->attributes == 0x28;
  389. }
  390. static char is_long_name(const direntry_t* direntry)
  391. {
  392. return direntry->attributes == 0xf;
  393. }
  394. static char is_short_name(const direntry_t* direntry)
  395. {
  396. return !is_volume_label(direntry) && !is_long_name(direntry)
  397. && !is_free(direntry);
  398. }
  399. static char is_directory(const direntry_t* direntry)
  400. {
  401. return direntry->attributes & 0x10 && direntry->name[0] != DIR_DELETED;
  402. }
  403. static inline char is_dot(const direntry_t* direntry)
  404. {
  405. return is_short_name(direntry) && direntry->name[0] == '.';
  406. }
  407. static char is_file(const direntry_t* direntry)
  408. {
  409. return is_short_name(direntry) && !is_directory(direntry);
  410. }
  411. static inline uint32_t begin_of_direntry(const direntry_t* direntry)
  412. {
  413. return le16_to_cpu(direntry->begin)|(le16_to_cpu(direntry->begin_hi)<<16);
  414. }
  415. static inline uint32_t filesize_of_direntry(const direntry_t* direntry)
  416. {
  417. return le32_to_cpu(direntry->size);
  418. }
  419. static void set_begin_of_direntry(direntry_t* direntry, uint32_t begin)
  420. {
  421. direntry->begin = cpu_to_le16(begin & 0xffff);
  422. direntry->begin_hi = cpu_to_le16((begin >> 16) & 0xffff);
  423. }
  424. static bool valid_filename(const unsigned char *name)
  425. {
  426. unsigned char c;
  427. if (!strcmp((const char*)name, ".") || !strcmp((const char*)name, "..")) {
  428. return false;
  429. }
  430. for (; (c = *name); name++) {
  431. if (!((c >= '0' && c <= '9') ||
  432. (c >= 'A' && c <= 'Z') ||
  433. (c >= 'a' && c <= 'z') ||
  434. c > 127 ||
  435. strchr(" $%'-_@~`!(){}^#&.+,;=[]", c) != NULL))
  436. {
  437. return false;
  438. }
  439. }
  440. return true;
  441. }
  442. static uint8_t to_valid_short_char(gunichar c)
  443. {
  444. c = g_unichar_toupper(c);
  445. if ((c >= '0' && c <= '9') ||
  446. (c >= 'A' && c <= 'Z') ||
  447. strchr("$%'-_@~`!(){}^#&", c) != NULL) {
  448. return c;
  449. } else {
  450. return 0;
  451. }
  452. }
  453. static direntry_t *create_short_filename(BDRVVVFATState *s,
  454. const char *filename,
  455. unsigned int directory_start)
  456. {
  457. int i, j = 0;
  458. direntry_t *entry = array_get_next(&(s->directory));
  459. const gchar *p, *last_dot = NULL;
  460. gunichar c;
  461. bool lossy_conversion = false;
  462. char tail[8];
  463. if (!entry) {
  464. return NULL;
  465. }
  466. memset(entry->name, 0x20, sizeof(entry->name));
  467. /* copy filename and search last dot */
  468. for (p = filename; ; p = g_utf8_next_char(p)) {
  469. c = g_utf8_get_char(p);
  470. if (c == '\0') {
  471. break;
  472. } else if (c == '.') {
  473. if (j == 0) {
  474. /* '.' at start of filename */
  475. lossy_conversion = true;
  476. } else {
  477. if (last_dot) {
  478. lossy_conversion = true;
  479. }
  480. last_dot = p;
  481. }
  482. } else if (!last_dot) {
  483. /* first part of the name; copy it */
  484. uint8_t v = to_valid_short_char(c);
  485. if (j < 8 && v) {
  486. entry->name[j++] = v;
  487. } else {
  488. lossy_conversion = true;
  489. }
  490. }
  491. }
  492. /* copy extension (if any) */
  493. if (last_dot) {
  494. j = 0;
  495. for (p = g_utf8_next_char(last_dot); ; p = g_utf8_next_char(p)) {
  496. c = g_utf8_get_char(p);
  497. if (c == '\0') {
  498. break;
  499. } else {
  500. /* extension; copy it */
  501. uint8_t v = to_valid_short_char(c);
  502. if (j < 3 && v) {
  503. entry->name[8 + (j++)] = v;
  504. } else {
  505. lossy_conversion = true;
  506. }
  507. }
  508. }
  509. }
  510. if (entry->name[0] == DIR_KANJI) {
  511. entry->name[0] = DIR_KANJI_FAKE;
  512. }
  513. /* numeric-tail generation */
  514. for (j = 0; j < 8; j++) {
  515. if (entry->name[j] == ' ') {
  516. break;
  517. }
  518. }
  519. for (i = lossy_conversion ? 1 : 0; i < 999999; i++) {
  520. direntry_t *entry1;
  521. if (i > 0) {
  522. int len = snprintf(tail, sizeof(tail), "~%u", (unsigned)i);
  523. assert(len <= 7);
  524. memcpy(entry->name + MIN(j, 8 - len), tail, len);
  525. }
  526. for (entry1 = array_get(&(s->directory), directory_start);
  527. entry1 < entry; entry1++) {
  528. if (!is_long_name(entry1) &&
  529. !memcmp(entry1->name, entry->name, 11)) {
  530. break; /* found dupe */
  531. }
  532. }
  533. if (entry1 == entry) {
  534. /* no dupe found */
  535. return entry;
  536. }
  537. }
  538. return NULL;
  539. }
  540. /* fat functions */
  541. static inline uint8_t fat_chksum(const direntry_t* entry)
  542. {
  543. uint8_t chksum=0;
  544. int i;
  545. for (i = 0; i < ARRAY_SIZE(entry->name); i++) {
  546. chksum = (((chksum & 0xfe) >> 1) |
  547. ((chksum & 0x01) ? 0x80 : 0)) + entry->name[i];
  548. }
  549. return chksum;
  550. }
  551. /* if return_time==0, this returns the fat_date, else the fat_time */
  552. static uint16_t fat_datetime(time_t time,int return_time) {
  553. struct tm* t;
  554. struct tm t1;
  555. t = &t1;
  556. localtime_r(&time,t);
  557. if(return_time)
  558. return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11));
  559. return cpu_to_le16((t->tm_mday)|((t->tm_mon+1)<<5)|((t->tm_year-80)<<9));
  560. }
  561. static inline void fat_set(BDRVVVFATState* s,unsigned int cluster,uint32_t value)
  562. {
  563. if(s->fat_type==32) {
  564. uint32_t* entry=array_get(&(s->fat),cluster);
  565. *entry=cpu_to_le32(value);
  566. } else if(s->fat_type==16) {
  567. uint16_t* entry=array_get(&(s->fat),cluster);
  568. *entry=cpu_to_le16(value&0xffff);
  569. } else {
  570. int offset = (cluster*3/2);
  571. unsigned char* p = array_get(&(s->fat), offset);
  572. switch (cluster&1) {
  573. case 0:
  574. p[0] = value&0xff;
  575. p[1] = (p[1]&0xf0) | ((value>>8)&0xf);
  576. break;
  577. case 1:
  578. p[0] = (p[0]&0xf) | ((value&0xf)<<4);
  579. p[1] = (value>>4);
  580. break;
  581. }
  582. }
  583. }
  584. static inline uint32_t fat_get(BDRVVVFATState* s,unsigned int cluster)
  585. {
  586. if(s->fat_type==32) {
  587. uint32_t* entry=array_get(&(s->fat),cluster);
  588. return le32_to_cpu(*entry);
  589. } else if(s->fat_type==16) {
  590. uint16_t* entry=array_get(&(s->fat),cluster);
  591. return le16_to_cpu(*entry);
  592. } else {
  593. const uint8_t* x=(uint8_t*)(s->fat.pointer)+cluster*3/2;
  594. return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
  595. }
  596. }
  597. static inline int fat_eof(BDRVVVFATState* s,uint32_t fat_entry)
  598. {
  599. if(fat_entry>s->max_fat_value-8)
  600. return -1;
  601. return 0;
  602. }
  603. static inline void init_fat(BDRVVVFATState* s)
  604. {
  605. if (s->fat_type == 12) {
  606. array_init(&(s->fat),1);
  607. array_ensure_allocated(&(s->fat),
  608. s->sectors_per_fat * 0x200 * 3 / 2 - 1);
  609. } else {
  610. array_init(&(s->fat),(s->fat_type==32?4:2));
  611. array_ensure_allocated(&(s->fat),
  612. s->sectors_per_fat * 0x200 / s->fat.item_size - 1);
  613. }
  614. memset(s->fat.pointer,0,s->fat.size);
  615. switch(s->fat_type) {
  616. case 12: s->max_fat_value=0xfff; break;
  617. case 16: s->max_fat_value=0xffff; break;
  618. case 32: s->max_fat_value=0x0fffffff; break;
  619. default: s->max_fat_value=0; /* error... */
  620. }
  621. }
  622. static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
  623. unsigned int directory_start, const char* filename, int is_dot)
  624. {
  625. int long_index = s->directory.next;
  626. direntry_t* entry = NULL;
  627. direntry_t* entry_long = NULL;
  628. if(is_dot) {
  629. entry=array_get_next(&(s->directory));
  630. memset(entry->name, 0x20, sizeof(entry->name));
  631. memcpy(entry->name,filename,strlen(filename));
  632. return entry;
  633. }
  634. entry_long=create_long_filename(s,filename);
  635. entry = create_short_filename(s, filename, directory_start);
  636. /* calculate checksum; propagate to long name */
  637. if(entry_long) {
  638. uint8_t chksum=fat_chksum(entry);
  639. /* calculate anew, because realloc could have taken place */
  640. entry_long=array_get(&(s->directory),long_index);
  641. while(entry_long<entry && is_long_name(entry_long)) {
  642. entry_long->reserved[1]=chksum;
  643. entry_long++;
  644. }
  645. }
  646. return entry;
  647. }
  648. /*
  649. * Read a directory. (the index of the corresponding mapping must be passed).
  650. */
  651. static int read_directory(BDRVVVFATState* s, int mapping_index)
  652. {
  653. mapping_t* mapping = array_get(&(s->mapping), mapping_index);
  654. direntry_t* direntry;
  655. const char* dirname = mapping->path;
  656. int first_cluster = mapping->begin;
  657. int parent_index = mapping->info.dir.parent_mapping_index;
  658. mapping_t* parent_mapping = (mapping_t*)
  659. (parent_index >= 0 ? array_get(&(s->mapping), parent_index) : NULL);
  660. int first_cluster_of_parent = parent_mapping ? parent_mapping->begin : -1;
  661. DIR* dir=opendir(dirname);
  662. struct dirent* entry;
  663. int i;
  664. assert(mapping->mode & MODE_DIRECTORY);
  665. if(!dir) {
  666. mapping->end = mapping->begin;
  667. return -1;
  668. }
  669. i = mapping->info.dir.first_dir_index =
  670. first_cluster == 0 ? 0 : s->directory.next;
  671. if (first_cluster != 0) {
  672. /* create the top entries of a subdirectory */
  673. (void)create_short_and_long_name(s, i, ".", 1);
  674. (void)create_short_and_long_name(s, i, "..", 1);
  675. }
  676. /* actually read the directory, and allocate the mappings */
  677. while((entry=readdir(dir))) {
  678. unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
  679. char* buffer;
  680. struct stat st;
  681. int is_dot=!strcmp(entry->d_name,".");
  682. int is_dotdot=!strcmp(entry->d_name,"..");
  683. if (first_cluster == 0 && s->directory.next >= s->root_entries - 1) {
  684. fprintf(stderr, "Too many entries in root directory\n");
  685. closedir(dir);
  686. return -2;
  687. }
  688. if(first_cluster == 0 && (is_dotdot || is_dot))
  689. continue;
  690. buffer = g_malloc(length);
  691. snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
  692. if(stat(buffer,&st)<0) {
  693. g_free(buffer);
  694. continue;
  695. }
  696. /* create directory entry for this file */
  697. if (!is_dot && !is_dotdot) {
  698. direntry = create_short_and_long_name(s, i, entry->d_name, 0);
  699. } else {
  700. direntry = array_get(&(s->directory), is_dot ? i : i + 1);
  701. }
  702. direntry->attributes=(S_ISDIR(st.st_mode)?0x10:0x20);
  703. direntry->reserved[0]=direntry->reserved[1]=0;
  704. direntry->ctime=fat_datetime(st.st_ctime,1);
  705. direntry->cdate=fat_datetime(st.st_ctime,0);
  706. direntry->adate=fat_datetime(st.st_atime,0);
  707. direntry->begin_hi=0;
  708. direntry->mtime=fat_datetime(st.st_mtime,1);
  709. direntry->mdate=fat_datetime(st.st_mtime,0);
  710. if(is_dotdot)
  711. set_begin_of_direntry(direntry, first_cluster_of_parent);
  712. else if(is_dot)
  713. set_begin_of_direntry(direntry, first_cluster);
  714. else
  715. direntry->begin=0; /* do that later */
  716. if (st.st_size > 0x7fffffff) {
  717. fprintf(stderr, "File %s is larger than 2GB\n", buffer);
  718. g_free(buffer);
  719. closedir(dir);
  720. return -2;
  721. }
  722. direntry->size=cpu_to_le32(S_ISDIR(st.st_mode)?0:st.st_size);
  723. /* create mapping for this file */
  724. if(!is_dot && !is_dotdot && (S_ISDIR(st.st_mode) || st.st_size)) {
  725. s->current_mapping = array_get_next(&(s->mapping));
  726. s->current_mapping->begin=0;
  727. s->current_mapping->end=st.st_size;
  728. /*
  729. * we get the direntry of the most recent direntry, which
  730. * contains the short name and all the relevant information.
  731. */
  732. s->current_mapping->dir_index=s->directory.next-1;
  733. s->current_mapping->first_mapping_index = -1;
  734. if (S_ISDIR(st.st_mode)) {
  735. s->current_mapping->mode = MODE_DIRECTORY;
  736. s->current_mapping->info.dir.parent_mapping_index =
  737. mapping_index;
  738. } else {
  739. s->current_mapping->mode = MODE_UNDEFINED;
  740. s->current_mapping->info.file.offset = 0;
  741. }
  742. s->current_mapping->path=buffer;
  743. s->current_mapping->read_only =
  744. (st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) == 0;
  745. } else {
  746. g_free(buffer);
  747. }
  748. }
  749. closedir(dir);
  750. /* fill with zeroes up to the end of the cluster */
  751. while(s->directory.next%(0x10*s->sectors_per_cluster)) {
  752. direntry = array_get_next(&(s->directory));
  753. memset(direntry,0,sizeof(direntry_t));
  754. }
  755. if (s->fat_type != 32 &&
  756. mapping_index == 0 &&
  757. s->directory.next < s->root_entries) {
  758. /* root directory */
  759. int cur = s->directory.next;
  760. array_ensure_allocated(&(s->directory), s->root_entries - 1);
  761. s->directory.next = s->root_entries;
  762. memset(array_get(&(s->directory), cur), 0,
  763. (s->root_entries - cur) * sizeof(direntry_t));
  764. }
  765. /* re-get the mapping, since s->mapping was possibly realloc()ed */
  766. mapping = array_get(&(s->mapping), mapping_index);
  767. first_cluster += (s->directory.next - mapping->info.dir.first_dir_index)
  768. * 0x20 / s->cluster_size;
  769. mapping->end = first_cluster;
  770. direntry = array_get(&(s->directory), mapping->dir_index);
  771. set_begin_of_direntry(direntry, mapping->begin);
  772. return 0;
  773. }
  774. static inline int32_t sector2cluster(BDRVVVFATState* s,off_t sector_num)
  775. {
  776. return (sector_num - s->offset_to_root_dir) / s->sectors_per_cluster;
  777. }
  778. static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num)
  779. {
  780. return s->offset_to_root_dir + s->sectors_per_cluster * cluster_num;
  781. }
  782. static int init_directories(BDRVVVFATState* s,
  783. const char *dirname, int heads, int secs,
  784. Error **errp)
  785. {
  786. bootsector_t* bootsector;
  787. mapping_t* mapping;
  788. unsigned int i;
  789. unsigned int cluster;
  790. memset(&(s->first_sectors[0]),0,0x40*0x200);
  791. s->cluster_size=s->sectors_per_cluster*0x200;
  792. s->cluster_buffer=g_malloc(s->cluster_size);
  793. /*
  794. * The formula: sc = spf+1+spf*spc*(512*8/fat_type),
  795. * where sc is sector_count,
  796. * spf is sectors_per_fat,
  797. * spc is sectors_per_clusters, and
  798. * fat_type = 12, 16 or 32.
  799. */
  800. i = 1+s->sectors_per_cluster*0x200*8/s->fat_type;
  801. s->sectors_per_fat=(s->sector_count+i)/i; /* round up */
  802. s->offset_to_fat = s->offset_to_bootsector + 1;
  803. s->offset_to_root_dir = s->offset_to_fat + s->sectors_per_fat * 2;
  804. array_init(&(s->mapping),sizeof(mapping_t));
  805. array_init(&(s->directory),sizeof(direntry_t));
  806. /* add volume label */
  807. {
  808. direntry_t* entry=array_get_next(&(s->directory));
  809. entry->attributes=0x28; /* archive | volume label */
  810. memcpy(entry->name, s->volume_label, sizeof(entry->name));
  811. }
  812. /* Now build FAT, and write back information into directory */
  813. init_fat(s);
  814. /* TODO: if there are more entries, bootsector has to be adjusted! */
  815. s->root_entries = 0x02 * 0x10 * s->sectors_per_cluster;
  816. s->cluster_count=sector2cluster(s, s->sector_count);
  817. mapping = array_get_next(&(s->mapping));
  818. mapping->begin = 0;
  819. mapping->dir_index = 0;
  820. mapping->info.dir.parent_mapping_index = -1;
  821. mapping->first_mapping_index = -1;
  822. mapping->path = g_strdup(dirname);
  823. i = strlen(mapping->path);
  824. if (i > 0 && mapping->path[i - 1] == '/')
  825. mapping->path[i - 1] = '\0';
  826. mapping->mode = MODE_DIRECTORY;
  827. mapping->read_only = 0;
  828. s->path = mapping->path;
  829. for (i = 0, cluster = 0; i < s->mapping.next; i++) {
  830. /* MS-DOS expects the FAT to be 0 for the root directory
  831. * (except for the media byte). */
  832. /* LATER TODO: still true for FAT32? */
  833. int fix_fat = (i != 0);
  834. mapping = array_get(&(s->mapping), i);
  835. if (mapping->mode & MODE_DIRECTORY) {
  836. char *path = mapping->path;
  837. mapping->begin = cluster;
  838. if(read_directory(s, i)) {
  839. error_setg(errp, "Could not read directory %s", path);
  840. return -1;
  841. }
  842. mapping = array_get(&(s->mapping), i);
  843. } else {
  844. assert(mapping->mode == MODE_UNDEFINED);
  845. mapping->mode=MODE_NORMAL;
  846. mapping->begin = cluster;
  847. if (mapping->end > 0) {
  848. direntry_t* direntry = array_get(&(s->directory),
  849. mapping->dir_index);
  850. mapping->end = cluster + 1 + (mapping->end-1)/s->cluster_size;
  851. set_begin_of_direntry(direntry, mapping->begin);
  852. } else {
  853. mapping->end = cluster + 1;
  854. fix_fat = 0;
  855. }
  856. }
  857. assert(mapping->begin < mapping->end);
  858. /* next free cluster */
  859. cluster = mapping->end;
  860. if(cluster > s->cluster_count) {
  861. error_setg(errp,
  862. "Directory does not fit in FAT%d (capacity %.2f MB)",
  863. s->fat_type, s->sector_count / 2000.0);
  864. return -1;
  865. }
  866. /* fix fat for entry */
  867. if (fix_fat) {
  868. int j;
  869. for(j = mapping->begin; j < mapping->end - 1; j++)
  870. fat_set(s, j, j+1);
  871. fat_set(s, mapping->end - 1, s->max_fat_value);
  872. }
  873. }
  874. mapping = array_get(&(s->mapping), 0);
  875. s->last_cluster_of_root_directory = mapping->end;
  876. /* the FAT signature */
  877. fat_set(s,0,s->max_fat_value);
  878. fat_set(s,1,s->max_fat_value);
  879. s->current_mapping = NULL;
  880. bootsector = (bootsector_t *)(s->first_sectors
  881. + s->offset_to_bootsector * 0x200);
  882. bootsector->jump[0]=0xeb;
  883. bootsector->jump[1]=0x3e;
  884. bootsector->jump[2]=0x90;
  885. memcpy(bootsector->name, BOOTSECTOR_OEM_NAME, 8);
  886. bootsector->sector_size=cpu_to_le16(0x200);
  887. bootsector->sectors_per_cluster=s->sectors_per_cluster;
  888. bootsector->reserved_sectors=cpu_to_le16(1);
  889. bootsector->number_of_fats=0x2; /* number of FATs */
  890. bootsector->root_entries = cpu_to_le16(s->root_entries);
  891. bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count);
  892. /* media descriptor: hard disk=0xf8, floppy=0xf0 */
  893. bootsector->media_type = (s->offset_to_bootsector > 0 ? 0xf8 : 0xf0);
  894. s->fat.pointer[0] = bootsector->media_type;
  895. bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat);
  896. bootsector->sectors_per_track = cpu_to_le16(secs);
  897. bootsector->number_of_heads = cpu_to_le16(heads);
  898. bootsector->hidden_sectors = cpu_to_le32(s->offset_to_bootsector);
  899. bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0);
  900. /* LATER TODO: if FAT32, this is wrong */
  901. /* drive_number: fda=0, hda=0x80 */
  902. bootsector->u.fat16.drive_number = s->offset_to_bootsector == 0 ? 0 : 0x80;
  903. bootsector->u.fat16.signature=0x29;
  904. bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd);
  905. memcpy(bootsector->u.fat16.volume_label, s->volume_label,
  906. sizeof(bootsector->u.fat16.volume_label));
  907. memcpy(bootsector->u.fat16.fat_type,
  908. s->fat_type == 12 ? "FAT12 " : "FAT16 ", 8);
  909. bootsector->magic[0]=0x55; bootsector->magic[1]=0xaa;
  910. return 0;
  911. }
  912. #ifdef DEBUG
  913. static BDRVVVFATState *vvv = NULL;
  914. #endif
  915. static int enable_write_target(BlockDriverState *bs, Error **errp);
  916. static int coroutine_fn is_consistent(BDRVVVFATState *s);
  917. static QemuOptsList runtime_opts = {
  918. .name = "vvfat",
  919. .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
  920. .desc = {
  921. {
  922. .name = "dir",
  923. .type = QEMU_OPT_STRING,
  924. .help = "Host directory to map to the vvfat device",
  925. },
  926. {
  927. .name = "fat-type",
  928. .type = QEMU_OPT_NUMBER,
  929. .help = "FAT type (12, 16 or 32)",
  930. },
  931. {
  932. .name = "floppy",
  933. .type = QEMU_OPT_BOOL,
  934. .help = "Create a floppy rather than a hard disk image",
  935. },
  936. {
  937. .name = "label",
  938. .type = QEMU_OPT_STRING,
  939. .help = "Use a volume label other than QEMU VVFAT",
  940. },
  941. {
  942. .name = "rw",
  943. .type = QEMU_OPT_BOOL,
  944. .help = "Make the image writable",
  945. },
  946. { /* end of list */ }
  947. },
  948. };
  949. static void vvfat_parse_filename(const char *filename, QDict *options,
  950. Error **errp)
  951. {
  952. int fat_type = 0;
  953. bool floppy = false;
  954. bool rw = false;
  955. int i;
  956. if (!strstart(filename, "fat:", NULL)) {
  957. error_setg(errp, "File name string must start with 'fat:'");
  958. return;
  959. }
  960. /* Parse options */
  961. if (strstr(filename, ":32:")) {
  962. fat_type = 32;
  963. } else if (strstr(filename, ":16:")) {
  964. fat_type = 16;
  965. } else if (strstr(filename, ":12:")) {
  966. fat_type = 12;
  967. }
  968. if (strstr(filename, ":floppy:")) {
  969. floppy = true;
  970. }
  971. if (strstr(filename, ":rw:")) {
  972. rw = true;
  973. }
  974. /* Get the directory name without options */
  975. i = strrchr(filename, ':') - filename;
  976. assert(i >= 3);
  977. if (filename[i - 2] == ':' && qemu_isalpha(filename[i - 1])) {
  978. /* workaround for DOS drive names */
  979. filename += i - 1;
  980. } else {
  981. filename += i + 1;
  982. }
  983. /* Fill in the options QDict */
  984. qdict_put_str(options, "dir", filename);
  985. qdict_put_int(options, "fat-type", fat_type);
  986. qdict_put_bool(options, "floppy", floppy);
  987. qdict_put_bool(options, "rw", rw);
  988. }
  989. static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
  990. Error **errp)
  991. {
  992. BDRVVVFATState *s = bs->opaque;
  993. int cyls, heads, secs;
  994. bool floppy;
  995. const char *dirname, *label;
  996. QemuOpts *opts;
  997. int ret;
  998. GRAPH_RDLOCK_GUARD_MAINLOOP();
  999. #ifdef DEBUG
  1000. vvv = s;
  1001. #endif
  1002. opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
  1003. if (!qemu_opts_absorb_qdict(opts, options, errp)) {
  1004. ret = -EINVAL;
  1005. goto fail;
  1006. }
  1007. dirname = qemu_opt_get(opts, "dir");
  1008. if (!dirname) {
  1009. error_setg(errp, "vvfat block driver requires a 'dir' option");
  1010. ret = -EINVAL;
  1011. goto fail;
  1012. }
  1013. s->fat_type = qemu_opt_get_number(opts, "fat-type", 0);
  1014. floppy = qemu_opt_get_bool(opts, "floppy", false);
  1015. memset(s->volume_label, ' ', sizeof(s->volume_label));
  1016. label = qemu_opt_get(opts, "label");
  1017. if (label) {
  1018. size_t label_length = strlen(label);
  1019. if (label_length > 11) {
  1020. error_setg(errp, "vvfat label cannot be longer than 11 bytes");
  1021. ret = -EINVAL;
  1022. goto fail;
  1023. }
  1024. memcpy(s->volume_label, label, label_length);
  1025. } else {
  1026. memcpy(s->volume_label, "QEMU VVFAT", 10);
  1027. }
  1028. if (floppy) {
  1029. /* 1.44MB or 2.88MB floppy. 2.88MB can be FAT12 (default) or FAT16. */
  1030. if (!s->fat_type) {
  1031. s->fat_type = 12;
  1032. secs = 36;
  1033. s->sectors_per_cluster = 2;
  1034. } else {
  1035. secs = s->fat_type == 12 ? 18 : 36;
  1036. s->sectors_per_cluster = 1;
  1037. }
  1038. cyls = 80;
  1039. heads = 2;
  1040. } else {
  1041. /* 32MB or 504MB disk*/
  1042. if (!s->fat_type) {
  1043. s->fat_type = 16;
  1044. }
  1045. s->offset_to_bootsector = 0x3f;
  1046. cyls = s->fat_type == 12 ? 64 : 1024;
  1047. heads = 16;
  1048. secs = 63;
  1049. }
  1050. switch (s->fat_type) {
  1051. case 32:
  1052. warn_report("FAT32 has not been tested. You are welcome to do so!");
  1053. break;
  1054. case 16:
  1055. case 12:
  1056. break;
  1057. default:
  1058. error_setg(errp, "Valid FAT types are only 12, 16 and 32");
  1059. ret = -EINVAL;
  1060. goto fail;
  1061. }
  1062. s->bs = bs;
  1063. /* LATER TODO: if FAT32, adjust */
  1064. s->sectors_per_cluster=0x10;
  1065. s->current_cluster=0xffffffff;
  1066. s->qcow = NULL;
  1067. s->qcow_filename = NULL;
  1068. s->fat2 = NULL;
  1069. s->downcase_short_names = 1;
  1070. DLOG(fprintf(stderr, "vvfat %s chs %d,%d,%d\n",
  1071. dirname, cyls, heads, secs));
  1072. s->sector_count = cyls * heads * secs - s->offset_to_bootsector;
  1073. bs->total_sectors = cyls * heads * secs;
  1074. if (qemu_opt_get_bool(opts, "rw", false)) {
  1075. if (!bdrv_is_read_only(bs)) {
  1076. ret = enable_write_target(bs, errp);
  1077. if (ret < 0) {
  1078. goto fail;
  1079. }
  1080. } else {
  1081. ret = -EPERM;
  1082. error_setg(errp,
  1083. "Unable to set VVFAT to 'rw' when drive is read-only");
  1084. goto fail;
  1085. }
  1086. } else {
  1087. ret = bdrv_apply_auto_read_only(bs, NULL, errp);
  1088. if (ret < 0) {
  1089. goto fail;
  1090. }
  1091. }
  1092. if (init_directories(s, dirname, heads, secs, errp)) {
  1093. ret = -EIO;
  1094. goto fail;
  1095. }
  1096. s->sector_count = s->offset_to_root_dir
  1097. + s->sectors_per_cluster * s->cluster_count;
  1098. /* Disable migration when vvfat is used rw */
  1099. if (s->qcow) {
  1100. error_setg(&s->migration_blocker,
  1101. "The vvfat (rw) format used by node '%s' "
  1102. "does not support live migration",
  1103. bdrv_get_device_or_node_name(bs));
  1104. ret = migrate_add_blocker_normal(&s->migration_blocker, errp);
  1105. if (ret < 0) {
  1106. goto fail;
  1107. }
  1108. }
  1109. if (s->offset_to_bootsector > 0) {
  1110. init_mbr(s, cyls, heads, secs);
  1111. }
  1112. qemu_co_mutex_init(&s->lock);
  1113. qemu_opts_del(opts);
  1114. return 0;
  1115. fail:
  1116. g_free(s->qcow_filename);
  1117. s->qcow_filename = NULL;
  1118. g_free(s->cluster_buffer);
  1119. s->cluster_buffer = NULL;
  1120. g_free(s->used_clusters);
  1121. s->used_clusters = NULL;
  1122. qemu_opts_del(opts);
  1123. return ret;
  1124. }
  1125. static void vvfat_refresh_limits(BlockDriverState *bs, Error **errp)
  1126. {
  1127. bs->bl.request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O */
  1128. }
  1129. static inline void vvfat_close_current_file(BDRVVVFATState *s)
  1130. {
  1131. if(s->current_mapping) {
  1132. s->current_mapping = NULL;
  1133. if (s->current_fd) {
  1134. qemu_close(s->current_fd);
  1135. s->current_fd = 0;
  1136. }
  1137. }
  1138. s->current_cluster = -1;
  1139. }
  1140. /* mappings between index1 and index2-1 are supposed to be ordered
  1141. * return value is the index of the last mapping for which end>cluster_num
  1142. */
  1143. static inline int find_mapping_for_cluster_aux(BDRVVVFATState* s,int cluster_num,int index1,int index2)
  1144. {
  1145. while(1) {
  1146. int index3;
  1147. mapping_t* mapping;
  1148. index3=(index1+index2)/2;
  1149. mapping=array_get(&(s->mapping),index3);
  1150. assert(mapping->begin < mapping->end);
  1151. if(mapping->begin>=cluster_num) {
  1152. assert(index2!=index3 || index2==0);
  1153. if(index2==index3)
  1154. return index1;
  1155. index2=index3;
  1156. } else {
  1157. if(index1==index3)
  1158. return mapping->end<=cluster_num ? index2 : index1;
  1159. index1=index3;
  1160. }
  1161. assert(index1<=index2);
  1162. DLOG(mapping=array_get(&(s->mapping),index1);
  1163. assert(mapping->begin<=cluster_num);
  1164. assert(index2 >= s->mapping.next ||
  1165. ((mapping = array_get(&(s->mapping),index2)) &&
  1166. mapping->end>cluster_num)));
  1167. }
  1168. }
  1169. static inline mapping_t* find_mapping_for_cluster(BDRVVVFATState* s,int cluster_num)
  1170. {
  1171. int index=find_mapping_for_cluster_aux(s,cluster_num,0,s->mapping.next);
  1172. mapping_t* mapping;
  1173. if(index>=s->mapping.next)
  1174. return NULL;
  1175. mapping=array_get(&(s->mapping),index);
  1176. if(mapping->begin>cluster_num)
  1177. return NULL;
  1178. assert(mapping->begin<=cluster_num && mapping->end>cluster_num);
  1179. return mapping;
  1180. }
  1181. static int open_file(BDRVVVFATState* s,mapping_t* mapping)
  1182. {
  1183. if(!mapping)
  1184. return -1;
  1185. if(!s->current_mapping ||
  1186. strcmp(s->current_mapping->path,mapping->path)) {
  1187. /* open file */
  1188. int fd = qemu_open_old(mapping->path,
  1189. O_RDONLY | O_BINARY | O_LARGEFILE);
  1190. if(fd<0)
  1191. return -1;
  1192. vvfat_close_current_file(s);
  1193. s->current_fd = fd;
  1194. }
  1195. s->current_mapping = mapping;
  1196. return 0;
  1197. }
  1198. static inline int read_cluster(BDRVVVFATState *s,int cluster_num)
  1199. {
  1200. if(s->current_cluster != cluster_num) {
  1201. int result=0;
  1202. off_t offset;
  1203. assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode & MODE_DIRECTORY));
  1204. if(!s->current_mapping
  1205. || s->current_mapping->begin>cluster_num
  1206. || s->current_mapping->end<=cluster_num) {
  1207. /* binary search of mappings for file */
  1208. mapping_t* mapping=find_mapping_for_cluster(s,cluster_num);
  1209. assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end));
  1210. if (mapping && mapping->mode & MODE_DIRECTORY) {
  1211. vvfat_close_current_file(s);
  1212. s->current_mapping = mapping;
  1213. read_cluster_directory:
  1214. offset = s->cluster_size*(cluster_num-s->current_mapping->begin);
  1215. s->cluster = (unsigned char*)s->directory.pointer+offset
  1216. + 0x20*s->current_mapping->info.dir.first_dir_index;
  1217. assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
  1218. assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
  1219. s->current_cluster = cluster_num;
  1220. return 0;
  1221. }
  1222. if(open_file(s,mapping))
  1223. return -2;
  1224. } else if (s->current_mapping->mode & MODE_DIRECTORY)
  1225. goto read_cluster_directory;
  1226. assert(s->current_fd);
  1227. offset = s->cluster_size *
  1228. ((cluster_num - s->current_mapping->begin)
  1229. + s->current_mapping->info.file.offset);
  1230. if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
  1231. return -3;
  1232. s->cluster=s->cluster_buffer;
  1233. result=read(s->current_fd,s->cluster,s->cluster_size);
  1234. if(result<0) {
  1235. s->current_cluster = -1;
  1236. return -1;
  1237. }
  1238. s->current_cluster = cluster_num;
  1239. }
  1240. return 0;
  1241. }
  1242. #ifdef DEBUG
  1243. static void print_direntry(const direntry_t* direntry)
  1244. {
  1245. int j = 0;
  1246. char buffer[1024];
  1247. fprintf(stderr, "direntry %p: ", direntry);
  1248. if(!direntry)
  1249. return;
  1250. if(is_long_name(direntry)) {
  1251. unsigned char* c=(unsigned char*)direntry;
  1252. int i;
  1253. for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
  1254. #define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = 0xb0; j++;}
  1255. ADD_CHAR(c[i]);
  1256. for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
  1257. ADD_CHAR(c[i]);
  1258. for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
  1259. ADD_CHAR(c[i]);
  1260. buffer[j] = 0;
  1261. fprintf(stderr, "%s\n", buffer);
  1262. } else {
  1263. int i;
  1264. for(i=0;i<11;i++)
  1265. ADD_CHAR(direntry->name[i]);
  1266. buffer[j] = 0;
  1267. fprintf(stderr, "%s attributes=0x%02x begin=%u size=%u\n",
  1268. buffer,
  1269. direntry->attributes,
  1270. begin_of_direntry(direntry),le32_to_cpu(direntry->size));
  1271. }
  1272. }
  1273. static void print_mapping(const mapping_t* mapping)
  1274. {
  1275. fprintf(stderr, "mapping (%p): begin, end = %u, %u, dir_index = %u, "
  1276. "first_mapping_index = %d, name = %s, mode = 0x%x, " ,
  1277. mapping, mapping->begin, mapping->end, mapping->dir_index,
  1278. mapping->first_mapping_index, mapping->path, mapping->mode);
  1279. if (mapping->mode & MODE_DIRECTORY)
  1280. fprintf(stderr, "parent_mapping_index = %d, first_dir_index = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index);
  1281. else
  1282. fprintf(stderr, "offset = %u\n", mapping->info.file.offset);
  1283. }
  1284. #endif
  1285. static int coroutine_fn GRAPH_RDLOCK
  1286. vvfat_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors)
  1287. {
  1288. BDRVVVFATState *s = bs->opaque;
  1289. int i;
  1290. for(i=0;i<nb_sectors;i++,sector_num++) {
  1291. if (sector_num >= bs->total_sectors)
  1292. return -1;
  1293. if (s->qcow) {
  1294. int64_t n;
  1295. int ret;
  1296. ret = bdrv_co_is_allocated(s->qcow->bs, sector_num * BDRV_SECTOR_SIZE,
  1297. (nb_sectors - i) * BDRV_SECTOR_SIZE, &n);
  1298. if (ret < 0) {
  1299. return ret;
  1300. }
  1301. if (ret) {
  1302. DLOG(fprintf(stderr, "sectors %" PRId64 "+%" PRId64
  1303. " allocated\n", sector_num,
  1304. n >> BDRV_SECTOR_BITS));
  1305. if (bdrv_co_pread(s->qcow, sector_num * BDRV_SECTOR_SIZE, n,
  1306. buf + i * 0x200, 0) < 0) {
  1307. return -1;
  1308. }
  1309. i += (n >> BDRV_SECTOR_BITS) - 1;
  1310. sector_num += (n >> BDRV_SECTOR_BITS) - 1;
  1311. continue;
  1312. }
  1313. DLOG(fprintf(stderr, "sector %" PRId64 " not allocated\n",
  1314. sector_num));
  1315. }
  1316. if (sector_num < s->offset_to_root_dir) {
  1317. if (sector_num < s->offset_to_fat) {
  1318. memcpy(buf + i * 0x200,
  1319. &(s->first_sectors[sector_num * 0x200]),
  1320. 0x200);
  1321. } else if (sector_num < s->offset_to_fat + s->sectors_per_fat) {
  1322. memcpy(buf + i * 0x200,
  1323. &(s->fat.pointer[(sector_num
  1324. - s->offset_to_fat) * 0x200]),
  1325. 0x200);
  1326. } else if (sector_num < s->offset_to_root_dir) {
  1327. memcpy(buf + i * 0x200,
  1328. &(s->fat.pointer[(sector_num - s->offset_to_fat
  1329. - s->sectors_per_fat) * 0x200]),
  1330. 0x200);
  1331. }
  1332. } else {
  1333. uint32_t sector = sector_num - s->offset_to_root_dir,
  1334. sector_offset_in_cluster=(sector%s->sectors_per_cluster),
  1335. cluster_num=sector/s->sectors_per_cluster;
  1336. if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) {
  1337. /* LATER TODO: strict: return -1; */
  1338. memset(buf+i*0x200,0,0x200);
  1339. continue;
  1340. }
  1341. memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
  1342. }
  1343. }
  1344. return 0;
  1345. }
  1346. static int coroutine_fn GRAPH_RDLOCK
  1347. vvfat_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
  1348. QEMUIOVector *qiov, BdrvRequestFlags flags)
  1349. {
  1350. int ret;
  1351. BDRVVVFATState *s = bs->opaque;
  1352. uint64_t sector_num = offset >> BDRV_SECTOR_BITS;
  1353. int nb_sectors = bytes >> BDRV_SECTOR_BITS;
  1354. void *buf;
  1355. assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));
  1356. assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE));
  1357. buf = g_try_malloc(bytes);
  1358. if (bytes && buf == NULL) {
  1359. return -ENOMEM;
  1360. }
  1361. qemu_co_mutex_lock(&s->lock);
  1362. ret = vvfat_read(bs, sector_num, buf, nb_sectors);
  1363. qemu_co_mutex_unlock(&s->lock);
  1364. qemu_iovec_from_buf(qiov, 0, buf, bytes);
  1365. g_free(buf);
  1366. return ret;
  1367. }
  1368. /* LATER TODO: statify all functions */
  1369. /*
  1370. * Idea of the write support (use snapshot):
  1371. *
  1372. * 1. check if all data is consistent, recording renames, modifications,
  1373. * new files and directories (in s->commits).
  1374. *
  1375. * 2. if the data is not consistent, stop committing
  1376. *
  1377. * 3. handle renames, and create new files and directories (do not yet
  1378. * write their contents)
  1379. *
  1380. * 4. walk the directories, fixing the mapping and direntries, and marking
  1381. * the handled mappings as not deleted
  1382. *
  1383. * 5. commit the contents of the files
  1384. *
  1385. * 6. handle deleted files and directories
  1386. *
  1387. */
  1388. typedef struct commit_t {
  1389. char* path;
  1390. union {
  1391. struct { uint32_t cluster; } rename;
  1392. struct { int dir_index; uint32_t modified_offset; } writeout;
  1393. struct { uint32_t first_cluster; } new_file;
  1394. struct { uint32_t cluster; } mkdir;
  1395. } param;
  1396. /* DELETEs and RMDIRs are handled differently: see handle_deletes() */
  1397. enum {
  1398. ACTION_RENAME, ACTION_WRITEOUT, ACTION_NEW_FILE, ACTION_MKDIR
  1399. } action;
  1400. } commit_t;
  1401. static void clear_commits(BDRVVVFATState* s)
  1402. {
  1403. int i;
  1404. DLOG(fprintf(stderr, "clear_commits (%u commits)\n", s->commits.next));
  1405. for (i = 0; i < s->commits.next; i++) {
  1406. commit_t* commit = array_get(&(s->commits), i);
  1407. assert(commit->path || commit->action == ACTION_WRITEOUT);
  1408. if (commit->action != ACTION_WRITEOUT) {
  1409. assert(commit->path);
  1410. g_free(commit->path);
  1411. } else
  1412. assert(commit->path == NULL);
  1413. }
  1414. s->commits.next = 0;
  1415. }
  1416. static void schedule_rename(BDRVVVFATState* s,
  1417. uint32_t cluster, char* new_path)
  1418. {
  1419. commit_t* commit = array_get_next(&(s->commits));
  1420. commit->path = new_path;
  1421. commit->param.rename.cluster = cluster;
  1422. commit->action = ACTION_RENAME;
  1423. }
  1424. static void schedule_writeout(BDRVVVFATState* s,
  1425. int dir_index, uint32_t modified_offset)
  1426. {
  1427. commit_t* commit = array_get_next(&(s->commits));
  1428. commit->path = NULL;
  1429. commit->param.writeout.dir_index = dir_index;
  1430. commit->param.writeout.modified_offset = modified_offset;
  1431. commit->action = ACTION_WRITEOUT;
  1432. }
  1433. static void schedule_new_file(BDRVVVFATState* s,
  1434. char* path, uint32_t first_cluster)
  1435. {
  1436. commit_t* commit = array_get_next(&(s->commits));
  1437. commit->path = path;
  1438. commit->param.new_file.first_cluster = first_cluster;
  1439. commit->action = ACTION_NEW_FILE;
  1440. }
  1441. static void schedule_mkdir(BDRVVVFATState* s, uint32_t cluster, char* path)
  1442. {
  1443. commit_t* commit = array_get_next(&(s->commits));
  1444. commit->path = path;
  1445. commit->param.mkdir.cluster = cluster;
  1446. commit->action = ACTION_MKDIR;
  1447. }
  1448. typedef struct {
  1449. /*
  1450. * Since the sequence number is at most 0x3f, and the filename
  1451. * length is at most 13 times the sequence number, the maximal
  1452. * filename length is 0x3f * 13 bytes.
  1453. */
  1454. unsigned char name[0x3f * 13 + 1];
  1455. gunichar2 name2[0x3f * 13 + 1];
  1456. int checksum, len;
  1457. int sequence_number;
  1458. } long_file_name;
  1459. static void lfn_init(long_file_name* lfn)
  1460. {
  1461. lfn->sequence_number = lfn->len = 0;
  1462. lfn->checksum = 0x100;
  1463. }
  1464. /* return 0 if parsed successfully, > 0 if no long name, < 0 if error */
  1465. static int parse_long_name(long_file_name* lfn,
  1466. const direntry_t* direntry)
  1467. {
  1468. int i, j, offset;
  1469. const unsigned char* pointer = (const unsigned char*)direntry;
  1470. if (!is_long_name(direntry))
  1471. return 1;
  1472. if (pointer[0] & 0x40) {
  1473. /* first entry; do some initialization */
  1474. lfn->sequence_number = pointer[0] & 0x3f;
  1475. lfn->checksum = pointer[13];
  1476. lfn->name[0] = 0;
  1477. lfn->name[lfn->sequence_number * 13] = 0;
  1478. } else if ((pointer[0] & 0x3f) != --lfn->sequence_number) {
  1479. /* not the expected sequence number */
  1480. return -1;
  1481. } else if (pointer[13] != lfn->checksum) {
  1482. /* not the expected checksum */
  1483. return -2;
  1484. } else if (pointer[12] || pointer[26] || pointer[27]) {
  1485. /* invalid zero fields */
  1486. return -3;
  1487. }
  1488. offset = 13 * (lfn->sequence_number - 1);
  1489. for (i = 0, j = 1; i < 13; i++, j+=2) {
  1490. if (j == 11)
  1491. j = 14;
  1492. else if (j == 26)
  1493. j = 28;
  1494. if (pointer[j] == 0 && pointer[j + 1] == 0) {
  1495. /* end of long file name */
  1496. break;
  1497. }
  1498. gunichar2 c = (pointer[j + 1] << 8) + pointer[j];
  1499. lfn->name2[offset + i] = c;
  1500. }
  1501. if (pointer[0] & 0x40) {
  1502. /* first entry; set len */
  1503. lfn->len = offset + i;
  1504. }
  1505. if ((pointer[0] & 0x3f) == 0x01) {
  1506. /* last entry; finalize entry */
  1507. glong olen;
  1508. gchar *utf8 = g_utf16_to_utf8(lfn->name2, lfn->len, NULL, &olen, NULL);
  1509. if (!utf8) {
  1510. return -4;
  1511. }
  1512. lfn->len = olen;
  1513. memcpy(lfn->name, utf8, olen + 1);
  1514. g_free(utf8);
  1515. }
  1516. return 0;
  1517. }
  1518. /* returns 0 if successful, >0 if no short_name, and <0 on error */
  1519. static int parse_short_name(BDRVVVFATState* s,
  1520. long_file_name* lfn, direntry_t* direntry)
  1521. {
  1522. int i, j;
  1523. if (!is_short_name(direntry))
  1524. return 1;
  1525. for (j = 7; j >= 0 && direntry->name[j] == ' '; j--);
  1526. for (i = 0; i <= j; i++) {
  1527. uint8_t c = direntry->name[i];
  1528. if (c != to_valid_short_char(c)) {
  1529. return -1;
  1530. } else if (s->downcase_short_names) {
  1531. lfn->name[i] = qemu_tolower(direntry->name[i]);
  1532. } else {
  1533. lfn->name[i] = direntry->name[i];
  1534. }
  1535. }
  1536. for (j = 2; j >= 0 && direntry->name[8 + j] == ' '; j--) {
  1537. }
  1538. if (j >= 0) {
  1539. lfn->name[i++] = '.';
  1540. lfn->name[i + j + 1] = '\0';
  1541. for (;j >= 0; j--) {
  1542. uint8_t c = direntry->name[8 + j];
  1543. if (c != to_valid_short_char(c)) {
  1544. return -2;
  1545. } else if (s->downcase_short_names) {
  1546. lfn->name[i + j] = qemu_tolower(c);
  1547. } else {
  1548. lfn->name[i + j] = c;
  1549. }
  1550. }
  1551. } else
  1552. lfn->name[i + j + 1] = '\0';
  1553. if (lfn->name[0] == DIR_KANJI_FAKE) {
  1554. lfn->name[0] = DIR_KANJI;
  1555. }
  1556. lfn->len = strlen((char*)lfn->name);
  1557. return 0;
  1558. }
  1559. static inline uint32_t modified_fat_get(BDRVVVFATState* s,
  1560. unsigned int cluster)
  1561. {
  1562. if (cluster < s->last_cluster_of_root_directory) {
  1563. if (cluster + 1 == s->last_cluster_of_root_directory)
  1564. return s->max_fat_value;
  1565. else
  1566. return cluster + 1;
  1567. }
  1568. if (s->fat_type==32) {
  1569. uint32_t* entry=((uint32_t*)s->fat2)+cluster;
  1570. return le32_to_cpu(*entry);
  1571. } else if (s->fat_type==16) {
  1572. uint16_t* entry=((uint16_t*)s->fat2)+cluster;
  1573. return le16_to_cpu(*entry);
  1574. } else {
  1575. const uint8_t* x=s->fat2+cluster*3/2;
  1576. return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
  1577. }
  1578. }
  1579. static inline bool coroutine_fn GRAPH_RDLOCK
  1580. cluster_was_modified(BDRVVVFATState *s, uint32_t cluster_num)
  1581. {
  1582. int was_modified = 0;
  1583. int i;
  1584. if (s->qcow == NULL) {
  1585. return 0;
  1586. }
  1587. for (i = 0; !was_modified && i < s->sectors_per_cluster; i++) {
  1588. was_modified = bdrv_co_is_allocated(s->qcow->bs,
  1589. (cluster2sector(s, cluster_num) +
  1590. i) * BDRV_SECTOR_SIZE,
  1591. BDRV_SECTOR_SIZE, NULL);
  1592. }
  1593. /*
  1594. * Note that this treats failures to learn allocation status the
  1595. * same as if an allocation has occurred. It's as safe as
  1596. * anything else, given that a failure to learn allocation status
  1597. * will probably result in more failures.
  1598. */
  1599. return !!was_modified;
  1600. }
  1601. static const char* get_basename(const char* path)
  1602. {
  1603. char* basename = strrchr(path, '/');
  1604. if (basename == NULL)
  1605. return path;
  1606. else
  1607. return basename + 1; /* strip '/' */
  1608. }
  1609. /*
  1610. * The array s->used_clusters holds the states of the clusters. If it is
  1611. * part of a file, it has bit 2 set, in case of a directory, bit 1. If it
  1612. * was modified, bit 3 is set.
  1613. * If any cluster is allocated, but not part of a file or directory, this
  1614. * driver refuses to commit.
  1615. */
  1616. typedef enum {
  1617. USED_DIRECTORY = 1, USED_FILE = 2, USED_ANY = 3, USED_ALLOCATED = 4
  1618. } used_t;
  1619. /*
  1620. * get_cluster_count_for_direntry() not only determines how many clusters
  1621. * are occupied by direntry, but also if it was renamed or modified.
  1622. *
  1623. * A file is thought to be renamed *only* if there already was a file with
  1624. * exactly the same first cluster, but a different name.
  1625. *
  1626. * Further, the files/directories handled by this function are
  1627. * assumed to be *not* deleted (and *only* those).
  1628. */
  1629. static uint32_t coroutine_fn GRAPH_RDLOCK
  1630. get_cluster_count_for_direntry(BDRVVVFATState* s, direntry_t* direntry, const char* path)
  1631. {
  1632. /*
  1633. * This is a little bit tricky:
  1634. * IF the guest OS just inserts a cluster into the file chain,
  1635. * and leaves the rest alone, (i.e. the original file had clusters
  1636. * 15 -> 16, but now has 15 -> 32 -> 16), then the following happens:
  1637. *
  1638. * - do_commit will write the cluster into the file at the given
  1639. * offset, but
  1640. *
  1641. * - the cluster which is overwritten should be moved to a later
  1642. * position in the file.
  1643. *
  1644. * I am not aware that any OS does something as braindead, but this
  1645. * situation could happen anyway when not committing for a long time.
  1646. * Just to be sure that this does not bite us, detect it, and copy the
  1647. * contents of the clusters to-be-overwritten into the qcow.
  1648. */
  1649. int copy_it = 0;
  1650. int was_modified = 0;
  1651. int32_t ret = 0;
  1652. uint32_t cluster_num = begin_of_direntry(direntry);
  1653. uint32_t offset = 0;
  1654. mapping_t* mapping = NULL;
  1655. const char* basename2 = NULL;
  1656. vvfat_close_current_file(s);
  1657. /* the root directory */
  1658. if (cluster_num == 0)
  1659. return 0;
  1660. /* write support */
  1661. if (s->qcow) {
  1662. basename2 = get_basename(path);
  1663. mapping = find_mapping_for_cluster(s, cluster_num);
  1664. if (mapping) {
  1665. const char* basename;
  1666. assert(mapping->mode & MODE_DELETED);
  1667. mapping->mode &= ~MODE_DELETED;
  1668. basename = get_basename(mapping->path);
  1669. assert(mapping->mode & MODE_NORMAL);
  1670. /* rename */
  1671. if (strcmp(basename, basename2))
  1672. schedule_rename(s, cluster_num, g_strdup(path));
  1673. } else if (is_file(direntry))
  1674. /* new file */
  1675. schedule_new_file(s, g_strdup(path), cluster_num);
  1676. else {
  1677. abort();
  1678. return 0;
  1679. }
  1680. }
  1681. while(1) {
  1682. if (s->qcow) {
  1683. if (!copy_it && cluster_was_modified(s, cluster_num)) {
  1684. if (mapping == NULL ||
  1685. mapping->begin > cluster_num ||
  1686. mapping->end <= cluster_num)
  1687. mapping = find_mapping_for_cluster(s, cluster_num);
  1688. if (mapping &&
  1689. (mapping->mode & MODE_DIRECTORY) == 0) {
  1690. /* was modified in qcow */
  1691. if (offset != s->cluster_size
  1692. * ((cluster_num - mapping->begin)
  1693. + mapping->info.file.offset)) {
  1694. /* offset of this cluster in file chain has changed */
  1695. abort();
  1696. copy_it = 1;
  1697. } else if (offset == 0) {
  1698. const char* basename = get_basename(mapping->path);
  1699. if (strcmp(basename, basename2))
  1700. copy_it = 1;
  1701. }
  1702. assert(mapping->first_mapping_index == -1
  1703. || mapping->info.file.offset > 0);
  1704. /* need to write out? */
  1705. if (!was_modified && is_file(direntry)) {
  1706. was_modified = 1;
  1707. schedule_writeout(s, mapping->dir_index, offset);
  1708. }
  1709. }
  1710. }
  1711. if (copy_it) {
  1712. int i;
  1713. /*
  1714. * This is horribly inefficient, but that is okay, since
  1715. * it is rarely executed, if at all.
  1716. */
  1717. int64_t offs = cluster2sector(s, cluster_num);
  1718. vvfat_close_current_file(s);
  1719. for (i = 0; i < s->sectors_per_cluster; i++) {
  1720. int res;
  1721. res = bdrv_co_is_allocated(s->qcow->bs,
  1722. (offs + i) * BDRV_SECTOR_SIZE,
  1723. BDRV_SECTOR_SIZE, NULL);
  1724. if (res < 0) {
  1725. return -1;
  1726. }
  1727. if (!res) {
  1728. res = vvfat_read(s->bs, offs, s->cluster_buffer, 1);
  1729. if (res) {
  1730. return -1;
  1731. }
  1732. res = bdrv_co_pwrite(s->qcow, offs * BDRV_SECTOR_SIZE,
  1733. BDRV_SECTOR_SIZE, s->cluster_buffer,
  1734. 0);
  1735. if (res < 0) {
  1736. return -2;
  1737. }
  1738. }
  1739. }
  1740. }
  1741. }
  1742. ret++;
  1743. if (s->used_clusters[cluster_num] & USED_ANY)
  1744. return 0;
  1745. s->used_clusters[cluster_num] = USED_FILE;
  1746. cluster_num = modified_fat_get(s, cluster_num);
  1747. if (fat_eof(s, cluster_num))
  1748. return ret;
  1749. else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16)
  1750. return -1;
  1751. offset += s->cluster_size;
  1752. }
  1753. }
  1754. /*
  1755. * This function looks at the modified data (qcow).
  1756. * It returns 0 upon inconsistency or error, and the number of clusters
  1757. * used by the directory, its subdirectories and their files.
  1758. */
  1759. static int coroutine_fn GRAPH_RDLOCK
  1760. check_directory_consistency(BDRVVVFATState *s, int cluster_num, const char* path)
  1761. {
  1762. int ret = 0;
  1763. unsigned char* cluster = g_malloc(s->cluster_size);
  1764. direntry_t* direntries = (direntry_t*)cluster;
  1765. mapping_t* mapping = find_mapping_for_cluster(s, cluster_num);
  1766. long_file_name lfn;
  1767. int path_len = strlen(path);
  1768. char path2[PATH_MAX + 1];
  1769. assert(path_len < PATH_MAX); /* len was tested before! */
  1770. pstrcpy(path2, sizeof(path2), path);
  1771. path2[path_len] = '/';
  1772. path2[path_len + 1] = '\0';
  1773. if (mapping) {
  1774. const char* basename = get_basename(mapping->path);
  1775. const char* basename2 = get_basename(path);
  1776. assert(mapping->mode & MODE_DIRECTORY);
  1777. assert(mapping->mode & MODE_DELETED);
  1778. mapping->mode &= ~MODE_DELETED;
  1779. if (strcmp(basename, basename2))
  1780. schedule_rename(s, cluster_num, g_strdup(path));
  1781. } else
  1782. /* new directory */
  1783. schedule_mkdir(s, cluster_num, g_strdup(path));
  1784. lfn_init(&lfn);
  1785. do {
  1786. int i;
  1787. int subret = 0;
  1788. ret++;
  1789. if (s->used_clusters[cluster_num] & USED_ANY) {
  1790. fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num);
  1791. goto fail;
  1792. }
  1793. s->used_clusters[cluster_num] = USED_DIRECTORY;
  1794. DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)cluster2sector(s, cluster_num)));
  1795. subret = vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster,
  1796. s->sectors_per_cluster);
  1797. if (subret) {
  1798. fprintf(stderr, "Error fetching direntries\n");
  1799. fail:
  1800. g_free(cluster);
  1801. return 0;
  1802. }
  1803. for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) {
  1804. int cluster_count = 0;
  1805. DLOG(fprintf(stderr, "check direntry %d:\n", i); print_direntry(direntries + i));
  1806. if (is_volume_label(direntries + i) || is_dot(direntries + i) ||
  1807. is_free(direntries + i))
  1808. continue;
  1809. subret = parse_long_name(&lfn, direntries + i);
  1810. if (subret < 0) {
  1811. fprintf(stderr, "Error in long name\n");
  1812. goto fail;
  1813. }
  1814. if (subret == 0 || is_free(direntries + i))
  1815. continue;
  1816. if (fat_chksum(direntries+i) != lfn.checksum) {
  1817. subret = parse_short_name(s, &lfn, direntries + i);
  1818. if (subret < 0) {
  1819. fprintf(stderr, "Error in short name (%d)\n", subret);
  1820. goto fail;
  1821. }
  1822. if (subret > 0 || !strcmp((char*)lfn.name, ".")
  1823. || !strcmp((char*)lfn.name, ".."))
  1824. continue;
  1825. }
  1826. lfn.checksum = 0x100; /* cannot use long name twice */
  1827. if (!valid_filename(lfn.name)) {
  1828. fprintf(stderr, "Invalid file name\n");
  1829. goto fail;
  1830. }
  1831. if (path_len + 1 + lfn.len >= PATH_MAX) {
  1832. fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name);
  1833. goto fail;
  1834. }
  1835. pstrcpy(path2 + path_len + 1, sizeof(path2) - path_len - 1,
  1836. (char*)lfn.name);
  1837. if (is_directory(direntries + i)) {
  1838. if (begin_of_direntry(direntries + i) == 0) {
  1839. DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i));
  1840. goto fail;
  1841. }
  1842. cluster_count = check_directory_consistency(s,
  1843. begin_of_direntry(direntries + i), path2);
  1844. if (cluster_count == 0) {
  1845. DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i));
  1846. goto fail;
  1847. }
  1848. } else if (is_file(direntries + i)) {
  1849. /* check file size with FAT */
  1850. cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2);
  1851. if (cluster_count !=
  1852. DIV_ROUND_UP(le32_to_cpu(direntries[i].size), s->cluster_size)) {
  1853. DLOG(fprintf(stderr, "Cluster count mismatch\n"));
  1854. goto fail;
  1855. }
  1856. } else
  1857. abort(); /* cluster_count = 0; */
  1858. ret += cluster_count;
  1859. }
  1860. cluster_num = modified_fat_get(s, cluster_num);
  1861. } while(!fat_eof(s, cluster_num));
  1862. g_free(cluster);
  1863. return ret;
  1864. }
  1865. /* returns 1 on success */
  1866. static int coroutine_fn GRAPH_RDLOCK
  1867. is_consistent(BDRVVVFATState* s)
  1868. {
  1869. int i, check;
  1870. int used_clusters_count = 0;
  1871. DLOG(checkpoint());
  1872. /*
  1873. * - get modified FAT
  1874. * - compare the two FATs (TODO)
  1875. * - get buffer for marking used clusters
  1876. * - recurse direntries from root (using bs->bdrv_pread to make
  1877. * sure to get the new data)
  1878. * - check that the FAT agrees with the size
  1879. * - count the number of clusters occupied by this directory and
  1880. * its files
  1881. * - check that the cumulative used cluster count agrees with the
  1882. * FAT
  1883. * - if all is fine, return number of used clusters
  1884. */
  1885. if (s->fat2 == NULL) {
  1886. int size = 0x200 * s->sectors_per_fat;
  1887. s->fat2 = g_malloc(size);
  1888. memcpy(s->fat2, s->fat.pointer, size);
  1889. }
  1890. check = vvfat_read(s->bs,
  1891. s->offset_to_fat, s->fat2, s->sectors_per_fat);
  1892. if (check) {
  1893. fprintf(stderr, "Could not copy fat\n");
  1894. return 0;
  1895. }
  1896. assert (s->used_clusters);
  1897. for (i = 0; i < sector2cluster(s, s->sector_count); i++)
  1898. s->used_clusters[i] &= ~USED_ANY;
  1899. clear_commits(s);
  1900. /* mark every mapped file/directory as deleted.
  1901. * (check_directory_consistency() will unmark those still present). */
  1902. if (s->qcow)
  1903. for (i = 0; i < s->mapping.next; i++) {
  1904. mapping_t* mapping = array_get(&(s->mapping), i);
  1905. if (mapping->first_mapping_index < 0)
  1906. mapping->mode |= MODE_DELETED;
  1907. }
  1908. used_clusters_count = check_directory_consistency(s, 0, s->path);
  1909. if (used_clusters_count <= 0) {
  1910. DLOG(fprintf(stderr, "problem in directory\n"));
  1911. return 0;
  1912. }
  1913. check = s->last_cluster_of_root_directory;
  1914. for (i = check; i < sector2cluster(s, s->sector_count); i++) {
  1915. if (modified_fat_get(s, i)) {
  1916. if(!s->used_clusters[i]) {
  1917. DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n", i));
  1918. return 0;
  1919. }
  1920. check++;
  1921. }
  1922. if (s->used_clusters[i] == USED_ALLOCATED) {
  1923. /* allocated, but not used... */
  1924. DLOG(fprintf(stderr, "unused, modified cluster: %d\n", i));
  1925. return 0;
  1926. }
  1927. }
  1928. if (check != used_clusters_count)
  1929. return 0;
  1930. return used_clusters_count;
  1931. }
  1932. static inline void adjust_mapping_indices(BDRVVVFATState* s,
  1933. int offset, int adjust)
  1934. {
  1935. int i;
  1936. for (i = 0; i < s->mapping.next; i++) {
  1937. mapping_t* mapping = array_get(&(s->mapping), i);
  1938. #define ADJUST_MAPPING_INDEX(name) \
  1939. if (mapping->name >= offset) \
  1940. mapping->name += adjust
  1941. ADJUST_MAPPING_INDEX(first_mapping_index);
  1942. if (mapping->mode & MODE_DIRECTORY)
  1943. ADJUST_MAPPING_INDEX(info.dir.parent_mapping_index);
  1944. }
  1945. }
  1946. /* insert or update mapping */
  1947. static mapping_t* insert_mapping(BDRVVVFATState* s,
  1948. uint32_t begin, uint32_t end)
  1949. {
  1950. /*
  1951. * - find mapping where mapping->begin >= begin,
  1952. * - if mapping->begin > begin: insert
  1953. * - adjust all references to mappings!
  1954. * - else: adjust
  1955. * - replace name
  1956. */
  1957. int index = find_mapping_for_cluster_aux(s, begin, 0, s->mapping.next);
  1958. mapping_t* mapping = NULL;
  1959. mapping_t* first_mapping = array_get(&(s->mapping), 0);
  1960. if (index < s->mapping.next && (mapping = array_get(&(s->mapping), index))
  1961. && mapping->begin < begin) {
  1962. mapping->end = begin;
  1963. index++;
  1964. mapping = array_get(&(s->mapping), index);
  1965. }
  1966. if (index >= s->mapping.next || mapping->begin > begin) {
  1967. mapping = array_insert(&(s->mapping), index, 1);
  1968. mapping->path = NULL;
  1969. adjust_mapping_indices(s, index, +1);
  1970. }
  1971. mapping->begin = begin;
  1972. mapping->end = end;
  1973. DLOG(mapping_t* next_mapping;
  1974. assert(index + 1 >= s->mapping.next ||
  1975. ((next_mapping = array_get(&(s->mapping), index + 1)) &&
  1976. next_mapping->begin >= end)));
  1977. if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
  1978. s->current_mapping = array_get(&(s->mapping),
  1979. s->current_mapping - first_mapping);
  1980. return mapping;
  1981. }
  1982. static int remove_mapping(BDRVVVFATState* s, int mapping_index)
  1983. {
  1984. mapping_t* mapping = array_get(&(s->mapping), mapping_index);
  1985. mapping_t* first_mapping = array_get(&(s->mapping), 0);
  1986. /* free mapping */
  1987. if (mapping->first_mapping_index < 0) {
  1988. g_free(mapping->path);
  1989. }
  1990. /* remove from s->mapping */
  1991. array_remove(&(s->mapping), mapping_index);
  1992. /* adjust all references to mappings */
  1993. adjust_mapping_indices(s, mapping_index, -1);
  1994. if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
  1995. s->current_mapping = array_get(&(s->mapping),
  1996. s->current_mapping - first_mapping);
  1997. return 0;
  1998. }
  1999. static void adjust_dirindices(BDRVVVFATState* s, int offset, int adjust)
  2000. {
  2001. int i;
  2002. for (i = 0; i < s->mapping.next; i++) {
  2003. mapping_t* mapping = array_get(&(s->mapping), i);
  2004. if (mapping->dir_index >= offset)
  2005. mapping->dir_index += adjust;
  2006. if ((mapping->mode & MODE_DIRECTORY) &&
  2007. mapping->info.dir.first_dir_index >= offset)
  2008. mapping->info.dir.first_dir_index += adjust;
  2009. }
  2010. }
  2011. static direntry_t* insert_direntries(BDRVVVFATState* s,
  2012. int dir_index, int count)
  2013. {
  2014. /*
  2015. * make room in s->directory,
  2016. * adjust_dirindices
  2017. */
  2018. direntry_t* result = array_insert(&(s->directory), dir_index, count);
  2019. if (result == NULL)
  2020. return NULL;
  2021. adjust_dirindices(s, dir_index, count);
  2022. return result;
  2023. }
  2024. static int remove_direntries(BDRVVVFATState* s, int dir_index, int count)
  2025. {
  2026. int ret = array_remove_slice(&(s->directory), dir_index, count);
  2027. if (ret)
  2028. return ret;
  2029. adjust_dirindices(s, dir_index, -count);
  2030. return 0;
  2031. }
  2032. /*
  2033. * Adapt the mappings of the cluster chain starting at first cluster
  2034. * (i.e. if a file starts at first_cluster, the chain is followed according
  2035. * to the modified fat, and the corresponding entries in s->mapping are
  2036. * adjusted)
  2037. */
  2038. static int commit_mappings(BDRVVVFATState* s,
  2039. uint32_t first_cluster, int dir_index)
  2040. {
  2041. mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
  2042. direntry_t* direntry = array_get(&(s->directory), dir_index);
  2043. uint32_t cluster = first_cluster;
  2044. vvfat_close_current_file(s);
  2045. assert(mapping);
  2046. assert(mapping->begin == first_cluster);
  2047. mapping->first_mapping_index = -1;
  2048. mapping->dir_index = dir_index;
  2049. mapping->mode = (dir_index <= 0 || is_directory(direntry)) ?
  2050. MODE_DIRECTORY : MODE_NORMAL;
  2051. while (!fat_eof(s, cluster)) {
  2052. uint32_t c, c1;
  2053. for (c = cluster, c1 = modified_fat_get(s, c); c + 1 == c1;
  2054. c = c1, c1 = modified_fat_get(s, c1));
  2055. c++;
  2056. if (c > mapping->end) {
  2057. int index = array_index(&(s->mapping), mapping);
  2058. int i, max_i = s->mapping.next - index;
  2059. for (i = 1; i < max_i && mapping[i].begin < c; i++);
  2060. while (--i > 0)
  2061. remove_mapping(s, index + 1);
  2062. }
  2063. assert(mapping == array_get(&(s->mapping), s->mapping.next - 1)
  2064. || mapping[1].begin >= c);
  2065. mapping->end = c;
  2066. if (!fat_eof(s, c1)) {
  2067. int i = find_mapping_for_cluster_aux(s, c1, 0, s->mapping.next);
  2068. mapping_t* next_mapping = i >= s->mapping.next ? NULL :
  2069. array_get(&(s->mapping), i);
  2070. if (next_mapping == NULL || next_mapping->begin > c1) {
  2071. int i1 = array_index(&(s->mapping), mapping);
  2072. next_mapping = insert_mapping(s, c1, c1+1);
  2073. if (c1 < c)
  2074. i1++;
  2075. mapping = array_get(&(s->mapping), i1);
  2076. }
  2077. next_mapping->dir_index = mapping->dir_index;
  2078. next_mapping->first_mapping_index =
  2079. mapping->first_mapping_index < 0 ?
  2080. array_index(&(s->mapping), mapping) :
  2081. mapping->first_mapping_index;
  2082. next_mapping->path = mapping->path;
  2083. next_mapping->mode = mapping->mode;
  2084. next_mapping->read_only = mapping->read_only;
  2085. if (mapping->mode & MODE_DIRECTORY) {
  2086. next_mapping->info.dir.parent_mapping_index =
  2087. mapping->info.dir.parent_mapping_index;
  2088. next_mapping->info.dir.first_dir_index =
  2089. mapping->info.dir.first_dir_index +
  2090. 0x10 * s->sectors_per_cluster *
  2091. (mapping->end - mapping->begin);
  2092. } else
  2093. next_mapping->info.file.offset = mapping->info.file.offset +
  2094. (mapping->end - mapping->begin);
  2095. mapping = next_mapping;
  2096. }
  2097. cluster = c1;
  2098. }
  2099. return 0;
  2100. }
  2101. static int coroutine_fn GRAPH_RDLOCK
  2102. commit_direntries(BDRVVVFATState* s, int dir_index, int parent_mapping_index)
  2103. {
  2104. direntry_t* direntry = array_get(&(s->directory), dir_index);
  2105. uint32_t first_cluster = dir_index == 0 ? 0 : begin_of_direntry(direntry);
  2106. mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
  2107. int factor = 0x10 * s->sectors_per_cluster;
  2108. int old_cluster_count, new_cluster_count;
  2109. int current_dir_index;
  2110. int first_dir_index;
  2111. int ret, i;
  2112. uint32_t c;
  2113. assert(direntry);
  2114. assert(mapping);
  2115. assert(mapping->begin == first_cluster);
  2116. assert(mapping->info.dir.first_dir_index < s->directory.next);
  2117. assert(mapping->mode & MODE_DIRECTORY);
  2118. assert(dir_index == 0 || is_directory(direntry));
  2119. DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n",
  2120. mapping->path, parent_mapping_index));
  2121. current_dir_index = mapping->info.dir.first_dir_index;
  2122. first_dir_index = current_dir_index;
  2123. mapping->info.dir.parent_mapping_index = parent_mapping_index;
  2124. if (first_cluster == 0) {
  2125. old_cluster_count = new_cluster_count =
  2126. s->last_cluster_of_root_directory;
  2127. } else {
  2128. for (old_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
  2129. c = fat_get(s, c))
  2130. old_cluster_count++;
  2131. for (new_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
  2132. c = modified_fat_get(s, c))
  2133. new_cluster_count++;
  2134. }
  2135. if (new_cluster_count > old_cluster_count) {
  2136. if (insert_direntries(s,
  2137. current_dir_index + factor * old_cluster_count,
  2138. factor * (new_cluster_count - old_cluster_count)) == NULL)
  2139. return -1;
  2140. } else if (new_cluster_count < old_cluster_count)
  2141. remove_direntries(s,
  2142. current_dir_index + factor * new_cluster_count,
  2143. factor * (old_cluster_count - new_cluster_count));
  2144. for (c = first_cluster; !fat_eof(s, c); c = modified_fat_get(s, c)) {
  2145. direntry_t *first_direntry;
  2146. direntry = array_get(&(s->directory), current_dir_index);
  2147. ret = vvfat_read(s->bs, cluster2sector(s, c), (uint8_t *)direntry,
  2148. s->sectors_per_cluster);
  2149. if (ret)
  2150. return ret;
  2151. /* The first directory entry on the filesystem is the volume name */
  2152. first_direntry = (direntry_t*) s->directory.pointer;
  2153. assert(!memcmp(first_direntry->name, s->volume_label, 11));
  2154. current_dir_index += factor;
  2155. }
  2156. ret = commit_mappings(s, first_cluster, dir_index);
  2157. if (ret)
  2158. return ret;
  2159. /* recurse */
  2160. for (i = 0; i < factor * new_cluster_count; i++) {
  2161. direntry = array_get(&(s->directory), first_dir_index + i);
  2162. if (is_directory(direntry) && !is_dot(direntry)) {
  2163. mapping = find_mapping_for_cluster(s, first_cluster);
  2164. if (mapping == NULL) {
  2165. return -1;
  2166. }
  2167. assert(mapping->mode & MODE_DIRECTORY);
  2168. ret = commit_direntries(s, first_dir_index + i,
  2169. array_index(&(s->mapping), mapping));
  2170. if (ret)
  2171. return ret;
  2172. }
  2173. }
  2174. return 0;
  2175. }
  2176. /* commit one file (adjust contents, adjust mapping),
  2177. return first_mapping_index */
  2178. static int coroutine_fn GRAPH_RDLOCK
  2179. commit_one_file(BDRVVVFATState* s, int dir_index, uint32_t offset)
  2180. {
  2181. direntry_t* direntry = array_get(&(s->directory), dir_index);
  2182. uint32_t c = begin_of_direntry(direntry);
  2183. uint32_t first_cluster = c;
  2184. mapping_t* mapping = find_mapping_for_cluster(s, c);
  2185. uint32_t size = filesize_of_direntry(direntry);
  2186. char *cluster;
  2187. uint32_t i;
  2188. int fd = 0;
  2189. assert(offset < size);
  2190. assert((offset % s->cluster_size) == 0);
  2191. if (mapping == NULL) {
  2192. return -1;
  2193. }
  2194. for (i = 0; i < offset; i += s->cluster_size) {
  2195. c = modified_fat_get(s, c);
  2196. }
  2197. fd = qemu_open_old(mapping->path, O_RDWR | O_CREAT | O_BINARY, 0666);
  2198. if (fd < 0) {
  2199. fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path,
  2200. strerror(errno), errno);
  2201. return fd;
  2202. }
  2203. if (offset > 0) {
  2204. if (lseek(fd, offset, SEEK_SET) != offset) {
  2205. qemu_close(fd);
  2206. return -3;
  2207. }
  2208. }
  2209. cluster = g_malloc(s->cluster_size);
  2210. while (offset < size) {
  2211. uint32_t c1;
  2212. int rest_size = (size - offset > s->cluster_size ?
  2213. s->cluster_size : size - offset);
  2214. int ret;
  2215. c1 = modified_fat_get(s, c);
  2216. assert((size - offset == 0 && fat_eof(s, c)) ||
  2217. (size > offset && c >=2 && !fat_eof(s, c)));
  2218. ret = vvfat_read(s->bs, cluster2sector(s, c),
  2219. (uint8_t*)cluster, DIV_ROUND_UP(rest_size, 0x200));
  2220. if (ret < 0) {
  2221. qemu_close(fd);
  2222. g_free(cluster);
  2223. return ret;
  2224. }
  2225. if (write(fd, cluster, rest_size) < 0) {
  2226. qemu_close(fd);
  2227. g_free(cluster);
  2228. return -2;
  2229. }
  2230. offset += rest_size;
  2231. c = c1;
  2232. }
  2233. if (ftruncate(fd, size)) {
  2234. perror("ftruncate()");
  2235. qemu_close(fd);
  2236. g_free(cluster);
  2237. return -4;
  2238. }
  2239. qemu_close(fd);
  2240. g_free(cluster);
  2241. return commit_mappings(s, first_cluster, dir_index);
  2242. }
  2243. #ifdef DEBUG
  2244. /* test, if all mappings point to valid direntries */
  2245. static void check1(BDRVVVFATState* s)
  2246. {
  2247. int i;
  2248. for (i = 0; i < s->mapping.next; i++) {
  2249. mapping_t* mapping = array_get(&(s->mapping), i);
  2250. if (mapping->mode & MODE_DELETED) {
  2251. fprintf(stderr, "deleted\n");
  2252. continue;
  2253. }
  2254. assert(mapping->dir_index < s->directory.next);
  2255. direntry_t* direntry = array_get(&(s->directory), mapping->dir_index);
  2256. assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0);
  2257. if (mapping->mode & MODE_DIRECTORY) {
  2258. assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster * (mapping->end - mapping->begin) <= s->directory.next);
  2259. assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors_per_cluster)) == 0);
  2260. }
  2261. }
  2262. }
  2263. /* test, if all direntries have mappings */
  2264. static void check2(BDRVVVFATState* s)
  2265. {
  2266. int i;
  2267. int first_mapping = -1;
  2268. for (i = 0; i < s->directory.next; i++) {
  2269. direntry_t* direntry = array_get(&(s->directory), i);
  2270. if (is_short_name(direntry) && begin_of_direntry(direntry)) {
  2271. mapping_t* mapping = find_mapping_for_cluster(s, begin_of_direntry(direntry));
  2272. assert(mapping);
  2273. assert(mapping->dir_index == i || is_dot(direntry));
  2274. assert(mapping->begin == begin_of_direntry(direntry) || is_dot(direntry));
  2275. }
  2276. if ((i % (0x10 * s->sectors_per_cluster)) == 0) {
  2277. /* cluster start */
  2278. int j, count = 0;
  2279. for (j = 0; j < s->mapping.next; j++) {
  2280. mapping_t* mapping = array_get(&(s->mapping), j);
  2281. if (mapping->mode & MODE_DELETED)
  2282. continue;
  2283. if (mapping->mode & MODE_DIRECTORY) {
  2284. if (mapping->info.dir.first_dir_index <= i && mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster > i) {
  2285. assert(++count == 1);
  2286. if (mapping->first_mapping_index == -1)
  2287. first_mapping = array_index(&(s->mapping), mapping);
  2288. else
  2289. assert(first_mapping == mapping->first_mapping_index);
  2290. if (mapping->info.dir.parent_mapping_index < 0)
  2291. assert(j == 0);
  2292. else {
  2293. mapping_t* parent = array_get(&(s->mapping), mapping->info.dir.parent_mapping_index);
  2294. assert(parent->mode & MODE_DIRECTORY);
  2295. assert(parent->info.dir.first_dir_index < mapping->info.dir.first_dir_index);
  2296. }
  2297. }
  2298. }
  2299. }
  2300. if (count == 0)
  2301. first_mapping = -1;
  2302. }
  2303. }
  2304. }
  2305. #endif
  2306. static int handle_renames_and_mkdirs(BDRVVVFATState* s)
  2307. {
  2308. int i;
  2309. #ifdef DEBUG
  2310. fprintf(stderr, "handle_renames\n");
  2311. for (i = 0; i < s->commits.next; i++) {
  2312. commit_t* commit = array_get(&(s->commits), i);
  2313. fprintf(stderr, "%d, %s (%u, %d)\n", i,
  2314. commit->path ? commit->path : "(null)",
  2315. commit->param.rename.cluster, commit->action);
  2316. }
  2317. #endif
  2318. for (i = 0; i < s->commits.next;) {
  2319. commit_t* commit = array_get(&(s->commits), i);
  2320. if (commit->action == ACTION_RENAME) {
  2321. mapping_t* mapping = find_mapping_for_cluster(s,
  2322. commit->param.rename.cluster);
  2323. char *old_path;
  2324. if (mapping == NULL) {
  2325. return -1;
  2326. }
  2327. old_path = mapping->path;
  2328. assert(commit->path);
  2329. mapping->path = commit->path;
  2330. if (rename(old_path, mapping->path))
  2331. return -2;
  2332. if (mapping->mode & MODE_DIRECTORY) {
  2333. int l1 = strlen(mapping->path);
  2334. int l2 = strlen(old_path);
  2335. int diff = l1 - l2;
  2336. direntry_t* direntry = array_get(&(s->directory),
  2337. mapping->info.dir.first_dir_index);
  2338. uint32_t c = mapping->begin;
  2339. int j = 0;
  2340. /* recurse */
  2341. while (!fat_eof(s, c)) {
  2342. do {
  2343. direntry_t *d = direntry + j;
  2344. if (is_file(d) || (is_directory(d) && !is_dot(d))) {
  2345. int l;
  2346. char *new_path;
  2347. mapping_t* m = find_mapping_for_cluster(s,
  2348. begin_of_direntry(d));
  2349. if (m == NULL) {
  2350. return -1;
  2351. }
  2352. l = strlen(m->path);
  2353. new_path = g_malloc(l + diff + 1);
  2354. assert(!strncmp(m->path, mapping->path, l2));
  2355. pstrcpy(new_path, l + diff + 1, mapping->path);
  2356. pstrcpy(new_path + l1, l + diff + 1 - l1,
  2357. m->path + l2);
  2358. schedule_rename(s, m->begin, new_path);
  2359. }
  2360. j++;
  2361. } while (j % (0x10 * s->sectors_per_cluster) != 0);
  2362. c = fat_get(s, c);
  2363. }
  2364. }
  2365. g_free(old_path);
  2366. array_remove(&(s->commits), i);
  2367. continue;
  2368. } else if (commit->action == ACTION_MKDIR) {
  2369. mapping_t* mapping;
  2370. int j, parent_path_len;
  2371. if (g_mkdir(commit->path, 0755)) {
  2372. return -5;
  2373. }
  2374. mapping = insert_mapping(s, commit->param.mkdir.cluster,
  2375. commit->param.mkdir.cluster + 1);
  2376. if (mapping == NULL)
  2377. return -6;
  2378. mapping->mode = MODE_DIRECTORY;
  2379. mapping->read_only = 0;
  2380. mapping->path = commit->path;
  2381. j = s->directory.next;
  2382. assert(j);
  2383. insert_direntries(s, s->directory.next,
  2384. 0x10 * s->sectors_per_cluster);
  2385. mapping->info.dir.first_dir_index = j;
  2386. parent_path_len = strlen(commit->path)
  2387. - strlen(get_basename(commit->path)) - 1;
  2388. for (j = 0; j < s->mapping.next; j++) {
  2389. mapping_t* m = array_get(&(s->mapping), j);
  2390. if (m->first_mapping_index < 0 && m != mapping &&
  2391. !strncmp(m->path, mapping->path, parent_path_len) &&
  2392. strlen(m->path) == parent_path_len)
  2393. break;
  2394. }
  2395. assert(j < s->mapping.next);
  2396. mapping->info.dir.parent_mapping_index = j;
  2397. array_remove(&(s->commits), i);
  2398. continue;
  2399. }
  2400. i++;
  2401. }
  2402. return 0;
  2403. }
  2404. /*
  2405. * TODO: make sure that the short name is not matching *another* file
  2406. */
  2407. static int coroutine_fn GRAPH_RDLOCK handle_commits(BDRVVVFATState* s)
  2408. {
  2409. int i, fail = 0;
  2410. vvfat_close_current_file(s);
  2411. for (i = 0; !fail && i < s->commits.next; i++) {
  2412. commit_t* commit = array_get(&(s->commits), i);
  2413. switch(commit->action) {
  2414. case ACTION_RENAME: case ACTION_MKDIR:
  2415. abort();
  2416. fail = -2;
  2417. break;
  2418. case ACTION_WRITEOUT: {
  2419. direntry_t* entry = array_get(&(s->directory),
  2420. commit->param.writeout.dir_index);
  2421. uint32_t begin = begin_of_direntry(entry);
  2422. mapping_t* mapping = find_mapping_for_cluster(s, begin);
  2423. assert(mapping);
  2424. assert(mapping->begin == begin);
  2425. assert(commit->path == NULL);
  2426. if (commit_one_file(s, commit->param.writeout.dir_index,
  2427. commit->param.writeout.modified_offset))
  2428. fail = -3;
  2429. break;
  2430. }
  2431. case ACTION_NEW_FILE: {
  2432. int begin = commit->param.new_file.first_cluster;
  2433. mapping_t* mapping = find_mapping_for_cluster(s, begin);
  2434. direntry_t* entry;
  2435. int j;
  2436. /* find direntry */
  2437. for (j = 0; j < s->directory.next; j++) {
  2438. entry = array_get(&(s->directory), j);
  2439. if (is_file(entry) && begin_of_direntry(entry) == begin)
  2440. break;
  2441. }
  2442. if (j >= s->directory.next) {
  2443. fail = -6;
  2444. continue;
  2445. }
  2446. /* make sure there exists an initial mapping */
  2447. if (mapping && mapping->begin != begin) {
  2448. mapping->end = begin;
  2449. mapping = NULL;
  2450. }
  2451. if (mapping == NULL) {
  2452. mapping = insert_mapping(s, begin, begin+1);
  2453. }
  2454. /* most members will be fixed in commit_mappings() */
  2455. assert(commit->path);
  2456. mapping->path = commit->path;
  2457. mapping->read_only = 0;
  2458. mapping->mode = MODE_NORMAL;
  2459. mapping->info.file.offset = 0;
  2460. if (commit_one_file(s, j, 0)) {
  2461. fail = -7;
  2462. }
  2463. break;
  2464. }
  2465. default:
  2466. abort();
  2467. }
  2468. }
  2469. if (i > 0 && array_remove_slice(&(s->commits), 0, i))
  2470. return -1;
  2471. return fail;
  2472. }
  2473. static int handle_deletes(BDRVVVFATState* s)
  2474. {
  2475. int i, deferred = 1, deleted = 1;
  2476. /* delete files corresponding to mappings marked as deleted */
  2477. /* handle DELETEs and unused mappings (modified_fat_get(s, mapping->begin) == 0) */
  2478. while (deferred && deleted) {
  2479. deferred = 0;
  2480. deleted = 0;
  2481. for (i = 1; i < s->mapping.next; i++) {
  2482. mapping_t* mapping = array_get(&(s->mapping), i);
  2483. if (mapping->mode & MODE_DELETED) {
  2484. direntry_t* entry = array_get(&(s->directory),
  2485. mapping->dir_index);
  2486. if (is_free(entry)) {
  2487. /* remove file/directory */
  2488. if (mapping->mode & MODE_DIRECTORY) {
  2489. int j, next_dir_index = s->directory.next,
  2490. first_dir_index = mapping->info.dir.first_dir_index;
  2491. if (rmdir(mapping->path) < 0) {
  2492. if (errno == ENOTEMPTY) {
  2493. deferred++;
  2494. continue;
  2495. } else
  2496. return -5;
  2497. }
  2498. for (j = 1; j < s->mapping.next; j++) {
  2499. mapping_t* m = array_get(&(s->mapping), j);
  2500. if (m->mode & MODE_DIRECTORY &&
  2501. m->info.dir.first_dir_index >
  2502. first_dir_index &&
  2503. m->info.dir.first_dir_index <
  2504. next_dir_index)
  2505. next_dir_index =
  2506. m->info.dir.first_dir_index;
  2507. }
  2508. remove_direntries(s, first_dir_index,
  2509. next_dir_index - first_dir_index);
  2510. deleted++;
  2511. }
  2512. } else {
  2513. if (unlink(mapping->path))
  2514. return -4;
  2515. deleted++;
  2516. }
  2517. DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(mapping); print_direntry(entry));
  2518. remove_mapping(s, i);
  2519. }
  2520. }
  2521. }
  2522. return 0;
  2523. }
  2524. /*
  2525. * synchronize mapping with new state:
  2526. *
  2527. * - copy FAT (with bdrv_pread)
  2528. * - mark all filenames corresponding to mappings as deleted
  2529. * - recurse direntries from root (using bs->bdrv_pread)
  2530. * - delete files corresponding to mappings marked as deleted
  2531. */
  2532. static int coroutine_fn GRAPH_RDLOCK do_commit(BDRVVVFATState* s)
  2533. {
  2534. int ret = 0;
  2535. /* the real meat are the commits. Nothing to do? Move along! */
  2536. if (s->commits.next == 0)
  2537. return 0;
  2538. vvfat_close_current_file(s);
  2539. ret = handle_renames_and_mkdirs(s);
  2540. if (ret) {
  2541. fprintf(stderr, "Error handling renames (%d)\n", ret);
  2542. abort();
  2543. return ret;
  2544. }
  2545. /* copy FAT (with bdrv_pread) */
  2546. memcpy(s->fat.pointer, s->fat2, 0x200 * s->sectors_per_fat);
  2547. /* recurse direntries from root (using bs->bdrv_pread) */
  2548. ret = commit_direntries(s, 0, -1);
  2549. if (ret) {
  2550. fprintf(stderr, "Fatal: error while committing (%d)\n", ret);
  2551. abort();
  2552. return ret;
  2553. }
  2554. ret = handle_commits(s);
  2555. if (ret) {
  2556. fprintf(stderr, "Error handling commits (%d)\n", ret);
  2557. abort();
  2558. return ret;
  2559. }
  2560. ret = handle_deletes(s);
  2561. if (ret) {
  2562. fprintf(stderr, "Error deleting\n");
  2563. abort();
  2564. return ret;
  2565. }
  2566. bdrv_make_empty(s->qcow, NULL);
  2567. memset(s->used_clusters, 0, sector2cluster(s, s->sector_count));
  2568. DLOG(checkpoint());
  2569. return 0;
  2570. }
  2571. static int coroutine_fn GRAPH_RDLOCK try_commit(BDRVVVFATState* s)
  2572. {
  2573. vvfat_close_current_file(s);
  2574. DLOG(checkpoint());
  2575. if(!is_consistent(s))
  2576. return -1;
  2577. return do_commit(s);
  2578. }
  2579. static int coroutine_fn GRAPH_RDLOCK
  2580. vvfat_write(BlockDriverState *bs, int64_t sector_num,
  2581. const uint8_t *buf, int nb_sectors)
  2582. {
  2583. BDRVVVFATState *s = bs->opaque;
  2584. int i, ret;
  2585. int first_cluster, last_cluster;
  2586. DLOG(checkpoint());
  2587. /* Check if we're operating in read-only mode */
  2588. if (s->qcow == NULL) {
  2589. return -EACCES;
  2590. }
  2591. vvfat_close_current_file(s);
  2592. if (sector_num == s->offset_to_bootsector && nb_sectors == 1) {
  2593. /*
  2594. * Write on bootsector. Allow only changing the reserved1 field,
  2595. * used to mark volume dirtiness
  2596. */
  2597. unsigned char *bootsector = s->first_sectors
  2598. + s->offset_to_bootsector * 0x200;
  2599. /*
  2600. * LATER TODO: if FAT32, this is wrong (see init_directories(),
  2601. * which always creates a FAT16 bootsector)
  2602. */
  2603. const int reserved1_offset = offsetof(bootsector_t, u.fat16.reserved1);
  2604. for (i = 0; i < 0x200; i++) {
  2605. if (i != reserved1_offset && bootsector[i] != buf[i]) {
  2606. fprintf(stderr, "Tried to write to protected bootsector\n");
  2607. return -1;
  2608. }
  2609. }
  2610. /* Update bootsector with the only updatable byte, and return success */
  2611. bootsector[reserved1_offset] = buf[reserved1_offset];
  2612. return 0;
  2613. }
  2614. /*
  2615. * Some sanity checks:
  2616. * - do not allow writing to the boot sector
  2617. */
  2618. if (sector_num < s->offset_to_fat)
  2619. return -1;
  2620. /*
  2621. * Values will be negative for writes to the FAT, which is located before
  2622. * the root directory.
  2623. */
  2624. first_cluster = sector2cluster(s, sector_num);
  2625. last_cluster = sector2cluster(s, sector_num + nb_sectors - 1);
  2626. for (i = first_cluster; i <= last_cluster;) {
  2627. mapping_t *mapping = NULL;
  2628. if (i >= 0) {
  2629. mapping = find_mapping_for_cluster(s, i);
  2630. }
  2631. if (mapping) {
  2632. if (mapping->read_only) {
  2633. fprintf(stderr, "Tried to write to write-protected file %s\n",
  2634. mapping->path);
  2635. return -1;
  2636. }
  2637. if (mapping->mode & MODE_DIRECTORY) {
  2638. int begin = cluster2sector(s, i);
  2639. int end = begin + s->sectors_per_cluster, k;
  2640. int dir_index;
  2641. const direntry_t* direntries;
  2642. long_file_name lfn;
  2643. lfn_init(&lfn);
  2644. if (begin < sector_num)
  2645. begin = sector_num;
  2646. if (end > sector_num + nb_sectors)
  2647. end = sector_num + nb_sectors;
  2648. dir_index = mapping->dir_index +
  2649. 0x10 * (begin - mapping->begin * s->sectors_per_cluster);
  2650. direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));
  2651. for (k = 0; k < (end - begin) * 0x10; k++) {
  2652. /* no access to the direntry of a read-only file */
  2653. if (is_short_name(direntries + k) &&
  2654. (direntries[k].attributes & 1)) {
  2655. if (memcmp(direntries + k,
  2656. array_get(&(s->directory), dir_index + k),
  2657. sizeof(direntry_t))) {
  2658. warn_report("tried to write to write-protected "
  2659. "file");
  2660. return -1;
  2661. }
  2662. }
  2663. }
  2664. }
  2665. i = mapping->end;
  2666. } else {
  2667. i++;
  2668. }
  2669. }
  2670. /*
  2671. * Use qcow backend. Commit later.
  2672. */
  2673. DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sectors));
  2674. ret = bdrv_co_pwrite(s->qcow, sector_num * BDRV_SECTOR_SIZE,
  2675. nb_sectors * BDRV_SECTOR_SIZE, buf, 0);
  2676. if (ret < 0) {
  2677. fprintf(stderr, "Error writing to qcow backend\n");
  2678. return ret;
  2679. }
  2680. for (i = first_cluster; i <= last_cluster; i++) {
  2681. if (i >= 0) {
  2682. s->used_clusters[i] |= USED_ALLOCATED;
  2683. }
  2684. }
  2685. DLOG(checkpoint());
  2686. /* TODO: add timeout */
  2687. try_commit(s);
  2688. DLOG(checkpoint());
  2689. return 0;
  2690. }
  2691. static int coroutine_fn GRAPH_RDLOCK
  2692. vvfat_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
  2693. QEMUIOVector *qiov, BdrvRequestFlags flags)
  2694. {
  2695. int ret;
  2696. BDRVVVFATState *s = bs->opaque;
  2697. uint64_t sector_num = offset >> BDRV_SECTOR_BITS;
  2698. int nb_sectors = bytes >> BDRV_SECTOR_BITS;
  2699. void *buf;
  2700. assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));
  2701. assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE));
  2702. buf = g_try_malloc(bytes);
  2703. if (bytes && buf == NULL) {
  2704. return -ENOMEM;
  2705. }
  2706. qemu_iovec_to_buf(qiov, 0, buf, bytes);
  2707. qemu_co_mutex_lock(&s->lock);
  2708. ret = vvfat_write(bs, sector_num, buf, nb_sectors);
  2709. qemu_co_mutex_unlock(&s->lock);
  2710. g_free(buf);
  2711. return ret;
  2712. }
  2713. static int coroutine_fn vvfat_co_block_status(BlockDriverState *bs,
  2714. bool want_zero, int64_t offset,
  2715. int64_t bytes, int64_t *n,
  2716. int64_t *map,
  2717. BlockDriverState **file)
  2718. {
  2719. *n = bytes;
  2720. return BDRV_BLOCK_DATA;
  2721. }
  2722. static void vvfat_qcow_options(BdrvChildRole role, bool parent_is_format,
  2723. int *child_flags, QDict *child_options,
  2724. int parent_flags, QDict *parent_options)
  2725. {
  2726. qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "off");
  2727. qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off");
  2728. qdict_set_default_str(child_options, BDRV_OPT_CACHE_NO_FLUSH, "on");
  2729. }
  2730. static BdrvChildClass child_vvfat_qcow;
  2731. static int enable_write_target(BlockDriverState *bs, Error **errp)
  2732. {
  2733. BDRVVVFATState *s = bs->opaque;
  2734. BlockDriver *bdrv_qcow = NULL;
  2735. QemuOpts *opts = NULL;
  2736. int ret;
  2737. int size = sector2cluster(s, s->sector_count);
  2738. QDict *options;
  2739. s->used_clusters = g_malloc0(size);
  2740. array_init(&(s->commits), sizeof(commit_t));
  2741. s->qcow_filename = create_tmp_file(errp);
  2742. if (!s->qcow_filename) {
  2743. ret = -ENOENT;
  2744. goto err;
  2745. }
  2746. bdrv_qcow = bdrv_find_format("qcow");
  2747. if (!bdrv_qcow) {
  2748. error_setg(errp, "Failed to locate qcow driver");
  2749. ret = -ENOENT;
  2750. goto err;
  2751. }
  2752. opts = qemu_opts_create(bdrv_qcow->create_opts, NULL, 0, &error_abort);
  2753. qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
  2754. bs->total_sectors * BDRV_SECTOR_SIZE, &error_abort);
  2755. qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:", &error_abort);
  2756. ret = bdrv_create(bdrv_qcow, s->qcow_filename, opts, errp);
  2757. qemu_opts_del(opts);
  2758. if (ret < 0) {
  2759. goto err;
  2760. }
  2761. options = qdict_new();
  2762. qdict_put_str(options, "write-target.driver", "qcow");
  2763. s->qcow = bdrv_open_child(s->qcow_filename, options, "write-target", bs,
  2764. &child_vvfat_qcow,
  2765. BDRV_CHILD_DATA | BDRV_CHILD_METADATA,
  2766. false, errp);
  2767. qobject_unref(options);
  2768. if (!s->qcow) {
  2769. ret = -EINVAL;
  2770. goto err;
  2771. }
  2772. #ifndef _WIN32
  2773. unlink(s->qcow_filename);
  2774. #endif
  2775. return 0;
  2776. err:
  2777. return ret;
  2778. }
  2779. static void vvfat_child_perm(BlockDriverState *bs, BdrvChild *c,
  2780. BdrvChildRole role,
  2781. BlockReopenQueue *reopen_queue,
  2782. uint64_t perm, uint64_t shared,
  2783. uint64_t *nperm, uint64_t *nshared)
  2784. {
  2785. assert(role & BDRV_CHILD_DATA);
  2786. /* This is a private node, nobody should try to attach to it */
  2787. *nperm = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE;
  2788. *nshared = BLK_PERM_WRITE_UNCHANGED;
  2789. }
  2790. static void vvfat_close(BlockDriverState *bs)
  2791. {
  2792. BDRVVVFATState *s = bs->opaque;
  2793. vvfat_close_current_file(s);
  2794. array_free(&(s->fat));
  2795. array_free(&(s->directory));
  2796. array_free(&(s->mapping));
  2797. g_free(s->cluster_buffer);
  2798. if (s->qcow) {
  2799. migrate_del_blocker(&s->migration_blocker);
  2800. }
  2801. }
  2802. static const char *const vvfat_strong_runtime_opts[] = {
  2803. "dir",
  2804. "fat-type",
  2805. "floppy",
  2806. "label",
  2807. "rw",
  2808. NULL
  2809. };
  2810. static BlockDriver bdrv_vvfat = {
  2811. .format_name = "vvfat",
  2812. .protocol_name = "fat",
  2813. .instance_size = sizeof(BDRVVVFATState),
  2814. .bdrv_parse_filename = vvfat_parse_filename,
  2815. .bdrv_open = vvfat_open,
  2816. .bdrv_refresh_limits = vvfat_refresh_limits,
  2817. .bdrv_close = vvfat_close,
  2818. .bdrv_child_perm = vvfat_child_perm,
  2819. .bdrv_co_preadv = vvfat_co_preadv,
  2820. .bdrv_co_pwritev = vvfat_co_pwritev,
  2821. .bdrv_co_block_status = vvfat_co_block_status,
  2822. .strong_runtime_opts = vvfat_strong_runtime_opts,
  2823. };
  2824. static void bdrv_vvfat_init(void)
  2825. {
  2826. child_vvfat_qcow = child_of_bds;
  2827. child_vvfat_qcow.inherit_options = vvfat_qcow_options;
  2828. bdrv_register(&bdrv_vvfat);
  2829. }
  2830. block_init(bdrv_vvfat_init);
  2831. #ifdef DEBUG
  2832. static void checkpoint(void)
  2833. {
  2834. assert(((mapping_t*)array_get(&(vvv->mapping), 0))->end == 2);
  2835. check1(vvv);
  2836. check2(vvv);
  2837. assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mapping->mode & MODE_DIRECTORY));
  2838. }
  2839. #endif