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