attrib.c 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279
  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 "attrib.h"
  24. #include "debug.h"
  25. #include "layout.h"
  26. #include "mft.h"
  27. #include "ntfs.h"
  28. #include "types.h"
  29. /**
  30. * ntfs_map_runlist_nolock - map (a part of) a runlist of an ntfs inode
  31. * @ni: ntfs inode for which to map (part of) a runlist
  32. * @vcn: map runlist part containing this vcn
  33. *
  34. * Map the part of a runlist containing the @vcn of the ntfs inode @ni.
  35. *
  36. * Return 0 on success and -errno on error.
  37. *
  38. * Locking: - The runlist must be locked for writing.
  39. * - This function modifies the runlist.
  40. */
  41. int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
  42. {
  43. ntfs_inode *base_ni;
  44. MFT_RECORD *mrec;
  45. ntfs_attr_search_ctx *ctx;
  46. runlist_element *rl;
  47. int err = 0;
  48. ntfs_debug("Mapping runlist part containing vcn 0x%llx.",
  49. (unsigned long long)vcn);
  50. if (!NInoAttr(ni))
  51. base_ni = ni;
  52. else
  53. base_ni = ni->ext.base_ntfs_ino;
  54. mrec = map_mft_record(base_ni);
  55. if (IS_ERR(mrec))
  56. return PTR_ERR(mrec);
  57. ctx = ntfs_attr_get_search_ctx(base_ni, mrec);
  58. if (unlikely(!ctx)) {
  59. err = -ENOMEM;
  60. goto err_out;
  61. }
  62. err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
  63. CASE_SENSITIVE, vcn, NULL, 0, ctx);
  64. if (likely(!err)) {
  65. rl = ntfs_mapping_pairs_decompress(ni->vol, ctx->attr,
  66. ni->runlist.rl);
  67. if (IS_ERR(rl))
  68. err = PTR_ERR(rl);
  69. else
  70. ni->runlist.rl = rl;
  71. }
  72. ntfs_attr_put_search_ctx(ctx);
  73. err_out:
  74. unmap_mft_record(base_ni);
  75. return err;
  76. }
  77. /**
  78. * ntfs_map_runlist - map (a part of) a runlist of an ntfs inode
  79. * @ni: ntfs inode for which to map (part of) a runlist
  80. * @vcn: map runlist part containing this vcn
  81. *
  82. * Map the part of a runlist containing the @vcn of the ntfs inode @ni.
  83. *
  84. * Return 0 on success and -errno on error.
  85. *
  86. * Locking: - The runlist must be unlocked on entry and is unlocked on return.
  87. * - This function takes the runlist lock for writing and modifies the
  88. * runlist.
  89. */
  90. int ntfs_map_runlist(ntfs_inode *ni, VCN vcn)
  91. {
  92. int err = 0;
  93. down_write(&ni->runlist.lock);
  94. /* Make sure someone else didn't do the work while we were sleeping. */
  95. if (likely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) <=
  96. LCN_RL_NOT_MAPPED))
  97. err = ntfs_map_runlist_nolock(ni, vcn);
  98. up_write(&ni->runlist.lock);
  99. return err;
  100. }
  101. /**
  102. * ntfs_find_vcn_nolock - find a vcn in the runlist described by an ntfs inode
  103. * @ni: ntfs inode describing the runlist to search
  104. * @vcn: vcn to find
  105. * @write_locked: true if the runlist is locked for writing
  106. *
  107. * Find the virtual cluster number @vcn in the runlist described by the ntfs
  108. * inode @ni and return the address of the runlist element containing the @vcn.
  109. * The runlist is left locked and the caller has to unlock it. In the error
  110. * case, the runlist is left in the same locking state as on entry.
  111. *
  112. * Note if @write_locked is FALSE the lock may be dropped inside the function
  113. * so you cannot rely on the runlist still being the same when this function
  114. * returns.
  115. *
  116. * Note you need to distinguish between the lcn of the returned runlist element
  117. * being >= 0 and LCN_HOLE. In the later case you have to return zeroes on
  118. * read and allocate clusters on write.
  119. *
  120. * Return the runlist element containing the @vcn on success and
  121. * ERR_PTR(-errno) on error. You need to test the return value with IS_ERR()
  122. * to decide if the return is success or failure and PTR_ERR() to get to the
  123. * error code if IS_ERR() is true.
  124. *
  125. * The possible error return codes are:
  126. * -ENOENT - No such vcn in the runlist, i.e. @vcn is out of bounds.
  127. * -ENOMEM - Not enough memory to map runlist.
  128. * -EIO - Critical error (runlist/file is corrupt, i/o error, etc).
  129. *
  130. * Locking: - The runlist must be unlocked on entry.
  131. * - On failing return, the runlist is unlocked.
  132. * - On successful return, the runlist is locked. If @need_write us
  133. * true, it is locked for writing. Otherwise is is locked for
  134. * reading.
  135. */
  136. runlist_element *ntfs_find_vcn_nolock(ntfs_inode *ni, const VCN vcn,
  137. const BOOL write_locked)
  138. {
  139. runlist_element *rl;
  140. int err = 0;
  141. BOOL is_retry = FALSE;
  142. ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",
  143. ni->mft_no, (unsigned long long)vcn,
  144. write_locked ? "write" : "read");
  145. BUG_ON(!ni);
  146. BUG_ON(!NInoNonResident(ni));
  147. BUG_ON(vcn < 0);
  148. retry_remap:
  149. rl = ni->runlist.rl;
  150. if (likely(rl && vcn >= rl[0].vcn)) {
  151. while (likely(rl->length)) {
  152. if (unlikely(vcn < rl[1].vcn)) {
  153. if (likely(rl->lcn >= LCN_HOLE)) {
  154. ntfs_debug("Done.");
  155. return rl;
  156. }
  157. break;
  158. }
  159. rl++;
  160. }
  161. if (likely(rl->lcn != LCN_RL_NOT_MAPPED)) {
  162. if (likely(rl->lcn == LCN_ENOENT))
  163. err = -ENOENT;
  164. else
  165. err = -EIO;
  166. }
  167. }
  168. if (!err && !is_retry) {
  169. /*
  170. * The @vcn is in an unmapped region, map the runlist and
  171. * retry.
  172. */
  173. if (!write_locked) {
  174. up_read(&ni->runlist.lock);
  175. down_write(&ni->runlist.lock);
  176. }
  177. err = ntfs_map_runlist_nolock(ni, vcn);
  178. if (!write_locked) {
  179. up_write(&ni->runlist.lock);
  180. down_read(&ni->runlist.lock);
  181. }
  182. if (likely(!err)) {
  183. is_retry = TRUE;
  184. goto retry_remap;
  185. }
  186. /*
  187. * -EINVAL and -ENOENT coming from a failed mapping attempt are
  188. * equivalent to i/o errors for us as they should not happen in
  189. * our code paths.
  190. */
  191. if (err == -EINVAL || err == -ENOENT)
  192. err = -EIO;
  193. } else if (!err)
  194. err = -EIO;
  195. if (err != -ENOENT)
  196. ntfs_error(ni->vol->sb, "Failed with error code %i.", err);
  197. return ERR_PTR(err);
  198. }
  199. /**
  200. * ntfs_attr_find - find (next) attribute in mft record
  201. * @type: attribute type to find
  202. * @name: attribute name to find (optional, i.e. NULL means don't care)
  203. * @name_len: attribute name length (only needed if @name present)
  204. * @ic: IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
  205. * @val: attribute value to find (optional, resident attributes only)
  206. * @val_len: attribute value length
  207. * @ctx: search context with mft record and attribute to search from
  208. *
  209. * You should not need to call this function directly. Use ntfs_attr_lookup()
  210. * instead.
  211. *
  212. * ntfs_attr_find() takes a search context @ctx as parameter and searches the
  213. * mft record specified by @ctx->mrec, beginning at @ctx->attr, for an
  214. * attribute of @type, optionally @name and @val.
  215. *
  216. * If the attribute is found, ntfs_attr_find() returns 0 and @ctx->attr will
  217. * point to the found attribute.
  218. *
  219. * If the attribute is not found, ntfs_attr_find() returns -ENOENT and
  220. * @ctx->attr will point to the attribute before which the attribute being
  221. * searched for would need to be inserted if such an action were to be desired.
  222. *
  223. * On actual error, ntfs_attr_find() returns -EIO. In this case @ctx->attr is
  224. * undefined and in particular do not rely on it not changing.
  225. *
  226. * If @ctx->is_first is TRUE, the search begins with @ctx->attr itself. If it
  227. * is FALSE, the search begins after @ctx->attr.
  228. *
  229. * If @ic is IGNORE_CASE, the @name comparisson is not case sensitive and
  230. * @ctx->ntfs_ino must be set to the ntfs inode to which the mft record
  231. * @ctx->mrec belongs. This is so we can get at the ntfs volume and hence at
  232. * the upcase table. If @ic is CASE_SENSITIVE, the comparison is case
  233. * sensitive. When @name is present, @name_len is the @name length in Unicode
  234. * characters.
  235. *
  236. * If @name is not present (NULL), we assume that the unnamed attribute is
  237. * being searched for.
  238. *
  239. * Finally, the resident attribute value @val is looked for, if present. If
  240. * @val is not present (NULL), @val_len is ignored.
  241. *
  242. * ntfs_attr_find() only searches the specified mft record and it ignores the
  243. * presence of an attribute list attribute (unless it is the one being searched
  244. * for, obviously). If you need to take attribute lists into consideration,
  245. * use ntfs_attr_lookup() instead (see below). This also means that you cannot
  246. * use ntfs_attr_find() to search for extent records of non-resident
  247. * attributes, as extents with lowest_vcn != 0 are usually described by the
  248. * attribute list attribute only. - Note that it is possible that the first
  249. * extent is only in the attribute list while the last extent is in the base
  250. * mft record, so do not rely on being able to find the first extent in the
  251. * base mft record.
  252. *
  253. * Warning: Never use @val when looking for attribute types which can be
  254. * non-resident as this most likely will result in a crash!
  255. */
  256. static int ntfs_attr_find(const ATTR_TYPE type, const ntfschar *name,
  257. const u32 name_len, const IGNORE_CASE_BOOL ic,
  258. const u8 *val, const u32 val_len, ntfs_attr_search_ctx *ctx)
  259. {
  260. ATTR_RECORD *a;
  261. ntfs_volume *vol = ctx->ntfs_ino->vol;
  262. ntfschar *upcase = vol->upcase;
  263. u32 upcase_len = vol->upcase_len;
  264. /*
  265. * Iterate over attributes in mft record starting at @ctx->attr, or the
  266. * attribute following that, if @ctx->is_first is TRUE.
  267. */
  268. if (ctx->is_first) {
  269. a = ctx->attr;
  270. ctx->is_first = FALSE;
  271. } else
  272. a = (ATTR_RECORD*)((u8*)ctx->attr +
  273. le32_to_cpu(ctx->attr->length));
  274. for (;; a = (ATTR_RECORD*)((u8*)a + le32_to_cpu(a->length))) {
  275. if ((u8*)a < (u8*)ctx->mrec || (u8*)a > (u8*)ctx->mrec +
  276. le32_to_cpu(ctx->mrec->bytes_allocated))
  277. break;
  278. ctx->attr = a;
  279. if (unlikely(le32_to_cpu(a->type) > le32_to_cpu(type) ||
  280. a->type == AT_END))
  281. return -ENOENT;
  282. if (unlikely(!a->length))
  283. break;
  284. if (a->type != type)
  285. continue;
  286. /*
  287. * If @name is present, compare the two names. If @name is
  288. * missing, assume we want an unnamed attribute.
  289. */
  290. if (!name) {
  291. /* The search failed if the found attribute is named. */
  292. if (a->name_length)
  293. return -ENOENT;
  294. } else if (!ntfs_are_names_equal(name, name_len,
  295. (ntfschar*)((u8*)a + le16_to_cpu(a->name_offset)),
  296. a->name_length, ic, upcase, upcase_len)) {
  297. register int rc;
  298. rc = ntfs_collate_names(name, name_len,
  299. (ntfschar*)((u8*)a +
  300. le16_to_cpu(a->name_offset)),
  301. a->name_length, 1, IGNORE_CASE,
  302. upcase, upcase_len);
  303. /*
  304. * If @name collates before a->name, there is no
  305. * matching attribute.
  306. */
  307. if (rc == -1)
  308. return -ENOENT;
  309. /* If the strings are not equal, continue search. */
  310. if (rc)
  311. continue;
  312. rc = ntfs_collate_names(name, name_len,
  313. (ntfschar*)((u8*)a +
  314. le16_to_cpu(a->name_offset)),
  315. a->name_length, 1, CASE_SENSITIVE,
  316. upcase, upcase_len);
  317. if (rc == -1)
  318. return -ENOENT;
  319. if (rc)
  320. continue;
  321. }
  322. /*
  323. * The names match or @name not present and attribute is
  324. * unnamed. If no @val specified, we have found the attribute
  325. * and are done.
  326. */
  327. if (!val)
  328. return 0;
  329. /* @val is present; compare values. */
  330. else {
  331. register int rc;
  332. rc = memcmp(val, (u8*)a + le16_to_cpu(
  333. a->data.resident.value_offset),
  334. min_t(u32, val_len, le32_to_cpu(
  335. a->data.resident.value_length)));
  336. /*
  337. * If @val collates before the current attribute's
  338. * value, there is no matching attribute.
  339. */
  340. if (!rc) {
  341. register u32 avl;
  342. avl = le32_to_cpu(
  343. a->data.resident.value_length);
  344. if (val_len == avl)
  345. return 0;
  346. if (val_len < avl)
  347. return -ENOENT;
  348. } else if (rc < 0)
  349. return -ENOENT;
  350. }
  351. }
  352. ntfs_error(vol->sb, "Inode is corrupt. Run chkdsk.");
  353. NVolSetErrors(vol);
  354. return -EIO;
  355. }
  356. /**
  357. * load_attribute_list - load an attribute list into memory
  358. * @vol: ntfs volume from which to read
  359. * @runlist: runlist of the attribute list
  360. * @al_start: destination buffer
  361. * @size: size of the destination buffer in bytes
  362. * @initialized_size: initialized size of the attribute list
  363. *
  364. * Walk the runlist @runlist and load all clusters from it copying them into
  365. * the linear buffer @al. The maximum number of bytes copied to @al is @size
  366. * bytes. Note, @size does not need to be a multiple of the cluster size. If
  367. * @initialized_size is less than @size, the region in @al between
  368. * @initialized_size and @size will be zeroed and not read from disk.
  369. *
  370. * Return 0 on success or -errno on error.
  371. */
  372. int load_attribute_list(ntfs_volume *vol, runlist *runlist, u8 *al_start,
  373. const s64 size, const s64 initialized_size)
  374. {
  375. LCN lcn;
  376. u8 *al = al_start;
  377. u8 *al_end = al + initialized_size;
  378. runlist_element *rl;
  379. struct buffer_head *bh;
  380. struct super_block *sb;
  381. unsigned long block_size;
  382. unsigned long block, max_block;
  383. int err = 0;
  384. unsigned char block_size_bits;
  385. ntfs_debug("Entering.");
  386. if (!vol || !runlist || !al || size <= 0 || initialized_size < 0 ||
  387. initialized_size > size)
  388. return -EINVAL;
  389. if (!initialized_size) {
  390. memset(al, 0, size);
  391. return 0;
  392. }
  393. sb = vol->sb;
  394. block_size = sb->s_blocksize;
  395. block_size_bits = sb->s_blocksize_bits;
  396. down_read(&runlist->lock);
  397. rl = runlist->rl;
  398. /* Read all clusters specified by the runlist one run at a time. */
  399. while (rl->length) {
  400. lcn = ntfs_rl_vcn_to_lcn(rl, rl->vcn);
  401. ntfs_debug("Reading vcn = 0x%llx, lcn = 0x%llx.",
  402. (unsigned long long)rl->vcn,
  403. (unsigned long long)lcn);
  404. /* The attribute list cannot be sparse. */
  405. if (lcn < 0) {
  406. ntfs_error(sb, "ntfs_rl_vcn_to_lcn() failed. Cannot "
  407. "read attribute list.");
  408. goto err_out;
  409. }
  410. block = lcn << vol->cluster_size_bits >> block_size_bits;
  411. /* Read the run from device in chunks of block_size bytes. */
  412. max_block = block + (rl->length << vol->cluster_size_bits >>
  413. block_size_bits);
  414. ntfs_debug("max_block = 0x%lx.", max_block);
  415. do {
  416. ntfs_debug("Reading block = 0x%lx.", block);
  417. bh = sb_bread(sb, block);
  418. if (!bh) {
  419. ntfs_error(sb, "sb_bread() failed. Cannot "
  420. "read attribute list.");
  421. goto err_out;
  422. }
  423. if (al + block_size >= al_end)
  424. goto do_final;
  425. memcpy(al, bh->b_data, block_size);
  426. brelse(bh);
  427. al += block_size;
  428. } while (++block < max_block);
  429. rl++;
  430. }
  431. if (initialized_size < size) {
  432. initialize:
  433. memset(al_start + initialized_size, 0, size - initialized_size);
  434. }
  435. done:
  436. up_read(&runlist->lock);
  437. return err;
  438. do_final:
  439. if (al < al_end) {
  440. /*
  441. * Partial block.
  442. *
  443. * Note: The attribute list can be smaller than its allocation
  444. * by multiple clusters. This has been encountered by at least
  445. * two people running Windows XP, thus we cannot do any
  446. * truncation sanity checking here. (AIA)
  447. */
  448. memcpy(al, bh->b_data, al_end - al);
  449. brelse(bh);
  450. if (initialized_size < size)
  451. goto initialize;
  452. goto done;
  453. }
  454. brelse(bh);
  455. /* Real overflow! */
  456. ntfs_error(sb, "Attribute list buffer overflow. Read attribute list "
  457. "is truncated.");
  458. err_out:
  459. err = -EIO;
  460. goto done;
  461. }
  462. /**
  463. * ntfs_external_attr_find - find an attribute in the attribute list of an inode
  464. * @type: attribute type to find
  465. * @name: attribute name to find (optional, i.e. NULL means don't care)
  466. * @name_len: attribute name length (only needed if @name present)
  467. * @ic: IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
  468. * @lowest_vcn: lowest vcn to find (optional, non-resident attributes only)
  469. * @val: attribute value to find (optional, resident attributes only)
  470. * @val_len: attribute value length
  471. * @ctx: search context with mft record and attribute to search from
  472. *
  473. * You should not need to call this function directly. Use ntfs_attr_lookup()
  474. * instead.
  475. *
  476. * Find an attribute by searching the attribute list for the corresponding
  477. * attribute list entry. Having found the entry, map the mft record if the
  478. * attribute is in a different mft record/inode, ntfs_attr_find() the attribute
  479. * in there and return it.
  480. *
  481. * On first search @ctx->ntfs_ino must be the base mft record and @ctx must
  482. * have been obtained from a call to ntfs_attr_get_search_ctx(). On subsequent
  483. * calls @ctx->ntfs_ino can be any extent inode, too (@ctx->base_ntfs_ino is
  484. * then the base inode).
  485. *
  486. * After finishing with the attribute/mft record you need to call
  487. * ntfs_attr_put_search_ctx() to cleanup the search context (unmapping any
  488. * mapped inodes, etc).
  489. *
  490. * If the attribute is found, ntfs_external_attr_find() returns 0 and
  491. * @ctx->attr will point to the found attribute. @ctx->mrec will point to the
  492. * mft record in which @ctx->attr is located and @ctx->al_entry will point to
  493. * the attribute list entry for the attribute.
  494. *
  495. * If the attribute is not found, ntfs_external_attr_find() returns -ENOENT and
  496. * @ctx->attr will point to the attribute in the base mft record before which
  497. * the attribute being searched for would need to be inserted if such an action
  498. * were to be desired. @ctx->mrec will point to the mft record in which
  499. * @ctx->attr is located and @ctx->al_entry will point to the attribute list
  500. * entry of the attribute before which the attribute being searched for would
  501. * need to be inserted if such an action were to be desired.
  502. *
  503. * Thus to insert the not found attribute, one wants to add the attribute to
  504. * @ctx->mrec (the base mft record) and if there is not enough space, the
  505. * attribute should be placed in a newly allocated extent mft record. The
  506. * attribute list entry for the inserted attribute should be inserted in the
  507. * attribute list attribute at @ctx->al_entry.
  508. *
  509. * On actual error, ntfs_external_attr_find() returns -EIO. In this case
  510. * @ctx->attr is undefined and in particular do not rely on it not changing.
  511. */
  512. static int ntfs_external_attr_find(const ATTR_TYPE type,
  513. const ntfschar *name, const u32 name_len,
  514. const IGNORE_CASE_BOOL ic, const VCN lowest_vcn,
  515. const u8 *val, const u32 val_len, ntfs_attr_search_ctx *ctx)
  516. {
  517. ntfs_inode *base_ni, *ni;
  518. ntfs_volume *vol;
  519. ATTR_LIST_ENTRY *al_entry, *next_al_entry;
  520. u8 *al_start, *al_end;
  521. ATTR_RECORD *a;
  522. ntfschar *al_name;
  523. u32 al_name_len;
  524. int err = 0;
  525. static const char *es = " Unmount and run chkdsk.";
  526. ni = ctx->ntfs_ino;
  527. base_ni = ctx->base_ntfs_ino;
  528. ntfs_debug("Entering for inode 0x%lx, type 0x%x.", ni->mft_no, type);
  529. if (!base_ni) {
  530. /* First call happens with the base mft record. */
  531. base_ni = ctx->base_ntfs_ino = ctx->ntfs_ino;
  532. ctx->base_mrec = ctx->mrec;
  533. }
  534. if (ni == base_ni)
  535. ctx->base_attr = ctx->attr;
  536. if (type == AT_END)
  537. goto not_found;
  538. vol = base_ni->vol;
  539. al_start = base_ni->attr_list;
  540. al_end = al_start + base_ni->attr_list_size;
  541. if (!ctx->al_entry)
  542. ctx->al_entry = (ATTR_LIST_ENTRY*)al_start;
  543. /*
  544. * Iterate over entries in attribute list starting at @ctx->al_entry,
  545. * or the entry following that, if @ctx->is_first is TRUE.
  546. */
  547. if (ctx->is_first) {
  548. al_entry = ctx->al_entry;
  549. ctx->is_first = FALSE;
  550. } else
  551. al_entry = (ATTR_LIST_ENTRY*)((u8*)ctx->al_entry +
  552. le16_to_cpu(ctx->al_entry->length));
  553. for (;; al_entry = next_al_entry) {
  554. /* Out of bounds check. */
  555. if ((u8*)al_entry < base_ni->attr_list ||
  556. (u8*)al_entry > al_end)
  557. break; /* Inode is corrupt. */
  558. ctx->al_entry = al_entry;
  559. /* Catch the end of the attribute list. */
  560. if ((u8*)al_entry == al_end)
  561. goto not_found;
  562. if (!al_entry->length)
  563. break;
  564. if ((u8*)al_entry + 6 > al_end || (u8*)al_entry +
  565. le16_to_cpu(al_entry->length) > al_end)
  566. break;
  567. next_al_entry = (ATTR_LIST_ENTRY*)((u8*)al_entry +
  568. le16_to_cpu(al_entry->length));
  569. if (le32_to_cpu(al_entry->type) > le32_to_cpu(type))
  570. goto not_found;
  571. if (type != al_entry->type)
  572. continue;
  573. /*
  574. * If @name is present, compare the two names. If @name is
  575. * missing, assume we want an unnamed attribute.
  576. */
  577. al_name_len = al_entry->name_length;
  578. al_name = (ntfschar*)((u8*)al_entry + al_entry->name_offset);
  579. if (!name) {
  580. if (al_name_len)
  581. goto not_found;
  582. } else if (!ntfs_are_names_equal(al_name, al_name_len, name,
  583. name_len, ic, vol->upcase, vol->upcase_len)) {
  584. register int rc;
  585. rc = ntfs_collate_names(name, name_len, al_name,
  586. al_name_len, 1, IGNORE_CASE,
  587. vol->upcase, vol->upcase_len);
  588. /*
  589. * If @name collates before al_name, there is no
  590. * matching attribute.
  591. */
  592. if (rc == -1)
  593. goto not_found;
  594. /* If the strings are not equal, continue search. */
  595. if (rc)
  596. continue;
  597. /*
  598. * FIXME: Reverse engineering showed 0, IGNORE_CASE but
  599. * that is inconsistent with ntfs_attr_find(). The
  600. * subsequent rc checks were also different. Perhaps I
  601. * made a mistake in one of the two. Need to recheck
  602. * which is correct or at least see what is going on...
  603. * (AIA)
  604. */
  605. rc = ntfs_collate_names(name, name_len, al_name,
  606. al_name_len, 1, CASE_SENSITIVE,
  607. vol->upcase, vol->upcase_len);
  608. if (rc == -1)
  609. goto not_found;
  610. if (rc)
  611. continue;
  612. }
  613. /*
  614. * The names match or @name not present and attribute is
  615. * unnamed. Now check @lowest_vcn. Continue search if the
  616. * next attribute list entry still fits @lowest_vcn. Otherwise
  617. * we have reached the right one or the search has failed.
  618. */
  619. if (lowest_vcn && (u8*)next_al_entry >= al_start &&
  620. (u8*)next_al_entry + 6 < al_end &&
  621. (u8*)next_al_entry + le16_to_cpu(
  622. next_al_entry->length) <= al_end &&
  623. sle64_to_cpu(next_al_entry->lowest_vcn) <=
  624. lowest_vcn &&
  625. next_al_entry->type == al_entry->type &&
  626. next_al_entry->name_length == al_name_len &&
  627. ntfs_are_names_equal((ntfschar*)((u8*)
  628. next_al_entry +
  629. next_al_entry->name_offset),
  630. next_al_entry->name_length,
  631. al_name, al_name_len, CASE_SENSITIVE,
  632. vol->upcase, vol->upcase_len))
  633. continue;
  634. if (MREF_LE(al_entry->mft_reference) == ni->mft_no) {
  635. if (MSEQNO_LE(al_entry->mft_reference) != ni->seq_no) {
  636. ntfs_error(vol->sb, "Found stale mft "
  637. "reference in attribute list "
  638. "of base inode 0x%lx.%s",
  639. base_ni->mft_no, es);
  640. err = -EIO;
  641. break;
  642. }
  643. } else { /* Mft references do not match. */
  644. /* If there is a mapped record unmap it first. */
  645. if (ni != base_ni)
  646. unmap_extent_mft_record(ni);
  647. /* Do we want the base record back? */
  648. if (MREF_LE(al_entry->mft_reference) ==
  649. base_ni->mft_no) {
  650. ni = ctx->ntfs_ino = base_ni;
  651. ctx->mrec = ctx->base_mrec;
  652. } else {
  653. /* We want an extent record. */
  654. ctx->mrec = map_extent_mft_record(base_ni,
  655. le64_to_cpu(
  656. al_entry->mft_reference), &ni);
  657. if (IS_ERR(ctx->mrec)) {
  658. ntfs_error(vol->sb, "Failed to map "
  659. "extent mft record "
  660. "0x%lx of base inode "
  661. "0x%lx.%s",
  662. MREF_LE(al_entry->
  663. mft_reference),
  664. base_ni->mft_no, es);
  665. err = PTR_ERR(ctx->mrec);
  666. if (err == -ENOENT)
  667. err = -EIO;
  668. /* Cause @ctx to be sanitized below. */
  669. ni = NULL;
  670. break;
  671. }
  672. ctx->ntfs_ino = ni;
  673. }
  674. ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec +
  675. le16_to_cpu(ctx->mrec->attrs_offset));
  676. }
  677. /*
  678. * ctx->vfs_ino, ctx->mrec, and ctx->attr now point to the
  679. * mft record containing the attribute represented by the
  680. * current al_entry.
  681. */
  682. /*
  683. * We could call into ntfs_attr_find() to find the right
  684. * attribute in this mft record but this would be less
  685. * efficient and not quite accurate as ntfs_attr_find() ignores
  686. * the attribute instance numbers for example which become
  687. * important when one plays with attribute lists. Also,
  688. * because a proper match has been found in the attribute list
  689. * entry above, the comparison can now be optimized. So it is
  690. * worth re-implementing a simplified ntfs_attr_find() here.
  691. */
  692. a = ctx->attr;
  693. /*
  694. * Use a manual loop so we can still use break and continue
  695. * with the same meanings as above.
  696. */
  697. do_next_attr_loop:
  698. if ((u8*)a < (u8*)ctx->mrec || (u8*)a > (u8*)ctx->mrec +
  699. le32_to_cpu(ctx->mrec->bytes_allocated))
  700. break;
  701. if (a->type == AT_END)
  702. continue;
  703. if (!a->length)
  704. break;
  705. if (al_entry->instance != a->instance)
  706. goto do_next_attr;
  707. /*
  708. * If the type and/or the name are mismatched between the
  709. * attribute list entry and the attribute record, there is
  710. * corruption so we break and return error EIO.
  711. */
  712. if (al_entry->type != a->type)
  713. break;
  714. if (!ntfs_are_names_equal((ntfschar*)((u8*)a +
  715. le16_to_cpu(a->name_offset)), a->name_length,
  716. al_name, al_name_len, CASE_SENSITIVE,
  717. vol->upcase, vol->upcase_len))
  718. break;
  719. ctx->attr = a;
  720. /*
  721. * If no @val specified or @val specified and it matches, we
  722. * have found it!
  723. */
  724. if (!val || (!a->non_resident && le32_to_cpu(
  725. a->data.resident.value_length) == val_len &&
  726. !memcmp((u8*)a +
  727. le16_to_cpu(a->data.resident.value_offset),
  728. val, val_len))) {
  729. ntfs_debug("Done, found.");
  730. return 0;
  731. }
  732. do_next_attr:
  733. /* Proceed to the next attribute in the current mft record. */
  734. a = (ATTR_RECORD*)((u8*)a + le32_to_cpu(a->length));
  735. goto do_next_attr_loop;
  736. }
  737. if (!err) {
  738. ntfs_error(vol->sb, "Base inode 0x%lx contains corrupt "
  739. "attribute list attribute.%s", base_ni->mft_no,
  740. es);
  741. err = -EIO;
  742. }
  743. if (ni != base_ni) {
  744. if (ni)
  745. unmap_extent_mft_record(ni);
  746. ctx->ntfs_ino = base_ni;
  747. ctx->mrec = ctx->base_mrec;
  748. ctx->attr = ctx->base_attr;
  749. }
  750. if (err != -ENOMEM)
  751. NVolSetErrors(vol);
  752. return err;
  753. not_found:
  754. /*
  755. * If we were looking for AT_END, we reset the search context @ctx and
  756. * use ntfs_attr_find() to seek to the end of the base mft record.
  757. */
  758. if (type == AT_END) {
  759. ntfs_attr_reinit_search_ctx(ctx);
  760. return ntfs_attr_find(AT_END, name, name_len, ic, val, val_len,
  761. ctx);
  762. }
  763. /*
  764. * The attribute was not found. Before we return, we want to ensure
  765. * @ctx->mrec and @ctx->attr indicate the position at which the
  766. * attribute should be inserted in the base mft record. Since we also
  767. * want to preserve @ctx->al_entry we cannot reinitialize the search
  768. * context using ntfs_attr_reinit_search_ctx() as this would set
  769. * @ctx->al_entry to NULL. Thus we do the necessary bits manually (see
  770. * ntfs_attr_init_search_ctx() below). Note, we _only_ preserve
  771. * @ctx->al_entry as the remaining fields (base_*) are identical to
  772. * their non base_ counterparts and we cannot set @ctx->base_attr
  773. * correctly yet as we do not know what @ctx->attr will be set to by
  774. * the call to ntfs_attr_find() below.
  775. */
  776. if (ni != base_ni)
  777. unmap_extent_mft_record(ni);
  778. ctx->mrec = ctx->base_mrec;
  779. ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec +
  780. le16_to_cpu(ctx->mrec->attrs_offset));
  781. ctx->is_first = TRUE;
  782. ctx->ntfs_ino = base_ni;
  783. ctx->base_ntfs_ino = NULL;
  784. ctx->base_mrec = NULL;
  785. ctx->base_attr = NULL;
  786. /*
  787. * In case there are multiple matches in the base mft record, need to
  788. * keep enumerating until we get an attribute not found response (or
  789. * another error), otherwise we would keep returning the same attribute
  790. * over and over again and all programs using us for enumeration would
  791. * lock up in a tight loop.
  792. */
  793. do {
  794. err = ntfs_attr_find(type, name, name_len, ic, val, val_len,
  795. ctx);
  796. } while (!err);
  797. ntfs_debug("Done, not found.");
  798. return err;
  799. }
  800. /**
  801. * ntfs_attr_lookup - find an attribute in an ntfs inode
  802. * @type: attribute type to find
  803. * @name: attribute name to find (optional, i.e. NULL means don't care)
  804. * @name_len: attribute name length (only needed if @name present)
  805. * @ic: IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
  806. * @lowest_vcn: lowest vcn to find (optional, non-resident attributes only)
  807. * @val: attribute value to find (optional, resident attributes only)
  808. * @val_len: attribute value length
  809. * @ctx: search context with mft record and attribute to search from
  810. *
  811. * Find an attribute in an ntfs inode. On first search @ctx->ntfs_ino must
  812. * be the base mft record and @ctx must have been obtained from a call to
  813. * ntfs_attr_get_search_ctx().
  814. *
  815. * This function transparently handles attribute lists and @ctx is used to
  816. * continue searches where they were left off at.
  817. *
  818. * After finishing with the attribute/mft record you need to call
  819. * ntfs_attr_put_search_ctx() to cleanup the search context (unmapping any
  820. * mapped inodes, etc).
  821. *
  822. * Return 0 if the search was successful and -errno if not.
  823. *
  824. * When 0, @ctx->attr is the found attribute and it is in mft record
  825. * @ctx->mrec. If an attribute list attribute is present, @ctx->al_entry is
  826. * the attribute list entry of the found attribute.
  827. *
  828. * When -ENOENT, @ctx->attr is the attribute which collates just after the
  829. * attribute being searched for, i.e. if one wants to add the attribute to the
  830. * mft record this is the correct place to insert it into. If an attribute
  831. * list attribute is present, @ctx->al_entry is the attribute list entry which
  832. * collates just after the attribute list entry of the attribute being searched
  833. * for, i.e. if one wants to add the attribute to the mft record this is the
  834. * correct place to insert its attribute list entry into.
  835. *
  836. * When -errno != -ENOENT, an error occured during the lookup. @ctx->attr is
  837. * then undefined and in particular you should not rely on it not changing.
  838. */
  839. int ntfs_attr_lookup(const ATTR_TYPE type, const ntfschar *name,
  840. const u32 name_len, const IGNORE_CASE_BOOL ic,
  841. const VCN lowest_vcn, const u8 *val, const u32 val_len,
  842. ntfs_attr_search_ctx *ctx)
  843. {
  844. ntfs_inode *base_ni;
  845. ntfs_debug("Entering.");
  846. if (ctx->base_ntfs_ino)
  847. base_ni = ctx->base_ntfs_ino;
  848. else
  849. base_ni = ctx->ntfs_ino;
  850. /* Sanity check, just for debugging really. */
  851. BUG_ON(!base_ni);
  852. if (!NInoAttrList(base_ni) || type == AT_ATTRIBUTE_LIST)
  853. return ntfs_attr_find(type, name, name_len, ic, val, val_len,
  854. ctx);
  855. return ntfs_external_attr_find(type, name, name_len, ic, lowest_vcn,
  856. val, val_len, ctx);
  857. }
  858. /**
  859. * ntfs_attr_init_search_ctx - initialize an attribute search context
  860. * @ctx: attribute search context to initialize
  861. * @ni: ntfs inode with which to initialize the search context
  862. * @mrec: mft record with which to initialize the search context
  863. *
  864. * Initialize the attribute search context @ctx with @ni and @mrec.
  865. */
  866. static inline void ntfs_attr_init_search_ctx(ntfs_attr_search_ctx *ctx,
  867. ntfs_inode *ni, MFT_RECORD *mrec)
  868. {
  869. ctx->mrec = mrec;
  870. /* Sanity checks are performed elsewhere. */
  871. ctx->attr = (ATTR_RECORD*)((u8*)mrec + le16_to_cpu(mrec->attrs_offset));
  872. ctx->is_first = TRUE;
  873. ctx->ntfs_ino = ni;
  874. ctx->al_entry = NULL;
  875. ctx->base_ntfs_ino = NULL;
  876. ctx->base_mrec = NULL;
  877. ctx->base_attr = NULL;
  878. }
  879. /**
  880. * ntfs_attr_reinit_search_ctx - reinitialize an attribute search context
  881. * @ctx: attribute search context to reinitialize
  882. *
  883. * Reinitialize the attribute search context @ctx, unmapping an associated
  884. * extent mft record if present, and initialize the search context again.
  885. *
  886. * This is used when a search for a new attribute is being started to reset
  887. * the search context to the beginning.
  888. */
  889. void ntfs_attr_reinit_search_ctx(ntfs_attr_search_ctx *ctx)
  890. {
  891. if (likely(!ctx->base_ntfs_ino)) {
  892. /* No attribute list. */
  893. ctx->is_first = TRUE;
  894. /* Sanity checks are performed elsewhere. */
  895. ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec +
  896. le16_to_cpu(ctx->mrec->attrs_offset));
  897. /*
  898. * This needs resetting due to ntfs_external_attr_find() which
  899. * can leave it set despite having zeroed ctx->base_ntfs_ino.
  900. */
  901. ctx->al_entry = NULL;
  902. return;
  903. } /* Attribute list. */
  904. if (ctx->ntfs_ino != ctx->base_ntfs_ino)
  905. unmap_extent_mft_record(ctx->ntfs_ino);
  906. ntfs_attr_init_search_ctx(ctx, ctx->base_ntfs_ino, ctx->base_mrec);
  907. return;
  908. }
  909. /**
  910. * ntfs_attr_get_search_ctx - allocate/initialize a new attribute search context
  911. * @ni: ntfs inode with which to initialize the search context
  912. * @mrec: mft record with which to initialize the search context
  913. *
  914. * Allocate a new attribute search context, initialize it with @ni and @mrec,
  915. * and return it. Return NULL if allocation failed.
  916. */
  917. ntfs_attr_search_ctx *ntfs_attr_get_search_ctx(ntfs_inode *ni, MFT_RECORD *mrec)
  918. {
  919. ntfs_attr_search_ctx *ctx;
  920. ctx = kmem_cache_alloc(ntfs_attr_ctx_cache, SLAB_NOFS);
  921. if (ctx)
  922. ntfs_attr_init_search_ctx(ctx, ni, mrec);
  923. return ctx;
  924. }
  925. /**
  926. * ntfs_attr_put_search_ctx - release an attribute search context
  927. * @ctx: attribute search context to free
  928. *
  929. * Release the attribute search context @ctx, unmapping an associated extent
  930. * mft record if present.
  931. */
  932. void ntfs_attr_put_search_ctx(ntfs_attr_search_ctx *ctx)
  933. {
  934. if (ctx->base_ntfs_ino && ctx->ntfs_ino != ctx->base_ntfs_ino)
  935. unmap_extent_mft_record(ctx->ntfs_ino);
  936. kmem_cache_free(ntfs_attr_ctx_cache, ctx);
  937. return;
  938. }
  939. /**
  940. * ntfs_attr_find_in_attrdef - find an attribute in the $AttrDef system file
  941. * @vol: ntfs volume to which the attribute belongs
  942. * @type: attribute type which to find
  943. *
  944. * Search for the attribute definition record corresponding to the attribute
  945. * @type in the $AttrDef system file.
  946. *
  947. * Return the attribute type definition record if found and NULL if not found.
  948. */
  949. static ATTR_DEF *ntfs_attr_find_in_attrdef(const ntfs_volume *vol,
  950. const ATTR_TYPE type)
  951. {
  952. ATTR_DEF *ad;
  953. BUG_ON(!vol->attrdef);
  954. BUG_ON(!type);
  955. for (ad = vol->attrdef; (u8*)ad - (u8*)vol->attrdef <
  956. vol->attrdef_size && ad->type; ++ad) {
  957. /* We have not found it yet, carry on searching. */
  958. if (likely(le32_to_cpu(ad->type) < le32_to_cpu(type)))
  959. continue;
  960. /* We found the attribute; return it. */
  961. if (likely(ad->type == type))
  962. return ad;
  963. /* We have gone too far already. No point in continuing. */
  964. break;
  965. }
  966. /* Attribute not found. */
  967. ntfs_debug("Attribute type 0x%x not found in $AttrDef.",
  968. le32_to_cpu(type));
  969. return NULL;
  970. }
  971. /**
  972. * ntfs_attr_size_bounds_check - check a size of an attribute type for validity
  973. * @vol: ntfs volume to which the attribute belongs
  974. * @type: attribute type which to check
  975. * @size: size which to check
  976. *
  977. * Check whether the @size in bytes is valid for an attribute of @type on the
  978. * ntfs volume @vol. This information is obtained from $AttrDef system file.
  979. *
  980. * Return 0 if valid, -ERANGE if not valid, or -ENOENT if the attribute is not
  981. * listed in $AttrDef.
  982. */
  983. int ntfs_attr_size_bounds_check(const ntfs_volume *vol, const ATTR_TYPE type,
  984. const s64 size)
  985. {
  986. ATTR_DEF *ad;
  987. BUG_ON(size < 0);
  988. /*
  989. * $ATTRIBUTE_LIST has a maximum size of 256kiB, but this is not
  990. * listed in $AttrDef.
  991. */
  992. if (unlikely(type == AT_ATTRIBUTE_LIST && size > 256 * 1024))
  993. return -ERANGE;
  994. /* Get the $AttrDef entry for the attribute @type. */
  995. ad = ntfs_attr_find_in_attrdef(vol, type);
  996. if (unlikely(!ad))
  997. return -ENOENT;
  998. /* Do the bounds check. */
  999. if (((sle64_to_cpu(ad->min_size) > 0) &&
  1000. size < sle64_to_cpu(ad->min_size)) ||
  1001. ((sle64_to_cpu(ad->max_size) > 0) && size >
  1002. sle64_to_cpu(ad->max_size)))
  1003. return -ERANGE;
  1004. return 0;
  1005. }
  1006. /**
  1007. * ntfs_attr_can_be_non_resident - check if an attribute can be non-resident
  1008. * @vol: ntfs volume to which the attribute belongs
  1009. * @type: attribute type which to check
  1010. *
  1011. * Check whether the attribute of @type on the ntfs volume @vol is allowed to
  1012. * be non-resident. This information is obtained from $AttrDef system file.
  1013. *
  1014. * Return 0 if the attribute is allowed to be non-resident, -EPERM if not, or
  1015. * -ENOENT if the attribute is not listed in $AttrDef.
  1016. */
  1017. int ntfs_attr_can_be_non_resident(const ntfs_volume *vol, const ATTR_TYPE type)
  1018. {
  1019. ATTR_DEF *ad;
  1020. /*
  1021. * $DATA is always allowed to be non-resident even if $AttrDef does not
  1022. * specify this in the flags of the $DATA attribute definition record.
  1023. */
  1024. if (type == AT_DATA)
  1025. return 0;
  1026. /* Find the attribute definition record in $AttrDef. */
  1027. ad = ntfs_attr_find_in_attrdef(vol, type);
  1028. if (unlikely(!ad))
  1029. return -ENOENT;
  1030. /* Check the flags and return the result. */
  1031. if (ad->flags & CAN_BE_NON_RESIDENT)
  1032. return 0;
  1033. return -EPERM;
  1034. }
  1035. /**
  1036. * ntfs_attr_can_be_resident - check if an attribute can be resident
  1037. * @vol: ntfs volume to which the attribute belongs
  1038. * @type: attribute type which to check
  1039. *
  1040. * Check whether the attribute of @type on the ntfs volume @vol is allowed to
  1041. * be resident. This information is derived from our ntfs knowledge and may
  1042. * not be completely accurate, especially when user defined attributes are
  1043. * present. Basically we allow everything to be resident except for index
  1044. * allocation and $EA attributes.
  1045. *
  1046. * Return 0 if the attribute is allowed to be non-resident and -EPERM if not.
  1047. *
  1048. * Warning: In the system file $MFT the attribute $Bitmap must be non-resident
  1049. * otherwise windows will not boot (blue screen of death)! We cannot
  1050. * check for this here as we do not know which inode's $Bitmap is
  1051. * being asked about so the caller needs to special case this.
  1052. */
  1053. int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPE type)
  1054. {
  1055. if (type != AT_INDEX_ALLOCATION && type != AT_EA)
  1056. return 0;
  1057. return -EPERM;
  1058. }
  1059. /**
  1060. * ntfs_attr_record_resize - resize an attribute record
  1061. * @m: mft record containing attribute record
  1062. * @a: attribute record to resize
  1063. * @new_size: new size in bytes to which to resize the attribute record @a
  1064. *
  1065. * Resize the attribute record @a, i.e. the resident part of the attribute, in
  1066. * the mft record @m to @new_size bytes.
  1067. *
  1068. * Return 0 on success and -errno on error. The following error codes are
  1069. * defined:
  1070. * -ENOSPC - Not enough space in the mft record @m to perform the resize.
  1071. *
  1072. * Note: On error, no modifications have been performed whatsoever.
  1073. *
  1074. * Warning: If you make a record smaller without having copied all the data you
  1075. * are interested in the data may be overwritten.
  1076. */
  1077. int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size)
  1078. {
  1079. ntfs_debug("Entering for new_size %u.", new_size);
  1080. /* Align to 8 bytes if it is not already done. */
  1081. if (new_size & 7)
  1082. new_size = (new_size + 7) & ~7;
  1083. /* If the actual attribute length has changed, move things around. */
  1084. if (new_size != le32_to_cpu(a->length)) {
  1085. u32 new_muse = le32_to_cpu(m->bytes_in_use) -
  1086. le32_to_cpu(a->length) + new_size;
  1087. /* Not enough space in this mft record. */
  1088. if (new_muse > le32_to_cpu(m->bytes_allocated))
  1089. return -ENOSPC;
  1090. /* Move attributes following @a to their new location. */
  1091. memmove((u8*)a + new_size, (u8*)a + le32_to_cpu(a->length),
  1092. le32_to_cpu(m->bytes_in_use) - ((u8*)a -
  1093. (u8*)m) - le32_to_cpu(a->length));
  1094. /* Adjust @m to reflect the change in used space. */
  1095. m->bytes_in_use = cpu_to_le32(new_muse);
  1096. /* Adjust @a to reflect the new size. */
  1097. if (new_size >= offsetof(ATTR_REC, length) + sizeof(a->length))
  1098. a->length = cpu_to_le32(new_size);
  1099. }
  1100. return 0;
  1101. }
  1102. /**
  1103. * ntfs_attr_set - fill (a part of) an attribute with a byte
  1104. * @ni: ntfs inode describing the attribute to fill
  1105. * @ofs: offset inside the attribute at which to start to fill
  1106. * @cnt: number of bytes to fill
  1107. * @val: the unsigned 8-bit value with which to fill the attribute
  1108. *
  1109. * Fill @cnt bytes of the attribute described by the ntfs inode @ni starting at
  1110. * byte offset @ofs inside the attribute with the constant byte @val.
  1111. *
  1112. * This function is effectively like memset() applied to an ntfs attribute.
  1113. * Note thie function actually only operates on the page cache pages belonging
  1114. * to the ntfs attribute and it marks them dirty after doing the memset().
  1115. * Thus it relies on the vm dirty page write code paths to cause the modified
  1116. * pages to be written to the mft record/disk.
  1117. *
  1118. * Return 0 on success and -errno on error. An error code of -ESPIPE means
  1119. * that @ofs + @cnt were outside the end of the attribute and no write was
  1120. * performed.
  1121. */
  1122. int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val)
  1123. {
  1124. ntfs_volume *vol = ni->vol;
  1125. struct address_space *mapping;
  1126. struct page *page;
  1127. u8 *kaddr;
  1128. pgoff_t idx, end;
  1129. unsigned int start_ofs, end_ofs, size;
  1130. ntfs_debug("Entering for ofs 0x%llx, cnt 0x%llx, val 0x%hx.",
  1131. (long long)ofs, (long long)cnt, val);
  1132. BUG_ON(ofs < 0);
  1133. BUG_ON(cnt < 0);
  1134. if (!cnt)
  1135. goto done;
  1136. mapping = VFS_I(ni)->i_mapping;
  1137. /* Work out the starting index and page offset. */
  1138. idx = ofs >> PAGE_CACHE_SHIFT;
  1139. start_ofs = ofs & ~PAGE_CACHE_MASK;
  1140. /* Work out the ending index and page offset. */
  1141. end = ofs + cnt;
  1142. end_ofs = end & ~PAGE_CACHE_MASK;
  1143. /* If the end is outside the inode size return -ESPIPE. */
  1144. if (unlikely(end > i_size_read(VFS_I(ni)))) {
  1145. ntfs_error(vol->sb, "Request exceeds end of attribute.");
  1146. return -ESPIPE;
  1147. }
  1148. end >>= PAGE_CACHE_SHIFT;
  1149. /* If there is a first partial page, need to do it the slow way. */
  1150. if (start_ofs) {
  1151. page = read_cache_page(mapping, idx,
  1152. (filler_t*)mapping->a_ops->readpage, NULL);
  1153. if (IS_ERR(page)) {
  1154. ntfs_error(vol->sb, "Failed to read first partial "
  1155. "page (sync error, index 0x%lx).", idx);
  1156. return PTR_ERR(page);
  1157. }
  1158. wait_on_page_locked(page);
  1159. if (unlikely(!PageUptodate(page))) {
  1160. ntfs_error(vol->sb, "Failed to read first partial page "
  1161. "(async error, index 0x%lx).", idx);
  1162. page_cache_release(page);
  1163. return PTR_ERR(page);
  1164. }
  1165. /*
  1166. * If the last page is the same as the first page, need to
  1167. * limit the write to the end offset.
  1168. */
  1169. size = PAGE_CACHE_SIZE;
  1170. if (idx == end)
  1171. size = end_ofs;
  1172. kaddr = kmap_atomic(page, KM_USER0);
  1173. memset(kaddr + start_ofs, val, size - start_ofs);
  1174. flush_dcache_page(page);
  1175. kunmap_atomic(kaddr, KM_USER0);
  1176. set_page_dirty(page);
  1177. page_cache_release(page);
  1178. if (idx == end)
  1179. goto done;
  1180. idx++;
  1181. }
  1182. /* Do the whole pages the fast way. */
  1183. for (; idx < end; idx++) {
  1184. /* Find or create the current page. (The page is locked.) */
  1185. page = grab_cache_page(mapping, idx);
  1186. if (unlikely(!page)) {
  1187. ntfs_error(vol->sb, "Insufficient memory to grab "
  1188. "page (index 0x%lx).", idx);
  1189. return -ENOMEM;
  1190. }
  1191. kaddr = kmap_atomic(page, KM_USER0);
  1192. memset(kaddr, val, PAGE_CACHE_SIZE);
  1193. flush_dcache_page(page);
  1194. kunmap_atomic(kaddr, KM_USER0);
  1195. /*
  1196. * If the page has buffers, mark them uptodate since buffer
  1197. * state and not page state is definitive in 2.6 kernels.
  1198. */
  1199. if (page_has_buffers(page)) {
  1200. struct buffer_head *bh, *head;
  1201. bh = head = page_buffers(page);
  1202. do {
  1203. set_buffer_uptodate(bh);
  1204. } while ((bh = bh->b_this_page) != head);
  1205. }
  1206. /* Now that buffers are uptodate, set the page uptodate, too. */
  1207. SetPageUptodate(page);
  1208. /*
  1209. * Set the page and all its buffers dirty and mark the inode
  1210. * dirty, too. The VM will write the page later on.
  1211. */
  1212. set_page_dirty(page);
  1213. /* Finally unlock and release the page. */
  1214. unlock_page(page);
  1215. page_cache_release(page);
  1216. }
  1217. /* If there is a last partial page, need to do it the slow way. */
  1218. if (end_ofs) {
  1219. page = read_cache_page(mapping, idx,
  1220. (filler_t*)mapping->a_ops->readpage, NULL);
  1221. if (IS_ERR(page)) {
  1222. ntfs_error(vol->sb, "Failed to read last partial page "
  1223. "(sync error, index 0x%lx).", idx);
  1224. return PTR_ERR(page);
  1225. }
  1226. wait_on_page_locked(page);
  1227. if (unlikely(!PageUptodate(page))) {
  1228. ntfs_error(vol->sb, "Failed to read last partial page "
  1229. "(async error, index 0x%lx).", idx);
  1230. page_cache_release(page);
  1231. return PTR_ERR(page);
  1232. }
  1233. kaddr = kmap_atomic(page, KM_USER0);
  1234. memset(kaddr, val, end_ofs);
  1235. flush_dcache_page(page);
  1236. kunmap_atomic(kaddr, KM_USER0);
  1237. set_page_dirty(page);
  1238. page_cache_release(page);
  1239. }
  1240. done:
  1241. ntfs_debug("Done.");
  1242. return 0;
  1243. }