attrib.c 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280
  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 and $EA are always allowed to be non-resident even if $AttrDef
  1022. * does not specify this in the flags of the $DATA attribute definition
  1023. * record.
  1024. */
  1025. if (type == AT_DATA || type == AT_EA)
  1026. return 0;
  1027. /* Find the attribute definition record in $AttrDef. */
  1028. ad = ntfs_attr_find_in_attrdef(vol, type);
  1029. if (unlikely(!ad))
  1030. return -ENOENT;
  1031. /* Check the flags and return the result. */
  1032. if (ad->flags & CAN_BE_NON_RESIDENT)
  1033. return 0;
  1034. return -EPERM;
  1035. }
  1036. /**
  1037. * ntfs_attr_can_be_resident - check if an attribute can be resident
  1038. * @vol: ntfs volume to which the attribute belongs
  1039. * @type: attribute type which to check
  1040. *
  1041. * Check whether the attribute of @type on the ntfs volume @vol is allowed to
  1042. * be resident. This information is derived from our ntfs knowledge and may
  1043. * not be completely accurate, especially when user defined attributes are
  1044. * present. Basically we allow everything to be resident except for index
  1045. * allocation and $EA attributes.
  1046. *
  1047. * Return 0 if the attribute is allowed to be non-resident and -EPERM if not.
  1048. *
  1049. * Warning: In the system file $MFT the attribute $Bitmap must be non-resident
  1050. * otherwise windows will not boot (blue screen of death)! We cannot
  1051. * check for this here as we do not know which inode's $Bitmap is
  1052. * being asked about so the caller needs to special case this.
  1053. */
  1054. int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPE type)
  1055. {
  1056. if (type != AT_INDEX_ALLOCATION && type != AT_EA)
  1057. return 0;
  1058. return -EPERM;
  1059. }
  1060. /**
  1061. * ntfs_attr_record_resize - resize an attribute record
  1062. * @m: mft record containing attribute record
  1063. * @a: attribute record to resize
  1064. * @new_size: new size in bytes to which to resize the attribute record @a
  1065. *
  1066. * Resize the attribute record @a, i.e. the resident part of the attribute, in
  1067. * the mft record @m to @new_size bytes.
  1068. *
  1069. * Return 0 on success and -errno on error. The following error codes are
  1070. * defined:
  1071. * -ENOSPC - Not enough space in the mft record @m to perform the resize.
  1072. *
  1073. * Note: On error, no modifications have been performed whatsoever.
  1074. *
  1075. * Warning: If you make a record smaller without having copied all the data you
  1076. * are interested in the data may be overwritten.
  1077. */
  1078. int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size)
  1079. {
  1080. ntfs_debug("Entering for new_size %u.", new_size);
  1081. /* Align to 8 bytes if it is not already done. */
  1082. if (new_size & 7)
  1083. new_size = (new_size + 7) & ~7;
  1084. /* If the actual attribute length has changed, move things around. */
  1085. if (new_size != le32_to_cpu(a->length)) {
  1086. u32 new_muse = le32_to_cpu(m->bytes_in_use) -
  1087. le32_to_cpu(a->length) + new_size;
  1088. /* Not enough space in this mft record. */
  1089. if (new_muse > le32_to_cpu(m->bytes_allocated))
  1090. return -ENOSPC;
  1091. /* Move attributes following @a to their new location. */
  1092. memmove((u8*)a + new_size, (u8*)a + le32_to_cpu(a->length),
  1093. le32_to_cpu(m->bytes_in_use) - ((u8*)a -
  1094. (u8*)m) - le32_to_cpu(a->length));
  1095. /* Adjust @m to reflect the change in used space. */
  1096. m->bytes_in_use = cpu_to_le32(new_muse);
  1097. /* Adjust @a to reflect the new size. */
  1098. if (new_size >= offsetof(ATTR_REC, length) + sizeof(a->length))
  1099. a->length = cpu_to_le32(new_size);
  1100. }
  1101. return 0;
  1102. }
  1103. /**
  1104. * ntfs_attr_set - fill (a part of) an attribute with a byte
  1105. * @ni: ntfs inode describing the attribute to fill
  1106. * @ofs: offset inside the attribute at which to start to fill
  1107. * @cnt: number of bytes to fill
  1108. * @val: the unsigned 8-bit value with which to fill the attribute
  1109. *
  1110. * Fill @cnt bytes of the attribute described by the ntfs inode @ni starting at
  1111. * byte offset @ofs inside the attribute with the constant byte @val.
  1112. *
  1113. * This function is effectively like memset() applied to an ntfs attribute.
  1114. * Note thie function actually only operates on the page cache pages belonging
  1115. * to the ntfs attribute and it marks them dirty after doing the memset().
  1116. * Thus it relies on the vm dirty page write code paths to cause the modified
  1117. * pages to be written to the mft record/disk.
  1118. *
  1119. * Return 0 on success and -errno on error. An error code of -ESPIPE means
  1120. * that @ofs + @cnt were outside the end of the attribute and no write was
  1121. * performed.
  1122. */
  1123. int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val)
  1124. {
  1125. ntfs_volume *vol = ni->vol;
  1126. struct address_space *mapping;
  1127. struct page *page;
  1128. u8 *kaddr;
  1129. pgoff_t idx, end;
  1130. unsigned int start_ofs, end_ofs, size;
  1131. ntfs_debug("Entering for ofs 0x%llx, cnt 0x%llx, val 0x%hx.",
  1132. (long long)ofs, (long long)cnt, val);
  1133. BUG_ON(ofs < 0);
  1134. BUG_ON(cnt < 0);
  1135. if (!cnt)
  1136. goto done;
  1137. mapping = VFS_I(ni)->i_mapping;
  1138. /* Work out the starting index and page offset. */
  1139. idx = ofs >> PAGE_CACHE_SHIFT;
  1140. start_ofs = ofs & ~PAGE_CACHE_MASK;
  1141. /* Work out the ending index and page offset. */
  1142. end = ofs + cnt;
  1143. end_ofs = end & ~PAGE_CACHE_MASK;
  1144. /* If the end is outside the inode size return -ESPIPE. */
  1145. if (unlikely(end > i_size_read(VFS_I(ni)))) {
  1146. ntfs_error(vol->sb, "Request exceeds end of attribute.");
  1147. return -ESPIPE;
  1148. }
  1149. end >>= PAGE_CACHE_SHIFT;
  1150. /* If there is a first partial page, need to do it the slow way. */
  1151. if (start_ofs) {
  1152. page = read_cache_page(mapping, idx,
  1153. (filler_t*)mapping->a_ops->readpage, NULL);
  1154. if (IS_ERR(page)) {
  1155. ntfs_error(vol->sb, "Failed to read first partial "
  1156. "page (sync error, index 0x%lx).", idx);
  1157. return PTR_ERR(page);
  1158. }
  1159. wait_on_page_locked(page);
  1160. if (unlikely(!PageUptodate(page))) {
  1161. ntfs_error(vol->sb, "Failed to read first partial page "
  1162. "(async error, index 0x%lx).", idx);
  1163. page_cache_release(page);
  1164. return PTR_ERR(page);
  1165. }
  1166. /*
  1167. * If the last page is the same as the first page, need to
  1168. * limit the write to the end offset.
  1169. */
  1170. size = PAGE_CACHE_SIZE;
  1171. if (idx == end)
  1172. size = end_ofs;
  1173. kaddr = kmap_atomic(page, KM_USER0);
  1174. memset(kaddr + start_ofs, val, size - start_ofs);
  1175. flush_dcache_page(page);
  1176. kunmap_atomic(kaddr, KM_USER0);
  1177. set_page_dirty(page);
  1178. page_cache_release(page);
  1179. if (idx == end)
  1180. goto done;
  1181. idx++;
  1182. }
  1183. /* Do the whole pages the fast way. */
  1184. for (; idx < end; idx++) {
  1185. /* Find or create the current page. (The page is locked.) */
  1186. page = grab_cache_page(mapping, idx);
  1187. if (unlikely(!page)) {
  1188. ntfs_error(vol->sb, "Insufficient memory to grab "
  1189. "page (index 0x%lx).", idx);
  1190. return -ENOMEM;
  1191. }
  1192. kaddr = kmap_atomic(page, KM_USER0);
  1193. memset(kaddr, val, PAGE_CACHE_SIZE);
  1194. flush_dcache_page(page);
  1195. kunmap_atomic(kaddr, KM_USER0);
  1196. /*
  1197. * If the page has buffers, mark them uptodate since buffer
  1198. * state and not page state is definitive in 2.6 kernels.
  1199. */
  1200. if (page_has_buffers(page)) {
  1201. struct buffer_head *bh, *head;
  1202. bh = head = page_buffers(page);
  1203. do {
  1204. set_buffer_uptodate(bh);
  1205. } while ((bh = bh->b_this_page) != head);
  1206. }
  1207. /* Now that buffers are uptodate, set the page uptodate, too. */
  1208. SetPageUptodate(page);
  1209. /*
  1210. * Set the page and all its buffers dirty and mark the inode
  1211. * dirty, too. The VM will write the page later on.
  1212. */
  1213. set_page_dirty(page);
  1214. /* Finally unlock and release the page. */
  1215. unlock_page(page);
  1216. page_cache_release(page);
  1217. }
  1218. /* If there is a last partial page, need to do it the slow way. */
  1219. if (end_ofs) {
  1220. page = read_cache_page(mapping, idx,
  1221. (filler_t*)mapping->a_ops->readpage, NULL);
  1222. if (IS_ERR(page)) {
  1223. ntfs_error(vol->sb, "Failed to read last partial page "
  1224. "(sync error, index 0x%lx).", idx);
  1225. return PTR_ERR(page);
  1226. }
  1227. wait_on_page_locked(page);
  1228. if (unlikely(!PageUptodate(page))) {
  1229. ntfs_error(vol->sb, "Failed to read last partial page "
  1230. "(async error, index 0x%lx).", idx);
  1231. page_cache_release(page);
  1232. return PTR_ERR(page);
  1233. }
  1234. kaddr = kmap_atomic(page, KM_USER0);
  1235. memset(kaddr, val, end_ofs);
  1236. flush_dcache_page(page);
  1237. kunmap_atomic(kaddr, KM_USER0);
  1238. set_page_dirty(page);
  1239. page_cache_release(page);
  1240. }
  1241. done:
  1242. ntfs_debug("Done.");
  1243. return 0;
  1244. }