attrib.c 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716
  1. /**
  2. * attrib.c - NTFS attribute operations. Part of the Linux-NTFS project.
  3. *
  4. * Copyright (c) 2001-2005 Anton Altaparmakov
  5. * Copyright (c) 2002 Richard Russon
  6. *
  7. * This program/include file is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as published
  9. * by the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program/include file is distributed in the hope that it will be
  13. * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
  14. * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program (in the main directory of the Linux-NTFS
  19. * distribution in the file COPYING); if not, write to the Free Software
  20. * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21. */
  22. #include <linux/buffer_head.h>
  23. #include <linux/swap.h>
  24. #include "attrib.h"
  25. #include "debug.h"
  26. #include "layout.h"
  27. #include "lcnalloc.h"
  28. #include "malloc.h"
  29. #include "mft.h"
  30. #include "ntfs.h"
  31. #include "types.h"
  32. /**
  33. * ntfs_map_runlist_nolock - map (a part of) a runlist of an ntfs inode
  34. * @ni: ntfs inode for which to map (part of) a runlist
  35. * @vcn: map runlist part containing this vcn
  36. *
  37. * Map the part of a runlist containing the @vcn of the ntfs inode @ni.
  38. *
  39. * Return 0 on success and -errno on error. There is one special error code
  40. * which is not an error as such. This is -ENOENT. It means that @vcn is out
  41. * of bounds of the runlist.
  42. *
  43. * Locking: - The runlist must be locked for writing.
  44. * - This function modifies the runlist.
  45. */
  46. int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
  47. {
  48. VCN end_vcn;
  49. ntfs_inode *base_ni;
  50. MFT_RECORD *m;
  51. ATTR_RECORD *a;
  52. ntfs_attr_search_ctx *ctx;
  53. runlist_element *rl;
  54. int err = 0;
  55. ntfs_debug("Mapping runlist part containing vcn 0x%llx.",
  56. (unsigned long long)vcn);
  57. if (!NInoAttr(ni))
  58. base_ni = ni;
  59. else
  60. base_ni = ni->ext.base_ntfs_ino;
  61. m = map_mft_record(base_ni);
  62. if (IS_ERR(m))
  63. return PTR_ERR(m);
  64. ctx = ntfs_attr_get_search_ctx(base_ni, m);
  65. if (unlikely(!ctx)) {
  66. err = -ENOMEM;
  67. goto err_out;
  68. }
  69. err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
  70. CASE_SENSITIVE, vcn, NULL, 0, ctx);
  71. if (unlikely(err)) {
  72. if (err == -ENOENT)
  73. err = -EIO;
  74. goto err_out;
  75. }
  76. a = ctx->attr;
  77. /*
  78. * Only decompress the mapping pairs if @vcn is inside it. Otherwise
  79. * we get into problems when we try to map an out of bounds vcn because
  80. * we then try to map the already mapped runlist fragment and
  81. * ntfs_mapping_pairs_decompress() fails.
  82. */
  83. end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn) + 1;
  84. if (unlikely(!a->data.non_resident.lowest_vcn && end_vcn <= 1))
  85. end_vcn = ni->allocated_size >> ni->vol->cluster_size_bits;
  86. if (unlikely(vcn >= end_vcn)) {
  87. err = -ENOENT;
  88. goto err_out;
  89. }
  90. rl = ntfs_mapping_pairs_decompress(ni->vol, a, ni->runlist.rl);
  91. if (IS_ERR(rl))
  92. err = PTR_ERR(rl);
  93. else
  94. ni->runlist.rl = rl;
  95. err_out:
  96. if (likely(ctx))
  97. ntfs_attr_put_search_ctx(ctx);
  98. unmap_mft_record(base_ni);
  99. return err;
  100. }
  101. /**
  102. * ntfs_map_runlist - map (a part of) a runlist of an ntfs inode
  103. * @ni: ntfs inode for which to map (part of) a runlist
  104. * @vcn: map runlist part containing this vcn
  105. *
  106. * Map the part of a runlist containing the @vcn of the ntfs inode @ni.
  107. *
  108. * Return 0 on success and -errno on error. There is one special error code
  109. * which is not an error as such. This is -ENOENT. It means that @vcn is out
  110. * of bounds of the runlist.
  111. *
  112. * Locking: - The runlist must be unlocked on entry and is unlocked on return.
  113. * - This function takes the runlist lock for writing and modifies the
  114. * runlist.
  115. */
  116. int ntfs_map_runlist(ntfs_inode *ni, VCN vcn)
  117. {
  118. int err = 0;
  119. down_write(&ni->runlist.lock);
  120. /* Make sure someone else didn't do the work while we were sleeping. */
  121. if (likely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) <=
  122. LCN_RL_NOT_MAPPED))
  123. err = ntfs_map_runlist_nolock(ni, vcn);
  124. up_write(&ni->runlist.lock);
  125. return err;
  126. }
  127. /**
  128. * ntfs_attr_vcn_to_lcn_nolock - convert a vcn into a lcn given an ntfs inode
  129. * @ni: ntfs inode of the attribute whose runlist to search
  130. * @vcn: vcn to convert
  131. * @write_locked: true if the runlist is locked for writing
  132. *
  133. * Find the virtual cluster number @vcn in the runlist of the ntfs attribute
  134. * described by the ntfs inode @ni and return the corresponding logical cluster
  135. * number (lcn).
  136. *
  137. * If the @vcn is not mapped yet, the attempt is made to map the attribute
  138. * extent containing the @vcn and the vcn to lcn conversion is retried.
  139. *
  140. * If @write_locked is true the caller has locked the runlist for writing and
  141. * if false for reading.
  142. *
  143. * Since lcns must be >= 0, we use negative return codes with special meaning:
  144. *
  145. * Return code Meaning / Description
  146. * ==========================================
  147. * LCN_HOLE Hole / not allocated on disk.
  148. * LCN_ENOENT There is no such vcn in the runlist, i.e. @vcn is out of bounds.
  149. * LCN_ENOMEM Not enough memory to map runlist.
  150. * LCN_EIO Critical error (runlist/file is corrupt, i/o error, etc).
  151. *
  152. * Locking: - The runlist must be locked on entry and is left locked on return.
  153. * - If @write_locked is FALSE, i.e. the runlist is locked for reading,
  154. * the lock may be dropped inside the function so you cannot rely on
  155. * the runlist still being the same when this function returns.
  156. */
  157. LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn,
  158. const BOOL write_locked)
  159. {
  160. LCN lcn;
  161. BOOL is_retry = FALSE;
  162. ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",
  163. ni->mft_no, (unsigned long long)vcn,
  164. write_locked ? "write" : "read");
  165. BUG_ON(!ni);
  166. BUG_ON(!NInoNonResident(ni));
  167. BUG_ON(vcn < 0);
  168. retry_remap:
  169. /* Convert vcn to lcn. If that fails map the runlist and retry once. */
  170. lcn = ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn);
  171. if (likely(lcn >= LCN_HOLE)) {
  172. ntfs_debug("Done, lcn 0x%llx.", (long long)lcn);
  173. return lcn;
  174. }
  175. if (lcn != LCN_RL_NOT_MAPPED) {
  176. if (lcn != LCN_ENOENT)
  177. lcn = LCN_EIO;
  178. } else if (!is_retry) {
  179. int err;
  180. if (!write_locked) {
  181. up_read(&ni->runlist.lock);
  182. down_write(&ni->runlist.lock);
  183. if (unlikely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) !=
  184. LCN_RL_NOT_MAPPED)) {
  185. up_write(&ni->runlist.lock);
  186. down_read(&ni->runlist.lock);
  187. goto retry_remap;
  188. }
  189. }
  190. err = ntfs_map_runlist_nolock(ni, vcn);
  191. if (!write_locked) {
  192. up_write(&ni->runlist.lock);
  193. down_read(&ni->runlist.lock);
  194. }
  195. if (likely(!err)) {
  196. is_retry = TRUE;
  197. goto retry_remap;
  198. }
  199. if (err == -ENOENT)
  200. lcn = LCN_ENOENT;
  201. else if (err == -ENOMEM)
  202. lcn = LCN_ENOMEM;
  203. else
  204. lcn = LCN_EIO;
  205. }
  206. if (lcn != LCN_ENOENT)
  207. ntfs_error(ni->vol->sb, "Failed with error code %lli.",
  208. (long long)lcn);
  209. return lcn;
  210. }
  211. /**
  212. * ntfs_attr_find_vcn_nolock - find a vcn in the runlist of an ntfs inode
  213. * @ni: ntfs inode describing the runlist to search
  214. * @vcn: vcn to find
  215. * @write_locked: true if the runlist is locked for writing
  216. *
  217. * Find the virtual cluster number @vcn in the runlist described by the ntfs
  218. * inode @ni and return the address of the runlist element containing the @vcn.
  219. *
  220. * If the @vcn is not mapped yet, the attempt is made to map the attribute
  221. * extent containing the @vcn and the vcn to lcn conversion is retried.
  222. *
  223. * If @write_locked is true the caller has locked the runlist for writing and
  224. * if false for reading.
  225. *
  226. * Note you need to distinguish between the lcn of the returned runlist element
  227. * being >= 0 and LCN_HOLE. In the later case you have to return zeroes on
  228. * read and allocate clusters on write.
  229. *
  230. * Return the runlist element containing the @vcn on success and
  231. * ERR_PTR(-errno) on error. You need to test the return value with IS_ERR()
  232. * to decide if the return is success or failure and PTR_ERR() to get to the
  233. * error code if IS_ERR() is true.
  234. *
  235. * The possible error return codes are:
  236. * -ENOENT - No such vcn in the runlist, i.e. @vcn is out of bounds.
  237. * -ENOMEM - Not enough memory to map runlist.
  238. * -EIO - Critical error (runlist/file is corrupt, i/o error, etc).
  239. *
  240. * Locking: - The runlist must be locked on entry and is left locked on return.
  241. * - If @write_locked is FALSE, i.e. the runlist is locked for reading,
  242. * the lock may be dropped inside the function so you cannot rely on
  243. * the runlist still being the same when this function returns.
  244. */
  245. runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn,
  246. const BOOL write_locked)
  247. {
  248. runlist_element *rl;
  249. int err = 0;
  250. BOOL is_retry = FALSE;
  251. ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",
  252. ni->mft_no, (unsigned long long)vcn,
  253. write_locked ? "write" : "read");
  254. BUG_ON(!ni);
  255. BUG_ON(!NInoNonResident(ni));
  256. BUG_ON(vcn < 0);
  257. retry_remap:
  258. rl = ni->runlist.rl;
  259. if (likely(rl && vcn >= rl[0].vcn)) {
  260. while (likely(rl->length)) {
  261. if (unlikely(vcn < rl[1].vcn)) {
  262. if (likely(rl->lcn >= LCN_HOLE)) {
  263. ntfs_debug("Done.");
  264. return rl;
  265. }
  266. break;
  267. }
  268. rl++;
  269. }
  270. if (likely(rl->lcn != LCN_RL_NOT_MAPPED)) {
  271. if (likely(rl->lcn == LCN_ENOENT))
  272. err = -ENOENT;
  273. else
  274. err = -EIO;
  275. }
  276. }
  277. if (!err && !is_retry) {
  278. /*
  279. * The @vcn is in an unmapped region, map the runlist and
  280. * retry.
  281. */
  282. if (!write_locked) {
  283. up_read(&ni->runlist.lock);
  284. down_write(&ni->runlist.lock);
  285. if (unlikely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) !=
  286. LCN_RL_NOT_MAPPED)) {
  287. up_write(&ni->runlist.lock);
  288. down_read(&ni->runlist.lock);
  289. goto retry_remap;
  290. }
  291. }
  292. err = ntfs_map_runlist_nolock(ni, vcn);
  293. if (!write_locked) {
  294. up_write(&ni->runlist.lock);
  295. down_read(&ni->runlist.lock);
  296. }
  297. if (likely(!err)) {
  298. is_retry = TRUE;
  299. goto retry_remap;
  300. }
  301. /*
  302. * -EINVAL coming from a failed mapping attempt is equivalent
  303. * to i/o error for us as it should not happen in our code
  304. * paths.
  305. */
  306. if (err == -EINVAL)
  307. err = -EIO;
  308. } else if (!err)
  309. err = -EIO;
  310. if (err != -ENOENT)
  311. ntfs_error(ni->vol->sb, "Failed with error code %i.", err);
  312. return ERR_PTR(err);
  313. }
  314. /**
  315. * ntfs_attr_find - find (next) attribute in mft record
  316. * @type: attribute type to find
  317. * @name: attribute name to find (optional, i.e. NULL means don't care)
  318. * @name_len: attribute name length (only needed if @name present)
  319. * @ic: IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
  320. * @val: attribute value to find (optional, resident attributes only)
  321. * @val_len: attribute value length
  322. * @ctx: search context with mft record and attribute to search from
  323. *
  324. * You should not need to call this function directly. Use ntfs_attr_lookup()
  325. * instead.
  326. *
  327. * ntfs_attr_find() takes a search context @ctx as parameter and searches the
  328. * mft record specified by @ctx->mrec, beginning at @ctx->attr, for an
  329. * attribute of @type, optionally @name and @val.
  330. *
  331. * If the attribute is found, ntfs_attr_find() returns 0 and @ctx->attr will
  332. * point to the found attribute.
  333. *
  334. * If the attribute is not found, ntfs_attr_find() returns -ENOENT and
  335. * @ctx->attr will point to the attribute before which the attribute being
  336. * searched for would need to be inserted if such an action were to be desired.
  337. *
  338. * On actual error, ntfs_attr_find() returns -EIO. In this case @ctx->attr is
  339. * undefined and in particular do not rely on it not changing.
  340. *
  341. * If @ctx->is_first is TRUE, the search begins with @ctx->attr itself. If it
  342. * is FALSE, the search begins after @ctx->attr.
  343. *
  344. * If @ic is IGNORE_CASE, the @name comparisson is not case sensitive and
  345. * @ctx->ntfs_ino must be set to the ntfs inode to which the mft record
  346. * @ctx->mrec belongs. This is so we can get at the ntfs volume and hence at
  347. * the upcase table. If @ic is CASE_SENSITIVE, the comparison is case
  348. * sensitive. When @name is present, @name_len is the @name length in Unicode
  349. * characters.
  350. *
  351. * If @name is not present (NULL), we assume that the unnamed attribute is
  352. * being searched for.
  353. *
  354. * Finally, the resident attribute value @val is looked for, if present. If
  355. * @val is not present (NULL), @val_len is ignored.
  356. *
  357. * ntfs_attr_find() only searches the specified mft record and it ignores the
  358. * presence of an attribute list attribute (unless it is the one being searched
  359. * for, obviously). If you need to take attribute lists into consideration,
  360. * use ntfs_attr_lookup() instead (see below). This also means that you cannot
  361. * use ntfs_attr_find() to search for extent records of non-resident
  362. * attributes, as extents with lowest_vcn != 0 are usually described by the
  363. * attribute list attribute only. - Note that it is possible that the first
  364. * extent is only in the attribute list while the last extent is in the base
  365. * mft record, so do not rely on being able to find the first extent in the
  366. * base mft record.
  367. *
  368. * Warning: Never use @val when looking for attribute types which can be
  369. * non-resident as this most likely will result in a crash!
  370. */
  371. static int ntfs_attr_find(const ATTR_TYPE type, const ntfschar *name,
  372. const u32 name_len, const IGNORE_CASE_BOOL ic,
  373. const u8 *val, const u32 val_len, ntfs_attr_search_ctx *ctx)
  374. {
  375. ATTR_RECORD *a;
  376. ntfs_volume *vol = ctx->ntfs_ino->vol;
  377. ntfschar *upcase = vol->upcase;
  378. u32 upcase_len = vol->upcase_len;
  379. /*
  380. * Iterate over attributes in mft record starting at @ctx->attr, or the
  381. * attribute following that, if @ctx->is_first is TRUE.
  382. */
  383. if (ctx->is_first) {
  384. a = ctx->attr;
  385. ctx->is_first = FALSE;
  386. } else
  387. a = (ATTR_RECORD*)((u8*)ctx->attr +
  388. le32_to_cpu(ctx->attr->length));
  389. for (;; a = (ATTR_RECORD*)((u8*)a + le32_to_cpu(a->length))) {
  390. if ((u8*)a < (u8*)ctx->mrec || (u8*)a > (u8*)ctx->mrec +
  391. le32_to_cpu(ctx->mrec->bytes_allocated))
  392. break;
  393. ctx->attr = a;
  394. if (unlikely(le32_to_cpu(a->type) > le32_to_cpu(type) ||
  395. a->type == AT_END))
  396. return -ENOENT;
  397. if (unlikely(!a->length))
  398. break;
  399. if (a->type != type)
  400. continue;
  401. /*
  402. * If @name is present, compare the two names. If @name is
  403. * missing, assume we want an unnamed attribute.
  404. */
  405. if (!name) {
  406. /* The search failed if the found attribute is named. */
  407. if (a->name_length)
  408. return -ENOENT;
  409. } else if (!ntfs_are_names_equal(name, name_len,
  410. (ntfschar*)((u8*)a + le16_to_cpu(a->name_offset)),
  411. a->name_length, ic, upcase, upcase_len)) {
  412. register int rc;
  413. rc = ntfs_collate_names(name, name_len,
  414. (ntfschar*)((u8*)a +
  415. le16_to_cpu(a->name_offset)),
  416. a->name_length, 1, IGNORE_CASE,
  417. upcase, upcase_len);
  418. /*
  419. * If @name collates before a->name, there is no
  420. * matching attribute.
  421. */
  422. if (rc == -1)
  423. return -ENOENT;
  424. /* If the strings are not equal, continue search. */
  425. if (rc)
  426. continue;
  427. rc = ntfs_collate_names(name, name_len,
  428. (ntfschar*)((u8*)a +
  429. le16_to_cpu(a->name_offset)),
  430. a->name_length, 1, CASE_SENSITIVE,
  431. upcase, upcase_len);
  432. if (rc == -1)
  433. return -ENOENT;
  434. if (rc)
  435. continue;
  436. }
  437. /*
  438. * The names match or @name not present and attribute is
  439. * unnamed. If no @val specified, we have found the attribute
  440. * and are done.
  441. */
  442. if (!val)
  443. return 0;
  444. /* @val is present; compare values. */
  445. else {
  446. register int rc;
  447. rc = memcmp(val, (u8*)a + le16_to_cpu(
  448. a->data.resident.value_offset),
  449. min_t(u32, val_len, le32_to_cpu(
  450. a->data.resident.value_length)));
  451. /*
  452. * If @val collates before the current attribute's
  453. * value, there is no matching attribute.
  454. */
  455. if (!rc) {
  456. register u32 avl;
  457. avl = le32_to_cpu(
  458. a->data.resident.value_length);
  459. if (val_len == avl)
  460. return 0;
  461. if (val_len < avl)
  462. return -ENOENT;
  463. } else if (rc < 0)
  464. return -ENOENT;
  465. }
  466. }
  467. ntfs_error(vol->sb, "Inode is corrupt. Run chkdsk.");
  468. NVolSetErrors(vol);
  469. return -EIO;
  470. }
  471. /**
  472. * load_attribute_list - load an attribute list into memory
  473. * @vol: ntfs volume from which to read
  474. * @runlist: runlist of the attribute list
  475. * @al_start: destination buffer
  476. * @size: size of the destination buffer in bytes
  477. * @initialized_size: initialized size of the attribute list
  478. *
  479. * Walk the runlist @runlist and load all clusters from it copying them into
  480. * the linear buffer @al. The maximum number of bytes copied to @al is @size
  481. * bytes. Note, @size does not need to be a multiple of the cluster size. If
  482. * @initialized_size is less than @size, the region in @al between
  483. * @initialized_size and @size will be zeroed and not read from disk.
  484. *
  485. * Return 0 on success or -errno on error.
  486. */
  487. int load_attribute_list(ntfs_volume *vol, runlist *runlist, u8 *al_start,
  488. const s64 size, const s64 initialized_size)
  489. {
  490. LCN lcn;
  491. u8 *al = al_start;
  492. u8 *al_end = al + initialized_size;
  493. runlist_element *rl;
  494. struct buffer_head *bh;
  495. struct super_block *sb;
  496. unsigned long block_size;
  497. unsigned long block, max_block;
  498. int err = 0;
  499. unsigned char block_size_bits;
  500. ntfs_debug("Entering.");
  501. if (!vol || !runlist || !al || size <= 0 || initialized_size < 0 ||
  502. initialized_size > size)
  503. return -EINVAL;
  504. if (!initialized_size) {
  505. memset(al, 0, size);
  506. return 0;
  507. }
  508. sb = vol->sb;
  509. block_size = sb->s_blocksize;
  510. block_size_bits = sb->s_blocksize_bits;
  511. down_read(&runlist->lock);
  512. rl = runlist->rl;
  513. /* Read all clusters specified by the runlist one run at a time. */
  514. while (rl->length) {
  515. lcn = ntfs_rl_vcn_to_lcn(rl, rl->vcn);
  516. ntfs_debug("Reading vcn = 0x%llx, lcn = 0x%llx.",
  517. (unsigned long long)rl->vcn,
  518. (unsigned long long)lcn);
  519. /* The attribute list cannot be sparse. */
  520. if (lcn < 0) {
  521. ntfs_error(sb, "ntfs_rl_vcn_to_lcn() failed. Cannot "
  522. "read attribute list.");
  523. goto err_out;
  524. }
  525. block = lcn << vol->cluster_size_bits >> block_size_bits;
  526. /* Read the run from device in chunks of block_size bytes. */
  527. max_block = block + (rl->length << vol->cluster_size_bits >>
  528. block_size_bits);
  529. ntfs_debug("max_block = 0x%lx.", max_block);
  530. do {
  531. ntfs_debug("Reading block = 0x%lx.", block);
  532. bh = sb_bread(sb, block);
  533. if (!bh) {
  534. ntfs_error(sb, "sb_bread() failed. Cannot "
  535. "read attribute list.");
  536. goto err_out;
  537. }
  538. if (al + block_size >= al_end)
  539. goto do_final;
  540. memcpy(al, bh->b_data, block_size);
  541. brelse(bh);
  542. al += block_size;
  543. } while (++block < max_block);
  544. rl++;
  545. }
  546. if (initialized_size < size) {
  547. initialize:
  548. memset(al_start + initialized_size, 0, size - initialized_size);
  549. }
  550. done:
  551. up_read(&runlist->lock);
  552. return err;
  553. do_final:
  554. if (al < al_end) {
  555. /*
  556. * Partial block.
  557. *
  558. * Note: The attribute list can be smaller than its allocation
  559. * by multiple clusters. This has been encountered by at least
  560. * two people running Windows XP, thus we cannot do any
  561. * truncation sanity checking here. (AIA)
  562. */
  563. memcpy(al, bh->b_data, al_end - al);
  564. brelse(bh);
  565. if (initialized_size < size)
  566. goto initialize;
  567. goto done;
  568. }
  569. brelse(bh);
  570. /* Real overflow! */
  571. ntfs_error(sb, "Attribute list buffer overflow. Read attribute list "
  572. "is truncated.");
  573. err_out:
  574. err = -EIO;
  575. goto done;
  576. }
  577. /**
  578. * ntfs_external_attr_find - find an attribute in the attribute list of an inode
  579. * @type: attribute type to find
  580. * @name: attribute name to find (optional, i.e. NULL means don't care)
  581. * @name_len: attribute name length (only needed if @name present)
  582. * @ic: IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
  583. * @lowest_vcn: lowest vcn to find (optional, non-resident attributes only)
  584. * @val: attribute value to find (optional, resident attributes only)
  585. * @val_len: attribute value length
  586. * @ctx: search context with mft record and attribute to search from
  587. *
  588. * You should not need to call this function directly. Use ntfs_attr_lookup()
  589. * instead.
  590. *
  591. * Find an attribute by searching the attribute list for the corresponding
  592. * attribute list entry. Having found the entry, map the mft record if the
  593. * attribute is in a different mft record/inode, ntfs_attr_find() the attribute
  594. * in there and return it.
  595. *
  596. * On first search @ctx->ntfs_ino must be the base mft record and @ctx must
  597. * have been obtained from a call to ntfs_attr_get_search_ctx(). On subsequent
  598. * calls @ctx->ntfs_ino can be any extent inode, too (@ctx->base_ntfs_ino is
  599. * then the base inode).
  600. *
  601. * After finishing with the attribute/mft record you need to call
  602. * ntfs_attr_put_search_ctx() to cleanup the search context (unmapping any
  603. * mapped inodes, etc).
  604. *
  605. * If the attribute is found, ntfs_external_attr_find() returns 0 and
  606. * @ctx->attr will point to the found attribute. @ctx->mrec will point to the
  607. * mft record in which @ctx->attr is located and @ctx->al_entry will point to
  608. * the attribute list entry for the attribute.
  609. *
  610. * If the attribute is not found, ntfs_external_attr_find() returns -ENOENT and
  611. * @ctx->attr will point to the attribute in the base mft record before which
  612. * the attribute being searched for would need to be inserted if such an action
  613. * were to be desired. @ctx->mrec will point to the mft record in which
  614. * @ctx->attr is located and @ctx->al_entry will point to the attribute list
  615. * entry of the attribute before which the attribute being searched for would
  616. * need to be inserted if such an action were to be desired.
  617. *
  618. * Thus to insert the not found attribute, one wants to add the attribute to
  619. * @ctx->mrec (the base mft record) and if there is not enough space, the
  620. * attribute should be placed in a newly allocated extent mft record. The
  621. * attribute list entry for the inserted attribute should be inserted in the
  622. * attribute list attribute at @ctx->al_entry.
  623. *
  624. * On actual error, ntfs_external_attr_find() returns -EIO. In this case
  625. * @ctx->attr is undefined and in particular do not rely on it not changing.
  626. */
  627. static int ntfs_external_attr_find(const ATTR_TYPE type,
  628. const ntfschar *name, const u32 name_len,
  629. const IGNORE_CASE_BOOL ic, const VCN lowest_vcn,
  630. const u8 *val, const u32 val_len, ntfs_attr_search_ctx *ctx)
  631. {
  632. ntfs_inode *base_ni, *ni;
  633. ntfs_volume *vol;
  634. ATTR_LIST_ENTRY *al_entry, *next_al_entry;
  635. u8 *al_start, *al_end;
  636. ATTR_RECORD *a;
  637. ntfschar *al_name;
  638. u32 al_name_len;
  639. int err = 0;
  640. static const char *es = " Unmount and run chkdsk.";
  641. ni = ctx->ntfs_ino;
  642. base_ni = ctx->base_ntfs_ino;
  643. ntfs_debug("Entering for inode 0x%lx, type 0x%x.", ni->mft_no, type);
  644. if (!base_ni) {
  645. /* First call happens with the base mft record. */
  646. base_ni = ctx->base_ntfs_ino = ctx->ntfs_ino;
  647. ctx->base_mrec = ctx->mrec;
  648. }
  649. if (ni == base_ni)
  650. ctx->base_attr = ctx->attr;
  651. if (type == AT_END)
  652. goto not_found;
  653. vol = base_ni->vol;
  654. al_start = base_ni->attr_list;
  655. al_end = al_start + base_ni->attr_list_size;
  656. if (!ctx->al_entry)
  657. ctx->al_entry = (ATTR_LIST_ENTRY*)al_start;
  658. /*
  659. * Iterate over entries in attribute list starting at @ctx->al_entry,
  660. * or the entry following that, if @ctx->is_first is TRUE.
  661. */
  662. if (ctx->is_first) {
  663. al_entry = ctx->al_entry;
  664. ctx->is_first = FALSE;
  665. } else
  666. al_entry = (ATTR_LIST_ENTRY*)((u8*)ctx->al_entry +
  667. le16_to_cpu(ctx->al_entry->length));
  668. for (;; al_entry = next_al_entry) {
  669. /* Out of bounds check. */
  670. if ((u8*)al_entry < base_ni->attr_list ||
  671. (u8*)al_entry > al_end)
  672. break; /* Inode is corrupt. */
  673. ctx->al_entry = al_entry;
  674. /* Catch the end of the attribute list. */
  675. if ((u8*)al_entry == al_end)
  676. goto not_found;
  677. if (!al_entry->length)
  678. break;
  679. if ((u8*)al_entry + 6 > al_end || (u8*)al_entry +
  680. le16_to_cpu(al_entry->length) > al_end)
  681. break;
  682. next_al_entry = (ATTR_LIST_ENTRY*)((u8*)al_entry +
  683. le16_to_cpu(al_entry->length));
  684. if (le32_to_cpu(al_entry->type) > le32_to_cpu(type))
  685. goto not_found;
  686. if (type != al_entry->type)
  687. continue;
  688. /*
  689. * If @name is present, compare the two names. If @name is
  690. * missing, assume we want an unnamed attribute.
  691. */
  692. al_name_len = al_entry->name_length;
  693. al_name = (ntfschar*)((u8*)al_entry + al_entry->name_offset);
  694. if (!name) {
  695. if (al_name_len)
  696. goto not_found;
  697. } else if (!ntfs_are_names_equal(al_name, al_name_len, name,
  698. name_len, ic, vol->upcase, vol->upcase_len)) {
  699. register int rc;
  700. rc = ntfs_collate_names(name, name_len, al_name,
  701. al_name_len, 1, IGNORE_CASE,
  702. vol->upcase, vol->upcase_len);
  703. /*
  704. * If @name collates before al_name, there is no
  705. * matching attribute.
  706. */
  707. if (rc == -1)
  708. goto not_found;
  709. /* If the strings are not equal, continue search. */
  710. if (rc)
  711. continue;
  712. /*
  713. * FIXME: Reverse engineering showed 0, IGNORE_CASE but
  714. * that is inconsistent with ntfs_attr_find(). The
  715. * subsequent rc checks were also different. Perhaps I
  716. * made a mistake in one of the two. Need to recheck
  717. * which is correct or at least see what is going on...
  718. * (AIA)
  719. */
  720. rc = ntfs_collate_names(name, name_len, al_name,
  721. al_name_len, 1, CASE_SENSITIVE,
  722. vol->upcase, vol->upcase_len);
  723. if (rc == -1)
  724. goto not_found;
  725. if (rc)
  726. continue;
  727. }
  728. /*
  729. * The names match or @name not present and attribute is
  730. * unnamed. Now check @lowest_vcn. Continue search if the
  731. * next attribute list entry still fits @lowest_vcn. Otherwise
  732. * we have reached the right one or the search has failed.
  733. */
  734. if (lowest_vcn && (u8*)next_al_entry >= al_start &&
  735. (u8*)next_al_entry + 6 < al_end &&
  736. (u8*)next_al_entry + le16_to_cpu(
  737. next_al_entry->length) <= al_end &&
  738. sle64_to_cpu(next_al_entry->lowest_vcn) <=
  739. lowest_vcn &&
  740. next_al_entry->type == al_entry->type &&
  741. next_al_entry->name_length == al_name_len &&
  742. ntfs_are_names_equal((ntfschar*)((u8*)
  743. next_al_entry +
  744. next_al_entry->name_offset),
  745. next_al_entry->name_length,
  746. al_name, al_name_len, CASE_SENSITIVE,
  747. vol->upcase, vol->upcase_len))
  748. continue;
  749. if (MREF_LE(al_entry->mft_reference) == ni->mft_no) {
  750. if (MSEQNO_LE(al_entry->mft_reference) != ni->seq_no) {
  751. ntfs_error(vol->sb, "Found stale mft "
  752. "reference in attribute list "
  753. "of base inode 0x%lx.%s",
  754. base_ni->mft_no, es);
  755. err = -EIO;
  756. break;
  757. }
  758. } else { /* Mft references do not match. */
  759. /* If there is a mapped record unmap it first. */
  760. if (ni != base_ni)
  761. unmap_extent_mft_record(ni);
  762. /* Do we want the base record back? */
  763. if (MREF_LE(al_entry->mft_reference) ==
  764. base_ni->mft_no) {
  765. ni = ctx->ntfs_ino = base_ni;
  766. ctx->mrec = ctx->base_mrec;
  767. } else {
  768. /* We want an extent record. */
  769. ctx->mrec = map_extent_mft_record(base_ni,
  770. le64_to_cpu(
  771. al_entry->mft_reference), &ni);
  772. if (IS_ERR(ctx->mrec)) {
  773. ntfs_error(vol->sb, "Failed to map "
  774. "extent mft record "
  775. "0x%lx of base inode "
  776. "0x%lx.%s",
  777. MREF_LE(al_entry->
  778. mft_reference),
  779. base_ni->mft_no, es);
  780. err = PTR_ERR(ctx->mrec);
  781. if (err == -ENOENT)
  782. err = -EIO;
  783. /* Cause @ctx to be sanitized below. */
  784. ni = NULL;
  785. break;
  786. }
  787. ctx->ntfs_ino = ni;
  788. }
  789. ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec +
  790. le16_to_cpu(ctx->mrec->attrs_offset));
  791. }
  792. /*
  793. * ctx->vfs_ino, ctx->mrec, and ctx->attr now point to the
  794. * mft record containing the attribute represented by the
  795. * current al_entry.
  796. */
  797. /*
  798. * We could call into ntfs_attr_find() to find the right
  799. * attribute in this mft record but this would be less
  800. * efficient and not quite accurate as ntfs_attr_find() ignores
  801. * the attribute instance numbers for example which become
  802. * important when one plays with attribute lists. Also,
  803. * because a proper match has been found in the attribute list
  804. * entry above, the comparison can now be optimized. So it is
  805. * worth re-implementing a simplified ntfs_attr_find() here.
  806. */
  807. a = ctx->attr;
  808. /*
  809. * Use a manual loop so we can still use break and continue
  810. * with the same meanings as above.
  811. */
  812. do_next_attr_loop:
  813. if ((u8*)a < (u8*)ctx->mrec || (u8*)a > (u8*)ctx->mrec +
  814. le32_to_cpu(ctx->mrec->bytes_allocated))
  815. break;
  816. if (a->type == AT_END)
  817. continue;
  818. if (!a->length)
  819. break;
  820. if (al_entry->instance != a->instance)
  821. goto do_next_attr;
  822. /*
  823. * If the type and/or the name are mismatched between the
  824. * attribute list entry and the attribute record, there is
  825. * corruption so we break and return error EIO.
  826. */
  827. if (al_entry->type != a->type)
  828. break;
  829. if (!ntfs_are_names_equal((ntfschar*)((u8*)a +
  830. le16_to_cpu(a->name_offset)), a->name_length,
  831. al_name, al_name_len, CASE_SENSITIVE,
  832. vol->upcase, vol->upcase_len))
  833. break;
  834. ctx->attr = a;
  835. /*
  836. * If no @val specified or @val specified and it matches, we
  837. * have found it!
  838. */
  839. if (!val || (!a->non_resident && le32_to_cpu(
  840. a->data.resident.value_length) == val_len &&
  841. !memcmp((u8*)a +
  842. le16_to_cpu(a->data.resident.value_offset),
  843. val, val_len))) {
  844. ntfs_debug("Done, found.");
  845. return 0;
  846. }
  847. do_next_attr:
  848. /* Proceed to the next attribute in the current mft record. */
  849. a = (ATTR_RECORD*)((u8*)a + le32_to_cpu(a->length));
  850. goto do_next_attr_loop;
  851. }
  852. if (!err) {
  853. ntfs_error(vol->sb, "Base inode 0x%lx contains corrupt "
  854. "attribute list attribute.%s", base_ni->mft_no,
  855. es);
  856. err = -EIO;
  857. }
  858. if (ni != base_ni) {
  859. if (ni)
  860. unmap_extent_mft_record(ni);
  861. ctx->ntfs_ino = base_ni;
  862. ctx->mrec = ctx->base_mrec;
  863. ctx->attr = ctx->base_attr;
  864. }
  865. if (err != -ENOMEM)
  866. NVolSetErrors(vol);
  867. return err;
  868. not_found:
  869. /*
  870. * If we were looking for AT_END, we reset the search context @ctx and
  871. * use ntfs_attr_find() to seek to the end of the base mft record.
  872. */
  873. if (type == AT_END) {
  874. ntfs_attr_reinit_search_ctx(ctx);
  875. return ntfs_attr_find(AT_END, name, name_len, ic, val, val_len,
  876. ctx);
  877. }
  878. /*
  879. * The attribute was not found. Before we return, we want to ensure
  880. * @ctx->mrec and @ctx->attr indicate the position at which the
  881. * attribute should be inserted in the base mft record. Since we also
  882. * want to preserve @ctx->al_entry we cannot reinitialize the search
  883. * context using ntfs_attr_reinit_search_ctx() as this would set
  884. * @ctx->al_entry to NULL. Thus we do the necessary bits manually (see
  885. * ntfs_attr_init_search_ctx() below). Note, we _only_ preserve
  886. * @ctx->al_entry as the remaining fields (base_*) are identical to
  887. * their non base_ counterparts and we cannot set @ctx->base_attr
  888. * correctly yet as we do not know what @ctx->attr will be set to by
  889. * the call to ntfs_attr_find() below.
  890. */
  891. if (ni != base_ni)
  892. unmap_extent_mft_record(ni);
  893. ctx->mrec = ctx->base_mrec;
  894. ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec +
  895. le16_to_cpu(ctx->mrec->attrs_offset));
  896. ctx->is_first = TRUE;
  897. ctx->ntfs_ino = base_ni;
  898. ctx->base_ntfs_ino = NULL;
  899. ctx->base_mrec = NULL;
  900. ctx->base_attr = NULL;
  901. /*
  902. * In case there are multiple matches in the base mft record, need to
  903. * keep enumerating until we get an attribute not found response (or
  904. * another error), otherwise we would keep returning the same attribute
  905. * over and over again and all programs using us for enumeration would
  906. * lock up in a tight loop.
  907. */
  908. do {
  909. err = ntfs_attr_find(type, name, name_len, ic, val, val_len,
  910. ctx);
  911. } while (!err);
  912. ntfs_debug("Done, not found.");
  913. return err;
  914. }
  915. /**
  916. * ntfs_attr_lookup - find an attribute in an ntfs inode
  917. * @type: attribute type to find
  918. * @name: attribute name to find (optional, i.e. NULL means don't care)
  919. * @name_len: attribute name length (only needed if @name present)
  920. * @ic: IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
  921. * @lowest_vcn: lowest vcn to find (optional, non-resident attributes only)
  922. * @val: attribute value to find (optional, resident attributes only)
  923. * @val_len: attribute value length
  924. * @ctx: search context with mft record and attribute to search from
  925. *
  926. * Find an attribute in an ntfs inode. On first search @ctx->ntfs_ino must
  927. * be the base mft record and @ctx must have been obtained from a call to
  928. * ntfs_attr_get_search_ctx().
  929. *
  930. * This function transparently handles attribute lists and @ctx is used to
  931. * continue searches where they were left off at.
  932. *
  933. * After finishing with the attribute/mft record you need to call
  934. * ntfs_attr_put_search_ctx() to cleanup the search context (unmapping any
  935. * mapped inodes, etc).
  936. *
  937. * Return 0 if the search was successful and -errno if not.
  938. *
  939. * When 0, @ctx->attr is the found attribute and it is in mft record
  940. * @ctx->mrec. If an attribute list attribute is present, @ctx->al_entry is
  941. * the attribute list entry of the found attribute.
  942. *
  943. * When -ENOENT, @ctx->attr is the attribute which collates just after the
  944. * attribute being searched for, i.e. if one wants to add the attribute to the
  945. * mft record this is the correct place to insert it into. If an attribute
  946. * list attribute is present, @ctx->al_entry is the attribute list entry which
  947. * collates just after the attribute list entry of the attribute being searched
  948. * for, i.e. if one wants to add the attribute to the mft record this is the
  949. * correct place to insert its attribute list entry into.
  950. *
  951. * When -errno != -ENOENT, an error occured during the lookup. @ctx->attr is
  952. * then undefined and in particular you should not rely on it not changing.
  953. */
  954. int ntfs_attr_lookup(const ATTR_TYPE type, const ntfschar *name,
  955. const u32 name_len, const IGNORE_CASE_BOOL ic,
  956. const VCN lowest_vcn, const u8 *val, const u32 val_len,
  957. ntfs_attr_search_ctx *ctx)
  958. {
  959. ntfs_inode *base_ni;
  960. ntfs_debug("Entering.");
  961. if (ctx->base_ntfs_ino)
  962. base_ni = ctx->base_ntfs_ino;
  963. else
  964. base_ni = ctx->ntfs_ino;
  965. /* Sanity check, just for debugging really. */
  966. BUG_ON(!base_ni);
  967. if (!NInoAttrList(base_ni) || type == AT_ATTRIBUTE_LIST)
  968. return ntfs_attr_find(type, name, name_len, ic, val, val_len,
  969. ctx);
  970. return ntfs_external_attr_find(type, name, name_len, ic, lowest_vcn,
  971. val, val_len, ctx);
  972. }
  973. /**
  974. * ntfs_attr_init_search_ctx - initialize an attribute search context
  975. * @ctx: attribute search context to initialize
  976. * @ni: ntfs inode with which to initialize the search context
  977. * @mrec: mft record with which to initialize the search context
  978. *
  979. * Initialize the attribute search context @ctx with @ni and @mrec.
  980. */
  981. static inline void ntfs_attr_init_search_ctx(ntfs_attr_search_ctx *ctx,
  982. ntfs_inode *ni, MFT_RECORD *mrec)
  983. {
  984. *ctx = (ntfs_attr_search_ctx) {
  985. .mrec = mrec,
  986. /* Sanity checks are performed elsewhere. */
  987. .attr = (ATTR_RECORD*)((u8*)mrec +
  988. le16_to_cpu(mrec->attrs_offset)),
  989. .is_first = TRUE,
  990. .ntfs_ino = ni,
  991. };
  992. }
  993. /**
  994. * ntfs_attr_reinit_search_ctx - reinitialize an attribute search context
  995. * @ctx: attribute search context to reinitialize
  996. *
  997. * Reinitialize the attribute search context @ctx, unmapping an associated
  998. * extent mft record if present, and initialize the search context again.
  999. *
  1000. * This is used when a search for a new attribute is being started to reset
  1001. * the search context to the beginning.
  1002. */
  1003. void ntfs_attr_reinit_search_ctx(ntfs_attr_search_ctx *ctx)
  1004. {
  1005. if (likely(!ctx->base_ntfs_ino)) {
  1006. /* No attribute list. */
  1007. ctx->is_first = TRUE;
  1008. /* Sanity checks are performed elsewhere. */
  1009. ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec +
  1010. le16_to_cpu(ctx->mrec->attrs_offset));
  1011. /*
  1012. * This needs resetting due to ntfs_external_attr_find() which
  1013. * can leave it set despite having zeroed ctx->base_ntfs_ino.
  1014. */
  1015. ctx->al_entry = NULL;
  1016. return;
  1017. } /* Attribute list. */
  1018. if (ctx->ntfs_ino != ctx->base_ntfs_ino)
  1019. unmap_extent_mft_record(ctx->ntfs_ino);
  1020. ntfs_attr_init_search_ctx(ctx, ctx->base_ntfs_ino, ctx->base_mrec);
  1021. return;
  1022. }
  1023. /**
  1024. * ntfs_attr_get_search_ctx - allocate/initialize a new attribute search context
  1025. * @ni: ntfs inode with which to initialize the search context
  1026. * @mrec: mft record with which to initialize the search context
  1027. *
  1028. * Allocate a new attribute search context, initialize it with @ni and @mrec,
  1029. * and return it. Return NULL if allocation failed.
  1030. */
  1031. ntfs_attr_search_ctx *ntfs_attr_get_search_ctx(ntfs_inode *ni, MFT_RECORD *mrec)
  1032. {
  1033. ntfs_attr_search_ctx *ctx;
  1034. ctx = kmem_cache_alloc(ntfs_attr_ctx_cache, SLAB_NOFS);
  1035. if (ctx)
  1036. ntfs_attr_init_search_ctx(ctx, ni, mrec);
  1037. return ctx;
  1038. }
  1039. /**
  1040. * ntfs_attr_put_search_ctx - release an attribute search context
  1041. * @ctx: attribute search context to free
  1042. *
  1043. * Release the attribute search context @ctx, unmapping an associated extent
  1044. * mft record if present.
  1045. */
  1046. void ntfs_attr_put_search_ctx(ntfs_attr_search_ctx *ctx)
  1047. {
  1048. if (ctx->base_ntfs_ino && ctx->ntfs_ino != ctx->base_ntfs_ino)
  1049. unmap_extent_mft_record(ctx->ntfs_ino);
  1050. kmem_cache_free(ntfs_attr_ctx_cache, ctx);
  1051. return;
  1052. }
  1053. #ifdef NTFS_RW
  1054. /**
  1055. * ntfs_attr_find_in_attrdef - find an attribute in the $AttrDef system file
  1056. * @vol: ntfs volume to which the attribute belongs
  1057. * @type: attribute type which to find
  1058. *
  1059. * Search for the attribute definition record corresponding to the attribute
  1060. * @type in the $AttrDef system file.
  1061. *
  1062. * Return the attribute type definition record if found and NULL if not found.
  1063. */
  1064. static ATTR_DEF *ntfs_attr_find_in_attrdef(const ntfs_volume *vol,
  1065. const ATTR_TYPE type)
  1066. {
  1067. ATTR_DEF *ad;
  1068. BUG_ON(!vol->attrdef);
  1069. BUG_ON(!type);
  1070. for (ad = vol->attrdef; (u8*)ad - (u8*)vol->attrdef <
  1071. vol->attrdef_size && ad->type; ++ad) {
  1072. /* We have not found it yet, carry on searching. */
  1073. if (likely(le32_to_cpu(ad->type) < le32_to_cpu(type)))
  1074. continue;
  1075. /* We found the attribute; return it. */
  1076. if (likely(ad->type == type))
  1077. return ad;
  1078. /* We have gone too far already. No point in continuing. */
  1079. break;
  1080. }
  1081. /* Attribute not found. */
  1082. ntfs_debug("Attribute type 0x%x not found in $AttrDef.",
  1083. le32_to_cpu(type));
  1084. return NULL;
  1085. }
  1086. /**
  1087. * ntfs_attr_size_bounds_check - check a size of an attribute type for validity
  1088. * @vol: ntfs volume to which the attribute belongs
  1089. * @type: attribute type which to check
  1090. * @size: size which to check
  1091. *
  1092. * Check whether the @size in bytes is valid for an attribute of @type on the
  1093. * ntfs volume @vol. This information is obtained from $AttrDef system file.
  1094. *
  1095. * Return 0 if valid, -ERANGE if not valid, or -ENOENT if the attribute is not
  1096. * listed in $AttrDef.
  1097. */
  1098. int ntfs_attr_size_bounds_check(const ntfs_volume *vol, const ATTR_TYPE type,
  1099. const s64 size)
  1100. {
  1101. ATTR_DEF *ad;
  1102. BUG_ON(size < 0);
  1103. /*
  1104. * $ATTRIBUTE_LIST has a maximum size of 256kiB, but this is not
  1105. * listed in $AttrDef.
  1106. */
  1107. if (unlikely(type == AT_ATTRIBUTE_LIST && size > 256 * 1024))
  1108. return -ERANGE;
  1109. /* Get the $AttrDef entry for the attribute @type. */
  1110. ad = ntfs_attr_find_in_attrdef(vol, type);
  1111. if (unlikely(!ad))
  1112. return -ENOENT;
  1113. /* Do the bounds check. */
  1114. if (((sle64_to_cpu(ad->min_size) > 0) &&
  1115. size < sle64_to_cpu(ad->min_size)) ||
  1116. ((sle64_to_cpu(ad->max_size) > 0) && size >
  1117. sle64_to_cpu(ad->max_size)))
  1118. return -ERANGE;
  1119. return 0;
  1120. }
  1121. /**
  1122. * ntfs_attr_can_be_non_resident - check if an attribute can be non-resident
  1123. * @vol: ntfs volume to which the attribute belongs
  1124. * @type: attribute type which to check
  1125. *
  1126. * Check whether the attribute of @type on the ntfs volume @vol is allowed to
  1127. * be non-resident. This information is obtained from $AttrDef system file.
  1128. *
  1129. * Return 0 if the attribute is allowed to be non-resident, -EPERM if not, and
  1130. * -ENOENT if the attribute is not listed in $AttrDef.
  1131. */
  1132. int ntfs_attr_can_be_non_resident(const ntfs_volume *vol, const ATTR_TYPE type)
  1133. {
  1134. ATTR_DEF *ad;
  1135. /* Find the attribute definition record in $AttrDef. */
  1136. ad = ntfs_attr_find_in_attrdef(vol, type);
  1137. if (unlikely(!ad))
  1138. return -ENOENT;
  1139. /* Check the flags and return the result. */
  1140. if (ad->flags & ATTR_DEF_RESIDENT)
  1141. return -EPERM;
  1142. return 0;
  1143. }
  1144. /**
  1145. * ntfs_attr_can_be_resident - check if an attribute can be resident
  1146. * @vol: ntfs volume to which the attribute belongs
  1147. * @type: attribute type which to check
  1148. *
  1149. * Check whether the attribute of @type on the ntfs volume @vol is allowed to
  1150. * be resident. This information is derived from our ntfs knowledge and may
  1151. * not be completely accurate, especially when user defined attributes are
  1152. * present. Basically we allow everything to be resident except for index
  1153. * allocation and $EA attributes.
  1154. *
  1155. * Return 0 if the attribute is allowed to be non-resident and -EPERM if not.
  1156. *
  1157. * Warning: In the system file $MFT the attribute $Bitmap must be non-resident
  1158. * otherwise windows will not boot (blue screen of death)! We cannot
  1159. * check for this here as we do not know which inode's $Bitmap is
  1160. * being asked about so the caller needs to special case this.
  1161. */
  1162. int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPE type)
  1163. {
  1164. if (type == AT_INDEX_ALLOCATION || type == AT_EA)
  1165. return -EPERM;
  1166. return 0;
  1167. }
  1168. /**
  1169. * ntfs_attr_record_resize - resize an attribute record
  1170. * @m: mft record containing attribute record
  1171. * @a: attribute record to resize
  1172. * @new_size: new size in bytes to which to resize the attribute record @a
  1173. *
  1174. * Resize the attribute record @a, i.e. the resident part of the attribute, in
  1175. * the mft record @m to @new_size bytes.
  1176. *
  1177. * Return 0 on success and -errno on error. The following error codes are
  1178. * defined:
  1179. * -ENOSPC - Not enough space in the mft record @m to perform the resize.
  1180. *
  1181. * Note: On error, no modifications have been performed whatsoever.
  1182. *
  1183. * Warning: If you make a record smaller without having copied all the data you
  1184. * are interested in the data may be overwritten.
  1185. */
  1186. int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size)
  1187. {
  1188. ntfs_debug("Entering for new_size %u.", new_size);
  1189. /* Align to 8 bytes if it is not already done. */
  1190. if (new_size & 7)
  1191. new_size = (new_size + 7) & ~7;
  1192. /* If the actual attribute length has changed, move things around. */
  1193. if (new_size != le32_to_cpu(a->length)) {
  1194. u32 new_muse = le32_to_cpu(m->bytes_in_use) -
  1195. le32_to_cpu(a->length) + new_size;
  1196. /* Not enough space in this mft record. */
  1197. if (new_muse > le32_to_cpu(m->bytes_allocated))
  1198. return -ENOSPC;
  1199. /* Move attributes following @a to their new location. */
  1200. memmove((u8*)a + new_size, (u8*)a + le32_to_cpu(a->length),
  1201. le32_to_cpu(m->bytes_in_use) - ((u8*)a -
  1202. (u8*)m) - le32_to_cpu(a->length));
  1203. /* Adjust @m to reflect the change in used space. */
  1204. m->bytes_in_use = cpu_to_le32(new_muse);
  1205. /* Adjust @a to reflect the new size. */
  1206. if (new_size >= offsetof(ATTR_REC, length) + sizeof(a->length))
  1207. a->length = cpu_to_le32(new_size);
  1208. }
  1209. return 0;
  1210. }
  1211. /**
  1212. * ntfs_attr_make_non_resident - convert a resident to a non-resident attribute
  1213. * @ni: ntfs inode describing the attribute to convert
  1214. *
  1215. * Convert the resident ntfs attribute described by the ntfs inode @ni to a
  1216. * non-resident one.
  1217. *
  1218. * Return 0 on success and -errno on error. The following error return codes
  1219. * are defined:
  1220. * -EPERM - The attribute is not allowed to be non-resident.
  1221. * -ENOMEM - Not enough memory.
  1222. * -ENOSPC - Not enough disk space.
  1223. * -EINVAL - Attribute not defined on the volume.
  1224. * -EIO - I/o error or other error.
  1225. * Note that -ENOSPC is also returned in the case that there is not enough
  1226. * space in the mft record to do the conversion. This can happen when the mft
  1227. * record is already very full. The caller is responsible for trying to make
  1228. * space in the mft record and trying again. FIXME: Do we need a separate
  1229. * error return code for this kind of -ENOSPC or is it always worth trying
  1230. * again in case the attribute may then fit in a resident state so no need to
  1231. * make it non-resident at all? Ho-hum... (AIA)
  1232. *
  1233. * NOTE to self: No changes in the attribute list are required to move from
  1234. * a resident to a non-resident attribute.
  1235. *
  1236. * Locking: - The caller must hold i_sem on the inode.
  1237. */
  1238. int ntfs_attr_make_non_resident(ntfs_inode *ni)
  1239. {
  1240. s64 new_size;
  1241. struct inode *vi = VFS_I(ni);
  1242. ntfs_volume *vol = ni->vol;
  1243. ntfs_inode *base_ni;
  1244. MFT_RECORD *m;
  1245. ATTR_RECORD *a;
  1246. ntfs_attr_search_ctx *ctx;
  1247. struct page *page;
  1248. runlist_element *rl;
  1249. u8 *kaddr;
  1250. unsigned long flags;
  1251. int mp_size, mp_ofs, name_ofs, arec_size, err, err2;
  1252. u32 attr_size;
  1253. u8 old_res_attr_flags;
  1254. /* Check that the attribute is allowed to be non-resident. */
  1255. err = ntfs_attr_can_be_non_resident(vol, ni->type);
  1256. if (unlikely(err)) {
  1257. if (err == -EPERM)
  1258. ntfs_debug("Attribute is not allowed to be "
  1259. "non-resident.");
  1260. else
  1261. ntfs_debug("Attribute not defined on the NTFS "
  1262. "volume!");
  1263. return err;
  1264. }
  1265. /*
  1266. * The size needs to be aligned to a cluster boundary for allocation
  1267. * purposes.
  1268. */
  1269. new_size = (i_size_read(vi) + vol->cluster_size - 1) &
  1270. ~(vol->cluster_size - 1);
  1271. if (new_size > 0) {
  1272. runlist_element *rl2;
  1273. /*
  1274. * Will need the page later and since the page lock nests
  1275. * outside all ntfs locks, we need to get the page now.
  1276. */
  1277. page = find_or_create_page(vi->i_mapping, 0,
  1278. mapping_gfp_mask(vi->i_mapping));
  1279. if (unlikely(!page))
  1280. return -ENOMEM;
  1281. /* Start by allocating clusters to hold the attribute value. */
  1282. rl = ntfs_cluster_alloc(vol, 0, new_size >>
  1283. vol->cluster_size_bits, -1, DATA_ZONE);
  1284. if (IS_ERR(rl)) {
  1285. err = PTR_ERR(rl);
  1286. ntfs_debug("Failed to allocate cluster%s, error code "
  1287. "%i.", (new_size >>
  1288. vol->cluster_size_bits) > 1 ? "s" : "",
  1289. err);
  1290. goto page_err_out;
  1291. }
  1292. /* Change the runlist terminator to LCN_ENOENT. */
  1293. rl2 = rl;
  1294. while (rl2->length)
  1295. rl2++;
  1296. BUG_ON(rl2->lcn != LCN_RL_NOT_MAPPED);
  1297. rl2->lcn = LCN_ENOENT;
  1298. } else {
  1299. rl = NULL;
  1300. page = NULL;
  1301. }
  1302. /* Determine the size of the mapping pairs array. */
  1303. mp_size = ntfs_get_size_for_mapping_pairs(vol, rl, 0, -1);
  1304. if (unlikely(mp_size < 0)) {
  1305. err = mp_size;
  1306. ntfs_debug("Failed to get size for mapping pairs array, error "
  1307. "code %i.", err);
  1308. goto rl_err_out;
  1309. }
  1310. down_write(&ni->runlist.lock);
  1311. if (!NInoAttr(ni))
  1312. base_ni = ni;
  1313. else
  1314. base_ni = ni->ext.base_ntfs_ino;
  1315. m = map_mft_record(base_ni);
  1316. if (IS_ERR(m)) {
  1317. err = PTR_ERR(m);
  1318. m = NULL;
  1319. ctx = NULL;
  1320. goto err_out;
  1321. }
  1322. ctx = ntfs_attr_get_search_ctx(base_ni, m);
  1323. if (unlikely(!ctx)) {
  1324. err = -ENOMEM;
  1325. goto err_out;
  1326. }
  1327. err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
  1328. CASE_SENSITIVE, 0, NULL, 0, ctx);
  1329. if (unlikely(err)) {
  1330. if (err == -ENOENT)
  1331. err = -EIO;
  1332. goto err_out;
  1333. }
  1334. m = ctx->mrec;
  1335. a = ctx->attr;
  1336. BUG_ON(NInoNonResident(ni));
  1337. BUG_ON(a->non_resident);
  1338. /*
  1339. * Calculate new offsets for the name and the mapping pairs array.
  1340. * We assume the attribute is not compressed or sparse.
  1341. */
  1342. name_ofs = (offsetof(ATTR_REC,
  1343. data.non_resident.compressed_size) + 7) & ~7;
  1344. mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7;
  1345. /*
  1346. * Determine the size of the resident part of the now non-resident
  1347. * attribute record.
  1348. */
  1349. arec_size = (mp_ofs + mp_size + 7) & ~7;
  1350. /*
  1351. * If the page is not uptodate bring it uptodate by copying from the
  1352. * attribute value.
  1353. */
  1354. attr_size = le32_to_cpu(a->data.resident.value_length);
  1355. BUG_ON(attr_size != i_size_read(vi));
  1356. if (page && !PageUptodate(page)) {
  1357. kaddr = kmap_atomic(page, KM_USER0);
  1358. memcpy(kaddr, (u8*)a +
  1359. le16_to_cpu(a->data.resident.value_offset),
  1360. attr_size);
  1361. memset(kaddr + attr_size, 0, PAGE_CACHE_SIZE - attr_size);
  1362. kunmap_atomic(kaddr, KM_USER0);
  1363. flush_dcache_page(page);
  1364. SetPageUptodate(page);
  1365. }
  1366. /* Backup the attribute flag. */
  1367. old_res_attr_flags = a->data.resident.flags;
  1368. /* Resize the resident part of the attribute record. */
  1369. err = ntfs_attr_record_resize(m, a, arec_size);
  1370. if (unlikely(err))
  1371. goto err_out;
  1372. /*
  1373. * Convert the resident part of the attribute record to describe a
  1374. * non-resident attribute.
  1375. */
  1376. a->non_resident = 1;
  1377. /* Move the attribute name if it exists and update the offset. */
  1378. if (a->name_length)
  1379. memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset),
  1380. a->name_length * sizeof(ntfschar));
  1381. a->name_offset = cpu_to_le16(name_ofs);
  1382. /*
  1383. * FIXME: For now just clear all of these as we do not support them
  1384. * when writing.
  1385. */
  1386. a->flags &= cpu_to_le16(0xffff & ~le16_to_cpu(ATTR_IS_SPARSE |
  1387. ATTR_IS_ENCRYPTED | ATTR_COMPRESSION_MASK));
  1388. /* Setup the fields specific to non-resident attributes. */
  1389. a->data.non_resident.lowest_vcn = 0;
  1390. a->data.non_resident.highest_vcn = cpu_to_sle64((new_size - 1) >>
  1391. vol->cluster_size_bits);
  1392. a->data.non_resident.mapping_pairs_offset = cpu_to_le16(mp_ofs);
  1393. a->data.non_resident.compression_unit = 0;
  1394. memset(&a->data.non_resident.reserved, 0,
  1395. sizeof(a->data.non_resident.reserved));
  1396. a->data.non_resident.allocated_size = cpu_to_sle64(new_size);
  1397. a->data.non_resident.data_size =
  1398. a->data.non_resident.initialized_size =
  1399. cpu_to_sle64(attr_size);
  1400. /* Generate the mapping pairs array into the attribute record. */
  1401. err = ntfs_mapping_pairs_build(vol, (u8*)a + mp_ofs,
  1402. arec_size - mp_ofs, rl, 0, -1, NULL);
  1403. if (unlikely(err)) {
  1404. ntfs_debug("Failed to build mapping pairs, error code %i.",
  1405. err);
  1406. goto undo_err_out;
  1407. }
  1408. /* Setup the in-memory attribute structure to be non-resident. */
  1409. /*
  1410. * FIXME: For now just clear all of these as we do not support them
  1411. * when writing.
  1412. */
  1413. NInoClearSparse(ni);
  1414. NInoClearEncrypted(ni);
  1415. NInoClearCompressed(ni);
  1416. ni->runlist.rl = rl;
  1417. write_lock_irqsave(&ni->size_lock, flags);
  1418. ni->allocated_size = new_size;
  1419. write_unlock_irqrestore(&ni->size_lock, flags);
  1420. /*
  1421. * This needs to be last since the address space operations ->readpage
  1422. * and ->writepage can run concurrently with us as they are not
  1423. * serialized on i_sem. Note, we are not allowed to fail once we flip
  1424. * this switch, which is another reason to do this last.
  1425. */
  1426. NInoSetNonResident(ni);
  1427. /* Mark the mft record dirty, so it gets written back. */
  1428. flush_dcache_mft_record_page(ctx->ntfs_ino);
  1429. mark_mft_record_dirty(ctx->ntfs_ino);
  1430. ntfs_attr_put_search_ctx(ctx);
  1431. unmap_mft_record(base_ni);
  1432. up_write(&ni->runlist.lock);
  1433. if (page) {
  1434. set_page_dirty(page);
  1435. unlock_page(page);
  1436. mark_page_accessed(page);
  1437. page_cache_release(page);
  1438. }
  1439. ntfs_debug("Done.");
  1440. return 0;
  1441. undo_err_out:
  1442. /* Convert the attribute back into a resident attribute. */
  1443. a->non_resident = 0;
  1444. /* Move the attribute name if it exists and update the offset. */
  1445. name_ofs = (offsetof(ATTR_RECORD, data.resident.reserved) +
  1446. sizeof(a->data.resident.reserved) + 7) & ~7;
  1447. if (a->name_length)
  1448. memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset),
  1449. a->name_length * sizeof(ntfschar));
  1450. mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7;
  1451. a->name_offset = cpu_to_le16(name_ofs);
  1452. arec_size = (mp_ofs + attr_size + 7) & ~7;
  1453. /* Resize the resident part of the attribute record. */
  1454. err2 = ntfs_attr_record_resize(m, a, arec_size);
  1455. if (unlikely(err2)) {
  1456. /*
  1457. * This cannot happen (well if memory corruption is at work it
  1458. * could happen in theory), but deal with it as well as we can.
  1459. * If the old size is too small, truncate the attribute,
  1460. * otherwise simply give it a larger allocated size.
  1461. * FIXME: Should check whether chkdsk complains when the
  1462. * allocated size is much bigger than the resident value size.
  1463. */
  1464. arec_size = le32_to_cpu(a->length);
  1465. if ((mp_ofs + attr_size) > arec_size) {
  1466. err2 = attr_size;
  1467. attr_size = arec_size - mp_ofs;
  1468. ntfs_error(vol->sb, "Failed to undo partial resident "
  1469. "to non-resident attribute "
  1470. "conversion. Truncating inode 0x%lx, "
  1471. "attribute type 0x%x from %i bytes to "
  1472. "%i bytes to maintain metadata "
  1473. "consistency. THIS MEANS YOU ARE "
  1474. "LOSING %i BYTES DATA FROM THIS %s.",
  1475. vi->i_ino,
  1476. (unsigned)le32_to_cpu(ni->type),
  1477. err2, attr_size, err2 - attr_size,
  1478. ((ni->type == AT_DATA) &&
  1479. !ni->name_len) ? "FILE": "ATTRIBUTE");
  1480. write_lock_irqsave(&ni->size_lock, flags);
  1481. ni->initialized_size = attr_size;
  1482. i_size_write(vi, attr_size);
  1483. write_unlock_irqrestore(&ni->size_lock, flags);
  1484. }
  1485. }
  1486. /* Setup the fields specific to resident attributes. */
  1487. a->data.resident.value_length = cpu_to_le32(attr_size);
  1488. a->data.resident.value_offset = cpu_to_le16(mp_ofs);
  1489. a->data.resident.flags = old_res_attr_flags;
  1490. memset(&a->data.resident.reserved, 0,
  1491. sizeof(a->data.resident.reserved));
  1492. /* Copy the data from the page back to the attribute value. */
  1493. if (page) {
  1494. kaddr = kmap_atomic(page, KM_USER0);
  1495. memcpy((u8*)a + mp_ofs, kaddr, attr_size);
  1496. kunmap_atomic(kaddr, KM_USER0);
  1497. }
  1498. /* Setup the allocated size in the ntfs inode in case it changed. */
  1499. write_lock_irqsave(&ni->size_lock, flags);
  1500. ni->allocated_size = arec_size - mp_ofs;
  1501. write_unlock_irqrestore(&ni->size_lock, flags);
  1502. /* Mark the mft record dirty, so it gets written back. */
  1503. flush_dcache_mft_record_page(ctx->ntfs_ino);
  1504. mark_mft_record_dirty(ctx->ntfs_ino);
  1505. err_out:
  1506. if (ctx)
  1507. ntfs_attr_put_search_ctx(ctx);
  1508. if (m)
  1509. unmap_mft_record(base_ni);
  1510. ni->runlist.rl = NULL;
  1511. up_write(&ni->runlist.lock);
  1512. rl_err_out:
  1513. if (rl) {
  1514. if (ntfs_cluster_free_from_rl(vol, rl) < 0) {
  1515. ntfs_error(vol->sb, "Failed to release allocated "
  1516. "cluster(s) in error code path. Run "
  1517. "chkdsk to recover the lost "
  1518. "cluster(s).");
  1519. NVolSetErrors(vol);
  1520. }
  1521. ntfs_free(rl);
  1522. page_err_out:
  1523. unlock_page(page);
  1524. page_cache_release(page);
  1525. }
  1526. if (err == -EINVAL)
  1527. err = -EIO;
  1528. return err;
  1529. }
  1530. /**
  1531. * ntfs_attr_set - fill (a part of) an attribute with a byte
  1532. * @ni: ntfs inode describing the attribute to fill
  1533. * @ofs: offset inside the attribute at which to start to fill
  1534. * @cnt: number of bytes to fill
  1535. * @val: the unsigned 8-bit value with which to fill the attribute
  1536. *
  1537. * Fill @cnt bytes of the attribute described by the ntfs inode @ni starting at
  1538. * byte offset @ofs inside the attribute with the constant byte @val.
  1539. *
  1540. * This function is effectively like memset() applied to an ntfs attribute.
  1541. * Note thie function actually only operates on the page cache pages belonging
  1542. * to the ntfs attribute and it marks them dirty after doing the memset().
  1543. * Thus it relies on the vm dirty page write code paths to cause the modified
  1544. * pages to be written to the mft record/disk.
  1545. *
  1546. * Return 0 on success and -errno on error. An error code of -ESPIPE means
  1547. * that @ofs + @cnt were outside the end of the attribute and no write was
  1548. * performed.
  1549. */
  1550. int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val)
  1551. {
  1552. ntfs_volume *vol = ni->vol;
  1553. struct address_space *mapping;
  1554. struct page *page;
  1555. u8 *kaddr;
  1556. pgoff_t idx, end;
  1557. unsigned int start_ofs, end_ofs, size;
  1558. ntfs_debug("Entering for ofs 0x%llx, cnt 0x%llx, val 0x%hx.",
  1559. (long long)ofs, (long long)cnt, val);
  1560. BUG_ON(ofs < 0);
  1561. BUG_ON(cnt < 0);
  1562. if (!cnt)
  1563. goto done;
  1564. mapping = VFS_I(ni)->i_mapping;
  1565. /* Work out the starting index and page offset. */
  1566. idx = ofs >> PAGE_CACHE_SHIFT;
  1567. start_ofs = ofs & ~PAGE_CACHE_MASK;
  1568. /* Work out the ending index and page offset. */
  1569. end = ofs + cnt;
  1570. end_ofs = end & ~PAGE_CACHE_MASK;
  1571. /* If the end is outside the inode size return -ESPIPE. */
  1572. if (unlikely(end > i_size_read(VFS_I(ni)))) {
  1573. ntfs_error(vol->sb, "Request exceeds end of attribute.");
  1574. return -ESPIPE;
  1575. }
  1576. end >>= PAGE_CACHE_SHIFT;
  1577. /* If there is a first partial page, need to do it the slow way. */
  1578. if (start_ofs) {
  1579. page = read_cache_page(mapping, idx,
  1580. (filler_t*)mapping->a_ops->readpage, NULL);
  1581. if (IS_ERR(page)) {
  1582. ntfs_error(vol->sb, "Failed to read first partial "
  1583. "page (sync error, index 0x%lx).", idx);
  1584. return PTR_ERR(page);
  1585. }
  1586. wait_on_page_locked(page);
  1587. if (unlikely(!PageUptodate(page))) {
  1588. ntfs_error(vol->sb, "Failed to read first partial page "
  1589. "(async error, index 0x%lx).", idx);
  1590. page_cache_release(page);
  1591. return PTR_ERR(page);
  1592. }
  1593. /*
  1594. * If the last page is the same as the first page, need to
  1595. * limit the write to the end offset.
  1596. */
  1597. size = PAGE_CACHE_SIZE;
  1598. if (idx == end)
  1599. size = end_ofs;
  1600. kaddr = kmap_atomic(page, KM_USER0);
  1601. memset(kaddr + start_ofs, val, size - start_ofs);
  1602. flush_dcache_page(page);
  1603. kunmap_atomic(kaddr, KM_USER0);
  1604. set_page_dirty(page);
  1605. page_cache_release(page);
  1606. if (idx == end)
  1607. goto done;
  1608. idx++;
  1609. }
  1610. /* Do the whole pages the fast way. */
  1611. for (; idx < end; idx++) {
  1612. /* Find or create the current page. (The page is locked.) */
  1613. page = grab_cache_page(mapping, idx);
  1614. if (unlikely(!page)) {
  1615. ntfs_error(vol->sb, "Insufficient memory to grab "
  1616. "page (index 0x%lx).", idx);
  1617. return -ENOMEM;
  1618. }
  1619. kaddr = kmap_atomic(page, KM_USER0);
  1620. memset(kaddr, val, PAGE_CACHE_SIZE);
  1621. flush_dcache_page(page);
  1622. kunmap_atomic(kaddr, KM_USER0);
  1623. /*
  1624. * If the page has buffers, mark them uptodate since buffer
  1625. * state and not page state is definitive in 2.6 kernels.
  1626. */
  1627. if (page_has_buffers(page)) {
  1628. struct buffer_head *bh, *head;
  1629. bh = head = page_buffers(page);
  1630. do {
  1631. set_buffer_uptodate(bh);
  1632. } while ((bh = bh->b_this_page) != head);
  1633. }
  1634. /* Now that buffers are uptodate, set the page uptodate, too. */
  1635. SetPageUptodate(page);
  1636. /*
  1637. * Set the page and all its buffers dirty and mark the inode
  1638. * dirty, too. The VM will write the page later on.
  1639. */
  1640. set_page_dirty(page);
  1641. /* Finally unlock and release the page. */
  1642. unlock_page(page);
  1643. page_cache_release(page);
  1644. }
  1645. /* If there is a last partial page, need to do it the slow way. */
  1646. if (end_ofs) {
  1647. page = read_cache_page(mapping, idx,
  1648. (filler_t*)mapping->a_ops->readpage, NULL);
  1649. if (IS_ERR(page)) {
  1650. ntfs_error(vol->sb, "Failed to read last partial page "
  1651. "(sync error, index 0x%lx).", idx);
  1652. return PTR_ERR(page);
  1653. }
  1654. wait_on_page_locked(page);
  1655. if (unlikely(!PageUptodate(page))) {
  1656. ntfs_error(vol->sb, "Failed to read last partial page "
  1657. "(async error, index 0x%lx).", idx);
  1658. page_cache_release(page);
  1659. return PTR_ERR(page);
  1660. }
  1661. kaddr = kmap_atomic(page, KM_USER0);
  1662. memset(kaddr, val, end_ofs);
  1663. flush_dcache_page(page);
  1664. kunmap_atomic(kaddr, KM_USER0);
  1665. set_page_dirty(page);
  1666. page_cache_release(page);
  1667. }
  1668. done:
  1669. ntfs_debug("Done.");
  1670. return 0;
  1671. }
  1672. #endif /* NTFS_RW */